mirror of
https://github.com/debauchee/barrier.git
synced 2026-05-11 00:58:14 +08:00
Added switch delay and double-tap options to win32 and added a
tray icon to the client and server that gives status feedback to the user and allows the user to kill the app.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#undef ARCH_NETWORK
|
||||
#undef ARCH_SLEEP
|
||||
#undef ARCH_STRING
|
||||
#undef ARCH_TASKBAR
|
||||
#undef ARCH_TIME
|
||||
|
||||
// include appropriate architecture implementation
|
||||
@@ -35,6 +36,7 @@
|
||||
# include "CArchNetworkWinsock.h"
|
||||
# include "CArchSleepWindows.h"
|
||||
# include "CArchStringWindows.h"
|
||||
# include "CArchTaskBarWindows.h"
|
||||
# include "CArchTimeWindows.h"
|
||||
#elif UNIX_LIKE
|
||||
# include "CArchConsoleUnix.h"
|
||||
@@ -47,6 +49,7 @@
|
||||
# include "CArchNetworkBSD.h"
|
||||
# include "CArchSleepUnix.h"
|
||||
# include "CArchStringUnix.h"
|
||||
# include "CArchTaskBarXWindows.h"
|
||||
# include "CArchTimeUnix.h"
|
||||
#endif
|
||||
|
||||
@@ -82,6 +85,10 @@
|
||||
# error unsupported platform for string
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_TASKBAR)
|
||||
# error unsupported platform for taskbar
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_TIME)
|
||||
# error unsupported platform for time
|
||||
#endif
|
||||
@@ -92,7 +99,7 @@
|
||||
|
||||
CArch* CArch::s_instance = NULL;
|
||||
|
||||
CArch::CArch(ARCH_ARGS)
|
||||
CArch::CArch(ARCH_ARGS* args)
|
||||
{
|
||||
// only once instance of CArch
|
||||
assert(s_instance == NULL);
|
||||
@@ -108,11 +115,13 @@ CArch::CArch(ARCH_ARGS)
|
||||
m_time = new ARCH_TIME;
|
||||
m_console = new ARCH_CONSOLE;
|
||||
m_daemon = new ARCH_DAEMON;
|
||||
m_taskbar = new ARCH_TASKBAR(args);
|
||||
}
|
||||
|
||||
CArch::~CArch()
|
||||
{
|
||||
// clean up
|
||||
delete m_taskbar;
|
||||
delete m_daemon;
|
||||
delete m_console;
|
||||
delete m_time;
|
||||
@@ -337,10 +346,10 @@ CArch::wait(CArchThread thread, double timeout)
|
||||
return m_mt->wait(thread, timeout);
|
||||
}
|
||||
|
||||
bool
|
||||
CArch::waitForEvent(double timeout)
|
||||
IArchMultithread::EWaitResult
|
||||
CArch::waitForEvent(CArchThread thread, double timeout)
|
||||
{
|
||||
return m_mt->waitForEvent(timeout);
|
||||
return m_mt->waitForEvent(thread, timeout);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -577,6 +586,24 @@ CArch::getWideCharEncoding()
|
||||
return m_string->getWideCharEncoding();
|
||||
}
|
||||
|
||||
void
|
||||
CArch::addReceiver(IArchTaskBarReceiver* receiver)
|
||||
{
|
||||
m_taskbar->addReceiver(receiver);
|
||||
}
|
||||
|
||||
void
|
||||
CArch::removeReceiver(IArchTaskBarReceiver* receiver)
|
||||
{
|
||||
m_taskbar->removeReceiver(receiver);
|
||||
}
|
||||
|
||||
void
|
||||
CArch::updateReceiver(IArchTaskBarReceiver* receiver)
|
||||
{
|
||||
m_taskbar->updateReceiver(receiver);
|
||||
}
|
||||
|
||||
double
|
||||
CArch::time()
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "IArchNetwork.h"
|
||||
#include "IArchSleep.h"
|
||||
#include "IArchString.h"
|
||||
#include "IArchTaskBar.h"
|
||||
#include "IArchTime.h"
|
||||
|
||||
/*!
|
||||
@@ -31,7 +32,7 @@ This macro evaluates to the singleton CArch object.
|
||||
*/
|
||||
#define ARCH (CArch::getInstance())
|
||||
|
||||
#define ARCH_ARGS
|
||||
#define ARCH_ARGS void
|
||||
|
||||
//! Delegating mplementation of architecture dependent interfaces
|
||||
/*!
|
||||
@@ -51,9 +52,10 @@ class CArch : public IArchConsole,
|
||||
public IArchNetwork,
|
||||
public IArchSleep,
|
||||
public IArchString,
|
||||
public IArchTaskBar,
|
||||
public IArchTime {
|
||||
public:
|
||||
CArch(ARCH_ARGS);
|
||||
CArch(ARCH_ARGS* args = NULL);
|
||||
~CArch();
|
||||
|
||||
//
|
||||
@@ -114,7 +116,7 @@ public:
|
||||
virtual void setPriorityOfThread(CArchThread, int n);
|
||||
virtual void testCancelThread();
|
||||
virtual bool wait(CArchThread, double timeout);
|
||||
virtual bool waitForEvent(double timeout);
|
||||
virtual EWaitResult waitForEvent(CArchThread, double timeout);
|
||||
virtual bool isSameThread(CArchThread, CArchThread);
|
||||
virtual bool isExitedThread(CArchThread);
|
||||
virtual void* getResultOfThread(CArchThread);
|
||||
@@ -164,6 +166,11 @@ public:
|
||||
virtual EWideCharEncoding
|
||||
getWideCharEncoding();
|
||||
|
||||
// IArchTaskBar
|
||||
virtual void addReceiver(IArchTaskBarReceiver*);
|
||||
virtual void removeReceiver(IArchTaskBarReceiver*);
|
||||
virtual void updateReceiver(IArchTaskBarReceiver*);
|
||||
|
||||
// IArchTime overrides
|
||||
virtual double time();
|
||||
|
||||
@@ -178,6 +185,7 @@ private:
|
||||
IArchNetwork* m_net;
|
||||
IArchSleep* m_sleep;
|
||||
IArchString* m_string;
|
||||
IArchTaskBar* m_taskbar;
|
||||
IArchTime* m_time;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "CArchConsoleWindows.h"
|
||||
#include "IArchMultithread.h"
|
||||
#include "CArch.h"
|
||||
#include <cstdio>
|
||||
|
||||
@@ -20,12 +21,12 @@
|
||||
// CArchConsoleWindows
|
||||
//
|
||||
|
||||
DWORD CArchConsoleWindows::s_thread = 0;
|
||||
CArchThread CArchConsoleWindows::s_thread = 0;
|
||||
|
||||
CArchConsoleWindows::CArchConsoleWindows() :
|
||||
m_output(NULL)
|
||||
{
|
||||
s_thread = GetCurrentThreadId();
|
||||
s_thread = ARCH->newCurrentThread();
|
||||
|
||||
m_mutex = ARCH->newMutex();
|
||||
}
|
||||
@@ -33,6 +34,7 @@ CArchConsoleWindows::CArchConsoleWindows() :
|
||||
CArchConsoleWindows::~CArchConsoleWindows()
|
||||
{
|
||||
ARCH->closeMutex(m_mutex);
|
||||
ARCH->closeThread(s_thread);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -101,7 +103,7 @@ CArchConsoleWindows::getNewlineForConsole()
|
||||
BOOL WINAPI
|
||||
CArchConsoleWindows::signalHandler(DWORD)
|
||||
{
|
||||
// terminate cleanly and skip remaining handlers
|
||||
PostThreadMessage(s_thread, WM_QUIT, 0, 0);
|
||||
// terminate thread and skip remaining handlers
|
||||
ARCH->cancelThread(s_thread);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ private:
|
||||
static BOOL WINAPI signalHandler(DWORD);
|
||||
|
||||
private:
|
||||
static DWORD s_thread;
|
||||
static CArchThread s_thread;
|
||||
|
||||
CArchMutex m_mutex;
|
||||
HANDLE m_output;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# include "CArchNetworkWinsock.cpp"
|
||||
# include "CArchSleepWindows.cpp"
|
||||
# include "CArchStringWindows.cpp"
|
||||
# include "CArchTaskBarWindows.cpp"
|
||||
# include "CArchTimeWindows.cpp"
|
||||
# include "XArchWindows.cpp"
|
||||
#elif UNIX_LIKE
|
||||
@@ -38,6 +39,7 @@
|
||||
# include "CArchNetworkBSD.cpp"
|
||||
# include "CArchSleepUnix.cpp"
|
||||
# include "CArchStringUnix.cpp"
|
||||
# include "CArchTaskBarXWindows.cpp"
|
||||
# include "CArchTimeUnix.cpp"
|
||||
# include "XArchUnix.cpp"
|
||||
#endif
|
||||
|
||||
@@ -517,11 +517,11 @@ CArchMultithreadPosix::wait(CArchThread target, double timeout)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CArchMultithreadPosix::waitForEvent(double /*timeout*/)
|
||||
IArchMultithread::EWaitResult
|
||||
CArchMultithreadPosix::waitForEvent(CArchThread, double /*timeout*/)
|
||||
{
|
||||
// not implemented
|
||||
return false;
|
||||
return kTimeout;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
virtual void setPriorityOfThread(CArchThread, int n);
|
||||
virtual void testCancelThread();
|
||||
virtual bool wait(CArchThread, double timeout);
|
||||
virtual bool waitForEvent(double timeout);
|
||||
virtual EWaitResult waitForEvent(CArchThread, double timeout);
|
||||
virtual bool isSameThread(CArchThread, CArchThread);
|
||||
virtual bool isExitedThread(CArchThread);
|
||||
virtual void* getResultOfThread(CArchThread);
|
||||
|
||||
@@ -453,6 +453,89 @@ CArchMultithreadWindows::wait(CArchThread target, double timeout)
|
||||
}
|
||||
}
|
||||
|
||||
IArchMultithread::EWaitResult
|
||||
CArchMultithreadWindows::waitForEvent(CArchThread target, double timeout)
|
||||
{
|
||||
// find current thread. ref the target so it can't go away while
|
||||
// we're watching it.
|
||||
lockMutex(m_threadMutex);
|
||||
CArchThreadImpl* self = findNoRef(GetCurrentThreadId());
|
||||
assert(self != NULL);
|
||||
if (target != NULL) {
|
||||
refThread(target);
|
||||
}
|
||||
unlockMutex(m_threadMutex);
|
||||
|
||||
// see if we've been cancelled before checking if any events
|
||||
// are pending.
|
||||
DWORD result = WaitForSingleObject(self->m_cancel, 0);
|
||||
if (result == WAIT_OBJECT_0) {
|
||||
if (target != NULL) {
|
||||
closeThread(target);
|
||||
}
|
||||
testCancelThreadImpl(self);
|
||||
}
|
||||
|
||||
// check if messages are available first. if we don't do this then
|
||||
// MsgWaitForMultipleObjects() will block even if the queue isn't
|
||||
// empty if the messages in the queue were there before the last
|
||||
// call to GetMessage()/PeekMessage().
|
||||
if (HIWORD(GetQueueStatus(QS_ALLINPUT)) != 0) {
|
||||
return kEvent;
|
||||
}
|
||||
|
||||
// convert timeout
|
||||
DWORD t;
|
||||
if (timeout < 0.0) {
|
||||
t = INFINITE;
|
||||
}
|
||||
else {
|
||||
t = (DWORD)(1000.0 * timeout);
|
||||
}
|
||||
|
||||
// wait for this thread to be cancelled or for the target thread to
|
||||
// terminate.
|
||||
DWORD n = (target == NULL || target == self) ? 1 : 2;
|
||||
HANDLE handles[2];
|
||||
handles[0] = self->m_cancel;
|
||||
handles[1] = (n == 2) ? target->m_exit : NULL;
|
||||
result = MsgWaitForMultipleObjects(n, handles, FALSE, t, QS_ALLINPUT);
|
||||
|
||||
// cancel takes priority
|
||||
if (result != WAIT_OBJECT_0 + 0 &&
|
||||
WaitForSingleObject(handles[0], 0) == WAIT_OBJECT_0) {
|
||||
result = WAIT_OBJECT_0 + 0;
|
||||
}
|
||||
|
||||
// release target
|
||||
if (target != NULL) {
|
||||
closeThread(target);
|
||||
}
|
||||
|
||||
// handle result
|
||||
switch (result) {
|
||||
case WAIT_OBJECT_0 + 0:
|
||||
// this thread was cancelled. does not return.
|
||||
testCancelThreadImpl(self);
|
||||
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
// target thread terminated
|
||||
if (n == 2) {
|
||||
return kExit;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case WAIT_OBJECT_0 + 2:
|
||||
// message is available
|
||||
return kEvent;
|
||||
|
||||
default:
|
||||
// timeout or error
|
||||
return kTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool
|
||||
CArchMultithreadWindows::waitForEvent(double timeout)
|
||||
{
|
||||
@@ -499,6 +582,7 @@ CArchMultithreadWindows::waitForEvent(double timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bool
|
||||
CArchMultithreadWindows::isSameThread(CArchThread thread1, CArchThread thread2)
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
virtual void setPriorityOfThread(CArchThread, int n);
|
||||
virtual void testCancelThread();
|
||||
virtual bool wait(CArchThread, double timeout);
|
||||
virtual bool waitForEvent(double timeout);
|
||||
virtual EWaitResult waitForEvent(CArchThread, double timeout);
|
||||
virtual bool isSameThread(CArchThread, CArchThread);
|
||||
virtual bool isExitedThread(CArchThread);
|
||||
virtual void* getResultOfThread(CArchThread);
|
||||
|
||||
518
lib/arch/CArchTaskBarWindows.cpp
Normal file
518
lib/arch/CArchTaskBarWindows.cpp
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2003 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 COPYING 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.
|
||||
*/
|
||||
|
||||
#include "CArchTaskBarWindows.h"
|
||||
#include "IArchTaskBarReceiver.h"
|
||||
#include "CArch.h"
|
||||
#include "XArch.h"
|
||||
#include <string.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
static const UINT kAddReceiver = WM_USER + 10;
|
||||
static const UINT kRemoveReceiver = WM_USER + 11;
|
||||
static const UINT kUpdateReceiver = WM_USER + 12;
|
||||
static const UINT kNotifyReceiver = WM_USER + 13;
|
||||
static const UINT kFirstReceiverID = WM_USER + 14;
|
||||
|
||||
//
|
||||
// CArchTaskBarWindows
|
||||
//
|
||||
|
||||
CArchTaskBarWindows* CArchTaskBarWindows::s_instance = NULL;
|
||||
HINSTANCE CArchTaskBarWindows::s_appInstance = NULL;
|
||||
|
||||
CArchTaskBarWindows::CArchTaskBarWindows(void* appInstance) :
|
||||
m_nextID(kFirstReceiverID)
|
||||
{
|
||||
// save the singleton instance
|
||||
s_instance = this;
|
||||
|
||||
// save app instance
|
||||
s_appInstance = reinterpret_cast<HINSTANCE>(appInstance);
|
||||
|
||||
// we need a mutex
|
||||
m_mutex = ARCH->newMutex();
|
||||
|
||||
// and a condition variable which uses the above mutex
|
||||
m_ready = false;
|
||||
m_condVar = ARCH->newCondVar();
|
||||
|
||||
// we're going to want to get a result from the thread we're
|
||||
// about to create to know if it initialized successfully.
|
||||
// so we lock the condition variable.
|
||||
ARCH->lockMutex(m_mutex);
|
||||
|
||||
// open a window and run an event loop in a separate thread.
|
||||
// this has to happen in a separate thread because if we
|
||||
// create a window on the current desktop with the current
|
||||
// thread then the current thread won't be able to switch
|
||||
// desktops if it needs to.
|
||||
m_thread = ARCH->newThread(&CArchTaskBarWindows::threadEntry, this);
|
||||
|
||||
// wait for child thread
|
||||
while (!m_ready) {
|
||||
ARCH->waitCondVar(m_condVar, m_mutex, -1.0);
|
||||
}
|
||||
|
||||
// ready
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
CArchTaskBarWindows::~CArchTaskBarWindows()
|
||||
{
|
||||
if (m_thread != NULL) {
|
||||
ARCH->cancelThread(m_thread);
|
||||
ARCH->wait(m_thread, -1.0);
|
||||
ARCH->closeThread(m_thread);
|
||||
}
|
||||
ARCH->closeCondVar(m_condVar);
|
||||
ARCH->closeMutex(m_mutex);
|
||||
s_instance = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::addDialog(HWND hwnd)
|
||||
{
|
||||
// add dialog to added dialogs list
|
||||
ARCH->lockMutex(s_instance->m_mutex);
|
||||
s_instance->m_addedDialogs.insert(std::make_pair(hwnd, true));
|
||||
ARCH->unlockMutex(s_instance->m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::removeDialog(HWND hwnd)
|
||||
{
|
||||
// mark dialog as removed
|
||||
ARCH->lockMutex(s_instance->m_mutex);
|
||||
CDialogs::iterator index = s_instance->m_dialogs.find(hwnd);
|
||||
if (index != s_instance->m_dialogs.end()) {
|
||||
index->second = false;
|
||||
}
|
||||
s_instance->m_addedDialogs.erase(hwnd);
|
||||
ARCH->unlockMutex(s_instance->m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::addReceiver(IArchTaskBarReceiver* receiver)
|
||||
{
|
||||
// ignore bogus receiver
|
||||
if (receiver == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add receiver if necessary
|
||||
CReceiverToInfoMap::iterator index = m_receivers.find(receiver);
|
||||
if (index == m_receivers.end()) {
|
||||
// add it, creating a new message ID for it
|
||||
CReceiverInfo info;
|
||||
info.m_id = getNextID();
|
||||
index = m_receivers.insert(std::make_pair(receiver, info)).first;
|
||||
|
||||
// add ID to receiver mapping
|
||||
m_idTable.insert(std::make_pair(info.m_id, index));
|
||||
}
|
||||
|
||||
// add receiver
|
||||
PostMessage(m_hwnd, kAddReceiver, index->second.m_id, 0);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::removeReceiver(IArchTaskBarReceiver* receiver)
|
||||
{
|
||||
// find receiver
|
||||
CReceiverToInfoMap::iterator index = m_receivers.find(receiver);
|
||||
if (index == m_receivers.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove icon. wait for this to finish before returning.
|
||||
SendMessage(m_hwnd, kRemoveReceiver, index->second.m_id, 0);
|
||||
|
||||
// recycle the ID
|
||||
recycleID(index->second.m_id);
|
||||
|
||||
// discard
|
||||
m_idTable.erase(index->second.m_id);
|
||||
m_receivers.erase(index);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::updateReceiver(IArchTaskBarReceiver* receiver)
|
||||
{
|
||||
// find receiver
|
||||
CReceiverToInfoMap::const_iterator index = m_receivers.find(receiver);
|
||||
if (index == m_receivers.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update icon and tool tip
|
||||
PostMessage(m_hwnd, kUpdateReceiver, index->second.m_id, 0);
|
||||
}
|
||||
|
||||
UINT
|
||||
CArchTaskBarWindows::getNextID()
|
||||
{
|
||||
if (m_oldIDs.empty()) {
|
||||
return m_nextID++;
|
||||
}
|
||||
UINT id = m_oldIDs.back();
|
||||
m_oldIDs.pop_back();
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::recycleID(UINT id)
|
||||
{
|
||||
m_oldIDs.push_back(id);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::addIcon(UINT id)
|
||||
{
|
||||
ARCH->lockMutex(m_mutex);
|
||||
CIDToReceiverMap::const_iterator index = m_idTable.find(id);
|
||||
if (index != m_idTable.end()) {
|
||||
modifyIconNoLock(index->second, NIM_ADD);
|
||||
}
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::removeIcon(UINT id)
|
||||
{
|
||||
ARCH->lockMutex(m_mutex);
|
||||
removeIconNoLock(id);
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::updateIcon(UINT id)
|
||||
{
|
||||
ARCH->lockMutex(m_mutex);
|
||||
CIDToReceiverMap::const_iterator index = m_idTable.find(id);
|
||||
if (index != m_idTable.end()) {
|
||||
modifyIconNoLock(index->second, NIM_MODIFY);
|
||||
}
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::addAllIcons()
|
||||
{
|
||||
ARCH->lockMutex(m_mutex);
|
||||
for (CReceiverToInfoMap::const_iterator index = m_receivers.begin();
|
||||
index != m_receivers.end(); ++index) {
|
||||
modifyIconNoLock(index, NIM_ADD);
|
||||
}
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::removeAllIcons()
|
||||
{
|
||||
ARCH->lockMutex(m_mutex);
|
||||
for (CReceiverToInfoMap::const_iterator index = m_receivers.begin();
|
||||
index != m_receivers.end(); ++index) {
|
||||
removeIconNoLock(index->second.m_id);
|
||||
}
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::modifyIconNoLock(
|
||||
CReceiverToInfoMap::const_iterator index, DWORD taskBarMessage)
|
||||
{
|
||||
// get receiver
|
||||
UINT id = index->second.m_id;
|
||||
IArchTaskBarReceiver* receiver = index->first;
|
||||
|
||||
// lock receiver so icon and tool tip are guaranteed to be consistent
|
||||
receiver->lock();
|
||||
|
||||
// get icon data
|
||||
HICON icon = reinterpret_cast<HICON>(
|
||||
const_cast<IArchTaskBarReceiver::Icon>(receiver->getIcon()));
|
||||
|
||||
// get tool tip
|
||||
std::string toolTip = receiver->getToolTip();
|
||||
|
||||
// done querying
|
||||
receiver->unlock();
|
||||
|
||||
// prepare to add icon
|
||||
NOTIFYICONDATA data;
|
||||
data.cbSize = sizeof(NOTIFYICONDATA);
|
||||
data.hWnd = m_hwnd;
|
||||
data.uID = id;
|
||||
data.uFlags = NIF_MESSAGE;
|
||||
data.uCallbackMessage = kNotifyReceiver;
|
||||
data.hIcon = icon;
|
||||
if (icon != NULL) {
|
||||
data.uFlags |= NIF_ICON;
|
||||
}
|
||||
if (!toolTip.empty()) {
|
||||
strncpy(data.szTip, toolTip.c_str(), sizeof(data.szTip));
|
||||
data.szTip[sizeof(data.szTip) - 1] = '\0';
|
||||
data.uFlags |= NIF_TIP;
|
||||
}
|
||||
else {
|
||||
data.szTip[0] = '\0';
|
||||
}
|
||||
|
||||
// add icon
|
||||
if (Shell_NotifyIcon(taskBarMessage, &data) == 0) {
|
||||
// failed
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::removeIconNoLock(UINT id)
|
||||
{
|
||||
NOTIFYICONDATA data;
|
||||
data.cbSize = sizeof(NOTIFYICONDATA);
|
||||
data.hWnd = m_hwnd;
|
||||
data.uID = id;
|
||||
if (Shell_NotifyIcon(NIM_DELETE, &data) == 0) {
|
||||
// failed
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::handleIconMessage(
|
||||
IArchTaskBarReceiver* receiver, LPARAM lParam)
|
||||
{
|
||||
// process message
|
||||
switch (lParam) {
|
||||
case WM_LBUTTONDOWN:
|
||||
receiver->showStatus();
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
receiver->primaryAction();
|
||||
break;
|
||||
|
||||
case WM_RBUTTONUP: {
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
receiver->runMenu(p.x, p.y);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
// currently unused
|
||||
break;
|
||||
|
||||
default:
|
||||
// unused
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CArchTaskBarWindows::processDialogs(MSG* msg)
|
||||
{
|
||||
// only one thread can be in this method on any particular object
|
||||
// at any given time. that's not a problem since only our event
|
||||
// loop calls this method and there's just one of those.
|
||||
|
||||
ARCH->lockMutex(m_mutex);
|
||||
|
||||
// remove removed dialogs
|
||||
m_dialogs.erase(false);
|
||||
|
||||
// merge added dialogs into the dialog list
|
||||
for (CDialogs::const_iterator index = m_addedDialogs.begin();
|
||||
index != m_addedDialogs.end(); ++index) {
|
||||
m_dialogs.insert(std::make_pair(index->first, index->second));
|
||||
}
|
||||
m_addedDialogs.clear();
|
||||
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
|
||||
// check message against all dialogs until one handles it.
|
||||
// note that we don't hold a lock while checking because
|
||||
// the message is processed and may make calls to this
|
||||
// object. that's okay because addDialog() and
|
||||
// removeDialog() don't change the map itself (just the
|
||||
// values of some elements).
|
||||
ARCH->lockMutex(m_mutex);
|
||||
for (CDialogs::const_iterator index = m_dialogs.begin();
|
||||
index != m_dialogs.end(); ++index) {
|
||||
if (index->second) {
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
if (IsDialogMessage(index->first, msg)) {
|
||||
return true;
|
||||
}
|
||||
ARCH->lockMutex(m_mutex);
|
||||
}
|
||||
}
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LRESULT
|
||||
CArchTaskBarWindows::wndProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
case kNotifyReceiver: {
|
||||
// lookup receiver
|
||||
CIDToReceiverMap::const_iterator index = m_idTable.find(wParam);
|
||||
if (index != m_idTable.end()) {
|
||||
IArchTaskBarReceiver* receiver = index->second->first;
|
||||
handleIconMessage(receiver, lParam);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kAddReceiver:
|
||||
addIcon(wParam);
|
||||
break;
|
||||
|
||||
case kRemoveReceiver:
|
||||
removeIcon(wParam);
|
||||
break;
|
||||
|
||||
case kUpdateReceiver:
|
||||
updateIcon(wParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (msg == m_taskBarRestart) {
|
||||
// task bar was recreated so re-add our icons
|
||||
addAllIcons();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
CArchTaskBarWindows::staticWndProc(HWND hwnd, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// if msg is WM_NCCREATE, extract the CArchTaskBarWindows* and put
|
||||
// it in the extra window data then forward the call.
|
||||
CArchTaskBarWindows* self = NULL;
|
||||
if (msg == WM_NCCREATE) {
|
||||
CREATESTRUCT* createInfo;
|
||||
createInfo = reinterpret_cast<CREATESTRUCT*>(lParam);
|
||||
self = reinterpret_cast<CArchTaskBarWindows*>(
|
||||
createInfo->lpCreateParams);
|
||||
SetWindowLong(hwnd, 0, reinterpret_cast<LONG>(self));
|
||||
}
|
||||
else {
|
||||
// get the extra window data and forward the call
|
||||
LONG data = GetWindowLong(hwnd, 0);
|
||||
if (data != 0) {
|
||||
self = reinterpret_cast<CArchTaskBarWindows*>(
|
||||
reinterpret_cast<void*>(data));
|
||||
}
|
||||
}
|
||||
|
||||
// forward the message
|
||||
if (self != NULL) {
|
||||
return self->wndProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
else {
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarWindows::threadMainLoop()
|
||||
{
|
||||
// register the task bar restart message
|
||||
m_taskBarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
||||
|
||||
// register a window class
|
||||
WNDCLASSEX classInfo;
|
||||
classInfo.cbSize = sizeof(classInfo);
|
||||
classInfo.style = CS_NOCLOSE;
|
||||
classInfo.lpfnWndProc = &CArchTaskBarWindows::staticWndProc;
|
||||
classInfo.cbClsExtra = 0;
|
||||
classInfo.cbWndExtra = sizeof(CArchTaskBarWindows*);
|
||||
classInfo.hInstance = s_appInstance;
|
||||
classInfo.hIcon = NULL;
|
||||
classInfo.hCursor = NULL;
|
||||
classInfo.hbrBackground = NULL;
|
||||
classInfo.lpszMenuName = NULL;
|
||||
classInfo.lpszClassName = TEXT("SynergyTaskBar");
|
||||
classInfo.hIconSm = NULL;
|
||||
ATOM windowClass = RegisterClassEx(&classInfo);
|
||||
|
||||
// create window
|
||||
m_hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
|
||||
reinterpret_cast<LPCTSTR>(windowClass),
|
||||
TEXT("Synergy Task Bar"),
|
||||
WS_POPUP,
|
||||
0, 0, 1, 1,
|
||||
NULL,
|
||||
NULL,
|
||||
s_appInstance,
|
||||
reinterpret_cast<void*>(this));
|
||||
|
||||
// signal ready
|
||||
ARCH->lockMutex(m_mutex);
|
||||
m_ready = true;
|
||||
ARCH->broadcastCondVar(m_condVar);
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
|
||||
// handle failure
|
||||
if (m_hwnd == NULL) {
|
||||
UnregisterClass((LPCTSTR)windowClass, s_appInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// main loop
|
||||
MSG msg;
|
||||
for (;;) {
|
||||
// wait for message
|
||||
if (ARCH->waitForEvent(NULL, -1.0) != IArchMultithread::kEvent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// peek for message and remove it. we don't GetMessage()
|
||||
// because we should never block here, only in waitForEvent().
|
||||
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check message against dialogs
|
||||
if (!processDialogs(&msg)) {
|
||||
// process message
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (XThread&) {
|
||||
// clean up
|
||||
removeAllIcons();
|
||||
DestroyWindow(m_hwnd);
|
||||
UnregisterClass((LPCTSTR)windowClass, s_appInstance);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
CArchTaskBarWindows::threadEntry(void* self)
|
||||
{
|
||||
reinterpret_cast<CArchTaskBarWindows*>(self)->threadMainLoop();
|
||||
return NULL;
|
||||
}
|
||||
110
lib/arch/CArchTaskBarWindows.h
Normal file
110
lib/arch/CArchTaskBarWindows.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2003 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 COPYING 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.
|
||||
*/
|
||||
|
||||
#ifndef CARCHTASKBARWINDOWS_H
|
||||
#define CARCHTASKBARWINDOWS_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "IArchTaskBar.h"
|
||||
#include "IArchMultithread.h"
|
||||
#include "stdmap.h"
|
||||
#include "stdvector.h"
|
||||
#include <windows.h>
|
||||
|
||||
#define ARCH_TASKBAR CArchTaskBarWindows
|
||||
|
||||
//! Win32 implementation of IArchTaskBar
|
||||
class CArchTaskBarWindows : public IArchTaskBar {
|
||||
public:
|
||||
CArchTaskBarWindows(void*);
|
||||
virtual ~CArchTaskBarWindows();
|
||||
|
||||
//! Add a dialog window
|
||||
/*!
|
||||
Tell the task bar event loop about a dialog. Win32 annoyingly
|
||||
requires messages destined for modeless dialog boxes to be
|
||||
dispatched differently than other messages.
|
||||
*/
|
||||
static void addDialog(HWND);
|
||||
|
||||
//! Remove a dialog window
|
||||
/*!
|
||||
Remove a dialog window added via \c addDialog().
|
||||
*/
|
||||
static void removeDialog(HWND);
|
||||
|
||||
// IArchTaskBar overrides
|
||||
virtual void addReceiver(IArchTaskBarReceiver*);
|
||||
virtual void removeReceiver(IArchTaskBarReceiver*);
|
||||
virtual void updateReceiver(IArchTaskBarReceiver*);
|
||||
|
||||
private:
|
||||
class CReceiverInfo {
|
||||
public:
|
||||
UINT m_id;
|
||||
};
|
||||
|
||||
typedef std::map<IArchTaskBarReceiver*, CReceiverInfo> CReceiverToInfoMap;
|
||||
typedef std::map<UINT, CReceiverToInfoMap::iterator> CIDToReceiverMap;
|
||||
typedef std::vector<UINT> CIDStack;
|
||||
typedef std::map<HWND, bool> CDialogs;
|
||||
|
||||
UINT getNextID();
|
||||
void recycleID(UINT);
|
||||
|
||||
void addIcon(UINT);
|
||||
void removeIcon(UINT);
|
||||
void updateIcon(UINT);
|
||||
void addAllIcons();
|
||||
void removeAllIcons();
|
||||
void modifyIconNoLock(CReceiverToInfoMap::const_iterator,
|
||||
DWORD taskBarMessage);
|
||||
void removeIconNoLock(UINT id);
|
||||
void handleIconMessage(IArchTaskBarReceiver*, LPARAM);
|
||||
|
||||
bool processDialogs(MSG*);
|
||||
LRESULT wndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static LRESULT CALLBACK
|
||||
staticWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
void threadMainLoop();
|
||||
static void* threadEntry(void*);
|
||||
|
||||
private:
|
||||
static CArchTaskBarWindows* s_instance;
|
||||
static HINSTANCE s_appInstance;
|
||||
|
||||
// multithread data
|
||||
CArchMutex m_mutex;
|
||||
CArchCond m_condVar;
|
||||
bool m_ready;
|
||||
int m_result;
|
||||
CArchThread m_thread;
|
||||
|
||||
// child thread data
|
||||
HWND m_hwnd;
|
||||
UINT m_taskBarRestart;
|
||||
|
||||
// shared data
|
||||
CReceiverToInfoMap m_receivers;
|
||||
CIDToReceiverMap m_idTable;
|
||||
CIDStack m_oldIDs;
|
||||
UINT m_nextID;
|
||||
|
||||
// dialogs
|
||||
CDialogs m_dialogs;
|
||||
CDialogs m_addedDialogs;
|
||||
};
|
||||
|
||||
#endif
|
||||
47
lib/arch/CArchTaskBarXWindows.cpp
Normal file
47
lib/arch/CArchTaskBarXWindows.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2003 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 COPYING 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.
|
||||
*/
|
||||
|
||||
#include "CArchTaskBarXWindows.h"
|
||||
|
||||
//
|
||||
// CArchTaskBarXWindows
|
||||
//
|
||||
|
||||
CArchTaskBarXWindows::CArchTaskBarXWindows(void*)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CArchTaskBarXWindows::~CArchTaskBarXWindows()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarXWindows::addReceiver(IArchTaskBarReceiver* /*receiver*/)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarXWindows::removeReceiver(IArchTaskBarReceiver* /*receiver*/)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CArchTaskBarXWindows::updateReceiver(IArchTaskBarReceiver* /*receiver*/)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
34
lib/arch/CArchTaskBarXWindows.h
Normal file
34
lib/arch/CArchTaskBarXWindows.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2003 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 COPYING 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.
|
||||
*/
|
||||
|
||||
#ifndef CARCHTASKBARXWINDOWS_H
|
||||
#define CARCHTASKBARXWINDOWS_H
|
||||
|
||||
#include "IArchTaskBar.h"
|
||||
|
||||
#define ARCH_TASKBAR CArchTaskBarXWindows
|
||||
|
||||
//! X11 implementation of IArchTaskBar
|
||||
class CArchTaskBarXWindows : public IArchTaskBar {
|
||||
public:
|
||||
CArchTaskBarXWindows(void*);
|
||||
virtual ~CArchTaskBarXWindows();
|
||||
|
||||
// IArchTaskBar overrides
|
||||
virtual void addReceiver(IArchTaskBarReceiver*);
|
||||
virtual void removeReceiver(IArchTaskBarReceiver*);
|
||||
virtual void updateReceiver(IArchTaskBarReceiver*);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -67,6 +67,13 @@ synergy. Each architecture must implement this interface.
|
||||
*/
|
||||
class IArchMultithread : public IInterface {
|
||||
public:
|
||||
//! Result of waitForEvent()
|
||||
enum EWaitResult {
|
||||
kEvent, //!< An event is pending
|
||||
kExit, //!< Thread exited
|
||||
kTimeout //!< Wait timed out
|
||||
};
|
||||
|
||||
//! Type of thread entry point
|
||||
typedef void* (*ThreadFunc)(void*);
|
||||
//! Type of thread identifier
|
||||
@@ -102,10 +109,12 @@ public:
|
||||
|
||||
//! Wait on a condition variable
|
||||
/*!
|
||||
Waiting on a conditation variable for up to \c timeout seconds.
|
||||
Wait on a conditation variable for up to \c timeout seconds.
|
||||
If \c timeout is < 0 then there is no timeout. The mutex must
|
||||
be locked when this method is called. The mutex is unlocked
|
||||
during the wait and locked again before returning.
|
||||
during the wait and locked again before returning. Returns
|
||||
true if the condition variable was signalled and false on
|
||||
timeout.
|
||||
|
||||
(Cancellation point)
|
||||
*/
|
||||
@@ -206,14 +215,18 @@ public:
|
||||
|
||||
//! Wait for a user event
|
||||
/*!
|
||||
Waits for up to \c timeout seconds for a pending user event.
|
||||
Returns true if an event occurred, false otherwise.
|
||||
Waits for up to \c timeout seconds for a pending user event or
|
||||
\c thread to exit (normally or by cancellation). Waits forever
|
||||
if \c timeout < 0. Returns kEvent if an event occurred, kExit
|
||||
if \c thread exited, or kTimeout if the timeout expired. If
|
||||
\c thread is NULL then it doesn't wait for any thread to exit
|
||||
and it will not return kExit.
|
||||
|
||||
This method is not required by all platforms.
|
||||
|
||||
(Cancellation point)
|
||||
*/
|
||||
virtual bool waitForEvent(double timeout) = 0;
|
||||
virtual EWaitResult waitForEvent(CArchThread thread, double timeout) = 0;
|
||||
|
||||
//! Compare threads
|
||||
/*!
|
||||
|
||||
63
lib/arch/IArchTaskBar.h
Normal file
63
lib/arch/IArchTaskBar.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2003 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 COPYING 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.
|
||||
*/
|
||||
|
||||
#ifndef IARCHTASKBAR_H
|
||||
#define IARCHTASKBAR_H
|
||||
|
||||
#include "IInterface.h"
|
||||
|
||||
class IArchTaskBarReceiver;
|
||||
|
||||
//! Interface for architecture dependent task bar control
|
||||
/*!
|
||||
This interface defines the task bar icon operations required
|
||||
by synergy. Each architecture must implement this interface
|
||||
though each operation can be a no-op.
|
||||
*/
|
||||
class IArchTaskBar : public IInterface {
|
||||
public:
|
||||
// Event data is architecture dependent
|
||||
typedef void* Event;
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Add a receiver
|
||||
/*!
|
||||
Add a receiver object to be notified of user and application
|
||||
events. This should be called before other methods. When
|
||||
the receiver is added to the task bar, its icon appears on
|
||||
the task bar.
|
||||
*/
|
||||
virtual void addReceiver(IArchTaskBarReceiver*) = 0;
|
||||
|
||||
//! Remove a receiver
|
||||
/*!
|
||||
Remove a receiver object from the task bar. This removes the
|
||||
icon from the task bar.
|
||||
*/
|
||||
virtual void removeReceiver(IArchTaskBarReceiver*) = 0;
|
||||
|
||||
//! Update a receiver
|
||||
/*!
|
||||
Updates the display of the receiver on the task bar. This
|
||||
should be called when the receiver appearance may have changed
|
||||
(e.g. it's icon or tool tip has changed).
|
||||
*/
|
||||
virtual void updateReceiver(IArchTaskBarReceiver*) = 0;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
#endif
|
||||
90
lib/arch/IArchTaskBarReceiver.h
Normal file
90
lib/arch/IArchTaskBarReceiver.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2003 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 COPYING 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.
|
||||
*/
|
||||
|
||||
#ifndef IARCHTASKBARRECEIVER_H
|
||||
#define IARCHTASKBARRECEIVER_H
|
||||
|
||||
#include "IInterface.h"
|
||||
#include "stdstring.h"
|
||||
|
||||
//! Interface for architecture dependent task bar event handling
|
||||
/*!
|
||||
This interface defines the task bar icon event handlers required
|
||||
by synergy. Each architecture must implement this interface
|
||||
though each operation can be a no-op.
|
||||
*/
|
||||
class IArchTaskBarReceiver : public IInterface {
|
||||
public:
|
||||
// Icon data is architecture dependent
|
||||
typedef void* Icon;
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Show status window
|
||||
/*!
|
||||
Open a window displaying current status. This should return
|
||||
immediately without waiting for the window to be closed.
|
||||
*/
|
||||
virtual void showStatus() = 0;
|
||||
|
||||
//! Popup menu
|
||||
/*!
|
||||
Popup a menu of operations at or around \c x,y and perform the
|
||||
chosen operation.
|
||||
*/
|
||||
virtual void runMenu(int x, int y) = 0;
|
||||
|
||||
//! Perform primary action
|
||||
/*!
|
||||
Perform the primary (default) action.
|
||||
*/
|
||||
virtual void primaryAction() = 0;
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Lock receiver
|
||||
/*!
|
||||
Locks the receiver from changing state. The receiver should be
|
||||
locked when querying it's state to ensure consistent results.
|
||||
Each call to \c lock() must have a matching \c unlock() and
|
||||
locks cannot be nested.
|
||||
*/
|
||||
virtual void lock() const = 0;
|
||||
|
||||
//! Unlock receiver
|
||||
virtual void unlock() const = 0;
|
||||
|
||||
//! Get icon
|
||||
/*!
|
||||
Returns the icon to display in the task bar. The interface
|
||||
to set the icon is left to subclasses. Getting and setting
|
||||
the icon must be thread safe.
|
||||
*/
|
||||
virtual const Icon getIcon() const = 0;
|
||||
|
||||
//! Get tooltip
|
||||
/*!
|
||||
Returns the tool tip to display in the task bar. The interface
|
||||
to set the tooltip is left to sublclasses. Getting and setting
|
||||
the icon must be thread safe.
|
||||
*/
|
||||
virtual std::string getToolTip() const = 0;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -26,6 +26,7 @@ EXTRA_DIST = \
|
||||
CArchNetworkWinsock.cpp \
|
||||
CArchSleepWindows.cpp \
|
||||
CArchStringWindows.cpp \
|
||||
CArchTaskBarWindows.cpp \
|
||||
CArchTimeWindows.cpp \
|
||||
XArchWindows.cpp \
|
||||
CArchConsoleWindows.h \
|
||||
@@ -37,6 +38,7 @@ EXTRA_DIST = \
|
||||
CArchNetworkWinsock.h \
|
||||
CArchSleepWindows.h \
|
||||
CArchStringWindows.h \
|
||||
CArchTaskBarWindows.h \
|
||||
CArchTimeWindows.h \
|
||||
XArchWindows.h \
|
||||
$(NULL)
|
||||
@@ -59,6 +61,8 @@ libarch_a_SOURCES = \
|
||||
IArchNetwork.h \
|
||||
IArchSleep.h \
|
||||
IArchString.h \
|
||||
IArchTaskBar.h \
|
||||
IArchTaskBarReceiver.h \
|
||||
IArchTime.h \
|
||||
XArch.h \
|
||||
$(NULL)
|
||||
@@ -72,6 +76,7 @@ EXTRA_libarch_a_SOURCES = \
|
||||
CArchNetworkBSD.cpp \
|
||||
CArchSleepUnix.cpp \
|
||||
CArchStringUnix.cpp \
|
||||
CArchTaskBarXWindows.cpp \
|
||||
CArchTimeUnix.cpp \
|
||||
CMultibyte.cpp \
|
||||
CMultibyteOS.cpp \
|
||||
@@ -87,6 +92,7 @@ EXTRA_libarch_a_SOURCES = \
|
||||
CArchNetworkBSD.h \
|
||||
CArchSleepUnix.h \
|
||||
CArchStringUnix.h \
|
||||
CArchTaskBarXWindows.h \
|
||||
CArchTimeUnix.h \
|
||||
XArchUnix.h \
|
||||
$(NULL)
|
||||
|
||||
@@ -115,6 +115,10 @@ SOURCE=.\CArchDaemonWindows.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CArchFileWindows.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CArchImpl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -143,6 +147,10 @@ SOURCE=.\CArchStringWindows.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CArchTaskBarWindows.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CArchTimeWindows.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -151,6 +159,14 @@ SOURCE=.\IArchConsole.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IArchDaemon.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IArchFile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IArchLog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -171,6 +187,14 @@ SOURCE=.\IArchString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IArchTaskBar.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IArchTaskBarReceiver.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IArchTime.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -232,6 +256,11 @@ SOURCE=.\CArchStringWindows.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CArchTaskBarWindows.cpp
|
||||
# PROP Exclude_From_Build 1
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CArchTimeWindows.cpp
|
||||
# PROP Exclude_From_Build 1
|
||||
# End Source File
|
||||
|
||||
Reference in New Issue
Block a user