From f177c0ba18193fb89ad1b5d84eac2906e8c3b4f1 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 8 Jan 2020 19:49:33 -0500 Subject: devdraw: drop pre-metal macOS support We didn't start using Metal until macOS 10.14, but it was available on 10.13, which is currently the oldest Apple-supported version of macOS. Simplify by deleting the old code. --- src/cmd/devdraw/cocoa-screen.m | 1674 ---------------------------------------- src/cmd/devdraw/macargv.m | 3 - src/cmd/devdraw/mkwsysrules.sh | 16 +- 3 files changed, 5 insertions(+), 1688 deletions(-) delete mode 100644 src/cmd/devdraw/cocoa-screen.m (limited to 'src') diff --git a/src/cmd/devdraw/cocoa-screen.m b/src/cmd/devdraw/cocoa-screen.m deleted file mode 100644 index 97128da2..00000000 --- a/src/cmd/devdraw/cocoa-screen.m +++ /dev/null @@ -1,1674 +0,0 @@ -/* - * Cocoa's event loop must be in main thread. - * - * Unless otherwise stated, all coordinate systems - * are bottom-left-based. - */ - -#define Cursor OSXCursor -#define Point OSXPoint -#define Rect OSXRect - -#import - -#undef Cursor -#undef Point -#undef Rect - -#include -#include -#include "cocoa-thread.h" -#include -#include -#include -#include -#include "cocoa-screen.h" -#include "osx-keycodes.h" -#include "devdraw.h" -#include "bigarrow.h" -#include "glendapng.h" - -// Use non-deprecated names. -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 -#define NSKeyDown NSEventTypeKeyDown -#define NSShiftKeyMask NSEventModifierFlagShift -#define NSAlternateKeyMask NSEventModifierFlagOption -#define NSCommandKeyMask NSEventModifierFlagCommand -#define NSResizableWindowMask NSWindowStyleMaskResizable -#define NSLeftMouseDown NSEventTypeLeftMouseDown -#define NSLeftMouseUp NSEventTypeLeftMouseUp -#define NSRightMouseDown NSEventTypeRightMouseDown -#define NSRightMouseUp NSEventTypeRightMouseUp -#define NSOtherMouseDown NSEventTypeOtherMouseDown -#define NSOtherMouseUp NSEventTypeOtherMouseUp -#define NSScrollWheel NSEventTypeScrollWheel -#define NSMouseMoved NSEventTypeMouseMoved -#define NSLeftMouseDragged NSEventTypeLeftMouseDragged -#define NSRightMouseDragged NSEventTypeRightMouseDragged -#define NSOtherMouseDragged NSEventTypeOtherMouseDragged -#define NSCompositeCopy NSCompositingOperationCopy -#define NSCompositeSourceIn NSCompositingOperationSourceIn -#define NSFlagsChanged NSEventTypeFlagsChanged -#define NSTitledWindowMask NSWindowStyleMaskTitled -#define NSClosableWindowMask NSWindowStyleMaskClosable -#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable -#define NSBorderlessWindowMask NSWindowStyleMaskBorderless -#endif - -AUTOFRAMEWORK(Cocoa) - -#define LOG if(0)NSLog -#define panic sysfatal - -int usegestures = 0; -int useliveresizing = 0; -int useoldfullscreen = 0; -int usebigarrow = 0; - -static void setprocname(const char*); - -/* - * By default, devdraw uses retina displays. - * Set devdrawretina=0 in the environment to override. - */ -int devdrawretina = 1; - -void -usage(void) -{ - fprint(2, "usage: devdraw (don't run directly)\n"); - threadexitsall("usage"); -} - -@interface appdelegate : NSObject @end - -NSObject *myApp; - -void -threadmain(int argc, char **argv) -{ - char *envvar; - - /* - * Move the protocol off stdin/stdout so that - * any inadvertent prints don't screw things up. - */ - dup(0,3); - dup(1,4); - close(0); - close(1); - open("/dev/null", OREAD); - open("/dev/null", OWRITE); - - ARGBEGIN{ - case 'D': /* for good ps -a listings */ - break; - case 'f': - useoldfullscreen = 1; - break; - case 'g': - usegestures = 1; - break; - case 'b': - usebigarrow = 1; - break; - default: - usage(); - }ARGEND - - setprocname(argv0); - - if (envvar = getenv("devdrawretina")) - devdrawretina = atoi(envvar) > 0; - - if(OSX_VERSION < 100700) - [NSAutoreleasePool new]; - - [NSApplication sharedApplication]; - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - myApp = [appdelegate new]; - [NSApp setDelegate:myApp]; - [NSApp run]; -} - -#define WIN win.ofs[win.isofs] - -struct -{ - NSWindow *ofs[2]; /* ofs[1] for old fullscreen; ofs[0] else */ - int isofs; - int isnfs; - NSView *content; - NSBitmapImageRep *img; - int needimg; - int deferflush; - NSCursor *cursor; - CGFloat topointscale; - CGFloat topixelscale; -} win; - -struct -{ - NSCursor *bigarrow; - int kbuttons; - int mbuttons; - NSPoint mpos; - int mscroll; - int willactivate; -} in; - -static void hidebars(int); -static void flushimg(NSRect); -static void autoflushwin(int); -static void flushwin(void); -static void followzoombutton(NSRect); -static void getmousepos(void); -static void makeicon(void); -static void makemenu(void); -static void makewin(char*); -static void sendmouse(void); -static void kicklabel0(char*); -static void setcursor0(Cursor*); -static void togglefs(void); -static void acceptresizing(int); - -static NSCursor* makecursor(Cursor*); - -static NSSize winsizepixels(); -static NSSize winsizepoints(); -static NSRect scalerect(NSRect, CGFloat); -static NSPoint scalepoint(NSPoint, CGFloat); -static NSRect dilate(NSRect); - -@implementation appdelegate -- (void)applicationDidFinishLaunching:(id)arg -{ - in.bigarrow = makecursor(&bigarrow); - makeicon(); - makemenu(); - [NSApplication - detachDrawingThread:@selector(callservep9p:) - toTarget:[self class] withObject:nil]; -} - -- (void)windowDidBecomeKey:(id)arg -{ - getmousepos(); - sendmouse(); -} -- (void)windowDidResize:(id)arg -{ - getmousepos(); - sendmouse(); -} -- (void)windowWillStartLiveResize:(id)arg -{ - if(useliveresizing == 0) - [win.content setHidden:YES]; -} -- (void)windowDidEndLiveResize:(id)arg -{ - if(useliveresizing == 0) - [win.content setHidden:NO]; -} -- (void)windowDidChangeScreen:(id)arg -{ - if(win.isnfs || win.isofs) - hidebars(1); - [win.ofs[1] setFrame:[[WIN screen] frame] display:YES]; -} -- (BOOL)windowShouldZoom:(id)arg toFrame:(NSRect)r -{ - followzoombutton(r); - return YES; -} -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)arg -{ - return YES; -} -- (void)applicationDidBecomeActive:(id)arg{ in.willactivate = 0;} -- (void)windowWillEnterFullScreen:(id)arg{ acceptresizing(1);} -- (void)windowDidEnterFullScreen:(id)arg{ win.isnfs = 1; hidebars(1);} -- (void)windowWillExitFullScreen:(id)arg{ win.isnfs = 0; hidebars(0);} -- (void)windowDidExitFullScreen:(id)arg -{ - NSButton *b; - - b = [WIN standardWindowButton:NSWindowMiniaturizeButton]; - - if([b isEnabled] == 0){ - [b setEnabled:YES]; - hidebars(0); - } -} -- (void)windowWillClose:(id)arg -{ - autoflushwin(0); /* can crash otherwise */ -} - -+ (void)callservep9p:(id)arg -{ - servep9p(); - [NSApp terminate:self]; -} -- (void)plumbmanual:(id)arg -{ - if(fork() != 0) - return; - execl("plumb", "plumb", "devdraw(1)", nil); -} -+ (void)callflushwin:(id)arg{ flushwin();} -- (void)calltogglefs:(id)arg{ togglefs();} - -+ (void)callflushimg:(NSValue*)v{ flushimg([v rectValue]);} -+ (void)callmakewin:(NSValue*)v{ makewin([v pointerValue]);} -+ (void)callsetcursor0:(NSValue*)v{ setcursor0([v pointerValue]);} -+ (void)callkicklabel0:(NSValue*)v{ kicklabel0([v pointerValue]);} -@end - -static Memimage* initimg(void); - -Memimage* -attachscreen(char *label, char *winsize) -{ - static int first = 1; - - if(first) - first = 0; - else - panic("attachscreen called twice"); - - if(label == nil) - label = "gnot a label"; - if(strcmp(label, "page") == 0) - useliveresizing = 1; - - /* - * Create window in main thread, else no cursor - * change while resizing. - */ - [appdelegate - performSelectorOnMainThread:@selector(callmakewin:) - withObject:[NSValue valueWithPointer:winsize] - waitUntilDone:YES]; -// makewin(winsize); - - kicklabel(label); - return initimg(); -} - -@interface appwin : NSWindow @end -@interface contentview : NSView @end - -@implementation appwin -- (NSTimeInterval)animationResizeTime:(NSRect)r -{ - return 0; -} -- (BOOL)canBecomeKeyWindow -{ - return YES; /* else no keyboard for old fullscreen */ -} -- (void)makeKeyAndOrderFront:(id)arg -{ - LOG(@"makeKeyAndOrderFront"); - - autoflushwin(1); - [win.content setHidden:NO]; - [super makeKeyAndOrderFront:arg]; -} -- (void)miniaturize:(id)arg -{ - [super miniaturize:arg]; - [NSApp hide:nil]; - - [win.content setHidden:YES]; - autoflushwin(0); -} -- (void)deminiaturize:(id)arg -{ - autoflushwin(1); - [win.content setHidden:NO]; - [super deminiaturize:arg]; -} - -- (NSDragOperation)draggingEntered:(id)arg -{ - NSPasteboard *b; - NSDragOperation op; - - op = [arg draggingSourceOperationMask]; - b = [arg draggingPasteboard]; - - if([[b types] containsObject:NSFilenamesPboardType]) - if(op&NSDragOperationLink) - return NSDragOperationLink; - - return NSDragOperationNone; -} - -- (BOOL)performDragOperation:(id)arg -{ - NSPasteboard *b; - NSArray *files; - int i, n; - - b = [arg draggingPasteboard]; - if(![[b types] containsObject:NSFilenamesPboardType]) - return NO; - - files = [b propertyListForType:NSFilenamesPboardType]; - n = [files count]; - for(i=0; i= 100700 - [w setCollectionBehavior: - NSWindowCollectionBehaviorFullScreenPrimary]; -#endif - [w setContentMinSize:NSMakeSize(128,128)]; - - [w registerForDraggedTypes:[NSArray arrayWithObjects: - NSFilenamesPboardType, nil]]; - - win.ofs[0] = w; - win.ofs[1] = [[appwin alloc] - initWithContentRect:sr - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered defer:YES]; - for(i=0; i<2; i++){ - [win.ofs[i] setAcceptsMouseMovedEvents:YES]; - [win.ofs[i] setDelegate:myApp]; - [win.ofs[i] setDisplaysWhenScreenProfileChanges:NO]; - } - win.isofs = 0; - win.content = [contentview new]; - [WIN setContentView:win.content]; - - topwin(); -} - -static Memimage* -initimg(void) -{ - Memimage *i; - NSSize size, ptsize; - Rectangle r; - - size = winsizepixels(); - LOG(@"initimg %.0f %.0f", size.width, size.height); - - r = Rect(0, 0, size.width, size.height); - i = allocmemimage(r, XBGR32); - if(i == nil) - panic("allocmemimage: %r"); - if(i->data == nil) - panic("i->data == nil"); - - win.img = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes:&i->data->bdata - pixelsWide:Dx(r) - pixelsHigh:Dy(r) - bitsPerSample:8 - samplesPerPixel:3 - hasAlpha:NO - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:bytesperline(r, 32) - bitsPerPixel:32]; - ptsize = winsizepoints(); - [win.img setSize: ptsize]; - win.topixelscale = size.width / ptsize.width; - win.topointscale = 1.0f / win.topixelscale; - - // NOTE: This is not really the display DPI. - // On retina, topixelscale is 2; otherwise it is 1. - // This formula gives us 220 for retina, 110 otherwise. - // That's not quite right but it's close to correct. - // http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density#Apple - displaydpi = win.topixelscale * 110; - - return i; -} - -void -resizeimg(void) -{ - [win.img release]; - _drawreplacescreenimage(initimg()); - - mouseresized = 1; - sendmouse(); -} - -static void -waitimg(int msec) -{ - NSDate *limit; - int n; - - win.needimg = 1; - win.deferflush = 0; - - n = 0; - limit = [NSDate dateWithTimeIntervalSinceNow:msec/1000.0]; - do{ - [[NSRunLoop currentRunLoop] - runMode:@"waiting image" - beforeDate:limit]; - n++; - }while(win.needimg && [(NSDate*)[NSDate date] compare:limit]<0); - - win.deferflush = win.needimg; - - LOG(@"waitimg %s (%d loop)", win.needimg?"defer":"ok", n); -} - -void -_flushmemscreen(Rectangle r) -{ - static int n; - NSRect rect; - - LOG(@"_flushmemscreen"); - - if(n==0){ - n++; - return; /* to skip useless white init rect */ - }else - if(n==1){ - [WIN performSelectorOnMainThread: - @selector(makeKeyAndOrderFront:) - withObject:nil - waitUntilDone:NO]; - n++; - }else - if([win.content canDraw] == 0) - return; - - rect = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r)); - - // This can get blocked behind responding to mouse events, - // which need to acquire the zlock, so let go of it during - // the flush. Perhaps the waitUntilDone:YES is wrong? - zunlock(); - [appdelegate - performSelectorOnMainThread:@selector(callflushimg:) - withObject:[NSValue valueWithRect:rect] - waitUntilDone:YES - modes:[NSArray arrayWithObjects: - NSRunLoopCommonModes, - @"waiting image", nil]]; - zlock(); -} - -static void drawimg(NSRect, uint); -static void drawresizehandle(void); - -enum -{ - Pixel = 1, - Barsize = 4*Pixel, - Cornersize = 3*Pixel, - Handlesize = 3*Barsize + 1*Pixel, -}; - -/* - * |rect| is in pixel coordinates. - */ -static void -flushimg(NSRect rect) -{ - NSRect dr, r; - - if([win.content lockFocusIfCanDraw] == 0) - return; - - if(win.needimg){ - if(!NSEqualSizes(scalerect(rect, win.topointscale).size, [win.img size])){ - LOG(@"flushimg reject %.0f %.0f", - rect.size.width, rect.size.height); - [win.content unlockFocus]; - return; - } - win.needimg = 0; - }else - win.deferflush = 1; - - LOG(@"flushimg ok %.0f %.0f", rect.size.width, rect.size.height); - - /* - * Unless we are inside "drawRect", we have to round - * the corners ourselves, if this is the custom. - * "NSCompositeSourceIn" can do that, but we don't - * apply it to the whole rectangle, because this - * slows down trackpad scrolling considerably in - * Acme. - */ - r = [win.content bounds]; - rect = dilate(scalerect(rect, win.topointscale)); - r.size.height -= Cornersize; - dr = NSIntersectionRect(r, rect); - LOG(@"r %.0f %.0f %.0f %.0f", r.origin.x, r.origin.y, rect.size.width, rect.size.height); - LOG(@"rect in points %f %f %.0f %.0f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); - LOG(@"dr in points %f %f %.0f %.0f", dr.origin.x, dr.origin.y, dr.size.width, dr.size.height); - drawimg(dr, NSCompositeCopy); - - r.origin.y = r.size.height; - r.size = NSMakeSize(Cornersize, Cornersize); - dr = NSIntersectionRect(r, rect); - drawimg(dr, NSCompositeSourceIn); - - r.origin.x = [win.img size].width - Cornersize; - dr = NSIntersectionRect(r, rect); - drawimg(dr, NSCompositeSourceIn); - - r.size.width = r.origin.x - Cornersize; - r.origin.x -= r.size.width; - dr = NSIntersectionRect(r, rect); - drawimg(dr, NSCompositeCopy); - - if(OSX_VERSION<100700 && win.isofs==0){ - r.origin.x = [win.img size].width - Handlesize; - r.origin.y = [win.img size].height - Handlesize; - r.size = NSMakeSize(Handlesize, Handlesize); - if(NSIntersectsRect(r, rect)) - drawresizehandle(); - } - [win.content unlockFocus]; -} - -static void -autoflushwin(int set) -{ - static NSTimer *t; - - if(set){ - if(t) - return; - /* - * We need "NSRunLoopCommonModes", otherwise the - * timer will not fire during live resizing. - */ - t = [NSTimer - timerWithTimeInterval:0.033 - target:[appdelegate class] - selector:@selector(callflushwin:) userInfo:nil - repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:t - forMode:NSRunLoopCommonModes]; - }else{ - [t invalidate]; - t = nil; - win.deferflush = 0; - } -} - -static void -flushwin(void) -{ - if(win.deferflush && win.needimg==0){ - [WIN flushWindow]; - win.deferflush = 0; - } -} - -/* - * |dr| is sized in points. What if I make it pixels? - */ -static void -drawimg(NSRect dr, uint op) -{ - CGContextRef c; - CGImageRef i; - NSRect sr; - - if(NSIsEmptyRect(dr)) - return; - - sr = [win.content convertRect:dr fromView:nil]; - LOG(@"before dr: %f %f %f %f\n", dr.origin.x, dr.origin.y, dr.size.width, dr.size.height); - LOG(@"before sr: %f %f %f %f\n", sr.origin.x, sr.origin.y, sr.size.width, sr.size.height); - - dr = scalerect(dr, win.topixelscale); - sr = scalerect(sr, win.topixelscale); - - LOG(@"dr: %f %f %f %f\n", dr.origin.x, dr.origin.y, dr.size.width, dr.size.height); - LOG(@"sr: %f %f %f %f\n", sr.origin.x, sr.origin.y, sr.size.width, sr.size.height); - if(OSX_VERSION >= 100800){ - i = CGImageCreateWithImageInRect([win.img CGImage], NSRectToCGRect(dr)); - c = [[WIN graphicsContext] graphicsPort]; - - CGContextSaveGState(c); - if(op == NSCompositeSourceIn) - CGContextSetBlendMode(c, kCGBlendModeSourceIn); - LOG(@"wim.img size %f %f\n", [win.img size].width, [win.img size].height); - CGContextTranslateCTM(c, 0, [win.img size].height); - CGContextScaleCTM(c, win.topointscale, -win.topointscale); - CGContextDrawImage(c, NSRectToCGRect(sr), i); - CGContextRestoreGState(c); - - CGImageRelease(i); - }else{ - [win.img drawInRect:dr fromRect:sr - operation:op fraction:1 - respectFlipped:YES hints:nil]; - } -// NSFrameRect(dr); -} - -static void -drawresizehandle(void) -{ - NSColor *color[Barsize]; - NSPoint a,b; - Point c; - int i,j; - - c = Pt([win.img size].width, [win.img size].height); - - [[WIN graphicsContext] setShouldAntialias:NO]; - - color[0] = [NSColor clearColor]; - color[1] = [NSColor darkGrayColor]; - color[2] = [NSColor lightGrayColor]; - color[3] = [NSColor whiteColor]; - - for(i=1; i+Barsize <= Handlesize; ) - for(j=0; j0) - keystroke(k); - else - keystroke([s characterAtIndex:0]); - break; - - case NSFlagsChanged: - if(in.mbuttons || in.kbuttons){ - in.kbuttons = 0; - if(m & NSControlKeyMask) - in.kbuttons |= 1; - if(m & NSAlternateKeyMask) - in.kbuttons |= 2; - if(m & NSCommandKeyMask) - in.kbuttons |= 4; - sendmouse(); - }else - if(m&NSAlternateKeyMask && (omod&NSAlternateKeyMask)==0) - keystroke(Kalt); - break; - - default: - panic("getkey: unexpected event type"); - } - omod = m; -} - -/* - * Devdraw does not use NSTrackingArea, that often - * forgets to update the cursor on entering and on - * leaving the area, and that sometimes stops sending - * us MouseMove events, at least on OS X Lion. - */ -static void -updatecursor(void) -{ - NSCursor *c; - int isdown, isinside; - - isinside = NSPointInRect(in.mpos, [win.content bounds]); - isdown = (in.mbuttons || in.kbuttons); - - if(win.cursor && (isinside || isdown)) - c = win.cursor; - else if(isinside && usebigarrow) - c = in.bigarrow; - else - c = [NSCursor arrowCursor]; - [c set]; - - /* - * Without this trick, we can come back from the dock - * with a resize cursor. - */ - if(OSX_VERSION >= 100700) - [NSCursor unhide]; -} - -static void -acceptresizing(int set) -{ - uint old, style; - - old = [WIN styleMask]; - - if((old | NSResizableWindowMask) != Winstyle) - return; /* when entering new fullscreen */ - - if(set) - style = Winstyle; - else - style = Winstyle & ~NSResizableWindowMask; - - if(style != old) - [WIN setStyleMask:style]; -} - -static void -getmousepos(void) -{ - NSPoint p, q; - - p = [WIN mouseLocationOutsideOfEventStream]; - q = [win.content convertPoint:p fromView:nil]; - - /* q is in point coordinates. in.mpos is in pixels. */ - q = scalepoint(q, win.topixelscale); - - in.mpos.x = round(q.x); - in.mpos.y = round(q.y); - - updatecursor(); - - if(win.isnfs || win.isofs) - hidebars(1); - else if(OSX_VERSION>=100700 && [WIN inLiveResize]==0){ - if(p.x<12 && p.y<12 && p.x>2 && p.y>2) - acceptresizing(0); - else - acceptresizing(1); - } -} - -static void -getmouse(NSEvent *e) -{ - float d; - int b, m; - - if([WIN isKeyWindow] == 0) - return; - - getmousepos(); - - switch([e type]){ - case NSLeftMouseDown: - case NSLeftMouseUp: - case NSOtherMouseDown: - case NSOtherMouseUp: - case NSRightMouseDown: - case NSRightMouseUp: - b = [NSEvent pressedMouseButtons]; - b = b&~6 | (b&4)>>1 | (b&2)<<1; - b = mouseswap(b); - - if(b == 1){ - m = [e modifierFlags]; - if(m & NSAlternateKeyMask){ - abortcompose(); - b = 2; - }else - if(m & NSCommandKeyMask) - b = 4; - } - in.mbuttons = b; - break; - - case NSScrollWheel: -#if OSX_VERSION >= 100700 - d = [e scrollingDeltaY]; -#else - d = [e deltaY]; -#endif - if(d>0) - in.mscroll = 8; - else - if(d<0) - in.mscroll = 16; - break; - - case NSMouseMoved: - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - break; - - default: - panic("getmouse: unexpected event type"); - } - sendmouse(); -} - -#define Minpinch 0.02 - -static void -getgesture(NSEvent *e) -{ - switch([e type]){ - case NSEventTypeMagnify: - if(fabs([e magnification]) > Minpinch) - togglefs(); - break; - } -} - -static void sendclick(int); - -static uint -msec(void) -{ - return nsec()/1000000; -} - -static void -gettouch(NSEvent *e, int type) -{ - static int tapping; - static uint taptime; - NSSet *set; - int p; - - switch(type){ - case NSTouchPhaseBegan: - p = NSTouchPhaseTouching; - set = [e touchesMatchingPhase:p inView:nil]; - if(set.count == 3){ - tapping = 1; - taptime = msec(); - }else - if(set.count > 3) - tapping = 0; - break; - - case NSTouchPhaseMoved: - tapping = 0; - break; - - case NSTouchPhaseEnded: - p = NSTouchPhaseTouching; - set = [e touchesMatchingPhase:p inView:nil]; - if(set.count == 0){ - if(tapping && msec()-taptime<400) - sendclick(2); - tapping = 0; - } - break; - - case NSTouchPhaseCancelled: - break; - - default: - panic("gettouch: unexpected event type"); - } -} - -static void -sendclick(int b) -{ - in.mbuttons = b; - sendmouse(); - in.mbuttons = 0; - sendmouse(); -} - -static void -sendmouse(void) -{ - NSSize size; - int b; - - size = winsizepixels(); - mouserect = Rect(0, 0, size.width, size.height); - - b = in.kbuttons | in.mbuttons | in.mscroll; - mousetrack(in.mpos.x, in.mpos.y, b, msec()); - in.mscroll = 0; -} - -/* - * |p| is in pixels. - */ -void -setmouse(Point p) -{ - NSPoint q; - NSRect r; - - if([NSApp isActive]==0 && in.willactivate==0) - return; - - if([WIN inLiveResize]) - return; - - in.mpos = scalepoint(NSMakePoint(p.x, p.y), win.topointscale); // race condition - - q = [win.content convertPoint:in.mpos toView:nil]; - q = [WIN convertRectToScreen:NSMakeRect(q.x, q.y, 0, 0)].origin; - - r = [[[NSScreen screens] objectAtIndex:0] frame]; - q.y = r.size.height - q.y; /* Quartz is top-left-based here */ - - CGWarpMouseCursorPosition(NSPointToCGPoint(q)); - CGAssociateMouseAndMouseCursorPosition(true); -} - -/* - * |r| is in points. - */ -static void -followzoombutton(NSRect r) -{ - NSRect wr; - Point p; - NSPoint pt; - - wr = [WIN frame]; - wr.origin.y += wr.size.height; - r.origin.y += r.size.height; - - getmousepos(); - pt.x = in.mpos.x; - pt.y = in.mpos.y; - pt = scalepoint(pt, win.topointscale); - pt.x = (r.origin.x - wr.origin.x) + pt.x; - pt.y = -(r.origin.y - wr.origin.y) + pt.y; - pt = scalepoint(pt, win.topixelscale); - - p.x = pt.x; - p.y = pt.y; - - setmouse(p); -} - -static void -togglefs(void) -{ - uint opt, tmp; - -#if OSX_VERSION >= 100700 - NSScreen *s, *s0; - - s = [WIN screen]; - s0 = [[NSScreen screens] objectAtIndex:0]; - - if((s==s0 && useoldfullscreen==0) || win.isnfs) { - [WIN toggleFullScreen:nil]; - return; - } -#endif - [win.content retain]; - [WIN orderOut:nil]; - [WIN setContentView:nil]; - - win.isofs = ! win.isofs; - hidebars(win.isofs); - - /* - * If we move the window from one space to another, - * ofs[0] and ofs[1] can be on different spaces. - * This "setCollectionBehavior" trick moves the - * window to the active space. - */ - opt = [WIN collectionBehavior]; - tmp = opt | NSWindowCollectionBehaviorCanJoinAllSpaces; - [WIN setContentView:win.content]; - [WIN setCollectionBehavior:tmp]; - [WIN makeKeyAndOrderFront:nil]; - [WIN setCollectionBehavior:opt]; - [win.content release]; -} - -enum -{ - Autohiddenbars = NSApplicationPresentationAutoHideDock - | NSApplicationPresentationAutoHideMenuBar, - - Hiddenbars = NSApplicationPresentationHideDock - | NSApplicationPresentationHideMenuBar, -}; - -static void -hidebars(int set) -{ - NSScreen *s,*s0; - uint old, opt; - - s = [WIN screen]; - s0 = [[NSScreen screens] objectAtIndex:0]; - old = [NSApp presentationOptions]; - -#if OSX_VERSION >= 100700 - /* This bit can get lost, resulting in dreadful bugs. */ - if(win.isnfs) - old |= NSApplicationPresentationFullScreen; -#endif - - if(set && s==s0) - opt = (old & ~Autohiddenbars) | Hiddenbars; - else - opt = old & ~(Autohiddenbars | Hiddenbars); - - if(opt != old) - [NSApp setPresentationOptions:opt]; -} - -static void -makemenu(void) -{ - NSMenu *m; - NSMenuItem *i0,*i1; - - m = [NSMenu new]; - i0 = [m addItemWithTitle:@"app" action:NULL keyEquivalent:@""]; - i1 = [m addItemWithTitle:@"help" action:NULL keyEquivalent:@""]; - [NSApp setMainMenu:m]; - [m release]; - - m = [[NSMenu alloc] initWithTitle:@"app"]; - [m addItemWithTitle:@"Full Screen" - action:@selector(calltogglefs:) - keyEquivalent:@"f"]; - [m addItemWithTitle:@"Hide" - action:@selector(hide:) - keyEquivalent:@"h"]; - [m addItemWithTitle:@"Quit" - action:@selector(terminate:) - keyEquivalent:@"q"]; - [i0 setSubmenu:m]; - [m release]; - - m = [[NSMenu alloc] initWithTitle:@"help"]; - [m addItemWithTitle:@"Plumb devdraw(1)" - action:@selector(plumbmanual:) - keyEquivalent:@""]; - [i1 setSubmenu:m]; - [m release]; -} - -// FIXME: Introduce a high-resolution Glenda image. -static void -makeicon(void) -{ - NSData *d; - NSImage *i; - - d = [[NSData alloc] - initWithBytes:glenda_png - length:(sizeof glenda_png)]; - - i = [[NSImage alloc] initWithData:d]; - [NSApp setApplicationIconImage:i]; - [[NSApp dockTile] display]; - [i release]; - [d release]; -} - -QLock snarfl; - -char* -getsnarf(void) -{ - NSPasteboard *pb; - NSString *s; - - pb = [NSPasteboard generalPasteboard]; - - qlock(&snarfl); - s = [pb stringForType:NSPasteboardTypeString]; - qunlock(&snarfl); - - if(s) - return strdup((char*)[s UTF8String]); - else - return nil; -} - -void -putsnarf(char *s) -{ - NSArray *t; - NSPasteboard *pb; - NSString *str; - - if(strlen(s) >= SnarfSize) - return; - - t = [NSArray arrayWithObject:NSPasteboardTypeString]; - pb = [NSPasteboard generalPasteboard]; - str = [[NSString alloc] initWithUTF8String:s]; - - qlock(&snarfl); - [pb declareTypes:t owner:nil]; - [pb setString:str forType:NSPasteboardTypeString]; - qunlock(&snarfl); - - [str release]; -} - -void -kicklabel(char *label) -{ - if(label == nil) - return; - - [appdelegate - performSelectorOnMainThread:@selector(callkicklabel0:) - withObject:[NSValue valueWithPointer:label] - waitUntilDone:YES]; -} - -static void -kicklabel0(char *label) { - NSString *s; - - s = [[NSString alloc] initWithUTF8String:label]; - [win.ofs[0] setTitle:s]; - [win.ofs[1] setTitle:s]; - [[NSApp dockTile] setBadgeLabel:s]; - [s release]; -} - -void -setcursor(Cursor *c, Cursor2 *c2) -{ - USED(c2); - - /* - * No cursor change unless in main thread. - */ - [appdelegate - performSelectorOnMainThread:@selector(callsetcursor0:) - withObject:[NSValue valueWithPointer:c] - waitUntilDone:YES]; -} - -static void -setcursor0(Cursor *c) -{ - NSCursor *d; - - d = win.cursor; - - if(c) - win.cursor = makecursor(c); - else - win.cursor = nil; - - updatecursor(); - - if(d) - [d release]; -} - -/* - * Cursors will be scaled on retina display. - */ -static NSCursor* -makecursor(Cursor *c) -{ - NSBitmapImageRep *r; - NSCursor *d; - NSImage *i; - NSPoint p; - int b; - uchar *plane[5]; - - r = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes:nil - pixelsWide:16 - pixelsHigh:16 - bitsPerSample:1 - samplesPerPixel:2 - hasAlpha:YES - isPlanar:YES - colorSpaceName:NSDeviceWhiteColorSpace - bytesPerRow:2 - bitsPerPixel:1]; - - [r getBitmapDataPlanes:plane]; - - for(b=0; b<2*16; b++){ - plane[0][b] = ~c->set[b]; - plane[1][b] = c->clr[b]; - } - p = NSMakePoint(-c->offset.x, -c->offset.y); - i = [NSImage new]; - [i addRepresentation:r]; - [r release]; - - d = [[NSCursor alloc] initWithImage:i hotSpot:p]; - [i release]; - return d; -} - -void -topwin(void) -{ - [WIN performSelectorOnMainThread: - @selector(makeKeyAndOrderFront:) - withObject:nil - waitUntilDone:NO]; - - in.willactivate = 1; - [NSApp activateIgnoringOtherApps:YES]; -} - -static NSSize -winsizepoints() -{ - return [win.content bounds].size; -} - -static NSSize -winsizepixels() -{ -#if OSX_VERSION >= 100700 - if (OSX_VERSION >= 100700 && devdrawretina) - return [win.content convertSizeToBacking: winsizepoints()]; - else -#endif - return winsizepoints(); -} - -static NSRect -scalerect(NSRect r, CGFloat scale) -{ - r.origin.x *= scale; - r.origin.y *= scale; - r.size.width *= scale; - r.size.height *= scale; - return r; -} - -/* - * Expands rectangle |r|'s bounds to more inclusive integer bounds to - * eliminate 1 pixel gaps. - */ -static NSRect -dilate(NSRect r) -{ - if(win.topixelscale > 1.0f){ - r.origin.x = floorf(r.origin.x); - r.origin.y = floorf(r.origin.y); - r.size.width = ceilf(r.size.width + 0.5); - r.size.height = ceilf(r.size.height + 0.5); - } - return r; -} - -static NSPoint -scalepoint(NSPoint pt, CGFloat scale) -{ - pt.x *= scale; - pt.y *= scale; - return pt; -} - -static void -setprocname(const char *s) -{ - CFStringRef process_name; - - process_name = CFStringCreateWithBytes(nil, (uchar*)s, strlen(s), kCFStringEncodingUTF8, false); - - // Adapted from Chrome's mac_util.mm. - // http://src.chromium.org/viewvc/chrome/trunk/src/base/mac/mac_util.mm - // - // Copyright (c) 2012 The Chromium Authors. All rights reserved. - // - // Redistribution and use in source and binary forms, with or without - // modification, are permitted provided that the following conditions are - // met: - // - // * Redistributions of source code must retain the above copyright - // notice, this list of conditions and the following disclaimer. - // * Redistributions in binary form must reproduce the above - // copyright notice, this list of conditions and the following disclaimer - // in the documentation and/or other materials provided with the - // distribution. - // * Neither the name of Google Inc. nor the names of its - // contributors may be used to endorse or promote products derived from - // this software without specific prior written permission. - // - // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Warning: here be dragons! This is SPI reverse-engineered from WebKit's - // plugin host, and could break at any time (although realistically it's only - // likely to break in a new major release). - // When 10.7 is available, check that this still works, and update this - // comment for 10.8. - - // Private CFType used in these LaunchServices calls. - typedef CFTypeRef PrivateLSASN; - typedef PrivateLSASN (*LSGetCurrentApplicationASNType)(); - typedef OSStatus (*LSSetApplicationInformationItemType)(int, PrivateLSASN, - CFStringRef, - CFStringRef, - CFDictionaryRef*); - - static LSGetCurrentApplicationASNType ls_get_current_application_asn_func = - NULL; - static LSSetApplicationInformationItemType - ls_set_application_information_item_func = NULL; - static CFStringRef ls_display_name_key = NULL; - - static bool did_symbol_lookup = false; - if (!did_symbol_lookup) { - did_symbol_lookup = true; - CFBundleRef launch_services_bundle = - CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices")); - if (!launch_services_bundle) { - fprint(2, "Failed to look up LaunchServices bundle\n"); - return; - } - - ls_get_current_application_asn_func = - (LSGetCurrentApplicationASNType)( - CFBundleGetFunctionPointerForName( - launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN"))); - if (!ls_get_current_application_asn_func) - fprint(2, "Could not find _LSGetCurrentApplicationASN\n"); - - ls_set_application_information_item_func = - (LSSetApplicationInformationItemType)( - CFBundleGetFunctionPointerForName( - launch_services_bundle, - CFSTR("_LSSetApplicationInformationItem"))); - if (!ls_set_application_information_item_func) - fprint(2, "Could not find _LSSetApplicationInformationItem\n"); - - CFStringRef* key_pointer = (CFStringRef*)( - CFBundleGetDataPointerForName(launch_services_bundle, - CFSTR("_kLSDisplayNameKey"))); - ls_display_name_key = key_pointer ? *key_pointer : NULL; - if (!ls_display_name_key) - fprint(2, "Could not find _kLSDisplayNameKey\n"); - - // Internally, this call relies on the Mach ports that are started up by the - // Carbon Process Manager. In debug builds this usually happens due to how - // the logging layers are started up; but in release, it isn't started in as - // much of a defined order. So if the symbols had to be loaded, go ahead - // and force a call to make sure the manager has been initialized and hence - // the ports are opened. - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - } - if (!ls_get_current_application_asn_func || - !ls_set_application_information_item_func || - !ls_display_name_key) { - return; - } - - PrivateLSASN asn = ls_get_current_application_asn_func(); - // Constant used by WebKit; what exactly it means is unknown. - const int magic_session_constant = -2; - OSErr err = - ls_set_application_information_item_func(magic_session_constant, asn, - ls_display_name_key, - process_name, - NULL /* optional out param */); - if(err != noErr) - fprint(2, "Call to set process name failed\n"); -} - -void -resizewindow(Rectangle r) -{ - USED(r); -} diff --git a/src/cmd/devdraw/macargv.m b/src/cmd/devdraw/macargv.m index 8db56be7..92df2a6f 100644 --- a/src/cmd/devdraw/macargv.m +++ b/src/cmd/devdraw/macargv.m @@ -12,9 +12,6 @@ AUTOFRAMEWORK(Cocoa) void main(void) { - if(OSX_VERSION < 100700) - [NSAutoreleasePool new]; - [NSApplication sharedApplication]; NSObject *delegate = [appdelegate new]; [NSApp setDelegate:delegate]; diff --git a/src/cmd/devdraw/mkwsysrules.sh b/src/cmd/devdraw/mkwsysrules.sh index e94afbd3..a1dc56d3 100644 --- a/src/cmd/devdraw/mkwsysrules.sh +++ b/src/cmd/devdraw/mkwsysrules.sh @@ -22,13 +22,11 @@ fi if [ "x$WSYSTYPE" = "x" ]; then if [ "x`uname`" = "xDarwin" ]; then - if sw_vers | grep 'ProductVersion: 10\.[0-5]\.' >/dev/null; then - echo 1>&2 'OS X 10.5 and older are not supported' + if sw_vers | egrep 'ProductVersion: (10\.[0-9]\.|10\.1[012])$' >/dev/null; then + echo 1>&2 'OS X 10.12 and older are not supported' exit 1 - else - #echo 1>&2 'WARNING: OS X Lion is not working. Copy binaries from a Snow Leopard system.' - WSYSTYPE=osx-cocoa fi + WSYSTYPE=osx-cocoa elif [ -d "$X11" ]; then WSYSTYPE=x11 else @@ -54,12 +52,8 @@ if [ $WSYSTYPE = x11 ]; then XO=`ls x11-*.c 2>/dev/null | sed 's/\.c$/.o/'` echo 'WSYSOFILES=$WSYSOFILES '$XO elif [ $WSYSTYPE = osx-cocoa ]; then - if sw_vers|awk '/ProductVersion/{split($2,a,".");exit(a[2]<14)}' >/dev/null; then # 0 is true in sh. - echo 'OBJCFLAGS=$OBJCFLAGS -fobjc-arc' - echo 'WSYSOFILES=$WSYSOFILES osx-draw.o cocoa-screen-metal-objc.o cocoa-srv.o cocoa-thread.o' - else - echo 'WSYSOFILES=$WSYSOFILES osx-draw.o cocoa-screen-objc.o cocoa-srv.o cocoa-thread.o' - fi + echo 'OBJCFLAGS=$OBJCFLAGS -fobjc-arc' + echo 'WSYSOFILES=$WSYSOFILES osx-draw.o cocoa-screen-metal-objc.o cocoa-srv.o cocoa-thread.o' echo 'MACARGV=macargv-objc.o' elif [ $WSYSTYPE = nowsys ]; then echo 'WSYSOFILES=nowsys.o' -- cgit v1.2.3