win32u: Move primary palette handling from user32.
[wine.git] / dlls / user32 / user_main.c
blobea30772067d7d7121ed1ce74635ebb53fb819c5c
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 DWORD exiting_thread_id;
49 extern void WDML_NotifyThreadDetach(void);
51 /***********************************************************************
52 * USER_Lock
54 void USER_Lock(void)
56 EnterCriticalSection( &user_section );
60 /***********************************************************************
61 * USER_Unlock
63 void USER_Unlock(void)
65 LeaveCriticalSection( &user_section );
69 /***********************************************************************
70 * USER_CheckNotLock
72 * Make sure that we don't hold the user lock.
74 void USER_CheckNotLock(void)
76 if (RtlIsCriticalSectionLockedByThread(&user_section))
78 ERR( "BUG: holding USER lock\n" );
79 DebugBreak();
84 /***********************************************************************
85 * UserRealizePalette (USER32.@)
87 UINT WINAPI UserRealizePalette( HDC hdc )
89 return NtUserCallOneParam( HandleToUlong(hdc), NtUserRealizePalette );
93 /***********************************************************************
94 * dpiaware_init
96 * Initialize the DPI awareness style.
98 static void dpiaware_init(void)
100 WCHAR buffer[256];
101 DWORD option;
103 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb->ProcessParameters->ImagePathName,
104 L"dpiAwareness", REG_DWORD, &option, sizeof(option), NULL ))
106 TRACE( "got option %x\n", option );
107 if (option <= 2)
109 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~(ULONG_PTR)option );
110 return;
114 if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2016/WindowsSettings",
115 L"dpiAwareness", buffer, ARRAY_SIZE(buffer), NULL ))
117 static const WCHAR * const types[] = { L"unaware", L"system", L"permonitor", L"permonitorv2" };
118 WCHAR *p, *start, *end;
119 ULONG_PTR i;
121 TRACE( "got dpiAwareness=%s\n", debugstr_w(buffer) );
122 for (start = buffer; *start; start = end)
124 start += wcsspn( start, L" \t\r\n" );
125 if (!(end = wcschr( start, ',' ))) end = start + lstrlenW(start);
126 else *end++ = 0;
127 if ((p = wcspbrk( start, L" \t\r\n" ))) *p = 0;
128 for (i = 0; i < ARRAY_SIZE(types); i++)
130 if (wcsicmp( start, types[i] )) continue;
131 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
132 return;
136 else if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2005/WindowsSettings",
137 L"dpiAware", buffer, ARRAY_SIZE(buffer), NULL ))
139 TRACE( "got dpiAware=%s\n", debugstr_w(buffer) );
140 if (!wcsicmp( buffer, L"true" ))
141 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
142 else if (!wcsicmp( buffer, L"true/pm" ) || !wcsicmp( buffer, L"per monitor" ))
143 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
144 else
145 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
149 static const struct user_callbacks user_funcs =
151 GetDesktopWindow,
152 GetWindowRect,
153 IsChild,
154 RedrawWindow,
155 SendMessageTimeoutW,
156 WindowFromDC,
159 static const void *kernel_callback_table[NtUserCallCount] =
161 User32CallEnumDisplayMonitor,
162 User32CallWinEventHook,
166 /***********************************************************************
167 * USER initialisation routine
169 static BOOL process_attach(void)
171 NtCurrentTeb()->Peb->KernelCallbackTable = kernel_callback_table;
173 /* FIXME: should not be needed */
174 NtUserCallOneParam( (UINT_PTR)&user_funcs, NtUserSetCallbacks );
176 dpiaware_init();
177 register_desktop_class();
179 /* Initialize system colors and metrics */
180 SYSPARAMS_Init();
182 return TRUE;
186 /**********************************************************************
187 * USER_IsExitingThread
189 BOOL USER_IsExitingThread( DWORD tid )
191 return (tid == exiting_thread_id);
195 /**********************************************************************
196 * thread_detach
198 static void thread_detach(void)
200 struct user_thread_info *thread_info = get_user_thread_info();
202 exiting_thread_id = GetCurrentThreadId();
204 WDML_NotifyThreadDetach();
206 NtUserCallNoParam( NtUserThreadDetach );
207 destroy_thread_windows();
208 CloseHandle( thread_info->server_queue );
209 HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );
210 HeapFree( GetProcessHeap(), 0, thread_info->rawinput );
212 exiting_thread_id = 0;
216 /***********************************************************************
217 * UserClientDllInitialize (USER32.@)
219 * USER dll initialisation routine (exported as UserClientDllInitialize for compatibility).
221 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
223 static HMODULE imm32_module;
224 BOOL ret = TRUE;
226 switch(reason)
228 case DLL_PROCESS_ATTACH:
229 user32_module = inst;
230 ret = process_attach();
231 if(ret)
232 imm32_module = LoadLibraryW(L"imm32.dll");
233 break;
234 case DLL_THREAD_DETACH:
235 thread_detach();
236 break;
237 case DLL_PROCESS_DETACH:
238 USER_unload_driver();
239 FreeLibrary(imm32_module);
240 DeleteCriticalSection(&user_section);
241 break;
243 return ret;
247 /***********************************************************************
248 * ExitWindowsEx (USER32.@)
250 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
252 WCHAR app[MAX_PATH];
253 WCHAR cmdline[MAX_PATH + 64];
254 PROCESS_INFORMATION pi;
255 STARTUPINFOW si;
256 void *redir;
258 GetSystemDirectoryW( app, MAX_PATH - ARRAY_SIZE( L"\\wineboot.exe" ));
259 lstrcatW( app, L"\\wineboot.exe" );
260 lstrcpyW( cmdline, app );
262 if (flags & EWX_FORCE) lstrcatW( cmdline, L" --kill" );
263 else
265 lstrcatW( cmdline, L" --end-session" );
266 if (flags & EWX_FORCEIFHUNG) lstrcatW( cmdline, L" --force" );
268 if (!(flags & EWX_REBOOT)) lstrcatW( cmdline, L" --shutdown" );
270 memset( &si, 0, sizeof si );
271 si.cb = sizeof si;
272 Wow64DisableWow64FsRedirection( &redir );
273 if (!CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
275 Wow64RevertWow64FsRedirection( redir );
276 ERR( "Failed to run %s\n", debugstr_w(cmdline) );
277 return FALSE;
279 Wow64RevertWow64FsRedirection( redir );
280 CloseHandle( pi.hProcess );
281 CloseHandle( pi.hThread );
282 return TRUE;
285 /***********************************************************************
286 * LockWorkStation (USER32.@)
288 BOOL WINAPI LockWorkStation(void)
290 TRACE(": stub\n");
291 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
292 return FALSE;
295 /***********************************************************************
296 * RegisterServicesProcess (USER32.@)
298 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
300 FIXME("(0x%x): stub\n", ServicesProcessId);
301 return 0;
304 /***********************************************************************
305 * ShutdownBlockReasonCreate (USER32.@)
307 BOOL WINAPI ShutdownBlockReasonCreate(HWND hwnd, LPCWSTR reason)
309 FIXME("(%p, %s): stub\n", hwnd, debugstr_w(reason));
310 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
311 return FALSE;
314 /***********************************************************************
315 * ShutdownBlockReasonDestroy (USER32.@)
317 BOOL WINAPI ShutdownBlockReasonDestroy(HWND hwnd)
319 FIXME("(%p): stub\n", hwnd);
320 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
321 return FALSE;