2011-09-06 10:10:43 -04:00
|
|
|
/*
|
|
|
|
|
* Cocoa's event loop must be in the main thread.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define Point OSXPoint
|
|
|
|
|
#define Rect OSXRect
|
|
|
|
|
#define Cursor OSXCursor
|
|
|
|
|
|
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
|
|
|
|
|
|
#undef Rect
|
|
|
|
|
#undef Point
|
|
|
|
|
#undef Cursor
|
|
|
|
|
|
|
|
|
|
#include <u.h>
|
|
|
|
|
#include <libc.h>
|
2011-09-19 08:58:59 -04:00
|
|
|
#include "cocoa-thread.h" // try libthread when possible
|
2011-09-06 10:10:43 -04:00
|
|
|
#include <draw.h>
|
|
|
|
|
#include <memdraw.h>
|
|
|
|
|
#include <keyboard.h>
|
|
|
|
|
#include <cursor.h>
|
|
|
|
|
#include "cocoa-screen.h"
|
|
|
|
|
#include "osx-keycodes.h"
|
|
|
|
|
#include "devdraw.h"
|
|
|
|
|
#include "glendapng.h"
|
|
|
|
|
|
|
|
|
|
AUTOFRAMEWORK(Cocoa)
|
|
|
|
|
|
|
|
|
|
#define panic sysfatal
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
/*
|
|
|
|
|
* Incompatible with Magic Mouse?
|
|
|
|
|
*/
|
|
|
|
|
int reimplementswipe = 0;
|
|
|
|
|
int usecopygesture = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
int useoldfullscreen = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
usage(void)
|
|
|
|
|
{
|
|
|
|
|
fprint(2, "usage: devdraw (don't run directly)\n");
|
|
|
|
|
exits("usage");
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
@interface appdelegate : NSObject
|
|
|
|
|
@end
|
|
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
void
|
|
|
|
|
main(int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Move the protocol off stdin/stdout so that
|
|
|
|
|
* any inadvertent prints don't screw things up.
|
|
|
|
|
*/
|
|
|
|
|
dup(0,3);
|
|
|
|
|
dup(1,4);
|
|
|
|
|
close(0);
|
|
|
|
|
close(1);
|
|
|
|
|
open("/dev/null", OREAD);
|
|
|
|
|
open("/dev/null", OWRITE);
|
|
|
|
|
|
2011-09-26 08:19:56 -07:00
|
|
|
// Libdraw doesn't permit arguments currently.
|
2011-09-19 08:58:59 -04:00
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
ARGBEGIN{
|
2011-09-19 08:58:59 -04:00
|
|
|
case 'D': // only for good ps -a listings
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
usage();
|
|
|
|
|
}ARGEND
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(usecopygesture)
|
|
|
|
|
reimplementswipe = 1;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
if(OSX_VERSION < 100700)
|
|
|
|
|
[NSAutoreleasePool new];
|
|
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
[NSApplication sharedApplication];
|
|
|
|
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
|
|
|
[NSApp setDelegate:[appdelegate new]];
|
|
|
|
|
[NSApp activateIgnoringOtherApps:YES];
|
|
|
|
|
[NSApp run];
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
struct {
|
2011-09-26 08:19:56 -07:00
|
|
|
NSWindow *std;
|
2011-10-03 18:16:09 -04:00
|
|
|
NSWindow *ofs; /* old fullscreen */
|
2011-09-19 08:58:59 -04:00
|
|
|
NSWindow *p;
|
|
|
|
|
NSView *content;
|
|
|
|
|
Cursor *cursor;
|
|
|
|
|
char *rectstr;
|
|
|
|
|
NSBitmapImageRep *img;
|
|
|
|
|
NSRect flushrect;
|
|
|
|
|
int needflush;
|
|
|
|
|
} win;
|
|
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
static void autohide(int);
|
2011-09-19 08:58:59 -04:00
|
|
|
static void drawimg(void);
|
|
|
|
|
static void flushwin(void);
|
2011-09-06 10:10:43 -04:00
|
|
|
static void getmousepos(void);
|
2011-09-19 08:58:59 -04:00
|
|
|
static void makeicon(void);
|
|
|
|
|
static void makemenu(void);
|
|
|
|
|
static void makewin(void);
|
|
|
|
|
static void resize(void);
|
2011-10-03 18:16:09 -04:00
|
|
|
static void sendmouse(void);
|
2011-09-19 08:58:59 -04:00
|
|
|
static void setcursor0(void);
|
2011-09-26 08:19:56 -07:00
|
|
|
static void togglefs(void);
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
@implementation appdelegate
|
|
|
|
|
- (void)applicationDidFinishLaunching:(id)arg
|
|
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
makeicon();
|
|
|
|
|
makemenu();
|
|
|
|
|
[NSApplication
|
|
|
|
|
detachDrawingThread:@selector(callservep9p:)
|
|
|
|
|
toTarget:[self class] withObject:nil];
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)windowDidBecomeKey:(id)arg
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
getmousepos();
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
- (void)windowDidResize:(id)arg
|
|
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
getmousepos();
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-19 08:58:59 -04:00
|
|
|
|
|
|
|
|
if([win.p inLiveResize])
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
resize();
|
|
|
|
|
}
|
|
|
|
|
- (void)windowDidEndLiveResize:(id)arg
|
|
|
|
|
{
|
|
|
|
|
resize();
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)windowDidDeminiaturize:(id)arg
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
resize();
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-26 08:19:56 -07:00
|
|
|
- (void)windowDidChangeScreenProfile:(id)arg
|
|
|
|
|
{
|
|
|
|
|
resize();
|
|
|
|
|
}
|
|
|
|
|
- (void)windowDidChangeScreen:(id)arg
|
|
|
|
|
{
|
2011-10-03 18:16:09 -04:00
|
|
|
if(win.p == win.ofs)
|
|
|
|
|
autohide(1);
|
2011-09-26 08:19:56 -07:00
|
|
|
[win.ofs setFrame:[[win.p screen] frame] display:YES];
|
|
|
|
|
resize();
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(id)arg
|
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
+ (void)callservep9p:(id)arg
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
|
|
|
|
servep9p();
|
|
|
|
|
[NSApp terminate:self];
|
|
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
+ (void)calldrawimg:(id)arg{ drawimg();}
|
|
|
|
|
+ (void)callflushwin:(id)arg{ flushwin();}
|
|
|
|
|
+ (void)callmakewin:(id)arg{ makewin();}
|
|
|
|
|
+ (void)callsetcursor0:(id)arg{ setcursor0();}
|
2011-09-26 08:19:56 -07:00
|
|
|
- (void)calltogglefs:(id)arg{ togglefs();}
|
2011-09-06 10:10:43 -04:00
|
|
|
@end
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static Memimage* makeimg(void);
|
|
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
Memimage*
|
|
|
|
|
attachscreen(char *label, char *winsize)
|
|
|
|
|
{
|
|
|
|
|
static int first = 1;
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(first)
|
|
|
|
|
first = 0;
|
|
|
|
|
else
|
2011-09-06 10:10:43 -04:00
|
|
|
panic("attachscreen called twice");
|
|
|
|
|
|
|
|
|
|
if(label == nil)
|
|
|
|
|
label = "gnot a label";
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
win.rectstr = strdup(winsize);
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
// Create window in main thread,
|
|
|
|
|
// else no cursor change when resizing.
|
2011-09-06 10:10:43 -04:00
|
|
|
[appdelegate
|
|
|
|
|
performSelectorOnMainThread:@selector(callmakewin:)
|
|
|
|
|
withObject:nil
|
|
|
|
|
waitUntilDone:YES];
|
|
|
|
|
// makewin();
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
kicklabel(label);
|
|
|
|
|
return makeimg();
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
@interface appview : NSView
|
|
|
|
|
@end
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
@interface appwin : NSWindow
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation appwin
|
|
|
|
|
- (NSTimeInterval)animationResizeTime:(NSRect)r
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-26 08:19:56 -07:00
|
|
|
- (BOOL)canBecomeKeyWindow
|
|
|
|
|
{
|
2011-10-03 18:16:09 -04:00
|
|
|
// just keyboard? or all inputs?
|
2011-09-26 08:19:56 -07:00
|
|
|
return YES; // else no keyboard focus with NSBorderlessWindowMask
|
|
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
@end
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
Winstyle = NSTitledWindowMask
|
|
|
|
|
| NSClosableWindowMask
|
|
|
|
|
| NSMiniaturizableWindowMask
|
|
|
|
|
| NSResizableWindowMask
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
makewin(void)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
|
|
|
|
NSRect r, sr;
|
|
|
|
|
Rectangle wr;
|
2011-09-19 08:58:59 -04:00
|
|
|
char *s;
|
|
|
|
|
int set;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
s = win.rectstr;
|
2011-09-26 08:19:56 -07:00
|
|
|
sr = [[NSScreen mainScreen] frame];
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
if(s && *s){
|
2011-09-19 08:58:59 -04:00
|
|
|
if(parsewinsize(s, &wr, &set) < 0)
|
2011-09-06 10:10:43 -04:00
|
|
|
sysfatal("%r");
|
|
|
|
|
}else{
|
|
|
|
|
wr = Rect(0, 0, sr.size.width*2/3, sr.size.height*2/3);
|
2011-09-19 08:58:59 -04:00
|
|
|
set = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
// The origin is the left-bottom corner with Cocoa.
|
|
|
|
|
r = NSMakeRect(wr.min.x, r.size.height-wr.min.y, Dx(wr), Dy(wr));
|
|
|
|
|
|
2011-09-26 08:19:56 -07:00
|
|
|
win.std = [[appwin alloc]
|
2011-09-06 10:10:43 -04:00
|
|
|
initWithContentRect:r
|
2011-09-19 08:58:59 -04:00
|
|
|
styleMask:Winstyle
|
2011-09-26 08:19:56 -07:00
|
|
|
backing:NSBackingStoreBuffered defer:NO];
|
2011-09-19 08:58:59 -04:00
|
|
|
if(!set)
|
2011-09-26 08:19:56 -07:00
|
|
|
[win.std center];
|
2011-09-06 10:10:43 -04:00
|
|
|
#if OSX_VERSION >= 100700
|
2011-09-26 08:19:56 -07:00
|
|
|
[win.std setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
2011-09-06 10:10:43 -04:00
|
|
|
#endif
|
2011-09-26 08:19:56 -07:00
|
|
|
[win.std setMinSize:NSMakeSize(128,128)];
|
|
|
|
|
[win.std setAcceptsMouseMovedEvents:YES];
|
|
|
|
|
[win.std setDelegate:[NSApp delegate]];
|
|
|
|
|
|
|
|
|
|
win.ofs = [[appwin alloc]
|
|
|
|
|
initWithContentRect:sr
|
|
|
|
|
styleMask:NSBorderlessWindowMask
|
|
|
|
|
backing:NSBackingStoreBuffered defer:NO];
|
|
|
|
|
[win.ofs setAcceptsMouseMovedEvents:YES];
|
|
|
|
|
[win.ofs setDelegate:[NSApp delegate]];
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-26 08:19:56 -07:00
|
|
|
win.content = [appview new];
|
|
|
|
|
[win.content setAcceptsTouchEvents:YES];
|
|
|
|
|
win.p = win.std;
|
|
|
|
|
[win.p setContentView:win.content];
|
|
|
|
|
[win.p makeKeyAndOrderFront:nil];
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
// explain the bottom-corner bug here (osx-screen-carbon.m:/^eresized)
|
2011-09-19 08:58:59 -04:00
|
|
|
static Memimage*
|
|
|
|
|
makeimg(void)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
|
|
|
|
static int first = 1;
|
2011-09-19 08:58:59 -04:00
|
|
|
Memimage *m;
|
2011-09-06 10:10:43 -04:00
|
|
|
NSSize size;
|
|
|
|
|
Rectangle r;
|
2011-09-19 08:58:59 -04:00
|
|
|
uint ch;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(first){
|
2011-09-06 10:10:43 -04:00
|
|
|
memimageinit();
|
2011-09-19 08:58:59 -04:00
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
size = [win.content bounds].size;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(size.width<=0 || size.height<=0){
|
|
|
|
|
NSLog(@"bad content size: %.0f %.0f", size.width, size.height);
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
r = Rect(0, 0, size.width, size.height);
|
|
|
|
|
ch = XBGR32;
|
|
|
|
|
m = allocmemimage(r, ch);
|
|
|
|
|
if(m == nil)
|
|
|
|
|
panic("allocmemimage: %r");
|
|
|
|
|
if(m->data == nil)
|
|
|
|
|
panic("m->data == nil");
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(win.img)
|
|
|
|
|
[win.img release];
|
|
|
|
|
win.img = [[NSBitmapImageRep alloc]
|
|
|
|
|
initWithBitmapDataPlanes:&m->data->bdata
|
|
|
|
|
pixelsWide:Dx(r)
|
|
|
|
|
pixelsHigh:Dy(r)
|
|
|
|
|
bitsPerSample:8
|
|
|
|
|
samplesPerPixel:4
|
|
|
|
|
hasAlpha:YES
|
|
|
|
|
isPlanar:NO
|
|
|
|
|
colorSpaceName:NSDeviceRGBColorSpace
|
|
|
|
|
bytesPerRow:bytesperline(r, 32)
|
|
|
|
|
bitsPerPixel:32];
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
_drawreplacescreenimage(m);
|
|
|
|
|
return m;
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static void
|
|
|
|
|
resize(void)
|
|
|
|
|
{
|
|
|
|
|
makeimg();
|
2011-10-03 18:16:09 -04:00
|
|
|
|
|
|
|
|
mouseresized = 1;
|
|
|
|
|
sendmouse();
|
2011-09-19 08:58:59 -04:00
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
void
|
|
|
|
|
_flushmemscreen(Rectangle r)
|
|
|
|
|
{
|
|
|
|
|
win.flushrect = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r));
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
// Call "lockFocusIfCanDraw" from main thread, else
|
|
|
|
|
// we deadlock while synchronizing both threads with
|
|
|
|
|
// qlock(): main thread must apparently be idle while we call it.
|
|
|
|
|
[appdelegate
|
|
|
|
|
performSelectorOnMainThread:@selector(calldrawimg:)
|
|
|
|
|
withObject:nil
|
|
|
|
|
waitUntilDone:YES];
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
static void drawresizehandle(void);
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static void
|
|
|
|
|
drawimg(void)
|
|
|
|
|
{
|
|
|
|
|
static int first = 1;
|
|
|
|
|
NSRect dr, sr;
|
|
|
|
|
|
|
|
|
|
if(first){
|
|
|
|
|
[NSTimer scheduledTimerWithTimeInterval:0.033
|
|
|
|
|
target:[appdelegate class]
|
|
|
|
|
selector:@selector(callflushwin:) userInfo:nil
|
|
|
|
|
repeats:YES];
|
|
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
dr = win.flushrect;
|
|
|
|
|
sr = [win.content convertRect:dr fromView:nil];
|
|
|
|
|
|
|
|
|
|
if([win.content lockFocusIfCanDraw]){
|
|
|
|
|
[win.img drawInRect:dr fromRect:sr
|
|
|
|
|
operation:NSCompositeCopy fraction:1
|
|
|
|
|
respectFlipped:YES hints:nil];
|
2011-10-03 18:16:09 -04:00
|
|
|
|
|
|
|
|
if(OSX_VERSION<100700 && win.p==win.std)
|
|
|
|
|
drawresizehandle();
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
[win.content unlockFocus];
|
|
|
|
|
win.needflush = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static void
|
|
|
|
|
flushwin(void)
|
|
|
|
|
{
|
|
|
|
|
if(win.needflush){
|
|
|
|
|
[win.p flushWindow];
|
|
|
|
|
win.needflush = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
Pixel = 1,
|
|
|
|
|
Handlesize = 16*Pixel,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
drawresizehandle(void)
|
|
|
|
|
{
|
|
|
|
|
NSBezierPath *p;
|
|
|
|
|
NSRect r;
|
|
|
|
|
NSSize size;
|
|
|
|
|
Point o;
|
|
|
|
|
|
|
|
|
|
size = [win.img size];
|
|
|
|
|
o = Pt(size.width+1-Handlesize, size.height+1-Handlesize);
|
|
|
|
|
r = NSMakeRect(o.x, o.y, Handlesize, Handlesize);
|
|
|
|
|
if(NSIntersectsRect(r, win.flushrect) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
[[NSColor whiteColor] setFill];
|
|
|
|
|
[[NSColor lightGrayColor] setStroke];
|
|
|
|
|
|
|
|
|
|
[NSBezierPath fillRect:r];
|
|
|
|
|
[NSBezierPath strokeRect:r];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[NSColor darkGrayColor] setStroke];
|
|
|
|
|
|
|
|
|
|
p = [NSBezierPath bezierPath];
|
|
|
|
|
|
|
|
|
|
[p moveToPoint:NSMakePoint(o.x+4, o.y+13)];
|
|
|
|
|
[p lineToPoint:NSMakePoint(o.x+13, o.y+4)];
|
|
|
|
|
|
|
|
|
|
[p moveToPoint:NSMakePoint(o.x+8, o.y+13)];
|
|
|
|
|
[p lineToPoint:NSMakePoint(o.x+13, o.y+8)];
|
|
|
|
|
|
|
|
|
|
[p moveToPoint:NSMakePoint(o.x+12, o.y+13)];
|
|
|
|
|
[p lineToPoint:NSMakePoint(o.x+13, o.y+12)];
|
|
|
|
|
|
|
|
|
|
[p stroke];
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
static void getgesture(NSEvent*);
|
|
|
|
|
static void getkeyboard(NSEvent*);
|
|
|
|
|
static void getmouse(NSEvent*);
|
2011-09-19 08:58:59 -04:00
|
|
|
static void gettouch(NSEvent*, int);
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
@implementation appview
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)drawRect:(NSRect)r
|
|
|
|
|
{
|
|
|
|
|
// else no window background
|
|
|
|
|
}
|
|
|
|
|
- (BOOL)isFlipped
|
|
|
|
|
{
|
|
|
|
|
return YES; // to have the origin at top left
|
|
|
|
|
}
|
|
|
|
|
- (BOOL)acceptsFirstResponder
|
|
|
|
|
{
|
|
|
|
|
return YES; // to receive mouseMoved events
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
- (void)mouseMoved:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)mouseDown:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)mouseDragged:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)mouseUp:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)otherMouseDown:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)otherMouseDragged:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)otherMouseUp:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)rightMouseDown:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)rightMouseDragged:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)rightMouseUp:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
- (void)scrollWheel:(NSEvent*)e{ getmouse(e);}
|
|
|
|
|
|
|
|
|
|
- (void)keyDown:(NSEvent*)e{ getkeyboard(e);}
|
|
|
|
|
- (void)flagsChanged:(NSEvent*)e{ getkeyboard(e);}
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)swipeWithEvent:(NSEvent*)e{ getgesture(e);}
|
|
|
|
|
- (void)magnifyWithEvent:(NSEvent*)e{ getgesture(e);}
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)touchesBeganWithEvent:(NSEvent*)e
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
gettouch(e, NSTouchPhaseBegan);
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)touchesMovedWithEvent:(NSEvent*)e
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
gettouch(e, NSTouchPhaseMoved);
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
- (void)touchesEndedWithEvent:(NSEvent*)e
|
|
|
|
|
{
|
|
|
|
|
gettouch(e, NSTouchPhaseEnded);
|
|
|
|
|
}
|
|
|
|
|
- (void)touchesCancelledWithEvent:(NSEvent*)e
|
|
|
|
|
{
|
|
|
|
|
gettouch(e, NSTouchPhaseCancelled);
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
|
int kalting;
|
|
|
|
|
int kbuttons;
|
|
|
|
|
int mbuttons;
|
|
|
|
|
Point mpos;
|
|
|
|
|
int mscroll;
|
|
|
|
|
int undo;
|
|
|
|
|
} in;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
static int keycvt[] =
|
|
|
|
|
{
|
|
|
|
|
[QZ_IBOOK_ENTER] '\n',
|
|
|
|
|
[QZ_RETURN] '\n',
|
|
|
|
|
[QZ_ESCAPE] 27,
|
|
|
|
|
[QZ_BACKSPACE] '\b',
|
|
|
|
|
[QZ_LALT] Kalt,
|
|
|
|
|
[QZ_LCTRL] Kctl,
|
|
|
|
|
[QZ_LSHIFT] Kshift,
|
|
|
|
|
[QZ_F1] KF+1,
|
|
|
|
|
[QZ_F2] KF+2,
|
|
|
|
|
[QZ_F3] KF+3,
|
|
|
|
|
[QZ_F4] KF+4,
|
|
|
|
|
[QZ_F5] KF+5,
|
|
|
|
|
[QZ_F6] KF+6,
|
|
|
|
|
[QZ_F7] KF+7,
|
|
|
|
|
[QZ_F8] KF+8,
|
|
|
|
|
[QZ_F9] KF+9,
|
|
|
|
|
[QZ_F10] KF+10,
|
|
|
|
|
[QZ_F11] KF+11,
|
|
|
|
|
[QZ_F12] KF+12,
|
|
|
|
|
[QZ_INSERT] Kins,
|
|
|
|
|
[QZ_DELETE] 0x7F,
|
|
|
|
|
[QZ_HOME] Khome,
|
|
|
|
|
[QZ_END] Kend,
|
|
|
|
|
[QZ_KP_PLUS] '+',
|
|
|
|
|
[QZ_KP_MINUS] '-',
|
|
|
|
|
[QZ_TAB] '\t',
|
|
|
|
|
[QZ_PAGEUP] Kpgup,
|
|
|
|
|
[QZ_PAGEDOWN] Kpgdown,
|
|
|
|
|
[QZ_UP] Kup,
|
|
|
|
|
[QZ_DOWN] Kdown,
|
|
|
|
|
[QZ_LEFT] Kleft,
|
|
|
|
|
[QZ_RIGHT] Kright,
|
|
|
|
|
[QZ_KP_MULTIPLY] '*',
|
|
|
|
|
[QZ_KP_DIVIDE] '/',
|
|
|
|
|
[QZ_KP_ENTER] '\n',
|
|
|
|
|
[QZ_KP_PERIOD] '.',
|
|
|
|
|
[QZ_KP0] '0',
|
|
|
|
|
[QZ_KP1] '1',
|
|
|
|
|
[QZ_KP2] '2',
|
|
|
|
|
[QZ_KP3] '3',
|
|
|
|
|
[QZ_KP4] '4',
|
|
|
|
|
[QZ_KP5] '5',
|
|
|
|
|
[QZ_KP6] '6',
|
|
|
|
|
[QZ_KP7] '7',
|
|
|
|
|
[QZ_KP8] '8',
|
|
|
|
|
[QZ_KP9] '9',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
getkeyboard(NSEvent *e)
|
|
|
|
|
{
|
|
|
|
|
char c;
|
2011-09-19 08:58:59 -04:00
|
|
|
int k, m;
|
|
|
|
|
uint code;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
m = [e modifierFlags];
|
|
|
|
|
|
|
|
|
|
switch([e type]){
|
|
|
|
|
case NSKeyDown:
|
2011-09-19 08:58:59 -04:00
|
|
|
in.kalting = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
c = [[e characters] characterAtIndex:0];
|
|
|
|
|
if(m & NSCommandKeyMask){
|
2011-09-19 08:58:59 -04:00
|
|
|
if(' '<=c && c<='~'){
|
2011-09-06 10:10:43 -04:00
|
|
|
keystroke(Kcmd+c);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
// to understand
|
2011-09-06 10:10:43 -04:00
|
|
|
k = c;
|
|
|
|
|
code = [e keyCode];
|
|
|
|
|
if(code < nelem(keycvt) && keycvt[code])
|
|
|
|
|
k = keycvt[code];
|
|
|
|
|
if(k == 0)
|
|
|
|
|
return;
|
|
|
|
|
if(k > 0)
|
|
|
|
|
keystroke(k);
|
|
|
|
|
else
|
|
|
|
|
keystroke(c);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSFlagsChanged:
|
2011-09-19 08:58:59 -04:00
|
|
|
if(in.mbuttons || in.kbuttons){
|
|
|
|
|
in.kbuttons = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
if(m & NSAlternateKeyMask)
|
2011-09-19 08:58:59 -04:00
|
|
|
in.kbuttons |= 2;
|
2011-09-06 10:10:43 -04:00
|
|
|
if(m & NSCommandKeyMask)
|
2011-09-19 08:58:59 -04:00
|
|
|
in.kbuttons |= 4;
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-06 10:10:43 -04:00
|
|
|
}else
|
2011-09-19 08:58:59 -04:00
|
|
|
if(m & NSAlternateKeyMask){
|
|
|
|
|
in.kalting = 1;
|
2011-09-06 10:10:43 -04:00
|
|
|
keystroke(Kalt);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
panic("getkey: unexpected event type");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
getmousepos(void)
|
|
|
|
|
{
|
|
|
|
|
NSPoint p;
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
p = [win.p mouseLocationOutsideOfEventStream];
|
|
|
|
|
p = [win.content convertPoint:p fromView:nil];
|
|
|
|
|
in.mpos = Pt(p.x, p.y);
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
getmouse(NSEvent *e)
|
|
|
|
|
{
|
|
|
|
|
float d;
|
2011-09-19 08:58:59 -04:00
|
|
|
int b, m;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
getmousepos();
|
|
|
|
|
|
|
|
|
|
switch([e type]){
|
|
|
|
|
case NSLeftMouseDown:
|
|
|
|
|
case NSLeftMouseUp:
|
|
|
|
|
case NSOtherMouseDown:
|
|
|
|
|
case NSOtherMouseUp:
|
|
|
|
|
case NSRightMouseDown:
|
|
|
|
|
case NSRightMouseUp:
|
|
|
|
|
b = [NSEvent pressedMouseButtons];
|
|
|
|
|
b = b&~6 | (b&4)>>1 | (b&2)<<1;
|
|
|
|
|
b = mouseswap(b);
|
|
|
|
|
|
|
|
|
|
if(b == 1){
|
|
|
|
|
m = [e modifierFlags];
|
2011-09-19 08:58:59 -04:00
|
|
|
if(m & NSAlternateKeyMask){
|
2011-09-06 10:10:43 -04:00
|
|
|
b = 2;
|
|
|
|
|
// Take the ALT away from the keyboard handler.
|
2011-09-19 08:58:59 -04:00
|
|
|
if(in.kalting){
|
|
|
|
|
in.kalting = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
keystroke(Kalt);
|
|
|
|
|
}
|
|
|
|
|
}else
|
|
|
|
|
if(m & NSCommandKeyMask)
|
|
|
|
|
b = 4;
|
|
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mbuttons = b;
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSScrollWheel:
|
|
|
|
|
#if OSX_VERSION >= 100700
|
|
|
|
|
d = [e scrollingDeltaY];
|
|
|
|
|
#else
|
|
|
|
|
d = [e deltaY];
|
|
|
|
|
#endif
|
|
|
|
|
if(d>0)
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mscroll = 8;
|
|
|
|
|
else
|
|
|
|
|
if(d<0)
|
|
|
|
|
in.mscroll = 16;
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSMouseMoved:
|
|
|
|
|
case NSLeftMouseDragged:
|
|
|
|
|
case NSRightMouseDragged:
|
|
|
|
|
case NSOtherMouseDragged:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
panic("getmouse: unexpected event type");
|
|
|
|
|
}
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static void sendswipe(int, int);
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
getgesture(NSEvent *e)
|
|
|
|
|
{
|
|
|
|
|
switch([e type]){
|
|
|
|
|
|
|
|
|
|
case NSEventTypeMagnify:
|
2011-09-19 08:58:59 -04:00
|
|
|
// if(fabs([e magnification]) > 0.025)
|
2011-09-26 08:19:56 -07:00
|
|
|
togglefs();
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSEventTypeSwipe:
|
2011-09-19 08:58:59 -04:00
|
|
|
if(reimplementswipe)
|
|
|
|
|
break;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
sendswipe(-[e deltaX], -[e deltaY]);
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
2011-09-19 08:58:59 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sendclick(int);
|
|
|
|
|
static void sendchord(int, int);
|
|
|
|
|
static void sendcmd(int);
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static uint
|
|
|
|
|
msec(void)
|
|
|
|
|
{
|
|
|
|
|
return nsec()/1000000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
Msec = 1,
|
|
|
|
|
Maxtap = 400*Msec,
|
|
|
|
|
Maxtouch = 3,
|
|
|
|
|
Mindelta = 0,
|
|
|
|
|
Minswipe = 15,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gettouch(NSEvent *e, int type)
|
|
|
|
|
{
|
|
|
|
|
static NSPoint delta, odelta;
|
|
|
|
|
static NSTouch *toucha[Maxtouch];
|
|
|
|
|
static NSTouch *touchb[Maxtouch];
|
|
|
|
|
static int done, ntouch, tapping;
|
|
|
|
|
static uint taptime;
|
|
|
|
|
NSArray *a;
|
|
|
|
|
NSPoint d;
|
|
|
|
|
NSSet *set;
|
|
|
|
|
NSSize s;
|
|
|
|
|
int i, p;
|
|
|
|
|
|
|
|
|
|
if(reimplementswipe==0 && type!=NSTouchPhaseEnded)
|
|
|
|
|
return;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
switch(type){
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
case NSTouchPhaseBegan:
|
|
|
|
|
p = NSTouchPhaseTouching;
|
|
|
|
|
set = [e touchesMatchingPhase:p inView:nil];
|
|
|
|
|
if(set.count == 3){
|
|
|
|
|
tapping = 1;
|
|
|
|
|
taptime = msec();
|
|
|
|
|
}else
|
|
|
|
|
if(set.count > 3)
|
|
|
|
|
tapping = 0;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case NSTouchPhaseMoved:
|
|
|
|
|
p = NSTouchPhaseMoved;
|
|
|
|
|
set = [e touchesMatchingPhase:p inView:nil];
|
|
|
|
|
a = [set allObjects];
|
|
|
|
|
if(set.count > Maxtouch)
|
|
|
|
|
return;
|
|
|
|
|
if(ntouch==0){
|
|
|
|
|
ntouch = set.count;
|
|
|
|
|
for(i=0; i<ntouch; i++){
|
|
|
|
|
assert(toucha[i] == nil);
|
|
|
|
|
toucha[i] = [[a objectAtIndex:i] retain];
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(ntouch != set.count)
|
|
|
|
|
break;
|
|
|
|
|
if(done)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
d = NSMakePoint(0,0);
|
|
|
|
|
for(i=0; i<ntouch; i++){
|
|
|
|
|
assert(touchb[i] == nil);
|
|
|
|
|
touchb[i] = [a objectAtIndex:i];
|
|
|
|
|
d.x += touchb[i].normalizedPosition.x;
|
|
|
|
|
d.y += touchb[i].normalizedPosition.y;
|
|
|
|
|
d.x -= toucha[i].normalizedPosition.x;
|
|
|
|
|
d.y -= toucha[i].normalizedPosition.y;
|
|
|
|
|
}
|
|
|
|
|
s = toucha[0].deviceSize;
|
|
|
|
|
d.x = d.x/ntouch * s.width;
|
|
|
|
|
d.y = d.y/ntouch * s.height;
|
|
|
|
|
if(fabs(d.x)>Mindelta || fabs(d.y)>Mindelta){
|
|
|
|
|
tapping = 0;
|
|
|
|
|
if(ntouch != 3){
|
|
|
|
|
done = 1;
|
|
|
|
|
goto Return;
|
|
|
|
|
}
|
|
|
|
|
delta = NSMakePoint(delta.x+d.x, delta.y+d.y);
|
|
|
|
|
d = NSMakePoint(fabs(delta.x), fabs(delta.y));
|
|
|
|
|
if(d.x>Minswipe || d.y>Minswipe){
|
|
|
|
|
if(d.x > d.y)
|
|
|
|
|
delta = NSMakePoint(-copysign(1,delta.x), 0);
|
|
|
|
|
else
|
|
|
|
|
delta = NSMakePoint(0, copysign(1,delta.y));
|
|
|
|
|
|
|
|
|
|
if(! NSEqualPoints(delta, odelta)){
|
|
|
|
|
// if(ntouch == 3)
|
|
|
|
|
sendswipe(-delta.x, -delta.y);
|
|
|
|
|
odelta = delta;
|
|
|
|
|
}
|
|
|
|
|
done = 1;
|
|
|
|
|
goto Return;
|
|
|
|
|
}
|
|
|
|
|
for(i=0; i<ntouch; i++){
|
|
|
|
|
[toucha[i] release];
|
|
|
|
|
toucha[i] = [touchb[i] retain];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Return:
|
|
|
|
|
for(i=0; i<ntouch; i++)
|
|
|
|
|
touchb[i] = nil;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case NSTouchPhaseEnded:
|
|
|
|
|
p = NSTouchPhaseTouching;
|
|
|
|
|
set = [e touchesMatchingPhase:p inView:nil];
|
|
|
|
|
if(set.count == 0){
|
|
|
|
|
in.undo = 0;
|
|
|
|
|
|
|
|
|
|
if(usecopygesture)
|
|
|
|
|
if(tapping && msec()-taptime<Maxtap)
|
|
|
|
|
sendclick(2);
|
|
|
|
|
tapping = 0;
|
|
|
|
|
odelta = NSMakePoint(0,0);
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
case NSTouchPhaseCancelled:
|
2011-09-06 10:10:43 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2011-09-19 08:58:59 -04:00
|
|
|
panic("gettouch: unexpected event type: %d", type);
|
|
|
|
|
}
|
|
|
|
|
for(i=0; i<ntouch; i++){
|
|
|
|
|
[toucha[i] release];
|
|
|
|
|
toucha[i] = nil;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-26 08:19:56 -07:00
|
|
|
for(i=0; i<ntouch; i++){
|
2011-09-19 08:58:59 -04:00
|
|
|
assert(toucha[i] == nil);
|
|
|
|
|
assert(touchb[i] == nil);
|
|
|
|
|
}
|
|
|
|
|
ntouch = 0;
|
|
|
|
|
delta = NSMakePoint(0,0);
|
|
|
|
|
done = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2011-09-19 08:58:59 -04:00
|
|
|
sendswipe(int dx, int dy)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
if(dx == -1){
|
|
|
|
|
sendcmd('x');
|
|
|
|
|
}else
|
|
|
|
|
if(dx == +1){
|
|
|
|
|
sendcmd('v');
|
|
|
|
|
}else
|
|
|
|
|
if(dy == -1){
|
|
|
|
|
if(usecopygesture)
|
|
|
|
|
sendcmd('c');
|
|
|
|
|
else
|
|
|
|
|
sendclick(2);
|
|
|
|
|
}else
|
|
|
|
|
if(dy == +1){
|
|
|
|
|
sendchord(2,1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
sendcmd(int c)
|
|
|
|
|
{
|
|
|
|
|
if(c=='x' || c=='v'){
|
|
|
|
|
if(in.undo)
|
|
|
|
|
c = 'z';
|
|
|
|
|
in.undo = ! in.undo;
|
|
|
|
|
}
|
2011-09-06 10:10:43 -04:00
|
|
|
keystroke(Kcmd+c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2011-09-19 08:58:59 -04:00
|
|
|
sendclick(int b)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mbuttons = b;
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mbuttons = 0;
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static void
|
|
|
|
|
sendchord(int b1, int b2)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mbuttons = b1;
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mbuttons |= b2;
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mbuttons = 0;
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse();
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2011-10-03 18:16:09 -04:00
|
|
|
sendmouse(void)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
NSSize size;
|
|
|
|
|
int b;
|
|
|
|
|
|
|
|
|
|
size = [win.img size];
|
|
|
|
|
mouserect = Rect(0, 0, size.width, size.height);
|
|
|
|
|
|
|
|
|
|
b = in.kbuttons | in.mbuttons | in.mscroll;
|
|
|
|
|
mousetrack(in.mpos.x, in.mpos.y, b, msec());
|
|
|
|
|
in.mscroll = 0;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
setmouse(Point p)
|
|
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
static int first = 1;
|
2011-09-06 10:10:43 -04:00
|
|
|
NSPoint q;
|
|
|
|
|
NSRect r;
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(first){
|
|
|
|
|
// try to move Acme's scrollbars without that!
|
|
|
|
|
CGSetLocalEventsSuppressionInterval(0);
|
|
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
r = [[win.p screen] frame];
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
q = NSMakePoint(p.x,p.y);
|
2011-09-19 08:58:59 -04:00
|
|
|
q = [win.content convertPoint:q toView:nil];
|
|
|
|
|
q = [win.p convertBaseToScreen:q];
|
2011-09-06 10:10:43 -04:00
|
|
|
q.y = r.size.height - q.y;
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
CGWarpMouseCursorPosition(NSPointToCGPoint(q));
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
// race condition
|
2011-09-19 08:58:59 -04:00
|
|
|
in.mpos = p;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2011-09-26 08:19:56 -07:00
|
|
|
togglefs(void)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
#if OSX_VERSION >= 100700
|
|
|
|
|
if(useoldfullscreen == 0){
|
|
|
|
|
[win.p toggleFullScreen:nil];
|
|
|
|
|
return;
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
#endif
|
|
|
|
|
NSScreen *screen;
|
2011-10-03 18:16:09 -04:00
|
|
|
int willfs;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
screen = [win.p screen];
|
2011-10-03 18:16:09 -04:00
|
|
|
|
|
|
|
|
willfs = !NSEqualRects([win.p frame], [screen frame]);
|
|
|
|
|
|
|
|
|
|
autohide(willfs);
|
|
|
|
|
|
2011-09-26 08:19:56 -07:00
|
|
|
[win.content retain];
|
|
|
|
|
[win.p orderOut:nil];
|
|
|
|
|
[win.p setContentView:nil];
|
2011-10-03 18:16:09 -04:00
|
|
|
|
|
|
|
|
if(willfs)
|
2011-09-26 08:19:56 -07:00
|
|
|
win.p = win.ofs;
|
2011-10-03 18:16:09 -04:00
|
|
|
else
|
|
|
|
|
win.p = win.std;
|
|
|
|
|
|
2011-09-26 08:19:56 -07:00
|
|
|
[win.p setContentView:win.content];
|
|
|
|
|
[win.p makeKeyAndOrderFront:nil];
|
|
|
|
|
[win.content release];
|
2011-10-03 18:16:09 -04:00
|
|
|
|
2011-09-26 08:19:56 -07:00
|
|
|
resize();
|
2011-10-03 18:16:09 -04:00
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
static void
|
|
|
|
|
autohide(int set)
|
|
|
|
|
{
|
|
|
|
|
NSScreen *s,*s0;
|
|
|
|
|
int opt;
|
|
|
|
|
|
|
|
|
|
s = [win.p screen];
|
|
|
|
|
s0 = [[NSScreen screens] objectAtIndex:0];
|
|
|
|
|
|
|
|
|
|
if(set && s==s0)
|
|
|
|
|
opt = NSApplicationPresentationAutoHideDock
|
|
|
|
|
| NSApplicationPresentationAutoHideMenuBar;
|
|
|
|
|
else
|
|
|
|
|
opt = NSApplicationPresentationDefault;
|
|
|
|
|
|
|
|
|
|
[NSApp setPresentationOptions:opt];
|
|
|
|
|
}
|
2011-09-19 08:58:59 -04:00
|
|
|
|
|
|
|
|
// Rewrite this function
|
|
|
|
|
// See ./osx-delegate.m implementation (NSLocalizedString)
|
2011-09-06 10:10:43 -04:00
|
|
|
static void
|
2011-09-19 08:58:59 -04:00
|
|
|
makemenu(void)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
|
|
|
|
NSString *title;
|
|
|
|
|
NSMenu *menu;
|
|
|
|
|
NSMenuItem *appmenu, *item;
|
|
|
|
|
|
|
|
|
|
menu = [NSMenu new];
|
|
|
|
|
appmenu = [NSMenuItem new];
|
|
|
|
|
[menu addItem:appmenu];
|
|
|
|
|
[NSApp setMenu:menu];
|
|
|
|
|
[menu release];
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
menu = [NSMenu new];
|
|
|
|
|
|
|
|
|
|
title = @"Full Screen";
|
2011-09-06 10:10:43 -04:00
|
|
|
item = [[NSMenuItem alloc]
|
|
|
|
|
initWithTitle:title
|
2011-09-26 08:19:56 -07:00
|
|
|
action:@selector(calltogglefs:) keyEquivalent:@"f"];
|
2011-09-19 08:58:59 -04:00
|
|
|
[menu addItem:item];
|
|
|
|
|
[item release];
|
2011-09-06 10:10:43 -04:00
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
title = @"Quit";
|
|
|
|
|
item = [[NSMenuItem alloc]
|
|
|
|
|
initWithTitle:title
|
|
|
|
|
action:@selector(terminate:) keyEquivalent:@"q"];
|
2011-09-06 10:10:43 -04:00
|
|
|
[menu addItem:item];
|
|
|
|
|
[item release];
|
2011-09-19 08:58:59 -04:00
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
[appmenu setSubmenu:menu];
|
|
|
|
|
[appmenu release];
|
|
|
|
|
[menu release];
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
static void
|
|
|
|
|
makeicon(void)
|
|
|
|
|
{
|
|
|
|
|
NSData *d;
|
|
|
|
|
NSImage *i;
|
|
|
|
|
|
|
|
|
|
d = [[NSData alloc]
|
|
|
|
|
initWithBytes:glenda_png
|
|
|
|
|
length:(sizeof glenda_png)];
|
|
|
|
|
|
|
|
|
|
i = [[NSImage alloc] initWithData:d];
|
|
|
|
|
[NSApp setApplicationIconImage:i];
|
|
|
|
|
[[NSApp dockTile] display];
|
|
|
|
|
[i release];
|
|
|
|
|
[d release];
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-06 10:10:43 -04:00
|
|
|
QLock snarfl;
|
|
|
|
|
|
|
|
|
|
char*
|
|
|
|
|
getsnarf(void)
|
|
|
|
|
{
|
|
|
|
|
NSPasteboard *pb;
|
2011-09-19 08:58:59 -04:00
|
|
|
NSString *s;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
pb = [NSPasteboard generalPasteboard];
|
|
|
|
|
|
|
|
|
|
qlock(&snarfl);
|
2011-10-03 18:16:09 -04:00
|
|
|
s = [pb stringForType:NSPasteboardTypeString];
|
2011-09-06 10:10:43 -04:00
|
|
|
qunlock(&snarfl);
|
|
|
|
|
|
|
|
|
|
if(s)
|
|
|
|
|
return strdup((char*)[s UTF8String]);
|
|
|
|
|
else
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
putsnarf(char *s)
|
|
|
|
|
{
|
|
|
|
|
NSArray *t;
|
|
|
|
|
NSPasteboard *pb;
|
2011-09-19 08:58:59 -04:00
|
|
|
NSString *str;
|
2011-09-06 10:10:43 -04:00
|
|
|
|
|
|
|
|
if(strlen(s) >= SnarfSize)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
t = [NSArray arrayWithObject:NSPasteboardTypeString];
|
|
|
|
|
pb = [NSPasteboard generalPasteboard];
|
|
|
|
|
str = [[NSString alloc] initWithUTF8String:s];
|
|
|
|
|
|
|
|
|
|
qlock(&snarfl);
|
|
|
|
|
[pb declareTypes:t owner:nil];
|
2011-10-03 18:16:09 -04:00
|
|
|
[pb setString:str forType:NSPasteboardTypeString];
|
2011-09-06 10:10:43 -04:00
|
|
|
qunlock(&snarfl);
|
|
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
[str release];
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-09-19 08:58:59 -04:00
|
|
|
kicklabel(char *label)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-10-03 18:16:09 -04:00
|
|
|
NSString *s;
|
|
|
|
|
|
2011-09-19 08:58:59 -04:00
|
|
|
if(label == nil)
|
|
|
|
|
return;
|
|
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
s = [[NSString alloc] initWithUTF8String:label];
|
|
|
|
|
[win.std setTitle:s];
|
|
|
|
|
[win.ofs setTitle:s];
|
|
|
|
|
[[NSApp dockTile] setBadgeLabel:s];
|
|
|
|
|
[s release];
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-09-19 08:58:59 -04:00
|
|
|
setcursor(Cursor *cursor)
|
2011-09-06 10:10:43 -04:00
|
|
|
{
|
2011-09-19 08:58:59 -04:00
|
|
|
win.cursor = cursor;
|
|
|
|
|
|
2011-10-03 18:16:09 -04:00
|
|
|
// no cursor change unless in main thread
|
2011-09-19 08:58:59 -04:00
|
|
|
[appdelegate
|
|
|
|
|
performSelectorOnMainThread:@selector(callsetcursor0:)
|
|
|
|
|
withObject:nil
|
|
|
|
|
waitUntilDone:YES];
|
|
|
|
|
// setcursor0();
|
|
|
|
|
|
|
|
|
|
win.cursor = nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
setcursor0(void)
|
|
|
|
|
{
|
|
|
|
|
Cursor *c;
|
|
|
|
|
NSBitmapImageRep *r;
|
|
|
|
|
NSCursor *d;
|
|
|
|
|
NSImage *i;
|
|
|
|
|
NSPoint p;
|
|
|
|
|
int b;
|
|
|
|
|
uchar *plane[5];
|
|
|
|
|
|
|
|
|
|
c = win.cursor;
|
|
|
|
|
|
|
|
|
|
if(c == nil){
|
|
|
|
|
[[NSCursor arrowCursor] set];
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
r = [[NSBitmapImageRep alloc]
|
|
|
|
|
initWithBitmapDataPlanes:nil
|
|
|
|
|
pixelsWide:16
|
|
|
|
|
pixelsHigh:16
|
|
|
|
|
bitsPerSample:1
|
|
|
|
|
samplesPerPixel:2
|
|
|
|
|
hasAlpha:YES
|
|
|
|
|
isPlanar:YES
|
|
|
|
|
colorSpaceName:NSDeviceBlackColorSpace
|
|
|
|
|
bytesPerRow:2
|
|
|
|
|
bitsPerPixel:1];
|
|
|
|
|
|
|
|
|
|
[r getBitmapDataPlanes:plane];
|
|
|
|
|
|
|
|
|
|
for(b=0; b<2*16; b++){
|
|
|
|
|
plane[0][b] = c->set[b];
|
|
|
|
|
plane[1][b] = c->clr[b];
|
|
|
|
|
}
|
|
|
|
|
p = NSMakePoint(-c->offset.x, -c->offset.y);
|
|
|
|
|
i = [NSImage new];
|
|
|
|
|
[i addRepresentation:r];
|
|
|
|
|
d = [[NSCursor alloc] initWithImage:i hotSpot:p];
|
|
|
|
|
[d set];
|
|
|
|
|
|
|
|
|
|
[d release];
|
|
|
|
|
[r release];
|
|
|
|
|
[i release];
|
2011-09-06 10:10:43 -04:00
|
|
|
}
|