[AQT-commit] CVS: adapters/c c2aqt.h,NONE,1.1 c2aqt.m,NONE,1.1 test.c,NONE,1.1
Brought to you by:
persquare
From: Per P. <per...@us...> - 2002-04-24 14:06:44
|
Update of /cvsroot/aquaterm/adapters/c In directory usw-pr-cvs1:/tmp/cvs-serv12767/c Added Files: c2aqt.h c2aqt.m test.c Log Message: Adding a C example based on a generic adapter. Up-to-date with AQTProtocol v0.3. This is a first step towards a unified adapter strategy. --- NEW FILE: c2aqt.h --- void aqtInit(void); // --- void aqtOpenGraph(int n); void aqtCloseGraph(void); void aqtRenderGraph(void); void aqtSetTitle(char *title); // --- void aqtUseColor(int col); void aqtSetColormapEntry(int col, float r, float g, float b); // --- void aqtUseLinewidth(float width); void aqtAddLine(float x1, float y1, float x2, float y2); void aqtAddPolygon(float *x, float *y, int n, int isFilled); void aqtAddCircle(float x, float y, float radius, int isFilled); // --- void aqtUseFont(char *fontname, float size); void aqtUseTextOrientation(int orient); void aqtUseTextJustification(int just); void aqtAddText(float x, float y, const char *str); // --- void aqtAddImageFromFile(char *filename, float x, float y, float w, float h); // --- void aqtGetSize(float *x_max, float *y_max); --- NEW FILE: c2aqt.m --- #import <Foundation/Foundation.h> #import <AppKit/AppKit.h> #import "AQTProtocol.h" #include "c2aqt.h" // // static NSAutoreleasePool *arpool; // Objective-C autorelease pool static id adapter; // Adapter object // // ---------------------------------------------------------------- // --- Objective-C Adapter for AquaTerm // ---------------------------------------------------------------- // // First we need some Cocoa magic incantations, documented at: // http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/DistrObjects/ // Look under "Making Substitutions During Message Encoding" // // The class NSBezierPath doesn't implement replacementObjectForPortCoder so // we add that behaviour as a category for NSBezierPath // @interface NSBezierPath (NSBezierPathDOCategory) -(id)replacementObjectForPortCoder:(NSPortCoder *)portCoder; @end @implementation NSBezierPath (NSBezierPathDOCategory) -(id)replacementObjectForPortCoder:(NSPortCoder *)portCoder { if ([portCoder isBycopy]) return self; return [super replacementObjectForPortCoder:portCoder]; } @end // // ---------------------------------------------------------------- // --- AQTAdapter - A class to mediate between C-function calls // --- and AquaTerm Objective-C remote messages // ---------------------------------------------------------------- // @interface AQTAdapter : NSObject { NSBezierPath *filledPathBuffer; NSBezierPath *pathBuffer; NSMutableDictionary *termInfo; float linewidth; int orient; int just; int colorIndex; @private id aqtConnection; } -(id)aqtConnection; -(NSMutableDictionary *)termInfo; -(BOOL)connectToAquaTerm; -(void)updateInfoFromServer; // // Obj-C methods implementing the functionality defined in C_API.h // -(void)openGraph:(int)n; -(void)closeGraph; -(void)render; -(void)setTitle:(NSString *)title; -(void)setColor:(NSColor *)color forIndex:(int)index; -(void)useColor:(int)index; -(void)useLinewidth:(float)width; -(void)appendPath:(NSBezierPath *)path; -(void)appendFilledPath:(NSBezierPath *)path; -(void)setFontWithName:(NSString *)name size:(float)size; -(void)useOrientation:(int)orient; -(void)useJustification:(int)just; -(void)lineFromPoint:(NSPoint)startpoint toPoint:(NSPoint)endpoint; -(void)putText:(NSString *)str at:(NSPoint)point; -(void)addImageFromFile:(NSString *)filename bounds:(NSRect)bounds; // -(void)flushBuffers; @end @implementation AQTAdapter -(id)init { if (self = [super init]) { filledPathBuffer = [[NSBezierPath alloc] init]; pathBuffer = [[NSBezierPath alloc] init]; termInfo = [[NSMutableDictionary alloc] initWithCapacity:0]; // // Try to get a local proxy of the object in AquaTerm that manages communication // if ([self connectToAquaTerm]) { // // This speeds up communication with the remote object, see // http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/DistrObjects/ // Look under "Connections and Proxies" // [aqtConnection setProtocolForProxy:@protocol(AQTProtocol)]; } } return self; } -(void)dealloc { [aqtConnection release]; [filledPathBuffer release]; [pathBuffer release]; [termInfo release]; [super dealloc]; } -(id)aqtConnection { return aqtConnection; } -(NSMutableDictionary *)termInfo { return termInfo; } -(BOOL)connectToAquaTerm { BOOL didConnect = NO; // // Establish a connection to AquaTerm. // First check if AquaTerm is already running, otherwise // try to launch AquaTerm from standard locations. // aqtConnection = [NSConnection rootProxyForConnectionWithRegisteredName:@"aquatermServer" host:nil]; if (aqtConnection) /* Server is running and ready to go */ { [aqtConnection retain]; didConnect = YES; } else /* Server isn't running, we must fire it up */ { // // Try to launch AquaTerm // if ([[NSWorkspace sharedWorkspace] launchApplication:@"AquaTerm"] == NO) { printf("Failed to launch AquaTerm.\n"); printf("You must either put AquaTerm.app in \n"); printf("the /Applications or ~/Applications folder\n"); } else { do { /* Wait for it to register with OS */ aqtConnection =[NSConnection rootProxyForConnectionWithRegisteredName:@"aquatermServer" host:nil]; } while (!aqtConnection); /* This could result in a hang if something goes wrong with registering! */ [aqtConnection retain]; didConnect = YES; } } return didConnect; } -(void) updateInfoFromServer { [termInfo setDictionary:[aqtConnection getAquaTermInfo]]; } // // Adapter methods, this is where the translation takes place! // // The methods known to AquaTerm are defined in AQTProtocol.h // -(void)openGraph:(int)n { // Set default values linewidth = 1; orient = 0; just = 1; colorIndex = 0; [aqtConnection openModel:n]; } -(void)closeGraph { [self flushBuffers]; [aqtConnection closeModel]; } -(void)render { [self flushBuffers]; [aqtConnection render]; } -(void)setTitle:(NSString *)title { [aqtConnection setTitle:title]; } -(void)setColor:(NSColor *)color forIndex:(int)index { [aqtConnection setColor:color forIndex:index]; } -(void)useColor:(int)index { // flush buffers before changing color... if(index != colorIndex) { [self flushBuffers]; colorIndex = index; } } -(void)useLinewidth:(float)width { // flush buffers before changing linewidth... if(width != linewidth) { [self flushBuffers]; linewidth = width; } } -(void)appendPath:(NSBezierPath *)path { [pathBuffer appendBezierPath:path]; } -(void)appendFilledPath:(NSBezierPath *)path { [filledPathBuffer appendBezierPath:path]; } -(void)setFontWithName:(NSString *)name size:(float)size { [aqtConnection setFontWithName:name size:size]; } -(void)useOrientation:(int)newOrient { orient = newOrient; } -(void)useJustification:(int)newJust { just = newJust; } -(void)lineFromPoint:(NSPoint)startpoint toPoint:(NSPoint)endpoint { [pathBuffer moveToPoint:startpoint]; [pathBuffer lineToPoint:endpoint]; } -(void)putText:(NSString *)str at:(NSPoint)point { // // Put a line of beautifully rendered Times Roman (AquaTerm default) // at the point (x,y), left justified and horisontally (angle 0.0). // Also, the client doesnt know the concept of color so we set the // linecolor to a fix value. Hence: // [aqtConnection addString:str atPoint:point withJustification:just atAngle:90.0*orient withIndexedColor:colorIndex]; } -(void)addImageFromFile:(NSString *)filename bounds:(NSRect)bounds { [aqtConnection addImageFromFile:filename bounds:bounds]; } -(void)flushBuffers { if (![pathBuffer isEmpty]) { [pathBuffer setLineWidth:linewidth]; [aqtConnection addPolyline:pathBuffer withIndexedColor:colorIndex]; [pathBuffer removeAllPoints]; } if (![filledPathBuffer isEmpty]) { [filledPathBuffer setLineWidth:linewidth]; [aqtConnection addPolygon:filledPathBuffer withIndexedColor:colorIndex]; [filledPathBuffer removeAllPoints]; } } @end /* AQTAdapter */ // // ---------------------------------------------------------------- // --- C API example // ---------------------------------------------------------------- // void aqtInit(void) { // The autorelease pool and the adapter object must be initialized, // this is the place to do it. But only once! // if (arpool == NULL) /* Make sure we don't leak mem by allocating every time */ { arpool = [[NSAutoreleasePool alloc] init]; adapter = [[AQTAdapter alloc] init]; } } void aqtOpenGraph(int n) { [adapter openGraph:n]; } void aqtCloseGraph(void) { [adapter closeGraph]; } void aqtRenderGraph(void) { [adapter render]; } void aqtSetTitle(char *title) { [adapter setTitle:[NSString stringWithCString:title]]; } void aqtUseColor(int col) { [adapter useColor:col]; } void aqtSetColormapEntry(int col, float r, float g, float b) { [adapter setColor:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1] forIndex:col]; } void aqtUseLinewidth(float width) { [adapter useLinewidth:width]; } void aqtAddLine(float x1, float y1, float x2, float y2) { NSBezierPath *path = [NSBezierPath bezierPath]; [path moveToPoint:NSMakePoint(x1, y1)]; [path lineToPoint:NSMakePoint(x2, y2)]; [adapter appendPath:path]; } void aqtAddPolygon(float *x, float *y, int n, bool isFilled) { int i; NSBezierPath *path = [NSBezierPath bezierPath]; [path moveToPoint:NSMakePoint(x[0], y[0])]; for (i = 1; i < n; i++) { [path lineToPoint:NSMakePoint(x[i], y[i])]; } if (isFilled) { [path closePath]; [adapter appendFilledPath:path]; } else { [adapter appendPath:path]; } } void aqtAddCircle(float x, float y, float radius, bool isFilled) { NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:NSMakeRect(x-radius, y-radius, 2*radius, 2*radius)]; if (isFilled) { [path closePath]; [adapter appendFilledPath:path]; } else { [adapter appendPath:path]; } } void aqtUseFont(char *fontname, float size) { [adapter setFontWithName:[NSString stringWithCString:fontname] size:size]; } void aqtUseTextOrientation(int orient) { [adapter useOrientation:orient]; } void aqtUseTextJustification(int just) { [adapter useJustification:just]; } void aqtAddText(float x, float y, const char *str) { [adapter putText:[NSString stringWithCString:str] at:NSMakePoint(x, y)]; } void aqtAddImageFromFile(char *filename, float x, float y, float w, float h) { [adapter addImageFromFile:[NSString stringWithCString:filename] bounds:NSMakeRect(x, y, w, h)]; } void aqtGetSize(float *x_max, float *y_max) { [adapter updateInfoFromServer]; // Force an update of the termInfo dictionary *x_max = [[[adapter termInfo] objectForKey:@"AQTXMax"] floatValue]; *y_max = [[[adapter termInfo] objectForKey:@"AQTYMax"] floatValue]; } // // ---------------------------------------------------------------- // --- End of C API example // ---------------------------------------------------------------- // --- NEW FILE: test.c --- #include <math.h> #include "c2aqt.h" enum { LEFT, CENTER, RIGHT }; int main(void) { int i; float x_max, y_max; float x[16], y[16]; float pi = 4.0*atan(1.0); // // Testing all functions in c2aqt.h // // Initialize AquaTerm adapter aqtInit(); // Get info from AquaTerm // Set color entries in colortable aqtSetColormapEntry(0, 0.0, 0.0, 0.0); // color 0 is now black aqtSetColormapEntry(1, 1.0, 0.0, 0.0); // color 1 is now red aqtSetColormapEntry(2, 0.0, 1.0, 0.0); // color 2 is now green aqtSetColormapEntry(3, 0.0, 0.0, 1.0); // color 3 is now blue // Open a new graph for drawing into aqtOpenGraph(1); // Set the title (Default is "Figure n") aqtSetTitle("Test of c2aqt"); aqtUseTextJustification(LEFT); for (i=0;i<4;i++) { // Select the pen color (default is 0) aqtUseColor(i); // Set the linewidth (default is 1.0) aqtUseLinewidth((i+1.0)*0.5); // Add a line using current attributes aqtAddLine(100, i*50.0+100, 400, i*50.0+100); // Select font and size (default is Times-Roman 16pt) aqtUseFont("Times-Roman", 10.0+i*10.0); // Add the text with the current attributes aqtAddText(400, i*50.0+100, "Hello World!"); } // Close current graph => render it in window aqtCloseGraph(); // Open a new graph for drawing into aqtOpenGraph(2); // Get the size of the canvas aqtGetSize(&x_max, &y_max); // Set the title (Default is "Figure n") aqtSetTitle("More tests of c2aqt"); // Set the linewidth (default is 1.0) aqtUseLinewidth(1.0); // Draw a circle aqtUseColor(1); aqtAddCircle(x_max/2, y_max/2, 200.0, 0); // Create a nice polygon for (i=0; i < 5;i++) { x[i] = 200.0*cos(i*2.0*pi/5.0)+x_max/2; y[i] = 200.0*sin(i*2.0*pi/5.0)+y_max/2; } // Draw a filled polygon inside it aqtUseColor(2); aqtAddPolygon(x, y, 5, 1); // Draw a filled circle inside the polygon aqtUseColor(3); aqtAddCircle(x_max/2, y_max/2, 100.0, 1); // Create another polygon (a polyline really...) for (i=0; i < 16;i++) { x[i] = 50.0*i+50; y[i] = 100.0*sin(i*2.0*pi/15.0)+y_max/2; } // Draw the polygon (no fill) aqtUseColor(1); aqtAddPolygon(x, y, 16, 0); // Close current graph => render it in window aqtCloseGraph(); return 0; } |