#DOCUMENTATION by cg
class: OSXOperatingSystem
added:
#copyright
#documentation
--- a/OSXOperatingSystem.st Wed Feb 15 21:25:09 2017 +0100
+++ b/OSXOperatingSystem.st Wed Feb 15 22:04:02 2017 +0100
@@ -1,3 +1,14 @@
+"
+ COPYRIGHT (c) 2013 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
"{ Package: 'stx:libbasic' }"
"{ NameSpace: Smalltalk }"
@@ -9,6 +20,185 @@
category:'OS-Unix'
!
+!OSXOperatingSystem primitiveDefinitions!
+%{
+
+#ifndef __OSX__
+# define NO_QUARTZ
+# define NO_COCOA
+#endif
+
+#ifndef NO_COCOA
+
+# undef Array
+# undef Number
+# undef Method
+# undef Point
+# undef Rectangle
+# undef Block
+# undef String
+# undef Character
+# undef Message
+# undef Object
+# undef Context
+# undef Time
+# undef Date
+# undef Set
+# undef Signal
+# undef Delay
+# undef NameSpace
+# undef Process
+# undef Processor
+# undef Class
+# undef FixedPoint
+# undef true
+# undef false
+
+# undef INT
+# undef UINT
+
+#include <ApplicationServices/ApplicationServices.h>
+#include <CoreFoundation/CoreFoundation.h>
+// #include <Foundation/Foundation.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <IOKit/graphics/IOGraphicsLib.h>
+
+#include <objc/runtime.h>
+#include <objc/message.h>
+
+# ifdef __DEF_Array
+# define Array __DEF_Array
+# endif
+# ifdef __DEF_Number
+# define Number __DEF_Number
+# endif
+# ifdef __DEF_Method
+# define Method __DEF_Method
+# endif
+# ifdef __DEF_Point
+# define Point __DEF_Point
+# endif
+# ifdef __DEF_Rectangle
+# define Rectangle __DEF_Rectangle
+# endif
+# ifdef __DEF_Block
+# define Block __DEF_Block
+# endif
+# ifdef __DEF_String
+# define String __DEF_String
+# endif
+# ifdef __DEF_Character
+# define Character __DEF_Character
+# endif
+# ifdef __DEF_Message
+# define Message __DEF_Message
+# endif
+# ifdef __DEF_Object
+# define Object __DEF_Object
+# endif
+# ifdef __DEF_Context
+# define Context __DEF_Context
+# endif
+# ifdef __DEF_Date
+# define Date __DEF_Date
+# endif
+# ifdef __DEF_Time
+# define Time __DEF_Time
+# endif
+# ifdef __DEF_Set
+# define Set __DEF_Set
+# endif
+# ifdef __DEF_Signal
+# define Signal __DEF_Signal
+# endif
+# ifdef __DEF_Delay
+# define Delay __DEF_Delay
+# endif
+# ifdef __DEF_NameSpace
+# define NameSpace __DEF_NameSpace
+# endif
+# ifdef __DEF_Process
+# define Process __DEF_Process
+# endif
+# ifdef __DEF_Processor
+# define Processor __DEF_Processor
+# endif
+# ifdef __DEF_Class
+# define Class __DEF_Class
+# endif
+# ifdef __DEF_FixedPoint
+# define FixedPoint __DEF_FixedPoint
+# endif
+# ifdef __DEF_true
+# undef true
+# define true __DEF_true
+# endif
+# ifdef __DEF_false
+# undef false
+# define false __DEF_false
+# endif
+
+# define INT STX_INT
+# define UINT STX_UINT
+
+#endif // NP_COCOA
+
+%}
+! !
+
+!OSXOperatingSystem primitiveFunctions!
+%{
+
+#ifndef NO_COCOA
+
+CGEventRef
+myCGEventCallback(CGEventTapProxy proxy, CGEventType type,
+ CGEventRef event, void *refcon)
+{
+ // Paranoid sanity check.
+ if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp))
+ return event;
+
+ // The incoming keycode.
+ CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
+
+ //Keypress code goes here.
+
+ // We must return the event for it to be useful.
+ return event;
+}
+
+#endif // NO_COCOA
+
+%}
+! !
+
+!OSXOperatingSystem class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2013 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+ a small number of OS-X specific redefinitions here.
+
+ [Author:]
+ Claus Gittinger
+"
+! !
!OSXOperatingSystem class methodsFor:'initialization'!
@@ -18,6 +208,40 @@
CodesetEncoder := nil.
! !
+!OSXOperatingSystem class methodsFor:'cocoa - events'!
+
+receiveNextEvent
+%{
+#ifndef NO_COCOA
+# if 0
+ CFMachPortRef eventTap;
+ CGEventMask eventMask;
+ CFRunLoopSourceRef runLoopSource;
+
+ // Create an event tap. We are interested in key presses.
+ eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
+ eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
+ eventMask, NULL, myCGEventCallback);
+ if (!eventTap) {
+ fprintf(stderr, "failed to create event tap\n");
+ } else{
+ fprintf(stderr, "ok\n");
+ }
+
+ // Create a run loop source.
+ runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, eventTap, 0);
+# if 0
+ // Add to the current run loop. kCFRunLoopCommonModes);
+# endif
+ // Enable the event tap.
+ CGEventTapEnable(eventTap, true);
+
+# endif
+#endif // NO_COCOA
+%}.
+ self primitiveFailed
+! !
+
!OSXOperatingSystem class methodsFor:'dummy shell operations'!
openApplicationHelperCommand
@@ -77,55 +301,55 @@
"called by Smalltalk initSystemPath"
"self defaultPackagePath"
- |path executablePath executableDir packagesDir
+ |path executablePath executableDir packagesDir
libDir appDir versionsDir vsnDirName vsnDir|
path := super defaultPackagePath.
executablePath := OperatingSystem pathOfSTXExecutable.
executablePath notNil ifTrue:[
- executableDir := executablePath asFilename directory.
- packagesDir := executableDir directory directory / 'Packages'.
- packagesDir exists ifTrue:[
- packagesDir := packagesDir pathName.
- (path includes:packagesDir) ifFalse:[
- path add:packagesDir.
- ].
- ].
- libDir := '/Library/Frameworks/SmalltalkX.framework' asFilename.
- libDir exists ifTrue:[
- versionsDir := libDir / 'Versions'.
- versionsDir exists ifTrue:[
- vsnDirName := '%1.%2.%3'
- bindWith:Smalltalk majorVersionNr
- with:Smalltalk minorVersionNr
- with:Smalltalk revisionNr.
- vsnDir := versionsDir / vsnDirName.
- vsnDir exists ifTrue:[
- vsnDir := vsnDir pathName.
- (path includes:vsnDir) ifFalse:[
- path add:vsnDir.
- ].
- ].
- ].
- ].
- appDir := '/Applications/SmalltalkX/' asFilename.
- appDir exists ifTrue:[
- versionsDir := appDir / 'Versions'.
- versionsDir exists ifTrue:[
- vsnDirName := '%1.%2.%3'
- bindWith:Smalltalk majorVersionNr
- with:Smalltalk minorVersionNr
- with:Smalltalk revisionNr.
- vsnDir := versionsDir / vsnDirName.
- vsnDir exists ifTrue:[
- vsnDir := vsnDir pathName.
- (path includes:vsnDir) ifFalse:[
- path add:vsnDir.
- ].
- ].
- ].
- ].
+ executableDir := executablePath asFilename directory.
+ packagesDir := executableDir directory directory / 'Packages'.
+ packagesDir exists ifTrue:[
+ packagesDir := packagesDir pathName.
+ (path includes:packagesDir) ifFalse:[
+ path add:packagesDir.
+ ].
+ ].
+ libDir := '/Library/Frameworks/SmalltalkX.framework' asFilename.
+ libDir exists ifTrue:[
+ versionsDir := libDir / 'Versions'.
+ versionsDir exists ifTrue:[
+ vsnDirName := '%1.%2.%3'
+ bindWith:Smalltalk majorVersionNr
+ with:Smalltalk minorVersionNr
+ with:Smalltalk revisionNr.
+ vsnDir := versionsDir / vsnDirName.
+ vsnDir exists ifTrue:[
+ vsnDir := vsnDir pathName.
+ (path includes:vsnDir) ifFalse:[
+ path add:vsnDir.
+ ].
+ ].
+ ].
+ ].
+ appDir := '/Applications/SmalltalkX/' asFilename.
+ appDir exists ifTrue:[
+ versionsDir := appDir / 'Versions'.
+ versionsDir exists ifTrue:[
+ vsnDirName := '%1.%2.%3'
+ bindWith:Smalltalk majorVersionNr
+ with:Smalltalk minorVersionNr
+ with:Smalltalk revisionNr.
+ vsnDir := versionsDir / vsnDirName.
+ vsnDir exists ifTrue:[
+ vsnDir := vsnDir pathName.
+ (path includes:vsnDir) ifFalse:[
+ path add:vsnDir.
+ ].
+ ].
+ ].
+ ].
].
^ path
!
@@ -163,6 +387,80 @@
^ true
! !
+!OSXOperatingSystem class methodsFor:'quartz - screen'!
+
+getFrameBufferImage:displayNr
+ "returns the framebuffer as an image object"
+
+ |width height bytesPerPixel address pixels depth pad img|
+
+%{
+#ifndef NO_QUARTZ
+ CGImageRef image_ref = CGDisplayCreateImage(CGMainDisplayID());
+ CGDataProviderRef provider = CGImageGetDataProvider(image_ref);
+ CFDataRef dataref = CGDataProviderCopyData(provider);
+ size_t c_width, c_height;
+
+ c_width = CGImageGetWidth(image_ref);
+ c_height = CGImageGetHeight(image_ref);
+ size_t c_bytesPerPixel = CGImageGetBitsPerPixel(image_ref) / 8;
+ pixels = __BYTEARRAY_UNINITIALIZED_NEW_INT(c_width * c_height * c_bytesPerPixel);
+ // uint8 *pixels = malloc(c_width * c_height * c_bytesPerPixel);
+ memcpy(__byteArrayVal(pixels), CFDataGetBytePtr(dataref), c_width * c_height * c_bytesPerPixel);
+ CFRelease(dataref);
+ CGImageRelease(image_ref);
+
+ width = __MKUINT( c_width );
+ height = __MKUINT( c_height );
+ bytesPerPixel = __MKUINT( c_bytesPerPixel );
+
+// CGDisplayBaseAddress is deprecated
+//
+// int i, saveFD = -1;
+// uint32_t rowBytes, rowUInt32s, *screen;
+//
+// CGDirectDisplayID targetDisplay = 0;
+//
+// // populate targetDisplay as in Figure 10.23
+// // use listDisplays() from Figure 10.23
+// // ...
+//
+// screen = (uint32_t *)CGDisplayBaseAddress(targetDisplay);
+// rowBytes = CGDisplayBytesPerRow(targetDisplay);
+// rowUInt32s = rowBytes / 4;
+// width = __MKUINT( CGDisplayPixelsWide(targetDisplay) );
+// height = __MKUINT( CGDisplayPixelsHigh(targetDisplay) );
+
+// for (i = 0; i < height; i++)
+// write(saveFD, screen + i * rowUInt32s, width * sizeof(uint32_t));
+//
+#endif // NO_QUARTZ
+
+%}.
+ width isNil ifTrue:[
+ ^ self primitiveFailed
+ ].
+ Transcript printf:'w:%d h:%d bpp:%d\n' withAll:{ width . height . bytesPerPixel }.
+
+ depth := bytesPerPixel * 8.
+
+ Transcript printf:'d:%d\n' withAll:{ depth }.
+
+ "/ MUST swap r and b channels - sigh
+ "/ pixels swapBGRtoRGB
+
+ img := Image extent:(width @ height) depth:depth bits:pixels.
+ depth >= 24 ifFalse:[
+ "/ check what we get here...
+ ^ self primitiveFailed:'unsupported depth'
+ ].
+
+ img bitsPerSample:#[8 8 8].
+ img samplesPerPixel:3.
+ img photometric:#rgb.
+ ^ img
+! !
+
!OSXOperatingSystem class methodsFor:'documentation'!
version