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
X11DRV_CreateDC( PHYSDEV
*pdev
, LPCWSTR device
, LPCWSTR output
, const DEVMODEW
* initData
)
101 X11DRV_PDEVICE
*physDev
= create_x11_physdev( root_window
);
103 if (!physDev
) return FALSE
;
105 physDev
->depth
= default_visual
.depth
;
106 physDev
->color_shifts
= &X11DRV_PALETTE_default_shifts
;
107 physDev
->dc_rect
= NtUserGetVirtualScreenRect();
108 OffsetRect( &physDev
->dc_rect
, -physDev
->dc_rect
.left
, -physDev
->dc_rect
.top
);
109 push_dc_driver( pdev
, &physDev
->dev
, &x11drv_funcs
.dc_funcs
);
110 if (xrender_funcs
&& !xrender_funcs
->pCreateDC( pdev
, device
, output
, initData
)) return FALSE
;
115 /**********************************************************************
116 * X11DRV_CreateCompatibleDC
118 static BOOL
X11DRV_CreateCompatibleDC( PHYSDEV orig
, PHYSDEV
*pdev
)
120 X11DRV_PDEVICE
*physDev
= create_x11_physdev( stock_bitmap_pixmap
);
122 if (!physDev
) return FALSE
;
125 SetRect( &physDev
->dc_rect
, 0, 0, 1, 1 );
126 push_dc_driver( pdev
, &physDev
->dev
, &x11drv_funcs
.dc_funcs
);
127 if (orig
) return TRUE
; /* we already went through Xrender if we have an orig device */
128 if (xrender_funcs
&& !xrender_funcs
->pCreateCompatibleDC( NULL
, pdev
)) return FALSE
;
133 /**********************************************************************
136 static BOOL
X11DRV_DeleteDC( PHYSDEV dev
)
138 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
140 XFreeGC( gdi_display
, physDev
->gc
);
146 void add_device_bounds( X11DRV_PDEVICE
*dev
, const RECT
*rect
)
150 if (!dev
->bounds
) return;
151 if (dev
->region
&& NtGdiGetRgnBox( dev
->region
, &rc
))
153 if (intersect_rect( &rc
, &rc
, rect
)) add_bounds_rect( dev
->bounds
, &rc
);
155 else add_bounds_rect( dev
->bounds
, rect
);
158 /***********************************************************************
159 * X11DRV_SetBoundsRect
161 static UINT
X11DRV_SetBoundsRect( PHYSDEV dev
, RECT
*rect
, UINT flags
)
163 X11DRV_PDEVICE
*pdev
= get_x11drv_dev( dev
);
165 if (flags
& DCB_DISABLE
) pdev
->bounds
= NULL
;
166 else if (flags
& DCB_ENABLE
) pdev
->bounds
= rect
;
167 return DCB_RESET
; /* we don't have device-specific bounds */
171 /***********************************************************************
172 * GetDeviceCaps (X11DRV.@)
174 static INT
X11DRV_GetDeviceCaps( PHYSDEV dev
, INT cap
)
181 dev
= GET_NEXT_PHYSDEV( dev
, pGetDeviceCaps
);
182 return dev
->funcs
->pGetDeviceCaps( dev
, cap
);
187 /***********************************************************************
190 static HFONT
X11DRV_SelectFont( PHYSDEV dev
, HFONT hfont
, UINT
*aa_flags
)
192 if (default_visual
.depth
<= 8) *aa_flags
= GGO_BITMAP
; /* no anti-aliasing on <= 8bpp */
193 dev
= GET_NEXT_PHYSDEV( dev
, pSelectFont
);
194 return dev
->funcs
->pSelectFont( dev
, hfont
, aa_flags
);
197 /**********************************************************************
198 * ExtEscape (X11DRV.@)
200 static INT
X11DRV_ExtEscape( PHYSDEV dev
, INT escape
, INT in_count
, LPCVOID in_data
,
201 INT out_count
, LPVOID out_data
)
203 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
207 case QUERYESCSUPPORT
:
208 if (in_data
&& in_count
>= sizeof(DWORD
))
210 switch (*(const INT
*)in_data
)
219 if (in_data
&& in_count
>= sizeof(enum x11drv_escape_codes
))
221 switch(*(const enum x11drv_escape_codes
*)in_data
)
223 case X11DRV_SET_DRAWABLE
:
224 if (in_count
>= sizeof(struct x11drv_escape_set_drawable
))
226 const struct x11drv_escape_set_drawable
*data
= in_data
;
227 physDev
->dc_rect
= data
->dc_rect
;
228 physDev
->drawable
= data
->drawable
;
229 XFreeGC( gdi_display
, physDev
->gc
);
230 physDev
->gc
= XCreateGC( gdi_display
, physDev
->drawable
, 0, NULL
);
231 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
232 XSetSubwindowMode( gdi_display
, physDev
->gc
, data
->mode
);
233 TRACE( "SET_DRAWABLE hdc %p drawable %lx dc_rect %s\n",
234 dev
->hdc
, physDev
->drawable
, wine_dbgstr_rect(&physDev
->dc_rect
) );
238 case X11DRV_GET_DRAWABLE
:
239 if (out_count
>= sizeof(struct x11drv_escape_get_drawable
))
241 struct x11drv_escape_get_drawable
*data
= out_data
;
242 data
->drawable
= physDev
->drawable
;
246 case X11DRV_FLUSH_GL_DRAWABLE
:
247 if (in_count
>= sizeof(struct x11drv_escape_flush_gl_drawable
))
249 const struct x11drv_escape_flush_gl_drawable
*data
= in_data
;
250 RECT rect
= physDev
->dc_rect
;
252 OffsetRect( &rect
, -physDev
->dc_rect
.left
, -physDev
->dc_rect
.top
);
253 if (data
->flush
) XFlush( gdi_display
);
254 XSetFunction( gdi_display
, physDev
->gc
, GXcopy
);
255 XCopyArea( gdi_display
, data
->gl_drawable
, physDev
->drawable
, physDev
->gc
,
256 0, 0, rect
.right
, rect
.bottom
,
257 physDev
->dc_rect
.left
, physDev
->dc_rect
.top
);
258 add_device_bounds( physDev
, &rect
);
262 case X11DRV_START_EXPOSURES
:
263 XSetGraphicsExposures( gdi_display
, physDev
->gc
, True
);
264 physDev
->exposures
= 0;
266 case X11DRV_END_EXPOSURES
:
267 if (out_count
>= sizeof(HRGN
))
269 HRGN hrgn
= 0, tmp
= 0;
271 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
272 if (physDev
->exposures
)
278 XWindowEvent( gdi_display
, physDev
->drawable
, ~0, &event
);
279 if (event
.type
== NoExpose
) break;
280 if (event
.type
== GraphicsExpose
)
285 rect
.left
= event
.xgraphicsexpose
.x
- physDev
->dc_rect
.left
;
286 rect
.top
= event
.xgraphicsexpose
.y
- physDev
->dc_rect
.top
;
287 rect
.right
= rect
.left
+ event
.xgraphicsexpose
.width
;
288 rect
.bottom
= rect
.top
+ event
.xgraphicsexpose
.height
;
289 if (NtGdiGetDCDword( dev
->hdc
, NtGdiGetLayout
, &layout
) &&
290 (layout
& LAYOUT_RTL
))
291 mirror_rect( &physDev
->dc_rect
, &rect
);
293 TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect
),
294 event
.xgraphicsexpose
.count
);
296 if (!tmp
) tmp
= NtGdiCreateRectRgn( rect
.left
, rect
.top
,
297 rect
.right
, rect
.bottom
);
298 else NtGdiSetRectRgn( tmp
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
299 if (hrgn
) NtGdiCombineRgn( hrgn
, hrgn
, tmp
, RGN_OR
);
305 if (!event
.xgraphicsexpose
.count
) break;
309 ERR( "got unexpected event %d\n", event
.type
);
313 if (tmp
) NtGdiDeleteObjectApp( tmp
);
315 *(HRGN
*)out_data
= hrgn
;
328 /**********************************************************************
329 * X11DRV_wine_get_wgl_driver
331 static struct opengl_funcs
*X11DRV_wine_get_wgl_driver( UINT version
)
333 return get_glx_driver( version
);
337 static const struct user_driver_funcs x11drv_funcs
=
339 .dc_funcs
.pArc
= X11DRV_Arc
,
340 .dc_funcs
.pChord
= X11DRV_Chord
,
341 .dc_funcs
.pCreateCompatibleDC
= X11DRV_CreateCompatibleDC
,
342 .dc_funcs
.pCreateDC
= X11DRV_CreateDC
,
343 .dc_funcs
.pDeleteDC
= X11DRV_DeleteDC
,
344 .dc_funcs
.pEllipse
= X11DRV_Ellipse
,
345 .dc_funcs
.pExtEscape
= X11DRV_ExtEscape
,
346 .dc_funcs
.pExtFloodFill
= X11DRV_ExtFloodFill
,
347 .dc_funcs
.pFillPath
= X11DRV_FillPath
,
348 .dc_funcs
.pGetDeviceCaps
= X11DRV_GetDeviceCaps
,
349 .dc_funcs
.pGetDeviceGammaRamp
= X11DRV_GetDeviceGammaRamp
,
350 .dc_funcs
.pGetICMProfile
= X11DRV_GetICMProfile
,
351 .dc_funcs
.pGetImage
= X11DRV_GetImage
,
352 .dc_funcs
.pGetNearestColor
= X11DRV_GetNearestColor
,
353 .dc_funcs
.pGetSystemPaletteEntries
= X11DRV_GetSystemPaletteEntries
,
354 .dc_funcs
.pGradientFill
= X11DRV_GradientFill
,
355 .dc_funcs
.pLineTo
= X11DRV_LineTo
,
356 .dc_funcs
.pPaintRgn
= X11DRV_PaintRgn
,
357 .dc_funcs
.pPatBlt
= X11DRV_PatBlt
,
358 .dc_funcs
.pPie
= X11DRV_Pie
,
359 .dc_funcs
.pPolyPolygon
= X11DRV_PolyPolygon
,
360 .dc_funcs
.pPolyPolyline
= X11DRV_PolyPolyline
,
361 .dc_funcs
.pPutImage
= X11DRV_PutImage
,
362 .dc_funcs
.pRealizeDefaultPalette
= X11DRV_RealizeDefaultPalette
,
363 .dc_funcs
.pRealizePalette
= X11DRV_RealizePalette
,
364 .dc_funcs
.pRectangle
= X11DRV_Rectangle
,
365 .dc_funcs
.pRoundRect
= X11DRV_RoundRect
,
366 .dc_funcs
.pSelectBrush
= X11DRV_SelectBrush
,
367 .dc_funcs
.pSelectFont
= X11DRV_SelectFont
,
368 .dc_funcs
.pSelectPen
= X11DRV_SelectPen
,
369 .dc_funcs
.pSetBoundsRect
= X11DRV_SetBoundsRect
,
370 .dc_funcs
.pSetDCBrushColor
= X11DRV_SetDCBrushColor
,
371 .dc_funcs
.pSetDCPenColor
= X11DRV_SetDCPenColor
,
372 .dc_funcs
.pSetDeviceClipping
= X11DRV_SetDeviceClipping
,
373 .dc_funcs
.pSetDeviceGammaRamp
= X11DRV_SetDeviceGammaRamp
,
374 .dc_funcs
.pSetPixel
= X11DRV_SetPixel
,
375 .dc_funcs
.pStretchBlt
= X11DRV_StretchBlt
,
376 .dc_funcs
.pStrokeAndFillPath
= X11DRV_StrokeAndFillPath
,
377 .dc_funcs
.pStrokePath
= X11DRV_StrokePath
,
378 .dc_funcs
.pUnrealizePalette
= X11DRV_UnrealizePalette
,
379 .dc_funcs
.priority
= GDI_PRIORITY_GRAPHICS_DRV
,
381 .pActivateKeyboardLayout
= X11DRV_ActivateKeyboardLayout
,
382 .pBeep
= X11DRV_Beep
,
383 .pGetKeyNameText
= X11DRV_GetKeyNameText
,
384 .pMapVirtualKeyEx
= X11DRV_MapVirtualKeyEx
,
385 .pToUnicodeEx
= X11DRV_ToUnicodeEx
,
386 .pVkKeyScanEx
= X11DRV_VkKeyScanEx
,
387 .pNotifyIMEStatus
= X11DRV_NotifyIMEStatus
,
388 .pDestroyCursorIcon
= X11DRV_DestroyCursorIcon
,
389 .pSetCursor
= X11DRV_SetCursor
,
390 .pGetCursorPos
= X11DRV_GetCursorPos
,
391 .pSetCursorPos
= X11DRV_SetCursorPos
,
392 .pClipCursor
= X11DRV_ClipCursor
,
393 .pSystrayDockInit
= X11DRV_SystrayDockInit
,
394 .pSystrayDockInsert
= X11DRV_SystrayDockInsert
,
395 .pSystrayDockClear
= X11DRV_SystrayDockClear
,
396 .pSystrayDockRemove
= X11DRV_SystrayDockRemove
,
397 .pChangeDisplaySettings
= X11DRV_ChangeDisplaySettings
,
398 .pGetCurrentDisplaySettings
= X11DRV_GetCurrentDisplaySettings
,
399 .pGetDisplayDepth
= X11DRV_GetDisplayDepth
,
400 .pUpdateDisplayDevices
= X11DRV_UpdateDisplayDevices
,
401 .pCreateDesktop
= X11DRV_CreateDesktop
,
402 .pCreateWindow
= X11DRV_CreateWindow
,
403 .pDesktopWindowProc
= X11DRV_DesktopWindowProc
,
404 .pDestroyWindow
= X11DRV_DestroyWindow
,
405 .pFlashWindowEx
= X11DRV_FlashWindowEx
,
406 .pGetDC
= X11DRV_GetDC
,
407 .pProcessEvents
= X11DRV_ProcessEvents
,
408 .pReleaseDC
= X11DRV_ReleaseDC
,
409 .pScrollDC
= X11DRV_ScrollDC
,
410 .pSetCapture
= X11DRV_SetCapture
,
411 .pSetDesktopWindow
= X11DRV_SetDesktopWindow
,
412 .pSetFocus
= X11DRV_SetFocus
,
413 .pSetLayeredWindowAttributes
= X11DRV_SetLayeredWindowAttributes
,
414 .pSetParent
= X11DRV_SetParent
,
415 .pSetWindowIcon
= X11DRV_SetWindowIcon
,
416 .pSetWindowRgn
= X11DRV_SetWindowRgn
,
417 .pSetWindowStyle
= X11DRV_SetWindowStyle
,
418 .pSetWindowText
= X11DRV_SetWindowText
,
419 .pShowWindow
= X11DRV_ShowWindow
,
420 .pSysCommand
= X11DRV_SysCommand
,
421 .pClipboardWindowProc
= X11DRV_ClipboardWindowProc
,
422 .pUpdateClipboard
= X11DRV_UpdateClipboard
,
423 .pCreateLayeredWindow
= X11DRV_CreateLayeredWindow
,
424 .pUpdateLayeredWindow
= X11DRV_UpdateLayeredWindow
,
425 .pWindowMessage
= X11DRV_WindowMessage
,
426 .pWindowPosChanging
= X11DRV_WindowPosChanging
,
427 .pCreateWindowSurface
= X11DRV_CreateWindowSurface
,
428 .pWindowPosChanged
= X11DRV_WindowPosChanged
,
429 .pSystemParametersInfo
= X11DRV_SystemParametersInfo
,
430 .pVulkanInit
= X11DRV_VulkanInit
,
431 .pwine_get_wgl_driver
= X11DRV_wine_get_wgl_driver
,
432 .pThreadDetach
= X11DRV_ThreadDetach
,
436 void init_user_driver(void)
438 __wine_set_user_driver( &x11drv_funcs
, WINE_GDI_DRIVER_VERSION
);