Blame


1 a287dbab 2011-09-06 rsc /*
2 d0a596c5 2011-10-12 rsc * Cocoa's event loop must be in main thread.
3 a3190377 2012-03-05 rsc *
4 a3190377 2012-03-05 rsc * Unless otherwise stated, all coordinate systems
5 a3190377 2012-03-05 rsc * are bottom-left-based.
6 a287dbab 2011-09-06 rsc */
7 a287dbab 2011-09-06 rsc
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
11 a287dbab 2011-09-06 rsc
12 a287dbab 2011-09-06 rsc #import <Cocoa/Cocoa.h>
13 a287dbab 2011-09-06 rsc
14 a287dbab 2011-09-06 rsc #undef Cursor
15 d0a596c5 2011-10-12 rsc #undef Point
16 d0a596c5 2011-10-12 rsc #undef Rect
17 a287dbab 2011-09-06 rsc
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"
30 a287dbab 2011-09-06 rsc
31 310ae033 2017-01-06 rsc // Use non-deprecated names.
32 310ae033 2017-01-06 rsc #define NSKeyDown NSEventTypeKeyDown
33 00b50225 2017-07-16 rsc #define NSShiftKeyMask NSEventModifierFlagShift
34 310ae033 2017-01-06 rsc #define NSAlternateKeyMask NSEventModifierFlagOption
35 310ae033 2017-01-06 rsc #define NSCommandKeyMask NSEventModifierFlagCommand
36 310ae033 2017-01-06 rsc #define NSResizableWindowMask NSWindowStyleMaskResizable
37 310ae033 2017-01-06 rsc #define NSLeftMouseDown NSEventTypeLeftMouseDown
38 310ae033 2017-01-06 rsc #define NSLeftMouseUp NSEventTypeLeftMouseUp
39 310ae033 2017-01-06 rsc #define NSRightMouseDown NSEventTypeRightMouseDown
40 310ae033 2017-01-06 rsc #define NSRightMouseUp NSEventTypeRightMouseUp
41 310ae033 2017-01-06 rsc #define NSOtherMouseDown NSEventTypeOtherMouseDown
42 310ae033 2017-01-06 rsc #define NSOtherMouseUp NSEventTypeOtherMouseUp
43 310ae033 2017-01-06 rsc #define NSScrollWheel NSEventTypeScrollWheel
44 310ae033 2017-01-06 rsc #define NSMouseMoved NSEventTypeMouseMoved
45 310ae033 2017-01-06 rsc #define NSLeftMouseDragged NSEventTypeLeftMouseDragged
46 310ae033 2017-01-06 rsc #define NSRightMouseDragged NSEventTypeRightMouseDragged
47 310ae033 2017-01-06 rsc #define NSOtherMouseDragged NSEventTypeOtherMouseDragged
48 310ae033 2017-01-06 rsc #define NSCompositeCopy NSCompositingOperationCopy
49 310ae033 2017-01-06 rsc #define NSCompositeSourceIn NSCompositingOperationSourceIn
50 310ae033 2017-01-06 rsc #define NSFlagsChanged NSEventTypeFlagsChanged
51 310ae033 2017-01-06 rsc #define NSTitledWindowMask NSWindowStyleMaskTitled
52 310ae033 2017-01-06 rsc #define NSClosableWindowMask NSWindowStyleMaskClosable
53 310ae033 2017-01-06 rsc #define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
54 310ae033 2017-01-06 rsc #define NSBorderlessWindowMask NSWindowStyleMaskBorderless
55 310ae033 2017-01-06 rsc
56 a287dbab 2011-09-06 rsc AUTOFRAMEWORK(Cocoa)
57 a287dbab 2011-09-06 rsc
58 a3190377 2012-03-05 rsc #define LOG if(0)NSLog
59 a3190377 2012-03-05 rsc #define panic sysfatal
60 a287dbab 2011-09-06 rsc
61 d0a596c5 2011-10-12 rsc int usegestures = 0;
62 a3190377 2012-03-05 rsc int useliveresizing = 0;
63 48107872 2011-09-19 rsc int useoldfullscreen = 0;
64 b4d0ac96 2011-10-23 rsc int usebigarrow = 0;
65 a287dbab 2011-09-06 rsc
66 1670a244 2013-08-07 rsc static void setprocname(const char*);
67 1670a244 2013-08-07 rsc
68 ef99c9f1 2012-10-16 rsc /*
69 4eac378e 2015-02-17 rsc * By default, devdraw uses retina displays.
70 4eac378e 2015-02-17 rsc * Set devdrawretina=0 in the environment to override.
71 ef99c9f1 2012-10-16 rsc */
72 4eac378e 2015-02-17 rsc int devdrawretina = 1;
73 ef99c9f1 2012-10-16 rsc
74 a287dbab 2011-09-06 rsc void
75 a287dbab 2011-09-06 rsc usage(void)
76 a287dbab 2011-09-06 rsc {
77 a287dbab 2011-09-06 rsc fprint(2, "usage: devdraw (don't run directly)\n");
78 d0a596c5 2011-10-12 rsc threadexitsall("usage");
79 a287dbab 2011-09-06 rsc }
80 a287dbab 2011-09-06 rsc
81 310ae033 2017-01-06 rsc @interface appdelegate : NSObject<NSApplicationDelegate,NSWindowDelegate> @end
82 48107872 2011-09-19 rsc
83 310ae033 2017-01-06 rsc NSObject<NSApplicationDelegate,NSWindowDelegate> *myApp;
84 310ae033 2017-01-06 rsc
85 a287dbab 2011-09-06 rsc void
86 d0a596c5 2011-10-12 rsc threadmain(int argc, char **argv)
87 a287dbab 2011-09-06 rsc {
88 ef99c9f1 2012-10-16 rsc char *envvar;
89 ef99c9f1 2012-10-16 rsc
90 a287dbab 2011-09-06 rsc /*
91 a287dbab 2011-09-06 rsc * Move the protocol off stdin/stdout so that
92 a287dbab 2011-09-06 rsc * any inadvertent prints don't screw things up.
93 a287dbab 2011-09-06 rsc */
94 a287dbab 2011-09-06 rsc dup(0,3);
95 a287dbab 2011-09-06 rsc dup(1,4);
96 a287dbab 2011-09-06 rsc close(0);
97 a287dbab 2011-09-06 rsc close(1);
98 a287dbab 2011-09-06 rsc open("/dev/null", OREAD);
99 a287dbab 2011-09-06 rsc open("/dev/null", OWRITE);
100 a287dbab 2011-09-06 rsc
101 a287dbab 2011-09-06 rsc ARGBEGIN{
102 d0a596c5 2011-10-12 rsc case 'D': /* for good ps -a listings */
103 a287dbab 2011-09-06 rsc break;
104 d0a596c5 2011-10-12 rsc case 'f':
105 d0a596c5 2011-10-12 rsc useoldfullscreen = 1;
106 d0a596c5 2011-10-12 rsc break;
107 d0a596c5 2011-10-12 rsc case 'g':
108 d0a596c5 2011-10-12 rsc usegestures = 1;
109 d0a596c5 2011-10-12 rsc break;
110 b4d0ac96 2011-10-23 rsc case 'b':
111 b4d0ac96 2011-10-23 rsc usebigarrow = 1;
112 b4d0ac96 2011-10-23 rsc break;
113 a287dbab 2011-09-06 rsc default:
114 a287dbab 2011-09-06 rsc usage();
115 a287dbab 2011-09-06 rsc }ARGEND
116 1670a244 2013-08-07 rsc
117 1670a244 2013-08-07 rsc setprocname(argv0);
118 a287dbab 2011-09-06 rsc
119 ef99c9f1 2012-10-16 rsc if (envvar = getenv("devdrawretina"))
120 ef99c9f1 2012-10-16 rsc devdrawretina = atoi(envvar) > 0;
121 ef99c9f1 2012-10-16 rsc
122 7479a49b 2011-10-03 rsc if(OSX_VERSION < 100700)
123 7479a49b 2011-10-03 rsc [NSAutoreleasePool new];
124 b4d0ac96 2011-10-23 rsc
125 a287dbab 2011-09-06 rsc [NSApplication sharedApplication];
126 a287dbab 2011-09-06 rsc [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
127 310ae033 2017-01-06 rsc myApp = [appdelegate new];
128 310ae033 2017-01-06 rsc [NSApp setDelegate:myApp];
129 a287dbab 2011-09-06 rsc [NSApp run];
130 a287dbab 2011-09-06 rsc }
131 a287dbab 2011-09-06 rsc
132 d0a596c5 2011-10-12 rsc #define WIN win.ofs[win.isofs]
133 d0a596c5 2011-10-12 rsc
134 d0a596c5 2011-10-12 rsc struct
135 d0a596c5 2011-10-12 rsc {
136 d0a596c5 2011-10-12 rsc NSWindow *ofs[2]; /* ofs[1] for old fullscreen; ofs[0] else */
137 d0a596c5 2011-10-12 rsc int isofs;
138 e067d2ea 2011-11-08 rsc int isnfs;
139 d0a596c5 2011-10-12 rsc NSView *content;
140 9bcf1373 2012-08-03 rsc NSBitmapImageRep *img;
141 a3190377 2012-03-05 rsc int needimg;
142 a3190377 2012-03-05 rsc int deferflush;
143 d0a596c5 2011-10-12 rsc NSCursor *cursor;
144 ef99c9f1 2012-10-16 rsc CGFloat topointscale;
145 ef99c9f1 2012-10-16 rsc CGFloat topixelscale;
146 48107872 2011-09-19 rsc } win;
147 48107872 2011-09-19 rsc
148 d0a596c5 2011-10-12 rsc struct
149 d0a596c5 2011-10-12 rsc {
150 ca81de0a 2011-12-10 rsc NSCursor *bigarrow;
151 d0a596c5 2011-10-12 rsc int kbuttons;
152 d0a596c5 2011-10-12 rsc int mbuttons;
153 ca81de0a 2011-12-10 rsc NSPoint mpos;
154 d0a596c5 2011-10-12 rsc int mscroll;
155 e89a71ff 2012-01-16 rsc int willactivate;
156 d0a596c5 2011-10-12 rsc } in;
157 d0a596c5 2011-10-12 rsc
158 e067d2ea 2011-11-08 rsc static void hidebars(int);
159 a3190377 2012-03-05 rsc static void flushimg(NSRect);
160 a3190377 2012-03-05 rsc static void autoflushwin(int);
161 48107872 2011-09-19 rsc static void flushwin(void);
162 d0a596c5 2011-10-12 rsc static void followzoombutton(NSRect);
163 a287dbab 2011-09-06 rsc static void getmousepos(void);
164 48107872 2011-09-19 rsc static void makeicon(void);
165 48107872 2011-09-19 rsc static void makemenu(void);
166 ca81de0a 2011-12-10 rsc static void makewin(char*);
167 7479a49b 2011-10-03 rsc static void sendmouse(void);
168 6a93bd5c 2015-11-11 rsc static void kicklabel0(char*);
169 ca81de0a 2011-12-10 rsc static void setcursor0(Cursor*);
170 513ce18d 2011-09-26 rsc static void togglefs(void);
171 fcce0598 2012-01-19 rsc static void acceptresizing(int);
172 a287dbab 2011-09-06 rsc
173 ca81de0a 2011-12-10 rsc static NSCursor* makecursor(Cursor*);
174 ef99c9f1 2012-10-16 rsc
175 ef99c9f1 2012-10-16 rsc static NSSize winsizepixels();
176 ef99c9f1 2012-10-16 rsc static NSSize winsizepoints();
177 ef99c9f1 2012-10-16 rsc static NSRect scalerect(NSRect, CGFloat);
178 ef99c9f1 2012-10-16 rsc static NSPoint scalepoint(NSPoint, CGFloat);
179 ef99c9f1 2012-10-16 rsc static NSRect dilate(NSRect);
180 ca81de0a 2011-12-10 rsc
181 a287dbab 2011-09-06 rsc @implementation appdelegate
182 a287dbab 2011-09-06 rsc - (void)applicationDidFinishLaunching:(id)arg
183 a287dbab 2011-09-06 rsc {
184 ca81de0a 2011-12-10 rsc in.bigarrow = makecursor(&bigarrow);
185 48107872 2011-09-19 rsc makeicon();
186 48107872 2011-09-19 rsc makemenu();
187 48107872 2011-09-19 rsc [NSApplication
188 48107872 2011-09-19 rsc detachDrawingThread:@selector(callservep9p:)
189 48107872 2011-09-19 rsc toTarget:[self class] withObject:nil];
190 a287dbab 2011-09-06 rsc }
191 d52bdd33 2015-06-03 rsc
192 48107872 2011-09-19 rsc - (void)windowDidBecomeKey:(id)arg
193 a287dbab 2011-09-06 rsc {
194 48107872 2011-09-19 rsc getmousepos();
195 7479a49b 2011-10-03 rsc sendmouse();
196 a287dbab 2011-09-06 rsc }
197 a287dbab 2011-09-06 rsc - (void)windowDidResize:(id)arg
198 a287dbab 2011-09-06 rsc {
199 48107872 2011-09-19 rsc getmousepos();
200 7479a49b 2011-10-03 rsc sendmouse();
201 a287dbab 2011-09-06 rsc }
202 a3190377 2012-03-05 rsc - (void)windowWillStartLiveResize:(id)arg
203 a3190377 2012-03-05 rsc {
204 a3190377 2012-03-05 rsc if(useliveresizing == 0)
205 a3190377 2012-03-05 rsc [win.content setHidden:YES];
206 a3190377 2012-03-05 rsc }
207 48107872 2011-09-19 rsc - (void)windowDidEndLiveResize:(id)arg
208 a287dbab 2011-09-06 rsc {
209 a3190377 2012-03-05 rsc if(useliveresizing == 0)
210 a3190377 2012-03-05 rsc [win.content setHidden:NO];
211 a287dbab 2011-09-06 rsc }
212 513ce18d 2011-09-26 rsc - (void)windowDidChangeScreen:(id)arg
213 513ce18d 2011-09-26 rsc {
214 e067d2ea 2011-11-08 rsc if(win.isnfs || win.isofs)
215 e067d2ea 2011-11-08 rsc hidebars(1);
216 d0a596c5 2011-10-12 rsc [win.ofs[1] setFrame:[[WIN screen] frame] display:YES];
217 513ce18d 2011-09-26 rsc }
218 d0a596c5 2011-10-12 rsc - (BOOL)windowShouldZoom:(id)arg toFrame:(NSRect)r
219 d0a596c5 2011-10-12 rsc {
220 d0a596c5 2011-10-12 rsc followzoombutton(r);
221 d0a596c5 2011-10-12 rsc return YES;
222 d0a596c5 2011-10-12 rsc }
223 a287dbab 2011-09-06 rsc - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)arg
224 a287dbab 2011-09-06 rsc {
225 a287dbab 2011-09-06 rsc return YES;
226 e067d2ea 2011-11-08 rsc }
227 e89a71ff 2012-01-16 rsc - (void)applicationDidBecomeActive:(id)arg{ in.willactivate = 0;}
228 fcce0598 2012-01-19 rsc - (void)windowWillEnterFullScreen:(id)arg{ acceptresizing(1);}
229 e067d2ea 2011-11-08 rsc - (void)windowDidEnterFullScreen:(id)arg{ win.isnfs = 1; hidebars(1);}
230 e067d2ea 2011-11-08 rsc - (void)windowWillExitFullScreen:(id)arg{ win.isnfs = 0; hidebars(0);}
231 e067d2ea 2011-11-08 rsc - (void)windowDidExitFullScreen:(id)arg
232 e067d2ea 2011-11-08 rsc {
233 e067d2ea 2011-11-08 rsc NSButton *b;
234 e067d2ea 2011-11-08 rsc
235 e067d2ea 2011-11-08 rsc b = [WIN standardWindowButton:NSWindowMiniaturizeButton];
236 e067d2ea 2011-11-08 rsc
237 e067d2ea 2011-11-08 rsc if([b isEnabled] == 0){
238 e067d2ea 2011-11-08 rsc [b setEnabled:YES];
239 e067d2ea 2011-11-08 rsc hidebars(0);
240 e067d2ea 2011-11-08 rsc }
241 a287dbab 2011-09-06 rsc }
242 a3190377 2012-03-05 rsc - (void)windowWillClose:(id)arg
243 a3190377 2012-03-05 rsc {
244 a3190377 2012-03-05 rsc autoflushwin(0); /* can crash otherwise */
245 a3190377 2012-03-05 rsc }
246 e067d2ea 2011-11-08 rsc
247 48107872 2011-09-19 rsc + (void)callservep9p:(id)arg
248 a287dbab 2011-09-06 rsc {
249 a287dbab 2011-09-06 rsc servep9p();
250 a287dbab 2011-09-06 rsc [NSApp terminate:self];
251 a287dbab 2011-09-06 rsc }
252 4464a877 2012-01-16 rsc - (void)plumbmanual:(id)arg
253 4464a877 2012-01-16 rsc {
254 4464a877 2012-01-16 rsc if(fork() != 0)
255 4464a877 2012-01-16 rsc return;
256 4464a877 2012-01-16 rsc execl("plumb", "plumb", "devdraw(1)", nil);
257 4464a877 2012-01-16 rsc }
258 48107872 2011-09-19 rsc + (void)callflushwin:(id)arg{ flushwin();}
259 513ce18d 2011-09-26 rsc - (void)calltogglefs:(id)arg{ togglefs();}
260 ca81de0a 2011-12-10 rsc
261 a3190377 2012-03-05 rsc + (void)callflushimg:(NSValue*)v{ flushimg([v rectValue]);}
262 ca81de0a 2011-12-10 rsc + (void)callmakewin:(NSValue*)v{ makewin([v pointerValue]);}
263 ca81de0a 2011-12-10 rsc + (void)callsetcursor0:(NSValue*)v{ setcursor0([v pointerValue]);}
264 6a93bd5c 2015-11-11 rsc + (void)callkicklabel0:(NSValue*)v{ kicklabel0([v pointerValue]);}
265 a287dbab 2011-09-06 rsc @end
266 a287dbab 2011-09-06 rsc
267 d0a596c5 2011-10-12 rsc static Memimage* initimg(void);
268 48107872 2011-09-19 rsc
269 a287dbab 2011-09-06 rsc Memimage*
270 a287dbab 2011-09-06 rsc attachscreen(char *label, char *winsize)
271 a287dbab 2011-09-06 rsc {
272 a287dbab 2011-09-06 rsc static int first = 1;
273 a287dbab 2011-09-06 rsc
274 48107872 2011-09-19 rsc if(first)
275 48107872 2011-09-19 rsc first = 0;
276 48107872 2011-09-19 rsc else
277 a287dbab 2011-09-06 rsc panic("attachscreen called twice");
278 a287dbab 2011-09-06 rsc
279 a287dbab 2011-09-06 rsc if(label == nil)
280 a287dbab 2011-09-06 rsc label = "gnot a label";
281 a3190377 2012-03-05 rsc if(strcmp(label, "page") == 0)
282 a3190377 2012-03-05 rsc useliveresizing = 1;
283 a287dbab 2011-09-06 rsc
284 d0a596c5 2011-10-12 rsc /*
285 d0a596c5 2011-10-12 rsc * Create window in main thread, else no cursor
286 d0a596c5 2011-10-12 rsc * change while resizing.
287 d0a596c5 2011-10-12 rsc */
288 a287dbab 2011-09-06 rsc [appdelegate
289 a287dbab 2011-09-06 rsc performSelectorOnMainThread:@selector(callmakewin:)
290 ca81de0a 2011-12-10 rsc withObject:[NSValue valueWithPointer:winsize]
291 a287dbab 2011-09-06 rsc waitUntilDone:YES];
292 ca81de0a 2011-12-10 rsc // makewin(winsize);
293 a287dbab 2011-09-06 rsc
294 48107872 2011-09-19 rsc kicklabel(label);
295 d0a596c5 2011-10-12 rsc return initimg();
296 48107872 2011-09-19 rsc }
297 a287dbab 2011-09-06 rsc
298 ca81de0a 2011-12-10 rsc @interface appwin : NSWindow @end
299 ca81de0a 2011-12-10 rsc @interface contentview : NSView @end
300 a287dbab 2011-09-06 rsc
301 48107872 2011-09-19 rsc @implementation appwin
302 48107872 2011-09-19 rsc - (NSTimeInterval)animationResizeTime:(NSRect)r
303 48107872 2011-09-19 rsc {
304 48107872 2011-09-19 rsc return 0;
305 a287dbab 2011-09-06 rsc }
306 513ce18d 2011-09-26 rsc - (BOOL)canBecomeKeyWindow
307 513ce18d 2011-09-26 rsc {
308 ca81de0a 2011-12-10 rsc return YES; /* else no keyboard for old fullscreen */
309 a3190377 2012-03-05 rsc }
310 a3190377 2012-03-05 rsc - (void)makeKeyAndOrderFront:(id)arg
311 a3190377 2012-03-05 rsc {
312 a3190377 2012-03-05 rsc LOG(@"makeKeyAndOrderFront");
313 a3190377 2012-03-05 rsc
314 a3190377 2012-03-05 rsc autoflushwin(1);
315 a3190377 2012-03-05 rsc [win.content setHidden:NO];
316 a3190377 2012-03-05 rsc [super makeKeyAndOrderFront:arg];
317 a3190377 2012-03-05 rsc }
318 a3190377 2012-03-05 rsc - (void)miniaturize:(id)arg
319 a3190377 2012-03-05 rsc {
320 a3190377 2012-03-05 rsc [super miniaturize:arg];
321 a3190377 2012-03-05 rsc [NSApp hide:nil];
322 a3190377 2012-03-05 rsc
323 a3190377 2012-03-05 rsc [win.content setHidden:YES];
324 a3190377 2012-03-05 rsc autoflushwin(0);
325 513ce18d 2011-09-26 rsc }
326 a3190377 2012-03-05 rsc - (void)deminiaturize:(id)arg
327 a3190377 2012-03-05 rsc {
328 a3190377 2012-03-05 rsc autoflushwin(1);
329 a3190377 2012-03-05 rsc [win.content setHidden:NO];
330 a3190377 2012-03-05 rsc [super deminiaturize:arg];
331 a3190377 2012-03-05 rsc }
332 d52bdd33 2015-06-03 rsc
333 d52bdd33 2015-06-03 rsc - (NSDragOperation)draggingEntered:(id)arg
334 d52bdd33 2015-06-03 rsc {
335 d52bdd33 2015-06-03 rsc NSPasteboard *b;
336 d52bdd33 2015-06-03 rsc NSDragOperation op;
337 d52bdd33 2015-06-03 rsc
338 d52bdd33 2015-06-03 rsc op = [arg draggingSourceOperationMask];
339 d52bdd33 2015-06-03 rsc b = [arg draggingPasteboard];
340 d52bdd33 2015-06-03 rsc
341 d52bdd33 2015-06-03 rsc if([[b types] containsObject:NSFilenamesPboardType])
342 d52bdd33 2015-06-03 rsc if(op&NSDragOperationLink)
343 d52bdd33 2015-06-03 rsc return NSDragOperationLink;
344 d52bdd33 2015-06-03 rsc
345 d52bdd33 2015-06-03 rsc return NSDragOperationNone;
346 d52bdd33 2015-06-03 rsc }
347 d52bdd33 2015-06-03 rsc
348 d52bdd33 2015-06-03 rsc - (BOOL)performDragOperation:(id)arg
349 d52bdd33 2015-06-03 rsc {
350 d52bdd33 2015-06-03 rsc NSPasteboard *b;
351 d52bdd33 2015-06-03 rsc NSArray *files;
352 d52bdd33 2015-06-03 rsc int i, n;
353 d52bdd33 2015-06-03 rsc
354 d52bdd33 2015-06-03 rsc b = [arg draggingPasteboard];
355 d52bdd33 2015-06-03 rsc if(![[b types] containsObject:NSFilenamesPboardType])
356 d52bdd33 2015-06-03 rsc return NO;
357 d52bdd33 2015-06-03 rsc
358 d52bdd33 2015-06-03 rsc files = [b propertyListForType:NSFilenamesPboardType];
359 d52bdd33 2015-06-03 rsc n = [files count];
360 d52bdd33 2015-06-03 rsc for(i=0; i<n; i++)
361 d52bdd33 2015-06-03 rsc if(fork() == 0)
362 d52bdd33 2015-06-03 rsc execl("macedit", "macedit", [[files objectAtIndex:i] UTF8String], nil);
363 d52bdd33 2015-06-03 rsc
364 d52bdd33 2015-06-03 rsc return YES;
365 d52bdd33 2015-06-03 rsc }
366 d52bdd33 2015-06-03 rsc
367 48107872 2011-09-19 rsc @end
368 7e2a1983 2012-03-05 rsc
369 7e2a1983 2012-03-05 rsc double
370 7e2a1983 2012-03-05 rsc min(double a, double b)
371 7e2a1983 2012-03-05 rsc {
372 7e2a1983 2012-03-05 rsc return a<b? a : b;
373 7e2a1983 2012-03-05 rsc }
374 a287dbab 2011-09-06 rsc
375 48107872 2011-09-19 rsc enum
376 a287dbab 2011-09-06 rsc {
377 48107872 2011-09-19 rsc Winstyle = NSTitledWindowMask
378 48107872 2011-09-19 rsc | NSClosableWindowMask
379 48107872 2011-09-19 rsc | NSMiniaturizableWindowMask
380 48107872 2011-09-19 rsc | NSResizableWindowMask
381 48107872 2011-09-19 rsc };
382 48107872 2011-09-19 rsc
383 48107872 2011-09-19 rsc static void
384 ca81de0a 2011-12-10 rsc makewin(char *s)
385 48107872 2011-09-19 rsc {
386 a287dbab 2011-09-06 rsc NSRect r, sr;
387 d0a596c5 2011-10-12 rsc NSWindow *w;
388 a287dbab 2011-09-06 rsc Rectangle wr;
389 d0a596c5 2011-10-12 rsc int i, set;
390 a287dbab 2011-09-06 rsc
391 513ce18d 2011-09-26 rsc sr = [[NSScreen mainScreen] frame];
392 7e2a1983 2012-03-05 rsc r = [[NSScreen mainScreen] visibleFrame];
393 a287dbab 2011-09-06 rsc
394 a287dbab 2011-09-06 rsc if(s && *s){
395 48107872 2011-09-19 rsc if(parsewinsize(s, &wr, &set) < 0)
396 a287dbab 2011-09-06 rsc sysfatal("%r");
397 a287dbab 2011-09-06 rsc }else{
398 a287dbab 2011-09-06 rsc wr = Rect(0, 0, sr.size.width*2/3, sr.size.height*2/3);
399 48107872 2011-09-19 rsc set = 0;
400 a287dbab 2011-09-06 rsc }
401 a287dbab 2011-09-06 rsc
402 7e2a1983 2012-03-05 rsc r.origin.x = wr.min.x;
403 7e2a1983 2012-03-05 rsc r.origin.y = sr.size.height-wr.max.y; /* winsize is top-left-based */
404 7e2a1983 2012-03-05 rsc r.size.width = min(Dx(wr), r.size.width);
405 7e2a1983 2012-03-05 rsc r.size.height = min(Dy(wr), r.size.height);
406 d0a596c5 2011-10-12 rsc r = [NSWindow contentRectForFrameRect:r
407 d0a596c5 2011-10-12 rsc styleMask:Winstyle];
408 d0a596c5 2011-10-12 rsc
409 d0a596c5 2011-10-12 rsc w = [[appwin alloc]
410 a287dbab 2011-09-06 rsc initWithContentRect:r
411 48107872 2011-09-19 rsc styleMask:Winstyle
412 513ce18d 2011-09-26 rsc backing:NSBackingStoreBuffered defer:NO];
413 d3a47e14 2014-12-02 rsc [w setTitle:@"devdraw"];
414 d3a47e14 2014-12-02 rsc
415 48107872 2011-09-19 rsc if(!set)
416 d0a596c5 2011-10-12 rsc [w center];
417 a287dbab 2011-09-06 rsc #if OSX_VERSION >= 100700
418 d0a596c5 2011-10-12 rsc [w setCollectionBehavior:
419 d0a596c5 2011-10-12 rsc NSWindowCollectionBehaviorFullScreenPrimary];
420 a287dbab 2011-09-06 rsc #endif
421 d0a596c5 2011-10-12 rsc [w setContentMinSize:NSMakeSize(128,128)];
422 d52bdd33 2015-06-03 rsc
423 d52bdd33 2015-06-03 rsc [w registerForDraggedTypes:[NSArray arrayWithObjects:
424 d52bdd33 2015-06-03 rsc NSFilenamesPboardType, nil]];
425 513ce18d 2011-09-26 rsc
426 d0a596c5 2011-10-12 rsc win.ofs[0] = w;
427 d0a596c5 2011-10-12 rsc win.ofs[1] = [[appwin alloc]
428 513ce18d 2011-09-26 rsc initWithContentRect:sr
429 513ce18d 2011-09-26 rsc styleMask:NSBorderlessWindowMask
430 d0a596c5 2011-10-12 rsc backing:NSBackingStoreBuffered defer:YES];
431 d0a596c5 2011-10-12 rsc for(i=0; i<2; i++){
432 d0a596c5 2011-10-12 rsc [win.ofs[i] setAcceptsMouseMovedEvents:YES];
433 310ae033 2017-01-06 rsc [win.ofs[i] setDelegate:myApp];
434 d0a596c5 2011-10-12 rsc [win.ofs[i] setDisplaysWhenScreenProfileChanges:NO];
435 d0a596c5 2011-10-12 rsc }
436 d0a596c5 2011-10-12 rsc win.isofs = 0;
437 ca81de0a 2011-12-10 rsc win.content = [contentview new];
438 d0a596c5 2011-10-12 rsc [WIN setContentView:win.content];
439 d3a47e14 2014-12-02 rsc
440 d3a47e14 2014-12-02 rsc topwin();
441 a287dbab 2011-09-06 rsc }
442 a287dbab 2011-09-06 rsc
443 48107872 2011-09-19 rsc static Memimage*
444 d0a596c5 2011-10-12 rsc initimg(void)
445 a287dbab 2011-09-06 rsc {
446 9bcf1373 2012-08-03 rsc Memimage *i;
447 ef99c9f1 2012-10-16 rsc NSSize size, ptsize;
448 a287dbab 2011-09-06 rsc Rectangle r;
449 a287dbab 2011-09-06 rsc
450 ef99c9f1 2012-10-16 rsc size = winsizepixels();
451 a3190377 2012-03-05 rsc LOG(@"initimg %.0f %.0f", size.width, size.height);
452 a287dbab 2011-09-06 rsc
453 a287dbab 2011-09-06 rsc r = Rect(0, 0, size.width, size.height);
454 9bcf1373 2012-08-03 rsc i = allocmemimage(r, XBGR32);
455 9bcf1373 2012-08-03 rsc if(i == nil)
456 a287dbab 2011-09-06 rsc panic("allocmemimage: %r");
457 9bcf1373 2012-08-03 rsc if(i->data == nil)
458 d0a596c5 2011-10-12 rsc panic("i->data == nil");
459 d0a596c5 2011-10-12 rsc
460 9bcf1373 2012-08-03 rsc win.img = [[NSBitmapImageRep alloc]
461 9bcf1373 2012-08-03 rsc initWithBitmapDataPlanes:&i->data->bdata
462 9bcf1373 2012-08-03 rsc pixelsWide:Dx(r)
463 9bcf1373 2012-08-03 rsc pixelsHigh:Dy(r)
464 9bcf1373 2012-08-03 rsc bitsPerSample:8
465 9bcf1373 2012-08-03 rsc samplesPerPixel:3
466 9bcf1373 2012-08-03 rsc hasAlpha:NO
467 9bcf1373 2012-08-03 rsc isPlanar:NO
468 9bcf1373 2012-08-03 rsc colorSpaceName:NSDeviceRGBColorSpace
469 9bcf1373 2012-08-03 rsc bytesPerRow:bytesperline(r, 32)
470 9bcf1373 2012-08-03 rsc bitsPerPixel:32];
471 ef99c9f1 2012-10-16 rsc ptsize = winsizepoints();
472 ef99c9f1 2012-10-16 rsc [win.img setSize: ptsize];
473 ef99c9f1 2012-10-16 rsc win.topixelscale = size.width / ptsize.width;
474 ef99c9f1 2012-10-16 rsc win.topointscale = 1.0f / win.topixelscale;
475 58b1904e 2012-11-26 rsc
476 58b1904e 2012-11-26 rsc // NOTE: This is not really the display DPI.
477 58b1904e 2012-11-26 rsc // On retina, topixelscale is 2; otherwise it is 1.
478 58b1904e 2012-11-26 rsc // This formula gives us 220 for retina, 110 otherwise.
479 58b1904e 2012-11-26 rsc // That's not quite right but it's close to correct.
480 58b1904e 2012-11-26 rsc // http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density#Apple
481 58b1904e 2012-11-26 rsc displaydpi = win.topixelscale * 110;
482 58b1904e 2012-11-26 rsc
483 9bcf1373 2012-08-03 rsc return i;
484 a3190377 2012-03-05 rsc }
485 a3190377 2012-03-05 rsc
486 55905845 2012-11-26 rsc void
487 55905845 2012-11-26 rsc resizeimg(void)
488 a3190377 2012-03-05 rsc {
489 9bcf1373 2012-08-03 rsc [win.img release];
490 a3190377 2012-03-05 rsc _drawreplacescreenimage(initimg());
491 9bcf1373 2012-08-03 rsc
492 a3190377 2012-03-05 rsc mouseresized = 1;
493 a3190377 2012-03-05 rsc sendmouse();
494 a3190377 2012-03-05 rsc }
495 a3190377 2012-03-05 rsc
496 a3190377 2012-03-05 rsc static void
497 a3190377 2012-03-05 rsc waitimg(int msec)
498 a3190377 2012-03-05 rsc {
499 a3190377 2012-03-05 rsc NSDate *limit;
500 a3190377 2012-03-05 rsc int n;
501 a3190377 2012-03-05 rsc
502 a3190377 2012-03-05 rsc win.needimg = 1;
503 a3190377 2012-03-05 rsc win.deferflush = 0;
504 a3190377 2012-03-05 rsc
505 a3190377 2012-03-05 rsc n = 0;
506 a3190377 2012-03-05 rsc limit = [NSDate dateWithTimeIntervalSinceNow:msec/1000.0];
507 a3190377 2012-03-05 rsc do{
508 a3190377 2012-03-05 rsc [[NSRunLoop currentRunLoop]
509 a3190377 2012-03-05 rsc runMode:@"waiting image"
510 a3190377 2012-03-05 rsc beforeDate:limit];
511 a3190377 2012-03-05 rsc n++;
512 a3190377 2012-03-05 rsc }while(win.needimg && [(NSDate*)[NSDate date] compare:limit]<0);
513 a3190377 2012-03-05 rsc
514 a3190377 2012-03-05 rsc win.deferflush = win.needimg;
515 a3190377 2012-03-05 rsc
516 a3190377 2012-03-05 rsc LOG(@"waitimg %s (%d loop)", win.needimg?"defer":"ok", n);
517 48107872 2011-09-19 rsc }
518 a287dbab 2011-09-06 rsc
519 48107872 2011-09-19 rsc void
520 48107872 2011-09-19 rsc _flushmemscreen(Rectangle r)
521 48107872 2011-09-19 rsc {
522 a3190377 2012-03-05 rsc static int n;
523 ca81de0a 2011-12-10 rsc NSRect rect;
524 48107872 2011-09-19 rsc
525 a3190377 2012-03-05 rsc LOG(@"_flushmemscreen");
526 ca81de0a 2011-12-10 rsc
527 a3190377 2012-03-05 rsc if(n==0){
528 a3190377 2012-03-05 rsc n++;
529 a3190377 2012-03-05 rsc return; /* to skip useless white init rect */
530 a3190377 2012-03-05 rsc }else
531 a3190377 2012-03-05 rsc if(n==1){
532 a3190377 2012-03-05 rsc [WIN performSelectorOnMainThread:
533 a3190377 2012-03-05 rsc @selector(makeKeyAndOrderFront:)
534 a3190377 2012-03-05 rsc withObject:nil
535 a3190377 2012-03-05 rsc waitUntilDone:NO];
536 a3190377 2012-03-05 rsc n++;
537 a3190377 2012-03-05 rsc }else
538 a3190377 2012-03-05 rsc if([win.content canDraw] == 0)
539 a3190377 2012-03-05 rsc return;
540 a3190377 2012-03-05 rsc
541 a3190377 2012-03-05 rsc rect = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r));
542 48107872 2011-09-19 rsc [appdelegate
543 a3190377 2012-03-05 rsc performSelectorOnMainThread:@selector(callflushimg:)
544 ca81de0a 2011-12-10 rsc withObject:[NSValue valueWithRect:rect]
545 a3190377 2012-03-05 rsc waitUntilDone:YES
546 a3190377 2012-03-05 rsc modes:[NSArray arrayWithObjects:
547 a3190377 2012-03-05 rsc NSRunLoopCommonModes,
548 a3190377 2012-03-05 rsc @"waiting image", nil]];
549 48107872 2011-09-19 rsc }
550 48107872 2011-09-19 rsc
551 9bcf1373 2012-08-03 rsc static void drawimg(NSRect, uint);
552 a3190377 2012-03-05 rsc static void drawresizehandle(void);
553 7479a49b 2011-10-03 rsc
554 a3190377 2012-03-05 rsc enum
555 a3190377 2012-03-05 rsc {
556 a3190377 2012-03-05 rsc Pixel = 1,
557 a3190377 2012-03-05 rsc Barsize = 4*Pixel,
558 a3190377 2012-03-05 rsc Cornersize = 3*Pixel,
559 a3190377 2012-03-05 rsc Handlesize = 3*Barsize + 1*Pixel,
560 a3190377 2012-03-05 rsc };
561 a3190377 2012-03-05 rsc
562 ef99c9f1 2012-10-16 rsc /*
563 ef99c9f1 2012-10-16 rsc * |rect| is in pixel coordinates.
564 ef99c9f1 2012-10-16 rsc */
565 48107872 2011-09-19 rsc static void
566 a3190377 2012-03-05 rsc flushimg(NSRect rect)
567 48107872 2011-09-19 rsc {
568 a3190377 2012-03-05 rsc NSRect dr, r;
569 48107872 2011-09-19 rsc
570 a3190377 2012-03-05 rsc if([win.content lockFocusIfCanDraw] == 0)
571 a3190377 2012-03-05 rsc return;
572 48107872 2011-09-19 rsc
573 a3190377 2012-03-05 rsc if(win.needimg){
574 ef99c9f1 2012-10-16 rsc if(!NSEqualSizes(scalerect(rect, win.topointscale).size, [win.img size])){
575 a3190377 2012-03-05 rsc LOG(@"flushimg reject %.0f %.0f",
576 a3190377 2012-03-05 rsc rect.size.width, rect.size.height);
577 a3190377 2012-03-05 rsc [win.content unlockFocus];
578 a3190377 2012-03-05 rsc return;
579 a3190377 2012-03-05 rsc }
580 a3190377 2012-03-05 rsc win.needimg = 0;
581 a3190377 2012-03-05 rsc }else
582 a3190377 2012-03-05 rsc win.deferflush = 1;
583 d0a596c5 2011-10-12 rsc
584 a3190377 2012-03-05 rsc LOG(@"flushimg ok %.0f %.0f", rect.size.width, rect.size.height);
585 7479a49b 2011-10-03 rsc
586 a3190377 2012-03-05 rsc /*
587 a3190377 2012-03-05 rsc * Unless we are inside "drawRect", we have to round
588 a3190377 2012-03-05 rsc * the corners ourselves, if this is the custom.
589 a3190377 2012-03-05 rsc * "NSCompositeSourceIn" can do that, but we don't
590 a3190377 2012-03-05 rsc * apply it to the whole rectangle, because this
591 a3190377 2012-03-05 rsc * slows down trackpad scrolling considerably in
592 a3190377 2012-03-05 rsc * Acme.
593 a3190377 2012-03-05 rsc */
594 a3190377 2012-03-05 rsc r = [win.content bounds];
595 ef99c9f1 2012-10-16 rsc rect = dilate(scalerect(rect, win.topointscale));
596 a3190377 2012-03-05 rsc r.size.height -= Cornersize;
597 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
598 310ae033 2017-01-06 rsc LOG(@"r %.0f %.0f %.0f %.0f", r.origin.x, r.origin.y, rect.size.width, rect.size.height);
599 ef99c9f1 2012-10-16 rsc LOG(@"rect in points %f %f %.0f %.0f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
600 ef99c9f1 2012-10-16 rsc LOG(@"dr in points %f %f %.0f %.0f", dr.origin.x, dr.origin.y, dr.size.width, dr.size.height);
601 9bcf1373 2012-08-03 rsc drawimg(dr, NSCompositeCopy);
602 7479a49b 2011-10-03 rsc
603 a3190377 2012-03-05 rsc r.origin.y = r.size.height;
604 a3190377 2012-03-05 rsc r.size = NSMakeSize(Cornersize, Cornersize);
605 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
606 9bcf1373 2012-08-03 rsc drawimg(dr, NSCompositeSourceIn);
607 ad4025bd 2012-07-31 rsc
608 9bcf1373 2012-08-03 rsc r.origin.x = [win.img size].width - Cornersize;
609 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
610 9bcf1373 2012-08-03 rsc drawimg(dr, NSCompositeSourceIn);
611 a3190377 2012-03-05 rsc
612 a3190377 2012-03-05 rsc r.size.width = r.origin.x - Cornersize;
613 a3190377 2012-03-05 rsc r.origin.x -= r.size.width;
614 a3190377 2012-03-05 rsc dr = NSIntersectionRect(r, rect);
615 9bcf1373 2012-08-03 rsc drawimg(dr, NSCompositeCopy);
616 a3190377 2012-03-05 rsc
617 a3190377 2012-03-05 rsc if(OSX_VERSION<100700 && win.isofs==0){
618 9bcf1373 2012-08-03 rsc r.origin.x = [win.img size].width - Handlesize;
619 9bcf1373 2012-08-03 rsc r.origin.y = [win.img size].height - Handlesize;
620 a3190377 2012-03-05 rsc r.size = NSMakeSize(Handlesize, Handlesize);
621 a3190377 2012-03-05 rsc if(NSIntersectsRect(r, rect))
622 a3190377 2012-03-05 rsc drawresizehandle();
623 48107872 2011-09-19 rsc }
624 a3190377 2012-03-05 rsc [win.content unlockFocus];
625 a287dbab 2011-09-06 rsc }
626 a287dbab 2011-09-06 rsc
627 48107872 2011-09-19 rsc static void
628 a3190377 2012-03-05 rsc autoflushwin(int set)
629 48107872 2011-09-19 rsc {
630 a3190377 2012-03-05 rsc static NSTimer *t;
631 a3190377 2012-03-05 rsc
632 a3190377 2012-03-05 rsc if(set){
633 a3190377 2012-03-05 rsc if(t)
634 a3190377 2012-03-05 rsc return;
635 a3190377 2012-03-05 rsc /*
636 a3190377 2012-03-05 rsc * We need "NSRunLoopCommonModes", otherwise the
637 a3190377 2012-03-05 rsc * timer will not fire during live resizing.
638 a3190377 2012-03-05 rsc */
639 a3190377 2012-03-05 rsc t = [NSTimer
640 a3190377 2012-03-05 rsc timerWithTimeInterval:0.033
641 a3190377 2012-03-05 rsc target:[appdelegate class]
642 a3190377 2012-03-05 rsc selector:@selector(callflushwin:) userInfo:nil
643 a3190377 2012-03-05 rsc repeats:YES];
644 a3190377 2012-03-05 rsc [[NSRunLoop currentRunLoop] addTimer:t
645 a3190377 2012-03-05 rsc forMode:NSRunLoopCommonModes];
646 a3190377 2012-03-05 rsc }else{
647 a3190377 2012-03-05 rsc [t invalidate];
648 a3190377 2012-03-05 rsc t = nil;
649 a3190377 2012-03-05 rsc win.deferflush = 0;
650 a3190377 2012-03-05 rsc }
651 a3190377 2012-03-05 rsc }
652 a3190377 2012-03-05 rsc
653 a3190377 2012-03-05 rsc static void
654 a3190377 2012-03-05 rsc flushwin(void)
655 a3190377 2012-03-05 rsc {
656 a3190377 2012-03-05 rsc if(win.deferflush && win.needimg==0){
657 d0a596c5 2011-10-12 rsc [WIN flushWindow];
658 a3190377 2012-03-05 rsc win.deferflush = 0;
659 48107872 2011-09-19 rsc }
660 7479a49b 2011-10-03 rsc }
661 7479a49b 2011-10-03 rsc
662 ef99c9f1 2012-10-16 rsc /*
663 ef99c9f1 2012-10-16 rsc * |dr| is sized in points. What if I make it pixels?
664 ef99c9f1 2012-10-16 rsc */
665 a3190377 2012-03-05 rsc static void
666 9bcf1373 2012-08-03 rsc drawimg(NSRect dr, uint op)
667 7479a49b 2011-10-03 rsc {
668 9bcf1373 2012-08-03 rsc CGContextRef c;
669 9bcf1373 2012-08-03 rsc CGImageRef i;
670 a3190377 2012-03-05 rsc NSRect sr;
671 7479a49b 2011-10-03 rsc
672 a3190377 2012-03-05 rsc if(NSIsEmptyRect(dr))
673 a3190377 2012-03-05 rsc return;
674 a3190377 2012-03-05 rsc
675 a3190377 2012-03-05 rsc sr = [win.content convertRect:dr fromView:nil];
676 ef99c9f1 2012-10-16 rsc LOG(@"before dr: %f %f %f %f\n", dr.origin.x, dr.origin.y, dr.size.width, dr.size.height);
677 ef99c9f1 2012-10-16 rsc LOG(@"before sr: %f %f %f %f\n", sr.origin.x, sr.origin.y, sr.size.width, sr.size.height);
678 a3190377 2012-03-05 rsc
679 ef99c9f1 2012-10-16 rsc dr = scalerect(dr, win.topixelscale);
680 ef99c9f1 2012-10-16 rsc sr = scalerect(sr, win.topixelscale);
681 ef99c9f1 2012-10-16 rsc
682 ef99c9f1 2012-10-16 rsc LOG(@"dr: %f %f %f %f\n", dr.origin.x, dr.origin.y, dr.size.width, dr.size.height);
683 ef99c9f1 2012-10-16 rsc LOG(@"sr: %f %f %f %f\n", sr.origin.x, sr.origin.y, sr.size.width, sr.size.height);
684 9bcf1373 2012-08-03 rsc if(OSX_VERSION >= 100800){
685 9bcf1373 2012-08-03 rsc i = CGImageCreateWithImageInRect([win.img CGImage], NSRectToCGRect(dr));
686 9bcf1373 2012-08-03 rsc c = [[WIN graphicsContext] graphicsPort];
687 a3190377 2012-03-05 rsc
688 9bcf1373 2012-08-03 rsc CGContextSaveGState(c);
689 9bcf1373 2012-08-03 rsc if(op == NSCompositeSourceIn)
690 9bcf1373 2012-08-03 rsc CGContextSetBlendMode(c, kCGBlendModeSourceIn);
691 ef99c9f1 2012-10-16 rsc LOG(@"wim.img size %f %f\n", [win.img size].width, [win.img size].height);
692 9bcf1373 2012-08-03 rsc CGContextTranslateCTM(c, 0, [win.img size].height);
693 ef99c9f1 2012-10-16 rsc CGContextScaleCTM(c, win.topointscale, -win.topointscale);
694 9bcf1373 2012-08-03 rsc CGContextDrawImage(c, NSRectToCGRect(sr), i);
695 9bcf1373 2012-08-03 rsc CGContextRestoreGState(c);
696 9bcf1373 2012-08-03 rsc
697 9bcf1373 2012-08-03 rsc CGImageRelease(i);
698 9bcf1373 2012-08-03 rsc }else{
699 9bcf1373 2012-08-03 rsc [win.img drawInRect:dr fromRect:sr
700 9bcf1373 2012-08-03 rsc operation:op fraction:1
701 9bcf1373 2012-08-03 rsc respectFlipped:YES hints:nil];
702 9bcf1373 2012-08-03 rsc }
703 a3190377 2012-03-05 rsc // NSFrameRect(dr);
704 a3190377 2012-03-05 rsc }
705 a3190377 2012-03-05 rsc
706 7479a49b 2011-10-03 rsc static void
707 a3190377 2012-03-05 rsc drawresizehandle(void)
708 7479a49b 2011-10-03 rsc {
709 d0a596c5 2011-10-12 rsc NSColor *color[Barsize];
710 d0a596c5 2011-10-12 rsc NSPoint a,b;
711 d0a596c5 2011-10-12 rsc Point c;
712 d0a596c5 2011-10-12 rsc int i,j;
713 7479a49b 2011-10-03 rsc
714 9bcf1373 2012-08-03 rsc c = Pt([win.img size].width, [win.img size].height);
715 7479a49b 2011-10-03 rsc
716 d0a596c5 2011-10-12 rsc [[WIN graphicsContext] setShouldAntialias:NO];
717 7479a49b 2011-10-03 rsc
718 d0a596c5 2011-10-12 rsc color[0] = [NSColor clearColor];
719 d0a596c5 2011-10-12 rsc color[1] = [NSColor darkGrayColor];
720 d0a596c5 2011-10-12 rsc color[2] = [NSColor lightGrayColor];
721 d0a596c5 2011-10-12 rsc color[3] = [NSColor whiteColor];
722 7479a49b 2011-10-03 rsc
723 d0a596c5 2011-10-12 rsc for(i=1; i+Barsize <= Handlesize; )
724 d0a596c5 2011-10-12 rsc for(j=0; j<Barsize; j++){
725 d0a596c5 2011-10-12 rsc [color[j] setStroke];
726 d0a596c5 2011-10-12 rsc i++;
727 d0a596c5 2011-10-12 rsc a = NSMakePoint(c.x-i, c.y-1);
728 d0a596c5 2011-10-12 rsc b = NSMakePoint(c.x-2, c.y+1-i);
729 d0a596c5 2011-10-12 rsc [NSBezierPath strokeLineFromPoint:a toPoint:b];
730 d0a596c5 2011-10-12 rsc }
731 d0a596c5 2011-10-12 rsc }
732 7479a49b 2011-10-03 rsc
733 a287dbab 2011-09-06 rsc static void getgesture(NSEvent*);
734 a287dbab 2011-09-06 rsc static void getkeyboard(NSEvent*);
735 a287dbab 2011-09-06 rsc static void getmouse(NSEvent*);
736 48107872 2011-09-19 rsc static void gettouch(NSEvent*, int);
737 ca81de0a 2011-12-10 rsc static void updatecursor(void);
738 a287dbab 2011-09-06 rsc
739 ca81de0a 2011-12-10 rsc @implementation contentview
740 a3190377 2012-03-05 rsc /*
741 a3190377 2012-03-05 rsc * "drawRect" is called each time Cocoa needs an
742 a3190377 2012-03-05 rsc * image, and each time we call "display". It is
743 a3190377 2012-03-05 rsc * preceded by background painting, and followed by
744 a3190377 2012-03-05 rsc * "flushWindow".
745 a3190377 2012-03-05 rsc */
746 48107872 2011-09-19 rsc - (void)drawRect:(NSRect)r
747 48107872 2011-09-19 rsc {
748 d0a596c5 2011-10-12 rsc static int first = 1;
749 d0a596c5 2011-10-12 rsc
750 a3190377 2012-03-05 rsc LOG(@"drawrect %.0f %.0f %.0f %.0f",
751 a3190377 2012-03-05 rsc r.origin.x, r.origin.y, r.size.width, r.size.height);
752 d0a596c5 2011-10-12 rsc
753 d0a596c5 2011-10-12 rsc if(first)
754 d0a596c5 2011-10-12 rsc first = 0;
755 d0a596c5 2011-10-12 rsc else
756 d0a596c5 2011-10-12 rsc resizeimg();
757 d0a596c5 2011-10-12 rsc
758 a3190377 2012-03-05 rsc if([WIN inLiveResize])
759 a3190377 2012-03-05 rsc waitimg(100);
760 a3190377 2012-03-05 rsc else
761 a3190377 2012-03-05 rsc waitimg(500);
762 48107872 2011-09-19 rsc }
763 48107872 2011-09-19 rsc - (BOOL)isFlipped
764 48107872 2011-09-19 rsc {
765 ca81de0a 2011-12-10 rsc return YES; /* to make the content's origin top left */
766 48107872 2011-09-19 rsc }
767 48107872 2011-09-19 rsc - (BOOL)acceptsFirstResponder
768 48107872 2011-09-19 rsc {
769 ca81de0a 2011-12-10 rsc return YES; /* else no keyboard */
770 ca81de0a 2011-12-10 rsc }
771 ca81de0a 2011-12-10 rsc - (id)initWithFrame:(NSRect)r
772 ca81de0a 2011-12-10 rsc {
773 ca81de0a 2011-12-10 rsc [super initWithFrame:r];
774 ca81de0a 2011-12-10 rsc [self setAcceptsTouchEvents:YES];
775 a3190377 2012-03-05 rsc [self setHidden:YES]; /* to avoid early "drawRect" call */
776 ca81de0a 2011-12-10 rsc return self;
777 ca81de0a 2011-12-10 rsc }
778 a3190377 2012-03-05 rsc - (void)setHidden:(BOOL)set
779 a3190377 2012-03-05 rsc {
780 a3190377 2012-03-05 rsc if(!set)
781 a3190377 2012-03-05 rsc [WIN makeFirstResponder:self]; /* for keyboard focus */
782 a3190377 2012-03-05 rsc [super setHidden:set];
783 a3190377 2012-03-05 rsc }
784 ca81de0a 2011-12-10 rsc - (void)cursorUpdate:(NSEvent*)e{ updatecursor();}
785 ca81de0a 2011-12-10 rsc
786 a287dbab 2011-09-06 rsc - (void)mouseMoved:(NSEvent*)e{ getmouse(e);}
787 a287dbab 2011-09-06 rsc - (void)mouseDown:(NSEvent*)e{ getmouse(e);}
788 a287dbab 2011-09-06 rsc - (void)mouseDragged:(NSEvent*)e{ getmouse(e);}
789 a287dbab 2011-09-06 rsc - (void)mouseUp:(NSEvent*)e{ getmouse(e);}
790 a287dbab 2011-09-06 rsc - (void)otherMouseDown:(NSEvent*)e{ getmouse(e);}
791 a287dbab 2011-09-06 rsc - (void)otherMouseDragged:(NSEvent*)e{ getmouse(e);}
792 a287dbab 2011-09-06 rsc - (void)otherMouseUp:(NSEvent*)e{ getmouse(e);}
793 a287dbab 2011-09-06 rsc - (void)rightMouseDown:(NSEvent*)e{ getmouse(e);}
794 a287dbab 2011-09-06 rsc - (void)rightMouseDragged:(NSEvent*)e{ getmouse(e);}
795 a287dbab 2011-09-06 rsc - (void)rightMouseUp:(NSEvent*)e{ getmouse(e);}
796 a287dbab 2011-09-06 rsc - (void)scrollWheel:(NSEvent*)e{ getmouse(e);}
797 a287dbab 2011-09-06 rsc
798 a287dbab 2011-09-06 rsc - (void)keyDown:(NSEvent*)e{ getkeyboard(e);}
799 a287dbab 2011-09-06 rsc - (void)flagsChanged:(NSEvent*)e{ getkeyboard(e);}
800 a287dbab 2011-09-06 rsc
801 48107872 2011-09-19 rsc - (void)magnifyWithEvent:(NSEvent*)e{ getgesture(e);}
802 a287dbab 2011-09-06 rsc
803 48107872 2011-09-19 rsc - (void)touchesBeganWithEvent:(NSEvent*)e
804 a287dbab 2011-09-06 rsc {
805 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseBegan);
806 a287dbab 2011-09-06 rsc }
807 48107872 2011-09-19 rsc - (void)touchesMovedWithEvent:(NSEvent*)e
808 48107872 2011-09-19 rsc {
809 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseMoved);
810 48107872 2011-09-19 rsc }
811 48107872 2011-09-19 rsc - (void)touchesEndedWithEvent:(NSEvent*)e
812 a287dbab 2011-09-06 rsc {
813 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseEnded);
814 a287dbab 2011-09-06 rsc }
815 48107872 2011-09-19 rsc - (void)touchesCancelledWithEvent:(NSEvent*)e
816 48107872 2011-09-19 rsc {
817 48107872 2011-09-19 rsc gettouch(e, NSTouchPhaseCancelled);
818 48107872 2011-09-19 rsc }
819 48107872 2011-09-19 rsc @end
820 a287dbab 2011-09-06 rsc
821 a287dbab 2011-09-06 rsc static int keycvt[] =
822 a287dbab 2011-09-06 rsc {
823 310ae033 2017-01-06 rsc [QZ_IBOOK_ENTER]= '\n',
824 310ae033 2017-01-06 rsc [QZ_RETURN]= '\n',
825 310ae033 2017-01-06 rsc [QZ_ESCAPE]= 27,
826 310ae033 2017-01-06 rsc [QZ_BACKSPACE]= '\b',
827 310ae033 2017-01-06 rsc [QZ_LALT]= Kalt,
828 310ae033 2017-01-06 rsc [QZ_LCTRL]= Kctl,
829 310ae033 2017-01-06 rsc [QZ_LSHIFT]= Kshift,
830 310ae033 2017-01-06 rsc [QZ_F1]= KF+1,
831 310ae033 2017-01-06 rsc [QZ_F2]= KF+2,
832 310ae033 2017-01-06 rsc [QZ_F3]= KF+3,
833 310ae033 2017-01-06 rsc [QZ_F4]= KF+4,
834 310ae033 2017-01-06 rsc [QZ_F5]= KF+5,
835 310ae033 2017-01-06 rsc [QZ_F6]= KF+6,
836 310ae033 2017-01-06 rsc [QZ_F7]= KF+7,
837 310ae033 2017-01-06 rsc [QZ_F8]= KF+8,
838 310ae033 2017-01-06 rsc [QZ_F9]= KF+9,
839 310ae033 2017-01-06 rsc [QZ_F10]= KF+10,
840 310ae033 2017-01-06 rsc [QZ_F11]= KF+11,
841 310ae033 2017-01-06 rsc [QZ_F12]= KF+12,
842 310ae033 2017-01-06 rsc [QZ_INSERT]= Kins,
843 310ae033 2017-01-06 rsc [QZ_DELETE]= 0x7F,
844 310ae033 2017-01-06 rsc [QZ_HOME]= Khome,
845 310ae033 2017-01-06 rsc [QZ_END]= Kend,
846 310ae033 2017-01-06 rsc [QZ_KP_PLUS]= '+',
847 310ae033 2017-01-06 rsc [QZ_KP_MINUS]= '-',
848 310ae033 2017-01-06 rsc [QZ_TAB]= '\t',
849 310ae033 2017-01-06 rsc [QZ_PAGEUP]= Kpgup,
850 310ae033 2017-01-06 rsc [QZ_PAGEDOWN]= Kpgdown,
851 310ae033 2017-01-06 rsc [QZ_UP]= Kup,
852 310ae033 2017-01-06 rsc [QZ_DOWN]= Kdown,
853 310ae033 2017-01-06 rsc [QZ_LEFT]= Kleft,
854 310ae033 2017-01-06 rsc [QZ_RIGHT]= Kright,
855 310ae033 2017-01-06 rsc [QZ_KP_MULTIPLY]= '*',
856 310ae033 2017-01-06 rsc [QZ_KP_DIVIDE]= '/',
857 310ae033 2017-01-06 rsc [QZ_KP_ENTER]= '\n',
858 310ae033 2017-01-06 rsc [QZ_KP_PERIOD]= '.',
859 310ae033 2017-01-06 rsc [QZ_KP0]= '0',
860 310ae033 2017-01-06 rsc [QZ_KP1]= '1',
861 310ae033 2017-01-06 rsc [QZ_KP2]= '2',
862 310ae033 2017-01-06 rsc [QZ_KP3]= '3',
863 310ae033 2017-01-06 rsc [QZ_KP4]= '4',
864 310ae033 2017-01-06 rsc [QZ_KP5]= '5',
865 310ae033 2017-01-06 rsc [QZ_KP6]= '6',
866 310ae033 2017-01-06 rsc [QZ_KP7]= '7',
867 310ae033 2017-01-06 rsc [QZ_KP8]= '8',
868 310ae033 2017-01-06 rsc [QZ_KP9]= '9',
869 a287dbab 2011-09-06 rsc };
870 5ec2425b 2012-01-16 rsc
871 5ec2425b 2012-01-16 rsc @interface apptext : NSTextView @end
872 a287dbab 2011-09-06 rsc
873 5ec2425b 2012-01-16 rsc @implementation apptext
874 5ec2425b 2012-01-16 rsc - (void)doCommandBySelector:(SEL)s{} /* Esc key beeps otherwise */
875 5ec2425b 2012-01-16 rsc - (void)insertText:(id)arg{} /* to avoid a latency after some time */
876 5ec2425b 2012-01-16 rsc @end
877 5ec2425b 2012-01-16 rsc
878 a287dbab 2011-09-06 rsc static void
879 5ec2425b 2012-01-16 rsc interpretdeadkey(NSEvent *e)
880 5ec2425b 2012-01-16 rsc {
881 5ec2425b 2012-01-16 rsc static apptext *t;
882 5ec2425b 2012-01-16 rsc
883 5ec2425b 2012-01-16 rsc if(t == nil)
884 5ec2425b 2012-01-16 rsc t = [apptext new];
885 5ec2425b 2012-01-16 rsc [t interpretKeyEvents:[NSArray arrayWithObject:e]];
886 5ec2425b 2012-01-16 rsc }
887 5ec2425b 2012-01-16 rsc
888 5ec2425b 2012-01-16 rsc static void
889 a287dbab 2011-09-06 rsc getkeyboard(NSEvent *e)
890 a287dbab 2011-09-06 rsc {
891 73b0f029 2012-01-16 rsc static int omod;
892 d0a596c5 2011-10-12 rsc NSString *s;
893 a287dbab 2011-09-06 rsc char c;
894 48107872 2011-09-19 rsc int k, m;
895 48107872 2011-09-19 rsc uint code;
896 a287dbab 2011-09-06 rsc
897 a287dbab 2011-09-06 rsc m = [e modifierFlags];
898 a287dbab 2011-09-06 rsc
899 a287dbab 2011-09-06 rsc switch([e type]){
900 a287dbab 2011-09-06 rsc case NSKeyDown:
901 d0a596c5 2011-10-12 rsc s = [e characters];
902 d0a596c5 2011-10-12 rsc c = [s UTF8String][0];
903 5ec2425b 2012-01-16 rsc
904 5ec2425b 2012-01-16 rsc interpretdeadkey(e);
905 d0a596c5 2011-10-12 rsc
906 a287dbab 2011-09-06 rsc if(m & NSCommandKeyMask){
907 00b50225 2017-07-16 rsc if((m & NSShiftKeyMask) && 'a' <= c && c <= 'z')
908 00b50225 2017-07-16 rsc c += 'A' - 'a';
909 d0a596c5 2011-10-12 rsc if(' '<=c && c<='~')
910 a287dbab 2011-09-06 rsc keystroke(Kcmd+c);
911 d0a596c5 2011-10-12 rsc break;
912 a287dbab 2011-09-06 rsc }
913 a287dbab 2011-09-06 rsc k = c;
914 a287dbab 2011-09-06 rsc code = [e keyCode];
915 d0a596c5 2011-10-12 rsc if(code<nelem(keycvt) && keycvt[code])
916 a287dbab 2011-09-06 rsc k = keycvt[code];
917 d0a596c5 2011-10-12 rsc if(k==0)
918 d0a596c5 2011-10-12 rsc break;
919 d0a596c5 2011-10-12 rsc if(k>0)
920 a287dbab 2011-09-06 rsc keystroke(k);
921 a287dbab 2011-09-06 rsc else
922 d0a596c5 2011-10-12 rsc keystroke([s characterAtIndex:0]);
923 a287dbab 2011-09-06 rsc break;
924 a287dbab 2011-09-06 rsc
925 a287dbab 2011-09-06 rsc case NSFlagsChanged:
926 48107872 2011-09-19 rsc if(in.mbuttons || in.kbuttons){
927 48107872 2011-09-19 rsc in.kbuttons = 0;
928 a287dbab 2011-09-06 rsc if(m & NSAlternateKeyMask)
929 48107872 2011-09-19 rsc in.kbuttons |= 2;
930 a287dbab 2011-09-06 rsc if(m & NSCommandKeyMask)
931 48107872 2011-09-19 rsc in.kbuttons |= 4;
932 7479a49b 2011-10-03 rsc sendmouse();
933 a287dbab 2011-09-06 rsc }else
934 73b0f029 2012-01-16 rsc if(m&NSAlternateKeyMask && (omod&NSAlternateKeyMask)==0)
935 a287dbab 2011-09-06 rsc keystroke(Kalt);
936 a287dbab 2011-09-06 rsc break;
937 a287dbab 2011-09-06 rsc
938 a287dbab 2011-09-06 rsc default:
939 a287dbab 2011-09-06 rsc panic("getkey: unexpected event type");
940 a287dbab 2011-09-06 rsc }
941 73b0f029 2012-01-16 rsc omod = m;
942 a287dbab 2011-09-06 rsc }
943 a287dbab 2011-09-06 rsc
944 ca81de0a 2011-12-10 rsc /*
945 ca81de0a 2011-12-10 rsc * Devdraw does not use NSTrackingArea, that often
946 ca81de0a 2011-12-10 rsc * forgets to update the cursor on entering and on
947 ca81de0a 2011-12-10 rsc * leaving the area, and that sometimes stops sending
948 ca81de0a 2011-12-10 rsc * us MouseMove events, at least on OS X Lion.
949 ca81de0a 2011-12-10 rsc */
950 a287dbab 2011-09-06 rsc static void
951 ca81de0a 2011-12-10 rsc updatecursor(void)
952 ca81de0a 2011-12-10 rsc {
953 ca81de0a 2011-12-10 rsc NSCursor *c;
954 ca81de0a 2011-12-10 rsc int isdown, isinside;
955 ca81de0a 2011-12-10 rsc
956 ca81de0a 2011-12-10 rsc isinside = NSPointInRect(in.mpos, [win.content bounds]);
957 ca81de0a 2011-12-10 rsc isdown = (in.mbuttons || in.kbuttons);
958 ca81de0a 2011-12-10 rsc
959 ca81de0a 2011-12-10 rsc if(win.cursor && (isinside || isdown))
960 ca81de0a 2011-12-10 rsc c = win.cursor;
961 ca81de0a 2011-12-10 rsc else if(isinside && usebigarrow)
962 ca81de0a 2011-12-10 rsc c = in.bigarrow;
963 ca81de0a 2011-12-10 rsc else
964 ca81de0a 2011-12-10 rsc c = [NSCursor arrowCursor];
965 ca81de0a 2011-12-10 rsc [c set];
966 ca81de0a 2011-12-10 rsc
967 ca81de0a 2011-12-10 rsc /*
968 ca81de0a 2011-12-10 rsc * Without this trick, we can come back from the dock
969 ca81de0a 2011-12-10 rsc * with a resize cursor.
970 ca81de0a 2011-12-10 rsc */
971 ca81de0a 2011-12-10 rsc if(OSX_VERSION >= 100700)
972 ca81de0a 2011-12-10 rsc [NSCursor unhide];
973 ca81de0a 2011-12-10 rsc }
974 ca81de0a 2011-12-10 rsc
975 ca81de0a 2011-12-10 rsc static void
976 fcce0598 2012-01-19 rsc acceptresizing(int set)
977 fcce0598 2012-01-19 rsc {
978 fcce0598 2012-01-19 rsc uint old, style;
979 fcce0598 2012-01-19 rsc
980 fcce0598 2012-01-19 rsc old = [WIN styleMask];
981 fcce0598 2012-01-19 rsc
982 fcce0598 2012-01-19 rsc if((old | NSResizableWindowMask) != Winstyle)
983 fcce0598 2012-01-19 rsc return; /* when entering new fullscreen */
984 fcce0598 2012-01-19 rsc
985 fcce0598 2012-01-19 rsc if(set)
986 fcce0598 2012-01-19 rsc style = Winstyle;
987 fcce0598 2012-01-19 rsc else
988 fcce0598 2012-01-19 rsc style = Winstyle & ~NSResizableWindowMask;
989 fcce0598 2012-01-19 rsc
990 fcce0598 2012-01-19 rsc if(style != old)
991 fcce0598 2012-01-19 rsc [WIN setStyleMask:style];
992 fcce0598 2012-01-19 rsc }
993 fcce0598 2012-01-19 rsc
994 fcce0598 2012-01-19 rsc static void
995 a287dbab 2011-09-06 rsc getmousepos(void)
996 a287dbab 2011-09-06 rsc {
997 fcce0598 2012-01-19 rsc NSPoint p, q;
998 a287dbab 2011-09-06 rsc
999 d0a596c5 2011-10-12 rsc p = [WIN mouseLocationOutsideOfEventStream];
1000 fcce0598 2012-01-19 rsc q = [win.content convertPoint:p fromView:nil];
1001 ef99c9f1 2012-10-16 rsc
1002 ef99c9f1 2012-10-16 rsc /* q is in point coordinates. in.mpos is in pixels. */
1003 ef99c9f1 2012-10-16 rsc q = scalepoint(q, win.topixelscale);
1004 ef99c9f1 2012-10-16 rsc
1005 fcce0598 2012-01-19 rsc in.mpos.x = round(q.x);
1006 fcce0598 2012-01-19 rsc in.mpos.y = round(q.y);
1007 ca81de0a 2011-12-10 rsc
1008 ca81de0a 2011-12-10 rsc updatecursor();
1009 10ccf8df 2012-01-16 rsc
1010 10ccf8df 2012-01-16 rsc if(win.isnfs || win.isofs)
1011 10ccf8df 2012-01-16 rsc hidebars(1);
1012 fcce0598 2012-01-19 rsc else if(OSX_VERSION>=100700 && [WIN inLiveResize]==0){
1013 fcce0598 2012-01-19 rsc if(p.x<12 && p.y<12 && p.x>2 && p.y>2)
1014 fcce0598 2012-01-19 rsc acceptresizing(0);
1015 fcce0598 2012-01-19 rsc else
1016 fcce0598 2012-01-19 rsc acceptresizing(1);
1017 fcce0598 2012-01-19 rsc }
1018 a287dbab 2011-09-06 rsc }
1019 a287dbab 2011-09-06 rsc
1020 a287dbab 2011-09-06 rsc static void
1021 a287dbab 2011-09-06 rsc getmouse(NSEvent *e)
1022 a287dbab 2011-09-06 rsc {
1023 a287dbab 2011-09-06 rsc float d;
1024 48107872 2011-09-19 rsc int b, m;
1025 a287dbab 2011-09-06 rsc
1026 ca81de0a 2011-12-10 rsc if([WIN isKeyWindow] == 0)
1027 ca81de0a 2011-12-10 rsc return;
1028 ca81de0a 2011-12-10 rsc
1029 a287dbab 2011-09-06 rsc getmousepos();
1030 a287dbab 2011-09-06 rsc
1031 a287dbab 2011-09-06 rsc switch([e type]){
1032 a287dbab 2011-09-06 rsc case NSLeftMouseDown:
1033 a287dbab 2011-09-06 rsc case NSLeftMouseUp:
1034 a287dbab 2011-09-06 rsc case NSOtherMouseDown:
1035 a287dbab 2011-09-06 rsc case NSOtherMouseUp:
1036 a287dbab 2011-09-06 rsc case NSRightMouseDown:
1037 a287dbab 2011-09-06 rsc case NSRightMouseUp:
1038 a287dbab 2011-09-06 rsc b = [NSEvent pressedMouseButtons];
1039 a287dbab 2011-09-06 rsc b = b&~6 | (b&4)>>1 | (b&2)<<1;
1040 a287dbab 2011-09-06 rsc b = mouseswap(b);
1041 a287dbab 2011-09-06 rsc
1042 a287dbab 2011-09-06 rsc if(b == 1){
1043 a287dbab 2011-09-06 rsc m = [e modifierFlags];
1044 48107872 2011-09-19 rsc if(m & NSAlternateKeyMask){
1045 73b0f029 2012-01-16 rsc abortcompose();
1046 a287dbab 2011-09-06 rsc b = 2;
1047 a287dbab 2011-09-06 rsc }else
1048 a287dbab 2011-09-06 rsc if(m & NSCommandKeyMask)
1049 a287dbab 2011-09-06 rsc b = 4;
1050 a287dbab 2011-09-06 rsc }
1051 48107872 2011-09-19 rsc in.mbuttons = b;
1052 a287dbab 2011-09-06 rsc break;
1053 a287dbab 2011-09-06 rsc
1054 a287dbab 2011-09-06 rsc case NSScrollWheel:
1055 a287dbab 2011-09-06 rsc #if OSX_VERSION >= 100700
1056 a287dbab 2011-09-06 rsc d = [e scrollingDeltaY];
1057 a287dbab 2011-09-06 rsc #else
1058 a287dbab 2011-09-06 rsc d = [e deltaY];
1059 a287dbab 2011-09-06 rsc #endif
1060 a287dbab 2011-09-06 rsc if(d>0)
1061 48107872 2011-09-19 rsc in.mscroll = 8;
1062 48107872 2011-09-19 rsc else
1063 48107872 2011-09-19 rsc if(d<0)
1064 48107872 2011-09-19 rsc in.mscroll = 16;
1065 a287dbab 2011-09-06 rsc break;
1066 a287dbab 2011-09-06 rsc
1067 a287dbab 2011-09-06 rsc case NSMouseMoved:
1068 a287dbab 2011-09-06 rsc case NSLeftMouseDragged:
1069 a287dbab 2011-09-06 rsc case NSRightMouseDragged:
1070 a287dbab 2011-09-06 rsc case NSOtherMouseDragged:
1071 a287dbab 2011-09-06 rsc break;
1072 a287dbab 2011-09-06 rsc
1073 a287dbab 2011-09-06 rsc default:
1074 a287dbab 2011-09-06 rsc panic("getmouse: unexpected event type");
1075 a287dbab 2011-09-06 rsc }
1076 7479a49b 2011-10-03 rsc sendmouse();
1077 d0a596c5 2011-10-12 rsc }
1078 d0a596c5 2011-10-12 rsc
1079 f4792e43 2012-01-21 rsc #define Minpinch 0.02
1080 d0a596c5 2011-10-12 rsc
1081 a287dbab 2011-09-06 rsc static void
1082 a287dbab 2011-09-06 rsc getgesture(NSEvent *e)
1083 a287dbab 2011-09-06 rsc {
1084 a287dbab 2011-09-06 rsc switch([e type]){
1085 a287dbab 2011-09-06 rsc case NSEventTypeMagnify:
1086 f4792e43 2012-01-21 rsc if(fabs([e magnification]) > Minpinch)
1087 513ce18d 2011-09-26 rsc togglefs();
1088 a287dbab 2011-09-06 rsc break;
1089 48107872 2011-09-19 rsc }
1090 48107872 2011-09-19 rsc }
1091 a287dbab 2011-09-06 rsc
1092 48107872 2011-09-19 rsc static void sendclick(int);
1093 a287dbab 2011-09-06 rsc
1094 48107872 2011-09-19 rsc static uint
1095 48107872 2011-09-19 rsc msec(void)
1096 48107872 2011-09-19 rsc {
1097 48107872 2011-09-19 rsc return nsec()/1000000;
1098 48107872 2011-09-19 rsc }
1099 a287dbab 2011-09-06 rsc
1100 48107872 2011-09-19 rsc static void
1101 48107872 2011-09-19 rsc gettouch(NSEvent *e, int type)
1102 48107872 2011-09-19 rsc {
1103 f4792e43 2012-01-21 rsc static int tapping;
1104 48107872 2011-09-19 rsc static uint taptime;
1105 48107872 2011-09-19 rsc NSSet *set;
1106 f4792e43 2012-01-21 rsc int p;
1107 48107872 2011-09-19 rsc
1108 48107872 2011-09-19 rsc switch(type){
1109 48107872 2011-09-19 rsc case NSTouchPhaseBegan:
1110 48107872 2011-09-19 rsc p = NSTouchPhaseTouching;
1111 48107872 2011-09-19 rsc set = [e touchesMatchingPhase:p inView:nil];
1112 48107872 2011-09-19 rsc if(set.count == 3){
1113 48107872 2011-09-19 rsc tapping = 1;
1114 48107872 2011-09-19 rsc taptime = msec();
1115 48107872 2011-09-19 rsc }else
1116 48107872 2011-09-19 rsc if(set.count > 3)
1117 48107872 2011-09-19 rsc tapping = 0;
1118 f4792e43 2012-01-21 rsc break;
1119 48107872 2011-09-19 rsc
1120 48107872 2011-09-19 rsc case NSTouchPhaseMoved:
1121 f4792e43 2012-01-21 rsc tapping = 0;
1122 f4792e43 2012-01-21 rsc break;
1123 48107872 2011-09-19 rsc
1124 48107872 2011-09-19 rsc case NSTouchPhaseEnded:
1125 48107872 2011-09-19 rsc p = NSTouchPhaseTouching;
1126 48107872 2011-09-19 rsc set = [e touchesMatchingPhase:p inView:nil];
1127 48107872 2011-09-19 rsc if(set.count == 0){
1128 f4792e43 2012-01-21 rsc if(tapping && msec()-taptime<400)
1129 d0a596c5 2011-10-12 rsc sendclick(2);
1130 48107872 2011-09-19 rsc tapping = 0;
1131 48107872 2011-09-19 rsc }
1132 a287dbab 2011-09-06 rsc break;
1133 a287dbab 2011-09-06 rsc
1134 48107872 2011-09-19 rsc case NSTouchPhaseCancelled:
1135 a287dbab 2011-09-06 rsc break;
1136 a287dbab 2011-09-06 rsc
1137 a287dbab 2011-09-06 rsc default:
1138 d0a596c5 2011-10-12 rsc panic("gettouch: unexpected event type");
1139 a287dbab 2011-09-06 rsc }
1140 a287dbab 2011-09-06 rsc }
1141 a287dbab 2011-09-06 rsc
1142 a287dbab 2011-09-06 rsc static void
1143 48107872 2011-09-19 rsc sendclick(int b)
1144 a287dbab 2011-09-06 rsc {
1145 48107872 2011-09-19 rsc in.mbuttons = b;
1146 7479a49b 2011-10-03 rsc sendmouse();
1147 48107872 2011-09-19 rsc in.mbuttons = 0;
1148 7479a49b 2011-10-03 rsc sendmouse();
1149 a287dbab 2011-09-06 rsc }
1150 a287dbab 2011-09-06 rsc
1151 48107872 2011-09-19 rsc static void
1152 7479a49b 2011-10-03 rsc sendmouse(void)
1153 a287dbab 2011-09-06 rsc {
1154 48107872 2011-09-19 rsc NSSize size;
1155 48107872 2011-09-19 rsc int b;
1156 48107872 2011-09-19 rsc
1157 ef99c9f1 2012-10-16 rsc size = winsizepixels();
1158 48107872 2011-09-19 rsc mouserect = Rect(0, 0, size.width, size.height);
1159 48107872 2011-09-19 rsc
1160 48107872 2011-09-19 rsc b = in.kbuttons | in.mbuttons | in.mscroll;
1161 48107872 2011-09-19 rsc mousetrack(in.mpos.x, in.mpos.y, b, msec());
1162 48107872 2011-09-19 rsc in.mscroll = 0;
1163 a287dbab 2011-09-06 rsc }
1164 a287dbab 2011-09-06 rsc
1165 ef99c9f1 2012-10-16 rsc /*
1166 ef99c9f1 2012-10-16 rsc * |p| is in pixels.
1167 ef99c9f1 2012-10-16 rsc */
1168 a287dbab 2011-09-06 rsc void
1169 a287dbab 2011-09-06 rsc setmouse(Point p)
1170 a287dbab 2011-09-06 rsc {
1171 a287dbab 2011-09-06 rsc NSPoint q;
1172 a287dbab 2011-09-06 rsc NSRect r;
1173 ca81de0a 2011-12-10 rsc
1174 e89a71ff 2012-01-16 rsc if([NSApp isActive]==0 && in.willactivate==0)
1175 ca81de0a 2011-12-10 rsc return;
1176 a287dbab 2011-09-06 rsc
1177 a3190377 2012-03-05 rsc if([WIN inLiveResize])
1178 a3190377 2012-03-05 rsc return;
1179 a3190377 2012-03-05 rsc
1180 ef99c9f1 2012-10-16 rsc in.mpos = scalepoint(NSMakePoint(p.x, p.y), win.topointscale); // race condition
1181 a287dbab 2011-09-06 rsc
1182 ca81de0a 2011-12-10 rsc q = [win.content convertPoint:in.mpos toView:nil];
1183 310ae033 2017-01-06 rsc q = [WIN convertRectToScreen:NSMakeRect(q.x, q.y, 0, 0)].origin;
1184 1f4c5744 2012-03-06 rsc
1185 1f4c5744 2012-03-06 rsc r = [[[NSScreen screens] objectAtIndex:0] frame];
1186 1f4c5744 2012-03-06 rsc q.y = r.size.height - q.y; /* Quartz is top-left-based here */
1187 a287dbab 2011-09-06 rsc
1188 48107872 2011-09-19 rsc CGWarpMouseCursorPosition(NSPointToCGPoint(q));
1189 310ae033 2017-01-06 rsc CGAssociateMouseAndMouseCursorPosition(true);
1190 a287dbab 2011-09-06 rsc }
1191 a287dbab 2011-09-06 rsc
1192 ef99c9f1 2012-10-16 rsc /*
1193 ef99c9f1 2012-10-16 rsc * |r| is in points.
1194 ef99c9f1 2012-10-16 rsc */
1195 a287dbab 2011-09-06 rsc static void
1196 d0a596c5 2011-10-12 rsc followzoombutton(NSRect r)
1197 d0a596c5 2011-10-12 rsc {
1198 d0a596c5 2011-10-12 rsc NSRect wr;
1199 d0a596c5 2011-10-12 rsc Point p;
1200 ef99c9f1 2012-10-16 rsc NSPoint pt;
1201 d0a596c5 2011-10-12 rsc
1202 d0a596c5 2011-10-12 rsc wr = [WIN frame];
1203 d0a596c5 2011-10-12 rsc wr.origin.y += wr.size.height;
1204 d0a596c5 2011-10-12 rsc r.origin.y += r.size.height;
1205 d0a596c5 2011-10-12 rsc
1206 ca81de0a 2011-12-10 rsc getmousepos();
1207 ef99c9f1 2012-10-16 rsc pt.x = in.mpos.x;
1208 ef99c9f1 2012-10-16 rsc pt.y = in.mpos.y;
1209 ef99c9f1 2012-10-16 rsc pt = scalepoint(pt, win.topointscale);
1210 ef99c9f1 2012-10-16 rsc pt.x = (r.origin.x - wr.origin.x) + pt.x;
1211 ef99c9f1 2012-10-16 rsc pt.y = -(r.origin.y - wr.origin.y) + pt.y;
1212 ef99c9f1 2012-10-16 rsc pt = scalepoint(pt, win.topixelscale);
1213 ef99c9f1 2012-10-16 rsc
1214 ef99c9f1 2012-10-16 rsc p.x = pt.x;
1215 ef99c9f1 2012-10-16 rsc p.y = pt.y;
1216 ef99c9f1 2012-10-16 rsc
1217 d0a596c5 2011-10-12 rsc setmouse(p);
1218 d0a596c5 2011-10-12 rsc }
1219 d0a596c5 2011-10-12 rsc
1220 d0a596c5 2011-10-12 rsc static void
1221 513ce18d 2011-09-26 rsc togglefs(void)
1222 a287dbab 2011-09-06 rsc {
1223 e067d2ea 2011-11-08 rsc uint opt, tmp;
1224 e067d2ea 2011-11-08 rsc
1225 48107872 2011-09-19 rsc #if OSX_VERSION >= 100700
1226 354c6c32 2012-02-28 rsc NSScreen *s, *s0;
1227 354c6c32 2012-02-28 rsc
1228 354c6c32 2012-02-28 rsc s = [WIN screen];
1229 354c6c32 2012-02-28 rsc s0 = [[NSScreen screens] objectAtIndex:0];
1230 354c6c32 2012-02-28 rsc
1231 354c6c32 2012-02-28 rsc if((s==s0 && useoldfullscreen==0) || win.isnfs) {
1232 d0a596c5 2011-10-12 rsc [WIN toggleFullScreen:nil];
1233 48107872 2011-09-19 rsc return;
1234 48107872 2011-09-19 rsc }
1235 48107872 2011-09-19 rsc #endif
1236 513ce18d 2011-09-26 rsc [win.content retain];
1237 d0a596c5 2011-10-12 rsc [WIN orderOut:nil];
1238 d0a596c5 2011-10-12 rsc [WIN setContentView:nil];
1239 7479a49b 2011-10-03 rsc
1240 e067d2ea 2011-11-08 rsc win.isofs = ! win.isofs;
1241 e067d2ea 2011-11-08 rsc hidebars(win.isofs);
1242 7479a49b 2011-10-03 rsc
1243 e067d2ea 2011-11-08 rsc /*
1244 e067d2ea 2011-11-08 rsc * If we move the window from one space to another,
1245 e067d2ea 2011-11-08 rsc * ofs[0] and ofs[1] can be on different spaces.
1246 e067d2ea 2011-11-08 rsc * This "setCollectionBehavior" trick moves the
1247 e067d2ea 2011-11-08 rsc * window to the active space.
1248 e067d2ea 2011-11-08 rsc */
1249 e067d2ea 2011-11-08 rsc opt = [WIN collectionBehavior];
1250 e067d2ea 2011-11-08 rsc tmp = opt | NSWindowCollectionBehaviorCanJoinAllSpaces;
1251 d0a596c5 2011-10-12 rsc [WIN setContentView:win.content];
1252 e067d2ea 2011-11-08 rsc [WIN setCollectionBehavior:tmp];
1253 d0a596c5 2011-10-12 rsc [WIN makeKeyAndOrderFront:nil];
1254 e067d2ea 2011-11-08 rsc [WIN setCollectionBehavior:opt];
1255 513ce18d 2011-09-26 rsc [win.content release];
1256 7479a49b 2011-10-03 rsc }
1257 a287dbab 2011-09-06 rsc
1258 e067d2ea 2011-11-08 rsc enum
1259 e067d2ea 2011-11-08 rsc {
1260 e067d2ea 2011-11-08 rsc Autohiddenbars = NSApplicationPresentationAutoHideDock
1261 e067d2ea 2011-11-08 rsc | NSApplicationPresentationAutoHideMenuBar,
1262 e067d2ea 2011-11-08 rsc
1263 e067d2ea 2011-11-08 rsc Hiddenbars = NSApplicationPresentationHideDock
1264 e067d2ea 2011-11-08 rsc | NSApplicationPresentationHideMenuBar,
1265 e067d2ea 2011-11-08 rsc };
1266 e067d2ea 2011-11-08 rsc
1267 7479a49b 2011-10-03 rsc static void
1268 e067d2ea 2011-11-08 rsc hidebars(int set)
1269 7479a49b 2011-10-03 rsc {
1270 7479a49b 2011-10-03 rsc NSScreen *s,*s0;
1271 e067d2ea 2011-11-08 rsc uint old, opt;
1272 7479a49b 2011-10-03 rsc
1273 d0a596c5 2011-10-12 rsc s = [WIN screen];
1274 7479a49b 2011-10-03 rsc s0 = [[NSScreen screens] objectAtIndex:0];
1275 e067d2ea 2011-11-08 rsc old = [NSApp presentationOptions];
1276 7479a49b 2011-10-03 rsc
1277 10ccf8df 2012-01-16 rsc #if OSX_VERSION >= 100700
1278 10ccf8df 2012-01-16 rsc /* This bit can get lost, resulting in dreadful bugs. */
1279 10ccf8df 2012-01-16 rsc if(win.isnfs)
1280 10ccf8df 2012-01-16 rsc old |= NSApplicationPresentationFullScreen;
1281 10ccf8df 2012-01-16 rsc #endif
1282 10ccf8df 2012-01-16 rsc
1283 7479a49b 2011-10-03 rsc if(set && s==s0)
1284 e067d2ea 2011-11-08 rsc opt = (old & ~Autohiddenbars) | Hiddenbars;
1285 7479a49b 2011-10-03 rsc else
1286 e067d2ea 2011-11-08 rsc opt = old & ~(Autohiddenbars | Hiddenbars);
1287 a287dbab 2011-09-06 rsc
1288 e067d2ea 2011-11-08 rsc if(opt != old)
1289 e067d2ea 2011-11-08 rsc [NSApp setPresentationOptions:opt];
1290 7479a49b 2011-10-03 rsc }
1291 7479a49b 2011-10-03 rsc
1292 a287dbab 2011-09-06 rsc static void
1293 48107872 2011-09-19 rsc makemenu(void)
1294 a287dbab 2011-09-06 rsc {
1295 d0a596c5 2011-10-12 rsc NSMenu *m;
1296 4464a877 2012-01-16 rsc NSMenuItem *i0,*i1;
1297 a287dbab 2011-09-06 rsc
1298 d0a596c5 2011-10-12 rsc m = [NSMenu new];
1299 4464a877 2012-01-16 rsc i0 = [m addItemWithTitle:@"app" action:NULL keyEquivalent:@""];
1300 4464a877 2012-01-16 rsc i1 = [m addItemWithTitle:@"help" action:NULL keyEquivalent:@""];
1301 d0a596c5 2011-10-12 rsc [NSApp setMainMenu:m];
1302 d0a596c5 2011-10-12 rsc [m release];
1303 a287dbab 2011-09-06 rsc
1304 4464a877 2012-01-16 rsc m = [[NSMenu alloc] initWithTitle:@"app"];
1305 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Full Screen"
1306 d0a596c5 2011-10-12 rsc action:@selector(calltogglefs:)
1307 d0a596c5 2011-10-12 rsc keyEquivalent:@"f"];
1308 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Hide"
1309 4464a877 2012-01-16 rsc action:@selector(hide:)
1310 4464a877 2012-01-16 rsc keyEquivalent:@"h"];
1311 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Quit"
1312 d0a596c5 2011-10-12 rsc action:@selector(terminate:)
1313 d0a596c5 2011-10-12 rsc keyEquivalent:@"q"];
1314 d0a596c5 2011-10-12 rsc [i0 setSubmenu:m];
1315 d0a596c5 2011-10-12 rsc [m release];
1316 4464a877 2012-01-16 rsc
1317 4464a877 2012-01-16 rsc m = [[NSMenu alloc] initWithTitle:@"help"];
1318 4464a877 2012-01-16 rsc [m addItemWithTitle:@"Plumb devdraw(1)"
1319 4464a877 2012-01-16 rsc action:@selector(plumbmanual:)
1320 4464a877 2012-01-16 rsc keyEquivalent:@""];
1321 4464a877 2012-01-16 rsc [i1 setSubmenu:m];
1322 4464a877 2012-01-16 rsc [m release];
1323 a287dbab 2011-09-06 rsc }
1324 a287dbab 2011-09-06 rsc
1325 ef99c9f1 2012-10-16 rsc // FIXME: Introduce a high-resolution Glenda image.
1326 48107872 2011-09-19 rsc static void
1327 48107872 2011-09-19 rsc makeicon(void)
1328 48107872 2011-09-19 rsc {
1329 48107872 2011-09-19 rsc NSData *d;
1330 48107872 2011-09-19 rsc NSImage *i;
1331 48107872 2011-09-19 rsc
1332 48107872 2011-09-19 rsc d = [[NSData alloc]
1333 48107872 2011-09-19 rsc initWithBytes:glenda_png
1334 48107872 2011-09-19 rsc length:(sizeof glenda_png)];
1335 48107872 2011-09-19 rsc
1336 48107872 2011-09-19 rsc i = [[NSImage alloc] initWithData:d];
1337 48107872 2011-09-19 rsc [NSApp setApplicationIconImage:i];
1338 48107872 2011-09-19 rsc [[NSApp dockTile] display];
1339 48107872 2011-09-19 rsc [i release];
1340 48107872 2011-09-19 rsc [d release];
1341 48107872 2011-09-19 rsc }
1342 48107872 2011-09-19 rsc
1343 a287dbab 2011-09-06 rsc QLock snarfl;
1344 a287dbab 2011-09-06 rsc
1345 a287dbab 2011-09-06 rsc char*
1346 a287dbab 2011-09-06 rsc getsnarf(void)
1347 a287dbab 2011-09-06 rsc {
1348 a287dbab 2011-09-06 rsc NSPasteboard *pb;
1349 48107872 2011-09-19 rsc NSString *s;
1350 a287dbab 2011-09-06 rsc
1351 a287dbab 2011-09-06 rsc pb = [NSPasteboard generalPasteboard];
1352 a287dbab 2011-09-06 rsc
1353 a287dbab 2011-09-06 rsc qlock(&snarfl);
1354 7479a49b 2011-10-03 rsc s = [pb stringForType:NSPasteboardTypeString];
1355 a287dbab 2011-09-06 rsc qunlock(&snarfl);
1356 a287dbab 2011-09-06 rsc
1357 a287dbab 2011-09-06 rsc if(s)
1358 a287dbab 2011-09-06 rsc return strdup((char*)[s UTF8String]);
1359 a287dbab 2011-09-06 rsc else
1360 a287dbab 2011-09-06 rsc return nil;
1361 a287dbab 2011-09-06 rsc }
1362 a287dbab 2011-09-06 rsc
1363 a287dbab 2011-09-06 rsc void
1364 a287dbab 2011-09-06 rsc putsnarf(char *s)
1365 a287dbab 2011-09-06 rsc {
1366 a287dbab 2011-09-06 rsc NSArray *t;
1367 a287dbab 2011-09-06 rsc NSPasteboard *pb;
1368 48107872 2011-09-19 rsc NSString *str;
1369 a287dbab 2011-09-06 rsc
1370 a287dbab 2011-09-06 rsc if(strlen(s) >= SnarfSize)
1371 a287dbab 2011-09-06 rsc return;
1372 a287dbab 2011-09-06 rsc
1373 a287dbab 2011-09-06 rsc t = [NSArray arrayWithObject:NSPasteboardTypeString];
1374 a287dbab 2011-09-06 rsc pb = [NSPasteboard generalPasteboard];
1375 a287dbab 2011-09-06 rsc str = [[NSString alloc] initWithUTF8String:s];
1376 a287dbab 2011-09-06 rsc
1377 a287dbab 2011-09-06 rsc qlock(&snarfl);
1378 a287dbab 2011-09-06 rsc [pb declareTypes:t owner:nil];
1379 7479a49b 2011-10-03 rsc [pb setString:str forType:NSPasteboardTypeString];
1380 a287dbab 2011-09-06 rsc qunlock(&snarfl);
1381 a287dbab 2011-09-06 rsc
1382 7479a49b 2011-10-03 rsc [str release];
1383 a287dbab 2011-09-06 rsc }
1384 a287dbab 2011-09-06 rsc
1385 a287dbab 2011-09-06 rsc void
1386 48107872 2011-09-19 rsc kicklabel(char *label)
1387 a287dbab 2011-09-06 rsc {
1388 48107872 2011-09-19 rsc if(label == nil)
1389 48107872 2011-09-19 rsc return;
1390 6a93bd5c 2015-11-11 rsc
1391 6a93bd5c 2015-11-11 rsc [appdelegate
1392 6a93bd5c 2015-11-11 rsc performSelectorOnMainThread:@selector(callkicklabel0:)
1393 6a93bd5c 2015-11-11 rsc withObject:[NSValue valueWithPointer:label]
1394 6a93bd5c 2015-11-11 rsc waitUntilDone:YES];
1395 6a93bd5c 2015-11-11 rsc }
1396 6a93bd5c 2015-11-11 rsc
1397 6a93bd5c 2015-11-11 rsc static void
1398 6a93bd5c 2015-11-11 rsc kicklabel0(char *label) {
1399 6a93bd5c 2015-11-11 rsc NSString *s;
1400 48107872 2011-09-19 rsc
1401 7479a49b 2011-10-03 rsc s = [[NSString alloc] initWithUTF8String:label];
1402 d0a596c5 2011-10-12 rsc [win.ofs[0] setTitle:s];
1403 d0a596c5 2011-10-12 rsc [win.ofs[1] setTitle:s];
1404 7479a49b 2011-10-03 rsc [[NSApp dockTile] setBadgeLabel:s];
1405 7479a49b 2011-10-03 rsc [s release];
1406 a287dbab 2011-09-06 rsc }
1407 a287dbab 2011-09-06 rsc
1408 a287dbab 2011-09-06 rsc void
1409 ca81de0a 2011-12-10 rsc setcursor(Cursor *c)
1410 a287dbab 2011-09-06 rsc {
1411 ca81de0a 2011-12-10 rsc /*
1412 ca81de0a 2011-12-10 rsc * No cursor change unless in main thread.
1413 ca81de0a 2011-12-10 rsc */
1414 b4d0ac96 2011-10-23 rsc [appdelegate
1415 b4d0ac96 2011-10-23 rsc performSelectorOnMainThread:@selector(callsetcursor0:)
1416 ca81de0a 2011-12-10 rsc withObject:[NSValue valueWithPointer:c]
1417 b4d0ac96 2011-10-23 rsc waitUntilDone:YES];
1418 b4d0ac96 2011-10-23 rsc }
1419 b4d0ac96 2011-10-23 rsc
1420 ca81de0a 2011-12-10 rsc static void
1421 b4d0ac96 2011-10-23 rsc setcursor0(Cursor *c)
1422 b4d0ac96 2011-10-23 rsc {
1423 ca81de0a 2011-12-10 rsc NSCursor *d;
1424 ca81de0a 2011-12-10 rsc
1425 ca81de0a 2011-12-10 rsc d = win.cursor;
1426 ca81de0a 2011-12-10 rsc
1427 ca81de0a 2011-12-10 rsc if(c)
1428 ca81de0a 2011-12-10 rsc win.cursor = makecursor(c);
1429 ca81de0a 2011-12-10 rsc else
1430 ca81de0a 2011-12-10 rsc win.cursor = nil;
1431 ca81de0a 2011-12-10 rsc
1432 ca81de0a 2011-12-10 rsc updatecursor();
1433 ca81de0a 2011-12-10 rsc
1434 ca81de0a 2011-12-10 rsc if(d)
1435 ca81de0a 2011-12-10 rsc [d release];
1436 ca81de0a 2011-12-10 rsc }
1437 ca81de0a 2011-12-10 rsc
1438 ef99c9f1 2012-10-16 rsc /*
1439 ef99c9f1 2012-10-16 rsc * Cursors will be scaled on retina display.
1440 ef99c9f1 2012-10-16 rsc */
1441 ca81de0a 2011-12-10 rsc static NSCursor*
1442 ca81de0a 2011-12-10 rsc makecursor(Cursor *c)
1443 ca81de0a 2011-12-10 rsc {
1444 48107872 2011-09-19 rsc NSBitmapImageRep *r;
1445 ca81de0a 2011-12-10 rsc NSCursor *d;
1446 48107872 2011-09-19 rsc NSImage *i;
1447 48107872 2011-09-19 rsc NSPoint p;
1448 48107872 2011-09-19 rsc int b;
1449 48107872 2011-09-19 rsc uchar *plane[5];
1450 48107872 2011-09-19 rsc
1451 ca81de0a 2011-12-10 rsc r = [[NSBitmapImageRep alloc]
1452 ca81de0a 2011-12-10 rsc initWithBitmapDataPlanes:nil
1453 ca81de0a 2011-12-10 rsc pixelsWide:16
1454 ca81de0a 2011-12-10 rsc pixelsHigh:16
1455 ca81de0a 2011-12-10 rsc bitsPerSample:1
1456 ca81de0a 2011-12-10 rsc samplesPerPixel:2
1457 ca81de0a 2011-12-10 rsc hasAlpha:YES
1458 ca81de0a 2011-12-10 rsc isPlanar:YES
1459 310ae033 2017-01-06 rsc colorSpaceName:NSDeviceWhiteColorSpace
1460 ca81de0a 2011-12-10 rsc bytesPerRow:2
1461 ca81de0a 2011-12-10 rsc bitsPerPixel:1];
1462 48107872 2011-09-19 rsc
1463 ca81de0a 2011-12-10 rsc [r getBitmapDataPlanes:plane];
1464 b4d0ac96 2011-10-23 rsc
1465 ca81de0a 2011-12-10 rsc for(b=0; b<2*16; b++){
1466 310ae033 2017-01-06 rsc plane[0][b] = ~c->set[b];
1467 ca81de0a 2011-12-10 rsc plane[1][b] = c->clr[b];
1468 d0a596c5 2011-10-12 rsc }
1469 ca81de0a 2011-12-10 rsc p = NSMakePoint(-c->offset.x, -c->offset.y);
1470 ca81de0a 2011-12-10 rsc i = [NSImage new];
1471 ca81de0a 2011-12-10 rsc [i addRepresentation:r];
1472 ca81de0a 2011-12-10 rsc [r release];
1473 b4d0ac96 2011-10-23 rsc
1474 ca81de0a 2011-12-10 rsc d = [[NSCursor alloc] initWithImage:i hotSpot:p];
1475 ca81de0a 2011-12-10 rsc [i release];
1476 ca81de0a 2011-12-10 rsc return d;
1477 e89a71ff 2012-01-16 rsc }
1478 e89a71ff 2012-01-16 rsc
1479 e89a71ff 2012-01-16 rsc void
1480 e89a71ff 2012-01-16 rsc topwin(void)
1481 e89a71ff 2012-01-16 rsc {
1482 e89a71ff 2012-01-16 rsc [WIN performSelectorOnMainThread:
1483 e89a71ff 2012-01-16 rsc @selector(makeKeyAndOrderFront:)
1484 e89a71ff 2012-01-16 rsc withObject:nil
1485 e89a71ff 2012-01-16 rsc waitUntilDone:NO];
1486 e89a71ff 2012-01-16 rsc
1487 e89a71ff 2012-01-16 rsc in.willactivate = 1;
1488 e89a71ff 2012-01-16 rsc [NSApp activateIgnoringOtherApps:YES];
1489 ef99c9f1 2012-10-16 rsc }
1490 ef99c9f1 2012-10-16 rsc
1491 ef99c9f1 2012-10-16 rsc static NSSize
1492 ef99c9f1 2012-10-16 rsc winsizepoints()
1493 ef99c9f1 2012-10-16 rsc {
1494 ef99c9f1 2012-10-16 rsc return [win.content bounds].size;
1495 ef99c9f1 2012-10-16 rsc }
1496 ef99c9f1 2012-10-16 rsc
1497 ef99c9f1 2012-10-16 rsc static NSSize
1498 ef99c9f1 2012-10-16 rsc winsizepixels()
1499 ef99c9f1 2012-10-16 rsc {
1500 c6d1f205 2012-11-26 rsc #if OSX_VERSION >= 100700
1501 ef99c9f1 2012-10-16 rsc if (OSX_VERSION >= 100700 && devdrawretina)
1502 ef99c9f1 2012-10-16 rsc return [win.content convertSizeToBacking: winsizepoints()];
1503 ef99c9f1 2012-10-16 rsc else
1504 7b9ef735 2012-11-26 rsc #endif
1505 ef99c9f1 2012-10-16 rsc return winsizepoints();
1506 ef99c9f1 2012-10-16 rsc }
1507 ef99c9f1 2012-10-16 rsc
1508 ef99c9f1 2012-10-16 rsc static NSRect
1509 ef99c9f1 2012-10-16 rsc scalerect(NSRect r, CGFloat scale)
1510 ef99c9f1 2012-10-16 rsc {
1511 ef99c9f1 2012-10-16 rsc r.origin.x *= scale;
1512 ef99c9f1 2012-10-16 rsc r.origin.y *= scale;
1513 ef99c9f1 2012-10-16 rsc r.size.width *= scale;
1514 ef99c9f1 2012-10-16 rsc r.size.height *= scale;
1515 ef99c9f1 2012-10-16 rsc return r;
1516 48107872 2011-09-19 rsc }
1517 ef99c9f1 2012-10-16 rsc
1518 ef99c9f1 2012-10-16 rsc /*
1519 ef99c9f1 2012-10-16 rsc * Expands rectangle |r|'s bounds to more inclusive integer bounds to
1520 ef99c9f1 2012-10-16 rsc * eliminate 1 pixel gaps.
1521 ef99c9f1 2012-10-16 rsc */
1522 ef99c9f1 2012-10-16 rsc static NSRect
1523 ef99c9f1 2012-10-16 rsc dilate(NSRect r)
1524 ef99c9f1 2012-10-16 rsc {
1525 ef99c9f1 2012-10-16 rsc if(win.topixelscale > 1.0f){
1526 ef99c9f1 2012-10-16 rsc r.origin.x = floorf(r.origin.x);
1527 ef99c9f1 2012-10-16 rsc r.origin.y = floorf(r.origin.y);
1528 ef99c9f1 2012-10-16 rsc r.size.width = ceilf(r.size.width + 0.5);
1529 ef99c9f1 2012-10-16 rsc r.size.height = ceilf(r.size.height + 0.5);
1530 ef99c9f1 2012-10-16 rsc }
1531 ef99c9f1 2012-10-16 rsc return r;
1532 ef99c9f1 2012-10-16 rsc }
1533 ef99c9f1 2012-10-16 rsc
1534 ef99c9f1 2012-10-16 rsc static NSPoint
1535 ef99c9f1 2012-10-16 rsc scalepoint(NSPoint pt, CGFloat scale)
1536 ef99c9f1 2012-10-16 rsc {
1537 ef99c9f1 2012-10-16 rsc pt.x *= scale;
1538 ef99c9f1 2012-10-16 rsc pt.y *= scale;
1539 ef99c9f1 2012-10-16 rsc return pt;
1540 1670a244 2013-08-07 rsc }
1541 1670a244 2013-08-07 rsc
1542 1670a244 2013-08-07 rsc static void
1543 1670a244 2013-08-07 rsc setprocname(const char *s)
1544 1670a244 2013-08-07 rsc {
1545 1670a244 2013-08-07 rsc CFStringRef process_name;
1546 1670a244 2013-08-07 rsc
1547 1670a244 2013-08-07 rsc process_name = CFStringCreateWithBytes(nil, (uchar*)s, strlen(s), kCFStringEncodingUTF8, false);
1548 1670a244 2013-08-07 rsc
1549 1670a244 2013-08-07 rsc // Adapted from Chrome's mac_util.mm.
1550 1670a244 2013-08-07 rsc // http://src.chromium.org/viewvc/chrome/trunk/src/base/mac/mac_util.mm
1551 1670a244 2013-08-07 rsc //
1552 1670a244 2013-08-07 rsc // Copyright (c) 2012 The Chromium Authors. All rights reserved.
1553 1670a244 2013-08-07 rsc //
1554 1670a244 2013-08-07 rsc // Redistribution and use in source and binary forms, with or without
1555 1670a244 2013-08-07 rsc // modification, are permitted provided that the following conditions are
1556 1670a244 2013-08-07 rsc // met:
1557 1670a244 2013-08-07 rsc //
1558 1670a244 2013-08-07 rsc // * Redistributions of source code must retain the above copyright
1559 1670a244 2013-08-07 rsc // notice, this list of conditions and the following disclaimer.
1560 1670a244 2013-08-07 rsc // * Redistributions in binary form must reproduce the above
1561 1670a244 2013-08-07 rsc // copyright notice, this list of conditions and the following disclaimer
1562 1670a244 2013-08-07 rsc // in the documentation and/or other materials provided with the
1563 1670a244 2013-08-07 rsc // distribution.
1564 1670a244 2013-08-07 rsc // * Neither the name of Google Inc. nor the names of its
1565 1670a244 2013-08-07 rsc // contributors may be used to endorse or promote products derived from
1566 1670a244 2013-08-07 rsc // this software without specific prior written permission.
1567 1670a244 2013-08-07 rsc //
1568 1670a244 2013-08-07 rsc // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1569 1670a244 2013-08-07 rsc // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1570 1670a244 2013-08-07 rsc // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1571 1670a244 2013-08-07 rsc // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1572 1670a244 2013-08-07 rsc // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1573 1670a244 2013-08-07 rsc // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1574 1670a244 2013-08-07 rsc // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1575 1670a244 2013-08-07 rsc // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1576 1670a244 2013-08-07 rsc // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1577 1670a244 2013-08-07 rsc // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1578 1670a244 2013-08-07 rsc // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1579 1670a244 2013-08-07 rsc // Warning: here be dragons! This is SPI reverse-engineered from WebKit's
1580 1670a244 2013-08-07 rsc // plugin host, and could break at any time (although realistically it's only
1581 1670a244 2013-08-07 rsc // likely to break in a new major release).
1582 1670a244 2013-08-07 rsc // When 10.7 is available, check that this still works, and update this
1583 1670a244 2013-08-07 rsc // comment for 10.8.
1584 1670a244 2013-08-07 rsc
1585 1670a244 2013-08-07 rsc // Private CFType used in these LaunchServices calls.
1586 1670a244 2013-08-07 rsc typedef CFTypeRef PrivateLSASN;
1587 1670a244 2013-08-07 rsc typedef PrivateLSASN (*LSGetCurrentApplicationASNType)();
1588 1670a244 2013-08-07 rsc typedef OSStatus (*LSSetApplicationInformationItemType)(int, PrivateLSASN,
1589 1670a244 2013-08-07 rsc CFStringRef,
1590 1670a244 2013-08-07 rsc CFStringRef,
1591 1670a244 2013-08-07 rsc CFDictionaryRef*);
1592 1670a244 2013-08-07 rsc
1593 1670a244 2013-08-07 rsc static LSGetCurrentApplicationASNType ls_get_current_application_asn_func =
1594 1670a244 2013-08-07 rsc NULL;
1595 1670a244 2013-08-07 rsc static LSSetApplicationInformationItemType
1596 1670a244 2013-08-07 rsc ls_set_application_information_item_func = NULL;
1597 1670a244 2013-08-07 rsc static CFStringRef ls_display_name_key = NULL;
1598 1670a244 2013-08-07 rsc
1599 1670a244 2013-08-07 rsc static bool did_symbol_lookup = false;
1600 1670a244 2013-08-07 rsc if (!did_symbol_lookup) {
1601 1670a244 2013-08-07 rsc did_symbol_lookup = true;
1602 1670a244 2013-08-07 rsc CFBundleRef launch_services_bundle =
1603 1670a244 2013-08-07 rsc CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
1604 1670a244 2013-08-07 rsc if (!launch_services_bundle) {
1605 1670a244 2013-08-07 rsc fprint(2, "Failed to look up LaunchServices bundle\n");
1606 1670a244 2013-08-07 rsc return;
1607 1670a244 2013-08-07 rsc }
1608 1670a244 2013-08-07 rsc
1609 1670a244 2013-08-07 rsc ls_get_current_application_asn_func =
1610 1670a244 2013-08-07 rsc (LSGetCurrentApplicationASNType)(
1611 1670a244 2013-08-07 rsc CFBundleGetFunctionPointerForName(
1612 1670a244 2013-08-07 rsc launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN")));
1613 1670a244 2013-08-07 rsc if (!ls_get_current_application_asn_func)
1614 1670a244 2013-08-07 rsc fprint(2, "Could not find _LSGetCurrentApplicationASN\n");
1615 1670a244 2013-08-07 rsc
1616 1670a244 2013-08-07 rsc ls_set_application_information_item_func =
1617 1670a244 2013-08-07 rsc (LSSetApplicationInformationItemType)(
1618 1670a244 2013-08-07 rsc CFBundleGetFunctionPointerForName(
1619 1670a244 2013-08-07 rsc launch_services_bundle,
1620 1670a244 2013-08-07 rsc CFSTR("_LSSetApplicationInformationItem")));
1621 1670a244 2013-08-07 rsc if (!ls_set_application_information_item_func)
1622 1670a244 2013-08-07 rsc fprint(2, "Could not find _LSSetApplicationInformationItem\n");
1623 1670a244 2013-08-07 rsc
1624 1670a244 2013-08-07 rsc CFStringRef* key_pointer = (CFStringRef*)(
1625 1670a244 2013-08-07 rsc CFBundleGetDataPointerForName(launch_services_bundle,
1626 1670a244 2013-08-07 rsc CFSTR("_kLSDisplayNameKey")));
1627 1670a244 2013-08-07 rsc ls_display_name_key = key_pointer ? *key_pointer : NULL;
1628 1670a244 2013-08-07 rsc if (!ls_display_name_key)
1629 1670a244 2013-08-07 rsc fprint(2, "Could not find _kLSDisplayNameKey\n");
1630 1670a244 2013-08-07 rsc
1631 1670a244 2013-08-07 rsc // Internally, this call relies on the Mach ports that are started up by the
1632 1670a244 2013-08-07 rsc // Carbon Process Manager. In debug builds this usually happens due to how
1633 1670a244 2013-08-07 rsc // the logging layers are started up; but in release, it isn't started in as
1634 1670a244 2013-08-07 rsc // much of a defined order. So if the symbols had to be loaded, go ahead
1635 1670a244 2013-08-07 rsc // and force a call to make sure the manager has been initialized and hence
1636 1670a244 2013-08-07 rsc // the ports are opened.
1637 1670a244 2013-08-07 rsc ProcessSerialNumber psn;
1638 1670a244 2013-08-07 rsc GetCurrentProcess(&psn);
1639 1670a244 2013-08-07 rsc }
1640 1670a244 2013-08-07 rsc if (!ls_get_current_application_asn_func ||
1641 1670a244 2013-08-07 rsc !ls_set_application_information_item_func ||
1642 1670a244 2013-08-07 rsc !ls_display_name_key) {
1643 1670a244 2013-08-07 rsc return;
1644 1670a244 2013-08-07 rsc }
1645 1670a244 2013-08-07 rsc
1646 1670a244 2013-08-07 rsc PrivateLSASN asn = ls_get_current_application_asn_func();
1647 1670a244 2013-08-07 rsc // Constant used by WebKit; what exactly it means is unknown.
1648 1670a244 2013-08-07 rsc const int magic_session_constant = -2;
1649 1670a244 2013-08-07 rsc OSErr err =
1650 1670a244 2013-08-07 rsc ls_set_application_information_item_func(magic_session_constant, asn,
1651 1670a244 2013-08-07 rsc ls_display_name_key,
1652 1670a244 2013-08-07 rsc process_name,
1653 1670a244 2013-08-07 rsc NULL /* optional out param */);
1654 1670a244 2013-08-07 rsc if(err != noErr)
1655 1670a244 2013-08-07 rsc fprint(2, "Call to set process name failed\n");
1656 ef99c9f1 2012-10-16 rsc }