some gcc 3.4.5 fixed; but not all we need
[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 = FALSE;
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 = NULL;
174 NTSTATUS Status = STATUS_SUCCESS;
175 LPPOINT Points = NULL;
176 ULONG Size = 0;
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 BOOL
262 FASTCALL
263 IntGdiModifyWorldTransform(PDC pDc,
264 CONST LPXFORM lpXForm,
265 DWORD Mode)
266 {
267 ASSERT(pDc && lpXForm);
268
269 switch(Mode)
270 {
271 case MWT_IDENTITY:
272 pDc->w.xformWorld2Wnd.eM11 = 1.0f;
273 pDc->w.xformWorld2Wnd.eM12 = 0.0f;
274 pDc->w.xformWorld2Wnd.eM21 = 0.0f;
275 pDc->w.xformWorld2Wnd.eM22 = 1.0f;
276 pDc->w.xformWorld2Wnd.eDx = 0.0f;
277 pDc->w.xformWorld2Wnd.eDy = 0.0f;
278 break;
279
280 case MWT_LEFTMULTIPLY:
281 IntGdiCombineTransform(&pDc->w.xformWorld2Wnd, lpXForm, &pDc->w.xformWorld2Wnd );
282 break;
283
284 case MWT_RIGHTMULTIPLY:
285 IntGdiCombineTransform(&pDc->w.xformWorld2Wnd, &pDc->w.xformWorld2Wnd, lpXForm);
286 break;
287
288 default:
289 SetLastWin32Error(ERROR_INVALID_PARAMETER);
290 return FALSE;
291 }
292
293 DC_UpdateXforms(pDc);
294 DC_UnlockDc(pDc);
295 return TRUE;
296 }
297
298 int
299 STDCALL
300 NtGdiGetGraphicsMode ( HDC hDC )
301 {
302 PDC dc;
303 int GraphicsMode; // default to failure
304
305 dc = DC_LockDc ( hDC );
306 if (!dc)
307 {
308 SetLastWin32Error(ERROR_INVALID_HANDLE);
309 return 0;
310 }
311
312 GraphicsMode = dc->w.GraphicsMode;
313
314 DC_UnlockDc(dc);
315 return GraphicsMode;
316 }
317
318 BOOL
319 STDCALL
320 NtGdiGetWorldTransform(HDC hDC,
321 LPXFORM XForm)
322 {
323 PDC dc = NULL;
324 NTSTATUS Status = STATUS_SUCCESS;
325
326 dc = DC_LockDc ( hDC );
327 if (!dc)
328 {
329 SetLastWin32Error(ERROR_INVALID_HANDLE);
330 return FALSE;
331 }
332 if (!XForm)
333 {
334 DC_UnlockDc(dc);
335 SetLastWin32Error(ERROR_INVALID_PARAMETER);
336 return FALSE;
337 }
338
339 _SEH_TRY
340 {
341 ProbeForWrite(XForm,
342 sizeof(XFORM),
343 1);
344 *XForm = dc->w.xformWorld2Wnd;
345 }
346 _SEH_HANDLE
347 {
348 Status = _SEH_GetExceptionCode();
349 }
350 _SEH_END;
351
352 DC_UnlockDc(dc);
353 return NT_SUCCESS(Status);
354 }
355
356 VOID
357 FASTCALL
358 CoordLPtoDP ( PDC Dc, LPPOINT Point )
359 {
360 FLOAT x, y;
361
362 ASSERT ( Dc );
363 ASSERT ( Point );
364
365 x = (FLOAT)Point->x;
366 y = (FLOAT)Point->y;
367 Point->x = x * Dc->w.xformWorld2Vport.eM11 +
368 y * Dc->w.xformWorld2Vport.eM21 + Dc->w.xformWorld2Vport.eDx;
369 Point->y = x * Dc->w.xformWorld2Vport.eM12 +
370 y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy;
371 }
372
373 VOID
374 FASTCALL
375 IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
376 {
377 INT i;
378
379 ASSERT ( Points );
380
381 for ( i = 0; i < Count; i++ )
382 CoordLPtoDP ( dc, &Points[i] );
383 }
384
385 /*!
386 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
387 * world transfrom, viewport origin settings for the given device context.
388 * \param hDC device context.
389 * \param Points an array of POINT structures (in/out).
390 * \param Count number of elements in the array of POINT structures.
391 * \return TRUE if success.
392 */
393 BOOL STDCALL
394 NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
395 {
396 PDC dc = NULL;
397 NTSTATUS Status = STATUS_SUCCESS;
398 LPPOINT Points = NULL;
399 ULONG Size = 0;
400
401 dc = DC_LockDc(hDC);
402 if (!dc)
403 {
404 SetLastWin32Error(ERROR_INVALID_HANDLE);
405 return FALSE;
406 }
407
408 if (!UnsafePoints || Count <= 0)
409 {
410 DC_UnlockDc(dc);
411 SetLastWin32Error(ERROR_INVALID_PARAMETER);
412 return FALSE;
413 }
414
415 Size = Count * sizeof(POINT);
416
417 Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
418 if(!Points)
419 {
420 DC_UnlockDc(dc);
421 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
422 return FALSE;
423 }
424
425 _SEH_TRY
426 {
427 ProbeForWrite(UnsafePoints,
428 Size,
429 1);
430 RtlCopyMemory(Points,
431 UnsafePoints,
432 Size);
433 }
434 _SEH_HANDLE
435 {
436 Status = _SEH_GetExceptionCode();
437 }
438 _SEH_END;
439
440 if(!NT_SUCCESS(Status))
441 {
442 DC_UnlockDc(dc);
443 ExFreePool(Points);
444 SetLastNtError(Status);
445 return FALSE;
446 }
447
448 IntLPtoDP(dc, Points, Count);
449
450 _SEH_TRY
451 {
452 /* pointer was already probed! */
453 RtlCopyMemory(UnsafePoints,
454 Points,
455 Size);
456 }
457 _SEH_HANDLE
458 {
459 Status = _SEH_GetExceptionCode();
460 }
461 _SEH_END;
462
463 if(!NT_SUCCESS(Status))
464 {
465 DC_UnlockDc(dc);
466 ExFreePool(Points);
467 SetLastNtError(Status);
468 return FALSE;
469 }
470
471 DC_UnlockDc(dc);
472 ExFreePool(Points);
473 return TRUE;
474 }
475
476 BOOL
477 STDCALL
478 NtGdiModifyWorldTransform(HDC hDC,
479 CONST LPXFORM UnsafeXForm,
480 DWORD Mode)
481 {
482 PDC dc = NULL;
483 XFORM SafeXForm;
484 BOOL Ret = FALSE;
485
486 if (!UnsafeXForm)
487 {
488 SetLastWin32Error(ERROR_INVALID_PARAMETER);
489 return FALSE;
490 }
491
492 dc = DC_LockDc(hDC);
493 if (!dc)
494 {
495 SetLastWin32Error(ERROR_INVALID_HANDLE);
496 return FALSE;
497 }
498
499 _SEH_TRY
500 {
501 ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
502 RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM));
503
504 Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
505 }
506 _SEH_HANDLE
507 {
508 SetLastNtError(_SEH_GetExceptionCode());
509 }
510 _SEH_END;
511
512 DC_UnlockDc(dc);
513 return Ret;
514 }
515
516 BOOL
517 STDCALL
518 NtGdiOffsetViewportOrgEx(HDC hDC,
519 int XOffset,
520 int YOffset,
521 LPPOINT UnsafePoint)
522 {
523 PDC dc = NULL;
524 NTSTATUS Status = STATUS_SUCCESS;
525
526 dc = DC_LockDc ( hDC );
527 if(!dc)
528 {
529 SetLastWin32Error(ERROR_INVALID_HANDLE);
530 return FALSE;
531 }
532
533 if (UnsafePoint)
534 {
535 _SEH_TRY
536 {
537 ProbeForWrite(UnsafePoint,
538 sizeof(POINT),
539 1);
540 UnsafePoint->x = dc->vportOrgX;
541 UnsafePoint->y = dc->vportOrgY;
542 }
543 _SEH_HANDLE
544 {
545 Status = _SEH_GetExceptionCode();
546 }
547 _SEH_END;
548
549 if ( !NT_SUCCESS(Status) )
550 {
551 SetLastNtError(Status);
552 DC_UnlockDc(dc);
553 return FALSE;
554 }
555 }
556
557 dc->vportOrgX += XOffset;
558 dc->vportOrgY += YOffset;
559 DC_UpdateXforms(dc);
560
561 DC_UnlockDc(dc);
562 return TRUE;
563 }
564
565 BOOL
566 STDCALL
567 NtGdiOffsetWindowOrgEx(HDC hDC,
568 int XOffset,
569 int YOffset,
570 LPPOINT Point)
571 {
572 PDC dc = NULL;
573
574 dc = DC_LockDc(hDC);
575 if (!dc)
576 {
577 SetLastWin32Error(ERROR_INVALID_HANDLE);
578 return FALSE;
579 }
580
581 if (Point)
582 {
583 NTSTATUS Status = STATUS_SUCCESS;
584
585 _SEH_TRY
586 {
587 ProbeForWrite(Point,
588 sizeof(POINT),
589 1);
590 Point->x = dc->wndOrgX;
591 Point->y = dc->wndOrgY;
592 }
593 _SEH_HANDLE
594 {
595 Status = _SEH_GetExceptionCode();
596 }
597 _SEH_END;
598
599 if(!NT_SUCCESS(Status))
600 {
601 SetLastNtError(Status);
602 DC_UnlockDc(dc);
603 return FALSE;
604 }
605 }
606
607 dc->wndOrgX += XOffset;
608 dc->wndOrgY += YOffset;
609
610 DC_UpdateXforms(dc);
611 DC_UnlockDc(dc);
612
613 return TRUE;
614 }
615
616 BOOL
617 STDCALL
618 NtGdiScaleViewportExtEx(HDC hDC,
619 int Xnum,
620 int Xdenom,
621 int Ynum,
622 int Ydenom,
623 LPSIZE Size)
624 {
625 UNIMPLEMENTED;
626 return FALSE;
627 }
628
629 BOOL
630 STDCALL
631 NtGdiScaleWindowExtEx(HDC hDC,
632 int Xnum,
633 int Xdenom,
634 int Ynum,
635 int Ydenom,
636 LPSIZE Size)
637 {
638 UNIMPLEMENTED;
639 return FALSE;
640 }
641
642 int
643 STDCALL
644 NtGdiSetGraphicsMode(HDC hDC,
645 int Mode)
646 {
647 INT ret;
648 PDC dc;
649
650 dc = DC_LockDc (hDC);
651 if (!dc)
652 {
653 SetLastWin32Error(ERROR_INVALID_HANDLE);
654 return 0;
655 }
656
657 /* One would think that setting the graphics mode to GM_COMPATIBLE
658 * would also reset the world transformation matrix to the unity
659 * matrix. However, in Windows, this is not the case. This doesn't
660 * make a lot of sense to me, but that's the way it is.
661 */
662
663 if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
664 {
665 DC_UnlockDc(dc);
666 SetLastWin32Error(ERROR_INVALID_PARAMETER);
667 return 0;
668 }
669
670 ret = dc->w.GraphicsMode;
671 dc->w.GraphicsMode = Mode;
672 DC_UnlockDc(dc);
673 return ret;
674 }
675
676 int
677 STDCALL
678 NtGdiSetMapMode(HDC hDC,
679 int MapMode)
680 {
681 int PrevMapMode;
682 PDC dc;
683
684 dc = DC_LockDc(hDC);
685 if (!dc)
686 {
687 SetLastWin32Error(ERROR_INVALID_HANDLE);
688 return 0;
689 }
690
691 PrevMapMode = dc->w.MapMode;
692
693 if (MapMode != dc->w.MapMode || (MapMode != MM_ISOTROPIC && MapMode != MM_ANISOTROPIC))
694 {
695 dc->w.MapMode = MapMode;
696
697 switch (MapMode)
698 {
699 case MM_TEXT:
700 dc->wndExtX = 1;
701 dc->wndExtY = 1;
702 dc->vportExtX = 1;
703 dc->vportExtY = 1;
704 break;
705
706 case MM_LOMETRIC:
707 case MM_ISOTROPIC:
708 dc->wndExtX = dc->GDIInfo->ulHorzSize * 10;
709 dc->wndExtY = dc->GDIInfo->ulVertSize * 10;
710 dc->vportExtX = dc->GDIInfo->ulHorzRes;
711 dc->vportExtY = -dc->GDIInfo->ulVertRes;
712 break;
713
714 case MM_HIMETRIC:
715 dc->wndExtX = dc->GDIInfo->ulHorzSize * 100;
716 dc->wndExtY = dc->GDIInfo->ulVertSize * 100;
717 dc->vportExtX = dc->GDIInfo->ulHorzRes;
718 dc->vportExtY = -dc->GDIInfo->ulVertRes;
719 break;
720
721 case MM_LOENGLISH:
722 dc->wndExtX = EngMulDiv(1000, dc->GDIInfo->ulHorzSize, 254);
723 dc->wndExtY = EngMulDiv(1000, dc->GDIInfo->ulVertSize, 254);
724 dc->vportExtX = dc->GDIInfo->ulHorzRes;
725 dc->vportExtY = -dc->GDIInfo->ulVertRes;
726 break;
727
728 case MM_HIENGLISH:
729 dc->wndExtX = EngMulDiv(10000, dc->GDIInfo->ulHorzSize, 254);
730 dc->wndExtY = EngMulDiv(10000, dc->GDIInfo->ulVertSize, 254);
731 dc->vportExtX = dc->GDIInfo->ulHorzRes;
732 dc->vportExtY = -dc->GDIInfo->ulVertRes;
733 break;
734
735 case MM_TWIPS:
736 dc->wndExtX = EngMulDiv(14400, dc->GDIInfo->ulHorzSize, 254);
737 dc->wndExtY = EngMulDiv(14400, dc->GDIInfo->ulVertSize, 254);
738 dc->vportExtX = dc->GDIInfo->ulHorzRes;
739 dc->vportExtY = -dc->GDIInfo->ulVertRes;
740 break;
741
742 case MM_ANISOTROPIC:
743 break;
744 }
745
746 DC_UpdateXforms(dc);
747 }
748
749 DC_UnlockDc(dc);
750
751 return PrevMapMode;
752 }
753
754 BOOL
755 STDCALL
756 NtGdiSetViewportExtEx(HDC hDC,
757 int XExtent,
758 int YExtent,
759 LPSIZE Size)
760 {
761 PDC dc = NULL;
762
763 dc = DC_LockDc(hDC);
764 if ( !dc )
765 {
766 SetLastWin32Error(ERROR_INVALID_HANDLE);
767 return FALSE;
768 }
769
770 switch (dc->w.MapMode)
771 {
772 case MM_HIENGLISH:
773 case MM_HIMETRIC:
774 case MM_LOENGLISH:
775 case MM_LOMETRIC:
776 case MM_TEXT:
777 case MM_TWIPS:
778 DC_UnlockDc(dc);
779 return FALSE;
780
781 case MM_ISOTROPIC:
782 // Here we should (probably) check that SetWindowExtEx *really* has
783 // been called
784 break;
785 }
786
787 if (Size)
788 {
789 NTSTATUS Status = STATUS_SUCCESS;
790
791 _SEH_TRY
792 {
793 ProbeForWrite(Size,
794 sizeof(SIZE),
795 1);
796 Size->cx = dc->vportExtX;
797 Size->cy = dc->vportExtY;
798
799 dc->vportExtX = XExtent;
800 dc->vportExtY = YExtent;
801
802 if (dc->w.MapMode == MM_ISOTROPIC)
803 IntFixIsotropicMapping(dc);
804 }
805 _SEH_HANDLE
806 {
807 Status = _SEH_GetExceptionCode();
808 }
809 _SEH_END;
810
811 if(!NT_SUCCESS(Status))
812 {
813 SetLastNtError(Status);
814 DC_UnlockDc(dc);
815 return FALSE;
816 }
817 }
818
819
820 DC_UpdateXforms(dc);
821 DC_UnlockDc(dc);
822
823 return TRUE;
824 }
825
826 BOOL
827 STDCALL
828 NtGdiSetViewportOrgEx(HDC hDC,
829 int X,
830 int Y,
831 LPPOINT Point)
832 {
833 PDC dc = NULL;
834
835 dc = DC_LockDc(hDC);
836 if (!dc)
837 {
838 SetLastWin32Error(ERROR_INVALID_HANDLE);
839 return FALSE;
840 }
841
842 if (Point)
843 {
844 NTSTATUS Status = STATUS_SUCCESS;
845
846 _SEH_TRY
847 {
848 ProbeForWrite(Point,
849 sizeof(POINT),
850 1);
851 Point->x = dc->vportOrgX;
852 Point->y = dc->vportOrgY;
853 }
854 _SEH_HANDLE
855 {
856 Status = _SEH_GetExceptionCode();
857 }
858 _SEH_END;
859
860 if(!NT_SUCCESS(Status))
861 {
862 SetLastNtError(Status);
863 DC_UnlockDc(dc);
864 return FALSE;
865 }
866 }
867
868 dc->vportOrgX = X;
869 dc->vportOrgY = Y;
870
871 DC_UpdateXforms(dc);
872 DC_UnlockDc(dc);
873
874 return TRUE;
875 }
876
877 BOOL
878 STDCALL
879 NtGdiSetWindowExtEx(HDC hDC,
880 int XExtent,
881 int YExtent,
882 LPSIZE Size)
883 {
884 PDC dc = NULL;
885
886 dc = DC_LockDc(hDC);
887 if (!dc)
888 {
889 SetLastWin32Error(ERROR_INVALID_HANDLE);
890 return FALSE;
891 }
892
893 switch (dc->w.MapMode)
894 {
895 case MM_HIENGLISH:
896 case MM_HIMETRIC:
897 case MM_LOENGLISH:
898 case MM_LOMETRIC:
899 case MM_TEXT:
900 case MM_TWIPS:
901 DC_UnlockDc(dc);
902 return FALSE;
903 }
904
905 if (Size)
906 {
907 NTSTATUS Status = STATUS_SUCCESS;
908
909 _SEH_TRY
910 {
911 ProbeForWrite(Size,
912 sizeof(SIZE),
913 1);
914 Size->cx = dc->wndExtX;
915 Size->cy = dc->wndExtY;
916 }
917 _SEH_HANDLE
918 {
919 Status = _SEH_GetExceptionCode();
920 }
921 _SEH_END;
922
923 if(!NT_SUCCESS(Status))
924 {
925 SetLastNtError(Status);
926 DC_UnlockDc(dc);
927 return FALSE;
928 }
929 }
930
931 dc->wndExtX = XExtent;
932 dc->wndExtY = YExtent;
933
934 DC_UpdateXforms(dc);
935 DC_UnlockDc(dc);
936
937 return TRUE;
938 }
939
940 BOOL
941 STDCALL
942 NtGdiSetWindowOrgEx(HDC hDC,
943 int X,
944 int Y,
945 LPPOINT Point)
946 {
947 PDC dc = NULL;
948
949 dc = DC_LockDc(hDC);
950 if (!dc)
951 {
952 SetLastWin32Error(ERROR_INVALID_HANDLE);
953 return FALSE;
954 }
955
956 if (Point)
957 {
958 NTSTATUS Status = STATUS_SUCCESS;
959
960 _SEH_TRY
961 {
962 ProbeForWrite(Point,
963 sizeof(POINT),
964 1);
965 Point->x = dc->wndOrgX;
966 Point->y = dc->wndOrgY;
967 }
968 _SEH_HANDLE
969 {
970 Status = _SEH_GetExceptionCode();
971 }
972 _SEH_END;
973
974 if(!NT_SUCCESS(Status))
975 {
976 SetLastNtError(Status);
977 DC_UnlockDc(dc);
978 return FALSE;
979 }
980 }
981
982 dc->wndOrgX = X;
983 dc->wndOrgY = Y;
984
985 DC_UpdateXforms(dc);
986 DC_UnlockDc(dc);
987
988 return TRUE;
989 }
990
991 BOOL
992 STDCALL
993 NtGdiSetWorldTransform(HDC hDC,
994 CONST LPXFORM XForm)
995 {
996 PDC dc = NULL;
997 NTSTATUS Status = STATUS_SUCCESS;
998
999 dc = DC_LockDc (hDC);
1000 if ( !dc )
1001 {
1002 SetLastWin32Error(ERROR_INVALID_HANDLE);
1003 return FALSE;
1004 }
1005
1006 if (!XForm)
1007 {
1008 DC_UnlockDc(dc);
1009 /* Win doesn't set LastError */
1010 return FALSE;
1011 }
1012
1013 /* Check that graphics mode is GM_ADVANCED */
1014 if ( dc->w.GraphicsMode != GM_ADVANCED )
1015 {
1016 DC_UnlockDc(dc);
1017 return FALSE;
1018 }
1019
1020 _SEH_TRY
1021 {
1022 ProbeForRead(XForm,
1023 sizeof(XFORM),
1024 1);
1025 dc->w.xformWorld2Wnd = *XForm;
1026 }
1027 _SEH_HANDLE
1028 {
1029 Status = _SEH_GetExceptionCode();
1030 }
1031 _SEH_END;
1032
1033 if(!NT_SUCCESS(Status))
1034 {
1035 DC_UnlockDc(dc);
1036 return FALSE;
1037 }
1038
1039 DC_UpdateXforms(dc);
1040 DC_UnlockDc(dc);
1041 return TRUE;
1042 }
1043
1044 /* EOF */