| Summary: | Completely blank mouse cursors end completely black | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Manuel Montoto <g.manu> |
| Component: | video | Assignee: | 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) | ||
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.