#DOCUMENTATION by cg
authorClaus Gittinger <cg@exept.de>
Wed, 15 Feb 2017 22:04:02 +0100
changeset 21452 3435141db80f
parent 21451 44f655bf5c80
child 21453 1598857f4864
#DOCUMENTATION by cg class: OSXOperatingSystem added: #copyright #documentation
OSXOperatingSystem.st
--- 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