Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Problem with hardware mousecursors.

This thread is locked; no one can reply to it. rss feed Print
Problem with hardware mousecursors.
Andrei Ellman
Member #3,434
April 2003

Hi,

I am having trouble getting the hardware cursor to work properly under Windows 2000. Accodring to the docs, there is no hardware mousecursor available in Windows fullscreen mode. However, when I run the following fragment of code in Windows in fullscreen mode, the mouse-cursor becomes invisible (but the mouse still worked because the user-interface reacts to mouseover etc. events). When I run this in windowed mode (both Direct-X-windowed and GDI), the cursor is invisible until I move the mouse, and then it appears (apart from that, it's just fine in windowed mode).

1/* install mouse and set_gfx_mode have already been caled */
2if(G_bUsingHardwareMouseCursor)
3{
4 if(show_os_cursor(MOUSE_CURSOR_ARROW) != 0)
5 {
6 /* We failed to set up a hardware-cursor */
7 G_bUsingHardwareMouseCursor = FALSE;
8 }
9}
10 
11 
12if(!G_bUsingHardwareMouseCursor)
13{
14 if(G_bGfxPageFlip)
15 {
16 show_mouse(G_bmpaPages[1-G_nPage]); /* show it on the screen (and not where we're doing the drawing) */
17 }
18 else
19 {
20 show_mouse(screen);
21 }
22}

I've worked out that the mousecursor invisibility is caused by show_os_cursor(MOUSE_CURSOR_ARROW) succeeding (returning 0). If hardware cursors are not available on Windows fullscreen, then how come show_os_cursor(MOUSE_CURSOR_ARROW) succeeds? This happens regardless of whether or not I'm using page-flipping or not setting up page-flipping and blitting directly to screen .

In fullscreen, the gfx driver-ID == DXAC and gfx_capabilities == 0x7F30083 . In windowed mode (Direct X windowed), gfx driver-ID == DXWN and gfx driver-ID == 0x7F3008C. In windowed mode (GDI), gfx driver-ID == GDIB and 0x400004

I also tried an alternate approach. Instead of using show_os_cursor(), I used enable_hardware_cursor() and select_mouse_cursor(MOUSE_CURSOR_ARROW) and show_mouse() (question: is MOUSE_CURSOR_ALLEGRO (the default) usually implemented by Allegro instead of the OS?).

1/* install mouse and set_gfx_mode have already been caled */
2if(G_bUsingHardwareMouseCursor)
3{
4 enable_hardware_cursor();
5 select_mouse_cursor(MOUSE_CURSOR_ARROW);
6}
7 
8 
9if(G_bGfxPageFlip)
10{
11 show_mouse(G_bmpaPages[1-G_nPage]); /* show it on the screen (and not where we're doing the drawing) */
12}
13else
14{
15 show_mouse(screen);
16}
17 
18if(G_bUsingHardwareMouseCursor && !(gfx_capabilities & GFX_HW_CURSOR))
19{
20 /* We failed to set up a hardware-cursor */
21 G_bUsingHardwareMouseCursor = FALSE;
22}

When I run this under the Direct X windowed mode (DXWN), it behaves as I expect it to. gfx_capabilities == 0x7F3008C. However, if I run this under the GDI windowed mode, the program crashes in the line blit(gdi_screen, mouse_frontbuffer, x, y, 0, 0, mouse_frontbuffer->w, mouse_frontbuffer->h); in update_mouse_pointer() in wgdi.c (mouse_frontbuffer is NULL). However, if I comment out the first select_mouse_cursor(MOUSE_CURSOR_ARROW); and insert the following two lines in the above code after the first show_mouse()

select_mouse_cursor(MOUSE_CURSOR_ARROW);
show_mouse(screen);

I end up with two mouse-cursors - the allegro mouse-cursor and the system arrow. The allegro mouse-cursor is drawn under the system arrow and sometimes lags behind it if the arrow is moved too fast. gfx_capabilities == 0x400004. In fullscren mode, the code causes the program to crash. If I take out the select_mouse_cursor(MOUSE_CURSOR_ARROW); line, gfx_capabilities == 0x7B3008A and the software cursor is used.

So my question is: Is there a reliable cross-platform way of setting a hardware-cursor (if it's supported for that platform)?

Oh, and in my program, I want to be able to use mouse-mickeys in fullscreen mode (I scroll the screen if the mousecursor attempts to go past the edge of the screen), so if mouse-mickeys are likely to not work, let me know. In Windowed mode, it is not important, as I plan to implement scrollbars and keyboard movement to achieve the same effect.

AE.

--
Don't let the illegitimates turn you into carbon.

Evert
Member #794
November 2000
avatar

Quote:

is MOUSE_CURSOR_ALLEGRO (the default) usually implemented by Allegro instead of the OS?

Yes. You'd get Allegro's arrow drawn by the OS.

Quote:

Is there a reliable cross-platform way of setting a hardware-cursor (if it's supported for that platform)?

What you posted should be it.

Quote:

I want to be able to use mouse-mickeys in fullscreen mode (I scroll the screen if the mousecursor attempts to go past the edge of the screen)

This will work in Windows, not in X11, which stops passing mouse movement events when the mouse leaves the window or hits the window edge.

Only had a quick read through your post, so I can't offer too much in ways of guidance, so I'll just ask the standard question: what version of Allegro are you using?

Andrei Ellman
Member #3,434
April 2003

Evert said:

What you posted should be it.

In that case, there must be a bug in the windows DX-fullscreen implementation of show_os_cursor(MOUSE_CURSOR_ARROW) (it should return -1, but it returns 0), and also, a separate bug in the Windows GDI code that handles hardware mousecursors.

Evert said:

Quote:

I want to be able to use mouse-mickeys in fullscreen mode (I scroll the screen if the mousecursor attempts to go past the edge of the screen)

This will work in Windows, not in X11, which stops passing mouse movement events when the mouse leaves the window or hits the window edge.

So is this only a problem in X11 windowed mode, or is it also a problem in X11 fullscreen mode? If this is not possible in fullscreen mode, is there any way to register if the mousecursor is being pushed past the edge of the screen?

Evert said:

is MOUSE_CURSOR_ALLEGRO (the default) usually implemented by Allegro instead of the OS?

Quote:

Yes. You'd get Allegro's arrow drawn by the OS.

So does that mean that if I want to use customised mousecursor bitmaps that I'm stuck with the software mousecursor?

AE.

--
Don't let the illegitimates turn you into carbon.

Evert
Member #794
November 2000
avatar

Quote:

there must be a bug in the windows DX-fullscreen implementation of show_os_cursor(MOUSE_CURSOR_ARROW)

There shouldn't be one. The corresponding vtable entry should be NULL.

Quote:

So is this only a problem in X11 windowed mode, or is it also a problem in X11 fullscreen mode?

Both. X11 fullscreen is just X11 windowed without window decorations and your program taking up the entire screen space. The two are identical otherwise.

Quote:

If this is not possible in fullscreen mode, is there any way to register if the mousecursor is being pushed past the edge of the screen?

Not that I know of. The only way to do it (and the way Allegro does it) is to warp the cursor to the centre of the screen. Not what you want with a hardware cursor, obviously.

Quote:

So does that mean that if I want to use customised mousecursor bitmaps that I'm stuck with the software mousecursor?

No. Sorry if I was unclear. :) If you want a customised mouse cursor, you should not normally bother with select_mouse_cursor() though, since that is only useful for giving you the OS cursor.

Andrei Ellman
Member #3,434
April 2003

Quote:

Quote:

there must be a bug in the windows DX-fullscreen implementation of show_os_cursor(MOUSE_CURSOR_ARROW)

There shouldn't be one. The corresponding vtable entry should be NULL.

I just checked the Allegro sourcecode and it isn't - it's a do-nothing function.

I've had a look and have discovered that all windows gfx modes (DX (both fullscreen and windowed) and GDI) use the same mouse-driver ( mouse_directx ). mouse_directx->enable_hardware_cursor is mouse_directx_enable_hardware_cursor which is a do-nothing function. The code in enable_hardware_cursor() checks to see if mouse_directx->enable_hardware_cursor is NULL and if it isn't, it does a few other things apart from call mouse_driver->enable_hardware_cursor, so I'm starting to suspect that there's a bug somewhere in the Windows mouse-code (or maybe additional mouse-drivers are needed depending on whether or not hardware cursors are supported).

Quote:

Quote:

If this is not possible in fullscreen mode, is there any way to register if the mousecursor is being pushed past the edge of the screen?

Not that I know of. The only way to do it (and the way Allegro does it) is to warp the cursor to the centre of the screen. Not what you want with a hardware cursor, obviously.

Even without a hardware cursor, I'll be displaying the cursor, so would not want to wrap it to the centre of the screen each time it passes the edge. Would I have to use a software-cursor in such cases?

Quote:

Quote:

So does that mean that if I want to use customised mousecursor bitmaps that I'm stuck with the software mousecursor?

No. Sorry if I was unclear. :) If you want a customised mouse cursor, you should not normally bother with select_mouse_cursor() though, since that is only useful for giving you the OS cursor.

I just tried it by calling enable_hardware_cursor(); and not calling select_mouse_cursor();. In both DX Fullscreen and DX Windowed, GFX_HW_CURSOR is not set in gfx_capabilities, but it is in GDI mode.

Quote:

what version of Allegro are you using?

Oops. Forgot to mention. 4.2.1 under Windows 2000

AE.

--
Don't let the illegitimates turn you into carbon.

Go to: