179 lines
6 KiB
C++
179 lines
6 KiB
C++
/*
|
|
* Deskflow -- mouse and keyboard sharing utility
|
|
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
|
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "base/EventTypes.h"
|
|
#include "base/IEventQueue.h"
|
|
#include "base/PriorityQueue.h"
|
|
#include "base/Stopwatch.h"
|
|
#include "mt/CondVar.h"
|
|
|
|
#include <map>
|
|
#include <queue>
|
|
#include <set>
|
|
|
|
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();
|
|
EventQueue(EventQueue const &) = delete;
|
|
EventQueue(EventQueue &&) = delete;
|
|
~EventQueue() override;
|
|
EventQueue &operator=(EventQueue const &) = delete;
|
|
EventQueue &operator=(EventQueue &&) = delete;
|
|
|
|
// IEventQueue overrides
|
|
void loop() override;
|
|
void adoptBuffer(IEventQueueBuffer *) override;
|
|
bool getEvent(Event &event, double timeout = -1.0) override;
|
|
bool dispatchEvent(const Event &event) override;
|
|
void addEvent(const Event &event) override;
|
|
EventQueueTimer *newTimer(double duration, void *target) override;
|
|
EventQueueTimer *newOneShotTimer(double duration, void *target) override;
|
|
void deleteTimer(EventQueueTimer *) override;
|
|
void adoptHandler(Event::Type type, void *target, IEventJob *handler) override;
|
|
void removeHandler(Event::Type type, void *target) override;
|
|
void removeHandlers(void *target) override;
|
|
Event::Type registerTypeOnce(Event::Type &type, const char *name) override;
|
|
bool isEmpty() const override;
|
|
IEventJob *getHandler(Event::Type type, void *target) const override;
|
|
const char *getTypeName(Event::Type type) override;
|
|
Event::Type getRegisteredType(const std::string &name) const override;
|
|
void *getSystemTarget() override;
|
|
void waitForReady() const override;
|
|
|
|
private:
|
|
uint32_t saveEvent(const Event &event);
|
|
Event removeEvent(uint32_t eventID);
|
|
bool hasTimerExpired(Event &event);
|
|
double getNextTimerTimeout() const;
|
|
void addEventToBuffer(const Event &event);
|
|
|
|
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;
|
|
};
|
|
|
|
using Timers = std::set<EventQueueTimer *>;
|
|
using TimerQueue = PriorityQueue<Timer>;
|
|
using EventTable = std::map<uint32_t, Event>;
|
|
using EventIDList = std::vector<uint32_t>;
|
|
using TypeMap = std::map<Event::Type, const char *>;
|
|
using NameMap = std::map<std::string, Event::Type>;
|
|
using TypeHandlerTable = std::map<Event::Type, IEventJob *>;
|
|
using HandlerTable = std::map<void *, TypeHandlerTable>;
|
|
|
|
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() override;
|
|
IStreamEvents &forIStream() override;
|
|
IDataSocketEvents &forIDataSocket() override;
|
|
IListenSocketEvents &forIListenSocket() override;
|
|
ISocketEvents &forISocket() override;
|
|
OSXScreenEvents &forOSXScreen() override;
|
|
ClientListenerEvents &forClientListener() override;
|
|
ClientProxyEvents &forClientProxy() override;
|
|
ClientProxyUnknownEvents &forClientProxyUnknown() override;
|
|
ServerEvents &forServer() override;
|
|
ServerAppEvents &forServerApp() override;
|
|
IKeyStateEvents &forIKeyState() override;
|
|
IPrimaryScreenEvents &forIPrimaryScreen() override;
|
|
IScreenEvents &forIScreen() override;
|
|
ClipboardEvents &forClipboard() override;
|
|
FileEvents &forFile() override;
|
|
EiEvents &forEi() override;
|
|
|
|
private:
|
|
ClientEvents *m_typesForClient;
|
|
IStreamEvents *m_typesForIStream;
|
|
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;
|
|
EiEvents *m_typesForEi;
|
|
Mutex *m_readyMutex;
|
|
CondVar<bool> *m_readyCondVar;
|
|
std::queue<Event> m_pending;
|
|
};
|
|
|
|
#define EVENT_TYPE_ACCESSOR(type_) \
|
|
type_##Events& \
|
|
EventQueue::for##type_() \
|
|
{ \
|
|
if (m_typesFor##type_ == nullptr) { \
|
|
m_typesFor##type_ = new type_##Events(); \
|
|
m_typesFor##type_->setEvents(dynamic_cast<IEventQueue *>(this)); \
|
|
} \
|
|
return *m_typesFor##type_; \
|
|
}
|