diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 000b22deb5b78..d609fdefd756d 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -171,7 +171,7 @@ static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const cha } /* Public functions */ -int SDL_MouseInit(void) +int SDL_MousePreInit(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -216,11 +216,62 @@ int SDL_MouseInit(void) return 0; } +void SDL_MousePostInit(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + /* Create a dummy mouse cursor for video backends that don't support true cursors, + * so that mouse grab and focus functionality will work. + */ + if (!mouse->def_cursor) { + SDL_Surface *surface = SDL_CreateRGBSurface(0, 1, 1, 32, 0xFF, 0xFF, 0xFF, 0xFF); + if (surface) { + SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch); + SDL_SetDefaultCursor(SDL_CreateColorCursor(surface, 0, 0)); + SDL_FreeSurface(surface); + } + } +} + void SDL_SetDefaultCursor(SDL_Cursor *cursor) { SDL_Mouse *mouse = SDL_GetMouse(); + if (cursor == mouse->def_cursor) { + return; + } + + if (mouse->def_cursor) { + SDL_Cursor *default_cursor = mouse->def_cursor; + SDL_Cursor *prev, *curr; + + if (mouse->cur_cursor == mouse->def_cursor) { + mouse->cur_cursor = NULL; + } + mouse->def_cursor = NULL; + + for (prev = NULL, curr = mouse->cursors; curr; + prev = curr, curr = curr->next) { + if (curr == default_cursor) { + if (prev) { + prev->next = curr->next; + } else { + mouse->cursors = curr->next; + } + + break; + } + } + + if (mouse->FreeCursor && default_cursor->driverdata) { + mouse->FreeCursor(default_cursor); + } else { + SDL_free(default_cursor); + } + } + mouse->def_cursor = cursor; + if (!mouse->cur_cursor) { SDL_SetCursor(cursor); } @@ -1271,11 +1322,6 @@ SDL_Cursor *SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) return NULL; } - if (!mouse->CreateCursor) { - SDL_SetError("Cursors are not currently supported"); - return NULL; - } - /* Sanity check the hot spot */ if ((hot_x < 0) || (hot_y < 0) || (hot_x >= surface->w) || (hot_y >= surface->h)) { @@ -1291,7 +1337,15 @@ SDL_Cursor *SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) surface = temp; } - cursor = mouse->CreateCursor(surface, hot_x, hot_y); + if (mouse->CreateCursor) { + cursor = mouse->CreateCursor(surface, hot_x, hot_y); + } else { + cursor = SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + } + } + if (cursor) { cursor->next = mouse->cursors; mouse->cursors = cursor; @@ -1416,6 +1470,8 @@ void SDL_FreeCursor(SDL_Cursor *cursor) if (mouse->FreeCursor) { mouse->FreeCursor(curr); + } else { + SDL_free(curr); } return; } diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index 64e82ab8ed74f..71337e4e12f7e 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -131,7 +131,8 @@ typedef struct } SDL_Mouse; /* Initialize the mouse subsystem */ -extern int SDL_MouseInit(void); +extern int SDL_MousePreInit(void); +extern void SDL_MousePostInit(void); /* Get the mouse state structure */ SDL_Mouse *SDL_GetMouse(void); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 9a09a902136ed..23ce7b1a7adf7 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -454,7 +454,7 @@ int SDL_VideoInit(const char *driver_name) goto pre_driver_error; } init_keyboard = SDL_TRUE; - if (SDL_MouseInit() < 0) { + if (SDL_MousePreInit() < 0) { goto pre_driver_error; } init_mouse = SDL_TRUE; @@ -550,6 +550,8 @@ int SDL_VideoInit(const char *driver_name) SDL_StartTextInput(); } + SDL_MousePostInit(); + /* We're ready to go! */ return 0; @@ -1335,6 +1337,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) { SDL_VideoDisplay *display; SDL_Window *other; + SDL_bool resized = SDL_FALSE; CHECK_WINDOW_MAGIC(window, -1); @@ -1443,7 +1446,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) SDL_zero(fullscreen_mode); if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) { - SDL_bool resized = SDL_TRUE; + resized = SDL_TRUE; if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) { resized = SDL_FALSE; @@ -1498,11 +1501,18 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) if (_this->SetWindowFullscreen) { _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); + } else { + resized = SDL_TRUE; } display->fullscreen_window = NULL; - /* Generate a mode change event here */ - SDL_OnWindowResized(window); + if (!resized) { + /* Generate a mode change event here */ + SDL_OnWindowResized(window); + } else { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, + window->windowed.w, window->windowed.h); + } /* Restore the cursor position */ SDL_RestoreMousePosition(window); @@ -2473,6 +2483,9 @@ void SDL_ShowWindow(SDL_Window *window) if (_this->ShowWindow) { _this->ShowWindow(_this, window); + } else { + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); } SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); } @@ -2490,6 +2503,9 @@ void SDL_HideWindow(SDL_Window *window) if (_this->HideWindow) { _this->HideWindow(_this, window); + } else { + SDL_SetMouseFocus(NULL); + SDL_SetKeyboardFocus(NULL); } window->is_hiding = SDL_FALSE; SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); diff --git a/src/video/dummy/SDL_nullvideo.c b/src/video/dummy/SDL_nullvideo.c index 109066d359015..41dcf1b84787d 100644 --- a/src/video/dummy/SDL_nullvideo.c +++ b/src/video/dummy/SDL_nullvideo.c @@ -53,7 +53,6 @@ /* Initialization/Query functions */ static int DUMMY_VideoInit(_THIS); -static int DUMMY_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void DUMMY_VideoQuit(_THIS); #if SDL_INPUT_LINUXEV @@ -104,7 +103,6 @@ static SDL_VideoDevice *DUMMY_CreateDevice(void) /* Set the function pointers */ device->VideoInit = DUMMY_VideoInit; device->VideoQuit = DUMMY_VideoQuit; - device->SetDisplayMode = DUMMY_SetDisplayMode; device->PumpEvents = DUMMY_PumpEvents; #if SDL_INPUT_LINUXEV if (evdev) { @@ -149,7 +147,7 @@ int DUMMY_VideoInit(_THIS) mode.format = SDL_PIXELFORMAT_RGB888; mode.w = 1024; mode.h = 768; - mode.refresh_rate = 0; + mode.refresh_rate = 60; mode.driverdata = NULL; if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; @@ -165,11 +163,6 @@ int DUMMY_VideoInit(_THIS) return 0; } -static int DUMMY_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) -{ - return 0; -} - void DUMMY_VideoQuit(_THIS) { #if SDL_INPUT_LINUXEV diff --git a/test/testautomation_video.c b/test/testautomation_video.c index aa9e7b92b360e..b8e548b26f5a4 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -278,6 +278,8 @@ int video_createWindowVariousFlags(void *arg) break; case 2: flags = SDL_WINDOW_OPENGL; + /* Skip - not every video driver supports OpenGL; comment out next line to run test */ + continue; break; case 3: flags = SDL_WINDOW_SHOWN;