Added events for dynamically connecting and disconnecting displays, with an iOS implementation

This commit is contained in:
Sam Lantinga 2020-10-08 16:42:20 -07:00
parent cd703b5628
commit 76980e30f2
20 changed files with 91 additions and 25 deletions

View file

@ -1795,6 +1795,9 @@
FABA34961D8B582100915323 = { FABA34961D8B582100915323 = {
ProvisioningStyle = Automatic; ProvisioningStyle = Automatic;
}; };
FDD2C53D0E2E80E400B7A85F = {
DevelopmentTeam = MXGJJ98X76;
};
}; };
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TestiPhoneOS" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TestiPhoneOS" */;
@ -2865,6 +2868,7 @@
FDD2C54C0E2E80E400B7A85F /* Debug */ = { FDD2C54C0E2E80E400B7A85F /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
DEVELOPMENT_TEAM = MXGJJ98X76;
INFOPLIST_FILE = Info.plist; INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = testsprite2; PRODUCT_NAME = testsprite2;
}; };
@ -2873,6 +2877,7 @@
FDD2C54D0E2E80E400B7A85F /* Release */ = { FDD2C54D0E2E80E400B7A85F /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
DEVELOPMENT_TEAM = MXGJJ98X76;
INFOPLIST_FILE = Info.plist; INFOPLIST_FILE = Info.plist;
PRODUCT_NAME = testsprite2; PRODUCT_NAME = testsprite2;
}; };

View file

@ -175,7 +175,9 @@ typedef enum
typedef enum typedef enum
{ {
SDL_DISPLAYEVENT_NONE, /**< Never used */ SDL_DISPLAYEVENT_NONE, /**< Never used */
SDL_DISPLAYEVENT_ORIENTATION /**< Display orientation has changed to data1 */ SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */
SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */
SDL_DISPLAYEVENT_DISCONNECTED, /**< Display has been removed from the system */
} SDL_DisplayEventID; } SDL_DisplayEventID;
typedef enum typedef enum

View file

@ -439,7 +439,8 @@ extern VideoBootStrap OFFSCREEN_bootstrap;
extern SDL_VideoDevice *SDL_GetVideoDevice(void); extern SDL_VideoDevice *SDL_GetVideoDevice(void);
extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display); extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display, SDL_bool send_event);
extern void SDL_DelVideoDisplay(int index);
extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode);
extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display); extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display);
extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex); extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex);

View file

@ -595,11 +595,11 @@ SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
} }
display.current_mode = display.desktop_mode; display.current_mode = display.desktop_mode;
return SDL_AddVideoDisplay(&display); return SDL_AddVideoDisplay(&display, SDL_FALSE);
} }
int int
SDL_AddVideoDisplay(const SDL_VideoDisplay * display) SDL_AddVideoDisplay(const SDL_VideoDisplay * display, SDL_bool send_event)
{ {
SDL_VideoDisplay *displays; SDL_VideoDisplay *displays;
int index = -1; int index = -1;
@ -621,12 +621,31 @@ SDL_AddVideoDisplay(const SDL_VideoDisplay * display)
SDL_itoa(index, name, 10); SDL_itoa(index, name, 10);
displays[index].name = SDL_strdup(name); displays[index].name = SDL_strdup(name);
} }
if (send_event) {
SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_CONNECTED, 0);
}
} else { } else {
SDL_OutOfMemory(); SDL_OutOfMemory();
} }
return index; return index;
} }
void
SDL_DelVideoDisplay(int index)
{
if (index < 0 || index >= _this->num_displays) {
return;
}
SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_DISCONNECTED, 0);
if (index < (_this->num_displays - 1)) {
SDL_memmove(&_this->displays[index], &_this->displays[index+1], (_this->num_displays - index - 1)*sizeof(_this->displays[index]));
}
--_this->num_displays;
}
int int
SDL_GetNumVideoDisplays(void) SDL_GetNumVideoDisplays(void)
{ {

View file

@ -389,7 +389,7 @@ Cocoa_InitModes(_THIS)
display.desktop_mode = mode; display.desktop_mode = mode;
display.current_mode = mode; display.current_mode = mode;
display.driverdata = displaydata; display.driverdata = displaydata;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
SDL_free(display.name); SDL_free(display.name);
} }
} }

View file

@ -258,7 +258,7 @@ DirectFB_InitModes(_THIS)
SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED)); SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
} }
SDL_DFB_FREE(screencbdata); SDL_DFB_FREE(screencbdata);
return; return;

View file

@ -228,7 +228,7 @@ static void _AddDisplay(BScreen *screen) {
display.desktop_mode = *mode; display.desktop_mode = *mode;
display.current_mode = *mode; display.current_mode = *mode;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
} }
/* /*

View file

@ -1262,7 +1262,7 @@ KMSDRM_VideoInit(_THIS)
display.current_mode = display.desktop_mode; display.current_mode = display.desktop_mode;
display.driverdata = dispdata; display.driverdata = dispdata;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
/****************/ /****************/
/* Atomic block */ /* Atomic block */

View file

@ -173,7 +173,7 @@ PND_videoinit(_THIS)
display.current_mode = current_mode; display.current_mode = current_mode;
display.driverdata = NULL; display.driverdata = NULL;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
return 1; return 1;
} }

View file

@ -167,7 +167,7 @@ PSP_VideoInit(_THIS)
display.current_mode = current_mode; display.current_mode = current_mode;
display.driverdata = NULL; display.driverdata = NULL;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
return 1; return 1;
} }

View file

@ -47,7 +47,7 @@ videoInit(_THIS)
SDL_zero(display); SDL_zero(display);
if (SDL_AddVideoDisplay(&display) < 0) { if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) {
return -1; return -1;
} }

View file

@ -196,7 +196,7 @@ AddDispManXDisplay(const int display_id)
display.driverdata = data; display.driverdata = data;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
} }
int int

View file

@ -47,7 +47,7 @@ static int exit_status;
/* SDL is being built as a static library, include main() */ /* SDL is being built as a static library, include main() */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
return SDL_UIKitRunApp(argc, argv, SDL_main); return SDL_UIKitRunApp(argc, argv, SDL_main);
} }
#endif /* SDL_MAIN_NEEDED && !IOS_DYLIB */ #endif /* SDL_MAIN_NEEDED && !IOS_DYLIB */
@ -56,7 +56,7 @@ int SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction)
int i; int i;
/* store arguments */ /* store arguments */
forward_main = mainFunction; forward_main = mainFunction;
forward_argc = argc; forward_argc = argc;
forward_argv = (char **)malloc((argc+1) * sizeof(char *)); forward_argv = (char **)malloc((argc+1) * sizeof(char *));
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
@ -349,6 +349,14 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
- (void)postFinishLaunch - (void)postFinishLaunch
{ {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(handleScreenDidConnectNotification:)
name:UIScreenDidConnectNotification object:nil];
[center addObserver:self selector:@selector(handleScreenDidDisconnectNotification:)
name:UIScreenDidDisconnectNotification object:nil];
/* Hide the launch screen the next time the run loop is run. SDL apps will /* Hide the launch screen the next time the run loop is run. SDL apps will
* have a chance to load resources while the launch screen is still up. */ * have a chance to load resources while the launch screen is still up. */
[self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0]; [self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0];
@ -520,6 +528,18 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
#endif #endif
- (void)handleScreenDidConnectNotification:(NSNotification*)aNotification
{
UIScreen *uiscreen = [aNotification object];
UIKit_AddDisplay(uiscreen, SDL_TRUE);
}
- (void)handleScreenDidDisconnectNotification:(NSNotification*)aNotification
{
UIScreen *uiscreen = [aNotification object];
UIKit_DelDisplay(uiscreen);
}
@end @end
#endif /* SDL_VIDEO_DRIVER_UIKIT */ #endif /* SDL_VIDEO_DRIVER_UIKIT */

View file

@ -43,6 +43,8 @@
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen); extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
extern int UIKit_InitModes(_THIS); extern int UIKit_InitModes(_THIS);
extern int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event);
extern void UIKit_DelDisplay(UIScreen *uiscreen);
extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); extern int UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);

View file

@ -265,10 +265,11 @@ UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscre
return 0; return 0;
} }
static int int
UIKit_AddDisplay(UIScreen *uiscreen) UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
{ {
UIScreenMode *uiscreenmode = uiscreen.currentMode; UIScreenMode *uiscreenmode = uiscreen.currentMode;
CGPoint origin = uiscreen.bounds.origin;
CGSize size = uiscreen.bounds.size; CGSize size = uiscreen.bounds.size;
SDL_VideoDisplay display; SDL_VideoDisplay display;
SDL_DisplayMode mode; SDL_DisplayMode mode;
@ -302,11 +303,27 @@ UIKit_AddDisplay(UIScreen *uiscreen)
} }
display.driverdata = (void *) CFBridgingRetain(data); display.driverdata = (void *) CFBridgingRetain(data);
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, send_event);
return 0; return 0;
} }
void
UIKit_DelDisplay(UIScreen *uiscreen)
{
int i;
for (i = 0; i < SDL_GetNumVideoDisplays(); ++i) {
SDL_DisplayData *data = (__bridge SDL_DisplayData *)SDL_GetDisplayDriverData(i);
if (data && data.uiscreen == uiscreen) {
CFRelease(SDL_GetDisplayDriverData(i));
SDL_DelVideoDisplay(i);
return;
}
}
}
SDL_bool SDL_bool
UIKit_IsDisplayLandscape(UIScreen *uiscreen) UIKit_IsDisplayLandscape(UIScreen *uiscreen)
{ {
@ -326,7 +343,7 @@ UIKit_InitModes(_THIS)
{ {
@autoreleasepool { @autoreleasepool {
for (UIScreen *uiscreen in [UIScreen screens]) { for (UIScreen *uiscreen in [UIScreen screens]) {
if (UIKit_AddDisplay(uiscreen) < 0) { if (UIKit_AddDisplay(uiscreen, SDL_FALSE) < 0) {
return -1; return -1;
} }
} }

View file

@ -170,7 +170,7 @@ VIVANTE_AddVideoDisplays(_THIS)
display.desktop_mode = current_mode; display.desktop_mode = current_mode;
display.current_mode = current_mode; display.current_mode = current_mode;
display.driverdata = data; display.driverdata = data;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
return 0; return 0;
} }

View file

@ -274,7 +274,7 @@ display_handle_done(void *data,
{ {
/* !!! FIXME: this will fail on any further property changes! */ /* !!! FIXME: this will fail on any further property changes! */
SDL_VideoDisplay *display = data; SDL_VideoDisplay *display = data;
SDL_AddVideoDisplay(display); SDL_AddVideoDisplay(display, SDL_FALSE);
wl_output_set_user_data(output, display->driverdata); wl_output_set_user_data(output, display->driverdata);
SDL_free(display->name); SDL_free(display->name);
SDL_free(display); SDL_free(display);

View file

@ -171,7 +171,7 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEX *info)
display.desktop_mode = mode; display.desktop_mode = mode;
display.current_mode = mode; display.current_mode = mode;
display.driverdata = displaydata; display.driverdata = displaydata;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
SDL_free(display.name); SDL_free(display.name);
return SDL_TRUE; return SDL_TRUE;
} }

View file

@ -293,7 +293,7 @@ WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex
} }
} }
if (SDL_AddVideoDisplay(&display) < 0) { if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) {
goto done; goto done;
} }
@ -376,7 +376,7 @@ WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterInd
display.desktop_mode = mode; display.desktop_mode = mode;
display.current_mode = mode; display.current_mode = mode;
if ((SDL_AddDisplayMode(&display, &mode) < 0) || if ((SDL_AddDisplayMode(&display, &mode) < 0) ||
(SDL_AddVideoDisplay(&display) < 0)) (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0))
{ {
return SDL_SetError("Failed to apply DXGI Display-detection workaround"); return SDL_SetError("Failed to apply DXGI Display-detection workaround");
} }

View file

@ -487,7 +487,7 @@ X11_InitModes_XRandR(_THIS)
display.desktop_mode = mode; display.desktop_mode = mode;
display.current_mode = mode; display.current_mode = mode;
display.driverdata = displaydata; display.driverdata = displaydata;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
} }
X11_XRRFreeScreenResources(res); X11_XRRFreeScreenResources(res);
@ -807,7 +807,7 @@ X11_InitModes(_THIS)
display.desktop_mode = mode; display.desktop_mode = mode;
display.current_mode = mode; display.current_mode = mode;
display.driverdata = displaydata; display.driverdata = displaydata;
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display, SDL_FALSE);
} }
#if SDL_VIDEO_DRIVER_X11_XINERAMA #if SDL_VIDEO_DRIVER_X11_XINERAMA