2016-05-14 11:37:07 +00:00
|
|
|
//
|
|
|
|
// MNVMApplication.m
|
|
|
|
// Mini vMac
|
|
|
|
//
|
|
|
|
// Created by Jesús A. Álvarez on 14/05/2016.
|
2018-04-28 10:12:43 +00:00
|
|
|
// Copyright © 2016-2018 namedfork. All rights reserved.
|
2016-05-14 11:37:07 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#import "MNVMApplication.h"
|
|
|
|
#import "AppDelegate.h"
|
|
|
|
|
|
|
|
@interface UIApplication ()
|
|
|
|
- (void)handleKeyUIEvent:(UIEvent *)event;
|
|
|
|
@end
|
|
|
|
|
|
|
|
Class keyboardEventClass = nil;
|
|
|
|
|
|
|
|
static int8_t usb_to_adb_scancode[] = {
|
|
|
|
-1, -1, -1, -1, 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37,
|
|
|
|
46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, 18, 19,
|
|
|
|
20, 21, 23, 22, 26, 28, 25, 29, 36, 53, 51, 48, 49, 27, 24, 33,
|
|
|
|
30, 42, 42, 41, 39, 10, 43, 47, 44, 57, 122, 120, 99, 118, 96, 97,
|
|
|
|
98, 100, 101, 109, 103, 111, 105, 107, 113, 114, 115, 116, 117, 119, 121, 60,
|
|
|
|
59, 61, 62, 71, 75, 67, 78, 69, 76, 83, 84, 85, 86, 87, 88, 89,
|
|
|
|
91, 92, 82, 65, 50, 55, 126, 81, 105, 107, 113, 106, 64, 79, 80, 90,
|
|
|
|
-1, -1, -1, -1, -1, 114, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74,
|
|
|
|
72, 73, -1, -1, -1, 95, -1, 94, -1, 93, -1, -1, -1, -1, -1, -1,
|
|
|
|
104, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
54, 56, 58, 55, 54, 56, 58, 55, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
|
|
|
};
|
|
|
|
|
|
|
|
@interface UIPhysicalKeyboardEvent : UIPressesEvent
|
|
|
|
|
|
|
|
@property (nonatomic, readonly) BOOL _isKeyDown;
|
|
|
|
@property (nonatomic, readonly) long _keyCode;
|
|
|
|
@property (nonatomic) int _modifierFlags;
|
|
|
|
@property(retain, nonatomic) NSString *_unmodifiedInput;
|
|
|
|
@property(retain, nonatomic) NSString *_modifiedInput;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation MNVMApplication
|
|
|
|
{
|
|
|
|
BOOL physicalCapsLocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (void)load {
|
|
|
|
// class is not visible
|
|
|
|
keyboardEventClass = NSClassFromString(@"UIPhysicalKeyboardEvent");
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)handleKeyboardEvent:(UIPhysicalKeyboardEvent *)event {
|
|
|
|
long keycode = event._keyCode;
|
|
|
|
int scancode = -1;
|
|
|
|
|
|
|
|
if (keycode >= 0 && keycode < sizeof(usb_to_adb_scancode)) {
|
|
|
|
scancode = usb_to_adb_scancode[keycode];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scancode == 57) {
|
|
|
|
// caps lock
|
|
|
|
if (event._isKeyDown && !physicalCapsLocked) {
|
2016-05-28 11:01:13 +00:00
|
|
|
[[AppDelegate sharedEmulator] keyDown:scancode];
|
2016-05-14 11:37:07 +00:00
|
|
|
physicalCapsLocked = YES;
|
|
|
|
} else if (event._isKeyDown && physicalCapsLocked) {
|
2016-05-28 11:01:13 +00:00
|
|
|
[[AppDelegate sharedEmulator] keyUp:scancode];
|
2016-05-14 11:37:07 +00:00
|
|
|
physicalCapsLocked = NO;
|
|
|
|
}
|
2016-05-28 11:01:13 +00:00
|
|
|
} else if (scancode >= 0 && [AppDelegate sharedEmulator].running) {
|
2016-05-14 11:37:07 +00:00
|
|
|
if (event._isKeyDown) {
|
|
|
|
[self _updateCapsLockStatus:event];
|
2016-05-28 11:01:13 +00:00
|
|
|
[[AppDelegate sharedEmulator] keyDown:scancode];
|
2016-05-14 11:37:07 +00:00
|
|
|
} else {
|
2016-05-28 11:01:13 +00:00
|
|
|
[[AppDelegate sharedEmulator] keyUp:scancode];
|
2016-05-14 11:37:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_updateCapsLockStatus:(UIPhysicalKeyboardEvent *)event {
|
2020-04-03 10:35:55 +00:00
|
|
|
if (event._modifierFlags == 0 && event._unmodifiedInput.length == 1 && event._modifiedInput.length == 1) {
|
2016-05-14 11:37:07 +00:00
|
|
|
unichar unmodifiedChar = [event._unmodifiedInput characterAtIndex:0];
|
|
|
|
unichar modifiedChar = [event._modifiedInput characterAtIndex:0];
|
|
|
|
if ([[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:unmodifiedChar]) {
|
|
|
|
BOOL currentCapsLock = [[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:modifiedChar];
|
|
|
|
if (currentCapsLock != physicalCapsLocked) {
|
|
|
|
physicalCapsLocked = currentCapsLock;
|
|
|
|
if (physicalCapsLocked) {
|
2016-05-28 11:01:13 +00:00
|
|
|
[[AppDelegate sharedEmulator] keyDown:57];
|
2016-05-14 11:37:07 +00:00
|
|
|
} else {
|
2016-05-28 11:01:13 +00:00
|
|
|
[[AppDelegate sharedEmulator] keyUp:57];
|
2016-05-14 11:37:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)handleKeyUIEvent:(UIEvent *)event {
|
2016-06-06 18:13:02 +00:00
|
|
|
static dispatch_once_t onceToken;
|
|
|
|
static BOOL handleKeyboardEvents = YES;
|
|
|
|
dispatch_once(&onceToken, ^{
|
|
|
|
if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) {
|
|
|
|
handleKeyboardEvents = [NSProcessInfo processInfo].operatingSystemVersion.majorVersion >= 9;
|
|
|
|
} else {
|
|
|
|
handleKeyboardEvents = NO;
|
|
|
|
}
|
|
|
|
});
|
2016-06-06 18:57:09 +00:00
|
|
|
BOOL emulatorIsFrontmost = [AppDelegate sharedEmulator].running && [AppDelegate sharedInstance].window.rootViewController.presentedViewController == nil;
|
|
|
|
if ([event isKindOfClass:keyboardEventClass] && handleKeyboardEvents && emulatorIsFrontmost) {
|
2016-05-14 11:37:07 +00:00
|
|
|
[self handleKeyboardEvent:(UIPhysicalKeyboardEvent*)event];
|
2023-02-01 17:11:49 +00:00
|
|
|
} else {
|
|
|
|
[super handleKeyUIEvent:event];
|
2016-05-14 11:37:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|