source: libcaca/trunk/caca/driver_cocoa.m @ 1421

Last change on this file since 1421 was 1421, checked in by Sam Hocevar, 13 years ago
  • Merged old code by Ol that can be used as a start for the Cocoa driver.
  • Property svn:keywords set to Id
File size: 11.3 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2006 Olivier Gutknecht <olg@no-distance.net>
4 *                2006 Sam Hocevar <sam@zoy.org>
5 *                All Rights Reserved
6 *
7 *  $Id: driver_cocoa.m 1421 2006-11-17 11:28:32Z sam $
8 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the Do What The Fuck You Want To
11 *  Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  This file contains the libcaca Cocoa input and output driver
17 */
18
19#include "config.h"
20#include "common.h"
21
22#if defined USE_COCOA
23
24#include <stdio.h>
25#include <stdlib.h>
26
27#import <Carbon/Carbon.h>
28#include <Cocoa/Cocoa.h>
29
30#include "caca.h"
31#include "caca_internals.h"
32#include "cucul.h"
33#include "cucul_internals.h"
34
35@interface CacaView : NSView
36{
37    NSFont* _font;
38    NSRect _r;
39    int xx;
40    int h, w;
41    uint32_t *_attrs;
42    uint32_t *_chars;
43    CFMutableDictionaryRef _cache;
44}
45- (void)setFont:(NSFont *)aFont;
46- (void)updateBuffersFromCaca:(caca_display_t *)dp;
47
48@end
49
50@implementation CacaView
51
52- (void)keyDown:(NSEvent *)theEvent
53{
54    NSLog(@"key %@", theEvent);
55}
56
57- (void)mouseMoved:(NSEvent *)theEvent
58{
59    NSLog(@"mouse %@", theEvent);
60}
61
62- (void)setupNewSize
63{
64    int fw = _r.size.width;
65    int fh = _r.size.height;
66    w = [self bounds].size.width /fw;
67    h = [self bounds].size.height / fh;
68//    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));
69//    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));
70}
71
72- (id)initWithFrame:(NSRect)frameRect
73{
74    if((self = [super initWithFrame:frameRect]) != nil) {
75        [[self window] makeFirstResponder:self];
76    }
77    return self;
78}
79
80- (NSFont *)font
81{
82    return _font;
83}
84
85- (void)setFont:(NSFont *)aFont
86{
87    [_font release];
88    _font = [aFont retain];
89    _r = [_font boundingRectForFont];
90    _r = NSMakeRect(0, 0, ceilf(_r.size.width), ceilf(_r.size.height));
91    [self setupNewSize];
92    [aFont set];
93}
94
95- (void)updateBuffersFromCaca:(caca_display_t *)dp
96{
97NSLog(@"update buffers");
98    if(_attrs)
99        free(_attrs);
100
101    _attrs = malloc(dp->cv->width * dp->cv->height * sizeof(uint32_t) * 2);
102    _chars = _attrs + dp->cv->width * dp->cv->height;
103    memcpy(_attrs, dp->cv->attrs, dp->cv->width * dp->cv->height * sizeof(uint32_t));
104    memcpy(_chars, dp->cv->chars, dp->cv->width * dp->cv->height * sizeof(uint32_t));
105
106    w = dp->cv->width;
107    h = dp->cv->height;
108
109    [self setNeedsDisplay:TRUE];
110}
111
112- (void)drawRect:(NSRect)rect
113{
114    //if([self inLiveResize]) [self setupNewSize];
115    int x, y;
116    int fw = _r.size.width;
117    int fh = _r.size.height;
118    uint32_t *attrs = _attrs;
119    uint32_t *chars = _chars;
120    NSGraphicsContext* viewContext = [NSGraphicsContext currentContext];
121    if(!attrs || !chars)
122    {
123        [[NSColor blueColor] set];
124        NSRectFill(rect);
125        return;
126    }
127    [[NSColor blackColor] set];
128    NSRectFill(rect);
129
130    for(y = 0; y < h; y++)
131    {
132        for(x = 0; x < w; x++)
133        {
134            unichar c = *chars++;
135            uint8_t argb[8];
136            _cucul_attr_to_argb4(*attrs++, argb);
137
138            /* FIXME: factorise this colour stuff */
139            NSRect r = NSMakeRect(x * fw, y * fh, fw, fh);
140            [[NSColor colorWithDeviceRed: (float)argb[1] / 255.0
141                                   green: (float)argb[2] / 255.0
142                                    blue: (float)argb[3] / 255.0
143                                   alpha: 1.0] setFill];
144            [[NSColor colorWithDeviceRed: (float)argb[5] / 255.0
145                                   green: (float)argb[6] / 255.0
146                                    blue: (float)argb[7] / 255.0
147                                   alpha: 1.0] setStroke];
148            NSRectFill(r);
149//            NSLog(@"%d %d %C %d %d %@ %@ %@", x, y, c, fg, bg, NSStringFromRect(r), _colormap[fg], _colormap[bg]);
150//            [[NSString stringWithCharacters:&c length:1] drawInRect:r withAttributes:[NSDictionary dictionaryWithObject:_colormap[fg] forKey:NSForegroundColorAttributeName]];
151            [[NSColor colorWithDeviceRed: (float)argb[5] / 255.0
152                                   green: (float)argb[6] / 255.0
153                                    blue: (float)argb[7] / 255.0
154                                   alpha: 1.0] setFill];
155            [[NSColor colorWithDeviceRed: (float)argb[5] / 255.0
156                                   green: (float)argb[6] / 255.0
157                                    blue: (float)argb[7] / 255.0
158                                   alpha: 1.0] setStroke];
159            [[NSString stringWithCharacters:&c length:1] drawInRect:r withAttributes:nil];
160//            [[NSString stringWithCharacters:&c length:1] drawInRect:r withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
161//                _colormap[fg], NSForegroundColorAttributeName, _colormap[bg], NSBackgroundColorAttributeName, nil]];
162}
163    }
164    [NSGraphicsContext setCurrentContext:viewContext];
165}
166@end
167
168struct driver_private
169{
170    NSWindow* window;
171    id view;
172    NSFont* font;
173    NSAutoreleasePool* pool;
174};
175
176
177//--------------------------------------------------------------------------------------------
178static OSStatus
179AppEventHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon)
180{
181    OSStatus    result = eventNotHandledErr;
182
183    switch(GetEventClass(inEvent))
184    {
185        case kEventClassCommand:
186        {
187            HICommandExtended cmd;
188            verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd));
189
190            switch(GetEventKind(inEvent))
191            {
192                case kEventCommandProcess:
193                    switch(cmd.commandID)
194                    {
195                        default:
196                            break;
197                    }
198                    break;
199            }
200            break;
201        }
202
203        default:
204            break;
205    }
206
207    return result;
208}
209
210
211static OSStatus
212WindowEventHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon)
213{
214    OSStatus err = eventNotHandledErr;
215
216    switch(GetEventClass(inEvent))
217    {
218        case kEventClassCommand:
219        {
220            HICommandExtended cmd;
221            verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd));
222
223            switch(GetEventKind(inEvent))
224            {
225                case kEventCommandProcess:
226                    switch(cmd.commandID)
227                    {
228                        // Add your own command-handling cases here
229                        default:
230                            break;
231                    }
232                    break;
233            }
234            break;
235        }
236
237        default:
238            break;
239    }
240
241    return err;
242}
243static int cocoa_init_graphics(caca_display_t *dp)
244{
245    int i;
246
247    dp->drv.p = malloc(sizeof(struct driver_private));
248    if(dp->drv.p == NULL)
249        return -1;
250
251    Handle aHand = GetNewMBar(128);
252    SetMenuBar(aHand);
253    MenuHandle menu = GetMenuHandle(128);
254    CreateStandardWindowMenu(0, &menu);
255    InsertMenu(menu, 0);
256
257    DrawMenuBar();
258    DisposeHandle(aHand);
259
260    NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];
261//    [NSApplication sharedApplication];
262    NSApplicationLoad();
263
264    NSLog(@"Start");
265
266    NSFont* f = [NSFont fontWithName:@"Monaco" size:10];
267    NSRect r = [f boundingRectForFont];
268
269    NSRect windowRect = NSMakeRect(0, 0, dp->cv->width * r.size.width,
270                                         dp->cv->height * r.size.height);
271    CacaView* v = [[[CacaView alloc] initWithFrame:windowRect] autorelease];
272
273//    [NSApp setMainMenu:[[[NSMenu alloc] initWithTitle:@"Caca"] autorelease]];
274    //[NSApp setAppleMenu:[[[NSMenu alloc] initWithTitle:@"ca"] autorelease]];
275    //[NSApp setDelegate:v];
276
277    NSWindow* w = [[NSWindow alloc]
278                   initWithContentRect:windowRect
279                             styleMask:NSTitledWindowMask
280                                        |NSResizableWindowMask
281                                        |NSClosableWindowMask
282                                        |NSWindowMiniaturizeButton
283                               backing:NSBackingStoreBuffered
284                                 defer:NO];
285    [w setContentView:v];
286    [v setFont:f];
287    [v setupNewSize];
288    [w setFrameTopLeftPoint:NSMakePoint(650, 650)];
289    [w makeKeyAndOrderFront:w];
290    [w setLevel:NSFloatingWindowLevel];
291    [w orderFrontRegardless];
292
293    dp->drv.p->window = w;
294    dp->drv.p->view = v;
295    dp->drv.p->font = f;
296    dp->drv.p->pool = p;
297
298//    NSLog(@"update4 %d %d", w, h);
299//    _cucul_set_size(dp->cv, windowRect.size.width, windowRect.size.height);
300    OSStatus err;
301    static const EventTypeSpec kAppEvents[] =
302    {
303        { kEventClassCommand, kEventCommandProcess }
304    };
305    InstallApplicationEventHandler(NewEventHandlerUPP(AppEventHandler),
306                                   GetEventTypeCount(kAppEvents), kAppEvents,
307                                   0, NULL);
308    NSLog(@"a");
309    /* Should not be run here, should it? */
310    RunApplicationEventLoop();
311    NSLog(@"ab");
312    return 0;
313}
314
315
316static void cocoa_display(caca_display_t *dp)
317{
318//NSLog(@"display1");
319    [dp->drv.p->view updateBuffersFromCaca:dp];
320#if 1
321    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
322#else
323    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[[NSCalendarDate date]
324    dateByAddingYears:0 months:(int)0 days:(int)0 hours:(int)0 minutes:(int)0 seconds:(int)5]];
325#endif
326//NSLog(@"display2");
327}
328
329static void cocoa_handle_resize(caca_display_t *dp)
330{
331    dp->resize.w = dp->cv->width;
332    dp->resize.h = dp->cv->height;
333}
334
335static int cocoa_get_event(caca_display_t *dp, struct caca_event *ev)
336{
337    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
338                             beforeDate:[NSDate date]];
339    ev->type = CACA_EVENT_NONE;
340    return 0;
341}
342
343static int cocoa_set_display_title(caca_display_t *dp, char const *title)
344{
345    [dp->drv.p->window setTitle:[NSString stringWithUTF8String:title]];
346    return 0;
347}
348
349static unsigned int cocoa_get_display_width(caca_display_t *dp)
350{
351    return [dp->drv.p->window frame].size.width;
352}
353
354static unsigned int cocoa_get_display_height(caca_display_t *dp)
355{
356    return [dp->drv.p->window frame].size.height;
357}
358
359static void cocoa_set_mouse(caca_display_t *dp, int flag)
360{
361    if(flag)
362        [[NSCursor arrowCursor] set];
363    else {
364        [[NSCursor disappearingItemCursor] set];
365    }
366}
367
368static int cocoa_end_graphics(caca_display_t *dp)
369{
370    [dp->drv.p->window close];
371    [dp->drv.p->window release];
372    [dp->drv.p->pool release];
373    [dp->drv.p->font release];
374    free(dp->drv.p);
375    return 0;
376}
377
378/*
379 * Driver initialisation
380 */
381
382int cocoa_install(caca_display_t *dp)
383{
384    dp->drv.driver = CACA_DRIVER_RAW;
385
386    dp->drv.init_graphics = cocoa_init_graphics;
387    dp->drv.end_graphics = cocoa_end_graphics;
388    dp->drv.set_display_title = cocoa_set_display_title;
389    dp->drv.get_display_width = cocoa_get_display_width;
390    dp->drv.get_display_height = cocoa_get_display_height;
391    dp->drv.display = cocoa_display;
392    dp->drv.handle_resize = cocoa_handle_resize;
393    dp->drv.get_event = cocoa_get_event;
394    dp->drv.set_mouse = cocoa_set_mouse;
395
396    return 0;
397}
398
399#endif /* USE_COCOA */
400
Note: See TracBrowser for help on using the repository browser.