kernelbase: Check pointer validity in unsafe_ptr_from_HLOCAL.
[wine.git] / dlls / user32 / driver.c
blobfbbf630a80e97e227a8645eab5dac03f135342a9
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);
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 );
47 return USER_Driver;
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 /**********************************************************************
63 * Null user driver
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 )
70 return TRUE;
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 )
95 return -1;
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 =
118 { NULL },
119 /* keyboard functions */
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 NULL,
128 NULL,
129 /* cursor/icon functions */
130 NULL,
131 NULL,
132 NULL,
133 loaderdrv_SetCursorPos,
134 NULL,
135 /* clipboard functions */
136 loaderdrv_UpdateClipboard,
137 /* display modes */
138 NULL,
139 NULL,
140 NULL,
141 /* windowing functions */
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146 NULL,
147 nulldrv_MsgWaitForMultipleObjectsEx,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 nulldrv_SetWindowIcon,
156 NULL,
157 nulldrv_SetWindowText,
158 NULL,
159 nulldrv_SysCommand,
160 NULL,
161 NULL,
162 NULL,
163 NULL,
164 /* system parameters */
165 NULL,
166 /* vulkan support */
167 NULL,
168 /* opengl support */
169 NULL,
170 /* thread management */
171 NULL,
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 );
181 return;
184 driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) );
185 *driver = *funcs;
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);
196 #undef SET_USER_FUNC
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 );
203 driver = prev;
206 __wine_set_display_driver( driver, version );