[CMAKE]
[reactos.git] / subsystems / win32 / win32k / eng / surface.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Driver Surace Functions
5 * FILE: subsys/win32k/eng/surface.c
6 * PROGRAMER: Jason Filby
7 * REVISION HISTORY:
8 * 3/7/1999: Created
9 * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
10 * TESTING TO BE DONE:
11 * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
12 * refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
13 */
14
15 #include <win32k.h>
16
17 #define NDEBUG
18 #include <debug.h>
19
20 enum Rle_EscapeCodes
21 {
22 RLE_EOL = 0, /* End of line */
23 RLE_END = 1, /* End of bitmap */
24 RLE_DELTA = 2 /* Delta */
25 };
26
27 INT FASTCALL BitsPerFormat(ULONG Format)
28 {
29 switch (Format)
30 {
31 case BMF_1BPP:
32 return 1;
33
34 case BMF_4BPP:
35 /* Fall through */
36 case BMF_4RLE:
37 return 4;
38
39 case BMF_8BPP:
40 /* Fall through */
41 case BMF_8RLE:
42 return 8;
43
44 case BMF_16BPP:
45 return 16;
46
47 case BMF_24BPP:
48 return 24;
49
50 case BMF_32BPP:
51 return 32;
52
53 default:
54 return 0;
55 }
56 }
57
58 ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
59 {
60 switch (Compression)
61 {
62 case BI_RGB:
63 /* Fall through */
64 case BI_BITFIELDS:
65 switch (Bits)
66 {
67 case 1:
68 return BMF_1BPP;
69 case 4:
70 return BMF_4BPP;
71 case 8:
72 return BMF_8BPP;
73 case 16:
74 return BMF_16BPP;
75 case 24:
76 return BMF_24BPP;
77 case 32:
78 return BMF_32BPP;
79 }
80 return 0;
81
82 case BI_RLE4:
83 return BMF_4RLE;
84
85 case BI_RLE8:
86 return BMF_8RLE;
87
88 default:
89 return 0;
90 }
91 }
92
93 BOOL INTERNAL_CALL
94 SURFACE_Cleanup(PVOID ObjectBody)
95 {
96 PSURFACE psurf = (PSURFACE)ObjectBody;
97 PVOID pvBits = psurf->SurfObj.pvBits;
98
99 /* If this is an API bitmap, free the bits */
100 if (pvBits != NULL &&
101 (psurf->flFlags & BITMAPOBJ_IS_APIBITMAP))
102 {
103 /* Check if we have a DIB section */
104 if (psurf->hSecure)
105 {
106 // FIXME: IMPLEMENT ME!
107 // MmUnsecureVirtualMemory(psurf->hSecure);
108 if (psurf->hDIBSection)
109 {
110 /* DIB was created from a section */
111 NTSTATUS Status;
112
113 pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
114 Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits);
115 if (!NT_SUCCESS(Status))
116 {
117 DPRINT1("Could not unmap section view!\n");
118 // Should we BugCheck here?
119 }
120 }
121 else
122 {
123 /* DIB was allocated */
124 EngFreeUserMem(pvBits);
125 }
126 }
127 else
128 {
129 // FIXME: use TAG
130 ExFreePool(psurf->SurfObj.pvBits);
131 }
132
133 if (psurf->hDIBPalette != NULL)
134 {
135 GreDeleteObject(psurf->hDIBPalette);
136 }
137 }
138
139 if (NULL != psurf->BitsLock)
140 {
141 ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
142 psurf->BitsLock = NULL;
143 }
144
145 return TRUE;
146 }
147
148 BOOL INTERNAL_CALL
149 SURFACE_InitBitsLock(PSURFACE psurf)
150 {
151 psurf->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
152 sizeof(FAST_MUTEX),
153 TAG_SURFACE);
154 if (NULL == psurf->BitsLock)
155 {
156 return FALSE;
157 }
158
159 ExInitializeFastMutex(psurf->BitsLock);
160
161 return TRUE;
162 }
163
164 void INTERNAL_CALL
165 SURFACE_CleanupBitsLock(PSURFACE psurf)
166 {
167 if (NULL != psurf->BitsLock)
168 {
169 ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
170 psurf->BitsLock = NULL;
171 }
172 }
173
174
175 /*
176 * @implemented
177 */
178 HBITMAP APIENTRY
179 EngCreateDeviceBitmap(IN DHSURF dhsurf,
180 IN SIZEL Size,
181 IN ULONG Format)
182 {
183 HBITMAP NewBitmap;
184 SURFOBJ *pso;
185
186 NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
187 if (!NewBitmap)
188 {
189 DPRINT1("EngCreateBitmap failed\n");
190 return 0;
191 }
192
193 pso = EngLockSurface((HSURF)NewBitmap);
194 if (!pso)
195 {
196 DPRINT1("EngLockSurface failed on newly created bitmap!\n");
197 GreDeleteObject(NewBitmap);
198 return NULL;
199 }
200
201 pso->dhsurf = dhsurf;
202 EngUnlockSurface(pso);
203
204 return NewBitmap;
205 }
206
207 BOOL DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format)
208 {
209 INT x = 0;
210 INT y = Size.cy - 1;
211 INT c;
212 INT length;
213 INT width;
214 INT height = Size.cy - 1;
215 BYTE *begin = CompressedBits;
216 BYTE *bits = CompressedBits;
217 BYTE *temp;
218 INT shift = 0;
219
220 if (Format == BMF_4RLE)
221 shift = 1;
222 else if(Format != BMF_8RLE)
223 return FALSE;
224
225 width = ((Size.cx + shift) >> shift);
226
227 _SEH2_TRY
228 {
229 while (y >= 0)
230 {
231 length = (*bits++) >> shift;
232 if (length)
233 {
234 c = *bits++;
235 while (length--)
236 {
237 if (x >= width) break;
238 temp = UncompressedBits + (((height - y) * Delta) + x);
239 x++;
240 *temp = c;
241 }
242 }
243 else
244 {
245 length = *bits++;
246 switch (length)
247 {
248 case RLE_EOL:
249 x = 0;
250 y--;
251 break;
252 case RLE_END:
253 _SEH2_YIELD(return TRUE);
254 case RLE_DELTA:
255 x += (*bits++) >> shift;
256 y -= (*bits++) >> shift;
257 break;
258 default:
259 length = length >> shift;
260 while (length--)
261 {
262 c = *bits++;
263 if (x < width)
264 {
265 temp = UncompressedBits + (((height - y) * Delta) + x);
266 x++;
267 *temp = c;
268 }
269 }
270 if ((bits - begin) & 1)
271 {
272 bits++;
273 }
274 }
275 }
276 }
277 }
278 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
279 {
280 DPRINT1("Decoding error\n");
281 _SEH2_YIELD(return FALSE);
282 }
283 _SEH2_END;
284
285 return TRUE;
286 }
287
288 HBITMAP FASTCALL
289 IntCreateBitmap(IN SIZEL Size,
290 IN LONG Width,
291 IN ULONG Format,
292 IN ULONG Flags,
293 IN PVOID Bits)
294 {
295 HBITMAP hbmp;
296 SURFOBJ *pso;
297 PSURFACE psurf;
298 PVOID UncompressedBits;
299 ULONG UncompressedFormat;
300
301 if (Format == 0)
302 return 0;
303
304 psurf = SURFACE_AllocSurfaceWithHandle();
305 if (psurf == NULL)
306 {
307 return 0;
308 }
309 hbmp = psurf->BaseObject.hHmgr;
310
311 if (! SURFACE_InitBitsLock(psurf))
312 {
313 SURFACE_UnlockSurface(psurf);
314 SURFACE_FreeSurfaceByHandle(hbmp);
315 return 0;
316 }
317 pso = &psurf->SurfObj;
318
319 if (Format == BMF_4RLE)
320 {
321 pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
322 pso->cjBits = pso->lDelta * Size.cy;
323 UncompressedFormat = BMF_4BPP;
324 UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
325 DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
326 }
327 else if (Format == BMF_8RLE)
328 {
329 pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
330 pso->cjBits = pso->lDelta * Size.cy;
331 UncompressedFormat = BMF_8BPP;
332 UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
333 DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
334 }
335 else
336 {
337 pso->lDelta = abs(Width);
338 pso->cjBits = pso->lDelta * Size.cy;
339 UncompressedBits = Bits;
340 UncompressedFormat = Format;
341 }
342
343 if (UncompressedBits != NULL)
344 {
345 pso->pvBits = UncompressedBits;
346 }
347 else
348 {
349 if (pso->cjBits == 0)
350 {
351 pso->pvBits = NULL;
352 }
353 else
354 {
355 if (0 != (Flags & BMF_USERMEM))
356 {
357 pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
358 }
359 else
360 {
361 pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
362 0 : FL_ZERO_MEMORY,
363 pso->cjBits, TAG_DIB);
364 }
365 if (pso->pvBits == NULL)
366 {
367 SURFACE_UnlockSurface(psurf);
368 SURFACE_FreeSurfaceByHandle(hbmp);
369 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
370 return 0;
371 }
372 }
373 }
374
375 if (0 == (Flags & BMF_TOPDOWN))
376 {
377 pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
378 pso->lDelta = - pso->lDelta;
379 }
380 else
381 {
382 pso->pvScan0 = pso->pvBits;
383 }
384
385 pso->dhsurf = 0; /* device managed surface */
386 pso->hsurf = (HSURF)hbmp;
387 pso->dhpdev = NULL;
388 pso->hdev = NULL;
389 pso->sizlBitmap = Size;
390 pso->iBitmapFormat = UncompressedFormat;
391 pso->iType = STYPE_BITMAP;
392 pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
393 pso->iUniq = 0;
394
395 psurf->flHooks = 0;
396 psurf->flFlags = 0;
397 psurf->dimension.cx = 0;
398 psurf->dimension.cy = 0;
399
400 psurf->hSecure = NULL;
401 psurf->hDIBSection = NULL;
402
403 SURFACE_UnlockSurface(psurf);
404
405 return hbmp;
406 }
407
408 /* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
409 typedef struct _DEVBITMAPINFO
410 {
411 ULONG Format;
412 ULONG Width;
413 ULONG Height;
414 ULONG Flags;
415 ULONG Size;
416 } DEVBITMAPINFO, *PDEVBITMAPINFO;
417
418 SURFOBJ*
419 FASTCALL
420 SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
421 IN PVOID Bits)
422 {
423 BOOLEAN Compressed = FALSE;
424 ULONG ScanLine = 0; // Compiler is dumb
425 ULONG Size;
426 SURFOBJ *pso;
427 PSURFACE psurf;
428 SIZEL LocalSize;
429 BOOLEAN AllocatedLocally = FALSE;
430 PVOID DecompressedBits = NULL;
431
432 /*
433 * First, check the format so we can get the aligned scanline width.
434 * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
435 * since they are compressed surfaces!
436 */
437 switch (BitmapInfo->Format)
438 {
439 case BMF_1BPP:
440 ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3;
441 break;
442
443 case BMF_4BPP:
444 ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
445 break;
446
447 case BMF_8BPP:
448 ScanLine = (BitmapInfo->Width + 3) & ~3;
449 break;
450
451 case BMF_16BPP:
452 ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1;
453 break;
454
455 case BMF_24BPP:
456 ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3;
457 break;
458
459 case BMF_32BPP:
460 ScanLine = BitmapInfo->Width << 2;
461 break;
462
463 case BMF_8RLE:
464 ScanLine = (BitmapInfo->Width + 3) & ~3;
465 Compressed = TRUE;
466 break;
467 case BMF_4RLE:
468 ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
469 Compressed = TRUE;
470 break;
471
472 case BMF_JPEG:
473 case BMF_PNG:
474 ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
475 DPRINT1("No support for JPEG and PNG formats\n");
476 return NULL;
477
478 default:
479 DPRINT1("Invalid bitmap format\n");
480 return NULL;
481 }
482
483 /* Save local bitmap size */
484 LocalSize.cy = BitmapInfo->Height;
485 LocalSize.cx = BitmapInfo->Width;
486
487 /* Does the device manage its own surface? */
488 if (!Bits)
489 {
490 /* We need to allocate bits for the caller, figure out the size */
491 if (Compressed)
492 {
493 /* Note: we should not be seeing this scenario from ENGDDI */
494 ASSERT(FALSE);
495 DPRINT1("RLE compressed bitmap requested with no valid bitmap bits\n");
496 return NULL;
497 }
498 else
499 {
500 /* The height times the bytes for each scanline */
501 Size = BitmapInfo->Height * ScanLine;
502 }
503
504 if (Size)
505 {
506 /* Check for allocation flag */
507 if (BitmapInfo->Flags & BMF_USERMEM)
508 {
509 /* Get the bits from user-mode memory */
510 Bits = EngAllocUserMem(Size, 'mbuG');
511 }
512 else
513 {
514 /* Get kernel bits (zeroed out if requested) */
515 Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
516 Size,
517 TAG_DIB);
518 }
519 AllocatedLocally = TRUE;
520 /* Bail out if that failed */
521 if (!Bits) return NULL;
522 }
523 }
524 else
525 {
526 /* Should not have asked for user memory */
527 ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
528
529 if (Compressed)
530 {
531 DecompressedBits = EngAllocMem(FL_ZERO_MEMORY, BitmapInfo->Height * ScanLine, TAG_DIB);
532
533 if(!DecompressedBits)
534 return NULL;
535
536 if(!DecompressBitmap(LocalSize, (BYTE *)Bits, (BYTE *)DecompressedBits, ScanLine, BitmapInfo->Format))
537 {
538 EngFreeMem(DecompressedBits);
539 return NULL;
540 }
541
542 BitmapInfo->Format = (BitmapInfo->Format == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
543 }
544 }
545
546 /* Allocate the actual surface object structure */
547 psurf = SURFACE_AllocSurfaceWithHandle();
548 if (!psurf)
549 {
550 if(Bits && AllocatedLocally)
551 {
552 if(BitmapInfo->Flags & BMF_USERMEM)
553 EngFreeUserMem(Bits);
554 else
555 EngFreeMem(Bits);
556 }
557 if (DecompressedBits)
558 EngFreeMem(DecompressedBits);
559 return NULL;
560 }
561
562 /* Lock down the surface */
563 if (!SURFACE_InitBitsLock(psurf))
564 {
565 /* Bail out if that failed */
566 SURFACE_UnlockSurface(psurf);
567 SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr);
568 return NULL;
569 }
570
571 /* We should now have our surface object */
572 pso = &psurf->SurfObj;
573
574 /* Save format and flags */
575 pso->iBitmapFormat = BitmapInfo->Format;
576 pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
577
578 /* Save size and type */
579 pso->sizlBitmap = LocalSize;
580 pso->iType = STYPE_BITMAP;
581
582 /* Device-managed surface, no flags or dimension */
583 pso->dhsurf = 0;
584 pso->dhpdev = NULL;
585 pso->hdev = NULL;
586 psurf->flFlags = 0;
587 psurf->dimension.cx = 0;
588 psurf->dimension.cy = 0;
589 psurf->hSecure = NULL;
590 psurf->hDIBSection = NULL;
591 psurf->flHooks = 0;
592
593 /* Set bits */
594 if(Compressed)
595 pso->pvBits = DecompressedBits;
596 else
597 pso->pvBits = Bits;
598
599 /* Number of bits is based on the height times the scanline */
600 pso->cjBits = BitmapInfo->Height * ScanLine;
601 if (BitmapInfo->Flags & BMF_TOPDOWN)
602 {
603 /* For topdown, the base address starts with the bits */
604 pso->pvScan0 = pso->pvBits;
605 pso->lDelta = ScanLine;
606 }
607 else
608 {
609 /* Otherwise we start with the end and go up */
610 pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
611 pso->lDelta = -ScanLine;
612 }
613
614 /* Finally set the handle and uniq */
615 pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
616 pso->iUniq = 0;
617
618 /* Unlock and return the surface */
619 SURFACE_UnlockSurface(psurf);
620 return pso;
621 }
622
623 /*
624 * @implemented
625 */
626 HBITMAP
627 APIENTRY
628 EngCreateBitmap(IN SIZEL Size,
629 IN LONG Width,
630 IN ULONG Format,
631 IN ULONG Flags,
632 IN PVOID Bits)
633 {
634 SURFOBJ* Surface;
635 DEVBITMAPINFO BitmapInfo;
636
637 /* Capture the parameters */
638 BitmapInfo.Format = Format;
639 BitmapInfo.Width = Size.cx;
640 BitmapInfo.Height = Size.cy;
641 BitmapInfo.Flags = Flags;
642
643 /*
644 * If the display driver supports framebuffer access, use the scanline width
645 * to determine the actual width of the bitmap, and convert it to pels instead
646 * of bytes.
647 */
648 if ((Bits) && (Width))
649 {
650 switch (BitmapInfo.Format)
651 {
652 /* Do the conversion for each bit depth we support */
653 case BMF_1BPP:
654 BitmapInfo.Width = Width * 8;
655 break;
656 case BMF_4BPP:
657 BitmapInfo.Width = Width * 2;
658 break;
659 case BMF_8BPP:
660 BitmapInfo.Width = Width;
661 break;
662 case BMF_16BPP:
663 BitmapInfo.Width = Width / 2;
664 break;
665 case BMF_24BPP:
666 BitmapInfo.Width = Width / 3;
667 break;
668 case BMF_32BPP:
669 BitmapInfo.Width = Width / 4;
670 break;
671 }
672 }
673
674 /* Now create the surface */
675 Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits);
676 if (!Surface) return 0;
677
678 /* Set public ownership and reutrn the handle */
679 GDIOBJ_SetOwnership(Surface->hsurf, NULL);
680 return Surface->hsurf;
681 }
682
683 /*
684 * @unimplemented
685 */
686 HSURF APIENTRY
687 EngCreateDeviceSurface(IN DHSURF dhsurf,
688 IN SIZEL Size,
689 IN ULONG Format)
690 {
691 HSURF hsurf;
692 SURFOBJ *pso;
693 PSURFACE psurf;
694
695 psurf = SURFACE_AllocSurfaceWithHandle();
696 if (!psurf)
697 {
698 return 0;
699 }
700
701 hsurf = psurf->BaseObject.hHmgr;
702 GDIOBJ_SetOwnership(hsurf, NULL);
703
704 if (!SURFACE_InitBitsLock(psurf))
705 {
706 SURFACE_UnlockSurface(psurf);
707 SURFACE_FreeSurfaceByHandle(hsurf);
708 return 0;
709 }
710 pso = &psurf->SurfObj;
711
712 pso->dhsurf = dhsurf;
713 pso->hsurf = hsurf;
714 pso->sizlBitmap = Size;
715 pso->iBitmapFormat = Format;
716 pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
717 pso->iType = STYPE_DEVICE;
718 pso->iUniq = 0;
719
720 psurf->flHooks = 0;
721
722 SURFACE_UnlockSurface(psurf);
723
724 return hsurf;
725 }
726
727 /*
728 * @implemented
729 */
730 BOOL
731 APIENTRY
732 EngAssociateSurface(
733 IN HSURF hsurf,
734 IN HDEV hdev,
735 IN FLONG flHooks)
736 {
737 SURFOBJ *pso;
738 PSURFACE psurf;
739 PDEVOBJ* ppdev;
740
741 ppdev = (PDEVOBJ*)hdev;
742
743 /* Lock the surface */
744 psurf = SURFACE_LockSurface(hsurf);
745 if (!psurf)
746 {
747 return FALSE;
748 }
749 pso = &psurf->SurfObj;
750
751 /* Associate the hdev */
752 pso->hdev = hdev;
753 pso->dhpdev = ppdev->dhpdev;
754
755 /* Hook up specified functions */
756 psurf->flHooks = flHooks;
757
758 SURFACE_UnlockSurface(psurf);
759
760 return TRUE;
761 }
762
763 /*
764 * @implemented
765 */
766 BOOL APIENTRY
767 EngModifySurface(
768 IN HSURF hsurf,
769 IN HDEV hdev,
770 IN FLONG flHooks,
771 IN FLONG flSurface,
772 IN DHSURF dhsurf,
773 OUT VOID *pvScan0,
774 IN LONG lDelta,
775 IN VOID *pvReserved)
776 {
777 SURFOBJ *pso;
778 PSURFACE psurf;
779 PDEVOBJ* ppdev;
780
781 psurf = SURFACE_LockSurface(hsurf);
782 if (psurf == NULL)
783 {
784 return FALSE;
785 }
786
787 ppdev = (PDEVOBJ*)hdev;
788 pso = &psurf->SurfObj;
789 pso->dhsurf = dhsurf;
790 pso->lDelta = lDelta;
791 pso->pvScan0 = pvScan0;
792
793 /* Associate the hdev */
794 pso->hdev = hdev;
795 pso->dhpdev = ppdev->dhpdev;
796
797 /* Hook up specified functions */
798 psurf->flHooks = flHooks;
799
800 SURFACE_UnlockSurface(psurf);
801
802 return TRUE;
803 }
804
805 /*
806 * @implemented
807 */
808 BOOL APIENTRY
809 EngDeleteSurface(IN HSURF hsurf)
810 {
811 GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
812 SURFACE_FreeSurfaceByHandle(hsurf);
813 return TRUE;
814 }
815
816 /*
817 * @implemented
818 */
819 BOOL APIENTRY
820 EngEraseSurface(SURFOBJ *pso,
821 RECTL *Rect,
822 ULONG iColor)
823 {
824 ASSERT(pso);
825 ASSERT(Rect);
826 return FillSolid(pso, Rect, iColor);
827 }
828
829 /*
830 * @implemented
831 */
832 SURFOBJ * APIENTRY
833 NtGdiEngLockSurface(IN HSURF hsurf)
834 {
835 return EngLockSurface(hsurf);
836 }
837
838
839 /*
840 * @implemented
841 */
842 SURFOBJ * APIENTRY
843 EngLockSurface(IN HSURF hsurf)
844 {
845 SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
846
847 if (psurf != NULL)
848 return &psurf->SurfObj;
849
850 return NULL;
851 }
852
853
854 /*
855 * @implemented
856 */
857 VOID APIENTRY
858 NtGdiEngUnlockSurface(IN SURFOBJ *pso)
859 {
860 EngUnlockSurface(pso);
861 }
862
863 /*
864 * @implemented
865 */
866 VOID APIENTRY
867 EngUnlockSurface(IN SURFOBJ *pso)
868 {
869 if (pso != NULL)
870 {
871 SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
872 GDIOBJ_ShareUnlockObjByPtr((POBJ)psurf);
873 }
874 }
875
876
877 /* EOF */