/* -*- Mode: ObjC; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * nativewindow_cocoa.mm * * Fri Dec 2 20:31:03 CET 2016 * Copyright 2016 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * DrumGizmo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* loop: http://stackoverflow.com/questions/6732400/cocoa-integrate-nsapplication-into-an-existing-c-mainloop draw pixels: http://stackoverflow.com/questions/10955913/how-can-i-display-an-array-of-pixels-on-a-nswindow */ #include #include #import bool running = true; @interface MyWindow : NSWindow { @public // MyView* my_view; } - (id) initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag; //- (void) setMyView:(MyView*)view; - (BOOL) windowShouldClose:(id)sender; - (void) mouseMoved:(NSEvent*)event; - (void) drawRect:(NSRect)dirtyRect; @end @implementation MyWindow - (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag { NSWindow* result = [super initWithContentRect:contentRect styleMask:(NSClosableWindowMask | NSTitledWindowMask | NSResizableWindowMask) backing:NSBackingStoreBuffered defer:NO]; [result setAcceptsMouseMovedEvents:YES]; [result setLevel: CGShieldingWindowLevel() + 1]; return result; } //- (void)setMyView:(MyView*)view //{ // //my_view = view; // //[self setContentSize:NSMakeSize(view->width, view->height) ]; //} - (BOOL)windowShouldClose:(id)sender { printf("closing!\n"); //if (puglview->closeFunc) // puglview->closeFunc(puglview); running = false; return YES; } #define WIDTH 100 #define HEIGHT 100 #define SIZE (WIDTH*HEIGHT) #define BYTES_PER_PIXEL 2 #define BITS_PER_COMPONENT 5 #define BITS_PER_PIXEL 16 - (void)drawRect:(NSRect)dirtyRect { } - (void) mouseMoved:(NSEvent*)event { /* if (puglview->motionFunc) { NSPoint loc = [event locationInWindow]; puglview->mods = getModifiers(puglview, event); puglview->motionFunc(puglview, loc.x, puglview->height - loc.y); } */ NSPoint loc = [event locationInWindow]; printf("mouseMove: %f %f\n", loc.x, loc.y); } @end @interface MyView : NSView { int colorBits; int depthBits; @public //PuglView* puglview; NSTrackingArea* trackingArea; } - (id) initWithFrame:(NSRect)frame colorBits:(int)numColorBits depthBits:(int)numDepthBits; - (void) reshape; - (void) drawRect:(NSRect)rect; @end @implementation MyView - (id) initWithFrame:(NSRect)frame colorBits:(int)numColorBits depthBits:(int)numDepthBits { colorBits = numColorBits; depthBits = numDepthBits; //NSOpenGLPixelFormatAttribute pixelAttribs[16] = { // NSOpenGLPFADoubleBuffer, // NSOpenGLPFAAccelerated, // NSOpenGLPFAColorSize, // colorBits, // NSOpenGLPFADepthSize, // depthBits, // 0 //}; // //NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] // initWithAttributes:pixelAttribs]; // //if (pixelFormat) { // self = [super initWithFrame:frame pixelFormat:pixelFormat]; // [pixelFormat release]; // if (self) { // [[self openGLContext] makeCurrentContext]; // [self reshape]; // } //} else { // self = nil; //} return self; } - (void) reshape { //[[self openGLContext] update]; // //NSRect bounds = [self bounds]; //int width = bounds.size.width; //int height = bounds.size.height; // //if (puglview) { // /* NOTE: Apparently reshape gets called when the GC gets around to // deleting the view (?), so we must have reset puglview to NULL when // this comes around. // */ // if (puglview->reshapeFunc) { // puglview->reshapeFunc(puglview, width, height); // } else { // puglDefaultReshape(puglview, width, height); // } // // puglview->width = width; // puglview->height = height; //} } - (void) drawRect:(NSRect)rect { printf("drawRect\n"); // Get current context CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; // Colorspace RGB CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Pixel Matrix allocation unsigned short *pixels = calloc(SIZE, sizeof(unsigned short)); // Random pixels will give you a non-organized RAINBOW for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { pixels[i+ j*HEIGHT] = arc4random() % USHRT_MAX; } } // Provider CGDataProviderRef provider = CGDataProviderCreateWithData(nil, pixels, SIZE, nil); // CGImage CGImageRef image = CGImageCreate(WIDTH, HEIGHT, BITS_PER_COMPONENT, BITS_PER_PIXEL, BYTES_PER_PIXEL*WIDTH, colorSpace, kCGImageAlphaNoneSkipFirst, // xRRRRRGGGGGBBBBB - 16-bits, first bit is ignored! provider, nil, //No decode NO, //No interpolation kCGRenderingIntentDefault); // Default rendering // Draw CGContextDrawImage(context, CGRectMake(0, 0, WIDTH, HEIGHT), image); // Once everything is written on screen we can release everything CGImageRelease(image); CGColorSpaceRelease(colorSpace); CGDataProviderRelease(provider); } @end #include "window.h" namespace GUI { NativeWindowCocoa::NativeWindowCocoa(void* native_window, Window& window) : buffer(nullptr) , window(window) { [NSAutoreleasePool new]; [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; /* id menubar = [[NSMenu new] autorelease]; id appMenuItem = [[NSMenuItem new] autorelease]; [menubar addItem:appMenuItem]; [NSApp setMainMenu:menubar]; id appMenu = [[NSMenu new] autorelease]; id appName = [[NSProcessInfo processInfo] processName]; id quitTitle = [@"Quit " stringByAppendingString:appName]; id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle action:@selector(terminate:) keyEquivalent:@"q"] autorelease]; [appMenu addItem:quitMenuItem]; [appMenuItem setSubmenu:appMenu]; */ id window = [[[MyWindow alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO] autorelease]; [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; // [window setTitle:appName]; [window makeKeyAndOrderFront:nil]; id my_view = [MyView new]; [window setContentView:my_view]; [NSApp activateIgnoringOtherApps:YES]; [window makeFirstResponder:my_view]; // [NSApp run]; } NativeWindowCocoa::~NativeWindowCocoa() { } void NativeWindowCocoa::setFixedSize(int width, int height) { } void NativeWindowCocoa::resize(int width, int height) { } void NativeWindowCocoa::move(int x, int y) { } void NativeWindowCocoa::show() { } void NativeWindowCocoa::hide() { } void NativeWindowCocoa::handleBuffer() { } void NativeWindowCocoa::redraw() { } void NativeWindowCocoa::setCaption(const std::string &caption) { } void NativeWindowCocoa::grabMouse(bool grab) { } bool NativeWindowCocoa::hasEvent() { return false; } std::shared_ptr NativeWindowCocoa::getNextEvent() { //[window setNeedsDisplay: YES]; while(running) { NSEvent * event; do { event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefa\ ultRunLoopMode dequeue:YES]; //Convert the cocoa events to something useful here and add them to your own event queue [NSApp sendEvent: event]; } while(event != nil); //printf("loop\n"); usleep(10000); } return nullptr; } std::shared_ptr NativeWindowCocoa::peekNextEvent() { return nullptr; } } // GUI::