summaryrefslogtreecommitdiffstats
path: root/src/lib/base/EventQueue.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/base/EventQueue.h')
-rw-r--r--src/lib/base/EventQueue.h200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/lib/base/EventQueue.h b/src/lib/base/EventQueue.h
new file mode 100644
index 0000000..97e7fba
--- /dev/null
+++ b/src/lib/base/EventQueue.h
@@ -0,0 +1,200 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2012-2016 Symless Ltd.
+ * Copyright (C) 2004 Chris Schoeneman
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "mt/CondVar.h"
+#include "arch/IArchMultithread.h"
+#include "base/IEventQueue.h"
+#include "base/Event.h"
+#include "base/PriorityQueue.h"
+#include "base/Stopwatch.h"
+#include "common/stdmap.h"
+#include "common/stdset.h"
+#include "base/NonBlockingStream.h"
+
+#include <queue>
+
+class Mutex;
+
+//! Event queue
+/*!
+An event queue that implements the platform independent parts and
+delegates the platform dependent parts to a subclass.
+*/
+class EventQueue : public IEventQueue {
+public:
+ EventQueue();
+ virtual ~EventQueue();
+
+ // IEventQueue overrides
+ virtual void loop();
+ virtual void adoptBuffer(IEventQueueBuffer*);
+ virtual bool getEvent(Event& event, double timeout = -1.0);
+ virtual bool dispatchEvent(const Event& event);
+ virtual void addEvent(const Event& event);
+ virtual EventQueueTimer*
+ newTimer(double duration, void* target);
+ virtual EventQueueTimer*
+ newOneShotTimer(double duration, void* target);
+ virtual void deleteTimer(EventQueueTimer*);
+ virtual void adoptHandler(Event::Type type,
+ void* target, IEventJob* handler);
+ virtual void removeHandler(Event::Type type, void* target);
+ virtual void removeHandlers(void* target);
+ virtual Event::Type
+ registerTypeOnce(Event::Type& type, const char* name);
+ virtual bool isEmpty() const;
+ virtual IEventJob* getHandler(Event::Type type, void* target) const;
+ virtual const char* getTypeName(Event::Type type);
+ virtual Event::Type
+ getRegisteredType(const String& name) const;
+ void* getSystemTarget();
+ virtual void waitForReady() const;
+
+private:
+ UInt32 saveEvent(const Event& event);
+ Event removeEvent(UInt32 eventID);
+ bool hasTimerExpired(Event& event);
+ double getNextTimerTimeout() const;
+ void addEventToBuffer(const Event& event);
+ bool parent_requests_shutdown() const;
+
+private:
+ class Timer {
+ public:
+ Timer(EventQueueTimer*, double timeout, double initialTime,
+ void* target, bool oneShot);
+ ~Timer();
+
+ void reset();
+
+ Timer& operator-=(double);
+
+ operator double() const;
+
+ bool isOneShot() const;
+ EventQueueTimer*
+ getTimer() const;
+ void* getTarget() const;
+ void fillEvent(TimerEvent&) const;
+
+ bool operator<(const Timer&) const;
+
+ private:
+ EventQueueTimer* m_timer;
+ double m_timeout;
+ void* m_target;
+ bool m_oneShot;
+ double m_time;
+ };
+
+ typedef std::set<EventQueueTimer*> Timers;
+ typedef PriorityQueue<Timer> TimerQueue;
+ typedef std::map<UInt32, Event> EventTable;
+ typedef std::vector<UInt32> EventIDList;
+ typedef std::map<Event::Type, const char*> TypeMap;
+ typedef std::map<String, Event::Type> NameMap;
+ typedef std::map<Event::Type, IEventJob*> TypeHandlerTable;
+ typedef std::map<void*, TypeHandlerTable> HandlerTable;
+
+ int m_systemTarget;
+ ArchMutex m_mutex;
+
+ // registered events
+ Event::Type m_nextType;
+ TypeMap m_typeMap;
+ NameMap m_nameMap;
+
+ // buffer of events
+ IEventQueueBuffer* m_buffer;
+
+ // saved events
+ EventTable m_events;
+ EventIDList m_oldEventIDs;
+
+ // timers
+ Stopwatch m_time;
+ Timers m_timers;
+ TimerQueue m_timerQueue;
+ TimerEvent m_timerEvent;
+
+ // event handlers
+ HandlerTable m_handlers;
+
+public:
+ //
+ // Event type providers.
+ //
+ ClientEvents& forClient();
+ IStreamEvents& forIStream();
+ IpcClientEvents& forIpcClient();
+ IpcClientProxyEvents& forIpcClientProxy();
+ IpcServerEvents& forIpcServer();
+ IpcServerProxyEvents& forIpcServerProxy();
+ IDataSocketEvents& forIDataSocket();
+ IListenSocketEvents& forIListenSocket();
+ ISocketEvents& forISocket();
+ OSXScreenEvents& forOSXScreen();
+ ClientListenerEvents& forClientListener();
+ ClientProxyEvents& forClientProxy();
+ ClientProxyUnknownEvents& forClientProxyUnknown();
+ ServerEvents& forServer();
+ ServerAppEvents& forServerApp();
+ IKeyStateEvents& forIKeyState();
+ IPrimaryScreenEvents& forIPrimaryScreen();
+ IScreenEvents& forIScreen();
+ ClipboardEvents& forClipboard();
+ FileEvents& forFile();
+
+private:
+ ClientEvents* m_typesForClient;
+ IStreamEvents* m_typesForIStream;
+ IpcClientEvents* m_typesForIpcClient;
+ IpcClientProxyEvents* m_typesForIpcClientProxy;
+ IpcServerEvents* m_typesForIpcServer;
+ IpcServerProxyEvents* m_typesForIpcServerProxy;
+ IDataSocketEvents* m_typesForIDataSocket;
+ IListenSocketEvents* m_typesForIListenSocket;
+ ISocketEvents* m_typesForISocket;
+ OSXScreenEvents* m_typesForOSXScreen;
+ ClientListenerEvents* m_typesForClientListener;
+ ClientProxyEvents* m_typesForClientProxy;
+ ClientProxyUnknownEvents* m_typesForClientProxyUnknown;
+ ServerEvents* m_typesForServer;
+ ServerAppEvents* m_typesForServerApp;
+ IKeyStateEvents* m_typesForIKeyState;
+ IPrimaryScreenEvents* m_typesForIPrimaryScreen;
+ IScreenEvents* m_typesForIScreen;
+ ClipboardEvents* m_typesForClipboard;
+ FileEvents* m_typesForFile;
+ Mutex* m_readyMutex;
+ CondVar<bool>* m_readyCondVar;
+ std::queue<Event> m_pending;
+ NonBlockingStream m_parentStream;
+};
+
+#define EVENT_TYPE_ACCESSOR(type_) \
+type_##Events& \
+EventQueue::for##type_() { \
+ if (m_typesFor##type_ == NULL) { \
+ m_typesFor##type_ = new type_##Events(); \
+ m_typesFor##type_->setEvents(dynamic_cast<IEventQueue*>(this)); \
+ } \
+ return *m_typesFor##type_; \
+}