1 /* $Id: dc.c,v 1.12 2000/03/08 21:23:14 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 /* FIXME: DCs should probably be thread safe */
24 * DC device-independent Get/SetXXX functions
25 * (RJJ) swiped from WINE
28 #define DC_GET_VAL( func_type, func_name, dc_field ) \
29 func_type STDCALL func_name( HDC hdc ) \
32 PDC dc = DC_HandleToPtr( hdc ); \
42 /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
43 * important that the function has the right signature, for the implementation
44 * we can do whatever we want.
46 #define DC_GET_VAL_EX( func_name, ret_x, ret_y, type ) \
47 BOOL STDCALL func_name( HDC hdc, LP##type pt ) \
49 PDC dc = DC_HandleToPtr( hdc ); \
54 ((LPPOINT)pt)->x = dc->ret_x; \
55 ((LPPOINT)pt)->y = dc->ret_y; \
60 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
61 INT STDCALL func_name( HDC hdc, INT mode ) \
64 PDC dc = DC_HandleToPtr( hdc ); \
69 if ((mode < min_val) || (mode > max_val)) \
73 prevMode = dc->dc_field; \
74 dc->dc_field = mode; \
79 // --------------------------------------------------------- File Statics
81 static void W32kSetDCState16(HDC hDC
, HDC hDCSave
);
83 // ----------------------------------------------------- Public Functions
85 BOOL STDCALL
W32kCancelDC(HDC hDC
)
90 HDC STDCALL
W32kCreateCompatableDC(HDC hDC
)
95 OrigDC
= DC_HandleToPtr(hDC
);
101 /* Allocate a new DC based on the original DC's device */
102 NewDC
= DC_AllocDC(OrigDC
->DriverName
);
109 DRIVER_ReferenceDriver (NewDC
->DriverName
);
111 /* Copy information from original DC to new DC */
112 NewDC
->hSelf
= NewDC
;
114 /* FIXME: Should this DC request its own PDEV? */
115 NewDC
->PDev
= OrigDC
->PDev
;
117 NewDC
->DMW
= OrigDC
->DMW
;
118 memcpy(NewDC
->FillPatternSurfaces
,
119 OrigDC
->FillPatternSurfaces
,
120 sizeof OrigDC
->FillPatternSurfaces
);
121 NewDC
->GDIInfo
= OrigDC
->GDIInfo
;
122 NewDC
->DevInfo
= OrigDC
->DevInfo
;
124 /* FIXME: Should this DC request its own surface? */
125 NewDC
->Surface
= OrigDC
->Surface
;
127 NewDC
->DriverFunctions
= OrigDC
->DriverFunctions
;
128 /* DriverName is copied in the AllocDC routine */
129 NewDC
->DeviceDriver
= OrigDC
->DeviceDriver
;
130 NewDC
->wndOrgX
= OrigDC
->wndOrgX
;
131 NewDC
->wndOrgY
= OrigDC
->wndOrgY
;
132 NewDC
->wndExtX
= OrigDC
->wndExtX
;
133 NewDC
->wndExtY
= OrigDC
->wndExtY
;
134 NewDC
->vportOrgX
= OrigDC
->vportOrgX
;
135 NewDC
->vportOrgY
= OrigDC
->vportOrgY
;
136 NewDC
->vportExtX
= OrigDC
->vportExtX
;
137 NewDC
->vportExtY
= OrigDC
->vportExtY
;
141 /* Create default bitmap */
142 if (!(hBitmap
= W32kCreateBitmap( 1, 1, 1, 1, NULL
)))
149 NewDC
->w
.flags
= DC_MEMORY
;
150 NewDC
->w
.bitsPerPixel
= 1;
151 NewDC
->w
.hBitmap
= hBitmap
;
152 NewDC
->w
.hFirstBitmap
= hBitmap
;
157 return DC_PtrToHandle(NewDC
);
160 HDC STDCALL
W32kCreateDC(LPCWSTR Driver
,
163 CONST PDEVMODEW InitData
)
165 PGD_ENABLEDRIVER GDEnableDriver
;
170 /* Check for existing DC object */
171 if ((NewDC
= DC_FindOpenDC(Driver
)) != NULL
)
173 hDC
= DC_PtrToHandle(NewDC
);
174 return W32kCreateCompatableDC(hDC
);
177 /* Allocate a DC object */
178 if ((NewDC
= DC_AllocDC(Driver
)) == NULL
)
183 /* Open the miniport driver */
184 if ((NewDC
->DeviceDriver
= DRIVER_FindMPDriver(Driver
)) == NULL
)
186 DbgPrint("FindMPDriver failed\n");
190 /* Get the DDI driver's entry point */
191 /* FIXME: Retrieve DDI driver name from registry */
192 if ((GDEnableDriver
= DRIVER_FindDDIDriver(L
"\\??\\C:\\reactos\\system32\\drivers\\vgaddi.dll")) == NULL
)
194 DbgPrint("FindDDIDriver failed\n");
198 /* Call DDI driver's EnableDriver function */
199 RtlZeroMemory(&DED
, sizeof(DED
));
200 if (!GDEnableDriver(DDI_DRIVER_VERSION
, sizeof(DED
), &DED
))
202 DbgPrint("DrvEnableDriver failed\n");
206 /* Construct DDI driver function dispatch table */
207 if (!DRIVER_BuildDDIFunctions(&DED
, &NewDC
->DriverFunctions
))
209 DbgPrint("BuildDDIFunctions failed\n");
213 /* Allocate a phyical device handle from the driver */
216 wcsncpy(NewDC
->DMW
.dmDeviceName
, Device
, DMMAXDEVICENAME
);
218 NewDC
->DMW
.dmSize
= sizeof(NewDC
->DMW
);
219 NewDC
->DMW
.dmFields
= 0x000fc000;
221 /* FIXME: get mode selection information from somewhere */
223 NewDC
->DMW
.dmLogPixels
= 96;
224 NewDC
->DMW
.dmBitsPerPel
= 8;
225 NewDC
->DMW
.dmPelsWidth
= 640;
226 NewDC
->DMW
.dmPelsHeight
= 480;
227 NewDC
->DMW
.dmDisplayFlags
= 0;
228 NewDC
->DMW
.dmDisplayFrequency
= 0;
229 NewDC
->PDev
= NewDC
->DriverFunctions
.EnablePDev(&NewDC
->DMW
,
232 NewDC
->FillPatternSurfaces
,
233 sizeof(NewDC
->GDIInfo
),
234 (ULONG
*) &NewDC
->GDIInfo
,
235 sizeof(NewDC
->DevInfo
),
239 NewDC
->DeviceDriver
);
240 if (NewDC
->PDev
== NULL
)
242 DbgPrint("DrvEnablePDEV failed\n");
246 /* Complete initialization of the physical device */
247 NewDC
->DriverFunctions
.CompletePDev(NewDC
->PDev
, NewDC
);
249 DRIVER_ReferenceDriver (Driver
);
251 /* Enable the drawing surface */
252 NewDC
->Surface
= NewDC
->DriverFunctions
.EnableSurface(NewDC
->PDev
);
254 /* Initialize the DC state */
257 return DC_PtrToHandle(NewDC
);
264 HDC STDCALL
W32kCreateIC(LPCWSTR Driver
,
267 CONST PDEVMODEW DevMode
)
269 /* FIXME: this should probably do something else... */
270 return W32kCreateDC(Driver
, Device
, Output
, DevMode
);
273 BOOL STDCALL
W32kDeleteDC(HDC DCHandle
)
279 DCToDelete
= DC_HandleToPtr(DCHandle
);
280 if (DCToDelete
== NULL
)
285 if (!DRIVER_UnreferenceDriver (DCToDelete
->DriverName
))
287 DCToDelete
->DriverFunctions
.DisableSurface(DCToDelete
->PDev
);
288 DCToDelete
->DriverFunctions
.DisablePDev(DCToDelete
->PDev
);
291 /* First delete all saved DCs */
292 while (DCToDelete
->saveLevel
)
297 savedHDC
= GDIOBJ_GetNextObject (DCHandle
, GO_DC_MAGIC
);
298 savedDC
= DC_HandleToPtr (savedHDC
);
303 GDIOBJ_SetNextObject (DCHandle
, GO_DC_MAGIC
, GDIOBJ_GetNextObject (savedHDC
, GO_DC_MAGIC
));
304 DCToDelete
->saveLevel
--;
305 DC_UnlockDC (savedDC
);
306 W32kDeleteDC (savedHDC
);
309 /* Free GDI resources allocated to this DC */
310 if (!(DCToDelete
->w
.flags
& DC_SAVED
))
312 DC_UnlockDC (DCToDelete
);
313 SelectObject (DCHandle
, STOCK_BLACK_PEN
);
314 SelectObject (DCHandle
, STOCK_WHITE_BRUSH
);
315 SelectObject (DCHandle
, STOCK_SYSTEM_FONT
);
316 DC_LockDC (DCHandle
);
317 if (DCToDelete
->w
.flags
& DC_MEMORY
)
319 W32kDeleteObject (DCToDelete
->w
.hFirstBitmap
);
322 if (DCToDelete
->w
.hClipRgn
)
324 W32kDeleteObject (DCToDelete
->w
.hClipRgn
);
326 if (DCToDelete
->w
.hVisRgn
)
328 W32kDeleteObject (DCToDelete
->w
.hVisRgn
);
330 if (DCToDelete
->w
.hGCClipRgn
)
332 W32kDeleteObject (DCToDelete
->w
.hGCClipRgn
);
335 PATH_DestroyGdiPath (&DCToDelete
->w
.path
);
338 DC_FreeDC (DCToDelete
);
340 return STATUS_SUCCESS
;
343 BOOL STDCALL
W32kDeleteObject(HGDIOBJ hObject
)
348 INT STDCALL
W32kDrawEscape(HDC hDC
,
356 INT STDCALL
W32kEnumObjects(HDC hDC
,
358 GOBJENUMPROC ObjectFunc
,
364 DC_GET_VAL( COLORREF
, W32kGetBkColor
, w
.backgroundColor
)
365 DC_GET_VAL( INT
, W32kGetBkMode
, w
.backgroundMode
)
366 DC_GET_VAL_EX( W32kGetBrushOrgEx
, w
.brushOrgX
, w
.brushOrgY
, POINT
)
367 DC_GET_VAL( HRGN
, W32kGetClipRgn
, w
.hClipRgn
)
369 HGDIOBJ STDCALL
W32kGetCurrentObject(HDC hDC
,
375 DC_GET_VAL_EX( W32kGetCurrentPositionEx
, w
.CursPosX
, w
.CursPosY
, POINT
)
377 BOOL STDCALL
W32kGetDCOrgEx(HDC hDC
,
386 dc
= DC_HandleToPtr(hDC
);
392 Point
->x
= Point
->y
= 0;
394 Point
->x
+= dc
->w
.DCOrgX
;
395 Point
->y
+= dc
->w
.DCOrgY
;
401 HDC STDCALL
W32kGetDCState16(HDC hDC
)
405 dc
= DC_HandleToPtr(hDC
);
411 newdc
= DC_AllocDC(NULL
);
418 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
420 newdc
->w
.devCaps
= dc
->w
.devCaps
;
422 newdc
->w
.hPen
= dc
->w
.hPen
;
423 newdc
->w
.hBrush
= dc
->w
.hBrush
;
424 newdc
->w
.hFont
= dc
->w
.hFont
;
425 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
426 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
428 newdc
->w
.hDevice
= dc
->w
.hDevice
;
429 newdc
->w
.hPalette
= dc
->w
.hPalette
;
431 newdc
->w
.totalExtent
= dc
->w
.totalExtent
;
432 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
433 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
434 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
435 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
436 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
437 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
438 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
439 newdc
->w
.textColor
= dc
->w
.textColor
;
440 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
441 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
442 newdc
->w
.textAlign
= dc
->w
.textAlign
;
443 newdc
->w
.charExtra
= dc
->w
.charExtra
;
444 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
445 newdc
->w
.breakCount
= dc
->w
.breakCount
;
446 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
447 newdc
->w
.breakRem
= dc
->w
.breakRem
;
448 newdc
->w
.MapMode
= dc
->w
.MapMode
;
449 newdc
->w
.GraphicsMode
= dc
->w
.GraphicsMode
;
451 /* Apparently, the DC origin is not changed by [GS]etDCState */
452 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
453 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
455 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
456 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
457 newdc
->w
.ArcDirection
= dc
->w
.ArcDirection
;
459 newdc
->w
.xformWorld2Wnd
= dc
->w
.xformWorld2Wnd
;
460 newdc
->w
.xformWorld2Vport
= dc
->w
.xformWorld2Vport
;
461 newdc
->w
.xformVport2World
= dc
->w
.xformVport2World
;
462 newdc
->w
.vport2WorldValid
= dc
->w
.vport2WorldValid
;
464 newdc
->wndOrgX
= dc
->wndOrgX
;
465 newdc
->wndOrgY
= dc
->wndOrgY
;
466 newdc
->wndExtX
= dc
->wndExtX
;
467 newdc
->wndExtY
= dc
->wndExtY
;
468 newdc
->vportOrgX
= dc
->vportOrgX
;
469 newdc
->vportOrgY
= dc
->vportOrgY
;
470 newdc
->vportExtX
= dc
->vportExtX
;
471 newdc
->vportExtY
= dc
->vportExtY
;
473 newdc
->hSelf
= DC_PtrToHandle(newdc
);
474 newdc
->saveLevel
= 0;
477 PATH_InitGdiPath( &newdc
->w
.path
);
480 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
483 newdc
->w
.hGCClipRgn
= newdc
->w
.hVisRgn
= 0;
487 newdc
->w
.hClipRgn
= W32kCreateRectRgn( 0, 0, 0, 0 );
488 W32kCombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
492 newdc
->w
.hClipRgn
= 0;
499 INT STDCALL
W32kGetDeviceCaps(HDC hDC
,
506 dc
= DC_HandleToPtr(hDC
);
512 /* Device capabilities for the printer */
516 if(W32kEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
523 if(W32kEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
529 case PHYSICALOFFSETX
:
530 if(W32kEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
536 case PHYSICALOFFSETY
:
537 if(W32kEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
544 if(W32kEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
551 if(W32kEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
558 if ((Index
< 0) || (Index
> sizeof(DEVICECAPS
) - sizeof(WORD
)))
564 DPRINT("(%04x,%d): returning %d\n",
565 hDC
, Index
, *(WORD
*)(((char *)dc
->w
.devCaps
) + Index
));
566 ret
= *(WORD
*)(((char *)dc
->w
.devCaps
) + Index
);
572 DC_GET_VAL( INT
, W32kGetMapMode
, w
.MapMode
)
573 DC_GET_VAL( INT
, W32kGetPolyFillMode
, w
.polyFillMode
)
575 INT STDCALL
W32kGetObject(HGDIOBJ hGDIObj
,
582 DWORD STDCALL
W32kGetObjectType(HGDIOBJ hGDIObj
)
587 DC_GET_VAL( INT
, W32kGetRelAbs
, w
.relAbsMode
)
588 DC_GET_VAL( INT
, W32kGetROP2
, w
.ROPmode
)
589 DC_GET_VAL( INT
, W32kGetStretchBltMode
, w
.stretchBltMode
)
591 HGDIOBJ STDCALL
W32kGetStockObject(INT Object
)
596 DC_GET_VAL( UINT
, W32kGetTextAlign
, w
.textAlign
)
597 DC_GET_VAL( COLORREF
, W32kGetTextColor
, w
.textColor
)
598 DC_GET_VAL_EX( W32kGetViewportExtEx
, vportExtX
, vportExtY
, SIZE
)
599 DC_GET_VAL_EX( W32kGetViewportOrgEx
, vportOrgX
, vportOrgY
, POINT
)
600 DC_GET_VAL_EX( W32kGetWindowExtEx
, wndExtX
, wndExtY
, SIZE
)
601 DC_GET_VAL_EX( W32kGetWindowOrgEx
, wndOrgX
, wndOrgY
, POINT
)
603 HDC STDCALL
W32kResetDC(HDC hDC
, CONST DEVMODE
*InitData
)
608 BOOL STDCALL
W32kRestoreDC(HDC hDC
, INT SaveLevel
)
613 dc
= DC_HandleToPtr(hDC
);
621 SaveLevel
= dc
->saveLevel
;
624 if ((SaveLevel
< 1) || (SaveLevel
> dc
->saveLevel
))
632 while (dc
->saveLevel
>= SaveLevel
)
634 HDC hdcs
= GDIOBJ_GetNextObject (hDC
, GO_DC_MAGIC
);
636 dcs
= DC_HandleToPtr (hdcs
);
643 GDIOBJ_SetNextObject (hDC
, GO_DC_MAGIC
, GDIOBJ_GetNextObject (hdcs
, GO_DC_MAGIC
));
644 if (--dc
->saveLevel
< SaveLevel
)
646 W32kSetDCState16 (hDC
, hdcs
);
648 if (!PATH_AssignGdiPath( &dc
->w
.path
, &dcs
->w
.path
))
650 /* FIXME: This might not be quite right, since we're
651 * returning FALSE but still destroying the saved DC state */
663 INT STDCALL
W32kSaveDC(HDC hDC
)
669 dc
= DC_HandleToPtr (hDC
);
675 if (!(hdcs
= W32kGetDCState16 (hDC
)))
681 dcs
= DC_HandleToPtr (hdcs
);
684 /* Copy path. The reason why path saving / restoring is in SaveDC/
685 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
686 * functions are only in Win16 (which doesn't have paths) and that
687 * SetDCState doesn't allow us to signal an error (which can happen
688 * when copying paths).
690 if (!PATH_AssignGdiPath (&dcs
->w
.path
, &dc
->w
.path
))
699 GDIOBJ_SetNextObject (hdcs
, GO_DC_MAGIC
, GDIOBJ_GetNextObject (hDC
, GO_DC_MAGIC
));
700 GDIOBJ_SetNextObject (hDC
, GO_DC_MAGIC
, hdcs
);
701 ret
= ++dc
->saveLevel
;
708 HGDIOBJ STDCALL
W32kSelectObject(HDC hDC
, HGDIOBJ GDIObj
)
713 DC_SET_MODE( W32kSetBkMode
, w
.backgroundMode
, TRANSPARENT
, OPAQUE
)
714 DC_SET_MODE( W32kSetPolyFillMode
, w
.polyFillMode
, ALTERNATE
, WINDING
)
715 // DC_SET_MODE( W32kSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE )
716 DC_SET_MODE( W32kSetROP2
, w
.ROPmode
, R2_BLACK
, R2_WHITE
)
717 DC_SET_MODE( W32kSetStretchBltMode
, w
.stretchBltMode
, BLACKONWHITE
, HALFTONE
)
719 COLORREF STDCALL
W32kSetBkColor(HDC hDC
, COLORREF color
)
722 PDC dc
= DC_HandleToPtr(hDC
);
729 oldColor
= dc
->w
.backgroundColor
;
730 dc
->w
.backgroundColor
= color
;
736 static void W32kSetDCState16(HDC hDC
, HDC hDCSave
)
740 dc
= DC_HandleToPtr(hDC
);
746 dcs
= DC_HandleToPtr(hDCSave
);
753 if (!dcs
->w
.flags
& DC_SAVED
)
756 DC_UnlockDC(hDCSave
);
761 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
764 dc
->w
.devCaps
= dcs
->w
.devCaps
;
767 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
770 dc
->w
.hDevice
= dcs
->w
.hDevice
;
773 dc
->w
.totalExtent
= dcs
->w
.totalExtent
;
774 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
775 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
776 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
777 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
778 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
779 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
780 dc
->w
.textColor
= dcs
->w
.textColor
;
781 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
782 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
783 dc
->w
.textAlign
= dcs
->w
.textAlign
;
784 dc
->w
.charExtra
= dcs
->w
.charExtra
;
785 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
786 dc
->w
.breakCount
= dcs
->w
.breakCount
;
787 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
788 dc
->w
.breakRem
= dcs
->w
.breakRem
;
789 dc
->w
.MapMode
= dcs
->w
.MapMode
;
790 dc
->w
.GraphicsMode
= dcs
->w
.GraphicsMode
;
792 /* Apparently, the DC origin is not changed by [GS]etDCState */
793 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
794 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
796 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
797 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
798 dc
->w
.ArcDirection
= dcs
->w
.ArcDirection
;
801 dc
->w
.xformWorld2Wnd
= dcs
->w
.xformWorld2Wnd
;
802 dc
->w
.xformWorld2Vport
= dcs
->w
.xformWorld2Vport
;
803 dc
->w
.xformVport2World
= dcs
->w
.xformVport2World
;
804 dc
->w
.vport2WorldValid
= dcs
->w
.vport2WorldValid
;
807 dc
->wndOrgX
= dcs
->wndOrgX
;
808 dc
->wndOrgY
= dcs
->wndOrgY
;
809 dc
->wndExtX
= dcs
->wndExtX
;
810 dc
->wndExtY
= dcs
->wndExtY
;
811 dc
->vportOrgX
= dcs
->vportOrgX
;
812 dc
->vportOrgY
= dcs
->vportOrgY
;
813 dc
->vportExtX
= dcs
->vportExtX
;
814 dc
->vportExtY
= dcs
->vportExtY
;
816 if (!(dc
->w
.flags
& DC_MEMORY
))
818 dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
826 dc
->w
.hClipRgn
= W32kCreateRectRgn( 0, 0, 0, 0 );
828 W32kCombineRgn( dc
->w
.hClipRgn
, dcs
->w
.hClipRgn
, 0, RGN_COPY
);
834 W32kDeleteObject( dc
->w
.hClipRgn
);
839 CLIPPING_UpdateGCRegion( dc
);
842 W32kSelectObject( hDC
, dcs
->w
.hBitmap
);
843 W32kSelectObject( hDC
, dcs
->w
.hBrush
);
844 W32kSelectObject( hDC
, dcs
->w
.hFont
);
845 W32kSelectObject( hDC
, dcs
->w
.hPen
);
846 W32kSetBkColor( hDC
, dcs
->w
.backgroundColor
);
847 W32kSetTextColor( hDC
, dcs
->w
.textColor
);
850 GDISelectPalette16( hDC
, dcs
->w
.hPalette
, FALSE
);
854 DC_UnlockDC(hDCSave
);
857 // ---------------------------------------------------- Private Interface
859 PDC
DC_AllocDC(LPCWSTR Driver
)
863 NewDC
= (PDC
) GDIOBJ_AllocObject(sizeof(DC
), GO_DC_MAGIC
);
870 NewDC
->DriverName
= ExAllocatePool(NonPagedPool
,
871 (wcslen(Driver
) + 1) * sizeof(WCHAR
));
872 wcscpy(NewDC
->DriverName
, Driver
);
878 PDC
DC_FindOpenDC(LPCWSTR Driver
)
884 void DC_InitDC(PDC DCToInit
)
888 DCHandle
= DC_PtrToHandle(DCToInit
);
889 // W32kRealizeDefaultPalette(DCHandle);
890 W32kSetTextColor(DCHandle
, DCToInit
->w
.textColor
);
891 W32kSetBkColor(DCHandle
, DCToInit
->w
.backgroundColor
);
892 W32kSelectObject(DCHandle
, DCToInit
->w
.hPen
);
893 W32kSelectObject(DCHandle
, DCToInit
->w
.hBrush
);
894 W32kSelectObject(DCHandle
, DCToInit
->w
.hFont
);
895 // CLIPPING_UpdateGCRegion(DCToInit);
898 void DC_FreeDC(PDC DCToFree
)
900 ExFreePool(DCToFree
->DriverName
);
901 if (!GDIOBJ_FreeObject((PGDIOBJ
)DCToFree
, GO_DC_MAGIC
))
903 DbgPrint("DC_FreeDC failed\n");
908 DC_UpdateXforms(PDC dc
)
910 XFORM xformWnd2Vport
;
911 FLOAT scaleX
, scaleY
;
913 /* Construct a transformation to do the window-to-viewport conversion */
914 scaleX
= (FLOAT
)dc
->vportExtX
/ (FLOAT
)dc
->wndExtX
;
915 scaleY
= (FLOAT
)dc
->vportExtY
/ (FLOAT
)dc
->wndExtY
;
916 xformWnd2Vport
.eM11
= scaleX
;
917 xformWnd2Vport
.eM12
= 0.0;
918 xformWnd2Vport
.eM21
= 0.0;
919 xformWnd2Vport
.eM22
= scaleY
;
920 xformWnd2Vport
.eDx
= (FLOAT
)dc
->vportOrgX
-
921 scaleX
* (FLOAT
)dc
->wndOrgX
;
922 xformWnd2Vport
.eDy
= (FLOAT
)dc
->vportOrgY
-
923 scaleY
* (FLOAT
)dc
->wndOrgY
;
925 /* Combine with the world transformation */
926 W32kCombineTransform(&dc
->w
.xformWorld2Vport
,
927 &dc
->w
.xformWorld2Wnd
,
930 /* Create inverse of world-to-viewport transformation */
931 dc
->w
.vport2WorldValid
= DC_InvertXform(&dc
->w
.xformWorld2Vport
,
932 &dc
->w
.xformVport2World
);
936 DC_InvertXform(const XFORM
*xformSrc
,
941 determinant
= xformSrc
->eM11
*xformSrc
->eM22
-
942 xformSrc
->eM12
*xformSrc
->eM21
;
943 if (determinant
> -1e-12 && determinant
< 1e-12)
948 xformDest
->eM11
= xformSrc
->eM22
/ determinant
;
949 xformDest
->eM12
= -xformSrc
->eM12
/ determinant
;
950 xformDest
->eM21
= -xformSrc
->eM21
/ determinant
;
951 xformDest
->eM22
= xformSrc
->eM11
/ determinant
;
952 xformDest
->eDx
= -xformSrc
->eDx
* xformDest
->eM11
-
953 xformSrc
->eDy
* xformDest
->eM21
;
954 xformDest
->eDy
= -xformSrc
->eDx
* xformDest
->eM12
-
955 xformSrc
->eDy
* xformDest
->eM22
;