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
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
);
42 D3DKMT_HANDLE handle
; /* Kernel mode graphics adapter handle */
43 struct list entry
; /* List entry */
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 CDECL
nulldrv_AbortDoc( PHYSDEV dev
)
66 static BOOL CDECL
nulldrv_Arc( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
67 INT xstart
, INT ystart
, INT xend
, INT yend
)
72 static BOOL CDECL
nulldrv_Chord( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
73 INT xstart
, INT ystart
, INT xend
, INT yend
)
78 static BOOL CDECL
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 CDECL
nulldrv_CreateDC( PHYSDEV
*dev
, LPCWSTR device
, LPCWSTR output
,
85 const DEVMODEW
*devmode
)
87 assert(0); /* should never be called */
91 static BOOL CDECL
nulldrv_DeleteDC( PHYSDEV dev
)
93 assert(0); /* should never be called */
97 static BOOL CDECL
nulldrv_DeleteObject( PHYSDEV dev
, HGDIOBJ obj
)
102 static BOOL CDECL
nulldrv_Ellipse( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
107 static INT CDECL
nulldrv_EndDoc( PHYSDEV dev
)
112 static INT CDECL
nulldrv_EndPage( PHYSDEV dev
)
117 static BOOL CDECL
nulldrv_EnumFonts( PHYSDEV dev
, LOGFONTW
*logfont
, FONTENUMPROCW proc
, LPARAM lParam
)
122 static INT CDECL
nulldrv_ExtEscape( PHYSDEV dev
, INT escape
, INT in_size
, const void *in_data
,
123 INT out_size
, void *out_data
)
128 static BOOL CDECL
nulldrv_ExtFloodFill( PHYSDEV dev
, INT x
, INT y
, COLORREF color
, UINT type
)
133 static BOOL CDECL
nulldrv_FontIsLinked( PHYSDEV dev
)
138 static UINT CDECL
nulldrv_GetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
143 static BOOL CDECL
nulldrv_GetCharABCWidths( PHYSDEV dev
, UINT first
, UINT count
,
144 WCHAR
*chars
, ABC
*abc
)
149 static BOOL CDECL
nulldrv_GetCharABCWidthsI( PHYSDEV dev
, UINT first
, UINT count
, WORD
*indices
, LPABC abc
)
154 static BOOL CDECL
nulldrv_GetCharWidth( PHYSDEV dev
, UINT first
, UINT count
,
155 const WCHAR
*chars
, INT
*buffer
)
160 static BOOL CDECL
nulldrv_GetCharWidthInfo( PHYSDEV dev
, void *info
)
165 static INT CDECL
nulldrv_GetDeviceCaps( PHYSDEV dev
, INT cap
)
171 case DRIVERVERSION
: return 0x4000;
172 case TECHNOLOGY
: return DT_RASDISPLAY
;
173 case HORZSIZE
: return muldiv( NtGdiGetDeviceCaps( dev
->hdc
, HORZRES
), 254,
174 NtGdiGetDeviceCaps( dev
->hdc
, LOGPIXELSX
) * 10 );
175 case VERTSIZE
: return muldiv( NtGdiGetDeviceCaps( dev
->hdc
, VERTRES
), 254,
176 NtGdiGetDeviceCaps( dev
->hdc
, LOGPIXELSY
) * 10 );
179 DC
*dc
= get_nulldrv_dc( dev
);
185 rect
= get_display_rect( dc
->display
);
186 if (!IsRectEmpty( &rect
)) return rect
.right
- rect
.left
;
189 ret
= get_system_metrics( SM_CXSCREEN
);
190 return ret
? ret
: 640;
194 DC
*dc
= get_nulldrv_dc( dev
);
200 rect
= get_display_rect( dc
->display
);
201 if (!IsRectEmpty( &rect
)) return rect
.bottom
- rect
.top
;
204 ret
= get_system_metrics( SM_CYSCREEN
);
205 return ret
? ret
: 480;
209 UNICODE_STRING display
;
212 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
214 dc
= get_nulldrv_dc( dev
);
215 RtlInitUnicodeString( &display
, dc
->display
);
216 return get_display_depth( &display
);
220 case PLANES
: return 1;
221 case NUMBRUSHES
: return -1;
222 case NUMPENS
: return -1;
223 case NUMMARKERS
: return 0;
224 case NUMFONTS
: return 0;
225 case PDEVICESIZE
: return 0;
226 case CURVECAPS
: return (CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
| CC_WIDE
|
227 CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
| CC_ROUNDRECT
);
228 case LINECAPS
: return (LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
229 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
);
230 case POLYGONALCAPS
: return (PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
| PC_SCANLINE
|
231 PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
| PC_INTERIORS
);
232 case TEXTCAPS
: return (TC_OP_CHARACTER
| TC_OP_STROKE
| TC_CP_STROKE
|
233 TC_CR_ANY
| TC_SF_X_YINDEP
| TC_SA_DOUBLE
| TC_SA_INTEGER
|
234 TC_SA_CONTIN
| TC_UA_ABLE
| TC_SO_ABLE
| TC_RA_ABLE
| TC_VA_ABLE
);
235 case CLIPCAPS
: return CP_RECTANGLE
;
236 case RASTERCAPS
: return (RC_BITBLT
| RC_BITMAP64
| RC_GDI20_OUTPUT
| RC_DI_BITMAP
| RC_DIBTODEV
|
237 RC_BIGFONT
| RC_STRETCHBLT
| RC_FLOODFILL
| RC_STRETCHDIB
| RC_DEVBITS
|
238 (NtGdiGetDeviceCaps( dev
->hdc
, SIZEPALETTE
) ? RC_PALETTE
: 0));
239 case ASPECTX
: return 36;
240 case ASPECTY
: return 36;
241 case ASPECTXY
: return (int)(hypot( NtGdiGetDeviceCaps( dev
->hdc
, ASPECTX
),
242 NtGdiGetDeviceCaps( dev
->hdc
, ASPECTY
)) + 0.5);
243 case CAPS1
: return 0;
244 case SIZEPALETTE
: return 0;
245 case NUMRESERVED
: return 20;
246 case PHYSICALWIDTH
: return 0;
247 case PHYSICALHEIGHT
: return 0;
248 case PHYSICALOFFSETX
: return 0;
249 case PHYSICALOFFSETY
: return 0;
250 case SCALINGFACTORX
: return 0;
251 case SCALINGFACTORY
: return 0;
254 UNICODE_STRING display
;
258 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) != DT_RASDISPLAY
)
261 dc
= get_nulldrv_dc( dev
);
263 memset( &devmode
, 0, sizeof(devmode
) );
264 devmode
.dmSize
= sizeof(devmode
);
265 RtlInitUnicodeString( &display
, dc
->display
);
266 if (NtUserEnumDisplaySettings( &display
, ENUM_CURRENT_SETTINGS
, &devmode
, 0 ) &&
267 devmode
.dmDisplayFrequency
)
268 return devmode
.dmDisplayFrequency
;
272 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
274 RECT rect
= get_virtual_screen_rect( 0 );
275 return rect
.right
- rect
.left
;
277 return NtGdiGetDeviceCaps( dev
->hdc
, HORZRES
);
279 if (NtGdiGetDeviceCaps( dev
->hdc
, TECHNOLOGY
) == DT_RASDISPLAY
)
281 RECT rect
= get_virtual_screen_rect( 0 );
282 return rect
.bottom
- rect
.top
;
284 return NtGdiGetDeviceCaps( dev
->hdc
, VERTRES
);
285 case BLTALIGNMENT
: return 0;
286 case SHADEBLENDCAPS
: return 0;
287 case COLORMGMTCAPS
: return 0;
289 case LOGPIXELSY
: return get_system_dpi();
291 bpp
= NtGdiGetDeviceCaps( dev
->hdc
, BITSPIXEL
);
292 /* Newer versions of Windows return -1 for 8-bit and higher */
293 return (bpp
> 4) ? -1 : (1 << bpp
);
295 /* The observed correspondence between BITSPIXEL and COLORRES is:
296 * BITSPIXEL: 8 -> COLORRES: 18
297 * BITSPIXEL: 16 -> COLORRES: 16
298 * BITSPIXEL: 24 -> COLORRES: 24
299 * BITSPIXEL: 32 -> COLORRES: 24 */
300 bpp
= NtGdiGetDeviceCaps( dev
->hdc
, BITSPIXEL
);
301 return (bpp
<= 8) ? 18 : min( 24, bpp
);
303 FIXME("(%p): unsupported capability %d, will return 0\n", dev
->hdc
, cap
);
308 static BOOL CDECL
nulldrv_GetDeviceGammaRamp( PHYSDEV dev
, void *ramp
)
310 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
314 static DWORD CDECL
nulldrv_GetFontData( PHYSDEV dev
, DWORD table
, DWORD offset
, LPVOID buffer
, DWORD length
)
319 static BOOL CDECL
nulldrv_GetFontRealizationInfo( PHYSDEV dev
, void *info
)
324 static DWORD CDECL
nulldrv_GetFontUnicodeRanges( PHYSDEV dev
, LPGLYPHSET glyphs
)
329 static DWORD CDECL
nulldrv_GetGlyphIndices( PHYSDEV dev
, LPCWSTR str
, INT count
, LPWORD indices
, DWORD flags
)
334 static DWORD CDECL
nulldrv_GetGlyphOutline( PHYSDEV dev
, UINT ch
, UINT format
, LPGLYPHMETRICS metrics
,
335 DWORD size
, LPVOID buffer
, const MAT2
*mat
)
340 static BOOL CDECL
nulldrv_GetICMProfile( PHYSDEV dev
, BOOL allow_default
, LPDWORD size
, LPWSTR filename
)
345 static DWORD CDECL
nulldrv_GetImage( PHYSDEV dev
, BITMAPINFO
*info
, struct gdi_image_bits
*bits
,
346 struct bitblt_coords
*src
)
348 return ERROR_NOT_SUPPORTED
;
351 static DWORD CDECL
nulldrv_GetKerningPairs( PHYSDEV dev
, DWORD count
, LPKERNINGPAIR pairs
)
356 static UINT CDECL
nulldrv_GetOutlineTextMetrics( PHYSDEV dev
, UINT size
, LPOUTLINETEXTMETRICW otm
)
361 static UINT CDECL
nulldrv_GetTextCharsetInfo( PHYSDEV dev
, LPFONTSIGNATURE fs
, DWORD flags
)
363 return DEFAULT_CHARSET
;
366 static BOOL CDECL
nulldrv_GetTextExtentExPoint( PHYSDEV dev
, LPCWSTR str
, INT count
, INT
*dx
)
371 static BOOL CDECL
nulldrv_GetTextExtentExPointI( PHYSDEV dev
, const WORD
*indices
, INT count
, INT
*dx
)
376 static INT CDECL
nulldrv_GetTextFace( PHYSDEV dev
, INT size
, LPWSTR name
)
380 DC
*dc
= get_nulldrv_dc( dev
);
382 if (NtGdiExtGetObjectW( dc
->hFont
, sizeof(font
), &font
))
384 ret
= lstrlenW( font
.lfFaceName
) + 1;
387 lstrcpynW( name
, font
.lfFaceName
, size
);
388 ret
= min( size
, ret
);
394 static BOOL CDECL
nulldrv_GetTextMetrics( PHYSDEV dev
, TEXTMETRICW
*metrics
)
399 static BOOL CDECL
nulldrv_LineTo( PHYSDEV dev
, INT x
, INT y
)
404 static BOOL CDECL
nulldrv_MoveTo( PHYSDEV dev
, INT x
, INT y
)
409 static BOOL CDECL
nulldrv_PaintRgn( PHYSDEV dev
, HRGN rgn
)
414 static BOOL CDECL
nulldrv_PatBlt( PHYSDEV dev
, struct bitblt_coords
*dst
, DWORD rop
)
419 static BOOL CDECL
nulldrv_Pie( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
420 INT xstart
, INT ystart
, INT xend
, INT yend
)
425 static BOOL CDECL
nulldrv_PolyPolygon( PHYSDEV dev
, const POINT
*points
, const INT
*counts
, UINT polygons
)
430 static BOOL CDECL
nulldrv_PolyPolyline( PHYSDEV dev
, const POINT
*points
, const DWORD
*counts
, DWORD lines
)
435 static DWORD CDECL
nulldrv_PutImage( PHYSDEV dev
, HRGN clip
, BITMAPINFO
*info
,
436 const struct gdi_image_bits
*bits
, struct bitblt_coords
*src
,
437 struct bitblt_coords
*dst
, DWORD rop
)
439 return ERROR_SUCCESS
;
442 static UINT CDECL
nulldrv_RealizeDefaultPalette( PHYSDEV dev
)
447 static UINT CDECL
nulldrv_RealizePalette( PHYSDEV dev
, HPALETTE palette
, BOOL primary
)
452 static BOOL CDECL
nulldrv_Rectangle( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
)
457 static BOOL CDECL
nulldrv_ResetDC( PHYSDEV dev
, const DEVMODEW
*devmode
)
462 static BOOL CDECL
nulldrv_RoundRect( PHYSDEV dev
, INT left
, INT top
, INT right
, INT bottom
,
463 INT ell_width
, INT ell_height
)
468 static HBITMAP CDECL
nulldrv_SelectBitmap( PHYSDEV dev
, HBITMAP bitmap
)
473 static HBRUSH CDECL
nulldrv_SelectBrush( PHYSDEV dev
, HBRUSH brush
, const struct brush_pattern
*pattern
)
478 static HFONT CDECL
nulldrv_SelectFont( PHYSDEV dev
, HFONT font
, UINT
*aa_flags
)
483 static HPEN CDECL
nulldrv_SelectPen( PHYSDEV dev
, HPEN pen
, const struct brush_pattern
*pattern
)
488 static COLORREF CDECL
nulldrv_SetBkColor( PHYSDEV dev
, COLORREF color
)
493 static UINT CDECL
nulldrv_SetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
498 static COLORREF CDECL
nulldrv_SetDCBrushColor( PHYSDEV dev
, COLORREF color
)
503 static COLORREF CDECL
nulldrv_SetDCPenColor( PHYSDEV dev
, COLORREF color
)
508 static void CDECL
nulldrv_SetDeviceClipping( PHYSDEV dev
, HRGN rgn
)
512 static BOOL CDECL
nulldrv_SetDeviceGammaRamp( PHYSDEV dev
, void *ramp
)
514 RtlSetLastWin32Error( ERROR_INVALID_PARAMETER
);
518 static COLORREF CDECL
nulldrv_SetPixel( PHYSDEV dev
, INT x
, INT y
, COLORREF color
)
523 static COLORREF CDECL
nulldrv_SetTextColor( PHYSDEV dev
, COLORREF color
)
528 static INT CDECL
nulldrv_StartDoc( PHYSDEV dev
, const DOCINFOW
*info
)
533 static INT CDECL
nulldrv_StartPage( PHYSDEV dev
)
538 static BOOL CDECL
nulldrv_UnrealizePalette( HPALETTE palette
)
543 static NTSTATUS CDECL
nulldrv_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP
*desc
)
545 return STATUS_PROCEDURE_NOT_FOUND
;
548 static NTSTATUS CDECL
nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER
*desc
)
550 return STATUS_PROCEDURE_NOT_FOUND
;
553 static NTSTATUS CDECL
nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID
*desc
)
555 return STATUS_PROCEDURE_NOT_FOUND
;
558 static NTSTATUS CDECL
nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO
*desc
)
560 return STATUS_PROCEDURE_NOT_FOUND
;
563 static NTSTATUS CDECL
nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER
*desc
)
565 return STATUS_PROCEDURE_NOT_FOUND
;
568 const struct gdi_dc_funcs null_driver
=
570 nulldrv_AbortDoc
, /* pAbortDoc */
571 nulldrv_AbortPath
, /* pAbortPath */
572 nulldrv_AlphaBlend
, /* pAlphaBlend */
573 nulldrv_AngleArc
, /* pAngleArc */
574 nulldrv_Arc
, /* pArc */
575 nulldrv_ArcTo
, /* pArcTo */
576 nulldrv_BeginPath
, /* pBeginPath */
577 nulldrv_BlendImage
, /* pBlendImage */
578 nulldrv_Chord
, /* pChord */
579 nulldrv_CloseFigure
, /* pCloseFigure */
580 nulldrv_CreateCompatibleDC
, /* pCreateCompatibleDC */
581 nulldrv_CreateDC
, /* pCreateDC */
582 nulldrv_DeleteDC
, /* pDeleteDC */
583 nulldrv_DeleteObject
, /* pDeleteObject */
584 nulldrv_Ellipse
, /* pEllipse */
585 nulldrv_EndDoc
, /* pEndDoc */
586 nulldrv_EndPage
, /* pEndPage */
587 nulldrv_EndPath
, /* pEndPath */
588 nulldrv_EnumFonts
, /* pEnumFonts */
589 nulldrv_ExtEscape
, /* pExtEscape */
590 nulldrv_ExtFloodFill
, /* pExtFloodFill */
591 nulldrv_ExtTextOut
, /* pExtTextOut */
592 nulldrv_FillPath
, /* pFillPath */
593 nulldrv_FillRgn
, /* pFillRgn */
594 nulldrv_FontIsLinked
, /* pFontIsLinked */
595 nulldrv_FrameRgn
, /* pFrameRgn */
596 nulldrv_GetBoundsRect
, /* pGetBoundsRect */
597 nulldrv_GetCharABCWidths
, /* pGetCharABCWidths */
598 nulldrv_GetCharABCWidthsI
, /* pGetCharABCWidthsI */
599 nulldrv_GetCharWidth
, /* pGetCharWidth */
600 nulldrv_GetCharWidthInfo
, /* pGetCharWidthInfo */
601 nulldrv_GetDeviceCaps
, /* pGetDeviceCaps */
602 nulldrv_GetDeviceGammaRamp
, /* pGetDeviceGammaRamp */
603 nulldrv_GetFontData
, /* pGetFontData */
604 nulldrv_GetFontRealizationInfo
, /* pGetFontRealizationInfo */
605 nulldrv_GetFontUnicodeRanges
, /* pGetFontUnicodeRanges */
606 nulldrv_GetGlyphIndices
, /* pGetGlyphIndices */
607 nulldrv_GetGlyphOutline
, /* pGetGlyphOutline */
608 nulldrv_GetICMProfile
, /* pGetICMProfile */
609 nulldrv_GetImage
, /* pGetImage */
610 nulldrv_GetKerningPairs
, /* pGetKerningPairs */
611 nulldrv_GetNearestColor
, /* pGetNearestColor */
612 nulldrv_GetOutlineTextMetrics
, /* pGetOutlineTextMetrics */
613 nulldrv_GetPixel
, /* pGetPixel */
614 nulldrv_GetSystemPaletteEntries
, /* pGetSystemPaletteEntries */
615 nulldrv_GetTextCharsetInfo
, /* pGetTextCharsetInfo */
616 nulldrv_GetTextExtentExPoint
, /* pGetTextExtentExPoint */
617 nulldrv_GetTextExtentExPointI
, /* pGetTextExtentExPointI */
618 nulldrv_GetTextFace
, /* pGetTextFace */
619 nulldrv_GetTextMetrics
, /* pGetTextMetrics */
620 nulldrv_GradientFill
, /* pGradientFill */
621 nulldrv_InvertRgn
, /* pInvertRgn */
622 nulldrv_LineTo
, /* pLineTo */
623 nulldrv_MoveTo
, /* pMoveTo */
624 nulldrv_PaintRgn
, /* pPaintRgn */
625 nulldrv_PatBlt
, /* pPatBlt */
626 nulldrv_Pie
, /* pPie */
627 nulldrv_PolyBezier
, /* pPolyBezier */
628 nulldrv_PolyBezierTo
, /* pPolyBezierTo */
629 nulldrv_PolyDraw
, /* pPolyDraw */
630 nulldrv_PolyPolygon
, /* pPolyPolygon */
631 nulldrv_PolyPolyline
, /* pPolyPolyline */
632 nulldrv_PolylineTo
, /* pPolylineTo */
633 nulldrv_PutImage
, /* pPutImage */
634 nulldrv_RealizeDefaultPalette
, /* pRealizeDefaultPalette */
635 nulldrv_RealizePalette
, /* pRealizePalette */
636 nulldrv_Rectangle
, /* pRectangle */
637 nulldrv_ResetDC
, /* pResetDC */
638 nulldrv_RoundRect
, /* pRoundRect */
639 nulldrv_SelectBitmap
, /* pSelectBitmap */
640 nulldrv_SelectBrush
, /* pSelectBrush */
641 nulldrv_SelectFont
, /* pSelectFont */
642 nulldrv_SelectPen
, /* pSelectPen */
643 nulldrv_SetBkColor
, /* pSetBkColor */
644 nulldrv_SetBoundsRect
, /* pSetBoundsRect */
645 nulldrv_SetDCBrushColor
, /* pSetDCBrushColor */
646 nulldrv_SetDCPenColor
, /* pSetDCPenColor */
647 nulldrv_SetDIBitsToDevice
, /* pSetDIBitsToDevice */
648 nulldrv_SetDeviceClipping
, /* pSetDeviceClipping */
649 nulldrv_SetDeviceGammaRamp
, /* pSetDeviceGammaRamp */
650 nulldrv_SetPixel
, /* pSetPixel */
651 nulldrv_SetTextColor
, /* pSetTextColor */
652 nulldrv_StartDoc
, /* pStartDoc */
653 nulldrv_StartPage
, /* pStartPage */
654 nulldrv_StretchBlt
, /* pStretchBlt */
655 nulldrv_StretchDIBits
, /* pStretchDIBits */
656 nulldrv_StrokeAndFillPath
, /* pStrokeAndFillPath */
657 nulldrv_StrokePath
, /* pStrokePath */
658 nulldrv_UnrealizePalette
, /* pUnrealizePalette */
659 nulldrv_D3DKMTCheckVidPnExclusiveOwnership
, /* pD3DKMTCheckVidPnExclusiveOwnership */
660 nulldrv_D3DKMTCloseAdapter
, /* pD3DKMTCloseAdapter */
661 nulldrv_D3DKMTOpenAdapterFromLuid
, /* pD3DKMTOpenAdapterFromLuid */
662 nulldrv_D3DKMTQueryVideoMemoryInfo
, /* pD3DKMTQueryVideoMemoryInfo */
663 nulldrv_D3DKMTSetVidPnSourceOwner
, /* pD3DKMTSetVidPnSourceOwner */
665 GDI_PRIORITY_NULL_DRV
/* priority */
669 /**********************************************************************
672 * These are fallbacks for entry points that are not implemented in the real driver.
675 static BOOL
nulldrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
680 static void nulldrv_Beep(void)
684 static UINT
nulldrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
686 return ~0; /* use default implementation */
689 static INT
nulldrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
691 return -1; /* use default implementation */
694 static UINT
nulldrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
696 return -1; /* use default implementation */
699 static BOOL
nulldrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
704 static INT
nulldrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
705 int size
, UINT flags
, HKL layout
)
707 return -2; /* use default implementation */
710 static void nulldrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
714 static SHORT
nulldrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
716 return -256; /* use default implementation */
719 static LRESULT
nulldrv_DesktopWindowProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
721 return default_window_proc( hwnd
, msg
, wparam
, lparam
, FALSE
);
724 static void nulldrv_DestroyCursorIcon( HCURSOR cursor
)
728 static void nulldrv_SetCursor( HCURSOR cursor
)
732 static BOOL
nulldrv_GetCursorPos( LPPOINT pt
)
737 static BOOL
nulldrv_SetCursorPos( INT x
, INT y
)
742 static BOOL
nulldrv_ClipCursor( LPCRECT clip
)
747 static void nulldrv_UpdateClipboard(void)
751 static LONG
nulldrv_ChangeDisplaySettings( LPDEVMODEW displays
, LPCWSTR primary_name
, HWND hwnd
,
752 DWORD flags
, LPVOID lparam
)
754 return E_NOTIMPL
; /* use default implementation */
757 static BOOL
nulldrv_GetCurrentDisplaySettings( LPCWSTR name
, BOOL is_primary
, LPDEVMODEW mode
)
759 return FALSE
; /* use default implementation */
762 static INT
nulldrv_GetDisplayDepth( LPCWSTR name
, BOOL is_primary
)
764 return -1; /* use default implementation */
767 static BOOL
nulldrv_UpdateDisplayDevices( const struct gdi_device_manager
*manager
, BOOL force
, void *param
)
772 static BOOL
nulldrv_CreateDesktopWindow( HWND hwnd
)
777 static BOOL
nodrv_CreateWindow( HWND hwnd
)
780 HWND parent
= NtUserGetAncestor( hwnd
, GA_PARENT
);
782 /* HWND_MESSAGE windows don't need a graphics driver */
783 if (!parent
|| parent
== UlongToHandle( NtUserGetThreadInfo()->msg_window
)) return TRUE
;
784 if (warned
++) return FALSE
;
786 ERR_(winediag
)( "Application tried to create a window, but no driver could be loaded.\n" );
787 if (driver_load_error
[0]) ERR_(winediag
)( "%s\n", debugstr_w(driver_load_error
) );
791 static BOOL
nulldrv_CreateWindow( HWND hwnd
)
796 static void nulldrv_DestroyWindow( HWND hwnd
)
800 static void nulldrv_FlashWindowEx( FLASHWINFO
*info
)
804 static void nulldrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
805 const RECT
*top_rect
, DWORD flags
)
809 static BOOL
nulldrv_ProcessEvents( DWORD mask
)
814 static void nulldrv_ReleaseDC( HWND hwnd
, HDC hdc
)
818 static BOOL
nulldrv_ScrollDC( HDC hdc
, INT dx
, INT dy
, HRGN update
)
822 NtGdiGetAppClipBox( hdc
, &rect
);
823 return NtGdiBitBlt( hdc
, rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
824 hdc
, rect
.left
- dx
, rect
.top
- dy
, SRCCOPY
, 0, 0 );
827 static void nulldrv_SetCapture( HWND hwnd
, UINT flags
)
831 static void nulldrv_SetFocus( HWND hwnd
)
835 static void nulldrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
839 static void nulldrv_SetParent( HWND hwnd
, HWND parent
, HWND old_parent
)
843 static void nulldrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
847 static void nulldrv_SetWindowIcon( HWND hwnd
, UINT type
, HICON icon
)
851 static void nulldrv_SetWindowStyle( HWND hwnd
, INT offset
, STYLESTRUCT
*style
)
855 static void nulldrv_SetWindowText( HWND hwnd
, LPCWSTR text
)
859 static UINT
nulldrv_ShowWindow( HWND hwnd
, INT cmd
, RECT
*rect
, UINT swp
)
861 return ~0; /* use default implementation */
864 static LRESULT
nulldrv_SysCommand( HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
869 static BOOL
nulldrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
870 const RECT
*window_rect
)
875 static LRESULT
nulldrv_WindowMessage( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
880 static BOOL
nulldrv_WindowPosChanging( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
881 const RECT
*window_rect
, const RECT
*client_rect
,
882 RECT
*visible_rect
, struct window_surface
**surface
)
887 static void nulldrv_WindowPosChanged( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
888 const RECT
*window_rect
, const RECT
*client_rect
,
889 const RECT
*visible_rect
, const RECT
*valid_rects
,
890 struct window_surface
*surface
)
894 static BOOL
nulldrv_SystemParametersInfo( UINT action
, UINT int_param
, void *ptr_param
, UINT flags
)
899 static const struct vulkan_funcs
*nulldrv_wine_get_vulkan_driver( UINT version
)
904 static struct opengl_funcs
*nulldrv_wine_get_wgl_driver( UINT version
)
909 static void nulldrv_ThreadDetach( void )
913 static const WCHAR guid_key_prefixW
[] =
915 '\\','R','e','g','i','s','t','r','y',
916 '\\','M','a','c','h','i','n','e',
917 '\\','S','y','s','t','e','m',
918 '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
919 '\\','C','o','n','t','r','o','l',
920 '\\','V','i','d','e','o','\\','{'
922 static const WCHAR guid_key_suffixW
[] = {'}','\\','0','0','0','0'};
924 static BOOL
load_desktop_driver( HWND hwnd
)
926 static const WCHAR guid_nullW
[] = {'0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0','0','-',
927 '0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0',0};
928 WCHAR key
[ARRAYSIZE(guid_key_prefixW
) + 40 + ARRAYSIZE(guid_key_suffixW
)], *ptr
;
930 KEY_VALUE_PARTIAL_INFORMATION
*info
= (void *)buf
;
931 ATOM_BASIC_INFORMATION
*abi
= (ATOM_BASIC_INFORMATION
*)buf
;
937 static const WCHAR prop_nameW
[] =
938 {'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_','d','e','v','i','c','e',
939 '_','g','u','i','d',0};
941 user_check_not_lock();
943 asciiz_to_unicode( driver_load_error
, "The explorer process failed to start." ); /* default error */
944 /* wait for graphics driver to be ready */
945 send_message( hwnd
, WM_NULL
, 0, 0 );
947 guid_atom
= HandleToULong( NtUserGetProp( hwnd
, prop_nameW
));
948 memcpy( key
, guid_key_prefixW
, sizeof(guid_key_prefixW
) );
949 ptr
= key
+ ARRAYSIZE(guid_key_prefixW
);
950 if (NtQueryInformationAtom( guid_atom
, AtomBasicInformation
, buf
, sizeof(buf
), NULL
))
952 wcscpy( ptr
, guid_nullW
);
953 ptr
+= ARRAY_SIZE(guid_nullW
) - 1;
957 memcpy( ptr
, abi
->Name
, abi
->NameLength
);
958 ptr
+= abi
->NameLength
/ sizeof(WCHAR
);
960 memcpy( ptr
, guid_key_suffixW
, sizeof(guid_key_suffixW
) );
961 ptr
+= ARRAY_SIZE(guid_key_suffixW
);
963 if (!(hkey
= reg_open_key( NULL
, key
, (ptr
- key
) * sizeof(WCHAR
) ))) return FALSE
;
965 if ((size
= query_reg_ascii_value( hkey
, "GraphicsDriver", info
, sizeof(buf
) )))
967 static const WCHAR nullW
[] = {'n','u','l','l',0};
968 TRACE( "trying driver %s\n", debugstr_wn( (const WCHAR
*)info
->Data
,
969 info
->DataLength
/ sizeof(WCHAR
) ));
970 if (info
->DataLength
!= sizeof(nullW
) || memcmp( info
->Data
, nullW
, sizeof(nullW
) ))
974 ret
= KeUserModeCallback( NtUserLoadDriver
, info
->Data
, info
->DataLength
,
975 &ret_ptr
, &ret_len
);
979 __wine_set_user_driver( &null_user_driver
, WINE_GDI_DRIVER_VERSION
);
983 else if ((size
= query_reg_ascii_value( hkey
, "DriverError", info
, sizeof(buf
) )))
985 memcpy( driver_load_error
, info
->Data
, min( info
->DataLength
, sizeof(driver_load_error
) ));
986 driver_load_error
[ARRAYSIZE(driver_load_error
) - 1] = 0;
993 /**********************************************************************
994 * Lazy loading user driver
996 * Initial driver used before another driver is loaded.
997 * Each entry point simply loads the real driver and chains to it.
1000 static const struct user_driver_funcs
*load_driver(void)
1002 USEROBJECTFLAGS flags
;
1005 if (!load_desktop_driver( get_desktop_window() ) || user_driver
== &lazy_load_driver
)
1007 winstation
= NtUserGetProcessWindowStation();
1008 if (!NtUserGetObjectInformation( winstation
, UOI_FLAGS
, &flags
, sizeof(flags
), NULL
)
1009 || (flags
.dwFlags
& WSF_VISIBLE
))
1010 null_user_driver
.pCreateWindow
= nodrv_CreateWindow
;
1012 __wine_set_user_driver( &null_user_driver
, WINE_GDI_DRIVER_VERSION
);
1018 /**********************************************************************
1019 * get_display_driver
1021 const struct gdi_dc_funcs
*get_display_driver(void)
1023 if (user_driver
== &lazy_load_driver
) load_driver();
1024 return &user_driver
->dc_funcs
;
1027 static BOOL
loaderdrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
1029 return load_driver()->pActivateKeyboardLayout( layout
, flags
);
1032 static void loaderdrv_Beep(void)
1034 load_driver()->pBeep();
1037 static INT
loaderdrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
1039 return load_driver()->pGetKeyNameText( lparam
, buffer
, size
);
1042 static UINT
loaderdrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
1044 return load_driver()->pGetKeyboardLayoutList( size
, layouts
);
1047 static UINT
loaderdrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
1049 return load_driver()->pMapVirtualKeyEx( code
, type
, layout
);
1052 static INT
loaderdrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
1053 int size
, UINT flags
, HKL layout
)
1055 return load_driver()->pToUnicodeEx( virt
, scan
, state
, str
, size
, flags
, layout
);
1058 static BOOL
loaderdrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
1060 return load_driver()->pRegisterHotKey( hwnd
, modifiers
, vk
);
1063 static void loaderdrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
1065 load_driver()->pUnregisterHotKey( hwnd
, modifiers
, vk
);
1068 static SHORT
loaderdrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
1070 return load_driver()->pVkKeyScanEx( ch
, layout
);
1073 static LONG
loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays
, LPCWSTR primary_name
, HWND hwnd
,
1074 DWORD flags
, LPVOID lparam
)
1076 return load_driver()->pChangeDisplaySettings( displays
, primary_name
, hwnd
, flags
, lparam
);
1079 static BOOL
loaderdrv_GetCurrentDisplaySettings( LPCWSTR name
, BOOL is_primary
, LPDEVMODEW mode
)
1081 return load_driver()->pGetCurrentDisplaySettings( name
, is_primary
, mode
);
1084 static INT
loaderdrv_GetDisplayDepth( LPCWSTR name
, BOOL is_primary
)
1086 return load_driver()->pGetDisplayDepth( name
, is_primary
);
1089 static void loaderdrv_SetCursor( HCURSOR cursor
)
1091 load_driver()->pSetCursor( cursor
);
1094 static BOOL
loaderdrv_GetCursorPos( POINT
*pt
)
1096 return load_driver()->pGetCursorPos( pt
);
1099 static BOOL
loaderdrv_SetCursorPos( INT x
, INT y
)
1101 return load_driver()->pSetCursorPos( x
, y
);
1104 static BOOL
loaderdrv_ClipCursor( const RECT
*clip
)
1106 return load_driver()->pClipCursor( clip
);
1109 static LRESULT
nulldrv_ClipboardWindowProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1114 static void loaderdrv_UpdateClipboard(void)
1116 load_driver()->pUpdateClipboard();
1119 static BOOL
loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager
*manager
, BOOL force
, void *param
)
1121 return load_driver()->pUpdateDisplayDevices( manager
, force
, param
);
1124 static BOOL
loaderdrv_CreateDesktopWindow( HWND hwnd
)
1126 return load_driver()->pCreateDesktopWindow( hwnd
);
1129 static BOOL
loaderdrv_CreateWindow( HWND hwnd
)
1131 return load_driver()->pCreateWindow( hwnd
);
1134 static void loaderdrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
1135 const RECT
*top_rect
, DWORD flags
)
1137 load_driver()->pGetDC( hdc
, hwnd
, top_win
, win_rect
, top_rect
, flags
);
1140 static void loaderdrv_FlashWindowEx( FLASHWINFO
*info
)
1142 load_driver()->pFlashWindowEx( info
);
1145 static void loaderdrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
1147 load_driver()->pSetLayeredWindowAttributes( hwnd
, key
, alpha
, flags
);
1150 static void loaderdrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
1152 load_driver()->pSetWindowRgn( hwnd
, hrgn
, redraw
);
1155 static BOOL
loaderdrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
1156 const RECT
*window_rect
)
1158 return load_driver()->pUpdateLayeredWindow( hwnd
, info
, window_rect
);
1161 static const struct vulkan_funcs
* loaderdrv_wine_get_vulkan_driver( UINT version
)
1163 return load_driver()->pwine_get_vulkan_driver( version
);
1166 static const struct user_driver_funcs lazy_load_driver
=
1169 /* keyboard functions */
1170 loaderdrv_ActivateKeyboardLayout
,
1172 loaderdrv_GetKeyNameText
,
1173 loaderdrv_GetKeyboardLayoutList
,
1174 loaderdrv_MapVirtualKeyEx
,
1175 loaderdrv_RegisterHotKey
,
1176 loaderdrv_ToUnicodeEx
,
1177 loaderdrv_UnregisterHotKey
,
1178 loaderdrv_VkKeyScanEx
,
1179 /* cursor/icon functions */
1180 nulldrv_DestroyCursorIcon
,
1181 loaderdrv_SetCursor
,
1182 loaderdrv_GetCursorPos
,
1183 loaderdrv_SetCursorPos
,
1184 loaderdrv_ClipCursor
,
1185 /* clipboard functions */
1186 nulldrv_ClipboardWindowProc
,
1187 loaderdrv_UpdateClipboard
,
1189 loaderdrv_ChangeDisplaySettings
,
1190 loaderdrv_GetCurrentDisplaySettings
,
1191 loaderdrv_GetDisplayDepth
,
1192 loaderdrv_UpdateDisplayDevices
,
1193 /* windowing functions */
1194 loaderdrv_CreateDesktopWindow
,
1195 loaderdrv_CreateWindow
,
1196 nulldrv_DesktopWindowProc
,
1197 nulldrv_DestroyWindow
,
1198 loaderdrv_FlashWindowEx
,
1200 nulldrv_ProcessEvents
,
1205 loaderdrv_SetLayeredWindowAttributes
,
1207 loaderdrv_SetWindowRgn
,
1208 nulldrv_SetWindowIcon
,
1209 nulldrv_SetWindowStyle
,
1210 nulldrv_SetWindowText
,
1213 loaderdrv_UpdateLayeredWindow
,
1214 nulldrv_WindowMessage
,
1215 nulldrv_WindowPosChanging
,
1216 nulldrv_WindowPosChanged
,
1217 /* system parameters */
1218 nulldrv_SystemParametersInfo
,
1219 /* vulkan support */
1220 loaderdrv_wine_get_vulkan_driver
,
1221 /* opengl support */
1222 nulldrv_wine_get_wgl_driver
,
1223 /* thread management */
1224 nulldrv_ThreadDetach
,
1227 const struct user_driver_funcs
*user_driver
= &lazy_load_driver
;
1229 /******************************************************************************
1230 * __wine_set_user_driver (win32u.so)
1232 void __wine_set_user_driver( const struct user_driver_funcs
*funcs
, UINT version
)
1234 struct user_driver_funcs
*driver
, *prev
;
1236 if (version
!= WINE_GDI_DRIVER_VERSION
)
1238 ERR( "version mismatch, driver wants %u but win32u has %u\n",
1239 version
, WINE_GDI_DRIVER_VERSION
);
1243 driver
= malloc( sizeof(*driver
) );
1244 *driver
= funcs
? *funcs
: null_user_driver
;
1246 #define SET_USER_FUNC(name) \
1247 do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
1249 SET_USER_FUNC(ActivateKeyboardLayout
);
1250 SET_USER_FUNC(Beep
);
1251 SET_USER_FUNC(GetKeyNameText
);
1252 SET_USER_FUNC(GetKeyboardLayoutList
);
1253 SET_USER_FUNC(MapVirtualKeyEx
);
1254 SET_USER_FUNC(RegisterHotKey
);
1255 SET_USER_FUNC(ToUnicodeEx
);
1256 SET_USER_FUNC(UnregisterHotKey
);
1257 SET_USER_FUNC(VkKeyScanEx
);
1258 SET_USER_FUNC(DestroyCursorIcon
);
1259 SET_USER_FUNC(SetCursor
);
1260 SET_USER_FUNC(GetCursorPos
);
1261 SET_USER_FUNC(SetCursorPos
);
1262 SET_USER_FUNC(ClipCursor
);
1263 SET_USER_FUNC(ClipboardWindowProc
);
1264 SET_USER_FUNC(UpdateClipboard
);
1265 SET_USER_FUNC(ChangeDisplaySettings
);
1266 SET_USER_FUNC(GetCurrentDisplaySettings
);
1267 SET_USER_FUNC(GetDisplayDepth
);
1268 SET_USER_FUNC(UpdateDisplayDevices
);
1269 SET_USER_FUNC(CreateDesktopWindow
);
1270 SET_USER_FUNC(CreateWindow
);
1271 SET_USER_FUNC(DesktopWindowProc
);
1272 SET_USER_FUNC(DestroyWindow
);
1273 SET_USER_FUNC(FlashWindowEx
);
1274 SET_USER_FUNC(GetDC
);
1275 SET_USER_FUNC(ProcessEvents
);
1276 SET_USER_FUNC(ReleaseDC
);
1277 SET_USER_FUNC(ScrollDC
);
1278 SET_USER_FUNC(SetCapture
);
1279 SET_USER_FUNC(SetFocus
);
1280 SET_USER_FUNC(SetLayeredWindowAttributes
);
1281 SET_USER_FUNC(SetParent
);
1282 SET_USER_FUNC(SetWindowRgn
);
1283 SET_USER_FUNC(SetWindowIcon
);
1284 SET_USER_FUNC(SetWindowStyle
);
1285 SET_USER_FUNC(SetWindowText
);
1286 SET_USER_FUNC(ShowWindow
);
1287 SET_USER_FUNC(SysCommand
);
1288 SET_USER_FUNC(UpdateLayeredWindow
);
1289 SET_USER_FUNC(WindowMessage
);
1290 SET_USER_FUNC(WindowPosChanging
);
1291 SET_USER_FUNC(WindowPosChanged
);
1292 SET_USER_FUNC(SystemParametersInfo
);
1293 SET_USER_FUNC(wine_get_vulkan_driver
);
1294 SET_USER_FUNC(wine_get_wgl_driver
);
1295 SET_USER_FUNC(ThreadDetach
);
1296 #undef SET_USER_FUNC
1298 prev
= InterlockedCompareExchangePointer( (void **)&user_driver
, driver
, (void *)&lazy_load_driver
);
1299 if (prev
!= &lazy_load_driver
)
1301 /* another thread beat us to it */
1307 /******************************************************************************
1308 * NtGdiExtEscape (win32u.@)
1310 * Access capabilities of a particular device that are not available through GDI.
1312 INT WINAPI
NtGdiExtEscape( HDC hdc
, WCHAR
*driver
, int driver_id
, INT escape
, INT input_size
,
1313 const char *input
, INT output_size
, char *output
)
1317 DC
* dc
= get_dc_ptr( hdc
);
1321 physdev
= GET_DC_PHYSDEV( dc
, pExtEscape
);
1322 ret
= physdev
->funcs
->pExtEscape( physdev
, escape
, input_size
, input
, output_size
, output
);
1323 release_dc_ptr( dc
);
1328 /******************************************************************************
1329 * NtGdiDdDDIOpenAdapterFromHdc (win32u.@)
1331 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC
*desc
)
1333 FIXME( "(%p): stub\n", desc
);
1334 return STATUS_NO_MEMORY
;
1337 /******************************************************************************
1338 * NtGdiDdDDIEscape (win32u.@)
1340 NTSTATUS WINAPI
NtGdiDdDDIEscape( const D3DKMT_ESCAPE
*desc
)
1342 FIXME( "(%p): stub\n", desc
);
1343 return STATUS_NO_MEMORY
;
1346 /******************************************************************************
1347 * NtGdiDdDDICloseAdapter (win32u.@)
1349 NTSTATUS WINAPI
NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER
*desc
)
1351 NTSTATUS status
= STATUS_INVALID_PARAMETER
;
1352 struct d3dkmt_adapter
*adapter
;
1354 TRACE("(%p)\n", desc
);
1356 if (!desc
|| !desc
->hAdapter
)
1357 return STATUS_INVALID_PARAMETER
;
1359 if (get_display_driver()->pD3DKMTCloseAdapter
)
1360 get_display_driver()->pD3DKMTCloseAdapter( desc
);
1362 pthread_mutex_lock( &driver_lock
);
1363 LIST_FOR_EACH_ENTRY( adapter
, &d3dkmt_adapters
, struct d3dkmt_adapter
, entry
)
1365 if (adapter
->handle
== desc
->hAdapter
)
1367 list_remove( &adapter
->entry
);
1369 status
= STATUS_SUCCESS
;
1373 pthread_mutex_unlock( &driver_lock
);
1378 /******************************************************************************
1379 * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@)
1381 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME
*desc
)
1383 D3DKMT_OPENADAPTERFROMLUID desc_luid
;
1386 FIXME( "desc %p stub.\n", desc
);
1388 if (!desc
|| !desc
->pDeviceName
) return STATUS_INVALID_PARAMETER
;
1390 memset( &desc_luid
, 0, sizeof( desc_luid
));
1391 if ((status
= NtGdiDdDDIOpenAdapterFromLuid( &desc_luid
))) return status
;
1393 desc
->AdapterLuid
= desc_luid
.AdapterLuid
;
1394 desc
->hAdapter
= desc_luid
.hAdapter
;
1395 return STATUS_SUCCESS
;
1398 /******************************************************************************
1399 * NtGdiDdDDIOpenAdapterFromLuid (win32u.@)
1401 NTSTATUS WINAPI
NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID
*desc
)
1403 static D3DKMT_HANDLE handle_start
= 0;
1404 struct d3dkmt_adapter
*adapter
;
1406 if (!(adapter
= malloc( sizeof( *adapter
) ))) return STATUS_NO_MEMORY
;
1408 pthread_mutex_lock( &driver_lock
);
1409 desc
->hAdapter
= adapter
->handle
= ++handle_start
;
1410 list_add_tail( &d3dkmt_adapters
, &adapter
->entry
);
1411 pthread_mutex_unlock( &driver_lock
);
1413 if (get_display_driver()->pD3DKMTOpenAdapterFromLuid
)
1414 get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc
);
1416 return STATUS_SUCCESS
;
1419 /******************************************************************************
1420 * NtGdiDdDDICreateDevice (win32u.@)
1422 NTSTATUS WINAPI
NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE
*desc
)
1424 static D3DKMT_HANDLE handle_start
= 0;
1425 struct d3dkmt_adapter
*adapter
;
1426 struct d3dkmt_device
*device
;
1429 TRACE("(%p)\n", desc
);
1432 return STATUS_INVALID_PARAMETER
;
1434 pthread_mutex_lock( &driver_lock
);
1435 LIST_FOR_EACH_ENTRY( adapter
, &d3dkmt_adapters
, struct d3dkmt_adapter
, entry
)
1437 if (adapter
->handle
== desc
->hAdapter
)
1443 pthread_mutex_unlock( &driver_lock
);
1446 return STATUS_INVALID_PARAMETER
;
1448 if (desc
->Flags
.LegacyMode
|| desc
->Flags
.RequestVSync
|| desc
->Flags
.DisableGpuTimeout
)
1449 FIXME("Flags unsupported.\n");
1451 device
= calloc( 1, sizeof( *device
) );
1453 return STATUS_NO_MEMORY
;
1455 pthread_mutex_lock( &driver_lock
);
1456 device
->handle
= ++handle_start
;
1457 list_add_tail( &d3dkmt_devices
, &device
->entry
);
1458 pthread_mutex_unlock( &driver_lock
);
1460 desc
->hDevice
= device
->handle
;
1461 return STATUS_SUCCESS
;
1464 /******************************************************************************
1465 * NtGdiDdDDIDestroyDevice (win32u.@)
1467 NTSTATUS WINAPI
NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE
*desc
)
1469 NTSTATUS status
= STATUS_INVALID_PARAMETER
;
1470 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc
;
1471 struct d3dkmt_device
*device
;
1473 TRACE("(%p)\n", desc
);
1475 if (!desc
|| !desc
->hDevice
)
1476 return STATUS_INVALID_PARAMETER
;
1478 pthread_mutex_lock( &driver_lock
);
1479 LIST_FOR_EACH_ENTRY( device
, &d3dkmt_devices
, struct d3dkmt_device
, entry
)
1481 if (device
->handle
== desc
->hDevice
)
1483 memset( &set_owner_desc
, 0, sizeof(set_owner_desc
) );
1484 set_owner_desc
.hDevice
= desc
->hDevice
;
1485 NtGdiDdDDISetVidPnSourceOwner( &set_owner_desc
);
1486 list_remove( &device
->entry
);
1488 status
= STATUS_SUCCESS
;
1492 pthread_mutex_unlock( &driver_lock
);
1497 /******************************************************************************
1498 * NtGdiDdDDIQueryStatistics (win32u.@)
1500 NTSTATUS WINAPI
NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS
*stats
)
1502 FIXME("(%p): stub\n", stats
);
1503 return STATUS_SUCCESS
;
1506 /******************************************************************************
1507 * NtGdiDdDDIQueryVideoMemoryInfo (win32u.@)
1509 NTSTATUS WINAPI
NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO
*desc
)
1511 OBJECT_BASIC_INFORMATION info
;
1514 TRACE("(%p)\n", desc
);
1516 if (!desc
|| !desc
->hAdapter
||
1517 (desc
->MemorySegmentGroup
!= D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL
&&
1518 desc
->MemorySegmentGroup
!= D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL
))
1519 return STATUS_INVALID_PARAMETER
;
1521 /* FIXME: Wine currently doesn't support linked adapters */
1522 if (desc
->PhysicalAdapterIndex
> 0)
1523 return STATUS_INVALID_PARAMETER
;
1525 status
= NtQueryObject(desc
->hProcess
? desc
->hProcess
: GetCurrentProcess(),
1526 ObjectBasicInformation
, &info
, sizeof(info
), NULL
);
1527 if (status
!= STATUS_SUCCESS
)
1529 if (!(info
.GrantedAccess
& PROCESS_QUERY_INFORMATION
))
1530 return STATUS_ACCESS_DENIED
;
1532 if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo
)
1533 return STATUS_PROCEDURE_NOT_FOUND
;
1534 return get_display_driver()->pD3DKMTQueryVideoMemoryInfo(desc
);
1537 /******************************************************************************
1538 * NtGdiDdDDISetQueuedLimit (win32u.@)
1540 NTSTATUS WINAPI
NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT
*desc
)
1542 FIXME( "(%p): stub\n", desc
);
1543 return STATUS_NOT_IMPLEMENTED
;
1546 /******************************************************************************
1547 * NtGdiDdDDISetVidPnSourceOwner (win32u.@)
1549 NTSTATUS WINAPI
NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER
*desc
)
1551 TRACE("(%p)\n", desc
);
1553 if (!get_display_driver()->pD3DKMTSetVidPnSourceOwner
)
1554 return STATUS_PROCEDURE_NOT_FOUND
;
1556 if (!desc
|| !desc
->hDevice
|| (desc
->VidPnSourceCount
&& (!desc
->pType
|| !desc
->pVidPnSourceId
)))
1557 return STATUS_INVALID_PARAMETER
;
1559 /* Store the VidPN source ownership info in the graphics driver because
1560 * the graphics driver needs to change ownership sometimes. For example,
1561 * when a new window is moved to a VidPN source with an exclusive owner,
1562 * such an exclusive owner will be released before showing the new window */
1563 return get_display_driver()->pD3DKMTSetVidPnSourceOwner( desc
);
1566 /******************************************************************************
1567 * NtGdiDdDDICheckVidPnExclusiveOwnership (win32u.@)
1569 NTSTATUS WINAPI
NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP
*desc
)
1571 TRACE("(%p)\n", desc
);
1573 if (!get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership
)
1574 return STATUS_PROCEDURE_NOT_FOUND
;
1576 if (!desc
|| !desc
->hAdapter
)
1577 return STATUS_INVALID_PARAMETER
;
1579 return get_display_driver()->pD3DKMTCheckVidPnExclusiveOwnership( desc
);