win32u: Move user_handles from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3e4f83f762
commit
018f8014a3
|
@ -50,19 +50,6 @@ extern void USER_unload_driver(void) DECLSPEC_HIDDEN;
|
|||
|
||||
struct received_message_info;
|
||||
|
||||
struct user_object
|
||||
{
|
||||
HANDLE handle;
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
#define OBJ_OTHER_PROCESS ((void *)1) /* returned by get_user_handle_ptr on unknown handles */
|
||||
|
||||
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN;
|
||||
void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* type of message-sending functions that need special WM_CHAR handling */
|
||||
enum wm_char_mapping
|
||||
{
|
||||
|
|
|
@ -36,9 +36,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
||||
#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
|
||||
#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
|
||||
|
||||
static DWORD process_layout = ~0u;
|
||||
|
||||
|
||||
|
@ -87,31 +84,12 @@ static inline void set_win_data( void *ptr, LONG_PTR val, UINT size )
|
|||
}
|
||||
|
||||
|
||||
static void *user_handles[NB_USER_HANDLES];
|
||||
|
||||
/***********************************************************************
|
||||
* alloc_user_handle
|
||||
*/
|
||||
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type )
|
||||
{
|
||||
HANDLE handle = 0;
|
||||
|
||||
SERVER_START_REQ( alloc_user_handle )
|
||||
{
|
||||
if (!wine_server_call_err( req )) handle = wine_server_ptr_handle( reply->handle );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (handle)
|
||||
{
|
||||
UINT index = USER_HANDLE_TO_INDEX( handle );
|
||||
|
||||
assert( index < NB_USER_HANDLES );
|
||||
ptr->handle = handle;
|
||||
ptr->type = type;
|
||||
InterlockedExchangePointer( &user_handles[index], ptr );
|
||||
}
|
||||
return handle;
|
||||
return UlongToHandle( NtUserCallTwoParam( (UINT_PTR)ptr, type, NtUserAllocHandle ));
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,23 +98,7 @@ HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type )
|
|||
*/
|
||||
void *get_user_handle_ptr( HANDLE handle, unsigned int type )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WORD index = USER_HANDLE_TO_INDEX( handle );
|
||||
|
||||
if (index >= NB_USER_HANDLES) return NULL;
|
||||
|
||||
USER_Lock();
|
||||
if ((ptr = user_handles[index]))
|
||||
{
|
||||
if (ptr->type == type &&
|
||||
((UINT)(UINT_PTR)ptr->handle == (UINT)(UINT_PTR)handle ||
|
||||
!HIWORD(handle) || HIWORD(handle) == 0xffff))
|
||||
return ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
else ptr = OBJ_OTHER_PROCESS;
|
||||
USER_Unlock();
|
||||
return ptr;
|
||||
return (void *)NtUserCallTwoParam( HandleToUlong(handle), type, NtUserGetHandlePtr );
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,21 +117,7 @@ void release_user_handle_ptr( void *ptr )
|
|||
*/
|
||||
void *free_user_handle( HANDLE handle, unsigned int type )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WORD index = USER_HANDLE_TO_INDEX( handle );
|
||||
|
||||
if ((ptr = get_user_handle_ptr( handle, type )) && ptr != OBJ_OTHER_PROCESS)
|
||||
{
|
||||
SERVER_START_REQ( free_user_handle )
|
||||
{
|
||||
req->handle = wine_server_user_handle( handle );
|
||||
if (wine_server_call( req )) ptr = NULL;
|
||||
else InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
USER_Unlock();
|
||||
}
|
||||
return ptr;
|
||||
return UlongToHandle( NtUserCallTwoParam( HandleToUlong(handle), type, NtUserFreeHandle ));
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,7 +130,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
|
|||
HINSTANCE instance, BOOL unicode,
|
||||
DWORD style, DWORD ex_style )
|
||||
{
|
||||
WORD index;
|
||||
WND *win;
|
||||
HWND handle = 0, full_parent = 0, full_owner = 0;
|
||||
struct tagCLASS *class = NULL;
|
||||
|
@ -253,8 +200,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
|
|||
|
||||
USER_Lock();
|
||||
|
||||
index = USER_HANDLE_TO_INDEX(handle);
|
||||
assert( index < NB_USER_HANDLES );
|
||||
win->obj.handle = handle;
|
||||
win->obj.type = NTUSER_OBJ_WINDOW;
|
||||
win->parent = full_parent;
|
||||
|
@ -264,7 +209,7 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
|
|||
win->cbWndExtra = extra_bytes;
|
||||
win->dpi = dpi;
|
||||
win->dpi_awareness = awareness;
|
||||
InterlockedExchangePointer( &user_handles[index], win );
|
||||
NtUserCallTwoParam( HandleToUlong(handle), (UINT_PTR)win, NtUserSetHandlePtr );
|
||||
if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE;
|
||||
return win;
|
||||
}
|
||||
|
@ -278,7 +223,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
|
|||
static void free_window_handle( HWND hwnd )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WORD index = USER_HANDLE_TO_INDEX(hwnd);
|
||||
|
||||
if ((ptr = get_user_handle_ptr( hwnd, NTUSER_OBJ_WINDOW )) && ptr != OBJ_OTHER_PROCESS)
|
||||
{
|
||||
|
@ -286,7 +230,7 @@ static void free_window_handle( HWND hwnd )
|
|||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
wine_server_call( req );
|
||||
InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
|
||||
NtUserCallTwoParam( HandleToUlong(hwnd), 0, NtUserSetHandlePtr );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
USER_Unlock();
|
||||
|
@ -1156,20 +1100,7 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
|
|||
*/
|
||||
static WND *next_thread_window( HWND *hwnd )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WND *win;
|
||||
WORD index = *hwnd ? USER_HANDLE_TO_INDEX( *hwnd ) + 1 : 0;
|
||||
|
||||
while (index < NB_USER_HANDLES)
|
||||
{
|
||||
if (!(ptr = user_handles[index++])) continue;
|
||||
if (ptr->type != NTUSER_OBJ_WINDOW) continue;
|
||||
win = (WND *)ptr;
|
||||
if (win->tid != GetCurrentThreadId()) continue;
|
||||
*hwnd = ptr->handle;
|
||||
return win;
|
||||
}
|
||||
return NULL;
|
||||
return (WND *)NtUserCallOneParam( (UINT_PTR)hwnd, NtUserNextThreadWindow );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1187,7 +1118,7 @@ void destroy_thread_windows(void)
|
|||
while ((win = next_thread_window( &hwnd )))
|
||||
{
|
||||
free_dce( win->dce, win->obj.handle );
|
||||
InterlockedCompareExchangePointer( &user_handles[USER_HANDLE_TO_INDEX(hwnd)], NULL, win );
|
||||
NtUserCallTwoParam( HandleToUlong(hwnd), 0, NtUserSetHandlePtr );
|
||||
win->obj.handle = *free_list_ptr;
|
||||
free_list_ptr = (WND **)&win->obj.handle;
|
||||
}
|
||||
|
|
|
@ -33,43 +33,6 @@
|
|||
struct tagCLASS;
|
||||
struct tagDIALOGINFO;
|
||||
|
||||
typedef struct tagWND
|
||||
{
|
||||
struct user_object obj; /* object header */
|
||||
HWND parent; /* Window parent */
|
||||
HWND owner; /* Window owner */
|
||||
struct tagCLASS *class; /* Window class */
|
||||
struct dce *dce; /* DCE pointer */
|
||||
WNDPROC winproc; /* Window procedure */
|
||||
DWORD tid; /* Owner thread id */
|
||||
HINSTANCE hInstance; /* Window hInstance (from CreateWindow) */
|
||||
RECT client_rect; /* Client area rel. to parent client area */
|
||||
RECT window_rect; /* Whole window rel. to parent client area */
|
||||
RECT visible_rect; /* Visible part of the whole rect, rel. to parent client area */
|
||||
RECT normal_rect; /* Normal window rect saved when maximized/minimized */
|
||||
POINT min_pos; /* Position for minimized window */
|
||||
POINT max_pos; /* Position for maximized window */
|
||||
LPWSTR text; /* Window text */
|
||||
void *pScroll; /* Scroll-bar info */
|
||||
DWORD dwStyle; /* Window style (from CreateWindow) */
|
||||
DWORD dwExStyle; /* Extended style (from CreateWindowEx) */
|
||||
UINT_PTR wIDmenu; /* ID or hmenu (from CreateWindow) */
|
||||
DWORD helpContext; /* Help context ID */
|
||||
UINT flags; /* Misc. flags (see below) */
|
||||
HMENU hSysMenu; /* window's copy of System Menu */
|
||||
HICON hIcon; /* window's icon */
|
||||
HICON hIconSmall; /* window's small icon */
|
||||
HICON hIconSmall2; /* window's secondary small icon, derived from hIcon */
|
||||
UINT dpi; /* window DPI */
|
||||
DPI_AWARENESS dpi_awareness; /* DPI awareness */
|
||||
struct window_surface *surface; /* Window surface if any */
|
||||
struct tagDIALOGINFO *dlgInfo;/* Dialog additional info (dialogs only) */
|
||||
int pixel_format; /* Pixel format set by the graphics driver */
|
||||
int cbWndExtra; /* class cbWndExtra at window creation */
|
||||
DWORD_PTR userdata; /* User private data */
|
||||
DWORD wExtra[1]; /* Window extra bytes */
|
||||
} WND;
|
||||
|
||||
/* WND flags values */
|
||||
#define WIN_RESTORE_MAX 0x0001 /* Maximize when restoring */
|
||||
#define WIN_NEED_SIZE 0x0002 /* Internal WM_SIZE is needed */
|
||||
|
|
|
@ -34,6 +34,59 @@ struct user_callbacks
|
|||
HWND (WINAPI *pWindowFromDC)( HDC );
|
||||
};
|
||||
|
||||
struct user_object
|
||||
{
|
||||
HANDLE handle;
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
#define OBJ_OTHER_PROCESS ((void *)1) /* returned by get_user_handle_ptr on unknown handles */
|
||||
|
||||
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
void set_user_handle_ptr( HANDLE handle, struct user_object *ptr ) DECLSPEC_HIDDEN;
|
||||
void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN;
|
||||
void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct tagWND
|
||||
{
|
||||
struct user_object obj; /* object header */
|
||||
HWND parent; /* Window parent */
|
||||
HWND owner; /* Window owner */
|
||||
struct tagCLASS *class; /* Window class */
|
||||
struct dce *dce; /* DCE pointer */
|
||||
WNDPROC winproc; /* Window procedure */
|
||||
DWORD tid; /* Owner thread id */
|
||||
HINSTANCE hInstance; /* Window hInstance (from CreateWindow) */
|
||||
RECT client_rect; /* Client area rel. to parent client area */
|
||||
RECT window_rect; /* Whole window rel. to parent client area */
|
||||
RECT visible_rect; /* Visible part of the whole rect, rel. to parent client area */
|
||||
RECT normal_rect; /* Normal window rect saved when maximized/minimized */
|
||||
POINT min_pos; /* Position for minimized window */
|
||||
POINT max_pos; /* Position for maximized window */
|
||||
WCHAR *text; /* Window text */
|
||||
void *pScroll; /* Scroll-bar info */
|
||||
DWORD dwStyle; /* Window style (from CreateWindow) */
|
||||
DWORD dwExStyle; /* Extended style (from CreateWindowEx) */
|
||||
UINT_PTR wIDmenu; /* ID or hmenu (from CreateWindow) */
|
||||
DWORD helpContext; /* Help context ID */
|
||||
UINT flags; /* Misc. flags (see below) */
|
||||
HMENU hSysMenu; /* window's copy of System Menu */
|
||||
HICON hIcon; /* window's icon */
|
||||
HICON hIconSmall; /* window's small icon */
|
||||
HICON hIconSmall2; /* window's secondary small icon, derived from hIcon */
|
||||
UINT dpi; /* window DPI */
|
||||
DPI_AWARENESS dpi_awareness; /* DPI awareness */
|
||||
struct window_surface *surface; /* Window surface if any */
|
||||
struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */
|
||||
int pixel_format; /* Pixel format set by the graphics driver */
|
||||
int cbWndExtra; /* class cbWndExtra at window creation */
|
||||
DWORD_PTR userdata; /* User private data */
|
||||
DWORD wExtra[1]; /* Window extra bytes */
|
||||
} WND;
|
||||
|
||||
WND *next_thread_window_ptr( HWND *hwnd );
|
||||
|
||||
/* this is the structure stored in TEB->Win32ClientInfo */
|
||||
/* no attempt is made to keep the layout compatible with the Windows one */
|
||||
struct user_thread_info
|
||||
|
|
|
@ -4589,6 +4589,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
|
|||
case 1: user_unlock(); return 0;
|
||||
default: user_check_not_lock(); return 0;
|
||||
}
|
||||
case NtUserNextThreadWindow:
|
||||
return (UINT_PTR)next_thread_window_ptr( (HWND *)arg );
|
||||
case NtUserSetCallbacks:
|
||||
return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg );
|
||||
default:
|
||||
|
@ -4615,9 +4617,18 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code
|
|||
case NtUserUnhookWindowsHook:
|
||||
return unhook_windows_hook( arg1, (HOOKPROC)arg2 );
|
||||
/* temporary exports */
|
||||
case NtUserAllocHandle:
|
||||
return HandleToUlong( alloc_user_handle( (struct user_object *)arg1, arg2 ));
|
||||
case NtUserFreeHandle:
|
||||
return (UINT_PTR)free_user_handle( UlongToHandle(arg1), arg2 );
|
||||
case NtUserGetHandlePtr:
|
||||
return (UINT_PTR)get_user_handle_ptr( UlongToHandle(arg1), arg2 );
|
||||
case NtUserRegisterWindowSurface:
|
||||
register_window_surface( (struct window_surface *)arg1, (struct window_surface *)arg2 );
|
||||
return 0;
|
||||
case NtUserSetHandlePtr:
|
||||
set_user_handle_ptr( UlongToHandle(arg1), (struct user_object *)arg2 );
|
||||
return 0;
|
||||
default:
|
||||
FIXME( "invalid code %u\n", code );
|
||||
return 0;
|
||||
|
|
|
@ -24,15 +24,124 @@
|
|||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "win32u_private.h"
|
||||
#include "ntuser_private.h"
|
||||
#include "wine/server.h"
|
||||
|
||||
#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
|
||||
#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
|
||||
|
||||
static void *user_handles[NB_USER_HANDLES];
|
||||
|
||||
static struct list window_surfaces = LIST_INIT( window_surfaces );
|
||||
static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/***********************************************************************
|
||||
* alloc_user_handle
|
||||
*/
|
||||
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type )
|
||||
{
|
||||
HANDLE handle = 0;
|
||||
|
||||
SERVER_START_REQ( alloc_user_handle )
|
||||
{
|
||||
if (!wine_server_call_err( req )) handle = wine_server_ptr_handle( reply->handle );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (handle)
|
||||
{
|
||||
UINT index = USER_HANDLE_TO_INDEX( handle );
|
||||
|
||||
assert( index < NB_USER_HANDLES );
|
||||
ptr->handle = handle;
|
||||
ptr->type = type;
|
||||
InterlockedExchangePointer( &user_handles[index], ptr );
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_user_handle_ptr
|
||||
*/
|
||||
void *get_user_handle_ptr( HANDLE handle, unsigned int type )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WORD index = USER_HANDLE_TO_INDEX( handle );
|
||||
|
||||
if (index >= NB_USER_HANDLES) return NULL;
|
||||
|
||||
user_lock();
|
||||
if ((ptr = user_handles[index]))
|
||||
{
|
||||
if (ptr->type == type &&
|
||||
((UINT)(UINT_PTR)ptr->handle == (UINT)(UINT_PTR)handle ||
|
||||
!HIWORD(handle) || HIWORD(handle) == 0xffff))
|
||||
return ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
else ptr = OBJ_OTHER_PROCESS;
|
||||
user_unlock();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* set_user_handle_ptr
|
||||
*/
|
||||
void set_user_handle_ptr( HANDLE handle, struct user_object *ptr )
|
||||
{
|
||||
WORD index = USER_HANDLE_TO_INDEX(handle);
|
||||
assert( index < NB_USER_HANDLES );
|
||||
InterlockedExchangePointer( &user_handles[index], ptr );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* free_user_handle
|
||||
*/
|
||||
void *free_user_handle( HANDLE handle, unsigned int type )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WORD index = USER_HANDLE_TO_INDEX( handle );
|
||||
|
||||
if ((ptr = get_user_handle_ptr( handle, type )) && ptr != OBJ_OTHER_PROCESS)
|
||||
{
|
||||
SERVER_START_REQ( free_user_handle )
|
||||
{
|
||||
req->handle = wine_server_user_handle( handle );
|
||||
if (wine_server_call( req )) ptr = NULL;
|
||||
else InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
user_unlock();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* next_thread_window
|
||||
*/
|
||||
WND *next_thread_window_ptr( HWND *hwnd )
|
||||
{
|
||||
struct user_object *ptr;
|
||||
WND *win;
|
||||
WORD index = *hwnd ? USER_HANDLE_TO_INDEX( *hwnd ) + 1 : 0;
|
||||
|
||||
while (index < NB_USER_HANDLES)
|
||||
{
|
||||
if (!(ptr = user_handles[index++])) continue;
|
||||
if (ptr->type != NTUSER_OBJ_WINDOW) continue;
|
||||
win = (WND *)ptr;
|
||||
if (win->tid != GetCurrentThreadId()) continue;
|
||||
*hwnd = ptr->handle;
|
||||
return win;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* register_window_surface
|
||||
*
|
||||
|
|
|
@ -88,6 +88,7 @@ enum
|
|||
NtUserGetDeskPattern,
|
||||
NtUserIncrementKeyStateCounter,
|
||||
NtUserLock,
|
||||
NtUserNextThreadWindow,
|
||||
NtUserSetCallbacks,
|
||||
};
|
||||
|
||||
|
@ -100,7 +101,11 @@ enum
|
|||
NtUserMonitorFromRect,
|
||||
NtUserUnhookWindowsHook,
|
||||
/* temporary exports */
|
||||
NtUserAllocHandle,
|
||||
NtUserFreeHandle,
|
||||
NtUserGetHandlePtr,
|
||||
NtUserRegisterWindowSurface,
|
||||
NtUserSetHandlePtr,
|
||||
};
|
||||
|
||||
/* color index used to retrieve system 55aa brush */
|
||||
|
|
Loading…
Reference in New Issue