cmd: DIR command outputs free space for the path.
[wine.git] / dlls / win32u / driver.c
blobed2e0973d39d4aaf23ae5db95065471e7fb2763d
1 /*
2 * Graphics driver management functions
4 * Copyright 1994 Bob Amstadt
5 * Copyright 1996, 2001 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #if 0
23 #pragma makedep unix
24 #endif
26 #include <assert.h>
27 #include <pthread.h>
29 #include "ntstatus.h"
30 #define WIN32_NO_STATUS
31 #include "ntgdi_private.h"
32 #include "ntuser_private.h"
33 #include "wine/winbase16.h"
34 #include "wine/list.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(driver);
38 WINE_DECLARE_DEBUG_CHANNEL(winediag);
40 struct d3dkmt_adapter
42 D3DKMT_HANDLE handle; /* Kernel mode graphics adapter handle */
43 struct list entry; /* List entry */
46 struct d3dkmt_device
48 D3DKMT_HANDLE handle; /* Kernel mode graphics device handle*/
49 struct list entry; /* List entry */
52 static const struct user_driver_funcs lazy_load_driver;
53 static struct user_driver_funcs null_user_driver;
55 static struct list d3dkmt_adapters = LIST_INIT( d3dkmt_adapters );
56 static struct list d3dkmt_devices = LIST_INIT( d3dkmt_devices );
58 static pthread_mutex_t driver_lock = PTHREAD_MUTEX_INITIALIZER;
59 static WCHAR driver_load_error[80];
61 static INT nulldrv_AbortDoc( PHYSDEV dev )
63 return 0;
66 static BOOL nulldrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
67 INT xstart, INT ystart, INT xend, INT yend )
69 return TRUE;
72 static BOOL nulldrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
73 INT xstart, INT ystart, INT xend, INT yend )
75 return TRUE;
78 static BOOL nulldrv_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
80 if (!user_driver->dc_funcs.pCreateCompatibleDC) return TRUE;
81 return user_driver->dc_funcs.pCreateCompatibleDC( NULL, pdev );
84 static BOOL nulldrv_CreateDC( PHYSDEV *dev, LPCWSTR device, LPCWSTR output,
85 const DEVMODEW *devmode )
87 assert(0); /* should never be called */
88 return FALSE;
91 static BOOL nulldrv_DeleteDC( PHYSDEV dev )
93 assert(0); /* should never be called */
94 return TRUE;
97 static BOOL nulldrv_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
99 return TRUE;
102 static BOOL nulldrv_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
104 return TRUE;
107 static INT nulldrv_EndDoc( PHYSDEV dev )
109 return 0;
112 static INT nulldrv_EndPage( PHYSDEV dev )
114 return 0;
117 static BOOL nulldrv_EnumFonts( PHYSDEV dev, LOGFONTW *logfont, font_enum_proc proc, LPARAM lParam )
119 return TRUE;
122 static INT nulldrv_ExtEscape( PHYSDEV dev, INT escape, INT in_size, const void *in_data,
123 INT out_size, void *out_data )
125 return 0;
128 static BOOL nulldrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type )
130 return TRUE;
133 static BOOL nulldrv_FontIsLinked( PHYSDEV dev )
135 return FALSE;
138 static UINT nulldrv_GetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
140 return DCB_RESET;
143 static BOOL nulldrv_GetCharABCWidths( PHYSDEV dev, UINT first, UINT count, WCHAR *chars, ABC *abc )
145 return FALSE;
148 static BOOL nulldrv_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count, WORD *indices, LPABC abc )
150 return FALSE;
153 static BOOL nulldrv_GetCharWidth( PHYSDEV dev, UINT first, UINT count,
154 const WCHAR *chars, INT *buffer )
156 return FALSE;
159 static BOOL nulldrv_GetCharWidthInfo( PHYSDEV dev, void *info )
161 return FALSE;
164 static INT nulldrv_GetDeviceCaps( PHYSDEV dev, INT cap )
166 int bpp;
168 switch (cap)
170 case DRIVERVERSION: return 0x4000;
171 case TECHNOLOGY: return DT_RASDISPLAY;
172 case HORZSIZE: return muldiv( NtGdiGetDeviceCaps( dev->hdc, HORZRES ), 254,
173 NtGdiGetDeviceCaps( dev->hdc, LOGPIXELSX ) * 10 );
174 case VERTSIZE: return muldiv( NtGdiGetDeviceCaps( dev->hdc, VERTRES ), 254,
175 NtGdiGetDeviceCaps( dev->hdc, LOGPIXELSY ) * 10 );
176 case HORZRES:
178 DC *dc = get_nulldrv_dc( dev );
179 RECT rect;
180 int ret;
182 if (dc->display[0])
184 rect = get_display_rect( dc->display );
185 if (!IsRectEmpty( &rect )) return rect.right - rect.left;
188 ret = get_system_metrics( SM_CXSCREEN );
189 return ret ? ret : 640;
191 case VERTRES:
193 DC *dc = get_nulldrv_dc( dev );
194 RECT rect;
195 int ret;
197 if (dc->display[0])
199 rect = get_display_rect( dc->display );
200 if (!IsRectEmpty( &rect )) return rect.bottom - rect.top;
203 ret = get_system_metrics( SM_CYSCREEN );
204 return ret ? ret : 480;
206 case BITSPIXEL:
208 UNICODE_STRING display;
209 DC *dc;
211 if (NtGdiGetDeviceCaps( dev->hdc, TECHNOLOGY ) == DT_RASDISPLAY)
213 dc = get_nulldrv_dc( dev );
214 RtlInitUnicodeString( &display, dc->display );
215 return get_display_depth( &display );
217 return 32;
219 case PLANES: return 1;
220 case NUMBRUSHES: return -1;
221 case NUMPENS: return -1;
222 case NUMMARKERS: return 0;
223 case NUMFONTS: return 0;
224 case PDEVICESIZE: return 0;
225 case CURVECAPS: return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
226 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
227 case LINECAPS: return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
228 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
229 case POLYGONALCAPS: return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
230 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
231 case TEXTCAPS: return (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
232 TC_CR_ANY | TC_SF_X_YINDEP | TC_SA_DOUBLE | TC_SA_INTEGER |
233 TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE | TC_VA_ABLE);
234 case CLIPCAPS: return CP_RECTANGLE;
235 case RASTERCAPS: return (RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT | RC_DI_BITMAP | RC_DIBTODEV |
236 RC_BIGFONT | RC_STRETCHBLT | RC_FLOODFILL | RC_STRETCHDIB | RC_DEVBITS |
237 (NtGdiGetDeviceCaps( dev->hdc, SIZEPALETTE ) ? RC_PALETTE : 0));
238 case ASPECTX: return 36;
239 case ASPECTY: return 36;
240 case ASPECTXY: return (int)(hypot( NtGdiGetDeviceCaps( dev->hdc, ASPECTX ),
241 NtGdiGetDeviceCaps( dev->hdc, ASPECTY )) + 0.5);
242 case CAPS1: return 0;
243 case SIZEPALETTE: return 0;
244 case NUMRESERVED: return 20;
245 case PHYSICALWIDTH: return 0;
246 case PHYSICALHEIGHT: return 0;
247 case PHYSICALOFFSETX: return 0;
248 case PHYSICALOFFSETY: return 0;
249 case SCALINGFACTORX: return 0;
250 case SCALINGFACTORY: return 0;
251 case VREFRESH:
253 UNICODE_STRING display;
254 DEVMODEW devmode;
255 DC *dc;
257 if (NtGdiGetDeviceCaps( dev->hdc, TECHNOLOGY ) != DT_RASDISPLAY)
258 return 0;
260 dc = get_nulldrv_dc( dev );
262 memset( &devmode, 0, sizeof(devmode) );
263 devmode.dmSize = sizeof(devmode);
264 RtlInitUnicodeString( &display, dc->display );
265 if (NtUserEnumDisplaySettings( &display, ENUM_CURRENT_SETTINGS, &devmode, 0 ) &&
266 devmode.dmDisplayFrequency)
267 return devmode.dmDisplayFrequency;
268 return 1;
270 case DESKTOPHORZRES:
271 if (NtGdiGetDeviceCaps( dev->hdc, TECHNOLOGY ) == DT_RASDISPLAY)
273 RECT rect = get_virtual_screen_rect( 0 );
274 return rect.right - rect.left;
276 return NtGdiGetDeviceCaps( dev->hdc, HORZRES );
277 case DESKTOPVERTRES:
278 if (NtGdiGetDeviceCaps( dev->hdc, TECHNOLOGY ) == DT_RASDISPLAY)
280 RECT rect = get_virtual_screen_rect( 0 );
281 return rect.bottom - rect.top;
283 return NtGdiGetDeviceCaps( dev->hdc, VERTRES );
284 case BLTALIGNMENT: return 0;
285 case SHADEBLENDCAPS: return 0;
286 case COLORMGMTCAPS: return 0;
287 case LOGPIXELSX:
288 case LOGPIXELSY: return get_system_dpi();
289 case NUMCOLORS:
290 bpp = NtGdiGetDeviceCaps( dev->hdc, BITSPIXEL );
291 /* Newer versions of Windows return -1 for 8-bit and higher */
292 return (bpp > 4) ? -1 : (1 << bpp);
293 case COLORRES:
294 /* The observed correspondence between BITSPIXEL and COLORRES is:
295 * BITSPIXEL: 8 -> COLORRES: 18
296 * BITSPIXEL: 16 -> COLORRES: 16
297 * BITSPIXEL: 24 -> COLORRES: 24
298 * BITSPIXEL: 32 -> COLORRES: 24 */
299 bpp = NtGdiGetDeviceCaps( dev->hdc, BITSPIXEL );
300 return (bpp <= 8) ? 18 : min( 24, bpp );
301 default:
302 FIXME("(%p): unsupported capability %d, will return 0\n", dev->hdc, cap );
303 return 0;
307 static BOOL nulldrv_GetDeviceGammaRamp( PHYSDEV dev, void *ramp )
309 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER );
310 return FALSE;
313 static DWORD nulldrv_GetFontData( PHYSDEV dev, DWORD table, DWORD offset, LPVOID buffer, DWORD length )
315 return FALSE;
318 static BOOL nulldrv_GetFontRealizationInfo( PHYSDEV dev, void *info )
320 return FALSE;
323 static DWORD nulldrv_GetFontUnicodeRanges( PHYSDEV dev, LPGLYPHSET glyphs )
325 return 0;
328 static DWORD nulldrv_GetGlyphIndices( PHYSDEV dev, LPCWSTR str, INT count, LPWORD indices, DWORD flags )
330 return GDI_ERROR;
333 static DWORD nulldrv_GetGlyphOutline( PHYSDEV dev, UINT ch, UINT format, LPGLYPHMETRICS metrics,
334 DWORD size, LPVOID buffer, const MAT2 *mat )
336 return GDI_ERROR;
339 static BOOL nulldrv_GetICMProfile( PHYSDEV dev, BOOL allow_default, LPDWORD size, LPWSTR filename )
341 return FALSE;
344 static DWORD nulldrv_GetImage( PHYSDEV dev, BITMAPINFO *info, struct gdi_image_bits *bits,
345 struct bitblt_coords *src )
347 return ERROR_NOT_SUPPORTED;
350 static DWORD nulldrv_GetKerningPairs( PHYSDEV dev, DWORD count, LPKERNINGPAIR pairs )
352 return 0;
355 static UINT nulldrv_GetOutlineTextMetrics( PHYSDEV dev, UINT size, LPOUTLINETEXTMETRICW otm )
357 return 0;
360 static UINT nulldrv_GetTextCharsetInfo( PHYSDEV dev, LPFONTSIGNATURE fs, DWORD flags )
362 return DEFAULT_CHARSET;
365 static BOOL nulldrv_GetTextExtentExPoint( PHYSDEV dev, LPCWSTR str, INT count, INT *dx )
367 return FALSE;
370 static BOOL nulldrv_GetTextExtentExPointI( PHYSDEV dev, const WORD *indices, INT count, INT *dx )
372 return FALSE;
375 static INT nulldrv_GetTextFace( PHYSDEV dev, INT size, LPWSTR name )
377 INT ret = 0;
378 LOGFONTW font;
379 DC *dc = get_nulldrv_dc( dev );
381 if (NtGdiExtGetObjectW( dc->hFont, sizeof(font), &font ))
383 ret = lstrlenW( font.lfFaceName ) + 1;
384 if (name)
386 lstrcpynW( name, font.lfFaceName, size );
387 ret = min( size, ret );
390 return ret;
393 static BOOL nulldrv_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
395 return FALSE;
398 static BOOL nulldrv_LineTo( PHYSDEV dev, INT x, INT y )
400 return TRUE;
403 static BOOL nulldrv_MoveTo( PHYSDEV dev, INT x, INT y )
405 return TRUE;
408 static BOOL nulldrv_PaintRgn( PHYSDEV dev, HRGN rgn )
410 return TRUE;
413 static BOOL nulldrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
415 return TRUE;
418 static BOOL nulldrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
419 INT xstart, INT ystart, INT xend, INT yend )
421 return TRUE;
424 static BOOL nulldrv_PolyPolygon( PHYSDEV dev, const POINT *points, const INT *counts, UINT polygons )
426 return TRUE;
429 static BOOL nulldrv_PolyPolyline( PHYSDEV dev, const POINT *points, const DWORD *counts, DWORD lines )
431 return TRUE;
434 static DWORD nulldrv_PutImage( PHYSDEV dev, HRGN clip, BITMAPINFO *info,
435 const struct gdi_image_bits *bits, struct bitblt_coords *src,
436 struct bitblt_coords *dst, DWORD rop )
438 return ERROR_SUCCESS;
441 static UINT nulldrv_RealizeDefaultPalette( PHYSDEV dev )
443 return 0;
446 static UINT nulldrv_RealizePalette( PHYSDEV dev, HPALETTE palette, BOOL primary )
448 return 0;
451 static BOOL nulldrv_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
453 return TRUE;
456 static BOOL nulldrv_ResetDC( PHYSDEV dev, const DEVMODEW *devmode )
458 return FALSE;
461 static BOOL nulldrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
462 INT ell_width, INT ell_height )
464 return TRUE;
467 static HBITMAP nulldrv_SelectBitmap( PHYSDEV dev, HBITMAP bitmap )
469 return bitmap;
472 static HBRUSH nulldrv_SelectBrush( PHYSDEV dev, HBRUSH brush, const struct brush_pattern *pattern )
474 return brush;
477 static HFONT nulldrv_SelectFont( PHYSDEV dev, HFONT font, UINT *aa_flags )
479 return font;
482 static HPEN nulldrv_SelectPen( PHYSDEV dev, HPEN pen, const struct brush_pattern *pattern )
484 return pen;
487 static COLORREF nulldrv_SetBkColor( PHYSDEV dev, COLORREF color )
489 return color;
492 static UINT nulldrv_SetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
494 return DCB_RESET;
497 static COLORREF nulldrv_SetDCBrushColor( PHYSDEV dev, COLORREF color )
499 return color;
502 static COLORREF nulldrv_SetDCPenColor( PHYSDEV dev, COLORREF color )
504 return color;
507 static void nulldrv_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
511 static BOOL nulldrv_SetDeviceGammaRamp( PHYSDEV dev, void *ramp )
513 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER );
514 return FALSE;
517 static COLORREF nulldrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
519 return color;
522 static COLORREF nulldrv_SetTextColor( PHYSDEV dev, COLORREF color )
524 return color;
527 static INT nulldrv_StartDoc( PHYSDEV dev, const DOCINFOW *info )
529 return 0;
532 static INT nulldrv_StartPage( PHYSDEV dev )
534 return 1;
537 static BOOL nulldrv_UnrealizePalette( HPALETTE palette )
539 return FALSE;
542 static NTSTATUS nulldrv_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc )
544 return STATUS_PROCEDURE_NOT_FOUND;
547 static NTSTATUS nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
549 return STATUS_PROCEDURE_NOT_FOUND;
552 static NTSTATUS nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc )
554 return STATUS_PROCEDURE_NOT_FOUND;
557 static NTSTATUS nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
559 return STATUS_PROCEDURE_NOT_FOUND;
562 static NTSTATUS nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc )
564 return STATUS_PROCEDURE_NOT_FOUND;
567 const struct gdi_dc_funcs null_driver =
569 nulldrv_AbortDoc, /* pAbortDoc */
570 nulldrv_AbortPath, /* pAbortPath */
571 nulldrv_AlphaBlend, /* pAlphaBlend */
572 nulldrv_AngleArc, /* pAngleArc */
573 nulldrv_Arc, /* pArc */
574 nulldrv_ArcTo, /* pArcTo */
575 nulldrv_BeginPath, /* pBeginPath */
576 nulldrv_BlendImage, /* pBlendImage */
577 nulldrv_Chord, /* pChord */
578 nulldrv_CloseFigure, /* pCloseFigure */
579 nulldrv_CreateCompatibleDC, /* pCreateCompatibleDC */
580 nulldrv_CreateDC, /* pCreateDC */
581 nulldrv_DeleteDC, /* pDeleteDC */
582 nulldrv_DeleteObject, /* pDeleteObject */
583 nulldrv_Ellipse, /* pEllipse */
584 nulldrv_EndDoc, /* pEndDoc */
585 nulldrv_EndPage, /* pEndPage */
586 nulldrv_EndPath, /* pEndPath */
587 nulldrv_EnumFonts, /* pEnumFonts */
588 nulldrv_ExtEscape, /* pExtEscape */
589 nulldrv_ExtFloodFill, /* pExtFloodFill */
590 nulldrv_ExtTextOut, /* pExtTextOut */
591 nulldrv_FillPath, /* pFillPath */
592 nulldrv_FillRgn, /* pFillRgn */
593 nulldrv_FontIsLinked, /* pFontIsLinked */
594 nulldrv_FrameRgn, /* pFrameRgn */
595 nulldrv_GetBoundsRect, /* pGetBoundsRect */
596 nulldrv_GetCharABCWidths, /* pGetCharABCWidths */
597 nulldrv_GetCharABCWidthsI, /* pGetCharABCWidthsI */
598 nulldrv_GetCharWidth, /* pGetCharWidth */
599 nulldrv_GetCharWidthInfo, /* pGetCharWidthInfo */
600 nulldrv_GetDeviceCaps, /* pGetDeviceCaps */
601 nulldrv_GetDeviceGammaRamp, /* pGetDeviceGammaRamp */
602 nulldrv_GetFontData, /* pGetFontData */
603 nulldrv_GetFontRealizationInfo, /* pGetFontRealizationInfo */
604 nulldrv_GetFontUnicodeRanges, /* pGetFontUnicodeRanges */
605 nulldrv_GetGlyphIndices, /* pGetGlyphIndices */
606 nulldrv_GetGlyphOutline, /* pGetGlyphOutline */
607 nulldrv_GetICMProfile, /* pGetICMProfile */
608 nulldrv_GetImage, /* pGetImage */
609 nulldrv_GetKerningPairs, /* pGetKerningPairs */
610 nulldrv_GetNearestColor, /* pGetNearestColor */
611 nulldrv_GetOutlineTextMetrics, /* pGetOutlineTextMetrics */
612 nulldrv_GetPixel, /* pGetPixel */
613 nulldrv_GetSystemPaletteEntries, /* pGetSystemPaletteEntries */
614 nulldrv_GetTextCharsetInfo, /* pGetTextCharsetInfo */
615 nulldrv_GetTextExtentExPoint, /* pGetTextExtentExPoint */
616 nulldrv_GetTextExtentExPointI, /* pGetTextExtentExPointI */
617 nulldrv_GetTextFace, /* pGetTextFace */
618 nulldrv_GetTextMetrics, /* pGetTextMetrics */
619 nulldrv_GradientFill, /* pGradientFill */
620 nulldrv_InvertRgn, /* pInvertRgn */
621 nulldrv_LineTo, /* pLineTo */
622 nulldrv_MoveTo, /* pMoveTo */
623 nulldrv_PaintRgn, /* pPaintRgn */
624 nulldrv_PatBlt, /* pPatBlt */
625 nulldrv_Pie, /* pPie */
626 nulldrv_PolyBezier, /* pPolyBezier */
627 nulldrv_PolyBezierTo, /* pPolyBezierTo */
628 nulldrv_PolyDraw, /* pPolyDraw */
629 nulldrv_PolyPolygon, /* pPolyPolygon */
630 nulldrv_PolyPolyline, /* pPolyPolyline */
631 nulldrv_PolylineTo, /* pPolylineTo */
632 nulldrv_PutImage, /* pPutImage */
633 nulldrv_RealizeDefaultPalette, /* pRealizeDefaultPalette */
634 nulldrv_RealizePalette, /* pRealizePalette */
635 nulldrv_Rectangle, /* pRectangle */
636 nulldrv_ResetDC, /* pResetDC */
637 nulldrv_RoundRect, /* pRoundRect */
638 nulldrv_SelectBitmap, /* pSelectBitmap */
639 nulldrv_SelectBrush, /* pSelectBrush */
640 nulldrv_SelectFont, /* pSelectFont */
641 nulldrv_SelectPen, /* pSelectPen */
642 nulldrv_SetBkColor, /* pSetBkColor */
643 nulldrv_SetBoundsRect, /* pSetBoundsRect */
644 nulldrv_SetDCBrushColor, /* pSetDCBrushColor */
645 nulldrv_SetDCPenColor, /* pSetDCPenColor */
646 nulldrv_SetDIBitsToDevice, /* pSetDIBitsToDevice */
647 nulldrv_SetDeviceClipping, /* pSetDeviceClipping */
648 nulldrv_SetDeviceGammaRamp, /* pSetDeviceGammaRamp */
649 nulldrv_SetPixel, /* pSetPixel */
650 nulldrv_SetTextColor, /* pSetTextColor */
651 nulldrv_StartDoc, /* pStartDoc */
652 nulldrv_StartPage, /* pStartPage */
653 nulldrv_StretchBlt, /* pStretchBlt */
654 nulldrv_StretchDIBits, /* pStretchDIBits */
655 nulldrv_StrokeAndFillPath, /* pStrokeAndFillPath */
656 nulldrv_StrokePath, /* pStrokePath */
657 nulldrv_UnrealizePalette, /* pUnrealizePalette */
658 nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */
659 nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */
660 nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */
661 nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */
662 nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */
664 GDI_PRIORITY_NULL_DRV /* priority */
668 /**********************************************************************
669 * Null user driver
671 * These are fallbacks for entry points that are not implemented in the real driver.
674 static BOOL nulldrv_ActivateKeyboardLayout( HKL layout, UINT flags )
676 return TRUE;
679 static void nulldrv_Beep(void)
683 static UINT nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts )
685 return ~0; /* use default implementation */
688 static INT nulldrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
690 return -1; /* use default implementation */
693 static UINT nulldrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
695 return -1; /* use default implementation */
698 static BOOL nulldrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
700 return TRUE;
703 static INT nulldrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
704 int size, UINT flags, HKL layout )
706 return -2; /* use default implementation */
709 static void nulldrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
713 static SHORT nulldrv_VkKeyScanEx( WCHAR ch, HKL layout )
715 return -256; /* use default implementation */
718 static UINT nulldrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const BYTE *state )
720 return 0;
723 static UINT nulldrv_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc )
725 return 0;
728 static void nulldrv_NotifyIMEStatus( HWND hwnd, UINT status )
732 static LRESULT nulldrv_DesktopWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
734 return default_window_proc( hwnd, msg, wparam, lparam, FALSE );
737 static void nulldrv_DestroyCursorIcon( HCURSOR cursor )
741 static void nulldrv_SetCursor( HWND hwnd, HCURSOR cursor )
745 static BOOL nulldrv_GetCursorPos( LPPOINT pt )
747 return TRUE;
750 static BOOL nulldrv_SetCursorPos( INT x, INT y )
752 return TRUE;
755 static BOOL nulldrv_ClipCursor( const RECT *clip, BOOL reset )
757 return TRUE;
760 static void nulldrv_UpdateClipboard(void)
764 static LONG nulldrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd,
765 DWORD flags, LPVOID lparam )
767 return E_NOTIMPL; /* use default implementation */
770 static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW mode )
772 return FALSE; /* use default implementation */
775 static INT nulldrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary )
777 return -1; /* use default implementation */
780 static BOOL nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, BOOL force, void *param )
782 return FALSE;
785 static BOOL nulldrv_CreateDesktop( const WCHAR *name, UINT width, UINT height )
787 return TRUE;
790 static BOOL nodrv_CreateWindow( HWND hwnd )
792 static int warned;
793 HWND parent = NtUserGetAncestor( hwnd, GA_PARENT );
795 /* HWND_MESSAGE windows don't need a graphics driver */
796 if (!parent || parent == UlongToHandle( NtUserGetThreadInfo()->msg_window )) return TRUE;
797 if (warned++) return FALSE;
799 ERR_(winediag)( "Application tried to create a window, but no driver could be loaded.\n" );
800 if (driver_load_error[0]) ERR_(winediag)( "%s\n", debugstr_w(driver_load_error) );
801 return FALSE;
804 static BOOL nulldrv_CreateWindow( HWND hwnd )
806 return TRUE;
809 static void nulldrv_DestroyWindow( HWND hwnd )
813 static void nulldrv_FlashWindowEx( FLASHWINFO *info )
817 static void nulldrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
818 const RECT *top_rect, DWORD flags )
822 static BOOL nulldrv_ProcessEvents( DWORD mask )
824 return FALSE;
827 static void nulldrv_ReleaseDC( HWND hwnd, HDC hdc )
831 static BOOL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
833 RECT rect;
835 NtGdiGetAppClipBox( hdc, &rect );
836 return NtGdiBitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
837 hdc, rect.left - dx, rect.top - dy, SRCCOPY, 0, 0 );
840 static void nulldrv_SetCapture( HWND hwnd, UINT flags )
844 static void nulldrv_SetDesktopWindow( HWND hwnd )
848 static void nulldrv_SetFocus( HWND hwnd )
852 static void nulldrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
856 static void nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
860 static void nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
864 static void nulldrv_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
868 static void nulldrv_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
872 static void nulldrv_SetWindowText( HWND hwnd, LPCWSTR text )
876 static UINT nulldrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
878 return ~0; /* use default implementation */
881 static LRESULT nulldrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam )
883 return -1;
886 static BOOL nulldrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
887 const RECT *window_rect )
889 return TRUE;
892 static LRESULT nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
894 return 0;
897 static BOOL nulldrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
898 const RECT *window_rect, const RECT *client_rect,
899 RECT *visible_rect, struct window_surface **surface )
901 return FALSE;
904 static void nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
905 const RECT *window_rect, const RECT *client_rect,
906 const RECT *visible_rect, const RECT *valid_rects,
907 struct window_surface *surface )
911 static BOOL nulldrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
913 return FALSE;
916 static const struct vulkan_funcs *nulldrv_wine_get_vulkan_driver( UINT version )
918 return NULL;
921 static struct opengl_funcs *nulldrv_wine_get_wgl_driver( UINT version )
923 return (void *)-1;
926 static void nulldrv_ThreadDetach( void )
930 static const WCHAR guid_key_prefixW[] =
932 '\\','R','e','g','i','s','t','r','y',
933 '\\','M','a','c','h','i','n','e',
934 '\\','S','y','s','t','e','m',
935 '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
936 '\\','C','o','n','t','r','o','l',
937 '\\','V','i','d','e','o','\\','{'
939 static const WCHAR guid_key_suffixW[] = {'}','\\','0','0','0','0'};
941 static BOOL load_desktop_driver( HWND hwnd )
943 static const WCHAR guid_nullW[] = {'0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0','0','-',
944 '0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0',0};
945 WCHAR key[ARRAYSIZE(guid_key_prefixW) + 40 + ARRAYSIZE(guid_key_suffixW)], *ptr;
946 char buf[4096];
947 KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buf;
948 ATOM_BASIC_INFORMATION *abi = (ATOM_BASIC_INFORMATION *)buf;
949 BOOL ret = FALSE;
950 HKEY hkey;
951 DWORD size;
952 UINT guid_atom;
954 static const WCHAR prop_nameW[] =
955 {'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_','d','e','v','i','c','e',
956 '_','g','u','i','d',0};
958 user_check_not_lock();
960 asciiz_to_unicode( driver_load_error, "The explorer process failed to start." ); /* default error */
961 /* wait for graphics driver to be ready */
962 send_message( hwnd, WM_NULL, 0, 0 );
964 guid_atom = HandleToULong( NtUserGetProp( hwnd, prop_nameW ));
965 memcpy( key, guid_key_prefixW, sizeof(guid_key_prefixW) );
966 ptr = key + ARRAYSIZE(guid_key_prefixW);
967 if (NtQueryInformationAtom( guid_atom, AtomBasicInformation, buf, sizeof(buf), NULL ))
969 wcscpy( ptr, guid_nullW );
970 ptr += ARRAY_SIZE(guid_nullW) - 1;
972 else
974 memcpy( ptr, abi->Name, abi->NameLength );
975 ptr += abi->NameLength / sizeof(WCHAR);
977 memcpy( ptr, guid_key_suffixW, sizeof(guid_key_suffixW) );
978 ptr += ARRAY_SIZE(guid_key_suffixW);
980 if (!(hkey = reg_open_key( NULL, key, (ptr - key) * sizeof(WCHAR) ))) return FALSE;
982 if ((size = query_reg_ascii_value( hkey, "GraphicsDriver", info, sizeof(buf) )))
984 static const WCHAR nullW[] = {'n','u','l','l',0};
985 TRACE( "trying driver %s\n", debugstr_wn( (const WCHAR *)info->Data,
986 info->DataLength / sizeof(WCHAR) ));
987 if (info->DataLength != sizeof(nullW) || memcmp( info->Data, nullW, sizeof(nullW) ))
989 void *ret_ptr;
990 ULONG ret_len;
991 ret = KeUserModeCallback( NtUserLoadDriver, info->Data, info->DataLength,
992 &ret_ptr, &ret_len );
994 else
996 __wine_set_user_driver( &null_user_driver, WINE_GDI_DRIVER_VERSION );
997 ret = TRUE;
1000 else if ((size = query_reg_ascii_value( hkey, "DriverError", info, sizeof(buf) )))
1002 memcpy( driver_load_error, info->Data, min( info->DataLength, sizeof(driver_load_error) ));
1003 driver_load_error[ARRAYSIZE(driver_load_error) - 1] = 0;
1006 NtClose( hkey );
1007 return ret;
1010 /**********************************************************************
1011 * Lazy loading user driver
1013 * Initial driver used before another driver is loaded.
1014 * Each entry point simply loads the real driver and chains to it.
1017 static const struct user_driver_funcs *load_driver(void)
1019 USEROBJECTFLAGS flags;
1020 HWINSTA winstation;
1022 if (!load_desktop_driver( get_desktop_window() ) || user_driver == &lazy_load_driver)
1024 winstation = NtUserGetProcessWindowStation();
1025 if (!NtUserGetObjectInformation( winstation, UOI_FLAGS, &flags, sizeof(flags), NULL )
1026 || (flags.dwFlags & WSF_VISIBLE))
1027 null_user_driver.pCreateWindow = nodrv_CreateWindow;
1029 __wine_set_user_driver( &null_user_driver, WINE_GDI_DRIVER_VERSION );
1032 return user_driver;
1035 /**********************************************************************
1036 * get_display_driver
1038 const struct gdi_dc_funcs *get_display_driver(void)
1040 if (user_driver == &lazy_load_driver) load_driver();
1041 return &user_driver->dc_funcs;
1044 static BOOL loaderdrv_ActivateKeyboardLayout( HKL layout, UINT flags )
1046 return load_driver()->pActivateKeyboardLayout( layout, flags );
1049 static void loaderdrv_Beep(void)
1051 load_driver()->pBeep();
1054 static INT loaderdrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
1056 return load_driver()->pGetKeyNameText( lparam, buffer, size );
1059 static UINT loaderdrv_GetKeyboardLayoutList( INT size, HKL *layouts )
1061 return load_driver()->pGetKeyboardLayoutList( size, layouts );
1064 static UINT loaderdrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
1066 return load_driver()->pMapVirtualKeyEx( code, type, layout );
1069 static INT loaderdrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str,
1070 int size, UINT flags, HKL layout )
1072 return load_driver()->pToUnicodeEx( virt, scan, state, str, size, flags, layout );
1075 static BOOL loaderdrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
1077 return load_driver()->pRegisterHotKey( hwnd, modifiers, vk );
1080 static void loaderdrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
1082 load_driver()->pUnregisterHotKey( hwnd, modifiers, vk );
1085 static SHORT loaderdrv_VkKeyScanEx( WCHAR ch, HKL layout )
1087 return load_driver()->pVkKeyScanEx( ch, layout );
1090 static UINT loaderdrv_ImeProcessKey( HIMC himc, UINT wparam, UINT lparam, const BYTE *state )
1092 return load_driver()->pImeProcessKey( himc, wparam, lparam, state );
1095 static UINT loaderdrv_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state, COMPOSITIONSTRING *compstr, HIMC himc )
1097 return load_driver()->pImeToAsciiEx( vkey, vsc, state, compstr, himc );
1100 static void loaderdrv_NotifyIMEStatus( HWND hwnd, UINT status )
1102 return load_driver()->pNotifyIMEStatus( hwnd, status );
1105 static LONG loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd,
1106 DWORD flags, LPVOID lparam )
1108 return load_driver()->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam );
1111 static BOOL loaderdrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW mode )
1113 return load_driver()->pGetCurrentDisplaySettings( name, is_primary, mode );
1116 static INT loaderdrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary )
1118 return load_driver()->pGetDisplayDepth( name, is_primary );
1121 static void loaderdrv_SetCursor( HWND hwnd, HCURSOR cursor )
1123 load_driver()->pSetCursor( hwnd, cursor );
1126 static BOOL loaderdrv_GetCursorPos( POINT *pt )
1128 return load_driver()->pGetCursorPos( pt );
1131 static BOOL loaderdrv_SetCursorPos( INT x, INT y )
1133 return load_driver()->pSetCursorPos( x, y );
1136 static BOOL loaderdrv_ClipCursor( const RECT *clip, BOOL reset )
1138 return load_driver()->pClipCursor( clip, reset );
1141 static LRESULT nulldrv_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1143 return 0;
1146 static void loaderdrv_UpdateClipboard(void)
1148 load_driver()->pUpdateClipboard();
1151 static BOOL loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, BOOL force, void *param )
1153 return load_driver()->pUpdateDisplayDevices( manager, force, param );
1156 static BOOL loaderdrv_CreateDesktop( const WCHAR *name, UINT width, UINT height )
1158 return load_driver()->pCreateDesktop( name, width, height );
1161 static BOOL loaderdrv_CreateWindow( HWND hwnd )
1163 return load_driver()->pCreateWindow( hwnd );
1166 static void loaderdrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
1167 const RECT *top_rect, DWORD flags )
1169 load_driver()->pGetDC( hdc, hwnd, top_win, win_rect, top_rect, flags );
1172 static void loaderdrv_FlashWindowEx( FLASHWINFO *info )
1174 load_driver()->pFlashWindowEx( info );
1177 static void loaderdrv_SetDesktopWindow( HWND hwnd )
1179 load_driver()->pSetDesktopWindow( hwnd );
1182 static void loaderdrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
1184 load_driver()->pSetLayeredWindowAttributes( hwnd, key, alpha, flags );
1187 static void loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
1189 load_driver()->pSetWindowRgn( hwnd, hrgn, redraw );
1192 static BOOL loaderdrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
1193 const RECT *window_rect )
1195 return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect );
1198 static const struct vulkan_funcs * loaderdrv_wine_get_vulkan_driver( UINT version )
1200 return load_driver()->pwine_get_vulkan_driver( version );
1203 static const struct user_driver_funcs lazy_load_driver =
1205 { NULL },
1206 /* keyboard functions */
1207 loaderdrv_ActivateKeyboardLayout,
1208 loaderdrv_Beep,
1209 loaderdrv_GetKeyNameText,
1210 loaderdrv_GetKeyboardLayoutList,
1211 loaderdrv_MapVirtualKeyEx,
1212 loaderdrv_RegisterHotKey,
1213 loaderdrv_ToUnicodeEx,
1214 loaderdrv_UnregisterHotKey,
1215 loaderdrv_VkKeyScanEx,
1216 loaderdrv_ImeProcessKey,
1217 loaderdrv_ImeToAsciiEx,
1218 loaderdrv_NotifyIMEStatus,
1219 /* cursor/icon functions */
1220 nulldrv_DestroyCursorIcon,
1221 loaderdrv_SetCursor,
1222 loaderdrv_GetCursorPos,
1223 loaderdrv_SetCursorPos,
1224 loaderdrv_ClipCursor,
1225 /* clipboard functions */
1226 nulldrv_ClipboardWindowProc,
1227 loaderdrv_UpdateClipboard,
1228 /* display modes */
1229 loaderdrv_ChangeDisplaySettings,
1230 loaderdrv_GetCurrentDisplaySettings,
1231 loaderdrv_GetDisplayDepth,
1232 loaderdrv_UpdateDisplayDevices,
1233 /* windowing functions */
1234 loaderdrv_CreateDesktop,
1235 loaderdrv_CreateWindow,
1236 nulldrv_DesktopWindowProc,
1237 nulldrv_DestroyWindow,
1238 loaderdrv_FlashWindowEx,
1239 loaderdrv_GetDC,
1240 nulldrv_ProcessEvents,
1241 nulldrv_ReleaseDC,
1242 nulldrv_ScrollDC,
1243 nulldrv_SetCapture,
1244 loaderdrv_SetDesktopWindow,
1245 nulldrv_SetFocus,
1246 loaderdrv_SetLayeredWindowAttributes,
1247 nulldrv_SetParent,
1248 loaderdrv_SetWindowRgn,
1249 nulldrv_SetWindowIcon,
1250 nulldrv_SetWindowStyle,
1251 nulldrv_SetWindowText,
1252 nulldrv_ShowWindow,
1253 nulldrv_SysCommand,
1254 loaderdrv_UpdateLayeredWindow,
1255 nulldrv_WindowMessage,
1256 nulldrv_WindowPosChanging,
1257 nulldrv_WindowPosChanged,
1258 /* system parameters */
1259 nulldrv_SystemParametersInfo,
1260 /* vulkan support */
1261 loaderdrv_wine_get_vulkan_driver,
1262 /* opengl support */
1263 nulldrv_wine_get_wgl_driver,
1264 /* thread management */
1265 nulldrv_ThreadDetach,
1268 const struct user_driver_funcs *user_driver = &lazy_load_driver;
1270 /******************************************************************************
1271 * __wine_set_user_driver (win32u.so)
1273 void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version )
1275 struct user_driver_funcs *driver, *prev;
1277 if (version != WINE_GDI_DRIVER_VERSION)
1279 ERR( "version mismatch, driver wants %u but win32u has %u\n",
1280 version, WINE_GDI_DRIVER_VERSION );
1281 return;
1284 driver = malloc( sizeof(*driver) );
1285 *driver = funcs ? *funcs : null_user_driver;
1287 #define SET_USER_FUNC(name) \
1288 do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
1290 SET_USER_FUNC(ActivateKeyboardLayout);
1291 SET_USER_FUNC(Beep);
1292 SET_USER_FUNC(GetKeyNameText);
1293 SET_USER_FUNC(GetKeyboardLayoutList);
1294 SET_USER_FUNC(MapVirtualKeyEx);
1295 SET_USER_FUNC(RegisterHotKey);
1296 SET_USER_FUNC(ToUnicodeEx);
1297 SET_USER_FUNC(UnregisterHotKey);
1298 SET_USER_FUNC(VkKeyScanEx);
1299 SET_USER_FUNC(ImeProcessKey);
1300 SET_USER_FUNC(ImeToAsciiEx);
1301 SET_USER_FUNC(NotifyIMEStatus);
1302 SET_USER_FUNC(DestroyCursorIcon);
1303 SET_USER_FUNC(SetCursor);
1304 SET_USER_FUNC(GetCursorPos);
1305 SET_USER_FUNC(SetCursorPos);
1306 SET_USER_FUNC(ClipCursor);
1307 SET_USER_FUNC(ClipboardWindowProc);
1308 SET_USER_FUNC(UpdateClipboard);
1309 SET_USER_FUNC(ChangeDisplaySettings);
1310 SET_USER_FUNC(GetCurrentDisplaySettings);
1311 SET_USER_FUNC(GetDisplayDepth);
1312 SET_USER_FUNC(UpdateDisplayDevices);
1313 SET_USER_FUNC(CreateDesktop);
1314 SET_USER_FUNC(CreateWindow);
1315 SET_USER_FUNC(DesktopWindowProc);
1316 SET_USER_FUNC(DestroyWindow);
1317 SET_USER_FUNC(FlashWindowEx);
1318 SET_USER_FUNC(GetDC);
1319 SET_USER_FUNC(ProcessEvents);
1320 SET_USER_FUNC(ReleaseDC);
1321 SET_USER_FUNC(ScrollDC);
1322 SET_USER_FUNC(SetCapture);
1323 SET_USER_FUNC(SetDesktopWindow);
1324 SET_USER_FUNC(SetFocus);
1325 SET_USER_FUNC(SetLayeredWindowAttributes);
1326 SET_USER_FUNC(SetParent);
1327 SET_USER_FUNC(SetWindowRgn);
1328 SET_USER_FUNC(SetWindowIcon);
1329 SET_USER_FUNC(SetWindowStyle);
1330 SET_USER_FUNC(SetWindowText);
1331 SET_USER_FUNC(ShowWindow);
1332 SET_USER_FUNC(SysCommand);
1333 SET_USER_FUNC(UpdateLayeredWindow);
1334 SET_USER_FUNC(WindowMessage);
1335 SET_USER_FUNC(WindowPosChanging);
1336 SET_USER_FUNC(WindowPosChanged);
1337 SET_USER_FUNC(SystemParametersInfo);
1338 SET_USER_FUNC(wine_get_vulkan_driver);
1339 SET_USER_FUNC(wine_get_wgl_driver);
1340 SET_USER_FUNC(ThreadDetach);
1341 #undef SET_USER_FUNC
1343 prev = InterlockedCompareExchangePointer( (void **)&user_driver, driver, (void *)&lazy_load_driver );
1344 if (prev != &lazy_load_driver)
1346 /* another thread beat us to it */
1347 free( driver );
1348 driver = prev;
1352 /******************************************************************************
1353 * NtGdiExtEscape (win32u.@)
1355 * Access capabilities of a particular device that are not available through GDI.
1357 INT WINAPI NtGdiExtEscape( HDC hdc, WCHAR *driver, int driver_id, INT escape, INT input_size,
1358 const char *input, INT output_size, char *output )
1360 PHYSDEV physdev;
1361 INT ret;
1362 DC * dc = get_dc_ptr( hdc );
1364 if (!dc) return 0;
1365 update_dc( dc );
1366 physdev = GET_DC_PHYSDEV( dc, pExtEscape );
1367 ret = physdev->funcs->pExtEscape( physdev, escape, input_size, input, output_size, output );
1368 release_dc_ptr( dc );
1369 return ret;
1373 /******************************************************************************
1374 * NtGdiDdDDIOpenAdapterFromHdc (win32u.@)
1376 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc )
1378 FIXME( "(%p): stub\n", desc );
1379 return STATUS_NO_MEMORY;
1382 /******************************************************************************
1383 * NtGdiDdDDIEscape (win32u.@)
1385 NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc )
1387 FIXME( "(%p): stub\n", desc );
1388 return STATUS_NO_MEMORY;
1391 /******************************************************************************
1392 * NtGdiDdDDICloseAdapter (win32u.@)
1394 NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
1396 NTSTATUS status = STATUS_INVALID_PARAMETER;
1397 struct d3dkmt_adapter *adapter;
1399 TRACE("(%p)\n", desc);
1401 if (!desc || !desc->hAdapter)
1402 return STATUS_INVALID_PARAMETER;
1404 if (get_display_driver()->pD3DKMTCloseAdapter)
1405 get_display_driver()->pD3DKMTCloseAdapter( desc );
1407 pthread_mutex_lock( &driver_lock );
1408 LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry )
1410 if (adapter->handle == desc->hAdapter)
1412 list_remove( &adapter->entry );
1413 free( adapter );
1414 status = STATUS_SUCCESS;
1415 break;
1418 pthread_mutex_unlock( &driver_lock );
1420 return status;
1423 /******************************************************************************
1424 * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@)
1426 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc )
1428 D3DKMT_OPENADAPTERFROMLUID desc_luid;
1429 NTSTATUS status;
1431 FIXME( "desc %p stub.\n", desc );
1433 if (!desc || !desc->pDeviceName) return STATUS_INVALID_PARAMETER;
1435 memset( &desc_luid, 0, sizeof( desc_luid ));
1436 if ((status = NtGdiDdDDIOpenAdapterFromLuid( &desc_luid ))) return status;
1438 desc->AdapterLuid = desc_luid.AdapterLuid;
1439 desc->hAdapter = desc_luid.hAdapter;
1440 return STATUS_SUCCESS;
1443 /******************************************************************************
1444 * NtGdiDdDDIOpenAdapterFromLuid (win32u.@)
1446 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc )
1448 static D3DKMT_HANDLE handle_start = 0;
1449 struct d3dkmt_adapter *adapter;
1451 if (!(adapter = malloc( sizeof( *adapter ) ))) return STATUS_NO_MEMORY;
1453 pthread_mutex_lock( &driver_lock );
1454 desc->hAdapter = adapter->handle = ++handle_start;
1455 list_add_tail( &d3dkmt_adapters, &adapter->entry );
1456 pthread_mutex_unlock( &driver_lock );
1458 if (get_display_driver()->pD3DKMTOpenAdapterFromLuid)
1459 get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc );
1461 return STATUS_SUCCESS;
1464 /******************************************************************************
1465 * NtGdiDdDDICreateDevice (win32u.@)
1467 NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc )
1469 static D3DKMT_HANDLE handle_start = 0;
1470 struct d3dkmt_adapter *adapter;
1471 struct d3dkmt_device *device;
1472 BOOL found = FALSE;
1474 TRACE("(%p)\n", desc);
1476 if (!desc)
1477 return STATUS_INVALID_PARAMETER;
1479 pthread_mutex_lock( &driver_lock );
1480 LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry )
1482 if (adapter->handle == desc->hAdapter)
1484 found = TRUE;
1485 break;
1488 pthread_mutex_unlock( &driver_lock );
1490 if (!found)
1491 return STATUS_INVALID_PARAMETER;
1493 if (desc->Flags.LegacyMode || desc->Flags.RequestVSync || desc->Flags.DisableGpuTimeout)
1494 FIXME("Flags unsupported.\n");
1496 device = calloc( 1, sizeof( *device ) );
1497 if (!device)
1498 return STATUS_NO_MEMORY;
1500 pthread_mutex_lock( &driver_lock );
1501 device->handle = ++handle_start;
1502 list_add_tail( &d3dkmt_devices, &device->entry );
1503 pthread_mutex_unlock( &driver_lock );
1505 desc->hDevice = device->handle;
1506 return STATUS_SUCCESS;
1509 /******************************************************************************
1510 * NtGdiDdDDIDestroyDevice (win32u.@)
1512 NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc )
1514 NTSTATUS status = STATUS_INVALID_PARAMETER;
1515 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc;
1516 struct d3dkmt_device *device;
1518 TRACE("(%p)\n", desc);
1520 if (!desc || !desc->hDevice)
1521 return STATUS_INVALID_PARAMETER;
1523 pthread_mutex_lock( &driver_lock );
1524 LIST_FOR_EACH_ENTRY( device, &d3dkmt_devices, struct d3dkmt_device, entry )
1526 if (device->handle == desc->hDevice)
1528 memset( &set_owner_desc, 0, sizeof(set_owner_desc) );
1529 set_owner_desc.hDevice = desc->hDevice;
1530 NtGdiDdDDISetVidPnSourceOwner( &set_owner_desc );
1531 list_remove( &device->entry );
1532 free( device );
1533 status = STATUS_SUCCESS;
1534 break;
1537 pthread_mutex_unlock( &driver_lock );
1539 return status;
1542 /******************************************************************************
1543 * NtGdiDdDDIQueryStatistics (win32u.@)
1545 NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats )
1547 FIXME("(%p): stub\n", stats);
1548 return STATUS_SUCCESS;
1551 /******************************************************************************
1552 * NtGdiDdDDIQueryVideoMemoryInfo (win32u.@)
1554 NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
1556 OBJECT_BASIC_INFORMATION info;
1557 NTSTATUS status;
1559 TRACE("(%p)\n", desc);
1561 if (!desc || !desc->hAdapter ||
1562 (desc->MemorySegmentGroup != D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL &&
1563 desc->MemorySegmentGroup != D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL))
1564 return STATUS_INVALID_PARAMETER;
1566 /* FIXME: Wine currently doesn't support linked adapters */
1567 if (desc->PhysicalAdapterIndex > 0)
1568 return STATUS_INVALID_PARAMETER;
1570 status = NtQueryObject(desc->hProcess ? desc->hProcess : GetCurrentProcess(),
1571 ObjectBasicInformation, &info, sizeof(info), NULL);
1572 if (status != STATUS_SUCCESS)
1573 return status;
1574 if (!(info.GrantedAccess & PROCESS_QUERY_INFORMATION))
1575 return STATUS_ACCESS_DENIED;
1577 if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo)
1578 return STATUS_PROCEDURE_NOT_FOUND;
1579 return get_display_driver()->pD3DKMTQueryVideoMemoryInfo(desc);
1582 /******************************************************************************
1583 * NtGdiDdDDISetQueuedLimit (win32u.@)
1585 NTSTATUS WINAPI NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT *desc )
1587 FIXME( "(%p): stub\n", desc );
1588 return STATUS_NOT_IMPLEMENTED;
1591 /******************************************************************************
1592 * NtGdiDdDDISetVidPnSourceOwner (win32u.@)
1594 NTSTATUS WINAPI NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc )
1596 TRACE("(%p)\n", desc);
1598 if (!get_display_driver()->pD3DKMTSetVidPnSourceOwner)
1599 return STATUS_PROCEDURE_NOT_FOUND;
1601 if (!desc || !desc->hDevice || (desc->VidPnSourceCount && (!desc->pType || !desc->pVidPnSourceId)))
1602 return STATUS_INVALID_PARAMETER;
1604 /* Store the VidPN source ownership info in the graphics driver because
1605 * the graphics driver needs to change ownership sometimes. For example,
1606 * when a new window is moved to a VidPN source with an exclusive owner,
1607 * such an exclusive owner will be released before showing the new window */
1608 return get_display_driver()->pD3DKMTSetVidPnSourceOwner( desc );
1611 /******************************************************************************
1612 * NtGdiDdDDICheckVidPnExclusiveOwnership (win32u.@)
1614 NTSTATUS WINAPI NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc )
1616 TRACE("(%p)\n", desc);
1618 if (!get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership)
1619 return STATUS_PROCEDURE_NOT_FOUND;
1621 if (!desc || !desc->hAdapter)
1622 return STATUS_INVALID_PARAMETER;
1624 return get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership( desc );