From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- plot/osx/Jamfile | 21 +++ plot/osx/Readme.txt | 1 + plot/osx/acoccoa.h | 402 ++++++++++++++++++++++++++++++++++++++++++++++++++++ plot/osx/helloc.c | 313 ++++++++++++++++++++++++++++++++++++++++ plot/osx/hellom.m | 181 +++++++++++++++++++++++ 5 files changed, 918 insertions(+) create mode 100644 plot/osx/Jamfile create mode 100644 plot/osx/Readme.txt create mode 100644 plot/osx/acoccoa.h create mode 100644 plot/osx/helloc.c create mode 100644 plot/osx/hellom.m (limited to 'plot/osx') diff --git a/plot/osx/Jamfile b/plot/osx/Jamfile new file mode 100644 index 0000000..933d56d --- /dev/null +++ b/plot/osx/Jamfile @@ -0,0 +1,21 @@ + +# Jamfile for OS X window code development + +#PREF_CCFLAGS = $(CCOPTFLAG) ; # Turn optimisation on +PREF_CCFLAGS = $(CCDEBUGFLAG) ; # Debugging flags +#PREF_CCFLAGS += -x objective-c ; +PREF_LINKFLAGS = $(LINKDEBUGFLAG) ; + +# Hello world +#Main hello : hello.m ; + +# Hello world window in C +Main helloc : helloc.c ; + +# Hello world window in Objective-C +ObjectCcFlags hellom : -ObjC ; +Main hellom : hellom.m ; + +#GuiBin tt ; +#Main tt : tt.m ; + diff --git a/plot/osx/Readme.txt b/plot/osx/Readme.txt new file mode 100644 index 0000000..44b083b --- /dev/null +++ b/plot/osx/Readme.txt @@ -0,0 +1 @@ +Develop Cocoa based simple window code. diff --git a/plot/osx/acoccoa.h b/plot/osx/acoccoa.h new file mode 100644 index 0000000..ba88cd4 --- /dev/null +++ b/plot/osx/acoccoa.h @@ -0,0 +1,402 @@ + +#ifndef ACOCCOA_H + +/* OS X Coccoa support code for Argyll. */ +/* In some places we really prefer not to have OS X code */ +/* in separate .m files, so we'll do it all from C. */ + +#include + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 +# include +# include +#else +# include + +/* Objective-C runtime compatibility functions for < 10.5 */ + +/* Create a class definition, but don't register it */ +Class CreateClassDefinition(const char *name, const char *superclassName) { + struct objc_class *meta_class; + struct objc_class *super_class; + struct objc_class *new_class; + struct objc_class *root_class; + + // Ensure that the superclass exists and that someone + // hasn't already implemented a class with the same name + // + super_class = (struct objc_class *)objc_lookUpClass(superclassName); + if (super_class == nil) { + printf("failed to lookup '%s'\n",superclassName); + return Nil; + } + + if (objc_lookUpClass(name) != nil) { + return Nil; + } + + // Find the root class + root_class = super_class; + while(root_class->super_class != nil) + root_class = root_class->super_class; + + // Allocate space for the class and its metaclass + if ((new_class = calloc(2, sizeof(struct objc_class))) == NULL) { + return Nil; + } + meta_class = &new_class[1]; + + // setup class + new_class->isa = meta_class; + new_class->info = CLS_CLASS; + meta_class->info = CLS_META; + + // Create a copy of the class name. + // For efficiency, we have the metaclass and the class itself + // to share this copy of the name, but this is not a requirement + // imposed by the runtime. + if ((new_class->name = strdup(name)) == NULL) { + free(new_class); + } + meta_class->name = new_class->name; + + // Allocate empty method lists. + // We can add methods later. + if ((new_class->methodLists = calloc( 1, sizeof(struct objc_method_list *))) == NULL) { + free((void *)new_class->name); + free(new_class); + return Nil; + } + *new_class->methodLists = (struct objc_method_list *) -1; + if ((meta_class->methodLists = calloc(1, sizeof(struct objc_method_list *))) == NULL) { + free(new_class->methodLists); + free((void *)new_class->name); + free(new_class); + return Nil; + } + *meta_class->methodLists = (struct objc_method_list *) -1; + + // Connect the class definition to the class hierarchy: + // Connect the class to the superclass. + // Connect the metaclass to the metaclass of the superclass. + // Connect the metaclass of the metaclass to the metaclass of the root class. + new_class->super_class = super_class; + meta_class->super_class = super_class->isa; + meta_class->isa = (void *)root_class->isa; + + // Set the sizes of the class and the metaclass. + new_class->instance_size = super_class->instance_size; + meta_class->instance_size = meta_class->super_class->instance_size; + + return new_class; +} + +/* Add an array of methods. Null terminated by name array */ +/* We assume that the class is being created, and that there are */ +/* no existing methods. */ +BOOL registerDynamicMethods(Class cls, const char *mnames[], IMP mimps[], const char *mtypes[]) { + int i, nmeth; + struct objc_method_list *methodList; + + /* Count the number of methods */ + for (nmeth = 0; mnames[nmeth] != NULL && mnames[nmeth][0] != '\000'; nmeth++) + ; + + /* Allocate an array */ + methodList = malloc(sizeof(struct objc_method_list) + (nmeth-1) * sizeof(struct objc_method)); + + methodList->method_count = nmeth; + for (i = 0; i < nmeth; i++) { + // Get or register the selector for the method name + SEL methodSEL = SELUID(mnames[i]); + + // Registering the method seems to register the selector + if (ISSELECTOR(methodSEL) == NO) { + methodSEL = sel_registerName(mnames[i]); + } + + // Fill out the method list + methodList->method_list[i].method_name = methodSEL; + methodList->method_list[i].method_imp = mimps[i]; + methodList->method_list[i].method_types = strdup(mtypes[i]); + } + + // Register our methods + class_addMethods((Class)cls, methodList); + + return YES; +} + +/* Add an array of instance variables. Null terminated by name array */ +/* We assume that the class is being created, and that there are */ +/* no existing methods. */ +BOOL registerDynamicVariables(Class cls, const char *names[], size_t sizes[], const char *types[]) { + int i, nvar = 1; + int vsize; + struct objc_ivar *ivarp; + + /* Count the number of variables */ + for (nvar = 0; names[nvar] != NULL && names[nvar][0] != '\000'; nvar++) + ; + + vsize = sizeof(struct objc_ivar_list) + (nvar - 1) * sizeof(struct objc_ivar); + cls->ivars = calloc(vsize, 1); + cls->ivars->ivar_count = nvar; + + for (i = 0; i < nvar; i++) { + int abytes; + ivarp = &cls->ivars->ivar_list[i]; + + /* Set the variable information */ + ivarp->ivar_name = strdup(names[i]); + ivarp->ivar_type = strdup(types[i]); + + /* Align the offset for this variable to it's size, limiting to 64 bits */ + if ((abytes = sizes[i]) > 8) + abytes = 8; + cls->instance_size = (cls->instance_size + abytes-1) & ~(abytes-1); + ivarp->ivar_offset = (int)cls->instance_size; + cls->instance_size += sizes[i]; + } + + return YES; +} + +#endif /* __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 */ + +extern id NSApp; + +/* Create a class */ +BOOL registerClass( +const char *name, /* Name of class being created */ +const char *supername, /* Name of superclass */ +const char *methnames[], /* List of method names, empty string terminated */ +IMP methimps[], /* Method implementations */ +const char *methsigs[], /* Method signatures */ +const char *varnames[], /* List of variable names, empty string terminated */ +size_t varsizes[], /* Variable size in bytes */ +const char *varsigs[] /* Variable signatures */ +) { + int i; + Class nclass; + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 + nclass = objc_allocateClassPair((Class)objc_getClass(supername), name, 0); + if (nclass == Nil) { + return NO; + } + + for (i = 0; methnames[i] != NULL && methnames[i][0] != '\000'; i++) { + class_addMethod(nclass, sel_getUid(methnames[i]), methimps[i], methsigs[i]); + } + + // Should check return value is YES + for (i = 0; varnames[i] != NULL && varnames[i][0] != '\000'; i++) { + int asize; + while( (1 << asize) < varsizes[i] && asize < 8) + asize++; + class_addIvar(nclass, varnames[i], varsizes[i], asize, varsigs[i]); + } + + // Must be called after adding instance variable + objc_registerClassPair(nclass); +#else + /* Use compat.h functions to do the dirty work */ + // Should check the return value! + if ((nclass = CreateClassDefinition(name, supername)) == Nil) { + return NO; + } + + registerDynamicMethods(nclass, methnames, methimps, methsigs); + + registerDynamicVariables(nclass, varnames, varsizes, varsigs); + + // Register the class with the runtime. + objc_addClass(nclass); +#endif + return YES; +} + +/* ------------------------------------------------ */ +/* One of the primary disadvantages of coding Coccoa in C */ +/* is the lack of compatible .h files. We have to make our own.. */ + +/* ------------------------------------------------ */ + +/* Foundation stuff */ + +#ifndef __OBJC__ + +#if !defined(FSTATIC_INLINE) +# if defined (__GNUC__) && (__GNUC__ == 4) +# define FSTATIC_INLINE static __inline__ __attribute__((always_inline)) +# else +# define FSTATIC_INLINE static __inline__ +# endif +#endif + +#ifdef __LP64__ +typedef double NSFloat; +#else +typedef float NSFloat; +#endif + +typedef struct _NSPoint { + NSFloat x; + NSFloat y; +} NSPoint; + +FSTATIC_INLINE NSPoint NSMakePoint(NSFloat x, NSFloat y) { + NSPoint r; + r.x = x; + r.y = y; + return r; +} + +typedef struct _NSSize { + NSFloat width; + NSFloat height; +} NSSize; + +FSTATIC_INLINE NSSize NSMakeSize(NSFloat w, NSFloat h) { + NSSize r; + r.width = w; + r.height = h; + return r; +} + + +typedef struct _NSRect { + NSPoint origin; + NSSize size; +} NSRect; + +FSTATIC_INLINE NSRect NSMakeRect(NSFloat x, NSFloat y, NSFloat w, NSFloat h) { + NSRect r; + r.origin.x = x; + r.origin.y = y; + r.size.width = w; + r.size.height = h; + return r; +} + +#endif /* !__OBJC__ */ + +/* ------------------------------------------------ */ +/* Constats for NSString class */ + +/* 10.4 and latter */ +typedef enum { + NSStringDrawingUsesLineFragmentOrigin = (1 << 0), + NSStringDrawingUsesFontLeading = (1 << 1), + NSStringDrawingDisableScreenFontSubstitution = (1 << 2), + NSStringDrawingUsesDeviceMetrics = (1 << 3), + NSStringDrawingOneShot = (1 << 4), + NSStringDrawingTruncatesLastVisibleLine = (1 << 5) +} NSStringDrawingOptions; + +/* ------------------------------------------------ */ +/* Constats for NSApplication class */ + +typedef enum { + NSApplicationPresentationDefault = 0, + NSApplicationPresentationAutoHideDock = (1 << 0), + NSApplicationPresentationHideDock = (1 << 1), + NSApplicationPresentationAutoHideMenuBar = (1 << 2), + NSApplicationPresentationHideMenuBar = (1 << 3), + NSApplicationPresentationDisableAppleMenu = (1 << 4), + NSApplicationPresentationDisableProcessSwitching = (1 << 5), + NSApplicationPresentationDisableForceQuit = (1 << 6), + NSApplicationPresentationDisableSessionTermination = (1 << 7), + NSApplicationPresentationDisableHideApplication = (1 << 8), + NSApplicationPresentationDisableMenuBarTransparency = (1 << 9), + NSApplicationPresentationFullScreen = (1 << 10), + NSApplicationPresentationAutoHideToolbar = (1 << 11) +} NSApplicationPresentationOptions; + +typedef enum { + NSTerminateCancel = 0, + NSTerminateNow = 1, + NSTerminateLater = 2 +} NSApplicationTerminateReply; + +/* ------------------------------------------------ */ +/* Constats for NSWindow class */ + +enum { + NSBorderlessWindowMask = 0, + NSTitledWindowMask = 1 << 0, + NSClosableWindowMask = 1 << 1, + NSMiniaturizableWindowMask = 1 << 2, + NSResizableWindowMask = 1 << 3, + NSTexturedBackgroundWindowMask = 1 << 8 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + ,NSUnscaledWindowMask = 1 << 11, + NSUnifiedTitleAndToolbarWindowMask = 1 << 12 +#endif +}; + +/* types of window backing store */ +typedef enum { + NSBackingStoreRetained = 0, + NSBackingStoreNonretained = 1, + NSBackingStoreBuffered = 2 +} NSBackingStoreType; + + +/* ------------------------------------------------ */ +/* Convenience functions */ + +/* Transform process to interact with descktop */ +void transProcess() { + OSStatus stat; + ProcessSerialNumber psn = { 0, 0 }; + + if (GetCurrentProcess(&psn) != noErr) { + /* Transform the process so that the desktop interacts with it properly. */ + /* We don't need resources or a bundle if we do this. */ + if (psn.lowLongOfPSN != 0 && (stat = TransformProcessType(&psn, + kProcessTransformToForegroundApplication)) != noErr) + fprintf(stderr,"TransformProcess failed with code %d\n",stat); + } +} + +/* Send a message to the object */ +#define sendMsg(oid, msg, ...) objc_msgSend(oid, sel_getUid(msg), ##__VA_ARGS__) + +/* alloc and init a new object */ +id newObject(const char *cname) { + id rv; + rv = objc_msgSend(objc_getClass(cname), sel_getUid("alloc")); + rv = objc_msgSend(rv, sel_getUid("init")); + return rv; +} +/* release an object */ +void delObject(id oid) { + objc_msgSend(oid, sel_getUid("release")); +} + +/* dealloc super */ +void delObjectSuper(id oid) { + struct objc_super ss; + ss.receiver = oid; +#ifdef __OBJC__ + ss.super_class = sendMsg(oid, "superclass"); +#else + ss.class = (Class)sendMsg(oid, "superclass"); +#endif + objc_msgSendSuper(&ss, sel_getUid("dealloc")); +} + +/* Create an NSString from a C string */ +id newNSString(const char *cstr) { + id str; + + str = objc_msgSend(objc_getClass("NSString"), sel_getUid("alloc")); + str = objc_msgSend(str, sel_getUid("initWithUTF8String:"), cstr); + + return str; +} + +#define ACOCCOA_H +#endif /* ACOCCOA_H */ diff --git a/plot/osx/helloc.c b/plot/osx/helloc.c new file mode 100644 index 0000000..9150989 --- /dev/null +++ b/plot/osx/helloc.c @@ -0,0 +1,313 @@ + +#include +#include +#include + +#ifdef __OBJC__ +# include +# include +#endif + +#include "acocoa.h" /* Argyll Cocoa support functions and defines */ + +/* +- (void) someMethod:... +{ + va_list va; + + va_start(va, _cmd); + + // process all args with va_arg + + va_end(va); +} + */ + +/* Our static instance variables for AppDelegate */ +typedef struct { + id window; /* NSWindow */ + id view; /* NSView */ +} cntx_t; + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +void MyView_setCntx(id self, SEL _cmd, void *val) { + object_setInstanceVariable(self, "cntx", val); +} + +void MyView_drawRect(id self, SEL _cmd, NSRect rect) { + double w = rect.size.width, h = rect.size.height; + + id aPath = sendClassMsg("NSBezierPath", "bezierPath"); + sendMsg(aPath, "setLineWidth:", 2.0); + sendMsg(aPath, "moveToPoint:", NSMakePoint(0.0, 0.0)); + sendMsg(aPath, "lineToPoint:", NSMakePoint(0.9 * w, 0.9 * h)); + sendMsg(aPath, "appendBezierPathWithRect:", NSMakeRect(0.5 * w, 0.5 * h, + 0.7 * w, 0.6 * h)); + sendMsg(aPath, "stroke"); + + { + id att = newObject("NSDictionary"); + id str = newNSString("String"); + sendMsg(str, "drawAtPoint:withAttributes:", NSMakePoint(0.1 * w, 0.1 * h), att); + } +} + +/* Clean up */ +void MyView_dealloc(id self, SEL _cmd) { + delObjectSuper(self); +} + +// Create our custom NSView */ +void createMyView() { + method_info minfo[] = { + { "setCntx:", (IMP)MyView_setCntx, "v@:^v" }, + { "drawRect:", (IMP)MyView_drawRect, "v@:@" }, + { "dealloc", (IMP)MyView_dealloc, "v@:" }, + { "" } + }; + + variable_info vinfo[] = { + { "cntx", sizeof(void *), "^v" }, + { "" } + }; + + registerClass("MyView", "NSView", minfo, vinfo); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +void MyWin_setCntx(id self, SEL _cmd, void *val) { + object_setInstanceVariable(self, "cntx", val); +} + +void MyWin_keyDown(id self, SEL _cmd, id event) { + int etype; + id nresp; + id str; + const char *cstr; + + etype = (int)sendMsg(event, "type"); + str = sendMsg(event, "characters"); + cstr = cNSString(str); + printf("Got Window KeyDown type %d, chars '%s'\n",etype, cstr); + + if (cstr[0] == ' ') + sendMsg(NSApp, "terminate:", self); +} + +/* Clean up */ +void MyWin_dealloc(id self, SEL _cmd) { + delObjectSuper(self); +} + +// Create our custom NSWin */ +void createMyWin() { + method_info minfo[] = { + { "setCntx:", (IMP)MyWin_setCntx, "v@:^v", }, + { "keyDown:", (IMP)MyWin_keyDown, "v@:@", }, + { "dealloc", (IMP)MyWin_dealloc, "v@:" }, + { "" } + }; + + variable_info vinfo[] = { + { "cntx", sizeof(void *), "^v" }, + { "" } + }; + + registerClass("MyWin", "NSWindow", minfo, vinfo); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +/* Create all the bits */ +void AppDel_willFinishLaunching(id self, SEL _cmd, id notification) { + cntx_t *cx; + id label; /* NSTextField */ + + cx = calloc(1, sizeof(cntx_t)); + + // Set cntx to to allocated structure + object_setInstanceVariable(self, "cntx", (void *)cx); + + /* Create Window */ + cx->window = sendClassMsg("MyWin", "alloc"); + cx->window = sendMsg(cx->window, + "initWithContentRect:styleMask:backing:defer:", + NSMakeRect(300, 300, 200, 100), + NSTitledWindowMask + | NSClosableWindowMask + | NSMiniaturizableWindowMask + | NSResizableWindowMask, + NSBackingStoreBuffered, + YES); + + /* Make the background white */ + sendMsg(cx->window, "setBackgroundColor:", sendClassMsg("NSColor","whiteColor")); + + /* Add title */ + sendMsg(cx->window, "setTitle:", newNSString("Hello World")); + +#ifdef NEVER + /* Create Label */ + label = sendClassMsg("NSTextField", "alloc"); + label = sendMsg(label, "initWithFrame:", NSMakeRect(30, 30, 80, 30)); + + sendMsg(label, "setSelectable:", NO); + sendMsg(label, "setBezeled:", NO); + sendMsg(label, "setDrawsBackground:", NO); + sendMsg(label, "setStringValue:", newNSString("Hello World")); + + /* Hmm. How does this work ? */ + cx->view = sendMsg(cx->window, "contentView"); + sendMsg(cx->view, "addSubview:", label); +#else + /* Use our custom view to draw contents */ + cx->view = newObject("MyView"); + + sendMsg(cx->view, "setCntx:", (void *)cx); + sendMsg(cx->window, "setContentView:", cx->view); + +// sendMsg(cx->window, "setInitialFirstResponder:", cx->view); +#endif + + // Window methods: + + // sendEvent: gets messages. + + // Set above the screen saver + // [aWindow setLevel:NSScreenSaverWindowLevel + 1]; + + // setCollectionBehavior: NSWindowCollectionBehaviorIgnoresCycle + // NSWindowCollectionBehaviorFullScreenPrimary + // NSWindowCollectionBehaviorStationary + // NSWindowCollectionBehaviorIgnoresCycle + + // center + // mouseDownCanMoveWindow + // setMovable: + // setContentMinSize: and setContentMaxSize: + // + // NSRect frame = [myWindow frame]; + // if (frame.size.width <= MIN_WIDTH_WITH_ADDITIONS) + // frame.size.width = MIN_WIDTH_WITH_ADDITIONS; + // frame.size.height += ADDITIONS_HEIGHT; + // frame.origin.y -= ADDITIONS_HEIGHT; + // [myWindow setFrame:frame display:YES animate:YES]; + // objc_msgSend(label, "release")); + // + // setExcludedFromWindowsMenu:YES + // + // setBackgroundColor: and setAlphaValue: + + // WindowImage object: + // setDepthLimit: + + // Setting cursor: + // NSTrackingArea class, along with the cursorUpdate: method of the NSResponder class + +} + +/* Map the window */ +void AppDel_didFinishLaunching(id self, SEL _cmd, id notification) { + cntx_t *cx; + + object_getInstanceVariable(self, "cntx", (void **)&cx); + sendMsg(cx->window, "makeKeyAndOrderFront:", self); + +#ifdef NEVER /* Test terminate */ + sleep(5); + sendMsg(NSApp, "terminate:", self); +#endif +} + +/* Should the application terminate ? */ +NSApplicationTerminateReply AppDel_shouldTerminate(id self, SEL _cmd, id notification) { + return NSTerminateNow; +} + +/* Clean up */ +void AppDel_dealloc(id self, SEL _cmd) { + cntx_t *cx; + + object_getInstanceVariable(self, "cntx", (void **)&cx); + delObject(cx->window); + delObjectSuper(self); +} + +// Create the delegate class that implements our window +void createAppDelClass() { + method_info minfo[] = { + { "applicationWillFinishLaunching:", (IMP)AppDel_willFinishLaunching, "v@:@" }, + { "applicationDidFinishLaunching:", (IMP)AppDel_didFinishLaunching, "v@:@" }, + { "applicationShouldTerminate:", (IMP)AppDel_shouldTerminate, "i@:@" }, + { "dealloc", (IMP)AppDel_dealloc, "v@:" }, + { "" } + }; + + variable_info vinfo[] = { + { "cntx", sizeof(void *), "^v" }, + { "" } + }; + + registerClass("AppDelegate", "NSObject", minfo, vinfo); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - */ +int main(int argc, char** argv) { + id pool; + id appDelObj; + + /* Transform process so that it interacts with desktop properly */ + transProcess(); + + /* Create an autorelease pool */ + pool = newObject("NSAutoreleasePool"); + + // Create all the classes we override + createAppDelClass(); + createMyWin(); + createMyView(); + + // Get our shared NSApplication and start it + sendClassMsg("NSApplication", "sharedApplication"); + + if (NSApp == NULL) { + fprintf(stderr,"Failed to initialized NSApplication... terminating...\n"); + return -1; + } + + /* Set a delegate to create the window */ + appDelObj = newObject("AppDelegate"); + sendMsg(NSApp, "setDelegate:", appDelObj); + +// if running on 10.7: +// sendMsg(NSApp, "disableRelaunchOnLogin")); + + /* Call the run loop */ + sendMsg(NSApp, "run"); + + // detachDrawingThread:toTarget:withObject: + + /* To terminate: + sendMsg(NSApp, "terminate:", self); + */ + + /* We're done with the pool */ + delObject(pool); + + return EXIT_SUCCESS; +} + +#ifdef NEVER + +- (void)drawRect:(NSRect)rect +{ + NSRect r = NSMakeRect(10, 10, 50, 60); + NSBezierPath *bp = [NSBezierPath bezierPathWithRect:r]; + NSColor *color = [NSColor blueColor]; + [color set]; + [bp fill]; +} + +#endif diff --git a/plot/osx/hellom.m b/plot/osx/hellom.m new file mode 100644 index 0000000..b306878 --- /dev/null +++ b/plot/osx/hellom.m @@ -0,0 +1,181 @@ + +#include +#include + +#include /* For diagnostics */ + +typedef struct { + id window; /* NSWindow */ + id view; /* NSTextField */ +} cntx_t; + +// - - - - - - - - - - - - - - - - - - - - - - - - - +@interface MyView : NSView { + void *cntx; +} +- (void)setCntx:(void *)cntx; +@end + +@implementation MyView + +- (void)setCntx:(void *)val { + cntx = val; +} + +- (void)drawRect:(NSRect)rect { +// NSGraphicsContext* aContext = [NSGraphicsContext currentContext]; + + [[NSColor redColor] setStroke]; + + NSBezierPath* aPath = [NSBezierPath bezierPath]; + [aPath setLineWidth:2.0]; + [aPath moveToPoint:NSMakePoint(0.0, 0.0)]; + [aPath lineToPoint:NSMakePoint(100.0, 100.0)]; + [aPath appendBezierPathWithRect:NSMakeRect(20.0, 160.0, 80.0, 50.0)]; + + [aPath stroke]; + + NSDictionary *att = [NSDictionary new]; + + [ @"String" drawAtPoint: NSMakePoint(10.0, 10.0) withAttributes: att ]; + +/* + +[@"Hello" drawInRect:r withAttributes:[NSDictionary +dictionaryWithObjectsAndKeys: +[NSColor redColor], NSForegroundColorAttributeName, +[NSFont systemFontOfSize:24], NSFontAttributeName, +nil]]; + +*/ +} + +@end + +/* To trigger an update: + +Send a setNeedsDisplayInRect: or setNeedsDisplay: message to the +view. Sending either of these messages marks part or all of the view as invalid + + */ + +// - - - - - - - - - - - - - - - - - - - - - - - - - + +@interface MyWin : NSWindow { + void *cntx; +} +- (void)setCntx:(void *)cntx; +@end + +@implementation MyWin + +- (void)setCntx:(void *)val { + cntx = val; +} + +- (void)keyDown:(NSEvent *)event { + printf("Got Window KeyDown type %d char %s\n",[event type], + [[event characters] cStringUsingEncoding:NSASCIIStringEncoding]); +} + +- (BOOL)windowShouldClose:(id)sender { + printf("Got Window windowShouldClose\n"); + [NSApp terminate: nil]; + return YES; +} + +@end + +// - - - - - - - - - - - - - - - - - - - - - - - - - + +@interface AppDelegate : NSObject { + void *cntx; +} +@end + +@implementation AppDelegate +- (void) applicationWillFinishLaunching: (NSNotification *)not { + cntx_t *cx; + + cx = calloc(1, sizeof(cntx_t)); + + cntx = (void *)cx; + + /* Create Window */ + cx->window = [[MyWin alloc] initWithContentRect: NSMakeRect(300, 300, 200, 100) + styleMask: (NSTitledWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask) + backing: NSBackingStoreBuffered + defer: YES]; + [cx->window setTitle: @"Hello World"]; + +#ifdef NEVER + /* Create Label */ + cx->label = [[NSTextField alloc] initWithFrame: NSMakeRect(30, 30, 80, 30)]; + [cx->label setSelectable: NO]; + [cx->label setBezeled: NO]; + [cx->label setDrawsBackground: NO]; + [cx->label setStringValue: @"Hello World"]; + + [[cx->window contentView] addSubview: cx->label]; + + [cx->label release]; + +#else + cx->view = [MyView new]; + [cx->view setCntx:(void *)cx]; + [cx->window setContentView: cx->view]; +#endif + // [window setContentView:customView] +} + +- (void) applicationDidFinishLaunching: (NSNotification *) not { + cntx_t *cx = (cntx_t *)cntx; + [cx->window makeKeyAndOrderFront: self]; +} + +- (void) dealloc { + cntx_t *cx = (cntx_t *)cntx; + [cx->window release]; + [super dealloc]; +} +@end + +// - - - - - - - - - - - - - - - - - - - - - - - - - + +int main (int argc, const char **argv) +{ + NSAutoreleasePool *pool; + id appDelObj; + + if (NSApp == nil) { + OSStatus stat; + ProcessSerialNumber psn = { 0, 0 }; + + if (GetCurrentProcess(&psn) == noErr) { + /* Transform the process so that the desktop interacts with it properly. */ + /* We don't need resources or a bundle if we do this. */ + if (psn.lowLongOfPSN != 0 && (stat = TransformProcessType(&psn, + kProcessTransformToForegroundApplication)) != noErr) + fprintf(stderr,"TransformProcess failed with code %d\n",stat); + } + + pool = [NSAutoreleasePool new]; + + [NSApplication sharedApplication]; + appDelObj = [AppDelegate new]; + [NSApp setDelegate: appDelObj]; + + // Run the event loop until done + [NSApp run]; + + [pool release]; + } + + // To terminate: + // [NSApp terminate: nil]; +} + + -- cgit v1.2.3