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 ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <internal/safe.h>
33 #include <win32k/coord.h>
34 #include <win32k/dc.h>
35 #include <include/error.h>
37 #include <win32k/debug1.h>
39 /* FUNCTIONS *****************************************************************/
41 BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
42 CONST LPXFORM Unsafexform1,
43 CONST LPXFORM Unsafexform2)
48 /* Check for illegal parameters */
49 if (!UnsafeXFormResult || !Unsafexform1 || !Unsafexform2)
54 MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) );
55 MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) );
57 /* Create the result in a temporary XFORM, since xformResult may be
58 * equal to xform1 or xform2 */
59 xformTemp.eM11 = xform1.eM11 * xform2.eM11 + xform1.eM12 * xform2.eM21;
60 xformTemp.eM12 = xform1.eM11 * xform2.eM12 + xform1.eM12 * xform2.eM22;
61 xformTemp.eM21 = xform1.eM21 * xform2.eM11 + xform1.eM22 * xform2.eM21;
62 xformTemp.eM22 = xform1.eM21 * xform2.eM12 + xform1.eM22 * xform2.eM22;
63 xformTemp.eDx = xform1.eDx * xform2.eM11 + xform1.eDy * xform2.eM21 + xform2.eDx;
64 xformTemp.eDy = xform1.eDx * xform2.eM12 + xform1.eDy * xform2.eM22 + xform2.eDy;
66 /* Copy the result to xformResult */
67 MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) );
73 CoordDPtoLP(PDC Dc, LPPOINT Point)
78 Point->x = x * Dc->w.xformVport2World.eM11 +
79 y * Dc->w.xformVport2World.eM21 + Dc->w.xformVport2World.eDx;
80 Point->y = x * Dc->w.xformVport2World.eM12 +
81 y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
85 * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
86 * world transfrom, viewport origin settings for the given device context.
87 * \param hDC device context.
88 * \param Points an array of POINT structures (in/out).
89 * \param Count number of elements in the array of POINT structures.
90 * \return TRUE if success.
99 LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT));
100 BOOL ret = FALSE; // default to failure
106 MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
108 dc = DC_LockDc (hDC);
112 if ( dc->w.vport2WorldValid )
114 for (i = 0; i < Count; i++)
116 CoordDPtoLP ( dc, &Points[i] );
122 MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) );
126 ExFreePool ( Points );
133 IntGetGraphicsMode ( PDC dc )
136 return dc->w.GraphicsMode;
141 NtGdiGetGraphicsMode ( HDC hDC )
143 PDC dc = DC_LockDc ( hDC );
144 int GraphicsMode = 0; // default to failure
148 GraphicsMode = dc->w.GraphicsMode;
157 NtGdiGetWorldTransform(HDC hDC,
165 dc = DC_LockDc (hDC);
169 *XForm = dc->w.xformWorld2Wnd;
178 CoordLPtoDP ( PDC Dc, LPPOINT Point )
187 Point->x = x * Dc->w.xformWorld2Vport.eM11 +
188 y * Dc->w.xformWorld2Vport.eM21 + Dc->w.xformWorld2Vport.eDx;
189 Point->y = x * Dc->w.xformWorld2Vport.eM12 +
190 y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy;
195 IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
201 for ( i = 0; i < Count; i++ )
202 CoordLPtoDP ( dc, &Points[i] );
206 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
207 * world transfrom, viewport origin settings for the given device context.
208 * \param hDC device context.
209 * \param Points an array of POINT structures (in/out).
210 * \param Count number of elements in the array of POINT structures.
211 * \return TRUE if success.
214 NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
217 LPPOINT Points = (LPPOINT)ExAllocatePool ( PagedPool, Count*sizeof(POINT) );
218 BOOL ret = FALSE; // default to failure
224 dc = DC_LockDc ( hDC );
230 MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
232 IntLPtoDP ( dc, Points, Count );
234 MmCopyToCaller ( UnsafePoints, Points, Count*sizeof(POINT) );
239 ExFreePool ( Points );
246 NtGdiModifyWorldTransform(HDC hDC,
247 CONST LPXFORM UnsafeXForm,
251 LPXFORM XForm = (LPXFORM) ExAllocatePool( PagedPool, sizeof( XFORM ) );
252 BOOL ret = FALSE; // default to failure
258 MmCopyFromCaller( XForm, UnsafeXForm, sizeof( XFORM ) );
260 dc = DC_LockDc (hDC);
263 /* Check that graphics mode is GM_ADVANCED */
264 if ( dc->w.GraphicsMode == GM_ADVANCED )
266 ret = TRUE; // switch to a default of success
270 dc->w.xformWorld2Wnd.eM11 = 1.0f;
271 dc->w.xformWorld2Wnd.eM12 = 0.0f;
272 dc->w.xformWorld2Wnd.eM21 = 0.0f;
273 dc->w.xformWorld2Wnd.eM22 = 1.0f;
274 dc->w.xformWorld2Wnd.eDx = 0.0f;
275 dc->w.xformWorld2Wnd.eDy = 0.0f;
278 case MWT_LEFTMULTIPLY:
279 NtGdiCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd );
282 case MWT_RIGHTMULTIPLY:
283 NtGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm);
291 DC_UpdateXforms ( dc );
295 ExFreePool ( XForm );
301 NtGdiOffsetViewportOrgEx(HDC hDC,
309 BOOL ret = FALSE; // default to failure
311 dc = DC_LockDc ( hDC );
315 if (NULL != UnsafePoint)
317 Point.x = dc->vportOrgX;
318 Point.y = dc->vportOrgY;
319 Status = MmCopyToCaller(UnsafePoint, &Point, sizeof(POINT));
320 if ( !NT_SUCCESS(Status) )
322 SetLastNtError(Status);
329 dc->vportOrgX += XOffset;
330 dc->vportOrgY += YOffset;
333 dc->w.DCOrgX += XOffset;
334 dc->w.DCOrgY += YOffset;
344 NtGdiOffsetWindowOrgEx(HDC hDC,
359 Point->x = dc->wndOrgX;
360 Point->y = dc->wndOrgY;
363 dc->wndOrgX += XOffset;
364 dc->wndOrgY += YOffset;
373 NtGdiScaleViewportExtEx(HDC hDC,
385 NtGdiScaleWindowExtEx(HDC hDC,
397 NtGdiSetGraphicsMode(HDC hDC,
403 dc = DC_LockDc (hDC);
409 /* One would think that setting the graphics mode to GM_COMPATIBLE
410 * would also reset the world transformation matrix to the unity
411 * matrix. However, in Windows, this is not the case. This doesn't
412 * make a lot of sense to me, but that's the way it is.
415 if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
421 ret = dc->w.GraphicsMode;
422 dc->w.GraphicsMode = Mode;
429 NtGdiSetMapMode(HDC hDC,
439 PrevMapMode = dc->w.MapMode;
440 dc->w.MapMode = MapMode;
449 NtGdiSetViewportExtEx(HDC hDC,
460 switch (dc->w.MapMode)
472 // Here we should (probably) check that SetWindowExtEx *really* has
479 Size->cx = dc->vportExtX;
480 Size->cy = dc->vportExtY;
483 dc->vportExtX = XExtent;
484 dc->vportExtY = YExtent;
493 NtGdiSetViewportOrgEx(HDC hDC,
508 Point->x = dc->vportOrgX;
509 Point->y = dc->vportOrgY;
522 NtGdiSetWindowExtEx(HDC hDC,
535 switch (dc->w.MapMode)
549 Size->cx = dc->wndExtX;
550 Size->cy = dc->wndExtY;
553 dc->wndExtX = XExtent;
554 dc->wndExtY = YExtent;
563 NtGdiSetWindowOrgEx(HDC hDC,
578 Point->x = dc->wndOrgX;
579 Point->y = dc->wndOrgY;
592 NtGdiSetWorldTransform(HDC hDC,
600 dc = DC_LockDc (hDC);
606 /* Check that graphics mode is GM_ADVANCED */
607 if ( dc->w.GraphicsMode != GM_ADVANCED )
612 dc->w.xformWorld2Wnd = *XForm;
613 DC_UpdateXforms (dc);