Move Window and Viewport Ext and Org to Dc_Attr. Tested it with qemu.
[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->Dc_Attr.szlViewportExt.cx, dc->GDIInfo->ulHorzSize, dc->GDIInfo->ulHorzRes) / dc->Dc_Attr.szlWindowExt.cx;
41 ULONG ydim = EngMulDiv(dc->Dc_Attr.szlViewportExt.cy, dc->GDIInfo->ulVertSize, dc->GDIInfo->ulVertRes) / dc->Dc_Attr.szlWindowExt.cy;
42
43 if (xdim > ydim)
44 {
45 dc->Dc_Attr.szlViewportExt.cx = dc->Dc_Attr.szlViewportExt.cx * abs(ydim / xdim);
46 if (!dc->Dc_Attr.szlViewportExt.cx) dc->Dc_Attr.szlViewportExt.cx = 1;
47 }
48 else
49 {
50 dc->Dc_Attr.szlViewportExt.cy = dc->Dc_Attr.szlViewportExt.cy * abs(xdim / ydim);
51 if (!dc->Dc_Attr.szlViewportExt.cy) dc->Dc_Attr.szlViewportExt.cy = 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->Dc_Attr.iGraphicsMode;
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->Dc_Attr.iGraphicsMode;
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;
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;
397 NTSTATUS Status = STATUS_SUCCESS;
398 LPPOINT Points;
399 ULONG Size;
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
477 BOOL
478 APIENTRY
479 NtGdiTransformPoints( HDC hdc,
480 PPOINT UnsafePtsIn,
481 PPOINT UnsafePtOut,
482 INT Count,
483 INT iMode )
484 {
485 UNIMPLEMENTED;
486 return FALSE;
487 }
488
489 BOOL
490 STDCALL
491 NtGdiModifyWorldTransform(HDC hDC,
492 CONST LPXFORM UnsafeXForm,
493 DWORD Mode)
494 {
495 PDC dc;
496 XFORM SafeXForm;
497 BOOL Ret = FALSE;
498
499 if (!UnsafeXForm)
500 {
501 SetLastWin32Error(ERROR_INVALID_PARAMETER);
502 return FALSE;
503 }
504
505 dc = DC_LockDc(hDC);
506 if (!dc)
507 {
508 SetLastWin32Error(ERROR_INVALID_HANDLE);
509 return FALSE;
510 }
511
512 _SEH_TRY
513 {
514 ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
515 RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM));
516
517 Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
518 }
519 _SEH_HANDLE
520 {
521 SetLastNtError(_SEH_GetExceptionCode());
522 }
523 _SEH_END;
524
525 DC_UnlockDc(dc);
526 return Ret;
527 }
528
529 BOOL
530 STDCALL
531 NtGdiOffsetViewportOrgEx(HDC hDC,
532 int XOffset,
533 int YOffset,
534 LPPOINT UnsafePoint)
535 {
536 PDC dc;
537 NTSTATUS Status = STATUS_SUCCESS;
538
539 dc = DC_LockDc ( hDC );
540 if(!dc)
541 {
542 SetLastWin32Error(ERROR_INVALID_HANDLE);
543 return FALSE;
544 }
545
546 if (UnsafePoint)
547 {
548 _SEH_TRY
549 {
550 ProbeForWrite(UnsafePoint,
551 sizeof(POINT),
552 1);
553 UnsafePoint->x = dc->Dc_Attr.ptlViewportOrg.x;
554 UnsafePoint->y = dc->Dc_Attr.ptlViewportOrg.y;
555 }
556 _SEH_HANDLE
557 {
558 Status = _SEH_GetExceptionCode();
559 }
560 _SEH_END;
561
562 if ( !NT_SUCCESS(Status) )
563 {
564 SetLastNtError(Status);
565 DC_UnlockDc(dc);
566 return FALSE;
567 }
568 }
569
570 dc->Dc_Attr.ptlViewportOrg.x += XOffset;
571 dc->Dc_Attr.ptlViewportOrg.y += YOffset;
572 DC_UpdateXforms(dc);
573
574 DC_UnlockDc(dc);
575 return TRUE;
576 }
577
578 BOOL
579 STDCALL
580 NtGdiOffsetWindowOrgEx(HDC hDC,
581 int XOffset,
582 int YOffset,
583 LPPOINT Point)
584 {
585 PDC dc;
586
587 dc = DC_LockDc(hDC);
588 if (!dc)
589 {
590 SetLastWin32Error(ERROR_INVALID_HANDLE);
591 return FALSE;
592 }
593
594 if (Point)
595 {
596 NTSTATUS Status = STATUS_SUCCESS;
597
598 _SEH_TRY
599 {
600 ProbeForWrite(Point,
601 sizeof(POINT),
602 1);
603 Point->x = dc->Dc_Attr.ptlWindowOrg.x;
604 Point->y = dc->Dc_Attr.ptlWindowOrg.y;
605 }
606 _SEH_HANDLE
607 {
608 Status = _SEH_GetExceptionCode();
609 }
610 _SEH_END;
611
612 if(!NT_SUCCESS(Status))
613 {
614 SetLastNtError(Status);
615 DC_UnlockDc(dc);
616 return FALSE;
617 }
618 }
619
620 dc->Dc_Attr.ptlWindowOrg.x += XOffset;
621 dc->Dc_Attr.ptlWindowOrg.y += YOffset;
622
623 DC_UpdateXforms(dc);
624 DC_UnlockDc(dc);
625
626 return TRUE;
627 }
628
629 BOOL
630 STDCALL
631 NtGdiScaleViewportExtEx(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 BOOL
643 STDCALL
644 NtGdiScaleWindowExtEx(HDC hDC,
645 int Xnum,
646 int Xdenom,
647 int Ynum,
648 int Ydenom,
649 LPSIZE Size)
650 {
651 UNIMPLEMENTED;
652 return FALSE;
653 }
654
655 int
656 STDCALL
657 NtGdiSetGraphicsMode(HDC hDC,
658 int Mode)
659 {
660 INT ret;
661 PDC dc;
662
663 dc = DC_LockDc (hDC);
664 if (!dc)
665 {
666 SetLastWin32Error(ERROR_INVALID_HANDLE);
667 return 0;
668 }
669
670 /* One would think that setting the graphics mode to GM_COMPATIBLE
671 * would also reset the world transformation matrix to the unity
672 * matrix. However, in Windows, this is not the case. This doesn't
673 * make a lot of sense to me, but that's the way it is.
674 */
675
676 if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
677 {
678 DC_UnlockDc(dc);
679 SetLastWin32Error(ERROR_INVALID_PARAMETER);
680 return 0;
681 }
682
683 ret = dc->Dc_Attr.iGraphicsMode;
684 dc->Dc_Attr.iGraphicsMode = Mode;
685 DC_UnlockDc(dc);
686 return ret;
687 }
688
689 int
690 STDCALL
691 NtGdiSetMapMode(HDC hDC,
692 int MapMode)
693 {
694 int PrevMapMode;
695 PDC dc;
696
697 dc = DC_LockDc(hDC);
698 if (!dc)
699 {
700 SetLastWin32Error(ERROR_INVALID_HANDLE);
701 return 0;
702 }
703
704 PrevMapMode = dc->Dc_Attr.iMapMode;
705
706 if (MapMode != dc->Dc_Attr.iMapMode || (MapMode != MM_ISOTROPIC && MapMode != MM_ANISOTROPIC))
707 {
708 dc->Dc_Attr.iMapMode = MapMode;
709
710 switch (MapMode)
711 {
712 case MM_TEXT:
713 dc->Dc_Attr.szlWindowExt.cx = 1;
714 dc->Dc_Attr.szlWindowExt.cy = 1;
715 dc->Dc_Attr.szlViewportExt.cx = 1;
716 dc->Dc_Attr.szlViewportExt.cy = 1;
717 break;
718
719 case MM_LOMETRIC:
720 case MM_ISOTROPIC:
721 dc->Dc_Attr.szlWindowExt.cx = dc->GDIInfo->ulHorzSize * 10;
722 dc->Dc_Attr.szlWindowExt.cy = dc->GDIInfo->ulVertSize * 10;
723 dc->Dc_Attr.szlViewportExt.cx = dc->GDIInfo->ulHorzRes;
724 dc->Dc_Attr.szlViewportExt.cy = -dc->GDIInfo->ulVertRes;
725 break;
726
727 case MM_HIMETRIC:
728 dc->Dc_Attr.szlWindowExt.cx = dc->GDIInfo->ulHorzSize * 100;
729 dc->Dc_Attr.szlWindowExt.cy = dc->GDIInfo->ulVertSize * 100;
730 dc->Dc_Attr.szlViewportExt.cx = dc->GDIInfo->ulHorzRes;
731 dc->Dc_Attr.szlViewportExt.cy = -dc->GDIInfo->ulVertRes;
732 break;
733
734 case MM_LOENGLISH:
735 dc->Dc_Attr.szlWindowExt.cx = EngMulDiv(1000, dc->GDIInfo->ulHorzSize, 254);
736 dc->Dc_Attr.szlWindowExt.cy = EngMulDiv(1000, dc->GDIInfo->ulVertSize, 254);
737 dc->Dc_Attr.szlViewportExt.cx = dc->GDIInfo->ulHorzRes;
738 dc->Dc_Attr.szlViewportExt.cy = -dc->GDIInfo->ulVertRes;
739 break;
740
741 case MM_HIENGLISH:
742 dc->Dc_Attr.szlWindowExt.cx = EngMulDiv(10000, dc->GDIInfo->ulHorzSize, 254);
743 dc->Dc_Attr.szlWindowExt.cy = EngMulDiv(10000, dc->GDIInfo->ulVertSize, 254);
744 dc->Dc_Attr.szlViewportExt.cx = dc->GDIInfo->ulHorzRes;
745 dc->Dc_Attr.szlViewportExt.cy = -dc->GDIInfo->ulVertRes;
746 break;
747
748 case MM_TWIPS:
749 dc->Dc_Attr.szlWindowExt.cx = EngMulDiv(14400, dc->GDIInfo->ulHorzSize, 254);
750 dc->Dc_Attr.szlWindowExt.cy = EngMulDiv(14400, dc->GDIInfo->ulVertSize, 254);
751 dc->Dc_Attr.szlViewportExt.cx = dc->GDIInfo->ulHorzRes;
752 dc->Dc_Attr.szlViewportExt.cy = -dc->GDIInfo->ulVertRes;
753 break;
754
755 case MM_ANISOTROPIC:
756 break;
757 }
758
759 DC_UpdateXforms(dc);
760 }
761
762 DC_UnlockDc(dc);
763
764 return PrevMapMode;
765 }
766
767 BOOL
768 STDCALL
769 NtGdiSetViewportExtEx(HDC hDC,
770 int XExtent,
771 int YExtent,
772 LPSIZE Size)
773 {
774 PDC dc;
775
776 dc = DC_LockDc(hDC);
777 if ( !dc )
778 {
779 SetLastWin32Error(ERROR_INVALID_HANDLE);
780 return FALSE;
781 }
782
783 switch (dc->Dc_Attr.iMapMode)
784 {
785 case MM_HIENGLISH:
786 case MM_HIMETRIC:
787 case MM_LOENGLISH:
788 case MM_LOMETRIC:
789 case MM_TEXT:
790 case MM_TWIPS:
791 DC_UnlockDc(dc);
792 return FALSE;
793
794 case MM_ISOTROPIC:
795 // Here we should (probably) check that SetWindowExtEx *really* has
796 // been called
797 break;
798 }
799
800 if (Size)
801 {
802 NTSTATUS Status = STATUS_SUCCESS;
803
804 _SEH_TRY
805 {
806 ProbeForWrite(Size,
807 sizeof(SIZE),
808 1);
809 Size->cx = dc->Dc_Attr.szlViewportExt.cx;
810 Size->cy = dc->Dc_Attr.szlViewportExt.cy;
811
812 dc->Dc_Attr.szlViewportExt.cx = XExtent;
813 dc->Dc_Attr.szlViewportExt.cy = YExtent;
814
815 if (dc->Dc_Attr.iMapMode == MM_ISOTROPIC)
816 IntFixIsotropicMapping(dc);
817 }
818 _SEH_HANDLE
819 {
820 Status = _SEH_GetExceptionCode();
821 }
822 _SEH_END;
823
824 if(!NT_SUCCESS(Status))
825 {
826 SetLastNtError(Status);
827 DC_UnlockDc(dc);
828 return FALSE;
829 }
830 }
831
832
833 DC_UpdateXforms(dc);
834 DC_UnlockDc(dc);
835
836 return TRUE;
837 }
838
839 BOOL
840 STDCALL
841 NtGdiSetViewportOrgEx(HDC hDC,
842 int X,
843 int Y,
844 LPPOINT Point)
845 {
846 PDC dc;
847
848 dc = DC_LockDc(hDC);
849 if (!dc)
850 {
851 SetLastWin32Error(ERROR_INVALID_HANDLE);
852 return FALSE;
853 }
854
855 if (Point)
856 {
857 NTSTATUS Status = STATUS_SUCCESS;
858
859 _SEH_TRY
860 {
861 ProbeForWrite(Point,
862 sizeof(POINT),
863 1);
864 Point->x = dc->Dc_Attr.ptlViewportOrg.x;
865 Point->y = dc->Dc_Attr.ptlViewportOrg.y;
866 }
867 _SEH_HANDLE
868 {
869 Status = _SEH_GetExceptionCode();
870 }
871 _SEH_END;
872
873 if(!NT_SUCCESS(Status))
874 {
875 SetLastNtError(Status);
876 DC_UnlockDc(dc);
877 return FALSE;
878 }
879 }
880
881 dc->Dc_Attr.ptlViewportOrg.x = X;
882 dc->Dc_Attr.ptlViewportOrg.y = Y;
883
884 DC_UpdateXforms(dc);
885 DC_UnlockDc(dc);
886
887 return TRUE;
888 }
889
890 BOOL
891 STDCALL
892 NtGdiSetWindowExtEx(HDC hDC,
893 int XExtent,
894 int YExtent,
895 LPSIZE Size)
896 {
897 PDC dc;
898
899 dc = DC_LockDc(hDC);
900 if (!dc)
901 {
902 SetLastWin32Error(ERROR_INVALID_HANDLE);
903 return FALSE;
904 }
905
906 switch (dc->Dc_Attr.iMapMode)
907 {
908 case MM_HIENGLISH:
909 case MM_HIMETRIC:
910 case MM_LOENGLISH:
911 case MM_LOMETRIC:
912 case MM_TEXT:
913 case MM_TWIPS:
914 DC_UnlockDc(dc);
915 return FALSE;
916 }
917
918 if (Size)
919 {
920 NTSTATUS Status = STATUS_SUCCESS;
921
922 _SEH_TRY
923 {
924 ProbeForWrite(Size,
925 sizeof(SIZE),
926 1);
927 Size->cx = dc->Dc_Attr.szlWindowExt.cx;
928 Size->cy = dc->Dc_Attr.szlWindowExt.cy;
929 }
930 _SEH_HANDLE
931 {
932 Status = _SEH_GetExceptionCode();
933 }
934 _SEH_END;
935
936 if(!NT_SUCCESS(Status))
937 {
938 SetLastNtError(Status);
939 DC_UnlockDc(dc);
940 return FALSE;
941 }
942 }
943
944 dc->Dc_Attr.szlWindowExt.cx = XExtent;
945 dc->Dc_Attr.szlWindowExt.cy = YExtent;
946
947 DC_UpdateXforms(dc);
948 DC_UnlockDc(dc);
949
950 return TRUE;
951 }
952
953 BOOL
954 STDCALL
955 NtGdiSetWindowOrgEx(HDC hDC,
956 int X,
957 int Y,
958 LPPOINT Point)
959 {
960 PDC dc;
961
962 dc = DC_LockDc(hDC);
963 if (!dc)
964 {
965 SetLastWin32Error(ERROR_INVALID_HANDLE);
966 return FALSE;
967 }
968
969 if (Point)
970 {
971 NTSTATUS Status = STATUS_SUCCESS;
972
973 _SEH_TRY
974 {
975 ProbeForWrite(Point,
976 sizeof(POINT),
977 1);
978 Point->x = dc->Dc_Attr.ptlWindowOrg.x;
979 Point->y = dc->Dc_Attr.ptlWindowOrg.y;
980 }
981 _SEH_HANDLE
982 {
983 Status = _SEH_GetExceptionCode();
984 }
985 _SEH_END;
986
987 if(!NT_SUCCESS(Status))
988 {
989 SetLastNtError(Status);
990 DC_UnlockDc(dc);
991 return FALSE;
992 }
993 }
994
995 dc->Dc_Attr.ptlWindowOrg.x = X;
996 dc->Dc_Attr.ptlWindowOrg.y = Y;
997
998 DC_UpdateXforms(dc);
999 DC_UnlockDc(dc);
1000
1001 return TRUE;
1002 }
1003
1004 BOOL
1005 STDCALL
1006 NtGdiSetWorldTransform(HDC hDC,
1007 CONST LPXFORM XForm)
1008 {
1009 PDC dc;
1010 NTSTATUS Status = STATUS_SUCCESS;
1011
1012 dc = DC_LockDc (hDC);
1013 if ( !dc )
1014 {
1015 SetLastWin32Error(ERROR_INVALID_HANDLE);
1016 return FALSE;
1017 }
1018
1019 if (!XForm)
1020 {
1021 DC_UnlockDc(dc);
1022 /* Win doesn't set LastError */
1023 return FALSE;
1024 }
1025
1026 /* Check that graphics mode is GM_ADVANCED */
1027 if ( dc->Dc_Attr.iGraphicsMode != GM_ADVANCED )
1028 {
1029 DC_UnlockDc(dc);
1030 return FALSE;
1031 }
1032
1033 _SEH_TRY
1034 {
1035 ProbeForRead(XForm,
1036 sizeof(XFORM),
1037 1);
1038 dc->w.xformWorld2Wnd = *XForm;
1039 }
1040 _SEH_HANDLE
1041 {
1042 Status = _SEH_GetExceptionCode();
1043 }
1044 _SEH_END;
1045
1046 if(!NT_SUCCESS(Status))
1047 {
1048 DC_UnlockDc(dc);
1049 return FALSE;
1050 }
1051
1052 DC_UpdateXforms(dc);
1053 DC_UnlockDc(dc);
1054 return TRUE;
1055 }
1056
1057 /* EOF */