From 2e8458402740ca116ca3cc91846f8d76e7ea4198 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 23 Dec 2005 09:40:15 +0000 Subject: [PATCH] From: "alan buckley" Subject: Patch for RISC OS cursor palette handling in SDL Date: Mon, 07 Nov 2005 09:14:15 -0800 The mouse cursor palette was not correctly restored on RISC OS if the system was using anything but the default mouse colours. Additionally I've modifed the order the wait for vsync is called as it should be after the screen bank switching. --- src/video/riscos/SDL_riscosFullScreenVideo.c | 7 +- src/video/riscos/SDL_riscosmouse.c | 135 ++++++++++++++----- src/video/riscos/SDL_riscosvideo.c | 5 + src/video/riscos/SDL_wimppoll.c | 6 +- 4 files changed, 114 insertions(+), 39 deletions(-) diff --git a/src/video/riscos/SDL_riscosFullScreenVideo.c b/src/video/riscos/SDL_riscosFullScreenVideo.c index e18cbd3ed..f3dd716e1 100644 --- a/src/video/riscos/SDL_riscosFullScreenVideo.c +++ b/src/video/riscos/SDL_riscosFullScreenVideo.c @@ -280,8 +280,6 @@ void FULLSCREEN_SetDeviceMode(_THIS) } else this->UpdateRects = FULLSCREEN_UpdateRects; /* Default do nothing implementation */ - if (this->SetColors == FULLSCREEN_SetColors) return; /* Already set up */ - this->SetColors = FULLSCREEN_SetColors; this->FlipHWSurface = FULLSCREEN_FlipHWSurface; @@ -368,14 +366,15 @@ static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface) { _kernel_swi_regs regs; regs.r[0] = 19; - /* Wait for Vsync */ - _kernel_swi(OS_Byte, ®s, ®s); FULLSCREEN_SetDisplayBank(this->hidden->current_bank); this->hidden->current_bank ^= 1; FULLSCREEN_SetWriteBank(this->hidden->current_bank); surface->pixels = this->hidden->bank[this->hidden->current_bank]; + /* Wait for Vsync */ + _kernel_swi(OS_Byte, ®s, ®s); + return(0); } diff --git a/src/video/riscos/SDL_riscosmouse.c b/src/video/riscos/SDL_riscosmouse.c index a75e9b879..fe2f350e4 100644 --- a/src/video/riscos/SDL_riscosmouse.c +++ b/src/video/riscos/SDL_riscosmouse.c @@ -40,9 +40,24 @@ #include "swis.h" static WMcursor *current_cursor = NULL; +static WMcursor *defined_cursor = NULL; extern int mouseInWindow; +/* Area to save cursor palette colours changed by SDL. + Actual values will be read before we change to the SDL cursor */ +static Uint8 wimp_cursor_palette[2][5] = { + {1, 25, 255, 255, 255}, + {3, 25, 255, 255, 255} +}; + +static int cursor_palette_saved = 0; + +void WIMP_SaveCursorPalette(); +void WIMP_RestoreWimpCursor(); +void WIMP_SetSDLCursorPalette(); + + void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor) { free(cursor->data); @@ -124,35 +139,17 @@ WMcursor *RISCOS_CreateWMCursor(_THIS, int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor) { + current_cursor = cursor; + if (cursor == NULL) { _kernel_osbyte(106,0,0); - current_cursor = NULL; + defined_cursor = NULL; } else { - if (current_cursor == NULL) - { - /* First time set up the mouse colours */ - Uint8 block[5]; - - /* Set up colour 1 as white */ - block[0] = 1; /* Colour to change 1 - 3 */ - block[1] = 25; /* Set pointer colour */ - block[2] = 255; /* red component*/ - block[3] = 255; /* green component */ - block[4] = 255; /* blue component*/ - _kernel_osword(12, (int *)block); - - /* Set colour 3 to back */ - block[0] = 3; /* Colour to change 1 - 3 */ - block[1] = 25; /* Set pointer colour*/ - block[2] = 0; /* red component*/ - block[3] = 0; /* green component */ - block[4] = 0; /* blue component*/ - _kernel_osword(12, (int *)block); - } + WMcursor *old_cursor = defined_cursor; - if (cursor != current_cursor) + if (cursor != defined_cursor) { Uint8 cursor_def[10]; @@ -167,15 +164,25 @@ int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor) cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */ cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */ - if (_kernel_osword(21, (int *)cursor_def) == 0) + if (_kernel_osword(21, (int *)cursor_def) != 0) { SDL_SetError("RISCOS couldn't create the cursor to show"); return(0); } - current_cursor = cursor; + defined_cursor = cursor; } - if ((this->screen->flags & SDL_FULLSCREEN) || mouseInWindow) _kernel_osbyte(106, 2, 0); + if (old_cursor == NULL) + { + /* First time or reshow in window, so save/setup palette */ + if (!cursor_palette_saved) + { + WIMP_SaveCursorPalette(); + } + WIMP_SetSDLCursorPalette(); + } + + _kernel_osbyte(106, 2, 0); } return(1); @@ -213,13 +220,11 @@ void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y) /* Reshow cursor when mouse re-enters the window */ void WIMP_ReshowCursor(_THIS) { - WMcursor *cursor = current_cursor; - current_cursor = NULL; - RISCOS_ShowWMCursor(this, cursor); + defined_cursor = NULL; + cursor_palette_saved = 0; + RISCOS_ShowWMCursor(this, current_cursor); } -extern int mouseInWindow; - void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { _kernel_swi_regs regs; @@ -249,6 +254,8 @@ void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y) int WIMP_ShowWMCursor(_THIS, WMcursor *cursor) { if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor); + else current_cursor = cursor; + return 1; } @@ -299,3 +306,69 @@ SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode) return mode; } + +/* Save mouse cursor palette to be restore when we are no longer + defining a cursor */ + +void WIMP_SaveCursorPalette() +{ + _kernel_swi_regs regs; + int colour; + + for (colour = 0; colour < 2; colour++) + { + regs.r[0] = (int)wimp_cursor_palette[colour][0]; + regs.r[1] = 25; + /* Read settings with OS_ReadPalette */ + if (_kernel_swi(0x2f, ®s, ®s) == NULL) + { + wimp_cursor_palette[colour][2] = (unsigned char)((regs.r[2] >> 8) & 0xFF); + wimp_cursor_palette[colour][3] = (unsigned char)((regs.r[2] >> 16) & 0xFF); + wimp_cursor_palette[colour][4] = (unsigned char)((regs.r[2] >> 24) & 0xFF); + } + } + + cursor_palette_saved = 1; +} + +/* Restore the WIMP's cursor when we leave the SDL window */ +void WIMP_RestoreWimpCursor() +{ + int colour; + + /* Reset to pointer shape 1 */ + _kernel_osbyte(106, 1, 0); + + /* Reset pointer colours */ + if (cursor_palette_saved) + { + for (colour = 0; colour < 2; colour++) + { + _kernel_osword(12, (int *)wimp_cursor_palette[colour]); + } + } + cursor_palette_saved = 0; +} + +/* Set palette used for SDL mouse cursors */ +void WIMP_SetSDLCursorPalette() +{ + /* First time set up the mouse colours */ + Uint8 block[5]; + + /* Set up colour 1 as white */ + block[0] = 1; /* Colour to change 1 - 3 */ + block[1] = 25; /* Set pointer colour */ + block[2] = 255; /* red component*/ + block[3] = 255; /* green component */ + block[4] = 255; /* blue component*/ + _kernel_osword(12, (int *)block); + + /* Set colour 3 to back */ + block[0] = 3; /* Colour to change 1 - 3 */ + block[1] = 25; /* Set pointer colour*/ + block[2] = 0; /* red component*/ + block[3] = 0; /* green component */ + block[4] = 0; /* blue component*/ + _kernel_osword(12, (int *)block); +} diff --git a/src/video/riscos/SDL_riscosvideo.c b/src/video/riscos/SDL_riscosvideo.c index fe0b6d0d0..47ed528f7 100644 --- a/src/video/riscos/SDL_riscosvideo.c +++ b/src/video/riscos/SDL_riscosvideo.c @@ -150,6 +150,11 @@ static SDL_VideoDevice *RISCOS_CreateDevice(int devindex) /* Set other entries for fullscreen mode */ FULLSCREEN_SetDeviceMode(device); + /* Mouse pointer needs to use the WIMP ShowCursor version so + that it doesn't modify the pointer until the SDL Window is + entered or the application goes full screen */ + device->ShowWMCursor = WIMP_ShowWMCursor; + return device; } diff --git a/src/video/riscos/SDL_wimppoll.c b/src/video/riscos/SDL_wimppoll.c index 266ad0af2..63dd43502 100644 --- a/src/video/riscos/SDL_wimppoll.c +++ b/src/video/riscos/SDL_wimppoll.c @@ -71,6 +71,7 @@ extern int riscos_using_threads; /* Mouse cursor handling */ extern void WIMP_ReshowCursor(_THIS); +extern void WIMP_RestoreWimpCursor(); int hasFocus = 0; int mouseInWindow = 0; @@ -191,10 +192,7 @@ void WIMP_Poll(_THIS, int waitTime) mouseInWindow = 0; //TODO: Lose buttons / dragging /* Reset to default pointer */ - regs.r[0] = 106; - regs.r[1] = 1; - regs.r[2] = 0; - _kernel_swi(OS_Byte, ®s, ®s); + WIMP_RestoreWimpCursor(); SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); } else sysEvent = 1;