update for HEAD-2003050101
[reactos.git] / subsys / win32k / objects / coord.c
1 /* $Id$
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