d2d1: Create feature level 10.0 device context state objects.
[wine.git] / dlls / user32 / user_main.c
blob78bc1fddfc2f27e4c33530aaa006571d66d0f746
1 /*
2 * USER initialization code
4 * Copyright 2000 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 <string.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
29 #include "controls.h"
30 #include "user_private.h"
31 #include "win.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(graphics);
36 HMODULE user32_module = 0;
38 static CRITICAL_SECTION user_section;
39 static CRITICAL_SECTION_DEBUG critsect_debug =
41 0, 0, &user_section,
42 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
43 0, 0, { (DWORD_PTR)(__FILE__ ": user_section") }
45 static CRITICAL_SECTION user_section = { &critsect_debug, -1, 0, 0, 0, 0 };
47 static HPALETTE (WINAPI *pfnGDISelectPalette)( HDC hdc, HPALETTE hpal, WORD bkgnd );
48 static UINT (WINAPI *pfnGDIRealizePalette)( HDC hdc );
49 static HPALETTE hPrimaryPalette;
51 static DWORD exiting_thread_id;
53 extern void WDML_NotifyThreadDetach(void);
55 #ifdef __MINGW32__
56 /* work around a Mingw build issue where _wassert causes a duplicate reference to MessageBoxW */
57 void __cdecl _wassert( const WCHAR *msg, const WCHAR *file, unsigned line) { abort(); }
58 #endif
60 /***********************************************************************
61 * USER_Lock
63 void USER_Lock(void)
65 EnterCriticalSection( &user_section );
69 /***********************************************************************
70 * USER_Unlock
72 void USER_Unlock(void)
74 LeaveCriticalSection( &user_section );
78 /***********************************************************************
79 * USER_CheckNotLock
81 * Make sure that we don't hold the user lock.
83 void USER_CheckNotLock(void)
85 if (RtlIsCriticalSectionLockedByThread(&user_section))
87 ERR( "BUG: holding USER lock\n" );
88 DebugBreak();
93 /***********************************************************************
94 * UserSelectPalette (Not a Windows API)
96 static HPALETTE WINAPI UserSelectPalette( HDC hDC, HPALETTE hPal, BOOL bForceBackground )
98 WORD wBkgPalette = 1;
100 if (!bForceBackground && (hPal != GetStockObject(DEFAULT_PALETTE)))
102 HWND hwnd = WindowFromDC( hDC );
103 if (hwnd)
105 HWND hForeground = GetForegroundWindow();
106 /* set primary palette if it's related to current active */
107 if (hForeground == hwnd || IsChild(hForeground,hwnd))
109 wBkgPalette = 0;
110 hPrimaryPalette = hPal;
114 return pfnGDISelectPalette( hDC, hPal, wBkgPalette);
118 /***********************************************************************
119 * UserRealizePalette (USER32.@)
121 UINT WINAPI UserRealizePalette( HDC hDC )
123 UINT realized = pfnGDIRealizePalette( hDC );
125 /* do not send anything if no colors were changed */
126 if (realized && GetCurrentObject( hDC, OBJ_PAL ) == hPrimaryPalette)
128 /* send palette change notification */
129 HWND hWnd = WindowFromDC( hDC );
130 if (hWnd) SendMessageTimeoutW( HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0,
131 SMTO_ABORTIFHUNG, 2000, NULL );
133 return realized;
137 /***********************************************************************
138 * palette_init
140 * Patch the function pointers in GDI for SelectPalette and RealizePalette
142 static void palette_init(void)
144 void **ptr;
145 HMODULE module = GetModuleHandleA( "gdi32" );
146 if (!module)
148 ERR( "cannot get GDI32 handle\n" );
149 return;
151 if ((ptr = (void**)GetProcAddress( module, "pfnSelectPalette" )))
152 pfnGDISelectPalette = InterlockedExchangePointer( ptr, UserSelectPalette );
153 else ERR( "cannot find pfnSelectPalette in GDI32\n" );
154 if ((ptr = (void**)GetProcAddress( module, "pfnRealizePalette" )))
155 pfnGDIRealizePalette = InterlockedExchangePointer( ptr, UserRealizePalette );
156 else ERR( "cannot find pfnRealizePalette in GDI32\n" );
160 /***********************************************************************
161 * dpiaware_init
163 * Initialize the DPI awareness style.
165 static void dpiaware_init(void)
167 WCHAR buffer[256];
168 DWORD option;
170 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb->ProcessParameters->ImagePathName,
171 L"dpiAwareness", REG_DWORD, &option, sizeof(option), NULL ))
173 TRACE( "got option %x\n", option );
174 if (option <= 2)
176 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~(ULONG_PTR)option );
177 return;
181 if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2016/WindowsSettings",
182 L"dpiAwareness", buffer, ARRAY_SIZE(buffer), NULL ))
184 static const WCHAR * const types[] = { L"unaware", L"system", L"permonitor", L"permonitorv2" };
185 WCHAR *p, *start, *end;
186 ULONG_PTR i;
188 TRACE( "got dpiAwareness=%s\n", debugstr_w(buffer) );
189 for (start = buffer; *start; start = end)
191 start += wcsspn( start, L" \t\r\n" );
192 if (!(end = wcschr( start, ',' ))) end = start + lstrlenW(start);
193 else *end++ = 0;
194 if ((p = wcspbrk( start, L" \t\r\n" ))) *p = 0;
195 for (i = 0; i < ARRAY_SIZE(types); i++)
197 if (wcsicmp( start, types[i] )) continue;
198 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
199 return;
203 else if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2005/WindowsSettings",
204 L"dpiAware", buffer, ARRAY_SIZE(buffer), NULL ))
206 TRACE( "got dpiAware=%s\n", debugstr_w(buffer) );
207 if (!wcsicmp( buffer, L"true" ))
208 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
209 else if (!wcsicmp( buffer, L"true/pm" ) || !wcsicmp( buffer, L"per monitor" ))
210 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
211 else
212 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
217 static const void *kernel_callback_table[NtUserCallCount] =
219 User32CallEnumDisplayMonitor,
223 /***********************************************************************
224 * USER initialisation routine
226 static BOOL process_attach(void)
228 NtCurrentTeb()->Peb->KernelCallbackTable = kernel_callback_table;
230 dpiaware_init();
231 register_desktop_class();
233 /* Initialize system colors and metrics */
234 SYSPARAMS_Init();
236 /* Setup palette function pointers */
237 palette_init();
239 return TRUE;
243 /**********************************************************************
244 * USER_IsExitingThread
246 BOOL USER_IsExitingThread( DWORD tid )
248 return (tid == exiting_thread_id);
252 /**********************************************************************
253 * thread_detach
255 static void thread_detach(void)
257 struct user_thread_info *thread_info = get_user_thread_info();
259 exiting_thread_id = GetCurrentThreadId();
261 WDML_NotifyThreadDetach();
262 USER_Driver->pThreadDetach();
264 destroy_thread_windows();
265 CloseHandle( thread_info->server_queue );
266 HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );
267 HeapFree( GetProcessHeap(), 0, thread_info->key_state );
268 HeapFree( GetProcessHeap(), 0, thread_info->rawinput );
270 exiting_thread_id = 0;
274 /***********************************************************************
275 * UserClientDllInitialize (USER32.@)
277 * USER dll initialisation routine (exported as UserClientDllInitialize for compatibility).
279 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
281 static HMODULE imm32_module;
282 BOOL ret = TRUE;
284 switch(reason)
286 case DLL_PROCESS_ATTACH:
287 user32_module = inst;
288 ret = process_attach();
289 if(ret)
290 imm32_module = LoadLibraryW(L"imm32.dll");
291 break;
292 case DLL_THREAD_DETACH:
293 thread_detach();
294 break;
295 case DLL_PROCESS_DETACH:
296 USER_unload_driver();
297 FreeLibrary(imm32_module);
298 DeleteCriticalSection(&user_section);
299 break;
301 return ret;
305 /***********************************************************************
306 * ExitWindowsEx (USER32.@)
308 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
310 WCHAR app[MAX_PATH];
311 WCHAR cmdline[MAX_PATH + 64];
312 PROCESS_INFORMATION pi;
313 STARTUPINFOW si;
314 void *redir;
316 GetSystemDirectoryW( app, MAX_PATH - ARRAY_SIZE( L"\\wineboot.exe" ));
317 lstrcatW( app, L"\\wineboot.exe" );
318 lstrcpyW( cmdline, app );
320 if (flags & EWX_FORCE) lstrcatW( cmdline, L" --kill" );
321 else
323 lstrcatW( cmdline, L" --end-session" );
324 if (flags & EWX_FORCEIFHUNG) lstrcatW( cmdline, L" --force" );
326 if (!(flags & EWX_REBOOT)) lstrcatW( cmdline, L" --shutdown" );
328 memset( &si, 0, sizeof si );
329 si.cb = sizeof si;
330 Wow64DisableWow64FsRedirection( &redir );
331 if (!CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
333 Wow64RevertWow64FsRedirection( redir );
334 ERR( "Failed to run %s\n", debugstr_w(cmdline) );
335 return FALSE;
337 Wow64RevertWow64FsRedirection( redir );
338 CloseHandle( pi.hProcess );
339 CloseHandle( pi.hThread );
340 return TRUE;
343 /***********************************************************************
344 * LockWorkStation (USER32.@)
346 BOOL WINAPI LockWorkStation(void)
348 TRACE(": stub\n");
349 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
350 return FALSE;
353 /***********************************************************************
354 * RegisterServicesProcess (USER32.@)
356 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
358 FIXME("(0x%x): stub\n", ServicesProcessId);
359 return 0;
362 /***********************************************************************
363 * ShutdownBlockReasonCreate (USER32.@)
365 BOOL WINAPI ShutdownBlockReasonCreate(HWND hwnd, LPCWSTR reason)
367 FIXME("(%p, %s): stub\n", hwnd, debugstr_w(reason));
368 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
369 return FALSE;
372 /***********************************************************************
373 * ShutdownBlockReasonDestroy (USER32.@)
375 BOOL WINAPI ShutdownBlockReasonDestroy(HWND hwnd)
377 FIXME("(%p): stub\n", hwnd);
378 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
379 return FALSE;