This commit is contained in:
brentfpage 2026-06-05 14:01:23 -06:00 committed by GitHub
commit f2f7235760
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 66 additions and 33 deletions

View file

@ -1124,9 +1124,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
public static native boolean nativeAllowRecreateActivity();
public static native int nativeCheckSDLThreadCounter();
public static native void onNativeFileDialog(int requestCode, String[] filelist, int filter);
public static native void onNativePinchStart();
public static native void onNativePinchUpdate(float scale);
public static native void onNativePinchEnd();
public static native void onNativePinchStart(float span_x, float span_y, float focus_x, float focus_y);
public static native void onNativePinchUpdate(float scale, float span_x, float span_y, float focus_x, float focus_y);
public static native void onNativePinchEnd(float span_x, float span_y, float focus_x, float focus_y);
/**
* This method is called by SDL using JNI.

View file

@ -440,19 +440,31 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = detector.getScaleFactor();
SDLActivity.onNativePinchUpdate(scale);
float span_x = getNormalizedX(detector.getCurrentSpanX());
float span_y = getNormalizedY(detector.getCurrentSpanY());
float focus_x = getNormalizedX(detector.getFocusX());
float focus_y = getNormalizedY(detector.getFocusY());
SDLActivity.onNativePinchUpdate(scale, span_x, span_y, focus_x, focus_y);
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
SDLActivity.onNativePinchStart();
float span_x = getNormalizedX(detector.getCurrentSpanX());
float span_y = getNormalizedY(detector.getCurrentSpanY());
float focus_x = getNormalizedX(detector.getFocusX());
float focus_y = getNormalizedY(detector.getFocusY());
SDLActivity.onNativePinchStart(span_x, span_y, focus_x, focus_y);
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
SDLActivity.onNativePinchEnd();
float span_x = getNormalizedX(detector.getCurrentSpanX());
float span_y = getNormalizedY(detector.getCurrentSpanY());
float focus_x = getNormalizedX(detector.getFocusX());
float focus_y = getNormalizedY(detector.getFocusY());
SDLActivity.onNativePinchEnd(span_x, span_y, focus_x, focus_y);
}
}

View file

@ -822,6 +822,10 @@ typedef struct SDL_PinchFingerEvent
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
float scale; /**< The scale change since the last SDL_EVENT_PINCH_UPDATE. Scale < 1 is "zoom out". Scale > 1 is "zoom in". */
float span_x; /**< The average X distance between each of the pointers forming the pinch in screen pixel coordinates. Or, -1 if this information is unavailable. */
float span_y; /**< The average Y distance between each of the pointers forming the pinch in screen pixel coordinates. Or, -1 if this information is unavailable. */
float focus_x; /**< The X coordinate of the current gesture's focal point in screen pixel coordinates. Or, -1 if this information is unavailable. */
float focus_y; /**< The Y coordinate of the current gesture's focal point in screen pixel coordinates. Or, -1 if this information is unavailable. */
SDL_WindowID windowID; /**< The window underneath the finger, if any */
} SDL_PinchFingerEvent;

View file

@ -123,14 +123,16 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
jint action, jfloat x, jfloat y, jfloat p);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePinchStart)(
JNIEnv *env, jclass jcls);
JNIEnv *env, jclass jcls,
jfloat span_x, jfloat span_y, jfloat focus_x, jfloat focus_y);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePinchUpdate)(
JNIEnv *env, jclass jcls,
jfloat scale);
jfloat scale, jfloat span_x, jfloat span_y, jfloat focus_x, jfloat focus_y);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePinchEnd)(
JNIEnv *env, jclass jcls);
JNIEnv *env, jclass jcls,
jfloat span_x, jfloat span_y, jfloat focus_x, jfloat focus_y);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)(
JNIEnv *env, jclass jcls,
@ -228,9 +230,9 @@ static JNINativeMethod SDLActivity_tab[] = {
{ "onNativeSoftReturnKey", "()Z", SDL_JAVA_INTERFACE(onNativeSoftReturnKey) },
{ "onNativeKeyboardFocusLost", "()V", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) },
{ "onNativeTouch", "(IIIFFF)V", SDL_JAVA_INTERFACE(onNativeTouch) },
{ "onNativePinchStart", "()V", SDL_JAVA_INTERFACE(onNativePinchStart) },
{ "onNativePinchUpdate", "(F)V", SDL_JAVA_INTERFACE(onNativePinchUpdate) },
{ "onNativePinchEnd", "()V", SDL_JAVA_INTERFACE(onNativePinchEnd) },
{ "onNativePinchStart", "(FFFF)V", SDL_JAVA_INTERFACE(onNativePinchStart) },
{ "onNativePinchUpdate", "(FFFFF)V", SDL_JAVA_INTERFACE(onNativePinchUpdate) },
{ "onNativePinchEnd", "(FFFF)V", SDL_JAVA_INTERFACE(onNativePinchEnd) },
{ "onNativeMouse", "(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) },
{ "onNativePen", "(IIIIFFF)V", SDL_JAVA_INTERFACE(onNativePen) },
{ "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
@ -1410,36 +1412,36 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)(
// Pinch
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePinchStart)(
JNIEnv *env, jclass jcls)
JNIEnv *env, jclass jcls, jfloat span_x, jfloat span_y, jfloat focus_x, jfloat focus_y)
{
SDL_LockMutex(Android_ActivityMutex);
if (Android_Window) {
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, 0, Android_Window, 0);
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, 0, Android_Window, 0, span_x, span_y, focus_x, focus_y);
}
SDL_UnlockMutex(Android_ActivityMutex);
}
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePinchUpdate)(
JNIEnv *env, jclass jcls, jfloat scale)
JNIEnv *env, jclass jcls, jfloat scale, jfloat span_x, jfloat span_y, jfloat focus_x, jfloat focus_y)
{
SDL_LockMutex(Android_ActivityMutex);
if (Android_Window) {
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, 0, Android_Window, scale);
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, 0, Android_Window, scale, span_x, span_y, focus_x, focus_y);
}
SDL_UnlockMutex(Android_ActivityMutex);
}
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativePinchEnd)(
JNIEnv *env, jclass jcls)
JNIEnv *env, jclass jcls, jfloat span_x, jfloat span_y, jfloat focus_x, jfloat focus_y)
{
SDL_LockMutex(Android_ActivityMutex);
if (Android_Window) {
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, Android_Window, 0);
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, Android_Window, 0, span_x, span_y, focus_x, focus_y);
}
SDL_UnlockMutex(Android_ActivityMutex);

View file

@ -614,7 +614,7 @@ void SDL_QuitTouch(void)
SDL_UnlockTouch();
}
int SDL_SendPinch(SDL_EventType type, Uint64 timestamp, SDL_Window *window, float scale)
int SDL_SendPinch(SDL_EventType type, Uint64 timestamp, SDL_Window *window, float scale, float span_x, float span_y, float focus_x, float focus_y)
{
/* Post the event, if desired */
int posted = 0;
@ -623,6 +623,10 @@ int SDL_SendPinch(SDL_EventType type, Uint64 timestamp, SDL_Window *window, floa
event.type = type;
event.common.timestamp = timestamp;
event.pinch.scale = scale;
event.pinch.span_x = span_x > 0 ? (span_x * (float)window->w) : -1.f;
event.pinch.span_y = span_y > 0 ? (span_y * (float)window->h) : -1.f;
event.pinch.focus_x = focus_x > 0 ? (focus_x * (float)window->w) : -1.f;
event.pinch.focus_y = focus_y > 0 ? (focus_y * (float)window->h) : -1.f;
event.pinch.windowID = window ? SDL_GetWindowID(window) : 0;
posted = (SDL_PushEvent(&event) > 0);
}

View file

@ -50,6 +50,6 @@ extern void SDL_DelTouch(SDL_TouchID id);
extern void SDL_QuitTouch(void);
// Send Gesture events
extern int SDL_SendPinch(SDL_EventType type, Uint64 timestamp, SDL_Window *window, float scale);
extern int SDL_SendPinch(SDL_EventType type, Uint64 timestamp, SDL_Window *window, float scale, float span_x, float span_y, float focus_x, float focus_y);
#endif // SDL_touch_c_h_

View file

@ -2042,17 +2042,17 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL
{
switch ([theEvent phase]) {
case NSEventPhaseBegan:
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, Cocoa_GetEventTimestamp([theEvent timestamp]), NULL, 0);
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, Cocoa_GetEventTimestamp([theEvent timestamp]), NULL, 0, -1, -1, -1, -1);
break;
case NSEventPhaseChanged:
{
CGFloat scale = 1.0f + [theEvent magnification];
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, Cocoa_GetEventTimestamp([theEvent timestamp]), NULL, scale);
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, Cocoa_GetEventTimestamp([theEvent timestamp]), NULL, scale, -1, -1, -1, -1);
}
break;
case NSEventPhaseEnded:
case NSEventPhaseCancelled:
SDL_SendPinch(SDL_EVENT_PINCH_END, Cocoa_GetEventTimestamp([theEvent timestamp]), NULL, 0);
SDL_SendPinch(SDL_EVENT_PINCH_END, Cocoa_GetEventTimestamp([theEvent timestamp]), NULL, 0, -1, -1, -1, -1);
break;
default:
break;

View file

@ -484,17 +484,28 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
{
CGFloat scale = sender.scale;
UIGestureRecognizerState state = sender.state;
CGPoint point1 = [sender locationOfTouch:0 inView:self];
CGPoint point2 = [sender locationOfTouch:1 inView:self];
CGFloat focus_x = (point1.x + point2.x)/2;
CGFloat focus_y = (point1.y + point2.y)/2;
CGFloat span_x = SDL_fabs(point1.x - point2.x);
CGFloat span_y = SDL_fabs(point1.y - point2.y);
CGRect bounds = self.bounds;
focus_x /= bounds.size.width;
focus_y /= bounds.size.height;
span_x /= bounds.size.width;
span_y /= bounds.size.height;
switch (state) {
case UIGestureRecognizerStateBegan:
pinch_scale = 1.0f;
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, 0, sdlwindow, 0);
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, 0, sdlwindow, 0, span_x, span_y, focus_x, focus_y);
break;
case UIGestureRecognizerStateChanged:
if (pinch_scale > 0.0f) {
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, 0, sdlwindow, scale / pinch_scale);
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, 0, sdlwindow, scale / pinch_scale, span_x, span_y, focus_x, focus_y);
}
pinch_scale = scale;
break;
@ -502,7 +513,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
case UIGestureRecognizerStateFailed:
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, sdlwindow, 0);
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, sdlwindow, 0, span_x, span_y, focus_x, focus_y);
break;
default:

View file

@ -322,7 +322,7 @@ static void handle_pinch_begin(void *data, struct zwp_pointer_gesture_pinch_v1 *
seat->pointer.gesture_focus = wind;
const Uint64 timestamp = Wayland_GetPointerTimestamp(seat, time);
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, timestamp, wind->sdlwindow, 0.0f);
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, timestamp, wind->sdlwindow, 0.0f, -1.0f, -1.0f, -1.0f, -1.0f);
}
}
@ -334,7 +334,7 @@ static void handle_pinch_update(void *data, struct zwp_pointer_gesture_pinch_v1
if (seat->pointer.gesture_focus) {
const Uint64 timestamp = Wayland_GetPointerTimestamp(seat, time);
const float s = (float)wl_fixed_to_double(scale);
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, timestamp, seat->pointer.gesture_focus->sdlwindow, s);
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, timestamp, seat->pointer.gesture_focus->sdlwindow, s, -1.0f, -1.0f, -1.0f, -1.0f);
}
}
@ -344,7 +344,7 @@ static void handle_pinch_end(void *data, struct zwp_pointer_gesture_pinch_v1 *zw
if (seat->pointer.gesture_focus) {
const Uint64 timestamp = Wayland_GetPointerTimestamp(seat, time);
SDL_SendPinch(SDL_EVENT_PINCH_END, timestamp, seat->pointer.gesture_focus->sdlwindow, 0.0f);
SDL_SendPinch(SDL_EVENT_PINCH_END, timestamp, seat->pointer.gesture_focus->sdlwindow, 0.0f, -1.0f, -1.0f, -1.0f, -1.0f);
seat->pointer.gesture_focus = NULL;
}
@ -2421,7 +2421,7 @@ static void Wayland_SeatDestroyPointer(SDL_WaylandSeat *seat)
// End any active gestures.
if (seat->pointer.gesture_focus) {
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, seat->pointer.gesture_focus->sdlwindow, 0.0f);
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, seat->pointer.gesture_focus->sdlwindow, 0.0f, -1.0f, -1.0f, -1.0f, -1.0f);
}
// Make sure focus is removed from a surface before the pointer is destroyed.

View file

@ -760,11 +760,11 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y);
if (cookie->evtype == XI_GesturePinchBegin) {
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, 0, window, 0);
SDL_SendPinch(SDL_EVENT_PINCH_BEGIN, 0, window, 0, -1, -1, -1, -1);
} else if (cookie->evtype == XI_GesturePinchUpdate) {
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, 0, window, (float)xev->scale);
SDL_SendPinch(SDL_EVENT_PINCH_UPDATE, 0, window, (float)xev->scale, -1, -1, -1, -1);
} else {
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, window, 0);
SDL_SendPinch(SDL_EVENT_PINCH_END, 0, window, 0, -1, -1, -1, -1);
}
} break;