Alexandre Julliard : winex11: Add support for remapping standard Win32 cursors to the X11 system cursors .
Alexandre Julliard
julliard at winehq.org
Mon Oct 18 13:36:52 CDT 2010
Module: wine
Branch: master
Commit: 45b87f1f9466315fe58de6d7fbf5123f48c0b231
URL: http://source.winehq.org/git/wine.git/?a=commit;h=45b87f1f9466315fe58de6d7fbf5123f48c0b231
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Oct 18 12:16:28 2010 +0200
winex11: Add support for remapping standard Win32 cursors to the X11 system cursors.
---
dlls/winex11.drv/mouse.c | 117 ++++++++++++++++++++++++++++++++++++++++
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/x11drv_main.c | 4 ++
3 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 0b87c44..0746fd9 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -23,6 +23,7 @@
#include "wine/port.h"
#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
#include <stdarg.h>
#ifdef SONAME_LIBXCURSOR
@@ -35,11 +36,13 @@ MAKE_FUNCPTR(XcursorImageLoadCursor);
MAKE_FUNCPTR(XcursorImagesCreate);
MAKE_FUNCPTR(XcursorImagesDestroy);
MAKE_FUNCPTR(XcursorImagesLoadCursor);
+MAKE_FUNCPTR(XcursorLibraryLoadCursor);
# undef MAKE_FUNCPTR
#endif /* SONAME_LIBXCURSOR */
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
+#define OEMRESOURCE
#include "windef.h"
#include "winbase.h"
@@ -120,6 +123,7 @@ void X11DRV_Xcursor_Init(void)
LOAD_FUNCPTR(XcursorImagesCreate);
LOAD_FUNCPTR(XcursorImagesDestroy);
LOAD_FUNCPTR(XcursorImagesLoadCursor);
+ LOAD_FUNCPTR(XcursorLibraryLoadCursor);
#undef LOAD_FUNCPTR
#endif /* SONAME_LIBXCURSOR */
}
@@ -622,6 +626,110 @@ cleanup:
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 */
@@ -838,6 +946,15 @@ static Cursor create_cursor( HANDLE handle )
info.cbSize = sizeof(info);
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 );
if (!info.hbmColor) bm.bmHeight /= 2;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a4b9d76..536a4a1 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -596,6 +596,7 @@ extern int dxgrab;
extern int use_xkb;
extern int use_take_focus;
extern int use_primary_selection;
+extern int use_system_cursors;
extern int usexcomposite;
extern int managed_mode;
extern int decorated_mode;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index b07061c..cf221b1 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -82,6 +82,7 @@ int usexcomposite = 1;
int use_xkb = 1;
int use_take_focus = 1;
int use_primary_selection = 0;
+int use_system_cursors = 1;
int managed_mode = 1;
int decorated_mode = 1;
int private_color_map = 0;
@@ -396,6 +397,9 @@ static void setup_options(void)
if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
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;
if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
screen_depth = atoi(buffer);
More information about the wine-cvs
mailing list