Re: [AD] Using system mouse cursor

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


> Revised patch, with some obvious bugfixes. I removed the parameter on the 
> public function and split the API into two functions: one to enable, one 
> to disable the hardware cursor.
> Added documentation for the two new functions.

Cleaned up patch. I mainly fixed the problems with position_mouse() not 
working properly with the hardware cursor enabled. The default mode with 
this patch is still Allegro's current behavior: the user has to call 
enable_hardware_cursor() explicitly for the hardware cursor to be 
available in X.
There is one potential trouble spot with this patch: calling 
position_mouse() repeatedly from within a tight loop will flood the X11 
event queue, pretty much making the application unresponsive. A possible 
solution would be to restrict how often the mouse can be warped. This 
could be done with some slight polishing and updating of the current code, 
but I'd like to know first if the problem occurs in a realistic situation 
where position_mouse() probably is not called continuously from within a 
tight loop.

Evert
diff -ur allegro/src/beos/bmouse.c alleg_work/src/beos/bmouse.c
--- allegro/src/beos/bmouse.c	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/src/beos/bmouse.c	2004-09-19 17:57:21.000000000 +0200
@@ -38,5 +38,6 @@
    be_mouse_set_range,	// AL_METHOD(void, set_range, (int x1, int y1, int x2, int y2));
    be_mouse_set_speed,	// AL_METHOD(void, set_speed, (int xspeed, int yspeed));
    be_mouse_get_mickeys,// AL_METHOD(void, get_mickeys, (int *mickeyx, int *mickeyy));
-   NULL                 // AL_METHOD(int,  analyse_data, (const char *buffer, int size));
+   NULL,                // AL_METHOD(int,  analyse_data, (const char *buffer, int size));
+   NULL                 // AL_METHOD(void,  enable_hardware_cursor, (AL_CONST int mode));
 };
diff -ur allegro/src/dos/dmouse.c alleg_work/src/dos/dmouse.c
--- allegro/src/dos/dmouse.c	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/src/dos/dmouse.c	2004-09-19 17:57:21.000000000 +0200
@@ -95,6 +95,7 @@
    mick_set_range,
    mick_set_speed,
    mick_get_mickeys,
+   NULL,
    NULL
 };
 
@@ -123,6 +124,7 @@
    int33_set_range,
    int33_set_speed,
    int33_get_mickeys,
+   NULL,
    NULL
 };
 
@@ -148,6 +150,7 @@
    int33_set_range,
    int33_set_speed,
    int33_get_mickeys,
+   NULL,
    NULL
 };
 
@@ -171,6 +174,7 @@
    int33_set_range,
    int33_set_speed,
    int33_get_mickeys,
+   NULL,
    NULL
 };
 
@@ -194,6 +198,7 @@
    mick_set_range,
    mick_set_speed,
    mick_get_mickeys,
+   NULL,
    NULL
 };
 
diff -ur allegro/src/macosx/qzmouse.m alleg_work/src/macosx/qzmouse.m
--- allegro/src/macosx/qzmouse.m	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/src/macosx/qzmouse.m	2004-09-19 17:57:21.000000000 +0200
@@ -46,7 +46,8 @@
    osx_mouse_set_range,
    NULL,       // AL_METHOD(void, set_speed, (int xspeed, int yspeed));
    osx_mouse_get_mickeys,
-   NULL        // AL_METHOD(int,  analyse_data, (AL_CONST char *buffer, int size));
+   NULL,       // AL_METHOD(int,  analyse_data, (AL_CONST char *buffer, int size));
+   NULL        // AL_METHOD(void,  enable_hardware_cursor, (AL_CONST int mode));
 };
 
 
diff -ur allegro/src/mouse.c alleg_work/src/mouse.c
--- allegro/src/mouse.c	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/src/mouse.c	2004-09-19 18:02:45.000000000 +0200
@@ -736,6 +736,41 @@
 
 
 
+/* enable_hardware_cursor:
+ *  enabels the hardware cursor on platforms where this needs to be done
+ *  explicitly
+ */
+void enable_hardware_cursor(void)
+{
+   if ((mouse_driver) && (mouse_driver->enable_hardware_cursor)) {
+      mouse_driver->enable_hardware_cursor(TRUE);
+      if (is_same_bitmap(_mouse_screen, screen)) {
+         BITMAP *bmp = _mouse_screen;
+         show_mouse(NULL);
+         show_mouse(bmp);
+      }
+   }
+}
+
+
+
+/* disable_hardware_cursor:
+ *  disables the hardware cursor on platforms where this interferes with mickeys
+ */
+void disable_hardware_cursor(void)
+{
+   if ((mouse_driver) && (mouse_driver->enable_hardware_cursor)) {
+      mouse_driver->enable_hardware_cursor(FALSE);
+      if (is_same_bitmap(_mouse_screen, screen)) {
+         BITMAP *bmp = _mouse_screen;
+         show_mouse(NULL);
+         show_mouse(bmp);
+      }
+   }
+}
+
+
+
 /* poll_mouse:
  *  Polls the current mouse state, and updates the user-visible information
  *  accordingly. On some drivers this is actually required to get the
diff -ur allegro/src/qnx/qmouse.c alleg_work/src/qnx/qmouse.c
--- allegro/src/qnx/qmouse.c	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/src/qnx/qmouse.c	2004-09-19 17:57:21.000000000 +0200
@@ -48,7 +48,8 @@
    qnx_mouse_set_range,
    NULL,       // AL_METHOD(void, set_speed, (int xspeed, int yspeed));
    qnx_mouse_get_mickeys,
-   NULL        // AL_METHOD(int,  analyse_data, (AL_CONST char *buffer, int size));
+   NULL,       // AL_METHOD(int,  analyse_data, (AL_CONST char *buffer, int size));
+   NULL        // AL_METHOD(void,  enable_hardware_cursor, (AL_CONST int mode));
 };
 
 
diff -ur allegro/src/win/wmouse.c alleg_work/src/win/wmouse.c
--- allegro/src/win/wmouse.c	2004-09-17 00:28:16.000000000 +0200
+++ alleg_work/src/win/wmouse.c	2004-09-19 17:57:21.000000000 +0200
@@ -62,7 +62,8 @@
    mouse_directx_set_range,
    mouse_directx_set_speed,
    mouse_directx_get_mickeys,
-   NULL                        // AL_METHOD(int, analyse_data, (AL_CONST char *buffer, int size));
+   NULL,                       // AL_METHOD(int, analyse_data, (AL_CONST char *buffer, int size));
+   NULL                        // AL_METHOD(void,  enable_hardware_cursor, (AL_CONST int mode));
 };
 
 
diff -ur allegro/src/x/xmouse.c alleg_work/src/x/xmouse.c
--- allegro/src/x/xmouse.c	2004-09-17 00:28:16.000000000 +0200
+++ alleg_work/src/x/xmouse.c	2004-09-20 00:33:47.000000000 +0200
@@ -64,7 +64,8 @@
    _xwin_mousedrv_set_range,
    _xwin_mousedrv_set_speed,
    _xwin_mousedrv_get_mickeys,
-   NULL
+   NULL,
+   _xwin_enable_hardware_cursor
 };
 
 
@@ -151,6 +152,9 @@
 
    mymickey_x = mymickey_y = 0;
 
+   if (_xwin.hw_cursor_ok)
+      XWarpPointer(_xwin.display, _xwin.window, _xwin.window, 0, 0, 
+                   _xwin.window_width, _xwin.window_height, x, y);
    XUNLOCK();
 
    _xwin_set_warped_mouse_mode(FALSE);
diff -ur allegro/src/x/xwin.c alleg_work/src/x/xwin.c
--- allegro/src/x/xwin.c	2004-09-17 00:28:16.000000000 +0200
+++ alleg_work/src/x/xwin.c	2004-09-20 00:33:43.000000000 +0200
@@ -430,10 +430,8 @@
 #ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
    /* Detect if ARGB cursors are supported */
    _xwin.support_argb_cursor = XcursorSupportsARGB(_xwin.display);
-   _xwin.hw_cursor_ok = 1;
-#else
-   _xwin.hw_cursor_ok = 0;
 #endif
+   _xwin.hw_cursor_ok = 0;
    
    return 0;
 }
@@ -1529,6 +1527,31 @@
 
 
 
+/* _xwin_enable_hardware_cursor:
+ *  enable the hardware cursor; this disables the mouse mickey warping hack
+ */
+void _xwin_enable_hardware_cursor(int mode)
+{
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+   if (_xwin.support_argb_cursor)
+      _xwin.hw_cursor_ok = mode;
+   else
+#endif
+      _xwin.hw_cursor_ok = 0;
+   
+   /* Switch to non-warped mode */
+   if (_xwin.hw_cursor_ok) {
+      _xwin.mouse_warped = 0;
+      /* Move X-cursor to Allegro cursor.  */
+      XWarpPointer(_xwin.display, _xwin.window, _xwin.window,
+		   0, 0, _xwin.window_width, _xwin.window_height,
+		   _mouse_x - (_xwin_mouse_extended_range ? _xwin.scroll_x : 0),
+		   _mouse_y - (_xwin_mouse_extended_range ? _xwin.scroll_y : 0));
+   }
+}
+
+
+
 #ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
 
 /* _xwin_set_mouse_sprite:
@@ -1660,12 +1683,10 @@
 
 
 /* _xwin_move_mouse:
- *  Move the custom X cursor. This is actually done automatically.
+ *  Get mouse move notification. Not that we need it...
  */
 void _xwin_move_mouse(int x, int y)
 {
-      _mouse_x = x;
-      _mouse_y = y;
 }
 
 #endif   /* ALLEGRO_XWINDOWS_WITH_XCURSOR */
@@ -2382,14 +2403,6 @@
 		   0, 0, _xwin.window_width, _xwin.window_height,
 		   _mouse_x - (_xwin_mouse_extended_range ? _xwin.scroll_x : 0),
 		   _mouse_y - (_xwin_mouse_extended_range ? _xwin.scroll_y : 0));
-      /* Re-enable hardware cursor */
-      _xwin.hw_cursor_ok = 1;
-#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
-      if (_xwin.support_argb_cursor && (_xwin.xcursor_image != None) && is_same_bitmap(_mouse_screen, screen)) {
-	 show_mouse(_mouse_screen);
-      }
-#endif
-         
    }
 
    /* Flush X-buffers.  */
@@ -2461,15 +2474,9 @@
  */
 static void _xwin_private_set_warped_mouse_mode(int permanent)
 {
-   _xwin.mouse_warped = ((permanent) ? 1 : (MOUSE_WARP_DELAY*7/8));
-   
-   /* Disable hardware cursor in warp mode */
-#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
-   if (_xwin.hw_cursor_ok && permanent && _xwin.support_argb_cursor && (_xwin.xcursor_image != None) && is_same_bitmap(_mouse_screen, screen)) {
-      show_mouse(_mouse_screen);
-   }
-#endif
-   _xwin.hw_cursor_ok = !permanent;
+   /* Don't enable warp mode if the hardware cursor is being displayed */
+   if (!_xwin.hw_cursor_ok)
+      _xwin.mouse_warped = ((permanent) ? 1 : (MOUSE_WARP_DELAY*7/8));
 }
 
 void _xwin_set_warped_mouse_mode(int permanent)
diff -ur allegro/src/x/xwin.h alleg_work/src/x/xwin.h
--- allegro/src/x/xwin.h	2004-09-17 00:28:16.000000000 +0200
+++ alleg_work/src/x/xwin.h	2004-09-19 17:57:21.000000000 +0200
@@ -42,7 +42,7 @@
 AL_FUNC(void, _xwin_flush_buffers, (void));
 AL_FUNC(void, _xwin_vsync, (void));
 AL_FUNC(void, _xwin_handle_input, (void));
-AL_FUNC(void, _xwin_set_warped_mouse_mode, (int permanent));
+AL_FUNC(void, _xwin_enable_hardware_cursor, (int mode));
 AL_FUNC(void, _xwin_redraw_window, (int x, int y, int w, int h));
 AL_FUNC(int, _xwin_scroll_screen, (int x, int y));
 AL_FUNC(void, _xwin_update_screen, (int x, int y, int w, int h));
diff -ur allegro/include/allegro/mouse.h alleg_work/include/allegro/mouse.h
--- allegro/include/allegro/mouse.h	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/include/allegro/mouse.h	2004-09-19 17:57:21.000000000 +0200
@@ -44,6 +44,7 @@
    AL_METHOD(void, set_speed, (int xspeed, int yspeed));
    AL_METHOD(void, get_mickeys, (int *mickeyx, int *mickeyy));
    AL_METHOD(int,  analyse_data, (AL_CONST char *buffer, int size));
+   AL_METHOD(void,  enable_hardware_cursor, (AL_CONST int mode));
 } MOUSE_DRIVER;
 
 
@@ -57,6 +58,9 @@
 AL_FUNC(int, poll_mouse, (void));
 AL_FUNC(int, mouse_needs_poll, (void));
 
+AL_FUNC(void, enable_hardware_cursor, (void));
+AL_FUNC(void, disable_hardware_cursor, (void));
+
 AL_VAR(struct BITMAP *, mouse_sprite);
 AL_VAR(int, mouse_x_focus);
 AL_VAR(int, mouse_y_focus);
diff -ur allegro/docs/src/allegro._tx alleg_work/docs/src/allegro._tx
--- allegro/docs/src/allegro._tx	2004-09-17 00:28:15.000000000 +0200
+++ alleg_work/docs/src/allegro._tx	2004-09-19 17:57:21.000000000 +0200
@@ -2177,6 +2177,19 @@
 @xref poll_mouse, install_mouse, mouse_x
    Returns TRUE if the current mouse driver is operating in polling mode.
 
+@@void @enable_hardware_cursor(void);
+@xref install_mouse, get_mouse_mickeys, gfx_capabilities
+   Enables the mouse hardware cursor on platforms where it interferes with
+   getting mouse mickeys. Using get_mouse_mickeys() becomes unreliable after
+   calling this function.
+
+@@void @disable_hardware_cursor(void);
+@xref install_mouse, get_mouse_mickeys, gfx_capabilities
+   Disables the mouse hardware cursor on platforms where it interferes with
+   getting mouse mickeys. Using get_mouse_mickeys() becomes reliable again
+   after calling this function.
+
+
 @@extern volatile int @mouse_x;
 @@extern volatile int @mouse_y;
 @@extern volatile int @mouse_z;


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/