Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completely blank mouse cursors end completely black #581

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Closed

Completely blank mouse cursors end completely black #581

SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Labels
duplicate This issue or pull request already exists

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

Reported in version: HG 2.0
Reported for operating system, platform: Windows (All), x86

Comments on the original bug report:

On 2012-05-03 01:30:39 +0000, Manuel Montoto wrote:

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.

On 2013-07-12 11:47:12 +0000, Ryan C. Gordon wrote:

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 ***

@SDLBugzilla SDLBugzilla added bug duplicate This issue or pull request already exists labels Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

1 participant