mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-21 18:53:38 +00:00
Detect device form factor (#12584)
This commit is contained in:
@@ -1345,6 +1345,25 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
static String getDeviceFormFactor()
|
||||
{
|
||||
// TODO: WearOS
|
||||
if (isAndroidTV()) {
|
||||
return "tv";
|
||||
} else if (isVRHeadset()) {
|
||||
return "headset";
|
||||
} else if (isTablet()) {
|
||||
return "tablet";
|
||||
//} else if (isAndroidAutomotive()) {
|
||||
// return "car";
|
||||
} else {
|
||||
return "phone";
|
||||
}
|
||||
}
|
||||
|
||||
public static double getDiagonal()
|
||||
{
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
|
||||
@@ -655,6 +655,64 @@ extern SDL_DECLSPEC bool SDLCALL SDL_IsTablet(void);
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_IsTV(void);
|
||||
|
||||
/**
|
||||
* The possible form factors for a device.
|
||||
*
|
||||
* \since This enum is available since SDL 3.4.0.
|
||||
*
|
||||
* \sa SDL_GetDeviceFormFactor
|
||||
* \sa SDL_GetDeviceFormFactorName
|
||||
*/
|
||||
typedef enum SDL_FormFactor {
|
||||
SDL_FORMFACTOR_UNKNOWN = 0,
|
||||
SDL_FORMFACTOR_DESKTOP,
|
||||
SDL_FORMFACTOR_LAPTOP,
|
||||
SDL_FORMFACTOR_PHONE,
|
||||
SDL_FORMFACTOR_TABLET,
|
||||
SDL_FORMFACTOR_CONSOLE,
|
||||
SDL_FORMFACTOR_HANDHELD,
|
||||
SDL_FORMFACTOR_WATCH,
|
||||
SDL_FORMFACTOR_TV,
|
||||
SDL_FORMFACTOR_HEADSET,
|
||||
SDL_FORMFACTOR_CAR
|
||||
} SDL_FormFactor;
|
||||
|
||||
/**
|
||||
* Get the form factor of the current device.
|
||||
*
|
||||
* This function guesses what the device may be, but may report inaccurate or
|
||||
* outright wrong results. For example, it may report a laptop as a desktop, or
|
||||
* a car device as a phone.
|
||||
*
|
||||
* Depending on the usage, there may be different functions better suited for
|
||||
* each purpose. For example, activating touch controls can be done by detecting
|
||||
* the presence of a touchscreen rather than restricting to phones and tablets.
|
||||
*
|
||||
* \returns the best guess for the form factor of the current device.
|
||||
*
|
||||
* \since This function is available since SDL 3.4.0.
|
||||
*
|
||||
* \sa SDL_FormFactor
|
||||
* \sa SDL_GetDeviceFormFactorName
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_FormFactor SDLCALL SDL_GetDeviceFormFactor(void);
|
||||
|
||||
/**
|
||||
* Get a short name for the current device.
|
||||
*
|
||||
* The name will be in English.
|
||||
*
|
||||
* \param form_factor the form factor to query.
|
||||
* \returns a human-readable name for the given form factor, or
|
||||
* "SDL_FORMFACTOR_UNKNOWN" if the form factor isn't recognized.
|
||||
*
|
||||
* \since This function is available since SDL 3.4.0.
|
||||
*
|
||||
* \sa SDL_FormFactor
|
||||
* \sa SDL_GetDeviceFormFactor
|
||||
*/
|
||||
extern SDL_DECLSPEC const char* SDLCALL SDL_GetDeviceFormFactorName(SDL_FormFactor form_factor);
|
||||
|
||||
/**
|
||||
* Application sandbox environment.
|
||||
*
|
||||
|
||||
57
src/SDL.c
57
src/SDL.c
@@ -849,28 +849,59 @@ bool SDL_IsPhone(void)
|
||||
|
||||
bool SDL_IsTablet(void)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
return SDL_IsAndroidTablet();
|
||||
#elif defined(SDL_PLATFORM_IOS)
|
||||
extern bool SDL_IsIPad(void);
|
||||
return SDL_IsIPad();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return SDL_GetDeviceFormFactor() == SDL_FORMFACTOR_TABLET;
|
||||
}
|
||||
|
||||
bool SDL_IsTV(void)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
return SDL_IsAndroidTV();
|
||||
return SDL_GetDeviceFormFactor() == SDL_FORMFACTOR_TV;
|
||||
}
|
||||
|
||||
SDL_FormFactor SDL_GetDeviceFormFactor(void)
|
||||
{
|
||||
#ifdef SDL_FORMFACTOR_PRIVATE
|
||||
return SDL_FORMFACTOR_PRIVATE;
|
||||
#elif defined(SDL_PLATFORM_ANDROID)
|
||||
return SDL_GetAndroidDeviceFormFactor();
|
||||
#elif defined(SDL_PLATFORM_IOS)
|
||||
extern bool SDL_IsAppleTV(void);
|
||||
return SDL_IsAppleTV();
|
||||
extern bool SDL_GetUIKitDeviceFormFactor(void);
|
||||
return SDL_GetUIKitDeviceFormFactor();
|
||||
#elif defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES) || defined(SDL_PLATFORM_PS2)
|
||||
return SDL_FORMFACTOR_CONSOLE;
|
||||
#elif defined(SDL_PLATFORM_PSP) || defined(SDL_PLATFORM_VITA) || defined(SDL_PLATFORM_3DS)
|
||||
return SDL_FORMFACTOR_HANDHELD;
|
||||
#elif defined(SDL_PLATFORM_QNXNTO)
|
||||
/* TODO: QNX is used in BlackBerry phones and tablets, and in many embedded devices */
|
||||
return SDL_FORMFACTOR_UNKNOWN;
|
||||
#elif defined(SDL_PLATFORM_WINGDK)
|
||||
/* TODO: GDK can be either desktop Windows or XBox */
|
||||
return SDL_FORMFACTOR_UNKNOWN;
|
||||
#else
|
||||
return false;
|
||||
return SDL_FORMFACTOR_DESKTOP;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* SDL_GetDeviceFormFactorName(SDL_FormFactor form_factor)
|
||||
{
|
||||
switch (form_factor)
|
||||
{
|
||||
#define CASE(x) case x: return #x;
|
||||
default:
|
||||
CASE(SDL_FORMFACTOR_UNKNOWN)
|
||||
CASE(SDL_FORMFACTOR_DESKTOP)
|
||||
CASE(SDL_FORMFACTOR_LAPTOP)
|
||||
CASE(SDL_FORMFACTOR_PHONE)
|
||||
CASE(SDL_FORMFACTOR_TABLET)
|
||||
CASE(SDL_FORMFACTOR_CONSOLE)
|
||||
CASE(SDL_FORMFACTOR_HANDHELD)
|
||||
CASE(SDL_FORMFACTOR_WATCH)
|
||||
CASE(SDL_FORMFACTOR_TV)
|
||||
CASE(SDL_FORMFACTOR_HEADSET)
|
||||
CASE(SDL_FORMFACTOR_CAR)
|
||||
#undef CASE
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Sandbox SDL_DetectSandbox(void)
|
||||
{
|
||||
#if defined(SDL_PLATFORM_LINUX)
|
||||
|
||||
@@ -369,6 +369,7 @@ static jmethodID midClipboardSetText;
|
||||
static jmethodID midCreateCustomCursor;
|
||||
static jmethodID midDestroyCustomCursor;
|
||||
static jmethodID midGetContext;
|
||||
static jmethodID midGetDeviceFormFactor;
|
||||
static jmethodID midGetManifestEnvironmentVariables;
|
||||
static jmethodID midGetNativeSurface;
|
||||
static jmethodID midInitTouch;
|
||||
@@ -659,6 +660,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
||||
midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "createCustomCursor", "([IIIII)I");
|
||||
midDestroyCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "destroyCustomCursor", "(I)V");
|
||||
midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/app/Activity;");
|
||||
midGetDeviceFormFactor = (*env)->GetStaticMethodID(env, mActivityClass, "getDeviceFormFactor", "()Ljava/lang/String;");
|
||||
midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass, "getManifestEnvironmentVariables", "()Z");
|
||||
midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass, "getNativeSurface", "()Landroid/view/Surface;");
|
||||
midInitTouch = (*env)->GetStaticMethodID(env, mActivityClass, "initTouch", "()V");
|
||||
@@ -691,6 +693,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
||||
!midCreateCustomCursor ||
|
||||
!midDestroyCustomCursor ||
|
||||
!midGetContext ||
|
||||
!midGetDeviceFormFactor ||
|
||||
!midGetManifestEnvironmentVariables ||
|
||||
!midGetNativeSurface ||
|
||||
!midInitTouch ||
|
||||
@@ -3505,4 +3508,37 @@ bool Android_JNI_ShowFileDialog(
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_FormFactor SDL_GetAndroidDeviceFormFactor(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
SDL_FormFactor form_factor = SDL_FORMFACTOR_UNKNOWN;
|
||||
jstring string;
|
||||
|
||||
string = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetDeviceFormFactor);
|
||||
if (string) {
|
||||
const char *utf = (*env)->GetStringUTFChars(env, string, 0);
|
||||
if (utf) {
|
||||
if (SDL_strcmp(utf, "tv") == 0) {
|
||||
form_factor = SDL_FORMFACTOR_TV;
|
||||
} else if (SDL_strcmp(utf, "tablet") == 0) {
|
||||
form_factor = SDL_FORMFACTOR_TABLET;
|
||||
} else if (SDL_strcmp(utf, "phone") == 0) {
|
||||
form_factor = SDL_FORMFACTOR_PHONE;
|
||||
} else if (SDL_strcmp(utf, "car") == 0) {
|
||||
form_factor = SDL_FORMFACTOR_CAR;
|
||||
} else if (SDL_strcmp(utf, "headset") == 0) {
|
||||
form_factor = SDL_FORMFACTOR_HEADSET;
|
||||
} else if (SDL_strcmp(utf, "watch") == 0) {
|
||||
form_factor = SDL_FORMFACTOR_WATCH;
|
||||
} else {
|
||||
form_factor = SDL_FORMFACTOR_UNKNOWN;
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, string, utf);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, string);
|
||||
}
|
||||
|
||||
return form_factor;
|
||||
}
|
||||
|
||||
#endif // SDL_PLATFORM_ANDROID
|
||||
|
||||
@@ -151,6 +151,7 @@ int SDL_GetAndroidSDKVersion(void);
|
||||
|
||||
bool SDL_IsAndroidTablet(void);
|
||||
bool SDL_IsAndroidTV(void);
|
||||
SDL_FormFactor SDL_GetAndroidDeviceFormFactor(void);
|
||||
|
||||
char *SDL_GetAndroidPackageName(void); // this is a SDL_malloc'd string the caller will own.
|
||||
|
||||
|
||||
@@ -1298,3 +1298,5 @@ _SDL_RequestNotificationPermission
|
||||
_SDL_ShowNotificationWithProperties
|
||||
_SDL_ShowNotification
|
||||
_SDL_RemoveNotification
|
||||
_SDL_GetDeviceFormFactor
|
||||
_SDL_GetDeviceFormFactorName
|
||||
|
||||
@@ -1299,6 +1299,8 @@ SDL3_0.0.0 {
|
||||
SDL_ShowNotificationWithProperties;
|
||||
SDL_ShowNotification;
|
||||
SDL_RemoveNotification;
|
||||
SDL_GetDeviceFormFactor;
|
||||
SDL_GetDeviceFormFactorName;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -1325,3 +1325,5 @@
|
||||
#define SDL_ShowNotificationWithProperties SDL_ShowNotificationWithProperties_REAL
|
||||
#define SDL_ShowNotification SDL_ShowNotification_REAL
|
||||
#define SDL_RemoveNotification SDL_RemoveNotification_REAL
|
||||
#define SDL_GetDeviceFormFactor SDL_GetDeviceFormFactor_REAL
|
||||
#define SDL_GetDeviceFormFactorName SDL_GetDeviceFormFactorName_REAL
|
||||
|
||||
@@ -1333,3 +1333,5 @@ SDL_DYNAPI_PROC(bool,SDL_RequestNotificationPermission,(void),(),return)
|
||||
SDL_DYNAPI_PROC(SDL_NotificationID,SDL_ShowNotificationWithProperties,(SDL_PropertiesID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_NotificationID,SDL_ShowNotification,(const char *a,const char *b,SDL_Surface *c,SDL_NotificationAction *d,int e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(bool,SDL_RemoveNotification,(SDL_NotificationID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_FormFactor,SDL_GetDeviceFormFactor,(void),(),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetDeviceFormFactorName,(SDL_FormFactor a),(a),return)
|
||||
|
||||
@@ -384,14 +384,26 @@ void SDL_NSLog(const char *prefix, const char *text)
|
||||
* This doesn't really have anything to do with the interfaces of the SDL video
|
||||
* subsystem, but we need to stuff this into an Objective-C source code file.
|
||||
*/
|
||||
bool SDL_IsIPad(void)
|
||||
{
|
||||
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
|
||||
}
|
||||
|
||||
bool SDL_IsAppleTV(void)
|
||||
bool SDL_GetUIKitDeviceFormFactor(void)
|
||||
{
|
||||
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomTV);
|
||||
// TODO: Apple Watch
|
||||
switch ([UIDevice currentDevice].userInterfaceIdiom) {
|
||||
case UIUserInterfaceIdiomPhone:
|
||||
return SDL_FORMFACTOR_PHONE;
|
||||
case UIUserInterfaceIdiomPad:
|
||||
return SDL_FORMFACTOR_TABLET;
|
||||
case UIUserInterfaceIdiomTV:
|
||||
return SDL_FORMFACTOR_TV;
|
||||
case UIUserInterfaceIdiomCarPlay:
|
||||
return SDL_FORMFACTOR_CAR;
|
||||
case UIUserInterfaceIdiomMac:
|
||||
return SDL_FORMFACTOR_DESKTOP;
|
||||
case UIUserInterfaceIdiomVision:
|
||||
return SDL_FORMFACTOR_HEADSET;
|
||||
default:
|
||||
return SDL_FORMFACTOR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_UIKIT
|
||||
|
||||
Reference in New Issue
Block a user