Moved win32k
[reactos.git] / reactos / subsystems / win32 / win32k / objects / coord.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Coordinate systems
24 * FILE: subsys/win32k/objects/coord.c
25 * PROGRAMER: Unknown
26 */
27
28 /* INCLUDES ******************************************************************/
29
30 #include <w32k.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 /* FUNCTIONS *****************************************************************/
36
37 BOOL FASTCALL
38 IntGdiCombineTransform(LPXFORM XFormResult,
39 LPXFORM xform1,
40 LPXFORM xform2)
41 {
42 /* Check for illegal parameters */
43 if (!XFormResult || !xform1 || !xform2)
44 {
45 return FALSE;
46 }
47
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;
56
57 return TRUE;
58 }
59
60 BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
61 CONST LPXFORM Unsafexform1,
62 CONST LPXFORM Unsafexform2)
63 {
64 XFORM xformTemp;
65 XFORM xform1 = {0}, xform2 = {0};
66 NTSTATUS Status = STATUS_SUCCESS;
67 BOOL Ret;
68
69 _SEH_TRY
70 {
71 ProbeForWrite(UnsafeXFormResult,
72 sizeof(XFORM),
73 1);
74 ProbeForRead(Unsafexform1,
75 sizeof(XFORM),
76 1);
77 ProbeForRead(Unsafexform2,
78 sizeof(XFORM),
79 1);
80 xform1 = *Unsafexform1;
81 xform2 = *Unsafexform2;
82 }
83 _SEH_HANDLE
84 {
85 Status = _SEH_GetExceptionCode();
86 }
87 _SEH_END;
88
89 if(!NT_SUCCESS(Status))
90 {
91 SetLastNtError(Status);
92 return FALSE;
93 }
94
95 Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2);
96
97 /* Copy the result to xformResult */
98 _SEH_TRY
99 {
100 /* pointer was already probed! */
101 *UnsafeXFormResult = xformTemp;
102 }
103 _SEH_HANDLE
104 {
105 Status = _SEH_GetExceptionCode();
106 }
107 _SEH_END;
108
109 if(!NT_SUCCESS(Status))
110 {
111 SetLastNtError(Status);
112 return FALSE;
113 }
114
115 return Ret;
116 }
117
118 VOID FASTCALL
119 CoordDPtoLP(PDC Dc, LPPOINT Point)
120 {
121 FLOAT x, y;
122 x = (FLOAT)Point->x;
123 y = (FLOAT)Point->y;
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;
128 }
129
130 VOID
131 FASTCALL
132 IntDPtoLP ( PDC dc, LPPOINT Points, INT Count )
133 {
134 INT i;
135
136 ASSERT ( Points );
137
138 for ( i = 0; i < Count; i++ )
139 CoordDPtoLP ( dc, &Points[i] );
140 }
141
142 /*!
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.
149 */
150 BOOL STDCALL
151 NtGdiDPtoLP(HDC hDC,
152 LPPOINT UnsafePoints,
153 int Count)
154 {
155 PDC dc;
156 NTSTATUS Status = STATUS_SUCCESS;
157 LPPOINT Points;
158 ULONG Size;
159
160 dc = DC_LockDc(hDC);
161 if (!dc)
162 {
163 SetLastWin32Error(ERROR_INVALID_HANDLE);
164 return FALSE;
165 }
166
167 if (!UnsafePoints || Count <= 0)
168 {
169 DC_UnlockDc(dc);
170 SetLastWin32Error(ERROR_INVALID_PARAMETER);
171 return FALSE;
172 }
173
174 Size = Count * sizeof(POINT);
175
176 Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
177 if(!Points)
178 {
179 DC_UnlockDc(dc);
180 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
181 return FALSE;
182 }
183
184 _SEH_TRY
185 {
186 ProbeForWrite(UnsafePoints,
187 Size,
188 1);
189 RtlCopyMemory(Points,
190 UnsafePoints,
191 Size);
192 }
193 _SEH_HANDLE
194 {
195 Status = _SEH_GetExceptionCode();
196 }
197 _SEH_END;
198
199 if(!NT_SUCCESS(Status))
200 {
201 DC_UnlockDc(dc);
202 ExFreePool(Points);
203 SetLastNtError(Status);
204 return FALSE;
205 }
206
207 IntDPtoLP(dc, Points, Count);
208
209 _SEH_TRY
210 {
211 /* pointer was already probed! */
212 RtlCopyMemory(UnsafePoints,
213 Points,
214 Size);
215 }
216 _SEH_HANDLE
217 {
218 Status = _SEH_GetExceptionCode();
219 }
220 _SEH_END;
221
222 if(!NT_SUCCESS(Status))
223 {
224 DC_UnlockDc(dc);
225 ExFreePool(Points);
226 SetLastNtError(Status);
227 return FALSE;
228 }
229
230 DC_UnlockDc(dc);
231 ExFreePool(Points);
232 return TRUE;
233 }
234
235 int
236 FASTCALL
237 IntGetGraphicsMode ( PDC dc )
238 {
239 ASSERT ( dc );
240 return dc->w.GraphicsMode;
241 }
242
243 int
244 STDCALL
245 NtGdiGetGraphicsMode ( HDC hDC )
246 {
247 PDC dc;
248 int GraphicsMode; // default to failure
249
250 dc = DC_LockDc ( hDC );
251 if (!dc)
252 {
253 SetLastWin32Error(ERROR_INVALID_HANDLE);
254 return 0;
255 }
256
257 GraphicsMode = dc->w.GraphicsMode;
258
259 DC_UnlockDc(dc);
260 return GraphicsMode;
261 }
262
263 BOOL
264 STDCALL
265 NtGdiGetWorldTransform(HDC hDC,
266 LPXFORM XForm)
267 {
268 PDC dc;
269 NTSTATUS Status = STATUS_SUCCESS;
270
271 dc = DC_LockDc ( hDC );
272 if (!dc)
273 {
274 SetLastWin32Error(ERROR_INVALID_HANDLE);
275 return FALSE;
276 }
277 if (!XForm)
278 {
279 DC_UnlockDc(dc);
280 SetLastWin32Error(ERROR_INVALID_PARAMETER);
281 return FALSE;
282 }
283
284 _SEH_TRY
285 {
286 ProbeForWrite(XForm,
287 sizeof(XFORM),
288 1);
289 *XForm = dc->w.xformWorld2Wnd;
290 }
291 _SEH_HANDLE
292 {
293 Status = _SEH_GetExceptionCode();
294 }
295 _SEH_END;
296
297 DC_UnlockDc(dc);
298 return NT_SUCCESS(Status);
299 }
300
301 VOID
302 FASTCALL
303 CoordLPtoDP ( PDC Dc, LPPOINT Point )
304 {
305 FLOAT x, y;
306
307 ASSERT ( Dc );
308 ASSERT ( Point );
309
310 x = (FLOAT)Point->x;
311 y = (FLOAT)Point->y;
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;
316 }
317
318 VOID
319 FASTCALL
320 IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
321 {
322 INT i;
323
324 ASSERT ( Points );
325
326 for ( i = 0; i < Count; i++ )
327 CoordLPtoDP ( dc, &Points[i] );
328 }
329
330 /*!
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.
337 */
338 BOOL STDCALL
339 NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
340 {
341 PDC dc;
342 NTSTATUS Status = STATUS_SUCCESS;
343 LPPOINT Points;
344 ULONG Size;
345
346 dc = DC_LockDc(hDC);
347 if (!dc)
348 {
349 SetLastWin32Error(ERROR_INVALID_HANDLE);
350 return FALSE;
351 }
352
353 if (!UnsafePoints || Count <= 0)
354 {
355 DC_UnlockDc(dc);
356 SetLastWin32Error(ERROR_INVALID_PARAMETER);
357 return FALSE;
358 }
359
360 Size = Count * sizeof(POINT);
361
362 Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
363 if(!Points)
364 {
365 DC_UnlockDc(dc);
366 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
367 return FALSE;
368 }
369
370 _SEH_TRY
371 {
372 ProbeForWrite(UnsafePoints,
373 Size,
374 1);
375 RtlCopyMemory(Points,
376 UnsafePoints,
377 Size);
378 }
379 _SEH_HANDLE
380 {
381 Status = _SEH_GetExceptionCode();
382 }
383 _SEH_END;
384
385 if(!NT_SUCCESS(Status))
386 {
387 DC_UnlockDc(dc);
388 ExFreePool(Points);
389 SetLastNtError(Status);
390 return FALSE;
391 }
392
393 IntLPtoDP(dc, Points, Count);
394
395 _SEH_TRY
396 {
397 /* pointer was already probed! */
398 RtlCopyMemory(UnsafePoints,
399 Points,
400 Size);
401 }
402 _SEH_HANDLE
403 {
404 Status = _SEH_GetExceptionCode();
405 }
406 _SEH_END;
407
408 if(!NT_SUCCESS(Status))
409 {
410 DC_UnlockDc(dc);
411 ExFreePool(Points);
412 SetLastNtError(Status);
413 return FALSE;
414 }
415
416 DC_UnlockDc(dc);
417 ExFreePool(Points);
418 return TRUE;
419 }
420
421 BOOL
422 STDCALL
423 NtGdiModifyWorldTransform(HDC hDC,
424 CONST LPXFORM UnsafeXForm,
425 DWORD Mode)
426 {
427 PDC dc;
428 XFORM SafeXForm = {0};
429 NTSTATUS Status = STATUS_SUCCESS;
430
431 dc = DC_LockDc(hDC);
432 if (!dc)
433 {
434 SetLastWin32Error(ERROR_INVALID_HANDLE);
435 return FALSE;
436 }
437
438 if (!UnsafeXForm)
439 {
440 DC_UnlockDc(dc);
441 SetLastWin32Error(ERROR_INVALID_PARAMETER);
442 return FALSE;
443 }
444
445 _SEH_TRY
446 {
447 ProbeForRead(UnsafeXForm,
448 sizeof(XFORM),
449 1);
450 SafeXForm = *UnsafeXForm;
451 }
452 _SEH_HANDLE
453 {
454 Status = _SEH_GetExceptionCode();
455 }
456 _SEH_END;
457
458 if(!NT_SUCCESS(Status))
459 {
460 DC_UnlockDc(dc);
461 SetLastNtError(Status);
462 return FALSE;
463 }
464
465 switch(Mode)
466 {
467 case MWT_IDENTITY:
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;
474 break;
475
476 case MWT_LEFTMULTIPLY:
477 IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &SafeXForm, &dc->w.xformWorld2Wnd );
478 break;
479
480 case MWT_RIGHTMULTIPLY:
481 IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, &SafeXForm);
482 break;
483
484 default:
485 DC_UnlockDc(dc);
486 SetLastWin32Error(ERROR_INVALID_PARAMETER);
487 return FALSE;
488 }
489
490 DC_UpdateXforms(dc);
491 DC_UnlockDc(dc);
492 return TRUE;
493 }
494
495 BOOL
496 STDCALL
497 NtGdiOffsetViewportOrgEx(HDC hDC,
498 int XOffset,
499 int YOffset,
500 LPPOINT UnsafePoint)
501 {
502 PDC dc;
503 NTSTATUS Status = STATUS_SUCCESS;
504
505 dc = DC_LockDc ( hDC );
506 if(!dc)
507 {
508 SetLastWin32Error(ERROR_INVALID_HANDLE);
509 return FALSE;
510 }
511
512 if (UnsafePoint)
513 {
514 _SEH_TRY
515 {
516 ProbeForWrite(UnsafePoint,
517 sizeof(POINT),
518 1);
519 UnsafePoint->x = dc->vportOrgX;
520 UnsafePoint->y = dc->vportOrgY;
521 }
522 _SEH_HANDLE
523 {
524 Status = _SEH_GetExceptionCode();
525 }
526 _SEH_END;
527
528 if ( !NT_SUCCESS(Status) )
529 {
530 SetLastNtError(Status);
531 DC_UnlockDc(dc);
532 return FALSE;
533 }
534 }
535
536 dc->vportOrgX += XOffset;
537 dc->vportOrgY += YOffset;
538 DC_UpdateXforms(dc);
539
540 DC_UnlockDc(dc);
541 return TRUE;
542 }
543
544 BOOL
545 STDCALL
546 NtGdiOffsetWindowOrgEx(HDC hDC,
547 int XOffset,
548 int YOffset,
549 LPPOINT Point)
550 {
551 PDC dc;
552
553 dc = DC_LockDc(hDC);
554 if (!dc)
555 {
556 SetLastWin32Error(ERROR_INVALID_HANDLE);
557 return FALSE;
558 }
559
560 if (Point)
561 {
562 NTSTATUS Status = STATUS_SUCCESS;
563
564 _SEH_TRY
565 {
566 ProbeForWrite(Point,
567 sizeof(POINT),
568 1);
569 Point->x = dc->wndOrgX;
570 Point->y = dc->wndOrgY;
571 }
572 _SEH_HANDLE
573 {
574 Status = _SEH_GetExceptionCode();
575 }
576 _SEH_END;
577
578 if(!NT_SUCCESS(Status))
579 {
580 SetLastNtError(Status);
581 DC_UnlockDc(dc);
582 return FALSE;
583 }
584 }
585
586 dc->wndOrgX += XOffset;
587 dc->wndOrgY += YOffset;
588
589 DC_UpdateXforms(dc);
590 DC_UnlockDc(dc);
591
592 return TRUE;
593 }
594
595 BOOL
596 STDCALL
597 NtGdiScaleViewportExtEx(HDC hDC,
598 int Xnum,
599 int Xdenom,
600 int Ynum,
601 int Ydenom,
602 LPSIZE Size)
603 {
604 UNIMPLEMENTED;
605 return FALSE;
606 }
607
608 BOOL
609 STDCALL
610 NtGdiScaleWindowExtEx(HDC hDC,
611 int Xnum,
612 int Xdenom,
613 int Ynum,
614 int Ydenom,
615 LPSIZE Size)
616 {
617 UNIMPLEMENTED;
618 return FALSE;
619 }
620
621 int
622 STDCALL
623 NtGdiSetGraphicsMode(HDC hDC,
624 int Mode)
625 {
626 INT ret;
627 PDC dc;
628
629 dc = DC_LockDc (hDC);
630 if (!dc)
631 {
632 SetLastWin32Error(ERROR_INVALID_HANDLE);
633 return 0;
634 }
635
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.
640 */
641
642 if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
643 {
644 DC_UnlockDc(dc);
645 SetLastWin32Error(ERROR_INVALID_PARAMETER);
646 return 0;
647 }
648
649 ret = dc->w.GraphicsMode;
650 dc->w.GraphicsMode = Mode;
651 DC_UnlockDc(dc);
652 return ret;
653 }
654
655 int
656 STDCALL
657 NtGdiSetMapMode(HDC hDC,
658 int MapMode)
659 {
660 int PrevMapMode;
661 PDC dc;
662
663 dc = DC_LockDc(hDC);
664 if (!dc)
665 {
666 SetLastWin32Error(ERROR_INVALID_HANDLE);
667 return 0;
668 }
669
670 PrevMapMode = dc->w.MapMode;
671 dc->w.MapMode = MapMode;
672
673 DC_UnlockDc(dc);
674
675 return PrevMapMode;
676 }
677
678 BOOL
679 STDCALL
680 NtGdiSetViewportExtEx(HDC hDC,
681 int XExtent,
682 int YExtent,
683 LPSIZE Size)
684 {
685 PDC dc;
686
687 dc = DC_LockDc(hDC);
688 if ( !dc )
689 {
690 SetLastWin32Error(ERROR_INVALID_HANDLE);
691 return FALSE;
692 }
693
694 switch (dc->w.MapMode)
695 {
696 case MM_HIENGLISH:
697 case MM_HIMETRIC:
698 case MM_LOENGLISH:
699 case MM_LOMETRIC:
700 case MM_TEXT:
701 case MM_TWIPS:
702 DC_UnlockDc(dc);
703 return FALSE;
704
705 case MM_ISOTROPIC:
706 // Here we should (probably) check that SetWindowExtEx *really* has
707 // been called
708 break;
709 }
710
711 if (Size)
712 {
713 NTSTATUS Status = STATUS_SUCCESS;
714
715 _SEH_TRY
716 {
717 ProbeForWrite(Size,
718 sizeof(SIZE),
719 1);
720 Size->cx = dc->vportExtX;
721 Size->cy = dc->vportExtY;
722 }
723 _SEH_HANDLE
724 {
725 Status = _SEH_GetExceptionCode();
726 }
727 _SEH_END;
728
729 if(!NT_SUCCESS(Status))
730 {
731 SetLastNtError(Status);
732 DC_UnlockDc(dc);
733 return FALSE;
734 }
735 }
736
737 dc->vportExtX = XExtent;
738 dc->vportExtY = YExtent;
739
740 DC_UpdateXforms(dc);
741 DC_UnlockDc(dc);
742
743 return TRUE;
744 }
745
746 BOOL
747 STDCALL
748 NtGdiSetViewportOrgEx(HDC hDC,
749 int X,
750 int Y,
751 LPPOINT Point)
752 {
753 PDC dc;
754
755 dc = DC_LockDc(hDC);
756 if (!dc)
757 {
758 SetLastWin32Error(ERROR_INVALID_HANDLE);
759 return FALSE;
760 }
761
762 if (Point)
763 {
764 NTSTATUS Status = STATUS_SUCCESS;
765
766 _SEH_TRY
767 {
768 ProbeForWrite(Point,
769 sizeof(POINT),
770 1);
771 Point->x = dc->vportOrgX;
772 Point->y = dc->vportOrgY;
773 }
774 _SEH_HANDLE
775 {
776 Status = _SEH_GetExceptionCode();
777 }
778 _SEH_END;
779
780 if(!NT_SUCCESS(Status))
781 {
782 SetLastNtError(Status);
783 DC_UnlockDc(dc);
784 return FALSE;
785 }
786 }
787
788 dc->vportOrgX = X;
789 dc->vportOrgY = Y;
790
791 DC_UpdateXforms(dc);
792 DC_UnlockDc(dc);
793
794 return TRUE;
795 }
796
797 BOOL
798 STDCALL
799 NtGdiSetWindowExtEx(HDC hDC,
800 int XExtent,
801 int YExtent,
802 LPSIZE Size)
803 {
804 PDC dc;
805
806 dc = DC_LockDc(hDC);
807 if (!dc)
808 {
809 SetLastWin32Error(ERROR_INVALID_HANDLE);
810 return FALSE;
811 }
812
813 switch (dc->w.MapMode)
814 {
815 case MM_HIENGLISH:
816 case MM_HIMETRIC:
817 case MM_LOENGLISH:
818 case MM_LOMETRIC:
819 case MM_TEXT:
820 case MM_TWIPS:
821 DC_UnlockDc(dc);
822 return FALSE;
823 }
824
825 if (Size)
826 {
827 NTSTATUS Status = STATUS_SUCCESS;
828
829 _SEH_TRY
830 {
831 ProbeForWrite(Size,
832 sizeof(SIZE),
833 1);
834 Size->cx = dc->wndExtX;
835 Size->cy = dc->wndExtY;
836 }
837 _SEH_HANDLE
838 {
839 Status = _SEH_GetExceptionCode();
840 }
841 _SEH_END;
842
843 if(!NT_SUCCESS(Status))
844 {
845 SetLastNtError(Status);
846 DC_UnlockDc(dc);
847 return FALSE;
848 }
849 }
850
851 dc->wndExtX = XExtent;
852 dc->wndExtY = YExtent;
853
854 DC_UpdateXforms(dc);
855 DC_UnlockDc(dc);
856
857 return TRUE;
858 }
859
860 BOOL
861 STDCALL
862 NtGdiSetWindowOrgEx(HDC hDC,
863 int X,
864 int Y,
865 LPPOINT Point)
866 {
867 PDC dc;
868
869 dc = DC_LockDc(hDC);
870 if (!dc)
871 {
872 SetLastWin32Error(ERROR_INVALID_HANDLE);
873 return FALSE;
874 }
875
876 if (Point)
877 {
878 NTSTATUS Status = STATUS_SUCCESS;
879
880 _SEH_TRY
881 {
882 ProbeForWrite(Point,
883 sizeof(POINT),
884 1);
885 Point->x = dc->wndOrgX;
886 Point->y = dc->wndOrgY;
887 }
888 _SEH_HANDLE
889 {
890 Status = _SEH_GetExceptionCode();
891 }
892 _SEH_END;
893
894 if(!NT_SUCCESS(Status))
895 {
896 SetLastNtError(Status);
897 DC_UnlockDc(dc);
898 return FALSE;
899 }
900 }
901
902 dc->wndOrgX = X;
903 dc->wndOrgY = Y;
904
905 DC_UpdateXforms(dc);
906 DC_UnlockDc(dc);
907
908 return TRUE;
909 }
910
911 BOOL
912 STDCALL
913 NtGdiSetWorldTransform(HDC hDC,
914 CONST LPXFORM XForm)
915 {
916 PDC dc;
917 NTSTATUS Status = STATUS_SUCCESS;
918
919 dc = DC_LockDc (hDC);
920 if ( !dc )
921 {
922 SetLastWin32Error(ERROR_INVALID_HANDLE);
923 return FALSE;
924 }
925
926 if (!XForm)
927 {
928 DC_UnlockDc(dc);
929 /* Win doesn't set LastError */
930 return FALSE;
931 }
932
933 /* Check that graphics mode is GM_ADVANCED */
934 if ( dc->w.GraphicsMode != GM_ADVANCED )
935 {
936 DC_UnlockDc(dc);
937 return FALSE;
938 }
939
940 _SEH_TRY
941 {
942 ProbeForRead(XForm,
943 sizeof(XFORM),
944 1);
945 dc->w.xformWorld2Wnd = *XForm;
946 }
947 _SEH_HANDLE
948 {
949 Status = _SEH_GetExceptionCode();
950 }
951 _SEH_END;
952
953 if(!NT_SUCCESS(Status))
954 {
955 DC_UnlockDc(dc);
956 return FALSE;
957 }
958
959 DC_UpdateXforms(dc);
960 DC_UnlockDc(dc);
961 return TRUE;
962 }
963
964 /* EOF */