Implement the isometric mapping mode and call the mapping functions for Ellipse and...
[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 void FASTCALL
38 IntFixIsotropicMapping(PDC dc)
39 {
40 ULONG xdim = EngMulDiv(dc->vportExtX, dc->GDIInfo->ulHorzSize, dc->GDIInfo->ulHorzRes) / dc->wndExtX;
41 ULONG ydim = EngMulDiv(dc->vportExtY, dc->GDIInfo->ulVertSize, dc->GDIInfo->ulVertRes) / dc->wndExtY;
42
43 if (xdim > ydim)
44 {
45 dc->vportExtX = dc->vportExtX * abs(ydim / xdim);
46 if (!dc->vportExtX) dc->vportExtX = 1;
47 }
48 else
49 {
50 dc->vportExtY = dc->vportExtY * abs(xdim / ydim);
51 if (!dc->vportExtY) dc->vportExtY = 1;
52 }
53 }
54
55 BOOL FASTCALL
56 IntGdiCombineTransform(LPXFORM XFormResult,
57 LPXFORM xform1,
58 LPXFORM xform2)
59 {
60 /* Check for illegal parameters */
61 if (!XFormResult || !xform1 || !xform2)
62 {
63 return FALSE;
64 }
65
66 /* Create the result in a temporary XFORM, since xformResult may be
67 * equal to xform1 or xform2 */
68 XFormResult->eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
69 XFormResult->eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
70 XFormResult->eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
71 XFormResult->eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
72 XFormResult->eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
73 XFormResult->eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
74
75 return TRUE;
76 }
77
78 BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
79 CONST LPXFORM Unsafexform1,
80 CONST LPXFORM Unsafexform2)
81 {
82 XFORM xformTemp;
83 XFORM xform1 = {0}, xform2 = {0};
84 NTSTATUS Status = STATUS_SUCCESS;
85 BOOL Ret;
86
87 _SEH_TRY
88 {
89 ProbeForWrite(UnsafeXFormResult,
90 sizeof(XFORM),
91 1);
92 ProbeForRead(Unsafexform1,
93 sizeof(XFORM),
94 1);
95 ProbeForRead(Unsafexform2,
96 sizeof(XFORM),
97 1);
98 xform1 = *Unsafexform1;
99 xform2 = *Unsafexform2;
100 }
101 _SEH_HANDLE
102 {
103 Status = _SEH_GetExceptionCode();
104 }
105 _SEH_END;
106
107 if(!NT_SUCCESS(Status))
108 {
109 SetLastNtError(Status);
110 return FALSE;
111 }
112
113 Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2);
114
115 /* Copy the result to xformResult */
116 _SEH_TRY
117 {
118 /* pointer was already probed! */
119 *UnsafeXFormResult = xformTemp;
120 }
121 _SEH_HANDLE
122 {
123 Status = _SEH_GetExceptionCode();
124 }
125 _SEH_END;
126
127 if(!NT_SUCCESS(Status))
128 {
129 SetLastNtError(Status);
130 return FALSE;
131 }
132
133 return Ret;
134 }
135
136 VOID FASTCALL
137 CoordDPtoLP(PDC Dc, LPPOINT Point)
138 {
139 FLOAT x, y;
140 x = (FLOAT)Point->x;
141 y = (FLOAT)Point->y;
142 Point->x = x * Dc->w.xformVport2World.eM11 +
143 y * Dc->w.xformVport2World.eM21 + Dc->w.xformVport2World.eDx;
144 Point->y = x * Dc->w.xformVport2World.eM12 +
145 y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
146 }
147
148 VOID
149 FASTCALL
150 IntDPtoLP ( PDC dc, LPPOINT Points, INT Count )
151 {
152 INT i;
153
154 ASSERT ( Points );
155
156 for ( i = 0; i < Count; i++ )
157 CoordDPtoLP ( dc, &Points[i] );
158 }
159
160 /*!
161 * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
162 * world transfrom, viewport origin settings for the given device context.
163 * \param hDC device context.
164 * \param Points an array of POINT structures (in/out).
165 * \param Count number of elements in the array of POINT structures.
166 * \return TRUE if success.
167 */
168 BOOL STDCALL
169 NtGdiDPtoLP(HDC hDC,
170 LPPOINT UnsafePoints,
171 int Count)
172 {
173 PDC dc;
174 NTSTATUS Status = STATUS_SUCCESS;
175 LPPOINT Points;
176 ULONG Size;
177
178 dc = DC_LockDc(hDC);
179 if (!dc)
180 {
181 SetLastWin32Error(ERROR_INVALID_HANDLE);
182 return FALSE;
183 }
184
185 if (!UnsafePoints || Count <= 0)
186 {
187 DC_UnlockDc(dc);
188 SetLastWin32Error(ERROR_INVALID_PARAMETER);
189 return FALSE;
190 }
191
192 Size = Count * sizeof(POINT);
193
194 Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
195 if(!Points)
196 {
197 DC_UnlockDc(dc);
198 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
199 return FALSE;
200 }
201
202 _SEH_TRY
203 {
204 ProbeForWrite(UnsafePoints,
205 Size,
206 1);
207 RtlCopyMemory(Points,
208 UnsafePoints,
209 Size);
210 }
211 _SEH_HANDLE
212 {
213 Status = _SEH_GetExceptionCode();
214 }
215 _SEH_END;
216
217 if(!NT_SUCCESS(Status))
218 {
219 DC_UnlockDc(dc);
220 ExFreePool(Points);
221 SetLastNtError(Status);
222 return FALSE;
223 }
224
225 IntDPtoLP(dc, Points, Count);
226
227 _SEH_TRY
228 {
229 /* pointer was already probed! */
230 RtlCopyMemory(UnsafePoints,
231 Points,
232 Size);
233 }
234 _SEH_HANDLE
235 {
236 Status = _SEH_GetExceptionCode();
237 }
238 _SEH_END;
239
240 if(!NT_SUCCESS(Status))
241 {
242 DC_UnlockDc(dc);
243 ExFreePool(Points);
244 SetLastNtError(Status);
245 return FALSE;
246 }
247
248 DC_UnlockDc(dc);
249 ExFreePool(Points);
250 return TRUE;
251 }
252
253 int
254 FASTCALL
255 IntGetGraphicsMode ( PDC dc )
256 {
257 ASSERT ( dc );
258 return dc->w.GraphicsMode;
259 }
260
261 int
262 STDCALL
263 NtGdiGetGraphicsMode ( HDC hDC )
264 {
265 PDC dc;
266 int GraphicsMode; // default to failure
267
268 dc = DC_LockDc ( hDC );
269 if (!dc)
270 {
271 SetLastWin32Error(ERROR_INVALID_HANDLE);
272 return 0;
273 }
274
275 GraphicsMode = dc->w.GraphicsMode;
276
277 DC_UnlockDc(dc);
278 return GraphicsMode;
279 }
280
281 BOOL
282 STDCALL
283 NtGdiGetWorldTransform(HDC hDC,
284 LPXFORM XForm)
285 {
286 PDC dc;
287 NTSTATUS Status = STATUS_SUCCESS;
288
289 dc = DC_LockDc ( hDC );
290 if (!dc)
291 {
292 SetLastWin32Error(ERROR_INVALID_HANDLE);
293 return FALSE;
294 }
295 if (!XForm)
296 {
297 DC_UnlockDc(dc);
298 SetLastWin32Error(ERROR_INVALID_PARAMETER);
299 return FALSE;
300 }
301
302 _SEH_TRY
303 {
304 ProbeForWrite(XForm,
305 sizeof(XFORM),
306 1);
307 *XForm = dc->w.xformWorld2Wnd;
308 }
309 _SEH_HANDLE
310 {
311 Status = _SEH_GetExceptionCode();
312 }
313 _SEH_END;
314
315 DC_UnlockDc(dc);
316 return NT_SUCCESS(Status);
317 }
318
319 VOID
320 FASTCALL
321 CoordLPtoDP ( PDC Dc, LPPOINT Point )
322 {
323 FLOAT x, y;
324
325 ASSERT ( Dc );
326 ASSERT ( Point );
327
328 x = (FLOAT)Point->x;
329 y = (FLOAT)Point->y;
330 Point->x = x * Dc->w.xformWorld2Vport.eM11 +
331 y * Dc->w.xformWorld2Vport.eM21 + Dc->w.xformWorld2Vport.eDx;
332 Point->y = x * Dc->w.xformWorld2Vport.eM12 +
333 y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy;
334 }
335
336 VOID
337 FASTCALL
338 IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
339 {
340 INT i;
341
342 ASSERT ( Points );
343
344 for ( i = 0; i < Count; i++ )
345 CoordLPtoDP ( dc, &Points[i] );
346 }
347
348 /*!
349 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
350 * world transfrom, viewport origin settings for the given device context.
351 * \param hDC device context.
352 * \param Points an array of POINT structures (in/out).
353 * \param Count number of elements in the array of POINT structures.
354 * \return TRUE if success.
355 */
356 BOOL STDCALL
357 NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
358 {
359 PDC dc;
360 NTSTATUS Status = STATUS_SUCCESS;
361 LPPOINT Points;
362 ULONG Size;
363
364 dc = DC_LockDc(hDC);
365 if (!dc)
366 {
367 SetLastWin32Error(ERROR_INVALID_HANDLE);
368 return FALSE;
369 }
370
371 if (!UnsafePoints || Count <= 0)
372 {
373 DC_UnlockDc(dc);
374 SetLastWin32Error(ERROR_INVALID_PARAMETER);
375 return FALSE;
376 }
377
378 Size = Count * sizeof(POINT);
379
380 Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
381 if(!Points)
382 {
383 DC_UnlockDc(dc);
384 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
385 return FALSE;
386 }
387
388 _SEH_TRY
389 {
390 ProbeForWrite(UnsafePoints,
391 Size,
392 1);
393 RtlCopyMemory(Points,
394 UnsafePoints,
395 Size);
396 }
397 _SEH_HANDLE
398 {
399 Status = _SEH_GetExceptionCode();
400 }
401 _SEH_END;
402
403 if(!NT_SUCCESS(Status))
404 {
405 DC_UnlockDc(dc);
406 ExFreePool(Points);
407 SetLastNtError(Status);
408 return FALSE;
409 }
410
411 IntLPtoDP(dc, Points, Count);
412
413 _SEH_TRY
414 {
415 /* pointer was already probed! */
416 RtlCopyMemory(UnsafePoints,
417 Points,
418 Size);
419 }
420 _SEH_HANDLE
421 {
422 Status = _SEH_GetExceptionCode();
423 }
424 _SEH_END;
425
426 if(!NT_SUCCESS(Status))
427 {
428 DC_UnlockDc(dc);
429 ExFreePool(Points);
430 SetLastNtError(Status);
431 return FALSE;
432 }
433
434 DC_UnlockDc(dc);
435 ExFreePool(Points);
436 return TRUE;
437 }
438
439 BOOL
440 STDCALL
441 NtGdiModifyWorldTransform(HDC hDC,
442 CONST LPXFORM UnsafeXForm,
443 DWORD Mode)
444 {
445 PDC dc;
446 XFORM SafeXForm = {0};
447 NTSTATUS Status = STATUS_SUCCESS;
448
449 dc = DC_LockDc(hDC);
450 if (!dc)
451 {
452 SetLastWin32Error(ERROR_INVALID_HANDLE);
453 return FALSE;
454 }
455
456 if (!UnsafeXForm)
457 {
458 DC_UnlockDc(dc);
459 SetLastWin32Error(ERROR_INVALID_PARAMETER);
460 return FALSE;
461 }
462
463 _SEH_TRY
464 {
465 ProbeForRead(UnsafeXForm,
466 sizeof(XFORM),
467 1);
468 SafeXForm = *UnsafeXForm;
469 }
470 _SEH_HANDLE
471 {
472 Status = _SEH_GetExceptionCode();
473 }
474 _SEH_END;
475
476 if(!NT_SUCCESS(Status))
477 {
478 DC_UnlockDc(dc);
479 SetLastNtError(Status);
480 return FALSE;
481 }
482
483 switch(Mode)
484 {
485 case MWT_IDENTITY:
486 dc->w.xformWorld2Wnd.eM11 = 1.0f;
487 dc->w.xformWorld2Wnd.eM12 = 0.0f;
488 dc->w.xformWorld2Wnd.eM21 = 0.0f;
489 dc->w.xformWorld2Wnd.eM22 = 1.0f;
490 dc->w.xformWorld2Wnd.eDx = 0.0f;
491 dc->w.xformWorld2Wnd.eDy = 0.0f;
492 break;
493
494 case MWT_LEFTMULTIPLY:
495 IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &SafeXForm, &dc->w.xformWorld2Wnd );
496 break;
497
498 case MWT_RIGHTMULTIPLY:
499 IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, &SafeXForm);
500 break;
501
502 default:
503 DC_UnlockDc(dc);
504 SetLastWin32Error(ERROR_INVALID_PARAMETER);
505 return FALSE;
506 }
507
508 DC_UpdateXforms(dc);
509 DC_UnlockDc(dc);
510 return TRUE;
511 }
512
513 BOOL
514 STDCALL
515 NtGdiOffsetViewportOrgEx(HDC hDC,
516 int XOffset,
517 int YOffset,
518 LPPOINT UnsafePoint)
519 {
520 PDC dc;
521 NTSTATUS Status = STATUS_SUCCESS;
522
523 dc = DC_LockDc ( hDC );
524 if(!dc)
525 {
526 SetLastWin32Error(ERROR_INVALID_HANDLE);
527 return FALSE;
528 }
529
530 if (UnsafePoint)
531 {
532 _SEH_TRY
533 {
534 ProbeForWrite(UnsafePoint,
535 sizeof(POINT),
536 1);
537 UnsafePoint->x = dc->vportOrgX;
538 UnsafePoint->y = dc->vportOrgY;
539 }
540 _SEH_HANDLE
541 {
542 Status = _SEH_GetExceptionCode();
543 }
544 _SEH_END;
545
546 if ( !NT_SUCCESS(Status) )
547 {
548 SetLastNtError(Status);
549 DC_UnlockDc(dc);
550 return FALSE;
551 }
552 }
553
554 dc->vportOrgX += XOffset;
555 dc->vportOrgY += YOffset;
556 DC_UpdateXforms(dc);
557
558 DC_UnlockDc(dc);
559 return TRUE;
560 }
561
562 BOOL
563 STDCALL
564 NtGdiOffsetWindowOrgEx(HDC hDC,
565 int XOffset,
566 int YOffset,
567 LPPOINT Point)
568 {
569 PDC dc;
570
571 dc = DC_LockDc(hDC);
572 if (!dc)
573 {
574 SetLastWin32Error(ERROR_INVALID_HANDLE);
575 return FALSE;
576 }
577
578 if (Point)
579 {
580 NTSTATUS Status = STATUS_SUCCESS;
581
582 _SEH_TRY
583 {
584 ProbeForWrite(Point,
585 sizeof(POINT),
586 1);
587 Point->x = dc->wndOrgX;
588 Point->y = dc->wndOrgY;
589 }
590 _SEH_HANDLE
591 {
592 Status = _SEH_GetExceptionCode();
593 }
594 _SEH_END;
595
596 if(!NT_SUCCESS(Status))
597 {
598 SetLastNtError(Status);
599 DC_UnlockDc(dc);
600 return FALSE;
601 }
602 }
603
604 dc->wndOrgX += XOffset;
605 dc->wndOrgY += YOffset;
606
607 DC_UpdateXforms(dc);
608 DC_UnlockDc(dc);
609
610 return TRUE;
611 }
612
613 BOOL
614 STDCALL
615 NtGdiScaleViewportExtEx(HDC hDC,
616 int Xnum,
617 int Xdenom,
618 int Ynum,
619 int Ydenom,
620 LPSIZE Size)
621 {
622 UNIMPLEMENTED;
623 return FALSE;
624 }
625
626 BOOL
627 STDCALL
628 NtGdiScaleWindowExtEx(HDC hDC,
629 int Xnum,
630 int Xdenom,
631 int Ynum,
632 int Ydenom,
633 LPSIZE Size)
634 {
635 UNIMPLEMENTED;
636 return FALSE;
637 }
638
639 int
640 STDCALL
641 NtGdiSetGraphicsMode(HDC hDC,
642 int Mode)
643 {
644 INT ret;
645 PDC dc;
646
647 dc = DC_LockDc (hDC);
648 if (!dc)
649 {
650 SetLastWin32Error(ERROR_INVALID_HANDLE);
651 return 0;
652 }
653
654 /* One would think that setting the graphics mode to GM_COMPATIBLE
655 * would also reset the world transformation matrix to the unity
656 * matrix. However, in Windows, this is not the case. This doesn't
657 * make a lot of sense to me, but that's the way it is.
658 */
659
660 if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
661 {
662 DC_UnlockDc(dc);
663 SetLastWin32Error(ERROR_INVALID_PARAMETER);
664 return 0;
665 }
666
667 ret = dc->w.GraphicsMode;
668 dc->w.GraphicsMode = Mode;
669 DC_UnlockDc(dc);
670 return ret;
671 }
672
673 int
674 STDCALL
675 NtGdiSetMapMode(HDC hDC,
676 int MapMode)
677 {
678 int PrevMapMode;
679 PDC dc;
680
681 dc = DC_LockDc(hDC);
682 if (!dc)
683 {
684 SetLastWin32Error(ERROR_INVALID_HANDLE);
685 return 0;
686 }
687
688 PrevMapMode = dc->w.MapMode;
689
690 if (MapMode != dc->w.MapMode || (MapMode != MM_ISOTROPIC && MapMode != MM_ANISOTROPIC))
691 {
692 dc->w.MapMode = MapMode;
693
694 switch (MapMode)
695 {
696 case MM_TEXT:
697 dc->wndExtX = 1;
698 dc->wndExtY = 1;
699 dc->vportExtX = 1;
700 dc->vportExtY = 1;
701 break;
702
703 case MM_LOMETRIC:
704 case MM_ISOTROPIC:
705 dc->wndExtX = dc->GDIInfo->ulHorzSize * 10;
706 dc->wndExtY = dc->GDIInfo->ulVertSize * 10;
707 dc->vportExtX = dc->GDIInfo->ulHorzRes;
708 dc->vportExtY = -dc->GDIInfo->ulVertRes;
709 break;
710
711 case MM_HIMETRIC:
712 dc->wndExtX = dc->GDIInfo->ulHorzSize * 100;
713 dc->wndExtY = dc->GDIInfo->ulVertSize * 100;
714 dc->vportExtX = dc->GDIInfo->ulHorzRes;
715 dc->vportExtY = -dc->GDIInfo->ulVertRes;
716 break;
717
718 case MM_LOENGLISH:
719 dc->wndExtX = EngMulDiv(1000, dc->GDIInfo->ulHorzSize, 254);
720 dc->wndExtY = EngMulDiv(1000, dc->GDIInfo->ulVertSize, 254);
721 dc->vportExtX = dc->GDIInfo->ulHorzRes;
722 dc->vportExtY = -dc->GDIInfo->ulVertRes;
723 break;
724
725 case MM_HIENGLISH:
726 dc->wndExtX = EngMulDiv(10000, dc->GDIInfo->ulHorzSize, 254);
727 dc->wndExtY = EngMulDiv(10000, dc->GDIInfo->ulVertSize, 254);
728 dc->vportExtX = dc->GDIInfo->ulHorzRes;
729 dc->vportExtY = -dc->GDIInfo->ulVertRes;
730 break;
731
732 case MM_TWIPS:
733 dc->wndExtX = EngMulDiv(14400, dc->GDIInfo->ulHorzSize, 254);
734 dc->wndExtY = EngMulDiv(14400, dc->GDIInfo->ulVertSize, 254);
735 dc->vportExtX = dc->GDIInfo->ulHorzRes;
736 dc->vportExtY = -dc->GDIInfo->ulVertRes;
737 break;
738
739 case MM_ANISOTROPIC:
740 break;
741 }
742
743 DC_UpdateXforms(dc);
744 }
745
746 DC_UnlockDc(dc);
747
748 return PrevMapMode;
749 }
750
751 BOOL
752 STDCALL
753 NtGdiSetViewportExtEx(HDC hDC,
754 int XExtent,
755 int YExtent,
756 LPSIZE Size)
757 {
758 PDC dc;
759
760 dc = DC_LockDc(hDC);
761 if ( !dc )
762 {
763 SetLastWin32Error(ERROR_INVALID_HANDLE);
764 return FALSE;
765 }
766
767 switch (dc->w.MapMode)
768 {
769 case MM_HIENGLISH:
770 case MM_HIMETRIC:
771 case MM_LOENGLISH:
772 case MM_LOMETRIC:
773 case MM_TEXT:
774 case MM_TWIPS:
775 DC_UnlockDc(dc);
776 return FALSE;
777
778 case MM_ISOTROPIC:
779 // Here we should (probably) check that SetWindowExtEx *really* has
780 // been called
781 break;
782 }
783
784 if (Size)
785 {
786 NTSTATUS Status = STATUS_SUCCESS;
787
788 _SEH_TRY
789 {
790 ProbeForWrite(Size,
791 sizeof(SIZE),
792 1);
793 Size->cx = dc->vportExtX;
794 Size->cy = dc->vportExtY;
795 }
796 _SEH_HANDLE
797 {
798 Status = _SEH_GetExceptionCode();
799 }
800 _SEH_END;
801
802 if(!NT_SUCCESS(Status))
803 {
804 SetLastNtError(Status);
805 DC_UnlockDc(dc);
806 return FALSE;
807 }
808 }
809
810 dc->vportExtX = XExtent;
811 dc->vportExtY = YExtent;
812
813 if (dc->w.MapMode == MM_ISOTROPIC)
814 IntFixIsotropicMapping(dc);
815 DC_UpdateXforms(dc);
816 DC_UnlockDc(dc);
817
818 return TRUE;
819 }
820
821 BOOL
822 STDCALL
823 NtGdiSetViewportOrgEx(HDC hDC,
824 int X,
825 int Y,
826 LPPOINT Point)
827 {
828 PDC dc;
829
830 dc = DC_LockDc(hDC);
831 if (!dc)
832 {
833 SetLastWin32Error(ERROR_INVALID_HANDLE);
834 return FALSE;
835 }
836
837 if (Point)
838 {
839 NTSTATUS Status = STATUS_SUCCESS;
840
841 _SEH_TRY
842 {
843 ProbeForWrite(Point,
844 sizeof(POINT),
845 1);
846 Point->x = dc->vportOrgX;
847 Point->y = dc->vportOrgY;
848 }
849 _SEH_HANDLE
850 {
851 Status = _SEH_GetExceptionCode();
852 }
853 _SEH_END;
854
855 if(!NT_SUCCESS(Status))
856 {
857 SetLastNtError(Status);
858 DC_UnlockDc(dc);
859 return FALSE;
860 }
861 }
862
863 dc->vportOrgX = X;
864 dc->vportOrgY = Y;
865
866 DC_UpdateXforms(dc);
867 DC_UnlockDc(dc);
868
869 return TRUE;
870 }
871
872 BOOL
873 STDCALL
874 NtGdiSetWindowExtEx(HDC hDC,
875 int XExtent,
876 int YExtent,
877 LPSIZE Size)
878 {
879 PDC dc;
880
881 dc = DC_LockDc(hDC);
882 if (!dc)
883 {
884 SetLastWin32Error(ERROR_INVALID_HANDLE);
885 return FALSE;
886 }
887
888 switch (dc->w.MapMode)
889 {
890 case MM_HIENGLISH:
891 case MM_HIMETRIC:
892 case MM_LOENGLISH:
893 case MM_LOMETRIC:
894 case MM_TEXT:
895 case MM_TWIPS:
896 DC_UnlockDc(dc);
897 return FALSE;
898 }
899
900 if (Size)
901 {
902 NTSTATUS Status = STATUS_SUCCESS;
903
904 _SEH_TRY
905 {
906 ProbeForWrite(Size,
907 sizeof(SIZE),
908 1);
909 Size->cx = dc->wndExtX;
910 Size->cy = dc->wndExtY;
911 }
912 _SEH_HANDLE
913 {
914 Status = _SEH_GetExceptionCode();
915 }
916 _SEH_END;
917
918 if(!NT_SUCCESS(Status))
919 {
920 SetLastNtError(Status);
921 DC_UnlockDc(dc);
922 return FALSE;
923 }
924 }
925
926 dc->wndExtX = XExtent;
927 dc->wndExtY = YExtent;
928
929 DC_UpdateXforms(dc);
930 DC_UnlockDc(dc);
931
932 return TRUE;
933 }
934
935 BOOL
936 STDCALL
937 NtGdiSetWindowOrgEx(HDC hDC,
938 int X,
939 int Y,
940 LPPOINT Point)
941 {
942 PDC dc;
943
944 dc = DC_LockDc(hDC);
945 if (!dc)
946 {
947 SetLastWin32Error(ERROR_INVALID_HANDLE);
948 return FALSE;
949 }
950
951 if (Point)
952 {
953 NTSTATUS Status = STATUS_SUCCESS;
954
955 _SEH_TRY
956 {
957 ProbeForWrite(Point,
958 sizeof(POINT),
959 1);
960 Point->x = dc->wndOrgX;
961 Point->y = dc->wndOrgY;
962 }
963 _SEH_HANDLE
964 {
965 Status = _SEH_GetExceptionCode();
966 }
967 _SEH_END;
968
969 if(!NT_SUCCESS(Status))
970 {
971 SetLastNtError(Status);
972 DC_UnlockDc(dc);
973 return FALSE;
974 }
975 }
976
977 dc->wndOrgX = X;
978 dc->wndOrgY = Y;
979
980 DC_UpdateXforms(dc);
981 DC_UnlockDc(dc);
982
983 return TRUE;
984 }
985
986 BOOL
987 STDCALL
988 NtGdiSetWorldTransform(HDC hDC,
989 CONST LPXFORM XForm)
990 {
991 PDC dc;
992 NTSTATUS Status = STATUS_SUCCESS;
993
994 dc = DC_LockDc (hDC);
995 if ( !dc )
996 {
997 SetLastWin32Error(ERROR_INVALID_HANDLE);
998 return FALSE;
999 }
1000
1001 if (!XForm)
1002 {
1003 DC_UnlockDc(dc);
1004 /* Win doesn't set LastError */
1005 return FALSE;
1006 }
1007
1008 /* Check that graphics mode is GM_ADVANCED */
1009 if ( dc->w.GraphicsMode != GM_ADVANCED )
1010 {
1011 DC_UnlockDc(dc);
1012 return FALSE;
1013 }
1014
1015 _SEH_TRY
1016 {
1017 ProbeForRead(XForm,
1018 sizeof(XFORM),
1019 1);
1020 dc->w.xformWorld2Wnd = *XForm;
1021 }
1022 _SEH_HANDLE
1023 {
1024 Status = _SEH_GetExceptionCode();
1025 }
1026 _SEH_END;
1027
1028 if(!NT_SUCCESS(Status))
1029 {
1030 DC_UnlockDc(dc);
1031 return FALSE;
1032 }
1033
1034 DC_UpdateXforms(dc);
1035 DC_UnlockDc(dc);
1036 return TRUE;
1037 }
1038
1039 /* EOF */