diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 28fa72f9700..a64ca292343 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -35,6 +35,7 @@ #define GHOST_C_API_H #include "GHOST_Types.h" +#include #ifdef __cplusplus extern "C" { @@ -837,6 +838,12 @@ extern GHOST_TUns8* GHOST_getClipboard(int selection); extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection); +extern GHOST_TSuccess GHOST_RecordEvents(GHOST_SystemHandle systemhandle, FILE *file); +extern GHOST_TSuccess GHOST_StopRecording(GHOST_SystemHandle systemhandle); +extern GHOST_TSuccess GHOST_PlaybackEvents(GHOST_SystemHandle systemhandle, FILE *file); +extern int GHOST_PlayingEvents(GHOST_SystemHandle systemhandle); +extern int GHOST_RecordingEvents(GHOST_SystemHandle systemhandle); + #ifdef __cplusplus } #endif diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h index dae645c8943..097ed34fc4e 100644 --- a/intern/ghost/GHOST_IEvent.h +++ b/intern/ghost/GHOST_IEvent.h @@ -34,8 +34,8 @@ #define _GHOST_IEVENT_H_ #include "GHOST_Types.h" - -class GHOST_IWindow; +#include "GHOST_IWindow.h" +#include "intern/GHOST_ModifierKeys.h" /** * Interface class for events received from GHOST. @@ -71,6 +71,13 @@ public: */ virtual GHOST_TUns64 getTime() = 0; + virtual void setTime(GHOST_TUns64 t) = 0; + + virtual void setPlaybackModifierKeys(GHOST_ModifierKeys keys) = 0; + virtual void getPlaybackModifierKeys(GHOST_ModifierKeys &keys) = 0; + virtual void setPlaybackCursor(GHOST_TInt32 x, GHOST_TInt32 y) = 0; + virtual void getPlaybackCursor(GHOST_TInt32 &x, GHOST_TInt32 &y) = 0; + /** * Returns the window this event was generated on, * or NULL if it is a 'system' event. @@ -83,6 +90,17 @@ public: * @return The event data. */ virtual GHOST_TEventDataPtr getData() = 0; + + virtual int serialize(char buf[256]) + { + return 0; + } + + int writeheader(char buf[256]) + { + sprintf(buf, "%lf %d %d", ((double)this->getTime())*0.001, this->getType(), this->getWindow()->getID()); + return 0; + } }; #endif // _GHOST_IEVENT_H_ diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 47f142e4c8a..14339c0ffb2 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -275,6 +275,13 @@ public: /*************************************************************************************** ** Event management functionality ***************************************************************************************/ + + virtual GHOST_TSuccess beginRecord(FILE *file) = 0; + virtual GHOST_TSuccess endRecord() = 0; + virtual GHOST_TSuccess playbackEvents(FILE *file) = 0; + + virtual bool playingEvents(bool *hasevent) const = 0; + virtual bool recordingEvents() = 0; /** * Retrieves events from the system and stores them in the queue. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 83757b17e8b..692d6e05d4d 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -65,6 +65,17 @@ public: virtual ~GHOST_IWindow() { } + + GHOST_IWindow() + { + static int id = 0; + m_id = id++; + } + + virtual int getID() + { + return m_id; + } /** * Returns indication as to whether the window is valid. @@ -305,6 +316,8 @@ public: */ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; }; +private: + int m_id; }; #endif // _GHOST_IWINDOW_H_ diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 839d85c9617..4e231d6eb48 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -95,6 +95,39 @@ GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle, return (GHOST_TimerTaskHandle) system->installTimer(delay, interval, timerproc, userdata); } +GHOST_TSuccess GHOST_RecordEvents(GHOST_SystemHandle systemhandle, FILE *file) +{ + GHOST_ISystem* system = (GHOST_ISystem*) systemhandle; + + return system->beginRecord(file); +} + +GHOST_TSuccess GHOST_StopRecording(GHOST_SystemHandle systemhandle) +{ + GHOST_ISystem* system = (GHOST_ISystem*) systemhandle; + + return system->endRecord(); +} + +GHOST_TSuccess GHOST_PlaybackEvents(GHOST_SystemHandle systemhandle, FILE *file) +{ + GHOST_ISystem* system = (GHOST_ISystem*) systemhandle; + + return system->playbackEvents(file); +} + +int GHOST_PlayingEvents(GHOST_SystemHandle systemhandle) +{ + GHOST_ISystem* system = (GHOST_ISystem*) systemhandle; + return system->playingEvents(NULL); +} + +int GHOST_RecordingEvents(GHOST_SystemHandle systemhandle) +{ + GHOST_ISystem* system = (GHOST_ISystem*) systemhandle; + + return system->recordingEvents(); +} GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle, diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h index 76cdb96d040..206cace3fa4 100644 --- a/intern/ghost/intern/GHOST_Event.h +++ b/intern/ghost/intern/GHOST_Event.h @@ -35,6 +35,14 @@ #include "GHOST_IEvent.h" +/* INTEGER CODES */ +#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__BIG_ENDIAN__) + /* Big Endian */ +#define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#else + /* Little Endian */ +#define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) +#endif /** * Base class for events received the operating system. @@ -73,6 +81,12 @@ public: return m_time; } + virtual void setTime(GHOST_TUns64 t) + { + m_time = t; + } + + /** * Returns the window this event was generated on, * or NULL if it is a 'system' event. @@ -91,7 +105,29 @@ public: { return m_data; } + + virtual void setPlaybackModifierKeys(GHOST_ModifierKeys keys) + { + m_playmods = keys; + } + virtual void getPlaybackModifierKeys(GHOST_ModifierKeys &keys) + { + keys = m_playmods; + } + + virtual void setPlaybackCursor(GHOST_TInt32 mx, GHOST_TInt32 my) + { + x = mx; + y = my; + } + + virtual void getPlaybackCursor(GHOST_TInt32 &mx, GHOST_TInt32 &my) + { + mx = x; + my = y; + } + protected: /** Type of this event. */ GHOST_TEventType m_type; @@ -101,6 +137,11 @@ protected: GHOST_IWindow* m_window; /** Pointer to the event data. */ GHOST_TEventDataPtr m_data; + + /** Modifier key state during event playback **/ + GHOST_ModifierKeys m_playmods; + /** Mouse cursor state during event playback **/ + GHOST_TInt32 x, y; }; #endif // _GHOST_EVENT_H_ diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h index d8631ea47e4..2adec231290 100644 --- a/intern/ghost/intern/GHOST_EventButton.h +++ b/intern/ghost/intern/GHOST_EventButton.h @@ -58,6 +58,23 @@ public: m_data = &m_buttonEventData; } + virtual int serialize(char buf[256]) + { + sprintf(buf, "button mask: %d", m_buttonEventData.button); + + return 0; + } + + GHOST_EventButton(GHOST_TUns64 time, GHOST_TEventType type, GHOST_IWindow* window, char buf[256]) + : GHOST_Event(time, type, window) + { + int i; + sscanf(buf, "button mask: %d", &i); + + m_buttonEventData.button = (GHOST_TButtonMask)i; + m_data = &m_buttonEventData; + } + protected: /** The button event data. */ GHOST_TEventButtonData m_buttonEventData; diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h index 5390e3b2253..f77df2cfae0 100644 --- a/intern/ghost/intern/GHOST_EventCursor.h +++ b/intern/ghost/intern/GHOST_EventCursor.h @@ -58,6 +58,24 @@ public: m_data = &m_cursorEventData; } + GHOST_EventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256]) + : GHOST_Event(msec, type, window) + { + int x, y; + sscanf(buf, "mousecursor: %d %d", &x, &y); + + m_cursorEventData.x = x; + m_cursorEventData.y = y; + m_data = &m_cursorEventData; + } + + virtual int serialize(char buf[256]) + { + sprintf(buf, "mousecursor: %d %d", m_cursorEventData.x, m_cursorEventData.y); + + return 0; + } + protected: /** The x,y-coordinates of the cursor position. */ GHOST_TEventCursorData m_cursorEventData; diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h index 87e4ca559a8..097838eb5e3 100644 --- a/intern/ghost/intern/GHOST_EventKey.h +++ b/intern/ghost/intern/GHOST_EventKey.h @@ -71,7 +71,24 @@ public: m_keyEventData.ascii = ascii; m_data = &m_keyEventData; } + + GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256]) + : GHOST_Event(msec, type, window) + { + int key, ascii; + sscanf(buf, "key: %d %d", &key, &ascii); + m_keyEventData.key = (GHOST_TKey) key; + m_keyEventData.ascii = ascii; + m_data = &m_keyEventData; + } + + virtual int serialize(char buf[256]) + { + sprintf(buf, "key: %d %d", m_keyEventData.key, m_keyEventData.ascii); + + return 0; + } protected: /** The key event data. */ GHOST_TEventKeyData m_keyEventData; diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp index 0eeb2245cd0..c50a40a2971 100644 --- a/intern/ghost/intern/GHOST_EventManager.cpp +++ b/intern/ghost/intern/GHOST_EventManager.cpp @@ -38,9 +38,20 @@ #include #include "GHOST_Debug.h" +#include "GHOST_System.h" +#include "GHOST_IWindow.h" +#include "GHOST_WindowManager.h" +#include "GHOST_Event.h" +#include "GHOST_EventButton.h" +#include "GHOST_EventCursor.h" +#include "GHOST_EventKey.h" +#include "GHOST_EventWheel.h" +#include "GHOST_EventTrackpad.h" GHOST_EventManager::GHOST_EventManager() { + m_playfile = m_recfile = NULL; + m_lasttime = 0; } @@ -87,6 +98,33 @@ GHOST_IEvent* GHOST_EventManager::peekEvent() return event; } + +GHOST_TSuccess GHOST_EventManager::beginRecord(FILE *file) +{ + if (m_playfile || !file) + return GHOST_kFailure; + + m_recfile = file; + return GHOST_kSuccess; +} + +GHOST_TSuccess GHOST_EventManager::endRecord() +{ + if (!m_recfile) + return GHOST_kFailure; + + m_recfile = NULL; + return GHOST_kSuccess; +} + +GHOST_TSuccess GHOST_EventManager::playbackEvents(FILE *file) +{ + if (m_recfile || !file) + return GHOST_kFailure; + + m_playfile = file; + return GHOST_kSuccess; +} GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event) { @@ -95,6 +133,39 @@ GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event) if (m_events.size() < m_events.max_size()) { m_events.push_front(event); success = GHOST_kSuccess; + if (m_recfile) { + GHOST_System *sys; + GHOST_ModifierKeys keys; + GHOST_TInt32 x, y; + char buf[256]; + + sys = reinterpret_cast(GHOST_ISystem::getSystem()); + + /*write event parent class data*/ + event->writeheader(buf); + fprintf(m_recfile, "%s\n", buf); + + /*write child class data*/ + event->serialize(buf); + fprintf(m_recfile, "%s\n", buf); + + /*write modifier key states*/ + sys->getModifierKeys(keys); + fprintf(m_recfile, "lshift: %d rshift: %d lalt: %d ralt: %d lctrl: %d rctrl: %d command: %d\n", + (int)keys.get(GHOST_kModifierKeyLeftShift), + (int)keys.get(GHOST_kModifierKeyRightShift), + (int)keys.get(GHOST_kModifierKeyLeftAlt), + (int)keys.get(GHOST_kModifierKeyRightAlt), + (int)keys.get(GHOST_kModifierKeyLeftControl), + (int)keys.get(GHOST_kModifierKeyRightControl), + (int)keys.get(GHOST_kModifierKeyCommand)); + fflush(m_recfile); + + sys->getCursorPosition(x, y); + + /*write mouse cursor state*/ + fprintf(m_recfile, "mcursorstate: %d %d\n", x, y); + } } else { success = GHOST_kFailure; @@ -121,6 +192,21 @@ bool GHOST_EventManager::dispatchEvent(GHOST_IEvent* event) return handled; } +bool GHOST_EventManager::playingEvents(bool *hasevent) { + if (hasevent && m_events.size()) { + GHOST_IEvent *event = m_events[m_events.size()-1]; + GHOST_System *sys; + + sys = reinterpret_cast(GHOST_ISystem::getSystem()); + *hasevent = event->getType()==0 || sys->getMilliSeconds()-m_lasttime > event->getTime(); + + if (event->getType()==0) + popEvent(); + } else if (hasevent) + *hasevent = true; + + return m_playfile != NULL; +} bool GHOST_EventManager::dispatchEvent() { @@ -136,18 +222,200 @@ bool GHOST_EventManager::dispatchEvent() bool GHOST_EventManager::dispatchEvents() { - bool handled; - if (getNumEvents()) { - handled = true; - while (getNumEvents()) { - if (!dispatchEvent()) { - handled = false; + bool handled = false; + + if (m_recfile && getNumEvents()) { + fprintf(m_recfile, "break\n"); + } + + if (m_playfile) { + GHOST_IEvent *event = NULL; + GHOST_System *sys; + GHOST_WindowManager *wm; + GHOST_TInt32 x, y; + GHOST_ModifierKeys modkeys; + std::vector windows; + double lasttime = -1.0; + char buf[256], *str; + + sys = reinterpret_cast(GHOST_ISystem::getSystem()); + wm = sys->getWindowManager(); + windows = wm->getWindows(); + + while (str = fgets(buf, 256, m_playfile)) { + GHOST_IWindow *iwin = NULL; + GHOST_TEventType type; + double time; + int winid, i; + int ctype; + + event = NULL; + + if (strcmp(str, "break\n")==0) { + event = new GHOST_Event(0, GHOST_kEventUnknown, NULL); + pushEvent(event); + continue; + } + + sscanf(str, "%lf %d %d", &time, &ctype, &winid); + type = (GHOST_TEventType)(ctype); + + if (lasttime > 0.0) { + double t = time; + + time -= lasttime; + lasttime = t; + } else lasttime = time; + + for (i=0; igetID() == winid) + break; + } + + if (i == windows.size()) { + printf("Eek! Could not find window %d!\n", winid); + str = fgets(buf, 256, m_playfile); + continue; + } + + iwin = windows[i]; + + str = fgets(buf, 256, m_playfile); + if (!str) + break; + + switch (type) { + case GHOST_kEventCursorMove: + event = new GHOST_EventCursor(time*1000, type, iwin, str); + break; + case GHOST_kEventButtonDown: + event = new GHOST_EventButton(time*1000, type, iwin, str); + break; + case GHOST_kEventButtonUp: + event = new GHOST_EventButton(time*1000, type, iwin, str); + break; + case GHOST_kEventWheel: + event = new GHOST_EventWheel(time*1000, type, iwin, str); + break; + case GHOST_kEventTrackpad: + event = new GHOST_EventTrackpad(time*1000, type, iwin, str); + break; + + case GHOST_kEventNDOFMotion: + break; + case GHOST_kEventNDOFButton: + break; + + case GHOST_kEventKeyDown: + event = new GHOST_EventKey(time*1000, type, iwin, str); + break; + case GHOST_kEventKeyUp: + event = new GHOST_EventKey(time*1000, type, iwin, str); + break; + // case GHOST_kEventKeyAuto: + + case GHOST_kEventQuit: + break; + + case GHOST_kEventWindowClose: + break; + case GHOST_kEventWindowActivate: + break; + case GHOST_kEventWindowDeactivate: + break; + case GHOST_kEventWindowUpdate: + break; + case GHOST_kEventWindowSize: + break; + case GHOST_kEventWindowMove: + break; + + case GHOST_kEventDraggingEntered: + break; + case GHOST_kEventDraggingUpdated: + break; + case GHOST_kEventDraggingExited: + break; + case GHOST_kEventDraggingDropDone: + break; + + case GHOST_kEventOpenMainFile: + break; + + case GHOST_kEventTimer: + break; + } + + str = fgets(buf, 256, m_playfile); + if (str) { + int lshift, rshift, lalt, ralt, lctrl, rctrl, command; + sscanf(str, "lshift: %d rshift: %d lalt: %d ralt: %d lctrl: %d rctrl: %d command: %d", + &lshift, &rshift, &lalt, &ralt, &lctrl, &rctrl, &command); + modkeys.set(GHOST_kModifierKeyLeftShift, lshift); + modkeys.set(GHOST_kModifierKeyRightShift, rshift); + modkeys.set(GHOST_kModifierKeyLeftAlt, lalt); + modkeys.set(GHOST_kModifierKeyRightAlt, ralt); + modkeys.set(GHOST_kModifierKeyLeftControl, lctrl); + modkeys.set(GHOST_kModifierKeyRightControl, rctrl); + modkeys.set(GHOST_kModifierKeyCommand, command); + } + + str = fgets(buf, 256, m_playfile); + if (str) { + /*read mouse cursor state*/ + sscanf(str, "mcursorstate: %d %d", &x, &y); + } + + if (event) { + event->setPlaybackCursor(x, y); + event->setPlaybackModifierKeys(modkeys); + pushEvent(event); } } + + if (getNumEvents()) { + handled = true; + while (getNumEvents()) { + event = m_events[m_events.size()-1]; + //event->geTime() stores delay between last event and this one + if (event->getType() == 0 || sys->getMilliSeconds()-m_lasttime < event->getTime()) { + handled = false; + + if (event->getType() == 0) + popEvent(); + break; + } + + //change event->time from delay-since-last-event to + //current system timevoid + m_lasttime = sys->getMilliSeconds(); + event->setTime(m_lasttime); + + event->getPlaybackModifierKeys(m_playmods); + event->getPlaybackCursor(m_x, m_y); + + if (!dispatchEvent()) { + handled = false; + } + } + } else { + handled = false; + m_playfile = NULL; + } + } else { + if (getNumEvents()) { + handled = true; + while (getNumEvents()) { + if (!dispatchEvent()) { + handled = false; + } + } + } + else { + handled = false; + } } - else { - handled = false; - } + return handled; } diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h index 40ba133e8fd..da6b281fe26 100644 --- a/intern/ghost/intern/GHOST_EventManager.h +++ b/intern/ghost/intern/GHOST_EventManager.h @@ -35,9 +35,10 @@ #include #include +#include #include "GHOST_IEventConsumer.h" - +#include "GHOST_ModifierKeys.h" /** * Manages an event stack and a list of event consumers. @@ -87,7 +88,31 @@ public: * @param event The event to push on the stack. */ virtual GHOST_TSuccess pushEvent(GHOST_IEvent* event); - + + virtual GHOST_TSuccess beginRecord(FILE *file); + virtual GHOST_TSuccess endRecord(); + virtual GHOST_TSuccess playbackEvents(FILE *file); + + virtual bool playingEvents(bool *hasevent); + + virtual bool recordingEvents() { + return m_recfile != NULL; + } + + /** only used during playback **/ + virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const + { + keys = m_playmods; + return GHOST_kSuccess; + } + + /** only used during playback **/ + virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const + { + x = m_x; + y = m_y; + } + /** * Dispatches the given event directly, bypassing the event stack. * @return Indication as to whether any of the consumers handled the event. @@ -168,6 +193,13 @@ protected: /** The list with event consumers. */ TConsumerVector m_consumers; +private: + /** used for playback functionality**/ + FILE *m_recfile; + FILE *m_playfile; + GHOST_ModifierKeys m_playmods; + GHOST_TUns64 m_lasttime; + GHOST_TInt32 m_x, m_y; }; #endif // _GHOST_EVENT_MANAGER_H_ diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h index cd32d16f428..29af361d4f6 100644 --- a/intern/ghost/intern/GHOST_EventTrackpad.h +++ b/intern/ghost/intern/GHOST_EventTrackpad.h @@ -60,7 +60,27 @@ public: m_trackpadEventData.deltaY = deltaY; m_data = &m_trackpadEventData; } - + + GHOST_EventTrackpad(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256]) + : GHOST_Event(msec, type, window) + { + int subtype, x, y, dx, dy; + sscanf(buf, "trackpad: %d %d %d %d %d", &subtype, &x, &y, &dx, &dy); + + m_trackpadEventData.subtype = (GHOST_TTrackpadEventSubTypes) subtype; + m_trackpadEventData.x = x; + m_trackpadEventData.y = y; + m_trackpadEventData.deltaX = dx; + m_trackpadEventData.deltaY = dy; + m_data = &m_trackpadEventData; + } + + virtual int serialize(char buf[256]) + { + sprintf(buf, "trackpad: %d %d %d %d %d", m_trackpadEventData.subtype, m_trackpadEventData.x, m_trackpadEventData.y, m_trackpadEventData.deltaX, m_trackpadEventData.deltaY); + + return 0; + } protected: /** The mouse pan data */ GHOST_TEventTrackpadData m_trackpadEventData; diff --git a/intern/ghost/intern/GHOST_EventWheel.h b/intern/ghost/intern/GHOST_EventWheel.h index 55e9dfb00cf..3c0f1cb1c32 100644 --- a/intern/ghost/intern/GHOST_EventWheel.h +++ b/intern/ghost/intern/GHOST_EventWheel.h @@ -58,6 +58,22 @@ public: m_data = &m_wheelEventData; } + GHOST_EventWheel(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256]) + : GHOST_Event(msec, type, window) + { + int z; + sscanf(buf, "wheel: %d", &z); + + m_wheelEventData.z = z; + m_data = &m_wheelEventData; + } + + virtual int serialize(char buf[256]) + { + sprintf(buf, "wheel: %d", m_wheelEventData.z); + + return 0; + } protected: /** The z-displacement of the mouse wheel. */ GHOST_TEventWheelData m_wheelEventData; diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index c89534e01c5..dee81bc225d 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -222,10 +222,37 @@ GHOST_TSuccess GHOST_System::addEventConsumer(GHOST_IEventConsumer* consumer) } + GHOST_TSuccess GHOST_System::beginRecord(FILE *file) + { + return this->m_eventManager->beginRecord(file); + } + + GHOST_TSuccess GHOST_System::endRecord() + { + return this->m_eventManager->endRecord(); + } + + GHOST_TSuccess GHOST_System::playbackEvents(FILE *file) + { + return this->m_eventManager->playbackEvents(file); + } + + + bool GHOST_System::playingEvents(bool *hasevent) const + { + return this->m_eventManager->playingEvents(hasevent); + } + + bool GHOST_System::recordingEvents() + { + return this->m_eventManager->recordingEvents(); + } + + GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent* event) { GHOST_TSuccess success; - if (m_eventManager) { + if (m_eventManager && !m_eventManager->playingEvents(NULL)) { success = m_eventManager->pushEvent(event); } else { diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index a18670738fe..dd8cb1f0778 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -236,6 +236,13 @@ public: ** Other (internal) functionality. ***************************************************************************************/ + virtual GHOST_TSuccess beginRecord(FILE *file); + virtual GHOST_TSuccess endRecord(); + virtual GHOST_TSuccess playbackEvents(FILE *file); + + virtual bool playingEvents(bool *hasevent) const; + virtual bool recordingEvents(); + /** * Pushes an event on the stack. * To dispatch it, call dispatchEvent() or dispatchEvents(). diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 961a637e616..6b430e45a0b 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -388,6 +388,10 @@ processEvents( bool anyProcessed = false; + if (playingEvents(&anyProcessed)) { + return anyProcessed; + } + do { GHOST_TimerManager* timerMgr = getTimerManager(); @@ -835,7 +839,10 @@ GHOST_SystemX11:: getModifierKeys( GHOST_ModifierKeys& keys ) const { - + if (this->playingEvents(NULL)) { + return getEventManager()->getModifierKeys(keys); + } + // analyse the masks retuned from XQueryPointer. memset((void *)m_keyboard_vector,0,sizeof(m_keyboard_vector)); @@ -946,7 +953,11 @@ getCursorPosition( Window root_return, child_return; int rx,ry,wx,wy; unsigned int mask_return; - + + if (playingEvents(NULL)) { + return getEventManager()->getCursorPosition(x, y); + } + if (XQueryPointer( m_display, RootWindow(m_display,DefaultScreen(m_display)), diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index d93bfc3a604..76a585fba04 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -263,7 +263,10 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list); //stupid compiler flag isn't working //remember to undef this later +#ifndef EVENT_RECORDER #define EVENT_RECORDER +#endif + #ifdef EVENT_RECORDER #include diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 764ba058a7a..4b1ea2809bc 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -47,6 +47,10 @@ #include "BKE_main.h" #include "BKE_screen.h" +#ifdef EVENT_RECORDER +#include "../../../../intern/ghost/GHOST_C-api.h" +#endif + #ifndef DISABLE_PYTHON #include "BPY_extern.h" #endif @@ -108,14 +112,21 @@ bContext *CTX_copy(const bContext *C) } #ifdef EVENT_RECORDER +extern GHOST_SystemHandle g_system; + int CTX_rec_events(bContext *C) { - return C->evtrec; + return GHOST_RecordingEvents(g_system); } int CTX_rec_events_set(bContext *C, int state) { - C->evtrec = state; + FILE *f = CTX_rec_file(C); + + if (GHOST_RecordingEvents(g_system) && !state) + GHOST_StopRecording(g_system); + else if (!GHOST_RecordingEvents(g_system) && state) + GHOST_RecordEvents(g_system, f); return 1; } @@ -128,25 +139,20 @@ FILE *CTX_rec_file(bContext *C) return f; } -double CTX_rec_lasttime(bContext *C, double newtime) -{ - double ret; - - if (C->evtlasttime == 0.0) { - ret = newtime; - } else ret = C->evtlasttime; - - C->evtlasttime = newtime; - - return ret; -} - int CTX_set_events_path(bContext *C, char *path) { - if (!path) + if (!path) { C->evtplaypath[0] = 0; - else + } else { + FILE *file = fopen(path, "rb"); + + if (!file) + return 0; + strcpy(C->evtplaypath, path); + if (g_system) + GHOST_PlaybackEvents(g_system, file); + } return 1; } @@ -156,8 +162,8 @@ int CTX_play_events(bContext *C, char **playpath) { if (playpath) *playpath = C->evtplaypath[0] ? C->evtplaypath : NULL; - - return C->evtplaypath[0]; + + return GHOST_PlayingEvents(g_system); } #endif diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 1bdd042f5d5..782d55c480a 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -258,6 +258,8 @@ int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2, float } } } + + return 0; } /*used for testing. returns an error string the two meshes don't match*/ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 97cc67fae57..6c056ea5c92 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -72,10 +72,6 @@ #include "wm_event_types.h" #include "wm_draw.h" -#ifdef EVENT_RECORDER -int erec_playing = 0; -#endif - /* ************ event management ************** */ void wm_event_add(wmWindow *win, wmEvent *event_to_add) @@ -1589,11 +1585,6 @@ void wm_event_do_handlers(bContext *C) wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win; -#ifdef EVENT_RECORDER - static FILE *file = NULL; - char *fpath = NULL; -#endif - for(win= wm->windows.first; win; win= win->next) { wmEvent *event; @@ -1630,82 +1621,11 @@ void wm_event_do_handlers(bContext *C) } } -#ifdef EVENT_RECORDER - if (CTX_play_events(C, &fpath) && fpath) - { - wmEvent evt; - double nextdelay = 0.0; - - erec_playing = 1; - - if (!file) - file= fopen(fpath, "rb"); - - while (file && !feof(file)) { - char buf1[6]; - fread(buf1, 5, 1, file); - buf1[5] = 0; - - if (strcasecmp(buf1, "event")) { - if (!strcasecmp(buf1, "break")) - break; - - fprintf(stderr, "EEK! bad event playback file!!"); - break; - } - - fread(&evt, sizeof(*event), 1, file); - - /*add in artifical delay after button open events*/ - if (!evt.customdata) { - evt.delay += nextdelay; - nextdelay = 0.0; - } - - if (evt.type == EVT_BUT_OPEN) - nextdelay = 1.0; - - /*don't do anything if theres customdata in the - event*/ - if (evt.customdata) - continue; - - wm_event_add(win, &evt); - } - - if (file && feof(file)) { - erec_playing = 0; - fclose(file); - CTX_set_events_path(C, NULL); - } - } -#endif - if (win->lasttime == 0.0) win->lasttime = PIL_check_seconds_timer(); while( (event= win->queue.first) ) { int action = WM_HANDLER_CONTINUE; -#if 1 - /*used for hackish recorder playback*/ - while (event->delay>0.0 && PIL_check_seconds_timer() - - win->lasttime < event->delay) ; - -#endif -#ifdef EVENT_RECORDER - if (CTX_rec_events(C) && !CTX_play_events(C, NULL)) { - FILE *file = CTX_rec_file(C); - char tag[6] = "event"; - double delay = PIL_check_seconds_timer(); - - delay -= CTX_rec_lasttime(C, delay); - event->delay = delay; - - fwrite(tag, sizeof(tag)-1, 1, file); - fwrite(event, sizeof(*event), 1, file); - fflush(file); - } -#endif if((G.f & G_DEBUG) && event && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) printf("pass on evt %d val %d\n", event->type, event->val); @@ -1842,22 +1762,9 @@ void wm_event_do_handlers(bContext *C) win->lasttime = PIL_check_seconds_timer(); } -#ifdef EVENT_RECORDER - if (CTX_rec_events(C) && !CTX_play_events(C, NULL)) { - FILE *file = CTX_rec_file(C); - char tag[6] = "break"; - - fwrite(tag, 5, 1, file); - fflush(file); - } -#endif /* only add mousemove when queue was read entirely */ -#ifdef EVENT_RECORDER - if(win->addmousemove && win->eventstate && !erec_playing) { -#else if(win->addmousemove && win->eventstate) { -#endif wmEvent event= *(win->eventstate); event.type= MOUSEMOVE; event.prevx= event.x; @@ -2256,11 +2163,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t switch (type) { /* mouse move */ case GHOST_kEventCursorMove: { -#ifdef EVENT_RECORDER - if(win->active && !erec_playing) { -#else if(win->active) { -#endif + GHOST_TEventCursorData *cd= customdata; wmEvent *lastevent= win->queue.last; @@ -2308,10 +2212,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t break; } case GHOST_kEventTrackpad: { -#ifdef EVENT_RECORDER - if(wm->winactive && !erec_playing) { -#endif - GHOST_TEventTrackpadData * pd = customdata; switch (pd->subtype) { case GHOST_kTrackpadEventMagnify: @@ -2345,21 +2245,13 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t update_tablet_data(win, &event); wm_event_add(win, &event); break; -#ifdef EVENT_RECORDER - } -#endif } /* mouse button */ case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd= customdata; event.val= (type==GHOST_kEventButtonDown) ? KM_PRESS:KM_RELEASE; /* Note!, this starts as 0/1 but later is converted to KM_PRESS/KM_RELEASE by tweak */ - - #ifdef EVENT_RECORDER - if (erec_playing) - return; - #endif - + if (bd->button == GHOST_kButtonMaskLeft) event.type= LEFTMOUSE; else if (bd->button == GHOST_kButtonMaskRight) @@ -2399,11 +2291,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t event.ascii= kd->ascii; event.val= (type==GHOST_kEventKeyDown)?KM_PRESS:KM_RELEASE; - #ifdef EVENT_RECORDER - if (erec_playing) - return; - #endif - /* exclude arrow keys, esc, etc from text input */ if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>0)) event.ascii= '\0'; @@ -2455,10 +2342,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t case GHOST_kEventWheel: { GHOST_TEventWheelData* wheelData = customdata; - #ifdef EVENT_RECORDER - if (erec_playing) - return; - #endif if (wheelData->z > 0) event.type= WHEELUPMOUSE; else