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>
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.
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
21
The above copyright notice and this permission notice shall be
22
included in all copies or substantial portions of the Software.
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.
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.
40
#import <QuartzCore/QuartzCore.h>
42
#import "sqSqueakOSXNSView.h"
43
#import "sqSqueakOSXScreenAndWindow.h"
44
#import "SqueakOSXAppDelegate.h"
45
#import "sqSqueakOSXApplication+events.h"
46
#import "sqSqueakOSXInfoPlistInterface.h"
48
#import "sqVirtualMachine.h"
50
//#import <OpenGL/CGLMacro.h>
52
extern SqueakOSXAppDelegate *gDelegateApp;
53
extern struct VirtualMachine* interpreterProxy;
55
static NSString *stringWithCharacter(unichar character) {
56
return [NSString stringWithCharacters: &character length: 1];
59
@implementation sqSqueakOSXNSView
60
@synthesize squeakTrackingRectForCursor,lastSeenKeyBoardStrokeDetails,
61
lastSeenKeyBoardModifierDetails,dragInProgress,dragCount,dragItems,windowLogic,savedScreenBoundsAtTimeOfFullScreen;
63
+ (NSOpenGLPixelFormat *)defaultPixelFormat {
64
NSOpenGLPixelFormatAttribute attrs[] =
66
NSOpenGLPFAAccelerated,
67
NSOpenGLPFANoRecovery,
68
NSOpenGLPFABackingStore,
71
return[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
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");
84
colorspace = CGColorSpaceCreateDeviceRGB();
85
[self initializeSqueakColorMap];
88
- (void) initializeVariables {
94
CGColorSpaceRelease(colorspace);
97
- (BOOL) acceptsFirstResponder {
109
- (void)viewDidMoveToWindow {
110
if (self.squeakTrackingRectForCursor)
111
[self removeTrackingRect: self.squeakTrackingRectForCursor];
113
self.squeakTrackingRectForCursor = [self addTrackingRect: [self bounds] owner: self userData:NULL assumeInside: NO];
116
- (void) updateTrackingAreas {
117
[super updateTrackingAreas];
118
[self removeTrackingRect: self.squeakTrackingRectForCursor];
119
self.squeakTrackingRectForCursor = [self addTrackingRect: [self bounds] owner: self userData:NULL assumeInside: NO];
122
- (void) viewWillStartLiveResize {
123
// [self.window setShowsResizeIndicator: YES];
124
[[NSCursor arrowCursor] set];
127
- (void) viewDidEndLiveResize {
128
// [self.window setShowsResizeIndicator: NO];
129
[((sqSqueakOSXApplication*) gDelegateApp.squeakApplication).squeakCursor performSelectorOnMainThread: @selector(set) withObject: nil waitUntilDone: NO];
132
- (void) drawImageUsingClip: (CGRect) clip {
138
clippy = CGRectUnion(clippy, clip);
143
- (void) drawThelayers {
145
[self drawRect: NSRectFromCGRect(clippy)];
148
// CGL_MACRO_DECLARE_VARIABLES();
150
[[self openGLContext] flushBuffer];
152
if (!firstDrawCompleted) {
153
firstDrawCompleted = YES;
154
if (getFullScreenFlag() == 0)
155
[self.window makeKeyAndOrderFront: self];
160
// CGL_MACRO_DECLARE_VARIABLES();
161
// Enable the multithreading
162
CGLContextObj ctx = [[self openGLContext] CGLContextObj];
163
CGLEnable( ctx, kCGLCEMPEngine);
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);
172
glDisable(GL_DITHER);
173
glDisable(GL_ALPHA_TEST);
175
glDisable(GL_STENCIL_TEST);
177
glDisable(GL_TEXTURE_2D);
178
glDisable(GL_DEPTH_TEST);
179
glDisable (GL_SCISSOR_TEST);
180
glDisable (GL_CULL_FACE);
182
glPixelZoom(1.0,1.0);
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 );
194
glDeleteTextures(1, &dt);
195
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 1);
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);
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);
214
-(void)defineQuad:(NSRect)r
217
// CGL_MACRO_DECLARE_VARIABLES();
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);
226
- (void)update // moved or resized
232
[[self openGLContext] makeCurrentContext];
233
// CGL_MACRO_DECLARE_VARIABLES();
234
[[self openGLContext] update];
236
rect = [self bounds];
238
glViewport(0, 0, (int) rect.size.width, (int) rect.size.height);
239
glPixelStorei( GL_UNPACK_ROW_LENGTH, rect.size.width );
241
glMatrixMode(GL_PROJECTION);
244
glMatrixMode(GL_MODELVIEW);
247
[self setNeedsDisplay:true];
250
- (void)reshape // scrolled, moved or resized
256
[[self openGLContext] makeCurrentContext];
257
// CGL_MACRO_DECLARE_VARIABLES();
258
[[self openGLContext] update];
260
rect = [self bounds];
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);
267
glMatrixMode(GL_MODELVIEW);
270
[self setNeedsDisplay:true];
273
-(void)drawRect:(NSRect)rect
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];
286
[self loadTexturesFrom:dispBitsIndex subRectangle: rect];
287
[self defineQuad:rect];
291
- (void)mouseEntered:(NSEvent *)theEvent {
292
[((sqSqueakOSXApplication*) gDelegateApp.squeakApplication).squeakCursor set];
295
- (void)mouseExited:(NSEvent *)theEvent {
296
[[NSCursor arrowCursor] set];
299
- (void)mouseMoved:(NSEvent *)theEvent {
300
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
303
- (void)mouseDragged:(NSEvent *)theEvent {
304
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
307
- (void)rightMouseDragged:(NSEvent *)theEvent {
308
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
311
- (void)otherMouseDragged:(NSEvent *)theEvent {
312
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
315
- (void)scrollWheel:(NSEvent *)theEvent {
316
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordWheelEvent: theEvent fromView: self];
319
- (void)mouseUp:(NSEvent *)theEvent {
320
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
323
- (void)rightMouseUp:(NSEvent *)theEvent {
324
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
327
- (void)otherMouseUp:(NSEvent *)theEvent {
328
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
331
- (void)mouseDown:(NSEvent *)theEvent {
332
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
335
- (void)rightMouseDown:(NSEvent *)theEvent {
336
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
338
- (void)otherMouseDown:(NSEvent *)theEvent {
339
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordMouseEvent: theEvent fromView: self];
342
- (NSString *) dealWithOpenStepChars: (NSString *) openStep {
345
static unichar combiningHelpChar[] = {0x003F, 0x20DD};
347
keyChar = [openStep characterAtIndex: 0];
349
//http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/KEYBOARD.TXT
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;
368
if (keyChar >= NSF1FunctionKey && keyChar <= NSF35FunctionKey) {
372
return stringWithCharacter(keyChar);
376
-(void) fakeKeyDownUp: (NSEvent*) theEvent {
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
382
keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
383
aKeyBoardStrokeDetails.keyCode = [theEvent keyCode];
384
aKeyBoardStrokeDetails.modifierFlags = [theEvent modifierFlags];
386
NSArray *down = [[NSArray alloc] initWithObjects: theEvent,nil];
387
@synchronized(self) {
388
lastSeenKeyBoardStrokeDetails = aKeyBoardStrokeDetails;
389
NSString *possibleConversion = [theEvent characters];
391
if ([possibleConversion length] > 0) {
392
NSString *c = [self dealWithOpenStepChars: possibleConversion];
393
[self insertText: c replacementRange: NSMakeRange(NSNotFound, 0)];
395
self.lastSeenKeyBoardStrokeDetails = NULL;
396
[self keyUp: theEvent];
401
-(void)keyDown:(NSEvent*)theEvent {
402
keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
403
aKeyBoardStrokeDetails.keyCode = [theEvent keyCode];
404
aKeyBoardStrokeDetails.modifierFlags = [theEvent modifierFlags];
406
NSArray *down = [[NSArray alloc] initWithObjects: theEvent,nil];
407
@synchronized(self) {
408
lastSeenKeyBoardStrokeDetails = aKeyBoardStrokeDetails;
409
[self interpretKeyEvents: down];
410
self.lastSeenKeyBoardStrokeDetails = NULL;
415
-(void)keyUp:(NSEvent*)theEvent {
416
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordKeyUpEvent: theEvent fromView: self];
419
/* 10.5 seems only to call insertText:, but 10.6 calls insertText:replacementRange: */
421
- (void)insertText:(id)aString
423
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordCharEvent: aString fromView: self];
426
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
428
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordCharEvent: aString fromView: self];
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];
439
- (void)doCommandBySelector:(SEL)aSelector {
441
unsigned short keyCode;
442
NSString *unicodeString;
443
BOOL isFunctionKey = NO;
445
if (self.lastSeenKeyBoardModifierDetails) {
446
isFunctionKey = (self.lastSeenKeyBoardModifierDetails.modifierFlags & NSFunctionKeyMask) == NSFunctionKeyMask;
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
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:)
459
else encode( (isFunctionKey ? 3: 13), (isFunctionKey ? 76: 36), insertNewline:)
460
else encode( 13, 36, insertLineBreak:)
461
else encode( 13, 36, insertNewlineIgnoringFieldEditor:)
463
else encode( 9, 48, insertTab:)
464
else encode( 9, 48, insertBacktab:)
465
else encode( 9, 48, insertTabIgnoringFieldEditor:)
467
else encode( 28, 123, moveLeft:)
468
else encode( 29, 124, moveRight:)
469
else encode( 30, 126, moveUp:)
470
else encode( 31, 125, moveDown:)
472
else encode( 30, 126, moveBackward:)
473
else encode( 31, 125, moveForward:)
474
else encode( 28, 123, moveLeftAndModifySelection:)
475
else encode( 29, 124, moveRightAndModifySelection:)
477
else encode( 30, 126, moveUpAndModifySelection:)
478
else encode( 31, 125, moveDownAndModifySelection:)
479
else encode( 28, 123, moveWordLeftAndModifySelection:)
480
else encode( 29, 124, moveWordRightAndModifySelection:)
482
else encode( 28, 123, moveWordLeft:)
483
else encode( 29, 124, moveWordRight:)
484
else encode( 30, 126, moveParagraphBackwardAndModifySelection:)
485
else encode( 31, 125, moveParagraphForwardAndModifySelection:)
487
else encode( 11, 116, pageUp:)
488
else encode( 12, 121, pageDown:)
490
else encode( 11, 116, pageUpAndModifySelection:)
491
else encode( 12, 121, pageDownAndModifySelection:)
493
else encode( (isFunctionKey ? 11 : 30), (isFunctionKey ? 116 : 126), scrollPageUp:)
494
else encode( (isFunctionKey ? 12 : 31), (isFunctionKey ? 121 : 125), scrollPageDown:)
496
else encode( 1, 115, moveToBeginningOfDocument:)
497
else encode( 4, 119, moveToEndOfDocument:)
499
else encode( (isFunctionKey ? 1 : 28), (isFunctionKey ? 115 : 123), moveToLeftEndOfLine:)
500
else encode( (isFunctionKey ? 4 : 29), (isFunctionKey ? 119 : 124), moveToRightEndOfLine:)
502
else encode( (isFunctionKey ? 1 : 28), (isFunctionKey ? 115 : 123), moveToLeftEndOfLineAndModifySelection:)
503
else encode( (isFunctionKey ? 4 : 29), (isFunctionKey ? 119 : 124), moveToRightEndOfLineAndModifySelection:)
505
else encode( 1, 115, scrollToBeginningOfDocument:)
506
else encode( 4, 119, scrollToEndOfDocument:)
508
else encode( 1, 115, moveToBeginningOfDocumentAndModifySelection:)
509
else encode( 4, 119, moveToEndOfDocumentAndModifySelection:)
512
else encode( 27, 53, cancelOperation:)
513
else encode( 27, 53, cancel:)
514
else encode( 27, 53, complete:)
515
else encode( 27, 71, delete:)
519
@synchronized(self) {
520
keyBoardStrokeDetails *aKeyBoardStrokeDetails = [[keyBoardStrokeDetails alloc] init];
521
aKeyBoardStrokeDetails.keyCode = keyCode;
522
aKeyBoardStrokeDetails.modifierFlags = self.lastSeenKeyBoardModifierDetails.modifierFlags;
523
lastSeenKeyBoardStrokeDetails = aKeyBoardStrokeDetails;
525
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordCharEvent: unicodeString fromView: self];
526
self.lastSeenKeyBoardStrokeDetails = NULL;
531
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange {
532
inputMark= NSMakeRange(0, 1);
533
inputSelection= NSMakeRange(NSNotFound, 0);
536
- (void) unmarkText {
537
inputMark= NSMakeRange(NSNotFound, 0);
540
- (BOOL) hasMarkedText {
541
return inputMark.location != NSNotFound;
544
- (NSInteger) conversationIdentifier {
545
return (NSInteger )self;
548
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
552
- (NSRange) markedRange {
556
- (NSRange) selectedRange {
557
return inputSelection;
560
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
561
return NSMakeRect(0,0, 0,0);
564
- (NSUInteger) characterIndexForPoint: (NSPoint)thePoint {
568
- (NSArray *) validAttributesForMarkedText {
572
- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex {
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];
582
for (fileName in files) {
583
if ([((sqSqueakOSXApplication*) gDelegateApp.squeakApplication) isImageFile: fileName] == YES)
584
[results addObject: fileName];
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];
597
for (fileName in files) {
598
if ([((sqSqueakOSXApplication*) gDelegateApp.squeakApplication) isImageFile: fileName] == NO)
599
[results addObject: fileName];
605
- (NSUInteger) countNumberOfNoneSqueakImageFilesInDraggedFiles: (id<NSDraggingInfo>)info {
606
NSArray *files = [self filterOutSqueakImageFilesFromDraggedFiles: info];
607
return [files count];
610
- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)info {
611
if (self.dragInProgress)
612
return NSDragOperationNone;
613
dragInProgress = YES;
614
self.dragCount = (int) [self countNumberOfNoneSqueakImageFilesInDraggedFiles: info];
617
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragEnter numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
619
return NSDragOperationGeneric;
622
- (NSDragOperation) draggingUpdated: (id<NSDraggingInfo>)info
625
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragMove numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
626
return NSDragOperationGeneric;
629
- (void) draggingExited: (id<NSDraggingInfo>)info
632
[(sqSqueakOSXApplication *) gDelegateApp.squeakApplication recordDragEvent: DragLeave numberOfFiles: self.dragCount where: [info draggingLocation] windowIndex: self.windowLogic.windowIndex];
634
self.dragInProgress = NO;
635
self.dragItems = NULL;
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];
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;
655
OSErr err = LSOpenFromURLSpec(&launchSpec, NULL);
666
- (NSString*) dragFileNameStringAtIndex: (sqInt) index {
669
if (index < 1 || index > [self.dragItems count])
671
NSString *filePath = [self.dragItems objectAtIndex: (NSUInteger) index - 1];
676
- (BOOL)ignoreModifierKeysWhileDragging {
680
- (void) ioSetFullScreen: (sqInt) fullScreen {
682
if ([self isInFullScreenMode] == YES && (fullScreen == 1))
684
if ([self isInFullScreenMode] == NO && (fullScreen == 0))
687
if ([self isInFullScreenMode] == NO && (fullScreen == 1)) {
688
self.savedScreenBoundsAtTimeOfFullScreen = (NSRect) [self bounds];
690
[self enterFullScreenMode:[NSScreen mainScreen] withOptions: nil];
691
extern struct VirtualMachine* interpreterProxy;
692
interpreterProxy->fullDisplayUpdate();
696
if ([self isInFullScreenMode] == YES && (fullScreen == 0)) {
698
[self exitFullScreenModeWithOptions: NULL];
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];
710
err = CGAcquireDisplayFadeReservation((CGDisplayReservationInterval)kCGMaxDisplayReservationInterval,
712
if (err == kCGErrorSuccess) {
713
CGDisplayFade(fadeToken,
714
((sqSqueakOSXInfoPlistInterface*) gDelegateApp.squeakApplication.infoPlistInterfaceLogic).SqueakUIFadeForFullScreenInSeconds,
715
(CGDisplayBlendFraction)kCGDisplayBlendNormal,
716
(CGDisplayBlendFraction)kCGDisplayBlendSolidColor,
727
err = CGDisplayFade(fadeToken,
728
((sqSqueakOSXInfoPlistInterface*) gDelegateApp.squeakApplication.infoPlistInterfaceLogic).SqueakUIFadeForFullScreenInSeconds,
729
(CGDisplayBlendFraction)kCGDisplayBlendSolidColor,
730
(CGDisplayBlendFraction)kCGDisplayBlendNormal,
735
if (err == kCGErrorSuccess) {
736
CGReleaseDisplayFadeReservation(fadeToken);
b'\\ No newline at end of file'