Implement SetTextJustification. Add code for Window and Viewport Org and Ext. Setup...
[reactos.git] / reactos / dll / win32 / gdi32 / objects / dc.c
1 #include "precomp.h"
2
3 #define NDEBUG
4 #include <debug.h>
5
6 HGDIOBJ stock_objects[NB_STOCK_OBJECTS]; // temp location.
7
8 HDC
9 FASTCALL
10 IntCreateDICW ( LPCWSTR lpwszDriver,
11 LPCWSTR lpwszDevice,
12 LPCWSTR lpwszOutput,
13 PDEVMODEW lpInitData,
14 ULONG iType )
15 {
16 UNICODE_STRING Device, Output;
17 HDC hDC = NULL;
18 BOOL Display = FALSE, Default = TRUE;
19 ULONG UMdhpdev = 0;
20
21 HANDLE hspool = NULL;
22
23 if ((!lpwszDevice) && (!lpwszDriver))
24 {
25 Default = FALSE; // Ask Win32k to set Default device.
26 Display = TRUE; // Most likely to be DISPLAY.
27 }
28 else
29 {
30 if (lpwszDevice) // First
31 {
32 if (!_wcsnicmp(lpwszDevice, L"\\\\.\\DISPLAY",11)) Display = TRUE;
33 RtlInitUnicodeString(&Device, lpwszDevice);
34 }
35 else
36 {
37 if (lpwszDriver) // Second
38 {
39 if ((!_wcsnicmp(lpwszDriver, L"DISPLAY",7)) ||
40 (!_wcsnicmp(lpwszDriver, L"\\\\.\\DISPLAY",11))) Display = TRUE;
41 RtlInitUnicodeString(&Device, lpwszDriver);
42 }
43 }
44 }
45
46 if (lpwszOutput) RtlInitUnicodeString(&Output, lpwszOutput);
47
48 if (!Display)
49 {
50 //Handle Print device or something else.
51 DPRINT1("Not a DISPLAY device! %wZ\n", &Device);
52 }
53
54 hDC = NtGdiOpenDCW( (Default ? &Device : NULL),
55 (PDEVMODEW) lpInitData,
56 (lpwszOutput ? &Output : NULL),
57 iType, // DCW 0 and ICW 1.
58 hspool,
59 (PVOID) NULL, // NULL for now.
60 (PVOID) &UMdhpdev );
61 #if 0
62 // Handle something other than a normal dc object.
63 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
64 {
65 PDC_ATTR Dc_Attr;
66 PLDC pLDC;
67
68 GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr);
69
70 pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC));
71
72 Dc_Attr->pvLDC = pLDC;
73 pLDC->hDC = hDC;
74 pLDC->iType = LDC_LDC; // 1 (init) local DC, 2 EMF LDC
75 DbgPrint("DC_ATTR Allocated -> 0x%x\n",Dc_Attr);
76 }
77 #endif
78 return hDC;
79 }
80
81
82 /*
83 * @implemented
84 */
85 HDC
86 STDCALL
87 CreateCompatibleDC ( HDC hdc)
88 {
89 /* FIXME need sharememory if it metadc */
90 return NtGdiCreateCompatibleDC(hdc);
91 }
92
93 /*
94 * @implemented
95 */
96 HDC
97 STDCALL
98 CreateDCA (
99 LPCSTR lpszDriver,
100 LPCSTR lpszDevice,
101 LPCSTR lpszOutput,
102 CONST DEVMODEA * lpdvmInit
103 )
104 {
105 ANSI_STRING DriverA, DeviceA, OutputA;
106 UNICODE_STRING DriverU, DeviceU, OutputU;
107 LPDEVMODEW dvmInitW = NULL;
108 HDC hDC;
109
110 /*
111 * If needed, convert to Unicode
112 * any string parameter.
113 */
114
115 if (NULL != lpszDriver)
116 {
117 RtlInitAnsiString(&DriverA, (LPSTR)lpszDriver);
118 RtlAnsiStringToUnicodeString(&DriverU, &DriverA, TRUE);
119 } else
120 DriverU.Buffer = NULL;
121 if (NULL != lpszDevice)
122 {
123 RtlInitAnsiString(&DeviceA, (LPSTR)lpszDevice);
124 RtlAnsiStringToUnicodeString(&DeviceU, &DeviceA, TRUE);
125 } else
126 DeviceU.Buffer = NULL;
127 if (NULL != lpszOutput)
128 {
129 RtlInitAnsiString(&OutputA, (LPSTR)lpszOutput);
130 RtlAnsiStringToUnicodeString(&OutputU, &OutputA, TRUE);
131 } else
132 OutputU.Buffer = NULL;
133
134 if ( lpdvmInit )
135 dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);
136
137 hDC = IntCreateDICW ( DriverU.Buffer,
138 DeviceU.Buffer,
139 OutputU.Buffer,
140 lpdvmInit ? dvmInitW : NULL,
141 0 );
142 HEAP_free (dvmInitW);
143 /*
144 * Free Unicode parameters.
145 */
146 RtlFreeUnicodeString(&DriverU);
147 RtlFreeUnicodeString(&DeviceU);
148 RtlFreeUnicodeString(&OutputU);
149
150 /*
151 * Return the possible DC handle.
152 */
153 return hDC;
154 }
155
156
157 /*
158 * @implemented
159 */
160 HDC
161 STDCALL
162 CreateDCW (
163 LPCWSTR lpwszDriver,
164 LPCWSTR lpwszDevice,
165 LPCWSTR lpwszOutput,
166 CONST DEVMODEW *lpInitData
167 )
168 {
169
170 return IntCreateDICW ( lpwszDriver,
171 lpwszDevice,
172 lpwszOutput,
173 (PDEVMODEW) lpInitData,
174 0 );
175 }
176
177
178 /*
179 * @implemented
180 */
181 HDC
182 STDCALL
183 CreateICW(
184 LPCWSTR lpszDriver,
185 LPCWSTR lpszDevice,
186 LPCWSTR lpszOutput,
187 CONST DEVMODEW *lpdvmInit
188 )
189 {
190 return IntCreateDICW ( lpszDriver,
191 lpszDevice,
192 lpszOutput,
193 (PDEVMODEW) lpdvmInit,
194 1 );
195 }
196
197
198 /*
199 * @implemented
200 */
201 HDC
202 STDCALL
203 CreateICA(
204 LPCSTR lpszDriver,
205 LPCSTR lpszDevice,
206 LPCSTR lpszOutput,
207 CONST DEVMODEA *lpdvmInit
208 )
209 {
210 NTSTATUS Status;
211 LPWSTR lpszDriverW, lpszDeviceW, lpszOutputW;
212 LPDEVMODEW dvmInitW = NULL;
213 HDC rc = 0;
214
215 Status = HEAP_strdupA2W ( &lpszDriverW, lpszDriver );
216 if (!NT_SUCCESS (Status))
217 SetLastError (RtlNtStatusToDosError(Status));
218 else
219 {
220 Status = HEAP_strdupA2W ( &lpszDeviceW, lpszDevice );
221 if (!NT_SUCCESS (Status))
222 SetLastError (RtlNtStatusToDosError(Status));
223 else
224 {
225 Status = HEAP_strdupA2W ( &lpszOutputW, lpszOutput );
226 if (!NT_SUCCESS (Status))
227 SetLastError (RtlNtStatusToDosError(Status));
228 else
229 {
230 if ( lpdvmInit )
231 dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);
232
233 rc = IntCreateDICW ( lpszDriverW,
234 lpszDeviceW,
235 lpszOutputW,
236 lpdvmInit ? dvmInitW : NULL,
237 1 );
238 HEAP_free (dvmInitW);
239 HEAP_free ( lpszOutputW );
240 }
241 HEAP_free ( lpszDeviceW );
242 }
243 HEAP_free ( lpszDriverW );
244 }
245 return rc;
246 }
247
248
249 /*
250 * @implemented
251 */
252 BOOL
253 STDCALL
254 DeleteDC(HDC hDC)
255 {
256 BOOL Ret = TRUE;
257 #if 0
258 PDC_ATTR Dc_Attr;
259 PLDC pLDC;
260
261 if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return FALSE;
262
263 if ( Dc_Attr )
264 {
265 pLDC = Dc_Attr->pvLDC;
266
267 if ( pLDC )
268 {
269 DPRINT1("Delete the Local DC structure\n");
270 LocalFree( pLDC );
271 }
272 }
273 #endif
274 Ret = NtGdiDeleteObjectApp(hDC);
275
276 return Ret;
277 }
278
279 /*
280 * @implemented
281 */
282 BOOL
283 STDCALL
284 DeleteObject(HGDIOBJ hObject)
285 {
286 UINT Type = 0;
287
288 /* From Wine: DeleteObject does not SetLastError() on a null object */
289 if(!hObject) return FALSE;
290
291 if (0 != ((DWORD) hObject & GDI_HANDLE_STOCK_MASK))
292 { // Relax! This is a normal return!
293 DPRINT("Trying to delete system object 0x%x\n", hObject);
294 return TRUE;
295 }
296 // If you dont own it?! Get OUT!
297 if(!GdiIsHandleValid(hObject)) return FALSE;
298
299 Type = GDI_HANDLE_GET_TYPE(hObject);
300
301 if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
302 (Type == GDI_OBJECT_TYPE_ENHMETAFILE))
303 return FALSE;
304
305 switch (Type)
306 {
307 case GDI_OBJECT_TYPE_DC:
308 return DeleteDC((HDC) hObject);
309 case GDI_OBJECT_TYPE_COLORSPACE:
310 return NtGdiDeleteColorSpace((HCOLORSPACE) hObject);
311 case GDI_OBJECT_TYPE_REGION:
312 return DeleteRegion((HRGN) hObject);
313 #if 0
314 case GDI_OBJECT_TYPE_METADC:
315 return MFDRV_DeleteObject( hObject );
316 case GDI_OBJECT_TYPE_EMF:
317 {
318 PLDC pLDC = GdiGetLDC(hObject);
319 if ( !pLDC ) return FALSE;
320 return EMFDRV_DeleteObject( hObject );
321 }
322 #endif
323 case GDI_OBJECT_TYPE_FONT:
324 break;
325
326 case GDI_OBJECT_TYPE_BRUSH:
327 case GDI_OBJECT_TYPE_EXTPEN:
328 case GDI_OBJECT_TYPE_PEN:
329 {
330 PBRUSH_ATTR Brh_Attr;
331 PTEB pTeb;
332
333 if ((!GdiGetHandleUserData(hObject, (PVOID) &Brh_Attr)) ||
334 (Brh_Attr == NULL) ) break;
335
336 pTeb = NtCurrentTeb();
337
338 if (pTeb->Win32ThreadInfo == NULL) break;
339
340 if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
341 {
342 PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
343 pTeb->GdiTebBatch.Offset);
344 pgO->gbHdr.Cmd = GdiBCDelObj;
345 pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
346 pgO->hgdiobj = hObject;
347
348 pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
349 pTeb->GdiBatchCount++;
350 if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
351 return TRUE;
352 }
353 break;
354 }
355 case GDI_OBJECT_TYPE_BITMAP:
356 default:
357 break;
358 }
359 return NtGdiDeleteObjectApp(hObject);
360 }
361
362 INT
363 STDCALL
364 GetArcDirection( HDC hdc )
365 {
366 return GetDCDWord( hdc, GdiGetArcDirection, 0);
367 }
368
369
370 INT
371 STDCALL
372 SetArcDirection( HDC hdc, INT nDirection )
373 {
374 return GetAndSetDCDWord( hdc, GdiGetSetArcDirection, nDirection, 0, 0, 0 );
375 }
376
377
378 HGDIOBJ
379 STDCALL
380 GetDCObject( HDC hDC, INT iType)
381 {
382 if((iType == GDI_OBJECT_TYPE_BRUSH) ||
383 (iType == GDI_OBJECT_TYPE_EXTPEN)||
384 (iType == GDI_OBJECT_TYPE_PEN) ||
385 (iType == GDI_OBJECT_TYPE_COLORSPACE))
386 {
387 HGDIOBJ hGO = NULL;
388 PDC_ATTR Dc_Attr;
389
390 if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return NULL;
391
392 switch (iType)
393 {
394 case GDI_OBJECT_TYPE_BRUSH:
395 hGO = Dc_Attr->hbrush;
396 break;
397
398 case GDI_OBJECT_TYPE_EXTPEN:
399 case GDI_OBJECT_TYPE_PEN:
400 hGO = Dc_Attr->hpen;
401 break;
402
403 case GDI_OBJECT_TYPE_COLORSPACE:
404 hGO = Dc_Attr->hColorSpace;
405 break;
406 }
407 return hGO;
408 }
409 return NtGdiGetDCObject( hDC, iType );
410 }
411
412
413 /*
414 * @implemented
415 *
416 */
417 HGDIOBJ
418 STDCALL
419 GetCurrentObject(HDC hdc,
420 UINT uObjectType)
421 {
422 switch(uObjectType)
423 {
424 case OBJ_EXTPEN:
425 case OBJ_PEN:
426 uObjectType = GDI_OBJECT_TYPE_PEN;
427 break;
428 case OBJ_BRUSH:
429 uObjectType = GDI_OBJECT_TYPE_BRUSH;
430 break;
431 case OBJ_PAL:
432 uObjectType = GDI_OBJECT_TYPE_PALETTE;
433 break;
434 case OBJ_FONT:
435 uObjectType = GDI_OBJECT_TYPE_FONT;
436 break;
437 case OBJ_BITMAP:
438 uObjectType = GDI_OBJECT_TYPE_BITMAP;
439 break;
440 case OBJ_COLORSPACE:
441 uObjectType = GDI_OBJECT_TYPE_COLORSPACE;
442 break;
443 /* tests show that OBJ_REGION is explicitly ignored */
444 case OBJ_REGION:
445 return NULL;
446 /* the SDK only mentions those above */
447 default:
448 SetLastError(ERROR_INVALID_PARAMETER);
449 return NULL;
450 }
451 return GetDCObject(hdc, uObjectType);
452 }
453
454
455 /*
456 * @implemented
457 */
458 DWORD
459 STDCALL
460 GetRelAbs(
461 HDC hdc,
462 DWORD dwIgnore
463 )
464 {
465 return GetDCDWord( hdc, GdiGetRelAbs, 0);
466 }
467
468
469 /*
470 * @implemented
471 */
472 DWORD
473 STDCALL
474 SetRelAbs(
475 HDC hdc,
476 INT Mode
477 )
478 {
479 return GetAndSetDCDWord( hdc, GdiGetSetRelAbs, Mode, 0, 0, 0 );
480 }
481
482
483 /*
484 * @implemented
485 */
486 DWORD
487 STDCALL
488 GetAndSetDCDWord( HDC hDC, INT u, DWORD dwIn, DWORD Unk1, DWORD Unk2, DWORD Unk3 )
489 {
490 BOOL Ret = TRUE;
491 // Handle something other than a normal dc object.
492 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
493 {
494 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
495 return 0; //call MFDRV
496 else
497 {
498 PLDC pLDC = GdiGetLDC(hDC);
499 if ( !pLDC )
500 {
501 SetLastError(ERROR_INVALID_HANDLE);
502 return 0;
503 }
504 if (pLDC->iType == LDC_EMFLDC)
505 {
506 Ret = TRUE; //call EMFDRV
507 if (Ret)
508 return u;
509 return 0;
510 }
511 }
512 }
513 Ret = NtGdiGetAndSetDCDword( hDC, u, dwIn, (DWORD*) &u );
514 if (Ret)
515 return u;
516 else
517 SetLastError(ERROR_INVALID_HANDLE);
518 return 0;
519 }
520
521
522 /*
523 * @implemented
524 */
525 DWORD
526 STDCALL
527 GetDCDWord( HDC hDC, INT u, DWORD Result )
528 {
529 BOOL Ret = NtGdiGetDCDword( hDC, u, (DWORD*) &u );
530 if (!Ret) return Result;
531 else return u;
532 }
533
534
535 /*
536 * @implemented
537 */
538 BOOL
539 STDCALL
540 GetAspectRatioFilterEx(
541 HDC hdc,
542 LPSIZE lpAspectRatio
543 )
544 {
545 return NtGdiGetDCPoint( hdc, GdiGetAspectRatioFilter, (LPPOINT) lpAspectRatio );
546 }
547
548
549 /*
550 * @implemented
551 */
552 BOOL
553 STDCALL
554 GetDCOrgEx(
555 HDC hdc,
556 LPPOINT lpPoint
557 )
558 {
559 return NtGdiGetDCPoint( hdc, GdiGetDCOrg, lpPoint );
560 }
561
562
563 /*
564 * @implemented
565 */
566 LONG
567 STDCALL
568 GetDCOrg(
569 HDC hdc
570 )
571 {
572 // Officially obsolete by Microsoft
573 POINT Pt;
574 if (!GetDCOrgEx(hdc, &Pt))
575 return 0;
576 return(MAKELONG(Pt.x, Pt.y));
577 }
578
579
580 int
581 GetNonFontObject(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
582 {
583 INT dwType;
584
585 hGdiObj = (HANDLE)GdiFixUpHandle(hGdiObj);
586 dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
587
588 if (!lpBuffer) // Should pass it all to Win32k and let god sort it out. ;^)
589 {
590 switch(dwType)
591 {
592 case GDI_OBJECT_TYPE_PEN:
593 return sizeof(LOGPEN);
594 case GDI_OBJECT_TYPE_BRUSH:
595 return sizeof(LOGBRUSH);
596 case GDI_OBJECT_TYPE_BITMAP:
597 return sizeof(BITMAP);
598 case GDI_OBJECT_TYPE_PALETTE:
599 return sizeof(WORD);
600 case GDI_OBJECT_TYPE_EXTPEN: /* we don't know the size, ask win32k */
601 break;
602 }
603 }
604
605 switch(dwType)
606 {
607 case GDI_OBJECT_TYPE_PEN: //Check the structures and see if A & W are the same.
608 case GDI_OBJECT_TYPE_EXTPEN:
609 case GDI_OBJECT_TYPE_BRUSH: // Mixing Apples and Oranges?
610 case GDI_OBJECT_TYPE_BITMAP:
611 case GDI_OBJECT_TYPE_PALETTE:
612 return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
613
614 case GDI_OBJECT_TYPE_DC:
615 case GDI_OBJECT_TYPE_REGION:
616 case GDI_OBJECT_TYPE_METAFILE:
617 case GDI_OBJECT_TYPE_ENHMETAFILE:
618 case GDI_OBJECT_TYPE_EMF:
619 SetLastError(ERROR_INVALID_HANDLE);
620 }
621 return 0;
622 }
623
624
625 /*
626 * @implemented
627 */
628 int
629 STDCALL
630 GetObjectA(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
631 {
632 ENUMLOGFONTEXDVW LogFont;
633 DWORD dwType;
634 INT Result = 0;
635
636 dwType = GDI_HANDLE_GET_TYPE(hGdiObj);;
637
638 if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct A
639 {
640 SetLastError(ERROR_NOT_SUPPORTED);
641 return 0;
642 }
643
644 if (dwType == GDI_OBJECT_TYPE_FONT)
645 {
646 if (!lpBuffer)
647 {
648 return sizeof(LOGFONTA);
649 }
650 if (cbSize == 0)
651 {
652 /* Windows does not SetLastError() */
653 return 0;
654 }
655 // ENUMLOGFONTEXDVW is the default size and should be the structure for
656 // Entry->KernelData for Font objects.
657 Result = NtGdiExtGetObjectW(hGdiObj, sizeof(ENUMLOGFONTEXDVW), &LogFont);
658
659 if (0 == Result)
660 {
661 return 0;
662 }
663
664 switch (cbSize)
665 {
666 case sizeof(ENUMLOGFONTEXDVA):
667 // need to move more here.
668 case sizeof(ENUMLOGFONTEXA):
669 EnumLogFontExW2A( (LPENUMLOGFONTEXA) lpBuffer, &LogFont.elfEnumLogfontEx );
670 break;
671
672 case sizeof(ENUMLOGFONTA):
673 // Same here, maybe? Check the structures.
674 case sizeof(EXTLOGFONTA):
675 // Same here
676 case sizeof(LOGFONTA):
677 LogFontW2A((LPLOGFONTA) lpBuffer, &LogFont.elfEnumLogfontEx.elfLogFont);
678 break;
679
680 default:
681 SetLastError(ERROR_BUFFER_OVERFLOW);
682 return 0;
683 }
684 return cbSize;
685 }
686
687 return GetNonFontObject(hGdiObj, cbSize, lpBuffer);
688 }
689
690
691 /*
692 * @implemented
693 */
694 int
695 STDCALL
696 GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
697 {
698 DWORD dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
699 INT Result = 0;
700
701 /*
702 Check List:
703 MSDN, "This can be a handle to one of the following: logical bitmap, a brush,
704 a font, a palette, a pen, or a device independent bitmap created by calling
705 the CreateDIBSection function."
706 */
707 if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct W
708 {
709 SetLastError(ERROR_NOT_SUPPORTED); // Not supported yet.
710 return 0;
711 }
712
713 if (dwType == GDI_OBJECT_TYPE_FONT)
714 {
715 if (!lpBuffer)
716 {
717 return sizeof(LOGFONTW);
718 }
719
720 if (cbSize == 0)
721 {
722 /* Windows does not SetLastError() */
723 return 0;
724 }
725 // Poorly written apps are not ReactOS problem!
726 // We fix it here if the size is larger than the default size.
727 if( cbSize > sizeof(ENUMLOGFONTEXDVW) ) cbSize = sizeof(ENUMLOGFONTEXDVW);
728
729 Result = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer); // Should handle the copy.
730
731 if (0 == Result)
732 {
733 return 0;
734 }
735 return cbSize;
736 }
737
738 return GetNonFontObject(hGdiObj, cbSize, lpBuffer);
739 }
740
741
742 /*
743 * @implemented
744 */
745 COLORREF
746 STDCALL
747 GetDCBrushColor(
748 HDC hdc
749 )
750 {
751 PDC_ATTR Dc_Attr;
752
753 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return CLR_INVALID;
754 return (COLORREF) Dc_Attr->ulPenClr;
755 }
756
757 /*
758 * @implemented
759 */
760 COLORREF
761 STDCALL
762 GetDCPenColor(
763 HDC hdc
764 )
765 {
766 PDC_ATTR Dc_Attr;
767
768 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return CLR_INVALID;
769 return (COLORREF) Dc_Attr->ulPenClr;
770 }
771
772 /*
773 * @implemented
774 */
775 COLORREF
776 STDCALL
777 SetDCBrushColor(
778 HDC hdc,
779 COLORREF crColor
780 )
781 {
782 PDC_ATTR Dc_Attr;
783 COLORREF OldColor = CLR_INVALID;
784
785 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldColor;
786 else
787 {
788 OldColor = (COLORREF) Dc_Attr->ulBrushClr;
789 Dc_Attr->ulBrushClr = (ULONG) crColor;
790
791 if ( Dc_Attr->crBrushClr != crColor ) // if same, don't force a copy.
792 {
793 Dc_Attr->ulDirty_ |= DIRTY_FILL;
794 Dc_Attr->crBrushClr = crColor;
795 }
796 }
797 return OldColor;
798 }
799
800 /*
801 * @implemented
802 */
803 COLORREF
804 STDCALL
805 SetDCPenColor(
806 HDC hdc,
807 COLORREF crColor
808 )
809 {
810 PDC_ATTR Dc_Attr;
811 COLORREF OldColor = CLR_INVALID;
812
813 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldColor;
814 else
815 {
816 OldColor = (COLORREF) Dc_Attr->ulPenClr;
817 Dc_Attr->ulPenClr = (ULONG) crColor;
818
819 if ( Dc_Attr->crPenClr != crColor )
820 {
821 Dc_Attr->ulDirty_ |= DIRTY_LINE;
822 Dc_Attr->crPenClr = crColor;
823 }
824 }
825 return OldColor;
826 }
827
828 /*
829 * @implemented
830 *
831 */
832 COLORREF
833 STDCALL
834 GetBkColor(HDC hdc)
835 {
836 PDC_ATTR Dc_Attr;
837 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
838 return Dc_Attr->ulBackgroundClr;
839 }
840
841 /*
842 * @implemented
843 */
844 COLORREF
845 STDCALL
846 SetBkColor(
847 HDC hdc,
848 COLORREF crColor
849 )
850 {
851 PDC_ATTR Dc_Attr;
852 COLORREF OldColor = CLR_INVALID;
853
854 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldColor;
855 #if 0
856 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
857 {
858 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
859 return MFDRV_SetBkColor( hDC, crColor );
860 else
861 {
862 PLDC pLDC = Dc_Attr->pvLDC;
863 if ( !pLDC )
864 {
865 SetLastError(ERROR_INVALID_HANDLE);
866 return FALSE;
867 }
868 if (pLDC->iType == LDC_EMFLDC)
869 {
870 return EMFDRV_SetBkColor( hDC, crColor );
871 }
872 }
873 }
874 #endif
875 OldColor = (COLORREF) Dc_Attr->ulBackgroundClr;
876 Dc_Attr->ulBackgroundClr = (ULONG) crColor;
877
878 if ( Dc_Attr->crBackgroundClr != crColor )
879 {
880 Dc_Attr->ulDirty_ |= DIRTY_LINE;
881 Dc_Attr->crBackgroundClr = crColor;
882 }
883 return OldColor;
884 }
885
886 /*
887 * @implemented
888 *
889 */
890 int
891 STDCALL
892 GetBkMode(HDC hdc)
893 {
894 PDC_ATTR Dc_Attr;
895 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
896 return Dc_Attr->lBkMode;
897 }
898
899 /*
900 * @implemented
901 *
902 */
903 int
904 STDCALL
905 SetBkMode(HDC hdc,
906 int iBkMode)
907 {
908 PDC_ATTR Dc_Attr;
909 INT OldMode = 0;
910
911 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldMode;
912 #if 0
913 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
914 {
915 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
916 return MFDRV_SetBkMode( hdc, iBkMode )
917 else
918 {
919 PLDC pLDC = Dc_Attr->pvLDC;
920 if ( !pLDC )
921 {
922 SetLastError(ERROR_INVALID_HANDLE);
923 return FALSE;
924 }
925 if (pLDC->iType == LDC_EMFLDC)
926 {
927 return EMFDRV_SetBkMode( hdc, iBkMode )
928 }
929 }
930 }
931 #endif
932 OldMode = Dc_Attr->lBkMode;
933 Dc_Attr->jBkMode = iBkMode; // Processed
934 Dc_Attr->lBkMode = iBkMode; // Raw
935 return OldMode;
936 }
937
938 /*
939 * @implemented
940 *
941 */
942 int
943 STDCALL
944 GetPolyFillMode(HDC hdc)
945 {
946 PDC_ATTR Dc_Attr;
947 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
948 return Dc_Attr->lFillMode;
949 }
950
951 /*
952 * @unimplemented
953 */
954 int
955 STDCALL
956 SetPolyFillMode(HDC hdc,
957 int iPolyFillMode)
958 {
959 INT fmode;
960 PDC_ATTR Dc_Attr;
961 #if 0
962 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
963 {
964 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
965 return MFDRV_SetPolyFillMode( hdc, iPolyFillMode )
966 else
967 {
968 PLDC pLDC = GdiGetLDC(hdc);
969 if ( !pLDC )
970 {
971 SetLastError(ERROR_INVALID_HANDLE);
972 return FALSE;
973 }
974 if (pLDC->iType == LDC_EMFLDC)
975 {
976 return EMFDRV_SetPolyFillMode( hdc, iPolyFillMode )
977 }
978 }
979 }
980 #endif
981 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
982
983 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
984 {
985 if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
986 {
987 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
988 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
989 }
990 }
991
992 fmode = Dc_Attr->lFillMode;
993 Dc_Attr->lFillMode = iPolyFillMode;
994
995 return fmode;
996 }
997
998 /*
999 * @implemented
1000 *
1001 */
1002 int
1003 STDCALL
1004 GetGraphicsMode(HDC hdc)
1005 {
1006 PDC_ATTR Dc_Attr;
1007 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
1008 return Dc_Attr->iGraphicsMode;
1009 }
1010
1011 /*
1012 * @unimplemented
1013 */
1014 int
1015 STDCALL
1016 SetGraphicsMode(HDC hdc,
1017 int iMode)
1018 {
1019 INT oMode;
1020 PDC_ATTR Dc_Attr;
1021 if ((iMode < GM_COMPATIBLE) || (iMode > GM_ADVANCED))
1022 {
1023 SetLastError(ERROR_INVALID_PARAMETER);
1024 return 0;
1025 }
1026 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
1027
1028 if (iMode == Dc_Attr->iGraphicsMode) return iMode;
1029
1030 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
1031 {
1032 if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
1033 {
1034 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1035 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
1036 }
1037 }
1038 oMode = Dc_Attr->iGraphicsMode;
1039 Dc_Attr->iGraphicsMode = iMode;
1040
1041 return oMode;
1042 }
1043
1044 /*
1045 * @implemented
1046 */
1047 HDC
1048 STDCALL
1049 ResetDCW(
1050 HDC hdc,
1051 CONST DEVMODEW *lpInitData
1052 )
1053 {
1054 NtGdiResetDC ( hdc, (PDEVMODEW)lpInitData, NULL, NULL, NULL);
1055 return hdc;
1056 }
1057
1058
1059 /*
1060 * @implemented
1061 */
1062 HDC
1063 STDCALL
1064 ResetDCA(
1065 HDC hdc,
1066 CONST DEVMODEA *lpInitData
1067 )
1068 {
1069 LPDEVMODEW InitDataW;
1070
1071 InitDataW = GdiConvertToDevmodeW((LPDEVMODEA)lpInitData);
1072
1073 NtGdiResetDC ( hdc, InitDataW, NULL, NULL, NULL);
1074 HEAP_free(InitDataW);
1075 return hdc;
1076 }
1077
1078
1079 /*
1080 * @implemented
1081 */
1082 int
1083 STDCALL
1084 StartDocW(
1085 HDC hdc,
1086 CONST DOCINFOW *a1
1087 )
1088 {
1089 return NtGdiStartDoc ( hdc, (DOCINFOW *)a1, NULL, 0);
1090 }
1091
1092
1093 /*
1094 * @implemented
1095 */
1096 DWORD
1097 STDCALL
1098 GetObjectType(
1099 HGDIOBJ h
1100 )
1101 {
1102 DWORD Ret = 0;
1103
1104 if(GdiIsHandleValid(h))
1105 {
1106 LONG Type = GDI_HANDLE_GET_TYPE(h);
1107 switch(Type)
1108 {
1109 case GDI_OBJECT_TYPE_PEN:
1110 Ret = OBJ_PEN;
1111 break;
1112 case GDI_OBJECT_TYPE_BRUSH:
1113 Ret = OBJ_BRUSH;
1114 break;
1115 case GDI_OBJECT_TYPE_BITMAP:
1116 Ret = OBJ_BITMAP;
1117 break;
1118 case GDI_OBJECT_TYPE_FONT:
1119 Ret = OBJ_FONT;
1120 break;
1121 case GDI_OBJECT_TYPE_PALETTE:
1122 Ret = OBJ_PAL;
1123 break;
1124 case GDI_OBJECT_TYPE_REGION:
1125 Ret = OBJ_REGION;
1126 break;
1127 case GDI_OBJECT_TYPE_DC:
1128 if ( GetDCDWord( h, GdiGetIsMemDc, 0))
1129 {
1130 Ret = OBJ_MEMDC;
1131 }
1132 else
1133 Ret = OBJ_DC;
1134 break;
1135 case GDI_OBJECT_TYPE_COLORSPACE:
1136 Ret = OBJ_COLORSPACE;
1137 break;
1138 case GDI_OBJECT_TYPE_METAFILE:
1139 Ret = OBJ_METAFILE;
1140 break;
1141 case GDI_OBJECT_TYPE_ENHMETAFILE:
1142 Ret = OBJ_ENHMETAFILE;
1143 break;
1144 case GDI_OBJECT_TYPE_METADC:
1145 Ret = OBJ_METADC;
1146 break;
1147 case GDI_OBJECT_TYPE_EXTPEN:
1148 Ret = OBJ_EXTPEN;
1149 break;
1150
1151 default:
1152 DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type);
1153 break;
1154 }
1155 }
1156 else
1157 /* From Wine: GetObjectType does SetLastError() on a null object */
1158 SetLastError(ERROR_INVALID_HANDLE);
1159 return Ret;
1160 }
1161
1162
1163 /*
1164 * @implemented
1165 */
1166 HGDIOBJ
1167 WINAPI
1168 GetStockObject(
1169 INT h
1170 )
1171 {
1172 HGDIOBJ Ret = NULL;
1173 if ((h < 0) || (h >= NB_STOCK_OBJECTS)) return Ret;
1174 Ret = stock_objects[h];
1175 if (!Ret)
1176 {
1177 HGDIOBJ Obj = NtGdiGetStockObject( h );
1178
1179 if (GdiIsHandleValid(Obj))
1180 {
1181 stock_objects[h] = Obj;
1182 return Obj;
1183 }// Returns Null anyway.
1184 }
1185 return Ret;
1186 }
1187
1188
1189 BOOL
1190 STDCALL
1191 GetViewportExtEx(
1192 HDC hdc,
1193 LPSIZE lpSize
1194 )
1195 {
1196 PDC_ATTR Dc_Attr;
1197
1198 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1199
1200 if ( Dc_Attr->flXform & PAGE_EXTENTS_CHANGED ) // Something was updated, go to kernel.
1201 return NtGdiGetDCPoint( hdc, GdiGetViewPortExt, (LPPOINT) lpSize );
1202 else
1203 {
1204 lpSize->cx = Dc_Attr->szlViewportExt.cx;
1205 lpSize->cy = Dc_Attr->szlViewportExt.cy;
1206 }
1207 return TRUE;
1208 }
1209
1210
1211 BOOL
1212 STDCALL
1213 GetViewportOrgEx(
1214 HDC hdc,
1215 LPPOINT lpPoint
1216 )
1217 {
1218 PDC_ATTR Dc_Attr;
1219
1220 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1221 lpPoint->x = Dc_Attr->ptlViewportOrg.x;
1222 lpPoint->x = Dc_Attr->ptlViewportOrg.x;
1223 return TRUE;
1224 // return NtGdiGetDCPoint( hdc, GdiGetViewPortOrg, lpPoint );
1225 }
1226
1227
1228 BOOL
1229 STDCALL
1230 GetWindowExtEx(
1231 HDC hdc,
1232 LPSIZE lpSize
1233 )
1234 {
1235 PDC_ATTR Dc_Attr;
1236
1237 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1238 lpSize->cx = Dc_Attr->szlWindowExt.cx;
1239 lpSize->cy = Dc_Attr->szlWindowExt.cy;
1240 return TRUE;
1241 // return NtGdiGetDCPoint( hdc, GdiGetWindowExt, (LPPOINT) lpSize );
1242 }
1243
1244
1245 BOOL
1246 STDCALL
1247 GetWindowOrgEx(
1248 HDC hdc,
1249 LPPOINT lpPoint
1250 )
1251 {
1252 PDC_ATTR Dc_Attr;
1253
1254 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1255 lpPoint->x = Dc_Attr->ptlWindowOrg.x;
1256 lpPoint->x = Dc_Attr->ptlWindowOrg.x;
1257 return TRUE;
1258 //return NtGdiGetDCPoint( hdc, GdiGetWindowOrg, lpPoint );
1259 }
1260
1261 /*
1262 * @unimplemented
1263 */
1264 BOOL
1265 STDCALL
1266 SetViewportExtEx(HDC hdc,
1267 int nXExtent,
1268 int nYExtent,
1269 LPSIZE lpSize)
1270 {
1271 #if 0
1272 PDC_ATTR Dc_Attr;
1273 #if 0
1274 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
1275 {
1276 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
1277 return MFDRV_SetViewportExtEx();
1278 else
1279 {
1280 PLDC pLDC = GdiGetLDC(hdc);
1281 if ( !pLDC )
1282 {
1283 SetLastError(ERROR_INVALID_HANDLE);
1284 return FALSE;
1285 }
1286 if (pLDC->iType == LDC_EMFLDC)
1287 {
1288 return EMFDRV_SetViewportExtEx();
1289 }
1290 }
1291 }
1292 #endif
1293 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1294
1295 if (lpSize)
1296 {
1297 lpSize->cx = Dc_Attr->szlWindowExt.cx;
1298 lpSize->cy = Dc_Attr->szlWindowExt.cy;
1299 }
1300
1301 if ((Dc_Attr->iMapMode == MM_ISOTROPIC) && (Dc_Attr->iMapMode == MM_ANISOTROPIC))
1302 {
1303 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
1304 {
1305 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
1306 {
1307 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1308 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
1309 }
1310 }
1311
1312 Dc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
1313 Dc_Attr->szlWindowExt.cx = nXExtent;
1314 Dc_Attr->szlWindowExt.cy = nYExtent;
1315 }
1316 return TRUE;
1317 #endif
1318 return NtGdiSetViewportExtEx(hdc, nXExtent, nYExtent, lpSize);
1319 }
1320
1321 /*
1322 * @unimplemented
1323 */
1324 BOOL
1325 STDCALL
1326 SetWindowOrgEx(HDC hdc,
1327 int X,
1328 int Y,
1329 LPPOINT lpPoint)
1330 {
1331 #if 0
1332 PDC_ATTR Dc_Attr;
1333 #if 0
1334 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
1335 {
1336 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
1337 return MFDRV_SetWindowOrgEx();
1338 else
1339 {
1340 PLDC pLDC = GdiGetLDC(hdc);
1341 if ( !pLDC )
1342 {
1343 SetLastError(ERROR_INVALID_HANDLE);
1344 return FALSE;
1345 }
1346 if (pLDC->iType == LDC_EMFLDC)
1347 {
1348 return EMFDRV_SetWindowOrgEx();
1349 }
1350 }
1351 }
1352 #endif
1353 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1354
1355 if (lpPoint)
1356 {
1357 lpPoint->x = Dc_Attr->ptlWindowOrg.x;
1358 lpPoint->y = Dc_Attr->ptlWindowOrg.y;
1359 }
1360
1361 if ((Dc_Attr->ptlWindowOrg.x == X) && (Dc_Attr->ptlWindowOrg.y == Y))
1362 return TRUE;
1363
1364 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
1365 {
1366 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
1367 {
1368 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1369 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
1370 }
1371 }
1372
1373 Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
1374 Dc_Attr->ptlWindowOrg.x = X;
1375 Dc_Attr->ptlWindowOrg.y = Y;
1376 return TRUE;
1377 #endif
1378 return NtGdiSetWindowOrgEx(hdc,X,Y,lpPoint);
1379 }
1380
1381 /*
1382 * @unimplemented
1383 */
1384 BOOL
1385 STDCALL
1386 SetWindowExtEx(HDC hdc,
1387 int nXExtent,
1388 int nYExtent,
1389 LPSIZE lpSize)
1390 {
1391 #if 0
1392 PDC_ATTR Dc_Attr;
1393 #if 0
1394 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
1395 {
1396 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
1397 return MFDRV_SetWindowExtEx();
1398 else
1399 {
1400 PLDC pLDC = GdiGetLDC(hdc);
1401 if ( !pLDC )
1402 {
1403 SetLastError(ERROR_INVALID_HANDLE);
1404 return FALSE;
1405 }
1406 if (pLDC->iType == LDC_EMFLDC)
1407 {
1408 return EMFDRV_SetWindowExtEx();
1409 }
1410 }
1411 }
1412 #endif
1413 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1414
1415 if (lpSize)
1416 {
1417 lpSize->cx = Dc_Attr->szlWindowExt.cx;
1418 lpSize->cy = Dc_Attr->szlWindowExt.cy;
1419 }
1420
1421 if ((Dc_Attr->iMapMode == MM_ISOTROPIC) && (Dc_Attr->iMapMode == MM_ANISOTROPIC))
1422 {
1423 if ((Dc_Attr->szlWindowExt.cx == nXExtent) && (Dc_Attr->szlWindowExt.cy == nYExtent))
1424 return TRUE;
1425
1426 if ((!nXExtent) && (!nYExtent)) return FALSE;
1427
1428 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
1429 {
1430 if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
1431 {
1432 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1433 Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
1434 }
1435 }
1436
1437 Dc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
1438 Dc_Attr->szlWindowExt.cx = nXExtent;
1439 Dc_Attr->szlWindowExt.cy = nYExtent;
1440 }
1441 return TRUE;
1442 #endif
1443 return NtGdiSetWindowExtEx(hdc, nXExtent, nYExtent, lpSize);
1444 }
1445
1446 /*
1447 * @unimplemented
1448 */
1449 BOOL
1450 STDCALL
1451 SetViewportOrgEx(HDC hdc,
1452 int X,
1453 int Y,
1454 LPPOINT lpPoint)
1455 {
1456 #if 0
1457 PDC_ATTR Dc_Attr;
1458 #if 0
1459 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
1460 {
1461 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
1462 return MFDRV_SetViewportOrgEx();
1463 else
1464 {
1465 PLDC pLDC = GdiGetLDC(hdc);
1466 if ( !pLDC )
1467 {
1468 SetLastError(ERROR_INVALID_HANDLE);
1469 return FALSE;
1470 }
1471 if (pLDC->iType == LDC_EMFLDC)
1472 {
1473 return EMFDRV_SetViewportOrgEx();
1474 }
1475 }
1476 }
1477 #endif
1478 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
1479
1480 if (lpPoint)
1481 {
1482 lpPoint->x = Dc_Attr->ptlViewportOrg.x;
1483 lpPoint->y = Dc_Attr->ptlViewportOrg.y;
1484 }
1485 Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID);
1486 Dc_Attr->ptlViewportOrg.x = X;
1487 Dc_Attr->ptlViewportOrg.y = Y;
1488 return TRUE;
1489 #endif
1490 return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint);
1491 }
1492
1493
1494
1495 /* FIXME: include correct header */
1496 HPALETTE STDCALL NtUserSelectPalette(HDC hDC,
1497 HPALETTE hpal,
1498 BOOL ForceBackground);
1499
1500 HPALETTE
1501 STDCALL
1502 SelectPalette(
1503 HDC hDC,
1504 HPALETTE hPal,
1505 BOOL bForceBackground)
1506 {
1507 #if 0
1508 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
1509 {
1510 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
1511 return MFDRV_SelectPalette( hDC, hPal, bForceBackground);
1512 else
1513 {
1514 PLDC pLDC = GdiGetLDC(hDC);
1515 if ( !pLDC )
1516 {
1517 SetLastError(ERROR_INVALID_HANDLE);
1518 return FALSE;
1519 }
1520 if (pLDC->iType == LDC_EMFLDC)
1521 {
1522 if return EMFDRV_SelectPalette( hDC, hPal, bForceBackground);
1523 }
1524 }
1525 }
1526 #endif
1527 return NtUserSelectPalette(hDC, hPal, bForceBackground);
1528 }
1529
1530 /*
1531 * @implemented
1532 *
1533 */
1534 int
1535 STDCALL
1536 GetMapMode(HDC hdc)
1537 {
1538 PDC_ATTR Dc_Attr;
1539 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
1540 return Dc_Attr->iMapMode;
1541 }
1542
1543 /*
1544 * @implemented
1545 */
1546 INT
1547 STDCALL
1548 SetMapMode(
1549 HDC hdc,
1550 INT Mode
1551 )
1552 {
1553 PDC_ATTR Dc_Attr;
1554 if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
1555 #if 0
1556 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
1557 {
1558 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
1559 return MFDRV_SetMapMode(hdc, Mode);
1560 else
1561 {
1562 SetLastError(ERROR_INVALID_HANDLE);
1563 return FALSE;
1564 }
1565 #endif
1566 if ((Mode == Dc_Attr->iMapMode) && (Mode != MM_ISOTROPIC)) return Mode;
1567 return GetAndSetDCDWord( hdc, GdiGetSetMapMode, Mode, 0, 0, 0 );
1568 }
1569
1570