~drgeo-developers/drgeo/trunk

« back to all changes in this revision

Viewing changes to VMs/iPad/source/iOS/vm/OSX/sqSqueakOSXNSView.m

  • Committer: Hilaire Fernandes
  • Date: 2012-01-27 21:15:40 UTC
  • Revision ID: hilaire.fernandes@gmail.com-20120127211540-912spf97bhpx6mve
Initial additions

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
//  sqSqueakOSXNSView.m
 
3
//  SqueakPureObjc
 
4
//
 
5
//  Created by John M McIntosh on 09-11-14.
 
6
//  Some code sqUnixQuartz.m -- display via native windows on Mac OS X  -*- ObjC -*-
 
7
//  Author: Ian Piumarta <ian.piumarta@squeakland.org>
 
8
/*
 
9
 Some of this code was funded via a grant from the European Smalltalk User Group (ESUG)
 
10
 Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
 
11
 MIT License
 
12
 Permission is hereby granted, free of charge, to any person
 
13
 obtaining a copy of this software and associated documentation
 
14
 files (the "Software"), to deal in the Software without
 
15
 restriction, including without limitation the rights to use,
 
16
 copy, modify, merge, publish, distribute, sublicense, and/or sell
 
17
 copies of the Software, and to permit persons to whom the
 
18
 Software is furnished to do so, subject to the following
 
19
 conditions:
 
20
 
 
21
 The above copyright notice and this permission notice shall be
 
22
 included in all copies or substantial portions of the Software.
 
23
 
 
24
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
25
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 
26
 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
27
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 
28
 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
29
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
30
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
31
 OTHER DEALINGS IN THE SOFTWARE.
 
32
 
 
33
 The end-user documentation included with the redistribution, if any, must include the following acknowledgment: 
 
34
 "This product includes software developed by Corporate Smalltalk Consulting Ltd (http://www.smalltalkconsulting.com) 
 
35
 and its contributors", in the same place and form as other third-party acknowledgments. 
 
36
 Alternately, this acknowledgment may appear in the software itself, in the same form and location as other 
 
37
 such third-party acknowledgments.
 
38
 */
 
39
//
 
40
#import <QuartzCore/QuartzCore.h>
 
41
 
 
42
#import "sqSqueakOSXNSView.h"
 
43
#import "sqSqueakOSXScreenAndWindow.h"
 
44
#import "SqueakOSXAppDelegate.h"
 
45
#import "sqSqueakOSXApplication+events.h"
 
46
#import "sqSqueakOSXInfoPlistInterface.h"
 
47
#import "sq.h"
 
48
#import "sqVirtualMachine.h"
 
49
 
 
50
//#import <OpenGL/CGLMacro.h>
 
51
 
 
52
extern SqueakOSXAppDelegate *gDelegateApp;
 
53
extern struct   VirtualMachine* interpreterProxy;
 
54
 
 
55
static NSString *stringWithCharacter(unichar character) {
 
56
        return [NSString stringWithCharacters: &character length: 1];
 
57
}
 
58
 
 
59
@implementation sqSqueakOSXNSView
 
60
@synthesize squeakTrackingRectForCursor,lastSeenKeyBoardStrokeDetails,
 
61
lastSeenKeyBoardModifierDetails,dragInProgress,dragCount,dragItems,windowLogic,savedScreenBoundsAtTimeOfFullScreen;
 
62
 
 
63
+ (NSOpenGLPixelFormat *)defaultPixelFormat {
 
64
        NSOpenGLPixelFormatAttribute attrs[] =
 
65
    {
 
66
                NSOpenGLPFAAccelerated,
 
67
                NSOpenGLPFANoRecovery,
 
68
                NSOpenGLPFABackingStore,
 
69
                0
 
70
    };
 
71
    return[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
 
72
}
 
73
 
 
74
- (void)awakeFromNib {
 
75
        self = [self initWithFrame: self.frame pixelFormat: [[self class] defaultPixelFormat] ];
 
76
        inputMark = NSMakeRange(NSNotFound, 0);
 
77
        inputSelection = NSMakeRange(0, 0);
 
78
    [self registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
 
79
        //      NSLog(@"registerForDraggedTypes");
 
80
        dragInProgress = NO;
 
81
        dragCount = 0;
 
82
        dragItems = NULL;
 
83
        clippyIsEmpty = YES;
 
84
        colorspace = CGColorSpaceCreateDeviceRGB();
 
85
        [self initializeSqueakColorMap];
 
86
}
 
87
 
 
88
- (void) initializeVariables {
 
89
}
 
90
 
 
91
- (void) dealloc {
 
92
    [super dealloc];
 
93
        free(colorMap32);
 
94
        CGColorSpaceRelease(colorspace);
 
95
}
 
96
 
 
97
- (BOOL) acceptsFirstResponder {
 
98
        return YES;
 
99
}
 
100
 
 
101
- (BOOL)isFlipped {
 
102
        return  YES;
 
103
}
 
104
 
 
105
- (BOOL)isOpaque {
 
106
        return YES;
 
107
}
 
108
 
 
109
- (void)viewDidMoveToWindow {
 
110
        if (self.squeakTrackingRectForCursor)
 
111
                [self removeTrackingRect: self.squeakTrackingRectForCursor];
 
112
        
 
113
        self.squeakTrackingRectForCursor = [self addTrackingRect: [self bounds] owner: self userData:NULL assumeInside: NO];
 
114
}
 
115
 
 
116
- (void) updateTrackingAreas {
 
117
        [super updateTrackingAreas];
 
118
        [self removeTrackingRect: self.squeakTrackingRectForCursor];
 
119
        self.squeakTrackingRectForCursor = [self addTrackingRect: [self bounds] owner: self userData:NULL assumeInside: NO];
 
120
}
 
121
 
 
122
- (void) viewWillStartLiveResize {
 
123
//      [self.window setShowsResizeIndicator: YES];
 
124
        [[NSCursor arrowCursor] set];
 
125
}
 
126
 
 
127
- (void) viewDidEndLiveResize {
 
128
//      [self.window setShowsResizeIndicator: NO];
 
129
        [((sqSqueakOSXApplication*) gDelegateApp.squeakApplication).squeakCursor performSelectorOnMainThread: @selector(set) withObject: nil waitUntilDone: NO];        
 
130
}
 
131
 
 
132
- (void) drawImageUsingClip: (CGRect) clip {
 
133
        
 
134
        if (clippyIsEmpty){
 
135
                clippy = clip;
 
136
                clippyIsEmpty = NO;
 
137
        } else {
 
138
                clippy = CGRectUnion(clippy, clip);
 
139
        }
 
140
        syncNeeded = YES;
 
141
}
 
142
 
 
143
- (void) drawThelayers {
 
144
        if (syncNeeded) { 
 
145
                [self drawRect: NSRectFromCGRect(clippy)];
 
146
                syncNeeded = NO;
 
147
                clippyIsEmpty = YES;
 
148
//              CGL_MACRO_DECLARE_VARIABLES();
 
149
                glFlush();
 
150
                [[self openGLContext] flushBuffer];  
 
151
        }
 
152
        if (!firstDrawCompleted) {
 
153
                firstDrawCompleted = YES;
 
154
                if (getFullScreenFlag() == 0)
 
155
                        [self.window makeKeyAndOrderFront: self];
 
156
        }
 
157
}
 
158
 
 
159
-(void)setupOpenGL {    
 
160
//      CGL_MACRO_DECLARE_VARIABLES();
 
161
// Enable the multithreading
 
162
        CGLContextObj ctx = [[self openGLContext] CGLContextObj];
 
163
        CGLEnable( ctx, kCGLCEMPEngine);
 
164
 
 
165
//      GLint newSwapInterval = 1;
 
166
//      CGLSetParameter(cgl_ctx, kCGLCPSwapInterval, &newSwapInterval);
 
167
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
168
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
169
        glClearColor(1.0, 1.0, 1.0, 1.0);
 
170
        glColor4f(1.0, 1.0, 1.0, 1.0);
 
171
        
 
172
        glDisable(GL_DITHER);
 
173
        glDisable(GL_ALPHA_TEST);
 
174
        glDisable(GL_BLEND);
 
175
        glDisable(GL_STENCIL_TEST);
 
176
        glDisable(GL_FOG);
 
177
        glDisable(GL_TEXTURE_2D);
 
178
        glDisable(GL_DEPTH_TEST);
 
179
        glDisable (GL_SCISSOR_TEST);
 
180
    glDisable (GL_CULL_FACE);
 
181
        glStencilMask(0);
 
182
        glPixelZoom(1.0,1.0);
 
183
        
 
184
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
 
185
        glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_PRIORITY, 0.0);
 
186
        glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
 
187
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);
 
188
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
189
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
190
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
191
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
192
        glPixelStorei( GL_UNPACK_ROW_LENGTH, self.frame.size.width );
 
193
        GLuint dt = 1;
 
194
        glDeleteTextures(1, &dt);
 
195
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 1);
 
196
        syncNeeded = NO;
 
197
}
 
198
 
 
199
- (void)loadTexturesFrom: (void*) lastBitsIndex subRectangle: (NSRect) subRect { 
 
200
//      CGL_MACRO_DECLARE_VARIABLES();
 
201
        static void *previousLastBitsIndex=null;
 
202
        NSRect r=[self frame];
 
203
        if (!(previousLastBitsIndex == lastBitsIndex)) {
 
204
                previousLastBitsIndex = lastBitsIndex;
 
205
                glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_ARB, r.size.width*r.size.height*4,lastBitsIndex);              
 
206
        }
 
207
                
 
208
        glViewport( subRect.origin.x,subRect.origin.y, subRect.size.width,subRect.size.height );
 
209
        char *subimg = ((char*)lastBitsIndex) + (unsigned int)(subRect.origin.x + (r.size.height-subRect.origin.y-subRect.size.height)*r.size.width)*4;
 
210
        glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, subRect.size.width, subRect.size.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, subimg );
 
211
        //      NSLog(@" draw %f %f %f %f",subRect.origin.x,subRect.origin.y,subRect.size.width,subRect.size.height);   
 
212
}
 
213
 
 
214
-(void)defineQuad:(NSRect)r
 
215
{
 
216
 
 
217
//      CGL_MACRO_DECLARE_VARIABLES();
 
218
         glBegin(GL_QUADS);
 
219
         glTexCoord2f(0.0f, 0.0f);                                      glVertex2f(-1.0f, 1.0f);
 
220
         glTexCoord2f(0.0f, r.size.height);                     glVertex2f(-1.0f, -1.0f);
 
221
         glTexCoord2f(r.size.width, r.size.height);  glVertex2f(1.0f, -1.0f);
 
222
         glTexCoord2f(r.size.width, 0.0f);                      glVertex2f(1.0f, 1.0f);
 
223
         glEnd();
 
224
}
 
225
 
 
226
- (void)update  // moved or resized
 
227
{
 
228
        NSRect rect;
 
229
        
 
230
        [super update];
 
231
        
 
232
        [[self openGLContext] makeCurrentContext];
 
233
//      CGL_MACRO_DECLARE_VARIABLES();
 
234
        [[self openGLContext] update];
 
235
        
 
236
        rect = [self bounds];
 
237
        
 
238
    glViewport(0, 0, (int) rect.size.width, (int) rect.size.height);
 
239
        glPixelStorei( GL_UNPACK_ROW_LENGTH, rect.size.width );
 
240
        
 
241
        glMatrixMode(GL_PROJECTION);
 
242
    glLoadIdentity();
 
243
        
 
244
        glMatrixMode(GL_MODELVIEW);
 
245
    glLoadIdentity(); 
 
246
        
 
247
        [self setNeedsDisplay:true];
 
248
}
 
249
 
 
250
- (void)reshape // scrolled, moved or resized
 
251
{
 
252
        NSRect rect;
 
253
        
 
254
        [super reshape];
 
255
        
 
256
        [[self openGLContext] makeCurrentContext];
 
257
//      CGL_MACRO_DECLARE_VARIABLES();
 
258
        [[self openGLContext] update];
 
259
        
 
260
        rect = [self bounds];
 
261
        
 
262
        glViewport(0, 0, (int) rect.size.width, (int) rect.size.height);
 
263
        glPixelStorei( GL_UNPACK_ROW_LENGTH, rect.size.width );
 
264
        glMatrixMode(GL_PROJECTION);
 
265
    glLoadIdentity();
 
266
        
 
267
        glMatrixMode(GL_MODELVIEW);
 
268
    glLoadIdentity();
 
269
        
 
270
        [self setNeedsDisplay:true];
 
271
}
 
272
 
 
273
-(void)drawRect:(NSRect)rect
 
274
{
 
275
//      NSLog(@" draw %f %f %f %f",rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
 
276
        sqInt formObj = interpreterProxy->displayObject();
 
277
        sqInt formPtrOop = interpreterProxy->fetchPointerofObject(0, formObj);  
 
278
        void* dispBitsIndex = interpreterProxy->firstIndexableField(formPtrOop);
 
279
    static int inited=NO;
 
280
    if ( dispBitsIndex ) {
 
281
                [[self openGLContext] makeCurrentContext];
 
282
                if (!inited) {
 
283
                        [self setupOpenGL];
 
284
                        inited=YES;
 
285
                }
 
286
                [self loadTexturesFrom:dispBitsIndex subRectangle: rect];
 
287
                [self defineQuad:rect];
 
288
  }
 
289
}
 
290
 
 
291
- (void)mouseEntered:(NSEvent *)theEvent {
 
292
        [((sqSqueakOSXApplication*) gDelegateApp.squeakApplication).squeakCursor set];
 
293
}
 
294
 
 
295
- (void)mouseExited:(NSEvent *)theEvent {
 
296
        [[NSCursor arrowCursor] set];
 
297
}
 
298
 
 
299
- (void)mouseMoved:(NSEvent *)theEvent {
 
300
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
301
}
 
302
 
 
303
- (void)mouseDragged:(NSEvent *)theEvent {
 
304
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
305
}
 
306
 
 
307
- (void)rightMouseDragged:(NSEvent *)theEvent {
 
308
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
309
}
 
310
 
 
311
- (void)otherMouseDragged:(NSEvent *)theEvent {
 
312
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
313
}
 
314
 
 
315
- (void)scrollWheel:(NSEvent *)theEvent {
 
316
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordWheelEvent: theEvent fromView: self];
 
317
}
 
318
 
 
319
- (void)mouseUp:(NSEvent *)theEvent {
 
320
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
321
}
 
322
 
 
323
- (void)rightMouseUp:(NSEvent *)theEvent {
 
324
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
325
}
 
326
 
 
327
- (void)otherMouseUp:(NSEvent *)theEvent {
 
328
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
329
}
 
330
 
 
331
- (void)mouseDown:(NSEvent *)theEvent {
 
332
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
333
}
 
334
 
 
335
- (void)rightMouseDown:(NSEvent *)theEvent {
 
336
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
337
}
 
338
- (void)otherMouseDown:(NSEvent *)theEvent {
 
339
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
 
340
}
 
341
 
 
342
- (NSString *) dealWithOpenStepChars: (NSString *) openStep {
 
343
        
 
344
        unichar keyChar; 
 
345
        static unichar combiningHelpChar[] = {0x003F, 0x20DD};
 
346
        
 
347
        keyChar = [openStep characterAtIndex: 0]; 
 
348
        
 
349
//http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/KEYBOARD.TXT
 
350
        
 
351
        switch (keyChar) { 
 
352
                case NSUpArrowFunctionKey: keyChar = 30; break; 
 
353
                case NSDownArrowFunctionKey: keyChar = 31; break; 
 
354
                case NSLeftArrowFunctionKey: keyChar = 28; break; 
 
355
                case NSRightArrowFunctionKey: keyChar = 29; break; 
 
356
                case NSInsertFunctionKey: 
 
357
                        return [NSString stringWithCharacters: combiningHelpChar length: 2];
 
358
                case NSDeleteFunctionKey: keyChar = 0x2326; break; 
 
359
                case NSHomeFunctionKey: keyChar = 1; break; 
 
360
                case NSEndFunctionKey: keyChar = 4; break;
 
361
                case NSPageUpFunctionKey: 
 
362
                        keyChar = 0x21DE; break;
 
363
                case NSPageDownFunctionKey: 
 
364
                        keyChar = 0x21DF; break;
 
365
                case NSClearLineFunctionKey: keyChar = 0x2327; break;
 
366
                case 127: keyChar = 8; break;
 
367
                default: 
 
368
                        if (keyChar >= NSF1FunctionKey && keyChar <= NSF35FunctionKey) { 
 
369
                                keyChar = 0; 
 
370
                        }
 
371
        }
 
372
        return stringWithCharacter(keyChar);
 
373
}
 
374
 
 
375
 
 
376
-(void)  fakeKeyDownUp: (NSEvent*) theEvent {
 
377
        
 
378
        //http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/CORPCHAR.TXT
 
379
        //http://www.internet4classrooms.com/mac_ext.gif
 
380
        //http://developer.apple.com/legacy/mac/library/documentation/mac/Text/Text-571.html
 
381
        
 
382
        keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
 
383
        aKeyBoardStrokeDetails.keyCode = [theEvent keyCode];
 
384
        aKeyBoardStrokeDetails.modifierFlags = [theEvent modifierFlags];
 
385
        
 
386
        NSArray *down = [[NSArray alloc] initWithObjects: theEvent,nil];
 
387
        @synchronized(self) {
 
388
                lastSeenKeyBoardStrokeDetails = aKeyBoardStrokeDetails;
 
389
                NSString *possibleConversion = [theEvent characters];
 
390
                
 
391
                if ([possibleConversion length] > 0) {
 
392
                        NSString *c = [self dealWithOpenStepChars: possibleConversion];
 
393
                        [self insertText: c replacementRange: NSMakeRange(NSNotFound, 0)];
 
394
                }
 
395
                self.lastSeenKeyBoardStrokeDetails = NULL;
 
396
                [self keyUp: theEvent]; 
 
397
        }
 
398
        [down release];
 
399
}
 
400
 
 
401
-(void)keyDown:(NSEvent*)theEvent {
 
402
        keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
 
403
        aKeyBoardStrokeDetails.keyCode = [theEvent keyCode];
 
404
        aKeyBoardStrokeDetails.modifierFlags = [theEvent modifierFlags];
 
405
        
 
406
        NSArray *down = [[NSArray alloc] initWithObjects: theEvent,nil];
 
407
        @synchronized(self) {
 
408
                lastSeenKeyBoardStrokeDetails = aKeyBoardStrokeDetails;
 
409
                [self interpretKeyEvents: down];
 
410
                self.lastSeenKeyBoardStrokeDetails = NULL;
 
411
        }
 
412
        [down release];
 
413
}
 
414
 
 
415
-(void)keyUp:(NSEvent*)theEvent {
 
416
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordKeyUpEvent: theEvent fromView: self];
 
417
}
 
418
 
 
419
/* 10.5 seems only to call insertText:, but 10.6 calls insertText:replacementRange: */
 
420
 
 
421
- (void)insertText:(id)aString
 
422
{
 
423
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordCharEvent: aString fromView: self];
 
424
}
 
425
 
 
426
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
 
427
{
 
428
        [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordCharEvent: aString fromView: self];
 
429
}
 
430
 
 
431
- (void)flagsChanged:(NSEvent *)theEvent {
 
432
        keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
 
433
        aKeyBoardStrokeDetails.keyCode = [theEvent keyCode];
 
434
        aKeyBoardStrokeDetails.modifierFlags = [theEvent modifierFlags];
 
435
        self.lastSeenKeyBoardModifierDetails = aKeyBoardStrokeDetails;
 
436
        [aKeyBoardStrokeDetails release];
 
437
}
 
438
 
 
439
- (void)doCommandBySelector:(SEL)aSelector {
 
440
        unichar unicode;
 
441
        unsigned short keyCode;
 
442
        NSString *unicodeString;
 
443
        BOOL isFunctionKey = NO;
 
444
        
 
445
        if (self.lastSeenKeyBoardModifierDetails) {
 
446
                isFunctionKey = (self.lastSeenKeyBoardModifierDetails.modifierFlags & NSFunctionKeyMask) == NSFunctionKeyMask;
 
447
        }
 
448
        
 
449
#define encode(c, k,  s)                 if (aSelector == @selector(s)) { unicode = c; keyCode = k; unicodeString = [NSString stringWithCharacters: &unicode length: 1]; } 
 
450
//http://developer.apple.com/documentation/mac/Text/Text-571.html
 
451
        
 
452
        encode(  8, 51, deleteBackward:)
 
453
        else encode( 8, 51, deleteWordBackward:) 
 
454
                else encode(127, 51, deleteForward:)
 
455
                        else encode(127, 51, deleteWordForward:)
 
456
                                else encode( 8, 51, deleteBackwardByDecomposingPreviousCharacter:) 
 
457
                                
 
458
                                
 
459
                                else encode( (isFunctionKey ? 3: 13), (isFunctionKey ? 76: 36), insertNewline:) 
 
460
                                        else encode( 13, 36, insertLineBreak:) 
 
461
                                                else encode( 13, 36, insertNewlineIgnoringFieldEditor:) 
 
462
                                                        
 
463
                                                        else encode(  9, 48, insertTab:)
 
464
                                                                else encode(  9, 48, insertBacktab:)
 
465
                                                                        else encode(  9, 48, insertTabIgnoringFieldEditor:)
 
466
                                                                                
 
467
                                                                                else encode( 28, 123,  moveLeft:)
 
468
                                                                                        else encode( 29, 124, moveRight:)
 
469
                                                                                                else encode( 30, 126, moveUp:)
 
470
                                                                                                        else encode( 31, 125, moveDown:)
 
471
                                                                                                                                
 
472
                                                                                                                else encode( 30, 126, moveBackward:)
 
473
                                                                                                                        else encode( 31, 125, moveForward:)
 
474
                                                                                                                                else encode( 28, 123, moveLeftAndModifySelection:)
 
475
                                                                                                                                        else encode( 29, 124, moveRightAndModifySelection:)
 
476
                                                                                                                                
 
477
                                                                                                                                                else encode( 30, 126, moveUpAndModifySelection:)
 
478
                                                                                                                                                        else encode( 31, 125, moveDownAndModifySelection:)
 
479
                                                                                                                                                                else encode( 28, 123, moveWordLeftAndModifySelection:)
 
480
                                                                                                                                                                        else encode( 29, 124, moveWordRightAndModifySelection:)
 
481
                                                                                                                                
 
482
                                                                                                                                                                                else encode( 28, 123, moveWordLeft:)
 
483
                                                                                                                                                                                        else encode( 29, 124, moveWordRight:)
 
484
                                                                                                                                                                                                else encode( 30, 126, moveParagraphBackwardAndModifySelection:)
 
485
                                                                                                                                                                                                        else encode( 31, 125, moveParagraphForwardAndModifySelection:)
 
486
                                                                                                                                                                                                                
 
487
                                                                                                                                                                                                                else encode( 11, 116, pageUp:)
 
488
                                                                                                                                                                                                                        else encode( 12, 121, pageDown:)
 
489
                                                                                                                                
 
490
                                                                                                                                                                                                                                else encode( 11, 116, pageUpAndModifySelection:)
 
491
                                                                                                                                                                                                                                        else encode( 12, 121, pageDownAndModifySelection:)
 
492
                                                                                                                                
 
493
                                                                                                                                                                                                                                                else encode( (isFunctionKey ? 11 : 30), (isFunctionKey ? 116 : 126), scrollPageUp:)
 
494
                                                                                                                                                                                                                                                        else encode( (isFunctionKey ? 12 : 31), (isFunctionKey ? 121 : 125), scrollPageDown:)
 
495
                                                                                                                                                                                                                                                                
 
496
                                                                                                                                                                                                                                                                else encode(  1, 115, moveToBeginningOfDocument:)
 
497
                                                                                                                                                                                                                                                                        else encode(  4, 119, moveToEndOfDocument:)
 
498
                                                                                                                                
 
499
                                                                                                                                                                                                                                                                                else encode(  (isFunctionKey ? 1 : 28), (isFunctionKey ? 115 : 123), moveToLeftEndOfLine:)
 
500
                                                                                                                                                                                                                                                                                        else encode(  (isFunctionKey ? 4 : 29), (isFunctionKey ? 119 : 124), moveToRightEndOfLine:)
 
501
                                                                                                                                                                                                                                                                                                
 
502
                                                                                                                                                                                                                                                                                                else encode(  (isFunctionKey ? 1 : 28), (isFunctionKey ? 115 : 123), moveToLeftEndOfLineAndModifySelection:)
 
503
                                                                                                                                                                                                                                                                                                        else encode(  (isFunctionKey ? 4 : 29), (isFunctionKey ? 119 : 124), moveToRightEndOfLineAndModifySelection:)
 
504
                                                                                                                                                                                                                                                                                                                
 
505
                                                                                                                                                                                                                                                                                                else encode(  1, 115, scrollToBeginningOfDocument:)
 
506
                                                                                                                                                                                                                                                                                                        else encode(  4, 119, scrollToEndOfDocument:)
 
507
                                                                                                                                
 
508
                                                                                                                                                                                                                                                                                                else encode(  1, 115, moveToBeginningOfDocumentAndModifySelection:)
 
509
                                                                                                                                                                                                                                                                                                        else encode(  4, 119, moveToEndOfDocumentAndModifySelection:)
 
510
                                                                                                                                                                                                                                                                                                                
 
511
                                                                                                                                                                                                                                                                                                                
 
512
                                                                                                                                                                                                                                                                                                                else encode( 27, 53, cancelOperation:)
 
513
                                                                                                                                                                                                                                                                                                                        else encode( 27, 53, cancel:)
 
514
                                                                                                                                                                                                                                                                                                                                else encode( 27, 53, complete:)
 
515
                                                                                                                                                                                                                                                                                                                                        else encode( 27, 71, delete:)
 
516
                                                                                                                                                                                                                                                                                                                                else 
 
517
                                                                                                                                                                                                                                                                                                                                        return;
 
518
        
 
519
        @synchronized(self) {
 
520
                keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
 
521
                aKeyBoardStrokeDetails.keyCode = keyCode;
 
522
                aKeyBoardStrokeDetails.modifierFlags = self.lastSeenKeyBoardModifierDetails.modifierFlags;
 
523
                lastSeenKeyBoardStrokeDetails = aKeyBoardStrokeDetails;
 
524
                        
 
525
                [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordCharEvent: unicodeString fromView: self];
 
526
                self.lastSeenKeyBoardStrokeDetails = NULL;
 
527
        }
 
528
}
 
529
 
 
530
 
 
531
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange {
 
532
        inputMark= NSMakeRange(0, 1);
 
533
        inputSelection= NSMakeRange(NSNotFound, 0);
 
534
}
 
535
 
 
536
- (void)                 unmarkText {
 
537
        inputMark= NSMakeRange(NSNotFound, 0); 
 
538
}
 
539
 
 
540
- (BOOL)                 hasMarkedText { 
 
541
        return inputMark.location != NSNotFound; 
 
542
}
 
543
 
 
544
- (NSInteger)            conversationIdentifier { 
 
545
        return (NSInteger )self; 
 
546
}
 
547
 
 
548
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { 
 
549
        return nil; 
 
550
}
 
551
 
 
552
- (NSRange)              markedRange { 
 
553
        return inputMark; 
 
554
}
 
555
 
 
556
- (NSRange)              selectedRange { 
 
557
        return inputSelection; 
 
558
}
 
559
 
 
560
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
 
561
        return NSMakeRect(0,0, 0,0); 
 
562
}
 
563
 
 
564
- (NSUInteger) characterIndexForPoint: (NSPoint)thePoint {
 
565
        return 0; 
 
566
}
 
567
 
 
568
- (NSArray *) validAttributesForMarkedText { 
 
569
        return nil;
 
570
}
 
571
 
 
572
- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex {
 
573
        return NO;
 
574
}
 
575
 
 
576
- (NSMutableArray *) filterSqueakImageFilesFromDraggedFiles: (id<NSDraggingInfo>)info {
 
577
        NSPasteboard *pboard= [info draggingPasteboard];
 
578
        NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10];
 
579
        if ([[pboard types] containsObject: NSFilenamesPboardType]) {
 
580
                NSArray *files= [pboard propertyListForType: NSFilenamesPboardType];
 
581
                NSString *fileName;
 
582
                for (fileName in files) {
 
583
                        if ([((sqSqueakOSXApplication*) gDelegateApp.squeakApplication) isImageFile: fileName] == YES)
 
584
                                [results addObject: fileName];
 
585
                }
 
586
        }
 
587
        return results;
 
588
}
 
589
 
 
590
 
 
591
- (NSMutableArray *) filterOutSqueakImageFilesFromDraggedFiles: (id<NSDraggingInfo>)info {
 
592
        NSPasteboard *pboard= [info draggingPasteboard];
 
593
        NSMutableArray *results = [NSMutableArray arrayWithCapacity: 10];
 
594
        if ([[pboard types] containsObject: NSFilenamesPboardType]) {
 
595
                NSArray *files= [pboard propertyListForType: NSFilenamesPboardType];
 
596
                NSString *fileName;
 
597
                for (fileName in files) {
 
598
                        if ([((sqSqueakOSXApplication*) gDelegateApp.squeakApplication) isImageFile: fileName] == NO)
 
599
                                [results addObject: fileName];
 
600
                }
 
601
        }
 
602
        return results;
 
603
}
 
604
 
 
605
- (NSUInteger) countNumberOfNoneSqueakImageFilesInDraggedFiles: (id<NSDraggingInfo>)info {
 
606
        NSArray *files = [self filterOutSqueakImageFilesFromDraggedFiles: info];
 
607
        return [files count];
 
608
}
 
609
 
 
610
- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)info {
 
611
        if (self.dragInProgress) 
 
612
                return NSDragOperationNone;
 
613
        dragInProgress = YES;
 
614
        self.dragCount = (int) [self countNumberOfNoneSqueakImageFilesInDraggedFiles: info];
 
615
        
 
616
        if (self.dragCount)
 
617
                [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragEnter numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
 
618
        
 
619
        return NSDragOperationGeneric;
 
620
}
 
621
 
 
622
- (NSDragOperation) draggingUpdated: (id<NSDraggingInfo>)info
 
623
{
 
624
        if (self.dragCount)
 
625
                [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragMove numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
 
626
        return NSDragOperationGeneric;
 
627
}
 
628
 
 
629
- (void) draggingExited: (id<NSDraggingInfo>)info
 
630
{
 
631
        if (self.dragCount)
 
632
                [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragLeave numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
 
633
        self.dragCount = 0;
 
634
        self.dragInProgress = NO;
 
635
        self.dragItems = NULL;
 
636
}
 
637
 
 
638
- (BOOL) performDragOperation: (id<NSDraggingInfo>)info {
 
639
        if (self.dragCount) {
 
640
                self.dragItems = [self filterOutSqueakImageFilesFromDraggedFiles: info];
 
641
                [(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragDrop numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
 
642
        } 
 
643
        
 
644
        NSArray *images = [self filterSqueakImageFilesFromDraggedFiles: info];
 
645
        if ([images count] > 0) {
 
646
                for (NSString *item in images ){
 
647
                        NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
 
648
                        LSLaunchURLSpec launchSpec;
 
649
                        launchSpec.appURL = (CFURLRef)url;
 
650
                        launchSpec.passThruParams = NULL;
 
651
                        launchSpec.itemURLs = (CFArrayRef) [NSArray arrayWithObject:[NSURL fileURLWithPath: item]];
 
652
                        launchSpec.launchFlags = kLSLaunchDefaults | kLSLaunchNewInstance;
 
653
                        launchSpec.asyncRefCon = NULL;
 
654
                        
 
655
                        OSErr err = LSOpenFromURLSpec(&launchSpec, NULL);
 
656
#pragma unused(err)
 
657
                }
 
658
        }
 
659
                
 
660
 
 
661
        
 
662
        dragInProgress = NO;
 
663
        return YES;
 
664
}
 
665
 
 
666
- (NSString*) dragFileNameStringAtIndex: (sqInt) index {
 
667
        if (!self.dragItems) 
 
668
                return NULL;
 
669
        if (index < 1 || index > [self.dragItems count])
 
670
                return NULL;
 
671
        NSString *filePath = [self.dragItems objectAtIndex: (NSUInteger) index - 1];
 
672
        return filePath;
 
673
}
 
674
 
 
675
 
 
676
- (BOOL)ignoreModifierKeysWhileDragging {
 
677
        return YES;
 
678
}
 
679
 
 
680
- (void)  ioSetFullScreen: (sqInt) fullScreen { 
 
681
        
 
682
        if ([self isInFullScreenMode] == YES && (fullScreen == 1)) 
 
683
                return;
 
684
        if ([self isInFullScreenMode] == NO && (fullScreen == 0))
 
685
                return;
 
686
        
 
687
        if ([self isInFullScreenMode] == NO && (fullScreen == 1)) {
 
688
                self.savedScreenBoundsAtTimeOfFullScreen = (NSRect) [self bounds];
 
689
                [self fadeOut];
 
690
                [self enterFullScreenMode:[NSScreen mainScreen] withOptions: nil];
 
691
                extern struct   VirtualMachine* interpreterProxy;
 
692
                interpreterProxy->fullDisplayUpdate();
 
693
                [self fadeIn];
 
694
        }
 
695
        
 
696
        if ([self isInFullScreenMode] == YES && (fullScreen == 0)) {
 
697
                [self fadeOut];
 
698
                [self exitFullScreenModeWithOptions: NULL];
 
699
                [self fadeIn];
 
700
                if ([self.window isKeyWindow] == NO) {
 
701
                        [self.window makeKeyAndOrderFront: self];
 
702
                        //      NOT SURE IF THIS IS NEEDED, MORE TESTING        [self.window setContentSize: self.savedScreenBoundsAtTimeOfFullScreen.size];
 
703
                }
 
704
        }
 
705
}
 
706
 
 
707
- (void)fadeOut {
 
708
        CGDisplayErr    err;
 
709
        
 
710
        err = CGAcquireDisplayFadeReservation((CGDisplayReservationInterval)kCGMaxDisplayReservationInterval,
 
711
                                                                                  &fadeToken);
 
712
        if (err == kCGErrorSuccess) {
 
713
                CGDisplayFade(fadeToken,
 
714
                                          ((sqSqueakOSXInfoPlistInterface*) gDelegateApp.squeakApplication.infoPlistInterfaceLogic).SqueakUIFadeForFullScreenInSeconds,
 
715
                                          (CGDisplayBlendFraction)kCGDisplayBlendNormal,
 
716
                                          (CGDisplayBlendFraction)kCGDisplayBlendSolidColor,
 
717
                                          0.0f,
 
718
                                          0.0f,
 
719
                                          0.0f,
 
720
                                          TRUE);
 
721
        } 
 
722
 
723
 
 
724
- (void)fadeIn {
 
725
        CGDisplayErr    err;
 
726
        
 
727
        err = CGDisplayFade(fadeToken,
 
728
                                                ((sqSqueakOSXInfoPlistInterface*) gDelegateApp.squeakApplication.infoPlistInterfaceLogic).SqueakUIFadeForFullScreenInSeconds,
 
729
                                                (CGDisplayBlendFraction)kCGDisplayBlendSolidColor,
 
730
                                                (CGDisplayBlendFraction)kCGDisplayBlendNormal,
 
731
                                                0.0f,
 
732
                                                0.0f,
 
733
                                                0.0f,
 
734
                                                TRUE);
 
735
        if (err == kCGErrorSuccess) {
 
736
                CGReleaseDisplayFadeReservation(fadeToken);
 
737
        } 
 
738
}
 
739
 
 
740
@end
 
 
b'\\ No newline at end of file'