7254b88ceec1467af9b44cb89a7e23f0ef9acbc9
[reactos.git] / reactos / subsys / win32k / objects / coord.c
1 /* $Id: coord.c,v 1.10 2003/03/18 08:34:37 gvg Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Coordinate systems
6 * FILE: subsys/win32k/objects/coord.c
7 * PROGRAMER: Unknown
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <windows.h>
13 #include <ddk/ntddk.h>
14 #include <internal/safe.h>
15 #include <win32k/coord.h>
16 #include <win32k/dc.h>
17 #define NDEBUG
18 #include <win32k/debug1.h>
19
20 /* FUNCTIONS *****************************************************************/
21
22 BOOL STDCALL W32kCombineTransform(LPXFORM UnsafeXFormResult,
23 CONST LPXFORM Unsafexform1,
24 CONST LPXFORM Unsafexform2)
25 {
26 XFORM xformTemp;
27 XFORM xform1, xform2;
28
29 /* Check for illegal parameters */
30 if (!UnsafeXFormResult || !Unsafexform1 || !Unsafexform2)
31 {
32 return FALSE;
33 }
34
35 MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) );
36 MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) );
37
38 /* Create the result in a temporary XFORM, since xformResult may be
39 * equal to xform1 or xform2 */
40 xformTemp.eM11 = xform1.eM11 * xform2.eM11 + xform1.eM12 * xform2.eM21;
41 xformTemp.eM12 = xform1.eM11 * xform2.eM12 + xform1.eM12 * xform2.eM22;
42 xformTemp.eM21 = xform1.eM21 * xform2.eM11 + xform1.eM22 * xform2.eM21;
43 xformTemp.eM22 = xform1.eM21 * xform2.eM12 + xform1.eM22 * xform2.eM22;
44 xformTemp.eDx = xform1.eDx * xform2.eM11 + xform1.eDy * xform2.eM21 + xform2.eDx;
45 xformTemp.eDy = xform1.eDx * xform2.eM12 + xform1.eDy * xform2.eM22 + xform2.eDy;
46
47 /* Copy the result to xformResult */
48 MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) );
49
50 return TRUE;
51 }
52
53 VOID STATIC
54 CoordDPtoLP(PDC Dc, LPPOINT Point)
55 {
56 FLOAT x, y;
57 x = (FLOAT)Point->x;
58 y = (FLOAT)Point->y;
59 Point->x = x * Dc->w.xformVport2World.eM11 +
60 y * Dc->w.xformVport2World.eM21 + Dc->w.xformVport2World.eDx;
61 Point->y = x * Dc->w.xformVport2World.eM12 +
62 y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
63 }
64
65 /*!
66 * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
67 * world transfrom, viewport origin settings for the given device context.
68 * \param hDC device context.
69 * \param Points an array of POINT structures (in/out).
70 * \param Count number of elements in the array of POINT structures.
71 * \return TRUE if success.
72 */
73 BOOL STDCALL
74 W32kDPtoLP(HDC hDC,
75 LPPOINT UnsafePoints,
76 int Count)
77 {
78 PDC Dc;
79 ULONG i;
80 LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT));
81
82 ASSERT(Points);
83 MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
84
85 Dc = DC_HandleToPtr (hDC);
86 if (Dc == NULL || !Dc->w.vport2WorldValid)
87 {
88 return(FALSE);
89 }
90
91 for (i = 0; i < Count; i++)
92 {
93 CoordDPtoLP(Dc, &Points[i]);
94 }
95 DC_ReleasePtr( hDC );
96
97 MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) );
98 return(TRUE);
99 }
100
101 int
102 STDCALL
103 W32kGetGraphicsMode(HDC hDC)
104 {
105 PDC dc;
106 int GraphicsMode;
107
108 dc = DC_HandleToPtr (hDC);
109 if (!dc)
110 {
111 return 0;
112 }
113
114 GraphicsMode = dc->w.GraphicsMode;
115 DC_ReleasePtr( hDC );
116 return GraphicsMode;
117 }
118
119 BOOL
120 STDCALL
121 W32kGetWorldTransform(HDC hDC,
122 LPXFORM XForm)
123 {
124 PDC dc;
125
126 dc = DC_HandleToPtr (hDC);
127 if (!dc)
128 {
129 return FALSE;
130 }
131 if (!XForm)
132 {
133 return FALSE;
134 }
135 *XForm = dc->w.xformWorld2Wnd;
136 DC_ReleasePtr( hDC );
137 return TRUE;
138 }
139
140 VOID STATIC
141 CoordLPtoDP(PDC Dc, LPPOINT Point)
142 {
143 FLOAT x, y;
144 x = (FLOAT)Point->x;
145 y = (FLOAT)Point->y;
146 Point->x = x * Dc->w.xformWorld2Vport.eM11 +
147 y * Dc->w.xformWorld2Vport.eM21 + Dc->w.xformWorld2Vport.eDx;
148 Point->y = x * Dc->w.xformWorld2Vport.eM12 +
149 y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy;
150 }
151
152 /*!
153 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
154 * world transfrom, viewport origin settings for the given device context.
155 * \param hDC device context.
156 * \param Points an array of POINT structures (in/out).
157 * \param Count number of elements in the array of POINT structures.
158 * \return TRUE if success.
159 */
160 BOOL STDCALL
161 W32kLPtoDP(HDC hDC, LPPOINT UnsafePoints, INT Count)
162 {
163 PDC Dc;
164 ULONG i;
165 LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT));
166
167 ASSERT(Points);
168 MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
169
170 Dc = DC_HandleToPtr (hDC);
171 if (Dc == NULL)
172 {
173 return(FALSE);
174 }
175
176 for (i = 0; i < Count; i++)
177 {
178 CoordLPtoDP(Dc, &Points[i]);
179 }
180 DC_ReleasePtr( hDC );
181 MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) );
182 return(TRUE);
183 }
184
185 BOOL
186 STDCALL
187 W32kModifyWorldTransform(HDC hDC,
188 CONST LPXFORM UnsafeXForm,
189 DWORD Mode)
190 {
191 PDC dc;
192 LPXFORM XForm = (LPXFORM) ExAllocatePool( PagedPool, sizeof( XFORM ) );
193
194 ASSERT( XForm );
195
196 MmCopyFromCaller( XForm, UnsafeXForm, sizeof( XFORM ) );
197
198 dc = DC_HandleToPtr (hDC);
199 if (!dc)
200 {
201 // SetLastError( ERROR_INVALID_HANDLE );
202 return FALSE;
203 }
204 if (!XForm)
205 {
206 return FALSE;
207 }
208
209 /* Check that graphics mode is GM_ADVANCED */
210 if (dc->w.GraphicsMode!=GM_ADVANCED)
211 {
212 return FALSE;
213 }
214 switch (Mode)
215 {
216 case MWT_IDENTITY:
217 dc->w.xformWorld2Wnd.eM11 = 1.0f;
218 dc->w.xformWorld2Wnd.eM12 = 0.0f;
219 dc->w.xformWorld2Wnd.eM21 = 0.0f;
220 dc->w.xformWorld2Wnd.eM22 = 1.0f;
221 dc->w.xformWorld2Wnd.eDx = 0.0f;
222 dc->w.xformWorld2Wnd.eDy = 0.0f;
223 break;
224
225 case MWT_LEFTMULTIPLY:
226 W32kCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd );
227 break;
228
229 case MWT_RIGHTMULTIPLY:
230 W32kCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm);
231 break;
232
233 default:
234 DC_ReleasePtr( hDC );
235 return FALSE;
236 }
237 DC_UpdateXforms (dc);
238 DC_ReleasePtr( hDC );
239 return TRUE;
240 }
241
242 BOOL
243 STDCALL
244 W32kOffsetViewportOrgEx(HDC hDC,
245 int XOffset,
246 int YOffset,
247 LPPOINT Point)
248 {
249 UNIMPLEMENTED;
250 }
251
252 BOOL
253 STDCALL
254 W32kOffsetWindowOrgEx(HDC hDC,
255 int XOffset,
256 int YOffset,
257 LPPOINT Point)
258 {
259 UNIMPLEMENTED;
260 }
261
262 BOOL
263 STDCALL
264 W32kScaleViewportExtEx(HDC hDC,
265 int Xnum,
266 int Xdenom,
267 int Ynum,
268 int Ydenom,
269 LPSIZE Size)
270 {
271 UNIMPLEMENTED;
272 }
273
274 BOOL
275 STDCALL
276 W32kScaleWindowExtEx(HDC hDC,
277 int Xnum,
278 int Xdenom,
279 int Ynum,
280 int Ydenom,
281 LPSIZE Size)
282 {
283 UNIMPLEMENTED;
284 }
285
286 int
287 STDCALL
288 W32kSetGraphicsMode(HDC hDC,
289 int Mode)
290 {
291 INT ret;
292 DC *dc;
293
294 dc = DC_HandleToPtr (hDC);
295 if (!dc)
296 {
297 return 0;
298 }
299
300 /* One would think that setting the graphics mode to GM_COMPATIBLE
301 * would also reset the world transformation matrix to the unity
302 * matrix. However, in Windows, this is not the case. This doesn't
303 * make a lot of sense to me, but that's the way it is.
304 */
305
306 if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
307 {
308 DC_ReleasePtr( hDC );
309 return 0;
310 }
311 ret = dc->w.GraphicsMode;
312 dc->w.GraphicsMode = Mode;
313 DC_ReleasePtr( hDC );
314 return ret;
315 }
316
317 int
318 STDCALL
319 W32kSetMapMode(HDC hDC,
320 int MapMode)
321 {
322 UNIMPLEMENTED;
323 }
324
325 BOOL
326 STDCALL
327 W32kSetViewportExtEx(HDC hDC,
328 int XExtent,
329 int YExtent,
330 LPSIZE Size)
331 {
332 UNIMPLEMENTED;
333 }
334
335 BOOL
336 STDCALL
337 W32kSetViewportOrgEx(HDC hDC,
338 int X,
339 int Y,
340 LPPOINT Point)
341 {
342 UNIMPLEMENTED;
343 }
344
345 BOOL
346 STDCALL
347 W32kSetWindowExtEx(HDC hDC,
348 int XExtent,
349 int YExtent,
350 LPSIZE Size)
351 {
352 UNIMPLEMENTED;
353 }
354
355 BOOL
356 STDCALL
357 W32kSetWindowOrgEx(HDC hDC,
358 int X,
359 int Y,
360 LPPOINT Point)
361 {
362 UNIMPLEMENTED;
363 }
364
365 BOOL
366 STDCALL
367 W32kSetWorldTransform(HDC hDC,
368 CONST LPXFORM XForm)
369 {
370 PDC dc;
371
372 dc = DC_HandleToPtr (hDC);
373 if (!dc)
374 {
375 return FALSE;
376 }
377 if (!XForm)
378 {
379 DC_ReleasePtr( hDC );
380 return FALSE;
381 }
382
383 /* Check that graphics mode is GM_ADVANCED */
384 if (dc->w.GraphicsMode != GM_ADVANCED)
385 {
386 DC_ReleasePtr( hDC );
387 return FALSE;
388 }
389 dc->w.xformWorld2Wnd = *XForm;
390 DC_UpdateXforms (dc);
391 DC_ReleasePtr( hDC );
392 return TRUE;
393 }
394
395