[Vm-dev] [commit][3536] JMM add bluetooth keyboard support to iOS tree.

commits at squeakvm.org commits at squeakvm.org
Tue Dec 15 22:07:04 UTC 2015


Revision: 3536
Author:   johnmci
Date:     2015-12-15 14:07:02 -0800 (Tue, 15 Dec 2015)
Log Message:
-----------
JMM add bluetooth keyboard support to iOS tree. Poke at  Cursor logic to understand bug why cursor is white box

Modified Paths:
--------------
    branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+cursor.m
    branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h
    branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m
    branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIController.m
    branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.h
    branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.m

Modified: branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+cursor.m
===================================================================
--- branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+cursor.m	2015-12-15 21:29:51 UTC (rev 3535)
+++ branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+cursor.m	2015-12-15 22:07:02 UTC (rev 3536)
@@ -98,8 +98,7 @@
 	
 	
 	NSPoint hotSpot= { -offsetX, -offsetY };
-	self.squeakCursor = nil;
-	squeakCursor = [[NSCursor alloc] initWithImage: image hotSpot: hotSpot];
+	self.squeakCursor = AUTORELEASEOBJ([[NSCursor alloc] initWithImage: image hotSpot: hotSpot]);
 
 /*	if (browserActiveAndDrawingContextOkAndNOTInFullScreenMode())
 		browserSetCursor(&macCursor);
@@ -108,10 +107,13 @@
 	
 	
 	if (!gSqueakHeadless || browserActiveAndDrawingContextOkAndInFullScreenMode()) {
-		self.squeakHasCursor = YES;
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [self.squeakCursor set];
-        });
+            if ([NSThread isMainThread]) {
+                [self.squeakCursor set];
+            } else {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [self.squeakCursor set];
+                });
+            }
 	}
 	}
 }
@@ -147,13 +149,15 @@
 	NSImage  *image= AUTORELEASEOBJ([[NSImage alloc] init]);
 	[image addRepresentation: bitmap];
 	NSPoint hotSpot= { -offsetX, -offsetY };
-	self.squeakHasCursor = YES;
-	self.squeakCursor = nil;
-	squeakCursor= [[NSCursor alloc] initWithImage: image hotSpot: hotSpot];
-        dispatch_async(dispatch_get_main_queue(), ^{
+	self.squeakCursor = AUTORELEASEOBJ([[NSCursor alloc] initWithImage: image hotSpot: hotSpot]);
+    if ([NSThread isMainThread]) {
             [self.squeakCursor set];
-        });
-	}
+    } else {
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self.squeakCursor set];
+            });
+    }
+    }
 	return 1;
 }
 @end

Modified: branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h
===================================================================
--- branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h	2015-12-15 21:29:51 UTC (rev 3535)
+++ branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h	2015-12-15 22:07:02 UTC (rev 3536)
@@ -42,10 +42,8 @@
 
 @interface sqSqueakOSXApplication : sqSqueakMainApplication {
 	NSCursor         *squeakCursor;
-	BOOL			squeakHasCursor;
 }
 @property (nonatomic,strong) NSCursor	*squeakCursor;
- at property (nonatomic,assign) BOOL		squeakHasCursor;
 
 - (NSInteger) parseArgument: (NSString *) argData peek: (char *) peek;
 - (void) parseArgs: (NSArray *) args;

Modified: branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m
===================================================================
--- branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m	2015-12-15 21:29:51 UTC (rev 3535)
+++ branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m	2015-12-15 22:07:02 UTC (rev 3536)
@@ -88,7 +88,7 @@
 static char *getVersionInfo(int verbose);
 
 @implementation sqSqueakOSXApplication 
- at synthesize squeakHasCursor,squeakCursor;
+ at synthesize squeakCursor;
 
 - (void) setupFloat {
 	fldcw(0x12bf);	/* signed infinity, round to nearest, REAL8, disable intrs, disable signals */

Modified: branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIController.m
===================================================================
--- branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIController.m	2015-12-15 21:29:51 UTC (rev 3535)
+++ branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIController.m	2015-12-15 22:07:02 UTC (rev 3536)
@@ -46,7 +46,49 @@
 static	sqWindowEvent evt;
 
 @implementation SqueakUIController
-// Subclasses override this method to define how the view they control will respond to device rotation 
+
+- (void)viewDidLoad {
+    // jdr - extra bluetooth keyboard support
+    for (SInt32 k=97; k<=123; k++) {
+        char ch[] = {k, 0};
+        if (k==123) {
+            ch[0] = 46; // for cmd-.
+        }
+        
+        NSString *key = [NSString stringWithCString:(const char *)&ch encoding:NSASCIIStringEncoding];
+        UIKeyCommand *command = [UIKeyCommand keyCommandWithInput:key
+                                                    modifierFlags:UIKeyModifierCommand
+                                                           action:@selector(handleShortcutCmd:)];
+        [self addKeyCommand: command];
+        
+        if (k < 123) {
+            UIKeyCommand *command2 = [UIKeyCommand keyCommandWithInput:key
+                                                    modifierFlags:UIKeyModifierCommand+UIKeyModifierShift
+                                                           action:@selector(handleShortcutShiftCmd:)];
+            [self addKeyCommand: command2];
+
+            UIKeyCommand *command3 = [UIKeyCommand keyCommandWithInput:key
+                                                    modifierFlags:UIKeyModifierControl
+                                                           action:@selector(handleShortcutCtrl:)];
+            [self addKeyCommand: command3];
+        }
+    }
+    
+    NSArray *arrows = @[UIKeyInputUpArrow, UIKeyInputDownArrow, UIKeyInputLeftArrow, UIKeyInputRightArrow];
+    
+    for (NSString *k in arrows) {
+        UIKeyCommand *command = [UIKeyCommand keyCommandWithInput:k
+                                                    modifierFlags:0
+                                                           action:@selector(handleArrows:)];
+        [self addKeyCommand: command];
+        UIKeyCommand *command2 = [UIKeyCommand keyCommandWithInput:k
+                                                    modifierFlags:UIKeyModifierCommand
+                                                           action:@selector(handleCmdArrows:)];
+        [self addKeyCommand: command2];
+    }
+}
+
+// Subclasses override this method to define how the view they control will respond to device rotation
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 	//Called by Main Thread, beware of calling Squeak routines in Squeak Thread
 	

Modified: branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.h
===================================================================
--- branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.h	2015-12-15 21:29:51 UTC (rev 3535)
+++ branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.h	2015-12-15 22:07:02 UTC (rev 3536)
@@ -54,4 +54,5 @@
 	- (void) drawThelayers;
 	- (void) drawImageUsingClip: (CGRect) clip;
 	@property (nonatomic,assign) void *squeakTheDisplayBits;
+    @property (nonatomic,strong) NSArray *arrowsNames;  // jdr
 @end

Modified: branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.m
===================================================================
--- branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.m	2015-12-15 21:29:51 UTC (rev 3535)
+++ branches/Cog/platforms/iOS/vm/iPhone/Classes/SqueakUIView.m	2015-12-15 22:07:02 UTC (rev 3536)
@@ -45,6 +45,7 @@
 
 extern struct	VirtualMachine* interpreterProxy;
 extern SqueakNoOGLIPhoneAppDelegate *gDelegateApp;
+SInt32 undoCounter=1, oldValue=0;  // jdr undo support
 
 @implementation SqueakUIView : UIView ;
 @synthesize squeakTheDisplayBits;
@@ -53,6 +54,13 @@
 	self = [super initWithFrame: aFrame];
 	self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
 	colorspace = CGColorSpaceCreateDeviceRGB();
+    
+    // jdr - hack cmd-z undo support
+    self.arrowsNames = @[UIKeyInputLeftArrow, UIKeyInputRightArrow, UIKeyInputUpArrow, UIKeyInputDownArrow];
+    
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [self setUndoFlag: undoCounter];
+    });
 	return self;
 }
 
@@ -97,6 +105,124 @@
 	return YES;
 }
 
+// jdr - extra bluetooth keyboard support
+
+- (void)sendCharCode: (sqInt) charCode pressCode: (sqInt) pressCode mod: (sqInt) mod uni: (sqInt) u  {
+    sqKeyboardEvent evt;
+    evt.type = EventTypeKeyboard;
+    evt.timeStamp = (int) ioMSecs();
+    evt.pressCode = pressCode;
+    evt.modifiers = mod;
+    evt.charCode = charCode;
+    evt.utf32Code = u;
+    evt.reserved1 = 0;
+    evt.windowIndex = 1;
+    [self pushEventToQueue: (sqInputEvent *)&evt];
+}
+
+- (void)sendTriplet:(sqInt)u mod: (sqInt)mod{
+    sqInt cc = [self figureOutKeyCode: u];
+    [self sendCharCode: cc pressCode: EventKeyDown mod: mod  uni: 0];
+    [self sendCharCode: u pressCode: EventKeyChar mod: mod uni: u];
+    [self sendCharCode: cc pressCode: EventKeyUp mod: mod uni: 0];
+}
+
+- (void)sendCmdTriplet:(sqInt)u {
+    [self sendTriplet: u mod: CommandKeyBit];
+}
+
+- (void)sendShiftCmdTriplet:(sqInt)u {
+    [self sendTriplet: u mod: CommandKeyBit | ShiftKeyBit];
+}
+
+- (void)sendCtrlTriplet:(sqInt)u {
+    [self sendTriplet: u mod: CtrlKeyBit];
+}
+
+- (void)handleShortcutCmd:(UIKeyCommand *)keyCommand {
+    NSString *input = [keyCommand input];
+    sqInt u = (sqInt)[input characterAtIndex:0];
+    [self sendCmdTriplet: u];
+}
+
+- (void)handleShortcutShiftCmd:(UIKeyCommand *)keyCommand {
+    NSString *input = [keyCommand input];
+    sqInt u = (sqInt)[input characterAtIndex:0]-32; // upper case
+    [self sendShiftCmdTriplet: u];
+}
+
+- (void)handleShortcutCtrl:(UIKeyCommand *)keyCommand {
+    NSString *input = [keyCommand input];
+    sqInt u = (sqInt)[input characterAtIndex:0]-96; // convert to ctrl character
+    [self sendCtrlTriplet: u];
+}
+
+- (void)handleArrows:(UIKeyCommand *)keyCommand {
+    sqInt u = (sqInt)[self.arrowsNames indexOfObject: [keyCommand input]];
+    [self sendTriplet: u+28 mod:0]; // fs gs rs us
+}
+
+- (void)handleCmdArrows:(UIKeyCommand *)keyCommand {
+    sqInt u = (sqInt)[self.arrowsNames indexOfObject: [keyCommand input]];
+    [self sendTriplet: u+28 mod:CommandKeyBit];
+}
+
+- (void)cut:(id)sender {
+    [self sendCmdTriplet: 'x'];
+}
+
+- (void)copy:(id)sender {
+    [self sendCmdTriplet: 'c'];
+}
+
+- (void)paste:(id)sender {
+    [self sendCmdTriplet: 'v'];
+}
+
+- (void)selectAll:(id)sender {
+    [self sendCmdTriplet: 'a'];
+}
+
+- (void)toggleItalics:(id)sender {
+    [self sendCmdTriplet: 'i']; // inspect
+}
+
+- (void)toggleBoldface:(id)sender {
+    [self sendCmdTriplet: 'b']; // browse
+}
+
+- (void)toggleUnderline:(id)sender {
+    [self sendCmdTriplet: 'u']; // align
+}
+
+// hack to use cmd-z
+- (void)setUndoFlag:(int)newValue {
+//    printf("%i %i\n", oldValue, newValue);
+    if (newValue == oldValue) { // undo
+        [self sendCmdTriplet: 'z'];
+        undoCounter++;
+        oldValue=undoCounter-1;
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self setUndoFlag: undoCounter];
+        });
+
+    }
+    else {
+        [[self.undoManager prepareWithInvocationTarget:self] setUndoFlag: oldValue];
+    }
+}
+
+// extra - shake generate a Cmd-.
+- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
+    if (motion == UIEventSubtypeMotionShake)
+    {
+        // User was shaking the device.
+        [self sendCharCode: 46 pressCode: EventKeyChar mod: CommandKeyBit uni: 0];
+    }
+}
+
+// =====================================
+
 - (BOOL)hasText {
 	return YES;
 }



More information about the Vm-dev mailing list