- Enable ACPI
[reactos.git] / reactos / 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 <w32k.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 VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
208 {
209 int x = 0;
210 int y = Size.cy - 1;
211 int c;
212 int length;
213 int width = ((Size.cx+1)/2);
214 int height = Size.cy - 1;
215 BYTE *begin = CompressedBits;
216 BYTE *bits = CompressedBits;
217 BYTE *temp;
218 while (y >= 0)
219 {
220 length = *bits++ / 2;
221 if (length)
222 {
223 c = *bits++;
224 while (length--)
225 {
226 if (x >= width) break;
227 temp = UncompressedBits + (((height - y) * Delta) + x);
228 x++;
229 *temp = c;
230 }
231 }
232 else
233 {
234 length = *bits++;
235 switch (length)
236 {
237 case RLE_EOL:
238 x = 0;
239 y--;
240 break;
241 case RLE_END:
242 return;
243 case RLE_DELTA:
244 x += (*bits++)/2;
245 y -= (*bits++)/2;
246 break;
247 default:
248 length /= 2;
249 while (length--)
250 {
251 c = *bits++;
252 if (x < width)
253 {
254 temp = UncompressedBits + (((height - y) * Delta) + x);
255 x++;
256 *temp = c;
257 }
258 }
259 if ((bits - begin) & 1)
260 {
261 bits++;
262 }
263 }
264 }
265 }
266 }
267
268 VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
269 {
270 int x = 0;
271 int y = Size.cy - 1;
272 int c;
273 int length;
274 int width = Size.cx;
275 int height = Size.cy - 1;
276 BYTE *begin = CompressedBits;
277 BYTE *bits = CompressedBits;
278 BYTE *temp;
279 while (y >= 0)
280 {
281 length = *bits++;
282 if (length)
283 {
284 c = *bits++;
285 while (length--)
286 {
287 if (x >= width) break;
288 temp = UncompressedBits + (((height - y) * Delta) + x);
289 x++;
290 *temp = c;
291 }
292 }
293 else
294 {
295 length = *bits++;
296 switch (length)
297 {
298 case RLE_EOL:
299 x = 0;
300 y--;
301 break;
302 case RLE_END:
303 return;
304 case RLE_DELTA:
305 x += *bits++;
306 y -= *bits++;
307 break;
308 default:
309 while (length--)
310 {
311 c = *bits++;
312 if (x < width)
313 {
314 temp = UncompressedBits + (((height - y) * Delta) + x);
315 x++;
316 *temp = c;
317 }
318 }
319 if ((bits - begin) & 1)
320 {
321 bits++;
322 }
323 }
324 }
325 }
326 }
327
328 HBITMAP FASTCALL
329 IntCreateBitmap(IN SIZEL Size,
330 IN LONG Width,
331 IN ULONG Format,
332 IN ULONG Flags,
333 IN PVOID Bits)
334 {
335 HBITMAP hbmp;
336 SURFOBJ *pso;
337 PSURFACE psurf;
338 PVOID UncompressedBits;
339 ULONG UncompressedFormat;
340
341 if (Format == 0)
342 return 0;
343
344 psurf = SURFACE_AllocSurfaceWithHandle();
345 if (psurf == NULL)
346 {
347 return 0;
348 }
349 hbmp = psurf->BaseObject.hHmgr;
350
351 if (! SURFACE_InitBitsLock(psurf))
352 {
353 SURFACE_UnlockSurface(psurf);
354 SURFACE_FreeSurfaceByHandle(hbmp);
355 return 0;
356 }
357 pso = &psurf->SurfObj;
358
359 if (Format == BMF_4RLE)
360 {
361 pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
362 pso->cjBits = pso->lDelta * Size.cy;
363 UncompressedFormat = BMF_4BPP;
364 UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
365 Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
366 }
367 else if (Format == BMF_8RLE)
368 {
369 pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
370 pso->cjBits = pso->lDelta * Size.cy;
371 UncompressedFormat = BMF_8BPP;
372 UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
373 Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
374 }
375 else
376 {
377 pso->lDelta = abs(Width);
378 pso->cjBits = pso->lDelta * Size.cy;
379 UncompressedBits = Bits;
380 UncompressedFormat = Format;
381 }
382
383 if (UncompressedBits != NULL)
384 {
385 pso->pvBits = UncompressedBits;
386 }
387 else
388 {
389 if (pso->cjBits == 0)
390 {
391 pso->pvBits = NULL;
392 }
393 else
394 {
395 if (0 != (Flags & BMF_USERMEM))
396 {
397 pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
398 }
399 else
400 {
401 pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
402 0 : FL_ZERO_MEMORY,
403 pso->cjBits, TAG_DIB);
404 }
405 if (pso->pvBits == NULL)
406 {
407 SURFACE_UnlockSurface(psurf);
408 SURFACE_FreeSurfaceByHandle(hbmp);
409 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
410 return 0;
411 }
412 }
413 }
414
415 if (0 == (Flags & BMF_TOPDOWN))
416 {
417 pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
418 pso->lDelta = - pso->lDelta;
419 }
420 else
421 {
422 pso->pvScan0 = pso->pvBits;
423 }
424
425 pso->dhsurf = 0; /* device managed surface */
426 pso->hsurf = (HSURF)hbmp;
427 pso->dhpdev = NULL;
428 pso->hdev = NULL;
429 pso->sizlBitmap = Size;
430 pso->iBitmapFormat = UncompressedFormat;
431 pso->iType = STYPE_BITMAP;
432 pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
433 pso->iUniq = 0;
434
435 psurf->flHooks = 0;
436 psurf->flFlags = 0;
437 psurf->dimension.cx = 0;
438 psurf->dimension.cy = 0;
439
440 psurf->hSecure = NULL;
441 psurf->hDIBSection = NULL;
442
443 SURFACE_UnlockSurface(psurf);
444
445 return hbmp;
446 }
447
448 /* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
449 typedef struct _DEVBITMAPINFO
450 {
451 ULONG Format;
452 ULONG Width;
453 ULONG Height;
454 ULONG Flags;
455 ULONG Size;
456 } DEVBITMAPINFO, *PDEVBITMAPINFO;
457
458 SURFOBJ*
459 FASTCALL
460 SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
461 IN PVOID Bits)
462 {
463 BOOLEAN Compressed = FALSE;
464 ULONG ScanLine = 0; // Compiler is dumb
465 ULONG Size;
466 SURFOBJ *pso;
467 PSURFACE psurf;
468 SIZEL LocalSize;
469 BOOLEAN AllocatedLocally = FALSE;
470
471 /*
472 * First, check the format so we can get the aligned scanline width.
473 * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
474 * since they are compressed surfaces!
475 */
476 switch (BitmapInfo->Format)
477 {
478 case BMF_1BPP:
479 ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3;
480 break;
481
482 case BMF_4BPP:
483 ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
484 break;
485
486 case BMF_8BPP:
487 ScanLine = (BitmapInfo->Width + 3) & ~3;
488 break;
489
490 case BMF_16BPP:
491 ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1;
492 break;
493
494 case BMF_24BPP:
495 ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3;
496 break;
497
498 case BMF_32BPP:
499 ScanLine = BitmapInfo->Width << 2;
500 break;
501
502 case BMF_8RLE:
503 case BMF_4RLE:
504 case BMF_JPEG:
505 case BMF_PNG:
506 Compressed = TRUE;
507 break;
508
509 default:
510 DPRINT1("Invalid bitmap format\n");
511 return NULL;
512 }
513
514 /* Does the device manage its own surface? */
515 if (!Bits)
516 {
517 /* We need to allocate bits for the caller, figure out the size */
518 if (Compressed)
519 {
520 /* Note: we should not be seeing this scenario from ENGDDI */
521 ASSERT(FALSE);
522 Size = BitmapInfo->Size;
523 }
524 else
525 {
526 /* The height times the bytes for each scanline */
527 Size = BitmapInfo->Height * ScanLine;
528 }
529
530 if (Size)
531 {
532 /* Check for allocation flag */
533 if (BitmapInfo->Flags & BMF_USERMEM)
534 {
535 /* Get the bits from user-mode memory */
536 Bits = EngAllocUserMem(Size, 'mbuG');
537 }
538 else
539 {
540 /* Get kernel bits (zeroed out if requested) */
541 Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
542 Size,
543 TAG_DIB);
544 }
545 AllocatedLocally = TRUE;
546 /* Bail out if that failed */
547 if (!Bits) return NULL;
548 }
549 }
550 else
551 {
552 /* Should not have asked for user memory */
553 ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
554 }
555
556 /* Allocate the actual surface object structure */
557 psurf = SURFACE_AllocSurfaceWithHandle();
558 if (!psurf)
559 {
560 if(Bits && AllocatedLocally)
561 {
562 if(BitmapInfo->Flags & BMF_USERMEM)
563 EngFreeUserMem(Bits);
564 else
565 EngFreeMem(Bits);
566 }
567 return NULL;
568 }
569
570 /* Lock down the surface */
571 if (!SURFACE_InitBitsLock(psurf))
572 {
573 /* Bail out if that failed */
574 SURFACE_UnlockSurface(psurf);
575 SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr);
576 return NULL;
577 }
578
579 /* We should now have our surface object */
580 pso = &psurf->SurfObj;
581
582 /* Save format and flags */
583 pso->iBitmapFormat = BitmapInfo->Format;
584 pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
585
586 /* Save size and type */
587 LocalSize.cy = BitmapInfo->Height;
588 LocalSize.cx = BitmapInfo->Width;
589 pso->sizlBitmap = LocalSize;
590 pso->iType = STYPE_BITMAP;
591
592 /* Device-managed surface, no flags or dimension */
593 pso->dhsurf = 0;
594 pso->dhpdev = NULL;
595 pso->hdev = NULL;
596 psurf->flFlags = 0;
597 psurf->dimension.cx = 0;
598 psurf->dimension.cy = 0;
599 psurf->hSecure = NULL;
600 psurf->hDIBSection = NULL;
601 psurf->flHooks = 0;
602
603 /* Set bits */
604 pso->pvBits = Bits;
605
606 /* Check for bitmap type */
607 if (!Compressed)
608 {
609 /* Number of bits is based on the height times the scanline */
610 pso->cjBits = BitmapInfo->Height * ScanLine;
611 if (BitmapInfo->Flags & BMF_TOPDOWN)
612 {
613 /* For topdown, the base address starts with the bits */
614 pso->pvScan0 = pso->pvBits;
615 pso->lDelta = ScanLine;
616
617 /* Hack for FreeType/Font Rendering, cannot use the Aligned ScanLine */
618 if (BitmapInfo->Format == BMF_1BPP) pso->lDelta = BitmapInfo->Width / 8;
619 }
620 else
621 {
622 /* Otherwise we start with the end and go up */
623 pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
624 pso->lDelta = -ScanLine;
625 }
626 }
627 else
628 {
629 /* Compressed surfaces don't have scanlines! */
630 ASSERT(FALSE); // Should not get here on ENGDDI
631 pso->lDelta = 0;
632 pso->cjBits = BitmapInfo->Size;
633
634 /* Check for JPG or PNG */
635 if ((BitmapInfo->Format != BMF_JPEG) && (BitmapInfo->Format != BMF_PNG))
636 {
637 /* Wherever the bit data is */
638 pso->pvScan0 = pso->pvBits;
639 }
640 else
641 {
642 /* Fancy formats don't use a base address */
643 pso->pvScan0 = NULL;
644 ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
645 }
646 }
647
648 /* Finally set the handle and uniq */
649 pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
650 pso->iUniq = 0;
651
652 /* Unlock and return the surface */
653 SURFACE_UnlockSurface(psurf);
654 return pso;
655 }
656
657 /*
658 * @implemented
659 */
660 HBITMAP
661 APIENTRY
662 EngCreateBitmap(IN SIZEL Size,
663 IN LONG Width,
664 IN ULONG Format,
665 IN ULONG Flags,
666 IN PVOID Bits)
667 {
668 SURFOBJ* Surface;
669 DEVBITMAPINFO BitmapInfo;
670
671 /* Capture the parameters */
672 BitmapInfo.Format = Format;
673 BitmapInfo.Width = Size.cx;
674 BitmapInfo.Height = Size.cy;
675 BitmapInfo.Flags = Flags;
676
677 /*
678 * If the display driver supports framebuffer access, use the scanline width
679 * to determine the actual width of the bitmap, and convert it to pels instead
680 * of bytes.
681 */
682 if ((Bits) && (Width))
683 {
684 switch (BitmapInfo.Format)
685 {
686 /* Do the conversion for each bit depth we support */
687 case BMF_1BPP:
688 BitmapInfo.Width = Width * 8;
689 break;
690 case BMF_4BPP:
691 BitmapInfo.Width = Width * 2;
692 break;
693 case BMF_8BPP:
694 BitmapInfo.Width = Width;
695 break;
696 case BMF_16BPP:
697 BitmapInfo.Width = Width / 2;
698 break;
699 case BMF_24BPP:
700 BitmapInfo.Width = Width / 3;
701 break;
702 case BMF_32BPP:
703 BitmapInfo.Width = Width / 4;
704 break;
705 }
706 }
707
708 /* Now create the surface */
709 Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits);
710 if (!Surface) return 0;
711
712 /* Set public ownership and reutrn the handle */
713 GDIOBJ_SetOwnership(Surface->hsurf, NULL);
714 return Surface->hsurf;
715 }
716
717 /*
718 * @unimplemented
719 */
720 HSURF APIENTRY
721 EngCreateDeviceSurface(IN DHSURF dhsurf,
722 IN SIZEL Size,
723 IN ULONG Format)
724 {
725 HSURF hsurf;
726 SURFOBJ *pso;
727 PSURFACE psurf;
728
729 psurf = SURFACE_AllocSurfaceWithHandle();
730 if (!psurf)
731 {
732 return 0;
733 }
734
735 hsurf = psurf->BaseObject.hHmgr;
736 GDIOBJ_SetOwnership(hsurf, NULL);
737
738 if (!SURFACE_InitBitsLock(psurf))
739 {
740 SURFACE_UnlockSurface(psurf);
741 SURFACE_FreeSurfaceByHandle(hsurf);
742 return 0;
743 }
744 pso = &psurf->SurfObj;
745
746 pso->dhsurf = dhsurf;
747 pso->hsurf = hsurf;
748 pso->sizlBitmap = Size;
749 pso->iBitmapFormat = Format;
750 pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
751 pso->iType = STYPE_DEVICE;
752 pso->iUniq = 0;
753
754 psurf->flHooks = 0;
755
756 SURFACE_UnlockSurface(psurf);
757
758 return hsurf;
759 }
760
761 /*
762 * @implemented
763 */
764 BOOL
765 APIENTRY
766 EngAssociateSurface(
767 IN HSURF hsurf,
768 IN HDEV hdev,
769 IN FLONG flHooks)
770 {
771 SURFOBJ *pso;
772 PSURFACE psurf;
773 PDEVOBJ* ppdev;
774
775 ppdev = (PDEVOBJ*)hdev;
776
777 /* Lock the surface */
778 psurf = SURFACE_LockSurface(hsurf);
779 if (!psurf)
780 {
781 return FALSE;
782 }
783 pso = &psurf->SurfObj;
784
785 /* Associate the hdev */
786 pso->hdev = hdev;
787 pso->dhpdev = ppdev->dhpdev;
788
789 /* Hook up specified functions */
790 psurf->flHooks = flHooks;
791
792 SURFACE_UnlockSurface(psurf);
793
794 return TRUE;
795 }
796
797 /*
798 * @implemented
799 */
800 BOOL APIENTRY
801 EngModifySurface(
802 IN HSURF hsurf,
803 IN HDEV hdev,
804 IN FLONG flHooks,
805 IN FLONG flSurface,
806 IN DHSURF dhsurf,
807 OUT VOID *pvScan0,
808 IN LONG lDelta,
809 IN VOID *pvReserved)
810 {
811 SURFOBJ *pso;
812 PSURFACE psurf;
813 PDEVOBJ* ppdev;
814
815 psurf = SURFACE_LockSurface(hsurf);
816 if (psurf == NULL)
817 {
818 return FALSE;
819 }
820
821 ppdev = (PDEVOBJ*)hdev;
822 pso = &psurf->SurfObj;
823 pso->dhsurf = dhsurf;
824 pso->lDelta = lDelta;
825 pso->pvScan0 = pvScan0;
826
827 /* Associate the hdev */
828 pso->hdev = hdev;
829 pso->dhpdev = ppdev->dhpdev;
830
831 /* Hook up specified functions */
832 psurf->flHooks = flHooks;
833
834 SURFACE_UnlockSurface(psurf);
835
836 return TRUE;
837 }
838
839 /*
840 * @implemented
841 */
842 BOOL APIENTRY
843 EngDeleteSurface(IN HSURF hsurf)
844 {
845 GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
846 SURFACE_FreeSurfaceByHandle(hsurf);
847 return TRUE;
848 }
849
850 /*
851 * @implemented
852 */
853 BOOL APIENTRY
854 EngEraseSurface(SURFOBJ *pso,
855 RECTL *Rect,
856 ULONG iColor)
857 {
858 ASSERT(pso);
859 ASSERT(Rect);
860 return FillSolid(pso, Rect, iColor);
861 }
862
863 /*
864 * @implemented
865 */
866 SURFOBJ * APIENTRY
867 NtGdiEngLockSurface(IN HSURF hsurf)
868 {
869 return EngLockSurface(hsurf);
870 }
871
872
873 /*
874 * @implemented
875 */
876 SURFOBJ * APIENTRY
877 EngLockSurface(IN HSURF hsurf)
878 {
879 SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
880
881 if (psurf != NULL)
882 return &psurf->SurfObj;
883
884 return NULL;
885 }
886
887
888 /*
889 * @implemented
890 */
891 VOID APIENTRY
892 NtGdiEngUnlockSurface(IN SURFOBJ *pso)
893 {
894 EngUnlockSurface(pso);
895 }
896
897 /*
898 * @implemented
899 */
900 VOID APIENTRY
901 EngUnlockSurface(IN SURFOBJ *pso)
902 {
903 if (pso != NULL)
904 {
905 SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
906 GDIOBJ_ShareUnlockObjByPtr((POBJ)psurf);
907 }
908 }
909
910
911 /* EOF */