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
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(x11drv
);
34 Display
*gdi_display
; /* display to use for all GDI functions */
36 static int palette_size
;
38 static Pixmap stock_bitmap_pixmap
; /* phys bitmap for the default stock bitmap */
40 static INIT_ONCE init_once
= INIT_ONCE_STATIC_INIT
;
42 static const struct user_driver_funcs x11drv_funcs
;
43 static const struct gdi_dc_funcs
*xrender_funcs
;
45 /**********************************************************************
48 * Perform initializations needed upon creation of the first device.
50 static BOOL WINAPI
device_init( INIT_ONCE
*once
, void *param
, void **context
)
52 /* Initialize XRender */
53 xrender_funcs
= X11DRV_XRender_Init();
56 X11DRV_Xcursor_Init();
58 palette_size
= X11DRV_PALETTE_Init();
60 stock_bitmap_pixmap
= XCreatePixmap( gdi_display
, root_window
, 1, 1, 1 );
66 static X11DRV_PDEVICE
*create_x11_physdev( Drawable drawable
)
68 X11DRV_PDEVICE
*physDev
;
70 InitOnceExecuteOnce( &init_once
, device_init
, NULL
, NULL
);
72 if (!(physDev
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*physDev
) ))) return NULL
;
74 physDev
->drawable
= drawable
;
75 physDev
->gc
= XCreateGC( gdi_display
, drawable
, 0, NULL
);
76 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
77 XSetSubwindowMode( gdi_display
, physDev
->gc
, IncludeInferiors
);
78 XFlush( gdi_display
);
82 /**********************************************************************
85 static BOOL CDECL
X11DRV_CreateDC( PHYSDEV
*pdev
, LPCWSTR device
, LPCWSTR output
,
86 const DEVMODEW
* initData
)
88 X11DRV_PDEVICE
*physDev
= create_x11_physdev( root_window
);
90 if (!physDev
) return FALSE
;
92 physDev
->depth
= default_visual
.depth
;
93 physDev
->color_shifts
= &X11DRV_PALETTE_default_shifts
;
94 physDev
->dc_rect
= get_virtual_screen_rect();
95 OffsetRect( &physDev
->dc_rect
, -physDev
->dc_rect
.left
, -physDev
->dc_rect
.top
);
96 push_dc_driver( pdev
, &physDev
->dev
, &x11drv_funcs
.dc_funcs
);
97 if (xrender_funcs
&& !xrender_funcs
->pCreateDC( pdev
, device
, output
, initData
)) return FALSE
;
102 /**********************************************************************
103 * X11DRV_CreateCompatibleDC
105 static BOOL CDECL
X11DRV_CreateCompatibleDC( PHYSDEV orig
, PHYSDEV
*pdev
)
107 X11DRV_PDEVICE
*physDev
= create_x11_physdev( stock_bitmap_pixmap
);
109 if (!physDev
) return FALSE
;
112 SetRect( &physDev
->dc_rect
, 0, 0, 1, 1 );
113 push_dc_driver( pdev
, &physDev
->dev
, &x11drv_funcs
.dc_funcs
);
114 if (orig
) return TRUE
; /* we already went through Xrender if we have an orig device */
115 if (xrender_funcs
&& !xrender_funcs
->pCreateCompatibleDC( NULL
, pdev
)) return FALSE
;
120 /**********************************************************************
123 static BOOL CDECL
X11DRV_DeleteDC( PHYSDEV dev
)
125 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
127 XFreeGC( gdi_display
, physDev
->gc
);
128 HeapFree( GetProcessHeap(), 0, physDev
);
133 void add_device_bounds( X11DRV_PDEVICE
*dev
, const RECT
*rect
)
137 if (!dev
->bounds
) return;
138 if (dev
->region
&& GetRgnBox( dev
->region
, &rc
))
140 if (IntersectRect( &rc
, &rc
, rect
)) add_bounds_rect( dev
->bounds
, &rc
);
142 else add_bounds_rect( dev
->bounds
, rect
);
145 /***********************************************************************
146 * X11DRV_SetBoundsRect
148 static UINT CDECL
X11DRV_SetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
150 X11DRV_PDEVICE
*pdev
= get_x11drv_dev( dev
);
152 if (flags
& DCB_DISABLE
) pdev
->bounds
= NULL
;
153 else if (flags
& DCB_ENABLE
) pdev
->bounds
= rect
;
154 return DCB_RESET
; /* we don't have device-specific bounds */
158 /***********************************************************************
159 * GetDeviceCaps (X11DRV.@)
161 static INT CDECL
X11DRV_GetDeviceCaps( PHYSDEV dev
, INT cap
)
168 dev
= GET_NEXT_PHYSDEV( dev
, pGetDeviceCaps
);
169 return dev
->funcs
->pGetDeviceCaps( dev
, cap
);
174 /***********************************************************************
177 static HFONT CDECL
X11DRV_SelectFont( PHYSDEV dev
, HFONT hfont
, UINT
*aa_flags
)
179 if (default_visual
.depth
<= 8) *aa_flags
= GGO_BITMAP
; /* no anti-aliasing on <= 8bpp */
180 dev
= GET_NEXT_PHYSDEV( dev
, pSelectFont
);
181 return dev
->funcs
->pSelectFont( dev
, hfont
, aa_flags
);
184 /**********************************************************************
185 * ExtEscape (X11DRV.@)
187 static INT CDECL
X11DRV_ExtEscape( PHYSDEV dev
, INT escape
, INT in_count
, LPCVOID in_data
,
188 INT out_count
, LPVOID out_data
)
190 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
194 case QUERYESCSUPPORT
:
195 if (in_data
&& in_count
>= sizeof(DWORD
))
197 switch (*(const INT
*)in_data
)
206 if (in_data
&& in_count
>= sizeof(enum x11drv_escape_codes
))
208 switch(*(const enum x11drv_escape_codes
*)in_data
)
210 case X11DRV_SET_DRAWABLE
:
211 if (in_count
>= sizeof(struct x11drv_escape_set_drawable
))
213 const struct x11drv_escape_set_drawable
*data
= in_data
;
214 physDev
->dc_rect
= data
->dc_rect
;
215 physDev
->drawable
= data
->drawable
;
216 XFreeGC( gdi_display
, physDev
->gc
);
217 physDev
->gc
= XCreateGC( gdi_display
, physDev
->drawable
, 0, NULL
);
218 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
219 XSetSubwindowMode( gdi_display
, physDev
->gc
, data
->mode
);
220 TRACE( "SET_DRAWABLE hdc %p drawable %lx dc_rect %s\n",
221 dev
->hdc
, physDev
->drawable
, wine_dbgstr_rect(&physDev
->dc_rect
) );
225 case X11DRV_GET_DRAWABLE
:
226 if (out_count
>= sizeof(struct x11drv_escape_get_drawable
))
228 struct x11drv_escape_get_drawable
*data
= out_data
;
229 data
->drawable
= physDev
->drawable
;
233 case X11DRV_FLUSH_GL_DRAWABLE
:
234 if (in_count
>= sizeof(struct x11drv_escape_flush_gl_drawable
))
236 const struct x11drv_escape_flush_gl_drawable
*data
= in_data
;
237 RECT rect
= physDev
->dc_rect
;
239 OffsetRect( &rect
, -physDev
->dc_rect
.left
, -physDev
->dc_rect
.top
);
240 if (data
->flush
) XFlush( gdi_display
);
241 XSetFunction( gdi_display
, physDev
->gc
, GXcopy
);
242 XCopyArea( gdi_display
, data
->gl_drawable
, physDev
->drawable
, physDev
->gc
,
243 0, 0, rect
.right
, rect
.bottom
,
244 physDev
->dc_rect
.left
, physDev
->dc_rect
.top
);
245 add_device_bounds( physDev
, &rect
);
249 case X11DRV_START_EXPOSURES
:
250 XSetGraphicsExposures( gdi_display
, physDev
->gc
, True
);
251 physDev
->exposures
= 0;
253 case X11DRV_END_EXPOSURES
:
254 if (out_count
>= sizeof(HRGN
))
256 HRGN hrgn
= 0, tmp
= 0;
258 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
259 if (physDev
->exposures
)
265 XWindowEvent( gdi_display
, physDev
->drawable
, ~0, &event
);
266 if (event
.type
== NoExpose
) break;
267 if (event
.type
== GraphicsExpose
)
271 rect
.left
= event
.xgraphicsexpose
.x
- physDev
->dc_rect
.left
;
272 rect
.top
= event
.xgraphicsexpose
.y
- physDev
->dc_rect
.top
;
273 rect
.right
= rect
.left
+ event
.xgraphicsexpose
.width
;
274 rect
.bottom
= rect
.top
+ event
.xgraphicsexpose
.height
;
275 if (GetLayout( dev
->hdc
) & LAYOUT_RTL
)
276 mirror_rect( &physDev
->dc_rect
, &rect
);
278 TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect
),
279 event
.xgraphicsexpose
.count
);
281 if (!tmp
) tmp
= CreateRectRgnIndirect( &rect
);
282 else SetRectRgn( tmp
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
283 if (hrgn
) CombineRgn( hrgn
, hrgn
, tmp
, RGN_OR
);
289 if (!event
.xgraphicsexpose
.count
) break;
293 ERR( "got unexpected event %d\n", event
.type
);
297 if (tmp
) DeleteObject( tmp
);
299 *(HRGN
*)out_data
= hrgn
;
312 /**********************************************************************
313 * X11DRV_wine_get_wgl_driver
315 static struct opengl_funcs
* CDECL
X11DRV_wine_get_wgl_driver( UINT version
)
317 return get_glx_driver( version
);
320 /**********************************************************************
321 * X11DRV_wine_get_vulkan_driver
323 static const struct vulkan_funcs
* CDECL
X11DRV_wine_get_vulkan_driver( UINT version
)
325 return get_vulkan_driver( version
);
329 static const struct user_driver_funcs x11drv_funcs
=
331 .dc_funcs
.pArc
= X11DRV_Arc
,
332 .dc_funcs
.pChord
= X11DRV_Chord
,
333 .dc_funcs
.pCreateCompatibleDC
= X11DRV_CreateCompatibleDC
,
334 .dc_funcs
.pCreateDC
= X11DRV_CreateDC
,
335 .dc_funcs
.pDeleteDC
= X11DRV_DeleteDC
,
336 .dc_funcs
.pEllipse
= X11DRV_Ellipse
,
337 .dc_funcs
.pExtEscape
= X11DRV_ExtEscape
,
338 .dc_funcs
.pExtFloodFill
= X11DRV_ExtFloodFill
,
339 .dc_funcs
.pFillPath
= X11DRV_FillPath
,
340 .dc_funcs
.pGetDeviceCaps
= X11DRV_GetDeviceCaps
,
341 .dc_funcs
.pGetDeviceGammaRamp
= X11DRV_GetDeviceGammaRamp
,
342 .dc_funcs
.pGetICMProfile
= X11DRV_GetICMProfile
,
343 .dc_funcs
.pGetImage
= X11DRV_GetImage
,
344 .dc_funcs
.pGetNearestColor
= X11DRV_GetNearestColor
,
345 .dc_funcs
.pGetSystemPaletteEntries
= X11DRV_GetSystemPaletteEntries
,
346 .dc_funcs
.pGradientFill
= X11DRV_GradientFill
,
347 .dc_funcs
.pLineTo
= X11DRV_LineTo
,
348 .dc_funcs
.pPaintRgn
= X11DRV_PaintRgn
,
349 .dc_funcs
.pPatBlt
= X11DRV_PatBlt
,
350 .dc_funcs
.pPie
= X11DRV_Pie
,
351 .dc_funcs
.pPolyPolygon
= X11DRV_PolyPolygon
,
352 .dc_funcs
.pPolyPolyline
= X11DRV_PolyPolyline
,
353 .dc_funcs
.pPutImage
= X11DRV_PutImage
,
354 .dc_funcs
.pRealizeDefaultPalette
= X11DRV_RealizeDefaultPalette
,
355 .dc_funcs
.pRealizePalette
= X11DRV_RealizePalette
,
356 .dc_funcs
.pRectangle
= X11DRV_Rectangle
,
357 .dc_funcs
.pRoundRect
= X11DRV_RoundRect
,
358 .dc_funcs
.pSelectBrush
= X11DRV_SelectBrush
,
359 .dc_funcs
.pSelectFont
= X11DRV_SelectFont
,
360 .dc_funcs
.pSelectPen
= X11DRV_SelectPen
,
361 .dc_funcs
.pSetBoundsRect
= X11DRV_SetBoundsRect
,
362 .dc_funcs
.pSetDCBrushColor
= X11DRV_SetDCBrushColor
,
363 .dc_funcs
.pSetDCPenColor
= X11DRV_SetDCPenColor
,
364 .dc_funcs
.pSetDeviceClipping
= X11DRV_SetDeviceClipping
,
365 .dc_funcs
.pSetDeviceGammaRamp
= X11DRV_SetDeviceGammaRamp
,
366 .dc_funcs
.pSetPixel
= X11DRV_SetPixel
,
367 .dc_funcs
.pStretchBlt
= X11DRV_StretchBlt
,
368 .dc_funcs
.pStrokeAndFillPath
= X11DRV_StrokeAndFillPath
,
369 .dc_funcs
.pStrokePath
= X11DRV_StrokePath
,
370 .dc_funcs
.pUnrealizePalette
= X11DRV_UnrealizePalette
,
371 .dc_funcs
.pD3DKMTCheckVidPnExclusiveOwnership
= X11DRV_D3DKMTCheckVidPnExclusiveOwnership
,
372 .dc_funcs
.pD3DKMTSetVidPnSourceOwner
= X11DRV_D3DKMTSetVidPnSourceOwner
,
373 .dc_funcs
.priority
= GDI_PRIORITY_GRAPHICS_DRV
,
375 .pActivateKeyboardLayout
= X11DRV_ActivateKeyboardLayout
,
376 .pBeep
= X11DRV_Beep
,
377 .pGetKeyNameText
= X11DRV_GetKeyNameText
,
378 .pMapVirtualKeyEx
= X11DRV_MapVirtualKeyEx
,
379 .pToUnicodeEx
= X11DRV_ToUnicodeEx
,
380 .pVkKeyScanEx
= X11DRV_VkKeyScanEx
,
381 .pDestroyCursorIcon
= X11DRV_DestroyCursorIcon
,
382 .pSetCursor
= X11DRV_SetCursor
,
383 .pGetCursorPos
= X11DRV_GetCursorPos
,
384 .pSetCursorPos
= X11DRV_SetCursorPos
,
385 .pClipCursor
= X11DRV_ClipCursor
,
386 .pChangeDisplaySettingsEx
= X11DRV_ChangeDisplaySettingsEx
,
387 .pEnumDisplaySettingsEx
= X11DRV_EnumDisplaySettingsEx
,
388 .pUpdateDisplayDevices
= X11DRV_UpdateDisplayDevices
,
389 .pCreateDesktopWindow
= X11DRV_CreateDesktopWindow
,
390 .pCreateWindow
= X11DRV_CreateWindow
,
391 .pDestroyWindow
= X11DRV_DestroyWindow
,
392 .pFlashWindowEx
= X11DRV_FlashWindowEx
,
393 .pGetDC
= X11DRV_GetDC
,
394 .pMsgWaitForMultipleObjectsEx
= X11DRV_MsgWaitForMultipleObjectsEx
,
395 .pReleaseDC
= X11DRV_ReleaseDC
,
396 .pScrollDC
= X11DRV_ScrollDC
,
397 .pSetCapture
= X11DRV_SetCapture
,
398 .pSetFocus
= X11DRV_SetFocus
,
399 .pSetLayeredWindowAttributes
= X11DRV_SetLayeredWindowAttributes
,
400 .pSetParent
= X11DRV_SetParent
,
401 .pSetWindowIcon
= X11DRV_SetWindowIcon
,
402 .pSetWindowRgn
= X11DRV_SetWindowRgn
,
403 .pSetWindowStyle
= X11DRV_SetWindowStyle
,
404 .pSetWindowText
= X11DRV_SetWindowText
,
405 .pShowWindow
= X11DRV_ShowWindow
,
406 .pSysCommand
= X11DRV_SysCommand
,
407 .pUpdateClipboard
= X11DRV_UpdateClipboard
,
408 .pUpdateLayeredWindow
= X11DRV_UpdateLayeredWindow
,
409 .pWindowMessage
= X11DRV_WindowMessage
,
410 .pWindowPosChanging
= X11DRV_WindowPosChanging
,
411 .pWindowPosChanged
= X11DRV_WindowPosChanged
,
412 .pSystemParametersInfo
= X11DRV_SystemParametersInfo
,
413 .pwine_get_vulkan_driver
= X11DRV_wine_get_vulkan_driver
,
414 .pwine_get_wgl_driver
= X11DRV_wine_get_wgl_driver
,
415 .pThreadDetach
= X11DRV_ThreadDetach
,
419 void init_user_driver(void)
421 __wine_set_user_driver( &x11drv_funcs
, WINE_GDI_DRIVER_VERSION
);