--- a/OSXOperatingSystem.st Tue Feb 28 09:43:01 2017 +0100
+++ b/OSXOperatingSystem.st Tue Feb 28 09:43:57 2017 +0100
@@ -15,7 +15,7 @@
UnixOperatingSystem subclass:#OSXOperatingSystem
instanceVariableNames:''
- classVariableNames:''
+ classVariableNames:'NSApp'
poolDictionaries:''
category:'OS-Unix'
!
@@ -23,6 +23,8 @@
!OSXOperatingSystem primitiveDefinitions!
%{
+#undef NO_COCOA
+
#ifndef __OSX__
# define NO_QUARTZ
# define NO_COCOA
@@ -60,6 +62,7 @@
#include <ApplicationServices/ApplicationServices.h>
#include <CoreFoundation/CoreFoundation.h>
// #include <Foundation/Foundation.h>
+#include <CoreGraphics/CGEventTypes.h>
#include <stdlib.h>
#include <stdio.h>
@@ -126,7 +129,7 @@
# define Processor __DEF_Processor
# endif
# ifdef __DEF_Class
-# define Class __DEF_Class
+# define STX_Class __DEF_Class
# endif
# ifdef __DEF_FixedPoint
# define FixedPoint __DEF_FixedPoint
@@ -143,7 +146,50 @@
# define INT STX_INT
# define UINT STX_UINT
-#endif // NP_COCOA
+typedef struct CMPoint {
+ double x;
+ double y;
+} CMPoint;
+
+typedef struct CMSize {
+ double width;
+ double height;
+} CMSize;
+
+typedef struct CMRect {
+ CMPoint origin;
+ CMSize size;
+} CMRect;
+
+typedef struct AppDel {
+ Class isa;
+
+ // Will be an NSWindow later.
+ id window;
+} AppDelegate;
+
+
+enum {
+ NSBorderlessWindowMask = 0,
+ NSTitledWindowMask = 1 << 0,
+ NSClosableWindowMask = 1 << 1,
+ NSMiniaturizableWindowMask = 1 << 2,
+ NSResizableWindowMask = 1 << 3,
+};
+
+typedef id(*CMacsSimpleMessage)(id, SEL);
+typedef void(*CMacsVoidMessage)(id, SEL);
+typedef void(*CMacsVoidMessage1)(id, SEL, void *);
+typedef id(*CMacsRectMessage1)(id, SEL, CMRect);
+typedef id(*CMacsWindowInitMessage)(id, SEL, CMRect, int, int, bool);
+
+extern CMacsSimpleMessage cmacs_simple_msgSend;
+extern CMacsVoidMessage cmacs_void_msgSend;
+extern CMacsVoidMessage1 cmacs_void_msgSend1;
+extern CMacsRectMessage1 cmacs_rect_msgSend1;
+extern CMacsWindowInitMessage cmacs_window_init_msgSend;
+
+#endif // NO_COCOA
%}
! !
@@ -170,6 +216,27 @@
return event;
}
+BOOL
+AppDel_didFinishLaunching(AppDelegate *self, SEL _cmd, id notification) {
+// self->window = cmacs_simple_msgSend((id)objc_getClass("NSWindow"), sel_getUid("alloc"));
+//
+// /// Create an instance of the window.
+// self->window = cmacs_window_init_msgSend(self->window, sel_getUid("initWithContentRect:styleMask:backing:defer:"), (CMRect){0,0,1024,460}, (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask), 0, false);
+//
+// /// Create an instance of our view class.
+// ///
+// /// Relies on the view having declared a constructor that allocates a class pair for it.
+// id view = cmacs_rect_msgSend1(cmacs_simple_msgSend((id)objc_getClass("View"), sel_getUid("alloc")), sel_getUid("initWithFrame:"), (CMRect){ 0, 0, 320, 480 });
+//
+// // here we simply add the view to the window.
+// cmacs_void_msgSend1(self->window, sel_getUid("setContentView:"), view);
+// cmacs_simple_msgSend(self->window, sel_getUid("becomeFirstResponder"));
+//
+// // Shows our window in the bottom-left hand corner of the screen.
+// cmacs_void_msgSend1(self->window, sel_getUid("makeKeyAndOrderFront:"), self);
+ return YES;
+}
+
#endif // NO_COCOA
%}
@@ -210,44 +277,43 @@
!OSXOperatingSystem class methodsFor:'cocoa - events'!
-generateButtonEvent:button down:down x:px y:py
+generateButtonEvent:button down:down x:screenX y:screenY
+ "synthesize and send a button event to the screen"
%{
#ifndef NO_COCOA
-# include <CoreGraphics/CGEventTypes.h>
-
- if (__bothSmallInteger(px, py)
+ if (__bothSmallInteger(screenX, screenY)
&& __isSmallInteger(button)) {
- CGPoint pt;
- pt.x = __intVal(px);
- pt.y = __intVal(py);
+ CGPoint pt;
+ pt.x = __intVal(screenX);
+ pt.y = __intVal(screenY);
+
+ CGEventType evType;
+ CGMouseButton evButton = __intVal(button);
- CGEventType evType;
- CGMouseButton evButton = __intVal(button);
-
- switch (evButton) {
- case 1:
- evType = (down == true) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
- evButton = 0;
- break;
- case 2:
- evType = (down == true) ? kCGEventRightMouseDown : kCGEventRightMouseUp;
- evButton = 1;
- break;
- case 3:
- evType = (down == true) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
- evButton = 2;
- break;
- default:
- evType = (down == true) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
- evButton = __intVal(button) - 1;
- break;
- }
-
- CGEventRef theEvent = CGEventCreateMouseEvent(NULL, evType, pt, evButton);
- CGEventSetType(theEvent, evType);
- CGEventPost(kCGHIDEventTap, theEvent);
- CFRelease(theEvent);
- RETURN(self);
+ switch (evButton) {
+ case 1:
+ evType = (down == true) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
+ evButton = 0;
+ break;
+ case 2:
+ evType = (down == true) ? kCGEventRightMouseDown : kCGEventRightMouseUp;
+ evButton = 1;
+ break;
+ case 3:
+ evType = (down == true) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
+ evButton = 2;
+ break;
+ default:
+ evType = (down == true) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
+ evButton = __intVal(button) - 1;
+ break;
+ }
+
+ CGEventRef theEvent = CGEventCreateMouseEvent(NULL, evType, pt, evButton);
+ CGEventSetType(theEvent, evType);
+ CGEventPost(kCGHIDEventTap, theEvent);
+ CFRelease(theEvent);
+ RETURN(self);
}
#endif // NO_COCOA
%}.
@@ -274,23 +340,77 @@
// Create an event tap. We are interested in key presses.
eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
- eventMask, NULL, myCGEventCallback);
+ eventMask, NULL, myCGEventCallback);
if (!eventTap) {
- fprintf(stderr, "failed to create event tap\n");
- } else{
- fprintf(stderr, "ok\n");
+ fprintf(stderr, "failed to create event tap\n");
+ } else {
+ fprintf(stderr, "ok\n");
+
+ // Create a run loop source.
+ runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, eventTap, 0);
+ // Enable the event tap.
+ CGEventTapEnable(eventTap, true);
}
- // Create a run loop source.
- runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, eventTap, 0);
- // Enable the event tap.
- CGEventTapEnable(eventTap, true);
-
#endif // NO_COCOA
%}.
self primitiveFailed
"Modified: / 28-02-2017 / 01:05:04 / cg"
+!
+
+getNSApp
+%{
+#ifndef NO_COCOA
+ Class AppDelClass = NULL;
+ id NSApp = NULL;
+
+ AppDelClass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "AppDelegate", 0);
+ class_addMethod(AppDelClass, sel_getUid("applicationDidFinishLaunching:"), (IMP)AppDel_didFinishLaunching, "i@:@");
+ objc_registerClassPair(AppDelClass);
+
+ NSApp = objc_msgSend((id)objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
+ if (NSApp == NULL) {
+ fprintf(stderr,"OSX: Failed to initialize NSApplication.\n");
+ RETURN(false);
+ }
+ @global(NSApp) = __MKEXTERNALADDRESS(NSApp);
+
+ id appDelObj = objc_msgSend((id)objc_getClass("AppDelegate"), sel_getUid("alloc"));
+ appDelObj = objc_msgSend(appDelObj, sel_getUid("init"));
+
+ objc_msgSend(NSApp, sel_getUid("setDelegate:"), appDelObj);
+ RETURN(true);
+#endif // NO_COCOA
+%}.
+ self primitiveFailed
+
+ "
+ self getNSApp
+ "
+
+ "Modified (comment): / 28-02-2017 / 01:35:31 / cg"
+!
+
+finishLaunching
+ NSApp isNil ifTrue:[
+ self getNSApp
+ ].
+%{
+#ifndef NO_COCOA
+ id NSApp = __externalAddressVal(@global(NSApp));
+
+ objc_msgSend(NSApp, sel_getUid("finishLaunching"));
+ RETURN(self);
+#endif // NO_COCOA
+%}.
+ self primitiveFailed
+
+ "
+ self finishLaunching
+ "
+
+ "Modified (comment): / 28-02-2017 / 01:35:31 / cg"
! !
!OSXOperatingSystem class methodsFor:'dummy shell operations'!
@@ -453,72 +573,77 @@
!
getFrameBufferImage:displayNr in:aRectangleOrNil
- "returns the framebuffer as an image object"
+ "returns the frameBuffer (if rect-arg is nil)
+ or part of the framebuffer (if non-nil) as an image object"
- |rx ry rwidth rheight bytesPerPixel bytesPerRow address pixels depth pad img|
+ |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_QUARTZ
CGImageRef image_ref;
CGDirectDisplayID displayID = CGMainDisplayID();
-
+
+ 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 = 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 = CFDataGetBytePtr(dataref);
- pixels = __BYTEARRAY_UNINITIALIZED_NEW_INT(c_width * c_height * c_bytesPerPixel);
+ pixels = __BYTEARRAY_UNINITIALIZED_NEW_INT(c_width * c_height * c_bytesPerPixel);
- if (c_bytesPerPixel == 4) {
- int row;
- unsigned char *srcRowPtr = c_pixels;
- unsigned char *dstRowPtr = __byteArrayVal(pixels);
-
- for (row=c_height; row>0; row--) {
- int col;
- unsigned int *pixSrcPtr = (int*)srcRowPtr;
- unsigned int *pixDstPtr = (int*)dstRowPtr;
-
- // swap abgr to argb
- for (col=c_width; col>0;col--) {
- unsigned int pix = *pixSrcPtr++;
+ if (c_bytesPerPixel == 4) {
+ int row;
+ unsigned char *srcRowPtr = c_pixels;
+ unsigned char *dstRowPtr = __byteArrayVal(pixels);
+
+ for (row=c_height; row>0; row--) {
+ int col;
+ unsigned int *pixSrcPtr = (int*)srcRowPtr;
+ unsigned int *pixDstPtr = (int*)dstRowPtr;
+
+ // swap abgr to argb
+ for (col=c_width; col>0;col--) {
+ unsigned int pix = *pixSrcPtr++;
- pix = ((pix >> 16) & 0x0000FF)|((pix << 16) & 0xFF0000)|(pix & 0x00FF00);
- *pixDstPtr++ = pix;
- }
- dstRowPtr += c_width * c_bytesPerPixel;
- srcRowPtr += c_bytesPerRow;
- }
- } else {
- }
- CFRelease(dataref);
- CGImageRelease(image_ref);
+ pix = ((pix >> 16) & 0x0000FF)|((pix << 16) & 0xFF0000)|(pix & 0x00FF00);
+ *pixDstPtr++ = pix;
+ }
+ dstRowPtr += c_width * c_bytesPerPixel;
+ srcRowPtr += c_bytesPerRow;
+ }
+ ok = true;
+ } else {
+ // to be determined what we get...
+ ok = false;
+ }
+ CFRelease(dataref);
+ CGImageRelease(image_ref);
- rwidth = __MKUINT( c_width );
- rheight = __MKUINT( c_height );
- bytesPerPixel = __MKUINT( c_bytesPerPixel );
- bytesPerRow = __MKUINT( c_bytesPerRow );
+ rwidth = __MKUINT( c_width );
+ rheight = __MKUINT( c_height );
+ bytesPerPixel = __MKUINT( c_bytesPerPixel );
+ bytesPerRow = __MKUINT( c_bytesPerRow );
}
// the following is no longer supported by apple
@@ -534,21 +659,21 @@
// rwidth = __MKUINT( CGDisplayPixelsWide(targetDisplay) );
// rheight = __MKUINT( CGDisplayPixelsHigh(targetDisplay) );
//
-
+
#endif // NO_QUARTZ
%}.
- rwidth isNil ifTrue:[
- ^ self primitiveFailed
+ (ok not or:[rwidth isNil]) ifTrue:[
+ ^ self primitiveFailed
].
depth := bytesPerPixel * 8.
- "/ Transcript printf:'w:%d h:%d bpp:%d depth:%d bpr: %d\n'
+ "/ Transcript printf:'w:%d h:%d bpp:%d depth:%d bpr: %d\n'
"/ withAll:{ rwidth . rheight . bytesPerPixel . depth . bytesPerRow}.
( #(16 32) 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.
@@ -576,4 +701,3 @@
version_CVS
^ '$Header$'
! !
-