--- a/OSXOperatingSystem.st Wed Apr 03 18:17:17 2019 +0200
+++ b/OSXOperatingSystem.st Thu Apr 04 00:24:02 2019 +0200
@@ -34,6 +34,7 @@
# define NO_QUARTZ
# define NO_COCOA
# define NO_CARBON
+# define NO_COREGRAPHICS
#endif
// #include <mach/clock.h>
@@ -73,6 +74,7 @@
# include <ApplicationServices/ApplicationServices.h>
# include <CoreFoundation/CoreFoundation.h>
// #include <Foundation/Foundation.h>
+# include <CoreGraphics/CGGeometry.h>
// #include <CoreGraphics/CGEventTypes.h>
@@ -211,19 +213,29 @@
#ifndef NO_COCOA
+struct ev {
+ struct ev* nextEvent;
+ CGEventType type;
+ CGKeyCode keycode;
+ int x,y;
+ int button;
+};
+static struct ev *nextRecordedEvent = NULL;
+static struct ev *lastRecordedEvent = NULL;
+
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.
-
+ if ((type == kCGEventKeyDown) || (type == kCGEventKeyUp)) {
+ // The incoming keycode.
+ CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
+ }
+ if (type == kCGEventMouseMoved) {
+ // loc = [NSEvent mouseLocation]
+ // int x = loc.x;
+ // int y = loc.y;
+ }
// We must return the event for it to be useful.
return event;
}
@@ -396,7 +408,7 @@
!
generateMouseMoveEventX:screenX y:screenY
- "synthesize and send a mosue move event to the screen"
+ "synthesize and send a mouse move event to the screen"
%{
#ifndef NO_COCOA
if (__bothSmallInteger(screenX, screenY)) {
@@ -491,7 +503,10 @@
CFRunLoopSourceRef runLoopSource;
// Create an event tap. We are interested in key presses.
- eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
+ // sigh: a global event tap requires root privileges
+ eventMask = ((1 << kCGEventKeyDown)
+ | (1 << kCGEventKeyUp)
+ | (1 << kCGEventMouseMoved));
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
eventMask, NULL, myCGEventCallback);
if (!eventTap) {
@@ -721,10 +736,10 @@
|rx ry rwidth rheight bytesPerPixel bytesPerRow address pixels depth pad img ok|
aRectangleOrNil notNil ifTrue:[
- rx := aRectangleOrNil left.
- ry := aRectangleOrNil top.
- rwidth := aRectangleOrNil width.
- rheight := aRectangleOrNil height.
+ rx := aRectangleOrNil left.
+ ry := aRectangleOrNil top.
+ rwidth := aRectangleOrNil width.
+ rheight := aRectangleOrNil height.
].
%{
#ifndef NO_COCOA
@@ -733,82 +748,82 @@
ok = false;
if (rx == nil) {
- image_ref = CGDisplayCreateImage(displayID);
+ image_ref = CGDisplayCreateImage(displayID);
} else {
- CGRect rect;
- rect.origin.x = (CGFloat)__intVal(rx);
- rect.origin.y = (CGFloat)__intVal(ry);
- rect.size.width = (CGFloat)__intVal(rwidth);
- rect.size.height = (CGFloat)__intVal(rheight);
- image_ref = CGDisplayCreateImageForRect(displayID, rect);
+ CGRect rect;
+ rect.origin.x = (CGFloat)__intVal(rx);
+ rect.origin.y = (CGFloat)__intVal(ry);
+ rect.size.width = (CGFloat)__intVal(rwidth);
+ rect.size.height = (CGFloat)__intVal(rheight);
+ image_ref = CGDisplayCreateImageForRect(displayID, rect);
}
if (image_ref != NULL) {
- CGDataProviderRef provider = CGImageGetDataProvider(image_ref);
- CFDataRef dataref = CGDataProviderCopyData(provider);
- size_t c_width = CGImageGetWidth(image_ref);
- size_t c_height = CGImageGetHeight(image_ref);
- size_t c_bytesPerRow = CGImageGetBytesPerRow(image_ref);
- size_t c_bytesPerPixel = CGImageGetBitsPerPixel(image_ref) / 8;
- unsigned char *c_pixels = (unsigned char *)CFDataGetBytePtr(dataref);
+ CGDataProviderRef provider = CGImageGetDataProvider(image_ref);
+ CFDataRef dataref = CGDataProviderCopyData(provider);
+ size_t c_width = CGImageGetWidth(image_ref);
+ size_t c_height = CGImageGetHeight(image_ref);
+ size_t c_bytesPerRow = CGImageGetBytesPerRow(image_ref);
+ size_t c_bytesPerPixel = CGImageGetBitsPerPixel(image_ref) / 8;
+ unsigned char *c_pixels = (unsigned char *)CFDataGetBytePtr(dataref);
- if (c_bytesPerPixel == 4) {
- int row;
- pixels = __BYTEARRAY_UNINITIALIZED_NEW_INT(c_width * c_height * 3);
- unsigned char *srcRowPtr = c_pixels;
- unsigned char *dstRowPtr = __byteArrayVal(pixels);
+ if (c_bytesPerPixel == 4) {
+ int row;
+ pixels = __BYTEARRAY_UNINITIALIZED_NEW_INT(c_width * c_height * 3);
+ unsigned char *srcRowPtr = c_pixels;
+ unsigned char *dstRowPtr = __byteArrayVal(pixels);
- for (row=c_height; row>0; row--) {
- int col = c_width;
- unsigned int *pixSrcPtr = (int*)srcRowPtr;
- unsigned char *pixDstPtr = dstRowPtr;
+ for (row=c_height; row>0; row--) {
+ int col = c_width;
+ unsigned int *pixSrcPtr = (int*)srcRowPtr;
+ unsigned char *pixDstPtr = dstRowPtr;
- // convert abgr to rgb
+ // convert abgr to rgb
#if (__POINTER_SIZE__ == 8) && defined(__LSBFIRST__)
- for (; col > 2; col -= 2) {
- // pick 2 pixels
- unsigned INT pix12 = ((unsigned INT*)pixSrcPtr)[0];
- pixSrcPtr += 2;
- // a2 r2 g2 b2 a1 r1 g1 b1 => r1..g1..b1..r2..g2..b2
- pixDstPtr[0] = (pix12 >> 16) & 0xFF;
- pixDstPtr[1] = (pix12 >> 8) & 0xFF;
- pixDstPtr[2] = pix12 & 0xFF;
- pixDstPtr[3] = (pix12 >> 48) & 0xFF;
- pixDstPtr[4] = (pix12 >> 40) & 0xFF;
- pixDstPtr[5] = (pix12 >> 32) & 0xFF;
- pixDstPtr += 6;
- }
+ for (; col > 2; col -= 2) {
+ // pick 2 pixels
+ unsigned INT pix12 = ((unsigned INT*)pixSrcPtr)[0];
+ pixSrcPtr += 2;
+ // a2 r2 g2 b2 a1 r1 g1 b1 => r1..g1..b1..r2..g2..b2
+ pixDstPtr[0] = (pix12 >> 16) & 0xFF;
+ pixDstPtr[1] = (pix12 >> 8) & 0xFF;
+ pixDstPtr[2] = pix12 & 0xFF;
+ pixDstPtr[3] = (pix12 >> 48) & 0xFF;
+ pixDstPtr[4] = (pix12 >> 40) & 0xFF;
+ pixDstPtr[5] = (pix12 >> 32) & 0xFF;
+ pixDstPtr += 6;
+ }
#endif
- for (; col>0;col--) {
- unsigned int pix = *pixSrcPtr++;
+ for (; col>0;col--) {
+ unsigned int pix = *pixSrcPtr++;
#if 0
- pix = ((pix >> 16) & 0x0000FF)|((pix << 16) & 0xFF0000)|(pix & 0x00FF00);
- pixDstPtr[0] = (pix >> 0);
- pixDstPtr[1] = (pix >> 8);
- pixDstPtr[2] = (pix >> 16);
+ pix = ((pix >> 16) & 0x0000FF)|((pix << 16) & 0xFF0000)|(pix & 0x00FF00);
+ pixDstPtr[0] = (pix >> 0);
+ pixDstPtr[1] = (pix >> 8);
+ pixDstPtr[2] = (pix >> 16);
#else
- pixDstPtr[0] = (pix >> 16) & 0xFF;
- pixDstPtr[1] = (pix >> 8) & 0xFF;
- pixDstPtr[2] = pix & 0xFF;
+ pixDstPtr[0] = (pix >> 16) & 0xFF;
+ pixDstPtr[1] = (pix >> 8) & 0xFF;
+ pixDstPtr[2] = pix & 0xFF;
#endif
- pixDstPtr += 3;
- }
- dstRowPtr += c_width * 3;
- srcRowPtr += c_bytesPerRow;
- }
- bytesPerPixel = __MKSMALLINT(3);
- bytesPerRow = __MKSMALLINT( c_width*3 );
- ok = true;
- } else {
- // to be determined what we get...
- ok = false;
- }
- CFRelease(dataref);
- CGImageRelease(image_ref);
+ pixDstPtr += 3;
+ }
+ dstRowPtr += c_width * 3;
+ srcRowPtr += c_bytesPerRow;
+ }
+ bytesPerPixel = __MKSMALLINT(3);
+ bytesPerRow = __MKSMALLINT( c_width*3 );
+ ok = true;
+ } else {
+ // to be determined what we get...
+ ok = false;
+ }
+ CFRelease(dataref);
+ CGImageRelease(image_ref);
- rwidth = __MKUINT( c_width );
- rheight = __MKUINT( c_height );
+ rwidth = __MKUINT( c_width );
+ rheight = __MKUINT( c_height );
}
// the following is no longer supported by apple
@@ -829,7 +844,7 @@
%}.
(ok not or:[rwidth isNil]) ifTrue:[
- ^ self primitiveFailed
+ ^ self primitiveFailed
].
depth := bytesPerPixel * 8.
@@ -837,22 +852,22 @@
"/ withAll:{ rwidth . rheight . bytesPerPixel . depth . bytesPerRow}.
( #(24) includes:depth) ifFalse:[
- "/ check what we get here...
- ^ self primitiveFailed:'unsupported depth'
+ "/ check what we get here...
+ ^ self primitiveFailed:'unsupported depth'
].
img := Image extent:(rwidth @ rheight) depth:depth bits:pixels.
depth == 24 ifTrue:[
- img bitsPerSample:#[8 8 8].
- img samplesPerPixel:3.
- img photometric:#rgb.
+ img bitsPerSample:#[8 8 8].
+ img samplesPerPixel:3.
+ img photometric:#rgb.
] ifFalse:[
- depth == 16 ifTrue:[
- "/ to be determined...
- img bitsPerSample:#[5 5 5].
- img samplesPerPixel:3.
- img photometric:#rgb.
- ].
+ depth == 16 ifTrue:[
+ "/ to be determined...
+ img bitsPerSample:#[5 5 5].
+ img samplesPerPixel:3.
+ img photometric:#rgb.
+ ].
].
^ img
@@ -868,6 +883,22 @@
"Modified: / 01-04-2019 / 00:39:22 / Claus Gittinger"
!
+getMousePosition
+ |xLoc yLoc|
+
+%{
+#ifndef NO_COREGRAPHICS
+ CGEventRef event = CGEventCreate(NULL);
+ CGPoint loc = CGEventGetLocation(event);
+ CFRelease(event);
+
+ xLoc = __MKFLOAT(loc.x);
+ yLoc = __MKFLOAT(loc.y);
+#endif // NO_COREGRAPHICS
+%}.
+ ^ xLoc @ yLoc
+!
+
getScreenBounds:displayNr
"returns the bounds of the screen.
This is needed, because the dimension of the XQuartz screen does not include the dock."
@@ -988,14 +1019,14 @@
map add:( 'default' -> nil ).
VoiceMapping := map.
^ VoiceMapping
-
+
"on OSX, this could be:
- ^ {
- 'male' -> 'Alex' .
- 'female' -> 'Fiona' .
- 'computer' -> 'Zarvox' .
- 'default' -> 'Fiona'
- }
+ ^ {
+ 'male' -> 'Alex' .
+ 'female' -> 'Fiona' .
+ 'computer' -> 'Zarvox' .
+ 'default' -> 'Fiona'
+ }
"
"
@@ -1020,8 +1051,8 @@
|seconds millis nanos|
%{
-// all of the experiments below only return 1us resolution
-// on my machine. Not sure if that has to do with the OSX version (high sierra)
+// all of the experiments below only provide 1us resolution on my machine
+// Not sure if that has to do with the OSX version (high sierra)
// therefore, it is disabled, and we fall back to the inherited method,
// which returns microsecond resolution nanos anyway.
#if 0
@@ -1095,4 +1126,3 @@
version_CVS
^ '$Header$'
! !
-