|
|
|
@@ -24,6 +24,8 @@ |
|
|
|
|
|
|
|
#include "pugl_internal.h" |
|
|
|
|
|
|
|
#include <assert.h> |
|
|
|
|
|
|
|
@interface PuglWindow : NSWindow |
|
|
|
{ |
|
|
|
@public |
|
|
|
@@ -54,7 +56,7 @@ |
|
|
|
[result setAcceptsMouseMovedEvents:YES]; |
|
|
|
[result setLevel: CGShieldingWindowLevel() + 1]; |
|
|
|
|
|
|
|
return result; |
|
|
|
return (PuglWindow*)result; |
|
|
|
|
|
|
|
// unused |
|
|
|
(void)aStyle; (void)bufferingType; (void)flag; |
|
|
|
@@ -88,28 +90,30 @@ puglDisplay(PuglView* view) |
|
|
|
|
|
|
|
@interface PuglOpenGLView : NSOpenGLView |
|
|
|
{ |
|
|
|
int colorBits; |
|
|
|
int depthBits; |
|
|
|
@public |
|
|
|
PuglView* puglview; |
|
|
|
|
|
|
|
NSTrackingArea* trackingArea; |
|
|
|
} |
|
|
|
|
|
|
|
- (id) initWithFrame:(NSRect)frame |
|
|
|
colorBits:(int)numColorBits |
|
|
|
depthBits:(int)numDepthBits; |
|
|
|
- (BOOL) acceptsFirstMouse:(NSEvent*)e; |
|
|
|
- (BOOL) isFlipped; |
|
|
|
- (BOOL) preservesContentInLiveResize; |
|
|
|
- (id) initWithFrame:(NSRect)frame; |
|
|
|
- (void) reshape; |
|
|
|
- (void) drawRect:(NSRect)rect; |
|
|
|
- (void) mouseEntered:(NSEvent*)event; |
|
|
|
- (void) mouseExited:(NSEvent*)event; |
|
|
|
- (void) drawRect:(NSRect)r; |
|
|
|
- (void) cursorUpdate:(NSEvent*)e; |
|
|
|
- (void) updateTrackingAreas; |
|
|
|
- (void) viewWillMoveToWindow:(NSWindow*)newWindow; |
|
|
|
- (void) mouseMoved:(NSEvent*)event; |
|
|
|
- (void) mouseDragged:(NSEvent*)event; |
|
|
|
- (void) rightMouseDragged:(NSEvent*)event; |
|
|
|
- (void) otherMouseDragged:(NSEvent*)event; |
|
|
|
- (void) mouseDown:(NSEvent*)event; |
|
|
|
- (void) mouseUp:(NSEvent*)event; |
|
|
|
- (void) rightMouseDown:(NSEvent*)event; |
|
|
|
- (void) otherMouseDown:(NSEvent*)event; |
|
|
|
- (void) mouseUp:(NSEvent*)event; |
|
|
|
- (void) rightMouseUp:(NSEvent*)event; |
|
|
|
- (void) otherMouseUp:(NSEvent*)event; |
|
|
|
- (void) scrollWheel:(NSEvent*)event; |
|
|
|
- (void) keyDown:(NSEvent*)event; |
|
|
|
- (void) keyUp:(NSEvent*)event; |
|
|
|
@@ -119,12 +123,26 @@ puglDisplay(PuglView* view) |
|
|
|
|
|
|
|
@implementation PuglOpenGLView |
|
|
|
|
|
|
|
- (BOOL) acceptsFirstMouse:(NSEvent*)e |
|
|
|
{ |
|
|
|
return YES; |
|
|
|
|
|
|
|
// unused |
|
|
|
(void)e; |
|
|
|
} |
|
|
|
|
|
|
|
- (BOOL) isFlipped |
|
|
|
{ |
|
|
|
return YES; |
|
|
|
} |
|
|
|
|
|
|
|
- (BOOL) preservesContentInLiveResize |
|
|
|
{ |
|
|
|
return NO; |
|
|
|
} |
|
|
|
|
|
|
|
- (id) initWithFrame:(NSRect)frame |
|
|
|
colorBits:(int)numColorBits |
|
|
|
depthBits:(int)numDepthBits |
|
|
|
{ |
|
|
|
colorBits = numColorBits; |
|
|
|
depthBits = numDepthBits; |
|
|
|
puglview = nil; |
|
|
|
trackingArea = nil; |
|
|
|
|
|
|
|
@@ -132,9 +150,9 @@ puglDisplay(PuglView* view) |
|
|
|
NSOpenGLPFADoubleBuffer, |
|
|
|
NSOpenGLPFAAccelerated, |
|
|
|
NSOpenGLPFAColorSize, |
|
|
|
colorBits, |
|
|
|
8, |
|
|
|
NSOpenGLPFADepthSize, |
|
|
|
depthBits, |
|
|
|
8, |
|
|
|
0 |
|
|
|
}; |
|
|
|
|
|
|
|
@@ -144,12 +162,13 @@ puglDisplay(PuglView* view) |
|
|
|
if (pixelFormat) { |
|
|
|
self = [super initWithFrame:frame pixelFormat:pixelFormat]; |
|
|
|
[pixelFormat release]; |
|
|
|
if (self) { |
|
|
|
[[self openGLContext] makeCurrentContext]; |
|
|
|
[self reshape]; |
|
|
|
} |
|
|
|
} else { |
|
|
|
self = nil; |
|
|
|
self = [super initWithFrame:frame]; |
|
|
|
} |
|
|
|
|
|
|
|
if (self) { |
|
|
|
[[self openGLContext] makeCurrentContext]; |
|
|
|
[self reshape]; |
|
|
|
} |
|
|
|
|
|
|
|
return self; |
|
|
|
@@ -159,80 +178,102 @@ puglDisplay(PuglView* view) |
|
|
|
{ |
|
|
|
[[self openGLContext] update]; |
|
|
|
|
|
|
|
NSRect bounds = [self bounds]; |
|
|
|
int width = bounds.size.width; |
|
|
|
int height = bounds.size.height; |
|
|
|
|
|
|
|
if (puglview) { |
|
|
|
if (!puglview) { |
|
|
|
/* NOTE: Apparently reshape gets called when the GC gets around to |
|
|
|
deleting the view (?), so we must have reset puglview to NULL when |
|
|
|
this comes around. |
|
|
|
*/ |
|
|
|
if (puglview->reshapeFunc) { |
|
|
|
puglview->reshapeFunc(puglview, width, height); |
|
|
|
} else { |
|
|
|
puglDefaultReshape(puglview, width, height); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
NSRect bounds = [self bounds]; |
|
|
|
int width = bounds.size.width; |
|
|
|
int height = bounds.size.height; |
|
|
|
|
|
|
|
puglview->width = width; |
|
|
|
puglview->height = height; |
|
|
|
if (puglview->reshapeFunc) { |
|
|
|
puglview->reshapeFunc(puglview, width, height); |
|
|
|
} else { |
|
|
|
puglDefaultReshape(puglview, width, height); |
|
|
|
} |
|
|
|
|
|
|
|
puglview->width = width; |
|
|
|
puglview->height = height; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) drawRect:(NSRect)rect |
|
|
|
- (void) drawRect:(NSRect)r |
|
|
|
{ |
|
|
|
puglDisplay(puglview); |
|
|
|
glFlush(); |
|
|
|
glSwapAPPLE(); |
|
|
|
|
|
|
|
// unused |
|
|
|
return; (void)rect; |
|
|
|
return; (void)r; |
|
|
|
} |
|
|
|
|
|
|
|
static unsigned |
|
|
|
getModifiers(PuglView* view, NSEvent* ev) |
|
|
|
- (void) cursorUpdate:(NSEvent*)e |
|
|
|
{ |
|
|
|
const unsigned modifierFlags = [ev modifierFlags]; |
|
|
|
[[NSCursor arrowCursor] set]; |
|
|
|
|
|
|
|
view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX); |
|
|
|
|
|
|
|
unsigned mods = 0; |
|
|
|
mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0; |
|
|
|
mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0; |
|
|
|
mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0; |
|
|
|
mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0; |
|
|
|
return mods; |
|
|
|
// unused |
|
|
|
return; (void)e; |
|
|
|
} |
|
|
|
|
|
|
|
-(void)updateTrackingAreas |
|
|
|
- (void) updateTrackingAreas |
|
|
|
{ |
|
|
|
static const int opts = NSTrackingMouseEnteredAndExited |
|
|
|
| NSTrackingMouseMoved |
|
|
|
| NSTrackingEnabledDuringMouseDrag |
|
|
|
| NSTrackingInVisibleRect |
|
|
|
| NSTrackingActiveAlways |
|
|
|
| NSTrackingCursorUpdate; |
|
|
|
|
|
|
|
if (trackingArea != nil) { |
|
|
|
[self removeTrackingArea:trackingArea]; |
|
|
|
[trackingArea release]; |
|
|
|
} |
|
|
|
|
|
|
|
const int opts = (NSTrackingMouseEnteredAndExited | |
|
|
|
NSTrackingMouseMoved | |
|
|
|
NSTrackingActiveAlways); |
|
|
|
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds] |
|
|
|
options:opts |
|
|
|
owner:self |
|
|
|
userInfo:nil]; |
|
|
|
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] |
|
|
|
options:opts |
|
|
|
owner:self |
|
|
|
userInfo:nil]; |
|
|
|
[self addTrackingArea:trackingArea]; |
|
|
|
[super updateTrackingAreas]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void)mouseEntered:(NSEvent*)theEvent |
|
|
|
- (void) viewWillMoveToWindow:(NSWindow*)newWindow |
|
|
|
{ |
|
|
|
[self updateTrackingAreas]; |
|
|
|
if (newWindow != nil) { |
|
|
|
[newWindow setAcceptsMouseMovedEvents:YES]; |
|
|
|
[newWindow makeFirstResponder:self]; |
|
|
|
} |
|
|
|
|
|
|
|
// unused |
|
|
|
return; (void)theEvent; |
|
|
|
[super viewWillMoveToWindow:newWindow]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void)mouseExited:(NSEvent*)theEvent |
|
|
|
static unsigned |
|
|
|
getModifiers(PuglView* view, NSEvent* ev) |
|
|
|
{ |
|
|
|
// unused |
|
|
|
return; (void)theEvent; |
|
|
|
const unsigned modifierFlags = [ev modifierFlags]; |
|
|
|
|
|
|
|
view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX); |
|
|
|
|
|
|
|
unsigned mods = 0; |
|
|
|
mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0; |
|
|
|
mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0; |
|
|
|
mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0; |
|
|
|
mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0; |
|
|
|
return mods; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
getFixedAppKitButton(NSInteger button) |
|
|
|
{ |
|
|
|
switch (button) { |
|
|
|
case 0: return 1; |
|
|
|
case 1: return 3; |
|
|
|
case 2: return 2; |
|
|
|
default: return button; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
- (void) mouseMoved:(NSEvent*)event |
|
|
|
@@ -240,63 +281,61 @@ getModifiers(PuglView* view, NSEvent* ev) |
|
|
|
if (puglview->motionFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->motionFunc(puglview, loc.x, puglview->height - loc.y); |
|
|
|
puglview->motionFunc(puglview, loc.x, loc.y); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
- (void) mouseDragged:(NSEvent*)event |
|
|
|
{ |
|
|
|
if (puglview->motionFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->motionFunc(puglview, loc.x, puglview->height - loc.y); |
|
|
|
} |
|
|
|
[self mouseMoved:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) rightMouseDragged:(NSEvent*)event |
|
|
|
{ |
|
|
|
if (puglview->motionFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->motionFunc(puglview, loc.x, puglview->height - loc.y); |
|
|
|
} |
|
|
|
[self mouseDragged:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) mouseDown:(NSEvent*)event |
|
|
|
- (void) otherMouseDragged:(NSEvent*)event |
|
|
|
{ |
|
|
|
if (puglview->mouseFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->mouseFunc(puglview, 1, true, loc.x, puglview->height - loc.y); |
|
|
|
} |
|
|
|
[self mouseDragged:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) mouseUp:(NSEvent*)event |
|
|
|
- (void) mouseDown:(NSEvent*)event |
|
|
|
{ |
|
|
|
if (puglview->mouseFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->mouseFunc(puglview, 1, false, loc.x, puglview->height - loc.y); |
|
|
|
puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), true, loc.x, loc.y); |
|
|
|
} |
|
|
|
[self updateTrackingAreas]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) rightMouseDown:(NSEvent*)event |
|
|
|
{ |
|
|
|
[self mouseDown:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) otherMouseDown:(NSEvent*)event |
|
|
|
{ |
|
|
|
[self mouseDown:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) mouseUp:(NSEvent*)event |
|
|
|
{ |
|
|
|
if (puglview->mouseFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->mouseFunc(puglview, 3, true, loc.x, puglview->height - loc.y); |
|
|
|
puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), false, loc.x, loc.y); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
- (void) rightMouseUp:(NSEvent*)event |
|
|
|
{ |
|
|
|
if (puglview->mouseFunc) { |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->mouseFunc(puglview, 3, false, loc.x, puglview->height - loc.y); |
|
|
|
} |
|
|
|
[self mouseUp:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) otherMouseUp:(NSEvent*)event |
|
|
|
{ |
|
|
|
[self mouseUp:event]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) scrollWheel:(NSEvent*)event |
|
|
|
@@ -305,10 +344,9 @@ getModifiers(PuglView* view, NSEvent* ev) |
|
|
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; |
|
|
|
puglview->mods = getModifiers(puglview, event); |
|
|
|
puglview->scrollFunc(puglview, |
|
|
|
loc.x, puglview->height - loc.y, |
|
|
|
loc.x, loc.y, |
|
|
|
[event deltaX], [event deltaY]); |
|
|
|
} |
|
|
|
[self updateTrackingAreas]; |
|
|
|
} |
|
|
|
|
|
|
|
- (void) keyDown:(NSEvent*)event |
|
|
|
@@ -368,6 +406,11 @@ puglCreateWindow(PuglView* view, const char* title) |
|
|
|
[NSApplication sharedApplication]; |
|
|
|
|
|
|
|
impl->glview = [PuglOpenGLView new]; |
|
|
|
|
|
|
|
if (!impl->glview) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
impl->glview->puglview = view; |
|
|
|
|
|
|
|
if (view->resizable) { |
|
|
|
|