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; -@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 -@synthesize squeakHasCursor,squeakCursor; +@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; }
vm-dev@lists.squeakfoundation.org