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
30 #include "wine/debug.h"
31 #include "wine/gdi_driver.h"
33 #include "user_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(user
);
37 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
39 static USER_DRIVER null_driver
, lazy_load_driver
;
41 const USER_DRIVER
*USER_Driver
= &lazy_load_driver
;
42 static char driver_load_error
[80];
44 static BOOL CDECL
nodrv_CreateWindow( HWND hwnd
);
46 static BOOL
load_desktop_driver( HWND hwnd
, HMODULE
*module
)
52 WCHAR key
[ARRAY_SIZE(L
"System\\CurrentControlSet\\Control\\Video\\{}\\0000") + 40];
57 strcpy( driver_load_error
, "The explorer process failed to start." ); /* default error */
58 SendMessageW( hwnd
, WM_NULL
, 0, 0 ); /* wait for the desktop process to be ready */
60 guid_atom
= HandleToULong( GetPropW( hwnd
, L
"__wine_display_device_guid" ));
61 lstrcpyW( key
, L
"System\\CurrentControlSet\\Control\\Video\\{" );
62 if (!GlobalGetAtomNameW( guid_atom
, key
+ lstrlenW(key
), 40 )) return 0;
63 lstrcatW( key
, L
"}\\0000" );
64 if (RegOpenKeyW( HKEY_LOCAL_MACHINE
, key
, &hkey
)) return 0;
66 if (!RegQueryValueExW( hkey
, L
"GraphicsDriver", NULL
, NULL
, (BYTE
*)path
, &size
))
68 if ((ret
= !wcscmp( path
, L
"null" ))) *module
= NULL
;
69 else ret
= (*module
= LoadLibraryW( path
)) != NULL
;
70 if (!ret
) ERR( "failed to load %s\n", debugstr_w(path
) );
71 TRACE( "%s %p\n", debugstr_w(path
), *module
);
75 size
= sizeof(driver_load_error
);
77 RegQueryValueExA( hkey
, "DriverError", NULL
, NULL
, (BYTE
*)driver_load_error
, &size
);
83 /* load the graphics driver */
84 static const USER_DRIVER
*load_driver(void)
87 HMODULE graphics_driver
;
88 USER_DRIVER
*driver
, *prev
;
90 driver
= HeapAlloc( GetProcessHeap(), 0, sizeof(*driver
) );
91 *driver
= null_driver
;
93 if (!load_desktop_driver( GetDesktopWindow(), &graphics_driver
))
95 USEROBJECTFLAGS flags
;
98 winstation
= GetProcessWindowStation();
99 if (!GetUserObjectInformationA(winstation
, UOI_FLAGS
, &flags
, sizeof(flags
), NULL
)
100 || (flags
.dwFlags
& WSF_VISIBLE
))
101 driver
->pCreateWindow
= nodrv_CreateWindow
;
103 else if (graphics_driver
)
105 #define GET_USER_FUNC(name) \
106 do { if ((ptr = GetProcAddress( graphics_driver, #name ))) driver->p##name = ptr; } while(0)
108 GET_USER_FUNC(ActivateKeyboardLayout
);
110 GET_USER_FUNC(GetKeyNameText
);
111 GET_USER_FUNC(GetKeyboardLayout
);
112 GET_USER_FUNC(GetKeyboardLayoutList
);
113 GET_USER_FUNC(GetKeyboardLayoutName
);
114 GET_USER_FUNC(LoadKeyboardLayout
);
115 GET_USER_FUNC(MapVirtualKeyEx
);
116 GET_USER_FUNC(RegisterHotKey
);
117 GET_USER_FUNC(ToUnicodeEx
);
118 GET_USER_FUNC(UnloadKeyboardLayout
);
119 GET_USER_FUNC(UnregisterHotKey
);
120 GET_USER_FUNC(VkKeyScanEx
);
121 GET_USER_FUNC(DestroyCursorIcon
);
122 GET_USER_FUNC(SetCursor
);
123 GET_USER_FUNC(GetCursorPos
);
124 GET_USER_FUNC(SetCursorPos
);
125 GET_USER_FUNC(ClipCursor
);
126 GET_USER_FUNC(UpdateClipboard
);
127 GET_USER_FUNC(ChangeDisplaySettingsEx
);
128 GET_USER_FUNC(EnumDisplayMonitors
);
129 GET_USER_FUNC(EnumDisplaySettingsEx
);
130 GET_USER_FUNC(GetMonitorInfo
);
131 GET_USER_FUNC(CreateDesktopWindow
);
132 GET_USER_FUNC(CreateWindow
);
133 GET_USER_FUNC(DestroyWindow
);
134 GET_USER_FUNC(FlashWindowEx
);
135 GET_USER_FUNC(GetDC
);
136 GET_USER_FUNC(MsgWaitForMultipleObjectsEx
);
137 GET_USER_FUNC(ReleaseDC
);
138 GET_USER_FUNC(ScrollDC
);
139 GET_USER_FUNC(SetCapture
);
140 GET_USER_FUNC(SetFocus
);
141 GET_USER_FUNC(SetLayeredWindowAttributes
);
142 GET_USER_FUNC(SetParent
);
143 GET_USER_FUNC(SetWindowRgn
);
144 GET_USER_FUNC(SetWindowIcon
);
145 GET_USER_FUNC(SetWindowStyle
);
146 GET_USER_FUNC(SetWindowText
);
147 GET_USER_FUNC(ShowWindow
);
148 GET_USER_FUNC(SysCommand
);
149 GET_USER_FUNC(UpdateLayeredWindow
);
150 GET_USER_FUNC(WindowMessage
);
151 GET_USER_FUNC(WindowPosChanging
);
152 GET_USER_FUNC(WindowPosChanged
);
153 GET_USER_FUNC(SystemParametersInfo
);
154 GET_USER_FUNC(ThreadDetach
);
158 prev
= InterlockedCompareExchangePointer( (void **)&USER_Driver
, driver
, &lazy_load_driver
);
159 if (prev
!= &lazy_load_driver
)
161 /* another thread beat us to it */
162 HeapFree( GetProcessHeap(), 0, driver
);
165 else LdrAddRefDll( 0, graphics_driver
);
167 __wine_set_display_driver( graphics_driver
);
168 register_builtin_classes();
173 /* unload the graphics driver on process exit */
174 void USER_unload_driver(void)
177 /* make sure we don't try to call the driver after it has been detached */
178 prev
= InterlockedExchangePointer( (void **)&USER_Driver
, &null_driver
);
179 if (prev
!= &lazy_load_driver
&& prev
!= &null_driver
)
180 HeapFree( GetProcessHeap(), 0, prev
);
184 /**********************************************************************
187 * These are fallbacks for entry points that are not implemented in the real driver.
190 static HKL CDECL
nulldrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
195 static void CDECL
nulldrv_Beep(void)
199 static UINT CDECL
nulldrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
204 ULONG_PTR baselayout
;
207 baselayout
= GetUserDefaultLCID();
208 langid
= PRIMARYLANGID(LANGIDFROMLCID(baselayout
));
209 if (langid
== LANG_CHINESE
|| langid
== LANG_JAPANESE
|| langid
== LANG_KOREAN
)
210 baselayout
= MAKELONG( baselayout
, 0xe001 ); /* IME */
212 baselayout
|= baselayout
<< 16;
214 /* Enumerate the Registry */
215 rc
= RegOpenKeyW(HKEY_LOCAL_MACHINE
,L
"System\\CurrentControlSet\\Control\\Keyboard Layouts",&hKeyKeyboard
);
216 if (rc
== ERROR_SUCCESS
)
221 rc
= RegEnumKeyW(hKeyKeyboard
, count
, szKeyName
, 9);
222 if (rc
== ERROR_SUCCESS
)
224 layout
= (HKL
)(ULONG_PTR
)wcstoul(szKeyName
,NULL
,16);
225 if (baselayout
!= 0 && layout
== (HKL
)baselayout
)
226 baselayout
= 0; /* found in the registry do not add again */
229 if (count
>= size
) break;
230 layouts
[count
] = layout
;
234 } while (rc
== ERROR_SUCCESS
);
235 RegCloseKey(hKeyKeyboard
);
238 /* make sure our base layout is on the list */
245 layouts
[count
] = (HKL
)baselayout
;
256 static INT CDECL
nulldrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
261 static HKL CDECL
nulldrv_GetKeyboardLayout( DWORD thread_id
)
266 static BOOL CDECL
nulldrv_GetKeyboardLayoutName( LPWSTR name
)
271 static HKL CDECL
nulldrv_LoadKeyboardLayout( LPCWSTR name
, UINT flags
)
276 static UINT CDECL
nulldrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
281 static BOOL CDECL
nulldrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
286 static INT CDECL
nulldrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
287 int size
, UINT flags
, HKL layout
)
292 static BOOL CDECL
nulldrv_UnloadKeyboardLayout( HKL layout
)
297 static void CDECL
nulldrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
301 static SHORT CDECL
nulldrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
303 static const short ctrl_vks
[] = {
304 0x332, 0x241, 0x242, 0x003, 0x244, 0x245, 0x246, 0x247,
305 0x008, 0x009, 0x20d, 0x24b, 0x24c, 0x00d, 0x24e, 0x24f,
306 0x250, 0x251, 0x252, 0x253, 0x254, 0x255, 0x256, 0x257,
307 0x258, 0x259, 0x25a, 0x01b, 0x2dc, 0x2dd, 0x336, 0x3bd
310 return ch
< ARRAY_SIZE(ctrl_vks
) ? ctrl_vks
[ch
] : -1;
313 static void CDECL
nulldrv_DestroyCursorIcon( HCURSOR cursor
)
317 static void CDECL
nulldrv_SetCursor( HCURSOR cursor
)
321 static BOOL CDECL
nulldrv_GetCursorPos( LPPOINT pt
)
326 static BOOL CDECL
nulldrv_SetCursorPos( INT x
, INT y
)
331 static BOOL CDECL
nulldrv_ClipCursor( LPCRECT clip
)
336 static void CDECL
nulldrv_UpdateClipboard(void)
340 static LONG CDECL
nulldrv_ChangeDisplaySettingsEx( LPCWSTR name
, LPDEVMODEW mode
, HWND hwnd
,
341 DWORD flags
, LPVOID lparam
)
343 return DISP_CHANGE_FAILED
;
346 static BOOL CDECL
nulldrv_EnumDisplaySettingsEx( LPCWSTR name
, DWORD num
, LPDEVMODEW mode
, DWORD flags
)
351 static BOOL CDECL
nulldrv_CreateDesktopWindow( HWND hwnd
)
356 static BOOL CDECL
nodrv_CreateWindow( HWND hwnd
)
359 HWND parent
= GetAncestor( hwnd
, GA_PARENT
);
361 /* HWND_MESSAGE windows don't need a graphics driver */
362 if (!parent
|| parent
== get_user_thread_info()->msg_window
) return TRUE
;
363 if (warned
++) return FALSE
;
365 ERR_(winediag
)( "Application tried to create a window, but no driver could be loaded.\n" );
366 if (driver_load_error
[0]) ERR_(winediag
)( "%s\n", driver_load_error
);
370 static BOOL CDECL
nulldrv_CreateWindow( HWND hwnd
)
375 static void CDECL
nulldrv_DestroyWindow( HWND hwnd
)
379 static void CDECL
nulldrv_FlashWindowEx( FLASHWINFO
*info
)
383 static void CDECL
nulldrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
384 const RECT
*top_rect
, DWORD flags
)
388 static DWORD CDECL
nulldrv_MsgWaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
, DWORD timeout
,
389 DWORD mask
, DWORD flags
)
391 return WaitForMultipleObjectsEx( count
, handles
, flags
& MWMO_WAITALL
,
392 timeout
, flags
& MWMO_ALERTABLE
);
395 static void CDECL
nulldrv_ReleaseDC( HWND hwnd
, HDC hdc
)
399 static BOOL CDECL
nulldrv_ScrollDC( HDC hdc
, INT dx
, INT dy
, HRGN update
)
403 GetClipBox( hdc
, &rect
);
404 return BitBlt( hdc
, rect
.left
, rect
.top
, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
405 hdc
, rect
.left
- dx
, rect
.top
- dy
, SRCCOPY
);
408 static void CDECL
nulldrv_SetCapture( HWND hwnd
, UINT flags
)
412 static void CDECL
nulldrv_SetFocus( HWND hwnd
)
416 static void CDECL
nulldrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
420 static void CDECL
nulldrv_SetParent( HWND hwnd
, HWND parent
, HWND old_parent
)
424 static void CDECL
nulldrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
428 static void CDECL
nulldrv_SetWindowIcon( HWND hwnd
, UINT type
, HICON icon
)
432 static void CDECL
nulldrv_SetWindowStyle( HWND hwnd
, INT offset
, STYLESTRUCT
*style
)
436 static void CDECL
nulldrv_SetWindowText( HWND hwnd
, LPCWSTR text
)
440 static UINT CDECL
nulldrv_ShowWindow( HWND hwnd
, INT cmd
, RECT
*rect
, UINT swp
)
445 static LRESULT CDECL
nulldrv_SysCommand( HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
450 static BOOL CDECL
nulldrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
451 const RECT
*window_rect
)
456 static LRESULT CDECL
nulldrv_WindowMessage( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
461 static void CDECL
nulldrv_WindowPosChanging( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
462 const RECT
*window_rect
, const RECT
*client_rect
,
463 RECT
*visible_rect
, struct window_surface
**surface
)
467 static void CDECL
nulldrv_WindowPosChanged( HWND hwnd
, HWND insert_after
, UINT swp_flags
,
468 const RECT
*window_rect
, const RECT
*client_rect
,
469 const RECT
*visible_rect
, const RECT
*valid_rects
,
470 struct window_surface
*surface
)
474 static BOOL CDECL
nulldrv_SystemParametersInfo( UINT action
, UINT int_param
, void *ptr_param
, UINT flags
)
479 static void CDECL
nulldrv_ThreadDetach( void )
483 static USER_DRIVER null_driver
=
485 /* keyboard functions */
486 nulldrv_ActivateKeyboardLayout
,
488 nulldrv_GetKeyNameText
,
489 nulldrv_GetKeyboardLayout
,
490 nulldrv_GetKeyboardLayoutList
,
491 nulldrv_GetKeyboardLayoutName
,
492 nulldrv_LoadKeyboardLayout
,
493 nulldrv_MapVirtualKeyEx
,
494 nulldrv_RegisterHotKey
,
496 nulldrv_UnloadKeyboardLayout
,
497 nulldrv_UnregisterHotKey
,
499 /* cursor/icon functions */
500 nulldrv_DestroyCursorIcon
,
502 nulldrv_GetCursorPos
,
503 nulldrv_SetCursorPos
,
505 /* clipboard functions */
506 nulldrv_UpdateClipboard
,
508 nulldrv_ChangeDisplaySettingsEx
,
509 nulldrv_EnumDisplayMonitors
,
510 nulldrv_EnumDisplaySettingsEx
,
511 nulldrv_GetMonitorInfo
,
512 /* windowing functions */
513 nulldrv_CreateDesktopWindow
,
514 nulldrv_CreateWindow
,
515 nulldrv_DestroyWindow
,
516 nulldrv_FlashWindowEx
,
518 nulldrv_MsgWaitForMultipleObjectsEx
,
523 nulldrv_SetLayeredWindowAttributes
,
525 nulldrv_SetWindowRgn
,
526 nulldrv_SetWindowIcon
,
527 nulldrv_SetWindowStyle
,
528 nulldrv_SetWindowText
,
531 nulldrv_UpdateLayeredWindow
,
532 nulldrv_WindowMessage
,
533 nulldrv_WindowPosChanging
,
534 nulldrv_WindowPosChanged
,
535 /* system parameters */
536 nulldrv_SystemParametersInfo
,
537 /* thread management */
542 /**********************************************************************
543 * Lazy loading user driver
545 * Initial driver used before another driver is loaded.
546 * Each entry point simply loads the real driver and chains to it.
549 static HKL CDECL
loaderdrv_ActivateKeyboardLayout( HKL layout
, UINT flags
)
551 return load_driver()->pActivateKeyboardLayout( layout
, flags
);
554 static void CDECL
loaderdrv_Beep(void)
556 load_driver()->pBeep();
559 static INT CDECL
loaderdrv_GetKeyNameText( LONG lparam
, LPWSTR buffer
, INT size
)
561 return load_driver()->pGetKeyNameText( lparam
, buffer
, size
);
564 static HKL CDECL
loaderdrv_GetKeyboardLayout( DWORD thread_id
)
566 return load_driver()->pGetKeyboardLayout( thread_id
);
569 static UINT CDECL
loaderdrv_GetKeyboardLayoutList( INT size
, HKL
*layouts
)
571 return load_driver()->pGetKeyboardLayoutList( size
, layouts
);
574 static BOOL CDECL
loaderdrv_GetKeyboardLayoutName( LPWSTR name
)
576 return load_driver()->pGetKeyboardLayoutName( name
);
579 static HKL CDECL
loaderdrv_LoadKeyboardLayout( LPCWSTR name
, UINT flags
)
581 return load_driver()->pLoadKeyboardLayout( name
, flags
);
584 static UINT CDECL
loaderdrv_MapVirtualKeyEx( UINT code
, UINT type
, HKL layout
)
586 return load_driver()->pMapVirtualKeyEx( code
, type
, layout
);
589 static BOOL CDECL
loaderdrv_RegisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
591 return load_driver()->pRegisterHotKey( hwnd
, modifiers
, vk
);
594 static INT CDECL
loaderdrv_ToUnicodeEx( UINT virt
, UINT scan
, const BYTE
*state
, LPWSTR str
,
595 int size
, UINT flags
, HKL layout
)
597 return load_driver()->pToUnicodeEx( virt
, scan
, state
, str
, size
, flags
, layout
);
600 static BOOL CDECL
loaderdrv_UnloadKeyboardLayout( HKL layout
)
602 return load_driver()->pUnloadKeyboardLayout( layout
);
605 static void CDECL
loaderdrv_UnregisterHotKey( HWND hwnd
, UINT modifiers
, UINT vk
)
607 load_driver()->pUnregisterHotKey( hwnd
, modifiers
, vk
);
610 static SHORT CDECL
loaderdrv_VkKeyScanEx( WCHAR ch
, HKL layout
)
612 return load_driver()->pVkKeyScanEx( ch
, layout
);
615 static void CDECL
loaderdrv_SetCursor( HCURSOR cursor
)
617 load_driver()->pSetCursor( cursor
);
620 static BOOL CDECL
loaderdrv_GetCursorPos( LPPOINT pt
)
622 return load_driver()->pGetCursorPos( pt
);
625 static BOOL CDECL
loaderdrv_SetCursorPos( INT x
, INT y
)
627 return load_driver()->pSetCursorPos( x
, y
);
630 static BOOL CDECL
loaderdrv_ClipCursor( LPCRECT clip
)
632 return load_driver()->pClipCursor( clip
);
635 static void CDECL
loaderdrv_UpdateClipboard(void)
637 load_driver()->pUpdateClipboard();
640 static LONG CDECL
loaderdrv_ChangeDisplaySettingsEx( LPCWSTR name
, LPDEVMODEW mode
, HWND hwnd
,
641 DWORD flags
, LPVOID lparam
)
643 return load_driver()->pChangeDisplaySettingsEx( name
, mode
, hwnd
, flags
, lparam
);
646 static BOOL CDECL
loaderdrv_EnumDisplayMonitors( HDC hdc
, LPRECT rect
, MONITORENUMPROC proc
, LPARAM lp
)
648 return load_driver()->pEnumDisplayMonitors( hdc
, rect
, proc
, lp
);
651 static BOOL CDECL
loaderdrv_EnumDisplaySettingsEx( LPCWSTR name
, DWORD num
, LPDEVMODEW mode
, DWORD flags
)
653 return load_driver()->pEnumDisplaySettingsEx( name
, num
, mode
, flags
);
656 static BOOL CDECL
loaderdrv_GetMonitorInfo( HMONITOR handle
, LPMONITORINFO info
)
658 return load_driver()->pGetMonitorInfo( handle
, info
);
661 static BOOL CDECL
loaderdrv_CreateDesktopWindow( HWND hwnd
)
663 return load_driver()->pCreateDesktopWindow( hwnd
);
666 static BOOL CDECL
loaderdrv_CreateWindow( HWND hwnd
)
668 return load_driver()->pCreateWindow( hwnd
);
671 static void CDECL
loaderdrv_FlashWindowEx( FLASHWINFO
*info
)
673 load_driver()->pFlashWindowEx( info
);
676 static void CDECL
loaderdrv_GetDC( HDC hdc
, HWND hwnd
, HWND top_win
, const RECT
*win_rect
,
677 const RECT
*top_rect
, DWORD flags
)
679 load_driver()->pGetDC( hdc
, hwnd
, top_win
, win_rect
, top_rect
, flags
);
682 static void CDECL
loaderdrv_SetLayeredWindowAttributes( HWND hwnd
, COLORREF key
, BYTE alpha
, DWORD flags
)
684 load_driver()->pSetLayeredWindowAttributes( hwnd
, key
, alpha
, flags
);
687 static void CDECL
loaderdrv_SetWindowRgn( HWND hwnd
, HRGN hrgn
, BOOL redraw
)
689 load_driver()->pSetWindowRgn( hwnd
, hrgn
, redraw
);
692 static BOOL CDECL
loaderdrv_UpdateLayeredWindow( HWND hwnd
, const UPDATELAYEREDWINDOWINFO
*info
,
693 const RECT
*window_rect
)
695 return load_driver()->pUpdateLayeredWindow( hwnd
, info
, window_rect
);
698 static USER_DRIVER lazy_load_driver
=
700 /* keyboard functions */
701 loaderdrv_ActivateKeyboardLayout
,
703 loaderdrv_GetKeyNameText
,
704 loaderdrv_GetKeyboardLayout
,
705 loaderdrv_GetKeyboardLayoutList
,
706 loaderdrv_GetKeyboardLayoutName
,
707 loaderdrv_LoadKeyboardLayout
,
708 loaderdrv_MapVirtualKeyEx
,
709 loaderdrv_RegisterHotKey
,
710 loaderdrv_ToUnicodeEx
,
711 loaderdrv_UnloadKeyboardLayout
,
712 loaderdrv_UnregisterHotKey
,
713 loaderdrv_VkKeyScanEx
,
714 /* cursor/icon functions */
715 nulldrv_DestroyCursorIcon
,
717 loaderdrv_GetCursorPos
,
718 loaderdrv_SetCursorPos
,
719 loaderdrv_ClipCursor
,
720 /* clipboard functions */
721 loaderdrv_UpdateClipboard
,
723 loaderdrv_ChangeDisplaySettingsEx
,
724 loaderdrv_EnumDisplayMonitors
,
725 loaderdrv_EnumDisplaySettingsEx
,
726 loaderdrv_GetMonitorInfo
,
727 /* windowing functions */
728 loaderdrv_CreateDesktopWindow
,
729 loaderdrv_CreateWindow
,
730 nulldrv_DestroyWindow
,
731 loaderdrv_FlashWindowEx
,
733 nulldrv_MsgWaitForMultipleObjectsEx
,
738 loaderdrv_SetLayeredWindowAttributes
,
740 loaderdrv_SetWindowRgn
,
741 nulldrv_SetWindowIcon
,
742 nulldrv_SetWindowStyle
,
743 nulldrv_SetWindowText
,
746 loaderdrv_UpdateLayeredWindow
,
747 nulldrv_WindowMessage
,
748 nulldrv_WindowPosChanging
,
749 nulldrv_WindowPosChanged
,
750 /* system parameters */
751 nulldrv_SystemParametersInfo
,
752 /* thread management */