Re: [AD] Using system mouse cursor |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
Or even better: this one. Some aesthetic fixes and a bugfix.
Evert
Index: include/xalleg.h
===================================================================
RCS file: /cvsroot/alleg/allegro/include/xalleg.h,v
retrieving revision 1.16
diff -u -r1.16 xalleg.h
--- include/xalleg.h 15 Nov 2002 11:07:48 -0000 1.16
+++ include/xalleg.h 24 Aug 2004 22:04:12 -0000
@@ -49,6 +49,11 @@
#include <X11/extensions/xf86dga.h>
#endif
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
+
+
#ifdef __cplusplus
extern "C" {
@@ -65,6 +70,9 @@
Visual *visual;
Colormap colormap;
XImage *ximage;
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+ XcursorImage *xcursor_image;
+#endif
Cursor cursor;
int cursor_shape;
Index: src/x/xgfxdrv.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xgfxdrv.c,v
retrieving revision 1.14
diff -u -r1.14 xgfxdrv.c
--- src/x/xgfxdrv.c 18 Aug 2004 12:45:53 -0000 1.14
+++ src/x/xgfxdrv.c 24 Aug 2004 22:04:14 -0000
@@ -39,7 +39,14 @@
NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL,
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+ _xwin_set_mouse_sprite,
+ _xwin_show_mouse,
+ _xwin_hide_mouse,
+ _xwin_move_mouse,
+#else
NULL, NULL, NULL, NULL,
+#endif
_xwin_drawing_mode,
NULL, NULL,
NULL,
@@ -71,7 +78,14 @@
NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL,
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+ _xwin_set_mouse_sprite,
+ _xwin_show_mouse,
+ _xwin_hide_mouse,
+ _xwin_move_mouse,
+#else
NULL, NULL, NULL, NULL,
+#endif
_xwin_drawing_mode,
NULL, NULL,
_xwin_fetch_mode_list,
Index: src/x/xwin.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xwin.c,v
retrieving revision 1.67
diff -u -r1.67 xwin.c
--- src/x/xwin.c 24 Aug 2004 14:06:22 -0000 1.67
+++ src/x/xwin.c 24 Aug 2004 22:04:17 -0000
@@ -48,6 +48,10 @@
#include <X11/extensions/xf86dga.h>
#endif
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
+
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
#include <X11/xpm.h>
@@ -70,6 +74,9 @@
0, /* visual */
None, /* colormap */
0, /* ximage */
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+ None, /* ARGB cursor image */
+#endif
None, /* cursor */
XC_heart, /* cursor_shape */
@@ -351,6 +358,42 @@
+/* _xwin_hide_x_mouse:
+ * Create invisible X cursor
+ */
+static void _xwin_hide_x_mouse(void)
+{
+ unsigned long gcmask;
+ XGCValues gcvalues;
+ Pixmap pixmap;
+
+ pixmap = XCreatePixmap(_xwin.display, _xwin.window, 1, 1, 1);
+ if (pixmap != None) {
+ GC temp_gc;
+ XColor color;
+
+ gcmask = GCFunction | GCForeground | GCBackground;
+ gcvalues.function = GXcopy;
+ gcvalues.foreground = 0;
+ gcvalues.background = 0;
+ temp_gc = XCreateGC(_xwin.display, pixmap, gcmask, &gcvalues);
+ XDrawPoint(_xwin.display, pixmap, temp_gc, 0, 0);
+ XFreeGC(_xwin.display, temp_gc);
+ color.pixel = 0;
+ color.red = color.green = color.blue = 0;
+ color.flags = DoRed | DoGreen | DoBlue;
+ _xwin.cursor = XCreatePixmapCursor(_xwin.display, pixmap, pixmap, &color, &color, 0, 0);
+ XDefineCursor(_xwin.display, _xwin.window, _xwin.cursor);
+ XFreePixmap(_xwin.display, pixmap);
+ }
+ else {
+ _xwin.cursor = XCreateFontCursor(_xwin.display, _xwin.cursor_shape);
+ XDefineCursor(_xwin.display, _xwin.window, _xwin.cursor);
+ }
+}
+
+
+
/* _xwin_create_window:
* Wrapper for XCreateWindow.
*/
@@ -360,7 +403,6 @@
XGCValues gcvalues;
XSetWindowAttributes setattr;
XWindowAttributes getattr;
- Pixmap pixmap;
if (_xwin.display == 0)
return -1;
@@ -412,29 +454,7 @@
_xwin.gc = XCreateGC(_xwin.display, _xwin.window, gcmask, &gcvalues);
/* Create invisible X cursor. */
- pixmap = XCreatePixmap(_xwin.display, _xwin.window, 1, 1, 1);
- if (pixmap != None) {
- GC temp_gc;
- XColor color;
-
- gcmask = GCFunction | GCForeground | GCBackground;
- gcvalues.function = GXcopy;
- gcvalues.foreground = 0;
- gcvalues.background = 0;
- temp_gc = XCreateGC(_xwin.display, pixmap, gcmask, &gcvalues);
- XDrawPoint(_xwin.display, pixmap, temp_gc, 0, 0);
- XFreeGC(_xwin.display, temp_gc);
- color.pixel = 0;
- color.red = color.green = color.blue = 0;
- color.flags = DoRed | DoGreen | DoBlue;
- _xwin.cursor = XCreatePixmapCursor(_xwin.display, pixmap, pixmap, &color, &color, 0, 0);
- XDefineCursor(_xwin.display, _xwin.window, _xwin.cursor);
- XFreePixmap(_xwin.display, pixmap);
- }
- else {
- _xwin.cursor = XCreateFontCursor(_xwin.display, _xwin.cursor_shape);
- XDefineCursor(_xwin.display, _xwin.window, _xwin.cursor);
- }
+ _xwin_hide_x_mouse();
return 0;
}
@@ -1582,6 +1602,141 @@
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+
+/* _xwin_set_mouse_sprite:
+ * Set custom X cursor (if supported)
+ */
+int _xwin_set_mouse_sprite(struct BITMAP *sprite, int x, int y)
+{
+#define GET_PIXEL_DATA(depth, getpix, mask) \
+ case depth: \
+ col = getpix(mouse_sprite, ix, iy); \
+ r = getr ## depth(col); \
+ g = getg ## depth(col); \
+ b = getb ## depth(col); \
+ if (col == (mask)) \
+ a = 0; \
+ else \
+ a = 255;
+
+ XLOCK();
+ if (!XcursorSupportsARGB(_xwin.display)) {
+ XUNLOCK();
+ return -1;
+ }
+
+ if (_xwin.xcursor_image != None) {
+ XcursorImageDestroy(_xwin.xcursor_image);
+ _xwin.xcursor_image = None;
+ }
+ XUNLOCK();
+
+ if (sprite) {
+ int ix, iy;
+ int r = 0, g = 0, b = 0, a = 0, c, col;
+
+ _xwin.xcursor_image = XcursorImageCreate(sprite->w, sprite->h);
+ if (_xwin.xcursor_image == None) {
+ return -1;
+ }
+
+ c = 0;
+ for(iy=0; iy<mouse_sprite->h; iy++) {
+ for(ix=0; ix<mouse_sprite->w; ix++) {
+ switch(bitmap_color_depth(mouse_sprite)) {
+ GET_PIXEL_DATA(8, _getpixel, MASK_COLOR_8)
+ break;
+
+ GET_PIXEL_DATA(15, _getpixel15, MASK_COLOR_15)
+ break;
+
+ GET_PIXEL_DATA(16, _getpixel16, MASK_COLOR_16)
+ break;
+
+ GET_PIXEL_DATA(24, _getpixel24, MASK_COLOR_24)
+ break;
+
+ GET_PIXEL_DATA(32, _getpixel32, MASK_COLOR_32)
+ break;
+ } /* End switch */
+ _xwin.xcursor_image->pixels[c++] = (a<<24)|(r<<16)|(g<<8)|(b);
+ }
+ }
+
+ _xwin.xcursor_image->xhot = mouse_x_focus;
+ _xwin.xcursor_image->yhot = mouse_y_focus;
+
+ return 0;
+ }
+
+#undef GET_PIXEL_DATA
+
+ return -1;
+}
+
+
+
+/* _xwin_show_mouse:
+ * Show the custom X cursor (if supported)
+ */
+int _xwin_show_mouse(struct BITMAP *bmp, int x, int y)
+{
+ /* Only draw on screen */
+ if (!is_same_bitmap(bmp, screen))
+ return -1;
+
+ XLOCK();
+ if (!XcursorSupportsARGB(_xwin.display)) {
+ XUNLOCK();
+ return -1;
+ }
+
+ if (_xwin.xcursor_image == None) {
+ XUNLOCK();
+ return -1;
+ }
+
+ if (_xwin.cursor != None) {
+ XUndefineCursor(_xwin.display, _xwin.window);
+ XFreeCursor(_xwin.display, _xwin.cursor);
+ }
+
+ _xwin.cursor = XcursorImageLoadCursor(_xwin.display, _xwin.xcursor_image);
+ XDefineCursor(_xwin.display, _xwin.window, _xwin.cursor);
+
+ XUNLOCK();
+ return 0;
+}
+
+
+
+/* _xwin_hide_mouse:
+ * Hide the custom X cursor (if supported)
+ */
+void _xwin_hide_mouse(void)
+{
+ XLOCK();
+ if (XcursorSupportsARGB(_xwin.display)) {
+ _xwin_hide_x_mouse();
+ }
+ XUNLOCK();
+ return;
+}
+
+
+
+/* _xwin_move_mouse:
+ * Move the custom X cursor. This is actually done automatically.
+ */
+void _xwin_move_mouse(int x, int y)
+{
+}
+
+#endif /* ALLEGRO_XWINDOWS_WITH_XCURSOR */
+
+
+
#ifdef ALLEGRO_XWINDOWS_WITH_XF86DGA
/* _xdga_fast_visual_depth:
Index: src/x/xwin.h
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xwin.h,v
retrieving revision 1.17
diff -u -r1.17 xwin.h
--- src/x/xwin.h 18 Aug 2004 13:03:46 -0000 1.17
+++ src/x/xwin.h 24 Aug 2004 22:04:17 -0000
@@ -51,6 +51,13 @@
AL_FUNC(int, _xwin_get_pointer_mapping, (unsigned char map[], int nmap));
AL_FUNC(void, _xwin_init_keyboard_tables, (void));
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+AL_FUNC(int, _xwin_set_mouse_sprite, (struct BITMAP *sprite, int x, int y));
+AL_FUNC(int, _xwin_show_mouse, (struct BITMAP *bmp, int x, int y));
+AL_FUNC(void, _xwin_hide_mouse, (void));
+AL_FUNC(void, _xwin_move_mouse, (int x, int y));
+#endif
+
AL_FUNC(BITMAP*, _xdga_create_screen, (GFX_DRIVER *drv, int w, int h,
int vw, int vh, int depth, int fullscreen));
AL_FUNC(void, _xdga_destroy_screen, (void));
Index: aclocal.m4
===================================================================
RCS file: /cvsroot/alleg/allegro/aclocal.m4,v
retrieving revision 1.67
diff -u -r1.67 aclocal.m4
--- aclocal.m4 24 Aug 2004 18:34:07 -0000 1.67
+++ aclocal.m4 24 Aug 2004 22:08:09 -0000
@@ -257,6 +257,19 @@
AC_DEFINE(ALLEGRO_XWINDOWS_WITH_XPM,1,[Define if xpm bitmap support is available.])
])
)
+
+ dnl Test for Xcursor library.
+ AC_CHECK_LIB(Xcursor, XcursorImageCreate,
+ AC_TRY_COMPILE([#include <X11/Xlib.h>
+ #include <X11/Xcursor/Xcursor.h>],
+ [XcursorImage *xcursor_image;
+ XcursorImageLoadCursor(0, xcursor_image);
+ XcursorSupportsARGB(0);
+ ],
+ [LIBS="-lXcursor $LIBS"
+ AC_DEFINE(ALLEGRO_XWINDOWS_WITH_XCURSOR,1,[Define if XCursor ARGB extension is available.])
+ ])
+ )
dnl Test for SHM extension.
if test -n "$allegro_enable_xwin_shm"; then