winex11: Add support for remapping standard Win32 cursors to the X11 system cursors.
This commit is contained in:
parent
94e65bae54
commit
45b87f1f94
|
@ -23,6 +23,7 @@
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#ifdef SONAME_LIBXCURSOR
|
#ifdef SONAME_LIBXCURSOR
|
||||||
|
@ -35,11 +36,13 @@ MAKE_FUNCPTR(XcursorImageLoadCursor);
|
||||||
MAKE_FUNCPTR(XcursorImagesCreate);
|
MAKE_FUNCPTR(XcursorImagesCreate);
|
||||||
MAKE_FUNCPTR(XcursorImagesDestroy);
|
MAKE_FUNCPTR(XcursorImagesDestroy);
|
||||||
MAKE_FUNCPTR(XcursorImagesLoadCursor);
|
MAKE_FUNCPTR(XcursorImagesLoadCursor);
|
||||||
|
MAKE_FUNCPTR(XcursorLibraryLoadCursor);
|
||||||
# undef MAKE_FUNCPTR
|
# undef MAKE_FUNCPTR
|
||||||
#endif /* SONAME_LIBXCURSOR */
|
#endif /* SONAME_LIBXCURSOR */
|
||||||
|
|
||||||
#define NONAMELESSUNION
|
#define NONAMELESSUNION
|
||||||
#define NONAMELESSSTRUCT
|
#define NONAMELESSSTRUCT
|
||||||
|
#define OEMRESOURCE
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
|
||||||
|
@ -120,6 +123,7 @@ void X11DRV_Xcursor_Init(void)
|
||||||
LOAD_FUNCPTR(XcursorImagesCreate);
|
LOAD_FUNCPTR(XcursorImagesCreate);
|
||||||
LOAD_FUNCPTR(XcursorImagesDestroy);
|
LOAD_FUNCPTR(XcursorImagesDestroy);
|
||||||
LOAD_FUNCPTR(XcursorImagesLoadCursor);
|
LOAD_FUNCPTR(XcursorImagesLoadCursor);
|
||||||
|
LOAD_FUNCPTR(XcursorLibraryLoadCursor);
|
||||||
#undef LOAD_FUNCPTR
|
#undef LOAD_FUNCPTR
|
||||||
#endif /* SONAME_LIBXCURSOR */
|
#endif /* SONAME_LIBXCURSOR */
|
||||||
}
|
}
|
||||||
|
@ -622,6 +626,110 @@ cleanup:
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct system_cursors
|
||||||
|
{
|
||||||
|
WORD id;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors user32_cursors[] =
|
||||||
|
{
|
||||||
|
{ OCR_NORMAL, "left_ptr" },
|
||||||
|
{ OCR_IBEAM, "xterm" },
|
||||||
|
{ OCR_WAIT, "watch" },
|
||||||
|
{ OCR_CROSS, "cross" },
|
||||||
|
{ OCR_UP, "center_ptr" },
|
||||||
|
{ OCR_SIZE, "fleur" },
|
||||||
|
{ OCR_SIZEALL, "fleur" },
|
||||||
|
{ OCR_ICON, "icon" },
|
||||||
|
{ OCR_SIZENWSE, "nwse-resize" },
|
||||||
|
{ OCR_SIZENESW, "nesw-resize" },
|
||||||
|
{ OCR_SIZEWE, "ew-resize" },
|
||||||
|
{ OCR_SIZENS, "ns-resize" },
|
||||||
|
{ OCR_NO, "not-allowed" },
|
||||||
|
{ OCR_HAND, "hand2" },
|
||||||
|
{ OCR_APPSTARTING, "left_ptr_watch" },
|
||||||
|
{ OCR_HELP, "question_arrow" },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors comctl32_cursors[] =
|
||||||
|
{
|
||||||
|
{ 102, "move" },
|
||||||
|
{ 104, "copy" },
|
||||||
|
{ 105, "left_ptr" },
|
||||||
|
{ 106, "row-resize" },
|
||||||
|
{ 107, "row-resize" },
|
||||||
|
{ 108, "hand2" },
|
||||||
|
{ 135, "col-resize" },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors ole32_cursors[] =
|
||||||
|
{
|
||||||
|
{ 1, "no-drop" },
|
||||||
|
{ 2, "move" },
|
||||||
|
{ 3, "copy" },
|
||||||
|
{ 4, "alias" },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct system_cursors riched20_cursors[] =
|
||||||
|
{
|
||||||
|
{ 105, "hand2" },
|
||||||
|
{ 107, "right_ptr" },
|
||||||
|
{ 109, "copy" },
|
||||||
|
{ 110, "move" },
|
||||||
|
{ 111, "no-drop" },
|
||||||
|
{ 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} }
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* create_xcursor_system_cursor
|
||||||
|
*
|
||||||
|
* Create an X cursor for a system cursor.
|
||||||
|
*/
|
||||||
|
static Cursor create_xcursor_system_cursor( const ICONINFOEXW *info )
|
||||||
|
{
|
||||||
|
const struct system_cursors *cursors;
|
||||||
|
unsigned int i;
|
||||||
|
Cursor cursor = 0;
|
||||||
|
HMODULE module;
|
||||||
|
|
||||||
|
if (!pXcursorLibraryLoadCursor) return 0;
|
||||||
|
if (info->szResName[0]) return 0; /* only integer resources are supported here */
|
||||||
|
if (!(module = GetModuleHandleW( info->szModName ))) return 0;
|
||||||
|
|
||||||
|
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])) return 0;
|
||||||
|
|
||||||
|
cursors = module_cursors[i].cursors;
|
||||||
|
for (i = 0; cursors[i].id; i++) if (cursors[i].id == info->wResID) break;
|
||||||
|
|
||||||
|
if (cursors[i].name)
|
||||||
|
{
|
||||||
|
wine_tsx11_lock();
|
||||||
|
cursor = pXcursorLibraryLoadCursor( gdi_display, cursors[i].name );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
if (!cursor) WARN( "no library cursor found for %s\n", debugstr_a(cursors[i].name) );
|
||||||
|
}
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SONAME_LIBXCURSOR */
|
#endif /* SONAME_LIBXCURSOR */
|
||||||
|
|
||||||
|
|
||||||
|
@ -838,6 +946,15 @@ static Cursor create_cursor( HANDLE handle )
|
||||||
info.cbSize = sizeof(info);
|
info.cbSize = sizeof(info);
|
||||||
if (!GetIconInfoExW( handle, &info )) return 0;
|
if (!GetIconInfoExW( handle, &info )) return 0;
|
||||||
|
|
||||||
|
#ifdef SONAME_LIBXCURSOR
|
||||||
|
if (use_system_cursors && (cursor = create_xcursor_system_cursor( &info )))
|
||||||
|
{
|
||||||
|
DeleteObject( info.hbmColor );
|
||||||
|
DeleteObject( info.hbmMask );
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GetObjectW( info.hbmMask, sizeof(bm), &bm );
|
GetObjectW( info.hbmMask, sizeof(bm), &bm );
|
||||||
if (!info.hbmColor) bm.bmHeight /= 2;
|
if (!info.hbmColor) bm.bmHeight /= 2;
|
||||||
|
|
||||||
|
|
|
@ -596,6 +596,7 @@ extern int dxgrab;
|
||||||
extern int use_xkb;
|
extern int use_xkb;
|
||||||
extern int use_take_focus;
|
extern int use_take_focus;
|
||||||
extern int use_primary_selection;
|
extern int use_primary_selection;
|
||||||
|
extern int use_system_cursors;
|
||||||
extern int usexcomposite;
|
extern int usexcomposite;
|
||||||
extern int managed_mode;
|
extern int managed_mode;
|
||||||
extern int decorated_mode;
|
extern int decorated_mode;
|
||||||
|
|
|
@ -82,6 +82,7 @@ int usexcomposite = 1;
|
||||||
int use_xkb = 1;
|
int use_xkb = 1;
|
||||||
int use_take_focus = 1;
|
int use_take_focus = 1;
|
||||||
int use_primary_selection = 0;
|
int use_primary_selection = 0;
|
||||||
|
int use_system_cursors = 1;
|
||||||
int managed_mode = 1;
|
int managed_mode = 1;
|
||||||
int decorated_mode = 1;
|
int decorated_mode = 1;
|
||||||
int private_color_map = 0;
|
int private_color_map = 0;
|
||||||
|
@ -396,6 +397,9 @@ static void setup_options(void)
|
||||||
if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
|
if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
|
||||||
use_primary_selection = IS_OPTION_TRUE( buffer[0] );
|
use_primary_selection = IS_OPTION_TRUE( buffer[0] );
|
||||||
|
|
||||||
|
if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
|
||||||
|
use_system_cursors = IS_OPTION_TRUE( buffer[0] );
|
||||||
|
|
||||||
screen_depth = 0;
|
screen_depth = 0;
|
||||||
if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
|
if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
|
||||||
screen_depth = atoi(buffer);
|
screen_depth = atoi(buffer);
|
||||||
|
|
Loading…
Reference in New Issue