Release 9.12.
[wine.git] / dlls / user32 / user_main.c
blobee4dbc190cd840ddc2a8f02948b62dd50d8e673f
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 "ntstatus.h"
22 #define WIN32_NO_STATUS
23 #include "user_private.h"
24 #include "controls.h"
25 #include "imm.h"
26 #include "immdev.h"
27 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(graphics);
31 WINE_DECLARE_DEBUG_CHANNEL(message);
33 HMODULE user32_module = 0;
35 extern void WDML_NotifyThreadDetach(void);
38 /***********************************************************************
39 * UserRealizePalette (USER32.@)
41 UINT WINAPI UserRealizePalette( HDC hdc )
43 return NtUserRealizePalette( hdc );
47 /***********************************************************************
48 * dpiaware_init
50 * Initialize the DPI awareness style.
52 static void dpiaware_init(void)
54 WCHAR buffer[256];
55 DWORD option;
57 if (!LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb->ProcessParameters->ImagePathName,
58 L"dpiAwareness", REG_DWORD, &option, sizeof(option), NULL ))
60 TRACE( "got option %lx\n", option );
61 if (option <= 2)
63 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~(ULONG_PTR)option );
64 return;
68 if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2016/WindowsSettings",
69 L"dpiAwareness", buffer, ARRAY_SIZE(buffer), NULL ))
71 static const WCHAR * const types[] = { L"unaware", L"system", L"permonitor", L"permonitorv2" };
72 WCHAR *p, *start, *end;
73 ULONG_PTR i;
75 TRACE( "got dpiAwareness=%s\n", debugstr_w(buffer) );
76 for (start = buffer; *start; start = end)
78 start += wcsspn( start, L" \t\r\n" );
79 if (!(end = wcschr( start, ',' ))) end = start + lstrlenW(start);
80 else *end++ = 0;
81 if ((p = wcspbrk( start, L" \t\r\n" ))) *p = 0;
82 for (i = 0; i < ARRAY_SIZE(types); i++)
84 if (wcsicmp( start, types[i] )) continue;
85 SetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
86 return;
90 else if (QueryActCtxSettingsW( 0, NULL, L"http://schemas.microsoft.com/SMI/2005/WindowsSettings",
91 L"dpiAware", buffer, ARRAY_SIZE(buffer), NULL ))
93 TRACE( "got dpiAware=%s\n", debugstr_w(buffer) );
94 if (!wcsicmp( buffer, L"true" ))
95 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
96 else if (!wcsicmp( buffer, L"true/pm" ) || !wcsicmp( buffer, L"per monitor" ))
97 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
98 else
99 SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
103 static NTSTATUS WINAPI User32CopyImage( void *args, ULONG size )
105 const struct copy_image_params *params = args;
106 HANDLE ret = CopyImage( params->hwnd, params->type, params->dx, params->dy, params->flags );
107 if (!ret) return STATUS_NO_MEMORY;
108 return NtCallbackReturn( &ret, sizeof(ret), STATUS_SUCCESS );
111 static NTSTATUS WINAPI User32DrawNonClientButton( void *args, ULONG size )
113 const struct draw_non_client_button_params *params = args;
114 user_api->pNonClientButtonDraw( params->hwnd, params->hdc, params->type, params->rect,
115 params->down, params->grayed );
116 return STATUS_SUCCESS;
119 static NTSTATUS WINAPI User32DrawScrollBar( void *args, ULONG size )
121 const struct draw_scroll_bar_params *params = args;
122 RECT rect = params->rect;
123 user_api->pScrollBarDraw( params->hwnd, params->hdc, params->bar, params->hit_test,
124 &params->tracking_info, params->arrows, params->interior,
125 &rect, params->enable_flags, params->arrow_size, params->thumb_pos,
126 params->thumb_size, params->vertical );
127 return STATUS_SUCCESS;
130 static NTSTATUS WINAPI User32DrawText( void *args, ULONG size )
132 const struct draw_text_params *params = args;
133 struct draw_text_result result;
135 size -= FIELD_OFFSET( struct draw_text_params, str );
136 result.rect = params->rect;
137 result.height = DrawTextW( params->hdc, params->str, size / sizeof(WCHAR), &result.rect, params->flags );
138 return NtCallbackReturn( &result, sizeof(result), STATUS_SUCCESS );
141 static NTSTATUS WINAPI User32ImmProcessKey( void *args, ULONG size )
143 const struct imm_process_key_params *params = args;
144 if (ImmProcessKey( params->hwnd, params->hkl, params->vkey, params->key_data, 0 ))
145 return STATUS_SUCCESS;
146 return STATUS_INVALID_PARAMETER;
149 static NTSTATUS WINAPI User32ImmTranslateMessage( void *args, ULONG size )
151 const struct imm_translate_message_params *params = args;
152 if (ImmTranslateMessage( params->hwnd, params->msg, params->wparam, params->key_data ))
153 return STATUS_SUCCESS;
154 return STATUS_INVALID_PARAMETER;
157 static NTSTATUS WINAPI User32LoadImage( void *args, ULONG size )
159 const struct load_image_params *params = args;
160 HANDLE ret = LoadImageW( params->hinst, params->name, params->type,
161 params->dx, params->dy, params->flags );
162 if (!ret) return STATUS_NO_MEMORY;
163 return NtCallbackReturn( &ret, sizeof(ret), STATUS_SUCCESS );
166 static NTSTATUS WINAPI User32LoadSysMenu( void *args, ULONG size )
168 const struct load_sys_menu_params *params = args;
169 HMENU ret = LoadMenuW( user32_module, params->mdi ? L"SYSMENUMDI" : L"SYSMENU" );
170 if (!ret) return STATUS_NO_MEMORY;
171 return NtCallbackReturn( &ret, sizeof(ret), STATUS_SUCCESS );
174 static NTSTATUS WINAPI User32FreeCachedClipboardData( void *args, ULONG size )
176 const struct free_cached_data_params *params = args;
177 free_cached_data( params->format, params->handle );
178 return STATUS_SUCCESS;
181 static NTSTATUS WINAPI User32PostDDEMessage( void *args, ULONG size )
183 const struct post_dde_message_params *params = args;
184 return post_dde_message( params->hwnd, params->msg, params->wparam, params->lparam,
185 params->dest_tid, params->type );
188 static NTSTATUS WINAPI User32RenderSsynthesizedFormat( void *args, ULONG size )
190 const struct render_synthesized_format_params *params = args;
191 render_synthesized_format( params->format, params->from );
192 return STATUS_SUCCESS;
195 static NTSTATUS WINAPI User32LoadDriver( void *args, ULONG size )
197 const WCHAR *path = args;
198 UNICODE_STRING str;
199 HMODULE module;
201 RtlInitUnicodeString( &str, path );
202 return LdrLoadDll( L"c:\\windows\\system32", 0, &str, &module );
205 static NTSTATUS WINAPI User32UnpackDDEMessage( void *args, ULONG size )
207 const struct unpack_dde_message_params *params = args;
208 struct unpack_dde_message_result result = { .wparam = params->wparam, .lparam = params->lparam };
210 size -= FIELD_OFFSET( struct unpack_dde_message_params, data );
211 if (!unpack_dde_message( params->hwnd, params->message, &result.wparam, &result.lparam,
212 params->data, size ))
213 return STATUS_NO_MEMORY;
215 return NtCallbackReturn( &result, sizeof(result), STATUS_SUCCESS );
218 static KERNEL_CALLBACK_PROC kernel_callback_table[NtUserCallCount] =
220 User32CallEnumDisplayMonitor,
221 User32CallSendAsyncCallback,
222 User32CallWinEventHook,
223 User32CallWindowProc,
224 User32CallWindowsHook,
225 User32CopyImage,
226 User32DrawNonClientButton,
227 User32DrawScrollBar,
228 User32DrawText,
229 User32FreeCachedClipboardData,
230 User32ImmProcessKey,
231 User32ImmTranslateMessage,
232 User32InitBuiltinClasses,
233 User32LoadDriver,
234 User32LoadImage,
235 User32LoadSysMenu,
236 User32PostDDEMessage,
237 User32RenderSsynthesizedFormat,
238 User32UnpackDDEMessage,
242 /***********************************************************************
243 * USER initialisation routine
245 static BOOL process_attach(void)
247 NtCurrentTeb()->Peb->KernelCallbackTable = kernel_callback_table;
249 winproc_init();
250 dpiaware_init();
251 SYSPARAMS_Init();
253 return TRUE;
257 /**********************************************************************
258 * thread_detach
260 static void thread_detach(void)
262 struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
264 NtUserCallNoParam( NtUserExitingThread );
266 WDML_NotifyThreadDetach();
268 NtUserCallNoParam( NtUserThreadDetach );
269 HeapFree( GetProcessHeap(), 0, (void *)(UINT_PTR)thread_info->wmchar_data );
273 /***********************************************************************
274 * UserClientDllInitialize (USER32.@)
276 * USER dll initialisation routine (exported as UserClientDllInitialize for compatibility).
278 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
280 static HMODULE imm32_module;
281 BOOL ret = TRUE;
283 switch(reason)
285 case DLL_PROCESS_ATTACH:
286 user32_module = inst;
287 ret = process_attach();
288 if(ret)
289 imm32_module = LoadLibraryW(L"imm32.dll");
290 break;
291 case DLL_THREAD_DETACH:
292 thread_detach();
293 break;
294 case DLL_PROCESS_DETACH:
295 FreeLibrary(imm32_module);
296 break;
298 return ret;
302 /***********************************************************************
303 * ExitWindowsEx (USER32.@)
305 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
307 WCHAR app[MAX_PATH];
308 WCHAR cmdline[MAX_PATH + 64];
309 PROCESS_INFORMATION pi;
310 STARTUPINFOW si;
311 void *redir;
313 GetSystemDirectoryW( app, MAX_PATH - ARRAY_SIZE( L"\\wineboot.exe" ));
314 lstrcatW( app, L"\\wineboot.exe" );
315 lstrcpyW( cmdline, app );
317 if (flags & EWX_FORCE) lstrcatW( cmdline, L" --kill" );
318 else
320 lstrcatW( cmdline, L" --end-session" );
321 if (flags & EWX_FORCEIFHUNG) lstrcatW( cmdline, L" --force" );
323 if (!(flags & EWX_REBOOT)) lstrcatW( cmdline, L" --shutdown" );
325 memset( &si, 0, sizeof si );
326 si.cb = sizeof si;
327 Wow64DisableWow64FsRedirection( &redir );
328 if (!CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
330 Wow64RevertWow64FsRedirection( redir );
331 ERR( "Failed to run %s\n", debugstr_w(cmdline) );
332 return FALSE;
334 Wow64RevertWow64FsRedirection( redir );
335 CloseHandle( pi.hProcess );
336 CloseHandle( pi.hThread );
337 return TRUE;
340 /***********************************************************************
341 * LockWorkStation (USER32.@)
343 BOOL WINAPI LockWorkStation(void)
345 TRACE(": stub\n");
346 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
347 return FALSE;
350 /***********************************************************************
351 * RegisterServicesProcess (USER32.@)
353 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
355 FIXME("(0x%lx): stub\n", ServicesProcessId);
356 return 0;
359 /***********************************************************************
360 * ShutdownBlockReasonCreate (USER32.@)
362 BOOL WINAPI ShutdownBlockReasonCreate(HWND hwnd, LPCWSTR reason)
364 FIXME("(%p, %s): stub\n", hwnd, debugstr_w(reason));
365 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
366 return FALSE;
369 /***********************************************************************
370 * ShutdownBlockReasonDestroy (USER32.@)
372 BOOL WINAPI ShutdownBlockReasonDestroy(HWND hwnd)
374 FIXME("(%p): stub\n", hwnd);
375 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
376 return FALSE;
379 const char *SPY_GetMsgName( UINT msg, HWND hwnd )
381 char buf[128];
382 NtUserMessageCall( hwnd, msg, ARRAYSIZE(buf), 0, buf, NtUserSpyGetMsgName, FALSE );
383 return wine_dbg_sprintf( "%s", buf );
386 void SPY_EnterMessage( INT flag, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
388 if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, 0, NtUserSpyEnter, flag );
391 void SPY_ExitMessage( INT flag, HWND hwnd, UINT msg, LRESULT lreturn, WPARAM wparam, LPARAM lparam )
393 if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, (void *)lreturn,
394 NtUserSpyExit, flag );