win32u: Move cursor icon handle management 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
018f8014a3
commit
bb895f4f59
|
@ -52,46 +52,10 @@ WINE_DECLARE_DEBUG_CHANNEL(resource);
|
|||
( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
|
||||
#define PNG_SIGN RIFF_FOURCC(0x89,'P','N','G')
|
||||
|
||||
static struct list icon_cache = LIST_INIT( icon_cache );
|
||||
|
||||
/**********************************************************************
|
||||
* User objects management
|
||||
*/
|
||||
|
||||
struct cursoricon_frame
|
||||
{
|
||||
UINT width; /* frame-specific width */
|
||||
UINT height; /* frame-specific height */
|
||||
HBITMAP color; /* color bitmap */
|
||||
HBITMAP alpha; /* pre-multiplied alpha bitmap for 32-bpp icons */
|
||||
HBITMAP mask; /* mask bitmap (followed by color for 1-bpp icons) */
|
||||
POINT hotspot;
|
||||
};
|
||||
|
||||
struct cursoricon_object
|
||||
{
|
||||
struct user_object obj; /* object header */
|
||||
struct list entry; /* entry in shared icons list */
|
||||
ULONG_PTR param; /* opaque param used by 16-bit code */
|
||||
UNICODE_STRING module; /* module for icons loaded from resources */
|
||||
LPWSTR resname; /* resource name for icons loaded from resources */
|
||||
HRSRC rsrc; /* resource for shared icons */
|
||||
BOOL is_shared; /* whether this object is shared */
|
||||
BOOL is_icon; /* whether icon or cursor */
|
||||
BOOL is_ani; /* whether this object is a static cursor or an animated cursor */
|
||||
UINT delay; /* delay between this frame and the next (in jiffies) */
|
||||
union
|
||||
{
|
||||
struct cursoricon_frame frame; /* frame-specific icon data */
|
||||
struct
|
||||
{
|
||||
UINT num_frames; /* number of frames in the icon/cursor */
|
||||
UINT num_steps; /* number of sequence steps in the icon/cursor */
|
||||
HICON *frames; /* list of animated cursor frames */
|
||||
} ani;
|
||||
};
|
||||
};
|
||||
|
||||
static HBITMAP create_color_bitmap( int width, int height )
|
||||
{
|
||||
HDC hdc = get_display_dc();
|
||||
|
@ -151,50 +115,6 @@ static void free_icon_frame( struct cursoricon_frame *frame )
|
|||
if (frame->mask) DeleteObject( frame->mask );
|
||||
}
|
||||
|
||||
static BOOL free_icon_handle( HICON handle )
|
||||
{
|
||||
struct cursoricon_object *obj = free_user_handle( handle, NTUSER_OBJ_ICON );
|
||||
|
||||
if (obj == OBJ_OTHER_PROCESS) WARN( "icon handle %p from other process\n", handle );
|
||||
else if (obj)
|
||||
{
|
||||
ULONG_PTR param = obj->param;
|
||||
UINT i;
|
||||
|
||||
assert( !obj->rsrc ); /* shared icons can't be freed */
|
||||
|
||||
if (!obj->is_ani)
|
||||
{
|
||||
free_icon_frame( &obj->frame );
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < obj->ani.num_steps; i++)
|
||||
{
|
||||
HICON hFrame = obj->ani.frames[i];
|
||||
|
||||
if (hFrame)
|
||||
{
|
||||
UINT j;
|
||||
|
||||
free_icon_handle( obj->ani.frames[i] );
|
||||
for (j=0; j < obj->ani.num_steps; j++)
|
||||
{
|
||||
if (obj->ani.frames[j] == hFrame) obj->ani.frames[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, obj->ani.frames );
|
||||
}
|
||||
if (!IS_INTRESOURCE( obj->resname )) HeapFree( GetProcessHeap(), 0, obj->resname );
|
||||
HeapFree( GetProcessHeap(), 0, obj );
|
||||
if (wow_handlers.free_icon_param && param) wow_handlers.free_icon_param( param );
|
||||
USER_Driver->pDestroyCursorIcon( handle );
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ULONG_PTR get_icon_param( HICON handle )
|
||||
{
|
||||
ULONG_PTR ret = 0;
|
||||
|
@ -875,123 +795,6 @@ static const CURSORICONFILEDIRENTRY *CURSORICON_FindBestIconFile( const CURSORIC
|
|||
return &dir->idEntries[n];
|
||||
}
|
||||
|
||||
static HICON alloc_cursoricon_handle( BOOL is_icon )
|
||||
{
|
||||
struct cursoricon_object *obj;
|
||||
HICON handle;
|
||||
|
||||
if (!(obj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj) ))) return NULL;
|
||||
obj->is_icon = is_icon;
|
||||
|
||||
if (!(handle = alloc_user_handle( &obj->obj, NTUSER_OBJ_ICON ))) free( obj );
|
||||
return handle;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserSetCursorIconData (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtUserSetCursorIconData( HCURSOR cursor, UNICODE_STRING *module, UNICODE_STRING *res_name,
|
||||
struct cursoricon_desc *desc )
|
||||
{
|
||||
struct cursoricon_object *obj;
|
||||
UINT i, j;
|
||||
|
||||
if (!(obj = get_icon_ptr( cursor ))) return FALSE;
|
||||
|
||||
if (obj->is_ani || obj->frame.width)
|
||||
{
|
||||
/* already initialized */
|
||||
release_user_handle_ptr( obj );
|
||||
SetLastError( ERROR_INVALID_CURSOR_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
obj->delay = desc->delay;
|
||||
|
||||
if (desc->num_steps)
|
||||
{
|
||||
if (!(obj->ani.frames = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
desc->num_steps * sizeof(*obj->ani.frames) )))
|
||||
{
|
||||
release_user_handle_ptr( obj );
|
||||
return FALSE;
|
||||
}
|
||||
obj->is_ani = TRUE;
|
||||
obj->ani.num_steps = desc->num_steps;
|
||||
obj->ani.num_frames = desc->num_frames;
|
||||
}
|
||||
else obj->frame = desc->frames[0];
|
||||
|
||||
if (!res_name)
|
||||
obj->resname = NULL;
|
||||
else if (res_name->Length)
|
||||
{
|
||||
obj->resname = HeapAlloc( GetProcessHeap(), 0, res_name->Length + sizeof(WCHAR) );
|
||||
if (obj->resname)
|
||||
{
|
||||
memcpy( obj->resname, res_name->Buffer, res_name->Length );
|
||||
obj->resname[res_name->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
obj->resname = MAKEINTRESOURCEW( LOWORD(res_name->Buffer) );
|
||||
|
||||
if (module && module->Length && (obj->module.Buffer = HeapAlloc( GetProcessHeap(), 0, module->Length )))
|
||||
{
|
||||
memcpy( obj->module.Buffer, module->Buffer, module->Length );
|
||||
obj->module.Length = module->Length;
|
||||
}
|
||||
|
||||
if (obj->is_ani)
|
||||
{
|
||||
/* Setup the animated frames in the correct sequence */
|
||||
for (i = 0; i < desc->num_steps; i++)
|
||||
{
|
||||
struct cursoricon_desc frame_desc;
|
||||
DWORD frame_id;
|
||||
|
||||
if (obj->ani.frames[i]) continue; /* already set */
|
||||
|
||||
frame_id = desc->frame_seq ? desc->frame_seq[i] : i;
|
||||
if (frame_id >= obj->ani.num_frames)
|
||||
{
|
||||
frame_id = obj->ani.num_frames - 1;
|
||||
ERR_(cursor)( "Sequence indicates frame past end of list, corrupt?\n" );
|
||||
}
|
||||
memset( &frame_desc, 0, sizeof(frame_desc) );
|
||||
frame_desc.delay = desc->frame_rates ? desc->frame_rates[i] : desc->delay;
|
||||
frame_desc.frames = &desc->frames[frame_id];
|
||||
if (!(obj->ani.frames[i] = alloc_cursoricon_handle( obj->is_icon )) ||
|
||||
!NtUserSetCursorIconData( obj->ani.frames[i], NULL, NULL, &frame_desc ))
|
||||
{
|
||||
release_user_handle_ptr( obj );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (desc->frame_seq)
|
||||
{
|
||||
for (j = i + 1; j < obj->ani.num_steps; j++)
|
||||
{
|
||||
if (desc->frame_seq[j] == frame_id) obj->ani.frames[j] = obj->ani.frames[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->flags & LR_SHARED)
|
||||
{
|
||||
obj->is_shared = TRUE;
|
||||
if (obj->module.Length)
|
||||
{
|
||||
obj->rsrc = desc->rsrc;
|
||||
list_add_head( &icon_cache, &obj->entry );
|
||||
}
|
||||
}
|
||||
|
||||
release_user_handle_ptr( obj );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* bmi_has_alpha
|
||||
*/
|
||||
|
@ -1262,7 +1065,7 @@ static HICON create_cursoricon_object( struct cursoricon_desc *desc, BOOL is_ico
|
|||
UNICODE_STRING res_str = { 0 };
|
||||
HICON handle;
|
||||
|
||||
if (!(handle = alloc_cursoricon_handle( is_icon ))) return 0;
|
||||
if (!(handle = UlongToHandle( NtUserCallOneParam( is_icon, NtUserCreateCursorIcon )))) return 0;
|
||||
|
||||
if (module) LdrGetDllFullName( module, &module_name );
|
||||
|
||||
|
@ -1276,7 +1079,7 @@ static HICON create_cursoricon_object( struct cursoricon_desc *desc, BOOL is_ico
|
|||
|
||||
if (!NtUserSetCursorIconData( handle, &module_name, &res_str, desc ))
|
||||
{
|
||||
DestroyCursor( handle );
|
||||
NtUserDestroyCursor( handle, 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1727,24 +1530,16 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
|
|||
/* If shared icon, check whether it was already loaded */
|
||||
if (loadflags & LR_SHARED)
|
||||
{
|
||||
WCHAR buf[MAX_PATH];
|
||||
UNICODE_STRING module = { 0, sizeof(buf) - sizeof(WCHAR), buf };
|
||||
struct cursoricon_object *ptr;
|
||||
WCHAR module_buf[MAX_PATH];
|
||||
UNICODE_STRING module_str, res_str;
|
||||
|
||||
if (!LdrGetDllFullName( hInstance, &module ))
|
||||
{
|
||||
USER_Lock();
|
||||
LIST_FOR_EACH_ENTRY( ptr, &icon_cache, struct cursoricon_object, entry )
|
||||
{
|
||||
if (ptr->module.Length != module.Length) continue;
|
||||
if (memcmp( ptr->module.Buffer, module.Buffer, module.Length )) continue;
|
||||
if (ptr->rsrc != hRsrc) continue;
|
||||
hIcon = ptr->obj.handle;
|
||||
break;
|
||||
}
|
||||
USER_Unlock();
|
||||
if (hIcon) return hIcon;
|
||||
}
|
||||
res_str.Length = 0;
|
||||
res_str.Buffer = MAKEINTRESOURCEW(wResId);
|
||||
module_str.Buffer = module_buf;
|
||||
module_str.MaximumLength = sizeof(module_buf);
|
||||
if (!LdrGetDllFullName( hInstance, &module_str ) &&
|
||||
(hIcon = NtUserFindExistingCursorIcon( &module_str, &res_str, hRsrc )))
|
||||
return hIcon;
|
||||
}
|
||||
|
||||
if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
|
||||
|
@ -1892,19 +1687,7 @@ HICON WINAPI CopyIcon( HICON icon )
|
|||
*/
|
||||
BOOL WINAPI DestroyIcon( HICON hIcon )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
struct cursoricon_object *obj = get_icon_ptr( hIcon );
|
||||
|
||||
TRACE_(icon)("%p\n", hIcon );
|
||||
|
||||
if (obj)
|
||||
{
|
||||
BOOL shared = obj->is_shared;
|
||||
release_user_handle_ptr( obj );
|
||||
ret = (NtUserGetCursor() != hIcon);
|
||||
if (!shared) free_icon_handle( hIcon );
|
||||
}
|
||||
return ret;
|
||||
return NtUserDestroyCursor( hIcon, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -128,10 +128,6 @@ static void CDECL nulldrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
|
|||
{
|
||||
}
|
||||
|
||||
static void CDECL nulldrv_DestroyCursorIcon( HCURSOR cursor )
|
||||
{
|
||||
}
|
||||
|
||||
static void CDECL nulldrv_SetCursor( HCURSOR cursor )
|
||||
{
|
||||
}
|
||||
|
@ -355,7 +351,7 @@ static struct user_driver_funcs lazy_load_driver =
|
|||
loaderdrv_UnregisterHotKey,
|
||||
NULL,
|
||||
/* cursor/icon functions */
|
||||
nulldrv_DestroyCursorIcon,
|
||||
NULL,
|
||||
loaderdrv_SetCursor,
|
||||
NULL,
|
||||
loaderdrv_SetCursorPos,
|
||||
|
@ -415,7 +411,6 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
|
|||
|
||||
SET_USER_FUNC(RegisterHotKey);
|
||||
SET_USER_FUNC(UnregisterHotKey);
|
||||
SET_USER_FUNC(DestroyCursorIcon);
|
||||
SET_USER_FUNC(SetCursor);
|
||||
SET_USER_FUNC(SetCursorPos);
|
||||
SET_USER_FUNC(ClipCursor);
|
||||
|
|
|
@ -143,10 +143,16 @@ static const struct user_callbacks user_funcs =
|
|||
WindowFromDC,
|
||||
};
|
||||
|
||||
static void WINAPI User32CallFreeIcon( ULONG *param, ULONG size )
|
||||
{
|
||||
wow_handlers.free_icon_param( *param );
|
||||
}
|
||||
|
||||
static const void *kernel_callback_table[NtUserCallCount] =
|
||||
{
|
||||
User32CallEnumDisplayMonitor,
|
||||
User32CallWinEventHook,
|
||||
User32CallFreeIcon,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -28,12 +28,15 @@
|
|||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include "win32u_private.h"
|
||||
#include "ntuser_private.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cursor);
|
||||
|
||||
static struct list icon_cache = LIST_INIT( icon_cache );
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserShowCursor (win32u.@)
|
||||
|
@ -155,3 +158,217 @@ BOOL get_clip_cursor( RECT *rect )
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
HICON alloc_cursoricon_handle( BOOL is_icon )
|
||||
{
|
||||
struct cursoricon_object *obj;
|
||||
HICON handle;
|
||||
|
||||
if (!(obj = calloc( 1, sizeof(*obj) ))) return NULL;
|
||||
obj->is_icon = is_icon;
|
||||
if (!(handle = alloc_user_handle( &obj->obj, NTUSER_OBJ_ICON ))) free( obj );
|
||||
return handle;
|
||||
}
|
||||
|
||||
static struct cursoricon_object *get_icon_ptr( HICON handle )
|
||||
{
|
||||
struct cursoricon_object *obj = get_user_handle_ptr( handle, NTUSER_OBJ_ICON );
|
||||
if (obj == OBJ_OTHER_PROCESS)
|
||||
{
|
||||
WARN( "icon handle %p from other process\n", handle );
|
||||
obj = NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static BOOL free_icon_handle( HICON handle )
|
||||
{
|
||||
struct cursoricon_object *obj = free_user_handle( handle, NTUSER_OBJ_ICON );
|
||||
|
||||
if (obj == OBJ_OTHER_PROCESS) WARN( "icon handle %p from other process\n", handle );
|
||||
else if (obj)
|
||||
{
|
||||
ULONG param = obj->param;
|
||||
void *ret_ptr;
|
||||
ULONG ret_len;
|
||||
UINT i;
|
||||
|
||||
assert( !obj->rsrc ); /* shared icons can't be freed */
|
||||
|
||||
if (!obj->is_ani)
|
||||
{
|
||||
if (obj->frame.alpha) NtGdiDeleteObjectApp( obj->frame.alpha );
|
||||
if (obj->frame.color) NtGdiDeleteObjectApp( obj->frame.color );
|
||||
if (obj->frame.mask) NtGdiDeleteObjectApp( obj->frame.mask );
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < obj->ani.num_steps; i++)
|
||||
{
|
||||
HICON hFrame = obj->ani.frames[i];
|
||||
|
||||
if (hFrame)
|
||||
{
|
||||
UINT j;
|
||||
|
||||
free_icon_handle( obj->ani.frames[i] );
|
||||
for (j = 0; j < obj->ani.num_steps; j++)
|
||||
{
|
||||
if (obj->ani.frames[j] == hFrame) obj->ani.frames[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
free( obj->ani.frames );
|
||||
}
|
||||
if (!IS_INTRESOURCE( obj->resname )) free( obj->resname );
|
||||
free( obj );
|
||||
if (param) KeUserModeCallback( NtUserCallFreeIcon, ¶m, sizeof(param), &ret_ptr, &ret_len );
|
||||
user_driver->pDestroyCursorIcon( handle );
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserDestroyCursor (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg )
|
||||
{
|
||||
struct cursoricon_object *obj;
|
||||
BOOL shared, ret;
|
||||
|
||||
TRACE( "%p\n", cursor );
|
||||
|
||||
if (!(obj = get_icon_ptr( cursor ))) return FALSE;
|
||||
shared = obj->is_shared;
|
||||
release_user_handle_ptr( obj );
|
||||
ret = NtUserGetCursor() != cursor;
|
||||
if (!shared) free_icon_handle( cursor );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserSetCursorIconData (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtUserSetCursorIconData( HCURSOR cursor, UNICODE_STRING *module, UNICODE_STRING *res_name,
|
||||
struct cursoricon_desc *desc )
|
||||
{
|
||||
struct cursoricon_object *obj;
|
||||
UINT i, j;
|
||||
|
||||
if (!(obj = get_icon_ptr( cursor ))) return FALSE;
|
||||
|
||||
if (obj->is_ani || obj->frame.width)
|
||||
{
|
||||
/* already initialized */
|
||||
release_user_handle_ptr( obj );
|
||||
SetLastError( ERROR_INVALID_CURSOR_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
obj->delay = desc->delay;
|
||||
|
||||
if (desc->num_steps)
|
||||
{
|
||||
if (!(obj->ani.frames = calloc( desc->num_steps, sizeof(*obj->ani.frames) )))
|
||||
{
|
||||
release_user_handle_ptr( obj );
|
||||
return FALSE;
|
||||
}
|
||||
obj->is_ani = TRUE;
|
||||
obj->ani.num_steps = desc->num_steps;
|
||||
obj->ani.num_frames = desc->num_frames;
|
||||
}
|
||||
else obj->frame = desc->frames[0];
|
||||
|
||||
if (!res_name)
|
||||
obj->resname = NULL;
|
||||
else if (res_name->Length)
|
||||
{
|
||||
obj->resname = malloc( res_name->Length + sizeof(WCHAR) );
|
||||
if (obj->resname)
|
||||
{
|
||||
memcpy( obj->resname, res_name->Buffer, res_name->Length );
|
||||
obj->resname[res_name->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
obj->resname = MAKEINTRESOURCEW( LOWORD(res_name->Buffer) );
|
||||
|
||||
if (module && module->Length && (obj->module.Buffer = malloc( module->Length )))
|
||||
{
|
||||
memcpy( obj->module.Buffer, module->Buffer, module->Length );
|
||||
obj->module.Length = module->Length;
|
||||
}
|
||||
|
||||
if (obj->is_ani)
|
||||
{
|
||||
/* Setup the animated frames in the correct sequence */
|
||||
for (i = 0; i < desc->num_steps; i++)
|
||||
{
|
||||
struct cursoricon_desc frame_desc;
|
||||
DWORD frame_id;
|
||||
|
||||
if (obj->ani.frames[i]) continue; /* already set */
|
||||
|
||||
frame_id = desc->frame_seq ? desc->frame_seq[i] : i;
|
||||
if (frame_id >= obj->ani.num_frames)
|
||||
{
|
||||
frame_id = obj->ani.num_frames - 1;
|
||||
ERR_(cursor)( "Sequence indicates frame past end of list, corrupt?\n" );
|
||||
}
|
||||
memset( &frame_desc, 0, sizeof(frame_desc) );
|
||||
frame_desc.delay = desc->frame_rates ? desc->frame_rates[i] : desc->delay;
|
||||
frame_desc.frames = &desc->frames[frame_id];
|
||||
if (!(obj->ani.frames[i] = alloc_cursoricon_handle( obj->is_icon )) ||
|
||||
!NtUserSetCursorIconData( obj->ani.frames[i], NULL, NULL, &frame_desc ))
|
||||
{
|
||||
release_user_handle_ptr( obj );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (desc->frame_seq)
|
||||
{
|
||||
for (j = i + 1; j < obj->ani.num_steps; j++)
|
||||
{
|
||||
if (desc->frame_seq[j] == frame_id) obj->ani.frames[j] = obj->ani.frames[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->flags & LR_SHARED)
|
||||
{
|
||||
obj->is_shared = TRUE;
|
||||
if (obj->module.Length)
|
||||
{
|
||||
obj->rsrc = desc->rsrc;
|
||||
list_add_head( &icon_cache, &obj->entry );
|
||||
}
|
||||
}
|
||||
|
||||
release_user_handle_ptr( obj );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserFindExistingCursorIcon (win32u.@)
|
||||
*/
|
||||
HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STRING *res_name, void *desc )
|
||||
{
|
||||
struct cursoricon_object *ptr;
|
||||
HICON ret = 0;
|
||||
|
||||
user_lock();
|
||||
LIST_FOR_EACH_ENTRY( ptr, &icon_cache, struct cursoricon_object, entry )
|
||||
{
|
||||
if (ptr->module.Length != module->Length) continue;
|
||||
if (memcmp( ptr->module.Buffer, module->Buffer, module->Length )) continue;
|
||||
/* We pass rsrc as desc argument, this is not compatible with Windows */
|
||||
if (ptr->rsrc != desc) continue;
|
||||
ret = ptr->obj.handle;
|
||||
break;
|
||||
}
|
||||
user_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1045,6 +1045,7 @@ static const struct user_driver_funcs lazy_load_driver =
|
|||
.pUnregisterHotKey = loaderdrv_UnregisterHotKey,
|
||||
.pVkKeyScanEx = loaderdrv_VkKeyScanEx,
|
||||
/* cursor/icon functions */
|
||||
.pDestroyCursorIcon = nulldrv_DestroyCursorIcon,
|
||||
.pSetCursor = loaderdrv_SetCursor,
|
||||
.pGetCursorPos = loaderdrv_GetCursorPos,
|
||||
.pSetCursorPos = loaderdrv_SetCursorPos,
|
||||
|
|
|
@ -1156,6 +1156,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserChangeDisplaySettings,
|
||||
NtUserClipCursor,
|
||||
NtUserCountClipboardFormats,
|
||||
NtUserDestroyCursor,
|
||||
NtUserEnumDisplayDevices,
|
||||
NtUserEnumDisplayMonitors,
|
||||
NtUserEnumDisplaySettings,
|
||||
|
@ -1170,6 +1171,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserMapVirtualKeyEx,
|
||||
NtUserScrollDC,
|
||||
NtUserSelectPalette,
|
||||
NtUserSetCursorIconData,
|
||||
NtUserSetCursorPos,
|
||||
NtUserSetSysColors,
|
||||
NtUserShowCursor,
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define __WINE_NTUSER_PRIVATE_H
|
||||
|
||||
#include "ntuser.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
struct user_callbacks
|
||||
{
|
||||
|
@ -124,4 +125,37 @@ struct user_key_state_info
|
|||
BYTE state[256]; /* State for each key */
|
||||
};
|
||||
|
||||
struct cursoricon_object
|
||||
{
|
||||
struct user_object obj; /* object header */
|
||||
struct list entry; /* entry in shared icons list */
|
||||
ULONG_PTR param; /* opaque param used by 16-bit code */
|
||||
UNICODE_STRING module; /* module for icons loaded from resources */
|
||||
LPWSTR resname; /* resource name for icons loaded from resources */
|
||||
HRSRC rsrc; /* resource for shared icons */
|
||||
BOOL is_shared; /* whether this object is shared */
|
||||
BOOL is_icon; /* whether icon or cursor */
|
||||
BOOL is_ani; /* whether this object is a static cursor or an animated cursor */
|
||||
UINT delay; /* delay between this frame and the next (in jiffies) */
|
||||
union
|
||||
{
|
||||
struct cursoricon_frame frame; /* frame-specific icon data */
|
||||
struct
|
||||
{
|
||||
UINT num_frames; /* number of frames in the icon/cursor */
|
||||
UINT num_steps; /* number of sequence steps in the icon/cursor */
|
||||
HICON *frames; /* list of animated cursor frames */
|
||||
} ani;
|
||||
};
|
||||
};
|
||||
|
||||
/* cursoricon.c */
|
||||
HICON alloc_cursoricon_handle( BOOL is_icon ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* window.c */
|
||||
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN;
|
||||
void *free_user_handle( HANDLE handle, 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;
|
||||
|
||||
#endif /* __WINE_NTUSER_PRIVATE_H */
|
||||
|
|
|
@ -108,6 +108,7 @@ static void * const syscalls[] =
|
|||
NtUserCloseWindowStation,
|
||||
NtUserCreateDesktopEx,
|
||||
NtUserCreateWindowStation,
|
||||
NtUserFindExistingCursorIcon,
|
||||
NtUserGetClipboardFormatName,
|
||||
NtUserGetClipboardOwner,
|
||||
NtUserGetClipboardSequenceNumber,
|
||||
|
|
|
@ -4552,6 +4552,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
|
|||
{
|
||||
switch(code)
|
||||
{
|
||||
case NtUserCreateCursorIcon:
|
||||
return HandleToUlong( alloc_cursoricon_handle( arg ));
|
||||
case NtUserGetClipCursor:
|
||||
return get_clip_cursor( (RECT *)arg );
|
||||
case NtUserGetCursorPos:
|
||||
|
|
|
@ -829,7 +829,7 @@
|
|||
@ stub NtUserDestroyAcceleratorTable
|
||||
@ stub NtUserDestroyActivationGroup
|
||||
@ stub NtUserDestroyActivationObject
|
||||
@ stub NtUserDestroyCursor
|
||||
@ stdcall NtUserDestroyCursor(long long)
|
||||
@ stub NtUserDestroyDCompositionHwndTarget
|
||||
@ stub NtUserDestroyInputContext
|
||||
@ stub NtUserDestroyMenu
|
||||
|
@ -881,7 +881,7 @@
|
|||
@ stub NtUserEvent
|
||||
@ stub NtUserExcludeUpdateRgn
|
||||
@ stub NtUserFillWindow
|
||||
@ stub NtUserFindExistingCursorIcon
|
||||
@ stdcall -syscall NtUserFindExistingCursorIcon(ptr ptr ptr)
|
||||
@ stub NtUserFindWindowEx
|
||||
@ stub NtUserFlashWindowEx
|
||||
@ stub NtUserForceWindowToDpiForTest
|
||||
|
@ -1180,7 +1180,7 @@
|
|||
@ stub NtUserSetCoreWindowPartner
|
||||
@ stub NtUserSetCursor
|
||||
@ stub NtUserSetCursorContents
|
||||
@ stub NtUserSetCursorIconData
|
||||
@ stdcall NtUserSetCursorIconData(long ptr ptr ptr)
|
||||
@ stdcall NtUserSetCursorPos(long long)
|
||||
@ stub NtUserSetDesktopColorTransform
|
||||
@ stub NtUserSetDesktopVisualInputSink
|
||||
|
|
|
@ -190,6 +190,7 @@ struct unix_funcs
|
|||
DWORD flags, void *lparam );
|
||||
BOOL (WINAPI *pNtUserClipCursor)( const RECT *rect );
|
||||
INT (WINAPI *pNtUserCountClipboardFormats)(void);
|
||||
BOOL (WINAPI *pNtUserDestroyCursor)( HCURSOR cursor, ULONG arg );
|
||||
NTSTATUS (WINAPI *pNtUserEnumDisplayDevices)( UNICODE_STRING *device, DWORD index,
|
||||
DISPLAY_DEVICEW *info, DWORD flags );
|
||||
BOOL (WINAPI *pNtUserEnumDisplayMonitors)( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp );
|
||||
|
@ -208,6 +209,8 @@ struct unix_funcs
|
|||
BOOL (WINAPI *pNtUserScrollDC)( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
|
||||
HRGN ret_update_rgn, RECT *update_rect );
|
||||
HPALETTE (WINAPI *pNtUserSelectPalette)( HDC hdc, HPALETTE hpal, WORD bkg );
|
||||
BOOL (WINAPI *pNtUserSetCursorIconData)( HCURSOR cursor, UNICODE_STRING *module,
|
||||
UNICODE_STRING *res_name, struct cursoricon_desc *desc );
|
||||
BOOL (WINAPI *pNtUserSetCursorPos)( INT x, INT y );
|
||||
BOOL (WINAPI *pNtUserSetSysColors)( INT count, const INT *colors, const COLORREF *values );
|
||||
INT (WINAPI *pNtUserShowCursor)( BOOL show );
|
||||
|
@ -237,6 +240,7 @@ struct unix_funcs
|
|||
};
|
||||
|
||||
/* cursoricon.c */
|
||||
extern HICON alloc_cursoricon_handle( BOOL is_icon ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_clip_cursor( RECT *rect ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* hook.c */
|
||||
|
|
|
@ -99,6 +99,15 @@ void set_user_handle_ptr( HANDLE handle, struct user_object *ptr )
|
|||
InterlockedExchangePointer( &user_handles[index], ptr );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* release_user_handle_ptr
|
||||
*/
|
||||
void release_user_handle_ptr( void *ptr )
|
||||
{
|
||||
assert( ptr && ptr != OBJ_OTHER_PROCESS );
|
||||
user_unlock();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* free_user_handle
|
||||
*/
|
||||
|
|
|
@ -738,6 +738,12 @@ INT WINAPI NtUserCountClipboardFormats(void)
|
|||
return unix_funcs->pNtUserCountClipboardFormats();
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
return unix_funcs->pNtUserDestroyCursor( cursor, arg );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
|
||||
DISPLAY_DEVICEW *info, DWORD flags )
|
||||
{
|
||||
|
@ -826,6 +832,13 @@ HPALETTE WINAPI NtUserSelectPalette( HDC hdc, HPALETTE hpal, WORD bkg )
|
|||
return unix_funcs->pNtUserSelectPalette( hdc, hpal, bkg );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserSetCursorIconData( HCURSOR cursor, UNICODE_STRING *module, UNICODE_STRING *res_name,
|
||||
struct cursoricon_desc *desc )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
return unix_funcs->pNtUserSetCursorIconData( cursor, module, res_name, desc );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserSetCursorPos( INT x, INT y )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
SYSCALL_ENTRY( NtUserCloseWindowStation ) \
|
||||
SYSCALL_ENTRY( NtUserCreateDesktopEx ) \
|
||||
SYSCALL_ENTRY( NtUserCreateWindowStation ) \
|
||||
SYSCALL_ENTRY( NtUserFindExistingCursorIcon ) \
|
||||
SYSCALL_ENTRY( NtUserGetClipboardFormatName ) \
|
||||
SYSCALL_ENTRY( NtUserGetClipboardOwner ) \
|
||||
SYSCALL_ENTRY( NtUserGetClipboardSequenceNumber ) \
|
||||
|
|
|
@ -264,6 +264,21 @@ NTSTATUS WINAPI wow64_NtUserGetCursor( UINT *args )
|
|||
return HandleToUlong( NtUserGetCursor() );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserFindExistingCursorIcon( UINT *args )
|
||||
{
|
||||
UNICODE_STRING32 *module32 = get_ptr( &args );
|
||||
UNICODE_STRING32 *res_name32 = get_ptr( &args );
|
||||
void *desc = get_ptr( &args );
|
||||
|
||||
UNICODE_STRING module;
|
||||
UNICODE_STRING res_name;
|
||||
HICON ret;
|
||||
|
||||
ret = NtUserFindExistingCursorIcon( unicode_str_32to64( &module, module32 ),
|
||||
unicode_str_32to64( &res_name, res_name32 ), desc );
|
||||
return HandleToUlong( ret );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserAttachThreadInput( UINT *args )
|
||||
{
|
||||
DWORD from = get_ulong( &args );
|
||||
|
|
|
@ -26,8 +26,12 @@
|
|||
/* KernelCallbackTable codes, not compatible with Windows */
|
||||
enum
|
||||
{
|
||||
/* user32 callbacks */
|
||||
NtUserCallEnumDisplayMonitor,
|
||||
NtUserCallWinEventHook,
|
||||
/* win16 hooks */
|
||||
NtUserCallFreeIcon,
|
||||
/* Vulkan support */
|
||||
NtUserCallVulkanDebugReportCallback,
|
||||
NtUserCallVulkanDebugUtilsCallback,
|
||||
NtUserCallCount
|
||||
|
@ -73,6 +77,7 @@ enum
|
|||
/* NtUserCallOneParam codes, not compatible with Windows */
|
||||
enum
|
||||
{
|
||||
NtUserCreateCursorIcon,
|
||||
NtUserGetClipCursor,
|
||||
NtUserGetCursorPos,
|
||||
NtUserGetPrimaryMonitorRect,
|
||||
|
@ -120,6 +125,16 @@ enum
|
|||
#define NTUSER_OBJ_HOOK 0x0f
|
||||
|
||||
/* NtUserSetCursorIconData parameter, not compatible with Windows */
|
||||
struct cursoricon_frame
|
||||
{
|
||||
UINT width; /* frame-specific width */
|
||||
UINT height; /* frame-specific height */
|
||||
HBITMAP color; /* color bitmap */
|
||||
HBITMAP alpha; /* pre-multiplied alpha bitmap for 32-bpp icons */
|
||||
HBITMAP mask; /* mask bitmap (followed by color for 1-bpp icons) */
|
||||
POINT hotspot;
|
||||
};
|
||||
|
||||
struct cursoricon_desc
|
||||
{
|
||||
UINT flags;
|
||||
|
@ -170,11 +185,14 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *d
|
|||
ULONG heap_size );
|
||||
HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK mask, ULONG arg3,
|
||||
ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 );
|
||||
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg );
|
||||
NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
|
||||
DISPLAY_DEVICEW *info, DWORD flags );
|
||||
BOOL WINAPI NtUserEnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp );
|
||||
BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
|
||||
DEVMODEW *dev_mode, DWORD flags );
|
||||
HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STRING *res_name,
|
||||
void *desc );
|
||||
SHORT WINAPI NtUserGetAsyncKeyState( INT key );
|
||||
INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
|
||||
HWND WINAPI NtUserGetClipboardOwner(void);
|
||||
|
|
Loading…
Reference in New Issue