diff --git a/caca/driver_cocoa.m b/caca/driver_cocoa.m index d910b14..b2a297a 100644 --- a/caca/driver_cocoa.m +++ b/caca/driver_cocoa.m @@ -1,6 +1,7 @@ /* * libcaca Colour ASCII-Art library - * Copyright (c) 2002-2006 Sam Hocevar + * Copyright (c) 2006 Olivier Gutknecht + * 2006 Sam Hocevar * All Rights Reserved * * $Id$ @@ -23,6 +24,7 @@ #include #include +#import #include #include "caca.h" @@ -30,58 +32,346 @@ #include "cucul.h" #include "cucul_internals.h" +@interface CacaView : NSView +{ + NSFont* _font; + NSRect _r; + int xx; + int h, w; + uint32_t *_attrs; + uint32_t *_chars; + CFMutableDictionaryRef _cache; +} +- (void)setFont:(NSFont *)aFont; +- (void)updateBuffersFromCaca:(caca_display_t *)dp; + +@end + +@implementation CacaView + +- (void)keyDown:(NSEvent *)theEvent +{ + NSLog(@"key %@", theEvent); +} + +- (void)mouseMoved:(NSEvent *)theEvent +{ + NSLog(@"mouse %@", theEvent); +} + +- (void)setupNewSize +{ + int fw = _r.size.width; + int fh = _r.size.height; + w = [self bounds].size.width /fw; + h = [self bounds].size.height / fh; +// NSLog(@"W %f %f %f %d %f", [self bounds].size.width , _r.size.width, [self bounds].size.width / _r.size.width, w, [self bounds].size.width-(w*fw)); +// NSLog(@"H %f %f %f %d %f", [self bounds].size.height , _r.size.height, [self bounds].size.height / _r.size.height, h, [self bounds].size.height-(h*fh)); +} + +- (id)initWithFrame:(NSRect)frameRect +{ + if((self = [super initWithFrame:frameRect]) != nil) { + [[self window] makeFirstResponder:self]; + } + return self; +} + +- (NSFont *)font +{ + return _font; +} + +- (void)setFont:(NSFont *)aFont +{ + [_font release]; + _font = [aFont retain]; + _r = [_font boundingRectForFont]; + _r = NSMakeRect(0, 0, ceilf(_r.size.width), ceilf(_r.size.height)); + [self setupNewSize]; + [aFont set]; +} + +- (void)updateBuffersFromCaca:(caca_display_t *)dp +{ +NSLog(@"update buffers"); + if(_attrs) + free(_attrs); + + _attrs = malloc(dp->cv->width * dp->cv->height * sizeof(uint32_t) * 2); + _chars = _attrs + dp->cv->width * dp->cv->height; + memcpy(_attrs, dp->cv->attrs, dp->cv->width * dp->cv->height * sizeof(uint32_t)); + memcpy(_chars, dp->cv->chars, dp->cv->width * dp->cv->height * sizeof(uint32_t)); + + w = dp->cv->width; + h = dp->cv->height; + + [self setNeedsDisplay:TRUE]; +} + +- (void)drawRect:(NSRect)rect +{ + //if([self inLiveResize]) [self setupNewSize]; + int x, y; + int fw = _r.size.width; + int fh = _r.size.height; + uint32_t *attrs = _attrs; + uint32_t *chars = _chars; + NSGraphicsContext* viewContext = [NSGraphicsContext currentContext]; + if(!attrs || !chars) + { + [[NSColor blueColor] set]; + NSRectFill(rect); + return; + } + [[NSColor blackColor] set]; + NSRectFill(rect); + + for(y = 0; y < h; y++) + { + for(x = 0; x < w; x++) + { + unichar c = *chars++; + uint8_t argb[8]; + _cucul_attr_to_argb4(*attrs++, argb); + + /* FIXME: factorise this colour stuff */ + NSRect r = NSMakeRect(x * fw, y * fh, fw, fh); + [[NSColor colorWithDeviceRed: (float)argb[1] / 255.0 + green: (float)argb[2] / 255.0 + blue: (float)argb[3] / 255.0 + alpha: 1.0] setFill]; + [[NSColor colorWithDeviceRed: (float)argb[5] / 255.0 + green: (float)argb[6] / 255.0 + blue: (float)argb[7] / 255.0 + alpha: 1.0] setStroke]; + NSRectFill(r); +// NSLog(@"%d %d %C %d %d %@ %@ %@", x, y, c, fg, bg, NSStringFromRect(r), _colormap[fg], _colormap[bg]); +// [[NSString stringWithCharacters:&c length:1] drawInRect:r withAttributes:[NSDictionary dictionaryWithObject:_colormap[fg] forKey:NSForegroundColorAttributeName]]; + [[NSColor colorWithDeviceRed: (float)argb[5] / 255.0 + green: (float)argb[6] / 255.0 + blue: (float)argb[7] / 255.0 + alpha: 1.0] setFill]; + [[NSColor colorWithDeviceRed: (float)argb[5] / 255.0 + green: (float)argb[6] / 255.0 + blue: (float)argb[7] / 255.0 + alpha: 1.0] setStroke]; + [[NSString stringWithCharacters:&c length:1] drawInRect:r withAttributes:nil]; +// [[NSString stringWithCharacters:&c length:1] drawInRect:r withAttributes:[NSDictionary dictionaryWithObjectsAndKeys: +// _colormap[fg], NSForegroundColorAttributeName, _colormap[bg], NSBackgroundColorAttributeName, nil]]; +} + } + [NSGraphicsContext setCurrentContext:viewContext]; +} +@end + struct driver_private { - /* Just testing stuff */ - NSAutoreleasePool *pool; + NSWindow* window; + id view; + NSFont* font; + NSAutoreleasePool* pool; }; + +//-------------------------------------------------------------------------------------------- +static OSStatus +AppEventHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) +{ + OSStatus result = eventNotHandledErr; + + switch(GetEventClass(inEvent)) + { + case kEventClassCommand: + { + HICommandExtended cmd; + verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd)); + + switch(GetEventKind(inEvent)) + { + case kEventCommandProcess: + switch(cmd.commandID) + { + default: + break; + } + break; + } + break; + } + + default: + break; + } + + return result; +} + + +static OSStatus +WindowEventHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) +{ + OSStatus err = eventNotHandledErr; + + switch(GetEventClass(inEvent)) + { + case kEventClassCommand: + { + HICommandExtended cmd; + verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd)); + + switch(GetEventKind(inEvent)) + { + case kEventCommandProcess: + switch(cmd.commandID) + { + // Add your own command-handling cases here + default: + break; + } + break; + } + break; + } + + default: + break; + } + + return err; +} static int cocoa_init_graphics(caca_display_t *dp) { + int i; + dp->drv.p = malloc(sizeof(struct driver_private)); + if(dp->drv.p == NULL) + return -1; + + Handle aHand = GetNewMBar(128); + SetMenuBar(aHand); + MenuHandle menu = GetMenuHandle(128); + CreateStandardWindowMenu(0, &menu); + InsertMenu(menu, 0); + + DrawMenuBar(); + DisposeHandle(aHand); - dp->drv.p->pool = [NSAutoreleasePool new]; + NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init]; +// [NSApplication sharedApplication]; + NSApplicationLoad(); + NSLog(@"Start"); + + NSFont* f = [NSFont fontWithName:@"Monaco" size:10]; + NSRect r = [f boundingRectForFont]; + + NSRect windowRect = NSMakeRect(0, 0, dp->cv->width * r.size.width, + dp->cv->height * r.size.height); + CacaView* v = [[[CacaView alloc] initWithFrame:windowRect] autorelease]; + +// [NSApp setMainMenu:[[[NSMenu alloc] initWithTitle:@"Caca"] autorelease]]; + //[NSApp setAppleMenu:[[[NSMenu alloc] initWithTitle:@"ca"] autorelease]]; + //[NSApp setDelegate:v]; + + NSWindow* w = [[NSWindow alloc] + initWithContentRect:windowRect + styleMask:NSTitledWindowMask + |NSResizableWindowMask + |NSClosableWindowMask + |NSWindowMiniaturizeButton + backing:NSBackingStoreBuffered + defer:NO]; + [w setContentView:v]; + [v setFont:f]; + [v setupNewSize]; + [w setFrameTopLeftPoint:NSMakePoint(650, 650)]; + [w makeKeyAndOrderFront:w]; + [w setLevel:NSFloatingWindowLevel]; + [w orderFrontRegardless]; + + dp->drv.p->window = w; + dp->drv.p->view = v; + dp->drv.p->font = f; + dp->drv.p->pool = p; + +// NSLog(@"update4 %d %d", w, h); +// _cucul_set_size(dp->cv, windowRect.size.width, windowRect.size.height); + OSStatus err; + static const EventTypeSpec kAppEvents[] = + { + { kEventClassCommand, kEventCommandProcess } + }; + InstallApplicationEventHandler(NewEventHandlerUPP(AppEventHandler), + GetEventTypeCount(kAppEvents), kAppEvents, + 0, NULL); + NSLog(@"a"); + /* Should not be run here, should it? */ + RunApplicationEventLoop(); + NSLog(@"ab"); return 0; } -static int cocoa_end_graphics(caca_display_t *dp) + +static void cocoa_display(caca_display_t *dp) { - [dp->drv.p->pool release]; +//NSLog(@"display1"); + [dp->drv.p->view updateBuffersFromCaca:dp]; +#if 1 + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]]; +#else + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[[NSCalendarDate date] + dateByAddingYears:0 months:(int)0 days:(int)0 hours:(int)0 minutes:(int)0 seconds:(int)5]]; +#endif +//NSLog(@"display2"); +} - free(dp->drv.p); +static void cocoa_handle_resize(caca_display_t *dp) +{ + dp->resize.w = dp->cv->width; + dp->resize.h = dp->cv->height; +} +static int cocoa_get_event(caca_display_t *dp, struct caca_event *ev) +{ + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate date]]; + ev->type = CACA_EVENT_NONE; return 0; } static int cocoa_set_display_title(caca_display_t *dp, char const *title) { - return -1; + [dp->drv.p->window setTitle:[NSString stringWithUTF8String:title]]; + return 0; } static unsigned int cocoa_get_display_width(caca_display_t *dp) { - return 0; + return [dp->drv.p->window frame].size.width; } static unsigned int cocoa_get_display_height(caca_display_t *dp) { - return 0; -} - -static void cocoa_display(caca_display_t *dp) -{ - ; + return [dp->drv.p->window frame].size.height; } -static void cocoa_handle_resize(caca_display_t *dp) +static void cocoa_set_mouse(caca_display_t *dp, int flag) { - ; + if(flag) + [[NSCursor arrowCursor] set]; + else { + [[NSCursor disappearingItemCursor] set]; + } } -static int cocoa_get_event(caca_display_t *dp, caca_event_t *ev) +static int cocoa_end_graphics(caca_display_t *dp) { - ev->type = CACA_EVENT_NONE; + [dp->drv.p->window close]; + [dp->drv.p->window release]; + [dp->drv.p->pool release]; + [dp->drv.p->font release]; + free(dp->drv.p); return 0; } @@ -101,9 +391,10 @@ int cocoa_install(caca_display_t *dp) dp->drv.display = cocoa_display; dp->drv.handle_resize = cocoa_handle_resize; dp->drv.get_event = cocoa_get_event; - dp->drv.set_mouse = NULL; + dp->drv.set_mouse = cocoa_set_mouse; return 0; } #endif /* USE_COCOA */ + diff --git a/configure.ac b/configure.ac index 124243c..1a1669b 100644 --- a/configure.ac +++ b/configure.ac @@ -206,7 +206,7 @@ if test "${enable_cocoa}" != "no"; then [ac_cv_my_have_cocoa="yes"]) if test "${ac_cv_my_have_cocoa}" = "yes"; then AC_DEFINE(USE_COCOA, 1, Define to 1 to activate the Cocoa backend driver) - CACA_LIBS="${CACA_LIBS} -Wl,-framework,Cocoa" + CACA_LIBS="${CACA_LIBS} -Wl,-framework,Carbon,-framework,Cocoa" CACA_DRIVERS="${CACA_DRIVERS} cocoa" elif test "${enable_cocoa}" = "yes"; then AC_MSG_ERROR([cannot find Cocoa development files])