d3d10: Return the read value from read_dword().
[wine.git] / dlls / user32 / driver.c
blob73f4ee672578cb11e4df9ec5a76ae5e3a8b04de5
1 /*
2 * USER driver support
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
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <wchar.h>
25 #include "user_private.h"
26 #include "winnls.h"
27 #include "wine/debug.h"
28 #include "controls.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(user);
31 WINE_DECLARE_DEBUG_CHANNEL(winediag);
33 static struct user_driver_funcs null_driver, lazy_load_driver;
35 const struct user_driver_funcs *USER_Driver = &lazy_load_driver;
36 static char driver_load_error[80];
38 static BOOL CDECL nodrv_CreateWindow( HWND hwnd );
40 static BOOL load_desktop_driver( HWND hwnd )
42 BOOL ret = FALSE;
43 HKEY hkey;
44 DWORD size;
45 WCHAR path[MAX_PATH];
46 WCHAR key[ARRAY_SIZE(L"System\\CurrentControlSet\\Control\\Video\\{}\\0000") + 40];
47 UINT guid_atom;
49 USER_CheckNotLock();
51 strcpy( driver_load_error, "The explorer process failed to start." ); /* default error */
52 wait_graphics_driver_ready();
54 guid_atom = HandleToULong( GetPropW( hwnd, L"__wine_display_device_guid" ));
55 lstrcpyW( key, L"System\\CurrentControlSet\\Control\\Video\\{" );
56 if (!GlobalGetAtomNameW( guid_atom, key + lstrlenW(key), 40 )) return 0;
57 lstrcatW( key, L"}\\0000" );
58 if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0;
59 size = sizeof(path);
60 if (!RegQueryValueExW( hkey, L"GraphicsDriver", NULL, NULL, (BYTE *)path, &size ))
62 if (wcscmp( path, L"null" ))
64 ret = LoadLibraryW( path ) != NULL;
65 if (!ret) ERR( "failed to load %s\n", debugstr_w(path) );
67 else
69 __wine_set_user_driver( &null_driver, WINE_GDI_DRIVER_VERSION );
70 ret = TRUE;
72 TRACE( "%s\n", debugstr_w(path) );
74 else
76 size = sizeof(driver_load_error);
77 RegQueryValueExA( hkey, "DriverError", NULL, NULL, (BYTE *)driver_load_error, &size );
79 RegCloseKey( hkey );
80 return ret;
83 /* load the graphics driver */
84 static const struct user_driver_funcs *load_driver(void)
86 struct user_driver_funcs driver;
87 USEROBJECTFLAGS flags;
88 HWINSTA winstation;
90 if (!load_desktop_driver( GetDesktopWindow() ) || USER_Driver == &lazy_load_driver)
92 memset( &driver, 0, sizeof(driver) );
93 winstation = NtUserGetProcessWindowStation();
94 if (!NtUserGetObjectInformation( winstation, UOI_FLAGS, &flags, sizeof(flags), NULL )
95 || (flags.dwFlags & WSF_VISIBLE))
96 driver.pCreateWindow = nodrv_CreateWindow;
98 __wine_set_user_driver( &driver, WINE_GDI_DRIVER_VERSION );
101 return USER_Driver;
104 /* unload the graphics driver on process exit */
105 void USER_unload_driver(void)
107 struct user_driver_funcs *prev;
108 __wine_set_display_driver( &null_driver, WINE_GDI_DRIVER_VERSION );
109 /* make sure we don't try to call the driver after it has been detached */
110 prev = InterlockedExchangePointer( (void **)&USER_Driver, &null_driver );
111 if (prev != &lazy_load_driver && prev != &null_driver)
112 HeapFree( GetProcessHeap(), 0, prev );
116 /**********************************************************************
117 * Null user driver
119 * These are fallbacks for entry points that are not implemented in the real driver.
122 static void CDECL nulldrv_Beep(void)
126 static BOOL CDECL nulldrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
128 return TRUE;
131 static void CDECL nulldrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
135 static void CDECL nulldrv_DestroyCursorIcon( HCURSOR cursor )
139 static void CDECL nulldrv_SetCursor( HCURSOR cursor )
143 static BOOL CDECL nulldrv_GetCursorPos( LPPOINT pt )
145 return TRUE;
148 static BOOL CDECL nulldrv_SetCursorPos( INT x, INT y )
150 return TRUE;
153 static BOOL CDECL nulldrv_ClipCursor( LPCRECT clip )
155 return TRUE;
158 static void CDECL nulldrv_UpdateClipboard(void)
162 static BOOL CDECL nodrv_CreateWindow( HWND hwnd )
164 static int warned;
165 HWND parent = GetAncestor( hwnd, GA_PARENT );
167 /* HWND_MESSAGE windows don't need a graphics driver */
168 if (!parent || parent == get_user_thread_info()->msg_window) return TRUE;
169 if (warned++) return FALSE;
171 ERR_(winediag)( "Application tried to create a window, but no driver could be loaded.\n" );
172 if (driver_load_error[0]) ERR_(winediag)( "%s\n", driver_load_error );
173 return FALSE;
176 static BOOL CDECL nulldrv_CreateDesktopWindow( HWND hwnd )
178 return TRUE;
181 static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
183 return TRUE;
186 static void CDECL nulldrv_DestroyWindow( HWND hwnd )
190 static void CDECL nulldrv_FlashWindowEx( FLASHWINFO *info )
194 static void CDECL nulldrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
195 const RECT *top_rect, DWORD flags )
199 static DWORD CDECL nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
200 DWORD mask, DWORD flags )
202 if (!count && !timeout) return WAIT_TIMEOUT;
203 return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
204 timeout, flags & MWMO_ALERTABLE );
207 static void CDECL nulldrv_ReleaseDC( HWND hwnd, HDC hdc )
211 static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags )
215 static void CDECL nulldrv_SetFocus( HWND hwnd )
219 static void CDECL nulldrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
223 static void CDECL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
227 static void CDECL nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
231 static void CDECL nulldrv_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
235 static void CDECL nulldrv_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
239 static void CDECL nulldrv_SetWindowText( HWND hwnd, LPCWSTR text )
243 static UINT CDECL nulldrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
245 return ~0; /* use default implementation */
248 static LRESULT CDECL nulldrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam )
250 return -1;
253 static BOOL CDECL nulldrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
254 const RECT *window_rect )
256 return TRUE;
259 static LRESULT CDECL nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
261 return 0;
264 static BOOL CDECL nulldrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
265 const RECT *window_rect, const RECT *client_rect,
266 RECT *visible_rect, struct window_surface **surface )
268 return FALSE;
271 static void CDECL nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
272 const RECT *window_rect, const RECT *client_rect,
273 const RECT *visible_rect, const RECT *valid_rects,
274 struct window_surface *surface )
278 static void CDECL nulldrv_ThreadDetach( void )
283 /**********************************************************************
284 * Lazy loading user driver
286 * Initial driver used before another driver is loaded.
287 * Each entry point simply loads the real driver and chains to it.
290 static void CDECL loaderdrv_Beep(void)
292 load_driver()->pBeep();
295 static BOOL CDECL loaderdrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
297 return load_driver()->pRegisterHotKey( hwnd, modifiers, vk );
300 static void CDECL loaderdrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
302 load_driver()->pUnregisterHotKey( hwnd, modifiers, vk );
305 static void CDECL loaderdrv_SetCursor( HCURSOR cursor )
307 load_driver()->pSetCursor( cursor );
310 static BOOL CDECL loaderdrv_GetCursorPos( LPPOINT pt )
312 return load_driver()->pGetCursorPos( pt );
315 static BOOL CDECL loaderdrv_SetCursorPos( INT x, INT y )
317 return load_driver()->pSetCursorPos( x, y );
320 static BOOL CDECL loaderdrv_ClipCursor( LPCRECT clip )
322 return load_driver()->pClipCursor( clip );
325 static void CDECL loaderdrv_UpdateClipboard(void)
327 load_driver()->pUpdateClipboard();
330 static BOOL CDECL loaderdrv_CreateDesktopWindow( HWND hwnd )
332 return load_driver()->pCreateDesktopWindow( hwnd );
335 static BOOL CDECL loaderdrv_CreateWindow( HWND hwnd )
337 return load_driver()->pCreateWindow( hwnd );
340 static void CDECL loaderdrv_FlashWindowEx( FLASHWINFO *info )
342 load_driver()->pFlashWindowEx( info );
345 static void CDECL loaderdrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
346 const RECT *top_rect, DWORD flags )
348 load_driver()->pGetDC( hdc, hwnd, top_win, win_rect, top_rect, flags );
351 static void CDECL loaderdrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
353 load_driver()->pSetLayeredWindowAttributes( hwnd, key, alpha, flags );
356 static void CDECL loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
358 load_driver()->pSetWindowRgn( hwnd, hrgn, redraw );
361 static BOOL CDECL loaderdrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
362 const RECT *window_rect )
364 return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect );
367 static struct user_driver_funcs lazy_load_driver =
369 { NULL },
370 /* keyboard functions */
371 NULL,
372 loaderdrv_Beep,
373 NULL,
374 NULL,
375 NULL,
376 loaderdrv_RegisterHotKey,
377 NULL,
378 loaderdrv_UnregisterHotKey,
379 NULL,
380 /* cursor/icon functions */
381 nulldrv_DestroyCursorIcon,
382 loaderdrv_SetCursor,
383 loaderdrv_GetCursorPos,
384 loaderdrv_SetCursorPos,
385 loaderdrv_ClipCursor,
386 /* clipboard functions */
387 loaderdrv_UpdateClipboard,
388 /* display modes */
389 NULL,
390 NULL,
391 NULL,
392 /* windowing functions */
393 loaderdrv_CreateDesktopWindow,
394 loaderdrv_CreateWindow,
395 nulldrv_DestroyWindow,
396 loaderdrv_FlashWindowEx,
397 loaderdrv_GetDC,
398 nulldrv_MsgWaitForMultipleObjectsEx,
399 nulldrv_ReleaseDC,
400 NULL,
401 nulldrv_SetCapture,
402 nulldrv_SetFocus,
403 loaderdrv_SetLayeredWindowAttributes,
404 nulldrv_SetParent,
405 loaderdrv_SetWindowRgn,
406 nulldrv_SetWindowIcon,
407 nulldrv_SetWindowStyle,
408 nulldrv_SetWindowText,
409 nulldrv_ShowWindow,
410 nulldrv_SysCommand,
411 loaderdrv_UpdateLayeredWindow,
412 nulldrv_WindowMessage,
413 nulldrv_WindowPosChanging,
414 nulldrv_WindowPosChanged,
415 /* system parameters */
416 NULL,
417 /* vulkan support */
418 NULL,
419 /* thread management */
420 nulldrv_ThreadDetach
423 void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version )
425 struct user_driver_funcs *driver, *prev;
427 if (version != WINE_GDI_DRIVER_VERSION)
429 ERR( "version mismatch, driver wants %u but user32 has %u\n", version, WINE_GDI_DRIVER_VERSION );
430 return;
433 driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) );
434 *driver = *funcs;
436 #define SET_USER_FUNC(name) \
437 do { if (!driver->p##name) driver->p##name = nulldrv_##name; } while(0)
439 SET_USER_FUNC(Beep);
440 SET_USER_FUNC(RegisterHotKey);
441 SET_USER_FUNC(UnregisterHotKey);
442 SET_USER_FUNC(DestroyCursorIcon);
443 SET_USER_FUNC(SetCursor);
444 SET_USER_FUNC(GetCursorPos);
445 SET_USER_FUNC(SetCursorPos);
446 SET_USER_FUNC(ClipCursor);
447 SET_USER_FUNC(UpdateClipboard);
448 SET_USER_FUNC(CreateDesktopWindow);
449 SET_USER_FUNC(CreateWindow);
450 SET_USER_FUNC(DestroyWindow);
451 SET_USER_FUNC(FlashWindowEx);
452 SET_USER_FUNC(GetDC);
453 SET_USER_FUNC(MsgWaitForMultipleObjectsEx);
454 SET_USER_FUNC(ReleaseDC);
455 SET_USER_FUNC(SetCapture);
456 SET_USER_FUNC(SetFocus);
457 SET_USER_FUNC(SetLayeredWindowAttributes);
458 SET_USER_FUNC(SetParent);
459 SET_USER_FUNC(SetWindowRgn);
460 SET_USER_FUNC(SetWindowIcon);
461 SET_USER_FUNC(SetWindowStyle);
462 SET_USER_FUNC(SetWindowText);
463 SET_USER_FUNC(ShowWindow);
464 SET_USER_FUNC(SysCommand);
465 SET_USER_FUNC(UpdateLayeredWindow);
466 SET_USER_FUNC(WindowMessage);
467 SET_USER_FUNC(WindowPosChanging);
468 SET_USER_FUNC(WindowPosChanged);
469 SET_USER_FUNC(ThreadDetach);
470 #undef SET_USER_FUNC
472 prev = InterlockedCompareExchangePointer( (void **)&USER_Driver, driver, &lazy_load_driver );
473 if (prev != &lazy_load_driver)
475 /* another thread beat us to it */
476 HeapFree( GetProcessHeap(), 0, driver );
477 driver = prev;
480 __wine_set_display_driver( driver, version );