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
)
70 Status
= MmCopyFromCaller( &xform1
, Unsafexform1
, sizeof(XFORM
) );
71 if(!NT_SUCCESS(Status
))
73 SetLastNtError(Status
);
76 Status
= MmCopyFromCaller( &xform2
, Unsafexform2
, sizeof(XFORM
) );
77 if(!NT_SUCCESS(Status
))
79 SetLastNtError(Status
);
83 Ret
= IntGdiCombineTransform(&xformTemp
, &xform1
, &xform2
);
85 /* Copy the result to xformResult */
86 Status
= MmCopyToCaller( UnsafeXFormResult
, &xformTemp
, sizeof(XFORM
) );
87 if(!NT_SUCCESS(Status
))
89 SetLastNtError(Status
);
97 CoordDPtoLP(PDC Dc
, LPPOINT Point
)
102 Point
->x
= x
* Dc
->w
.xformVport2World
.eM11
+
103 y
* Dc
->w
.xformVport2World
.eM21
+ Dc
->w
.xformVport2World
.eDx
;
104 Point
->y
= x
* Dc
->w
.xformVport2World
.eM12
+
105 y
* Dc
->w
.xformVport2World
.eM22
+ Dc
->w
.xformVport2World
.eDy
;
110 IntDPtoLP ( PDC dc
, LPPOINT Points
, INT Count
)
116 for ( i
= 0; i
< Count
; i
++ )
117 CoordDPtoLP ( dc
, &Points
[i
] );
121 * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
122 * world transfrom, viewport origin settings for the given device context.
123 * \param hDC device context.
124 * \param Points an array of POINT structures (in/out).
125 * \param Count number of elements in the array of POINT structures.
126 * \return TRUE if success.
130 LPPOINT UnsafePoints
,
141 SetLastWin32Error(ERROR_INVALID_HANDLE
);
145 if (!UnsafePoints
|| Count
<= 0)
148 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
152 Size
= Count
* sizeof(POINT
);
154 Points
= (LPPOINT
)ExAllocatePoolWithTag(PagedPool
, Size
, TAG_COORD
);
158 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
162 Status
= MmCopyFromCaller(Points
, UnsafePoints
, Size
);
163 if(!NT_SUCCESS(Status
))
167 SetLastNtError(Status
);
171 IntDPtoLP(dc
, Points
, Count
);
173 Status
= MmCopyToCaller(UnsafePoints
, Points
, Size
);
174 if(!NT_SUCCESS(Status
))
178 SetLastNtError(Status
);
189 IntGetGraphicsMode ( PDC dc
)
192 return dc
->w
.GraphicsMode
;
197 NtGdiGetGraphicsMode ( HDC hDC
)
200 int GraphicsMode
; // default to failure
202 dc
= DC_LockDc ( hDC
);
205 SetLastWin32Error(ERROR_INVALID_HANDLE
);
209 GraphicsMode
= dc
->w
.GraphicsMode
;
217 NtGdiGetWorldTransform(HDC hDC
,
223 dc
= DC_LockDc ( hDC
);
226 SetLastWin32Error(ERROR_INVALID_HANDLE
);
232 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
236 Status
= MmCopyToCaller(XForm
, &dc
->w
.xformWorld2Wnd
, sizeof(XFORM
));
239 return NT_SUCCESS(Status
);
244 CoordLPtoDP ( PDC Dc
, LPPOINT Point
)
253 Point
->x
= x
* Dc
->w
.xformWorld2Vport
.eM11
+
254 y
* Dc
->w
.xformWorld2Vport
.eM21
+ Dc
->w
.xformWorld2Vport
.eDx
;
255 Point
->y
= x
* Dc
->w
.xformWorld2Vport
.eM12
+
256 y
* Dc
->w
.xformWorld2Vport
.eM22
+ Dc
->w
.xformWorld2Vport
.eDy
;
261 IntLPtoDP ( PDC dc
, LPPOINT Points
, INT Count
)
267 for ( i
= 0; i
< Count
; i
++ )
268 CoordLPtoDP ( dc
, &Points
[i
] );
272 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
273 * world transfrom, viewport origin settings for the given device context.
274 * \param hDC device context.
275 * \param Points an array of POINT structures (in/out).
276 * \param Count number of elements in the array of POINT structures.
277 * \return TRUE if success.
280 NtGdiLPtoDP ( HDC hDC
, LPPOINT UnsafePoints
, INT Count
)
290 SetLastWin32Error(ERROR_INVALID_HANDLE
);
294 if (!UnsafePoints
|| Count
<= 0)
297 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
301 Size
= Count
* sizeof(POINT
);
303 Points
= (LPPOINT
)ExAllocatePoolWithTag(PagedPool
, Size
, TAG_COORD
);
307 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
311 Status
= MmCopyFromCaller(Points
, UnsafePoints
, Size
);
312 if(!NT_SUCCESS(Status
))
316 SetLastNtError(Status
);
320 IntLPtoDP(dc
, Points
, Count
);
322 Status
= MmCopyToCaller(UnsafePoints
, Points
, Size
);
323 if(!NT_SUCCESS(Status
))
327 SetLastNtError(Status
);
338 NtGdiModifyWorldTransform(HDC hDC
,
339 CONST LPXFORM UnsafeXForm
,
349 SetLastWin32Error(ERROR_INVALID_HANDLE
);
356 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
360 Status
= MmCopyFromCaller(&SafeXForm
, UnsafeXForm
, sizeof(XFORM
));
361 if(!NT_SUCCESS(Status
))
364 SetLastNtError(Status
);
371 dc
->w
.xformWorld2Wnd
.eM11
= 1.0f
;
372 dc
->w
.xformWorld2Wnd
.eM12
= 0.0f
;
373 dc
->w
.xformWorld2Wnd
.eM21
= 0.0f
;
374 dc
->w
.xformWorld2Wnd
.eM22
= 1.0f
;
375 dc
->w
.xformWorld2Wnd
.eDx
= 0.0f
;
376 dc
->w
.xformWorld2Wnd
.eDy
= 0.0f
;
379 case MWT_LEFTMULTIPLY
:
380 IntGdiCombineTransform(&dc
->w
.xformWorld2Wnd
, &SafeXForm
, &dc
->w
.xformWorld2Wnd
);
383 case MWT_RIGHTMULTIPLY
:
384 IntGdiCombineTransform(&dc
->w
.xformWorld2Wnd
, &dc
->w
.xformWorld2Wnd
, &SafeXForm
);
389 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
400 NtGdiOffsetViewportOrgEx(HDC hDC
,
409 dc
= DC_LockDc ( hDC
);
412 SetLastWin32Error(ERROR_INVALID_HANDLE
);
418 Point
.x
= dc
->vportOrgX
;
419 Point
.y
= dc
->vportOrgY
;
420 Status
= MmCopyToCaller(UnsafePoint
, &Point
, sizeof(POINT
));
421 if ( !NT_SUCCESS(Status
) )
423 SetLastNtError(Status
);
429 dc
->vportOrgX
+= XOffset
;
430 dc
->vportOrgY
+= YOffset
;
439 NtGdiOffsetWindowOrgEx(HDC hDC
,
449 SetLastWin32Error(ERROR_INVALID_HANDLE
);
458 SafePoint
.x
= dc
->wndOrgX
;
459 SafePoint
.y
= dc
->wndOrgY
;
461 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
462 if(!NT_SUCCESS(Status
))
464 SetLastNtError(Status
);
470 dc
->wndOrgX
+= XOffset
;
471 dc
->wndOrgY
+= YOffset
;
481 NtGdiScaleViewportExtEx(HDC hDC
,
494 NtGdiScaleWindowExtEx(HDC hDC
,
507 NtGdiSetGraphicsMode(HDC hDC
,
513 dc
= DC_LockDc (hDC
);
516 SetLastWin32Error(ERROR_INVALID_HANDLE
);
520 /* One would think that setting the graphics mode to GM_COMPATIBLE
521 * would also reset the world transformation matrix to the unity
522 * matrix. However, in Windows, this is not the case. This doesn't
523 * make a lot of sense to me, but that's the way it is.
526 if ((Mode
!= GM_COMPATIBLE
) && (Mode
!= GM_ADVANCED
))
529 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
533 ret
= dc
->w
.GraphicsMode
;
534 dc
->w
.GraphicsMode
= Mode
;
541 NtGdiSetMapMode(HDC hDC
,
550 SetLastWin32Error(ERROR_INVALID_HANDLE
);
554 PrevMapMode
= dc
->w
.MapMode
;
555 dc
->w
.MapMode
= MapMode
;
564 NtGdiSetViewportExtEx(HDC hDC
,
574 SetLastWin32Error(ERROR_INVALID_HANDLE
);
578 switch (dc
->w
.MapMode
)
590 // Here we should (probably) check that SetWindowExtEx *really* has
600 SafeSize
.cx
= dc
->vportExtX
;
601 SafeSize
.cy
= dc
->vportExtY
;
603 Status
= MmCopyToCaller(Size
, &SafeSize
, sizeof(SIZE
));
604 if(!NT_SUCCESS(Status
))
606 SetLastNtError(Status
);
612 dc
->vportExtX
= XExtent
;
613 dc
->vportExtY
= YExtent
;
623 NtGdiSetViewportOrgEx(HDC hDC
,
633 SetLastWin32Error(ERROR_INVALID_HANDLE
);
642 SafePoint
.x
= dc
->vportOrgX
;
643 SafePoint
.y
= dc
->vportOrgY
;
645 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
646 if(!NT_SUCCESS(Status
))
648 SetLastNtError(Status
);
665 NtGdiSetWindowExtEx(HDC hDC
,
675 SetLastWin32Error(ERROR_INVALID_HANDLE
);
679 switch (dc
->w
.MapMode
)
696 SafeSize
.cx
= dc
->wndExtX
;
697 SafeSize
.cy
= dc
->wndExtY
;
699 Status
= MmCopyToCaller(Size
, &SafeSize
, sizeof(SIZE
));
700 if(!NT_SUCCESS(Status
))
702 SetLastNtError(Status
);
708 dc
->wndExtX
= XExtent
;
709 dc
->wndExtY
= YExtent
;
719 NtGdiSetWindowOrgEx(HDC hDC
,
729 SetLastWin32Error(ERROR_INVALID_HANDLE
);
738 SafePoint
.x
= dc
->wndOrgX
;
739 SafePoint
.y
= dc
->wndOrgY
;
741 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
742 if(!NT_SUCCESS(Status
))
744 SetLastNtError(Status
);
761 NtGdiSetWorldTransform(HDC hDC
,
767 dc
= DC_LockDc (hDC
);
770 SetLastWin32Error(ERROR_INVALID_HANDLE
);
777 /* Win doesn't set LastError */
781 /* Check that graphics mode is GM_ADVANCED */
782 if ( dc
->w
.GraphicsMode
!= GM_ADVANCED
)
788 Status
= MmCopyFromCaller(&dc
->w
.xformWorld2Wnd
, XForm
, sizeof(XFORM
));
789 if(!NT_SUCCESS(Status
))