4 * Copyright 2000, 2005 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
25 #include "user_private.h"
27 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(user
);
32 static struct user_driver_funcs null_driver
, lazy_load_driver
;
34 const struct user_driver_funcs
*USER_Driver
= &lazy_load_driver
;
36 /* load the graphics driver */
37 static const struct user_driver_funcs
*load_driver(void)
39 wait_graphics_driver_ready();
40 if (USER_Driver
== &lazy_load_driver
)
42 static struct user_driver_funcs empty_funcs
;
43 WARN( "failed to load the display driver, falling back to null driver\n" );
44 __wine_set_user_driver( &empty_funcs
, WINE_GDI_DRIVER_VERSION
);
50 /* unload the graphics driver on process exit */
51 void USER_unload_driver(void)
53 struct user_driver_funcs
*prev
;
54 __wine_set_display_driver( &null_driver
, WINE_GDI_DRIVER_VERSION
);
55 /* make sure we don't try to call the driver after it has been detached */
56 prev
= InterlockedExchangePointer( (void **)&USER_Driver
, &null_driver
);
57 if (prev
!= &lazy_load_driver
&& prev
!= &null_driver
)
58 HeapFree( GetProcessHeap(), 0, prev
);
62 /**********************************************************************
65 * These are fallbacks for entry points that are not implemented in the real driver.
68 static BOOL CDECL
nulldrv_SetCursorPos( INT x
, INT y
)
73 static void CDECL
nulldrv_UpdateClipboard(void)
77 static DWORD CDECL
nulldrv_MsgWaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
, DWORD timeout
,
78 DWORD mask
, DWORD flags
)
80 if (!count
&& !timeout
) return WAIT_TIMEOUT
;
81 return WaitForMultipleObjectsEx( count
, handles
, flags
& MWMO_WAITALL
,
82 timeout
, flags
& MWMO_ALERTABLE
);
85 static void CDECL
nulldrv_SetWindowIcon( HWND hwnd
, UINT type
, HICON icon
)
89 static void CDECL
nulldrv_SetWindowText( HWND hwnd
, LPCWSTR text
)
93 static LRESULT CDECL
nulldrv_SysCommand( HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
99 /**********************************************************************
100 * Lazy loading user driver
102 * Initial driver used before another driver is loaded.
103 * Each entry point simply loads the real driver and chains to it.
106 static BOOL CDECL
loaderdrv_SetCursorPos( INT x
, INT y
)
108 return load_driver()->pSetCursorPos( x
, y
);
111 static void CDECL
loaderdrv_UpdateClipboard(void)
113 load_driver()->pUpdateClipboard();
116 static struct user_driver_funcs lazy_load_driver
=
119 /* keyboard functions */
129 /* cursor/icon functions */
133 loaderdrv_SetCursorPos
,
135 /* clipboard functions */
136 loaderdrv_UpdateClipboard
,
141 /* windowing functions */
147 nulldrv_MsgWaitForMultipleObjectsEx
,
155 nulldrv_SetWindowIcon
,
157 nulldrv_SetWindowText
,
164 /* system parameters */
170 /* thread management */
174 void CDECL
__wine_set_user_driver( const struct user_driver_funcs
*funcs
, UINT version
)
176 struct user_driver_funcs
*driver
, *prev
;
178 if (version
!= WINE_GDI_DRIVER_VERSION
)
180 ERR( "version mismatch, driver wants %u but user32 has %u\n", version
, WINE_GDI_DRIVER_VERSION
);
184 driver
= HeapAlloc( GetProcessHeap(), 0, sizeof(*driver
) );
187 #define SET_USER_FUNC(name) \
188 do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
190 SET_USER_FUNC(SetCursorPos
);
191 SET_USER_FUNC(UpdateClipboard
);
192 SET_USER_FUNC(MsgWaitForMultipleObjectsEx
);
193 SET_USER_FUNC(SetWindowIcon
);
194 SET_USER_FUNC(SetWindowText
);
195 SET_USER_FUNC(SysCommand
);
198 prev
= InterlockedCompareExchangePointer( (void **)&USER_Driver
, driver
, &lazy_load_driver
);
199 if (prev
!= &lazy_load_driver
)
201 /* another thread beat us to it */
202 HeapFree( GetProcessHeap(), 0, driver
);
206 __wine_set_display_driver( driver
, version
);