devdraw: fix screen grabber, allocation warning

R=rsc
CC=plan9port.codebot
http://codereview.appspot.com/5170041
This commit is contained in:
David Jeannot 2011-10-03 18:16:09 -04:00 committed by Russ Cox
parent c49b45ed3e
commit 7479a49b90

View file

@ -72,6 +72,9 @@ main(int argc, char **argv)
if(usecopygesture) if(usecopygesture)
reimplementswipe = 1; reimplementswipe = 1;
if(OSX_VERSION < 100700)
[NSAutoreleasePool new];
[NSApplication sharedApplication]; [NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp setDelegate:[appdelegate new]]; [NSApp setDelegate:[appdelegate new]];
@ -81,18 +84,17 @@ main(int argc, char **argv)
struct { struct {
NSWindow *std; NSWindow *std;
NSWindow *ofs; NSWindow *ofs; /* old fullscreen */
NSWindow *p; NSWindow *p;
NSView *content; NSView *content;
Cursor *cursor; Cursor *cursor;
NSString *title;
QLock titlel;
char *rectstr; char *rectstr;
NSBitmapImageRep *img; NSBitmapImageRep *img;
NSRect flushrect; NSRect flushrect;
int needflush; int needflush;
} win; } win;
static void autohide(int);
static void drawimg(void); static void drawimg(void);
static void flushwin(void); static void flushwin(void);
static void getmousepos(void); static void getmousepos(void);
@ -100,7 +102,7 @@ static void makeicon(void);
static void makemenu(void); static void makemenu(void);
static void makewin(void); static void makewin(void);
static void resize(void); static void resize(void);
static void sendmouse(int); static void sendmouse(void);
static void setcursor0(void); static void setcursor0(void);
static void togglefs(void); static void togglefs(void);
@ -116,12 +118,12 @@ static void togglefs(void);
- (void)windowDidBecomeKey:(id)arg - (void)windowDidBecomeKey:(id)arg
{ {
getmousepos(); getmousepos();
sendmouse(0); sendmouse();
} }
- (void)windowDidResize:(id)arg - (void)windowDidResize:(id)arg
{ {
getmousepos(); getmousepos();
sendmouse(0); sendmouse();
if([win.p inLiveResize]) if([win.p inLiveResize])
return; return;
@ -142,8 +144,9 @@ static void togglefs(void);
} }
- (void)windowDidChangeScreen:(id)arg - (void)windowDidChangeScreen:(id)arg
{ {
if(win.p == win.ofs)
autohide(1);
[win.ofs setFrame:[[win.p screen] frame] display:YES]; [win.ofs setFrame:[[win.p screen] frame] display:YES];
resize(); resize();
} }
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)arg - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)arg
@ -204,6 +207,7 @@ attachscreen(char *label, char *winsize)
} }
- (BOOL)canBecomeKeyWindow - (BOOL)canBecomeKeyWindow
{ {
// just keyboard? or all inputs?
return YES; // else no keyboard focus with NSBorderlessWindowMask return YES; // else no keyboard focus with NSBorderlessWindowMask
} }
@end @end
@ -245,8 +249,6 @@ makewin(void)
[win.std center]; [win.std center];
#if OSX_VERSION >= 100700 #if OSX_VERSION >= 100700
[win.std setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; [win.std setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
#else
[win.std setShowsResizeIndicator:YES];
#endif #endif
[win.std setMinSize:NSMakeSize(128,128)]; [win.std setMinSize:NSMakeSize(128,128)];
[win.std setAcceptsMouseMovedEvents:YES]; [win.std setAcceptsMouseMovedEvents:YES];
@ -266,6 +268,7 @@ makewin(void)
[win.p makeKeyAndOrderFront:nil]; [win.p makeKeyAndOrderFront:nil];
} }
// explain the bottom-corner bug here (osx-screen-carbon.m:/^eresized)
static Memimage* static Memimage*
makeimg(void) makeimg(void)
{ {
@ -315,7 +318,9 @@ static void
resize(void) resize(void)
{ {
makeimg(); makeimg();
sendmouse(1);
mouseresized = 1;
sendmouse();
} }
void void
@ -332,6 +337,8 @@ _flushmemscreen(Rectangle r)
waitUntilDone:YES]; waitUntilDone:YES];
} }
static void drawresizehandle(void);
static void static void
drawimg(void) drawimg(void)
{ {
@ -352,6 +359,10 @@ drawimg(void)
[win.img drawInRect:dr fromRect:sr [win.img drawInRect:dr fromRect:sr
operation:NSCompositeCopy fraction:1 operation:NSCompositeCopy fraction:1
respectFlipped:YES hints:nil]; respectFlipped:YES hints:nil];
if(OSX_VERSION<100700 && win.p==win.std)
drawresizehandle();
[win.content unlockFocus]; [win.content unlockFocus];
win.needflush = 1; win.needflush = 1;
} }
@ -366,6 +377,49 @@ flushwin(void)
} }
} }
enum
{
Pixel = 1,
Handlesize = 16*Pixel,
};
static void
drawresizehandle(void)
{
NSBezierPath *p;
NSRect r;
NSSize size;
Point o;
size = [win.img size];
o = Pt(size.width+1-Handlesize, size.height+1-Handlesize);
r = NSMakeRect(o.x, o.y, Handlesize, Handlesize);
if(NSIntersectsRect(r, win.flushrect) == 0)
return;
[[NSColor whiteColor] setFill];
[[NSColor lightGrayColor] setStroke];
[NSBezierPath fillRect:r];
[NSBezierPath strokeRect:r];
[[NSColor darkGrayColor] setStroke];
p = [NSBezierPath bezierPath];
[p moveToPoint:NSMakePoint(o.x+4, o.y+13)];
[p lineToPoint:NSMakePoint(o.x+13, o.y+4)];
[p moveToPoint:NSMakePoint(o.x+8, o.y+13)];
[p lineToPoint:NSMakePoint(o.x+13, o.y+8)];
[p moveToPoint:NSMakePoint(o.x+12, o.y+13)];
[p lineToPoint:NSMakePoint(o.x+13, o.y+12)];
[p stroke];
}
static void getgesture(NSEvent*); static void getgesture(NSEvent*);
static void getkeyboard(NSEvent*); static void getkeyboard(NSEvent*);
static void getmouse(NSEvent*); static void getmouse(NSEvent*);
@ -519,7 +573,7 @@ getkeyboard(NSEvent *e)
in.kbuttons |= 2; in.kbuttons |= 2;
if(m & NSCommandKeyMask) if(m & NSCommandKeyMask)
in.kbuttons |= 4; in.kbuttons |= 4;
sendmouse(0); sendmouse();
}else }else
if(m & NSAlternateKeyMask){ if(m & NSAlternateKeyMask){
in.kalting = 1; in.kalting = 1;
@ -599,7 +653,7 @@ getmouse(NSEvent *e)
default: default:
panic("getmouse: unexpected event type"); panic("getmouse: unexpected event type");
} }
sendmouse(0); sendmouse();
} }
static void sendswipe(int, int); static void sendswipe(int, int);
@ -803,32 +857,29 @@ static void
sendclick(int b) sendclick(int b)
{ {
in.mbuttons = b; in.mbuttons = b;
sendmouse(0); sendmouse();
in.mbuttons = 0; in.mbuttons = 0;
sendmouse(0); sendmouse();
} }
static void static void
sendchord(int b1, int b2) sendchord(int b1, int b2)
{ {
in.mbuttons = b1; in.mbuttons = b1;
sendmouse(0); sendmouse();
in.mbuttons |= b2; in.mbuttons |= b2;
sendmouse(0); sendmouse();
in.mbuttons = 0; in.mbuttons = 0;
sendmouse(0); sendmouse();
} }
static void static void
sendmouse(int resized) sendmouse(void)
{ {
NSSize size; NSSize size;
int b; int b;
size = [win.img size]; size = [win.img size];
if(resized)
mouseresized = 1;
mouserect = Rect(0, 0, size.width, size.height); mouserect = Rect(0, 0, size.width, size.height);
b = in.kbuttons | in.mbuttons | in.mscroll; b = in.kbuttons | in.mbuttons | in.mscroll;
@ -859,8 +910,6 @@ setmouse(Point p)
// race condition // race condition
in.mpos = p; in.mpos = p;
//NSLog(@"setmouse %d %d", p.x, p.y);
} }
static void static void
@ -873,31 +922,47 @@ togglefs(void)
} }
#endif #endif
NSScreen *screen; NSScreen *screen;
int opt; int willfs;
screen = [win.p screen]; screen = [win.p screen];
willfs = !NSEqualRects([win.p frame], [screen frame]);
autohide(willfs);
[win.content retain]; [win.content retain];
[win.p orderOut:nil]; [win.p orderOut:nil];
[win.p setContentView:nil]; [win.p setContentView:nil];
if(NSEqualRects([win.p frame], [screen frame])){
opt = NSApplicationPresentationDefault; if(willfs)
[NSApp setPresentationOptions:opt];
win.p = win.std;
}else{
opt = NSApplicationPresentationAutoHideDock
| NSApplicationPresentationAutoHideMenuBar;
[NSApp setPresentationOptions:opt];
win.p = win.ofs; win.p = win.ofs;
} else
win.p = win.std;
[win.p setContentView:win.content]; [win.p setContentView:win.content];
[win.p makeKeyAndOrderFront:nil]; [win.p makeKeyAndOrderFront:nil];
[win.content release]; [win.content release];
resize();
qlock(&win.titlel); resize();
[win.p setTitle:win.title]; }
qunlock(&win.titlel);
} static void
autohide(int set)
{
NSScreen *s,*s0;
int opt;
s = [win.p screen];
s0 = [[NSScreen screens] objectAtIndex:0];
if(set && s==s0)
opt = NSApplicationPresentationAutoHideDock
| NSApplicationPresentationAutoHideMenuBar;
else
opt = NSApplicationPresentationDefault;
[NSApp setPresentationOptions:opt];
}
// Rewrite this function // Rewrite this function
// See ./osx-delegate.m implementation (NSLocalizedString) // See ./osx-delegate.m implementation (NSLocalizedString)
@ -962,26 +1027,14 @@ getsnarf(void)
pb = [NSPasteboard generalPasteboard]; pb = [NSPasteboard generalPasteboard];
// use NSPasteboardTypeString instead of NSStringPboardType
qlock(&snarfl); qlock(&snarfl);
s = [pb stringForType:NSStringPboardType]; s = [pb stringForType:NSPasteboardTypeString];
qunlock(&snarfl); qunlock(&snarfl);
// change the pastebuffer here to see if s is
// altered. Move the lock accordingly.
if(s) if(s)
return strdup((char*)[s UTF8String]); return strdup((char*)[s UTF8String]);
else else
return nil; return nil;
// "you should periodically drain and create
// autorelease pools (like the Application Kit does
// on the main thread); otherwise, autoreleased
// objects accumulate and your memory footprint
// grows."
// Should we do it here?
// Verify that we need it before.
} }
void void
@ -990,7 +1043,6 @@ putsnarf(char *s)
NSArray *t; NSArray *t;
NSPasteboard *pb; NSPasteboard *pb;
NSString *str; NSString *str;
int r;
if(strlen(s) >= SnarfSize) if(strlen(s) >= SnarfSize)
return; return;
@ -1001,26 +1053,25 @@ putsnarf(char *s)
qlock(&snarfl); qlock(&snarfl);
[pb declareTypes:t owner:nil]; [pb declareTypes:t owner:nil];
r = [pb setString:str forType:NSPasteboardTypeString]; [pb setString:str forType:NSPasteboardTypeString];
qunlock(&snarfl); qunlock(&snarfl);
if(!r) [str release];
NSLog(@"putsnarf: setString failed");
} }
void void
kicklabel(char *label) kicklabel(char *label)
{ {
NSString *s;
if(label == nil) if(label == nil)
return; return;
qlock(&win.titlel); s = [[NSString alloc] initWithUTF8String:label];
if(win.title) [win.std setTitle:s];
[win.title release]; [win.ofs setTitle:s];
win.title = [[NSString alloc] initWithUTF8String:label]; [[NSApp dockTile] setBadgeLabel:s];
[win.p setTitle:win.title]; [s release];
[[NSApp dockTile] setBadgeLabel:win.title];
qunlock(&win.titlel);
} }
void void
@ -1028,7 +1079,7 @@ setcursor(Cursor *cursor)
{ {
win.cursor = cursor; win.cursor = cursor;
// cursor change only if main thread // no cursor change unless in main thread
[appdelegate [appdelegate
performSelectorOnMainThread:@selector(callsetcursor0:) performSelectorOnMainThread:@selector(callsetcursor0:)
withObject:nil withObject:nil