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