Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regenerate cursors when they are drawn over #1123

Merged
merged 3 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion krnl386/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include "winternl.h"
#include "kernel16_private.h"
#include "wine/debug.h"
#include "winuser.h"
#include "wingdi.h"

WINE_DEFAULT_DEBUG_CHANNEL(global);

Expand Down Expand Up @@ -792,10 +794,21 @@ DWORD WINAPI WIN16_GlobalFree16(HGLOBAL16 handle)
CURRENT_STACK16->es = 0;
return GlobalFree16(handle);
}
void regen_icon(HICON16 icon);
DWORD WINAPI WIN16_GlobalUnlock16(HGLOBAL16 handle)
{
DWORD ret = MAKELONG(GlobalUnlock16(handle), handle);
CURRENT_STACK16->es = 0;
return MAKELONG(GlobalUnlock16(handle), handle);
if (!ret) return 0;
GLOBALARENA *pArena = GET_ARENA_PTR(handle);
if (pArena->wType == (GT_RESOURCE | (12 << 4))) // GD_CURSOR
{
static void (*regen_icon)(HICON16) = 0;
if (!regen_icon)
regen_icon = (void (*)(HICON16))GetProcAddress(GetModuleHandle("user.exe16"), "regen_icon");
regen_icon((HICON16)handle);
}
return ret;
}


Expand Down
1 change: 1 addition & 0 deletions krnl386/krnl386.def
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ EXPORTS
GLOBAL_GetLink
GLOBAL_SetLink
GLOBAL_FindLink
GLOBAL_SetSeg
vm_inject
set_vm_inject_cb
get_idle_event
1 change: 1 addition & 0 deletions krnl386/krnl386.exe16.spec
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,7 @@
@ cdecl -arch=win32 GLOBAL_GetLink(long)
@ cdecl -arch=win32 GLOBAL_SetLink(long long)
@ cdecl -arch=win32 GLOBAL_FindLink(long)
@ cdecl -arch=win32 GLOBAL_SetSeg(long long long)
@ stdcall -arch=win32 set_vm_inject_cb(long)
@ stdcall -arch=win32 vm_inject(long long long long long)
@ stdcall -arch=win32 get_idle_event()
46 changes: 46 additions & 0 deletions user/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,51 @@ HICON get_icon_32( HICON16 icon16 )
return ret;
}

struct hicons
{
HICON oldicon;
HICON newicon;
};

BOOL CALLBACK enum_cur_wnd(HWND hwnd, LPARAM lparam)
{
struct hicons *icons = (struct hicons *)lparam;
if (GetClassLongA(hwnd, GCL_HCURSOR) == icons->oldicon)
SetClassLongA(hwnd, GCL_HCURSOR, icons->newicon);
return TRUE;
}

void regen_icon(HICON16 icon)
{
CURSORICONINFO *ptr = get_icon_ptr( icon );
if (ptr)
{
unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
if (GlobalSize16( icon ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + xor_size + and_size )
{
DWORD *hiconptr = (DWORD *)((char *)(ptr + 1) + xor_size + and_size);
HICON oldicon = *(HICON *)hiconptr, newicon;
if (oldicon)
{
*hiconptr = 0;
if (newicon = get_icon_32(icon))
{
struct hicons icons = {oldicon, newicon};
// TODO: all window classes
EnumThreadWindows(GetCurrentThreadId(), enum_cur_wnd, (LPARAM)&icons);
if (GetCursor() == oldicon)
SetCursor(newicon);
DestroyIcon(oldicon);
}
else
*hiconptr = oldicon;
}
}
}
}


/* retrieve the 16-bit counterpart of a 32-bit icon, creating it if needed */
HICON16 get_icon_16( HICON icon )
{
Expand Down Expand Up @@ -2902,6 +2947,7 @@ HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 c
FreeResource16(handle);

if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
GLOBAL_SetSeg(hIcon, 0, 5 | (type == IMAGE_ICON ? 14 : 12) << 4); // GT_RESOURCE | (GD_ICON || GD_CURSOR)
return hIcon;
}
default:
Expand Down
1 change: 1 addition & 0 deletions user/user.def
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ EXPORTS
LoadString16
set_realized_palette
get_realized_palette
regen_icon
1 change: 1 addition & 0 deletions user/user.exe16.spec
Original file line number Diff line number Diff line change
Expand Up @@ -597,3 +597,4 @@
@ stdcall -arch=win32 LoadString16(long long ptr long)
@ stdcall -arch=win32 set_realized_palette(long)
@ stdcall -arch=win32 get_realized_palette()
@ cdecl -arch=win32 regen_icon(long)