1 #include <Cocoa/Cocoa.h>
4 #define CAML_NAME_SPACE
7 #include <sys/socket.h>
10 #include <caml/mlvalues.h>
11 #include <caml/memory.h>
12 #include <caml/callback.h>
13 #include <caml/alloc.h>
14 #include <caml/fail.h>
39 static int terminating = 0;
40 static pthread_mutex_t terminate_mutex = PTHREAD_MUTEX_INITIALIZER;
41 static int server_fd = -1;
42 static CGFloat backing_scale_factor = -1.0;
44 void Abort (NSString *format, ...)
47 va_start (argList, format);
48 NSString *str = [[NSString alloc] initWithFormat:format arguments:argList];
51 NSAlert *alert = [[NSAlert alloc] init];
52 [alert addButtonWithTitle:@"Quit"];
53 [alert setMessageText:@"Internal Error"];
54 [alert setInformativeText:str];
55 [alert setAlertStyle:NSCriticalAlertStyle];
57 [NSApp terminate:nil];
60 void *caml_main_thread (void *argv)
64 pthread_mutex_lock (&terminate_mutex);
65 if (terminating == 0) {
67 [NSApp performSelectorOnMainThread:@selector(terminate:)
71 pthread_mutex_unlock (&terminate_mutex);
76 NSCursor *GetCursor (int idx)
78 static NSCursor *cursors[5];
79 static BOOL initialised = NO;
81 if (initialised == NO) {
82 cursors[0] = [NSCursor arrowCursor];
83 cursors[1] = [NSCursor pointingHandCursor];
84 cursors[2] = [NSCursor arrowCursor];
85 cursors[3] = [NSCursor closedHandCursor];
86 cursors[4] = [NSCursor IBeamCursor];
93 @implementation NSWindow (CategoryNSWindow)
97 return ([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask;
102 @implementation NSView (CategoryNSView)
104 - (NSPoint)locationFromEvent:(NSEvent *)event
107 [self convertPointToBacking:[self convertPoint:[event locationInWindow] fromView:nil]];
108 NSRect bounds = [self convertRectToBacking:[self bounds]];
109 point.y = bounds.size.height - point.y;
113 - (NSRect)convertFrameToBacking
115 return [self convertRectToBacking:[self frame]];
120 @implementation NSEvent (CategoryNSEvent)
122 - (int)deviceIndependentModifierFlags
124 return [self modifierFlags] & NSDeviceIndependentModifierFlagsMask;
129 @interface Connector : NSObject
131 - (instancetype)initWithFileDescriptor:(int)fd;
133 - (void)notifyReshapeWidth:(int)w height:(int)h;
134 - (void)notifyExpose;
135 - (void)keyDown:(uint32_t)key modifierFlags:(NSEventModifierFlags)mask;
137 - (void)mouseEntered:(NSPoint)loc;
139 - (void)mouseMoved:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags;
140 - (void)mouseDown:(NSUInteger)buttons atPoint:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags;
141 - (void)mouseUp:(NSUInteger)buttons atPoint:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags;
144 @implementation Connector
147 NSFileHandle *fileHandle;
150 - (instancetype)initWithFileDescriptor:(int)fd
153 data = [NSMutableData dataWithLength:32];
154 fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd];
158 - (void)setByte:(int8_t)b offset:(int)off
160 [data replaceBytesInRange:NSMakeRange (off, 1) withBytes:&b];
163 - (void)setShort:(int16_t)s offset:(int)off
165 [data replaceBytesInRange:NSMakeRange (off, 2) withBytes:&s];
168 - (void)setInt:(int32_t)n offset:(int)off
170 [data replaceBytesInRange:NSMakeRange (off, 4) withBytes:&n];
175 [fileHandle writeData:data];
178 - (void)notifyReshapeWidth:(int)w height:(int)h
180 [self setByte:EVENT_RESHAPE offset:0];
181 [self setShort:w offset:16];
182 [self setShort:h offset:18];
188 [self setByte:EVENT_EXPOSE offset:0];
192 - (void)keyDown:(uint32_t)key modifierFlags:(NSEventModifierFlags)mask
194 [self setByte:EVENT_KEYDOWN offset:0];
195 [self setInt:key offset:16];
196 [self setInt:mask offset:20];
200 - (void)notifyWinstate:(BOOL)fullScreen
202 [self setByte:EVENT_WINSTATE offset:0];
203 [self setInt:fullScreen offset:16];
209 [self setByte:EVENT_QUIT offset:0];
213 - (void)mouseEntered:(NSPoint)loc
215 [self setByte:EVENT_ENTER offset:0];
216 [self setShort:loc.x offset:16];
217 [self setShort:loc.y offset:20];
223 [self setByte:EVENT_LEAVE offset:0];
227 - (void)mouseDragged:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags
229 [self setByte:EVENT_MOTION offset:0];
230 [self setShort:aPoint.x offset:16];
231 [self setShort:aPoint.y offset:20];
232 [self setInt:flags offset:24];
236 - (void)mouseMoved:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags
238 [self setByte:EVENT_PMOTION offset:0];
239 [self setShort:aPoint.x offset:16];
240 [self setShort:aPoint.y offset:20];
241 [self setInt:flags offset:24];
245 - (void)mouseDown:(NSUInteger)buttons atPoint:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags
247 [self setByte:EVENT_MOUSE offset:0];
248 [self setShort:1 offset:10];
249 [self setInt:buttons offset:12];
250 [self setShort:aPoint.x offset:16];
251 [self setShort:aPoint.y offset:20];
252 [self setInt:flags offset:24];
256 - (void)mouseUp:(NSUInteger)buttons atPoint:(NSPoint)aPoint modifierFlags:(NSEventModifierFlags)flags
258 [self setByte:EVENT_MOUSE offset:0];
259 [self setShort:0 offset:10];
260 [self setInt:buttons offset:12];
261 [self setShort:aPoint.x offset:16];
262 [self setShort:aPoint.y offset:20];
263 [self setInt:flags offset:24];
267 - (void)scrollByDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY
269 [self setByte:EVENT_SCROLL offset:0];
270 [self setInt:(int32_t) deltaX offset:16];
271 [self setInt:(int32_t) deltaY offset:20];
275 - (void)zoom:(CGFloat)z at:(NSPoint)p
277 [self setByte:EVENT_ZOOM offset:0];
278 [self setInt:(int32_t) (z * 1000) offset:16];
279 [self setShort:p.x offset:20];
280 [self setShort:p.y offset:22];
284 - (void)openFile:(NSString *)filename
286 const char *utf8 = [filename UTF8String];
287 unsigned len = [filename lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
288 [self setByte:EVENT_OPEN offset:0];
290 unsigned data_len = [data length] - 4;
292 unsigned chunk_len = MIN (data_len - 4, len - off);
293 [self setShort:chunk_len offset:2];
294 [data replaceBytesInRange:NSMakeRange (4, chunk_len) withBytes:(utf8 + off)];
298 [self setShort:0 offset:2];
304 @interface MyDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate>
309 - (void)setwinbgcol:(NSColor *)col;
310 - (void)applicationWillFinishLaunching:(NSNotification *)not;
311 - (void)applicationDidFinishLaunching:(NSNotification *)not;
312 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;
313 - (void)makeCurrentContext;
317 @interface MyWindow : NSWindow
321 @interface MyView : NSView
323 Connector *connector;
327 - (instancetype)initWithFrame:(NSRect)frame connector:(Connector *)aConnector;
328 - (void)setCursor:(NSCursor *)aCursor;
332 @implementation MyView
334 - (instancetype)initWithFrame:(NSRect)frame connector:(Connector *)aConnector
336 self = [super initWithFrame:frame];
339 connector = aConnector;
340 cursor = [NSCursor arrowCursor];
341 self.acceptsTouchEvents = YES;
347 - (void)setCursor:(NSCursor *)aCursor
352 -(void)resetCursorRects
354 [self addCursorRect:[self bounds] cursor:cursor];
357 - (void)drawRect:(NSRect)bounds
359 // NSLog(@"drawRect: %@", [NSValue valueWithRect:bounds]);
360 [connector notifyExpose];
363 - (void)viewWillMoveToWindow:(NSWindow *)newWindow {
364 NSTrackingArea* trackingArea = [[NSTrackingArea alloc]
365 initWithRect:[self bounds]
366 options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp | NSTrackingInVisibleRect)
369 [self addTrackingArea:trackingArea];
372 - (void)keyDown:(NSEvent *)event
374 // int key = [event keyCode];
375 NSEventModifierFlags mask = [event deviceIndependentModifierFlags];
376 NSString *chars = [event charactersIgnoringModifiers];
377 const uint32_t *c = (uint32_t *) [chars cStringUsingEncoding:NSUTF32LittleEndianStringEncoding];
379 if (*c == 0x7f && !(mask & NSFunctionKeyMask)) {
380 [connector keyDown:0x8 modifierFlags:mask];
382 [connector keyDown:*c modifierFlags:mask];
388 - (void)flagsChanged:(NSEvent *)event
390 NSEventModifierFlags mask = [event deviceIndependentModifierFlags];
391 NSLog (@"flagsChanged: 0x%lx", mask);
393 [connector keyDown:0 modifierFlags:mask];
397 - (void)mouseDown:(NSEvent *)event
399 [connector mouseDown:BUTTON_LEFT
400 atPoint:[self locationFromEvent:event]
401 modifierFlags:[event deviceIndependentModifierFlags]];
404 - (void)mouseUp:(NSEvent *)event
406 [connector mouseUp:BUTTON_LEFT
407 atPoint:[self locationFromEvent:event]
408 modifierFlags:[event deviceIndependentModifierFlags]];
411 - (void)rightMouseDown:(NSEvent *)event
413 [connector mouseDown:BUTTON_RIGHT
414 atPoint:[self locationFromEvent:event]
415 modifierFlags:[event deviceIndependentModifierFlags]];
418 - (void)rightMouseUp:(NSEvent *)event
420 [connector mouseUp:BUTTON_RIGHT
421 atPoint:[self locationFromEvent:event]
422 modifierFlags:[event deviceIndependentModifierFlags]];
425 - (void)rightMouseDragged:(NSEvent *)event
427 [connector mouseDragged:[self locationFromEvent:event]
428 modifierFlags:[event deviceIndependentModifierFlags]];
431 - (void)mouseDragged:(NSEvent *)event
433 [connector mouseDragged:[self locationFromEvent:event]
434 modifierFlags:[event deviceIndependentModifierFlags]];
437 - (void)mouseMoved:(NSEvent *)event
439 [connector mouseMoved:[self locationFromEvent:event]
440 modifierFlags:[event deviceIndependentModifierFlags]];
443 - (void)mouseEntered:(NSEvent *)event
445 [connector mouseEntered:[self locationFromEvent:event]];
448 - (void)mouseExited:(NSEvent *)event
450 [connector mouseExited];
453 - (void)scrollWheel:(NSEvent *)event
455 CGFloat deltaX = [event scrollingDeltaX];
456 CGFloat deltaY = -[event scrollingDeltaY];
458 if ([event hasPreciseScrollingDeltas]) {
459 [connector scrollByDeltaX:(backing_scale_factor * deltaX)
460 deltaY:(backing_scale_factor * deltaY)];
462 NSPoint loc = [self locationFromEvent:event];
463 NSEventModifierFlags mask = [event deviceIndependentModifierFlags];
465 [connector mouseDown:BUTTON_WHEEL_DOWN atPoint:loc modifierFlags:mask];
466 [connector mouseUp:BUTTON_WHEEL_DOWN atPoint:loc modifierFlags:mask];
467 } else if (deltaY < 0.0) {
468 [connector mouseDown:BUTTON_WHEEL_UP atPoint:loc modifierFlags:mask];
469 [connector mouseUp:BUTTON_WHEEL_UP atPoint:loc modifierFlags:mask];
474 - (void)magnifyWithEvent:(NSEvent *)event
476 [connector zoom:[event magnification] at:[self locationFromEvent:event]];
481 @implementation MyWindow
483 - (BOOL)canBecomeKeyWindow
490 @implementation MyDelegate
494 NSOpenGLContext *glContext;
496 Connector *connector;
499 - (instancetype)initWithArgv:(char **)theArgv fileDescriptor:(int)fd
504 connector = [[Connector alloc] initWithFileDescriptor:fd];
509 - (void)setTitle:(NSString *)title
511 [window setTitle:title];
516 [window makeKeyAndOrderFront:self];
521 return [[window contentView] convertFrameToBacking].size.width;
526 return [[window contentView] convertFrameToBacking].size.height;
529 - (void)setwinbgcol:(NSColor *)col
531 [window setBackgroundColor:col];
534 - (void)applicationWillFinishLaunching:(NSNotification *)not
536 NSLog(@"applicationWillFinishLaunching");
537 id menubar = [NSMenu new];
538 id appMenuItem = [NSMenuItem new];
539 id fileMenuItem = [NSMenuItem new];
540 id windowMenuItem = [NSMenuItem new];
541 id helpMenuItem = [NSMenuItem new];
542 [menubar addItem:appMenuItem];
543 [menubar addItem:fileMenuItem];
544 [menubar addItem:windowMenuItem];
545 [menubar addItem:helpMenuItem];
546 [NSApp setMainMenu:menubar];
547 id appMenu = [NSMenu new];
548 id appName = [[NSProcessInfo processInfo] processName];
549 id aboutMenuItem = [[NSMenuItem alloc] initWithTitle:[@"About " stringByAppendingString:appName]
550 action:@selector(orderFrontStandardAboutPanel:)
552 id hideMenuItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName]
553 action:@selector(hide:)
555 id hideOthersMenuItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others"
556 action:@selector(hideOtherApplications:)
558 [hideOthersMenuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
559 id showAllMenuItem = [[NSMenuItem alloc] initWithTitle:@"Show All"
560 action:@selector(unhideAllApplications:)
562 id quitMenuItem = [[NSMenuItem alloc] initWithTitle:[@"Quit " stringByAppendingString:appName]
563 action:@selector(terminate:)
565 [appMenu addItem:aboutMenuItem];
566 [appMenu addItem:[NSMenuItem separatorItem]];
567 [appMenu addItem:hideMenuItem];
568 [appMenu addItem:hideOthersMenuItem];
569 [appMenu addItem:showAllMenuItem];
570 [appMenu addItem:[NSMenuItem separatorItem]];
571 [appMenu addItem:quitMenuItem];
572 [appMenuItem setSubmenu:appMenu];
574 id fileMenu = [[NSMenu alloc] initWithTitle:@"File"];
575 id openMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open..."
576 action:@selector(openDocument:)
578 id closeMenuItem = [[NSMenuItem alloc] initWithTitle:@"Close"
579 action:@selector(performClose:)
581 [fileMenu addItem:openMenuItem];
582 [fileMenu addItem:[NSMenuItem separatorItem]];
583 [fileMenu addItem:closeMenuItem];
584 [fileMenuItem setSubmenu:fileMenu];
586 id windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
587 id miniaturizeMenuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize"
588 action:@selector(performMiniaturize:)
590 id zoomMenuItem = [[NSMenuItem alloc] initWithTitle:@"Zoom"
591 action:@selector(performZoom:)
594 [windowMenu addItem:miniaturizeMenuItem];
595 [windowMenu addItem:zoomMenuItem];
596 [windowMenuItem setSubmenu:windowMenu];
598 id helpMenu = [[NSMenu alloc] initWithTitle:@"Help"];
599 id reportIssueMenuItem = [[NSMenuItem alloc] initWithTitle:@"Report an issue..."
600 action:@selector(reportIssue:)
602 [helpMenu addItem:reportIssueMenuItem];
603 [helpMenuItem setSubmenu:helpMenu];
605 window = [[MyWindow alloc] initWithContentRect:NSMakeRect(0, 0, 400, 400)
606 styleMask:(NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask | NSResizableWindowMask)
607 backing:NSBackingStoreBuffered
611 [window setAcceptsMouseMovedEvents:YES];
612 [window setDelegate:self];
615 [[NSNotificationCenter defaultCenter] addObserver:self
616 selector:@selector(didEnterFullScreen)
617 name:NSWindowDidEnterFullScreenNotification
619 [[NSNotificationCenter defaultCenter] addObserver:self
620 selector:@selector(didExitFullScreen)
621 name:NSWindowDidExitFullScreenNotification
624 MyView *myView = [[MyView alloc] initWithFrame:[[window contentView] bounds]
625 connector:connector];
627 [window setContentView:myView];
628 [window makeFirstResponder:myView];
630 [myView setWantsBestResolutionOpenGLSurface:YES];
632 NSOpenGLPixelFormatAttribute attrs[] =
634 NSOpenGLPFAAccelerated,
635 NSOpenGLPFADoubleBuffer,
636 NSOpenGLPFAColorSize, 24,
637 NSOpenGLPFAAlphaSize, 8,
638 NSOpenGLPFADepthSize, 24,
641 NSOpenGLPixelFormat *pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
642 glContext = [[NSOpenGLContext alloc] initWithFormat:pixFormat shareContext:nil];
644 [glContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
645 [glContext setView:myView];
647 backing_scale_factor = [window backingScaleFactor];
650 - (void)reshape:(NSValue *)val
652 // NSLog (@"reshape: %@ isFullScreen: %d", val, [window isFullScreen]);
653 if ([window isFullScreen]) {
654 [window toggleFullScreen:self];
656 [window setFrame:[window frameRectForContentRect:[val rectValue]]
660 - (void)makeCurrentContext
662 [glContext makeCurrentContext];
663 NSLog (@"OpenGL Version: %s", glGetString(GL_VERSION));
668 [glContext flushBuffer];
671 - (void)didEnterFullScreen
673 // NSLog (@"didEnterFullScreen: %d", [window isFullScreen]);
674 [connector notifyWinstate:YES];
677 - (void)didExitFullScreen
679 // NSLog (@"didExitFullScreen: %d", [window isFullScreen]);
680 [connector notifyWinstate:NO];
685 // NSLog (@"fullscreen: %d", [window isFullScreen]);
686 if ([window isFullScreen] == NO) {
687 [window toggleFullScreen:self];
691 - (void)setCursor:(NSCursor *)aCursor
693 [[window contentView] setCursor: aCursor];
694 [window invalidateCursorRectsForView:[window contentView]];
697 - (void)windowDidResize:(NSNotification *)notification
700 NSRect frame = [[window contentView] convertFrameToBacking];
701 [connector notifyReshapeWidth:frame.size.width height:frame.size.height];
704 - (void)windowDidMove:(NSNotification *)notification
709 - (void)applicationWillTerminate:(NSDictionary *)userInfo
711 pthread_mutex_lock (&terminate_mutex);
712 if (terminating == 0) {
714 [connector notifyQuit];
716 pthread_mutex_unlock (&terminate_mutex);
717 pthread_join (thread, NULL);
720 - (void)windowDidChangeOcclusionState:(NSNotification *)notification
724 - (void)applicationDidFinishLaunching:(NSNotification *)not
726 NSLog(@"applicationDidFinishLaunching");
727 int ret = pthread_create (&thread, NULL, caml_main_thread, argv);
729 Abort (@"pthread_create: %s.", strerror (ret));
733 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
738 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
740 NSLog (@"openFile: %@", filename);
741 [connector openFile:filename];
745 - (void)openDocument:(id)sender
747 NSOpenPanel *openPanel = [NSOpenPanel openPanel];
748 [openPanel beginSheetModalForWindow:window
749 completionHandler:^(NSInteger result){
750 if (result == NSFileHandlingPanelOKButton) {
751 NSString *filename = [[[openPanel URLs] objectAtIndex:0] path];
752 if (filename != nil) {
753 [self application:NSApp openFile:filename];
759 - (void)reportIssue:(id)sender
761 [[NSWorkspace sharedWorkspace]
762 openURL:[NSURL URLWithString:@"https://github.com/moosotc/llpp/issues"]];
767 CAMLprim value ml_mapwin (value unit)
770 [[NSApp delegate] performSelectorOnMainThread:@selector(mapwin)
773 CAMLreturn (Val_unit);
776 CAMLprim value ml_swapb (value unit)
779 [[NSApp delegate] swapb];
780 CAMLreturn (Val_unit);
783 CAMLprim value ml_getw (value unit)
785 return Val_int([[NSApp delegate] getw]);
788 CAMLprim value ml_geth (value unit)
790 return Val_int([[NSApp delegate] geth]);
793 CAMLprim value ml_makecurrentcontext (value unit)
796 [[NSApp delegate] makeCurrentContext];
797 CAMLreturn (Val_unit);
800 CAMLprim value ml_setwinbgcol (value col)
803 int r = ((col >> 16) & 0xff) / 255;
804 int g = ((col >> 8) & 0xff) / 255;
805 int b = ((col >> 0) & 0xff) / 255;
806 NSColor *color = [NSColor colorWithRed:r green:g blue:b alpha:1.0];
807 [[NSApp delegate] performSelectorOnMainThread:@selector(setwinbgcol:)
810 CAMLreturn (Val_unit);
813 CAMLprim value ml_settitle (value title)
816 NSString *str = [NSString stringWithUTF8String:String_val(title)];
817 [[NSApp delegate] performSelectorOnMainThread:@selector(setTitle:)
820 CAMLreturn (Val_unit);
823 CAMLprim value ml_reshape (value w, value h)
826 NSRect r = NSMakeRect (0, 0, Int_val (w), Int_val (h));
827 [[NSApp delegate] performSelectorOnMainThread:@selector(reshape:)
828 withObject:[NSValue valueWithRect:r]
830 CAMLreturn (Val_unit);
833 CAMLprim value ml_fullscreen (value unit)
836 [[NSApp delegate] performSelectorOnMainThread:@selector(fullscreen)
839 CAMLreturn (Val_unit);
842 CAMLprim value ml_setcursor (value curs)
845 // NSLog (@"ml_setcursor: %d", Int_val (curs));
846 NSCursor *cursor = GetCursor (Int_val (curs));
847 [[NSApp delegate] performSelectorOnMainThread:@selector(setCursor:)
850 CAMLreturn (Val_unit);
853 CAMLprim value ml_get_server_fd (value unit)
856 CAMLreturn (Val_int (server_fd));
859 CAMLprim value ml_get_backing_scale_factor (value unit)
862 CAMLreturn (Val_int ((int) backing_scale_factor));
865 CAMLprim value ml_nslog (value str)
868 NSLog (@"%s", String_val (str));
869 CAMLreturn (Val_unit);
872 // HACK to eliminate arg injected by OS X -psn_...
873 int adjust_argv (int argc, char **argv)
875 if (argc > 1 && strncmp (argv[1], "-psn", 4) == 0) {
876 for (unsigned i = 1; i < argc - 1; i ++) {
881 for (int i = 0; i < argc; i ++) {
882 NSLog (@"arg %d: %s", i, argv[i]);
887 int main(int argc, char **argv)
891 int ret = socketpair (AF_UNIX, SOCK_STREAM, 0, sv);
893 Abort (@"socketpair: %s", strerror (ret));
895 // NSLog (@"socketpair sv0 %d sv1 %d", sv[0], sv[1]);
897 argc = adjust_argv (argc, argv);
898 [NSApplication sharedApplication];
899 [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
900 id delegate = [[MyDelegate alloc] initWithArgv:argv fileDescriptor:sv[1]];
901 [NSApp setDelegate:delegate];
902 [NSApp activateIgnoringOtherApps:YES];