mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-11 13:29:30 +00:00
fixed issue #19: on OS X, display can slide around if initial clicks are near top of screen
This commit is contained in:
parent
5d4560c1a7
commit
7767f128e5
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
#include "utils_macosx.h"
|
#include "utils_macosx.h"
|
||||||
|
#include <SDL_syswm.h>
|
||||||
|
|
||||||
// This is used from video_sdl.cpp.
|
// This is used from video_sdl.cpp.
|
||||||
void NSAutoReleasePool_wrap(void (*fn)(void))
|
void NSAutoReleasePool_wrap(void (*fn)(void))
|
||||||
|
@ -40,3 +41,18 @@ void disable_SDL2_macosx_menu_bar_keyboard_shortcuts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_fullscreen_osx(SDL_Window * window)
|
||||||
|
{
|
||||||
|
if (!window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SysWMinfo wmInfo;
|
||||||
|
SDL_VERSION(&wmInfo.version);
|
||||||
|
if (!SDL_GetWindowWMInfo(window, &wmInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NSWindowStyleMask styleMask = [wmInfo.info.cocoa.window styleMask];
|
||||||
|
return (styleMask & NSWindowStyleMaskFullScreen) != 0;
|
||||||
|
}
|
||||||
|
|
|
@ -140,6 +140,7 @@ static int screen_depth; // Depth of current screen
|
||||||
static SDL_Palette *sdl_palette = NULL; // Color palette to be used as CLUT and gamma table
|
static SDL_Palette *sdl_palette = NULL; // Color palette to be used as CLUT and gamma table
|
||||||
static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors
|
static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors
|
||||||
static bool toggle_fullscreen = false;
|
static bool toggle_fullscreen = false;
|
||||||
|
static bool did_add_event_watch = false;
|
||||||
|
|
||||||
static bool mouse_grabbed = false;
|
static bool mouse_grabbed = false;
|
||||||
|
|
||||||
|
@ -167,6 +168,7 @@ static void (*video_refresh)(void);
|
||||||
static int redraw_func(void *arg);
|
static int redraw_func(void *arg);
|
||||||
static int update_sdl_video();
|
static int update_sdl_video();
|
||||||
static int present_sdl_video();
|
static int present_sdl_video();
|
||||||
|
static int SDLCALL on_sdl_event_generated(void *userdata, SDL_Event * event);
|
||||||
|
|
||||||
// From sys_unix.cpp
|
// From sys_unix.cpp
|
||||||
extern void SysMountFirstFloppy(void);
|
extern void SysMountFirstFloppy(void);
|
||||||
|
@ -695,7 +697,7 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags
|
||||||
int window_height = height;
|
int window_height = height;
|
||||||
Uint32 window_flags = 0;
|
Uint32 window_flags = 0;
|
||||||
const int window_flags_to_monitor = SDL_WINDOW_FULLSCREEN;
|
const int window_flags_to_monitor = SDL_WINDOW_FULLSCREEN;
|
||||||
|
|
||||||
if (flags & SDL_WINDOW_FULLSCREEN) {
|
if (flags & SDL_WINDOW_FULLSCREEN) {
|
||||||
SDL_DisplayMode desktop_mode;
|
SDL_DisplayMode desktop_mode;
|
||||||
if (SDL_GetDesktopDisplayMode(0, &desktop_mode) != 0) {
|
if (SDL_GetDesktopDisplayMode(0, &desktop_mode) != 0) {
|
||||||
|
@ -705,8 +707,6 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags
|
||||||
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
window_width = desktop_mode.w;
|
window_width = desktop_mode.w;
|
||||||
window_height = desktop_mode.h;
|
window_height = desktop_mode.h;
|
||||||
} else {
|
|
||||||
window_flags |= SDL_WINDOW_RESIZABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdl_window) {
|
if (sdl_window) {
|
||||||
|
@ -724,6 +724,10 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags
|
||||||
// Apply anti-aliasing, if and when appropriate (usually in fullscreen)
|
// Apply anti-aliasing, if and when appropriate (usually in fullscreen)
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||||
|
|
||||||
|
// Always use a resize-able window. This helps allow SDL to manage
|
||||||
|
// transitions involving fullscreen to or from windowed-mode.
|
||||||
|
window_flags |= SDL_WINDOW_RESIZABLE;
|
||||||
|
|
||||||
if (!sdl_window) {
|
if (!sdl_window) {
|
||||||
sdl_window = SDL_CreateWindow(
|
sdl_window = SDL_CreateWindow(
|
||||||
"Basilisk II",
|
"Basilisk II",
|
||||||
|
@ -737,6 +741,14 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some SDL events (regarding some native-window events), need processing
|
||||||
|
// as they are generated. SDL2 has a facility, SDL_AddEventWatch(), which
|
||||||
|
// allows events to be processed as they are generated.
|
||||||
|
if (!did_add_event_watch) {
|
||||||
|
SDL_AddEventWatch(&on_sdl_event_generated, NULL);
|
||||||
|
did_add_event_watch = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sdl_renderer) {
|
if (!sdl_renderer) {
|
||||||
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED);
|
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED);
|
||||||
|
@ -1041,11 +1053,11 @@ void driver_base::restore_mouse_accel(void)
|
||||||
// Toggle mouse grab
|
// Toggle mouse grab
|
||||||
void driver_base::toggle_mouse_grab(void)
|
void driver_base::toggle_mouse_grab(void)
|
||||||
{
|
{
|
||||||
if (mouse_grabbed)
|
if (mouse_grabbed)
|
||||||
ungrab_mouse();
|
ungrab_mouse();
|
||||||
else
|
else
|
||||||
grab_mouse();
|
grab_mouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab mouse, switch to relative mouse mode
|
// Grab mouse, switch to relative mouse mode
|
||||||
void driver_base::grab_mouse(void)
|
void driver_base::grab_mouse(void)
|
||||||
|
@ -1470,14 +1482,18 @@ static void do_toggle_fullscreen(void)
|
||||||
int x, y;
|
int x, y;
|
||||||
SDL_GetMouseState(&x, &y);
|
SDL_GetMouseState(&x, &y);
|
||||||
|
|
||||||
// save the screen contents
|
// Apply fullscreen
|
||||||
SDL_Surface *tmp_surface = SDL_ConvertSurface(drv->s, drv->s->format,
|
if (sdl_window) {
|
||||||
drv->s->flags);
|
if (display_type == DISPLAY_SCREEN) {
|
||||||
|
display_type = DISPLAY_WINDOW;
|
||||||
|
SDL_SetWindowFullscreen(sdl_window, 0);
|
||||||
|
} else {
|
||||||
|
display_type = DISPLAY_SCREEN;
|
||||||
|
SDL_SetWindowFullscreen(sdl_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// switch modes
|
// switch modes
|
||||||
display_type = (display_type == DISPLAY_SCREEN) ? DISPLAY_WINDOW
|
|
||||||
: DISPLAY_SCREEN;
|
|
||||||
drv->set_video_mode(display_type == DISPLAY_SCREEN ? SDL_WINDOW_FULLSCREEN : 0);
|
|
||||||
drv->adapt_to_video_mode();
|
drv->adapt_to_video_mode();
|
||||||
|
|
||||||
// reset the palette
|
// reset the palette
|
||||||
|
@ -1486,11 +1502,6 @@ static void do_toggle_fullscreen(void)
|
||||||
#endif
|
#endif
|
||||||
drv->update_palette();
|
drv->update_palette();
|
||||||
|
|
||||||
// restore the screen contents
|
|
||||||
SDL_BlitSurface(tmp_surface, NULL, drv->s, NULL);
|
|
||||||
SDL_FreeSurface(tmp_surface);
|
|
||||||
update_sdl_video();
|
|
||||||
|
|
||||||
// reset the video refresh handler
|
// reset the video refresh handler
|
||||||
VideoRefreshInit();
|
VideoRefreshInit();
|
||||||
|
|
||||||
|
@ -1499,7 +1510,7 @@ static void do_toggle_fullscreen(void)
|
||||||
|
|
||||||
// restore the mouse position
|
// restore the mouse position
|
||||||
SDL_WarpMouseGlobal(x, y);
|
SDL_WarpMouseGlobal(x, y);
|
||||||
|
|
||||||
// resume redraw thread
|
// resume redraw thread
|
||||||
toggle_fullscreen = false;
|
toggle_fullscreen = false;
|
||||||
#ifndef USE_CPU_EMUL_SERVICES
|
#ifndef USE_CPU_EMUL_SERVICES
|
||||||
|
@ -1514,6 +1525,26 @@ static void do_toggle_fullscreen(void)
|
||||||
/*
|
/*
|
||||||
* Execute video VBL routine
|
* Execute video VBL routine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static bool is_fullscreen(SDL_Window * window)
|
||||||
|
{
|
||||||
|
#ifdef __MACOSX__
|
||||||
|
// On OSX, SDL, at least as of 2.0.5 (and possibly beyond), does not always
|
||||||
|
// report changes to fullscreen via the SDL_WINDOW_FULLSCREEN flag.
|
||||||
|
// (Example: https://bugzilla.libsdl.org/show_bug.cgi?id=3766 , which
|
||||||
|
// involves fullscreen/windowed toggles via window-manager UI controls).
|
||||||
|
// Until it does, or adds a facility to do so, we'll use a platform-specific
|
||||||
|
// code path to detect fullscreen changes.
|
||||||
|
extern bool is_fullscreen_osx(SDL_Window * window);
|
||||||
|
return is_fullscreen_osx(sdl_window);
|
||||||
|
#else
|
||||||
|
if (!window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const Uint32 sdl_window_flags = SDL_GetWindowFlags(sdl_window);
|
||||||
|
return (sdl_window_flags & SDL_WINDOW_FULLSCREEN) != 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SHEEPSHAVER
|
#ifdef SHEEPSHAVER
|
||||||
void VideoVBL(void)
|
void VideoVBL(void)
|
||||||
|
@ -1952,6 +1983,38 @@ static void force_complete_window_refresh()
|
||||||
* SDL event handling
|
* SDL event handling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int SDLCALL on_sdl_event_generated(void *userdata, SDL_Event * event)
|
||||||
|
{
|
||||||
|
switch (event->type) {
|
||||||
|
case SDL_WINDOWEVENT: {
|
||||||
|
switch (event->window.event) {
|
||||||
|
case SDL_WINDOWEVENT_RESIZED: {
|
||||||
|
// Handle changes of fullscreen. This is done here, in
|
||||||
|
// on_sdl_event_generated() and not the main SDL_Event-processing
|
||||||
|
// loop, in order to perform this change on the main thread.
|
||||||
|
// (Some os'es UI APIs, such as OSX's NSWindow, are not
|
||||||
|
// thread-safe.)
|
||||||
|
const bool is_full = is_fullscreen(sdl_window);
|
||||||
|
const bool adjust_fullscreen = \
|
||||||
|
(display_type == DISPLAY_WINDOW && is_full) ||
|
||||||
|
(display_type == DISPLAY_SCREEN && !is_full);
|
||||||
|
if (adjust_fullscreen) {
|
||||||
|
do_toggle_fullscreen();
|
||||||
|
if (is_fullscreen(sdl_window)) {
|
||||||
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
|
} else {
|
||||||
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; // return 1 to add event to queue, 0 to drop it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void handle_events(void)
|
static void handle_events(void)
|
||||||
{
|
{
|
||||||
SDL_Event events[10];
|
SDL_Event events[10];
|
||||||
|
@ -1961,7 +2024,7 @@ static void handle_events(void)
|
||||||
while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) > 0) {
|
while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) > 0) {
|
||||||
for (int i = 0; i < n_events; i++) {
|
for (int i = 0; i < n_events; i++) {
|
||||||
SDL_Event & event = events[i];
|
SDL_Event & event = events[i];
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
|
||||||
// Mouse button
|
// Mouse button
|
||||||
|
@ -2072,7 +2135,7 @@ static void handle_events(void)
|
||||||
case SDL_WINDOWEVENT_RESTORED:
|
case SDL_WINDOWEVENT_RESTORED:
|
||||||
force_complete_window_refresh();
|
force_complete_window_refresh();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user