mmdevapi: Query MemoryWineUnixFuncs virtual memory and store the resulting handle.
[wine.git] / dlls / gdi32 / dc.c
blob44dd9b9373dab28cb54d6e42cb3a2e6d4de85c6c
1 /*
2 * GDI Device Context functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 * Copyright 1997 Bertho A. Stultiens
6 * 1999 Huw D M Davies
7 * Copyright 2021 Jacek Caban for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "gdi_private.h"
25 #include "ntuser.h"
26 #include "ddrawgdi.h"
27 #include "winnls.h"
29 #include "wine/list.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
34 static struct list drivers = LIST_INIT( drivers );
36 static CRITICAL_SECTION driver_section;
37 static CRITICAL_SECTION_DEBUG critsect_debug =
39 0, 0, &driver_section,
40 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
41 0, 0, { (DWORD_PTR)(__FILE__ ": driver_section") }
43 static CRITICAL_SECTION driver_section = { &critsect_debug, -1, 0, 0, 0, 0 };
45 typedef const void * (CDECL *driver_entry_point)( unsigned int version );
47 struct graphics_driver
49 struct list entry;
50 HMODULE module; /* module handle */
51 driver_entry_point entry_point;
55 DC_ATTR *get_dc_attr( HDC hdc )
57 DWORD type = gdi_handle_type( hdc );
58 DC_ATTR *dc_attr;
59 if ((type & 0x1f0000) != NTGDI_OBJ_DC || !(dc_attr = get_gdi_client_ptr( hdc, 0 )))
61 SetLastError( ERROR_INVALID_HANDLE );
62 return NULL;
64 return dc_attr->disabled ? NULL : dc_attr;
67 static BOOL is_display_device( const WCHAR *name )
69 const WCHAR *p = name;
71 if (!name)
72 return FALSE;
74 if (wcsnicmp( name, L"\\\\.\\DISPLAY", lstrlenW(L"\\\\.\\DISPLAY") )) return FALSE;
76 p += lstrlenW(L"\\\\.\\DISPLAY");
78 if (!iswdigit( *p++ ))
79 return FALSE;
81 for (; *p; p++)
83 if (!iswdigit( *p ))
84 return FALSE;
87 return TRUE;
90 static BOOL get_driver_name( const WCHAR *device, WCHAR *driver, DWORD size )
92 WCHAR *p;
94 /* display is a special case */
95 if (!wcsicmp( device, L"display" ) || is_display_device( device ))
97 lstrcpynW( driver, L"display", size );
98 return TRUE;
101 size = GetProfileStringW(L"devices", device, L"", driver, size);
102 if (!size)
104 WARN("Unable to find %s in [devices] section of win.ini\n", debugstr_w(device));
105 return FALSE;
107 p = wcschr(driver, ',');
108 if (!p)
110 WARN("%s entry in [devices] section of win.ini is malformed.\n", debugstr_w(device));
111 return FALSE;
113 *p = 0;
114 TRACE("Found %s for %s\n", debugstr_w(driver), debugstr_w(device));
115 return TRUE;
118 static struct graphics_driver *create_driver( HMODULE module )
120 struct graphics_driver *driver;
122 if (!(driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver)))) return NULL;
123 driver->module = module;
125 if (module)
126 driver->entry_point = (void *)GetProcAddress( module, "wine_get_gdi_driver" );
127 else
128 driver->entry_point = NULL;
130 return driver;
133 #ifdef __i386__
134 static const WCHAR printer_env[] = L"w32x86";
135 #elif defined __x86_64__
136 static const WCHAR printer_env[] = L"x64";
137 #elif defined __arm__
138 static const WCHAR printer_env[] = L"arm";
139 #elif defined __aarch64__
140 static const WCHAR printer_env[] = L"arm64";
141 #else
142 #error not defined for this cpu
143 #endif
145 static driver_entry_point load_driver( LPCWSTR name )
147 HMODULE module;
148 struct graphics_driver *driver, *new_driver;
150 if ((module = GetModuleHandleW( name )))
152 EnterCriticalSection( &driver_section );
153 LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry )
155 if (driver->module == module) goto done;
157 LeaveCriticalSection( &driver_section );
160 if (!(module = LoadLibraryW( name )))
162 WCHAR path[MAX_PATH];
164 GetSystemDirectoryW( path, MAX_PATH );
165 swprintf( path + wcslen(path), MAX_PATH - wcslen(path), L"\\spool\\drivers\\%s\\3\\%s",
166 printer_env, name );
167 if (!(module = LoadLibraryW( path ))) return NULL;
170 if (!(new_driver = create_driver( module )))
172 FreeLibrary( module );
173 return NULL;
176 /* check if someone else added it in the meantime */
177 EnterCriticalSection( &driver_section );
178 LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry )
180 if (driver->module != module) continue;
181 FreeLibrary( module );
182 HeapFree( GetProcessHeap(), 0, new_driver );
183 goto done;
185 driver = new_driver;
186 list_add_head( &drivers, &driver->entry );
187 TRACE( "loaded driver %p for %s\n", driver, debugstr_w(name) );
188 done:
189 LeaveCriticalSection( &driver_section );
190 return driver->entry_point;
193 /***********************************************************************
194 * CreateDCW (GDI32.@)
196 HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
197 const DEVMODEW *devmode )
199 UNICODE_STRING device_str, output_str;
200 driver_entry_point entry_point = NULL;
201 const WCHAR *display = NULL, *p;
202 WCHAR buf[300], *port = NULL;
203 BOOL is_display = FALSE;
204 HANDLE hspool = NULL;
205 DC_ATTR *dc_attr;
206 HDC ret;
208 if (!device || !get_driver_name( device, buf, 300 ))
210 if (!driver)
212 ERR( "no device found for %s\n", debugstr_w(device) );
213 return 0;
215 lstrcpyW(buf, driver);
218 if (output)
220 output_str.Length = output_str.MaximumLength = lstrlenW(output) * sizeof(WCHAR);
221 output_str.Buffer = (WCHAR *)output;
224 if (is_display_device( driver ))
226 display = driver;
227 is_display = TRUE;
229 else if (is_display_device( device ))
231 display = device;
232 is_display = TRUE;
234 else if (!wcsicmp( buf, L"display" ) || is_display_device( buf ))
236 is_display = TRUE;
238 else if (!(entry_point = load_driver( buf )))
240 ERR( "no driver found for %s\n", debugstr_w(buf) );
241 return 0;
243 else if (!OpenPrinterW( (WCHAR *)device, &hspool, NULL ))
245 return 0;
247 else if (output && !(port = HeapAlloc( GetProcessHeap(), 0, output_str.Length + sizeof(WCHAR) )))
249 ClosePrinter( hspool );
250 return 0;
253 if (display)
255 /* Use only the display name. For example, \\.\DISPLAY1 in \\.\DISPLAY1\Monitor0 */
256 p = display + 12;
257 while (iswdigit( *p )) p++;
259 device_str.Length = device_str.MaximumLength = (p - display) * sizeof(WCHAR);
260 device_str.Buffer = (WCHAR *)display;
262 else if (device)
264 device_str.Length = device_str.MaximumLength = lstrlenW( device ) * sizeof(WCHAR);
265 device_str.Buffer = (WCHAR *)device;
268 ret = NtGdiOpenDCW( device || display ? &device_str : NULL, devmode, output ? &output_str : NULL,
269 0, is_display, entry_point, NULL, NULL );
271 if (ret && hspool && (dc_attr = get_dc_attr( ret )))
273 if (port)
275 memcpy( port, output, output_str.Length );
276 port[output_str.Length / sizeof(WCHAR)] = 0;
278 dc_attr->hspool = HandleToULong( hspool );
279 dc_attr->output = (ULONG_PTR)port;
281 else if (hspool)
283 ClosePrinter( hspool );
284 HeapFree( GetProcessHeap(), 0, port );
287 return ret;
290 /***********************************************************************
291 * CreateDCA (GDI32.@)
293 HDC WINAPI CreateDCA( const char *driver, const char *device, const char *output,
294 const DEVMODEA *init_data )
296 UNICODE_STRING driverW, deviceW, outputW;
297 DEVMODEW *init_dataW = NULL;
298 HDC ret;
300 if (driver) RtlCreateUnicodeStringFromAsciiz( &driverW, driver );
301 else driverW.Buffer = NULL;
303 if (device) RtlCreateUnicodeStringFromAsciiz( &deviceW, device );
304 else deviceW.Buffer = NULL;
306 if (output) RtlCreateUnicodeStringFromAsciiz( &outputW, output );
307 else outputW.Buffer = NULL;
309 if (init_data)
311 /* don't convert init_data for DISPLAY driver, it's not used */
312 if (!driverW.Buffer || wcsicmp( driverW.Buffer, L"display" ))
313 init_dataW = GdiConvertToDevmodeW( init_data );
316 ret = CreateDCW( driverW.Buffer, deviceW.Buffer, outputW.Buffer, init_dataW );
318 RtlFreeUnicodeString( &driverW );
319 RtlFreeUnicodeString( &deviceW );
320 RtlFreeUnicodeString( &outputW );
321 HeapFree( GetProcessHeap(), 0, init_dataW );
322 return ret;
325 /***********************************************************************
326 * CreateICA (GDI32.@)
328 HDC WINAPI CreateICA( const char *driver, const char *device, const char *output,
329 const DEVMODEA *init_data )
331 /* Nothing special yet for ICs */
332 return CreateDCA( driver, device, output, init_data );
336 /***********************************************************************
337 * CreateICW (GDI32.@)
339 HDC WINAPI CreateICW( const WCHAR *driver, const WCHAR *device, const WCHAR *output,
340 const DEVMODEW *init_data )
342 /* Nothing special yet for ICs */
343 return CreateDCW( driver, device, output, init_data );
346 /***********************************************************************
347 * GdiConvertToDevmodeW (GDI32.@)
349 DEVMODEW *WINAPI GdiConvertToDevmodeW( const DEVMODEA *dmA )
351 DEVMODEW *dmW;
352 WORD dmW_size, dmA_size;
354 dmA_size = dmA->dmSize;
356 /* this is the minimal dmSize that XP accepts */
357 if (dmA_size < FIELD_OFFSET(DEVMODEA, dmFields))
358 return NULL;
360 if (dmA_size > sizeof(DEVMODEA))
361 dmA_size = sizeof(DEVMODEA);
363 dmW_size = dmA_size + CCHDEVICENAME;
364 if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
365 dmW_size += CCHFORMNAME;
367 dmW = HeapAlloc( GetProcessHeap(), 0, dmW_size + dmA->dmDriverExtra );
368 if (!dmW) return NULL;
370 MultiByteToWideChar( CP_ACP, 0, (const char*) dmA->dmDeviceName, -1,
371 dmW->dmDeviceName, CCHDEVICENAME );
372 /* copy slightly more, to avoid long computations */
373 memcpy( &dmW->dmSpecVersion, &dmA->dmSpecVersion, dmA_size - CCHDEVICENAME );
375 if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
377 if (dmA->dmFields & DM_FORMNAME)
378 MultiByteToWideChar( CP_ACP, 0, (const char*) dmA->dmFormName, -1,
379 dmW->dmFormName, CCHFORMNAME );
380 else
381 dmW->dmFormName[0] = 0;
383 if (dmA_size > FIELD_OFFSET(DEVMODEA, dmLogPixels))
384 memcpy( &dmW->dmLogPixels, &dmA->dmLogPixels, dmA_size - FIELD_OFFSET(DEVMODEA, dmLogPixels) );
387 if (dmA->dmDriverExtra)
388 memcpy( (char *)dmW + dmW_size, (const char *)dmA + dmA_size, dmA->dmDriverExtra );
390 dmW->dmSize = dmW_size;
392 return dmW;
395 /***********************************************************************
396 * DeleteDC (GDI32.@)
398 BOOL WINAPI DeleteDC( HDC hdc )
400 DC_ATTR *dc_attr;
402 if (is_meta_dc( hdc )) return METADC_DeleteDC( hdc );
403 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
404 HeapFree( GetProcessHeap(), 0, (WCHAR *)(ULONG_PTR)dc_attr->output );
405 dc_attr->output = 0;
406 if (dc_attr->hspool) ClosePrinter( ULongToHandle(dc_attr->hspool) );
407 dc_attr->hspool = 0;
408 if (dc_attr->emf) EMFDC_DeleteDC( dc_attr );
409 return NtGdiDeleteObjectApp( hdc );
412 /***********************************************************************
413 * ResetDCA (GDI32.@)
415 HDC WINAPI ResetDCA( HDC hdc, const DEVMODEA *devmode )
417 DEVMODEW *devmodeW;
418 HDC ret;
420 if (devmode) devmodeW = GdiConvertToDevmodeW( devmode );
421 else devmodeW = NULL;
423 ret = ResetDCW( hdc, devmodeW );
425 HeapFree( GetProcessHeap(), 0, devmodeW );
426 return ret;
429 /***********************************************************************
430 * ResetDCW (GDI32.@)
432 HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
434 return NtGdiResetDC( hdc, devmode, NULL, NULL, NULL ) ? hdc : 0;
437 /***********************************************************************
438 * SaveDC (GDI32.@)
440 INT WINAPI SaveDC( HDC hdc )
442 DC_ATTR *dc_attr;
444 if (is_meta_dc( hdc )) return METADC_SaveDC( hdc );
445 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
446 if (dc_attr->emf && !EMFDC_SaveDC( dc_attr )) return FALSE;
447 return NtGdiSaveDC( hdc );
450 /***********************************************************************
451 * RestoreDC (GDI32.@)
453 BOOL WINAPI RestoreDC( HDC hdc, INT level )
455 DC_ATTR *dc_attr;
457 if (is_meta_dc( hdc )) return METADC_RestoreDC( hdc, level );
458 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
459 if (dc_attr->emf && !EMFDC_RestoreDC( dc_attr, level )) return FALSE;
460 return NtGdiRestoreDC( hdc, level );
463 /***********************************************************************
464 * GetDeviceCaps (GDI32.@)
466 INT WINAPI GetDeviceCaps( HDC hdc, INT cap )
468 if (is_meta_dc( hdc )) return METADC_GetDeviceCaps( hdc, cap );
469 if (!get_dc_attr( hdc )) return FALSE;
470 return NtGdiGetDeviceCaps( hdc, cap );
473 /***********************************************************************
474 * Escape (GDI32.@)
476 INT WINAPI Escape( HDC hdc, INT escape, INT in_count, const char *in_data, void *out_data )
478 INT ret;
479 POINT *pt;
481 switch (escape)
483 case ABORTDOC:
484 return AbortDoc( hdc );
486 case ENDDOC:
487 return EndDoc( hdc );
489 case GETPHYSPAGESIZE:
490 pt = out_data;
491 pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH );
492 pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT );
493 return 1;
495 case GETPRINTINGOFFSET:
496 pt = out_data;
497 pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX );
498 pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY );
499 return 1;
501 case GETSCALINGFACTOR:
502 pt = out_data;
503 pt->x = GetDeviceCaps( hdc, SCALINGFACTORX );
504 pt->y = GetDeviceCaps( hdc, SCALINGFACTORY );
505 return 1;
507 case NEWFRAME:
508 return EndPage( hdc );
510 case SETABORTPROC:
511 return SetAbortProc( hdc, (ABORTPROC)in_data );
513 case STARTDOC:
515 DOCINFOA doc;
516 char *name = NULL;
518 /* in_data may not be 0 terminated so we must copy it */
519 if (in_data)
521 name = HeapAlloc( GetProcessHeap(), 0, in_count+1 );
522 memcpy( name, in_data, in_count );
523 name[in_count] = 0;
525 /* out_data is actually a pointer to the DocInfo structure and used as
526 * a second input parameter */
527 if (out_data) doc = *(DOCINFOA *)out_data;
528 else
530 doc.cbSize = sizeof(doc);
531 doc.lpszOutput = NULL;
532 doc.lpszDatatype = NULL;
533 doc.fwType = 0;
535 doc.lpszDocName = name;
536 ret = StartDocA( hdc, &doc );
537 HeapFree( GetProcessHeap(), 0, name );
538 if (ret > 0) ret = StartPage( hdc );
539 return ret;
542 case QUERYESCSUPPORT:
544 DWORD code;
546 if (in_count < sizeof(SHORT)) return 0;
547 code = (in_count < sizeof(DWORD)) ? *(const USHORT *)in_data : *(const DWORD *)in_data;
548 switch (code)
550 case ABORTDOC:
551 case ENDDOC:
552 case GETPHYSPAGESIZE:
553 case GETPRINTINGOFFSET:
554 case GETSCALINGFACTOR:
555 case NEWFRAME:
556 case QUERYESCSUPPORT:
557 case SETABORTPROC:
558 case STARTDOC:
559 return TRUE;
561 break;
565 /* if not handled internally, pass it to the driver */
566 return ExtEscape( hdc, escape, in_count, in_data, 0, out_data );
569 /***********************************************************************
570 * ExtEscape [GDI32.@]
572 INT WINAPI ExtEscape( HDC hdc, INT escape, INT input_size, const char *input,
573 INT output_size, char *output )
575 if (is_meta_dc( hdc ))
576 return METADC_ExtEscape( hdc, escape, input_size, input, output_size, output );
577 return NtGdiExtEscape( hdc, NULL, 0, escape, input_size, input, output_size, output );
580 /***********************************************************************
581 * GetTextAlign (GDI32.@)
583 UINT WINAPI GetTextAlign( HDC hdc )
585 DC_ATTR *dc_attr = get_dc_attr( hdc );
586 return dc_attr ? dc_attr->text_align : 0;
589 /***********************************************************************
590 * SetTextAlign (GDI32.@)
592 UINT WINAPI SetTextAlign( HDC hdc, UINT align )
594 DC_ATTR *dc_attr;
595 UINT ret;
597 TRACE("hdc=%p align=%d\n", hdc, align);
599 if (is_meta_dc( hdc )) return METADC_SetTextAlign( hdc, align );
600 if (!(dc_attr = get_dc_attr( hdc ))) return GDI_ERROR;
601 if (dc_attr->emf && !EMFDC_SetTextAlign( dc_attr, align )) return GDI_ERROR;
603 ret = dc_attr->text_align;
604 dc_attr->text_align = align;
605 return ret;
608 /***********************************************************************
609 * GetBkColor (GDI32.@)
611 COLORREF WINAPI GetBkColor( HDC hdc )
613 DC_ATTR *dc_attr = get_dc_attr( hdc );
614 return dc_attr ? dc_attr->background_color : CLR_INVALID;
617 /***********************************************************************
618 * SetBkColor (GDI32.@)
620 COLORREF WINAPI SetBkColor( HDC hdc, COLORREF color )
622 DC_ATTR *dc_attr;
623 COLORREF ret;
625 if (is_meta_dc( hdc )) return METADC_SetBkColor( hdc, color );
626 if (!(dc_attr = get_dc_attr( hdc ))) return CLR_INVALID;
627 if (dc_attr->emf && !EMFDC_SetBkColor( dc_attr, color )) return CLR_INVALID;
628 return NtGdiGetAndSetDCDword( hdc, NtGdiSetBkColor, color, &ret ) ? ret : CLR_INVALID;
631 /***********************************************************************
632 * GetDCBrushColor (GDI32.@)
634 COLORREF WINAPI GetDCBrushColor( HDC hdc )
636 DC_ATTR *dc_attr = get_dc_attr( hdc );
637 return dc_attr ? dc_attr->brush_color : CLR_INVALID;
640 /***********************************************************************
641 * SetDCBrushColor (GDI32.@)
643 COLORREF WINAPI SetDCBrushColor( HDC hdc, COLORREF color )
645 DC_ATTR *dc_attr;
646 COLORREF ret;
648 if (!(dc_attr = get_dc_attr( hdc ))) return CLR_INVALID;
649 if (dc_attr->emf && !EMFDC_SetDCBrushColor( dc_attr, color )) return CLR_INVALID;
650 return NtGdiGetAndSetDCDword( hdc, NtGdiSetDCBrushColor, color, &ret ) ? ret : CLR_INVALID;
653 /***********************************************************************
654 * GetDCPenColor (GDI32.@)
656 COLORREF WINAPI GetDCPenColor(HDC hdc)
658 DC_ATTR *dc_attr = get_dc_attr( hdc );
659 return dc_attr ? dc_attr->pen_color : CLR_INVALID;
662 /***********************************************************************
663 * SetDCPenColor (GDI32.@)
665 COLORREF WINAPI SetDCPenColor( HDC hdc, COLORREF color )
667 DC_ATTR *dc_attr;
668 COLORREF ret;
670 if (!(dc_attr = get_dc_attr( hdc ))) return CLR_INVALID;
671 if (dc_attr->emf && !EMFDC_SetDCPenColor( dc_attr, color )) return CLR_INVALID;
672 return NtGdiGetAndSetDCDword( hdc, NtGdiSetDCPenColor, color, &ret ) ? ret : CLR_INVALID;
675 /***********************************************************************
676 * GetTextColor (GDI32.@)
678 COLORREF WINAPI GetTextColor( HDC hdc )
680 DC_ATTR *dc_attr = get_dc_attr( hdc );
681 return dc_attr ? dc_attr->text_color : 0;
684 /***********************************************************************
685 * SetTextColor (GDI32.@)
687 COLORREF WINAPI SetTextColor( HDC hdc, COLORREF color )
689 DC_ATTR *dc_attr;
690 COLORREF ret;
692 if (is_meta_dc( hdc )) return METADC_SetTextColor( hdc, color );
693 if (!(dc_attr = get_dc_attr( hdc ))) return CLR_INVALID;
694 if (dc_attr->emf && !EMFDC_SetTextColor( dc_attr, color )) return CLR_INVALID;
695 return NtGdiGetAndSetDCDword( hdc, NtGdiSetTextColor, color, &ret ) ? ret : CLR_INVALID;
698 /***********************************************************************
699 * GetBkMode (GDI32.@)
701 INT WINAPI GetBkMode( HDC hdc )
703 DC_ATTR *dc_attr = get_dc_attr( hdc );
704 return dc_attr ? dc_attr->background_mode : 0;
707 /***********************************************************************
708 * SetBkMode (GDI32.@)
710 INT WINAPI SetBkMode( HDC hdc, INT mode )
712 DC_ATTR *dc_attr;
713 INT ret;
715 if (mode <= 0 || mode > BKMODE_LAST)
717 SetLastError(ERROR_INVALID_PARAMETER);
718 return 0;
721 if (is_meta_dc( hdc )) return METADC_SetBkMode( hdc, mode );
722 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
723 if (dc_attr->emf && !EMFDC_SetBkMode( dc_attr, mode )) return 0;
725 ret = dc_attr->background_mode;
726 dc_attr->background_mode = mode;
727 return ret;
730 /***********************************************************************
731 * GetGraphicsMode (GDI32.@)
733 INT WINAPI GetGraphicsMode( HDC hdc )
735 DC_ATTR *dc_attr = get_dc_attr( hdc );
736 return dc_attr ? dc_attr->graphics_mode : 0;
739 /***********************************************************************
740 * SetGraphicsMode (GDI32.@)
742 INT WINAPI SetGraphicsMode( HDC hdc, INT mode )
744 DWORD ret;
745 return NtGdiGetAndSetDCDword( hdc, NtGdiSetGraphicsMode, mode, &ret ) ? ret : 0;
748 /***********************************************************************
749 * GetArcDirection (GDI32.@)
751 INT WINAPI GetArcDirection( HDC hdc )
753 DC_ATTR *dc_attr = get_dc_attr( hdc );
754 return dc_attr ? dc_attr->arc_direction : 0;
757 /***********************************************************************
758 * SetArcDirection (GDI32.@)
760 INT WINAPI SetArcDirection( HDC hdc, INT dir )
762 DC_ATTR *dc_attr;
763 INT ret;
765 if (dir != AD_COUNTERCLOCKWISE && dir != AD_CLOCKWISE)
767 SetLastError(ERROR_INVALID_PARAMETER);
768 return 0;
771 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
772 if (dc_attr->emf && !EMFDC_SetArcDirection( dc_attr, dir )) return 0;
774 ret = dc_attr->arc_direction;
775 dc_attr->arc_direction = dir;
776 return ret;
779 /***********************************************************************
780 * GetLayout (GDI32.@)
782 DWORD WINAPI GetLayout( HDC hdc )
784 DC_ATTR *dc_attr = get_dc_attr( hdc );
785 return dc_attr ? dc_attr->layout : GDI_ERROR;
788 /***********************************************************************
789 * SetLayout (GDI32.@)
791 DWORD WINAPI SetLayout( HDC hdc, DWORD layout )
793 DC_ATTR *dc_attr;
795 if (is_meta_dc( hdc )) return METADC_SetLayout( hdc, layout );
796 if (!(dc_attr = get_dc_attr( hdc ))) return GDI_ERROR;
797 if (dc_attr->emf && !EMFDC_SetLayout( dc_attr, layout )) return GDI_ERROR;
798 return NtGdiSetLayout( hdc, -1, layout );
801 /***********************************************************************
802 * GetMapMode (GDI32.@)
804 INT WINAPI GetMapMode( HDC hdc )
806 DC_ATTR *dc_attr = get_dc_attr( hdc );
807 return dc_attr ? dc_attr->map_mode : 0;
810 /***********************************************************************
811 * SetMapMode (GDI32.@)
813 INT WINAPI SetMapMode( HDC hdc, INT mode )
815 DC_ATTR *dc_attr;
816 DWORD ret;
818 TRACE("%p %d\n", hdc, mode );
820 if (is_meta_dc( hdc )) return METADC_SetMapMode( hdc, mode );
821 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
822 if (dc_attr->emf && !EMFDC_SetMapMode( dc_attr, mode )) return 0;
823 return NtGdiGetAndSetDCDword( hdc, NtGdiSetMapMode, mode, &ret ) ? ret : 0;
826 /***********************************************************************
827 * GetTextCharacterExtra (GDI32.@)
829 INT WINAPI GetTextCharacterExtra( HDC hdc )
831 DC_ATTR *dc_attr = get_dc_attr( hdc );
832 return dc_attr ? dc_attr->char_extra : 0x80000000;
835 /***********************************************************************
836 * SetTextCharacterExtra (GDI32.@)
838 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
840 DC_ATTR *dc_attr;
841 INT ret;
843 if (is_meta_dc( hdc )) return METADC_SetTextCharacterExtra( hdc, extra );
844 if (!(dc_attr = get_dc_attr( hdc ))) return 0x8000000;
845 ret = dc_attr->char_extra;
846 dc_attr->char_extra = extra;
847 return ret;
850 /***********************************************************************
851 * SetMapperFlags (GDI32.@)
853 DWORD WINAPI SetMapperFlags( HDC hdc, DWORD flags )
855 DC_ATTR *dc_attr;
856 DWORD ret;
858 if (is_meta_dc( hdc )) return METADC_SetMapperFlags( hdc, flags );
859 if (!(dc_attr = get_dc_attr( hdc ))) return GDI_ERROR;
860 if (dc_attr->emf && !EMFDC_SetMapperFlags( dc_attr, flags )) return GDI_ERROR;
861 ret = dc_attr->mapper_flags;
862 dc_attr->mapper_flags = flags;
863 return ret;
866 /***********************************************************************
867 * GetPolyFillMode (GDI32.@)
869 INT WINAPI GetPolyFillMode( HDC hdc )
871 DC_ATTR *dc_attr = get_dc_attr( hdc );
872 return dc_attr ? dc_attr->poly_fill_mode : 0;
875 /***********************************************************************
876 * SetPolyFillMode (GDI32.@)
878 INT WINAPI SetPolyFillMode( HDC hdc, INT mode )
880 DC_ATTR *dc_attr;
881 INT ret;
883 if (mode <= 0 || mode > POLYFILL_LAST)
885 SetLastError(ERROR_INVALID_PARAMETER);
886 return 0;
889 if (is_meta_dc( hdc )) return METADC_SetPolyFillMode( hdc, mode );
890 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
891 if (dc_attr->emf && !EMFDC_SetPolyFillMode( dc_attr, mode )) return 0;
893 ret = dc_attr->poly_fill_mode;
894 dc_attr->poly_fill_mode = mode;
895 return ret;
898 /***********************************************************************
899 * GetStretchBltMode (GDI32.@)
901 INT WINAPI GetStretchBltMode( HDC hdc )
903 DC_ATTR *dc_attr = get_dc_attr( hdc );
904 return dc_attr ? dc_attr->stretch_blt_mode : 0;
907 /***********************************************************************
908 * GetBrushOrgEx (GDI32.@)
910 BOOL WINAPI GetBrushOrgEx( HDC hdc, POINT *point )
912 DC_ATTR *dc_attr;
913 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
914 *point = dc_attr->brush_org;
915 return TRUE;
918 /***********************************************************************
919 * SetBrushOrgEx (GDI32.@)
921 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, POINT *oldorg )
923 DC_ATTR *dc_attr;
924 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
925 if (oldorg) *oldorg = dc_attr->brush_org;
926 dc_attr->brush_org.x = x;
927 dc_attr->brush_org.y = y;
928 return TRUE;
931 /***********************************************************************
932 * FixBrushOrgEx (GDI32.@)
934 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, POINT *oldorg )
936 return SetBrushOrgEx( hdc, x, y, oldorg );
939 /***********************************************************************
940 * GetDCOrgEx (GDI32.@)
942 BOOL WINAPI GetDCOrgEx( HDC hdc, POINT *point )
944 DC_ATTR *dc_attr;
945 if (!point || !(dc_attr = get_dc_attr( hdc ))) return FALSE;
946 point->x = dc_attr->vis_rect.left;
947 point->y = dc_attr->vis_rect.top;
948 return TRUE;
951 /***********************************************************************
952 * GetWindowExtEx (GDI32.@)
954 BOOL WINAPI GetWindowExtEx( HDC hdc, SIZE *size )
956 DC_ATTR *dc_attr;
957 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
958 *size = dc_attr->wnd_ext;
959 return TRUE;
962 /***********************************************************************
963 * SetWindowExtEx (GDI32.@)
965 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, SIZE *size )
967 DC_ATTR *dc_attr;
969 if (is_meta_dc( hdc )) return METADC_SetWindowExtEx( hdc, x, y );
970 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
971 if (dc_attr->emf && !EMFDC_SetWindowExtEx( dc_attr, x, y )) return FALSE;
973 if (size) *size = dc_attr->wnd_ext;
974 if (dc_attr->map_mode != MM_ISOTROPIC && dc_attr->map_mode != MM_ANISOTROPIC) return TRUE;
975 if (!x || !y) return FALSE;
976 dc_attr->wnd_ext.cx = x;
977 dc_attr->wnd_ext.cy = y;
978 return NtGdiComputeXformCoefficients( hdc );
981 /***********************************************************************
982 * GetWindowOrgEx (GDI32.@)
984 BOOL WINAPI GetWindowOrgEx( HDC hdc, POINT *point )
986 DC_ATTR *dc_attr;
987 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
988 *point = dc_attr->wnd_org;
989 return TRUE;
992 /***********************************************************************
993 * SetWindowOrgEx (GDI32.@)
995 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, POINT *point )
997 DC_ATTR *dc_attr;
999 if (is_meta_dc( hdc )) return METADC_SetWindowOrgEx( hdc, x, y );
1000 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1001 if (dc_attr->emf && !EMFDC_SetWindowOrgEx( dc_attr, x, y )) return FALSE;
1003 if (point) *point = dc_attr->wnd_org;
1004 dc_attr->wnd_org.x = x;
1005 dc_attr->wnd_org.y = y;
1006 return NtGdiComputeXformCoefficients( hdc );
1009 /***********************************************************************
1010 * OffsetWindowOrgEx (GDI32.@)
1012 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, POINT *point )
1014 DC_ATTR *dc_attr;
1016 if (is_meta_dc( hdc )) return METADC_OffsetWindowOrgEx( hdc, x, y );
1017 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1018 if (point) *point = dc_attr->wnd_org;
1019 dc_attr->wnd_org.x += x;
1020 dc_attr->wnd_org.y += y;
1021 if (dc_attr->emf && !EMFDC_SetWindowOrgEx( dc_attr, dc_attr->wnd_org.x,
1022 dc_attr->wnd_org.y )) return FALSE;
1023 return NtGdiComputeXformCoefficients( hdc );
1026 /***********************************************************************
1027 * GetViewportExtEx (GDI32.@)
1029 BOOL WINAPI GetViewportExtEx( HDC hdc, SIZE *size )
1031 DC_ATTR *dc_attr;
1032 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1033 *size = dc_attr->vport_ext;
1034 return TRUE;
1037 /***********************************************************************
1038 * SetViewportExtEx (GDI32.@)
1040 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
1042 DC_ATTR *dc_attr;
1044 if (is_meta_dc( hdc )) return METADC_SetViewportExtEx( hdc, x, y );
1045 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1046 if (dc_attr->emf && !EMFDC_SetViewportExtEx( dc_attr, x, y )) return FALSE;
1048 if (size) *size = dc_attr->vport_ext;
1049 if (dc_attr->map_mode != MM_ISOTROPIC && dc_attr->map_mode != MM_ANISOTROPIC) return TRUE;
1050 if (!x || !y) return FALSE;
1051 dc_attr->vport_ext.cx = x;
1052 dc_attr->vport_ext.cy = y;
1053 return NtGdiComputeXformCoefficients( hdc );
1056 /***********************************************************************
1057 * GetViewportOrgEx (GDI32.@)
1059 BOOL WINAPI GetViewportOrgEx( HDC hdc, POINT *point )
1061 DC_ATTR *dc_attr;
1062 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1063 *point = dc_attr->vport_org;
1064 return TRUE;
1067 /***********************************************************************
1068 * SetViewportOrgEx (GDI32.@)
1070 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, POINT *point )
1072 DC_ATTR *dc_attr;
1074 if (is_meta_dc( hdc )) return METADC_SetViewportOrgEx( hdc, x, y );
1075 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1076 if (dc_attr->emf && !EMFDC_SetViewportOrgEx( dc_attr, x, y )) return FALSE;
1078 if (point) *point = dc_attr->vport_org;
1079 dc_attr->vport_org.x = x;
1080 dc_attr->vport_org.y = y;
1081 return NtGdiComputeXformCoefficients( hdc );
1084 /***********************************************************************
1085 * OffsetViewportOrgEx (GDI32.@)
1087 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, POINT *point )
1089 DC_ATTR *dc_attr;
1091 if (is_meta_dc( hdc )) return METADC_OffsetViewportOrgEx( hdc, x, y );
1092 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1093 if (point) *point = dc_attr->vport_org;
1094 dc_attr->vport_org.x += x;
1095 dc_attr->vport_org.y += y;
1096 if (dc_attr->emf && !EMFDC_SetViewportOrgEx( dc_attr, dc_attr->vport_org.x,
1097 dc_attr->vport_org.y )) return FALSE;
1098 return NtGdiComputeXformCoefficients( hdc );
1101 /***********************************************************************
1102 * GetWorldTransform (GDI32.@)
1104 BOOL WINAPI GetWorldTransform( HDC hdc, XFORM *xform )
1106 return NtGdiGetTransform( hdc, 0x203, xform );
1109 /****************************************************************************
1110 * ModifyWorldTransform (GDI32.@)
1112 BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform, DWORD mode )
1114 DC_ATTR *dc_attr;
1116 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1117 if (dc_attr->emf && !EMFDC_ModifyWorldTransform( dc_attr, xform, mode )) return FALSE;
1118 return NtGdiModifyWorldTransform( hdc, xform, mode );
1121 /***********************************************************************
1122 * SetWorldTransform (GDI32.@)
1124 BOOL WINAPI SetWorldTransform( HDC hdc, const XFORM *xform )
1126 DC_ATTR *dc_attr;
1128 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1129 if (dc_attr->emf && !EMFDC_SetWorldTransform( dc_attr, xform )) return FALSE;
1130 return NtGdiModifyWorldTransform( hdc, xform, MWT_SET );
1133 /***********************************************************************
1134 * SetStretchBltMode (GDI32.@)
1136 INT WINAPI SetStretchBltMode( HDC hdc, INT mode )
1138 DC_ATTR *dc_attr;
1139 INT ret;
1141 if (mode <= 0 || mode > MAXSTRETCHBLTMODE)
1143 SetLastError(ERROR_INVALID_PARAMETER);
1144 return 0;
1147 if (is_meta_dc( hdc )) return METADC_SetStretchBltMode( hdc, mode );
1148 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
1149 if (dc_attr->emf && !EMFDC_SetStretchBltMode( dc_attr, mode )) return 0;
1151 ret = dc_attr->stretch_blt_mode;
1152 dc_attr->stretch_blt_mode = mode;
1153 return ret;
1156 /***********************************************************************
1157 * GetCurrentPositionEx (GDI32.@)
1159 BOOL WINAPI GetCurrentPositionEx( HDC hdc, POINT *point )
1161 DC_ATTR *dc_attr;
1162 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1163 *point = dc_attr->cur_pos;
1164 return TRUE;
1167 /***********************************************************************
1168 * GetROP2 (GDI32.@)
1170 INT WINAPI GetROP2( HDC hdc )
1172 DC_ATTR *dc_attr = get_dc_attr( hdc );
1173 return dc_attr ? dc_attr->rop_mode : 0;
1176 /***********************************************************************
1177 * GetRelAbs (GDI32.@)
1179 INT WINAPI GetRelAbs( HDC hdc, DWORD ignore )
1181 DC_ATTR *dc_attr = get_dc_attr( hdc );
1182 return dc_attr ? dc_attr->rel_abs_mode : 0;
1185 /***********************************************************************
1186 * SetRelAbs (GDI32.@)
1188 INT WINAPI SetRelAbs( HDC hdc, INT mode )
1190 DC_ATTR *dc_attr;
1191 INT ret;
1193 if (mode != ABSOLUTE && mode != RELATIVE)
1195 SetLastError(ERROR_INVALID_PARAMETER);
1196 return 0;
1199 if (is_meta_dc( hdc )) return METADC_SetRelAbs( hdc, mode );
1200 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
1201 ret = dc_attr->rel_abs_mode;
1202 dc_attr->rel_abs_mode = mode;
1203 return ret;
1206 /***********************************************************************
1207 * SetROP2 (GDI32.@)
1209 INT WINAPI SetROP2( HDC hdc, INT mode )
1211 DC_ATTR *dc_attr;
1212 INT ret;
1214 if ((mode < R2_BLACK) || (mode > R2_WHITE))
1216 SetLastError(ERROR_INVALID_PARAMETER);
1217 return 0;
1220 if (is_meta_dc( hdc )) return METADC_SetROP2( hdc, mode );
1221 if (!(dc_attr = get_dc_attr( hdc ))) return 0;
1222 if (dc_attr->emf && !EMFDC_SetROP2( dc_attr, mode )) return 0;
1224 ret = dc_attr->rop_mode;
1225 dc_attr->rop_mode = mode;
1226 return ret;
1229 /***********************************************************************
1230 * GetMiterLimit (GDI32.@)
1232 BOOL WINAPI GetMiterLimit( HDC hdc, FLOAT *limit )
1234 DC_ATTR *dc_attr;
1235 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1236 if (limit) *limit = dc_attr->miter_limit;
1237 return TRUE;
1240 /*******************************************************************
1241 * SetMiterLimit (GDI32.@)
1243 BOOL WINAPI SetMiterLimit( HDC hdc, FLOAT limit, FLOAT *old_limit )
1245 DC_ATTR *dc_attr;
1246 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1247 /* FIXME: record EMFs */
1248 if (old_limit) *old_limit = dc_attr->miter_limit;
1249 dc_attr->miter_limit = limit;
1250 return TRUE;
1253 /***********************************************************************
1254 * SetPixel (GDI32.@)
1256 COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
1258 DC_ATTR *dc_attr;
1260 if (is_meta_dc( hdc )) return METADC_SetPixel( hdc, x, y, color );
1261 if (!(dc_attr = get_dc_attr( hdc ))) return CLR_INVALID;
1262 if (dc_attr->emf && !EMFDC_SetPixel( dc_attr, x, y, color )) return CLR_INVALID;
1263 return NtGdiSetPixel( hdc, x, y, color );
1266 /***********************************************************************
1267 * SetPixelV (GDI32.@)
1269 BOOL WINAPI SetPixelV( HDC hdc, INT x, INT y, COLORREF color )
1271 return SetPixel( hdc, x, y, color ) != CLR_INVALID;
1274 /***********************************************************************
1275 * LineTo (GDI32.@)
1277 BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
1279 DC_ATTR *dc_attr;
1281 TRACE( "%p, (%d, %d)\n", hdc, x, y );
1283 if (is_meta_dc( hdc )) return METADC_LineTo( hdc, x, y );
1284 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1285 if (dc_attr->emf && !EMFDC_LineTo( dc_attr, x, y )) return FALSE;
1286 return NtGdiLineTo( hdc, x, y );
1289 /***********************************************************************
1290 * MoveToEx (GDI32.@)
1292 BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, POINT *pt )
1294 DC_ATTR *dc_attr;
1296 TRACE( "%p, (%d, %d), %p\n", hdc, x, y, pt );
1298 if (is_meta_dc( hdc )) return METADC_MoveTo( hdc, x, y );
1299 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1300 if (dc_attr->emf && !EMFDC_MoveTo( dc_attr, x, y )) return FALSE;
1301 return NtGdiMoveTo( hdc, x, y, pt );
1304 /***********************************************************************
1305 * Arc (GDI32.@)
1307 BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
1308 INT xstart, INT ystart, INT xend, INT yend )
1310 DC_ATTR *dc_attr;
1312 TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
1313 right, bottom, xstart, ystart, xend, yend );
1315 if (is_meta_dc( hdc ))
1316 return METADC_Arc( hdc, left, top, right, bottom,
1317 xstart, ystart, xend, yend );
1319 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1320 if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
1321 xstart, ystart, xend, yend, EMR_ARC ))
1322 return FALSE;
1324 return NtGdiArcInternal( NtGdiArc, hdc, left, top, right, bottom,
1325 xstart, ystart, xend, yend );
1328 /***********************************************************************
1329 * ArcTo (GDI32.@)
1331 BOOL WINAPI ArcTo( HDC hdc, INT left, INT top, INT right, INT bottom,
1332 INT xstart, INT ystart, INT xend, INT yend )
1334 DC_ATTR *dc_attr;
1336 TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
1337 right, bottom, xstart, ystart, xend, yend );
1339 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1340 if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
1341 xstart, ystart, xend, yend, EMR_ARCTO ))
1342 return FALSE;
1344 return NtGdiArcInternal( NtGdiArcTo, hdc, left, top, right, bottom,
1345 xstart, ystart, xend, yend );
1348 /***********************************************************************
1349 * Chord (GDI32.@)
1351 BOOL WINAPI Chord( HDC hdc, INT left, INT top, INT right, INT bottom,
1352 INT xstart, INT ystart, INT xend, INT yend )
1354 DC_ATTR *dc_attr;
1356 TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
1357 right, bottom, xstart, ystart, xend, yend );
1359 if (is_meta_dc( hdc ))
1360 return METADC_Chord( hdc, left, top, right, bottom,
1361 xstart, ystart, xend, yend );
1363 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1364 if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
1365 xstart, ystart, xend, yend, EMR_CHORD ))
1366 return FALSE;
1368 return NtGdiArcInternal( NtGdiChord, hdc, left, top, right, bottom,
1369 xstart, ystart, xend, yend );
1372 /***********************************************************************
1373 * Pie (GDI32.@)
1375 BOOL WINAPI Pie( HDC hdc, INT left, INT top, INT right, INT bottom,
1376 INT xstart, INT ystart, INT xend, INT yend )
1378 DC_ATTR *dc_attr;
1380 TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
1381 right, bottom, xstart, ystart, xend, yend );
1383 if (is_meta_dc( hdc ))
1384 return METADC_Pie( hdc, left, top, right, bottom,
1385 xstart, ystart, xend, yend );
1387 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1388 if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
1389 xstart, ystart, xend, yend, EMR_PIE ))
1390 return FALSE;
1392 return NtGdiArcInternal( NtGdiPie, hdc, left, top, right, bottom,
1393 xstart, ystart, xend, yend );
1396 /***********************************************************************
1397 * AngleArc (GDI32.@)
1399 BOOL WINAPI AngleArc( HDC hdc, INT x, INT y, DWORD radius, FLOAT start_angle, FLOAT sweep_angle )
1401 DC_ATTR *dc_attr;
1403 TRACE( "%p, (%d, %d), %lu, %f, %f\n", hdc, x, y, radius, start_angle, sweep_angle );
1405 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1406 if (dc_attr->emf && !EMFDC_AngleArc( dc_attr, x, y, radius, start_angle, sweep_angle ))
1407 return FALSE;
1408 return NtGdiAngleArc( hdc, x, y, radius, start_angle, sweep_angle );
1411 /***********************************************************************
1412 * Ellipse (GDI32.@)
1414 BOOL WINAPI Ellipse( HDC hdc, INT left, INT top, INT right, INT bottom )
1416 DC_ATTR *dc_attr;
1418 TRACE( "%p, (%d, %d)-(%d, %d)\n", hdc, left, top, right, bottom );
1420 if (is_meta_dc( hdc )) return METADC_Ellipse( hdc, left, top, right, bottom );
1421 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1422 if (dc_attr->emf && !EMFDC_Ellipse( dc_attr, left, top, right, bottom )) return FALSE;
1423 return NtGdiEllipse( hdc, left, top, right, bottom );
1426 /***********************************************************************
1427 * Rectangle (GDI32.@)
1429 BOOL WINAPI Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom )
1431 DC_ATTR *dc_attr;
1433 TRACE( "%p, (%d, %d)-(%d, %d)\n", hdc, left, top, right, bottom );
1435 if (is_meta_dc( hdc )) return METADC_Rectangle( hdc, left, top, right, bottom );
1436 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1437 if (dc_attr->emf && !EMFDC_Rectangle( dc_attr, left, top, right, bottom )) return FALSE;
1438 return NtGdiRectangle( hdc, left, top, right, bottom );
1441 /***********************************************************************
1442 * RoundRect (GDI32.@)
1444 BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right,
1445 INT bottom, INT ell_width, INT ell_height )
1447 DC_ATTR *dc_attr;
1449 TRACE( "%p, (%d, %d)-(%d, %d), %dx%d\n", hdc, left, top, right, bottom,
1450 ell_width, ell_height );
1452 if (is_meta_dc( hdc ))
1453 return METADC_RoundRect( hdc, left, top, right, bottom, ell_width, ell_height );
1455 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1456 if (dc_attr->emf && !EMFDC_RoundRect( dc_attr, left, top, right, bottom,
1457 ell_width, ell_height ))
1458 return FALSE;
1460 return NtGdiRoundRect( hdc, left, top, right, bottom, ell_width, ell_height );
1463 /**********************************************************************
1464 * Polygon (GDI32.@)
1466 BOOL WINAPI Polygon( HDC hdc, const POINT *points, INT count )
1468 DC_ATTR *dc_attr;
1470 TRACE( "%p, %p, %d\n", hdc, points, count );
1472 if (is_meta_dc( hdc )) return METADC_Polygon( hdc, points, count );
1473 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1474 if (dc_attr->emf && !EMFDC_Polygon( dc_attr, points, count )) return FALSE;
1475 return NtGdiPolyPolyDraw( hdc, points, (const ULONG *)&count, 1, NtGdiPolyPolygon );
1478 /**********************************************************************
1479 * PolyPolygon (GDI32.@)
1481 BOOL WINAPI PolyPolygon( HDC hdc, const POINT *points, const INT *counts, UINT polygons )
1483 DC_ATTR *dc_attr;
1485 TRACE( "%p, %p, %p, %u\n", hdc, points, counts, polygons );
1487 if (is_meta_dc( hdc )) return METADC_PolyPolygon( hdc, points, counts, polygons );
1488 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1489 if (dc_attr->emf && !EMFDC_PolyPolygon( dc_attr, points, counts, polygons )) return FALSE;
1490 return NtGdiPolyPolyDraw( hdc, points, (const ULONG *)counts, polygons, NtGdiPolyPolygon );
1493 /**********************************************************************
1494 * Polyline (GDI32.@)
1496 BOOL WINAPI Polyline( HDC hdc, const POINT *points, INT count )
1498 DC_ATTR *dc_attr;
1500 TRACE( "%p, %p, %d\n", hdc, points, count );
1502 if (is_meta_dc( hdc )) return METADC_Polyline( hdc, points, count );
1503 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1504 if (dc_attr->emf && !EMFDC_Polyline( dc_attr, points, count )) return FALSE;
1505 return NtGdiPolyPolyDraw( hdc, points, (const ULONG *)&count, 1, NtGdiPolyPolyline );
1508 /**********************************************************************
1509 * PolyPolyline (GDI32.@)
1511 BOOL WINAPI PolyPolyline( HDC hdc, const POINT *points, const DWORD *counts, DWORD polylines )
1513 DC_ATTR *dc_attr;
1515 TRACE( "%p, %p, %p, %lu\n", hdc, points, counts, polylines );
1517 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1518 if (dc_attr->emf && !EMFDC_PolyPolyline( dc_attr, points, counts, polylines )) return FALSE;
1519 return NtGdiPolyPolyDraw( hdc, points, counts, polylines, NtGdiPolyPolyline );
1522 /******************************************************************************
1523 * PolyBezier (GDI32.@)
1525 BOOL WINAPI PolyBezier( HDC hdc, const POINT *points, DWORD count )
1527 DC_ATTR *dc_attr;
1529 TRACE( "%p, %p, %lu\n", hdc, points, count );
1531 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1532 if (dc_attr->emf && !EMFDC_PolyBezier( dc_attr, points, count )) return FALSE;
1533 return NtGdiPolyPolyDraw( hdc, points, &count, 1, NtGdiPolyBezier );
1536 /******************************************************************************
1537 * PolyBezierTo (GDI32.@)
1539 BOOL WINAPI PolyBezierTo( HDC hdc, const POINT *points, DWORD count )
1541 DC_ATTR *dc_attr;
1543 TRACE( "%p, %p, %lu\n", hdc, points, count );
1545 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1546 if (dc_attr->emf && !EMFDC_PolyBezierTo( dc_attr, points, count )) return FALSE;
1547 return NtGdiPolyPolyDraw( hdc, points, &count, 1, NtGdiPolyBezierTo );
1550 /**********************************************************************
1551 * PolylineTo (GDI32.@)
1553 BOOL WINAPI PolylineTo( HDC hdc, const POINT *points, DWORD count )
1555 DC_ATTR *dc_attr;
1557 TRACE( "%p, %p, %lu\n", hdc, points, count );
1559 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1560 if (dc_attr->emf && !EMFDC_PolylineTo( dc_attr, points, count )) return FALSE;
1561 return NtGdiPolyPolyDraw( hdc, points, &count, 1, NtGdiPolylineTo );
1564 /***********************************************************************
1565 * PolyDraw (GDI32.@)
1567 BOOL WINAPI PolyDraw( HDC hdc, const POINT *points, const BYTE *types, DWORD count )
1569 DC_ATTR *dc_attr;
1571 TRACE( "%p, %p, %p, %lu\n", hdc, points, types, count );
1573 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1574 if (dc_attr->emf && !EMFDC_PolyDraw( dc_attr, points, types, count )) return FALSE;
1575 return NtGdiPolyDraw( hdc, points, types, count );
1578 /***********************************************************************
1579 * FillRgn (GDI32.@)
1581 BOOL WINAPI FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
1583 DC_ATTR *dc_attr;
1585 TRACE( "%p, %p, %p\n", hdc, hrgn, hbrush );
1587 if (is_meta_dc( hdc )) return METADC_FillRgn( hdc, hrgn, hbrush );
1588 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1589 if (dc_attr->emf && !EMFDC_FillRgn( dc_attr, hrgn, hbrush )) return FALSE;
1590 return NtGdiFillRgn( hdc, hrgn, hbrush );
1593 /***********************************************************************
1594 * PaintRgn (GDI32.@)
1596 BOOL WINAPI PaintRgn( HDC hdc, HRGN hrgn )
1598 DC_ATTR *dc_attr;
1600 TRACE( "%p, %p\n", hdc, hrgn );
1602 if (is_meta_dc( hdc )) return METADC_PaintRgn( hdc, hrgn );
1603 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1604 if (dc_attr->emf && !EMFDC_PaintRgn( dc_attr, hrgn )) return FALSE;
1605 return NtGdiFillRgn( hdc, hrgn, GetCurrentObject( hdc, OBJ_BRUSH ));
1608 /***********************************************************************
1609 * FrameRgn (GDI32.@)
1611 BOOL WINAPI FrameRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush, INT width, INT height )
1613 DC_ATTR *dc_attr;
1615 TRACE( "%p, %p, %p, %dx%d\n", hdc, hrgn, hbrush, width, height );
1617 if (is_meta_dc( hdc )) return METADC_FrameRgn( hdc, hrgn, hbrush, width, height );
1618 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1619 if (dc_attr->emf && !EMFDC_FrameRgn( dc_attr, hrgn, hbrush, width, height ))
1620 return FALSE;
1621 return NtGdiFrameRgn( hdc, hrgn, hbrush, width, height );
1624 /***********************************************************************
1625 * InvertRgn (GDI32.@)
1627 BOOL WINAPI InvertRgn( HDC hdc, HRGN hrgn )
1629 DC_ATTR *dc_attr;
1631 TRACE( "%p, %p\n", hdc, hrgn );
1633 if (is_meta_dc( hdc )) return METADC_InvertRgn( hdc, hrgn );
1634 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1635 if (dc_attr->emf && !EMFDC_InvertRgn( dc_attr, hrgn )) return FALSE;
1636 return NtGdiInvertRgn( hdc, hrgn );
1639 /***********************************************************************
1640 * ExtFloodFill (GDI32.@)
1642 BOOL WINAPI ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, UINT fill_type )
1644 DC_ATTR *dc_attr;
1646 TRACE( "%p, (%d, %d), %08lx, %x\n", hdc, x, y, color, fill_type );
1648 if (is_meta_dc( hdc )) return METADC_ExtFloodFill( hdc, x, y, color, fill_type );
1649 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1650 if (dc_attr->emf && !EMFDC_ExtFloodFill( dc_attr, x, y, color, fill_type )) return FALSE;
1651 return NtGdiExtFloodFill( hdc, x, y, color, fill_type );
1654 /***********************************************************************
1655 * FloodFill (GDI32.@)
1657 BOOL WINAPI FloodFill( HDC hdc, INT x, INT y, COLORREF color )
1659 return ExtFloodFill( hdc, x, y, color, FLOODFILLBORDER );
1662 /******************************************************************************
1663 * GdiGradientFill (GDI32.@)
1665 BOOL WINAPI GdiGradientFill( HDC hdc, TRIVERTEX *vert_array, ULONG nvert,
1666 void *grad_array, ULONG ngrad, ULONG mode )
1668 DC_ATTR *dc_attr;
1670 TRACE( "%p vert_array:%p nvert:%ld grad_array:%p ngrad:%ld\n", hdc, vert_array,
1671 nvert, grad_array, ngrad );
1673 if (!(dc_attr = get_dc_attr( hdc )))
1675 SetLastError( ERROR_INVALID_PARAMETER );
1676 return FALSE;
1678 if (dc_attr->emf &&
1679 !EMFDC_GradientFill( dc_attr, vert_array, nvert, grad_array, ngrad, mode ))
1680 return FALSE;
1681 return NtGdiGradientFill( hdc, vert_array, nvert, grad_array, ngrad, mode );
1684 /***********************************************************************
1685 * SetTextJustification (GDI32.@)
1687 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
1689 DC_ATTR *dc_attr;
1691 if (is_meta_dc( hdc )) return METADC_SetTextJustification( hdc, extra, breaks );
1692 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1693 if (dc_attr->emf && !EMFDC_SetTextJustification( dc_attr, extra, breaks ))
1694 return FALSE;
1695 return NtGdiSetTextJustification( hdc, extra, breaks );
1698 /***********************************************************************
1699 * PatBlt (GDI32.@)
1701 BOOL WINAPI PatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWORD rop )
1703 DC_ATTR *dc_attr;
1705 if (is_meta_dc( hdc )) return METADC_PatBlt( hdc, left, top, width, height, rop );
1706 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1707 if (dc_attr->emf && !EMFDC_PatBlt( dc_attr, left, top, width, height, rop ))
1708 return FALSE;
1709 return NtGdiPatBlt( hdc, left, top, width, height, rop );
1712 /***********************************************************************
1713 * BitBlt (GDI32.@)
1715 BOOL WINAPI DECLSPEC_HOTPATCH BitBlt( HDC hdc_dst, INT x_dst, INT y_dst, INT width, INT height,
1716 HDC hdc_src, INT x_src, INT y_src, DWORD rop )
1718 DC_ATTR *dc_attr;
1720 if (is_meta_dc( hdc_dst )) return METADC_BitBlt( hdc_dst, x_dst, y_dst, width, height,
1721 hdc_src, x_src, y_src, rop );
1722 if (!(dc_attr = get_dc_attr( hdc_dst ))) return FALSE;
1723 if (dc_attr->emf && !EMFDC_BitBlt( dc_attr, x_dst, y_dst, width, height,
1724 hdc_src, x_src, y_src, rop ))
1725 return FALSE;
1726 return NtGdiBitBlt( hdc_dst, x_dst, y_dst, width, height,
1727 hdc_src, x_src, y_src, rop, 0 /* FIXME */, 0 /* FIXME */ );
1730 /***********************************************************************
1731 * StretchBlt (GDI32.@)
1733 BOOL WINAPI StretchBlt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1734 HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src,
1735 DWORD rop )
1737 DC_ATTR *dc_attr;
1739 if (is_meta_dc( hdc )) return METADC_StretchBlt( hdc, x_dst, y_dst, width_dst, height_dst,
1740 hdc_src, x_src, y_src, width_src,
1741 height_src, rop );
1742 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1743 if (dc_attr->emf && !EMFDC_StretchBlt( dc_attr, x_dst, y_dst, width_dst, height_dst,
1744 hdc_src, x_src, y_src, width_src,
1745 height_src, rop ))
1746 return FALSE;
1747 return NtGdiStretchBlt( hdc, x_dst, y_dst, width_dst, height_dst,
1748 hdc_src, x_src, y_src, width_src,
1749 height_src, rop, 0 /* FIXME */ );
1752 /***********************************************************************
1753 * MaskBlt [GDI32.@]
1755 BOOL WINAPI MaskBlt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1756 HDC hdc_src, INT x_src, INT y_src, HBITMAP mask,
1757 INT x_mask, INT y_mask, DWORD rop )
1759 DC_ATTR *dc_attr;
1761 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1762 if (dc_attr->emf && !EMFDC_MaskBlt( dc_attr, x_dst, y_dst, width_dst, height_dst,
1763 hdc_src, x_src, y_src, mask, x_mask, y_mask, rop ))
1764 return FALSE;
1765 return NtGdiMaskBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src,
1766 mask, x_mask, y_mask, rop, 0 /* FIXME */ );
1769 /***********************************************************************
1770 * PlgBlt (GDI32.@)
1772 BOOL WINAPI PlgBlt( HDC hdc, const POINT *points, HDC hdc_src, INT x_src, INT y_src,
1773 INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask )
1775 DC_ATTR *dc_attr;
1777 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1778 if (dc_attr->emf && !EMFDC_PlgBlt( dc_attr, points, hdc_src, x_src, y_src,
1779 width, height, mask, x_mask, y_mask ))
1780 return FALSE;
1781 return NtGdiPlgBlt( hdc, points, hdc_src, x_src, y_src, width, height,
1782 mask, x_mask, y_mask, 0 /* FIXME */ );
1785 /******************************************************************************
1786 * GdiTransparentBlt (GDI32.@)
1788 BOOL WINAPI GdiTransparentBlt( HDC hdc, int x_dst, int y_dst, int width_dst, int height_dst,
1789 HDC hdc_src, int x_src, int y_src, int width_src, int height_src,
1790 UINT color )
1792 DC_ATTR *dc_attr;
1794 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1795 if (dc_attr->emf && !EMFDC_TransparentBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, hdc_src,
1796 x_src, y_src, width_src, height_src, color ))
1797 return FALSE;
1798 return NtGdiTransparentBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src,
1799 width_src, height_src, color );
1802 /******************************************************************************
1803 * GdiAlphaBlend (GDI32.@)
1805 BOOL WINAPI GdiAlphaBlend( HDC hdc_dst, int x_dst, int y_dst, int width_dst, int height_dst,
1806 HDC hdc_src, int x_src, int y_src, int width_src, int height_src,
1807 BLENDFUNCTION blend_function)
1809 DC_ATTR *dc_attr;
1811 if (!(dc_attr = get_dc_attr( hdc_dst ))) return FALSE;
1812 if (dc_attr->emf && !EMFDC_AlphaBlend( dc_attr, x_dst, y_dst, width_dst, height_dst,
1813 hdc_src, x_src, y_src, width_src,
1814 height_src, blend_function ))
1815 return FALSE;
1816 return NtGdiAlphaBlend( hdc_dst, x_dst, y_dst, width_dst, height_dst,
1817 hdc_src, x_src, y_src, width_src, height_src,
1818 blend_function, 0 /* FIXME */ );
1821 /***********************************************************************
1822 * SetDIBitsToDevice (GDI32.@)
1824 INT WINAPI SetDIBitsToDevice( HDC hdc, INT x_dst, INT y_dst, DWORD cx,
1825 DWORD cy, INT x_src, INT y_src, UINT startscan,
1826 UINT lines, const void *bits, const BITMAPINFO *bmi,
1827 UINT coloruse )
1829 DC_ATTR *dc_attr;
1831 if (is_meta_dc( hdc ))
1832 return METADC_SetDIBitsToDevice( hdc, x_dst, y_dst, cx, cy, x_src, y_src, startscan,
1833 lines, bits, bmi, coloruse );
1834 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1835 if (dc_attr->emf && !EMFDC_SetDIBitsToDevice( dc_attr, x_dst, y_dst, cx, cy, x_src, y_src,
1836 startscan, lines, bits, bmi, coloruse ))
1837 return 0;
1838 return NtGdiSetDIBitsToDeviceInternal( hdc, x_dst, y_dst, cx, cy, x_src, y_src,
1839 startscan, lines, bits, bmi, coloruse,
1840 0, 0, FALSE, NULL );
1843 /***********************************************************************
1844 * StretchDIBits (GDI32.@)
1846 INT WINAPI DECLSPEC_HOTPATCH StretchDIBits( HDC hdc, INT x_dst, INT y_dst, INT width_dst,
1847 INT height_dst, INT x_src, INT y_src, INT width_src,
1848 INT height_src, const void *bits, const BITMAPINFO *bmi,
1849 UINT coloruse, DWORD rop )
1851 DC_ATTR *dc_attr;
1853 if (is_meta_dc( hdc ))
1854 return METADC_StretchDIBits( hdc, x_dst, y_dst, width_dst, height_dst, x_src, y_src,
1855 width_src, height_src, bits, bmi, coloruse, rop );
1856 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1857 if (dc_attr->emf && !EMFDC_StretchDIBits( dc_attr, x_dst, y_dst, width_dst, height_dst,
1858 x_src, y_src, width_src, height_src, bits,
1859 bmi, coloruse, rop ))
1860 return FALSE;
1861 return NtGdiStretchDIBitsInternal( hdc, x_dst, y_dst, width_dst, height_dst, x_src, y_src,
1862 width_src, height_src, bits, bmi, coloruse, rop,
1863 0, 0, NULL );
1866 /***********************************************************************
1867 * BeginPath (GDI32.@)
1869 BOOL WINAPI BeginPath(HDC hdc)
1871 DC_ATTR *dc_attr;
1873 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1874 if (dc_attr->emf && !EMFDC_BeginPath( dc_attr )) return FALSE;
1875 return NtGdiBeginPath( hdc );
1878 /***********************************************************************
1879 * EndPath (GDI32.@)
1881 BOOL WINAPI EndPath(HDC hdc)
1883 DC_ATTR *dc_attr;
1885 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1886 if (dc_attr->emf && !EMFDC_EndPath( dc_attr )) return FALSE;
1887 return NtGdiEndPath( hdc );
1890 /***********************************************************************
1891 * AbortPath (GDI32.@)
1893 BOOL WINAPI AbortPath( HDC hdc )
1895 DC_ATTR *dc_attr;
1897 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1898 if (dc_attr->emf && !EMFDC_AbortPath( dc_attr )) return FALSE;
1899 return NtGdiAbortPath( hdc );
1902 /***********************************************************************
1903 * CloseFigure (GDI32.@)
1905 BOOL WINAPI CloseFigure( HDC hdc )
1907 DC_ATTR *dc_attr;
1909 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1910 if (dc_attr->emf && !EMFDC_CloseFigure( dc_attr )) return FALSE;
1911 return NtGdiCloseFigure( hdc );
1914 /***********************************************************************
1915 * FillPath (GDI32.@)
1917 BOOL WINAPI FillPath( HDC hdc )
1919 DC_ATTR *dc_attr;
1921 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1922 if (dc_attr->emf && !EMFDC_FillPath( dc_attr )) return FALSE;
1923 return NtGdiFillPath( hdc );
1926 /*******************************************************************
1927 * StrokeAndFillPath (GDI32.@)
1929 BOOL WINAPI StrokeAndFillPath( HDC hdc )
1931 DC_ATTR *dc_attr;
1933 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1934 if (dc_attr->emf && !EMFDC_StrokeAndFillPath( dc_attr )) return FALSE;
1935 return NtGdiStrokeAndFillPath( hdc );
1938 /*******************************************************************
1939 * StrokePath (GDI32.@)
1941 BOOL WINAPI StrokePath( HDC hdc )
1943 DC_ATTR *dc_attr;
1945 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1946 if (dc_attr->emf && !EMFDC_StrokePath( dc_attr )) return FALSE;
1947 return NtGdiStrokePath( hdc );
1950 /***********************************************************************
1951 * FlattenPath (GDI32.@)
1953 BOOL WINAPI FlattenPath( HDC hdc )
1955 DC_ATTR *dc_attr;
1957 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1958 if (dc_attr->emf && !EMFDC_FlattenPath( dc_attr )) return FALSE;
1959 return NtGdiFlattenPath( hdc );
1962 /***********************************************************************
1963 * WidenPath (GDI32.@)
1965 BOOL WINAPI WidenPath( HDC hdc )
1967 DC_ATTR *dc_attr;
1969 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1970 if (dc_attr->emf && !EMFDC_WidenPath( dc_attr )) return FALSE;
1971 return NtGdiWidenPath( hdc );
1974 /***********************************************************************
1975 * SelectClipPath (GDI32.@)
1977 BOOL WINAPI SelectClipPath( HDC hdc, INT mode )
1979 DC_ATTR *dc_attr;
1981 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
1982 if (dc_attr->emf && !EMFDC_SelectClipPath( dc_attr, mode )) return FALSE;
1983 return NtGdiSelectClipPath( hdc, mode );
1986 /***********************************************************************
1987 * GetClipRgn (GDI32.@)
1989 INT WINAPI GetClipRgn( HDC hdc, HRGN rgn )
1991 return NtGdiGetRandomRgn( hdc, rgn, NTGDI_RGN_MIRROR_RTL | 1 );
1994 /***********************************************************************
1995 * GetMetaRgn (GDI32.@)
1997 INT WINAPI GetMetaRgn( HDC hdc, HRGN rgn )
1999 return NtGdiGetRandomRgn( hdc, rgn, NTGDI_RGN_MIRROR_RTL | 2 );
2002 /***********************************************************************
2003 * IntersectClipRect (GDI32.@)
2005 INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top, INT right, INT bottom )
2007 DC_ATTR *dc_attr;
2009 TRACE("%p %d,%d - %d,%d\n", hdc, left, top, right, bottom );
2011 if (is_meta_dc( hdc )) return METADC_IntersectClipRect( hdc, left, top, right, bottom );
2012 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2013 if (dc_attr->emf && !EMFDC_IntersectClipRect( dc_attr, left, top, right, bottom ))
2014 return FALSE;
2015 return NtGdiIntersectClipRect( hdc, left, top, right, bottom );
2018 /***********************************************************************
2019 * OffsetClipRgn (GDI32.@)
2021 INT WINAPI OffsetClipRgn( HDC hdc, INT x, INT y )
2023 DC_ATTR *dc_attr;
2025 if (is_meta_dc( hdc )) return METADC_OffsetClipRgn( hdc, x, y );
2026 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2027 if (dc_attr->emf && !EMFDC_OffsetClipRgn( dc_attr, x, y )) return FALSE;
2028 return NtGdiOffsetClipRgn( hdc, x, y );
2031 /***********************************************************************
2032 * ExcludeClipRect (GDI32.@)
2034 INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top, INT right, INT bottom )
2036 DC_ATTR *dc_attr;
2038 if (is_meta_dc( hdc )) return METADC_ExcludeClipRect( hdc, left, top, right, bottom );
2039 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2040 if (dc_attr->emf && !EMFDC_ExcludeClipRect( dc_attr, left, top, right, bottom ))
2041 return FALSE;
2042 return NtGdiExcludeClipRect( hdc, left, top, right, bottom );
2045 /******************************************************************************
2046 * ExtSelectClipRgn (GDI32.@)
2048 INT WINAPI ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT mode )
2050 DC_ATTR *dc_attr;
2052 TRACE("%p %p %d\n", hdc, hrgn, mode );
2054 if (is_meta_dc( hdc )) return METADC_ExtSelectClipRgn( hdc, hrgn, mode );
2055 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2056 if (dc_attr->emf && !EMFDC_ExtSelectClipRgn( dc_attr, hrgn, mode ))
2057 return FALSE;
2058 return NtGdiExtSelectClipRgn( hdc, hrgn, mode );
2061 /***********************************************************************
2062 * SelectClipRgn (GDI32.@)
2064 INT WINAPI SelectClipRgn( HDC hdc, HRGN hrgn )
2066 return ExtSelectClipRgn( hdc, hrgn, RGN_COPY );
2069 /***********************************************************************
2070 * SetMetaRgn (GDI32.@)
2072 INT WINAPI SetMetaRgn( HDC hdc )
2074 DC_ATTR *dc_attr;
2076 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2077 if (dc_attr->emf) FIXME( "EMFs are not yet supported\n" );
2078 return NtGdiSetMetaRgn( hdc );
2081 /***********************************************************************
2082 * DPtoLP (GDI32.@)
2084 BOOL WINAPI DPtoLP( HDC hdc, POINT *points, INT count )
2086 return NtGdiTransformPoints( hdc, points, points, count, NtGdiDPtoLP );
2089 /***********************************************************************
2090 * LPtoDP (GDI32.@)
2092 BOOL WINAPI LPtoDP( HDC hdc, POINT *points, INT count )
2094 return NtGdiTransformPoints( hdc, points, points, count, NtGdiLPtoDP );
2097 /***********************************************************************
2098 * ScaleViewportExtEx (GDI32.@)
2100 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT x_num, INT x_denom,
2101 INT y_num, INT y_denom, SIZE *size )
2103 DC_ATTR *dc_attr;
2105 if (is_meta_dc( hdc )) return METADC_ScaleViewportExtEx( hdc, x_num, x_denom, y_num, y_denom );
2106 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2107 if (dc_attr->emf && !EMFDC_ScaleViewportExtEx( dc_attr, x_num, x_denom, y_num, y_denom ))
2108 return FALSE;
2109 return NtGdiScaleViewportExtEx( hdc, x_num, x_denom, y_num, y_denom, size );
2112 /***********************************************************************
2113 * ScaleWindowExtEx (GDI32.@)
2115 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT x_num, INT x_denom,
2116 INT y_num, INT y_denom, SIZE *size )
2118 DC_ATTR *dc_attr;
2120 if (is_meta_dc( hdc )) return METADC_ScaleWindowExtEx( hdc, x_num, x_denom, y_num, y_denom );
2121 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2122 if (dc_attr->emf && !EMFDC_ScaleWindowExtEx( dc_attr, x_num, x_denom, y_num, y_denom ))
2123 return FALSE;
2124 return NtGdiScaleWindowExtEx( hdc, x_num, x_denom, y_num, y_denom, size );
2127 static UINT WINAPI realize_palette( HDC hdc )
2129 return NtUserRealizePalette( hdc );
2132 /* Pointers to USER implementation of SelectPalette/RealizePalette */
2133 /* they will be patched by USER on startup */
2134 HPALETTE (WINAPI *pfnSelectPalette)( HDC hdc, HPALETTE hpal, WORD bkgnd ) = NtUserSelectPalette;
2135 UINT (WINAPI *pfnRealizePalette)( HDC hdc ) = realize_palette;
2137 /***********************************************************************
2138 * SelectPalette (GDI32.@)
2140 HPALETTE WINAPI SelectPalette( HDC hdc, HPALETTE palette, BOOL force_background )
2142 DC_ATTR *dc_attr;
2144 palette = get_full_gdi_handle( palette );
2145 if (is_meta_dc( hdc )) return ULongToHandle( METADC_SelectPalette( hdc, palette ) );
2146 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2147 if (dc_attr->emf && !EMFDC_SelectPalette( dc_attr, palette )) return 0;
2148 return pfnSelectPalette( hdc, palette, force_background );
2151 /***********************************************************************
2152 * RealizePalette (GDI32.@)
2154 UINT WINAPI RealizePalette( HDC hdc )
2156 if (is_meta_dc( hdc )) return METADC_RealizePalette( hdc );
2157 return pfnRealizePalette( hdc );
2160 /***********************************************************************
2161 * GdiSetPixelFormat (GDI32.@)
2163 BOOL WINAPI GdiSetPixelFormat( HDC hdc, INT format, const PIXELFORMATDESCRIPTOR *descr )
2165 TRACE( "(%p,%d,%p)\n", hdc, format, descr );
2166 return NtGdiSetPixelFormat( hdc, format );
2169 /***********************************************************************
2170 * CancelDC (GDI32.@)
2172 BOOL WINAPI CancelDC(HDC hdc)
2174 FIXME( "stub\n" );
2175 return TRUE;
2178 /***********************************************************************
2179 * StartDocW [GDI32.@]
2181 * StartDoc calls the STARTDOC Escape with the input data pointing to DocName
2182 * and the output data (which is used as a second input parameter).pointing at
2183 * the whole docinfo structure. This seems to be an undocumented feature of
2184 * the STARTDOC Escape.
2186 * Note: we now do it the other way, with the STARTDOC Escape calling StartDoc.
2188 INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc )
2190 WCHAR *output = NULL;
2191 DC_ATTR *dc_attr;
2192 ABORTPROC proc;
2193 DOCINFOW info;
2194 INT ret;
2196 TRACE("%p %p\n", hdc, doc);
2198 if (doc)
2200 info = *doc;
2202 else
2204 memset( &info, 0, sizeof(info) );
2205 info.cbSize = sizeof(info);
2208 TRACE("DocName %s, Output %s, Datatype %s, fwType %#lx\n",
2209 debugstr_w(info.lpszDocName), debugstr_w(info.lpszOutput),
2210 debugstr_w(info.lpszDatatype), info.fwType);
2212 if (!(dc_attr = get_dc_attr( hdc ))) return SP_ERROR;
2214 proc = (ABORTPROC)(UINT_PTR)dc_attr->abort_proc;
2215 if (proc && !proc( hdc, 0 )) return 0;
2217 if (dc_attr->hspool)
2219 if (!info.lpszOutput) info.lpszOutput = (const WCHAR *)(ULONG_PTR)dc_attr->output;
2220 output = StartDocDlgW( ULongToHandle( dc_attr->hspool ), &info );
2221 if (output) info.lpszOutput = output;
2224 ret = NtGdiStartDoc( hdc, &info, NULL, 0 );
2225 HeapFree( GetProcessHeap(), 0, output );
2226 return ret;
2229 /***********************************************************************
2230 * StartDocA [GDI32.@]
2232 INT WINAPI StartDocA( HDC hdc, const DOCINFOA *doc )
2234 WCHAR *doc_name = NULL, *output = NULL, *data_type = NULL;
2235 DOCINFOW docW;
2236 INT ret, len;
2238 if (!doc) return StartDocW(hdc, NULL);
2240 docW.cbSize = doc->cbSize;
2241 if (doc->lpszDocName)
2243 len = MultiByteToWideChar( CP_ACP, 0, doc->lpszDocName, -1, NULL, 0 );
2244 doc_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2245 MultiByteToWideChar( CP_ACP, 0, doc->lpszDocName, -1, doc_name, len );
2247 if (doc->lpszOutput)
2249 len = MultiByteToWideChar( CP_ACP, 0, doc->lpszOutput, -1, NULL, 0 );
2250 output = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2251 MultiByteToWideChar( CP_ACP, 0, doc->lpszOutput, -1, output, len );
2253 if (doc->lpszDatatype)
2255 len = MultiByteToWideChar( CP_ACP, 0, doc->lpszDatatype, -1, NULL, 0);
2256 data_type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2257 MultiByteToWideChar( CP_ACP, 0, doc->lpszDatatype, -1, data_type, len );
2260 docW.lpszDocName = doc_name;
2261 docW.lpszOutput = output;
2262 docW.lpszDatatype = data_type;
2263 docW.fwType = doc->fwType;
2265 ret = StartDocW(hdc, &docW);
2267 HeapFree( GetProcessHeap(), 0, doc_name );
2268 HeapFree( GetProcessHeap(), 0, output );
2269 HeapFree( GetProcessHeap(), 0, data_type );
2270 return ret;
2273 /***********************************************************************
2274 * StartPage (GDI32.@)
2276 INT WINAPI StartPage( HDC hdc )
2278 return NtGdiStartPage( hdc );
2281 /***********************************************************************
2282 * EndPage (GDI32.@)
2284 INT WINAPI EndPage( HDC hdc )
2286 return NtGdiEndPage( hdc );
2289 /***********************************************************************
2290 * EndDoc (GDI32.@)
2292 INT WINAPI EndDoc( HDC hdc )
2294 return NtGdiEndDoc( hdc );
2297 /***********************************************************************
2298 * AbortDoc (GDI32.@)
2300 INT WINAPI AbortDoc( HDC hdc )
2302 return NtGdiAbortDoc( hdc );
2305 /**********************************************************************
2306 * SetAbortProc (GDI32.@)
2308 INT WINAPI SetAbortProc( HDC hdc, ABORTPROC abrtprc )
2310 DC_ATTR *dc_attr;
2312 if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
2313 dc_attr->abort_proc = (UINT_PTR)abrtprc;
2314 return TRUE;
2317 /***********************************************************************
2318 * SetICMMode (GDI32.@)
2320 INT WINAPI SetICMMode( HDC hdc, INT mode )
2322 /* FIXME: Assume that ICM is always off, and cannot be turned on */
2323 switch (mode)
2325 case ICM_OFF: return ICM_OFF;
2326 case ICM_ON: return 0;
2327 case ICM_QUERY: return ICM_OFF;
2329 return 0;
2332 /***********************************************************************
2333 * GdiIsMetaPrintDC (GDI32.@)
2335 BOOL WINAPI GdiIsMetaPrintDC( HDC hdc )
2337 FIXME( "%p\n", hdc );
2338 return FALSE;
2341 /***********************************************************************
2342 * GdiIsMetaFileDC (GDI32.@)
2344 BOOL WINAPI GdiIsMetaFileDC( HDC hdc )
2346 TRACE( "%p\n", hdc );
2348 switch (GetObjectType( hdc ))
2350 case OBJ_METADC:
2351 case OBJ_ENHMETADC:
2352 return TRUE;
2354 return FALSE;
2357 /***********************************************************************
2358 * GdiIsPlayMetafileDC (GDI32.@)
2360 BOOL WINAPI GdiIsPlayMetafileDC( HDC hdc )
2362 FIXME( "%p\n", hdc );
2363 return FALSE;
2366 /*******************************************************************
2367 * DrawEscape (GDI32.@)
2369 INT WINAPI DrawEscape( HDC hdc, INT escape, INT input_size, const char *input )
2371 FIXME( "stub\n" );
2372 return 0;
2375 /*******************************************************************
2376 * NamedEscape (GDI32.@)
2378 INT WINAPI NamedEscape( HDC hdc, const WCHAR *driver, INT escape, INT input_size,
2379 const char *input, INT output_size, char *output )
2381 FIXME( "(%p %s %d, %d %p %d %p)\n", hdc, wine_dbgstr_w(driver), escape, input_size,
2382 input, output_size, output );
2383 return 0;
2386 /*******************************************************************
2387 * DdQueryDisplaySettingsUniqueness (GDI32.@)
2388 * GdiEntry13
2390 ULONG WINAPI DdQueryDisplaySettingsUniqueness(void)
2392 static int warn_once;
2393 if (!warn_once++) FIXME( "stub\n" );
2394 return 0;