1#import <Cocoa/Cocoa.h> 2#import <Carbon/Carbon.h> 3 4static NSWindow* nsParentWindow = nil; 5static NSWindow* nsWindow = nil; 6static NSView* nsView = nil; 7static bool cocoaApplication = false; 8static id oldDelegate = nil; 9static int widgetX = 0, widgetY = 0; 10 11@interface SdlCocoaWindow : NSWindow 12- (void)windowDidMove:(id)notification; 13- (void)windowWillMiniaturize:(NSNotification *)notification; 14- (void)windowDidDeminiaturize:(NSNotification *)notification; 15@end 16 17@implementation SdlCocoaWindow 18- (void)windowDidMove:(id)notification 19{ 20 NSRect parentFrame = [nsParentWindow frame]; 21 NSPoint point = NSMakePoint(parentFrame.origin.x + widgetX, parentFrame.origin.y + widgetY); 22 23 [self setFrameOrigin:point]; 24} 25 26- (void)windowWillMiniaturize:(NSNotification *)notification 27{ 28 [self setIsVisible:NO]; 29} 30 31- (void)windowDidDeminiaturize:(NSNotification *)notification 32{ 33 [self setIsVisible:YES]; 34} 35@end 36 37void initSdlCocoaView(void* parent, int x, int y, int width, int height, bool carbonParent) 38{ 39 printf("[SDL] Creating Cocoa view x: %d, y: %d, width: %d, height %d, carbon %d\n", x, y, width, height, carbonParent); 40 41 NSRect contentRect; 42 43 if (carbonParent) 44 { 45 contentRect = NSMakeRect(x, y, width, height); 46 47 if (!nsWindow) 48 { 49 // initWithWindowRef always returns the same result for the same WindowRef 50 nsWindow = [[NSWindow alloc] initWithWindowRef:(WindowRef)parent]; 51 52 [nsWindow setContentView:[[[NSView alloc] initWithFrame:contentRect] autorelease]]; 53 } 54 } 55 else 56 { 57 contentRect = NSMakeRect(0, 0, width, height); 58 59 if (!nsWindow) 60 { 61 nsWindow = [[SdlCocoaWindow alloc] initWithContentRect:contentRect styleMask:NSDocModalWindowMask backing:NSBackingStoreBuffered defer:NO]; 62 63 nsParentWindow = (NSWindow*)parent; 64 widgetX = x; 65 widgetY = y; 66 oldDelegate = [nsParentWindow delegate]; 67 cocoaApplication = true; 68 69 [nsWindow setLevel:NSFloatingWindowLevel]; 70 [nsWindow setHasShadow:NO]; 71 72 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 73 74 [nc addObserver:nsWindow selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:nsParentWindow]; 75 [nc addObserver:nsWindow selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification object:nsParentWindow]; 76 [nc addObserver:nsWindow selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:nsParentWindow]; 77 } 78 } 79 80 if (!nsView) 81 { 82 nsView = [[NSView alloc] initWithFrame:contentRect]; 83 84 [[nsWindow contentView] addSubview:nsView]; 85 [nsView release]; 86 87 if (carbonParent) 88 [nsWindow orderOut:nil]; // very important, otherwise window won't be placed correctly on repeat showings 89 else 90 { 91 NSRect parentFrame = [nsParentWindow frame]; 92 NSPoint point = NSMakePoint(parentFrame.origin.x + x, parentFrame.origin.y + y); 93 94 [nsWindow setFrameOrigin:point]; 95 } 96 97 [nsWindow orderFront:nil]; 98 } 99 else 100 { 101 [nsView setFrame:contentRect]; 102 [[nsWindow contentView] setFrame:contentRect]; 103 } 104 105 // finally, set SDL environment variables with all this nonsense 106 char SDL_windowhack[50]; 107 108 sprintf(SDL_windowhack,"SDL_NSWindowPointer=%ld",(int)nsWindow); 109 putenv(SDL_windowhack); 110 111 sprintf(SDL_windowhack,"SDL_NSViewPointer=%ld",(int)nsView); 112 putenv(SDL_windowhack); 113} 114 115void destroyCocoaView(void) 116{ 117 if (cocoaApplication) 118 { 119 [nsParentWindow setDelegate:oldDelegate]; 120 121 // we're using a floating panel so it doesn't automatically get destroyed 122 [nsWindow release]; 123 124 nsWindow = nil; 125 nsView = nil; 126 oldDelegate = nil; 127 } 128 else if (nsWindow) 129 { 130 // Reference count cannot fall below 2 because SDL releases the window when closing 131 // and again when reinitialising (even though this is our own window...). 132 if ([nsWindow retainCount] > 2) 133 [nsWindow release]; 134 135 // SDL takes care of all the destroying...a little too much, so make sure our Carbon 136 // window is still displayed (via its Cocoa wrapper) 137 [nsWindow makeKeyAndOrderFront:nil]; 138 } 139} 140