Added first version of Mac implementation
This commit is contained in:
parent
1bc99c1547
commit
4d50ed3fe2
63
include/MiniFB.h
Normal file
63
include/MiniFB.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#ifndef _MINIFB_H_
|
||||||
|
#define _MINIFB_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MFB_KEY_ESC = 0x18,
|
||||||
|
MFB_KEY_A = 0x41,
|
||||||
|
MFB_KEY_B = 0x42,
|
||||||
|
MFB_KEY_C = 0x43,
|
||||||
|
MFB_KEY_D = 0x44,
|
||||||
|
MFB_KEY_E = 0x45,
|
||||||
|
MFB_KEY_F = 0x46,
|
||||||
|
MFB_KEY_G = 0x47,
|
||||||
|
MFB_KEY_H = 0x48,
|
||||||
|
MFB_KEY_I = 0x49,
|
||||||
|
MFB_KEY_J = 0x4A,
|
||||||
|
MFB_KEY_K = 0x4B,
|
||||||
|
MFB_KEY_L = 0x4C,
|
||||||
|
MFB_KEY_M = 0x4D,
|
||||||
|
MFB_KEY_N = 0x4E,
|
||||||
|
MFB_KEY_O = 0x4F,
|
||||||
|
MFB_KEY_P = 0x50,
|
||||||
|
MFB_KEY_Q = 0x51,
|
||||||
|
MFB_KEY_R = 0x52,
|
||||||
|
MFB_KEY_S = 0x53,
|
||||||
|
MFB_KEY_T = 0x54,
|
||||||
|
MFB_KEY_U = 0x55,
|
||||||
|
MFB_KEY_V = 0x56,
|
||||||
|
MFB_KEY_W = 0x57,
|
||||||
|
MFB_KEY_X = 0x58,
|
||||||
|
MFB_KEY_Y = 0x59,
|
||||||
|
MFB_KEY_Z = 0x5A,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define MFB_RGB(r, g, b) (((unsigned int)r) << 16) | (((unsigned int)g) << 8) | b
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Create a window
|
||||||
|
int mfb_open(const char* name, int width, int height);
|
||||||
|
|
||||||
|
// Update the display. Input buffer is assumed to be a 32-bit buffer of the size given in the open call
|
||||||
|
// Will return -1 on error, 0 if no key has been pressed otherwise the key code matching the keycode enum
|
||||||
|
int mfb_update(void* buffer);
|
||||||
|
|
||||||
|
// Close the window
|
||||||
|
void mfb_close();
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
97
src/macosx/MiniFB.m
Normal file
97
src/macosx/MiniFB.m
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
#include "OSXWindow.h"
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <MiniFB.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* g_updateBuffer = 0;
|
||||||
|
int g_width = 0;
|
||||||
|
int g_height = 0;
|
||||||
|
static NSWindow* window_;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int mfb_open(const char* name, int width, int height)
|
||||||
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
g_width = width;
|
||||||
|
g_height = height;
|
||||||
|
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
|
unsigned int styles = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask;
|
||||||
|
|
||||||
|
NSRect rectangle = NSMakeRect(0, 0, width, height);
|
||||||
|
window_ = [[OSXWindow alloc] initWithContentRect:rectangle styleMask:styles backing:NSBackingStoreBuffered defer:NO];
|
||||||
|
|
||||||
|
if (!window_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
[window_ setTitle:[NSString stringWithUTF8String:name]];
|
||||||
|
[window_ setReleasedWhenClosed:NO];
|
||||||
|
[window_ performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:nil waitUntilDone:YES];
|
||||||
|
|
||||||
|
[window_ center];
|
||||||
|
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
|
||||||
|
[pool drain];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void mfb_close()
|
||||||
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
if (window_)
|
||||||
|
[window_ close];
|
||||||
|
|
||||||
|
[pool drain];
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static int updateEvents()
|
||||||
|
{
|
||||||
|
int state = 0;
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
switch ([event type])
|
||||||
|
{
|
||||||
|
case NSKeyDown:
|
||||||
|
case NSKeyUp:
|
||||||
|
{
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default :
|
||||||
|
{
|
||||||
|
[NSApp sendEvent:event];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[pool release];
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int mfb_update(void* buffer)
|
||||||
|
{
|
||||||
|
g_updateBuffer = buffer;
|
||||||
|
int state = updateEvents();
|
||||||
|
[[window_ contentView] setNeedsDisplay:YES];
|
||||||
|
return state;
|
||||||
|
}
|
10
src/macosx/OSXWindow.h
Normal file
10
src/macosx/OSXWindow.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
// @class OSXWindowFrameView;
|
||||||
|
|
||||||
|
@interface OSXWindow : NSWindow
|
||||||
|
{
|
||||||
|
NSView* childContentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
136
src/macosx/OSXWindow.m
Normal file
136
src/macosx/OSXWindow.m
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#import "OSXWindow.h"
|
||||||
|
#import "OSXWindowFrameView.h"
|
||||||
|
|
||||||
|
@implementation OSXWindow
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (id)initWithContentRect:(NSRect)contentRect
|
||||||
|
styleMask:(NSUInteger)windowStyle
|
||||||
|
backing:(NSBackingStoreType)bufferingType
|
||||||
|
defer:(BOOL)deferCreation
|
||||||
|
{
|
||||||
|
self = [super
|
||||||
|
initWithContentRect:contentRect
|
||||||
|
styleMask:windowStyle
|
||||||
|
backing:bufferingType
|
||||||
|
defer:deferCreation];
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
[self setOpaque:YES];
|
||||||
|
[self setBackgroundColor:[NSColor clearColor]];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
addObserver:self
|
||||||
|
selector:@selector(mainWindowChanged:)
|
||||||
|
name:NSWindowDidBecomeMainNotification
|
||||||
|
object:self];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
addObserver:self
|
||||||
|
selector:@selector(mainWindowChanged:)
|
||||||
|
name:NSWindowDidResignMainNotification
|
||||||
|
object:self];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
removeObserver:self];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)setContentSize:(NSSize)newSize
|
||||||
|
{
|
||||||
|
NSSize sizeDelta = newSize;
|
||||||
|
NSSize childBoundsSize = [childContentView bounds].size;
|
||||||
|
sizeDelta.width -= childBoundsSize.width;
|
||||||
|
sizeDelta.height -= childBoundsSize.height;
|
||||||
|
|
||||||
|
OSXWindowFrameView *frameView = [super contentView];
|
||||||
|
NSSize newFrameSize = [frameView bounds].size;
|
||||||
|
newFrameSize.width += sizeDelta.width;
|
||||||
|
newFrameSize.height += sizeDelta.height;
|
||||||
|
|
||||||
|
[super setContentSize:newFrameSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)mainWindowChanged:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)setContentView:(NSView *)aView
|
||||||
|
{
|
||||||
|
if ([childContentView isEqualTo:aView])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSRect bounds = [self frame];
|
||||||
|
bounds.origin = NSZeroPoint;
|
||||||
|
|
||||||
|
OSXWindowFrameView *frameView = [super contentView];
|
||||||
|
if (!frameView)
|
||||||
|
{
|
||||||
|
frameView = [[[OSXWindowFrameView alloc] initWithFrame:bounds] autorelease];
|
||||||
|
|
||||||
|
[super setContentView:frameView];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childContentView)
|
||||||
|
{
|
||||||
|
[childContentView removeFromSuperview];
|
||||||
|
}
|
||||||
|
childContentView = aView;
|
||||||
|
[childContentView setFrame:[self contentRectForFrameRect:bounds]];
|
||||||
|
[childContentView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
|
[frameView addSubview:childContentView];
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (NSView *)contentView
|
||||||
|
{
|
||||||
|
return childContentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (BOOL)canBecomeKeyWindow
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (BOOL)canBecomeMainWindow
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
|
||||||
|
{
|
||||||
|
windowFrame.origin = NSZeroPoint;
|
||||||
|
return NSInsetRect(windowFrame, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
+ (NSRect)frameRectForContentRect:(NSRect)windowContentRect styleMask:(NSUInteger)windowStyle
|
||||||
|
{
|
||||||
|
return NSInsetRect(windowContentRect, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
8
src/macosx/OSXWindowFrameView.h
Normal file
8
src/macosx/OSXWindowFrameView.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface OSXWindowFrameView : NSView
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
50
src/macosx/OSXWindowFrameView.m
Normal file
50
src/macosx/OSXWindowFrameView.m
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#import "OSXWindowFrameView.h"
|
||||||
|
|
||||||
|
@implementation OSXWindowFrameView
|
||||||
|
|
||||||
|
extern void* g_updateBuffer;
|
||||||
|
extern int g_width;
|
||||||
|
extern int g_height;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (NSRect)resizeRect
|
||||||
|
{
|
||||||
|
const CGFloat resizeBoxSize = 16.0;
|
||||||
|
const CGFloat contentViewPadding = 5.5;
|
||||||
|
|
||||||
|
NSRect contentViewRect = [[self window] contentRectForFrameRect:[[self window] frame]];
|
||||||
|
NSRect resizeRect = NSMakeRect(
|
||||||
|
NSMaxX(contentViewRect) + contentViewPadding,
|
||||||
|
NSMinY(contentViewRect) - resizeBoxSize - contentViewPadding,
|
||||||
|
resizeBoxSize,
|
||||||
|
resizeBoxSize);
|
||||||
|
|
||||||
|
return resizeRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)drawRect:(NSRect)rect
|
||||||
|
{
|
||||||
|
if (!g_updateBuffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||||
|
|
||||||
|
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
||||||
|
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, g_updateBuffer, g_width * g_height * 4, NULL);
|
||||||
|
|
||||||
|
CGImageRef img = CGImageCreate(g_width, g_height, 8, 32, g_width * 4, space, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
|
||||||
|
provider, NULL, false, kCGRenderingIntentDefault);
|
||||||
|
|
||||||
|
CGColorSpaceRelease(space);
|
||||||
|
CGDataProviderRelease(provider);
|
||||||
|
|
||||||
|
CGContextDrawImage(context, CGRectMake(0, 0, g_width, g_height), img);
|
||||||
|
|
||||||
|
CGImageRelease(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user