Refactor NativeTouchHandler, restore absolute touch, Bug fixes
This commit is contained in:
1 parent
d673c4900c
commit
e7fd911fb8
17 files changed
+459
-278
No files matched your search
@@ -34,7 +34,8 @@
|
|||||||
useFramePacing:(BOOL)useFramePacing
|
useFramePacing:(BOOL)useFramePacing
|
||||||
enableHdr:(BOOL)enableHdr
|
enableHdr:(BOOL)enableHdr
|
||||||
btMouseSupport:(BOOL)btMouseSupport
|
btMouseSupport:(BOOL)btMouseSupport
|
||||||
absoluteTouchMode:(BOOL)absoluteTouchMode
|
// absoluteTouchMode:(BOOL)absoluteTouchMode
|
||||||
|
touchMode:(NSInteger)touchMode
|
||||||
statsOverlay:(BOOL)statsOverlay;
|
statsOverlay:(BOOL)statsOverlay;
|
||||||
|
|
||||||
- (NSArray*) getHosts;
|
- (NSArray*) getHosts;
|
||||||
|
|||||||
@@ -73,7 +73,8 @@
|
|||||||
useFramePacing:(BOOL)useFramePacing
|
useFramePacing:(BOOL)useFramePacing
|
||||||
enableHdr:(BOOL)enableHdr
|
enableHdr:(BOOL)enableHdr
|
||||||
btMouseSupport:(BOOL)btMouseSupport
|
btMouseSupport:(BOOL)btMouseSupport
|
||||||
absoluteTouchMode:(BOOL)absoluteTouchMode
|
// absoluteTouchMode:(BOOL)absoluteTouchMode
|
||||||
|
touchMode:(NSInteger)touchMode
|
||||||
statsOverlay:(BOOL)statsOverlay {
|
statsOverlay:(BOOL)statsOverlay {
|
||||||
|
|
||||||
[_managedObjectContext performBlockAndWait:^{
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
@@ -99,7 +100,8 @@
|
|||||||
settingsToSave.useFramePacing = useFramePacing;
|
settingsToSave.useFramePacing = useFramePacing;
|
||||||
settingsToSave.enableHdr = enableHdr;
|
settingsToSave.enableHdr = enableHdr;
|
||||||
settingsToSave.btMouseSupport = btMouseSupport;
|
settingsToSave.btMouseSupport = btMouseSupport;
|
||||||
settingsToSave.absoluteTouchMode = absoluteTouchMode;
|
// settingsToSave.absoluteTouchMode = absoluteTouchMode;
|
||||||
|
settingsToSave.touchMode = [NSNumber numberWithInteger:(uint16_t)touchMode];
|
||||||
settingsToSave.statsOverlay = statsOverlay;
|
settingsToSave.statsOverlay = statsOverlay;
|
||||||
|
|
||||||
[self saveData];
|
[self saveData];
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "Settings+CoreDataClass.h"
|
#import "Settings+CoreDataClass.h"
|
||||||
|
#define RELATIVE_TOUCH_MODE 0
|
||||||
|
#define NATIVE_TOUCH_MODE 1
|
||||||
|
#define ABSOLUTE_TOUCH_MODE 2
|
||||||
|
|
||||||
|
|
||||||
@interface TemporarySettings : NSObject
|
@interface TemporarySettings : NSObject
|
||||||
|
|
||||||
@@ -37,7 +41,8 @@
|
|||||||
@property (nonatomic) BOOL optimizeGames;
|
@property (nonatomic) BOOL optimizeGames;
|
||||||
@property (nonatomic) BOOL enableHdr;
|
@property (nonatomic) BOOL enableHdr;
|
||||||
@property (nonatomic) BOOL btMouseSupport;
|
@property (nonatomic) BOOL btMouseSupport;
|
||||||
@property (nonatomic) BOOL absoluteTouchMode;
|
// @property (nonatomic) BOOL absoluteTouchMode;
|
||||||
|
@property (nonatomic, retain) NSNumber * touchMode;
|
||||||
@property (nonatomic) BOOL statsOverlay;
|
@property (nonatomic) BOOL statsOverlay;
|
||||||
@property (nonatomic) BOOL liftStreamViewForKeyboard;
|
@property (nonatomic) BOOL liftStreamViewForKeyboard;
|
||||||
@property (nonatomic) BOOL showKeyboardToolbar;
|
@property (nonatomic) BOOL showKeyboardToolbar;
|
||||||
|
|||||||
@@ -83,7 +83,8 @@
|
|||||||
self.swapABXYButtons = settings.swapABXYButtons;
|
self.swapABXYButtons = settings.swapABXYButtons;
|
||||||
self.onscreenControls = settings.onscreenControls;
|
self.onscreenControls = settings.onscreenControls;
|
||||||
self.btMouseSupport = settings.btMouseSupport;
|
self.btMouseSupport = settings.btMouseSupport;
|
||||||
self.absoluteTouchMode = settings.absoluteTouchMode;
|
// self.absoluteTouchMode = settings.absoluteTouchMode;
|
||||||
|
self.touchMode = settings.touchMode;
|
||||||
self.statsOverlay = settings.statsOverlay;
|
self.statsOverlay = settings.statsOverlay;
|
||||||
self.keyboardToggleFingers = settings.keyboardToggleFingers;
|
self.keyboardToggleFingers = settings.keyboardToggleFingers;
|
||||||
self.swipeExitScreenEdge = settings.swipeExitScreenEdge;
|
self.swipeExitScreenEdge = settings.swipeExitScreenEdge;
|
||||||
|
|||||||
@@ -38,85 +38,83 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- (void)onLongPressStart:(NSTimer*)timer {
|
- (void)onLongPressStart:(NSTimer*)timer {
|
||||||
// // Raise the left click and start a right click
|
// Raise the left click and start a right click
|
||||||
// LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||||
// LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
// // Ignore touch down events with more than one finger
|
// Ignore touch down events with more than one finger
|
||||||
// return;
|
if ([[event allTouches] count] > 1) {
|
||||||
// if ([[event allTouches] count] > 1) {
|
return;
|
||||||
// return;
|
}
|
||||||
// }
|
|
||||||
//
|
UITouch* touch = [touches anyObject];
|
||||||
// UITouch* touch = [touches anyObject];
|
CGPoint touchLocation = [touch locationInView:view];
|
||||||
// CGPoint touchLocation = [touch locationInView:view];
|
|
||||||
//
|
// Don't reposition for finger down events within the deadzone. This makes double-clicking easier.
|
||||||
// // Don't reposition for finger down events within the deadzone. This makes double-clicking easier.
|
if (touch.timestamp - lastTouchUp.timestamp > DOUBLE_TAP_DEAD_ZONE_DELAY ||
|
||||||
// if (touch.timestamp - lastTouchUp.timestamp > DOUBLE_TAP_DEAD_ZONE_DELAY ||
|
sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchUpLocation.x / view.bounds.size.width), 2) +
|
||||||
// sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchUpLocation.x / view.bounds.size.width), 2) +
|
pow((touchLocation.y / view.bounds.size.height) - (lastTouchUpLocation.y / view.bounds.size.height), 2)) > DOUBLE_TAP_DEAD_ZONE_DELTA) {
|
||||||
// pow((touchLocation.y / view.bounds.size.height) - (lastTouchUpLocation.y / view.bounds.size.height), 2)) > DOUBLE_TAP_DEAD_ZONE_DELTA) {
|
[view updateCursorLocation:touchLocation isMouse:NO];
|
||||||
// [view updateCursorLocation:touchLocation isMouse:NO];
|
}
|
||||||
// }
|
|
||||||
//
|
// Press the left button down
|
||||||
// // Press the left button down
|
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||||
// LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
|
||||||
//
|
// Start the long press timer
|
||||||
// // Start the long press timer
|
longPressTimer = [NSTimer scheduledTimerWithTimeInterval:LONG_PRESS_ACTIVATION_DELAY
|
||||||
// longPressTimer = [NSTimer scheduledTimerWithTimeInterval:LONG_PRESS_ACTIVATION_DELAY
|
target:self
|
||||||
// target:self
|
selector:@selector(onLongPressStart:)
|
||||||
// selector:@selector(onLongPressStart:)
|
userInfo:nil
|
||||||
// userInfo:nil
|
repeats:NO];
|
||||||
// repeats:NO];
|
|
||||||
//
|
lastTouchDown = touch;
|
||||||
// lastTouchDown = touch;
|
lastTouchDownLocation = touchLocation;
|
||||||
// lastTouchDownLocation = touchLocation;
|
}
|
||||||
//}
|
|
||||||
//
|
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
//- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
// Ignore touch move events with more than one finger
|
||||||
// // Ignore touch move events with more than one finger
|
if ([[event allTouches] count] > 1) {
|
||||||
// return;
|
return;
|
||||||
// if ([[event allTouches] count] > 1) {
|
}
|
||||||
// return;
|
|
||||||
// }
|
UITouch* touch = [touches anyObject];
|
||||||
//
|
CGPoint touchLocation = [touch locationInView:view];
|
||||||
// UITouch* touch = [touches anyObject];
|
|
||||||
// CGPoint touchLocation = [touch locationInView:view];
|
if (sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchDownLocation.x / view.bounds.size.width), 2) +
|
||||||
//
|
pow((touchLocation.y / view.bounds.size.height) - (lastTouchDownLocation.y / view.bounds.size.height), 2)) > LONG_PRESS_ACTIVATION_DELTA) {
|
||||||
// if (sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchDownLocation.x / view.bounds.size.width), 2) +
|
// Moved too far since touch down. Cancel the long press timer.
|
||||||
// pow((touchLocation.y / view.bounds.size.height) - (lastTouchDownLocation.y / view.bounds.size.height), 2)) > LONG_PRESS_ACTIVATION_DELTA) {
|
[longPressTimer invalidate];
|
||||||
// // Moved too far since touch down. Cancel the long press timer.
|
longPressTimer = nil;
|
||||||
// [longPressTimer invalidate];
|
}
|
||||||
// longPressTimer = nil;
|
|
||||||
// }
|
[view updateCursorLocation:[[touches anyObject] locationInView:view] isMouse:NO];
|
||||||
//
|
}
|
||||||
// [view updateCursorLocation:[[touches anyObject] locationInView:view] isMouse:NO];
|
|
||||||
//}
|
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
//
|
// Only fire this logic if all touches have ended
|
||||||
//- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
if ([[event allTouches] count] == [touches count]) {
|
||||||
// // Only fire this logic if all touches have ended
|
// Cancel the long press timer
|
||||||
// if ([[event allTouches] count] == [touches count]) {
|
[longPressTimer invalidate];
|
||||||
// // Cancel the long press timer
|
longPressTimer = nil;
|
||||||
// [longPressTimer invalidate];
|
|
||||||
// longPressTimer = nil;
|
// Left button up on finger up
|
||||||
//
|
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||||
// // Left button up on finger up
|
|
||||||
// LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
// Raise right button too in case we triggered a long press gesture
|
||||||
//
|
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||||
// // Raise right button too in case we triggered a long press gesture
|
|
||||||
// LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
// Remember this last touch for touch-down deadzoning
|
||||||
//
|
lastTouchUp = [touches anyObject];
|
||||||
// // Remember this last touch for touch-down deadzoning
|
lastTouchUpLocation = [lastTouchUp locationInView:view];
|
||||||
// lastTouchUp = [touches anyObject];
|
}
|
||||||
// lastTouchUpLocation = [lastTouchUp locationInView:view];
|
}
|
||||||
// }
|
|
||||||
//}
|
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
//
|
// Treat this as a normal touchesEnded event
|
||||||
//- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
|
[self touchesEnded:touches withEvent:event];
|
||||||
// // Treat this as a normal touchesEnded event
|
}
|
||||||
// [self touchesEnded:touches withEvent:event];
|
|
||||||
//}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -1061,7 +1061,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
|||||||
// Even if no gamepads are present, we will always count one if OSC is enabled,
|
// Even if no gamepads are present, we will always count one if OSC is enabled,
|
||||||
// or it's set to auto and no keyboard or mouse is present. Absolute touch mode
|
// or it's set to auto and no keyboard or mouse is present. Absolute touch mode
|
||||||
// disables the OSC.
|
// disables the OSC.
|
||||||
if (level != OnScreenControlsLevelOff && (![ControllerSupport hasKeyboardOrMouse] || level != OnScreenControlsLevelAuto) && !settings.absoluteTouchMode) {
|
if (level != OnScreenControlsLevelOff && (![ControllerSupport hasKeyboardOrMouse] || level != OnScreenControlsLevelAuto) && (settings.touchMode.intValue == RELATIVE_TOUCH_MODE)) {
|
||||||
mask |= 0x1;
|
mask |= 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,33 +2,22 @@
|
|||||||
// NativeTouchHandler.h
|
// NativeTouchHandler.h
|
||||||
// Moonlight
|
// Moonlight
|
||||||
//
|
//
|
||||||
// Created by ZWM on 2024/5/14.
|
// Created by ZWM on 2024/6/16.
|
||||||
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#import "StreamView.h"
|
#import "StreamView.h"
|
||||||
|
#import "DataManager.h"
|
||||||
|
#include <Limelight.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface TouchPointer : NSObject
|
@interface NativeTouchHandler : UIResponder
|
||||||
|
|
||||||
+ (void)initContextWith:(StreamView *)view;
|
- (id)initWith:(StreamView*)view and:(TemporarySettings*)settings;
|
||||||
+ (void)populatePointerId:(UITouch*)touch;
|
|
||||||
+ (void)removePointerId:(UITouch*)touch;
|
|
||||||
+ (uint32_t) retrievePointerIdFromDict:(UITouch*)touch;
|
|
||||||
+ (void)setPointerVelocityDivider:(CGFloat)dividerLocation;
|
|
||||||
+ (void)setPointerVelocityFactor:(CGFloat)velocityFactor;
|
|
||||||
+ (void)populatePointerObjIntoDict:(UITouch*)touch;
|
|
||||||
+ (void)removePointerObjFromDict:(UITouch*)touch;
|
|
||||||
+ (void)updatePointerObjInDict:(UITouch *)touch;
|
|
||||||
+ (CGPoint)selectCoordsFor:(UITouch *)touch;
|
|
||||||
|
|
||||||
|
|
||||||
- (instancetype)initWith:(UITouch *)touch;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
@@ -2,134 +2,146 @@
|
|||||||
// NativeTouchHandler.m
|
// NativeTouchHandler.m
|
||||||
// Moonlight
|
// Moonlight
|
||||||
//
|
//
|
||||||
// Created by ZWM on 2024/5/14.
|
// Created by Admin on 2024/6/16.
|
||||||
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "NativeTouchHandler.h"
|
#import "NativeTouchHandler.h"
|
||||||
|
#import "NativeTouchPointer.h"
|
||||||
|
#import "StreamView.h"
|
||||||
|
#import "DataManager.h"
|
||||||
|
|
||||||
#include <Limelight.h>
|
#include <Limelight.h>
|
||||||
|
|
||||||
|
|
||||||
// Use a Dictionary to store UITouch object's memory address as key, and pointerId as value,字典存放UITouch对象地址和pointerId映射关系
|
|
||||||
// pointerId will be generated from electronic noise, by arc4_random, pointerId,由随机噪声生成
|
|
||||||
// Use a NSSet store pointerId, for quick repeition inquiry, NSSet存放活跃的pointerId合集,用于快速查找,以防重复.
|
|
||||||
static NSMutableDictionary *pointerIdDict; //pointerId Dict for native touch.
|
|
||||||
static NSMutableSet<NSNumber *> *pointerIdSet; //pointerIdSet for native touch.
|
|
||||||
static NSMutableDictionary *pointerDict;
|
|
||||||
|
|
||||||
static CGFloat pointerVelocityFactor;
|
@implementation NativeTouchHandler {
|
||||||
static CGFloat pointerVelocityDivider;
|
StreamView* streamView;
|
||||||
static CGFloat pointerVelocityDividerLocation;
|
bool activateCoordSelector;
|
||||||
|
|
||||||
StreamView *streamView;
|
|
||||||
|
|
||||||
@implementation TouchPointer{
|
|
||||||
CGPoint initialPoint;
|
|
||||||
CGPoint latestPoint;
|
|
||||||
CGPoint previousPoint;
|
|
||||||
CGPoint latestRelativePoint;
|
|
||||||
CGPoint previousRelativePoint;
|
|
||||||
CGFloat velocityX;
|
|
||||||
CGFloat velocityY;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)setPointerVelocityDivider:(CGFloat)dividerLocation{
|
|
||||||
pointerVelocityDivider = dividerLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)setPointerVelocityFactor:(CGFloat)velocityFactor{
|
|
||||||
pointerVelocityFactor = velocityFactor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (instancetype)initWith:(UITouch *)touch{
|
- (id)initWith:(StreamView*)view and:(TemporarySettings*)settings{
|
||||||
self = [self init];
|
self = [self init];
|
||||||
self->initialPoint = [touch locationInView:streamView];
|
self->streamView = view;
|
||||||
self->latestPoint = self->initialPoint;
|
activateCoordSelector = (settings.pointerVelocityModeDivider.floatValue != 1.0);
|
||||||
self->latestRelativePoint = self->initialPoint;
|
[NativeTouchPointer setPointerVelocityDivider:settings.pointerVelocityModeDivider.floatValue];
|
||||||
return self;
|
[NativeTouchPointer setPointerVelocityFactor:settings.touchPointerVelocityFactor.floatValue];
|
||||||
}
|
[NativeTouchPointer initContextWith:streamView];
|
||||||
|
|
||||||
- (void)updatePointerCoords:(UITouch *)touch{
|
return self;
|
||||||
previousPoint = latestPoint;
|
|
||||||
latestPoint = [touch locationInView:streamView];
|
|
||||||
velocityX = latestPoint.x - previousPoint.x;
|
|
||||||
velocityY = latestPoint.y - previousPoint.y;
|
|
||||||
previousRelativePoint = latestRelativePoint;
|
|
||||||
latestRelativePoint.x = previousRelativePoint.x + pointerVelocityFactor * velocityX;
|
|
||||||
latestRelativePoint.y = previousRelativePoint.y + pointerVelocityFactor * velocityY;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initContextWith:(StreamView *)view{
|
|
||||||
streamView = view;
|
|
||||||
pointerIdDict = [NSMutableDictionary dictionary];
|
|
||||||
pointerIdSet = [NSMutableSet set];
|
|
||||||
pointerDict = [NSMutableDictionary dictionary];
|
|
||||||
pointerVelocityDividerLocation = CGRectGetWidth([[UIScreen mainScreen] bounds]) * pointerVelocityDivider;
|
|
||||||
NSLog(@"pointerVelocityDivider: %.2f", pointerVelocityDivider);
|
|
||||||
NSLog(@"pointerVelocityDividerLocation: %.2f", pointerVelocityDividerLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)populatePointerObjIntoDict:(UITouch*)touch{
|
|
||||||
[pointerDict setObject:[[TouchPointer alloc] initWith:touch] forKey:@((uint64_t)touch)];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)removePointerObjFromDict:(UITouch*)touch{
|
|
||||||
uint64_t eventAddrValue = (uint64_t)touch;
|
|
||||||
TouchPointer* pointer = [pointerDict objectForKey:@(eventAddrValue)];
|
|
||||||
if(pointer != nil){
|
|
||||||
[pointerDict removeObjectForKey:@(eventAddrValue)];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)updatePointerObjInDict:(UITouch *)touch{
|
|
||||||
[[pointerDict objectForKey:@((uint64_t)touch)] updatePointerCoords:touch];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
+ (CGPoint)selectCoordsFor:(UITouch *)touch{
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
TouchPointer *pointer = [pointerDict objectForKey:@((uint64_t)touch)];
|
|
||||||
if((pointer -> initialPoint).x > pointerVelocityDividerLocation){ //if first contact coords locates on the right side of divider.
|
|
||||||
return pointer->latestRelativePoint;
|
|
||||||
}
|
|
||||||
return [touch locationInView:streamView];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if !TARGET_OS_TV
|
||||||
|
if (@available(iOS 13.4, *)) {
|
||||||
// 随机生成pointerId并填入NSDict和NSSet
|
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
||||||
// generate & populate pointerId into NSDict & NSSet, called in UITouchPhaseBegan
|
|
||||||
+ (void)populatePointerId:(UITouch*)touch{
|
|
||||||
uint64_t eventAddrValue = (uint64_t)touch;
|
|
||||||
uint32_t randomPointerId = arc4random_uniform(UINT32_MAX); // generate pointerId from eletronic noise.
|
|
||||||
for(;;){
|
|
||||||
if([pointerIdSet containsObject:@(randomPointerId)]) randomPointerId = arc4random_uniform(UINT32_MAX); // in case of new pointerId collides with existing ones, generate again.
|
|
||||||
else{ // populate pointerId into NSDict & NSSet.
|
|
||||||
[pointerIdDict setObject:@(randomPointerId) forKey:@(eventAddrValue)];
|
|
||||||
[pointerIdSet addObject:@(randomPointerId)];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- (void)sendTouchEvent:(UITouch*)event touchType:(uint8_t)touchType{
|
||||||
|
CGPoint targetCoords;
|
||||||
|
if(activateCoordSelector && event.phase == UITouchPhaseMoved) targetCoords = [NativeTouchPointer selectCoordsFor:event]; // coordinates of touch pointer replaced to relative ones here.
|
||||||
|
else targetCoords = [event locationInView:streamView];
|
||||||
|
CGPoint location = [streamView adjustCoordinatesForVideoArea:targetCoords];
|
||||||
|
CGSize videoSize = [streamView getVideoAreaSize];
|
||||||
|
LiSendTouchEvent(touchType,[NativeTouchPointer retrievePointerIdFromDict:event],location.x / videoSize.width, location.y / videoSize.height,(event.force / event.maximumPossibleForce) / sin(event.altitudeAngle),0.0f, 0.0f,[streamView getRotationFromAzimuthAngle:[event azimuthAngleInView:streamView]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)handleUITouch:(UITouch*)event index:(int)index{
|
||||||
|
uint8_t type;
|
||||||
|
//BOOL pointerVelocityScaleEnabled = (settings.pointerVelocityModeDivider.floatValue != 1.0); // when the divider is 1.0, means 0% of screen shall pass velocity-scaled pointer to sunshine.
|
||||||
|
// NSLog(@"handleUITouch %ld,%d",(long)event.phase,(uint32_t)event);
|
||||||
|
//#define LI_TOUCH_EVENT_HOVER 0x00
|
||||||
|
//#define LI_TOUCH_EVENT_DOWN 0x01
|
||||||
|
//#define LI_TOUCH_EVENT_UP 0x02
|
||||||
|
//#define LI_TOUCH_EVENT_MOVE 0x03
|
||||||
|
//#define LI_TOUCH_EVENT_CANCEL 0x04
|
||||||
|
//#define LI_TOUCH_EVENT_BUTTON_ONLY 0x05
|
||||||
|
//#define LI_TOUCH_EVENT_HOVER_LEAVE 0x06
|
||||||
|
//#define LI_TOUCH_EVENT_CANCEL_ALL 0x07
|
||||||
|
//#define LI_ROT_UNKNOWN 0xFFFF
|
||||||
|
|
||||||
// remove pointerId in UITouchPhaseEnded condition
|
// UITouchPhaseBegan, // whenever a finger touches the surface.
|
||||||
+ (void)removePointerId:(UITouch*)touch{
|
// UITouchPhaseMoved, // whenever a finger moves on the surface.
|
||||||
uint64_t eventAddrValue = (uint64_t)touch;
|
// UITouchPhaseStationary, // whenever a finger is touching the surface but hasn't moved since the previous event.
|
||||||
NSNumber* pointerIdObj = [pointerIdDict objectForKey:@(eventAddrValue)];
|
// UITouchPhaseEnded, // whenever a finger leaves the surface.
|
||||||
if(pointerIdObj != nil){
|
// UITouchPhaseCancelled, // whenever a touch doesn't end but we need to stop tracking (e.g. putting device to face)
|
||||||
[pointerIdSet removeObject:pointerIdObj];
|
// UITouchPhaseRegionEntered API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos), // whenever a touch is entering the region of a user interface
|
||||||
[pointerIdDict removeObjectForKey:@(eventAddrValue)];
|
// UITouchPhaseRegionMoved API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos), // when a touch is inside the region of a user interface, but hasn’t yet made contact or left the region
|
||||||
|
// UITouchPhaseRegionExited API_AVAILABLE(ios(13.4), tvos(13.4))
|
||||||
|
|
||||||
|
switch (event.phase) {
|
||||||
|
case UITouchPhaseBegan://开始触摸
|
||||||
|
type = LI_TOUCH_EVENT_DOWN;
|
||||||
|
[NativeTouchPointer populatePointerId:event]; //获取并记录pointerId
|
||||||
|
if(activateCoordSelector) [NativeTouchPointer populatePointerObjIntoDict:event];
|
||||||
|
break;
|
||||||
|
case UITouchPhaseMoved://移动
|
||||||
|
case UITouchPhaseStationary:
|
||||||
|
type = LI_TOUCH_EVENT_MOVE;
|
||||||
|
if(activateCoordSelector) [NativeTouchPointer updatePointerObjInDict:event];
|
||||||
|
break;
|
||||||
|
case UITouchPhaseEnded://触摸结束
|
||||||
|
type = LI_TOUCH_EVENT_UP;
|
||||||
|
[self sendTouchEvent:event touchType:type]; //先发送,再删除
|
||||||
|
[NativeTouchPointer removePointerId:event]; //删除pointerId
|
||||||
|
if(activateCoordSelector) [NativeTouchPointer removePointerObjFromDict:event];
|
||||||
|
return;
|
||||||
|
case UITouchPhaseCancelled://触摸取消
|
||||||
|
type = LI_TOUCH_EVENT_CANCEL;
|
||||||
|
[self sendTouchEvent:event touchType:type]; //先发送,再删除
|
||||||
|
[NativeTouchPointer removePointerId:event]; //删除pointerId
|
||||||
|
if(activateCoordSelector) [NativeTouchPointer removePointerObjFromDict:event];
|
||||||
|
return;
|
||||||
|
case UITouchPhaseRegionEntered://停留
|
||||||
|
case UITouchPhaseRegionMoved://停留
|
||||||
|
type = LI_TOUCH_EVENT_HOVER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
[self sendTouchEvent:event touchType:type];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从字典中获取UITouch事件对应的pointerId
|
|
||||||
// call this only when NSDcit & NSSet is up-to-date.
|
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
+ (uint32_t) retrievePointerIdFromDict:(UITouch*)touch{
|
#if !TARGET_OS_TV
|
||||||
return [[pointerIdDict objectForKey:@((uint64_t)touch)] unsignedIntValue];
|
if (@available(iOS 13.4, *)) {
|
||||||
|
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
||||||
|
return;
|
||||||
|
// NSLog(@"touchesMoved - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
|
#if !TARGET_OS_TV
|
||||||
|
if (@available(iOS 13.4, *)) {
|
||||||
|
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
||||||
|
return;
|
||||||
|
// NSLog(@"touchesEnded - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
|
#if !TARGET_OS_TV
|
||||||
|
if (@available(iOS 13.4, *)) {
|
||||||
|
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// NSLog(@"touchesCancelled - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// NativeTouchPointer.h
|
||||||
|
// Moonlight
|
||||||
|
//
|
||||||
|
// Created by ZWM on 2024/5/14.
|
||||||
|
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "StreamView.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface NativeTouchPointer : NSObject
|
||||||
|
|
||||||
|
+ (void)initContextWith:(StreamView *)view;
|
||||||
|
+ (void)populatePointerId:(UITouch*)touch;
|
||||||
|
+ (void)removePointerId:(UITouch*)touch;
|
||||||
|
+ (uint32_t) retrievePointerIdFromDict:(UITouch*)touch;
|
||||||
|
+ (void)setPointerVelocityDivider:(CGFloat)dividerLocation;
|
||||||
|
+ (void)setPointerVelocityFactor:(CGFloat)velocityFactor;
|
||||||
|
+ (void)populatePointerObjIntoDict:(UITouch*)touch;
|
||||||
|
+ (void)removePointerObjFromDict:(UITouch*)touch;
|
||||||
|
+ (void)updatePointerObjInDict:(UITouch *)touch;
|
||||||
|
+ (CGPoint)selectCoordsFor:(UITouch *)touch;
|
||||||
|
|
||||||
|
|
||||||
|
- (instancetype)initWith:(UITouch *)touch;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
//
|
||||||
|
// NativeTouchPointer.m
|
||||||
|
// Moonlight
|
||||||
|
//
|
||||||
|
// Created by ZWM on 2024/5/14.
|
||||||
|
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "NativeTouchPointer.h"
|
||||||
|
#include <Limelight.h>
|
||||||
|
|
||||||
|
// native touch pointer class deals with:
|
||||||
|
// generating pointerId randomly, pointerId Dic & set management
|
||||||
|
// pointer instance with coordinate manipulation.
|
||||||
|
|
||||||
|
|
||||||
|
// Use a Dictionary to store UITouch object's memory address as key, and pointerId as value,字典存放UITouch对象地址和pointerId映射关系
|
||||||
|
// pointerId will be generated from electronic noise, by arc4_random, pointerId,由随机噪声生成
|
||||||
|
// Use a NSSet store pointerId, for quick repeition inquiry, NSSet存放活跃的pointerId合集,用于快速查找,以防重复.
|
||||||
|
static NSMutableDictionary *pointerIdDict; //pointerId Dict for native touch.
|
||||||
|
static NSMutableSet<NSNumber *> *pointerIdSet; //pointerIdSet for native touch.
|
||||||
|
static NSMutableDictionary *pointerDict;
|
||||||
|
|
||||||
|
static CGFloat pointerVelocityFactor;
|
||||||
|
static CGFloat pointerVelocityDivider;
|
||||||
|
static CGFloat pointerVelocityDividerLocation;
|
||||||
|
|
||||||
|
StreamView *streamView;
|
||||||
|
|
||||||
|
@implementation NativeTouchPointer{
|
||||||
|
CGPoint initialPoint;
|
||||||
|
CGPoint latestPoint;
|
||||||
|
CGPoint previousPoint;
|
||||||
|
CGPoint latestRelativePoint;
|
||||||
|
CGPoint previousRelativePoint;
|
||||||
|
CGFloat velocityX;
|
||||||
|
CGFloat velocityY;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)setPointerVelocityDivider:(CGFloat)dividerLocation{
|
||||||
|
pointerVelocityDivider = dividerLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)setPointerVelocityFactor:(CGFloat)velocityFactor{
|
||||||
|
pointerVelocityFactor = velocityFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (instancetype)initWith:(UITouch *)touch{
|
||||||
|
self = [self init];
|
||||||
|
self->initialPoint = [touch locationInView:streamView];
|
||||||
|
self->latestPoint = self->initialPoint;
|
||||||
|
self->latestRelativePoint = self->initialPoint;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updatePointerCoords:(UITouch *)touch{
|
||||||
|
previousPoint = latestPoint;
|
||||||
|
latestPoint = [touch locationInView:streamView];
|
||||||
|
velocityX = latestPoint.x - previousPoint.x;
|
||||||
|
velocityY = latestPoint.y - previousPoint.y;
|
||||||
|
previousRelativePoint = latestRelativePoint;
|
||||||
|
latestRelativePoint.x = previousRelativePoint.x + pointerVelocityFactor * velocityX;
|
||||||
|
latestRelativePoint.y = previousRelativePoint.y + pointerVelocityFactor * velocityY;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)initContextWith:(StreamView *)view{
|
||||||
|
streamView = view;
|
||||||
|
pointerIdDict = [NSMutableDictionary dictionary];
|
||||||
|
pointerIdSet = [NSMutableSet set];
|
||||||
|
pointerDict = [NSMutableDictionary dictionary];
|
||||||
|
pointerVelocityDividerLocation = CGRectGetWidth([[UIScreen mainScreen] bounds]) * pointerVelocityDivider;
|
||||||
|
NSLog(@"pointerVelocityDivider: %.2f", pointerVelocityDivider);
|
||||||
|
NSLog(@"pointerVelocityDividerLocation: %.2f", pointerVelocityDividerLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)populatePointerObjIntoDict:(UITouch*)touch{
|
||||||
|
[pointerDict setObject:[[NativeTouchPointer alloc] initWith:touch] forKey:@((uint64_t)touch)];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)removePointerObjFromDict:(UITouch*)touch{
|
||||||
|
uint64_t eventAddrValue = (uint64_t)touch;
|
||||||
|
NativeTouchPointer* pointer = [pointerDict objectForKey:@(eventAddrValue)];
|
||||||
|
if(pointer != nil){
|
||||||
|
[pointerDict removeObjectForKey:@(eventAddrValue)];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)updatePointerObjInDict:(UITouch *)touch{
|
||||||
|
[[pointerDict objectForKey:@((uint64_t)touch)] updatePointerCoords:touch];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (CGPoint)selectCoordsFor:(UITouch *)touch{
|
||||||
|
NativeTouchPointer *pointer = [pointerDict objectForKey:@((uint64_t)touch)];
|
||||||
|
if((pointer -> initialPoint).x > pointerVelocityDividerLocation){ //if first contact coords locates on the right side of divider.
|
||||||
|
return pointer->latestRelativePoint;
|
||||||
|
}
|
||||||
|
return [touch locationInView:streamView];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 随机生成pointerId并填入NSDict和NSSet
|
||||||
|
// generate & populate pointerId into NSDict & NSSet, called in UITouchPhaseBegan
|
||||||
|
+ (void)populatePointerId:(UITouch*)touch{
|
||||||
|
uint64_t eventAddrValue = (uint64_t)touch;
|
||||||
|
uint32_t randomPointerId = arc4random_uniform(UINT32_MAX); // generate pointerId from eletronic noise.
|
||||||
|
for(;;){
|
||||||
|
if([pointerIdSet containsObject:@(randomPointerId)]) randomPointerId = arc4random_uniform(UINT32_MAX); // in case of new pointerId collides with existing ones, generate again.
|
||||||
|
else{ // populate pointerId into NSDict & NSSet.
|
||||||
|
[pointerIdDict setObject:@(randomPointerId) forKey:@(eventAddrValue)];
|
||||||
|
[pointerIdSet addObject:@(randomPointerId)];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// remove pointerId in UITouchPhaseEnded condition
|
||||||
|
+ (void)removePointerId:(UITouch*)touch{
|
||||||
|
uint64_t eventAddrValue = (uint64_t)touch;
|
||||||
|
NSNumber* pointerIdObj = [pointerIdDict objectForKey:@(eventAddrValue)];
|
||||||
|
if(pointerIdObj != nil){
|
||||||
|
[pointerIdSet removeObject:pointerIdObj];
|
||||||
|
[pointerIdDict removeObjectForKey:@(eventAddrValue)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从字典中获取UITouch事件对应的pointerId
|
||||||
|
// call this only when NSDcit & NSSet is up-to-date.
|
||||||
|
+ (uint32_t) retrievePointerIdFromDict:(UITouch*)touch{
|
||||||
|
return [[pointerIdDict objectForKey:@((uint64_t)touch)] unsignedIntValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -28,6 +28,10 @@
|
|||||||
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
|
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
|
||||||
config:(StreamConfiguration*)streamConfig;
|
config:(StreamConfiguration*)streamConfig;
|
||||||
- (void) showOnScreenControls;
|
- (void) showOnScreenControls;
|
||||||
|
- (CGSize) getVideoAreaSize;
|
||||||
|
- (CGPoint) adjustCoordinatesForVideoArea:(CGPoint)point;
|
||||||
|
- (uint16_t)getRotationFromAzimuthAngle:(float)azimuthAngle;
|
||||||
|
|
||||||
- (OnScreenControlsLevel) getCurrentOscState;
|
- (OnScreenControlsLevel) getCurrentOscState;
|
||||||
|
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
#import "ControllerSupport.h"
|
#import "ControllerSupport.h"
|
||||||
#import "KeyboardSupport.h"
|
#import "KeyboardSupport.h"
|
||||||
|
#import "NativeTouchPointer.h"
|
||||||
#import "NativeTouchHandler.h"
|
#import "NativeTouchHandler.h"
|
||||||
#import "RelativeTouchHandler.h"
|
#import "RelativeTouchHandler.h"
|
||||||
#import "AbsoluteTouchHandler.h"
|
#import "AbsoluteTouchHandler.h"
|
||||||
@@ -92,21 +93,24 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
// tvOS requires RelativeTouchHandler to manage Apple Remote input
|
// tvOS requires RelativeTouchHandler to manage Apple Remote input
|
||||||
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self];
|
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self];
|
||||||
#else
|
#else
|
||||||
// iOS uses RelativeTouchHandler or AbsoluteTouchHandler depending on user preference
|
// iOS uses touch Mode depending on user preference
|
||||||
if (settings.absoluteTouchMode) {
|
|
||||||
// self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self];
|
|
||||||
[TouchPointer setPointerVelocityDivider:settings.pointerVelocityModeDivider.floatValue];
|
switch (settings.touchMode.intValue) {
|
||||||
[TouchPointer setPointerVelocityFactor:settings.touchPointerVelocityFactor.floatValue];
|
case NATIVE_TOUCH_MODE:
|
||||||
[TouchPointer initContextWith:self];
|
self->touchHandler = [[NativeTouchHandler alloc] initWith:self and:settings]; break;
|
||||||
}
|
case RELATIVE_TOUCH_MODE:
|
||||||
else {
|
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self]; break;
|
||||||
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self];
|
case ABSOLUTE_TOUCH_MODE:
|
||||||
|
self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self]; break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport streamConfig:streamConfig];
|
onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport streamConfig:streamConfig];
|
||||||
OnScreenControlsLevel level = (OnScreenControlsLevel)[settings.onscreenControls integerValue];
|
OnScreenControlsLevel level = (OnScreenControlsLevel)[settings.onscreenControls integerValue];
|
||||||
if (settings.absoluteTouchMode) {
|
if (settings.touchMode.intValue != RELATIVE_TOUCH_MODE) {
|
||||||
Log(LOG_I, @"On-screen controls disabled in absolute touch mode");
|
Log(LOG_I, @"On-screen controls disabled in non-relative touch mode");
|
||||||
[onScreenControls setLevel:OnScreenControlsLevelOff];
|
[onScreenControls setLevel:OnScreenControlsLevelOff];
|
||||||
}
|
}
|
||||||
else if (level == OnScreenControlsLevelAuto) {
|
else if (level == OnScreenControlsLevelAuto) {
|
||||||
@@ -335,11 +339,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
- (void)sendTouchEvent:(UITouch*)event touchType:(uint8_t)touchType{
|
- (void)sendTouchEvent:(UITouch*)event touchType:(uint8_t)touchType{
|
||||||
CGPoint targetCoords;
|
CGPoint targetCoords;
|
||||||
if(settings.pointerVelocityModeDivider.floatValue != 1.0 && event.phase == UITouchPhaseMoved) targetCoords = [TouchPointer selectCoordsFor:event]; // coordinates of touch pointer replaced to relative ones here.
|
if(settings.pointerVelocityModeDivider.floatValue != 1.0 && event.phase == UITouchPhaseMoved) targetCoords = [NativeTouchPointer selectCoordsFor:event]; // coordinates of touch pointer replaced to relative ones here.
|
||||||
else targetCoords = [event locationInView:self];
|
else targetCoords = [event locationInView:self];
|
||||||
CGPoint location = [self adjustCoordinatesForVideoArea:targetCoords];
|
CGPoint location = [self adjustCoordinatesForVideoArea:targetCoords];
|
||||||
CGSize videoSize = [self getVideoAreaSize];
|
CGSize videoSize = [self getVideoAreaSize];
|
||||||
LiSendTouchEvent(touchType,[TouchPointer retrievePointerIdFromDict:event],location.x / videoSize.width, location.y / videoSize.height,(event.force / event.maximumPossibleForce) / sin(event.altitudeAngle),0.0f, 0.0f,[self getRotationFromAzimuthAngle:[event azimuthAngleInView:self]]);
|
LiSendTouchEvent(touchType,[NativeTouchPointer retrievePointerIdFromDict:event],location.x / videoSize.width, location.y / videoSize.height,(event.force / event.maximumPossibleForce) / sin(event.altitudeAngle),0.0f, 0.0f,[self getRotationFromAzimuthAngle:[event azimuthAngleInView:self]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -369,25 +373,25 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
switch (event.phase) {
|
switch (event.phase) {
|
||||||
case UITouchPhaseBegan://开始触摸
|
case UITouchPhaseBegan://开始触摸
|
||||||
type = LI_TOUCH_EVENT_DOWN;
|
type = LI_TOUCH_EVENT_DOWN;
|
||||||
[TouchPointer populatePointerId:event]; //获取并记录pointerId
|
[NativeTouchPointer populatePointerId:event]; //获取并记录pointerId
|
||||||
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [TouchPointer populatePointerObjIntoDict:event];
|
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [NativeTouchPointer populatePointerObjIntoDict:event];
|
||||||
break;
|
break;
|
||||||
case UITouchPhaseMoved://移动
|
case UITouchPhaseMoved://移动
|
||||||
case UITouchPhaseStationary:
|
case UITouchPhaseStationary:
|
||||||
type = LI_TOUCH_EVENT_MOVE;
|
type = LI_TOUCH_EVENT_MOVE;
|
||||||
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [TouchPointer updatePointerObjInDict:event];
|
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [NativeTouchPointer updatePointerObjInDict:event];
|
||||||
break;
|
break;
|
||||||
case UITouchPhaseEnded://触摸结束
|
case UITouchPhaseEnded://触摸结束
|
||||||
type = LI_TOUCH_EVENT_UP;
|
type = LI_TOUCH_EVENT_UP;
|
||||||
[self sendTouchEvent:event touchType:type]; //先发送,再删除
|
[self sendTouchEvent:event touchType:type]; //先发送,再删除
|
||||||
[TouchPointer removePointerId:event]; //删除pointerId
|
[NativeTouchPointer removePointerId:event]; //删除pointerId
|
||||||
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [TouchPointer removePointerObjFromDict:event];
|
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [NativeTouchPointer removePointerObjFromDict:event];
|
||||||
return;
|
return;
|
||||||
case UITouchPhaseCancelled://触摸取消
|
case UITouchPhaseCancelled://触摸取消
|
||||||
type = LI_TOUCH_EVENT_CANCEL;
|
type = LI_TOUCH_EVENT_CANCEL;
|
||||||
[self sendTouchEvent:event touchType:type]; //先发送,再删除
|
[self sendTouchEvent:event touchType:type]; //先发送,再删除
|
||||||
[TouchPointer removePointerId:event]; //删除pointerId
|
[NativeTouchPointer removePointerId:event]; //删除pointerId
|
||||||
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [TouchPointer removePointerObjFromDict:event];
|
if(settings.pointerVelocityModeDivider.floatValue != 1.0) [NativeTouchPointer removePointerObjFromDict:event];
|
||||||
return;
|
return;
|
||||||
case UITouchPhaseRegionEntered://停留
|
case UITouchPhaseRegionEntered://停留
|
||||||
case UITouchPhaseRegionMoved://停留
|
case UITouchPhaseRegionMoved://停留
|
||||||
@@ -480,29 +484,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
|
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
// NSArray<UITouch*> *arr1 = [[event allTouches] allObjects];
|
if (settings.touchMode.intValue == NATIVE_TOUCH_MODE) {
|
||||||
//// NSLog(@"touchesBegan - %lu",[[event allTouches] count]);
|
[touchHandler touchesBegan:touches withEvent:event];
|
||||||
//// NSLog(@"touchesBegan - %lu",arr1.count);
|
return; //This is a native touch oriented fork, in native touch mode, this call back method deals with native touch only.
|
||||||
//
|
|
||||||
// for(int i=0;i<arr1.count;i++){
|
|
||||||
// if (arr1[i].type == UITouchTypePencil) {
|
|
||||||
// [self sendStylusEvent:arr1[i]];
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// // TemporarySettings* settings = [[[DataManager alloc] init] getSettings];
|
|
||||||
// if (settings.absoluteTouchMode) {
|
|
||||||
// [self handleUITouch:arr1[i] index:i];
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (settings.absoluteTouchMode) {
|
|
||||||
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
for (UITouch* touch in touches) {
|
for (UITouch* touch in touches) {
|
||||||
@@ -511,7 +497,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NSLog(@"touchesBegan - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ([self handleMouseButtonEvent:BUTTON_ACTION_PRESS
|
if ([self handleMouseButtonEvent:BUTTON_ACTION_PRESS
|
||||||
@@ -659,9 +644,9 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
if (settings.absoluteTouchMode) {
|
if (settings.touchMode.intValue == NATIVE_TOUCH_MODE) {
|
||||||
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
[touchHandler touchesMoved:touches withEvent:event];
|
||||||
return;
|
return; //This is a native touch oriented fork, in native touch mode, this call back method deals with native touch only.
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
for (UITouch* touch in touches) {
|
for (UITouch* touch in touches) {
|
||||||
@@ -670,8 +655,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NSLog(@"touchesMoved - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
|
||||||
UITouch *touch = [touches anyObject];
|
UITouch *touch = [touches anyObject];
|
||||||
if (touch.type == UITouchTypeIndirectPointer) {
|
if (touch.type == UITouchTypeIndirectPointer) {
|
||||||
if (@available(iOS 14.0, *)) {
|
if (@available(iOS 14.0, *)) {
|
||||||
@@ -741,9 +724,9 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
if (settings.absoluteTouchMode) {
|
if (settings.touchMode.intValue == NATIVE_TOUCH_MODE) {
|
||||||
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
[touchHandler touchesEnded:touches withEvent:event];
|
||||||
return;
|
return; //This is a native touch oriented fork, in native touch mode, this call back method deals with native touch only.
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
for (UITouch* touch in touches) {
|
for (UITouch* touch in touches) {
|
||||||
@@ -752,7 +735,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NSLog(@"touchesEnded - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ([self handleMouseButtonEvent:BUTTON_ACTION_RELEASE
|
if ([self handleMouseButtonEvent:BUTTON_ACTION_RELEASE
|
||||||
@@ -775,10 +757,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
[touchHandler touchesCancelled:touches withEvent:event];
|
[touchHandler touchesCancelled:touches withEvent:event];
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
if (settings.absoluteTouchMode) {
|
if (settings.touchMode.intValue == NATIVE_TOUCH_MODE) return; //This is a native touch oriented fork, in native touch mode, this call back method deals with native touch only.
|
||||||
for (UITouch* touch in touches) [self handleUITouch:touch index:0];// Native touch (absoluteTouch) first!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else{
|
else{
|
||||||
for (UITouch* touch in touches) {
|
for (UITouch* touch in touches) {
|
||||||
if (touch.type == UITouchTypePencil) {
|
if (touch.type == UITouchTypePencil) {
|
||||||
@@ -787,7 +766,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NSLog(@"touchesCancelled - allTouches %lu, pointerSet count %lu",[[event allTouches] count], [pointerIdSet count]);
|
|
||||||
#endif
|
#endif
|
||||||
[self handleMouseButtonEvent:BUTTON_ACTION_RELEASE
|
[self handleMouseButtonEvent:BUTTON_ACTION_RELEASE
|
||||||
forTouches:touches
|
forTouches:touches
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
|
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
|
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
|
||||||
<attribute name="absoluteTouchMode" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
|
||||||
<attribute name="audioConfig" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="audioConfig" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
@@ -42,6 +41,7 @@
|
|||||||
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
<attribute name="swipeExitScreenEdge" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="swipeExitScreenEdge" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="swipeToExitDistance" optional="YES" attributeType="Float" defaultValueString="0.5" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="swipeToExitDistance" optional="YES" attributeType="Float" defaultValueString="0.5" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="touchMode" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="touchPointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="touchPointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
|
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
|
||||||
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
|||||||
@@ -264,7 +264,8 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
[self.hdrSelector setSelectedSegmentIndex:currentSettings.enableHdr ? 1 : 0];
|
[self.hdrSelector setSelectedSegmentIndex:currentSettings.enableHdr ? 1 : 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self.touchModeSelector setSelectedSegmentIndex:currentSettings.absoluteTouchMode ? 1 : 0];
|
// [self.touchModeSelector setSelectedSegmentIndex:currentSettings.absoluteTouchMode ? 1 : 0];
|
||||||
|
[self.touchModeSelector setSelectedSegmentIndex:currentSettings.touchMode.intValue]; //Load old touchMode setting
|
||||||
[self.touchModeSelector addTarget:self action:@selector(touchModeChanged) forControlEvents:UIControlEventValueChanged];
|
[self.touchModeSelector addTarget:self action:@selector(touchModeChanged) forControlEvents:UIControlEventValueChanged];
|
||||||
[self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlay ? 1 : 0];
|
[self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlay ? 1 : 0];
|
||||||
[self.btMouseSelector setSelectedSegmentIndex:currentSettings.btMouseSupport ? 1 : 0];
|
[self.btMouseSelector setSelectedSegmentIndex:currentSettings.btMouseSupport ? 1 : 0];
|
||||||
@@ -280,7 +281,7 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
||||||
[self.framerateSelector addTarget:self action:@selector(updateBitrate) forControlEvents:UIControlEventValueChanged];
|
[self.framerateSelector addTarget:self action:@selector(updateBitrate) forControlEvents:UIControlEventValueChanged];
|
||||||
[self.onscreenControlSelector setSelectedSegmentIndex:onscreenControls];
|
[self.onscreenControlSelector setSelectedSegmentIndex:onscreenControls];
|
||||||
[self.onscreenControlSelector setEnabled:!currentSettings.absoluteTouchMode];
|
[self.onscreenControlSelector setEnabled:[self.touchModeSelector selectedSegmentIndex] == RELATIVE_TOUCH_MODE];//initialize controller UI widget
|
||||||
[self.bitrateSlider setMinimumValue:0];
|
[self.bitrateSlider setMinimumValue:0];
|
||||||
[self.bitrateSlider setMaximumValue:(sizeof(bitrateTable) / sizeof(*bitrateTable)) - 1];
|
[self.bitrateSlider setMaximumValue:(sizeof(bitrateTable) / sizeof(*bitrateTable)) - 1];
|
||||||
[self.bitrateSlider setValue:[self getSliderValueForBitrate:_bitrate] animated:YES];
|
[self.bitrateSlider setValue:[self getSliderValueForBitrate:_bitrate] animated:YES];
|
||||||
@@ -302,10 +303,13 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
[self.pointerVelocityModeDividerSlider setValue:currentSettings.pointerVelocityModeDivider.floatValue * 100 animated:YES]; // Load old setting.
|
[self.pointerVelocityModeDividerSlider setValue:currentSettings.pointerVelocityModeDivider.floatValue * 100 animated:YES]; // Load old setting.
|
||||||
[self.pointerVelocityModeDividerUILabel setText:[NSString stringWithFormat:@"Touch Pointer Velocity: Scaled on %d%% of Right Screen", 100 - (uint8_t)self.pointerVelocityModeDividerSlider.value]]; // Initiate label display
|
[self.pointerVelocityModeDividerUILabel setText:[NSString stringWithFormat:@"Touch Pointer Velocity: Scaled on %d%% of Right Screen", 100 - (uint8_t)self.pointerVelocityModeDividerSlider.value]]; // Initiate label display
|
||||||
[self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
|
[self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
|
||||||
|
[self.pointerVelocityModeDividerSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == NATIVE_TOUCH_MODE]; // pointer velocity scaling works only in native touch mode.
|
||||||
|
|
||||||
[self.touchPointerVelocityFactorSlider setValue:currentSettings.touchPointerVelocityFactor.floatValue * 100 animated:YES]; // Load old setting.
|
[self.touchPointerVelocityFactorSlider setValue:currentSettings.touchPointerVelocityFactor.floatValue * 100 animated:YES]; // Load old setting.
|
||||||
[self.touchPointerVelocityFactorUILabel setText:[NSString stringWithFormat:@"Touch Pointer Velocity Factor: %d%%", (uint16_t)self.touchPointerVelocityFactorSlider.value]]; // Initiate label display
|
[self.touchPointerVelocityFactorUILabel setText:[NSString stringWithFormat:@"Touch Pointer Velocity Factor: %d%%", (uint16_t)self.touchPointerVelocityFactorSlider.value]]; // Initiate label display
|
||||||
[self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
|
[self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
|
||||||
|
[self.touchPointerVelocityFactorSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == NATIVE_TOUCH_MODE]; // pointer velocity scaling works only in native touch mode.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) pointerVelocityModeDividerSliderMoved {
|
- (void) pointerVelocityModeDividerSliderMoved {
|
||||||
@@ -338,9 +342,9 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
|
|
||||||
- (void) touchModeChanged {
|
- (void) touchModeChanged {
|
||||||
// Disable on-screen controls in absolute touch mode
|
// Disable on-screen controls in absolute touch mode
|
||||||
[self.onscreenControlSelector setEnabled:[self.touchModeSelector selectedSegmentIndex] == 0];
|
[self.onscreenControlSelector setEnabled:[self.touchModeSelector selectedSegmentIndex] == RELATIVE_TOUCH_MODE];
|
||||||
[self.pointerVelocityModeDividerSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == 1]; // pointer velocity scaling works only in native touch mode.
|
[self.pointerVelocityModeDividerSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == NATIVE_TOUCH_MODE]; // pointer velocity scaling works only in native touch mode.
|
||||||
[self.touchPointerVelocityFactorSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == 1]; // pointer velocity scaling works only in native touch mode.
|
[self.touchPointerVelocityFactorSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == NATIVE_TOUCH_MODE]; // pointer velocity scaling works only in native touch mode.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateBitrate {
|
- (void) updateBitrate {
|
||||||
@@ -625,7 +629,8 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
uint32_t preferredCodec = [self getChosenCodecPreference];
|
uint32_t preferredCodec = [self getChosenCodecPreference];
|
||||||
BOOL btMouseSupport = [self.btMouseSelector selectedSegmentIndex] == 1;
|
BOOL btMouseSupport = [self.btMouseSelector selectedSegmentIndex] == 1;
|
||||||
BOOL useFramePacing = [self.framePacingSelector selectedSegmentIndex] == 1;
|
BOOL useFramePacing = [self.framePacingSelector selectedSegmentIndex] == 1;
|
||||||
BOOL absoluteTouchMode = [self.touchModeSelector selectedSegmentIndex] == 1;
|
// BOOL absoluteTouchMode = [self.touchModeSelector selectedSegmentIndex] == 1;
|
||||||
|
NSInteger touchMode = [self.touchModeSelector selectedSegmentIndex];
|
||||||
BOOL statsOverlay = [self.statsOverlaySelector selectedSegmentIndex] == 1;
|
BOOL statsOverlay = [self.statsOverlaySelector selectedSegmentIndex] == 1;
|
||||||
BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1;
|
BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1;
|
||||||
[dataMan saveSettingsWithBitrate:_bitrate
|
[dataMan saveSettingsWithBitrate:_bitrate
|
||||||
@@ -649,7 +654,8 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
useFramePacing:useFramePacing
|
useFramePacing:useFramePacing
|
||||||
enableHdr:enableHdr
|
enableHdr:enableHdr
|
||||||
btMouseSupport:btMouseSupport
|
btMouseSupport:btMouseSupport
|
||||||
absoluteTouchMode:absoluteTouchMode
|
// absoluteTouchMode:absoluteTouchMode
|
||||||
|
touchMode:touchMode
|
||||||
statsOverlay:statsOverlay];
|
statsOverlay:statsOverlay];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,12 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
693B3A9B218638CD00982F7B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 693B3A9A218638CD00982F7B /* Settings.bundle */; };
|
693B3A9B218638CD00982F7B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 693B3A9A218638CD00982F7B /* Settings.bundle */; };
|
||||||
840751AF2BF472A30096B657 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751AE2BF472A30096B657 /* NativeTouchHandler.m */; };
|
|
||||||
840751B02BF472A30096B657 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751AE2BF472A30096B657 /* NativeTouchHandler.m */; };
|
|
||||||
840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
|
840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
|
||||||
840751B42BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
|
840751B42BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
|
||||||
|
843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */; };
|
||||||
|
843CC7F12C1E757D00BBC475 /* NativeTouchPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */; };
|
||||||
|
843CC7F62C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */; };
|
||||||
|
843CC7F72C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */; };
|
||||||
84591A512BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84591A502BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m */; };
|
84591A512BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84591A502BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m */; };
|
||||||
98181BE92791277400E43572 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98181BE82791275D00E43572 /* libSDL2.a */; };
|
98181BE92791277400E43572 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98181BE82791275D00E43572 /* libSDL2.a */; };
|
||||||
98181BEB2791278F00E43572 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98181BEA2791278300E43572 /* libSDL2.a */; };
|
98181BEB2791278F00E43572 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98181BEA2791278300E43572 /* libSDL2.a */; };
|
||||||
@@ -177,10 +179,12 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.7.xcdatamodel"; sourceTree = "<group>"; };
|
566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.7.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
|
693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
|
||||||
840751AD2BF472810096B657 /* NativeTouchHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeTouchHandler.h; sourceTree = "<group>"; };
|
|
||||||
840751AE2BF472A30096B657 /* NativeTouchHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeTouchHandler.m; sourceTree = "<group>"; };
|
|
||||||
840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = "<group>"; };
|
840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = "<group>"; };
|
||||||
840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomTapGestureRecognizer.m; sourceTree = "<group>"; };
|
840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomTapGestureRecognizer.m; sourceTree = "<group>"; };
|
||||||
|
843CC7EE2C1E757D00BBC475 /* NativeTouchPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeTouchPointer.h; sourceTree = "<group>"; };
|
||||||
|
843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeTouchPointer.m; sourceTree = "<group>"; };
|
||||||
|
843CC7F42C1E778000BBC475 /* NativeTouchHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeTouchHandler.h; sourceTree = "<group>"; };
|
||||||
|
843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NativeTouchHandler.m; sourceTree = "<group>"; };
|
||||||
84591A4F2BE16240006AAB10 /* CustomEdgeSwipeGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomEdgeSwipeGestureRecognizer.h; sourceTree = "<group>"; };
|
84591A4F2BE16240006AAB10 /* CustomEdgeSwipeGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomEdgeSwipeGestureRecognizer.h; sourceTree = "<group>"; };
|
||||||
84591A502BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomEdgeSwipeGestureRecognizer.m; sourceTree = "<group>"; };
|
84591A502BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomEdgeSwipeGestureRecognizer.m; sourceTree = "<group>"; };
|
||||||
9803CCAB254F9EAF00EE185E /* ConnectionCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConnectionCallbacks.h; sourceTree = "<group>"; };
|
9803CCAB254F9EAF00EE185E /* ConnectionCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConnectionCallbacks.h; sourceTree = "<group>"; };
|
||||||
@@ -591,12 +595,12 @@
|
|||||||
FB89460919F646E200339C8A /* Input */ = {
|
FB89460919F646E200339C8A /* Input */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
840751AD2BF472810096B657 /* NativeTouchHandler.h */,
|
|
||||||
840751AE2BF472A30096B657 /* NativeTouchHandler.m */,
|
|
||||||
FB89460A19F646E200339C8A /* ControllerSupport.h */,
|
FB89460A19F646E200339C8A /* ControllerSupport.h */,
|
||||||
FB89460B19F646E200339C8A /* ControllerSupport.m */,
|
FB89460B19F646E200339C8A /* ControllerSupport.m */,
|
||||||
FB89460C19F646E200339C8A /* StreamView.h */,
|
FB89460C19F646E200339C8A /* StreamView.h */,
|
||||||
FB89460D19F646E200339C8A /* StreamView.m */,
|
FB89460D19F646E200339C8A /* StreamView.m */,
|
||||||
|
843CC7EE2C1E757D00BBC475 /* NativeTouchPointer.h */,
|
||||||
|
843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */,
|
||||||
FB4678EB1A50C40900377732 /* OnScreenControls.h */,
|
FB4678EB1A50C40900377732 /* OnScreenControls.h */,
|
||||||
FB4678EC1A50C40900377732 /* OnScreenControls.m */,
|
FB4678EC1A50C40900377732 /* OnScreenControls.m */,
|
||||||
FB1A674B2131E65900507771 /* KeyboardSupport.h */,
|
FB1A674B2131E65900507771 /* KeyboardSupport.h */,
|
||||||
@@ -608,6 +612,8 @@
|
|||||||
840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */,
|
840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */,
|
||||||
840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */,
|
840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */,
|
||||||
9819CC12254F107A008A7C8E /* RelativeTouchHandler.h */,
|
9819CC12254F107A008A7C8E /* RelativeTouchHandler.h */,
|
||||||
|
843CC7F42C1E778000BBC475 /* NativeTouchHandler.h */,
|
||||||
|
843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */,
|
||||||
9819CC13254F107A008A7C8E /* RelativeTouchHandler.m */,
|
9819CC13254F107A008A7C8E /* RelativeTouchHandler.m */,
|
||||||
9819CC20254F180F008A7C8E /* AbsoluteTouchHandler.h */,
|
9819CC20254F180F008A7C8E /* AbsoluteTouchHandler.h */,
|
||||||
9819CC21254F180F008A7C8E /* AbsoluteTouchHandler.m */,
|
9819CC21254F180F008A7C8E /* AbsoluteTouchHandler.m */,
|
||||||
@@ -1053,6 +1059,7 @@
|
|||||||
FB1A67C3213245EA00507771 /* AppAssetManager.m in Sources */,
|
FB1A67C3213245EA00507771 /* AppAssetManager.m in Sources */,
|
||||||
FB1A67C5213245EA00507771 /* AppAssetRetriever.m in Sources */,
|
FB1A67C5213245EA00507771 /* AppAssetRetriever.m in Sources */,
|
||||||
FB1A67C7213245EA00507771 /* PairManager.m in Sources */,
|
FB1A67C7213245EA00507771 /* PairManager.m in Sources */,
|
||||||
|
843CC7F12C1E757D00BBC475 /* NativeTouchPointer.m in Sources */,
|
||||||
FB1A67C9213245EA00507771 /* WakeOnLanManager.m in Sources */,
|
FB1A67C9213245EA00507771 /* WakeOnLanManager.m in Sources */,
|
||||||
FB1A67CB213245EA00507771 /* ConnectionHelper.m in Sources */,
|
FB1A67CB213245EA00507771 /* ConnectionHelper.m in Sources */,
|
||||||
FB1A67BD213245E000507771 /* DiscoveryManager.m in Sources */,
|
FB1A67BD213245E000507771 /* DiscoveryManager.m in Sources */,
|
||||||
@@ -1062,6 +1069,7 @@
|
|||||||
FB1A67B1213245D500507771 /* HttpManager.m in Sources */,
|
FB1A67B1213245D500507771 /* HttpManager.m in Sources */,
|
||||||
FB1A67B3213245D500507771 /* HttpRequest.m in Sources */,
|
FB1A67B3213245D500507771 /* HttpRequest.m in Sources */,
|
||||||
FB1A67B5213245D500507771 /* HttpResponse.m in Sources */,
|
FB1A67B5213245D500507771 /* HttpResponse.m in Sources */,
|
||||||
|
843CC7F72C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */,
|
||||||
FB1A67B7213245D500507771 /* ServerInfoResponse.m in Sources */,
|
FB1A67B7213245D500507771 /* ServerInfoResponse.m in Sources */,
|
||||||
FB1A67B9213245D500507771 /* AppAssetResponse.m in Sources */,
|
FB1A67B9213245D500507771 /* AppAssetResponse.m in Sources */,
|
||||||
FB1A67BB213245D500507771 /* AppListResponse.m in Sources */,
|
FB1A67BB213245D500507771 /* AppListResponse.m in Sources */,
|
||||||
@@ -1071,7 +1079,6 @@
|
|||||||
988FCD42293B091B003050E2 /* KeyboardInputField.m in Sources */,
|
988FCD42293B091B003050E2 /* KeyboardInputField.m in Sources */,
|
||||||
FB1A67A3213245BD00507771 /* Connection.m in Sources */,
|
FB1A67A3213245BD00507771 /* Connection.m in Sources */,
|
||||||
FB1A67A5213245BD00507771 /* StreamConfiguration.m in Sources */,
|
FB1A67A5213245BD00507771 /* StreamConfiguration.m in Sources */,
|
||||||
840751B02BF472A30096B657 /* NativeTouchHandler.m in Sources */,
|
|
||||||
FB1A67A7213245BD00507771 /* StreamManager.m in Sources */,
|
FB1A67A7213245BD00507771 /* StreamManager.m in Sources */,
|
||||||
FB1A67A9213245BD00507771 /* VideoDecoderRenderer.m in Sources */,
|
FB1A67A9213245BD00507771 /* VideoDecoderRenderer.m in Sources */,
|
||||||
FB1A67A12132458C00507771 /* main.m in Sources */,
|
FB1A67A12132458C00507771 /* main.m in Sources */,
|
||||||
@@ -1087,7 +1094,7 @@
|
|||||||
9819CC14254F107A008A7C8E /* RelativeTouchHandler.m in Sources */,
|
9819CC14254F107A008A7C8E /* RelativeTouchHandler.m in Sources */,
|
||||||
FB1A674D2131E65900507771 /* KeyboardSupport.m in Sources */,
|
FB1A674D2131E65900507771 /* KeyboardSupport.m in Sources */,
|
||||||
84591A512BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m in Sources */,
|
84591A512BE1625E006AAB10 /* CustomEdgeSwipeGestureRecognizer.m in Sources */,
|
||||||
840751AF2BF472A30096B657 /* NativeTouchHandler.m in Sources */,
|
843CC7F62C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */,
|
||||||
FB89463219F646E200339C8A /* VideoDecoderRenderer.m in Sources */,
|
FB89463219F646E200339C8A /* VideoDecoderRenderer.m in Sources */,
|
||||||
FB290D0419B2C406004C83CF /* AppDelegate.m in Sources */,
|
FB290D0419B2C406004C83CF /* AppDelegate.m in Sources */,
|
||||||
FB9AFD401A7E127D00872C98 /* AppListResponse.m in Sources */,
|
FB9AFD401A7E127D00872C98 /* AppListResponse.m in Sources */,
|
||||||
@@ -1105,6 +1112,7 @@
|
|||||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
|
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
|
||||||
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */,
|
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */,
|
||||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,
|
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,
|
||||||
|
843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */,
|
||||||
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
||||||
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
FB89462D19F646E200339C8A /* MDNSManager.m in Sources */,
|
||||||
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
FB89462B19F646E200339C8A /* StreamView.m in Sources */,
|
||||||
|
|||||||
+2
-1
@@ -153,7 +153,8 @@
|
|||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Touchpad"/>
|
<segment title="Touchpad"/>
|
||||||
<segment title="Native Multi-Point Touch"/>
|
<segment title="Native Multi-Touch"/>
|
||||||
|
<segment title="Absolute Touch"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
|||||||
+2
-1
@@ -155,7 +155,8 @@
|
|||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Touchpad"/>
|
<segment title="Touchpad"/>
|
||||||
<segment title="Native Multi-Point Touch"/>
|
<segment title="Native Multi-Touch"/>
|
||||||
|
<segment title="Absolute Touch"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
|||||||
Reference in new issue
Block a user