We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1488

Summary: Completely blank mouse cursors end completely black
Product: SDL Reporter: Manuel Montoto <g.manu>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED DUPLICATE QA Contact: Sam Lantinga <slouken>
Severity: trivial    
Priority: P2 CC: icculus
Version: HG 2.0   
Hardware: x86   
OS: Windows (All)   

Description Manuel Montoto 2012-05-03 01:30:39 UTC
Not a deal breaker, but looks like there's some sort of circumstance in Windows that doesn't allow you to create a blank mouse cursor under SDL 2.0. 

I'm porting an old 1.2 application and for some stupid reason I used a blank cursor to hide the pointer when needed. This is not possible anymore under 2.0. I'm just going to call to the corresponding SDL function to hide it, but before doing it, for the sake of completeness, I felt it was better to fill this bug report.

If, when creating the cursor surface, the alpha mask is all 0s, then the result is just the opposite one could expect: the cursor is a black square. This behavior doesn't show under SDL 1.2, or at least, it didn't in the version I had (can't really check which one it was now).

I have been peeking at the SDL 2.0 source code and have not found why it should work on 1.2 and not on 2.0, because as far as I have been able to understand, the problem lies in the call to the function to CreateIconIndirect() in WIN_CreateCursor(). So... Looks like a Windows bug, to me.

Still, I would suggest a small patch like one of those two:

static SDL_Cursor *
WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    SDL_Cursor *cursor;
    HICON hicon;
    HDC hdc;
    BITMAPV4HEADER bmh;
    LPVOID pixels;
    ICONINFO ii;

    // Small patch to ensure an empty mouse cursor remains empty and not black.
    *((unsigned long *)surface->pixels) = *((unsigned long *)surface->pixels) | 0x01000000 ;

    SDL_zero(bmh);

(Rest of the function)


My tests, checking pixel by pixel with screen captures, determine that no pixel is drawn in any way with this patch, and no noticeable difference is created in a "normal" mouse cursor.

Still, I'm not sure if it's really clean to always modify the alpha channel :-) So we can patch the image only if we find the mouse cursor alpha channel is REALLY blank:

static SDL_Cursor *
WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    SDL_Cursor *cursor;
    HICON hicon;
    HDC hdc;
    BITMAPV4HEADER bmh;
    LPVOID pixels;
    ICONINFO ii;

    {
      // Small patch to ensure an empty mouse cursor remains empty and not black.

      int varx, vary ;
      int bFound ;
      unsigned long *pixel_pointer ;

      // Found flag

      bFound = 0 ;

      // For each line...

      for(vary = 0; vary < surface->h; vary++) {

        // Get the pixel_pointer to the start of this line

        pixel_pointer = (unsigned long *)(((unsigned char *)surface->pixels) + (vary * surface->pitch))  ;

        // Iterate over all the pixels in the line

        for(varx = 0; varx < surface->w; varx++) {

          // If the alpha value on this pixel contains a value over 0 we are over

          if( (*pixel_pointer) && 0xFF000000) {
          
            bFound = 1 ; // Set the flag so we can know there's something here
            break ;      // then break
          }
          
          // Increase the pixel_pointer to look at the next pixel

          pixel_pointer++ ;
        }

        // If we found an alpha value over 0 while traversing the line, break the Y loop, too

        if(bFound) break ;
      }

      // If after all we had a 100% invisible graphic, we add a very small
      // alpha value to the first pixel, so the Windows bug is not triggered

      if(!bFound) *((unsigned long *)surface->pixels) = 0x01000000 ;
    }

    SDL_zero(bmh);

(Rest of the function)


Much longer but still we are talking about very small images, and although it is going to break soon on the vast majority of times, completing the full iteration is too fast to really care about.

The behaviour and the patches have been tested both on Windows 7 Ultimate x64 and Windows XP x86.
Comment 1 Ryan C. Gordon 2013-07-12 11:47:12 UTC
This is a duplicate of Bug #1461. This is good information, though, so I'm just consolidating here and will make a note in the other bug to check the existing comments here, too.

--ryan.

*** This bug has been marked as a duplicate of bug 1461 ***