2 d0a596c5 2011-10-12 rsc * Cocoa's event loop must be in main thread.
4 a3190377 2012-03-05 rsc * Unless otherwise stated, all coordinate systems
5 a3190377 2012-03-05 rsc * are bottom-left-based.
8 d0a596c5 2011-10-12 rsc #define Cursor OSXCursor
9 a287dbab 2011-09-06 rsc #define Point OSXPoint
10 a287dbab 2011-09-06 rsc #define Rect OSXRect
12 a287dbab 2011-09-06 rsc #import <Cocoa/Cocoa.h>
14 a287dbab 2011-09-06 rsc #undef Cursor
18 a287dbab 2011-09-06 rsc #include <u.h>
19 a287dbab 2011-09-06 rsc #include <libc.h>
20 d0a596c5 2011-10-12 rsc #include "cocoa-thread.h"
21 a287dbab 2011-09-06 rsc #include <draw.h>
22 a287dbab 2011-09-06 rsc #include <memdraw.h>
23 a287dbab 2011-09-06 rsc #include <keyboard.h>
24 a287dbab 2011-09-06 rsc #include <cursor.h>
25 a287dbab 2011-09-06 rsc #include "cocoa-screen.h"
26 a287dbab 2011-09-06 rsc #include "osx-keycodes.h"
27 a287dbab 2011-09-06 rsc #include "devdraw.h"
28 ca81de0a 2011-12-10 rsc #include "bigarrow.h"
29 a287dbab 2011-09-06 rsc #include "glendapng.h"
31 a287dbab 2011-09-06 rsc AUTOFRAMEWORK(Cocoa)
33 a3190377 2012-03-05 rsc #define LOG if(0)NSLog
34 a3190377 2012-03-05 rsc #define panic sysfatal
36 d0a596c5 2011-10-12 rsc int usegestures = 0;
37 a3190377 2012-03-05 rsc int useliveresizing = 0;
38 48107872 2011-09-19 rsc int useoldfullscreen = 0;
39 b4d0ac96 2011-10-23 rsc int usebigarrow = 0;
44 a287dbab 2011-09-06 rsc fprint(2, "usage: devdraw (don't run directly)\n");
45 d0a596c5 2011-10-12 rsc threadexitsall("usage");
48 ca81de0a 2011-12-10 rsc @interface appdelegate : NSObject @end
51 d0a596c5 2011-10-12 rsc threadmain(int argc, char **argv)
54 a287dbab 2011-09-06 rsc * Move the protocol off stdin/stdout so that
55 a287dbab 2011-09-06 rsc * any inadvertent prints don't screw things up.
61 a287dbab 2011-09-06 rsc open("/dev/null", OREAD);
62 a287dbab 2011-09-06 rsc open("/dev/null", OWRITE);
65 d0a596c5 2011-10-12 rsc case 'D': /* for good ps -a listings */
68 d0a596c5 2011-10-12 rsc useoldfullscreen = 1;
71 d0a596c5 2011-10-12 rsc usegestures = 1;
74 b4d0ac96 2011-10-23 rsc usebigarrow = 1;
80 7479a49b 2011-10-03 rsc if(OSX_VERSION < 100700)
81 7479a49b 2011-10-03 rsc [NSAutoreleasePool new];
83 a287dbab 2011-09-06 rsc [NSApplication sharedApplication];
84 a287dbab 2011-09-06 rsc [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
85 a287dbab 2011-09-06 rsc [NSApp setDelegate:[appdelegate new]];
86 a287dbab 2011-09-06 rsc [NSApp activateIgnoringOtherApps:YES];
90 d0a596c5 2011-10-12 rsc #define WIN win.ofs[win.isofs]
94 d0a596c5 2011-10-12 rsc NSWindow *ofs[2]; /* ofs[1] for old fullscreen; ofs[0] else */
97 d0a596c5 2011-10-12 rsc NSView *content;
98 48107872 2011-09-19 rsc NSBitmapImageRep *img;
100 a3190377 2012-03-05 rsc int deferflush;
101 d0a596c5 2011-10-12 rsc NSCursor *cursor;
106 ca81de0a 2011-12-10 rsc NSCursor *bigarrow;
107 d0a596c5 2011-10-12 rsc int kbuttons;
108 d0a596c5 2011-10-12 rsc int mbuttons;
109 ca81de0a 2011-12-10 rsc NSPoint mpos;
110 d0a596c5 2011-10-12 rsc int mscroll;
111 e89a71ff 2012-01-16 rsc int willactivate;
114 e067d2ea 2011-11-08 rsc static void hidebars(int);
115 a3190377 2012-03-05 rsc static void flushimg(NSRect);
116 a3190377 2012-03-05 rsc static void autoflushwin(int);
117 48107872 2011-09-19 rsc static void flushwin(void);
118 d0a596c5 2011-10-12 rsc static void followzoombutton(NSRect);
119 a287dbab 2011-09-06 rsc static void getmousepos(void);
120 48107872 2011-09-19 rsc static void makeicon(void);
121 48107872 2011-09-19 rsc static void makemenu(void);
122 ca81de0a 2011-12-10 rsc static void makewin(char*);
123 7479a49b 2011-10-03 rsc static void sendmouse(void);
124 ca81de0a 2011-12-10 rsc static void setcursor0(Cursor*);
125 513ce18d 2011-09-26 rsc static void togglefs(void);
126 fcce0598 2012-01-19 rsc static void acceptresizing(int);
128 ca81de0a 2011-12-10 rsc static NSCursor* makecursor(Cursor*);
130 a287dbab 2011-09-06 rsc @implementation appdelegate
131 a287dbab 2011-09-06 rsc - (void)applicationDidFinishLaunching:(id)arg
133 ca81de0a 2011-12-10 rsc in.bigarrow = makecursor(&bigarrow);
136 48107872 2011-09-19 rsc [NSApplication
137 48107872 2011-09-19 rsc detachDrawingThread:@selector(callservep9p:)
138 48107872 2011-09-19 rsc toTarget:[self class] withObject:nil];
140 48107872 2011-09-19 rsc - (void)windowDidBecomeKey:(id)arg
142 48107872 2011-09-19 rsc getmousepos();
143 7479a49b 2011-10-03 rsc sendmouse();
145 a287dbab 2011-09-06 rsc - (void)windowDidResize:(id)arg
147 48107872 2011-09-19 rsc getmousepos();
148 7479a49b 2011-10-03 rsc sendmouse();
150 a3190377 2012-03-05 rsc - (void)windowWillStartLiveResize:(id)arg
152 a3190377 2012-03-05 rsc if(useliveresizing == 0)
153 a3190377 2012-03-05 rsc [win.content setHidden:YES];
155 48107872 2011-09-19 rsc - (void)windowDidEndLiveResize:(id)arg
157 a3190377 2012-03-05 rsc if(useliveresizing == 0)
158 a3190377 2012-03-05 rsc [win.content setHidden:NO];
160 513ce18d 2011-09-26 rsc - (void)windowDidChangeScreen:(id)arg
162 e067d2ea 2011-11-08 rsc if(win.isnfs || win.isofs)
163 e067d2ea 2011-11-08 rsc hidebars(1);
164 d0a596c5 2011-10-12 rsc [win.ofs[1] setFrame:[[WIN screen] frame] display:YES];
166 d0a596c5 2011-10-12 rsc - (BOOL)windowShouldZoom:(id)arg toFrame:(NSRect)r
168 d0a596c5 2011-10-12 rsc followzoombutton(r);
171 a287dbab 2011-09-06 rsc - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)arg
175 e89a71ff 2012-01-16 rsc - (void)applicationDidBecomeActive:(id)arg{ in.willactivate = 0;}
176 fcce0598 2012-01-19 rsc - (void)windowWillEnterFullScreen:(id)arg{ acceptresizing(1);}
177 e067d2ea 2011-11-08 rsc - (void)windowDidEnterFullScreen:(id)arg{ win.isnfs = 1; hidebars(1);}
178 e067d2ea 2011-11-08 rsc - (void)windowWillExitFullScreen:(id)arg{ win.isnfs = 0; hidebars(0);}
179 e067d2ea 2011-11-08 rsc - (void)windowDidExitFullScreen:(id)arg
181 e067d2ea 2011-11-08 rsc NSButton *b;
183 e067d2ea 2011-11-08 rsc b = [WIN standardWindowButton:NSWindowMiniaturizeButton];
185 e067d2ea 2011-11-08 rsc if([b isEnabled] == 0){
186 e067d2ea 2011-11-08 rsc [b setEnabled:YES];
187 e067d2ea 2011-11-08 rsc hidebars(0);
190 a3190377 2012-03-05 rsc - (void)windowWillClose:(id)arg
192 a3190377 2012-03-05 rsc autoflushwin(0); /* can crash otherwise */
195 48107872 2011-09-19 rsc + (void)callservep9p:(id)arg
198 a287dbab 2011-09-06 rsc [NSApp terminate:self];
200 4464a877 2012-01-16 rsc - (void)plumbmanual:(id)arg
202 4464a877 2012-01-16 rsc if(fork() != 0)
204 4464a877 2012-01-16 rsc execl("plumb", "plumb", "devdraw(1)", nil);
206 48107872 2011-09-19 rsc + (void)callflushwin:(id)arg{ flushwin();}
207 513ce18d 2011-09-26 rsc - (void)calltogglefs:(id)arg{ togglefs();}
209 a3190377 2012-03-05 rsc + (void)callflushimg:(NSValue*)v{ flushimg([v rectValue]);}
210 ca81de0a 2011-12-10 rsc + (void)callmakewin:(NSValue*)v{ makewin([v pointerValue]);}
211 ca81de0a 2011-12-10 rsc + (void)callsetcursor0:(NSValue*)v{ setcursor0([v pointerValue]);}
214 d0a596c5 2011-10-12 rsc static Memimage* initimg(void);
217 a287dbab 2011-09-06 rsc attachscreen(char *label, char *winsize)
219 a287dbab 2011-09-06 rsc static int first = 1;
224 a287dbab 2011-09-06 rsc panic("attachscreen called twice");
226 a287dbab 2011-09-06 rsc if(label == nil)
227 a287dbab 2011-09-06 rsc label = "gnot a label";
228 a3190377 2012-03-05 rsc if(strcmp(label, "page") == 0)
229 a3190377 2012-03-05 rsc useliveresizing = 1;
232 d0a596c5 2011-10-12 rsc * Create window in main thread, else no cursor
233 d0a596c5 2011-10-12 rsc * change while resizing.
235 a287dbab 2011-09-06 rsc [appdelegate
236 a287dbab 2011-09-06 rsc performSelectorOnMainThread:@selector(callmakewin:)
237 ca81de0a 2011-12-10 rsc withObject:[NSValue valueWithPointer:winsize]
238 a287dbab 2011-09-06 rsc waitUntilDone:YES];
239 ca81de0a 2011-12-10 rsc // makewin(winsize);
241 48107872 2011-09-19 rsc kicklabel(label);
242 d0a596c5 2011-10-12 rsc return initimg();
245 ca81de0a 2011-12-10 rsc @interface appwin : NSWindow @end
246 ca81de0a 2011-12-10 rsc @interface contentview : NSView @end
248 48107872 2011-09-19 rsc @implementation appwin
249 48107872 2011-09-19 rsc - (NSTimeInterval)animationResizeTime:(NSRect)r
253 513ce18d 2011-09-26 rsc - (BOOL)canBecomeKeyWindow
255 ca81de0a 2011-12-10 rsc return YES; /* else no keyboard for old fullscreen */
257 a3190377 2012-03-05 rsc - (void)makeKeyAndOrderFront:(id)arg
259 a3190377 2012-03-05 rsc LOG(@"makeKeyAndOrderFront");
261 a3190377 2012-03-05 rsc autoflushwin(1);
262 a3190377 2012-03-05 rsc [win.content setHidden:NO];
263 a3190377 2012-03-05 rsc [super makeKeyAndOrderFront:arg];
265 a3190377 2012-03-05 rsc - (void)miniaturize:(id)arg
267 a3190377 2012-03-05 rsc [super miniaturize:arg];
268 a3190377 2012-03-05 rsc [NSApp hide:nil];
270 a3190377 2012-03-05 rsc [win.content setHidden:YES];
271 a3190377 2012-03-05 rsc autoflushwin(0);
273 a3190377 2012-03-05 rsc - (void)deminiaturize:(id)arg
275 a3190377 2012-03-05 rsc autoflushwin(1);
276 a3190377 2012-03-05 rsc [win.content setHidden:NO];
277 a3190377 2012-03-05 rsc [super deminiaturize:arg];
282 7e2a1983 2012-03-05 rsc min(double a, double b)
284 7e2a1983 2012-03-05 rsc return a<b? a : b;
289 48107872 2011-09-19 rsc Winstyle = NSTitledWindowMask
290 48107872 2011-09-19 rsc | NSClosableWindowMask
291 48107872 2011-09-19 rsc | NSMiniaturizableWindowMask
292 48107872 2011-09-19 rsc | NSResizableWindowMask
296 ca81de0a 2011-12-10 rsc makewin(char *s)
298 a287dbab 2011-09-06 rsc NSRect r, sr;
299 d0a596c5 2011-10-12 rsc NSWindow *w;
300 a287dbab 2011-09-06 rsc Rectangle wr;
303 513ce18d 2011-09-26 rsc sr = [[NSScreen mainScreen] frame];
304 7e2a1983 2012-03-05 rsc r = [[NSScreen mainScreen] visibleFrame];
306 a287dbab 2011-09-06 rsc if(s && *s){
307 48107872 2011-09-19 rsc if(parsewinsize(s, &wr, &set) < 0)
308 a287dbab 2011-09-06 rsc sysfatal("%r");
310 a287dbab 2011-09-06 rsc wr = Rect(0, 0, sr.size.width*2/3, sr.size.height*2/3);
314 7e2a1983 2012-03-05 rsc r.origin.x = wr.min.x;
315 7e2a1983 2012-03-05 rsc r.origin.y = sr.size.height-wr.max.y; /* winsize is top-left-based */
316 7e2a1983 2012-03-05 rsc r.size.width = min(Dx(wr), r.size.width);
317 7e2a1983 2012-03-05 rsc r.size.height = min(Dy(wr), r.size.height);
318 d0a596c5 2011-10-12 rsc r = [NSWindow contentRectForFrameRect:r
319 d0a596c5 2011-10-12 rsc styleMask:Winstyle];
321 d0a596c5 2011-10-12 rsc w = [[appwin alloc]
322 a287dbab 2011-09-06 rsc initWithContentRect:r
323 48107872 2011-09-19 rsc styleMask:Winstyle
324 513ce18d 2011-09-26 rsc backing:NSBackingStoreBuffered defer:NO];
327 a287dbab 2011-09-06 rsc #if OSX_VERSION >= 100700
328 d0a596c5 2011-10-12 rsc [w setCollectionBehavior:
329 d0a596c5 2011-10-12 rsc NSWindowCollectionBehaviorFullScreenPrimary];
331 d0a596c5 2011-10-12 rsc [w setContentMinSize:NSMakeSize(128,128)];
333 d0a596c5 2011-10-12 rsc win.ofs[0] = w;
334 d0a596c5 2011-10-12 rsc win.ofs[1] = [[appwin alloc]
335 513ce18d 2011-09-26 rsc initWithContentRect:sr
336 513ce18d 2011-09-26 rsc styleMask:NSBorderlessWindowMask
337 d0a596c5 2011-10-12 rsc backing:NSBackingStoreBuffered defer:YES];
338 d0a596c5 2011-10-12 rsc for(i=0; i<2; i++){
339 d0a596c5 2011-10-12 rsc [win.ofs[i] setAcceptsMouseMovedEvents:YES];
340 d0a596c5 2011-10-12 rsc [win.ofs[i] setDelegate:[NSApp delegate]];
341 d0a596c5 2011-10-12 rsc [win.ofs[i] setDisplaysWhenScreenProfileChanges:NO];
343 d0a596c5 2011-10-12 rsc win.isofs = 0;
344 ca81de0a 2011-12-10 rsc win.content = [contentview new];
345 d0a596c5 2011-10-12 rsc [WIN setContentView:win.content];
348 48107872 2011-09-19 rsc static Memimage*
349 d0a596c5 2011-10-12 rsc initimg(void)
351 d0a596c5 2011-10-12 rsc Memimage *i;
352 a287dbab 2011-09-06 rsc NSSize size;
353 a287dbab 2011-09-06 rsc Rectangle r;
355 48107872 2011-09-19 rsc size = [win.content bounds].size;
356 a3190377 2012-03-05 rsc LOG(@"initimg %.0f %.0f", size.width, size.height);
358 a287dbab 2011-09-06 rsc r = Rect(0, 0, size.width, size.height);
359 d0a596c5 2011-10-12 rsc i = allocmemimage(r, XBGR32);
360 d0a596c5 2011-10-12 rsc if(i == nil)
361 a287dbab 2011-09-06 rsc panic("allocmemimage: %r");
362 d0a596c5 2011-10-12 rsc if(i->data == nil)
363 d0a596c5 2011-10-12 rsc panic("i->data == nil");
365 48107872 2011-09-19 rsc win.img = [[NSBitmapImageRep alloc]
366 d0a596c5 2011-10-12 rsc initWithBitmapDataPlanes:&i->data->bdata
367 48107872 2011-09-19 rsc pixelsWide:Dx(r)
368 48107872 2011-09-19 rsc pixelsHigh:Dy(r)
369 48107872 2011-09-19 rsc bitsPerSample:8
370 d0a596c5 2011-10-12 rsc samplesPerPixel:3
373 48107872 2011-09-19 rsc colorSpaceName:NSDeviceRGBColorSpace
374 48107872 2011-09-19 rsc bytesPerRow:bytesperline(r, 32)
375 48107872 2011-09-19 rsc bitsPerPixel:32];
382 a3190377 2012-03-05 rsc [win.img release];
383 a3190377 2012-03-05 rsc _drawreplacescreenimage(initimg());
385 a3190377 2012-03-05 rsc mouseresized = 1;
386 a3190377 2012-03-05 rsc sendmouse();
390 a3190377 2012-03-05 rsc waitimg(int msec)
392 a3190377 2012-03-05 rsc NSDate *limit;
395 a3190377 2012-03-05 rsc win.needimg = 1;
396 a3190377 2012-03-05 rsc win.deferflush = 0;
399 a3190377 2012-03-05 rsc limit = [NSDate dateWithTimeIntervalSinceNow:msec/1000.0];
401 a3190377 2012-03-05 rsc [[NSRunLoop currentRunLoop]
402 a3190377 2012-03-05 rsc runMode:@"waiting image"
403 a3190377 2012-03-05 rsc beforeDate:limit];
405 a3190377 2012-03-05 rsc }while(win.needimg && [(NSDate*)[NSDate date] compare:limit]<0);
407 a3190377 2012-03-05 rsc win.deferflush = win.needimg;
409 a3190377 2012-03-05 rsc LOG(@"waitimg %s (%d loop)", win.needimg?"defer":"ok", n);
413 48107872 2011-09-19 rsc _flushmemscreen(Rectangle r)
415 a3190377 2012-03-05 rsc static int n;
416 ca81de0a 2011-12-10 rsc NSRect rect;
418 a3190377 2012-03-05 rsc LOG(@"_flushmemscreen");
422 a3190377 2012-03-05 rsc return; /* to skip useless white init rect */
425 a3190377 2012-03-05 rsc [WIN performSelectorOnMainThread:
426 a3190377 2012-03-05 rsc @selector(makeKeyAndOrderFront:)
427 a3190377 2012-03-05 rsc withObject:nil
428 a3190377 2012-03-05 rsc waitUntilDone:NO];
431 a3190377 2012-03-05 rsc if([win.content canDraw] == 0)
434 a3190377 2012-03-05 rsc rect = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r));
435 48107872 2011-09-19 rsc [appdelegate
436 a3190377 2012-03-05 rsc performSelectorOnMainThread:@selector(callflushimg:)
437 ca81de0a 2011-12-10 rsc withObject:[NSValue valueWithRect:rect]
438 a3190377 2012-03-05 rsc waitUntilDone:YES
439 a3190377 2012-03-05 rsc modes:[NSArray arrayWithObjects:
440 a3190377 2012-03-05 rsc NSRunLoopCommonModes,
441 a3190377 2012-03-05 rsc @"waiting image", nil]];
444 a3190377 2012-03-05 rsc static void drawimg(NSRect, uint);
445 a3190377 2012-03-05 rsc static void drawresizehandle(void);
450 a3190377 2012-03-05 rsc Barsize = 4*Pixel,
451 a3190377 2012-03-05 rsc Cornersize = 3*Pixel,
452 a3190377 2012-03-05 rsc Handlesize = 3*Barsize + 1*Pixel,
456 a3190377 2012-03-05 rsc flushimg(NSRect rect)
458 a3190377 2012-03-05 rsc NSRect dr, r;
460 a3190377 2012-03-05 rsc if([win.content lockFocusIfCanDraw] == 0)
463 a3190377 2012-03-05 rsc if(win.needimg){
464 a3190377 2012-03-05 rsc if(!NSEqualSizes(rect.size, [win.img size])){
465 a3190377 2012-03-05 rsc LOG(@"flushimg reject %.0f %.0f",
466 a3190377 2012-03-05 rsc rect.size.width, rect.size.height);
467 a3190377 2012-03-05 rsc [win.content unlockFocus];
470 a3190377 2012-03-05 rsc win.needimg = 0;
472 a3190377 2012-03-05 rsc win.deferflush = 1;
474 a3190377 2012-03-05 rsc LOG(@"flushimg ok %.0f %.0f", rect.size.width, rect.size.height);
477 a3190377 2012-03-05 rsc * Unless we are inside "drawRect", we have to round
478 a3190377 2012-03-05 rsc * the corners ourselves, if this is the custom.
479 a3190377 2012-03-05 rsc * "NSCompositeSourceIn" can do that, but we don't
480 a3190377 2012-03-05 rsc * apply it to the whole rectangle, because this
481 a3190377 2012-03-05 rsc * slows down trackpad scrolling considerably in
484 a3190377 2012-03-05 rsc r = [win.content bounds];
485 a3190377 2012-03-05 rsc r.size.height -= Cornersize;
486 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
487 a3190377 2012-03-05 rsc drawimg(dr, NSCompositeCopy);
489 a3190377 2012-03-05 rsc r.origin.y = r.size.height;
490 a3190377 2012-03-05 rsc r.size = NSMakeSize(Cornersize, Cornersize);
491 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
492 a3190377 2012-03-05 rsc drawimg(dr, NSCompositeSourceIn);
494 a3190377 2012-03-05 rsc r.origin.x = [win.img size].width - Cornersize;
495 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
496 a3190377 2012-03-05 rsc drawimg(dr, NSCompositeSourceIn);
498 a3190377 2012-03-05 rsc r.size.width = r.origin.x - Cornersize;
499 a3190377 2012-03-05 rsc r.origin.x -= r.size.width;
500 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
501 a3190377 2012-03-05 rsc drawimg(dr, NSCompositeCopy);
503 a3190377 2012-03-05 rsc if(OSX_VERSION<100700 && win.isofs==0){
504 a3190377 2012-03-05 rsc r.origin.x = [win.img size].width - Handlesize;
505 a3190377 2012-03-05 rsc r.origin.y = [win.img size].height - Handlesize;
506 a3190377 2012-03-05 rsc r.size = NSMakeSize(Handlesize, Handlesize);
507 a3190377 2012-03-05 rsc if(NSIntersectsRect(r, rect))
508 a3190377 2012-03-05 rsc drawresizehandle();
510 a3190377 2012-03-05 rsc [win.content unlockFocus];
514 a3190377 2012-03-05 rsc autoflushwin(int set)
516 a3190377 2012-03-05 rsc static NSTimer *t;
522 a3190377 2012-03-05 rsc * We need "NSRunLoopCommonModes", otherwise the
523 a3190377 2012-03-05 rsc * timer will not fire during live resizing.
525 a3190377 2012-03-05 rsc t = [NSTimer
526 a3190377 2012-03-05 rsc timerWithTimeInterval:0.033
527 a3190377 2012-03-05 rsc target:[appdelegate class]
528 a3190377 2012-03-05 rsc selector:@selector(callflushwin:) userInfo:nil
529 a3190377 2012-03-05 rsc repeats:YES];
530 a3190377 2012-03-05 rsc [[NSRunLoop currentRunLoop] addTimer:t
531 a3190377 2012-03-05 rsc forMode:NSRunLoopCommonModes];
533 a3190377 2012-03-05 rsc [t invalidate];
535 a3190377 2012-03-05 rsc win.deferflush = 0;
540 a3190377 2012-03-05 rsc flushwin(void)
542 a3190377 2012-03-05 rsc if(win.deferflush && win.needimg==0){
543 d0a596c5 2011-10-12 rsc [WIN flushWindow];
544 a3190377 2012-03-05 rsc win.deferflush = 0;
549 a3190377 2012-03-05 rsc drawimg(NSRect dr, uint op)
553 a3190377 2012-03-05 rsc if(NSIsEmptyRect(dr))
556 a3190377 2012-03-05 rsc sr = [win.content convertRect:dr fromView:nil];
558 a3190377 2012-03-05 rsc [win.img drawInRect:dr fromRect:sr
559 a3190377 2012-03-05 rsc operation:op fraction:1
560 a3190377 2012-03-05 rsc respectFlipped:YES hints:nil];
562 a3190377 2012-03-05 rsc // NSFrameRect(dr);
566 a3190377 2012-03-05 rsc drawresizehandle(void)
568 d0a596c5 2011-10-12 rsc NSColor *color[Barsize];
569 d0a596c5 2011-10-12 rsc NSPoint a,b;
573 a3190377 2012-03-05 rsc c = Pt([win.img size].width, [win.img size].height);
575 d0a596c5 2011-10-12 rsc [[WIN graphicsContext] setShouldAntialias:NO];
577 d0a596c5 2011-10-12 rsc color[0] = [NSColor clearColor];
578 d0a596c5 2011-10-12 rsc color[1] = [NSColor darkGrayColor];
579 d0a596c5 2011-10-12 rsc color[2] = [NSColor lightGrayColor];
580 d0a596c5 2011-10-12 rsc color[3] = [NSColor whiteColor];
582 d0a596c5 2011-10-12 rsc for(i=1; i+Barsize <= Handlesize; )
583 d0a596c5 2011-10-12 rsc for(j=0; j<Barsize; j++){
584 d0a596c5 2011-10-12 rsc [color[j] setStroke];
586 d0a596c5 2011-10-12 rsc a = NSMakePoint(c.x-i, c.y-1);
587 d0a596c5 2011-10-12 rsc b = NSMakePoint(c.x-2, c.y+1-i);
588 d0a596c5 2011-10-12 rsc [NSBezierPath strokeLineFromPoint:a toPoint:b];
592 a287dbab 2011-09-06 rsc static void getgesture(NSEvent*);
593 a287dbab 2011-09-06 rsc static void getkeyboard(NSEvent*);
594 a287dbab 2011-09-06 rsc static void getmouse(NSEvent*);
595 48107872 2011-09-19 rsc static void gettouch(NSEvent*, int);
596 ca81de0a 2011-12-10 rsc static void updatecursor(void);
598 ca81de0a 2011-12-10 rsc @implementation contentview
600 a3190377 2012-03-05 rsc * "drawRect" is called each time Cocoa needs an
601 a3190377 2012-03-05 rsc * image, and each time we call "display". It is
602 a3190377 2012-03-05 rsc * preceded by background painting, and followed by
603 a3190377 2012-03-05 rsc * "flushWindow".
605 48107872 2011-09-19 rsc - (void)drawRect:(NSRect)r
607 d0a596c5 2011-10-12 rsc static int first = 1;
609 a3190377 2012-03-05 rsc LOG(@"drawrect %.0f %.0f %.0f %.0f",
610 a3190377 2012-03-05 rsc r.origin.x, r.origin.y, r.size.width, r.size.height);
615 d0a596c5 2011-10-12 rsc resizeimg();
617 a3190377 2012-03-05 rsc if([WIN inLiveResize])
618 a3190377 2012-03-05 rsc waitimg(100);
620 a3190377 2012-03-05 rsc waitimg(500);
622 48107872 2011-09-19 rsc - (BOOL)isFlipped
624 ca81de0a 2011-12-10 rsc return YES; /* to make the content's origin top left */
626 48107872 2011-09-19 rsc - (BOOL)acceptsFirstResponder
628 ca81de0a 2011-12-10 rsc return YES; /* else no keyboard */
630 ca81de0a 2011-12-10 rsc - (id)initWithFrame:(NSRect)r
632 ca81de0a 2011-12-10 rsc [super initWithFrame:r];
633 ca81de0a 2011-12-10 rsc [self setAcceptsTouchEvents:YES];
634 a3190377 2012-03-05 rsc [self setHidden:YES]; /* to avoid early "drawRect" call */
635 ca81de0a 2011-12-10 rsc return self;
637 a3190377 2012-03-05 rsc - (void)setHidden:(BOOL)set
640 a3190377 2012-03-05 rsc [WIN makeFirstResponder:self]; /* for keyboard focus */
641 a3190377 2012-03-05 rsc [super setHidden:set];
643 ca81de0a 2011-12-10 rsc - (void)cursorUpdate:(NSEvent*)e{ updatecursor();}
645 a287dbab 2011-09-06 rsc - (void)mouseMoved:(NSEvent*)e{ getmouse(e);}
646 a287dbab 2011-09-06 rsc - (void)mouseDown:(NSEvent*)e{ getmouse(e);}
647 a287dbab 2011-09-06 rsc - (void)mouseDragged:(NSEvent*)e{ getmouse(e);}
648 a287dbab 2011-09-06 rsc - (void)mouseUp:(NSEvent*)e{ getmouse(e);}
649 a287dbab 2011-09-06 rsc - (void)otherMouseDown:(NSEvent*)e{ getmouse(e);}
650 a287dbab 2011-09-06 rsc - (void)otherMouseDragged:(NSEvent*)e{ getmouse(e);}
651 a287dbab 2011-09-06 rsc - (void)otherMouseUp:(NSEvent*)e{ getmouse(e);}
652 a287dbab 2011-09-06 rsc - (void)rightMouseDown:(NSEvent*)e{ getmouse(e);}
653 a287dbab 2011-09-06 rsc - (void)rightMouseDragged:(NSEvent*)e{ getmouse(e);}
654 a287dbab 2011-09-06 rsc - (void)rightMouseUp:(NSEvent*)e{ getmouse(e);}
655 a287dbab 2011-09-06 rsc - (void)scrollWheel:(NSEvent*)e{ getmouse(e);}
657 a287dbab 2011-09-06 rsc - (void)keyDown:(NSEvent*)e{ getkeyboard(e);}
658 a287dbab 2011-09-06 rsc - (void)flagsChanged:(NSEvent*)e{ getkeyboard(e);}
660 48107872 2011-09-19 rsc - (void)magnifyWithEvent:(NSEvent*)e{ getgesture(e);}
662 48107872 2011-09-19 rsc - (void)touchesBeganWithEvent:(NSEvent*)e
664 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseBegan);
666 48107872 2011-09-19 rsc - (void)touchesMovedWithEvent:(NSEvent*)e
668 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseMoved);
670 48107872 2011-09-19 rsc - (void)touchesEndedWithEvent:(NSEvent*)e
672 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseEnded);
674 48107872 2011-09-19 rsc - (void)touchesCancelledWithEvent:(NSEvent*)e
676 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseCancelled);
680 a287dbab 2011-09-06 rsc static int keycvt[] =
682 a287dbab 2011-09-06 rsc [QZ_IBOOK_ENTER] '\n',
683 a287dbab 2011-09-06 rsc [QZ_RETURN] '\n',
684 a287dbab 2011-09-06 rsc [QZ_ESCAPE] 27,
685 a287dbab 2011-09-06 rsc [QZ_BACKSPACE] '\b',
686 a287dbab 2011-09-06 rsc [QZ_LALT] Kalt,
687 a287dbab 2011-09-06 rsc [QZ_LCTRL] Kctl,
688 a287dbab 2011-09-06 rsc [QZ_LSHIFT] Kshift,
689 a287dbab 2011-09-06 rsc [QZ_F1] KF+1,
690 a287dbab 2011-09-06 rsc [QZ_F2] KF+2,
691 a287dbab 2011-09-06 rsc [QZ_F3] KF+3,
692 a287dbab 2011-09-06 rsc [QZ_F4] KF+4,
693 a287dbab 2011-09-06 rsc [QZ_F5] KF+5,
694 a287dbab 2011-09-06 rsc [QZ_F6] KF+6,
695 a287dbab 2011-09-06 rsc [QZ_F7] KF+7,
696 a287dbab 2011-09-06 rsc [QZ_F8] KF+8,
697 a287dbab 2011-09-06 rsc [QZ_F9] KF+9,
698 a287dbab 2011-09-06 rsc [QZ_F10] KF+10,
699 a287dbab 2011-09-06 rsc [QZ_F11] KF+11,
700 a287dbab 2011-09-06 rsc [QZ_F12] KF+12,
701 a287dbab 2011-09-06 rsc [QZ_INSERT] Kins,
702 a287dbab 2011-09-06 rsc [QZ_DELETE] 0x7F,
703 a287dbab 2011-09-06 rsc [QZ_HOME] Khome,
704 a287dbab 2011-09-06 rsc [QZ_END] Kend,
705 a287dbab 2011-09-06 rsc [QZ_KP_PLUS] '+',
706 a287dbab 2011-09-06 rsc [QZ_KP_MINUS] '-',
707 a287dbab 2011-09-06 rsc [QZ_TAB] '\t',
708 a287dbab 2011-09-06 rsc [QZ_PAGEUP] Kpgup,
709 a287dbab 2011-09-06 rsc [QZ_PAGEDOWN] Kpgdown,
710 a287dbab 2011-09-06 rsc [QZ_UP] Kup,
711 a287dbab 2011-09-06 rsc [QZ_DOWN] Kdown,
712 a287dbab 2011-09-06 rsc [QZ_LEFT] Kleft,
713 a287dbab 2011-09-06 rsc [QZ_RIGHT] Kright,
714 a287dbab 2011-09-06 rsc [QZ_KP_MULTIPLY] '*',
715 a287dbab 2011-09-06 rsc [QZ_KP_DIVIDE] '/',
716 a287dbab 2011-09-06 rsc [QZ_KP_ENTER] '\n',
717 a287dbab 2011-09-06 rsc [QZ_KP_PERIOD] '.',
718 a287dbab 2011-09-06 rsc [QZ_KP0] '0',
719 a287dbab 2011-09-06 rsc [QZ_KP1] '1',
720 a287dbab 2011-09-06 rsc [QZ_KP2] '2',
721 a287dbab 2011-09-06 rsc [QZ_KP3] '3',
722 a287dbab 2011-09-06 rsc [QZ_KP4] '4',
723 a287dbab 2011-09-06 rsc [QZ_KP5] '5',
724 a287dbab 2011-09-06 rsc [QZ_KP6] '6',
725 a287dbab 2011-09-06 rsc [QZ_KP7] '7',
726 a287dbab 2011-09-06 rsc [QZ_KP8] '8',
727 a287dbab 2011-09-06 rsc [QZ_KP9] '9',
730 5ec2425b 2012-01-16 rsc @interface apptext : NSTextView @end
732 5ec2425b 2012-01-16 rsc @implementation apptext
733 5ec2425b 2012-01-16 rsc - (void)doCommandBySelector:(SEL)s{} /* Esc key beeps otherwise */
734 5ec2425b 2012-01-16 rsc - (void)insertText:(id)arg{} /* to avoid a latency after some time */
738 5ec2425b 2012-01-16 rsc interpretdeadkey(NSEvent *e)
740 5ec2425b 2012-01-16 rsc static apptext *t;
742 5ec2425b 2012-01-16 rsc if(t == nil)
743 5ec2425b 2012-01-16 rsc t = [apptext new];
744 5ec2425b 2012-01-16 rsc [t interpretKeyEvents:[NSArray arrayWithObject:e]];
748 a287dbab 2011-09-06 rsc getkeyboard(NSEvent *e)
750 73b0f029 2012-01-16 rsc static int omod;
751 d0a596c5 2011-10-12 rsc NSString *s;
756 a287dbab 2011-09-06 rsc m = [e modifierFlags];
758 a287dbab 2011-09-06 rsc switch([e type]){
759 a287dbab 2011-09-06 rsc case NSKeyDown:
760 d0a596c5 2011-10-12 rsc s = [e characters];
761 d0a596c5 2011-10-12 rsc c = [s UTF8String][0];
763 5ec2425b 2012-01-16 rsc interpretdeadkey(e);
765 a287dbab 2011-09-06 rsc if(m & NSCommandKeyMask){
766 d0a596c5 2011-10-12 rsc if(' '<=c && c<='~')
767 a287dbab 2011-09-06 rsc keystroke(Kcmd+c);
771 a287dbab 2011-09-06 rsc code = [e keyCode];
772 d0a596c5 2011-10-12 rsc if(code<nelem(keycvt) && keycvt[code])
773 a287dbab 2011-09-06 rsc k = keycvt[code];
777 a287dbab 2011-09-06 rsc keystroke(k);
779 d0a596c5 2011-10-12 rsc keystroke([s characterAtIndex:0]);
782 a287dbab 2011-09-06 rsc case NSFlagsChanged:
783 48107872 2011-09-19 rsc if(in.mbuttons || in.kbuttons){
784 48107872 2011-09-19 rsc in.kbuttons = 0;
785 a287dbab 2011-09-06 rsc if(m & NSAlternateKeyMask)
786 48107872 2011-09-19 rsc in.kbuttons |= 2;
787 a287dbab 2011-09-06 rsc if(m & NSCommandKeyMask)
788 48107872 2011-09-19 rsc in.kbuttons |= 4;
789 7479a49b 2011-10-03 rsc sendmouse();
791 73b0f029 2012-01-16 rsc if(m&NSAlternateKeyMask && (omod&NSAlternateKeyMask)==0)
792 a287dbab 2011-09-06 rsc keystroke(Kalt);
796 a287dbab 2011-09-06 rsc panic("getkey: unexpected event type");
802 ca81de0a 2011-12-10 rsc * Devdraw does not use NSTrackingArea, that often
803 ca81de0a 2011-12-10 rsc * forgets to update the cursor on entering and on
804 ca81de0a 2011-12-10 rsc * leaving the area, and that sometimes stops sending
805 ca81de0a 2011-12-10 rsc * us MouseMove events, at least on OS X Lion.
808 ca81de0a 2011-12-10 rsc updatecursor(void)
810 ca81de0a 2011-12-10 rsc NSCursor *c;
811 ca81de0a 2011-12-10 rsc int isdown, isinside;
813 ca81de0a 2011-12-10 rsc isinside = NSPointInRect(in.mpos, [win.content bounds]);
814 ca81de0a 2011-12-10 rsc isdown = (in.mbuttons || in.kbuttons);
816 ca81de0a 2011-12-10 rsc if(win.cursor && (isinside || isdown))
817 ca81de0a 2011-12-10 rsc c = win.cursor;
818 ca81de0a 2011-12-10 rsc else if(isinside && usebigarrow)
819 ca81de0a 2011-12-10 rsc c = in.bigarrow;
821 ca81de0a 2011-12-10 rsc c = [NSCursor arrowCursor];
825 ca81de0a 2011-12-10 rsc * Without this trick, we can come back from the dock
826 ca81de0a 2011-12-10 rsc * with a resize cursor.
828 ca81de0a 2011-12-10 rsc if(OSX_VERSION >= 100700)
829 ca81de0a 2011-12-10 rsc [NSCursor unhide];
833 fcce0598 2012-01-19 rsc acceptresizing(int set)
835 fcce0598 2012-01-19 rsc uint old, style;
837 fcce0598 2012-01-19 rsc old = [WIN styleMask];
839 fcce0598 2012-01-19 rsc if((old | NSResizableWindowMask) != Winstyle)
840 fcce0598 2012-01-19 rsc return; /* when entering new fullscreen */
843 fcce0598 2012-01-19 rsc style = Winstyle;
845 fcce0598 2012-01-19 rsc style = Winstyle & ~NSResizableWindowMask;
847 fcce0598 2012-01-19 rsc if(style != old)
848 fcce0598 2012-01-19 rsc [WIN setStyleMask:style];
852 a287dbab 2011-09-06 rsc getmousepos(void)
854 fcce0598 2012-01-19 rsc NSPoint p, q;
856 d0a596c5 2011-10-12 rsc p = [WIN mouseLocationOutsideOfEventStream];
857 fcce0598 2012-01-19 rsc q = [win.content convertPoint:p fromView:nil];
858 fcce0598 2012-01-19 rsc in.mpos.x = round(q.x);
859 fcce0598 2012-01-19 rsc in.mpos.y = round(q.y);
861 ca81de0a 2011-12-10 rsc updatecursor();
863 10ccf8df 2012-01-16 rsc if(win.isnfs || win.isofs)
864 10ccf8df 2012-01-16 rsc hidebars(1);
865 fcce0598 2012-01-19 rsc else if(OSX_VERSION>=100700 && [WIN inLiveResize]==0){
866 fcce0598 2012-01-19 rsc if(p.x<12 && p.y<12 && p.x>2 && p.y>2)
867 fcce0598 2012-01-19 rsc acceptresizing(0);
869 fcce0598 2012-01-19 rsc acceptresizing(1);
874 a287dbab 2011-09-06 rsc getmouse(NSEvent *e)
879 ca81de0a 2011-12-10 rsc if([WIN isKeyWindow] == 0)
882 a287dbab 2011-09-06 rsc getmousepos();
884 a287dbab 2011-09-06 rsc switch([e type]){
885 a287dbab 2011-09-06 rsc case NSLeftMouseDown:
886 a287dbab 2011-09-06 rsc case NSLeftMouseUp:
887 a287dbab 2011-09-06 rsc case NSOtherMouseDown:
888 a287dbab 2011-09-06 rsc case NSOtherMouseUp:
889 a287dbab 2011-09-06 rsc case NSRightMouseDown:
890 a287dbab 2011-09-06 rsc case NSRightMouseUp:
891 a287dbab 2011-09-06 rsc b = [NSEvent pressedMouseButtons];
892 a287dbab 2011-09-06 rsc b = b&~6 | (b&4)>>1 | (b&2)<<1;
893 a287dbab 2011-09-06 rsc b = mouseswap(b);
896 a287dbab 2011-09-06 rsc m = [e modifierFlags];
897 48107872 2011-09-19 rsc if(m & NSAlternateKeyMask){
898 73b0f029 2012-01-16 rsc abortcompose();
901 a287dbab 2011-09-06 rsc if(m & NSCommandKeyMask)
904 48107872 2011-09-19 rsc in.mbuttons = b;
907 a287dbab 2011-09-06 rsc case NSScrollWheel:
908 a287dbab 2011-09-06 rsc #if OSX_VERSION >= 100700
909 a287dbab 2011-09-06 rsc d = [e scrollingDeltaY];
911 a287dbab 2011-09-06 rsc d = [e deltaY];
914 48107872 2011-09-19 rsc in.mscroll = 8;
917 48107872 2011-09-19 rsc in.mscroll = 16;
920 a287dbab 2011-09-06 rsc case NSMouseMoved:
921 a287dbab 2011-09-06 rsc case NSLeftMouseDragged:
922 a287dbab 2011-09-06 rsc case NSRightMouseDragged:
923 a287dbab 2011-09-06 rsc case NSOtherMouseDragged:
927 a287dbab 2011-09-06 rsc panic("getmouse: unexpected event type");
929 7479a49b 2011-10-03 rsc sendmouse();
932 f4792e43 2012-01-21 rsc #define Minpinch 0.02
935 a287dbab 2011-09-06 rsc getgesture(NSEvent *e)
937 a287dbab 2011-09-06 rsc switch([e type]){
938 a287dbab 2011-09-06 rsc case NSEventTypeMagnify:
939 f4792e43 2012-01-21 rsc if(fabs([e magnification]) > Minpinch)
945 48107872 2011-09-19 rsc static void sendclick(int);
950 48107872 2011-09-19 rsc return nsec()/1000000;
954 48107872 2011-09-19 rsc gettouch(NSEvent *e, int type)
956 f4792e43 2012-01-21 rsc static int tapping;
957 48107872 2011-09-19 rsc static uint taptime;
961 48107872 2011-09-19 rsc switch(type){
962 48107872 2011-09-19 rsc case NSTouchPhaseBegan:
963 48107872 2011-09-19 rsc p = NSTouchPhaseTouching;
964 48107872 2011-09-19 rsc set = [e touchesMatchingPhase:p inView:nil];
965 48107872 2011-09-19 rsc if(set.count == 3){
966 48107872 2011-09-19 rsc tapping = 1;
967 48107872 2011-09-19 rsc taptime = msec();
969 48107872 2011-09-19 rsc if(set.count > 3)
970 48107872 2011-09-19 rsc tapping = 0;
973 48107872 2011-09-19 rsc case NSTouchPhaseMoved:
974 f4792e43 2012-01-21 rsc tapping = 0;
977 48107872 2011-09-19 rsc case NSTouchPhaseEnded:
978 48107872 2011-09-19 rsc p = NSTouchPhaseTouching;
979 48107872 2011-09-19 rsc set = [e touchesMatchingPhase:p inView:nil];
980 48107872 2011-09-19 rsc if(set.count == 0){
981 f4792e43 2012-01-21 rsc if(tapping && msec()-taptime<400)
982 d0a596c5 2011-10-12 rsc sendclick(2);
983 48107872 2011-09-19 rsc tapping = 0;
987 48107872 2011-09-19 rsc case NSTouchPhaseCancelled:
991 d0a596c5 2011-10-12 rsc panic("gettouch: unexpected event type");
996 48107872 2011-09-19 rsc sendclick(int b)
998 48107872 2011-09-19 rsc in.mbuttons = b;
999 7479a49b 2011-10-03 rsc sendmouse();
1000 48107872 2011-09-19 rsc in.mbuttons = 0;
1001 7479a49b 2011-10-03 rsc sendmouse();
1004 48107872 2011-09-19 rsc static void
1005 7479a49b 2011-10-03 rsc sendmouse(void)
1007 48107872 2011-09-19 rsc NSSize size;
1010 d0a596c5 2011-10-12 rsc size = [win.content bounds].size;
1011 48107872 2011-09-19 rsc mouserect = Rect(0, 0, size.width, size.height);
1013 48107872 2011-09-19 rsc b = in.kbuttons | in.mbuttons | in.mscroll;
1014 48107872 2011-09-19 rsc mousetrack(in.mpos.x, in.mpos.y, b, msec());
1015 48107872 2011-09-19 rsc in.mscroll = 0;
1019 a287dbab 2011-09-06 rsc setmouse(Point p)
1021 48107872 2011-09-19 rsc static int first = 1;
1025 e89a71ff 2012-01-16 rsc if([NSApp isActive]==0 && in.willactivate==0)
1029 d0a596c5 2011-10-12 rsc /* Try to move Acme's scrollbars without that! */
1030 48107872 2011-09-19 rsc CGSetLocalEventsSuppressionInterval(0);
1033 a3190377 2012-03-05 rsc if([WIN inLiveResize])
1036 ca81de0a 2011-12-10 rsc in.mpos = NSMakePoint(p.x, p.y); // race condition
1038 ca81de0a 2011-12-10 rsc q = [win.content convertPoint:in.mpos toView:nil];
1039 d0a596c5 2011-10-12 rsc q = [WIN convertBaseToScreen:q];
1041 1f4c5744 2012-03-06 rsc r = [[[NSScreen screens] objectAtIndex:0] frame];
1042 1f4c5744 2012-03-06 rsc q.y = r.size.height - q.y; /* Quartz is top-left-based here */
1044 48107872 2011-09-19 rsc CGWarpMouseCursorPosition(NSPointToCGPoint(q));
1047 a287dbab 2011-09-06 rsc static void
1048 d0a596c5 2011-10-12 rsc followzoombutton(NSRect r)
1053 d0a596c5 2011-10-12 rsc wr = [WIN frame];
1054 d0a596c5 2011-10-12 rsc wr.origin.y += wr.size.height;
1055 d0a596c5 2011-10-12 rsc r.origin.y += r.size.height;
1057 ca81de0a 2011-12-10 rsc getmousepos();
1058 d0a596c5 2011-10-12 rsc p.x = (r.origin.x - wr.origin.x) + in.mpos.x;
1059 d0a596c5 2011-10-12 rsc p.y = -(r.origin.y - wr.origin.y) + in.mpos.y;
1060 d0a596c5 2011-10-12 rsc setmouse(p);
1063 d0a596c5 2011-10-12 rsc static void
1064 513ce18d 2011-09-26 rsc togglefs(void)
1066 e067d2ea 2011-11-08 rsc uint opt, tmp;
1068 48107872 2011-09-19 rsc #if OSX_VERSION >= 100700
1069 354c6c32 2012-02-28 rsc NSScreen *s, *s0;
1071 354c6c32 2012-02-28 rsc s = [WIN screen];
1072 354c6c32 2012-02-28 rsc s0 = [[NSScreen screens] objectAtIndex:0];
1074 354c6c32 2012-02-28 rsc if((s==s0 && useoldfullscreen==0) || win.isnfs) {
1075 d0a596c5 2011-10-12 rsc [WIN toggleFullScreen:nil];
1079 513ce18d 2011-09-26 rsc [win.content retain];
1080 d0a596c5 2011-10-12 rsc [WIN orderOut:nil];
1081 d0a596c5 2011-10-12 rsc [WIN setContentView:nil];
1083 e067d2ea 2011-11-08 rsc win.isofs = ! win.isofs;
1084 e067d2ea 2011-11-08 rsc hidebars(win.isofs);
1087 e067d2ea 2011-11-08 rsc * If we move the window from one space to another,
1088 e067d2ea 2011-11-08 rsc * ofs[0] and ofs[1] can be on different spaces.
1089 e067d2ea 2011-11-08 rsc * This "setCollectionBehavior" trick moves the
1090 e067d2ea 2011-11-08 rsc * window to the active space.
1092 e067d2ea 2011-11-08 rsc opt = [WIN collectionBehavior];
1093 e067d2ea 2011-11-08 rsc tmp = opt | NSWindowCollectionBehaviorCanJoinAllSpaces;
1094 d0a596c5 2011-10-12 rsc [WIN setContentView:win.content];
1095 e067d2ea 2011-11-08 rsc [WIN setCollectionBehavior:tmp];
1096 d0a596c5 2011-10-12 rsc [WIN makeKeyAndOrderFront:nil];
1097 e067d2ea 2011-11-08 rsc [WIN setCollectionBehavior:opt];
1098 513ce18d 2011-09-26 rsc [win.content release];
1103 e067d2ea 2011-11-08 rsc Autohiddenbars = NSApplicationPresentationAutoHideDock
1104 e067d2ea 2011-11-08 rsc | NSApplicationPresentationAutoHideMenuBar,
1106 e067d2ea 2011-11-08 rsc Hiddenbars = NSApplicationPresentationHideDock
1107 e067d2ea 2011-11-08 rsc | NSApplicationPresentationHideMenuBar,
1110 7479a49b 2011-10-03 rsc static void
1111 e067d2ea 2011-11-08 rsc hidebars(int set)
1113 7479a49b 2011-10-03 rsc NSScreen *s,*s0;
1114 e067d2ea 2011-11-08 rsc uint old, opt;
1116 d0a596c5 2011-10-12 rsc s = [WIN screen];
1117 7479a49b 2011-10-03 rsc s0 = [[NSScreen screens] objectAtIndex:0];
1118 e067d2ea 2011-11-08 rsc old = [NSApp presentationOptions];
1120 10ccf8df 2012-01-16 rsc #if OSX_VERSION >= 100700
1121 10ccf8df 2012-01-16 rsc /* This bit can get lost, resulting in dreadful bugs. */
1122 10ccf8df 2012-01-16 rsc if(win.isnfs)
1123 10ccf8df 2012-01-16 rsc old |= NSApplicationPresentationFullScreen;
1126 7479a49b 2011-10-03 rsc if(set && s==s0)
1127 e067d2ea 2011-11-08 rsc opt = (old & ~Autohiddenbars) | Hiddenbars;
1129 e067d2ea 2011-11-08 rsc opt = old & ~(Autohiddenbars | Hiddenbars);
1131 e067d2ea 2011-11-08 rsc if(opt != old)
1132 e067d2ea 2011-11-08 rsc [NSApp setPresentationOptions:opt];
1135 a287dbab 2011-09-06 rsc static void
1136 48107872 2011-09-19 rsc makemenu(void)
1139 4464a877 2012-01-16 rsc NSMenuItem *i0,*i1;
1141 d0a596c5 2011-10-12 rsc m = [NSMenu new];
1142 4464a877 2012-01-16 rsc i0 = [m addItemWithTitle:@"app" action:NULL keyEquivalent:@""];
1143 4464a877 2012-01-16 rsc i1 = [m addItemWithTitle:@"help" action:NULL keyEquivalent:@""];
1144 d0a596c5 2011-10-12 rsc [NSApp setMainMenu:m];
1145 d0a596c5 2011-10-12 rsc [m release];
1147 4464a877 2012-01-16 rsc m = [[NSMenu alloc] initWithTitle:@"app"];
1148 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Full Screen"
1149 d0a596c5 2011-10-12 rsc action:@selector(calltogglefs:)
1150 d0a596c5 2011-10-12 rsc keyEquivalent:@"f"];
1151 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Hide"
1152 4464a877 2012-01-16 rsc action:@selector(hide:)
1153 4464a877 2012-01-16 rsc keyEquivalent:@"h"];
1154 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Quit"
1155 d0a596c5 2011-10-12 rsc action:@selector(terminate:)
1156 d0a596c5 2011-10-12 rsc keyEquivalent:@"q"];
1157 d0a596c5 2011-10-12 rsc [i0 setSubmenu:m];
1158 d0a596c5 2011-10-12 rsc [m release];
1160 4464a877 2012-01-16 rsc m = [[NSMenu alloc] initWithTitle:@"help"];
1161 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Plumb devdraw(1)"
1162 4464a877 2012-01-16 rsc action:@selector(plumbmanual:)
1163 4464a877 2012-01-16 rsc keyEquivalent:@""];
1164 4464a877 2012-01-16 rsc [i1 setSubmenu:m];
1165 4464a877 2012-01-16 rsc [m release];
1168 48107872 2011-09-19 rsc static void
1169 48107872 2011-09-19 rsc makeicon(void)
1172 48107872 2011-09-19 rsc NSImage *i;
1174 48107872 2011-09-19 rsc d = [[NSData alloc]
1175 48107872 2011-09-19 rsc initWithBytes:glenda_png
1176 48107872 2011-09-19 rsc length:(sizeof glenda_png)];
1178 48107872 2011-09-19 rsc i = [[NSImage alloc] initWithData:d];
1179 48107872 2011-09-19 rsc [NSApp setApplicationIconImage:i];
1180 48107872 2011-09-19 rsc [[NSApp dockTile] display];
1181 48107872 2011-09-19 rsc [i release];
1182 48107872 2011-09-19 rsc [d release];
1185 a287dbab 2011-09-06 rsc QLock snarfl;
1188 a287dbab 2011-09-06 rsc getsnarf(void)
1190 a287dbab 2011-09-06 rsc NSPasteboard *pb;
1191 48107872 2011-09-19 rsc NSString *s;
1193 a287dbab 2011-09-06 rsc pb = [NSPasteboard generalPasteboard];
1195 a287dbab 2011-09-06 rsc qlock(&snarfl);
1196 7479a49b 2011-10-03 rsc s = [pb stringForType:NSPasteboardTypeString];
1197 a287dbab 2011-09-06 rsc qunlock(&snarfl);
1200 a287dbab 2011-09-06 rsc return strdup((char*)[s UTF8String]);
1202 a287dbab 2011-09-06 rsc return nil;
1206 a287dbab 2011-09-06 rsc putsnarf(char *s)
1208 a287dbab 2011-09-06 rsc NSArray *t;
1209 a287dbab 2011-09-06 rsc NSPasteboard *pb;
1210 48107872 2011-09-19 rsc NSString *str;
1212 a287dbab 2011-09-06 rsc if(strlen(s) >= SnarfSize)
1215 a287dbab 2011-09-06 rsc t = [NSArray arrayWithObject:NSPasteboardTypeString];
1216 a287dbab 2011-09-06 rsc pb = [NSPasteboard generalPasteboard];
1217 a287dbab 2011-09-06 rsc str = [[NSString alloc] initWithUTF8String:s];
1219 a287dbab 2011-09-06 rsc qlock(&snarfl);
1220 a287dbab 2011-09-06 rsc [pb declareTypes:t owner:nil];
1221 7479a49b 2011-10-03 rsc [pb setString:str forType:NSPasteboardTypeString];
1222 a287dbab 2011-09-06 rsc qunlock(&snarfl);
1224 7479a49b 2011-10-03 rsc [str release];
1228 48107872 2011-09-19 rsc kicklabel(char *label)
1230 7479a49b 2011-10-03 rsc NSString *s;
1232 48107872 2011-09-19 rsc if(label == nil)
1235 7479a49b 2011-10-03 rsc s = [[NSString alloc] initWithUTF8String:label];
1236 d0a596c5 2011-10-12 rsc [win.ofs[0] setTitle:s];
1237 d0a596c5 2011-10-12 rsc [win.ofs[1] setTitle:s];
1238 7479a49b 2011-10-03 rsc [[NSApp dockTile] setBadgeLabel:s];
1239 7479a49b 2011-10-03 rsc [s release];
1243 ca81de0a 2011-12-10 rsc setcursor(Cursor *c)
1246 ca81de0a 2011-12-10 rsc * No cursor change unless in main thread.
1248 b4d0ac96 2011-10-23 rsc [appdelegate
1249 b4d0ac96 2011-10-23 rsc performSelectorOnMainThread:@selector(callsetcursor0:)
1250 ca81de0a 2011-12-10 rsc withObject:[NSValue valueWithPointer:c]
1251 b4d0ac96 2011-10-23 rsc waitUntilDone:YES];
1254 ca81de0a 2011-12-10 rsc static void
1255 b4d0ac96 2011-10-23 rsc setcursor0(Cursor *c)
1257 ca81de0a 2011-12-10 rsc NSCursor *d;
1259 ca81de0a 2011-12-10 rsc d = win.cursor;
1262 ca81de0a 2011-12-10 rsc win.cursor = makecursor(c);
1264 ca81de0a 2011-12-10 rsc win.cursor = nil;
1266 ca81de0a 2011-12-10 rsc updatecursor();
1269 ca81de0a 2011-12-10 rsc [d release];
1272 ca81de0a 2011-12-10 rsc static NSCursor*
1273 ca81de0a 2011-12-10 rsc makecursor(Cursor *c)
1275 48107872 2011-09-19 rsc NSBitmapImageRep *r;
1276 ca81de0a 2011-12-10 rsc NSCursor *d;
1277 48107872 2011-09-19 rsc NSImage *i;
1280 48107872 2011-09-19 rsc uchar *plane[5];
1282 ca81de0a 2011-12-10 rsc r = [[NSBitmapImageRep alloc]
1283 ca81de0a 2011-12-10 rsc initWithBitmapDataPlanes:nil
1284 ca81de0a 2011-12-10 rsc pixelsWide:16
1285 ca81de0a 2011-12-10 rsc pixelsHigh:16
1286 ca81de0a 2011-12-10 rsc bitsPerSample:1
1287 ca81de0a 2011-12-10 rsc samplesPerPixel:2
1288 ca81de0a 2011-12-10 rsc hasAlpha:YES
1289 ca81de0a 2011-12-10 rsc isPlanar:YES
1290 ca81de0a 2011-12-10 rsc colorSpaceName:NSDeviceBlackColorSpace
1291 ca81de0a 2011-12-10 rsc bytesPerRow:2
1292 ca81de0a 2011-12-10 rsc bitsPerPixel:1];
1294 ca81de0a 2011-12-10 rsc [r getBitmapDataPlanes:plane];
1296 ca81de0a 2011-12-10 rsc for(b=0; b<2*16; b++){
1297 ca81de0a 2011-12-10 rsc plane[0][b] = c->set[b];
1298 ca81de0a 2011-12-10 rsc plane[1][b] = c->clr[b];
1300 ca81de0a 2011-12-10 rsc p = NSMakePoint(-c->offset.x, -c->offset.y);
1301 ca81de0a 2011-12-10 rsc i = [NSImage new];
1302 ca81de0a 2011-12-10 rsc [i addRepresentation:r];
1303 ca81de0a 2011-12-10 rsc [r release];
1305 ca81de0a 2011-12-10 rsc d = [[NSCursor alloc] initWithImage:i hotSpot:p];
1306 ca81de0a 2011-12-10 rsc [i release];
1311 e89a71ff 2012-01-16 rsc topwin(void)
1313 e89a71ff 2012-01-16 rsc [WIN performSelectorOnMainThread:
1314 e89a71ff 2012-01-16 rsc @selector(makeKeyAndOrderFront:)
1315 e89a71ff 2012-01-16 rsc withObject:nil
1316 e89a71ff 2012-01-16 rsc waitUntilDone:NO];
1318 e89a71ff 2012-01-16 rsc in.willactivate = 1;
1319 e89a71ff 2012-01-16 rsc [NSApp activateIgnoringOtherApps:YES];