1 933b9805 2020-01-13 rsc #define Cursor OSXCursor
2 933b9805 2020-01-13 rsc #define Point OSXPoint
3 933b9805 2020-01-13 rsc #define Rect OSXRect
5 933b9805 2020-01-13 rsc #import <Cocoa/Cocoa.h>
6 933b9805 2020-01-13 rsc #import <Metal/Metal.h>
7 933b9805 2020-01-13 rsc #import <QuartzCore/CAMetalLayer.h>
13 933b9805 2020-01-13 rsc #include <u.h>
14 933b9805 2020-01-13 rsc #include <libc.h>
15 933b9805 2020-01-13 rsc #include <thread.h>
16 933b9805 2020-01-13 rsc #include <draw.h>
17 933b9805 2020-01-13 rsc #include <memdraw.h>
18 88ed92aa 2020-01-13 rsc #include <memlayer.h>
19 88ed92aa 2020-01-13 rsc #include <mouse.h>
20 933b9805 2020-01-13 rsc #include <cursor.h>
21 88ed92aa 2020-01-13 rsc #include <keyboard.h>
22 88ed92aa 2020-01-13 rsc #include <drawfcall.h>
23 933b9805 2020-01-13 rsc #include "devdraw.h"
24 933b9805 2020-01-13 rsc #include "bigarrow.h"
25 933b9805 2020-01-13 rsc #include "glendapng.h"
27 933b9805 2020-01-13 rsc AUTOFRAMEWORK(Cocoa)
28 933b9805 2020-01-13 rsc AUTOFRAMEWORK(Metal)
29 933b9805 2020-01-13 rsc AUTOFRAMEWORK(QuartzCore)
30 04da0159 2020-01-13 rsc AUTOFRAMEWORK(CoreFoundation)
32 933b9805 2020-01-13 rsc #define LOG if(0)NSLog
34 892b3c46 2020-01-13 rsc // TODO: Maintain list of views for dock menu.
36 933b9805 2020-01-13 rsc static void setprocname(const char*);
37 933b9805 2020-01-13 rsc static uint keycvt(uint);
38 933b9805 2020-01-13 rsc static uint msec(void);
40 94d381ec 2020-05-18 rsc static void rpc_resizeimg(Client*);
41 94d381ec 2020-05-18 rsc static void rpc_resizewindow(Client*, Rectangle);
42 94d381ec 2020-05-18 rsc static void rpc_setcursor(Client*, Cursor*, Cursor2*);
43 94d381ec 2020-05-18 rsc static void rpc_setlabel(Client*, char*);
44 94d381ec 2020-05-18 rsc static void rpc_setmouse(Client*, Point);
45 94d381ec 2020-05-18 rsc static void rpc_topwin(Client*);
46 94d381ec 2020-05-18 rsc static void rpc_bouncemouse(Client*, Mouse);
47 94d381ec 2020-05-18 rsc static void rpc_flush(Client*, Rectangle);
49 94d381ec 2020-05-18 rsc static ClientImpl macimpl = {
50 94d381ec 2020-05-18 rsc rpc_resizeimg,
51 94d381ec 2020-05-18 rsc rpc_resizewindow,
52 94d381ec 2020-05-18 rsc rpc_setcursor,
53 94d381ec 2020-05-18 rsc rpc_setlabel,
54 94d381ec 2020-05-18 rsc rpc_setmouse,
56 94d381ec 2020-05-18 rsc rpc_bouncemouse,
60 b1a086de 2020-01-13 rsc @class DrawView;
61 b1a086de 2020-01-13 rsc @class DrawLayer;
63 843e5af1 2020-01-13 rsc @interface AppDelegate : NSObject<NSApplicationDelegate>
66 933b9805 2020-01-13 rsc static AppDelegate *myApp = NULL;
69 41547af3 2020-01-13 rsc gfx_main(void)
72 892b3c46 2020-01-13 rsc setprocname(argv0);
74 933b9805 2020-01-13 rsc @autoreleasepool{
75 933b9805 2020-01-13 rsc [NSApplication sharedApplication];
76 933b9805 2020-01-13 rsc [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
77 933b9805 2020-01-13 rsc myApp = [AppDelegate new];
78 933b9805 2020-01-13 rsc [NSApp setDelegate:myApp];
85 41547af3 2020-01-13 rsc rpc_shutdown(void)
87 933b9805 2020-01-13 rsc [NSApp terminate:myApp];
90 933b9805 2020-01-13 rsc @implementation AppDelegate
91 b1a086de 2020-01-13 rsc - (void)applicationDidFinishLaunching:(id)arg
93 b1a086de 2020-01-13 rsc NSMenu *m, *sm;
97 b1a086de 2020-01-13 rsc LOG(@"applicationDidFinishLaunching");
99 b1a086de 2020-01-13 rsc sm = [NSMenu new];
100 b1a086de 2020-01-13 rsc [sm addItemWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"];
101 b1a086de 2020-01-13 rsc [sm addItemWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@"h"];
102 b1a086de 2020-01-13 rsc [sm addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
103 b1a086de 2020-01-13 rsc m = [NSMenu new];
104 b1a086de 2020-01-13 rsc [m addItemWithTitle:@"DEVDRAW" action:NULL keyEquivalent:@""];
105 b1a086de 2020-01-13 rsc [m setSubmenu:sm forItem:[m itemWithTitle:@"DEVDRAW"]];
106 b1a086de 2020-01-13 rsc [NSApp setMainMenu:m];
108 b1a086de 2020-01-13 rsc d = [[NSData alloc] initWithBytes:glenda_png length:(sizeof glenda_png)];
109 b1a086de 2020-01-13 rsc i = [[NSImage alloc] initWithData:d];
110 b1a086de 2020-01-13 rsc [NSApp setApplicationIconImage:i];
111 b1a086de 2020-01-13 rsc [[NSApp dockTile] display];
113 41547af3 2020-01-13 rsc gfx_started();
116 b1a086de 2020-01-13 rsc - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
117 892b3c46 2020-01-13 rsc return client0 != nil;
121 b1a086de 2020-01-13 rsc @interface DrawLayer : CAMetalLayer
122 b1a086de 2020-01-13 rsc @property (nonatomic, retain) id<MTLCommandQueue> cmd;
123 b1a086de 2020-01-13 rsc @property (nonatomic, retain) id<MTLTexture> texture;
126 b1a086de 2020-01-13 rsc @implementation DrawLayer
127 b1a086de 2020-01-13 rsc - (void)display
129 b1a086de 2020-01-13 rsc LOG(@"display");
130 b1a086de 2020-01-13 rsc LOG(@"display query drawable");
132 b1a086de 2020-01-13 rsc @autoreleasepool{
133 b1a086de 2020-01-13 rsc id<CAMetalDrawable> drawable = [self nextDrawable];
134 b1a086de 2020-01-13 rsc if(!drawable){
135 b1a086de 2020-01-13 rsc LOG(@"display couldn't get drawable");
136 b1a086de 2020-01-13 rsc [self setNeedsDisplay];
140 b1a086de 2020-01-13 rsc LOG(@"display got drawable");
142 b1a086de 2020-01-13 rsc id<MTLCommandBuffer> cbuf = [self.cmd commandBuffer];
143 b1a086de 2020-01-13 rsc id<MTLBlitCommandEncoder> blit = [cbuf blitCommandEncoder];
144 b1a086de 2020-01-13 rsc [blit copyFromTexture:self.texture
145 b1a086de 2020-01-13 rsc sourceSlice:0
146 b1a086de 2020-01-13 rsc sourceLevel:0
147 b1a086de 2020-01-13 rsc sourceOrigin:MTLOriginMake(0, 0, 0)
148 b1a086de 2020-01-13 rsc sourceSize:MTLSizeMake(self.texture.width, self.texture.height, self.texture.depth)
149 b1a086de 2020-01-13 rsc toTexture:drawable.texture
150 b1a086de 2020-01-13 rsc destinationSlice:0
151 b1a086de 2020-01-13 rsc destinationLevel:0
152 b1a086de 2020-01-13 rsc destinationOrigin:MTLOriginMake(0, 0, 0)];
153 b1a086de 2020-01-13 rsc [blit endEncoding];
155 b1a086de 2020-01-13 rsc [cbuf presentDrawable:drawable];
156 b1a086de 2020-01-13 rsc drawable = nil;
157 b1a086de 2020-01-13 rsc [cbuf addCompletedHandler:^(id<MTLCommandBuffer> cmdBuff){
158 b1a086de 2020-01-13 rsc if(cmdBuff.error){
159 b1a086de 2020-01-13 rsc NSLog(@"command buffer finished with error: %@",
160 b1a086de 2020-01-13 rsc cmdBuff.error.localizedDescription);
162 b1a086de 2020-01-13 rsc LOG(@"command buffer finishes present drawable");
164 b1a086de 2020-01-13 rsc [cbuf commit];
166 b1a086de 2020-01-13 rsc LOG(@"display commit");
170 b1a086de 2020-01-13 rsc @interface DrawView : NSView<NSTextInputClient,NSWindowDelegate>
171 b1a086de 2020-01-13 rsc @property (nonatomic, assign) Client *client;
172 b1a086de 2020-01-13 rsc @property (nonatomic, retain) DrawLayer *dlayer;
173 b1a086de 2020-01-13 rsc @property (nonatomic, retain) NSWindow *win;
174 b1a086de 2020-01-13 rsc @property (nonatomic, retain) NSCursor *currentCursor;
175 b1a086de 2020-01-13 rsc @property (nonatomic, assign) Memimage *img;
177 b1a086de 2020-01-13 rsc - (id)attach:(Client*)client winsize:(char*)winsize label:(char*)label;
178 b1a086de 2020-01-13 rsc - (void)topwin;
179 b1a086de 2020-01-13 rsc - (void)setlabel:(char*)label;
180 b1a086de 2020-01-13 rsc - (void)setcursor:(Cursor*)c cursor2:(Cursor2*)c2;
181 b1a086de 2020-01-13 rsc - (void)setmouse:(Point)p;
182 b1a086de 2020-01-13 rsc - (void)clearInput;
183 b1a086de 2020-01-13 rsc - (void)getmouse:(NSEvent*)e;
184 b1a086de 2020-01-13 rsc - (void)sendmouse:(NSUInteger)b;
185 b1a086de 2020-01-13 rsc - (void)resetLastInputRect;
186 b1a086de 2020-01-13 rsc - (void)enlargeLastInputRect:(NSRect)r;
189 b1a086de 2020-01-13 rsc @implementation DrawView
191 b1a086de 2020-01-13 rsc NSMutableString *_tmpText;
192 b1a086de 2020-01-13 rsc NSRange _markedRange;
193 b1a086de 2020-01-13 rsc NSRange _selectedRange;
194 b1a086de 2020-01-13 rsc NSRect _lastInputRect; // The view is flipped, this is not.
195 b1a086de 2020-01-13 rsc BOOL _tapping;
196 b1a086de 2020-01-13 rsc NSUInteger _tapFingers;
197 b1a086de 2020-01-13 rsc NSUInteger _tapTime;
202 b1a086de 2020-01-13 rsc LOG(@"View init");
203 b1a086de 2020-01-13 rsc self = [super init];
204 b1a086de 2020-01-13 rsc [self setAllowedTouchTypes:NSTouchTypeMaskDirect|NSTouchTypeMaskIndirect];
205 b1a086de 2020-01-13 rsc _tmpText = [[NSMutableString alloc] initWithCapacity:2];
206 b1a086de 2020-01-13 rsc _markedRange = NSMakeRange(NSNotFound, 0);
207 b1a086de 2020-01-13 rsc _selectedRange = NSMakeRange(0, 0);
208 b1a086de 2020-01-13 rsc return self;
211 b1a086de 2020-01-13 rsc - (CALayer*)makeBackingLayer { return [DrawLayer layer]; }
212 b1a086de 2020-01-13 rsc - (BOOL)wantsUpdateLayer { return YES; }
213 b1a086de 2020-01-13 rsc - (BOOL)isOpaque { return YES; }
214 b1a086de 2020-01-13 rsc - (BOOL)isFlipped { return YES; }
215 b1a086de 2020-01-13 rsc - (BOOL)acceptsFirstResponder { return YES; }
217 41547af3 2020-01-13 rsc // rpc_attach allocates a new screen window with the given label and size
218 b1a086de 2020-01-13 rsc // and attaches it to client c (by setting c->view).
220 41547af3 2020-01-13 rsc rpc_attach(Client *c, char *label, char *winsize)
222 b1a086de 2020-01-13 rsc LOG(@"attachscreen(%s, %s)", label, winsize);
224 94d381ec 2020-05-18 rsc c->impl = &macimpl;
225 b1a086de 2020-01-13 rsc dispatch_sync(dispatch_get_main_queue(), ^(void) {
226 b1a086de 2020-01-13 rsc @autoreleasepool {
227 b1a086de 2020-01-13 rsc DrawView *view = [[DrawView new] attach:c winsize:winsize label:label];
228 b1a086de 2020-01-13 rsc [view initimg];
231 b1a086de 2020-01-13 rsc return ((__bridge DrawView*)c->view).img;
234 b1a086de 2020-01-13 rsc - (id)attach:(Client*)client winsize:(char*)winsize label:(char*)label {
235 933b9805 2020-01-13 rsc NSRect r, sr;
236 933b9805 2020-01-13 rsc Rectangle wr;
239 933b9805 2020-01-13 rsc NSArray *allDevices;
241 7f6458b0 2021-01-06 rsc NSWindowStyleMask Winstyle = NSWindowStyleMaskTitled
242 933b9805 2020-01-13 rsc | NSWindowStyleMaskClosable
243 933b9805 2020-01-13 rsc | NSWindowStyleMaskMiniaturizable
244 933b9805 2020-01-13 rsc | NSWindowStyleMaskResizable;
246 7f6458b0 2021-01-06 rsc if(label == nil || *label == '\0')
247 7f6458b0 2021-01-06 rsc Winstyle &= ~NSWindowStyleMaskTitled;
249 b1a086de 2020-01-13 rsc s = winsize;
250 933b9805 2020-01-13 rsc sr = [[NSScreen mainScreen] frame];
251 933b9805 2020-01-13 rsc r = [[NSScreen mainScreen] visibleFrame];
253 933b9805 2020-01-13 rsc LOG(@"makewin(%s)", s);
254 892b3c46 2020-01-13 rsc if(s == nil || *s == '\0' || parsewinsize(s, &wr, &set) < 0) {
255 933b9805 2020-01-13 rsc wr = Rect(0, 0, sr.size.width*2/3, sr.size.height*2/3);
259 933b9805 2020-01-13 rsc r.origin.x = wr.min.x;
260 933b9805 2020-01-13 rsc r.origin.y = sr.size.height-wr.max.y; /* winsize is top-left-based */
261 933b9805 2020-01-13 rsc r.size.width = fmin(Dx(wr), r.size.width);
262 933b9805 2020-01-13 rsc r.size.height = fmin(Dy(wr), r.size.height);
263 933b9805 2020-01-13 rsc r = [NSWindow contentRectForFrameRect:r styleMask:Winstyle];
265 843e5af1 2020-01-13 rsc NSWindow *win = [[NSWindow alloc]
266 933b9805 2020-01-13 rsc initWithContentRect:r
267 933b9805 2020-01-13 rsc styleMask:Winstyle
268 933b9805 2020-01-13 rsc backing:NSBackingStoreBuffered defer:NO];
269 933b9805 2020-01-13 rsc [win setTitle:@"devdraw"];
272 933b9805 2020-01-13 rsc [win center];
273 933b9805 2020-01-13 rsc [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
274 933b9805 2020-01-13 rsc [win setContentMinSize:NSMakeSize(64,64)];
275 933b9805 2020-01-13 rsc [win setOpaque:YES];
276 933b9805 2020-01-13 rsc [win setRestorable:NO];
277 933b9805 2020-01-13 rsc [win setAcceptsMouseMovedEvents:YES];
279 b1a086de 2020-01-13 rsc client->view = CFBridgingRetain(self);
280 b1a086de 2020-01-13 rsc self.client = client;
281 b1a086de 2020-01-13 rsc self.win = win;
282 b1a086de 2020-01-13 rsc self.currentCursor = nil;
283 b1a086de 2020-01-13 rsc [win setContentView:self];
284 b1a086de 2020-01-13 rsc [win setDelegate:self];
285 b1a086de 2020-01-13 rsc [self setWantsLayer:YES];
286 b1a086de 2020-01-13 rsc [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay];
288 b1a086de 2020-01-13 rsc id<MTLDevice> device = nil;
289 933b9805 2020-01-13 rsc allDevices = MTLCopyAllDevices();
290 933b9805 2020-01-13 rsc for(id mtlDevice in allDevices) {
291 933b9805 2020-01-13 rsc if ([mtlDevice isLowPower] && ![mtlDevice isRemovable]) {
292 933b9805 2020-01-13 rsc device = mtlDevice;
297 933b9805 2020-01-13 rsc device = MTLCreateSystemDefaultDevice();
299 b1a086de 2020-01-13 rsc DrawLayer *layer = (DrawLayer*)[self layer];
300 b1a086de 2020-01-13 rsc self.dlayer = layer;
301 933b9805 2020-01-13 rsc layer.device = device;
302 b1a086de 2020-01-13 rsc layer.cmd = [device newCommandQueue];
303 933b9805 2020-01-13 rsc layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
304 933b9805 2020-01-13 rsc layer.framebufferOnly = YES;
305 933b9805 2020-01-13 rsc layer.opaque = YES;
307 933b9805 2020-01-13 rsc // We use a default transparent layer on top of the CAMetalLayer.
308 933b9805 2020-01-13 rsc // This seems to make fullscreen applications behave.
309 b1a086de 2020-01-13 rsc // Specifically, without this code if you enter full screen with Cmd-F,
310 b1a086de 2020-01-13 rsc // the screen goes black until the first mouse click.
312 933b9805 2020-01-13 rsc CALayer *stub = [CALayer layer];
313 933b9805 2020-01-13 rsc stub.frame = CGRectMake(0, 0, 1, 1);
314 933b9805 2020-01-13 rsc [stub setNeedsDisplay];
315 933b9805 2020-01-13 rsc [layer addSublayer:stub];
318 933b9805 2020-01-13 rsc [NSEvent setMouseCoalescingEnabled:NO];
320 b1a086de 2020-01-13 rsc [self topwin];
321 b1a086de 2020-01-13 rsc [self setlabel:label];
322 b1a086de 2020-01-13 rsc [self setcursor:nil cursor2:nil];
324 b1a086de 2020-01-13 rsc return self;
327 b1a086de 2020-01-13 rsc // rpc_topwin moves the window to the top of the desktop.
328 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
330 b1a086de 2020-01-13 rsc rpc_topwin(Client *c)
332 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)c->view;
333 b1a086de 2020-01-13 rsc dispatch_sync(dispatch_get_main_queue(), ^(void) {
334 b1a086de 2020-01-13 rsc [view topwin];
338 b1a086de 2020-01-13 rsc - (void)topwin {
339 b1a086de 2020-01-13 rsc [self.win makeKeyAndOrderFront:nil];
340 b1a086de 2020-01-13 rsc [NSApp activateIgnoringOtherApps:YES];
343 b1a086de 2020-01-13 rsc // rpc_setlabel updates the client window's label.
344 b1a086de 2020-01-13 rsc // If label == nil, the call is a no-op.
345 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
347 b1a086de 2020-01-13 rsc rpc_setlabel(Client *client, char *label)
349 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)client->view;
350 b1a086de 2020-01-13 rsc dispatch_sync(dispatch_get_main_queue(), ^(void){
351 b1a086de 2020-01-13 rsc [view setlabel:label];
355 b1a086de 2020-01-13 rsc - (void)setlabel:(char*)label {
356 b1a086de 2020-01-13 rsc LOG(@"setlabel(%s)", label);
357 b1a086de 2020-01-13 rsc if(label == nil)
360 b1a086de 2020-01-13 rsc @autoreleasepool{
361 b1a086de 2020-01-13 rsc NSString *s = [[NSString alloc] initWithUTF8String:label];
362 b1a086de 2020-01-13 rsc [self.win setTitle:s];
364 892b3c46 2020-01-13 rsc [[NSApp dockTile] setBadgeLabel:s];
368 b1a086de 2020-01-13 rsc // rpc_setcursor updates the client window's cursor image.
369 b1a086de 2020-01-13 rsc // Either c and c2 are both non-nil, or they are both nil to use the default arrow.
370 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
372 b1a086de 2020-01-13 rsc rpc_setcursor(Client *client, Cursor *c, Cursor2 *c2)
374 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)client->view;
375 b1a086de 2020-01-13 rsc dispatch_sync(dispatch_get_main_queue(), ^(void){
376 b1a086de 2020-01-13 rsc [view setcursor:c cursor2:c2];
380 b1a086de 2020-01-13 rsc - (void)setcursor:(Cursor*)c cursor2:(Cursor2*)c2 {
382 b1a086de 2020-01-13 rsc c = &bigarrow;
383 b1a086de 2020-01-13 rsc c2 = &bigarrow2;
386 933b9805 2020-01-13 rsc NSBitmapImageRep *r, *r2;
389 933b9805 2020-01-13 rsc uchar *plane[5], *plane2[5];
392 933b9805 2020-01-13 rsc r = [[NSBitmapImageRep alloc]
393 933b9805 2020-01-13 rsc initWithBitmapDataPlanes:nil
394 933b9805 2020-01-13 rsc pixelsWide:16
395 933b9805 2020-01-13 rsc pixelsHigh:16
396 933b9805 2020-01-13 rsc bitsPerSample:1
397 933b9805 2020-01-13 rsc samplesPerPixel:2
398 933b9805 2020-01-13 rsc hasAlpha:YES
399 933b9805 2020-01-13 rsc isPlanar:YES
400 933b9805 2020-01-13 rsc colorSpaceName:NSDeviceWhiteColorSpace
401 933b9805 2020-01-13 rsc bytesPerRow:2
402 933b9805 2020-01-13 rsc bitsPerPixel:0];
403 933b9805 2020-01-13 rsc [r getBitmapDataPlanes:plane];
404 933b9805 2020-01-13 rsc for(b=0; b<nelem(c->set); b++){
405 933b9805 2020-01-13 rsc plane[0][b] = ~c->set[b] & c->clr[b];
406 933b9805 2020-01-13 rsc plane[1][b] = c->set[b] | c->clr[b];
409 933b9805 2020-01-13 rsc r2 = [[NSBitmapImageRep alloc]
410 933b9805 2020-01-13 rsc initWithBitmapDataPlanes:nil
411 933b9805 2020-01-13 rsc pixelsWide:32
412 933b9805 2020-01-13 rsc pixelsHigh:32
413 933b9805 2020-01-13 rsc bitsPerSample:1
414 933b9805 2020-01-13 rsc samplesPerPixel:2
415 933b9805 2020-01-13 rsc hasAlpha:YES
416 933b9805 2020-01-13 rsc isPlanar:YES
417 933b9805 2020-01-13 rsc colorSpaceName:NSDeviceWhiteColorSpace
418 933b9805 2020-01-13 rsc bytesPerRow:4
419 933b9805 2020-01-13 rsc bitsPerPixel:0];
420 933b9805 2020-01-13 rsc [r2 getBitmapDataPlanes:plane2];
421 933b9805 2020-01-13 rsc for(b=0; b<nelem(c2->set); b++){
422 933b9805 2020-01-13 rsc plane2[0][b] = ~c2->set[b] & c2->clr[b];
423 933b9805 2020-01-13 rsc plane2[1][b] = c2->set[b] | c2->clr[b];
426 b1a086de 2020-01-13 rsc static BOOL debug = NO;
428 933b9805 2020-01-13 rsc NSData *data = [r representationUsingType: NSBitmapImageFileTypeBMP properties: @{}];
429 933b9805 2020-01-13 rsc [data writeToFile: @"/tmp/r.bmp" atomically: NO];
430 933b9805 2020-01-13 rsc data = [r2 representationUsingType: NSBitmapImageFileTypeBMP properties: @{}];
431 933b9805 2020-01-13 rsc [data writeToFile: @"/tmp/r2.bmp" atomically: NO];
435 933b9805 2020-01-13 rsc i = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)];
436 933b9805 2020-01-13 rsc [i addRepresentation:r2];
437 933b9805 2020-01-13 rsc [i addRepresentation:r];
439 933b9805 2020-01-13 rsc p = NSMakePoint(-c->offset.x, -c->offset.y);
440 b1a086de 2020-01-13 rsc self.currentCursor = [[NSCursor alloc] initWithImage:i hotSpot:p];
441 b1a086de 2020-01-13 rsc [self.win invalidateCursorRectsForView:self];
444 b1a086de 2020-01-13 rsc - (void)initimg {
445 41547af3 2020-01-13 rsc @autoreleasepool {
446 41547af3 2020-01-13 rsc CGFloat scale;
447 41547af3 2020-01-13 rsc NSSize size;
448 41547af3 2020-01-13 rsc MTLTextureDescriptor *textureDesc;
450 41547af3 2020-01-13 rsc size = [self convertSizeToBacking:[self bounds].size];
451 41547af3 2020-01-13 rsc self.client->mouserect = Rect(0, 0, size.width, size.height);
453 41547af3 2020-01-13 rsc LOG(@"initimg %.0f %.0f", size.width, size.height);
455 41547af3 2020-01-13 rsc self.img = allocmemimage(self.client->mouserect, XRGB32);
456 41547af3 2020-01-13 rsc if(self.img == nil)
457 41547af3 2020-01-13 rsc panic("allocmemimage: %r");
458 41547af3 2020-01-13 rsc if(self.img->data == nil)
459 41547af3 2020-01-13 rsc panic("img->data == nil");
461 41547af3 2020-01-13 rsc textureDesc = [MTLTextureDescriptor
462 41547af3 2020-01-13 rsc texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
463 41547af3 2020-01-13 rsc width:size.width
464 41547af3 2020-01-13 rsc height:size.height
465 41547af3 2020-01-13 rsc mipmapped:NO];
466 41547af3 2020-01-13 rsc textureDesc.allowGPUOptimizedContents = YES;
467 41547af3 2020-01-13 rsc textureDesc.usage = MTLTextureUsageShaderRead;
468 41547af3 2020-01-13 rsc textureDesc.cpuCacheMode = MTLCPUCacheModeWriteCombined;
469 41547af3 2020-01-13 rsc self.dlayer.texture = [self.dlayer.device newTextureWithDescriptor:textureDesc];
471 41547af3 2020-01-13 rsc scale = [self.win backingScaleFactor];
472 41547af3 2020-01-13 rsc [self.dlayer setDrawableSize:size];
473 41547af3 2020-01-13 rsc [self.dlayer setContentsScale:scale];
475 41547af3 2020-01-13 rsc // NOTE: This is not really the display DPI.
476 41547af3 2020-01-13 rsc // On retina, scale is 2; otherwise it is 1.
477 41547af3 2020-01-13 rsc // This formula gives us 220 for retina, 110 otherwise.
478 41547af3 2020-01-13 rsc // That's not quite right but it's close to correct.
479 41547af3 2020-01-13 rsc // https://en.wikipedia.org/wiki/Retina_display#Models
480 41547af3 2020-01-13 rsc self.client->displaydpi = scale * 110;
484 41547af3 2020-01-13 rsc // rpc_flush flushes changes to view.img's rectangle r
485 b1a086de 2020-01-13 rsc // to the on-screen window, making them visible.
486 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
488 41547af3 2020-01-13 rsc rpc_flush(Client *client, Rectangle r)
490 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)client->view;
491 b1a086de 2020-01-13 rsc dispatch_async(dispatch_get_main_queue(), ^(void){
492 41547af3 2020-01-13 rsc [view flush:r];
496 41547af3 2020-01-13 rsc - (void)flush:(Rectangle)r {
497 b1a086de 2020-01-13 rsc @autoreleasepool{
498 41547af3 2020-01-13 rsc if(!rectclip(&r, Rect(0, 0, self.dlayer.texture.width, self.dlayer.texture.height)) || !rectclip(&r, self.img->r))
501 587933c1 2020-05-18 rsc // drawlk protects the pixel data in self.img.
502 41547af3 2020-01-13 rsc // In addition to avoiding a technical data race,
503 41547af3 2020-01-13 rsc // the lock avoids drawing partial updates, which makes
504 41547af3 2020-01-13 rsc // animations like sweeping windows much less flickery.
505 587933c1 2020-05-18 rsc qlock(&drawlk);
506 b1a086de 2020-01-13 rsc [self.dlayer.texture
507 b1a086de 2020-01-13 rsc replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r))
508 b1a086de 2020-01-13 rsc mipmapLevel:0
509 b1a086de 2020-01-13 rsc withBytes:byteaddr(self.img, Pt(r.min.x, r.min.y))
510 b1a086de 2020-01-13 rsc bytesPerRow:self.img->width*sizeof(u32int)];
511 587933c1 2020-05-18 rsc qunlock(&drawlk);
513 b1a086de 2020-01-13 rsc NSRect nr = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r));
514 b1a086de 2020-01-13 rsc dispatch_time_t time;
516 b1a086de 2020-01-13 rsc LOG(@"callsetNeedsDisplayInRect(%g, %g, %g, %g)", nr.origin.x, nr.origin.y, nr.size.width, nr.size.height);
517 b1a086de 2020-01-13 rsc nr = [self.win convertRectFromBacking:nr];
518 b1a086de 2020-01-13 rsc LOG(@"setNeedsDisplayInRect(%g, %g, %g, %g)", nr.origin.x, nr.origin.y, nr.size.width, nr.size.height);
519 b1a086de 2020-01-13 rsc [self.dlayer setNeedsDisplayInRect:nr];
521 b1a086de 2020-01-13 rsc time = dispatch_time(DISPATCH_TIME_NOW, 16 * NSEC_PER_MSEC);
522 b1a086de 2020-01-13 rsc dispatch_after(time, dispatch_get_main_queue(), ^(void){
523 b1a086de 2020-01-13 rsc [self.dlayer setNeedsDisplayInRect:nr];
526 b1a086de 2020-01-13 rsc [self enlargeLastInputRect:nr];
530 b1a086de 2020-01-13 rsc // rpc_resizeimg forces the client window to discard its current window and make a new one.
531 b1a086de 2020-01-13 rsc // It is called when the user types Cmd-R to toggle whether retina mode is forced.
532 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
534 b1a086de 2020-01-13 rsc rpc_resizeimg(Client *c)
536 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)c->view;
537 f66f0a58 2020-02-03 noreply dispatch_async(dispatch_get_main_queue(), ^(void){
538 b1a086de 2020-01-13 rsc [view resizeimg];
542 b1a086de 2020-01-13 rsc - (void)resizeimg {
543 b1a086de 2020-01-13 rsc [self initimg];
544 41547af3 2020-01-13 rsc gfx_replacescreenimage(self.client, self.img);
547 b1a086de 2020-01-13 rsc - (void)windowDidResize:(NSNotification *)notification {
548 b1a086de 2020-01-13 rsc if(![self inLiveResize] && self.img) {
549 b1a086de 2020-01-13 rsc [self resizeimg];
552 b1a086de 2020-01-13 rsc - (void)viewDidEndLiveResize
554 b1a086de 2020-01-13 rsc [super viewDidEndLiveResize];
555 b1a086de 2020-01-13 rsc if(self.img)
556 b1a086de 2020-01-13 rsc [self resizeimg];
559 b1a086de 2020-01-13 rsc - (void)viewDidChangeBackingProperties
561 b1a086de 2020-01-13 rsc [super viewDidChangeBackingProperties];
562 b1a086de 2020-01-13 rsc if(self.img)
563 b1a086de 2020-01-13 rsc [self resizeimg];
566 b1a086de 2020-01-13 rsc // rpc_resizewindow asks for the client window to be resized to size r.
567 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
569 b1a086de 2020-01-13 rsc rpc_resizewindow(Client *c, Rectangle r)
571 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)c->view;
573 b1a086de 2020-01-13 rsc LOG(@"resizewindow %d %d %d %d", r.min.x, r.min.y, Dx(r), Dy(r));
574 b1a086de 2020-01-13 rsc dispatch_async(dispatch_get_main_queue(), ^(void){
577 b1a086de 2020-01-13 rsc s = [view convertSizeFromBacking:NSMakeSize(Dx(r), Dy(r))];
578 b1a086de 2020-01-13 rsc [view.win setContentSize:s];
583 b1a086de 2020-01-13 rsc - (void)windowDidBecomeKey:(id)arg {
584 b1a086de 2020-01-13 rsc [self sendmouse:0];
587 1d0d432c 2020-01-16 rsc - (void)windowDidResignKey:(id)arg {
588 1d0d432c 2020-01-16 rsc gfx_abortcompose(self.client);
591 933b9805 2020-01-13 rsc - (void)mouseMoved:(NSEvent*)e{ [self getmouse:e];}
592 933b9805 2020-01-13 rsc - (void)mouseDown:(NSEvent*)e{ [self getmouse:e];}
593 933b9805 2020-01-13 rsc - (void)mouseDragged:(NSEvent*)e{ [self getmouse:e];}
594 933b9805 2020-01-13 rsc - (void)mouseUp:(NSEvent*)e{ [self getmouse:e];}
595 933b9805 2020-01-13 rsc - (void)otherMouseDown:(NSEvent*)e{ [self getmouse:e];}
596 933b9805 2020-01-13 rsc - (void)otherMouseDragged:(NSEvent*)e{ [self getmouse:e];}
597 933b9805 2020-01-13 rsc - (void)otherMouseUp:(NSEvent*)e{ [self getmouse:e];}
598 933b9805 2020-01-13 rsc - (void)rightMouseDown:(NSEvent*)e{ [self getmouse:e];}
599 933b9805 2020-01-13 rsc - (void)rightMouseDragged:(NSEvent*)e{ [self getmouse:e];}
600 933b9805 2020-01-13 rsc - (void)rightMouseUp:(NSEvent*)e{ [self getmouse:e];}
602 933b9805 2020-01-13 rsc - (void)scrollWheel:(NSEvent*)e
604 933b9805 2020-01-13 rsc NSInteger s;
606 933b9805 2020-01-13 rsc s = [e scrollingDeltaY];
608 933b9805 2020-01-13 rsc [self sendmouse:8];
609 933b9805 2020-01-13 rsc else if (s < 0)
610 933b9805 2020-01-13 rsc [self sendmouse:16];
613 933b9805 2020-01-13 rsc - (void)keyDown:(NSEvent*)e
615 933b9805 2020-01-13 rsc LOG(@"keyDown to interpret");
617 933b9805 2020-01-13 rsc [self interpretKeyEvents:[NSArray arrayWithObject:e]];
619 933b9805 2020-01-13 rsc [self resetLastInputRect];
622 933b9805 2020-01-13 rsc - (void)flagsChanged:(NSEvent*)e
624 933b9805 2020-01-13 rsc static NSEventModifierFlags omod;
625 933b9805 2020-01-13 rsc NSEventModifierFlags m;
628 933b9805 2020-01-13 rsc LOG(@"flagsChanged");
629 933b9805 2020-01-13 rsc m = [e modifierFlags];
631 933b9805 2020-01-13 rsc b = [NSEvent pressedMouseButtons];
632 933b9805 2020-01-13 rsc b = (b&~6) | (b&4)>>1 | (b&2)<<1;
634 933b9805 2020-01-13 rsc if(m & ~omod & NSEventModifierFlagControl)
636 933b9805 2020-01-13 rsc if(m & ~omod & NSEventModifierFlagOption)
638 933b9805 2020-01-13 rsc if(m & ~omod & NSEventModifierFlagCommand)
640 933b9805 2020-01-13 rsc [self sendmouse:b];
641 933b9805 2020-01-13 rsc }else if(m & ~omod & NSEventModifierFlagOption)
642 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, Kalt);
647 933b9805 2020-01-13 rsc - (void)magnifyWithEvent:(NSEvent*)e
649 933b9805 2020-01-13 rsc if(fabs([e magnification]) > 0.02)
650 933b9805 2020-01-13 rsc [[self window] toggleFullScreen:nil];
653 933b9805 2020-01-13 rsc - (void)touchesBeganWithEvent:(NSEvent*)e
655 933b9805 2020-01-13 rsc _tapping = YES;
656 933b9805 2020-01-13 rsc _tapFingers = [e touchesMatchingPhase:NSTouchPhaseTouching inView:nil].count;
657 933b9805 2020-01-13 rsc _tapTime = msec();
659 933b9805 2020-01-13 rsc - (void)touchesMovedWithEvent:(NSEvent*)e
661 933b9805 2020-01-13 rsc _tapping = NO;
663 933b9805 2020-01-13 rsc - (void)touchesEndedWithEvent:(NSEvent*)e
666 933b9805 2020-01-13 rsc && [e touchesMatchingPhase:NSTouchPhaseTouching inView:nil].count == 0
667 933b9805 2020-01-13 rsc && msec() - _tapTime < 250){
668 933b9805 2020-01-13 rsc switch(_tapFingers){
670 933b9805 2020-01-13 rsc [self sendmouse:2];
671 933b9805 2020-01-13 rsc [self sendmouse:0];
674 933b9805 2020-01-13 rsc [self sendmouse:2];
675 933b9805 2020-01-13 rsc [self sendmouse:1];
676 933b9805 2020-01-13 rsc [self sendmouse:0];
679 933b9805 2020-01-13 rsc _tapping = NO;
682 933b9805 2020-01-13 rsc - (void)touchesCancelledWithEvent:(NSEvent*)e
684 933b9805 2020-01-13 rsc _tapping = NO;
687 933b9805 2020-01-13 rsc - (void)getmouse:(NSEvent *)e
689 933b9805 2020-01-13 rsc NSUInteger b;
690 933b9805 2020-01-13 rsc NSEventModifierFlags m;
692 933b9805 2020-01-13 rsc b = [NSEvent pressedMouseButtons];
693 933b9805 2020-01-13 rsc b = b&~6 | (b&4)>>1 | (b&2)<<1;
694 933b9805 2020-01-13 rsc b = mouseswap(b);
697 933b9805 2020-01-13 rsc m = [e modifierFlags];
698 933b9805 2020-01-13 rsc if(m & NSEventModifierFlagOption){
699 b1a086de 2020-01-13 rsc gfx_abortcompose(self.client);
702 933b9805 2020-01-13 rsc if(m & NSEventModifierFlagCommand)
705 933b9805 2020-01-13 rsc [self sendmouse:b];
708 933b9805 2020-01-13 rsc - (void)sendmouse:(NSUInteger)b
712 933b9805 2020-01-13 rsc p = [self.window convertPointToBacking:
713 933b9805 2020-01-13 rsc [self.window mouseLocationOutsideOfEventStream]];
714 88ed92aa 2020-01-13 rsc p.y = Dy(self.client->mouserect) - p.y;
715 933b9805 2020-01-13 rsc // LOG(@"(%g, %g) <- sendmouse(%d)", p.x, p.y, (uint)b);
716 b1a086de 2020-01-13 rsc gfx_mousetrack(self.client, p.x, p.y, b, msec());
717 933b9805 2020-01-13 rsc if(b && _lastInputRect.size.width && _lastInputRect.size.height)
718 933b9805 2020-01-13 rsc [self resetLastInputRect];
721 b1a086de 2020-01-13 rsc // rpc_setmouse moves the mouse cursor.
722 b1a086de 2020-01-13 rsc // Called from an RPC thread with no client lock held.
724 b1a086de 2020-01-13 rsc rpc_setmouse(Client *c, Point p)
726 b1a086de 2020-01-13 rsc DrawView *view = (__bridge DrawView*)c->view;
727 b1a086de 2020-01-13 rsc dispatch_async(dispatch_get_main_queue(), ^(void){
728 b1a086de 2020-01-13 rsc [view setmouse:p];
732 41547af3 2020-01-13 rsc - (void)setmouse:(Point)p {
733 b1a086de 2020-01-13 rsc @autoreleasepool{
736 b1a086de 2020-01-13 rsc LOG(@"setmouse(%d,%d)", p.x, p.y);
737 b1a086de 2020-01-13 rsc q = [self.win convertPointFromBacking:NSMakePoint(p.x, p.y)];
738 b1a086de 2020-01-13 rsc LOG(@"(%g, %g) <- fromBacking", q.x, q.y);
739 b1a086de 2020-01-13 rsc q = [self convertPoint:q toView:nil];
740 b1a086de 2020-01-13 rsc LOG(@"(%g, %g) <- toWindow", q.x, q.y);
741 b1a086de 2020-01-13 rsc q = [self.win convertPointToScreen:q];
742 b1a086de 2020-01-13 rsc LOG(@"(%g, %g) <- toScreen", q.x, q.y);
743 b1a086de 2020-01-13 rsc // Quartz has the origin of the "global display
744 b1a086de 2020-01-13 rsc // coordinate space" at the top left of the primary
745 b1a086de 2020-01-13 rsc // screen with y increasing downward, while Cocoa has
746 b1a086de 2020-01-13 rsc // the origin at the bottom left of the primary screen
747 b1a086de 2020-01-13 rsc // with y increasing upward. We flip the coordinate
748 b1a086de 2020-01-13 rsc // with a negative sign and shift upward by the height
749 b1a086de 2020-01-13 rsc // of the primary screen.
750 b1a086de 2020-01-13 rsc q.y = NSScreen.screens[0].frame.size.height - q.y;
751 b1a086de 2020-01-13 rsc LOG(@"(%g, %g) <- setmouse", q.x, q.y);
752 b1a086de 2020-01-13 rsc CGWarpMouseCursorPosition(NSPointToCGPoint(q));
753 b1a086de 2020-01-13 rsc CGAssociateMouseAndMouseCursorPosition(true);
758 b1a086de 2020-01-13 rsc - (void)resetCursorRects {
759 b1a086de 2020-01-13 rsc [super resetCursorRects];
760 b1a086de 2020-01-13 rsc [self addCursorRect:self.bounds cursor:self.currentCursor];
763 933b9805 2020-01-13 rsc // conforms to protocol NSTextInputClient
764 41547af3 2020-01-13 rsc - (BOOL)hasMarkedText { return _markedRange.location != NSNotFound; }
765 41547af3 2020-01-13 rsc - (NSRange)markedRange { return _markedRange; }
766 41547af3 2020-01-13 rsc - (NSRange)selectedRange { return _selectedRange; }
768 933b9805 2020-01-13 rsc - (void)setMarkedText:(id)string
769 933b9805 2020-01-13 rsc selectedRange:(NSRange)sRange
770 933b9805 2020-01-13 rsc replacementRange:(NSRange)rRange
772 933b9805 2020-01-13 rsc NSString *str;
774 933b9805 2020-01-13 rsc LOG(@"setMarkedText: %@ (%ld, %ld) (%ld, %ld)", string,
775 933b9805 2020-01-13 rsc sRange.location, sRange.length,
776 933b9805 2020-01-13 rsc rRange.location, rRange.length);
778 933b9805 2020-01-13 rsc [self clearInput];
780 933b9805 2020-01-13 rsc if([string isKindOfClass:[NSAttributedString class]])
781 933b9805 2020-01-13 rsc str = [string string];
783 933b9805 2020-01-13 rsc str = string;
785 933b9805 2020-01-13 rsc if(rRange.location == NSNotFound){
786 933b9805 2020-01-13 rsc if(_markedRange.location != NSNotFound){
787 933b9805 2020-01-13 rsc rRange = _markedRange;
789 933b9805 2020-01-13 rsc rRange = _selectedRange;
793 933b9805 2020-01-13 rsc if(str.length == 0){
794 933b9805 2020-01-13 rsc [_tmpText deleteCharactersInRange:rRange];
795 933b9805 2020-01-13 rsc [self unmarkText];
797 933b9805 2020-01-13 rsc _markedRange = NSMakeRange(rRange.location, str.length);
798 933b9805 2020-01-13 rsc [_tmpText replaceCharactersInRange:rRange withString:str];
800 933b9805 2020-01-13 rsc _selectedRange.location = rRange.location + sRange.location;
801 933b9805 2020-01-13 rsc _selectedRange.length = sRange.length;
803 933b9805 2020-01-13 rsc if(_tmpText.length){
805 933b9805 2020-01-13 rsc LOG(@"text length %ld", _tmpText.length);
806 933b9805 2020-01-13 rsc for(i = 0; i <= _tmpText.length; ++i){
807 933b9805 2020-01-13 rsc if(i == _markedRange.location)
808 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, '[');
809 933b9805 2020-01-13 rsc if(_selectedRange.length){
810 933b9805 2020-01-13 rsc if(i == _selectedRange.location)
811 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, '{');
812 933b9805 2020-01-13 rsc if(i == NSMaxRange(_selectedRange))
813 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, '}');
815 933b9805 2020-01-13 rsc if(i == NSMaxRange(_markedRange))
816 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, ']');
817 933b9805 2020-01-13 rsc if(i < _tmpText.length)
818 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, [_tmpText characterAtIndex:i]);
821 933b9805 2020-01-13 rsc l = 1 + _tmpText.length - NSMaxRange(_selectedRange)
822 933b9805 2020-01-13 rsc + (_selectedRange.length > 0);
823 933b9805 2020-01-13 rsc LOG(@"move left %d", l);
824 933b9805 2020-01-13 rsc for(i = 0; i < l; ++i)
825 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, Kleft);
828 933b9805 2020-01-13 rsc LOG(@"text: \"%@\" (%ld,%ld) (%ld,%ld)", _tmpText,
829 933b9805 2020-01-13 rsc _markedRange.location, _markedRange.length,
830 933b9805 2020-01-13 rsc _selectedRange.location, _selectedRange.length);
833 41547af3 2020-01-13 rsc - (void)unmarkText {
834 933b9805 2020-01-13 rsc //NSUInteger i;
835 933b9805 2020-01-13 rsc NSUInteger len;
837 933b9805 2020-01-13 rsc LOG(@"unmarkText");
838 933b9805 2020-01-13 rsc len = [_tmpText length];
839 933b9805 2020-01-13 rsc //for(i = 0; i < len; ++i)
840 b1a086de 2020-01-13 rsc // gfx_keystroke(self.client, [_tmpText characterAtIndex:i]);
841 933b9805 2020-01-13 rsc [_tmpText deleteCharactersInRange:NSMakeRange(0, len)];
842 933b9805 2020-01-13 rsc _markedRange = NSMakeRange(NSNotFound, 0);
843 933b9805 2020-01-13 rsc _selectedRange = NSMakeRange(0, 0);
846 41547af3 2020-01-13 rsc - (NSArray<NSAttributedStringKey>*)validAttributesForMarkedText {
847 933b9805 2020-01-13 rsc LOG(@"validAttributesForMarkedText");
851 41547af3 2020-01-13 rsc - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)r
852 933b9805 2020-01-13 rsc actualRange:(NSRangePointer)actualRange
855 933b9805 2020-01-13 rsc NSAttributedString *s;
857 933b9805 2020-01-13 rsc LOG(@"attributedSubstringForProposedRange: (%ld, %ld) (%ld, %ld)",
858 933b9805 2020-01-13 rsc r.location, r.length, actualRange->location, actualRange->length);
859 933b9805 2020-01-13 rsc sr = NSMakeRange(0, [_tmpText length]);
860 933b9805 2020-01-13 rsc sr = NSIntersectionRange(sr, r);
861 933b9805 2020-01-13 rsc if(actualRange)
862 933b9805 2020-01-13 rsc *actualRange = sr;
863 933b9805 2020-01-13 rsc LOG(@"use range: %ld, %ld", sr.location, sr.length);
865 933b9805 2020-01-13 rsc if(sr.length)
866 933b9805 2020-01-13 rsc s = [[NSAttributedString alloc]
867 933b9805 2020-01-13 rsc initWithString:[_tmpText substringWithRange:sr]];
868 933b9805 2020-01-13 rsc LOG(@" return %@", s);
872 41547af3 2020-01-13 rsc - (void)insertText:(id)s replacementRange:(NSRange)r {
873 933b9805 2020-01-13 rsc NSUInteger i;
874 933b9805 2020-01-13 rsc NSUInteger len;
876 933b9805 2020-01-13 rsc LOG(@"insertText: %@ replacementRange: %ld, %ld", s, r.location, r.length);
878 933b9805 2020-01-13 rsc [self clearInput];
880 933b9805 2020-01-13 rsc len = [s length];
881 933b9805 2020-01-13 rsc for(i = 0; i < len; ++i)
882 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, [s characterAtIndex:i]);
883 933b9805 2020-01-13 rsc [_tmpText deleteCharactersInRange:NSMakeRange(0, _tmpText.length)];
884 933b9805 2020-01-13 rsc _markedRange = NSMakeRange(NSNotFound, 0);
885 933b9805 2020-01-13 rsc _selectedRange = NSMakeRange(0, 0);
888 933b9805 2020-01-13 rsc - (NSUInteger)characterIndexForPoint:(NSPoint)point
890 933b9805 2020-01-13 rsc LOG(@"characterIndexForPoint: %g, %g", point.x, point.y);
894 41547af3 2020-01-13 rsc - (NSRect)firstRectForCharacterRange:(NSRange)r actualRange:(NSRangePointer)actualRange {
895 933b9805 2020-01-13 rsc LOG(@"firstRectForCharacterRange: (%ld, %ld) (%ld, %ld)",
896 933b9805 2020-01-13 rsc r.location, r.length, actualRange->location, actualRange->length);
897 933b9805 2020-01-13 rsc if(actualRange)
898 933b9805 2020-01-13 rsc *actualRange = r;
899 933b9805 2020-01-13 rsc return [[self window] convertRectToScreen:_lastInputRect];
902 41547af3 2020-01-13 rsc - (void)doCommandBySelector:(SEL)s {
904 933b9805 2020-01-13 rsc NSEventModifierFlags m;
907 933b9805 2020-01-13 rsc LOG(@"doCommandBySelector (%@)", NSStringFromSelector(s));
909 933b9805 2020-01-13 rsc e = [NSApp currentEvent];
910 933b9805 2020-01-13 rsc c = [[e characters] characterAtIndex:0];
911 933b9805 2020-01-13 rsc k = keycvt(c);
912 933b9805 2020-01-13 rsc LOG(@"keyDown: character0: 0x%x -> 0x%x", c, k);
913 933b9805 2020-01-13 rsc m = [e modifierFlags];
915 933b9805 2020-01-13 rsc if(m & NSEventModifierFlagCommand){
916 933b9805 2020-01-13 rsc if((m & NSEventModifierFlagShift) && 'a' <= k && k <= 'z')
917 933b9805 2020-01-13 rsc k += 'A' - 'a';
918 933b9805 2020-01-13 rsc if(' '<=k && k<='~')
922 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, k);
925 933b9805 2020-01-13 rsc // Helper for managing input rect approximately
926 41547af3 2020-01-13 rsc - (void)resetLastInputRect {
927 933b9805 2020-01-13 rsc LOG(@"resetLastInputRect");
928 933b9805 2020-01-13 rsc _lastInputRect.origin.x = 0.0;
929 933b9805 2020-01-13 rsc _lastInputRect.origin.y = 0.0;
930 933b9805 2020-01-13 rsc _lastInputRect.size.width = 0.0;
931 933b9805 2020-01-13 rsc _lastInputRect.size.height = 0.0;
934 41547af3 2020-01-13 rsc - (void)enlargeLastInputRect:(NSRect)r {
935 933b9805 2020-01-13 rsc r.origin.y = [self bounds].size.height - r.origin.y - r.size.height;
936 933b9805 2020-01-13 rsc _lastInputRect = NSUnionRect(_lastInputRect, r);
937 933b9805 2020-01-13 rsc LOG(@"update last input rect (%g, %g, %g, %g)",
938 933b9805 2020-01-13 rsc _lastInputRect.origin.x, _lastInputRect.origin.y,
939 933b9805 2020-01-13 rsc _lastInputRect.size.width, _lastInputRect.size.height);
942 41547af3 2020-01-13 rsc - (void)clearInput {
943 933b9805 2020-01-13 rsc if(_tmpText.length){
946 933b9805 2020-01-13 rsc l = 1 + _tmpText.length - NSMaxRange(_selectedRange)
947 933b9805 2020-01-13 rsc + (_selectedRange.length > 0);
948 933b9805 2020-01-13 rsc LOG(@"move right %d", l);
949 933b9805 2020-01-13 rsc for(i = 0; i < l; ++i)
950 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, Kright);
951 933b9805 2020-01-13 rsc l = _tmpText.length+2+2*(_selectedRange.length > 0);
952 933b9805 2020-01-13 rsc LOG(@"backspace %d", l);
953 933b9805 2020-01-13 rsc for(uint i = 0; i < l; ++i)
954 b1a086de 2020-01-13 rsc gfx_keystroke(self.client, Kbs);
958 b741db60 2020-01-14 rsc - (NSApplicationPresentationOptions)window:(id)arg
959 b741db60 2020-01-14 rsc willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions {
960 4c548931 2020-01-14 rsc // The default for full-screen is to auto-hide the dock and menu bar,
961 4c548931 2020-01-14 rsc // but the menu bar in particular comes back when the cursor is just
962 4c548931 2020-01-14 rsc // near the top of the screen, which makes acme's top tag line very difficult to use.
963 4c548931 2020-01-14 rsc // Disable the menu bar entirely.
964 4c548931 2020-01-14 rsc // In theory this code disables the dock entirely too, but if you drag the mouse
965 4c548931 2020-01-14 rsc // down far enough off the bottom of the screen the dock still unhides.
966 4c548931 2020-01-14 rsc // That's OK.
967 b741db60 2020-01-14 rsc NSApplicationPresentationOptions o;
968 b741db60 2020-01-14 rsc o = proposedOptions;
969 b741db60 2020-01-14 rsc o &= ~(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar);
970 b741db60 2020-01-14 rsc o |= NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar;
974 3d1382b9 2020-01-14 rsc - (void)windowWillEnterFullScreen:(NSNotification*)notification {
975 4c548931 2020-01-14 rsc // This is a heavier-weight way to make sure the menu bar and dock go away,
976 4c548931 2020-01-14 rsc // but this affects all screens even though the app is running on full screen
977 4c548931 2020-01-14 rsc // on only one screen, so it's not great. The behavior from the
978 4c548931 2020-01-14 rsc // willUseFullScreenPresentationOptions seems to be enough for now.
980 3d1382b9 2020-01-14 rsc [[NSApplication sharedApplication]
981 3d1382b9 2020-01-14 rsc setPresentationOptions:NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock];
985 3d1382b9 2020-01-14 rsc - (void)windowDidExitFullScreen:(NSNotification*)notification {
987 3d1382b9 2020-01-14 rsc [[NSApplication sharedApplication]
988 3d1382b9 2020-01-14 rsc setPresentationOptions:NSApplicationPresentationDefault];
996 933b9805 2020-01-13 rsc return nsec()/1000000;
1000 933b9805 2020-01-13 rsc keycvt(uint code)
1002 933b9805 2020-01-13 rsc switch(code){
1003 933b9805 2020-01-13 rsc case '\r': return '\n';
1004 933b9805 2020-01-13 rsc case 127: return '\b';
1005 933b9805 2020-01-13 rsc case NSUpArrowFunctionKey: return Kup;
1006 933b9805 2020-01-13 rsc case NSDownArrowFunctionKey: return Kdown;
1007 933b9805 2020-01-13 rsc case NSLeftArrowFunctionKey: return Kleft;
1008 933b9805 2020-01-13 rsc case NSRightArrowFunctionKey: return Kright;
1009 933b9805 2020-01-13 rsc case NSInsertFunctionKey: return Kins;
1010 933b9805 2020-01-13 rsc case NSDeleteFunctionKey: return Kdel;
1011 933b9805 2020-01-13 rsc case NSHomeFunctionKey: return Khome;
1012 933b9805 2020-01-13 rsc case NSEndFunctionKey: return Kend;
1013 933b9805 2020-01-13 rsc case NSPageUpFunctionKey: return Kpgup;
1014 933b9805 2020-01-13 rsc case NSPageDownFunctionKey: return Kpgdown;
1015 933b9805 2020-01-13 rsc case NSF1FunctionKey: return KF|1;
1016 933b9805 2020-01-13 rsc case NSF2FunctionKey: return KF|2;
1017 933b9805 2020-01-13 rsc case NSF3FunctionKey: return KF|3;
1018 933b9805 2020-01-13 rsc case NSF4FunctionKey: return KF|4;
1019 933b9805 2020-01-13 rsc case NSF5FunctionKey: return KF|5;
1020 933b9805 2020-01-13 rsc case NSF6FunctionKey: return KF|6;
1021 933b9805 2020-01-13 rsc case NSF7FunctionKey: return KF|7;
1022 933b9805 2020-01-13 rsc case NSF8FunctionKey: return KF|8;
1023 933b9805 2020-01-13 rsc case NSF9FunctionKey: return KF|9;
1024 933b9805 2020-01-13 rsc case NSF10FunctionKey: return KF|10;
1025 933b9805 2020-01-13 rsc case NSF11FunctionKey: return KF|11;
1026 933b9805 2020-01-13 rsc case NSF12FunctionKey: return KF|12;
1027 933b9805 2020-01-13 rsc case NSBeginFunctionKey:
1028 933b9805 2020-01-13 rsc case NSPrintScreenFunctionKey:
1029 933b9805 2020-01-13 rsc case NSScrollLockFunctionKey:
1030 933b9805 2020-01-13 rsc case NSF13FunctionKey:
1031 933b9805 2020-01-13 rsc case NSF14FunctionKey:
1032 933b9805 2020-01-13 rsc case NSF15FunctionKey:
1033 933b9805 2020-01-13 rsc case NSF16FunctionKey:
1034 933b9805 2020-01-13 rsc case NSF17FunctionKey:
1035 933b9805 2020-01-13 rsc case NSF18FunctionKey:
1036 933b9805 2020-01-13 rsc case NSF19FunctionKey:
1037 933b9805 2020-01-13 rsc case NSF20FunctionKey:
1038 933b9805 2020-01-13 rsc case NSF21FunctionKey:
1039 933b9805 2020-01-13 rsc case NSF22FunctionKey:
1040 933b9805 2020-01-13 rsc case NSF23FunctionKey:
1041 933b9805 2020-01-13 rsc case NSF24FunctionKey:
1042 933b9805 2020-01-13 rsc case NSF25FunctionKey:
1043 933b9805 2020-01-13 rsc case NSF26FunctionKey:
1044 933b9805 2020-01-13 rsc case NSF27FunctionKey:
1045 933b9805 2020-01-13 rsc case NSF28FunctionKey:
1046 933b9805 2020-01-13 rsc case NSF29FunctionKey:
1047 933b9805 2020-01-13 rsc case NSF30FunctionKey:
1048 933b9805 2020-01-13 rsc case NSF31FunctionKey:
1049 933b9805 2020-01-13 rsc case NSF32FunctionKey:
1050 933b9805 2020-01-13 rsc case NSF33FunctionKey:
1051 933b9805 2020-01-13 rsc case NSF34FunctionKey:
1052 933b9805 2020-01-13 rsc case NSF35FunctionKey:
1053 933b9805 2020-01-13 rsc case NSPauseFunctionKey:
1054 933b9805 2020-01-13 rsc case NSSysReqFunctionKey:
1055 933b9805 2020-01-13 rsc case NSBreakFunctionKey:
1056 933b9805 2020-01-13 rsc case NSResetFunctionKey:
1057 933b9805 2020-01-13 rsc case NSStopFunctionKey:
1058 933b9805 2020-01-13 rsc case NSMenuFunctionKey:
1059 933b9805 2020-01-13 rsc case NSUserFunctionKey:
1060 933b9805 2020-01-13 rsc case NSSystemFunctionKey:
1061 933b9805 2020-01-13 rsc case NSPrintFunctionKey:
1062 933b9805 2020-01-13 rsc case NSClearLineFunctionKey:
1063 933b9805 2020-01-13 rsc case NSClearDisplayFunctionKey:
1064 933b9805 2020-01-13 rsc case NSInsertLineFunctionKey:
1065 933b9805 2020-01-13 rsc case NSDeleteLineFunctionKey:
1066 933b9805 2020-01-13 rsc case NSInsertCharFunctionKey:
1067 933b9805 2020-01-13 rsc case NSDeleteCharFunctionKey:
1068 933b9805 2020-01-13 rsc case NSPrevFunctionKey:
1069 933b9805 2020-01-13 rsc case NSNextFunctionKey:
1070 933b9805 2020-01-13 rsc case NSSelectFunctionKey:
1071 933b9805 2020-01-13 rsc case NSExecuteFunctionKey:
1072 933b9805 2020-01-13 rsc case NSUndoFunctionKey:
1073 933b9805 2020-01-13 rsc case NSRedoFunctionKey:
1074 933b9805 2020-01-13 rsc case NSFindFunctionKey:
1075 933b9805 2020-01-13 rsc case NSHelpFunctionKey:
1076 933b9805 2020-01-13 rsc case NSModeSwitchFunctionKey: return 0;
1077 933b9805 2020-01-13 rsc default: return code;
1081 41547af3 2020-01-13 rsc // rpc_getsnarf reads the current pasteboard as a plain text string.
1082 41547af3 2020-01-13 rsc // Called from an RPC thread with no client lock held.
1084 b1a086de 2020-01-13 rsc rpc_getsnarf(void)
1086 41547af3 2020-01-13 rsc char __block *ret;
1089 41547af3 2020-01-13 rsc dispatch_sync(dispatch_get_main_queue(), ^(void) {
1090 41547af3 2020-01-13 rsc @autoreleasepool {
1091 41547af3 2020-01-13 rsc NSPasteboard *pb = [NSPasteboard generalPasteboard];
1092 41547af3 2020-01-13 rsc NSString *s = [pb stringForType:NSPasteboardTypeString];
1094 41547af3 2020-01-13 rsc ret = strdup((char*)[s UTF8String]);
1097 41547af3 2020-01-13 rsc return ret;
1100 41547af3 2020-01-13 rsc // rpc_putsnarf writes the given text to the pasteboard.
1101 41547af3 2020-01-13 rsc // Called from an RPC thread with no client lock held.
1103 b1a086de 2020-01-13 rsc rpc_putsnarf(char *s)
1105 41547af3 2020-01-13 rsc if(s == nil || strlen(s) >= SnarfSize)
1108 41547af3 2020-01-13 rsc dispatch_sync(dispatch_get_main_queue(), ^(void) {
1109 41547af3 2020-01-13 rsc @autoreleasepool{
1110 41547af3 2020-01-13 rsc NSArray *t = [NSArray arrayWithObject:NSPasteboardTypeString];
1111 41547af3 2020-01-13 rsc NSPasteboard *pb = [NSPasteboard generalPasteboard];
1112 41547af3 2020-01-13 rsc NSString *str = [[NSString alloc] initWithUTF8String:s];
1113 41547af3 2020-01-13 rsc [pb declareTypes:t owner:nil];
1114 41547af3 2020-01-13 rsc [pb setString:str forType:NSPasteboardTypeString];
1119 50923426 2020-01-13 rsc // rpc_bouncemouse is for sending a mouse event
1120 50923426 2020-01-13 rsc // back to the X11 window manager rio(1).
1121 50923426 2020-01-13 rsc // Does not apply here.
1122 94d381ec 2020-05-18 rsc static void
1123 50923426 2020-01-13 rsc rpc_bouncemouse(Client *c, Mouse m)
1127 50923426 2020-01-13 rsc // We don't use the graphics thread state during memimagedraw,
1128 50923426 2020-01-13 rsc // so rpc_gfxdrawlock and rpc_gfxdrawunlock are no-ops.
1130 50923426 2020-01-13 rsc rpc_gfxdrawlock(void)
1135 50923426 2020-01-13 rsc rpc_gfxdrawunlock(void)
1139 933b9805 2020-01-13 rsc static void
1140 933b9805 2020-01-13 rsc setprocname(const char *s)
1142 933b9805 2020-01-13 rsc CFStringRef process_name;
1144 933b9805 2020-01-13 rsc process_name = CFStringCreateWithBytes(nil, (uchar*)s, strlen(s), kCFStringEncodingUTF8, false);
1146 933b9805 2020-01-13 rsc // Adapted from Chrome's mac_util.mm.
1147 933b9805 2020-01-13 rsc // http://src.chromium.org/viewvc/chrome/trunk/src/base/mac/mac_util.mm
1149 933b9805 2020-01-13 rsc // Copyright (c) 2012 The Chromium Authors. All rights reserved.
1151 933b9805 2020-01-13 rsc // Redistribution and use in source and binary forms, with or without
1152 933b9805 2020-01-13 rsc // modification, are permitted provided that the following conditions are
1155 933b9805 2020-01-13 rsc // * Redistributions of source code must retain the above copyright
1156 933b9805 2020-01-13 rsc // notice, this list of conditions and the following disclaimer.
1157 933b9805 2020-01-13 rsc // * Redistributions in binary form must reproduce the above
1158 933b9805 2020-01-13 rsc // copyright notice, this list of conditions and the following disclaimer
1159 933b9805 2020-01-13 rsc // in the documentation and/or other materials provided with the
1160 933b9805 2020-01-13 rsc // distribution.
1161 933b9805 2020-01-13 rsc // * Neither the name of Google Inc. nor the names of its
1162 933b9805 2020-01-13 rsc // contributors may be used to endorse or promote products derived from
1163 933b9805 2020-01-13 rsc // this software without specific prior written permission.
1165 933b9805 2020-01-13 rsc // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1166 933b9805 2020-01-13 rsc // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1167 933b9805 2020-01-13 rsc // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1168 933b9805 2020-01-13 rsc // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1169 933b9805 2020-01-13 rsc // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1170 933b9805 2020-01-13 rsc // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1171 933b9805 2020-01-13 rsc // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1172 933b9805 2020-01-13 rsc // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1173 933b9805 2020-01-13 rsc // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1174 933b9805 2020-01-13 rsc // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1175 933b9805 2020-01-13 rsc // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1176 933b9805 2020-01-13 rsc // Warning: here be dragons! This is SPI reverse-engineered from WebKit's
1177 933b9805 2020-01-13 rsc // plugin host, and could break at any time (although realistically it's only
1178 933b9805 2020-01-13 rsc // likely to break in a new major release).
1179 933b9805 2020-01-13 rsc // When 10.7 is available, check that this still works, and update this
1180 933b9805 2020-01-13 rsc // comment for 10.8.
1182 933b9805 2020-01-13 rsc // Private CFType used in these LaunchServices calls.
1183 933b9805 2020-01-13 rsc typedef CFTypeRef PrivateLSASN;
1184 933b9805 2020-01-13 rsc typedef PrivateLSASN (*LSGetCurrentApplicationASNType)();
1185 933b9805 2020-01-13 rsc typedef OSStatus (*LSSetApplicationInformationItemType)(int, PrivateLSASN,
1186 933b9805 2020-01-13 rsc CFStringRef,
1187 933b9805 2020-01-13 rsc CFStringRef,
1188 933b9805 2020-01-13 rsc CFDictionaryRef*);
1190 933b9805 2020-01-13 rsc static LSGetCurrentApplicationASNType ls_get_current_application_asn_func =
1192 933b9805 2020-01-13 rsc static LSSetApplicationInformationItemType
1193 933b9805 2020-01-13 rsc ls_set_application_information_item_func = NULL;
1194 933b9805 2020-01-13 rsc static CFStringRef ls_display_name_key = NULL;
1196 933b9805 2020-01-13 rsc static bool did_symbol_lookup = false;
1197 933b9805 2020-01-13 rsc if (!did_symbol_lookup) {
1198 933b9805 2020-01-13 rsc did_symbol_lookup = true;
1199 933b9805 2020-01-13 rsc CFBundleRef launch_services_bundle =
1200 933b9805 2020-01-13 rsc CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
1201 933b9805 2020-01-13 rsc if (!launch_services_bundle) {
1202 933b9805 2020-01-13 rsc fprint(2, "Failed to look up LaunchServices bundle\n");
1206 933b9805 2020-01-13 rsc ls_get_current_application_asn_func =
1207 933b9805 2020-01-13 rsc (LSGetCurrentApplicationASNType)(
1208 933b9805 2020-01-13 rsc CFBundleGetFunctionPointerForName(
1209 933b9805 2020-01-13 rsc launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN")));
1210 933b9805 2020-01-13 rsc if (!ls_get_current_application_asn_func)
1211 933b9805 2020-01-13 rsc fprint(2, "Could not find _LSGetCurrentApplicationASN\n");
1213 933b9805 2020-01-13 rsc ls_set_application_information_item_func =
1214 933b9805 2020-01-13 rsc (LSSetApplicationInformationItemType)(
1215 933b9805 2020-01-13 rsc CFBundleGetFunctionPointerForName(
1216 933b9805 2020-01-13 rsc launch_services_bundle,
1217 933b9805 2020-01-13 rsc CFSTR("_LSSetApplicationInformationItem")));
1218 933b9805 2020-01-13 rsc if (!ls_set_application_information_item_func)
1219 933b9805 2020-01-13 rsc fprint(2, "Could not find _LSSetApplicationInformationItem\n");
1221 933b9805 2020-01-13 rsc CFStringRef* key_pointer = (CFStringRef*)(
1222 933b9805 2020-01-13 rsc CFBundleGetDataPointerForName(launch_services_bundle,
1223 933b9805 2020-01-13 rsc CFSTR("_kLSDisplayNameKey")));
1224 933b9805 2020-01-13 rsc ls_display_name_key = key_pointer ? *key_pointer : NULL;
1225 933b9805 2020-01-13 rsc if (!ls_display_name_key)
1226 933b9805 2020-01-13 rsc fprint(2, "Could not find _kLSDisplayNameKey\n");
1228 933b9805 2020-01-13 rsc // Internally, this call relies on the Mach ports that are started up by the
1229 933b9805 2020-01-13 rsc // Carbon Process Manager. In debug builds this usually happens due to how
1230 933b9805 2020-01-13 rsc // the logging layers are started up; but in release, it isn't started in as
1231 933b9805 2020-01-13 rsc // much of a defined order. So if the symbols had to be loaded, go ahead
1232 933b9805 2020-01-13 rsc // and force a call to make sure the manager has been initialized and hence
1233 933b9805 2020-01-13 rsc // the ports are opened.
1234 933b9805 2020-01-13 rsc ProcessSerialNumber psn;
1235 933b9805 2020-01-13 rsc GetCurrentProcess(&psn);
1237 933b9805 2020-01-13 rsc if (!ls_get_current_application_asn_func ||
1238 933b9805 2020-01-13 rsc !ls_set_application_information_item_func ||
1239 933b9805 2020-01-13 rsc !ls_display_name_key) {
1243 933b9805 2020-01-13 rsc PrivateLSASN asn = ls_get_current_application_asn_func();
1244 933b9805 2020-01-13 rsc // Constant used by WebKit; what exactly it means is unknown.
1245 933b9805 2020-01-13 rsc const int magic_session_constant = -2;
1246 933b9805 2020-01-13 rsc OSErr err =
1247 933b9805 2020-01-13 rsc ls_set_application_information_item_func(magic_session_constant, asn,
1248 933b9805 2020-01-13 rsc ls_display_name_key,
1249 933b9805 2020-01-13 rsc process_name,
1250 933b9805 2020-01-13 rsc NULL /* optional out param */);
1251 933b9805 2020-01-13 rsc if(err != noErr)
1252 933b9805 2020-01-13 rsc fprint(2, "Call to set process name failed\n");