Change DC and DC_ATTR members from MATRIX_S and EFLOAT_S, which are explicit fpu...
[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 /*
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 XFORM xformTemp;
72 /* Check for illegal parameters */
73 if (!XFormResult || !xform1 || !xform2)
74 {
75 return FALSE;
76 }
77
78 /* Create the result in a temporary XFORM, since xformResult may be
79 * equal to xform1 or xform2 */
80 xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
81 xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
82 xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
83 xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
84 xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
85 xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
86 *XFormResult = xformTemp;
87
88 return TRUE;
89 }
90
91 BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
92 LPXFORM Unsafexform1,
93 LPXFORM Unsafexform2)
94 {
95 BOOL Ret;
96
97 _SEH_TRY
98 {
99 ProbeForWrite(UnsafeXFormResult,
100 sizeof(XFORM),
101 1);
102 ProbeForRead(Unsafexform1,
103 sizeof(XFORM),
104 1);
105 ProbeForRead(Unsafexform2,
106 sizeof(XFORM),
107 1);
108 Ret = IntGdiCombineTransform(UnsafeXFormResult, Unsafexform1, Unsafexform2);
109 }
110 _SEH_HANDLE
111 {
112 Ret = FALSE;
113 }
114 _SEH_END;
115
116 return Ret;
117 }
118
119
120 int
121 FASTCALL
122 IntGetGraphicsMode ( PDC dc )
123 {
124 PDC_ATTR Dc_Attr;
125 ASSERT ( dc );
126 Dc_Attr = dc->pDc_Attr;
127 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
128 return Dc_Attr->iGraphicsMode;
129 }
130
131 BOOL
132 FASTCALL
133 IntGdiModifyWorldTransform(PDC pDc,
134 CONST LPXFORM lpXForm,
135 DWORD Mode)
136 {
137 ASSERT(pDc);
138 XFORM xformWorld2Wnd;
139
140 switch(Mode)
141 {
142 case MWT_IDENTITY:
143 xformWorld2Wnd.eM11 = 1.0f;
144 xformWorld2Wnd.eM12 = 0.0f;
145 xformWorld2Wnd.eM21 = 0.0f;
146 xformWorld2Wnd.eM22 = 1.0f;
147 xformWorld2Wnd.eDx = 0.0f;
148 xformWorld2Wnd.eDy = 0.0f;
149 XForm2MatrixS(&pDc->DcLevel.mxWorldToPage, &xformWorld2Wnd);
150 break;
151
152 case MWT_LEFTMULTIPLY:
153 MatrixS2XForm(&xformWorld2Wnd, &pDc->DcLevel.mxWorldToPage);
154 IntGdiCombineTransform(&xformWorld2Wnd, lpXForm, &xformWorld2Wnd);
155 XForm2MatrixS(&pDc->DcLevel.mxWorldToPage, &xformWorld2Wnd);
156 break;
157
158 case MWT_RIGHTMULTIPLY:
159 MatrixS2XForm(&xformWorld2Wnd, &pDc->DcLevel.mxWorldToPage);
160 IntGdiCombineTransform(&xformWorld2Wnd, &xformWorld2Wnd, lpXForm);
161 XForm2MatrixS(&pDc->DcLevel.mxWorldToPage, &xformWorld2Wnd);
162 break;
163
164 case MWT_MAX+1: // Must be MWT_SET????
165 XForm2MatrixS(&pDc->DcLevel.mxWorldToPage, lpXForm); // Do it like Wine.
166 break;
167
168 default:
169 return FALSE;
170 }
171 DC_UpdateXforms(pDc);
172 return TRUE;
173 }
174
175 BOOL
176 STDCALL
177 NtGdiGetTransform(HDC hDC,
178 DWORD iXform,
179 LPXFORM XForm)
180 {
181 PDC dc;
182 NTSTATUS Status = STATUS_SUCCESS;
183
184 dc = DC_LockDc ( hDC );
185 if (!dc)
186 {
187 SetLastWin32Error(ERROR_INVALID_HANDLE);
188 return FALSE;
189 }
190 if (!XForm)
191 {
192 DC_UnlockDc(dc);
193 SetLastWin32Error(ERROR_INVALID_PARAMETER);
194 return FALSE;
195 }
196
197 _SEH_TRY
198 {
199 ProbeForWrite(XForm,
200 sizeof(XFORM),
201 1);
202 switch(iXform)
203 {
204 case GdiWorldSpaceToPageSpace:
205 MatrixS2XForm(XForm, &dc->DcLevel.mxWorldToPage);
206 break;
207 default:
208 break;
209 }
210 }
211 _SEH_HANDLE
212 {
213 Status = _SEH_GetExceptionCode();
214 }
215 _SEH_END;
216
217 DC_UnlockDc(dc);
218 return NT_SUCCESS(Status);
219 }
220
221
222 /*!
223 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
224 * world transfrom, viewport origin settings for the given device context.
225 * \param hDC device context.
226 * \param Points an array of POINT structures (in/out).
227 * \param Count number of elements in the array of POINT structures.
228 * \return TRUE if success.
229 */
230 BOOL
231 APIENTRY
232 NtGdiTransformPoints( HDC hDC,
233 PPOINT UnsafePtsIn,
234 PPOINT UnsafePtOut,
235 INT Count,
236 INT iMode )
237 {
238 PDC dc;
239 NTSTATUS Status = STATUS_SUCCESS;
240 LPPOINT Points;
241 ULONG Size;
242
243 dc = DC_LockDc(hDC);
244 if (!dc)
245 {
246 SetLastWin32Error(ERROR_INVALID_HANDLE);
247 return FALSE;
248 }
249
250 if (!UnsafePtsIn || !UnsafePtOut || Count <= 0)
251 {
252 DC_UnlockDc(dc);
253 SetLastWin32Error(ERROR_INVALID_PARAMETER);
254 return FALSE;
255 }
256
257 Size = Count * sizeof(POINT);
258
259 Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
260 if(!Points)
261 {
262 DC_UnlockDc(dc);
263 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
264 return FALSE;
265 }
266
267 _SEH_TRY
268 {
269 ProbeForWrite(UnsafePtOut,
270 Size,
271 1);
272 ProbeForRead(UnsafePtsIn,
273 Size,
274 1);
275 RtlCopyMemory(Points,
276 UnsafePtsIn,
277 Size);
278 }
279 _SEH_HANDLE
280 {
281 Status = _SEH_GetExceptionCode();
282 }
283 _SEH_END;
284
285 if(!NT_SUCCESS(Status))
286 {
287 DC_UnlockDc(dc);
288 ExFreePool(Points);
289 SetLastNtError(Status);
290 return FALSE;
291 }
292
293 switch (iMode)
294 {
295 case GdiDpToLp:
296 IntDPtoLP(dc, Points, Count);
297 break;
298 case GdiLpToDp:
299 IntLPtoDP(dc, Points, Count);
300 break;
301 case 2: // Not supported yet. Need testing.
302 default:
303 {
304 DC_UnlockDc(dc);
305 ExFreePool(Points);
306 SetLastWin32Error(ERROR_INVALID_PARAMETER);
307 return FALSE;
308 }
309 }
310
311 _SEH_TRY
312 {
313 /* pointer was already probed! */
314 RtlCopyMemory(UnsafePtOut,
315 Points,
316 Size);
317 }
318 _SEH_HANDLE
319 {
320 Status = _SEH_GetExceptionCode();
321 }
322 _SEH_END;
323
324 if(!NT_SUCCESS(Status))
325 {
326 DC_UnlockDc(dc);
327 ExFreePool(Points);
328 SetLastNtError(Status);
329 return FALSE;
330 }
331 //
332 // If we are getting called that means User XForms is a mess!
333 //
334 DC_UnlockDc(dc);
335 ExFreePool(Points);
336 return TRUE;
337 }
338
339 BOOL
340 STDCALL
341 NtGdiModifyWorldTransform(HDC hDC,
342 LPXFORM UnsafeXForm,
343 DWORD Mode)
344 {
345 PDC dc;
346 XFORM SafeXForm;
347 BOOL Ret = TRUE;
348
349 dc = DC_LockDc(hDC);
350 if (!dc)
351 {
352 SetLastWin32Error(ERROR_INVALID_HANDLE);
353 return FALSE;
354 }
355
356 // The xform is permitted to be NULL for MWT_IDENTITY.
357 // However, if it is not NULL, then it must be valid even though it is not used.
358 if (UnsafeXForm != NULL || Mode != MWT_IDENTITY)
359 {
360 _SEH_TRY
361 {
362 ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
363 RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM));
364 }
365 _SEH_HANDLE
366 {
367 Ret = FALSE;
368 }
369 _SEH_END;
370 }
371
372 // Safe to handle kernel mode data.
373 if (Ret) Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
374 DC_UnlockDc(dc);
375 return Ret;
376 }
377
378 BOOL
379 STDCALL
380 NtGdiOffsetViewportOrgEx(HDC hDC,
381 int XOffset,
382 int YOffset,
383 LPPOINT UnsafePoint)
384 {
385 PDC dc;
386 PDC_ATTR Dc_Attr;
387 NTSTATUS Status = STATUS_SUCCESS;
388
389 dc = DC_LockDc ( hDC );
390 if(!dc)
391 {
392 SetLastWin32Error(ERROR_INVALID_HANDLE);
393 return FALSE;
394 }
395 Dc_Attr = dc->pDc_Attr;
396 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
397
398 if (UnsafePoint)
399 {
400 _SEH_TRY
401 {
402 ProbeForWrite(UnsafePoint,
403 sizeof(POINT),
404 1);
405 UnsafePoint->x = Dc_Attr->ptlViewportOrg.x;
406 UnsafePoint->y = Dc_Attr->ptlViewportOrg.y;
407 }
408 _SEH_HANDLE
409 {
410 Status = _SEH_GetExceptionCode();
411 }
412 _SEH_END;
413
414 if ( !NT_SUCCESS(Status) )
415 {
416 SetLastNtError(Status);
417 DC_UnlockDc(dc);
418 return FALSE;
419 }
420 }
421
422 Dc_Attr->ptlViewportOrg.x += XOffset;
423 Dc_Attr->ptlViewportOrg.y += YOffset;
424 DC_UpdateXforms(dc);
425 DC_UnlockDc(dc);
426 return TRUE;
427 }
428
429 BOOL
430 STDCALL
431 NtGdiOffsetWindowOrgEx(HDC hDC,
432 int XOffset,
433 int YOffset,
434 LPPOINT Point)
435 {
436 PDC dc;
437 PDC_ATTR Dc_Attr;
438
439 dc = DC_LockDc(hDC);
440 if (!dc)
441 {
442 SetLastWin32Error(ERROR_INVALID_HANDLE);
443 return FALSE;
444 }
445 Dc_Attr = dc->pDc_Attr;
446 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
447
448 if (Point)
449 {
450 NTSTATUS Status = STATUS_SUCCESS;
451
452 _SEH_TRY
453 {
454 ProbeForWrite(Point,
455 sizeof(POINT),
456 1);
457 Point->x = Dc_Attr->ptlWindowOrg.x;
458 Point->y = Dc_Attr->ptlWindowOrg.y;
459 }
460 _SEH_HANDLE
461 {
462 Status = _SEH_GetExceptionCode();
463 }
464 _SEH_END;
465
466 if(!NT_SUCCESS(Status))
467 {
468 SetLastNtError(Status);
469 DC_UnlockDc(dc);
470 return FALSE;
471 }
472 }
473
474 Dc_Attr->ptlWindowOrg.x += XOffset;
475 Dc_Attr->ptlWindowOrg.y += YOffset;
476
477 DC_UpdateXforms(dc);
478 DC_UnlockDc(dc);
479
480 return TRUE;
481 }
482
483 BOOL
484 STDCALL
485 NtGdiScaleViewportExtEx(HDC hDC,
486 int Xnum,
487 int Xdenom,
488 int Ynum,
489 int Ydenom,
490 LPSIZE pSize)
491 {
492 PDC pDC;
493 PDC_ATTR pDc_Attr;
494 BOOL Ret = FALSE;
495 LONG X, Y;
496
497 pDC = DC_LockDc(hDC);
498 if (!pDC)
499 {
500 SetLastWin32Error(ERROR_INVALID_HANDLE);
501 return FALSE;
502 }
503 pDc_Attr = pDC->pDc_Attr;
504 if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
505
506 if ( pSize )
507 {
508 NTSTATUS Status = STATUS_SUCCESS;
509
510 _SEH_TRY
511 {
512 ProbeForWrite(pSize,
513 sizeof(LPSIZE),
514 1);
515
516 pSize->cx = pDc_Attr->szlViewportExt.cx;
517 pSize->cy = pDc_Attr->szlViewportExt.cy;
518 }
519 _SEH_HANDLE
520 {
521 Status = _SEH_GetExceptionCode();
522 }
523 _SEH_END;
524
525 if(!NT_SUCCESS(Status))
526 {
527 SetLastNtError(Status);
528 DC_UnlockDc(pDC);
529 return FALSE;
530 }
531 }
532
533 if (pDc_Attr->iMapMode > MM_TWIPS)
534 {
535 if ( ( Xdenom ) && ( Ydenom ) )
536 {
537 X = Xnum * pDc_Attr->szlViewportExt.cx / Xdenom;
538 if ( X )
539 {
540 Y = Ynum * pDc_Attr->szlViewportExt.cy / Ydenom;
541 if ( Y )
542 {
543 pDc_Attr->szlViewportExt.cx = X;
544 pDc_Attr->szlViewportExt.cy = Y;
545
546 IntMirrorWindowOrg(pDC);
547
548 pDc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
549
550 if (pDc_Attr->iMapMode == MM_ISOTROPIC) IntFixIsotropicMapping(pDC);
551 DC_UpdateXforms(pDC);
552
553 Ret = TRUE;
554 }
555 }
556 }
557 }
558 else
559 Ret = TRUE;
560
561 DC_UnlockDc(pDC);
562 return Ret;
563 }
564
565 BOOL
566 STDCALL
567 NtGdiScaleWindowExtEx(HDC hDC,
568 int Xnum,
569 int Xdenom,
570 int Ynum,
571 int Ydenom,
572 LPSIZE pSize)
573 {
574 PDC pDC;
575 PDC_ATTR pDc_Attr;
576 BOOL Ret = FALSE;
577 LONG X, Y;
578
579 pDC = DC_LockDc(hDC);
580 if (!pDC)
581 {
582 SetLastWin32Error(ERROR_INVALID_HANDLE);
583 return FALSE;
584 }
585 pDc_Attr = pDC->pDc_Attr;
586 if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
587
588 if ( pSize )
589 {
590 NTSTATUS Status = STATUS_SUCCESS;
591
592 _SEH_TRY
593 {
594 ProbeForWrite(pSize,
595 sizeof(LPSIZE),
596 1);
597
598 X = pDc_Attr->szlWindowExt.cx;
599 if (pDc_Attr->dwLayout & LAYOUT_RTL) X = -X;
600 pSize->cx = X;
601 pSize->cy = pDc_Attr->szlWindowExt.cy;
602 }
603 _SEH_HANDLE
604 {
605 Status = _SEH_GetExceptionCode();
606 }
607 _SEH_END;
608
609 if(!NT_SUCCESS(Status))
610 {
611 SetLastNtError(Status);
612 DC_UnlockDc(pDC);
613 return FALSE;
614 }
615 }
616
617 if (pDc_Attr->iMapMode > MM_TWIPS)
618 {
619 if (( Xdenom ) && ( Ydenom ))
620 {
621 X = Xnum * pDc_Attr->szlWindowExt.cx / Xdenom;
622 if ( X )
623 {
624 Y = Ynum * pDc_Attr->szlWindowExt.cy / Ydenom;
625 if ( Y )
626 {
627 pDc_Attr->szlWindowExt.cx = X;
628 pDc_Attr->szlWindowExt.cy = Y;
629
630 IntMirrorWindowOrg(pDC);
631
632 pDc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
633
634 if (pDc_Attr->iMapMode == MM_ISOTROPIC) IntFixIsotropicMapping(pDC);
635 DC_UpdateXforms(pDC);
636
637 Ret = TRUE;
638 }
639 }
640 }
641 }
642 else
643 Ret = TRUE;
644
645 DC_UnlockDc(pDC);
646 return Ret;
647 }
648
649 int
650 STDCALL
651 IntGdiSetMapMode(PDC dc,
652 int MapMode)
653 {
654 int PrevMapMode;
655 PDC_ATTR Dc_Attr = dc->pDc_Attr;
656 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
657
658 PrevMapMode = Dc_Attr->iMapMode;
659
660 if (MapMode != Dc_Attr->iMapMode || (MapMode != MM_ISOTROPIC && MapMode != MM_ANISOTROPIC))
661 {
662 Dc_Attr->iMapMode = MapMode;
663
664 switch (MapMode)
665 {
666 case MM_TEXT:
667 Dc_Attr->szlWindowExt.cx = 1;
668 Dc_Attr->szlWindowExt.cy = 1;
669 Dc_Attr->szlViewportExt.cx = 1;
670 Dc_Attr->szlViewportExt.cy = 1;
671 break;
672
673 case MM_LOMETRIC:
674 case MM_ISOTROPIC:
675 Dc_Attr->szlWindowExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzSize * 10;
676 Dc_Attr->szlWindowExt.cy = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertSize * 10;
677 Dc_Attr->szlViewportExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzRes;
678 Dc_Attr->szlViewportExt.cy = -((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertRes;
679 break;
680
681 case MM_HIMETRIC:
682 Dc_Attr->szlWindowExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzSize * 100;
683 Dc_Attr->szlWindowExt.cy = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertSize * 100;
684 Dc_Attr->szlViewportExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzRes;
685 Dc_Attr->szlViewportExt.cy = -((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertRes;
686 break;
687
688 case MM_LOENGLISH:
689 Dc_Attr->szlWindowExt.cx = EngMulDiv(1000, ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzSize, 254);
690 Dc_Attr->szlWindowExt.cy = EngMulDiv(1000, ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertSize, 254);
691 Dc_Attr->szlViewportExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzRes;
692 Dc_Attr->szlViewportExt.cy = -((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertRes;
693 break;
694
695 case MM_HIENGLISH:
696 Dc_Attr->szlWindowExt.cx = EngMulDiv(10000, ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzSize, 254);
697 Dc_Attr->szlWindowExt.cy = EngMulDiv(10000, ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertSize, 254);
698 Dc_Attr->szlViewportExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzRes;
699 Dc_Attr->szlViewportExt.cy = -((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertRes;
700 break;
701
702 case MM_TWIPS:
703 Dc_Attr->szlWindowExt.cx = EngMulDiv(14400, ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzSize, 254);
704 Dc_Attr->szlWindowExt.cy = EngMulDiv(14400, ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertSize, 254);
705 Dc_Attr->szlViewportExt.cx = ((PGDIDEVICE)dc->pPDev)->GDIInfo.ulHorzRes;
706 Dc_Attr->szlViewportExt.cy = -((PGDIDEVICE)dc->pPDev)->GDIInfo.ulVertRes;
707 break;
708
709 case MM_ANISOTROPIC:
710 break;
711 }
712
713 DC_UpdateXforms(dc);
714 }
715
716 return PrevMapMode;
717 }
718
719 BOOL
720 STDCALL
721 NtGdiSetViewportExtEx(HDC hDC,
722 int XExtent,
723 int YExtent,
724 LPSIZE Size)
725 {
726 PDC dc;
727 PDC_ATTR Dc_Attr;
728
729 dc = DC_LockDc(hDC);
730 if ( !dc )
731 {
732 SetLastWin32Error(ERROR_INVALID_HANDLE);
733 return FALSE;
734 }
735 Dc_Attr = dc->pDc_Attr;
736 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
737
738 switch (Dc_Attr->iMapMode)
739 {
740 case MM_HIENGLISH:
741 case MM_HIMETRIC:
742 case MM_LOENGLISH:
743 case MM_LOMETRIC:
744 case MM_TEXT:
745 case MM_TWIPS:
746 DC_UnlockDc(dc);
747 return FALSE;
748
749 case MM_ISOTROPIC:
750 // Here we should (probably) check that SetWindowExtEx *really* has
751 // been called
752 break;
753 }
754
755 if (Size)
756 {
757 NTSTATUS Status = STATUS_SUCCESS;
758
759 _SEH_TRY
760 {
761 ProbeForWrite(Size,
762 sizeof(SIZE),
763 1);
764 Size->cx = Dc_Attr->szlViewportExt.cx;
765 Size->cy = Dc_Attr->szlViewportExt.cy;
766
767 Dc_Attr->szlViewportExt.cx = XExtent;
768 Dc_Attr->szlViewportExt.cy = YExtent;
769
770 if (Dc_Attr->iMapMode == MM_ISOTROPIC)
771 IntFixIsotropicMapping(dc);
772 }
773 _SEH_HANDLE
774 {
775 Status = _SEH_GetExceptionCode();
776 }
777 _SEH_END;
778
779 if(!NT_SUCCESS(Status))
780 {
781 SetLastNtError(Status);
782 DC_UnlockDc(dc);
783 return FALSE;
784 }
785 }
786
787
788 DC_UpdateXforms(dc);
789 DC_UnlockDc(dc);
790
791 return TRUE;
792 }
793
794 BOOL
795 STDCALL
796 NtGdiSetViewportOrgEx(HDC hDC,
797 int X,
798 int Y,
799 LPPOINT Point)
800 {
801 PDC dc;
802 PDC_ATTR Dc_Attr;
803
804 dc = DC_LockDc(hDC);
805 if (!dc)
806 {
807 SetLastWin32Error(ERROR_INVALID_HANDLE);
808 return FALSE;
809 }
810 Dc_Attr = dc->pDc_Attr;
811 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
812
813 if (Point)
814 {
815 NTSTATUS Status = STATUS_SUCCESS;
816
817 _SEH_TRY
818 {
819 ProbeForWrite(Point,
820 sizeof(POINT),
821 1);
822 Point->x = Dc_Attr->ptlViewportOrg.x;
823 Point->y = Dc_Attr->ptlViewportOrg.y;
824 }
825 _SEH_HANDLE
826 {
827 Status = _SEH_GetExceptionCode();
828 }
829 _SEH_END;
830
831 if(!NT_SUCCESS(Status))
832 {
833 SetLastNtError(Status);
834 DC_UnlockDc(dc);
835 return FALSE;
836 }
837 }
838
839 Dc_Attr->ptlViewportOrg.x = X;
840 Dc_Attr->ptlViewportOrg.y = Y;
841
842 DC_UpdateXforms(dc);
843 DC_UnlockDc(dc);
844
845 return TRUE;
846 }
847
848 BOOL
849 STDCALL
850 NtGdiSetWindowExtEx(HDC hDC,
851 int XExtent,
852 int YExtent,
853 LPSIZE Size)
854 {
855 PDC dc;
856 PDC_ATTR Dc_Attr;
857
858 dc = DC_LockDc(hDC);
859 if (!dc)
860 {
861 SetLastWin32Error(ERROR_INVALID_HANDLE);
862 return FALSE;
863 }
864 Dc_Attr = dc->pDc_Attr;
865 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
866
867 switch (Dc_Attr->iMapMode)
868 {
869 case MM_HIENGLISH:
870 case MM_HIMETRIC:
871 case MM_LOENGLISH:
872 case MM_LOMETRIC:
873 case MM_TEXT:
874 case MM_TWIPS:
875 DC_UnlockDc(dc);
876 return FALSE;
877 }
878
879 if (Size)
880 {
881 NTSTATUS Status = STATUS_SUCCESS;
882
883 _SEH_TRY
884 {
885 ProbeForWrite(Size,
886 sizeof(SIZE),
887 1);
888 Size->cx = Dc_Attr->szlWindowExt.cx;
889 Size->cy = Dc_Attr->szlWindowExt.cy;
890 }
891 _SEH_HANDLE
892 {
893 Status = _SEH_GetExceptionCode();
894 }
895 _SEH_END;
896
897 if(!NT_SUCCESS(Status))
898 {
899 SetLastNtError(Status);
900 DC_UnlockDc(dc);
901 return FALSE;
902 }
903 }
904
905 Dc_Attr->szlWindowExt.cx = XExtent;
906 Dc_Attr->szlWindowExt.cy = YExtent;
907
908 DC_UpdateXforms(dc);
909 DC_UnlockDc(dc);
910
911 return TRUE;
912 }
913
914 BOOL
915 STDCALL
916 NtGdiSetWindowOrgEx(HDC hDC,
917 int X,
918 int Y,
919 LPPOINT Point)
920 {
921 PDC dc;
922 PDC_ATTR Dc_Attr;
923
924 dc = DC_LockDc(hDC);
925 if (!dc)
926 {
927 SetLastWin32Error(ERROR_INVALID_HANDLE);
928 return FALSE;
929 }
930 Dc_Attr = dc->pDc_Attr;
931 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
932
933 if (Point)
934 {
935 NTSTATUS Status = STATUS_SUCCESS;
936
937 _SEH_TRY
938 {
939 ProbeForWrite(Point,
940 sizeof(POINT),
941 1);
942 Point->x = Dc_Attr->ptlWindowOrg.x;
943 Point->y = Dc_Attr->ptlWindowOrg.y;
944 }
945 _SEH_HANDLE
946 {
947 Status = _SEH_GetExceptionCode();
948 }
949 _SEH_END;
950
951 if(!NT_SUCCESS(Status))
952 {
953 SetLastNtError(Status);
954 DC_UnlockDc(dc);
955 return FALSE;
956 }
957 }
958
959 Dc_Attr->ptlWindowOrg.x = X;
960 Dc_Attr->ptlWindowOrg.y = Y;
961
962 DC_UpdateXforms(dc);
963 DC_UnlockDc(dc);
964
965 return TRUE;
966 }
967
968 //
969 // Mirror Window function.
970 //
971 VOID
972 FASTCALL
973 IntMirrorWindowOrg(PDC dc)
974 {
975 PDC_ATTR Dc_Attr;
976 LONG X;
977
978 Dc_Attr = dc->pDc_Attr;
979 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
980
981 if (!(Dc_Attr->dwLayout & LAYOUT_RTL))
982 {
983 Dc_Attr->ptlWindowOrg.x = Dc_Attr->lWindowOrgx; // Flip it back.
984 return;
985 }
986 if (!Dc_Attr->szlViewportExt.cx) return;
987 //
988 // WOrgx = wox - (Width - 1) * WExtx / VExtx
989 //
990 X = (dc->erclWindow.right - dc->erclWindow.left) - 1; // Get device width - 1
991
992 X = ( X * Dc_Attr->szlWindowExt.cx) / Dc_Attr->szlViewportExt.cx;
993
994 Dc_Attr->ptlWindowOrg.x = Dc_Attr->lWindowOrgx - X; // Now set the inverted win origion.
995
996 return;
997 }
998
999 // NtGdiSetLayout
1000 //
1001 // The default is left to right. This function changes it to right to left, which
1002 // is the standard in Arabic and Hebrew cultures.
1003 //
1004 /*
1005 * @implemented
1006 */
1007 DWORD
1008 APIENTRY
1009 NtGdiSetLayout(
1010 IN HDC hdc,
1011 IN LONG wox,
1012 IN DWORD dwLayout)
1013 {
1014 PDC dc;
1015 PDC_ATTR Dc_Attr;
1016 DWORD oLayout;
1017
1018 dc = DC_LockDc(hdc);
1019 if (!dc)
1020 {
1021 SetLastWin32Error(ERROR_INVALID_HANDLE);
1022 return GDI_ERROR;
1023 }
1024 Dc_Attr = dc->pDc_Attr;
1025 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
1026
1027 Dc_Attr->dwLayout = dwLayout;
1028 oLayout = Dc_Attr->dwLayout;
1029
1030 if (!(dwLayout & LAYOUT_ORIENTATIONMASK))
1031 {
1032 DC_UnlockDc(dc);
1033 return oLayout;
1034 }
1035
1036 if (dwLayout & LAYOUT_RTL) Dc_Attr->iMapMode = MM_ANISOTROPIC;
1037
1038 Dc_Attr->szlWindowExt.cy = -Dc_Attr->szlWindowExt.cy;
1039 Dc_Attr->ptlWindowOrg.x = -Dc_Attr->ptlWindowOrg.x;
1040
1041 if (wox == -1)
1042 IntMirrorWindowOrg(dc);
1043 else
1044 Dc_Attr->ptlWindowOrg.x = wox - Dc_Attr->ptlWindowOrg.x;
1045
1046 if (!(Dc_Attr->flTextAlign & TA_CENTER)) Dc_Attr->flTextAlign |= TA_RIGHT;
1047
1048 if (dc->DcLevel.flPath & DCPATH_CLOCKWISE)
1049 dc->DcLevel.flPath &= ~DCPATH_CLOCKWISE;
1050 else
1051 dc->DcLevel.flPath |= DCPATH_CLOCKWISE;
1052
1053 Dc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
1054
1055 // DC_UpdateXforms(dc);
1056 DC_UnlockDc(dc);
1057 return oLayout;
1058 }
1059
1060 /*
1061 * @implemented
1062 */
1063 LONG
1064 APIENTRY
1065 NtGdiGetDeviceWidth(
1066 IN HDC hdc)
1067 {
1068 PDC dc;
1069 LONG Ret;
1070 dc = DC_LockDc(hdc);
1071 if (!dc)
1072 {
1073 SetLastWin32Error(ERROR_INVALID_HANDLE);
1074 return 0;
1075 }
1076 Ret = dc->erclWindow.right - dc->erclWindow.left;
1077 DC_UnlockDc(dc);
1078 return Ret;
1079 }
1080
1081 /*
1082 * @implemented
1083 */
1084 BOOL
1085 APIENTRY
1086 NtGdiMirrorWindowOrg(
1087 IN HDC hdc)
1088 {
1089 PDC dc;
1090 dc = DC_LockDc(hdc);
1091 if (!dc)
1092 {
1093 SetLastWin32Error(ERROR_INVALID_HANDLE);
1094 return FALSE;
1095 }
1096 IntMirrorWindowOrg(dc);
1097 DC_UnlockDc(dc);
1098 return TRUE;
1099 }
1100
1101 /*
1102 * @implemented
1103 */
1104 BOOL
1105 APIENTRY
1106 NtGdiSetSizeDevice(
1107 IN HDC hdc,
1108 IN INT cxVirtualDevice,
1109 IN INT cyVirtualDevice)
1110 {
1111 PDC dc;
1112 PDC_ATTR pDc_Attr;
1113
1114 if (!cxVirtualDevice ||
1115 !cyVirtualDevice ) return FALSE;
1116
1117 dc = DC_LockDc(hdc);
1118 if (!dc) return FALSE;
1119
1120 pDc_Attr = dc->pDc_Attr;
1121 if(!pDc_Attr) pDc_Attr = &dc->Dc_Attr;
1122
1123 pDc_Attr->szlVirtualDeviceSize.cx = cxVirtualDevice;
1124 pDc_Attr->szlVirtualDeviceSize.cy = cyVirtualDevice;
1125
1126 // DC_UpdateXforms(dc);
1127 DC_UnlockDc(dc);
1128
1129 return TRUE;
1130 }
1131
1132 /*
1133 * @implemented
1134 */
1135 BOOL
1136 APIENTRY
1137 NtGdiSetVirtualResolution(
1138 IN HDC hdc,
1139 IN INT cxVirtualDevicePixel,
1140 IN INT cyVirtualDevicePixel,
1141 IN INT cxVirtualDeviceMm,
1142 IN INT cyVirtualDeviceMm)
1143 {
1144 PDC dc;
1145 PDC_ATTR pDc_Attr;
1146
1147 // Need test types for zeros and non zeros
1148
1149 dc = DC_LockDc(hdc);
1150 if (!dc) return FALSE;
1151
1152 pDc_Attr = dc->pDc_Attr;
1153 if(!pDc_Attr) pDc_Attr = &dc->Dc_Attr;
1154
1155 pDc_Attr->szlVirtualDevicePixel.cx = cxVirtualDevicePixel;
1156 pDc_Attr->szlVirtualDevicePixel.cy = cyVirtualDevicePixel;
1157 pDc_Attr->szlVirtualDeviceMm.cx = cxVirtualDeviceMm;
1158 pDc_Attr->szlVirtualDeviceMm.cy = cyVirtualDeviceMm;
1159
1160 // DC_UpdateXforms(dc);
1161 DC_UnlockDc(dc);
1162 return TRUE;
1163 }
1164
1165 /* EOF */