2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Coordinate systems
24 * FILE: subsys/win32k/objects/coord.c
28 /* INCLUDES ******************************************************************/
35 /* FUNCTIONS *****************************************************************/
38 IntGdiCombineTransform(LPXFORM XFormResult
,
42 /* Check for illegal parameters */
43 if (!XFormResult
|| !xform1
|| !xform2
)
48 /* Create the result in a temporary XFORM, since xformResult may be
49 * equal to xform1 or xform2 */
50 XFormResult
->eM11
= xform1
->eM11
* xform2
->eM11
+ xform1
->eM12
* xform2
->eM21
;
51 XFormResult
->eM12
= xform1
->eM11
* xform2
->eM12
+ xform1
->eM12
* xform2
->eM22
;
52 XFormResult
->eM21
= xform1
->eM21
* xform2
->eM11
+ xform1
->eM22
* xform2
->eM21
;
53 XFormResult
->eM22
= xform1
->eM21
* xform2
->eM12
+ xform1
->eM22
* xform2
->eM22
;
54 XFormResult
->eDx
= xform1
->eDx
* xform2
->eM11
+ xform1
->eDy
* xform2
->eM21
+ xform2
->eDx
;
55 XFormResult
->eDy
= xform1
->eDx
* xform2
->eM12
+ xform1
->eDy
* xform2
->eM22
+ xform2
->eDy
;
60 BOOL STDCALL
NtGdiCombineTransform(LPXFORM UnsafeXFormResult
,
61 CONST LPXFORM Unsafexform1
,
62 CONST LPXFORM Unsafexform2
)
65 XFORM xform1
= {0}, xform2
= {0};
66 NTSTATUS Status
= STATUS_SUCCESS
;
71 ProbeForWrite(UnsafeXFormResult
,
74 ProbeForRead(Unsafexform1
,
77 ProbeForRead(Unsafexform2
,
80 xform1
= *Unsafexform1
;
81 xform2
= *Unsafexform2
;
85 Status
= _SEH_GetExceptionCode();
89 if(!NT_SUCCESS(Status
))
91 SetLastNtError(Status
);
95 Ret
= IntGdiCombineTransform(&xformTemp
, &xform1
, &xform2
);
97 /* Copy the result to xformResult */
100 /* pointer was already probed! */
101 *UnsafeXFormResult
= xformTemp
;
105 Status
= _SEH_GetExceptionCode();
109 if(!NT_SUCCESS(Status
))
111 SetLastNtError(Status
);
119 CoordDPtoLP(PDC Dc
, LPPOINT Point
)
124 Point
->x
= x
* Dc
->w
.xformVport2World
.eM11
+
125 y
* Dc
->w
.xformVport2World
.eM21
+ Dc
->w
.xformVport2World
.eDx
;
126 Point
->y
= x
* Dc
->w
.xformVport2World
.eM12
+
127 y
* Dc
->w
.xformVport2World
.eM22
+ Dc
->w
.xformVport2World
.eDy
;
132 IntDPtoLP ( PDC dc
, LPPOINT Points
, INT Count
)
138 for ( i
= 0; i
< Count
; i
++ )
139 CoordDPtoLP ( dc
, &Points
[i
] );
143 * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
144 * world transfrom, viewport origin settings for the given device context.
145 * \param hDC device context.
146 * \param Points an array of POINT structures (in/out).
147 * \param Count number of elements in the array of POINT structures.
148 * \return TRUE if success.
152 LPPOINT UnsafePoints
,
156 NTSTATUS Status
= STATUS_SUCCESS
;
163 SetLastWin32Error(ERROR_INVALID_HANDLE
);
167 if (!UnsafePoints
|| Count
<= 0)
170 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
174 Size
= Count
* sizeof(POINT
);
176 Points
= (LPPOINT
)ExAllocatePoolWithTag(PagedPool
, Size
, TAG_COORD
);
180 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
186 ProbeForWrite(UnsafePoints
,
189 RtlCopyMemory(Points
,
195 Status
= _SEH_GetExceptionCode();
199 if(!NT_SUCCESS(Status
))
203 SetLastNtError(Status
);
207 IntDPtoLP(dc
, Points
, Count
);
211 /* pointer was already probed! */
212 RtlCopyMemory(UnsafePoints
,
218 Status
= _SEH_GetExceptionCode();
222 if(!NT_SUCCESS(Status
))
226 SetLastNtError(Status
);
237 IntGetGraphicsMode ( PDC dc
)
240 return dc
->w
.GraphicsMode
;
245 NtGdiGetGraphicsMode ( HDC hDC
)
248 int GraphicsMode
; // default to failure
250 dc
= DC_LockDc ( hDC
);
253 SetLastWin32Error(ERROR_INVALID_HANDLE
);
257 GraphicsMode
= dc
->w
.GraphicsMode
;
265 NtGdiGetWorldTransform(HDC hDC
,
269 NTSTATUS Status
= STATUS_SUCCESS
;
271 dc
= DC_LockDc ( hDC
);
274 SetLastWin32Error(ERROR_INVALID_HANDLE
);
280 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
289 *XForm
= dc
->w
.xformWorld2Wnd
;
293 Status
= _SEH_GetExceptionCode();
298 return NT_SUCCESS(Status
);
303 CoordLPtoDP ( PDC Dc
, LPPOINT Point
)
312 Point
->x
= x
* Dc
->w
.xformWorld2Vport
.eM11
+
313 y
* Dc
->w
.xformWorld2Vport
.eM21
+ Dc
->w
.xformWorld2Vport
.eDx
;
314 Point
->y
= x
* Dc
->w
.xformWorld2Vport
.eM12
+
315 y
* Dc
->w
.xformWorld2Vport
.eM22
+ Dc
->w
.xformWorld2Vport
.eDy
;
320 IntLPtoDP ( PDC dc
, LPPOINT Points
, INT Count
)
326 for ( i
= 0; i
< Count
; i
++ )
327 CoordLPtoDP ( dc
, &Points
[i
] );
331 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
332 * world transfrom, viewport origin settings for the given device context.
333 * \param hDC device context.
334 * \param Points an array of POINT structures (in/out).
335 * \param Count number of elements in the array of POINT structures.
336 * \return TRUE if success.
339 NtGdiLPtoDP ( HDC hDC
, LPPOINT UnsafePoints
, INT Count
)
342 NTSTATUS Status
= STATUS_SUCCESS
;
349 SetLastWin32Error(ERROR_INVALID_HANDLE
);
353 if (!UnsafePoints
|| Count
<= 0)
356 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
360 Size
= Count
* sizeof(POINT
);
362 Points
= (LPPOINT
)ExAllocatePoolWithTag(PagedPool
, Size
, TAG_COORD
);
366 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
372 ProbeForWrite(UnsafePoints
,
375 RtlCopyMemory(Points
,
381 Status
= _SEH_GetExceptionCode();
385 if(!NT_SUCCESS(Status
))
389 SetLastNtError(Status
);
393 IntLPtoDP(dc
, Points
, Count
);
397 /* pointer was already probed! */
398 RtlCopyMemory(UnsafePoints
,
404 Status
= _SEH_GetExceptionCode();
408 if(!NT_SUCCESS(Status
))
412 SetLastNtError(Status
);
423 NtGdiModifyWorldTransform(HDC hDC
,
424 CONST LPXFORM UnsafeXForm
,
428 XFORM SafeXForm
= {0};
429 NTSTATUS Status
= STATUS_SUCCESS
;
434 SetLastWin32Error(ERROR_INVALID_HANDLE
);
441 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
447 ProbeForRead(UnsafeXForm
,
450 SafeXForm
= *UnsafeXForm
;
454 Status
= _SEH_GetExceptionCode();
458 if(!NT_SUCCESS(Status
))
461 SetLastNtError(Status
);
468 dc
->w
.xformWorld2Wnd
.eM11
= 1.0f
;
469 dc
->w
.xformWorld2Wnd
.eM12
= 0.0f
;
470 dc
->w
.xformWorld2Wnd
.eM21
= 0.0f
;
471 dc
->w
.xformWorld2Wnd
.eM22
= 1.0f
;
472 dc
->w
.xformWorld2Wnd
.eDx
= 0.0f
;
473 dc
->w
.xformWorld2Wnd
.eDy
= 0.0f
;
476 case MWT_LEFTMULTIPLY
:
477 IntGdiCombineTransform(&dc
->w
.xformWorld2Wnd
, &SafeXForm
, &dc
->w
.xformWorld2Wnd
);
480 case MWT_RIGHTMULTIPLY
:
481 IntGdiCombineTransform(&dc
->w
.xformWorld2Wnd
, &dc
->w
.xformWorld2Wnd
, &SafeXForm
);
486 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
497 NtGdiOffsetViewportOrgEx(HDC hDC
,
503 NTSTATUS Status
= STATUS_SUCCESS
;
505 dc
= DC_LockDc ( hDC
);
508 SetLastWin32Error(ERROR_INVALID_HANDLE
);
516 ProbeForWrite(UnsafePoint
,
519 UnsafePoint
->x
= dc
->vportOrgX
;
520 UnsafePoint
->y
= dc
->vportOrgY
;
524 Status
= _SEH_GetExceptionCode();
528 if ( !NT_SUCCESS(Status
) )
530 SetLastNtError(Status
);
536 dc
->vportOrgX
+= XOffset
;
537 dc
->vportOrgY
+= YOffset
;
546 NtGdiOffsetWindowOrgEx(HDC hDC
,
556 SetLastWin32Error(ERROR_INVALID_HANDLE
);
562 NTSTATUS Status
= STATUS_SUCCESS
;
569 Point
->x
= dc
->wndOrgX
;
570 Point
->y
= dc
->wndOrgY
;
574 Status
= _SEH_GetExceptionCode();
578 if(!NT_SUCCESS(Status
))
580 SetLastNtError(Status
);
586 dc
->wndOrgX
+= XOffset
;
587 dc
->wndOrgY
+= YOffset
;
597 NtGdiScaleViewportExtEx(HDC hDC
,
610 NtGdiScaleWindowExtEx(HDC hDC
,
623 NtGdiSetGraphicsMode(HDC hDC
,
629 dc
= DC_LockDc (hDC
);
632 SetLastWin32Error(ERROR_INVALID_HANDLE
);
636 /* One would think that setting the graphics mode to GM_COMPATIBLE
637 * would also reset the world transformation matrix to the unity
638 * matrix. However, in Windows, this is not the case. This doesn't
639 * make a lot of sense to me, but that's the way it is.
642 if ((Mode
!= GM_COMPATIBLE
) && (Mode
!= GM_ADVANCED
))
645 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
649 ret
= dc
->w
.GraphicsMode
;
650 dc
->w
.GraphicsMode
= Mode
;
657 NtGdiSetMapMode(HDC hDC
,
666 SetLastWin32Error(ERROR_INVALID_HANDLE
);
670 PrevMapMode
= dc
->w
.MapMode
;
671 dc
->w
.MapMode
= MapMode
;
680 NtGdiSetViewportExtEx(HDC hDC
,
690 SetLastWin32Error(ERROR_INVALID_HANDLE
);
694 switch (dc
->w
.MapMode
)
706 // Here we should (probably) check that SetWindowExtEx *really* has
713 NTSTATUS Status
= STATUS_SUCCESS
;
720 Size
->cx
= dc
->vportExtX
;
721 Size
->cy
= dc
->vportExtY
;
725 Status
= _SEH_GetExceptionCode();
729 if(!NT_SUCCESS(Status
))
731 SetLastNtError(Status
);
737 dc
->vportExtX
= XExtent
;
738 dc
->vportExtY
= YExtent
;
748 NtGdiSetViewportOrgEx(HDC hDC
,
758 SetLastWin32Error(ERROR_INVALID_HANDLE
);
764 NTSTATUS Status
= STATUS_SUCCESS
;
771 Point
->x
= dc
->vportOrgX
;
772 Point
->y
= dc
->vportOrgY
;
776 Status
= _SEH_GetExceptionCode();
780 if(!NT_SUCCESS(Status
))
782 SetLastNtError(Status
);
799 NtGdiSetWindowExtEx(HDC hDC
,
809 SetLastWin32Error(ERROR_INVALID_HANDLE
);
813 switch (dc
->w
.MapMode
)
827 NTSTATUS Status
= STATUS_SUCCESS
;
834 Size
->cx
= dc
->wndExtX
;
835 Size
->cy
= dc
->wndExtY
;
839 Status
= _SEH_GetExceptionCode();
843 if(!NT_SUCCESS(Status
))
845 SetLastNtError(Status
);
851 dc
->wndExtX
= XExtent
;
852 dc
->wndExtY
= YExtent
;
862 NtGdiSetWindowOrgEx(HDC hDC
,
872 SetLastWin32Error(ERROR_INVALID_HANDLE
);
878 NTSTATUS Status
= STATUS_SUCCESS
;
885 Point
->x
= dc
->wndOrgX
;
886 Point
->y
= dc
->wndOrgY
;
890 Status
= _SEH_GetExceptionCode();
894 if(!NT_SUCCESS(Status
))
896 SetLastNtError(Status
);
913 NtGdiSetWorldTransform(HDC hDC
,
917 NTSTATUS Status
= STATUS_SUCCESS
;
919 dc
= DC_LockDc (hDC
);
922 SetLastWin32Error(ERROR_INVALID_HANDLE
);
929 /* Win doesn't set LastError */
933 /* Check that graphics mode is GM_ADVANCED */
934 if ( dc
->w
.GraphicsMode
!= GM_ADVANCED
)
945 dc
->w
.xformWorld2Wnd
= *XForm
;
949 Status
= _SEH_GetExceptionCode();
953 if(!NT_SUCCESS(Status
))