1 /* $Id: dc.c,v 1.32 2002/07/13 21:37:26 ei Exp $
3 * DC.C - Device context functions
7 #undef WIN32_LEAN_AND_MEAN
11 #include <win32k/bitmaps.h>
12 #include <win32k/coord.h>
13 #include <win32k/driver.h>
14 #include <win32k/dc.h>
15 #include <win32k/print.h>
16 #include <win32k/region.h>
17 #include <win32k/gdiobj.h>
18 #include <win32k/pen.h>
19 #include <win32k/text.h>
20 #include "../eng/objects.h"
23 #include <win32k/debug1.h>
26 /* FIXME: DCs should probably be thread safe */
29 * DC device-independent Get/SetXXX functions
30 * (RJJ) swiped from WINE
33 #define DC_GET_VAL( func_type, func_name, dc_field ) \
34 func_type STDCALL func_name( HDC hdc ) \
37 PDC dc = DC_HandleToPtr( hdc ); \
43 DC_ReleasePtr( hdc ); \
47 /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
48 * important that the function has the right signature, for the implementation
49 * we can do whatever we want.
51 #define DC_GET_VAL_EX( func_name, ret_x, ret_y, type ) \
52 BOOL STDCALL func_name( HDC hdc, LP##type pt ) \
54 PDC dc = DC_HandleToPtr( hdc ); \
59 ((LPPOINT)pt)->x = dc->ret_x; \
60 ((LPPOINT)pt)->y = dc->ret_y; \
61 DC_ReleasePtr( hdc ); \
65 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
66 INT STDCALL func_name( HDC hdc, INT mode ) \
69 PDC dc = DC_HandleToPtr( hdc ); \
74 if ((mode < min_val) || (mode > max_val)) \
78 prevMode = dc->dc_field; \
79 dc->dc_field = mode; \
80 DC_ReleasePtr( hdc ); \
84 VOID
BitmapToSurf(HDC hdc
, PSURFGDI SurfGDI
, PSURFOBJ SurfObj
, PBITMAPOBJ Bitmap
);
86 // --------------------------------------------------------- File Statics
88 static void W32kSetDCState16(HDC hDC
, HDC hDCSave
);
90 // ----------------------------------------------------- Public Functions
92 BOOL STDCALL
W32kCancelDC(HDC hDC
)
97 HDC STDCALL
W32kCreateCompatableDC(HDC hDC
)
99 PDC NewDC
, OrigDC
= NULL
;
104 OrigDC
= DC_HandleToPtr(hDC
);
107 hNewDC
= DC_AllocDC(L
"DISPLAY");
109 NewDC
= DC_HandleToPtr( hNewDC
);
112 /* Allocate a new DC based on the original DC's device */
113 hNewDC
= DC_AllocDC(OrigDC
->DriverName
);
115 NewDC
= DC_HandleToPtr( hNewDC
);
123 /* Copy information from original DC to new DC */
124 NewDC
->hSelf
= NewDC
;
126 /* FIXME: Should this DC request its own PDEV? */
129 NewDC
->PDev
= OrigDC
->PDev
;
130 NewDC
->DMW
= OrigDC
->DMW
;
131 memcpy(NewDC
->FillPatternSurfaces
,
132 OrigDC
->FillPatternSurfaces
,
133 sizeof OrigDC
->FillPatternSurfaces
);
134 NewDC
->GDIInfo
= OrigDC
->GDIInfo
;
135 NewDC
->DevInfo
= OrigDC
->DevInfo
;
138 // Create a 1x1 monochrome bitmap surface
141 NewDC
->Surface
= EngCreateBitmap(onebyone
, 1, BMF_1BPP
, 0, NULL
);
143 /* DriverName is copied in the AllocDC routine */
145 NewDC
->DeviceDriver
= DRIVER_FindMPDriver(NewDC
->DriverName
);
147 NewDC
->DeviceDriver
= OrigDC
->DeviceDriver
;
148 NewDC
->wndOrgX
= OrigDC
->wndOrgX
;
149 NewDC
->wndOrgY
= OrigDC
->wndOrgY
;
150 NewDC
->wndExtX
= OrigDC
->wndExtX
;
151 NewDC
->wndExtY
= OrigDC
->wndExtY
;
152 NewDC
->vportOrgX
= OrigDC
->vportOrgX
;
153 NewDC
->vportOrgY
= OrigDC
->vportOrgY
;
154 NewDC
->vportExtX
= OrigDC
->vportExtX
;
155 NewDC
->vportExtY
= OrigDC
->vportExtY
;
160 /* Create default bitmap */
161 if (!(hBitmap
= W32kCreateBitmap( 1, 1, 1, 1, NULL
)))
163 DC_ReleasePtr( hNewDC
);
167 NewDC
->w
.flags
= DC_MEMORY
;
168 NewDC
->w
.bitsPerPixel
= 1;
169 NewDC
->w
.hBitmap
= hBitmap
;
170 NewDC
->w
.hFirstBitmap
= hBitmap
;
174 NewDC
->w
.hPalette
= OrigDC
->w
.hPalette
;
175 NewDC
->w
.textColor
= OrigDC
->w
.textColor
;
176 NewDC
->w
.textAlign
= OrigDC
->w
.textAlign
;
178 DC_ReleasePtr( hDC
);
179 DC_ReleasePtr( hNewDC
);
184 #include <ddk/ntddvid.h>
186 HDC STDCALL
W32kCreateDC(LPCWSTR Driver
,
189 CONST PDEVMODEW InitData
)
191 PGD_ENABLEDRIVER GDEnableDriver
;
198 /* Check for existing DC object */
199 if ((hNewDC
= DC_FindOpenDC(Driver
)) != NULL
)
202 return W32kCreateCompatableDC(hDC
);
205 DPRINT("NAME: %S\n", Driver
); // FIXME: Should not crash if NULL
207 /* Allocate a DC object */
208 if ((hNewDC
= DC_AllocDC(Driver
)) == NULL
)
213 NewDC
= DC_HandleToPtr( hNewDC
);
216 /* Open the miniport driver */
217 if ((NewDC
->DeviceDriver
= DRIVER_FindMPDriver(Driver
)) == NULL
)
219 DPRINT("FindMPDriver failed\n");
223 /* Get the DDI driver's entry point */
224 /* FIXME: Retrieve DDI driver name from registry */
225 if ((GDEnableDriver
= DRIVER_FindDDIDriver(L
"\\SystemRoot\\system32\\drivers\\vgaddi.dll")) == NULL
)
227 DPRINT("FindDDIDriver failed\n");
231 /* Call DDI driver's EnableDriver function */
232 RtlZeroMemory(&DED
, sizeof(DED
));
234 if (!GDEnableDriver(DDI_DRIVER_VERSION
, sizeof(DED
), &DED
))
236 DPRINT("DrvEnableDriver failed\n");
239 DPRINT("Building DDI Functions\n");
241 /* Construct DDI driver function dispatch table */
242 if (!DRIVER_BuildDDIFunctions(&DED
, &NewDC
->DriverFunctions
))
244 DPRINT("BuildDDIFunctions failed\n");
248 /* Allocate a phyical device handle from the driver */
251 DPRINT("Device in u: %u\n", Device
);
252 // wcsncpy(NewDC->DMW.dmDeviceName, Device, DMMAXDEVICENAME); FIXME: this crashes everything?
254 NewDC
->DMW
.dmSize
= sizeof(NewDC
->DMW
);
255 NewDC
->DMW
.dmFields
= 0x000fc000;
257 /* FIXME: get mode selection information from somewhere */
259 NewDC
->DMW
.dmLogPixels
= 96;
260 NewDC
->DMW
.dmBitsPerPel
= 4;
261 NewDC
->DMW
.dmPelsWidth
= 640;
262 NewDC
->DMW
.dmPelsHeight
= 480;
263 NewDC
->DMW
.dmDisplayFlags
= 0;
264 NewDC
->DMW
.dmDisplayFrequency
= 0;
266 NewDC
->w
.bitsPerPixel
= 4; // FIXME: set this here??
268 DPRINT("Enabling PDev\n");
270 NewDC
->PDev
= NewDC
->DriverFunctions
.EnablePDev(&NewDC
->DMW
,
273 NewDC
->FillPatternSurfaces
,
274 sizeof(NewDC
->GDIInfo
),
275 (ULONG
*) &NewDC
->GDIInfo
,
276 sizeof(NewDC
->DevInfo
),
280 NewDC
->DeviceDriver
);
281 if (NewDC
->PDev
== NULL
)
283 DPRINT("DrvEnablePDEV failed\n");
287 DPRINT("calling completePDev\n");
289 /* Complete initialization of the physical device */
290 NewDC
->DriverFunctions
.CompletePDev(NewDC
->PDev
, NewDC
);
292 DPRINT("calling DRIVER_ReferenceDriver\n");
294 DRIVER_ReferenceDriver (Driver
);
296 DPRINT("calling EnableSurface\n");
298 /* Enable the drawing surface */
299 NewDC
->Surface
= NewDC
->DriverFunctions
.EnableSurface(NewDC
->PDev
); // hsurf
300 NewDC
->w
.hPalette
= NewDC
->DevInfo
.hpalDefault
;
302 SurfObj
= (PSURFOBJ
)AccessUserObject(NewDC
->Surface
);
303 SurfObj
->dhpdev
= NewDC
->PDev
;
305 DPRINT("Bits per pel: %u\n", NewDC
->w
.bitsPerPixel
);
307 /* Initialize the DC state */
310 W32kSetTextColor(hNewDC
, RGB(0xff, 0xff, 0xff));
311 W32kSetTextAlign(hNewDC
, TA_BASELINE
);
312 DC_ReleasePtr( hNewDC
);
316 DC_ReleasePtr( hNewDC
);
321 HDC STDCALL
W32kCreateIC(LPCWSTR Driver
,
324 CONST PDEVMODEW DevMode
)
326 /* FIXME: this should probably do something else... */
327 return W32kCreateDC(Driver
, Device
, Output
, DevMode
);
330 BOOL STDCALL
W32kDeleteDC(HDC DCHandle
)
334 DCToDelete
= DC_HandleToPtr(DCHandle
);
335 if (DCToDelete
== NULL
)
339 DPRINT( "Deleting DC\n" );
340 if ((!(DCToDelete
->w
.flags
& DC_MEMORY
))) // Don't reset the display if its a memory DC
342 if (!DRIVER_UnreferenceDriver (DCToDelete
->DriverName
))
344 DPRINT( "No more references to driver, reseting display\n" );
345 DCToDelete
->DriverFunctions
.DisableSurface(DCToDelete
->PDev
);
347 DCToDelete
->DriverFunctions
.AssertMode( DCToDelete
->PDev
, FALSE
);
349 DCToDelete
->DriverFunctions
.DisablePDev(DCToDelete
->PDev
);
353 /* First delete all saved DCs */
354 while (DCToDelete
->saveLevel
)
359 savedHDC
= DC_GetNextDC (DCToDelete
);
360 savedDC
= DC_HandleToPtr (savedHDC
);
365 DC_SetNextDC (DCToDelete
, DC_GetNextDC (savedDC
));
366 DCToDelete
->saveLevel
--;
367 DC_ReleasePtr( savedHDC
);
368 W32kDeleteDC (savedHDC
);
371 /* Free GDI resources allocated to this DC */
372 if (!(DCToDelete
->w
.flags
& DC_SAVED
))
375 W32kSelectObject (DCHandle, STOCK_BLACK_PEN);
376 W32kSelectObject (DCHandle, STOCK_WHITE_BRUSH);
377 W32kSelectObject (DCHandle, STOCK_SYSTEM_FONT);
378 DC_LockDC (DCHandle); W32kSelectObject does not recognize stock objects yet */
379 if (DCToDelete
->w
.flags
& DC_MEMORY
)
381 W32kDeleteObject (DCToDelete
->w
.hFirstBitmap
);
384 if (DCToDelete
->w
.hClipRgn
)
386 W32kDeleteObject (DCToDelete
->w
.hClipRgn
);
388 if (DCToDelete
->w
.hVisRgn
)
390 W32kDeleteObject (DCToDelete
->w
.hVisRgn
);
392 if (DCToDelete
->w
.hGCClipRgn
)
394 W32kDeleteObject (DCToDelete
->w
.hGCClipRgn
);
397 PATH_DestroyGdiPath (&DCToDelete
->w
.path
);
399 DC_ReleasePtr( DCToDelete
);
400 DC_FreeDC (DCToDelete
);
405 INT STDCALL
W32kDrawEscape(HDC hDC
,
413 INT STDCALL
W32kEnumObjects(HDC hDC
,
415 GOBJENUMPROC ObjectFunc
,
421 DC_GET_VAL( COLORREF
, W32kGetBkColor
, w
.backgroundColor
)
422 DC_GET_VAL( INT
, W32kGetBkMode
, w
.backgroundMode
)
423 DC_GET_VAL_EX( W32kGetBrushOrgEx
, w
.brushOrgX
, w
.brushOrgY
, POINT
)
424 DC_GET_VAL( HRGN
, W32kGetClipRgn
, w
.hClipRgn
)
426 HGDIOBJ STDCALL
W32kGetCurrentObject(HDC hDC
,
432 DC_GET_VAL_EX( W32kGetCurrentPositionEx
, w
.CursPosX
, w
.CursPosY
, POINT
)
434 BOOL STDCALL
W32kGetDCOrgEx(HDC hDC
,
443 dc
= DC_HandleToPtr(hDC
);
449 Point
->x
= Point
->y
= 0;
451 Point
->x
+= dc
->w
.DCOrgX
;
452 Point
->y
+= dc
->w
.DCOrgY
;
453 DC_ReleasePtr( hDC
);
457 HDC STDCALL
W32kGetDCState16(HDC hDC
)
462 dc
= DC_HandleToPtr(hDC
);
468 hnewdc
= DC_AllocDC(NULL
);
471 DC_ReleasePtr( hDC
);
474 newdc
= DC_HandleToPtr( hnewdc
);
477 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
479 newdc
->w
.devCaps
= dc
->w
.devCaps
;
481 newdc
->w
.hPen
= dc
->w
.hPen
;
482 newdc
->w
.hBrush
= dc
->w
.hBrush
;
483 newdc
->w
.hFont
= dc
->w
.hFont
;
484 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
485 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
487 newdc
->w
.hDevice
= dc
->w
.hDevice
;
488 newdc
->w
.hPalette
= dc
->w
.hPalette
;
490 newdc
->w
.totalExtent
= dc
->w
.totalExtent
;
491 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
492 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
493 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
494 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
495 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
496 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
497 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
498 newdc
->w
.textColor
= dc
->w
.textColor
;
499 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
500 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
501 newdc
->w
.textAlign
= dc
->w
.textAlign
;
502 newdc
->w
.charExtra
= dc
->w
.charExtra
;
503 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
504 newdc
->w
.breakCount
= dc
->w
.breakCount
;
505 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
506 newdc
->w
.breakRem
= dc
->w
.breakRem
;
507 newdc
->w
.MapMode
= dc
->w
.MapMode
;
508 newdc
->w
.GraphicsMode
= dc
->w
.GraphicsMode
;
510 /* Apparently, the DC origin is not changed by [GS]etDCState */
511 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
512 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
514 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
515 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
516 newdc
->w
.ArcDirection
= dc
->w
.ArcDirection
;
518 newdc
->w
.xformWorld2Wnd
= dc
->w
.xformWorld2Wnd
;
519 newdc
->w
.xformWorld2Vport
= dc
->w
.xformWorld2Vport
;
520 newdc
->w
.xformVport2World
= dc
->w
.xformVport2World
;
521 newdc
->w
.vport2WorldValid
= dc
->w
.vport2WorldValid
;
523 newdc
->wndOrgX
= dc
->wndOrgX
;
524 newdc
->wndOrgY
= dc
->wndOrgY
;
525 newdc
->wndExtX
= dc
->wndExtX
;
526 newdc
->wndExtY
= dc
->wndExtY
;
527 newdc
->vportOrgX
= dc
->vportOrgX
;
528 newdc
->vportOrgY
= dc
->vportOrgY
;
529 newdc
->vportExtX
= dc
->vportExtX
;
530 newdc
->vportExtY
= dc
->vportExtY
;
532 newdc
->hSelf
= hnewdc
;
533 newdc
->saveLevel
= 0;
536 PATH_InitGdiPath( &newdc
->w
.path
);
539 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
542 newdc
->w
.hGCClipRgn
= newdc
->w
.hVisRgn
= 0;
546 newdc
->w
.hClipRgn
= W32kCreateRectRgn( 0, 0, 0, 0 );
547 W32kCombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
551 newdc
->w
.hClipRgn
= 0;
553 DC_ReleasePtr( hnewdc
);
557 INT STDCALL
W32kGetDeviceCaps(HDC hDC
,
564 dc
= DC_HandleToPtr(hDC
);
570 /* Device capabilities for the printer */
574 if(W32kEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
581 if(W32kEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
587 case PHYSICALOFFSETX
:
588 if(W32kEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
594 case PHYSICALOFFSETY
:
595 if(W32kEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
602 if(W32kEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
609 if(W32kEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
616 if ((Index
< 0) || (Index
> sizeof(DEVICECAPS
) - sizeof(WORD
)))
621 DPRINT("(%04x,%d): returning %d\n",
622 hDC
, Index
, *(WORD
*)(((char *)dc
->w
.devCaps
) + Index
));
623 ret
= *(WORD
*)(((char *)dc
->w
.devCaps
) + Index
);
625 DC_ReleasePtr( hDC
);
629 DC_GET_VAL( INT
, W32kGetMapMode
, w
.MapMode
)
630 DC_GET_VAL( INT
, W32kGetPolyFillMode
, w
.polyFillMode
)
632 INT STDCALL
W32kGetObjectA(HANDLE handle
, INT count
, LPVOID buffer
)
640 gdiObject
= GDIOBJ_LockObj (handle
, GO_MAGIC_DONTCARE
);
644 magic
= GDIOBJ_GetHandleMagic (handle
);
647 /* case GO_PEN_MAGIC:
648 result = PEN_GetObject((PENOBJ *)gdiObject, count, buffer);
651 result = BRUSH_GetObject((BRUSHOBJ *)gdiObject, count, buffer);
653 case GO_BITMAP_MAGIC
:
654 result
= BITMAP_GetObject((BITMAPOBJ
*)gdiObject
, count
, buffer
);
656 /* case GO_FONT_MAGIC:
657 result = FONT_GetObjectA((FONTOBJ *)gdiObject, count, buffer);
659 // FIXME: Fix the LOGFONT structure for the stock fonts
661 if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
662 FixStockFontSizeA(handle, count, buffer);
664 case GO_PALETTE_MAGIC:
665 result = PALETTE_GetObject((PALETTEOBJ *)gdiObject, count, buffer);
668 case GO_REGION_MAGIC
:
670 case GO_DISABLED_DC_MAGIC
:
671 case GO_META_DC_MAGIC
:
672 case GO_METAFILE_MAGIC
:
673 case GO_METAFILE_DC_MAGIC
:
674 case GO_ENHMETAFILE_MAGIC
:
675 case GO_ENHMETAFILE_DC_MAGIC
:
676 // FIXME("Magic %04x not implemented\n", magic);
680 DbgPrint("Invalid GDI Magic %04x\n", magic
);
683 GDIOBJ_UnlockObj (handle
, GO_MAGIC_DONTCARE
);
687 INT STDCALL
W32kGetObjectW(HANDLE handle
, INT count
, LPVOID buffer
)
689 PGDIOBJHDR gdiObject
;
695 gdiObject
= GDIOBJ_LockObj(handle
, GO_MAGIC_DONTCARE
);
699 magic
= GDIOBJ_GetHandleMagic (handle
);
702 /* case GO_PEN_MAGIC:
703 result = PEN_GetObject((PENOBJ *)gdiObject, count, buffer);
706 result = BRUSH_GetObject((BRUSHOBJ *)gdiObject, count, buffer);
708 case GO_BITMAP_MAGIC
:
709 result
= BITMAP_GetObject((BITMAPOBJ
*)gdiObject
, count
, buffer
);
711 /* case GO_FONT_MAGIC:
712 result = FONT_GetObjectW((FONTOBJ *)gdiObject, count, buffer);
714 // Fix the LOGFONT structure for the stock fonts
716 if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
717 FixStockFontSizeW(handle, count, buffer);
719 case GO_PALETTE_MAGIC:
720 result = PALETTE_GetObject((PALETTEOBJ *)gdiObject, count, buffer);
723 // FIXME("Magic %04x not implemented\n", gdiObject->magic);
726 GDIOBJ_UnlockObj(handle
, GO_MAGIC_DONTCARE
);
730 INT STDCALL
W32kGetObject(HANDLE handle
, INT count
, LPVOID buffer
)
732 return W32kGetObjectW(handle
, count
, buffer
);
735 DWORD STDCALL
W32kGetObjectType(HANDLE handle
)
741 ptr
= GDIOBJ_LockObj(handle
, GO_MAGIC_DONTCARE
);
745 magic
= GDIOBJ_GetHandleMagic (handle
);
754 case GO_BITMAP_MAGIC
:
760 case GO_PALETTE_MAGIC
:
763 case GO_REGION_MAGIC
:
769 case GO_META_DC_MAGIC
:
772 case GO_METAFILE_MAGIC
:
773 result
= OBJ_METAFILE
;
775 case GO_METAFILE_DC_MAGIC
:
778 case GO_ENHMETAFILE_MAGIC
:
779 result
= OBJ_ENHMETAFILE
;
781 case GO_ENHMETAFILE_DC_MAGIC
:
782 result
= OBJ_ENHMETADC
;
785 // FIXME("Magic %04x not implemented\n", magic);
788 GDIOBJ_UnlockObj(handle
, GO_MAGIC_DONTCARE
);
792 DC_GET_VAL( INT
, W32kGetRelAbs
, w
.relAbsMode
)
793 DC_GET_VAL( INT
, W32kGetROP2
, w
.ROPmode
)
794 DC_GET_VAL( INT
, W32kGetStretchBltMode
, w
.stretchBltMode
)
795 DC_GET_VAL( UINT
, W32kGetTextAlign
, w
.textAlign
)
796 DC_GET_VAL( COLORREF
, W32kGetTextColor
, w
.textColor
)
797 DC_GET_VAL_EX( W32kGetViewportExtEx
, vportExtX
, vportExtY
, SIZE
)
798 DC_GET_VAL_EX( W32kGetViewportOrgEx
, vportOrgX
, vportOrgY
, POINT
)
799 DC_GET_VAL_EX( W32kGetWindowExtEx
, wndExtX
, wndExtY
, SIZE
)
800 DC_GET_VAL_EX( W32kGetWindowOrgEx
, wndOrgX
, wndOrgY
, POINT
)
802 HDC STDCALL
W32kResetDC(HDC hDC
, CONST DEVMODEW
*InitData
)
807 BOOL STDCALL
W32kRestoreDC(HDC hDC
, INT SaveLevel
)
812 dc
= DC_HandleToPtr(hDC
);
820 SaveLevel
= dc
->saveLevel
;
823 if ((SaveLevel
< 1) || (SaveLevel
> dc
->saveLevel
))
829 while (dc
->saveLevel
>= SaveLevel
)
831 HDC hdcs
= DC_GetNextDC (dc
);
833 dcs
= DC_HandleToPtr (hdcs
);
838 DC_SetNextDC (dcs
, DC_GetNextDC (dcs
));
839 if (--dc
->saveLevel
< SaveLevel
)
841 W32kSetDCState16 (hDC
, hdcs
);
843 if (!PATH_AssignGdiPath( &dc
->w
.path
, &dcs
->w
.path
))
845 /* FIXME: This might not be quite right, since we're
846 * returning FALSE but still destroying the saved DC state */
851 DC_ReleasePtr( hdcs
);
854 DC_ReleasePtr( hDC
);
858 INT STDCALL
W32kSaveDC(HDC hDC
)
864 dc
= DC_HandleToPtr (hDC
);
870 if (!(hdcs
= W32kGetDCState16 (hDC
)))
874 dcs
= DC_HandleToPtr (hdcs
);
877 /* Copy path. The reason why path saving / restoring is in SaveDC/
878 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
879 * functions are only in Win16 (which doesn't have paths) and that
880 * SetDCState doesn't allow us to signal an error (which can happen
881 * when copying paths).
883 if (!PATH_AssignGdiPath (&dcs
->w
.path
, &dc
->w
.path
))
890 DC_SetNextDC (dcs
, DC_GetNextDC (dc
));
891 DC_SetNextDC (dc
, hdcs
);
892 ret
= ++dc
->saveLevel
;
893 DC_ReleasePtr( hdcs
);
894 DC_ReleasePtr( hDC
);
899 HGDIOBJ STDCALL
W32kSelectObject(HDC hDC
, HGDIOBJ hGDIObj
)
911 if(!hDC
|| !hGDIObj
) return NULL
;
913 dc
= DC_HandleToPtr(hDC
);
914 objectMagic
= GDIOBJ_GetHandleMagic (hGDIObj
);
915 // GdiObjHdr = hGDIObj;
917 // FIXME: Get object handle from GDIObj and use it instead of GDIObj below?
919 switch(objectMagic
) {
921 objOrg
= (HGDIOBJ
)dc
->w
.hPen
;
922 dc
->w
.hPen
= hGDIObj
;
924 // Convert the color of the pen to the format of the DC
925 PalGDI
= (PPALGDI
)AccessInternalObject(dc
->w
.hPalette
);
926 XlateObj
= (PXLATEOBJ
)EngCreateXlate(PalGDI
->Mode
, PAL_RGB
, dc
->w
.hPalette
, NULL
);
927 pen
= GDIOBJ_LockObj(dc
->w
.hPen
, GO_PEN_MAGIC
);
928 pen
->logpen
.lopnColor
= XLATEOBJ_iXlate(XlateObj
, pen
->logpen
.lopnColor
);
929 GDIOBJ_UnlockObj( dc
->w
.hPen
, GO_PEN_MAGIC
);
932 objOrg
= (HGDIOBJ
)dc
->w
.hBrush
;
933 dc
->w
.hBrush
= (HBRUSH
) hGDIObj
;
936 objOrg
= (HGDIOBJ
)dc
->w
.hFont
;
937 dc
->w
.hFont
= (HFONT
) hGDIObj
;
939 case GO_BITMAP_MAGIC
:
940 // must be memory dc to select bitmap
941 if (!(dc
->w
.flags
& DC_MEMORY
)) return NULL
;
942 objOrg
= (HGDIOBJ
)dc
->w
.hBitmap
;
944 // setup mem dc for drawing into bitmap
945 pb
= BITMAPOBJ_HandleToPtr (hGDIObj
);
946 surfobj
= ExAllocatePool(PagedPool
, sizeof(SURFOBJ
));
947 surfgdi
= ExAllocatePool(PagedPool
, sizeof(SURFGDI
));
949 BitmapToSurf(hDC
, surfgdi
, surfobj
, pb
); // Put the bitmap in a surface
950 dc
->w
.hBitmap
= CreateGDIHandle(surfgdi
, surfobj
); // Assign the DC's bitmap
951 dc
->Surface
= dc
->w
.hBitmap
;
953 // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
956 if((pb
->dib
->dsBmih
.biBitCount
> 8) && (pb
->dib
->dsBmih
.biBitCount
< 24))
958 dc
->w
.hPalette
= EngCreatePalette(PAL_BITFIELDS
, pb
->dib
->dsBmih
.biClrUsed
, NULL
, 0, 0, 0);
960 if(pb
->dib
->dsBmih
.biBitCount
>= 24)
962 dc
->w
.hPalette
= EngCreatePalette(PAL_RGB
, pb
->dib
->dsBmih
.biClrUsed
, NULL
, 0, 0, 0);
967 case GO_REGION_MAGIC
:
968 /* objOrg = (HGDIOBJ)hDC->region; */
969 objOrg
= NULL
; /* FIXME? hDC->region is destroyed below */
970 SelectClipRgn(hDC
, (HRGN
)hGDIObj
);
976 DC_ReleasePtr( hDC
);
980 DC_SET_MODE( W32kSetBkMode
, w
.backgroundMode
, TRANSPARENT
, OPAQUE
)
981 DC_SET_MODE( W32kSetPolyFillMode
, w
.polyFillMode
, ALTERNATE
, WINDING
)
982 // DC_SET_MODE( W32kSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE )
983 DC_SET_MODE( W32kSetROP2
, w
.ROPmode
, R2_BLACK
, R2_WHITE
)
984 DC_SET_MODE( W32kSetStretchBltMode
, w
.stretchBltMode
, BLACKONWHITE
, HALFTONE
)
986 COLORREF STDCALL
W32kSetBkColor(HDC hDC
, COLORREF color
)
989 PDC dc
= DC_HandleToPtr(hDC
);
996 oldColor
= dc
->w
.backgroundColor
;
997 dc
->w
.backgroundColor
= color
;
998 DC_ReleasePtr( hDC
);
1002 static void W32kSetDCState16(HDC hDC
, HDC hDCSave
)
1006 dc
= DC_HandleToPtr(hDC
);
1012 dcs
= DC_HandleToPtr(hDCSave
);
1015 DC_ReleasePtr( hDC
);
1018 if (!dcs
->w
.flags
& DC_SAVED
)
1023 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
1026 dc
->w
.devCaps
= dcs
->w
.devCaps
;
1029 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
1032 dc
->w
.hDevice
= dcs
->w
.hDevice
;
1035 dc
->w
.totalExtent
= dcs
->w
.totalExtent
;
1036 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
1037 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
1038 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
1039 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
1040 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
1041 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
1042 dc
->w
.textColor
= dcs
->w
.textColor
;
1043 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
1044 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
1045 dc
->w
.textAlign
= dcs
->w
.textAlign
;
1046 dc
->w
.charExtra
= dcs
->w
.charExtra
;
1047 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
1048 dc
->w
.breakCount
= dcs
->w
.breakCount
;
1049 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
1050 dc
->w
.breakRem
= dcs
->w
.breakRem
;
1051 dc
->w
.MapMode
= dcs
->w
.MapMode
;
1052 dc
->w
.GraphicsMode
= dcs
->w
.GraphicsMode
;
1054 /* Apparently, the DC origin is not changed by [GS]etDCState */
1055 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
1056 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
1058 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
1059 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
1060 dc
->w
.ArcDirection
= dcs
->w
.ArcDirection
;
1063 dc
->w
.xformWorld2Wnd
= dcs
->w
.xformWorld2Wnd
;
1064 dc
->w
.xformWorld2Vport
= dcs
->w
.xformWorld2Vport
;
1065 dc
->w
.xformVport2World
= dcs
->w
.xformVport2World
;
1066 dc
->w
.vport2WorldValid
= dcs
->w
.vport2WorldValid
;
1069 dc
->wndOrgX
= dcs
->wndOrgX
;
1070 dc
->wndOrgY
= dcs
->wndOrgY
;
1071 dc
->wndExtX
= dcs
->wndExtX
;
1072 dc
->wndExtY
= dcs
->wndExtY
;
1073 dc
->vportOrgX
= dcs
->vportOrgX
;
1074 dc
->vportOrgY
= dcs
->vportOrgY
;
1075 dc
->vportExtX
= dcs
->vportExtX
;
1076 dc
->vportExtY
= dcs
->vportExtY
;
1078 if (!(dc
->w
.flags
& DC_MEMORY
))
1080 dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
1084 if (dcs
->w
.hClipRgn
)
1086 if (!dc
->w
.hClipRgn
)
1088 dc
->w
.hClipRgn
= W32kCreateRectRgn( 0, 0, 0, 0 );
1090 W32kCombineRgn( dc
->w
.hClipRgn
, dcs
->w
.hClipRgn
, 0, RGN_COPY
);
1096 W32kDeleteObject( dc
->w
.hClipRgn
);
1101 CLIPPING_UpdateGCRegion( dc
);
1104 W32kSelectObject( hDC
, dcs
->w
.hBitmap
);
1105 W32kSelectObject( hDC
, dcs
->w
.hBrush
);
1106 W32kSelectObject( hDC
, dcs
->w
.hFont
);
1107 W32kSelectObject( hDC
, dcs
->w
.hPen
);
1108 W32kSetBkColor( hDC
, dcs
->w
.backgroundColor
);
1109 W32kSetTextColor( hDC
, dcs
->w
.textColor
);
1112 GDISelectPalette16( hDC
, dcs
->w
.hPalette
, FALSE
);
1115 DC_ReleasePtr( hDCSave
);
1116 DC_ReleasePtr( hDC
);
1119 // ---------------------------------------------------- Private Interface
1121 HDC
DC_AllocDC(LPCWSTR Driver
)
1126 hDC
= (HDC
) GDIOBJ_AllocObj(sizeof(DC
), GO_DC_MAGIC
);
1132 NewDC
= (PDC
) GDIOBJ_LockObj( hDC
, GO_DC_MAGIC
);
1136 NewDC
->DriverName
= ExAllocatePool(PagedPool
, (wcslen(Driver
) + 1) * sizeof(WCHAR
));
1137 wcscpy(NewDC
->DriverName
, Driver
);
1140 GDIOBJ_UnlockObj( hDC
, GO_DC_MAGIC
);
1144 HDC
DC_FindOpenDC(LPCWSTR Driver
)
1149 void DC_InitDC(HDC DCHandle
)
1151 // W32kRealizeDefaultPalette(DCHandle);
1153 if( (DCToInit
= DC_HandleToPtr( DCHandle
) ) ){
1154 W32kSetTextColor(DCHandle
, DCToInit
->w
.textColor
);
1155 W32kSetBkColor(DCHandle
, DCToInit
->w
.backgroundColor
);
1156 W32kSelectObject(DCHandle
, DCToInit
->w
.hPen
);
1157 W32kSelectObject(DCHandle
, DCToInit
->w
.hBrush
);
1158 W32kSelectObject(DCHandle
, DCToInit
->w
.hFont
);
1160 DPRINT("DC_InitDC: can't get dc for handle %d\n", DCHandle
);
1161 // CLIPPING_UpdateGCRegion(DCToInit);
1164 void DC_FreeDC(HDC DCToFree
)
1166 if (!GDIOBJ_FreeObj(DCToFree
, GO_DC_MAGIC
))
1168 DPRINT("DC_FreeDC failed\n");
1172 BOOL
DC_InternalDeleteDC( PDC DCToDelete
)
1174 ExFreePool(DCToDelete
->DriverName
);
1178 HDC
DC_GetNextDC (PDC pDC
)
1183 void DC_SetNextDC (PDC pDC
, HDC hNextDC
)
1185 pDC
->hNext
= hNextDC
;
1189 DC_UpdateXforms(PDC dc
)
1191 XFORM xformWnd2Vport
;
1192 FLOAT scaleX
, scaleY
;
1194 /* Construct a transformation to do the window-to-viewport conversion */
1195 scaleX
= (FLOAT
)dc
->vportExtX
/ (FLOAT
)dc
->wndExtX
;
1196 scaleY
= (FLOAT
)dc
->vportExtY
/ (FLOAT
)dc
->wndExtY
;
1197 xformWnd2Vport
.eM11
= scaleX
;
1198 xformWnd2Vport
.eM12
= 0.0;
1199 xformWnd2Vport
.eM21
= 0.0;
1200 xformWnd2Vport
.eM22
= scaleY
;
1201 xformWnd2Vport
.eDx
= (FLOAT
)dc
->vportOrgX
- scaleX
* (FLOAT
)dc
->wndOrgX
;
1202 xformWnd2Vport
.eDy
= (FLOAT
)dc
->vportOrgY
- scaleY
* (FLOAT
)dc
->wndOrgY
;
1204 /* Combine with the world transformation */
1205 W32kCombineTransform(&dc
->w
.xformWorld2Vport
, &dc
->w
.xformWorld2Wnd
, &xformWnd2Vport
);
1207 /* Create inverse of world-to-viewport transformation */
1208 dc
->w
.vport2WorldValid
= DC_InvertXform(&dc
->w
.xformWorld2Vport
, &dc
->w
.xformVport2World
);
1212 DC_InvertXform(const XFORM
*xformSrc
,
1217 determinant
= xformSrc
->eM11
*xformSrc
->eM22
- xformSrc
->eM12
*xformSrc
->eM21
;
1218 if (determinant
> -1e-12 && determinant
< 1e-12)
1223 xformDest
->eM11
= xformSrc
->eM22
/ determinant
;
1224 xformDest
->eM12
= -xformSrc
->eM12
/ determinant
;
1225 xformDest
->eM21
= -xformSrc
->eM21
/ determinant
;
1226 xformDest
->eM22
= xformSrc
->eM11
/ determinant
;
1227 xformDest
->eDx
= -xformSrc
->eDx
* xformDest
->eM11
- xformSrc
->eDy
* xformDest
->eM21
;
1228 xformDest
->eDy
= -xformSrc
->eDx
* xformDest
->eM12
- xformSrc
->eDy
* xformDest
->eM22
;