diff options
Diffstat (limited to 'intern/ghost')
-rw-r--r-- | intern/ghost/SConscript | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_C-api.cpp | 19 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextCGL.h | 9 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextCGL.mm | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextGLX.cpp | 108 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_DisplayManagerX11.cpp | 5 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.h | 5 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 56 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowCocoa.mm | 27 |
9 files changed, 159 insertions, 80 deletions
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 025559e11a4..78566210047 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -48,7 +48,8 @@ sources.remove('intern' + os.sep + 'GHOST_ContextWGL.cpp') pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget', 'GHOST_NDOFManager', 'GHOST_Context'] -defs = env['BF_GL_DEFINITIONS'] +defs = [] +defs += env['BF_GL_DEFINITIONS'] if env['WITH_BF_GL_EGL']: defs.append('WITH_EGL') diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index af992bf5a3c..9baa66abad9 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -358,27 +358,20 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, int bounds[4], const int mouse_ungrab_xy[2]) { GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - GHOST_Rect bounds_rect, bounds_win; - GHOST_TInt32 mouse_ungrab_xy_global[2]; + GHOST_Rect bounds_rect; + GHOST_TInt32 mouse_xy[2]; if (bounds) { - /* if this is X11 specific we need a function that converts */ - window->getClientBounds(bounds_win); - window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t); - window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b); - + bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]); } - if (mouse_ungrab_xy) { - if (bounds == NULL) - window->getClientBounds(bounds_win); - window->clientToScreen(mouse_ungrab_xy[0], bounds_win.getHeight() - mouse_ungrab_xy[1], - mouse_ungrab_xy_global[0], mouse_ungrab_xy_global[1]); + mouse_xy[0] = mouse_ungrab_xy[0]; + mouse_xy[1] = mouse_ungrab_xy[1]; } return window->setCursorGrab(mode, bounds ? &bounds_rect : NULL, - mouse_ungrab_xy ? mouse_ungrab_xy_global : NULL); + mouse_ungrab_xy ? mouse_xy : NULL); } diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index 92fdbfc53de..953235669a8 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -128,18 +128,9 @@ public: private: //void initContextCGLEW() - /** The window containing the OpenGL view */ - NSWindow *m_window; - /** The openGL view */ NSOpenGLView *m_openGLView; - const int m_contextProfileMask; - const int m_contextMajorVersion; - const int m_contextMinorVersion; - const int m_contextFlags; - const int m_contextResetNotificationStrategy; - /** The OpenGL drawing context */ NSOpenGLContext *m_openGLContext; diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 51895e5fa1a..6a9c23ea72b 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -58,16 +58,9 @@ GHOST_ContextCGL::GHOST_ContextCGL( int contextFlags, int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), - m_window(window), m_openGLView(openGLView), - m_contextProfileMask(contextProfileMask), - m_contextMajorVersion(contextMajorVersion), - m_contextMinorVersion(contextMinorVersion), - m_contextFlags(contextFlags), - m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_openGLContext(nil) { - assert(window != nil); assert(openGLView != nil); } diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index 3cce2236143..0ee8da15dea 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -40,6 +40,13 @@ #include <cstdio> #include <cstring> +/* needed for intel drivers (works w/ mesa-swrast & nvidia) */ +#define USE_GLXEW_INIT_WORKAROUND + +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s); +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end); +#endif #ifdef WITH_GLEW_MX GLXEWContext *glxewContext = NULL; @@ -154,10 +161,54 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); #endif - /* needed so 'GLXEW_ARB_create_context' is valid */ - mxIgnoreNoVersion(1); - initContextGLXEW(); - mxIgnoreNoVersion(0); + + + /* -------------------------------------------------------------------- */ + /* Begin Inline Glew */ + +#ifdef USE_GLXEW_INIT_WORKAROUND + const GLubyte *extStart = (GLubyte *)""; + const GLubyte *extEnd; + if (glXQueryExtension(m_display, NULL, NULL)) { + extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS); + if ((extStart == NULL) || + (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXChooseFBConfig")) == NULL || + (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB( + (const GLubyte *)"glXCreateContextAttribsARB")) == NULL) + { + extStart = (GLubyte *)""; + } + } + extEnd = extStart + _glewStrLen(extStart); + +#undef GLXEW_ARB_create_context + const bool GLXEW_ARB_create_context = + _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd); +#undef GLXEW_ARB_create_context_profile + const bool GLXEW_ARB_create_context_profile = + _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd); +#undef GLXEW_ARB_create_context_robustness +const bool GLXEW_ARB_create_context_robustness = + _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd); +#ifdef WITH_GLEW_ES +#undef GLXEW_EXT_create_context_es_profile + const bool GLXEW_EXT_create_context_es_profile = + _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd); +#undef GLXEW_EXT_create_context_es2_profile + const bool GLXEW_EXT_create_context_es2_profile = + _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd); +#endif /* WITH_GLEW_ES */ + + /* End Inline Glew */ + /* -------------------------------------------------------------------- */ +#else + /* important to initialize only glxew (_not_ glew), + * since this breaks w/ Mesa's `swrast`, see: T46431 */ + glxewInit(); +#endif /* USE_GLXEW_INIT_WORKAROUND */ + + if (GLXEW_ARB_create_context) { int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; @@ -246,6 +297,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() if (framebuffer_config) { m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); + XFree(framebuffer_config); } } else { @@ -263,6 +315,10 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() glXMakeCurrent(m_display, m_window, m_context); + // Seems that this has to be called after MakeCurrent, + // which means we cannot use glX extensions until after we create a context + initContextGLXEW(); + initClearGL(); ::glXSwapBuffers(m_display, m_window); @@ -404,5 +460,49 @@ int GHOST_X11_GL_GetAttributes( GHOST_ASSERT(i <= attribs_max, "attribute size too small"); + (void)attribs_max; + return i; } + + +/* excuse inlining part of glew */ +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen(const GLubyte *s, GLubyte c) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; +} + +static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n) +{ + GLuint i = 0; + if (a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end) +{ + const GLubyte *p; + GLuint len = _glewStrLen((const GLubyte *)name); + p = start; + while (p < end) { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE; + p += n + 1; + } + return GL_FALSE; +} +#endif /* USE_GLXEW_INIT_WORKAROUND */
\ No newline at end of file diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 0cc116292c0..b3e6f2e53fa 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -117,7 +117,7 @@ getDisplaySetting( if (dpy == NULL) return GHOST_kFailure; - (void) display; + (void)display; #ifdef WITH_X11_XF86VMODE int majorVersion, minorVersion; @@ -149,6 +149,7 @@ getDisplaySetting( GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); + (void)index; setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy)); setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy)); @@ -267,6 +268,8 @@ setCurrentDisplaySetting( return GHOST_kSuccess; #else + (void)setting; + /* Just pretend the request was successful. */ return GHOST_kSuccess; #endif diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 3d6b40ee541..cfddd5b3781 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -297,9 +297,8 @@ protected: */ GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y; - /** Multitouch trackpad availability */ - bool m_hasMultiTouchTrackpad; - + /** Temporarily ignore momentum scroll events */ + bool m_ignoreMomentumScroll; }; #endif // __GHOST_SYSTEMCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b9686e5af9b..a3c48ff3b2d 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -284,7 +284,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) * CocoaAppDelegate * ObjC object to capture applicationShouldTerminate, and send quit event **/ -@interface CocoaAppDelegate : NSObject { +@interface CocoaAppDelegate : NSObject <NSFileManagerDelegate> { GHOST_SystemCocoa *systemCocoa; } - (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa; @@ -370,12 +370,11 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() rstring = (char*)malloc( len ); sysctl( mib, 2, rstring, &len, NULL, 0 ); - m_hasMultiTouchTrackpad = false; - free( rstring ); rstring = NULL; m_ignoreWindowSizedMessages = false; + m_ignoreMomentumScroll = false; } GHOST_SystemCocoa::~GHOST_SystemCocoa() @@ -1223,10 +1222,10 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) NSEvent *event = (NSEvent *)eventPtr; switch ([event subtype]) { - case NX_SUBTYPE_TABLET_POINT: + case NSTabletPointEventSubtype: handleTabletEvent(eventPtr, NSTabletPoint); return true; - case NX_SUBTYPE_TABLET_PROXIMITY: + case NSTabletProximityEventSubtype: handleTabletEvent(eventPtr, NSTabletProximity); return true; default: @@ -1317,6 +1316,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y; window->getCursorGrabInitPos(x_warp, y_warp); + window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp); window->getCursorGrabAccum(x_accum, y_accum); x_accum += [event deltaX]; @@ -1368,6 +1368,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) //Post event window->getCursorGrabInitPos(x_cur, y_cur); + window->screenToClientIntern(x_cur, y_cur, x_cur, y_cur); window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y); pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); break; @@ -1388,25 +1389,36 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } } break; - - /* these events only happen on swiping trackpads or tablets */ - /* warning: using tablet + trackpad at same time frustrates this static variable */ - case NSEventTypeBeginGesture: - m_hasMultiTouchTrackpad = 1; - break; - case NSEventTypeEndGesture: - m_hasMultiTouchTrackpad = 0; - break; - + case NSScrollWheel: { - int *momentum = NULL; + NSEventPhase momentumPhase = NSEventPhaseNone; + NSEventPhase phase = NSEventPhaseNone; + bool hasMultiTouch = false; if ([event respondsToSelector:@selector(momentumPhase)]) - momentum = (int *)[event momentumPhase]; + momentumPhase = [event momentumPhase]; + if ([event respondsToSelector:@selector(phase)]) + phase = [event phase]; + if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)]) + hasMultiTouch = [event hasPreciseScrollingDeltas]; + + /* when pressing a key while momentum scrolling continues after + * lifting fingers off the trackpad, the action can unexpectedly + * change from e.g. scrolling to zooming. this works around the + * issue by ignoring momentum scroll after a key press */ + if (momentumPhase) + { + if (m_ignoreMomentumScroll) + break; + } + else + { + m_ignoreMomentumScroll = false; + } /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ - if (!m_hasMultiTouchTrackpad && momentum == NULL) { + if (!hasMultiTouch && momentumPhase == NSEventPhaseNone) { GHOST_TInt32 delta; double deltaF = [event deltaY]; @@ -1422,16 +1434,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x, y; double dx; double dy; - + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - int phase = [event phase]; - /* with 10.7 nice scrolling deltas are supported */ dx = [event scrollingDeltaX]; dy = [event scrollingDeltaY]; /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */ - if (phase == 0 && momentum==NULL) { + if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { dx = [event deltaX]; dy = [event deltaY]; } @@ -1566,6 +1576,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) pushEvent( new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL) ); //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); } + m_ignoreMomentumScroll = true; break; case NSFlagsChanged: @@ -1585,6 +1596,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) } m_modifierMask = modifiers; + m_ignoreMomentumScroll = true; break; default: diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index f1f38cc14b3..38813e14a1b 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -393,16 +393,6 @@ enum { systemCocoa->handleMouseEvent(event); } -- (void)beginGestureWithEvent:(NSEvent *)event -{ - systemCocoa->handleMouseEvent(event); -} - -- (void)endGestureWithEvent:(NSEvent *)event -{ - systemCocoa->handleMouseEvent(event); -} - - (void)tabletPoint:(NSEvent *)event { systemCocoa->handleTabletEvent(event,[event type]); @@ -1195,18 +1185,18 @@ GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType ty #if defined(WITH_GL_PROFILE_CORE) GHOST_Context *context = new GHOST_ContextCGL( - m_initStereoVisual, - m_initNumOfAASamples, + m_wantStereoVisual, + m_wantNumOfAASamples, m_window, m_openGLView, - CGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + GL_CONTEXT_CORE_PROFILE_BIT, 3, 2, GHOST_OPENGL_CGL_CONTEXT_FLAGS, GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY); #elif defined(WITH_GL_PROFILE_ES20) GHOST_Context *context = new GHOST_ContextCGL( - m_initStereoVisual, - m_initNumOfAASamples, + m_wantStereoVisual, + m_wantNumOfAASamples, m_window, m_openGLView, CGL_CONTEXT_ES2_PROFILE_BIT_EXT, @@ -1463,12 +1453,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode if (mode != GHOST_kGrabDisable) { //No need to perform grab without warp as it is always on in OS X if (mode != GHOST_kGrabNormal) { - GHOST_TInt32 x_old,y_old; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - m_systemCocoa->getCursorPosition(x_old,y_old); - screenToClientIntern(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - //Warp position is stored in client (window base) coordinates + m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setCursorGrabAccum(0, 0); if (mode == GHOST_kGrabHide) { @@ -1486,7 +1473,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode } else { if (m_cursorGrab==GHOST_kGrabHide) { - //No need to set again cursor position, as it has not changed for Cocoa + m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setWindowCursorVisibility(true); } |