MAC/Cocoa:
authorDamien Plisson <damien.plisson@yahoo.fr>
Sun, 15 Nov 2009 08:34:31 +0000 (08:34 +0000)
committerDamien Plisson <damien.plisson@yahoo.fr>
Sun, 15 Nov 2009 08:34:31 +0000 (08:34 +0000)
- Drag'n'Drop events are now correctly signaled to the main loop for dispatch (these events were directly handled in cocoa callbacks without notifying the process loop)
- Fix timestamping of events & add debug print of drag'n'drop events.

intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
intern/ghost/intern/GHOST_EventPrinter.cpp
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_WindowCocoa.mm

index f105928c9a3c678fe64b6328642555a177e09882..99b2991df0dc5724244f19b02a7df5b691ad1373 100644 (file)
@@ -155,11 +155,11 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 d
                NULL);*/
 
 #ifdef GHOST_DEBUG
-       printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
+/*     printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
        printf("  setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
        printf("  setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
        printf("  setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
-       printf("  setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));
+       printf("  setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate)); */
 #endif // GHOST_DEBUG
 
        //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
index b4f5cc960832f8d5c1f623022e6a08fcfcd6639f..c6b3416669ea6844dbf44be4dc01e421d4d7e3d1 100644 (file)
@@ -33,6 +33,7 @@
 #include "GHOST_EventPrinter.h"
 #include <iostream>
 #include "GHOST_EventKey.h"
+#include "GHOST_EventDragnDrop.h"
 #include "GHOST_Debug.h"
 
 #ifdef HAVE_CONFIG_H
@@ -97,7 +98,77 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent* event)
                std::cout << "GHOST_kEventKeyDown, key: " << str.Ptr();
                }
                break;
+                       
+       case GHOST_kEventDraggingEntered:
+               {
+                       GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
+                       std::cout << "GHOST_kEventDraggingEntered, dragged object type : " << dragnDropData->dataType;
+                       std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
+               }
+               break;
+                       
+       case GHOST_kEventDraggingUpdated:
+               {
+                       GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
+                       std::cout << "GHOST_kEventDraggingUpdated, dragged object type : " << dragnDropData->dataType;
+                       std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
+               }
+               break;
 
+       case GHOST_kEventDraggingExited:
+               {
+                       GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
+                       std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType;
+               }
+               break;
+       
+       case GHOST_kEventDraggingDropDone:
+               {
+                       GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
+                       std::cout << "GHOST_kEventDraggingDropDone, dragged object type : " << dragnDropData->dataType;
+                       std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
+                       switch (dragnDropData->dataType) {
+                               case GHOST_kDragnDropTypeString:
+                                       std::cout << " string received = " << (char*)dragnDropData->data;
+                                       break;
+                               case GHOST_kDragnDropTypeFilenames:
+                               {
+                                       GHOST_TStringArray *strArray = (GHOST_TStringArray*)dragnDropData->data;
+                                       int i;
+                                       std::cout << "\nReceived " << strArray->count << " filenames";
+                                       for (i=0;i<strArray->count;i++)
+                                               std::cout << " Filename #" << i << ": " << strArray->strings[i];
+                               }
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               break;
+
+       case GHOST_kEventDraggingDropOnIcon:
+               {
+                       GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
+                       std::cout << "GHOST_kEventDraggingDropOnIcon, dragged object type : " << dragnDropData->dataType;
+                       switch (dragnDropData->dataType) {
+                               case GHOST_kDragnDropTypeString:
+                                       std::cout << " string received = " << (char*)dragnDropData->data;
+                                       break;
+                               case GHOST_kDragnDropTypeFilenames:
+                               {
+                                       GHOST_TStringArray *strArray = (GHOST_TStringArray*)dragnDropData->data;
+                                       int i;
+                                       std::cout << "\nReceived " << strArray->count << " filenames";
+                                       for (i=0;i<strArray->count;i++)
+                                               std::cout << " Filename #" << i << ": " << strArray->strings[i];
+                               }
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               break;
+                       
        case GHOST_kEventQuit:
                std::cout << "GHOST_kEventQuit"; 
                break;
index 5ba3a2b373ba55bd3c853523ebe1e52cef10506c..684f028a8333783e4c35c5218714ffcd93818338 100644 (file)
@@ -246,6 +246,9 @@ protected:
        /** Start time at initialization. */
        GHOST_TUns64 m_start_time;
        
+       /** Event has been processed directly by Cocoa and has sent a ghost event to be dispatched */
+       bool m_outsideLoopEventProcessed;
+       
        /** Mouse buttons state */
        GHOST_TUns32 m_pressedMouseButtons;
        
index 5e504f0d6ab10d74ea78798f0f866055a0e1979d..b31db472ef16d90addfaa2ee8a382bc04b401db2 100644 (file)
@@ -449,12 +449,12 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
        m_pressedMouseButtons =0;
        m_cursorDelta_x=0;
        m_cursorDelta_y=0;
+       m_outsideLoopEventProcessed = false;
        m_displayManager = new GHOST_DisplayManagerCocoa ();
        GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
        m_displayManager->initialize();
 
        //NSEvent timeStamp is given in system uptime, state start date is boot time
-       //FIXME : replace by Cocoa equivalent
        int mib[2];
        struct timeval boottime;
        size_t len;
@@ -560,17 +560,13 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
 GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
 {
        //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])
-       int mib[2];
-       struct timeval boottime;
-       size_t len;
+       struct timeval currentTime;
        
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_BOOTTIME;
-       len = sizeof(struct timeval);
+       gettimeofday(&currentTime, NULL);
        
-       sysctl(mib, 2, &boottime, &len, NULL, 0);
-
-       return ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
+       //Return timestamp of system uptime
+       
+       return ((currentTime.tv_sec*1000)+(currentTime.tv_usec/1000)-m_start_time);
 }
 
 
@@ -744,6 +740,8 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
        bool anyProcessed = false;
        NSEvent *event;
        
+       m_outsideLoopEventProcessed = false;
+       
        //      SetMouseCoalescingEnabled(false, NULL);
        //TODO : implement timer ??
        
@@ -842,7 +840,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
        
        
        
-    return anyProcessed;
+    return anyProcessed || m_outsideLoopEventProcessed;
 }
 
 //Note: called from NSWindow delegate
@@ -879,6 +877,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
                                return GHOST_kFailure;
                                break;
                }
+       
+       m_outsideLoopEventProcessed = true;
        return GHOST_kSuccess;
 }
 
@@ -895,7 +895,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
                        setAcceptDragOperation(FALSE); //Drag operation needs to be accepted explicitely by the event manager
                case GHOST_kEventDraggingUpdated:
                case GHOST_kEventDraggingExited:
-                       pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),GHOST_kEventDraggingEntered,draggedObjectType,window,mouseX,mouseY,NULL));
+                       pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),eventType,draggedObjectType,window,mouseX,mouseY,NULL));
                        break;
                        
                case GHOST_kEventDraggingDropDone:
@@ -969,12 +969,13 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
                                        return GHOST_kFailure;
                                        break;
                        }
-                       pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),GHOST_kEventDraggingEntered,draggedObjectType,window,mouseX,mouseY,eventData));
+                       pushEvent(new GHOST_EventDragnDrop(getMilliSeconds(),eventType,draggedObjectType,window,mouseX,mouseY,eventData));
                }
                        break;
                default:
                        return GHOST_kFailure;
        }
+       m_outsideLoopEventProcessed = true;
        return GHOST_kSuccess;
 }
 
@@ -1007,6 +1008,7 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
        }
        else {
                pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
+               m_outsideLoopEventProcessed = true;
                return GHOST_kExitNow;
        }
        
@@ -1079,7 +1081,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                case NSLeftMouseDown:
                case NSRightMouseDown:
                case NSOtherMouseDown:
-                       pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
+                       pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
                        //Handle tablet events combined with mouse events
                        switch ([event subtype]) {
                                case NX_SUBTYPE_TABLET_POINT:
@@ -1097,7 +1099,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                case NSLeftMouseUp:
                case NSRightMouseUp:
                case NSOtherMouseUp:
-                       pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
+                       pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
                        //Handle tablet events combined with mouse events
                        switch ([event subtype]) {
                                case NX_SUBTYPE_TABLET_POINT:
@@ -1141,7 +1143,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                                y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
                                                window->setCursorGrabAccum(x_accum, y_accum);
                                                
-                                               pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
+                                               pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
                                        }
                                                break;
                                        case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
@@ -1185,14 +1187,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                                
                                                //Post event
                                                window->getCursorGrabInitPos(x_cur, y_cur);
-                                               pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum));
+                                               pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum));
                                        }
                                                break;
                                        default:
                                        {
                                                //Normal cursor operation: send mouse position in window
                                                NSPoint mousePos = [event locationInWindow];
-                                               pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
+                                               pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
                                                m_cursorDelta_x=0;
                                                m_cursorDelta_y=0; //Mouse motion occured between two cursor warps, so we can reset the delta counter
                                        }
@@ -1208,7 +1210,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                if (deltaF == 0.0) break; //discard trackpad delta=0 events
                                
                                delta = deltaF > 0.0 ? 1 : -1;
-                               pushEvent(new GHOST_EventWheel([event timestamp], window, delta));
+                               pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta));
                        }
                        break;
                        
@@ -1267,26 +1269,26 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
                                break; //Cmd-Q is directly handled by Cocoa
 
                        if ([event type] == NSKeyDown) {
-                               pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) );
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyDown, window, keyCode, ascii) );
                                //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii);
                        } else {
-                               pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyUp, window, keyCode, ascii) );
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyUp, window, keyCode, ascii) );
                        }
                        break;
        
                case NSFlagsChanged: 
                        modifiers = [event modifierFlags];
                        if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
                        }
                        if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
                        }
                        if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
                        }
                        if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
                        }
                        
                        m_modifierMask = modifiers;
index 459a4a54ee31fe536d2fa32e65be1a22e59f6bbf..54a62636895065d46f31b6e02a52ef52243b1668 100644 (file)
@@ -157,6 +157,10 @@ extern "C" {
        return NSDragOperationCopy;
 }
 
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+       return NO; //No need to overflow blender event queue. Events shall be sent only on changes
+}
 
 - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
 {