2 * X11 graphics driver initialisation functions
4 * Copyright 1996 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(x11drv
);
38 Display
*gdi_display
; /* display to use for all GDI functions */
40 static int palette_size
;
42 static Pixmap stock_bitmap_pixmap
; /* phys bitmap for the default stock bitmap */
44 static pthread_once_t init_once
= PTHREAD_ONCE_INIT
;
46 static const struct user_driver_funcs x11drv_funcs
;
47 static const struct gdi_dc_funcs
*xrender_funcs
;
50 void init_recursive_mutex( pthread_mutex_t
*mutex
)
52 pthread_mutexattr_t attr
;
54 pthread_mutexattr_init( &attr
);
55 pthread_mutexattr_settype( &attr
, PTHREAD_MUTEX_RECURSIVE
);
56 pthread_mutex_init( mutex
, &attr
);
57 pthread_mutexattr_destroy( &attr
);
61 /**********************************************************************
64 * Perform initializations needed upon creation of the first device.
66 static void device_init(void)
68 /* Initialize XRender */
69 xrender_funcs
= X11DRV_XRender_Init();
72 X11DRV_Xcursor_Init();
74 palette_size
= X11DRV_PALETTE_Init();
76 stock_bitmap_pixmap
= XCreatePixmap( gdi_display
, root_window
, 1, 1, 1 );
80 static X11DRV_PDEVICE
*create_x11_physdev( Drawable drawable
)
82 X11DRV_PDEVICE
*physDev
;
84 pthread_once( &init_once
, device_init
);
86 if (!(physDev
= calloc( 1, sizeof(*physDev
) ))) return NULL
;
88 physDev
->drawable
= drawable
;
89 physDev
->gc
= XCreateGC( gdi_display
, drawable
, 0, NULL
);
90 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
91 XSetSubwindowMode( gdi_display
, physDev
->gc
, IncludeInferiors
);
92 XFlush( gdi_display
);
96 /**********************************************************************
99 static BOOL CDECL
X11DRV_CreateDC( PHYSDEV
*pdev
, LPCWSTR device
, LPCWSTR output
,
100 const DEVMODEW
* initData
)
102 X11DRV_PDEVICE
*physDev
= create_x11_physdev( root_window
);
104 if (!physDev
) return FALSE
;
106 physDev
->depth
= default_visual
.depth
;
107 physDev
->color_shifts
= &X11DRV_PALETTE_default_shifts
;
108 physDev
->dc_rect
= NtUserGetVirtualScreenRect();
109 OffsetRect( &physDev
->dc_rect
, -physDev
->dc_rect
.left
, -physDev
->dc_rect
.top
);
110 push_dc_driver( pdev
, &physDev
->dev
, &x11drv_funcs
.dc_funcs
);
111 if (xrender_funcs
&& !xrender_funcs
->pCreateDC( pdev
, device
, output
, initData
)) return FALSE
;
116 /**********************************************************************
117 * X11DRV_CreateCompatibleDC
119 static BOOL CDECL
X11DRV_CreateCompatibleDC( PHYSDEV orig
, PHYSDEV
*pdev
)
121 X11DRV_PDEVICE
*physDev
= create_x11_physdev( stock_bitmap_pixmap
);
123 if (!physDev
) return FALSE
;
126 SetRect( &physDev
->dc_rect
, 0, 0, 1, 1 );
127 push_dc_driver( pdev
, &physDev
->dev
, &x11drv_funcs
.dc_funcs
);
128 if (orig
) return TRUE
; /* we already went through Xrender if we have an orig device */
129 if (xrender_funcs
&& !xrender_funcs
->pCreateCompatibleDC( NULL
, pdev
)) return FALSE
;
134 /**********************************************************************
137 static BOOL CDECL
X11DRV_DeleteDC( PHYSDEV dev
)
139 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
141 XFreeGC( gdi_display
, physDev
->gc
);
147 void add_device_bounds( X11DRV_PDEVICE
*dev
, const RECT
*rect
)
151 if (!dev
->bounds
) return;
152 if (dev
->region
&& NtGdiGetRgnBox( dev
->region
, &rc
))
154 if (intersect_rect( &rc
, &rc
, rect
)) add_bounds_rect( dev
->bounds
, &rc
);
156 else add_bounds_rect( dev
->bounds
, rect
);
159 /***********************************************************************
160 * X11DRV_SetBoundsRect
162 static UINT CDECL
X11DRV_SetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
164 X11DRV_PDEVICE
*pdev
= get_x11drv_dev( dev
);
166 if (flags
& DCB_DISABLE
) pdev
->bounds
= NULL
;
167 else if (flags
& DCB_ENABLE
) pdev
->bounds
= rect
;
168 return DCB_RESET
; /* we don't have device-specific bounds */
172 /***********************************************************************
173 * GetDeviceCaps (X11DRV.@)
175 static INT CDECL
X11DRV_GetDeviceCaps( PHYSDEV dev
, INT cap
)
182 dev
= GET_NEXT_PHYSDEV( dev
, pGetDeviceCaps
);
183 return dev
->funcs
->pGetDeviceCaps( dev
, cap
);
188 /***********************************************************************
191 static HFONT CDECL
X11DRV_SelectFont( PHYSDEV dev
, HFONT hfont
, UINT
*aa_flags
)
193 if (default_visual
.depth
<= 8) *aa_flags
= GGO_BITMAP
; /* no anti-aliasing on <= 8bpp */
194 dev
= GET_NEXT_PHYSDEV( dev
, pSelectFont
);
195 return dev
->funcs
->pSelectFont( dev
, hfont
, aa_flags
);
198 /**********************************************************************
199 * ExtEscape (X11DRV.@)
201 static INT CDECL
X11DRV_ExtEscape( PHYSDEV dev
, INT escape
, INT in_count
, LPCVOID in_data
,
202 INT out_count
, LPVOID out_data
)
204 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
208 case QUERYESCSUPPORT
:
209 if (in_data
&& in_count
>= sizeof(DWORD
))
211 switch (*(const INT
*)in_data
)
220 if (in_data
&& in_count
>= sizeof(enum x11drv_escape_codes
))
222 switch(*(const enum x11drv_escape_codes
*)in_data
)
224 case X11DRV_SET_DRAWABLE
:
225 if (in_count
>= sizeof(struct x11drv_escape_set_drawable
))
227 const struct x11drv_escape_set_drawable
*data
= in_data
;
228 physDev
->dc_rect
= data
->dc_rect
;
229 physDev
->drawable
= data
->drawable
;
230 XFreeGC( gdi_display
, physDev
->gc
);
231 physDev
->gc
= XCreateGC( gdi_display
, physDev
->drawable
, 0, NULL
);
232 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
233 XSetSubwindowMode( gdi_display
, physDev
->gc
, data
->mode
);
234 TRACE( "SET_DRAWABLE hdc %p drawable %lx dc_rect %s\n",
235 dev
->hdc
, physDev
->drawable
, wine_dbgstr_rect(&physDev
->dc_rect
) );
239 case X11DRV_GET_DRAWABLE
:
240 if (out_count
>= sizeof(struct x11drv_escape_get_drawable
))
242 struct x11drv_escape_get_drawable
*data
= out_data
;
243 data
->drawable
= physDev
->drawable
;
247 case X11DRV_FLUSH_GL_DRAWABLE
:
248 if (in_count
>= sizeof(struct x11drv_escape_flush_gl_drawable
))
250 const struct x11drv_escape_flush_gl_drawable
*data
= in_data
;
251 RECT rect
= physDev
->dc_rect
;
253 OffsetRect( &rect
, -physDev
->dc_rect
.left
, -physDev
->dc_rect
.top
);
254 if (data
->flush
) XFlush( gdi_display
);
255 XSetFunction( gdi_display
, physDev
->gc
, GXcopy
);
256 XCopyArea( gdi_display
, data
->gl_drawable
, physDev
->drawable
, physDev
->gc
,
257 0, 0, rect
.right
, rect
.bottom
,
258 physDev
->dc_rect
.left
, physDev
->dc_rect
.top
);
259 add_device_bounds( physDev
, &rect
);
263 case X11DRV_START_EXPOSURES
:
264 XSetGraphicsExposures( gdi_display
, physDev
->gc
, True
);
265 physDev
->exposures
= 0;
267 case X11DRV_END_EXPOSURES
:
268 if (out_count
>= sizeof(HRGN
))
270 HRGN hrgn
= 0, tmp
= 0;
272 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
273 if (physDev
->exposures
)
279 XWindowEvent( gdi_display
, physDev
->drawable
, ~0, &event
);
280 if (event
.type
== NoExpose
) break;
281 if (event
.type
== GraphicsExpose
)
286 rect
.left
= event
.xgraphicsexpose
.x
- physDev
->dc_rect
.left
;
287 rect
.top
= event
.xgraphicsexpose
.y
- physDev
->dc_rect
.top
;
288 rect
.right
= rect
.left
+ event
.xgraphicsexpose
.width
;
289 rect
.bottom
= rect
.top
+ event
.xgraphicsexpose
.height
;
290 if (NtGdiGetDCDword( dev
->hdc
, NtGdiGetLayout
, &layout
) &&
291 (layout
& LAYOUT_RTL
))
292 mirror_rect( &physDev
->dc_rect
, &rect
);
294 TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect
),
295 event
.xgraphicsexpose
.count
);
297 if (!tmp
) tmp
= NtGdiCreateRectRgn( rect
.left
, rect
.top
,
298 rect
.right
, rect
.bottom
);
299 else NtGdiSetRectRgn( tmp
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
300 if (hrgn
) NtGdiCombineRgn( hrgn
, hrgn
, tmp
, RGN_OR
);
306 if (!event
.xgraphicsexpose
.count
) break;
310 ERR( "got unexpected event %d\n", event
.type
);
314 if (tmp
) NtGdiDeleteObjectApp( tmp
);
316 *(HRGN
*)out_data
= hrgn
;
329 /**********************************************************************
330 * X11DRV_wine_get_wgl_driver
332 static struct opengl_funcs
*X11DRV_wine_get_wgl_driver( UINT version
)
334 return get_glx_driver( version
);
337 /**********************************************************************
338 * X11DRV_wine_get_vulkan_driver
340 static const struct vulkan_funcs
*X11DRV_wine_get_vulkan_driver( UINT version
)
342 return get_vulkan_driver( version
);
346 static const struct user_driver_funcs x11drv_funcs
=
348 .dc_funcs
.pArc
= X11DRV_Arc
,
349 .dc_funcs
.pChord
= X11DRV_Chord
,
350 .dc_funcs
.pCreateCompatibleDC
= X11DRV_CreateCompatibleDC
,
351 .dc_funcs
.pCreateDC
= X11DRV_CreateDC
,
352 .dc_funcs
.pDeleteDC
= X11DRV_DeleteDC
,
353 .dc_funcs
.pEllipse
= X11DRV_Ellipse
,
354 .dc_funcs
.pExtEscape
= X11DRV_ExtEscape
,
355 .dc_funcs
.pExtFloodFill
= X11DRV_ExtFloodFill
,
356 .dc_funcs
.pFillPath
= X11DRV_FillPath
,
357 .dc_funcs
.pGetDeviceCaps
= X11DRV_GetDeviceCaps
,
358 .dc_funcs
.pGetDeviceGammaRamp
= X11DRV_GetDeviceGammaRamp
,
359 .dc_funcs
.pGetICMProfile
= X11DRV_GetICMProfile
,
360 .dc_funcs
.pGetImage
= X11DRV_GetImage
,
361 .dc_funcs
.pGetNearestColor
= X11DRV_GetNearestColor
,
362 .dc_funcs
.pGetSystemPaletteEntries
= X11DRV_GetSystemPaletteEntries
,
363 .dc_funcs
.pGradientFill
= X11DRV_GradientFill
,
364 .dc_funcs
.pLineTo
= X11DRV_LineTo
,
365 .dc_funcs
.pPaintRgn
= X11DRV_PaintRgn
,
366 .dc_funcs
.pPatBlt
= X11DRV_PatBlt
,
367 .dc_funcs
.pPie
= X11DRV_Pie
,
368 .dc_funcs
.pPolyPolygon
= X11DRV_PolyPolygon
,
369 .dc_funcs
.pPolyPolyline
= X11DRV_PolyPolyline
,
370 .dc_funcs
.pPutImage
= X11DRV_PutImage
,
371 .dc_funcs
.pRealizeDefaultPalette
= X11DRV_RealizeDefaultPalette
,
372 .dc_funcs
.pRealizePalette
= X11DRV_RealizePalette
,
373 .dc_funcs
.pRectangle
= X11DRV_Rectangle
,
374 .dc_funcs
.pRoundRect
= X11DRV_RoundRect
,
375 .dc_funcs
.pSelectBrush
= X11DRV_SelectBrush
,
376 .dc_funcs
.pSelectFont
= X11DRV_SelectFont
,
377 .dc_funcs
.pSelectPen
= X11DRV_SelectPen
,
378 .dc_funcs
.pSetBoundsRect
= X11DRV_SetBoundsRect
,
379 .dc_funcs
.pSetDCBrushColor
= X11DRV_SetDCBrushColor
,
380 .dc_funcs
.pSetDCPenColor
= X11DRV_SetDCPenColor
,
381 .dc_funcs
.pSetDeviceClipping
= X11DRV_SetDeviceClipping
,
382 .dc_funcs
.pSetDeviceGammaRamp
= X11DRV_SetDeviceGammaRamp
,
383 .dc_funcs
.pSetPixel
= X11DRV_SetPixel
,
384 .dc_funcs
.pStretchBlt
= X11DRV_StretchBlt
,
385 .dc_funcs
.pStrokeAndFillPath
= X11DRV_StrokeAndFillPath
,
386 .dc_funcs
.pStrokePath
= X11DRV_StrokePath
,
387 .dc_funcs
.pUnrealizePalette
= X11DRV_UnrealizePalette
,
388 .dc_funcs
.pD3DKMTCheckVidPnExclusiveOwnership
= X11DRV_D3DKMTCheckVidPnExclusiveOwnership
,
389 .dc_funcs
.pD3DKMTCloseAdapter
= X11DRV_D3DKMTCloseAdapter
,
390 .dc_funcs
.pD3DKMTOpenAdapterFromLuid
= X11DRV_D3DKMTOpenAdapterFromLuid
,
391 .dc_funcs
.pD3DKMTQueryVideoMemoryInfo
= X11DRV_D3DKMTQueryVideoMemoryInfo
,
392 .dc_funcs
.pD3DKMTSetVidPnSourceOwner
= X11DRV_D3DKMTSetVidPnSourceOwner
,
393 .dc_funcs
.priority
= GDI_PRIORITY_GRAPHICS_DRV
,
395 .pActivateKeyboardLayout
= X11DRV_ActivateKeyboardLayout
,
396 .pBeep
= X11DRV_Beep
,
397 .pGetKeyNameText
= X11DRV_GetKeyNameText
,
398 .pMapVirtualKeyEx
= X11DRV_MapVirtualKeyEx
,
399 .pToUnicodeEx
= X11DRV_ToUnicodeEx
,
400 .pVkKeyScanEx
= X11DRV_VkKeyScanEx
,
401 .pDestroyCursorIcon
= X11DRV_DestroyCursorIcon
,
402 .pSetCursor
= X11DRV_SetCursor
,
403 .pGetCursorPos
= X11DRV_GetCursorPos
,
404 .pSetCursorPos
= X11DRV_SetCursorPos
,
405 .pClipCursor
= X11DRV_ClipCursor
,
406 .pChangeDisplaySettings
= X11DRV_ChangeDisplaySettings
,
407 .pGetCurrentDisplaySettings
= X11DRV_GetCurrentDisplaySettings
,
408 .pGetDisplayDepth
= X11DRV_GetDisplayDepth
,
409 .pUpdateDisplayDevices
= X11DRV_UpdateDisplayDevices
,
410 .pCreateDesktopWindow
= X11DRV_CreateDesktopWindow
,
411 .pCreateWindow
= X11DRV_CreateWindow
,
412 .pDesktopWindowProc
= X11DRV_DesktopWindowProc
,
413 .pDestroyWindow
= X11DRV_DestroyWindow
,
414 .pFlashWindowEx
= X11DRV_FlashWindowEx
,
415 .pGetDC
= X11DRV_GetDC
,
416 .pProcessEvents
= X11DRV_ProcessEvents
,
417 .pReleaseDC
= X11DRV_ReleaseDC
,
418 .pScrollDC
= X11DRV_ScrollDC
,
419 .pSetCapture
= X11DRV_SetCapture
,
420 .pSetFocus
= X11DRV_SetFocus
,
421 .pSetLayeredWindowAttributes
= X11DRV_SetLayeredWindowAttributes
,
422 .pSetParent
= X11DRV_SetParent
,
423 .pSetWindowIcon
= X11DRV_SetWindowIcon
,
424 .pSetWindowRgn
= X11DRV_SetWindowRgn
,
425 .pSetWindowStyle
= X11DRV_SetWindowStyle
,
426 .pSetWindowText
= X11DRV_SetWindowText
,
427 .pShowWindow
= X11DRV_ShowWindow
,
428 .pSysCommand
= X11DRV_SysCommand
,
429 .pClipboardWindowProc
= X11DRV_ClipboardWindowProc
,
430 .pUpdateClipboard
= X11DRV_UpdateClipboard
,
431 .pUpdateLayeredWindow
= X11DRV_UpdateLayeredWindow
,
432 .pWindowMessage
= X11DRV_WindowMessage
,
433 .pWindowPosChanging
= X11DRV_WindowPosChanging
,
434 .pWindowPosChanged
= X11DRV_WindowPosChanged
,
435 .pSystemParametersInfo
= X11DRV_SystemParametersInfo
,
436 .pwine_get_vulkan_driver
= X11DRV_wine_get_vulkan_driver
,
437 .pwine_get_wgl_driver
= X11DRV_wine_get_wgl_driver
,
438 .pThreadDetach
= X11DRV_ThreadDetach
,
442 void init_user_driver(void)
444 __wine_set_user_driver( &x11drv_funcs
, WINE_GDI_DRIVER_VERSION
);