winemac: Use system cursors when possible.
This commit is contained in:
parent
a49df4b317
commit
b79d955342
|
@ -44,6 +44,90 @@ static CRITICAL_SECTION cursor_cache_section = { &critsect_debug, -1, 0, 0, 0, 0
|
||||||
static CFMutableDictionaryRef cursor_cache;
|
static CFMutableDictionaryRef cursor_cache;
|
||||||
|
|
||||||
|
|
||||||
|
struct system_cursors
|
||||||
|
{
|
||||||
|
WORD id;
|
||||||
|
CFStringRef name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors user32_cursors[] =
|
||||||
|
{
|
||||||
|
{ OCR_NORMAL, CFSTR("arrowCursor") },
|
||||||
|
{ OCR_IBEAM, CFSTR("IBeamCursor") },
|
||||||
|
{ OCR_CROSS, CFSTR("crosshairCursor") },
|
||||||
|
{ OCR_SIZEWE, CFSTR("resizeLeftRightCursor") },
|
||||||
|
{ OCR_SIZENS, CFSTR("resizeUpDownCursor") },
|
||||||
|
{ OCR_NO, CFSTR("operationNotAllowedCursor") },
|
||||||
|
{ OCR_HAND, CFSTR("pointingHandCursor") },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors comctl32_cursors[] =
|
||||||
|
{
|
||||||
|
{ 102, CFSTR("closedHandCursor") },
|
||||||
|
{ 104, CFSTR("dragCopyCursor") },
|
||||||
|
{ 105, CFSTR("arrowCursor") },
|
||||||
|
{ 106, CFSTR("resizeLeftRightCursor") },
|
||||||
|
{ 107, CFSTR("resizeLeftRightCursor") },
|
||||||
|
{ 108, CFSTR("pointingHandCursor") },
|
||||||
|
{ 135, CFSTR("resizeUpDownCursor") },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors ole32_cursors[] =
|
||||||
|
{
|
||||||
|
{ 1, CFSTR("operationNotAllowedCursor") },
|
||||||
|
{ 2, CFSTR("closedHandCursor") },
|
||||||
|
{ 3, CFSTR("dragCopyCursor") },
|
||||||
|
{ 4, CFSTR("dragLinkCursor") },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors riched20_cursors[] =
|
||||||
|
{
|
||||||
|
{ 105, CFSTR("pointingHandCursor") },
|
||||||
|
{ 109, CFSTR("dragCopyCursor") },
|
||||||
|
{ 110, CFSTR("closedHandCursor") },
|
||||||
|
{ 111, CFSTR("operationNotAllowedCursor") },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
const struct system_cursors *cursors;
|
||||||
|
WCHAR name[16];
|
||||||
|
} module_cursors[] =
|
||||||
|
{
|
||||||
|
{ user32_cursors, {'u','s','e','r','3','2','.','d','l','l',0} },
|
||||||
|
{ comctl32_cursors, {'c','o','m','c','t','l','3','2','.','d','l','l',0} },
|
||||||
|
{ ole32_cursors, {'o','l','e','3','2','.','d','l','l',0} },
|
||||||
|
{ riched20_cursors, {'r','i','c','h','e','d','2','0','.','d','l','l',0} }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The names of NSCursor class methods which return cursor objects. */
|
||||||
|
static const CFStringRef cocoa_cursor_names[] =
|
||||||
|
{
|
||||||
|
CFSTR("arrowCursor"),
|
||||||
|
CFSTR("closedHandCursor"),
|
||||||
|
CFSTR("contextualMenuCursor"),
|
||||||
|
CFSTR("crosshairCursor"),
|
||||||
|
CFSTR("disappearingItemCursor"),
|
||||||
|
CFSTR("dragCopyCursor"),
|
||||||
|
CFSTR("dragLinkCursor"),
|
||||||
|
CFSTR("IBeamCursor"),
|
||||||
|
CFSTR("IBeamCursorForVerticalLayout"),
|
||||||
|
CFSTR("openHandCursor"),
|
||||||
|
CFSTR("operationNotAllowedCursor"),
|
||||||
|
CFSTR("pointingHandCursor"),
|
||||||
|
CFSTR("resizeDownCursor"),
|
||||||
|
CFSTR("resizeLeftCursor"),
|
||||||
|
CFSTR("resizeLeftRightCursor"),
|
||||||
|
CFSTR("resizeRightCursor"),
|
||||||
|
CFSTR("resizeUpCursor"),
|
||||||
|
CFSTR("resizeUpDownCursor"),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* send_mouse_input
|
* send_mouse_input
|
||||||
*
|
*
|
||||||
|
@ -89,6 +173,90 @@ static void send_mouse_input(HWND hwnd, UINT flags, int x, int y,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* copy_system_cursor_name
|
||||||
|
*/
|
||||||
|
CFStringRef copy_system_cursor_name(ICONINFOEXW *info)
|
||||||
|
{
|
||||||
|
static const WCHAR idW[] = {'%','h','u',0};
|
||||||
|
const struct system_cursors *cursors;
|
||||||
|
unsigned int i;
|
||||||
|
CFStringRef cursor_name = NULL;
|
||||||
|
HMODULE module;
|
||||||
|
HKEY key;
|
||||||
|
WCHAR *p, name[MAX_PATH * 2];
|
||||||
|
|
||||||
|
TRACE("info->szModName %s info->szResName %s info->wResID %hu\n", debugstr_w(info->szModName),
|
||||||
|
debugstr_w(info->szResName), info->wResID);
|
||||||
|
|
||||||
|
if (!info->szModName[0]) return NULL;
|
||||||
|
|
||||||
|
p = strrchrW(info->szModName, '\\');
|
||||||
|
strcpyW(name, p ? p + 1 : info->szModName);
|
||||||
|
p = name + strlenW(name);
|
||||||
|
*p++ = ',';
|
||||||
|
if (info->szResName[0]) strcpyW(p, info->szResName);
|
||||||
|
else sprintfW(p, idW, info->wResID);
|
||||||
|
|
||||||
|
/* @@ Wine registry key: HKCU\Software\Wine\Mac Driver\Cursors */
|
||||||
|
if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Mac Driver\\Cursors", &key))
|
||||||
|
{
|
||||||
|
WCHAR value[64];
|
||||||
|
DWORD size, ret;
|
||||||
|
|
||||||
|
value[0] = 0;
|
||||||
|
size = sizeof(value) / sizeof(WCHAR);
|
||||||
|
ret = RegQueryValueExW(key, name, NULL, NULL, (BYTE *)value, &size);
|
||||||
|
RegCloseKey(key);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
if (!value[0])
|
||||||
|
{
|
||||||
|
TRACE("registry forces standard cursor for %s\n", debugstr_w(name));
|
||||||
|
return NULL; /* force standard cursor */
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor_name = CFStringCreateWithCharacters(NULL, value, strlenW(value));
|
||||||
|
if (!cursor_name)
|
||||||
|
{
|
||||||
|
WARN("CFStringCreateWithCharacters failed for %s\n", debugstr_w(value));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure it's one of the appropriate NSCursor class methods. */
|
||||||
|
for (i = 0; i < sizeof(cocoa_cursor_names) / sizeof(cocoa_cursor_names[0]); i++)
|
||||||
|
if (CFEqual(cursor_name, cocoa_cursor_names[i]))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
WARN("%s mapped to invalid Cocoa cursor name %s\n", debugstr_w(name), debugstr_w(value));
|
||||||
|
CFRelease(cursor_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->szResName[0]) goto done; /* only integer resources are supported here */
|
||||||
|
if (!(module = GetModuleHandleW(info->szModName))) goto done;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(module_cursors)/sizeof(module_cursors[0]); i++)
|
||||||
|
if (GetModuleHandleW(module_cursors[i].name) == module) break;
|
||||||
|
if (i == sizeof(module_cursors)/sizeof(module_cursors[0])) goto done;
|
||||||
|
|
||||||
|
cursors = module_cursors[i].cursors;
|
||||||
|
for (i = 0; cursors[i].id; i++)
|
||||||
|
if (cursors[i].id == info->wResID)
|
||||||
|
{
|
||||||
|
cursor_name = CFRetain(cursors[i].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (cursor_name)
|
||||||
|
TRACE("%s -> %s\n", debugstr_w(name), debugstr_cf(cursor_name));
|
||||||
|
else
|
||||||
|
WARN("no system cursor found for %s\n", debugstr_w(name));
|
||||||
|
return cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* release_provider_cfdata
|
* release_provider_cfdata
|
||||||
*
|
*
|
||||||
|
@ -580,8 +748,6 @@ void CDECL macdrv_SetCursor(HCURSOR cursor)
|
||||||
if (cursor)
|
if (cursor)
|
||||||
{
|
{
|
||||||
ICONINFOEXW info;
|
ICONINFOEXW info;
|
||||||
BITMAP bm;
|
|
||||||
HDC hdc;
|
|
||||||
|
|
||||||
EnterCriticalSection(&cursor_cache_section);
|
EnterCriticalSection(&cursor_cache_section);
|
||||||
if (cursor_cache)
|
if (cursor_cache)
|
||||||
|
@ -606,6 +772,16 @@ void CDECL macdrv_SetCursor(HCURSOR cursor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((cursor_name = copy_system_cursor_name(&info)))
|
||||||
|
{
|
||||||
|
DeleteObject(info.hbmColor);
|
||||||
|
DeleteObject(info.hbmMask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BITMAP bm;
|
||||||
|
HDC hdc;
|
||||||
|
|
||||||
GetObjectW(info.hbmMask, sizeof(bm), &bm);
|
GetObjectW(info.hbmMask, sizeof(bm), &bm);
|
||||||
if (!info.hbmColor) bm.bmHeight = max(1, bm.bmHeight / 2);
|
if (!info.hbmColor) bm.bmHeight = max(1, bm.bmHeight / 2);
|
||||||
|
|
||||||
|
@ -628,6 +804,7 @@ void CDECL macdrv_SetCursor(HCURSOR cursor)
|
||||||
|
|
||||||
DeleteObject(info.hbmMask);
|
DeleteObject(info.hbmMask);
|
||||||
DeleteDC(hdc);
|
DeleteDC(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
if (cursor_name || cursor_frames)
|
if (cursor_name || cursor_frames)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue