1 /* $Id: dc.c,v 1.14 2000/04/01 12:31:29 jfilby Exp $
3 * DC.C - Device context functions
7 #undef WIN32_LEAN_AND_MEAN
10 #include <win32k/bitmaps.h>
11 #include <win32k/coord.h>
12 #include <win32k/driver.h>
13 #include <win32k/dc.h>
14 #include <win32k/print.h>
15 #include <win32k/region.h>
16 #include <win32k/gdiobj.h>
19 #include <internal/debug.h>
21 void TestEngXxx(PDC Dc
)
26 DbgPrint("testing.. ");
27 brushobj
.iSolidColor
= 1;
28 SurfObj
= AccessUserObject(Dc
->Surface
);
31 EngLineTo(SurfObj
, NULL
, &brushobj
, 0, 0, 639, 479, NULL
, NULL
);
32 EngLineTo(SurfObj
, NULL
, &brushobj
, 639, 0, 0, 479, NULL
, NULL
);
35 EngLineTo(SurfObj
, NULL
, &brushobj
, 0, 0, 639, 0, NULL
, NULL
);
36 EngLineTo(SurfObj
, NULL
, &brushobj
, 639, 0, 639, 479, NULL
, NULL
);
37 EngLineTo(SurfObj
, NULL
, &brushobj
, 639, 479, 0, 479, NULL
, NULL
);
38 EngLineTo(SurfObj
, NULL
, &brushobj
, 0, 479, 0, 0, NULL
, NULL
);
41 /* FIXME: DCs should probably be thread safe */
44 * DC device-independent Get/SetXXX functions
45 * (RJJ) swiped from WINE
48 #define DC_GET_VAL( func_type, func_name, dc_field ) \
49 func_type STDCALL func_name( HDC hdc ) \
52 PDC dc = DC_HandleToPtr( hdc ); \
62 /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
63 * important that the function has the right signature, for the implementation
64 * we can do whatever we want.
66 #define DC_GET_VAL_EX( func_name, ret_x, ret_y, type ) \
67 BOOL STDCALL func_name( HDC hdc, LP##type pt ) \
69 PDC dc = DC_HandleToPtr( hdc ); \
74 ((LPPOINT)pt)->x = dc->ret_x; \
75 ((LPPOINT)pt)->y = dc->ret_y; \
80 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
81 INT STDCALL func_name( HDC hdc, INT mode ) \
84 PDC dc = DC_HandleToPtr( hdc ); \
89 if ((mode < min_val) || (mode > max_val)) \
93 prevMode = dc->dc_field; \
94 dc->dc_field = mode; \
99 // --------------------------------------------------------- File Statics
101 static void W32kSetDCState16(HDC hDC
, HDC hDCSave
);
103 // ----------------------------------------------------- Public Functions
105 BOOL STDCALL
W32kCancelDC(HDC hDC
)
110 HDC STDCALL
W32kCreateCompatableDC(HDC hDC
)
115 OrigDC
= DC_HandleToPtr(hDC
);
121 /* Allocate a new DC based on the original DC's device */
122 NewDC
= DC_AllocDC(OrigDC
->DriverName
);
129 DRIVER_ReferenceDriver (NewDC
->DriverName
);
131 /* Copy information from original DC to new DC */
132 NewDC
->hSelf
= NewDC
;
134 /* FIXME: Should this DC request its own PDEV? */
135 NewDC
->PDev
= OrigDC
->PDev
;
137 NewDC
->DMW
= OrigDC
->DMW
;
138 memcpy(NewDC
->FillPatternSurfaces
,
139 OrigDC
->FillPatternSurfaces
,
140 sizeof OrigDC
->FillPatternSurfaces
);
141 NewDC
->GDIInfo
= OrigDC
->GDIInfo
;
142 NewDC
->DevInfo
= OrigDC
->DevInfo
;
144 /* FIXME: Should this DC request its own surface? */
145 NewDC
->Surface
= OrigDC
->Surface
;
147 NewDC
->DriverFunctions
= OrigDC
->DriverFunctions
;
148 /* DriverName is copied in the AllocDC routine */
149 NewDC
->DeviceDriver
= OrigDC
->DeviceDriver
;
150 NewDC
->wndOrgX
= OrigDC
->wndOrgX
;
151 NewDC
->wndOrgY
= OrigDC
->wndOrgY
;
152 NewDC
->wndExtX
= OrigDC
->wndExtX
;
153 NewDC
->wndExtY
= OrigDC
->wndExtY
;
154 NewDC
->vportOrgX
= OrigDC
->vportOrgX
;
155 NewDC
->vportOrgY
= OrigDC
->vportOrgY
;
156 NewDC
->vportExtX
= OrigDC
->vportExtX
;
157 NewDC
->vportExtY
= OrigDC
->vportExtY
;
161 /* Create default bitmap */
162 if (!(hBitmap
= W32kCreateBitmap( 1, 1, 1, 1, NULL
)))
169 NewDC
->w
.flags
= DC_MEMORY
;
170 NewDC
->w
.bitsPerPixel
= 1;
171 NewDC
->w
.hBitmap
= hBitmap
;
172 NewDC
->w
.hFirstBitmap
= hBitmap
;
177 return DC_PtrToHandle(NewDC
);
180 HDC STDCALL
W32kCreateDC(LPCWSTR Driver
,
183 CONST PDEVMODEW InitData
)
185 PGD_ENABLEDRIVER GDEnableDriver
;
190 /* Check for existing DC object */
191 if ((NewDC
= DC_FindOpenDC(Driver
)) != NULL
)
193 hDC
= DC_PtrToHandle(NewDC
);
194 return W32kCreateCompatableDC(hDC
);
197 /* Allocate a DC object */
198 if ((NewDC
= DC_AllocDC(Driver
)) == NULL
)
203 /* Open the miniport driver */
204 if ((NewDC
->DeviceDriver
= DRIVER_FindMPDriver(Driver
)) == NULL
)
206 DbgPrint("FindMPDriver failed\n");
210 /* Get the DDI driver's entry point */
211 /* FIXME: Retrieve DDI driver name from registry */
212 if ((GDEnableDriver
= DRIVER_FindDDIDriver(L
"\\??\\C:\\reactos\\system32\\drivers\\vgaddi.dll")) == NULL
)
214 DbgPrint("FindDDIDriver failed\n");
218 /* Call DDI driver's EnableDriver function */
219 RtlZeroMemory(&DED
, sizeof(DED
));
221 if (!GDEnableDriver(DDI_DRIVER_VERSION
, sizeof(DED
), &DED
))
223 DbgPrint("DrvEnableDriver failed\n");
227 /* Construct DDI driver function dispatch table */
228 if (!DRIVER_BuildDDIFunctions(&DED
, &NewDC
->DriverFunctions
))
230 DbgPrint("BuildDDIFunctions failed\n");
234 /* Allocate a phyical device handle from the driver */
237 wcsncpy(NewDC
->DMW
.dmDeviceName
, Device
, DMMAXDEVICENAME
);
239 NewDC
->DMW
.dmSize
= sizeof(NewDC
->DMW
);
240 NewDC
->DMW
.dmFields
= 0x000fc000;
242 /* FIXME: get mode selection information from somewhere */
244 NewDC
->DMW
.dmLogPixels
= 96;
245 NewDC
->DMW
.dmBitsPerPel
= 8;
246 NewDC
->DMW
.dmPelsWidth
= 640;
247 NewDC
->DMW
.dmPelsHeight
= 480;
248 NewDC
->DMW
.dmDisplayFlags
= 0;
249 NewDC
->DMW
.dmDisplayFrequency
= 0;
251 NewDC
->PDev
= NewDC
->DriverFunctions
.EnablePDev(&NewDC
->DMW
,
254 NewDC
->FillPatternSurfaces
,
255 sizeof(NewDC
->GDIInfo
),
256 (ULONG
*) &NewDC
->GDIInfo
,
257 sizeof(NewDC
->DevInfo
),
261 NewDC
->DeviceDriver
);
262 if (NewDC
->PDev
== NULL
)
264 DbgPrint("DrvEnablePDEV failed\n");
268 /* Complete initialization of the physical device */
269 NewDC
->DriverFunctions
.CompletePDev(NewDC
->PDev
, NewDC
);
271 DRIVER_ReferenceDriver (Driver
);
273 /* Enable the drawing surface */
274 NewDC
->Surface
= NewDC
->DriverFunctions
.EnableSurface(NewDC
->PDev
); // hsurf
276 /* Test EngXxx functions */
279 /* Initialize the DC state */
282 return DC_PtrToHandle(NewDC
);
289 HDC STDCALL
W32kCreateIC(LPCWSTR Driver
,
292 CONST PDEVMODEW DevMode
)
294 /* FIXME: this should probably do something else... */
295 return W32kCreateDC(Driver
, Device
, Output
, DevMode
);
298 BOOL STDCALL
W32kDeleteDC(HDC DCHandle
)
304 DCToDelete
= DC_HandleToPtr(DCHandle
);
305 if (DCToDelete
== NULL
)
310 if (!DRIVER_UnreferenceDriver (DCToDelete
->DriverName
))
312 DCToDelete
->DriverFunctions
.DisableSurface(DCToDelete
->PDev
);
313 DCToDelete
->DriverFunctions
.DisablePDev(DCToDelete
->PDev
);
316 /* First delete all saved DCs */
317 while (DCToDelete
->saveLevel
)
322 savedHDC
= GDIOBJ_GetNextObject (DCHandle
, GO_DC_MAGIC
);
323 savedDC
= DC_HandleToPtr (savedHDC
);
328 GDIOBJ_SetNextObject (DCHandle
, GO_DC_MAGIC
, GDIOBJ_GetNextObject (savedHDC
, GO_DC_MAGIC
));
329 DCToDelete
->saveLevel
--;
330 DC_UnlockDC (savedDC
);
331 W32kDeleteDC (savedHDC
);
334 /* Free GDI resources allocated to this DC */
335 if (!(DCToDelete
->w
.flags
& DC_SAVED
))
337 DC_UnlockDC (DCToDelete
);
338 SelectObject (DCHandle
, STOCK_BLACK_PEN
);
339 SelectObject (DCHandle
, STOCK_WHITE_BRUSH
);
340 SelectObject (DCHandle
, STOCK_SYSTEM_FONT
);
341 DC_LockDC (DCHandle
);
342 if (DCToDelete
->w
.flags
& DC_MEMORY
)
344 W32kDeleteObject (DCToDelete
->w
.hFirstBitmap
);
347 if (DCToDelete
->w
.hClipRgn
)
349 W32kDeleteObject (DCToDelete
->w
.hClipRgn
);
351 if (DCToDelete
->w
.hVisRgn
)
353 W32kDeleteObject (DCToDelete
->w
.hVisRgn
);
355 if (DCToDelete
->w
.hGCClipRgn
)
357 W32kDeleteObject (DCToDelete
->w
.hGCClipRgn
);
360 PATH_DestroyGdiPath (&DCToDelete
->w
.path
);
363 DC_FreeDC (DCToDelete
);
365 return STATUS_SUCCESS
;
368 BOOL STDCALL
W32kDeleteObject(HGDIOBJ hObject
)
373 INT STDCALL
W32kDrawEscape(HDC hDC
,
381 INT STDCALL
W32kEnumObjects(HDC hDC
,
383 GOBJENUMPROC ObjectFunc
,
389 DC_GET_VAL( COLORREF
, W32kGetBkColor
, w
.backgroundColor
)
390 DC_GET_VAL( INT
, W32kGetBkMode
, w
.backgroundMode
)
391 DC_GET_VAL_EX( W32kGetBrushOrgEx
, w
.brushOrgX
, w
.brushOrgY
, POINT
)
392 DC_GET_VAL( HRGN
, W32kGetClipRgn
, w
.hClipRgn
)
394 HGDIOBJ STDCALL
W32kGetCurrentObject(HDC hDC
,
400 DC_GET_VAL_EX( W32kGetCurrentPositionEx
, w
.CursPosX
, w
.CursPosY
, POINT
)
402 BOOL STDCALL
W32kGetDCOrgEx(HDC hDC
,
411 dc
= DC_HandleToPtr(hDC
);
417 Point
->x
= Point
->y
= 0;
419 Point
->x
+= dc
->w
.DCOrgX
;
420 Point
->y
+= dc
->w
.DCOrgY
;
426 HDC STDCALL
W32kGetDCState16(HDC hDC
)
430 dc
= DC_HandleToPtr(hDC
);
436 newdc
= DC_AllocDC(NULL
);
443 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
445 newdc
->w
.devCaps
= dc
->w
.devCaps
;
447 newdc
->w
.hPen
= dc
->w
.hPen
;
448 newdc
->w
.hBrush
= dc
->w
.hBrush
;
449 newdc
->w
.hFont
= dc
->w
.hFont
;
450 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
451 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
453 newdc
->w
.hDevice
= dc
->w
.hDevice
;
454 newdc
->w
.hPalette
= dc
->w
.hPalette
;
456 newdc
->w
.totalExtent
= dc
->w
.totalExtent
;
457 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
458 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
459 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
460 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
461 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
462 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
463 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
464 newdc
->w
.textColor
= dc
->w
.textColor
;
465 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
466 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
467 newdc
->w
.textAlign
= dc
->w
.textAlign
;
468 newdc
->w
.charExtra
= dc
->w
.charExtra
;
469 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
470 newdc
->w
.breakCount
= dc
->w
.breakCount
;
471 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
472 newdc
->w
.breakRem
= dc
->w
.breakRem
;
473 newdc
->w
.MapMode
= dc
->w
.MapMode
;
474 newdc
->w
.GraphicsMode
= dc
->w
.GraphicsMode
;
476 /* Apparently, the DC origin is not changed by [GS]etDCState */
477 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
478 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
480 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
481 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
482 newdc
->w
.ArcDirection
= dc
->w
.ArcDirection
;
484 newdc
->w
.xformWorld2Wnd
= dc
->w
.xformWorld2Wnd
;
485 newdc
->w
.xformWorld2Vport
= dc
->w
.xformWorld2Vport
;
486 newdc
->w
.xformVport2World
= dc
->w
.xformVport2World
;
487 newdc
->w
.vport2WorldValid
= dc
->w
.vport2WorldValid
;
489 newdc
->wndOrgX
= dc
->wndOrgX
;
490 newdc
->wndOrgY
= dc
->wndOrgY
;
491 newdc
->wndExtX
= dc
->wndExtX
;
492 newdc
->wndExtY
= dc
->wndExtY
;
493 newdc
->vportOrgX
= dc
->vportOrgX
;
494 newdc
->vportOrgY
= dc
->vportOrgY
;
495 newdc
->vportExtX
= dc
->vportExtX
;
496 newdc
->vportExtY
= dc
->vportExtY
;
498 newdc
->hSelf
= DC_PtrToHandle(newdc
);
499 newdc
->saveLevel
= 0;
502 PATH_InitGdiPath( &newdc
->w
.path
);
505 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
508 newdc
->w
.hGCClipRgn
= newdc
->w
.hVisRgn
= 0;
512 newdc
->w
.hClipRgn
= W32kCreateRectRgn( 0, 0, 0, 0 );
513 W32kCombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
517 newdc
->w
.hClipRgn
= 0;
524 INT STDCALL
W32kGetDeviceCaps(HDC hDC
,
531 dc
= DC_HandleToPtr(hDC
);
537 /* Device capabilities for the printer */
541 if(W32kEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
548 if(W32kEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
554 case PHYSICALOFFSETX
:
555 if(W32kEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
561 case PHYSICALOFFSETY
:
562 if(W32kEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
569 if(W32kEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
576 if(W32kEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
583 if ((Index
< 0) || (Index
> sizeof(DEVICECAPS
) - sizeof(WORD
)))
589 DPRINT("(%04x,%d): returning %d\n",
590 hDC
, Index
, *(WORD
*)(((char *)dc
->w
.devCaps
) + Index
));
591 ret
= *(WORD
*)(((char *)dc
->w
.devCaps
) + Index
);
597 DC_GET_VAL( INT
, W32kGetMapMode
, w
.MapMode
)
598 DC_GET_VAL( INT
, W32kGetPolyFillMode
, w
.polyFillMode
)
600 INT STDCALL
W32kGetObject(HGDIOBJ hGDIObj
,
607 DWORD STDCALL
W32kGetObjectType(HGDIOBJ hGDIObj
)
612 DC_GET_VAL( INT
, W32kGetRelAbs
, w
.relAbsMode
)
613 DC_GET_VAL( INT
, W32kGetROP2
, w
.ROPmode
)
614 DC_GET_VAL( INT
, W32kGetStretchBltMode
, w
.stretchBltMode
)
616 HGDIOBJ STDCALL
W32kGetStockObject(INT Object
)
621 DC_GET_VAL( UINT
, W32kGetTextAlign
, w
.textAlign
)
622 DC_GET_VAL( COLORREF
, W32kGetTextColor
, w
.textColor
)
623 DC_GET_VAL_EX( W32kGetViewportExtEx
, vportExtX
, vportExtY
, SIZE
)
624 DC_GET_VAL_EX( W32kGetViewportOrgEx
, vportOrgX
, vportOrgY
, POINT
)
625 DC_GET_VAL_EX( W32kGetWindowExtEx
, wndExtX
, wndExtY
, SIZE
)
626 DC_GET_VAL_EX( W32kGetWindowOrgEx
, wndOrgX
, wndOrgY
, POINT
)
628 HDC STDCALL
W32kResetDC(HDC hDC
, CONST DEVMODE
*InitData
)
633 BOOL STDCALL
W32kRestoreDC(HDC hDC
, INT SaveLevel
)
638 dc
= DC_HandleToPtr(hDC
);
646 SaveLevel
= dc
->saveLevel
;
649 if ((SaveLevel
< 1) || (SaveLevel
> dc
->saveLevel
))
657 while (dc
->saveLevel
>= SaveLevel
)
659 HDC hdcs
= GDIOBJ_GetNextObject (hDC
, GO_DC_MAGIC
);
661 dcs
= DC_HandleToPtr (hdcs
);
668 GDIOBJ_SetNextObject (hDC
, GO_DC_MAGIC
, GDIOBJ_GetNextObject (hdcs
, GO_DC_MAGIC
));
669 if (--dc
->saveLevel
< SaveLevel
)
671 W32kSetDCState16 (hDC
, hdcs
);
673 if (!PATH_AssignGdiPath( &dc
->w
.path
, &dcs
->w
.path
))
675 /* FIXME: This might not be quite right, since we're
676 * returning FALSE but still destroying the saved DC state */
688 INT STDCALL
W32kSaveDC(HDC hDC
)
694 dc
= DC_HandleToPtr (hDC
);
700 if (!(hdcs
= W32kGetDCState16 (hDC
)))
706 dcs
= DC_HandleToPtr (hdcs
);
709 /* Copy path. The reason why path saving / restoring is in SaveDC/
710 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
711 * functions are only in Win16 (which doesn't have paths) and that
712 * SetDCState doesn't allow us to signal an error (which can happen
713 * when copying paths).
715 if (!PATH_AssignGdiPath (&dcs
->w
.path
, &dc
->w
.path
))
724 GDIOBJ_SetNextObject (hdcs
, GO_DC_MAGIC
, GDIOBJ_GetNextObject (hDC
, GO_DC_MAGIC
));
725 GDIOBJ_SetNextObject (hDC
, GO_DC_MAGIC
, hdcs
);
726 ret
= ++dc
->saveLevel
;
733 HGDIOBJ STDCALL
W32kSelectObject(HDC hDC
, HGDIOBJ GDIObj
)
738 DC_SET_MODE( W32kSetBkMode
, w
.backgroundMode
, TRANSPARENT
, OPAQUE
)
739 DC_SET_MODE( W32kSetPolyFillMode
, w
.polyFillMode
, ALTERNATE
, WINDING
)
740 // DC_SET_MODE( W32kSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE )
741 DC_SET_MODE( W32kSetROP2
, w
.ROPmode
, R2_BLACK
, R2_WHITE
)
742 DC_SET_MODE( W32kSetStretchBltMode
, w
.stretchBltMode
, BLACKONWHITE
, HALFTONE
)
744 COLORREF STDCALL
W32kSetBkColor(HDC hDC
, COLORREF color
)
747 PDC dc
= DC_HandleToPtr(hDC
);
754 oldColor
= dc
->w
.backgroundColor
;
755 dc
->w
.backgroundColor
= color
;
761 static void W32kSetDCState16(HDC hDC
, HDC hDCSave
)
765 dc
= DC_HandleToPtr(hDC
);
771 dcs
= DC_HandleToPtr(hDCSave
);
778 if (!dcs
->w
.flags
& DC_SAVED
)
781 DC_UnlockDC(hDCSave
);
786 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
789 dc
->w
.devCaps
= dcs
->w
.devCaps
;
792 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
795 dc
->w
.hDevice
= dcs
->w
.hDevice
;
798 dc
->w
.totalExtent
= dcs
->w
.totalExtent
;
799 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
800 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
801 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
802 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
803 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
804 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
805 dc
->w
.textColor
= dcs
->w
.textColor
;
806 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
807 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
808 dc
->w
.textAlign
= dcs
->w
.textAlign
;
809 dc
->w
.charExtra
= dcs
->w
.charExtra
;
810 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
811 dc
->w
.breakCount
= dcs
->w
.breakCount
;
812 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
813 dc
->w
.breakRem
= dcs
->w
.breakRem
;
814 dc
->w
.MapMode
= dcs
->w
.MapMode
;
815 dc
->w
.GraphicsMode
= dcs
->w
.GraphicsMode
;
817 /* Apparently, the DC origin is not changed by [GS]etDCState */
818 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
819 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
821 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
822 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
823 dc
->w
.ArcDirection
= dcs
->w
.ArcDirection
;
826 dc
->w
.xformWorld2Wnd
= dcs
->w
.xformWorld2Wnd
;
827 dc
->w
.xformWorld2Vport
= dcs
->w
.xformWorld2Vport
;
828 dc
->w
.xformVport2World
= dcs
->w
.xformVport2World
;
829 dc
->w
.vport2WorldValid
= dcs
->w
.vport2WorldValid
;
832 dc
->wndOrgX
= dcs
->wndOrgX
;
833 dc
->wndOrgY
= dcs
->wndOrgY
;
834 dc
->wndExtX
= dcs
->wndExtX
;
835 dc
->wndExtY
= dcs
->wndExtY
;
836 dc
->vportOrgX
= dcs
->vportOrgX
;
837 dc
->vportOrgY
= dcs
->vportOrgY
;
838 dc
->vportExtX
= dcs
->vportExtX
;
839 dc
->vportExtY
= dcs
->vportExtY
;
841 if (!(dc
->w
.flags
& DC_MEMORY
))
843 dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
851 dc
->w
.hClipRgn
= W32kCreateRectRgn( 0, 0, 0, 0 );
853 W32kCombineRgn( dc
->w
.hClipRgn
, dcs
->w
.hClipRgn
, 0, RGN_COPY
);
859 W32kDeleteObject( dc
->w
.hClipRgn
);
864 CLIPPING_UpdateGCRegion( dc
);
867 W32kSelectObject( hDC
, dcs
->w
.hBitmap
);
868 W32kSelectObject( hDC
, dcs
->w
.hBrush
);
869 W32kSelectObject( hDC
, dcs
->w
.hFont
);
870 W32kSelectObject( hDC
, dcs
->w
.hPen
);
871 W32kSetBkColor( hDC
, dcs
->w
.backgroundColor
);
872 W32kSetTextColor( hDC
, dcs
->w
.textColor
);
875 GDISelectPalette16( hDC
, dcs
->w
.hPalette
, FALSE
);
879 DC_UnlockDC(hDCSave
);
882 // ---------------------------------------------------- Private Interface
884 PDC
DC_AllocDC(LPCWSTR Driver
)
888 NewDC
= (PDC
) GDIOBJ_AllocObject(sizeof(DC
), GO_DC_MAGIC
);
895 NewDC
->DriverName
= ExAllocatePool(NonPagedPool
,
896 (wcslen(Driver
) + 1) * sizeof(WCHAR
));
897 wcscpy(NewDC
->DriverName
, Driver
);
903 PDC
DC_FindOpenDC(LPCWSTR Driver
)
909 void DC_InitDC(PDC DCToInit
)
913 DCHandle
= DC_PtrToHandle(DCToInit
);
914 // W32kRealizeDefaultPalette(DCHandle);
915 W32kSetTextColor(DCHandle
, DCToInit
->w
.textColor
);
916 W32kSetBkColor(DCHandle
, DCToInit
->w
.backgroundColor
);
917 W32kSelectObject(DCHandle
, DCToInit
->w
.hPen
);
918 W32kSelectObject(DCHandle
, DCToInit
->w
.hBrush
);
919 W32kSelectObject(DCHandle
, DCToInit
->w
.hFont
);
920 // CLIPPING_UpdateGCRegion(DCToInit);
923 void DC_FreeDC(PDC DCToFree
)
925 ExFreePool(DCToFree
->DriverName
);
926 if (!GDIOBJ_FreeObject((PGDIOBJ
)DCToFree
, GO_DC_MAGIC
))
928 DbgPrint("DC_FreeDC failed\n");
933 DC_UpdateXforms(PDC dc
)
935 XFORM xformWnd2Vport
;
936 FLOAT scaleX
, scaleY
;
938 /* Construct a transformation to do the window-to-viewport conversion */
939 scaleX
= (FLOAT
)dc
->vportExtX
/ (FLOAT
)dc
->wndExtX
;
940 scaleY
= (FLOAT
)dc
->vportExtY
/ (FLOAT
)dc
->wndExtY
;
941 xformWnd2Vport
.eM11
= scaleX
;
942 xformWnd2Vport
.eM12
= 0.0;
943 xformWnd2Vport
.eM21
= 0.0;
944 xformWnd2Vport
.eM22
= scaleY
;
945 xformWnd2Vport
.eDx
= (FLOAT
)dc
->vportOrgX
-
946 scaleX
* (FLOAT
)dc
->wndOrgX
;
947 xformWnd2Vport
.eDy
= (FLOAT
)dc
->vportOrgY
-
948 scaleY
* (FLOAT
)dc
->wndOrgY
;
950 /* Combine with the world transformation */
951 W32kCombineTransform(&dc
->w
.xformWorld2Vport
,
952 &dc
->w
.xformWorld2Wnd
,
955 /* Create inverse of world-to-viewport transformation */
956 dc
->w
.vport2WorldValid
= DC_InvertXform(&dc
->w
.xformWorld2Vport
,
957 &dc
->w
.xformVport2World
);
961 DC_InvertXform(const XFORM
*xformSrc
,
966 determinant
= xformSrc
->eM11
*xformSrc
->eM22
-
967 xformSrc
->eM12
*xformSrc
->eM21
;
968 if (determinant
> -1e-12 && determinant
< 1e-12)
973 xformDest
->eM11
= xformSrc
->eM22
/ determinant
;
974 xformDest
->eM12
= -xformSrc
->eM12
/ determinant
;
975 xformDest
->eM21
= -xformSrc
->eM21
/ determinant
;
976 xformDest
->eM22
= xformSrc
->eM11
/ determinant
;
977 xformDest
->eDx
= -xformSrc
->eDx
* xformDest
->eM11
-
978 xformSrc
->eDy
* xformDest
->eM21
;
979 xformDest
->eDy
= -xformSrc
->eDx
* xformDest
->eM12
-
980 xformSrc
->eDy
* xformDest
->eM22
;