summaryrefslogtreecommitdiff
path: root/navit/graphics/cocoa
diff options
context:
space:
mode:
authorgeoghegan <geoghegan@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-12-24 21:45:44 +0000
committergeoghegan <geoghegan@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-12-24 21:45:44 +0000
commit6975429b94f1f5cd40cc3ba37c32d72357e14704 (patch)
treebb0eda7bfa318ec6847b44b37334f1ea5eb2a007 /navit/graphics/cocoa
parent27f4c9e7e080484f8c11b7810eadcde196dc2015 (diff)
downloadnavit-6975429b94f1f5cd40cc3ba37c32d72357e14704.tar.gz
#include <glib.h>
#include "config.h" #include "config_.h" #include "debug.h" #include "plugin.h" #include "point.h" #include "window.h" #include "graphics.h" #include "event.h" #include "item.h" #include "callback.h" #include "color.h" #include <iconv.h> #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED #define USE_UIKIT 1 #else #define USE_UIKIT 0 #endif #if USE_UIKIT #import <UIKit/UIKit.h> #define NSRect CGRect #define NSMakeRect CGRectMake #define REVERSE_Y 0 CGContextRef current_context(void) { return UIGraphicsGetCurrentContext(); } #else #import <Cocoa/Cocoa.h> #define UIView NSView #define UIViewController NSViewController #define UIApplicationDelegate NSApplicationDelegate #define UIWindow NSWindow #define UIApplication NSApplication #define UIApplicationMain(a,b,c,d) NSApplicationMain(a,b) #define UIScreen NSScreen #define UIEvent NSEvent #define applicationFrame frame #define REVERSE_Y 1 CGContextRef current_context(void) { return [[NSGraphicsContext currentContext] graphicsPort]; } #endif @interface NavitView : UIView { @public struct graphics_priv *graphics; } @end static struct graphics_priv { struct window win; NavitView *view; CGLayerRef layer; CGContextRef layer_context; struct callback_list *cbl; struct point p, pclean; int w, h, wraparound, overlay_disabled, cleanup; struct graphics_priv *parent, *next, *overlays; } *global_graphics_cocoa; iconv_t utf8_macosroman; struct graphics_gc_priv { CGFloat rgba[4]; int w; }; struct graphics_font_priv { int size; char *name; }; @implementation NavitView - (void)drawRect:(NSRect)rect { struct graphics_priv *gr=NULL; #if 0 NSLog(@"NavitView:drawRect..."); #endif CGContextRef X = current_context(); CGContextDrawLayerAtPoint(X, CGPointZero, graphics->layer); if (!graphics->overlay_disabled) gr=graphics->overlays; while (gr) { if (!gr->overlay_disabled) { struct CGPoint pc; pc.x=gr->p.x; pc.y=gr->p.y; if (gr->wraparound) { if (pc.x < 0) pc.x+=graphics->w; if (pc.y < 0) pc.y+=graphics->h; } #if REVERSE_Y pc.y=graphics->h-pc.y-gr->h; #endif dbg(0,"draw %dx%d at %f,%f\n",gr->w,gr->h,pc.x,pc.y); CGContextDrawLayerAtPoint(X, pc, gr->layer); } gr=gr->next; } } #if USE_UIKIT - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *arr=touches.allObjects; UITouch *touch=[arr objectAtIndex: 0]; struct CGPoint pc=[touch locationInView: self]; struct point p; p.x=pc.x; p.y=pc.y; dbg(0,"Enter count=%d %d %d\n",touches.count,p.x,p.y); callback_list_call_attr_3(graphics->cbl, attr_button, GINT_TO_POINTER(1), GINT_TO_POINTER(1), (void *)&p); } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *arr=touches.allObjects; UITouch *touch=[arr objectAtIndex: 0]; struct CGPoint pc=[touch locationInView: self]; struct point p; p.x=pc.x; p.y=pc.y; dbg(0,"Enter count=%d %d %d\n",touches.count,p.x,p.y); callback_list_call_attr_3(graphics->cbl, attr_button, GINT_TO_POINTER(0), GINT_TO_POINTER(1), (void *)&p); } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *arr=touches.allObjects; UITouch *touch=[arr objectAtIndex: 0]; struct CGPoint pc=[touch locationInView: self]; struct point p; p.x=pc.x; p.y=pc.y; dbg(0,"Enter count=%d %d %d\n",touches.count,p.x,p.y); callback_list_call_attr_3(graphics->cbl, attr_button, GINT_TO_POINTER(0), GINT_TO_POINTER(1), (void *)&p); } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *arr=touches.allObjects; UITouch *touch=[arr objectAtIndex: 0]; struct CGPoint pc=[touch locationInView: self]; struct point p; p.x=pc.x; p.y=pc.y; dbg(0,"Enter count=%d %d %d\n",touches.count,p.x,p.y); callback_list_call_attr_1(graphics->cbl, attr_motion, (void *)&p); } #else - (void)mouseDown:(UIEvent *)theEvent { struct point p; p.x=theEvent.locationInWindow.x; p.y=graphics->h-theEvent.locationInWindow.y; dbg(0,"Enter %d %d\n",p.x,p.y); callback_list_call_attr_3(graphics->cbl, attr_button, GINT_TO_POINTER(1), GINT_TO_POINTER(1), (void *)&p); } - (void)mouseUp:(UIEvent *)theEvent { struct point p; p.x=theEvent.locationInWindow.x; p.y=graphics->h-theEvent.locationInWindow.y; dbg(0,"Enter %d %d\n",p.x,p.y); callback_list_call_attr_3(graphics->cbl, attr_button, GINT_TO_POINTER(0), GINT_TO_POINTER(1), (void *)&p); } - (void)mouseDragged:(UIEvent *)theEvent { struct point p; p.x=theEvent.locationInWindow.x; p.y=graphics->h-theEvent.locationInWindow.y; dbg(0,"Enter %d %d\n",p.x,p.y); callback_list_call_attr_1(graphics->cbl, attr_motion, (void *)&p); } #endif - (void)dealloc { [super dealloc]; } @end @interface NavitViewController : UIViewController { NSRect frame; CGLayerRef layer; } @property (nonatomic) NSRect frame; - (id) init_withFrame : (NSRect) _frame; @end @implementation NavitViewController @synthesize frame; - (id) init_withFrame : (NSRect) _frame { NSLog(@"init with frame\n"); frame = _frame; return [self init]; } static void free_graphics(struct graphics_priv *gr) { if (gr->layer) { CGLayerRelease(gr->layer); gr->layer=NULL; } } static void setup_graphics(struct graphics_priv *gr) { CGRect lr=CGRectMake(0, 0, gr->w, gr->h); gr->layer=CGLayerCreateWithContext(current_context(), lr.size, NULL); gr->layer_context=CGLayerGetContext(gr->layer); #if REVERSE_Y CGContextScaleCTM(gr->layer_context, 1, -1); CGContextTranslateCTM(gr->layer_context, 0, -gr->h); #endif CGContextSetRGBFillColor(gr->layer_context, 0, 0, 0, 0); CGContextSetRGBStrokeColor(gr->layer_context, 0, 0, 0, 0); CGContextClearRect(gr->layer_context, lr); } - (void)loadView { NSLog(@"loadView"); NavitView* myV = [NavitView alloc]; if (global_graphics_cocoa) { global_graphics_cocoa->view=myV; myV->graphics=global_graphics_cocoa; global_graphics_cocoa->w=frame.size.width; global_graphics_cocoa->h=frame.size.height; setup_graphics(global_graphics_cocoa); } [myV initWithFrame: frame]; [self setView: myV]; [myV release]; } - (void)didReceiveMemoryWarning { dbg(0,"enter\n"); } - (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [super dealloc]; } @end @class NavitViewController; @interface NavitAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; NavitViewController *viewController; } @property (nonatomic, retain) /*IBOutlet*/ UIWindow *window; @property (nonatomic, retain) /*IBOutlet*/ NavitViewController *viewController; @end @implementation NavitAppDelegate @synthesize window; @synthesize viewController; #if USE_UIKIT - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions #else - (void) applicationDidFinishLaunching:(NSNotification *)aNotification #endif { NSLog(@"DidFinishLaunching\n"); #if USE_UIKIT [[UIApplication sharedApplication] setStatusBarHidden:NO]; #endif NSRect appFrame = [UIScreen mainScreen].applicationFrame; self.viewController = [[[NavitViewController alloc] init_withFrame : appFrame] autorelease]; NSRect windowRect = NSMakeRect(0, 0, appFrame.size.width, appFrame.size.height); #if USE_UIKIT self.window = [[[UIWindow alloc] initWithFrame:windowRect] autorelease]; #else self.window = [[[UIWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO] autorelease]; #endif utf8_macosroman=iconv_open("MACROMAN","UTF-8"); #if USE_UIKIT [window addSubview:viewController.view]; [window makeKeyAndVisible]; #else NSWindowController * controller = [[NSWindowController alloc] initWithWindow : window]; NSLog(@"Setting view\n"); [viewController loadView]; [window setContentView : viewController.view]; [controller setWindow : window]; [controller showWindow : nil]; #endif if (global_graphics_cocoa) { callback_list_call_attr_2(global_graphics_cocoa->cbl, attr_resize, (int)appFrame.size.width, (int)appFrame.size.height); } #if USE_UIKIT return YES; #endif } - (void)dealloc { [viewController release]; [window release]; [super dealloc]; } @end static void draw_mode(struct graphics_priv *gr, enum draw_mode_num mode) { if (mode == draw_mode_end) { dbg(0,"end %p\n",gr); if (!gr->parent) { #if USE_UIKIT [gr->view setNeedsDisplay]; #else [gr->view display]; #endif } } } static void draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { CGPoint points[count]; int i; for (i = 0 ; i < count ; i++) { points[i].x=p[i].x; points[i].y=p[i].y; } CGContextSetStrokeColor(gr->layer_context, gc->rgba); CGContextSetLineWidth(gr->layer_context, gc->w); CGContextSetLineCap(gr->layer_context, kCGLineCapRound); CGContextBeginPath(gr->layer_context); CGContextAddLines(gr->layer_context, points, count); CGContextStrokePath(gr->layer_context); } static void draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { CGPoint points[count]; int i; for (i = 0 ; i < count ; i++) { points[i].x=p[i].x; points[i].y=p[i].y; } CGContextSetFillColor(gr->layer_context, gc->rgba); CGContextBeginPath(gr->layer_context); CGContextAddLines(gr->layer_context, points, count); CGContextFillPath(gr->layer_context); } static void draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h) { CGRect lr=CGRectMake(p->x, p->y, w, h); if (p->x <= 0 && p->y <= 0 && p->x+w+1 >= gr->w && p->y+h+1 >= gr->h) { dbg(0,"clear %p %dx%d\n",gr,w,h); free_graphics(gr); setup_graphics(gr); } CGContextSetFillColor(gr->layer_context, gc->rgba); CGContextFillRect(gr->layer_context, lr); } static void draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy) { size_t len,inlen=strlen(text)+1,outlen=strlen(text)+1; char outb[outlen]; char *inp=text,*outp=outb; len=iconv (utf8_macosroman, &inp, &inlen, &outp, &outlen); CGContextSetFillColor(gr->layer_context, fg->rgba); CGContextSelectFont(gr->layer_context, font->name, font->size/16.0, kCGEncodingMacRoman); CGContextSetTextDrawingMode(gr->layer_context, kCGTextFill); CGAffineTransform xform = CGAffineTransformMake(dx/65536.0, dy/65536.0, dy/65536.0, -dx/65536.0, 0.0f, 0.0f); CGContextSetTextMatrix(gr->layer_context, xform); CGContextShowTextAtPoint(gr->layer_context, p->x, p->y, outb, strlen(outb)); } static void draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img) { CGImageRef imgc=(CGImageRef) img; int w=CGImageGetWidth(imgc); int h=CGImageGetHeight(imgc); CGRect rect=CGRectMake(0, 0, w, h); CGContextSaveGState(gr->layer_context); CGContextTranslateCTM(gr->layer_context, p->x, p->y+h); CGContextScaleCTM(gr->layer_context, 1.0, -1.0); CGContextDrawImage(gr->layer_context, rect, imgc); CGContextRestoreGState(gr->layer_context); } static void font_destroy(struct graphics_font_priv *font) { g_free(font); } static struct graphics_font_methods font_methods = { font_destroy }; static void draw_drag(struct graphics_priv *gr, struct point *p) { if (!gr->cleanup) { gr->pclean=gr->p; gr->cleanup=1; } if (p) gr->p=*p; else { gr->p.x=0; gr->p.y=0; } } static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, char *font, int size, int flags) { struct graphics_font_priv *ret=g_new0(struct graphics_font_priv, 1); *meth=font_methods; ret->size=size; ret->name="Helvetica"; return ret; } static void gc_destroy(struct graphics_gc_priv *gc) { g_free(gc); } static void gc_set_linewidth(struct graphics_gc_priv *gc, int w) { gc->w=w; } static void gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n) { } static void gc_set_foreground(struct graphics_gc_priv *gc, struct color *c) { gc->rgba[0]=c->r/65535.0; gc->rgba[1]=c->g/65535.0; gc->rgba[2]=c->b/65535.0; gc->rgba[3]=c->a/65535.0; } static void gc_set_background(struct graphics_gc_priv *gc, struct color *c) { } static void gc_set_stipple(struct graphics_gc_priv *gc, struct graphics_image_priv *img) { } static struct graphics_gc_methods gc_methods = { gc_destroy, gc_set_linewidth, gc_set_dashes, gc_set_foreground, gc_set_background, gc_set_stipple, }; static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth) { struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1); gc->w=1; *meth=gc_methods; return gc; } static void background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc) { } static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound); static struct graphics_image_priv * image_new(struct graphics_priv *gra, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot, int rotation) { NSString *s=[[NSString alloc]initWithCString:path encoding:NSMacOSRomanStringEncoding]; CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((CFDataRef)[NSData dataWithContentsOfFile:s]); [s release]; if (!imgDataProvider) return NULL; CGImageRef image = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(imgDataProvider); dbg(0,"size %dx%d\n",CGImageGetWidth(image),CGImageGetHeight(image)); if (w) *w=CGImageGetWidth(image); if (h) *h=CGImageGetHeight(image); if (hot) { hot->x=CGImageGetWidth(image)/2; hot->y=CGImageGetHeight(image)/2; } return (struct graphics_image_priv *)image; } static void * get_data(struct graphics_priv *this, const char *type) { dbg(0,"enter\n"); if (strcmp(type,"window")) return NULL; return &this->win; } static void image_free(struct graphics_priv *gr, struct graphics_image_priv *priv) { CGImageRelease((CGImageRef)priv); } static void get_text_bbox(struct graphics_priv *gr, struct graphics_font_priv *font, char *text, int dx, int dy, struct point *ret, int estimate) { int len = g_utf8_strlen(text, -1); int xMin = 0; int yMin = 0; int yMax = 13*font->size/256; int xMax = 9*font->size*len/256; ret[0].x = xMin; ret[0].y = -yMin; ret[1].x = xMin; ret[1].y = -yMax; ret[2].x = xMax; ret[2].y = -yMax; ret[3].x = xMax; ret[3].y = -yMin; } static void overlay_disable(struct graphics_priv *gr, int disabled) { gr->overlay_disabled=disabled; } static struct graphics_methods graphics_methods = { NULL, /* graphics_destroy, */ draw_mode, draw_lines, draw_polygon, draw_rectangle, NULL, /* draw_circle, */ draw_text, draw_image, NULL, /* draw_image_warp, */ NULL, /* draw_restore, */ draw_drag, font_new, gc_new, background_gc, overlay_new, image_new, get_data, image_free, get_text_bbox, overlay_disable, NULL, /* overlay_resize, */ NULL, /* set_attr, */ }; static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound) { struct graphics_priv *ret=g_new0(struct graphics_priv, 1); *meth=graphics_methods; ret->p=*p; ret->w=w; ret->h=h; ret->parent=gr; ret->next=gr->overlays; ret->wraparound=wraparound; gr->overlays=ret; setup_graphics(gr); return ret; } struct graphics_priv * graphics_cocoa_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl) { struct graphics_priv *ret; *meth=graphics_methods; dbg(0,"enter\n"); if(!event_request_system("cocoa","graphics_cocoa")) return NULL; ret=g_new0(struct graphics_priv, 1); ret->cbl=cbl; global_graphics_cocoa=ret; return ret; } static void event_cocoa_main_loop_run(void) { dbg(0,"enter\n"); #if 0 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"]; freopen("/tmp/log.txt","a+",stderr); NSLog(@"Test\n"); #endif NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; #if USE_UIKIT dbg(0,"calling main\n"); int retval = UIApplicationMain(main_argc, main_argv, nil, @"NavitAppDelegate"); dbg(0,"retval=%d\n",retval); #else NavitAppDelegate * delegate = [[NavitAppDelegate alloc] init]; NSApplication * application = [NSApplication sharedApplication]; [application setDelegate:delegate]; NSLog(@"Test\n"); [NSApp run]; [delegate release]; #endif [pool release]; } @interface NavitTimer : NSObject{ @public struct callback *cb; NSTimer *timer; } - (void)onTimer:(NSTimer*)theTimer; @end @implementation NavitTimer - (void)onTimer:(NSTimer*)theTimer { callback_call_0(cb); } @end struct event_idle { struct callback *cb; NSTimer *timer; }; static struct event_timeout * event_cocoa_add_timeout(int timeout, int multi, struct callback *cb) { NavitTimer *ret=[[NavitTimer alloc]init]; ret->cb=cb; ret->timer=[NSTimer scheduledTimerWithTimeInterval:(timeout/1000.0) target:ret selector:@selector(onTimer:) userInfo:nil repeats:multi?YES:NO]; dbg(0,"timer=%p\n",ret->timer); return (struct event_timeout *)ret; } static void event_cocoa_remove_timeout(struct event_timeout *ev) { NavitTimer *t=(NavitTimer *)ev; [t->timer invalidate]; [t release]; } static struct event_idle * event_cocoa_add_idle(int priority, struct callback *cb) { NavitTimer *ret=[[NavitTimer alloc]init]; ret->cb=cb; ret->timer=[NSTimer scheduledTimerWithTimeInterval:(0.0) target:ret selector:@selector(onTimer:) userInfo:nil repeats:YES]; dbg(0,"timer=%p\n",ret->timer); return (struct event_idle *)ret; } static void event_cocoa_remove_idle(struct event_idle *ev) { NavitTimer *t=(NavitTimer *)ev; [t->timer invalidate]; [t release]; } static struct event_methods event_cocoa_methods = { event_cocoa_main_loop_run, NULL, /* event_cocoa_main_loop_quit, */ NULL, /* event_cocoa_add_watch, */ NULL, /* event_cocoa_remove_watch, */ event_cocoa_add_timeout, event_cocoa_remove_timeout, event_cocoa_add_idle, event_cocoa_remove_idle, NULL, /* event_cocoa_call_callback, */ }; static struct event_priv * event_cocoa_new(struct event_methods *meth) { dbg(0,"enter\n"); *meth=event_cocoa_methods; return NULL; } void plugin_init(void) { dbg(0,"enter\n"); plugin_register_graphics_type("cocoa", graphics_cocoa_new); plugin_register_event_type("cocoa", event_cocoa_new); } git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@4866 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/graphics/cocoa')
-rw-r--r--navit/graphics/cocoa/graphics_cocoa.m2
1 files changed, 1 insertions, 1 deletions
diff --git a/navit/graphics/cocoa/graphics_cocoa.m b/navit/graphics/cocoa/graphics_cocoa.m
index 3ac78b883..908f9bc19 100644
--- a/navit/graphics/cocoa/graphics_cocoa.m
+++ b/navit/graphics/cocoa/graphics_cocoa.m
@@ -1,3 +1,4 @@
+#include <glib.h>
#include "config.h"
#include "config_.h"
#include "debug.h"
@@ -9,7 +10,6 @@
#include "item.h"
#include "callback.h"
#include "color.h"
-#include <glib.h>
#include <iconv.h>
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED