d3d10: Return the read value from read_dword().
[wine.git] / dlls / user32 / user_main.c
blob62097edcdaa649b230e62a21933b5dad438d15c6
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 /***********************************************************************
56 * USER_Lock
58 void USER_Lock(void)
60 EnterCriticalSection( &user_section );
64 /***********************************************************************
65 * USER_Unlock
67 void USER_Unlock(void)
69 LeaveCriticalSection( &user_section );
73 /***********************************************************************
74 * USER_CheckNotLock
76 * Make sure that we don't hold the user lock.
78 void USER_CheckNotLock(void)
80 if (RtlIsCriticalSectionLockedByThread(&user_section))
82 ERR( "BUG: holding USER lock\n" );
83 DebugBreak();
88 /***********************************************************************
89 * UserSelectPalette (Not a Windows API)
91 static HPALETTE WINAPI UserSelectPalette( HDC hDC, HPALETTE hPal, BOOL bForceBackground )
93 WORD wBkgPalette = 1;
95 if (!bForceBackground && (hPal != GetStockObject(DEFAULT_PALETTE)))
97 HWND hwnd = WindowFromDC( hDC );
98 if (hwnd)
100 HWND hForeground = GetForegroundWindow();
101 /* set primary palette if it's related to current active */
102 if (hForeground == hwnd || IsChild(hForeground,hwnd))
104 wBkgPalette = 0;
105 hPrimaryPalette = hPal;
109 return pfnGDISelectPalette( hDC, hPal, wBkgPalette);
113 /***********************************************************************
114 * UserRealizePalette (USER32.@)
116 UINT WINAPI UserRealizePalette( HDC hDC )
118 UINT realized = pfnGDIRealizePalette( hDC );
120 /* do not send anything if no colors were changed */
121 if (realized && GetCurrentObject( hDC, OBJ_PAL ) == hPrimaryPalette)
123 /* send palette change notification */
124 HWND hWnd = WindowFromDC( hDC );
125 if (hWnd) SendMessageTimeoutW( HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0,
126 SMTO_ABORTIFHUNG, 2000, NULL );
128 return realized;
132 /***********************************************************************
133 * palette_init
135 * Patch the function pointers in GDI for SelectPalette and RealizePalette
137 static void palette_init(void)
139 void **ptr;
140 HMODULE module = GetModuleHandleA( "gdi32" );
141 if (!module)
143 ERR( "cannot get GDI32 handle\n" );
144 return;
146 if ((ptr = (void**)GetProcAddress( module, "pfnSelectPalette" )))
147 pfnGDISelectPalette = InterlockedExchangePointer( ptr, UserSelectPalette );
148 else ERR( "cannot find pfnSelectPalette in GDI32\n" );
149 if ((ptr = (void**)GetProcAddress( module, "pfnRealizePalette" )))
150 pfnGDIRealizePalette = InterlockedExchangePointer( ptr, UserRealizePalette );
151 else ERR( "cannot find pfnRealizePalette in GDI32\n" );
155 /***********************************************************************
156 * dpiaware_init
158 * Initialize the DPI awareness style.
160 static void dpiaware_init(void)
162 WCHAR buffer[256];
163 DWORD option;
165 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb->ProcessParameters->ImagePathName,
166 L"dpiAwareness", REG_DWORD, &option, sizeof(option), NULL ))
168 TRACE( "got option %x\n", option );
169 if (option <= 2)
171 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~(ULONG_PTR)option );
172 return;
176 if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2016/WindowsSettings",
177 L"dpiAwareness", buffer, ARRAY_SIZE(buffer), NULL ))
179 static const WCHAR * const types[] = { L"unaware", L"system", L"permonitor", L"permonitorv2" };
180 WCHAR *p, *start, *end;
181 ULONG_PTR i;
183 TRACE( "got dpiAwareness=%s\n", debugstr_w(buffer) );
184 for (start = buffer; *start; start = end)
186 start += wcsspn( start, L" \t\r\n" );
187 if (!(end = wcschr( start, ',' ))) end = start + lstrlenW(start);
188 else *end++ = 0;
189 if ((p = wcspbrk( start, L" \t\r\n" ))) *p = 0;
190 for (i = 0; i < ARRAY_SIZE(types); i++)
192 if (wcsicmp( start, types[i] )) continue;
193 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
194 return;
198 else if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2005/WindowsSettings",
199 L"dpiAware", buffer, ARRAY_SIZE(buffer), NULL ))
201 TRACE( "got dpiAware=%s\n", debugstr_w(buffer) );
202 if (!wcsicmp( buffer, L"true" ))
203 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
204 else if (!wcsicmp( buffer, L"true/pm" ) || !wcsicmp( buffer, L"per monitor" ))
205 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
206 else
207 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
212 static const void *kernel_callback_table[NtUserCallCount] =
214 User32CallEnumDisplayMonitor,
218 /***********************************************************************
219 * USER initialisation routine
221 static BOOL process_attach(void)
223 NtCurrentTeb()->Peb->KernelCallbackTable = kernel_callback_table;
225 dpiaware_init();
226 register_desktop_class();
228 /* Initialize system colors and metrics */
229 SYSPARAMS_Init();
231 /* Setup palette function pointers */
232 palette_init();
234 return TRUE;
238 /**********************************************************************
239 * USER_IsExitingThread
241 BOOL USER_IsExitingThread( DWORD tid )
243 return (tid == exiting_thread_id);
247 /**********************************************************************
248 * thread_detach
250 static void thread_detach(void)
252 struct user_thread_info *thread_info = get_user_thread_info();
254 exiting_thread_id = GetCurrentThreadId();
256 WDML_NotifyThreadDetach();
257 USER_Driver->pThreadDetach();
259 destroy_thread_windows();
260 CloseHandle( thread_info->server_queue );
261 HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );
262 HeapFree( GetProcessHeap(), 0, thread_info->key_state );
263 HeapFree( GetProcessHeap(), 0, thread_info->rawinput );
265 exiting_thread_id = 0;
269 /***********************************************************************
270 * UserClientDllInitialize (USER32.@)
272 * USER dll initialisation routine (exported as UserClientDllInitialize for compatibility).
274 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
276 static HMODULE imm32_module;
277 BOOL ret = TRUE;
279 switch(reason)
281 case DLL_PROCESS_ATTACH:
282 user32_module = inst;
283 ret = process_attach();
284 if(ret)
285 imm32_module = LoadLibraryW(L"imm32.dll");
286 break;
287 case DLL_THREAD_DETACH:
288 thread_detach();
289 break;
290 case DLL_PROCESS_DETACH:
291 USER_unload_driver();
292 FreeLibrary(imm32_module);
293 DeleteCriticalSection(&user_section);
294 break;
296 return ret;
300 /***********************************************************************
301 * ExitWindowsEx (USER32.@)
303 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
305 WCHAR app[MAX_PATH];
306 WCHAR cmdline[MAX_PATH + 64];
307 PROCESS_INFORMATION pi;
308 STARTUPINFOW si;
309 void *redir;
311 GetSystemDirectoryW( app, MAX_PATH - ARRAY_SIZE( L"\\wineboot.exe" ));
312 lstrcatW( app, L"\\wineboot.exe" );
313 lstrcpyW( cmdline, app );
315 if (flags & EWX_FORCE) lstrcatW( cmdline, L" --kill" );
316 else
318 lstrcatW( cmdline, L" --end-session" );
319 if (flags & EWX_FORCEIFHUNG) lstrcatW( cmdline, L" --force" );
321 if (!(flags & EWX_REBOOT)) lstrcatW( cmdline, L" --shutdown" );
323 memset( &si, 0, sizeof si );
324 si.cb = sizeof si;
325 Wow64DisableWow64FsRedirection( &redir );
326 if (!CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
328 Wow64RevertWow64FsRedirection( redir );
329 ERR( "Failed to run %s\n", debugstr_w(cmdline) );
330 return FALSE;
332 Wow64RevertWow64FsRedirection( redir );
333 CloseHandle( pi.hProcess );
334 CloseHandle( pi.hThread );
335 return TRUE;
338 /***********************************************************************
339 * LockWorkStation (USER32.@)
341 BOOL WINAPI LockWorkStation(void)
343 TRACE(": stub\n");
344 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
345 return FALSE;
348 /***********************************************************************
349 * RegisterServicesProcess (USER32.@)
351 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
353 FIXME("(0x%x): stub\n", ServicesProcessId);
354 return 0;
357 /***********************************************************************
358 * ShutdownBlockReasonCreate (USER32.@)
360 BOOL WINAPI ShutdownBlockReasonCreate(HWND hwnd, LPCWSTR reason)
362 FIXME("(%p, %s): stub\n", hwnd, debugstr_w(reason));
363 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
364 return FALSE;
367 /***********************************************************************
368 * ShutdownBlockReasonDestroy (USER32.@)
370 BOOL WINAPI ShutdownBlockReasonDestroy(HWND hwnd)
372 FIXME("(%p): stub\n", hwnd);
373 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
374 return FALSE;