fix: #8107: Remove legacy tray code

This commit is contained in:
sithlord48
2025-01-19 14:37:34 -05:00
committed by Nick Bolton
parent 62f53bbb92
commit 2040df435f
49 changed files with 15 additions and 2836 deletions

View File

@ -22,79 +22,16 @@ if(WIN32)
set(EXE_DESCRIPTION "${CMAKE_PROJECT_DESCRIPTION}\\n CLI client application")
set(EXE_ICON "
#include \"${CMAKE_CURRENT_SOURCE_DIR}/resource.h\"
IDI_DESKFLOW ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"
IDI_TASKBAR_NOT_RUNNING ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/tb_idle.ico\"
IDI_TASKBAR_NOT_WORKING ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/tb_error.ico\"
IDI_TASKBAR_NOT_CONNECTED ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"
IDI_TASKBAR_CONNECTED ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/tb_run.ico\"
")
set(EXE_RC_DIALOG "
IDD_TASKBAR_STATUS DIALOG DISCARDABLE 0, 0, 145, 18
STYLE DS_MODALFRAME | WS_POPUP
FONT 8, \"MS Sans Serif\"
BEGIN
EDITTEXT IDC_TASKBAR_STATUS_STATUS,3,3,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
END
")
set(EXE_RC_MENU "
IDR_TASKBAR MENU DISCARDABLE
BEGIN
POPUP \"${CMAKE_PROJECT_PROPER_NAME}\"
BEGIN
MENUITEM \"Show Status\", IDC_TASKBAR_STATUS
MENUITEM \"Show Log\", IDC_TASKBAR_SHOW_LOG
MENUITEM \"Copy Log To Clipboard\", IDC_TASKBAR_LOG
POPUP \"Set Log Level\"
BEGIN
MENUITEM \"Error\", IDC_TASKBAR_LOG_LEVEL_ERROR
MENUITEM \"Warning\", IDC_TASKBAR_LOG_LEVEL_WARNING
MENUITEM \"Note\", IDC_TASKBAR_LOG_LEVEL_NOTE
MENUITEM \"Info\", IDC_TASKBAR_LOG_LEVEL_INFO
MENUITEM \"Debug\", IDC_TASKBAR_LOG_LEVEL_DEBUG
MENUITEM \"Debug1\", IDC_TASKBAR_LOG_LEVEL_DEBUG1
MENUITEM \"Debug2\", IDC_TASKBAR_LOG_LEVEL_DEBUG2
END
MENUITEM SEPARATOR
MENUITEM \"Quit\", IDC_TASKBAR_QUIT
END
END
")
set(EXE_RC_STRINGTABLE "
STRINGTABLE DISCARDABLE
BEGIN
IDS_FAILED \"${CMAKE_PROJECT_PROPER_NAME} is about to quit with errors or warnings. Please check the log then click OK.\"
IDS_INIT_FAILED \"${CMAKE_PROJECT_PROPER_NAME} failed to initialize: %{1}\"
IDS_UNCAUGHT_EXCEPTION \"Uncaught exception: %{1}\"
END
")
configure_file(${CMAKE_SOURCE_DIR}/src/apps/res/rc_template.rc.in ${target}.rc)
set(PLATFORM_SOURCES
${target}.exe.manifest
MSWindowsClientTaskBarReceiver.cpp
MSWindowsClientTaskBarReceiver.h
resource.h
${PROJECT_SOURCE_DIR}/src/apps/res/deskflow.ico
${PROJECT_SOURCE_DIR}/src/apps/res/tb_error.ico
${PROJECT_SOURCE_DIR}/src/apps/res/tb_idle.ico
${PROJECT_SOURCE_DIR}/src/apps/res/tb_run.ico
${CMAKE_CURRENT_BINARY_DIR}/${target}.rc
)
elseif(APPLE)
set(PLATFORM_SOURCES
OSXClientTaskBarReceiver.cpp
OSXClientTaskBarReceiver.h
)
elseif(UNIX)
set(PLATFORM_SOURCES
XWindowsClientTaskBarReceiver.cpp
XWindowsClientTaskBarReceiver.h
)
endif()
add_executable(${target} ${PLATFORM_SOURCES} ${target}.cpp)

View File

@ -1,333 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "MSWindowsClientTaskBarReceiver.h"
#include "arch/Arch.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/ArchTaskBarWindows.h"
#include "base/EventQueue.h"
#include "base/EventTypes.h"
#include "base/log_outputters.h"
#include "client/Client.h"
#include "platform/MSWindowsClipboard.h"
#include "platform/MSWindowsScreen.h"
#include "resource.h"
//
// MSWindowsClientTaskBarReceiver
//
const UINT MSWindowsClientTaskBarReceiver::s_stateToIconID[kMaxState] = {
IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_WORKING, IDI_TASKBAR_NOT_CONNECTED, IDI_TASKBAR_CONNECTED
};
MSWindowsClientTaskBarReceiver::MSWindowsClientTaskBarReceiver(
HINSTANCE appInstance, const BufferedLogOutputter *logBuffer, IEventQueue *events
)
: ClientTaskBarReceiver(events),
m_appInstance(appInstance),
m_window(NULL),
m_logBuffer(logBuffer)
{
for (uint32_t i = 0; i < kMaxState; ++i) {
m_icon[i] = loadIcon(s_stateToIconID[i]);
}
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
// don't create the window yet. we'll create it on demand. this
// has the side benefit of being created in the thread used for
// the task bar. that's good because it means the existence of
// the window won't prevent changing the main thread's desktop.
// add ourself to the task bar
ARCH->addReceiver(this);
}
MSWindowsClientTaskBarReceiver::~MSWindowsClientTaskBarReceiver()
{
cleanup();
}
void MSWindowsClientTaskBarReceiver::cleanup()
{
ARCH->removeReceiver(this);
for (uint32_t i = 0; i < kMaxState; ++i) {
deleteIcon(m_icon[i]);
}
DestroyMenu(m_menu);
destroyWindow();
}
void MSWindowsClientTaskBarReceiver::showStatus()
{
// create the window
createWindow();
// lock self while getting status
lock();
// get the current status
std::string status = getToolTip();
// done getting status
unlock();
// update dialog
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
if (!IsWindowVisible(m_window)) {
// position it by the mouse
POINT cursorPos;
GetCursorPos(&cursorPos);
RECT windowRect;
GetWindowRect(m_window, &windowRect);
int x = cursorPos.x;
int y = cursorPos.y;
int fw = GetSystemMetrics(SM_CXDLGFRAME);
int fh = GetSystemMetrics(SM_CYDLGFRAME);
int ww = windowRect.right - windowRect.left;
int wh = windowRect.bottom - windowRect.top;
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
if (fw < 1) {
fw = 1;
}
if (fh < 1) {
fh = 1;
}
if (x + ww - fw > sw) {
x -= ww - fw;
} else {
x -= fw;
}
if (x < 0) {
x = 0;
}
if (y + wh - fh > sh) {
y -= wh - fh;
} else {
y -= fh;
}
if (y < 0) {
y = 0;
}
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh, SWP_SHOWWINDOW);
}
}
void MSWindowsClientTaskBarReceiver::runMenu(int x, int y)
{
// do popup menu. we need a window to pass to TrackPopupMenu().
// the SetForegroundWindow() and SendMessage() calls around
// TrackPopupMenu() are to get the menu to be dismissed when
// another window gets activated and are just one of those
// win32 weirdnesses.
createWindow();
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6, CLOG->getFilter() - kERROR, MF_BYPOSITION);
int n =
TrackPopupMenu(menu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, 0, m_window, NULL);
SendMessage(m_window, WM_NULL, 0, 0);
// perform the requested operation
switch (n) {
case IDC_TASKBAR_STATUS:
showStatus();
break;
case IDC_TASKBAR_LOG:
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;
}
}
void MSWindowsClientTaskBarReceiver::primaryAction()
{
showStatus();
}
IArchTaskBarReceiver::Icon MSWindowsClientTaskBarReceiver::getIcon() const
{
return static_cast<Icon>(m_icon[getStatus()]);
}
void MSWindowsClientTaskBarReceiver::copyLog() const
{
if (m_logBuffer != NULL) {
// collect log buffer
std::string data;
for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin(); index != m_logBuffer->end(); ++index) {
data += *index;
data += "\n";
}
// copy log to clipboard
if (!data.empty()) {
MSWindowsClipboard clipboard(m_window);
clipboard.open(0);
clipboard.emptyUnowned();
clipboard.add(IClipboard::kText, data);
clipboard.close();
}
}
}
void MSWindowsClientTaskBarReceiver::onStatusChanged()
{
if (IsWindowVisible(m_window)) {
showStatus();
}
}
HICON
MSWindowsClientTaskBarReceiver::loadIcon(UINT id)
{
HANDLE icon = LoadImage(m_appInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
return static_cast<HICON>(icon);
}
void MSWindowsClientTaskBarReceiver::deleteIcon(HICON icon)
{
if (icon != NULL) {
DestroyIcon(icon);
}
}
void MSWindowsClientTaskBarReceiver::createWindow()
{
// ignore if already created
if (m_window != NULL) {
return;
}
// get the status dialog
m_window = CreateDialogParam(
m_appInstance, MAKEINTRESOURCE(IDD_TASKBAR_STATUS), NULL, (DLGPROC)&MSWindowsClientTaskBarReceiver::staticDlgProc,
reinterpret_cast<LPARAM>(static_cast<void *>(this))
);
// window should appear on top of everything, including (especially)
// the task bar.
LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
// tell the task bar about this dialog
ArchTaskBarWindows::addDialog(m_window);
}
void MSWindowsClientTaskBarReceiver::destroyWindow()
{
if (m_window != NULL) {
ArchTaskBarWindows::removeDialog(m_window);
DestroyWindow(m_window);
m_window = NULL;
}
}
BOOL MSWindowsClientTaskBarReceiver::dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM)
{
switch (msg) {
case WM_INITDIALOG:
// use default focus
return TRUE;
case WM_ACTIVATE:
// hide when another window is activated
if (LOWORD(wParam) == WA_INACTIVE) {
ShowWindow(hwnd, SW_HIDE);
}
break;
}
return FALSE;
}
BOOL CALLBACK MSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// if msg is WM_INITDIALOG, extract the MSWindowsClientTaskBarReceiver*
// and put it in the extra window data then forward the call.
MSWindowsClientTaskBarReceiver *self = NULL;
if (msg == WM_INITDIALOG) {
self = static_cast<MSWindowsClientTaskBarReceiver *>(reinterpret_cast<void *>(lParam));
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam);
} else {
// get the extra window data and forward the call
LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (data != 0) {
self = (MSWindowsClientTaskBarReceiver *)data;
}
}
// forward the message
if (self != NULL) {
return self->dlgProc(hwnd, msg, wParam, lParam);
} else {
return (msg == WM_INITDIALOG) ? TRUE : FALSE;
}
}
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
{
ArchMiscWindows::setIcons(
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW), IMAGE_ICON, 32, 32, LR_SHARED),
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW), IMAGE_ICON, 16, 16, LR_SHARED)
);
return new MSWindowsClientTaskBarReceiver(MSWindowsScreen::getWindowInstance(), logBuffer, events);
}

View File

@ -1,66 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "deskflow/ClientTaskBarReceiver.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
class BufferedLogOutputter;
class IEventQueue;
//! Implementation of ClientTaskBarReceiver for Microsoft Windows
class MSWindowsClientTaskBarReceiver : public ClientTaskBarReceiver
{
public:
MSWindowsClientTaskBarReceiver(HINSTANCE, const BufferedLogOutputter *, IEventQueue *events);
virtual ~MSWindowsClientTaskBarReceiver();
// IArchTaskBarReceiver overrides
void showStatus() override;
void runMenu(int x, int y) override;
void primaryAction() override;
Icon getIcon() const override;
void cleanup();
protected:
void copyLog() const;
// ClientTaskBarReceiver overrides
virtual void onStatusChanged();
private:
HICON loadIcon(UINT);
void deleteIcon(HICON);
void createWindow();
void destroyWindow();
BOOL dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL CALLBACK staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
HINSTANCE m_appInstance;
HWND m_window;
HMENU m_menu;
HICON m_icon[kMaxState];
const BufferedLogOutputter *m_logBuffer;
static const UINT s_stateToIconID[];
};

View File

@ -1,61 +0,0 @@
/*
* Deskflow -- 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/>.
*/
#include "OSXClientTaskBarReceiver.h"
#include "arch/Arch.h"
//
// OSXClientTaskBarReceiver
//
OSXClientTaskBarReceiver::OSXClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events)
: ClientTaskBarReceiver(events)
{
// add ourself to the task bar
ARCH->addReceiver(this);
}
OSXClientTaskBarReceiver::~OSXClientTaskBarReceiver()
{
ARCH->removeReceiver(this);
}
void OSXClientTaskBarReceiver::showStatus()
{
// do nothing
}
void OSXClientTaskBarReceiver::runMenu(int, int)
{
// do nothing
}
void OSXClientTaskBarReceiver::primaryAction()
{
// do nothing
}
IArchTaskBarReceiver::Icon OSXClientTaskBarReceiver::getIcon() const
{
return nullptr;
}
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
{
return new OSXClientTaskBarReceiver(logBuffer, events);
}

View File

@ -1,38 +0,0 @@
/*
* Deskflow -- 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 "deskflow/ClientTaskBarReceiver.h"
class BufferedLogOutputter;
class IEventQueue;
//! Implementation of ClientTaskBarReceiver for OS X
class OSXClientTaskBarReceiver : public ClientTaskBarReceiver
{
public:
OSXClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
virtual ~OSXClientTaskBarReceiver();
// IArchTaskBarReceiver overrides
void showStatus() override;
void runMenu(int x, int y) override;
void primaryAction() override;
Icon getIcon() const override;
};

View File

@ -1,61 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "XWindowsClientTaskBarReceiver.h"
#include "arch/Arch.h"
//
// CXWindowsClientTaskBarReceiver
//
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events)
: ClientTaskBarReceiver(events)
{
// add ourself to the task bar
ARCH->addReceiver(this);
}
CXWindowsClientTaskBarReceiver::~CXWindowsClientTaskBarReceiver()
{
ARCH->removeReceiver(this);
}
void CXWindowsClientTaskBarReceiver::showStatus()
{
// do nothing
}
void CXWindowsClientTaskBarReceiver::runMenu(int, int)
{
// do nothing
}
void CXWindowsClientTaskBarReceiver::primaryAction()
{
// do nothing
}
IArchTaskBarReceiver::Icon CXWindowsClientTaskBarReceiver::getIcon() const
{
return nullptr;
}
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
{
return new CXWindowsClientTaskBarReceiver(logBuffer, events);
}

View File

@ -1,43 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "deskflow/ClientTaskBarReceiver.h"
class BufferedLogOutputter;
class IEventQueue;
//! Implementation of ClientTaskBarReceiver for X Windows
class CXWindowsClientTaskBarReceiver : public ClientTaskBarReceiver
{
public:
CXWindowsClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
CXWindowsClientTaskBarReceiver(const CXWindowsClientTaskBarReceiver &) = delete;
CXWindowsClientTaskBarReceiver(CXWindowsClientTaskBarReceiver &&) = delete;
virtual ~CXWindowsClientTaskBarReceiver();
CXWindowsClientTaskBarReceiver &operator=(const CXWindowsClientTaskBarReceiver &) = delete;
CXWindowsClientTaskBarReceiver &operator=(CXWindowsClientTaskBarReceiver &&) = delete;
// IArchTaskBarReceiver overrides
void showStatus() override;
void runMenu(int x, int y) override;
void primaryAction() override;
Icon getIcon() const override;
};

View File

@ -25,16 +25,6 @@
#include "arch/win32/ArchMiscWindows.h"
#endif
#if WINAPI_MSWINDOWS
#include "MSWindowsClientTaskBarReceiver.h"
#elif WINAPI_XWINDOWS
#include "XWindowsClientTaskBarReceiver.h"
#elif WINAPI_CARBON
#include "OSXClientTaskBarReceiver.h"
#else
#error Platform not supported.
#endif
int main(int argc, char **argv)
{
#if SYSAPI_WIN32
@ -48,6 +38,6 @@ int main(int argc, char **argv)
Log log;
EventQueue events;
ClientApp app(&events, createTaskBarReceiver);
ClientApp app(&events);
return app.run(argc, argv);
}

View File

@ -1,37 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by deskflowc.rc
//
#define IDS_FAILED 1
#define IDS_INIT_FAILED 2
#define IDS_UNCAUGHT_EXCEPTION 3
#define IDI_DESKFLOW 101
#define IDI_TASKBAR_NOT_RUNNING 102
#define IDI_TASKBAR_NOT_WORKING 103
#define IDI_TASKBAR_NOT_CONNECTED 104
#define IDI_TASKBAR_CONNECTED 105
#define IDR_TASKBAR 107
#define IDD_TASKBAR_STATUS 108
#define IDC_TASKBAR_STATUS_STATUS 1000
#define IDC_TASKBAR_QUIT 40001
#define IDC_TASKBAR_STATUS 40002
#define IDC_TASKBAR_LOG 40003
#define IDC_TASKBAR_SHOW_LOG 40004
#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009
#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010
#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011
#define IDC_TASKBAR_LOG_LEVEL_INFO 40012
#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013
#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014
#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40016
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -57,10 +57,10 @@ int main(int argc, char **argv)
EventQueue events;
if (isServer(argc, argv)) {
ServerApp app(&events, nullptr);
ServerApp app(&events);
return app.run(argc, argv);
} else if (isClient(argc, argv)) {
ClientApp app(&events, nullptr);
ClientApp app(&events);
return app.run(argc, argv);
} else {
showHelp();

View File

@ -22,83 +22,16 @@ if(WIN32)
set(EXE_DESCRIPTION "${CMAKE_PROJECT_DESCRIPTION}\\n CLI server application")
set(EXE_ICON "
#include \"${CMAKE_CURRENT_SOURCE_DIR}/resource.h\"
IDI_DESKFLOW ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"
IDI_TASKBAR_NOT_RUNNING ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/tb_idle.ico\"
IDI_TASKBAR_NOT_WORKING ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/tb_error.ico\"
IDI_TASKBAR_NOT_CONNECTED ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"
IDI_TASKBAR_CONNECTED ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/tb_run.ico\"
")
set(EXE_RC_DIALOG "
IDD_TASKBAR_STATUS DIALOG DISCARDABLE 0, 0, 145, 18
STYLE DS_MODALFRAME | WS_POPUP
FONT 8, \"MS Sans Serif\"
BEGIN
EDITTEXT IDC_TASKBAR_STATUS_STATUS,3,3,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
LISTBOX IDC_TASKBAR_STATUS_CLIENTS,3,17,139,40,NOT LBS_NOTIFY | LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL | WS_TABSTOP
END
")
set(EXE_RC_MENU "
IDR_TASKBAR MENU DISCARDABLE
BEGIN
POPUP \"${CMAKE_PROJECT_PROPER_NAME}\"
BEGIN
MENUITEM \"Show Status\", IDC_TASKBAR_STATUS
MENUITEM \"Show Log\", IDC_TASKBAR_SHOW_LOG
MENUITEM \"Copy Log To Clipboard\", IDC_TASKBAR_LOG
POPUP \"Set Log Level\"
BEGIN
MENUITEM \"Error\", IDC_TASKBAR_LOG_LEVEL_ERROR
MENUITEM \"Warning\", IDC_TASKBAR_LOG_LEVEL_WARNING
MENUITEM \"Note\", IDC_TASKBAR_LOG_LEVEL_NOTE
MENUITEM \"Info\", IDC_TASKBAR_LOG_LEVEL_INFO
MENUITEM \"Debug\", IDC_TASKBAR_LOG_LEVEL_DEBUG
MENUITEM \"Debug1\", IDC_TASKBAR_LOG_LEVEL_DEBUG1
MENUITEM \"Debug2\", IDC_TASKBAR_LOG_LEVEL_DEBUG2
END
MENUITEM \"Reload Configuration\", IDC_RELOAD_CONFIG
MENUITEM \"Force Reconnect\", IDC_FORCE_RECONNECT
MENUITEM \"Reset Server\", ID_DESKFLOW_RESETSERVER
MENUITEM SEPARATOR
MENUITEM \"Quit\", IDC_TASKBAR_QUIT
END
END
")
set(EXE_RC_STRINGTABLE "
STRINGTABLE DISCARDABLE
BEGIN
IDS_FAILED \"${CMAKE_PROJECT_PROPER_NAME} is about to quit with errors or warnings. Please check the log then click OK.\"
IDS_INIT_FAILED \"${CMAKE_PROJECT_PROPER_NAME} failed to initialize: %{1}\"
IDS_UNCAUGHT_EXCEPTION \"Uncaught exception: %{1}\"
END
")
configure_file(${CMAKE_SOURCE_DIR}/src/apps/res/rc_template.rc.in ${target}.rc)
set(PLATFORM_SOURCES
${target}.exe.manifest
MSWindowsServerTaskBarReceiver.cpp
MSWindowsServerTaskBarReceiver.h
resource.h
${PROJECT_SOURCE_DIR}/src/apps/res/deskflow.ico
${PROJECT_SOURCE_DIR}/src/apps/res/tb_error.ico
${PROJECT_SOURCE_DIR}/src/apps/res/tb_idle.ico
${PROJECT_SOURCE_DIR}/src/apps/res/tb_run.ico
${CMAKE_CURRENT_BINARY_DIR}/${target}.rc
)
elseif(APPLE)
set(PLATFORM_SOURCES
OSXServerTaskBarReceiver.cpp
OSXServerTaskBarReceiver.h
)
elseif(UNIX)
set(PLATFORM_SOURCES
XWindowsServerTaskBarReceiver.cpp
XWindowsServerTaskBarReceiver.h
)
endif()
add_executable(${target} ${PLATFORM_SOURCES} ${target}.cpp)

View File

@ -1,360 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "MSWindowsServerTaskBarReceiver.h"
#include "arch/Arch.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/ArchTaskBarWindows.h"
#include "base/EventQueue.h"
#include "base/EventTypes.h"
#include "base/IEventQueue.h"
#include "base/log_outputters.h"
#include "platform/MSWindowsClipboard.h"
#include "platform/MSWindowsScreen.h"
#include "resource.h"
#include "server/Server.h"
//
// MSWindowsServerTaskBarReceiver
//
const UINT MSWindowsServerTaskBarReceiver::s_stateToIconID[kMaxState] = {
IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_WORKING, IDI_TASKBAR_NOT_CONNECTED, IDI_TASKBAR_CONNECTED
};
MSWindowsServerTaskBarReceiver::MSWindowsServerTaskBarReceiver(
HINSTANCE appInstance, const BufferedLogOutputter *logBuffer, IEventQueue *events
)
: ServerTaskBarReceiver(events),
m_events(events),
m_appInstance(appInstance),
m_window(NULL),
m_logBuffer(logBuffer)
{
for (uint32_t i = 0; i < kMaxState; ++i) {
m_icon[i] = loadIcon(s_stateToIconID[i]);
}
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
// don't create the window yet. we'll create it on demand. this
// has the side benefit of being created in the thread used for
// the task bar. that's good because it means the existence of
// the window won't prevent changing the main thread's desktop.
// add ourself to the task bar
ARCH->addReceiver(this);
}
void MSWindowsServerTaskBarReceiver::cleanup()
{
ARCH->removeReceiver(this);
for (uint32_t i = 0; i < kMaxState; ++i) {
deleteIcon(m_icon[i]);
}
DestroyMenu(m_menu);
destroyWindow();
}
MSWindowsServerTaskBarReceiver::~MSWindowsServerTaskBarReceiver()
{
cleanup();
}
void MSWindowsServerTaskBarReceiver::showStatus()
{
// create the window
createWindow();
// lock self while getting status
lock();
// get the current status
std::string status = getToolTip();
// get the connect clients, if any
const Clients &clients = getClients();
// done getting status
unlock();
// update dialog
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_CLIENTS);
SendMessage(child, LB_RESETCONTENT, 0, 0);
for (Clients::const_iterator index = clients.begin(); index != clients.end();) {
const char *client = index->c_str();
if (++index == clients.end()) {
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)client);
} else {
SendMessage(child, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)client);
}
}
if (!IsWindowVisible(m_window)) {
// position it by the mouse
POINT cursorPos;
GetCursorPos(&cursorPos);
RECT windowRect;
GetWindowRect(m_window, &windowRect);
int x = cursorPos.x;
int y = cursorPos.y;
int fw = GetSystemMetrics(SM_CXDLGFRAME);
int fh = GetSystemMetrics(SM_CYDLGFRAME);
int ww = windowRect.right - windowRect.left;
int wh = windowRect.bottom - windowRect.top;
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
if (fw < 1) {
fw = 1;
}
if (fh < 1) {
fh = 1;
}
if (x + ww - fw > sw) {
x -= ww - fw;
} else {
x -= fw;
}
if (x < 0) {
x = 0;
}
if (y + wh - fh > sh) {
y -= wh - fh;
} else {
y -= fh;
}
if (y < 0) {
y = 0;
}
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh, SWP_SHOWWINDOW);
}
}
void MSWindowsServerTaskBarReceiver::runMenu(int x, int y)
{
// do popup menu. we need a window to pass to TrackPopupMenu().
// the SetForegroundWindow() and SendMessage() calls around
// TrackPopupMenu() are to get the menu to be dismissed when
// another window gets activated and are just one of those
// win32 weirdnesses.
createWindow();
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6, CLOG->getFilter() - kERROR, MF_BYPOSITION);
int n =
TrackPopupMenu(menu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, 0, m_window, NULL);
SendMessage(m_window, WM_NULL, 0, 0);
// perform the requested operation
switch (n) {
case IDC_TASKBAR_STATUS:
showStatus();
break;
case IDC_TASKBAR_LOG:
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_RELOAD_CONFIG:
m_events->addEvent(Event(m_events->forServerApp().reloadConfig(), m_events->getSystemTarget()));
break;
case IDC_FORCE_RECONNECT:
m_events->addEvent(Event(m_events->forServerApp().forceReconnect(), m_events->getSystemTarget()));
break;
case ID_DESKFLOW_RESETSERVER:
m_events->addEvent(Event(m_events->forServerApp().resetServer(), m_events->getSystemTarget()));
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;
}
}
void MSWindowsServerTaskBarReceiver::primaryAction()
{
showStatus();
}
IArchTaskBarReceiver::Icon MSWindowsServerTaskBarReceiver::getIcon() const
{
return static_cast<Icon>(m_icon[getStatus()]);
}
void MSWindowsServerTaskBarReceiver::copyLog() const
{
if (m_logBuffer != NULL) {
// collect log buffer
std::string data;
for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin(); index != m_logBuffer->end(); ++index) {
data += *index;
data += "\n";
}
// copy log to clipboard
if (!data.empty()) {
MSWindowsClipboard clipboard(m_window);
clipboard.open(0);
clipboard.emptyUnowned();
clipboard.add(IClipboard::kText, data);
clipboard.close();
}
}
}
void MSWindowsServerTaskBarReceiver::onStatusChanged()
{
if (IsWindowVisible(m_window)) {
showStatus();
}
}
HICON
MSWindowsServerTaskBarReceiver::loadIcon(UINT id)
{
HANDLE icon = LoadImage(m_appInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
return static_cast<HICON>(icon);
}
void MSWindowsServerTaskBarReceiver::deleteIcon(HICON icon)
{
if (icon != NULL) {
DestroyIcon(icon);
}
}
void MSWindowsServerTaskBarReceiver::createWindow()
{
// ignore if already created
if (m_window != NULL) {
return;
}
// get the status dialog
m_window = CreateDialogParam(
m_appInstance, MAKEINTRESOURCE(IDD_TASKBAR_STATUS), NULL, (DLGPROC)&MSWindowsServerTaskBarReceiver::staticDlgProc,
reinterpret_cast<LPARAM>(static_cast<void *>(this))
);
// window should appear on top of everything, including (especially)
// the task bar.
LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
// tell the task bar about this dialog
ArchTaskBarWindows::addDialog(m_window);
}
void MSWindowsServerTaskBarReceiver::destroyWindow()
{
if (m_window != NULL) {
ArchTaskBarWindows::removeDialog(m_window);
DestroyWindow(m_window);
m_window = NULL;
}
}
BOOL MSWindowsServerTaskBarReceiver::dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM)
{
switch (msg) {
case WM_INITDIALOG:
// use default focus
return TRUE;
case WM_ACTIVATE:
// hide when another window is activated
if (LOWORD(wParam) == WA_INACTIVE) {
ShowWindow(hwnd, SW_HIDE);
}
break;
}
return FALSE;
}
BOOL CALLBACK MSWindowsServerTaskBarReceiver::staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// if msg is WM_INITDIALOG, extract the MSWindowsServerTaskBarReceiver*
// and put it in the extra window data then forward the call.
MSWindowsServerTaskBarReceiver *self = NULL;
if (msg == WM_INITDIALOG) {
self = static_cast<MSWindowsServerTaskBarReceiver *>(reinterpret_cast<void *>(lParam));
SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
} else {
// get the extra window data and forward the call
LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (data != 0) {
self = static_cast<MSWindowsServerTaskBarReceiver *>(reinterpret_cast<void *>(data));
}
}
// forward the message
if (self != NULL) {
return self->dlgProc(hwnd, msg, wParam, lParam);
} else {
return (msg == WM_INITDIALOG) ? TRUE : FALSE;
}
}
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
{
ArchMiscWindows::setIcons(
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW), IMAGE_ICON, 32, 32, LR_SHARED),
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW), IMAGE_ICON, 16, 16, LR_SHARED)
);
return new MSWindowsServerTaskBarReceiver(MSWindowsScreen::getWindowInstance(), logBuffer, events);
}

View File

@ -1,67 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "deskflow/ServerTaskBarReceiver.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
class BufferedLogOutputter;
class IEventQueue;
//! Implementation of ServerTaskBarReceiver for Microsoft Windows
class MSWindowsServerTaskBarReceiver : public ServerTaskBarReceiver
{
public:
MSWindowsServerTaskBarReceiver(HINSTANCE, const BufferedLogOutputter *, IEventQueue *events);
virtual ~MSWindowsServerTaskBarReceiver();
// IArchTaskBarReceiver overrides
void showStatus() override;
void runMenu(int x, int y) override;
void primaryAction() override;
Icon getIcon() const override;
void cleanup();
protected:
void copyLog() const;
// ServerTaskBarReceiver overrides
virtual void onStatusChanged();
private:
HICON loadIcon(UINT);
void deleteIcon(HICON);
void createWindow();
void destroyWindow();
BOOL dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL CALLBACK staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
HINSTANCE m_appInstance;
HWND m_window;
HMENU m_menu;
HICON m_icon[kMaxState];
const BufferedLogOutputter *m_logBuffer;
IEventQueue *m_events;
static const UINT s_stateToIconID[];
};

View File

@ -1,61 +0,0 @@
/*
* Deskflow -- 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/>.
*/
#include "OSXServerTaskBarReceiver.h"
#include "arch/Arch.h"
//
// OSXServerTaskBarReceiver
//
OSXServerTaskBarReceiver::OSXServerTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events)
: ServerTaskBarReceiver(events)
{
// add ourself to the task bar
ARCH->addReceiver(this);
}
OSXServerTaskBarReceiver::~OSXServerTaskBarReceiver()
{
ARCH->removeReceiver(this);
}
void OSXServerTaskBarReceiver::showStatus()
{
// do nothing
}
void OSXServerTaskBarReceiver::runMenu(int, int)
{
// do nothing
}
void OSXServerTaskBarReceiver::primaryAction()
{
// do nothing
}
IArchTaskBarReceiver::Icon OSXServerTaskBarReceiver::getIcon() const
{
return nullptr;
}
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
{
return new OSXServerTaskBarReceiver(logBuffer, events);
}

View File

@ -1,37 +0,0 @@
/*
* Deskflow -- 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 "deskflow/ServerTaskBarReceiver.h"
class BufferedLogOutputter;
//! Implementation of ServerTaskBarReceiver for OS X
class OSXServerTaskBarReceiver : public ServerTaskBarReceiver
{
public:
OSXServerTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
virtual ~OSXServerTaskBarReceiver();
// IArchTaskBarReceiver overrides
void showStatus() override;
void runMenu(int x, int y) override;
void primaryAction() override;
Icon getIcon() const override;
};

View File

@ -1,61 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "XWindowsServerTaskBarReceiver.h"
#include "arch/Arch.h"
//
// CXWindowsServerTaskBarReceiver
//
CXWindowsServerTaskBarReceiver::CXWindowsServerTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events)
: ServerTaskBarReceiver(events)
{
// add ourself to the task bar
ARCH->addReceiver(this);
}
CXWindowsServerTaskBarReceiver::~CXWindowsServerTaskBarReceiver()
{
ARCH->removeReceiver(this);
}
void CXWindowsServerTaskBarReceiver::showStatus()
{
// do nothing
}
void CXWindowsServerTaskBarReceiver::runMenu(int, int)
{
// do nothing
}
void CXWindowsServerTaskBarReceiver::primaryAction()
{
// do nothing
}
IArchTaskBarReceiver::Icon CXWindowsServerTaskBarReceiver::getIcon() const
{
return nullptr;
}
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
{
return new CXWindowsServerTaskBarReceiver(logBuffer, events);
}

View File

@ -1,43 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "deskflow/ServerTaskBarReceiver.h"
class BufferedLogOutputter;
class IEventQueue;
//! Implementation of ServerTaskBarReceiver for X Windows
class CXWindowsServerTaskBarReceiver : public ServerTaskBarReceiver
{
public:
CXWindowsServerTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
CXWindowsServerTaskBarReceiver(const CXWindowsServerTaskBarReceiver &) = delete;
CXWindowsServerTaskBarReceiver(CXWindowsServerTaskBarReceiver &&) = delete;
virtual ~CXWindowsServerTaskBarReceiver();
CXWindowsServerTaskBarReceiver &operator=(const CXWindowsServerTaskBarReceiver &) = delete;
CXWindowsServerTaskBarReceiver &operator=(const CXWindowsServerTaskBarReceiver &&) = delete;
// IArchTaskBarReceiver overrides
void showStatus() override;
void runMenu(int x, int y) override;
void primaryAction() override;
Icon getIcon() const override;
};

View File

@ -25,16 +25,6 @@
#include "arch/win32/ArchMiscWindows.h"
#endif
#if WINAPI_MSWINDOWS
#include "MSWindowsServerTaskBarReceiver.h"
#elif WINAPI_XWINDOWS
#include "XWindowsServerTaskBarReceiver.h"
#elif WINAPI_CARBON
#include "OSXServerTaskBarReceiver.h"
#else
#error Platform not supported.
#endif
int main(int argc, char **argv)
{
#if SYSAPI_WIN32
@ -48,6 +38,6 @@ int main(int argc, char **argv)
Log log;
EventQueue events;
ServerApp app(&events, createTaskBarReceiver);
ServerApp app(&events);
return app.run(argc, argv);
}

View File

@ -1,42 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by server .rc file
//
#define IDS_FAILED 1
#define IDS_INIT_FAILED 2
#define IDS_UNCAUGHT_EXCEPTION 3
#define IDI_DESKFLOW 101
#define IDI_TASKBAR_NOT_RUNNING 102
#define IDI_TASKBAR_NOT_WORKING 103
#define IDI_TASKBAR_NOT_CONNECTED 104
#define IDI_TASKBAR_CONNECTED 105
#define IDR_TASKBAR 107
#define IDD_TASKBAR_STATUS 108
#define IDC_TASKBAR_STATUS_STATUS 1000
#define IDC_TASKBAR_STATUS_CLIENTS 1001
#define IDC_TASKBAR_QUIT 40003
#define IDC_TASKBAR_STATUS 40004
#define IDC_TASKBAR_LOG 40005
#define IDC_RELOAD_CONFIG 40006
#define IDC_FORCE_RECONNECT 40007
#define IDC_TASKBAR_SHOW_LOG 40008
#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009
#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010
#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011
#define IDC_TASKBAR_LOG_LEVEL_INFO 40012
#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013
#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014
#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015
#define ID_DESKFLOW_RELOADSYSTEM 40016
#define ID_DESKFLOW_RESETSERVER 40017
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40018
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@ -50,7 +50,6 @@ void Arch::init()
{
ARCH_NETWORK::init();
#if SYSAPI_WIN32
ARCH_TASKBAR::init();
ArchMiscWindows::init();
#endif
}

View File

@ -48,7 +48,6 @@
#include "arch/win32/ArchSleepWindows.h"
#include "arch/win32/ArchStringWindows.h"
#include "arch/win32/ArchSystemWindows.h"
#include "arch/win32/ArchTaskBarWindows.h"
#include "arch/win32/ArchTimeWindows.h"
#elif SYSAPI_UNIX
@ -61,7 +60,6 @@
#include "arch/unix/ArchSleepUnix.h"
#include "arch/unix/ArchStringUnix.h"
#include "arch/unix/ArchSystemUnix.h"
#include "arch/unix/ArchTaskBarXWindows.h"
#include "arch/unix/ArchTimeUnix.h"
#if HAVE_PTHREAD
@ -95,7 +93,6 @@ class Arch : public ARCH_CONSOLE,
public ARCH_SLEEP,
public ARCH_STRING,
public ARCH_SYSTEM,
public ARCH_TASKBAR,
public ARCH_TIME
{
public:

View File

@ -38,8 +38,6 @@ if(WIN32)
win32/ArchStringWindows.h
win32/ArchSystemWindows.cpp
win32/ArchSystemWindows.h
win32/ArchTaskBarWindows.cpp
win32/ArchTaskBarWindows.h
win32/ArchTimeWindows.cpp
win32/ArchTimeWindows.h
win32/XArchWindows.cpp
@ -66,8 +64,6 @@ elseif(UNIX)
unix/ArchStringUnix.h
unix/ArchSystemUnix.cpp
unix/ArchSystemUnix.h
unix/ArchTaskBarXWindows.cpp
unix/ArchTaskBarXWindows.h
unix/ArchTimeUnix.cpp
unix/ArchTimeUnix.h
unix/XArchUnix.cpp
@ -92,8 +88,6 @@ add_library(arch STATIC ${PLATFORM_CODE}
IArchString.cpp
IArchString.h
IArchSystem.h
IArchTaskBar.h
IArchTaskBarReceiver.h
IArchTime.h
multibyte.h
vsnprintf.h

View File

@ -1,64 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "common/IInterface.h"
class IArchTaskBarReceiver;
//! Interface for architecture dependent task bar control
/*!
This interface defines the task bar icon operations required
by deskflow. Each architecture must implement this interface
though each operation can be a no-op.
*/
class IArchTaskBar : public IInterface
{
public:
//! @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;
//@}
virtual void init() = 0;
};

View File

@ -1,102 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "common/IInterface.h"
#include <string>
class IScreen;
class INode;
//! Interface for architecture dependent task bar event handling
/*!
This interface defines the task bar icon event handlers required
by deskflow. Each architecture must implement this interface
though each operation can be a no-op.
*/
class IArchTaskBarReceiver : public IInterface
{
public:
// Icon data is architecture dependent
using Icon = void *;
//! @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 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;
virtual void updateStatus(INode *, const std::string &errorMsg) = 0;
virtual void cleanup()
{
}
//@}
};

View File

@ -1,48 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "arch/unix/ArchTaskBarXWindows.h"
//
// ArchTaskBarXWindows
//
ArchTaskBarXWindows::ArchTaskBarXWindows()
{
// do nothing
}
ArchTaskBarXWindows::~ArchTaskBarXWindows()
{
// do nothing
}
void ArchTaskBarXWindows::addReceiver(IArchTaskBarReceiver * /*receiver*/)
{
// do nothing
}
void ArchTaskBarXWindows::removeReceiver(IArchTaskBarReceiver * /*receiver*/)
{
// do nothing
}
void ArchTaskBarXWindows::updateReceiver(IArchTaskBarReceiver * /*receiver*/)
{
// do nothing
}

View File

@ -1,36 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "arch/IArchTaskBar.h"
#define ARCH_TASKBAR ArchTaskBarXWindows
//! X11 implementation of IArchTaskBar
class ArchTaskBarXWindows : public IArchTaskBar
{
public:
ArchTaskBarXWindows();
virtual ~ArchTaskBarXWindows();
// IArchTaskBar overrides
virtual void addReceiver(IArchTaskBarReceiver *);
virtual void removeReceiver(IArchTaskBarReceiver *);
virtual void updateReceiver(IArchTaskBarReceiver *);
};

View File

@ -1,488 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "arch/win32/ArchTaskBarWindows.h"
#include "arch/Arch.h"
#include "arch/IArchTaskBarReceiver.h"
#include "arch/XArch.h"
#include "arch/win32/ArchMiscWindows.h"
#include "deskflow/win32/AppUtilWindows.h"
#include <shellapi.h>
#include <string.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;
//
// ArchTaskBarWindows
//
ArchTaskBarWindows *ArchTaskBarWindows::s_instance = NULL;
ArchTaskBarWindows::ArchTaskBarWindows()
: m_mutex(NULL),
m_condVar(NULL),
m_ready(false),
m_result(0),
m_thread(NULL),
m_hwnd(NULL),
m_taskBarRestart(0),
m_nextID(kFirstReceiverID)
{
// save the singleton instance
s_instance = this;
}
ArchTaskBarWindows::~ArchTaskBarWindows()
{
if (m_thread != NULL) {
PostMessage(m_hwnd, WM_QUIT, 0, 0);
ARCH->wait(m_thread, -1.0);
ARCH->closeThread(m_thread);
}
if (m_condVar != NULL) {
ARCH->closeCondVar(m_condVar);
}
if (m_mutex != NULL) {
ARCH->closeMutex(m_mutex);
}
s_instance = NULL;
}
void ArchTaskBarWindows::init()
{
// 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(&ArchTaskBarWindows::threadEntry, this);
// wait for child thread
while (!m_ready) {
ARCH->waitCondVar(m_condVar, m_mutex, -1.0);
}
// ready
ARCH->unlockMutex(m_mutex);
}
void ArchTaskBarWindows::addDialog(HWND hwnd)
{
ArchMiscWindows::addDialog(hwnd);
}
void ArchTaskBarWindows::removeDialog(HWND hwnd)
{
ArchMiscWindows::removeDialog(hwnd);
}
void ArchTaskBarWindows::addReceiver(IArchTaskBarReceiver *receiver)
{
// ignore bogus receiver
if (receiver == NULL) {
return;
}
// add receiver if necessary
ReceiverToInfoMap::iterator index = m_receivers.find(receiver);
if (index == m_receivers.end()) {
// add it, creating a new message ID for it
ReceiverInfo 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 ArchTaskBarWindows::removeReceiver(IArchTaskBarReceiver *receiver)
{
// find receiver
ReceiverToInfoMap::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 ArchTaskBarWindows::updateReceiver(IArchTaskBarReceiver *receiver)
{
// find receiver
ReceiverToInfoMap::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 ArchTaskBarWindows::getNextID()
{
if (m_oldIDs.empty()) {
return m_nextID++;
}
UINT id = m_oldIDs.back();
m_oldIDs.pop_back();
return id;
}
void ArchTaskBarWindows::recycleID(UINT id)
{
m_oldIDs.push_back(id);
}
void ArchTaskBarWindows::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 ArchTaskBarWindows::removeIcon(UINT id)
{
ARCH->lockMutex(m_mutex);
removeIconNoLock(id);
ARCH->unlockMutex(m_mutex);
}
void ArchTaskBarWindows::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 ArchTaskBarWindows::addAllIcons()
{
ARCH->lockMutex(m_mutex);
for (ReceiverToInfoMap::const_iterator index = m_receivers.begin(); index != m_receivers.end(); ++index) {
modifyIconNoLock(index, NIM_ADD);
}
ARCH->unlockMutex(m_mutex);
}
void ArchTaskBarWindows::removeAllIcons()
{
ARCH->lockMutex(m_mutex);
for (ReceiverToInfoMap::const_iterator index = m_receivers.begin(); index != m_receivers.end(); ++index) {
removeIconNoLock(index->second.m_id);
}
ARCH->unlockMutex(m_mutex);
}
void ArchTaskBarWindows::modifyIconNoLock(ReceiverToInfoMap::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 = static_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 ArchTaskBarWindows::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 ArchTaskBarWindows::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 ArchTaskBarWindows::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);
// there was previously some code here, with the comment "remove removed
// dialogs":
// m_dialogs.erase(false);
//
// it's not entirely clear what this code was doing, but it was probably
// trying to erase dialogs that had been removed (i.e. the map value was
// `false`).
for (auto it = m_dialogs.begin(); it != m_dialogs.end();) {
if (it->second == false) {
it = m_dialogs.erase(it);
} else {
++it;
}
}
// merge added dialogs into the dialog list
for (Dialogs::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 (Dialogs::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
ArchTaskBarWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case kNotifyReceiver: {
// lookup receiver
CIDToReceiverMap::const_iterator index = m_idTable.find((UINT)wParam);
if (index != m_idTable.end()) {
IArchTaskBarReceiver *receiver = index->second->first;
handleIconMessage(receiver, lParam);
return 0;
}
break;
}
case kAddReceiver:
addIcon((UINT)wParam);
break;
case kRemoveReceiver:
removeIcon((UINT)wParam);
break;
case kUpdateReceiver:
updateIcon((UINT)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 ArchTaskBarWindows::staticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// if msg is WM_NCCREATE, extract the ArchTaskBarWindows* and put
// it in the extra window data then forward the call.
ArchTaskBarWindows *self = NULL;
if (msg == WM_NCCREATE) {
CREATESTRUCT *createInfo;
createInfo = reinterpret_cast<CREATESTRUCT *>(lParam);
self = static_cast<ArchTaskBarWindows *>(createInfo->lpCreateParams);
SetWindowLongPtr(hwnd, 0, reinterpret_cast<LONG_PTR>(createInfo->lpCreateParams));
} else {
// get the extra window data and forward the call
LONG_PTR data = GetWindowLongPtr(hwnd, 0);
if (data != 0) {
self = static_cast<ArchTaskBarWindows *>(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 ArchTaskBarWindows::threadMainLoop()
{
// register the task bar restart message
m_taskBarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
// register a window class
LPCTSTR className = TEXT("DeskflowTaskBar");
WNDCLASSEX classInfo;
classInfo.cbSize = sizeof(classInfo);
classInfo.style = CS_NOCLOSE;
classInfo.lpfnWndProc = &ArchTaskBarWindows::staticWndProc;
classInfo.cbClsExtra = 0;
classInfo.cbWndExtra = sizeof(ArchTaskBarWindows *);
classInfo.hInstance = instanceWin32();
classInfo.hIcon = NULL;
classInfo.hCursor = NULL;
classInfo.hbrBackground = NULL;
classInfo.lpszMenuName = NULL;
classInfo.lpszClassName = className;
classInfo.hIconSm = NULL;
ATOM windowClass = RegisterClassEx(&classInfo);
// create window
m_hwnd = CreateWindowEx(
WS_EX_TOOLWINDOW, className, TEXT("Deskflow Task Bar"), WS_POPUP, 0, 0, 1, 1, NULL, NULL, instanceWin32(),
static_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(className, instanceWin32());
return;
}
// main loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
if (!processDialogs(&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// clean up
removeAllIcons();
DestroyWindow(m_hwnd);
UnregisterClass(className, instanceWin32());
}
void *ArchTaskBarWindows::threadEntry(void *self)
{
static_cast<ArchTaskBarWindows *>(self)->threadMainLoop();
return NULL;
}
HINSTANCE ArchTaskBarWindows::instanceWin32()
{
return ArchMiscWindows::instanceWin32();
}

View File

@ -1,114 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "arch/IArchMultithread.h"
#include "arch/IArchTaskBar.h"
#include "common/stdmap.h"
#include "common/stdvector.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#define ARCH_TASKBAR ArchTaskBarWindows
//! Win32 implementation of IArchTaskBar
class ArchTaskBarWindows : public IArchTaskBar
{
public:
ArchTaskBarWindows();
virtual ~ArchTaskBarWindows();
virtual void init();
//! 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 ReceiverInfo
{
public:
UINT m_id;
};
using ReceiverToInfoMap = std::map<IArchTaskBarReceiver *, ReceiverInfo>;
using CIDToReceiverMap = std::map<UINT, ReceiverToInfoMap::iterator>;
using CIDStack = std::vector<UINT>;
using Dialogs = std::map<HWND, bool>;
UINT getNextID();
void recycleID(UINT);
void addIcon(UINT);
void removeIcon(UINT);
void updateIcon(UINT);
void addAllIcons();
void removeAllIcons();
void modifyIconNoLock(ReceiverToInfoMap::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 *);
HINSTANCE instanceWin32();
private:
static ArchTaskBarWindows *s_instance;
// multithread data
ArchMutex m_mutex;
ArchCond m_condVar;
bool m_ready;
int m_result;
ArchThread m_thread;
// child thread data
HWND m_hwnd;
UINT m_taskBarRestart;
// shared data
ReceiverToInfoMap m_receivers;
CIDToReceiverMap m_idTable;
CIDStack m_oldIDs;
UINT m_nextID;
// dialogs
Dialogs m_dialogs;
Dialogs m_addedDialogs;
};

View File

@ -67,14 +67,12 @@ App *App::s_instance = nullptr;
// App
//
App::App(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver, deskflow::ArgsBase *args)
App::App(IEventQueue *events, deskflow::ArgsBase *args)
: m_bye(&exit),
m_taskBarReceiver(NULL),
m_suspended(false),
m_events(events),
m_args(args),
m_fileLog(nullptr),
m_createTaskBarReceiver(createTaskBarReceiver),
m_appUtil(events),
m_ipcClient(nullptr),
m_socketMultiplexer(nullptr)
@ -228,10 +226,6 @@ void App::initApp(int argc, const char **argv)
// as a tray icon tooltip
BufferedLogOutputter *logBuffer = new BufferedLogOutputter(1000);
CLOG->insert(logBuffer, true);
// make the task bar receiver. the user can control this app
// through the task bar.
m_taskBarReceiver = m_createTaskBarReceiver(logBuffer, m_events);
}
}
@ -276,7 +270,7 @@ void App::runEventsLoop(void *)
// MinimalApp
//
MinimalApp::MinimalApp() : App(NULL, NULL, new deskflow::ArgsBase())
MinimalApp::MinimalApp() : App(NULL, new deskflow::ArgsBase())
{
m_arch.init();
setEvents(m_events);

View File

@ -55,7 +55,7 @@ public:
}
};
App(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver, deskflow::ArgsBase *args);
App(IEventQueue *events, deskflow::ArgsBase *args);
App(App const &) = delete;
App(App &&) = delete;
virtual ~App();
@ -110,11 +110,6 @@ public:
m_socketMultiplexer = sm;
}
virtual IArchTaskBarReceiver *taskBarReceiver() const
{
return m_taskBarReceiver;
}
SocketMultiplexer *getSocketMultiplexer() const
{
return m_socketMultiplexer;
@ -136,7 +131,6 @@ protected:
void cleanupIpcClient();
void runEventsLoop(void *);
IArchTaskBarReceiver *m_taskBarReceiver;
bool m_suspended;
IEventQueue *m_events;
@ -201,7 +195,6 @@ private:
" -1, --no-restart do not try to restart on failure.\n" \
"* --restart restart the server automatically if it fails.\n" \
" -l --log <file> write log messages to file.\n" \
" --no-tray disable the system tray icon.\n" \
" --enable-drag-drop enable file drag & drop.\n" \
" --enable-crypto enable TLS encryption.\n" \
" --tls-cert specify the path to the TLS certificate file.\n"

View File

@ -199,8 +199,6 @@ bool ArgParser::parseGenericArgs(int argc, const char *const *argv, int &i)
m_app->version();
}
argsBase().m_shouldExitOk = true;
} else if (isArg(i, argc, argv, nullptr, "--no-tray")) {
argsBase().m_disableTray = true;
} else if (isArg(i, argc, argv, nullptr, "--ipc")) {
argsBase().m_enableIpc = true;
} else if (isArg(i, argc, argv, nullptr, "--server")) {

View File

@ -94,8 +94,6 @@ add_library(${lib_name} STATIC ${PLATFORM_CODE}
ClientApp.h
ClientArgs.cpp
ClientArgs.h
ClientTaskBarReceiver.cpp
ClientTaskBarReceiver.h
clipboard_types.h
Clipboard.cpp
Clipboard.h
@ -149,8 +147,6 @@ add_library(${lib_name} STATIC ${PLATFORM_CODE}
ServerApp.h
ServerArgs.cpp
ServerArgs.h
ServerTaskBarReceiver.cpp
ServerTaskBarReceiver.h
StreamChunker.cpp
StreamChunker.h
XDeskflow.cpp

View File

@ -19,7 +19,6 @@
#include "deskflow/ClientApp.h"
#include "arch/Arch.h"
#include "arch/IArchTaskBarReceiver.h"
#include "base/Event.h"
#include "base/IEventQueue.h"
#include "base/Log.h"
@ -74,8 +73,8 @@
#define RETRY_TIME 1.0
ClientApp::ClientApp(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver)
: App(events, createTaskBarReceiver, new deskflow::ClientArgs()),
ClientApp::ClientApp(IEventQueue *events)
: App(events, new deskflow::ClientArgs()),
m_client(NULL),
m_clientScreen(NULL),
m_serverAddress(NULL)
@ -230,9 +229,6 @@ void ClientApp::updateStatus()
void ClientApp::updateStatus(const std::string &msg)
{
if (m_taskBarReceiver) {
m_taskBarReceiver->updateStatus(m_client, msg);
}
}
void ClientApp::resetRestartTimeout()
@ -542,11 +538,6 @@ int ClientApp::runInner(int argc, char **argv, ILogOutputter *outputter, Startup
// run
result = startup(argc, argv);
} catch (...) {
if (m_taskBarReceiver) {
// done with task bar receiver
delete m_taskBarReceiver;
}
delete m_serverAddress;
throw;

View File

@ -36,7 +36,7 @@ class ClientArgs;
class ClientApp : public App
{
public:
ClientApp(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver);
ClientApp(IEventQueue *events);
virtual ~ClientApp();
//

View File

@ -1,123 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "deskflow/ClientTaskBarReceiver.h"
#include "arch/Arch.h"
#include "base/IEventQueue.h"
#include "base/String.h"
#include "client/Client.h"
#include "common/constants.h"
#include "mt/Lock.h"
//
// ClientTaskBarReceiver
//
ClientTaskBarReceiver::ClientTaskBarReceiver(IEventQueue *events) : m_state(kNotRunning), m_events(events)
{
// do nothing
}
ClientTaskBarReceiver::~ClientTaskBarReceiver()
{
// do nothing
}
void ClientTaskBarReceiver::updateStatus(Client *client, const std::string &errorMsg)
{
{
// update our status
m_errorMessage = errorMsg;
if (client == NULL) {
if (m_errorMessage.empty()) {
m_state = kNotRunning;
} else {
m_state = kNotWorking;
}
} else {
m_server = client->getServerAddress().getHostname();
if (client->isConnected()) {
m_state = kConnected;
} else if (client->isConnecting()) {
m_state = kConnecting;
} else {
m_state = kNotConnected;
}
}
// let subclasses have a go
onStatusChanged(client);
}
// tell task bar
ARCH->updateReceiver(this);
}
ClientTaskBarReceiver::EState ClientTaskBarReceiver::getStatus() const
{
return m_state;
}
const std::string &ClientTaskBarReceiver::getErrorMessage() const
{
return m_errorMessage;
}
void ClientTaskBarReceiver::quit()
{
m_events->addEvent(Event(Event::kQuit));
}
void ClientTaskBarReceiver::onStatusChanged(Client *)
{
// do nothing
}
void ClientTaskBarReceiver::lock() const
{
// do nothing
}
void ClientTaskBarReceiver::unlock() const
{
// do nothing
}
std::string ClientTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return deskflow::string::sprintf("%s: Not running", kAppName);
case kNotWorking:
return deskflow::string::sprintf("%s: %s", kAppName, m_errorMessage.c_str());
case kNotConnected:
return deskflow::string::sprintf("%s: Not connected: %s", kAppName, m_errorMessage.c_str());
case kConnecting:
return deskflow::string::sprintf("%s: Connecting to %s...", kAppName, m_server.c_str());
case kConnected:
return deskflow::string::sprintf("%s: Connected to %s", kAppName, m_server.c_str());
default:
return "";
}
}

View File

@ -1,98 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "arch/IArchTaskBarReceiver.h"
#include "base/log_outputters.h"
#include "client/Client.h"
class IEventQueue;
//! Implementation of IArchTaskBarReceiver for the deskflow server
class ClientTaskBarReceiver : public IArchTaskBarReceiver
{
public:
ClientTaskBarReceiver(IEventQueue *events);
virtual ~ClientTaskBarReceiver();
//! @name manipulators
//@{
//! Update status
/*!
Determine the status and query required information from the client.
*/
void updateStatus(Client *, const std::string &errorMsg);
void updateStatus(INode *n, const std::string &errorMsg)
{
updateStatus((Client *)n, errorMsg);
}
//@}
// IArchTaskBarReceiver overrides
virtual void showStatus() = 0;
virtual void runMenu(int x, int y) = 0;
virtual void primaryAction() = 0;
virtual void lock() const;
virtual void unlock() const;
virtual Icon getIcon() const = 0;
virtual std::string getToolTip() const;
virtual void cleanup()
{
}
protected:
enum EState
{
kNotRunning,
kNotWorking,
kNotConnected,
kConnecting,
kConnected,
kMaxState
};
//! Get status
EState getStatus() const;
//! Get error message
const std::string &getErrorMessage() const;
//! Quit app
/*!
Causes the application to quit gracefully
*/
void quit();
//! Status change notification
/*!
Called when status changes. The default implementation does nothing.
*/
virtual void onStatusChanged(Client *client);
private:
EState m_state;
std::string m_errorMessage;
std::string m_server;
IEventQueue *m_events;
};
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events);

View File

@ -27,7 +27,6 @@ class ArgsBase;
}
class ILogOutputter;
class IArchTaskBarReceiver;
namespace deskflow {
class Screen;
}
@ -41,7 +40,6 @@ public:
virtual int standardStartup(int argc, char **argv) = 0;
virtual int runInner(int argc, char **argv, ILogOutputter *outputter, StartupFunc startup) = 0;
virtual void startNode() = 0;
virtual IArchTaskBarReceiver *taskBarReceiver() const = 0;
virtual void bye(int error) = 0;
virtual int mainLoop() = 0;
virtual void initApp(int argc, const char **argv) = 0;

View File

@ -28,7 +28,6 @@
#include "deskflow/ArgParser.h"
#include "deskflow/Screen.h"
#include "deskflow/ServerArgs.h"
#include "deskflow/ServerTaskBarReceiver.h"
#include "deskflow/XScreen.h"
#include "net/InverseSockets/InverseSocketFactory.h"
#include "net/SocketMultiplexer.h"
@ -81,8 +80,8 @@ using namespace deskflow::server;
// ServerApp
//
ServerApp::ServerApp(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver)
: App(events, createTaskBarReceiver, new deskflow::ServerArgs()),
ServerApp::ServerApp(IEventQueue *events)
: App(events, new deskflow::ServerArgs()),
m_server(NULL),
m_serverState(kUninitialized),
m_serverScreen(NULL),
@ -327,9 +326,6 @@ void ServerApp::updateStatus()
void ServerApp::updateStatus(const std::string &msg)
{
if (m_taskBarReceiver) {
m_taskBarReceiver->updateStatus(m_server, msg);
}
}
void ServerApp::closeClientListener(ClientListener *listen)
@ -808,11 +804,6 @@ int ServerApp::runInner(int argc, char **argv, ILogOutputter *outputter, Startup
// run
int result = startup(argc, argv);
if (m_taskBarReceiver) {
// done with task bar receiver
delete m_taskBarReceiver;
}
delete m_deskflowAddress;
return result;
}

View File

@ -56,7 +56,7 @@ class ServerApp : public App
using ServerConfig = deskflow::server::Config;
public:
ServerApp(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver);
ServerApp(IEventQueue *events);
virtual ~ServerApp();
//

View File

@ -1,123 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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/>.
*/
#include "deskflow/ServerTaskBarReceiver.h"
#include "arch/Arch.h"
#include "base/IEventQueue.h"
#include "base/String.h"
#include "common/constants.h"
#include "mt/Lock.h"
#include "server/Server.h"
//
// ServerTaskBarReceiver
//
ServerTaskBarReceiver::ServerTaskBarReceiver(IEventQueue *events) : m_state(kNotRunning), m_events(events)
{
// do nothing
}
ServerTaskBarReceiver::~ServerTaskBarReceiver()
{
// do nothing
}
void ServerTaskBarReceiver::updateStatus(Server *server, const std::string &errorMsg)
{
{
// update our status
m_errorMessage = errorMsg;
if (server == NULL) {
if (m_errorMessage.empty()) {
m_state = kNotRunning;
} else {
m_state = kNotWorking;
}
} else {
m_clients.clear();
server->getClients(m_clients);
if (m_clients.size() <= 1) {
m_state = kNotConnected;
} else {
m_state = kConnected;
}
}
// let subclasses have a go
onStatusChanged(server);
}
// tell task bar
ARCH->updateReceiver(this);
}
ServerTaskBarReceiver::EState ServerTaskBarReceiver::getStatus() const
{
return m_state;
}
const std::string &ServerTaskBarReceiver::getErrorMessage() const
{
return m_errorMessage;
}
const ServerTaskBarReceiver::Clients &ServerTaskBarReceiver::getClients() const
{
return m_clients;
}
void ServerTaskBarReceiver::quit()
{
m_events->addEvent(Event(Event::kQuit));
}
void ServerTaskBarReceiver::onStatusChanged(Server *)
{
// do nothing
}
void ServerTaskBarReceiver::lock() const
{
// do nothing
}
void ServerTaskBarReceiver::unlock() const
{
// do nothing
}
std::string ServerTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return deskflow::string::sprintf("%s: Not running", kAppName);
case kNotWorking:
return deskflow::string::sprintf("%s: %s", kAppName, m_errorMessage.c_str());
case kNotConnected:
return deskflow::string::sprintf("%s: Waiting for clients", kAppName);
case kConnected:
return deskflow::string::sprintf("%s: Connected", kAppName);
default:
return "";
}
}

View File

@ -1,102 +0,0 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* 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 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 "arch/IArchTaskBarReceiver.h"
#include "base/Event.h"
#include "base/EventTypes.h"
#include "common/stdvector.h"
#include "deskflow/ServerApp.h"
#include "server/Server.h"
class IEventQueue;
//! Implementation of IArchTaskBarReceiver for the deskflow server
class ServerTaskBarReceiver : public IArchTaskBarReceiver
{
public:
ServerTaskBarReceiver(IEventQueue *events);
virtual ~ServerTaskBarReceiver();
//! @name manipulators
//@{
//! Update status
/*!
Determine the status and query required information from the server.
*/
void updateStatus(Server *, const std::string &errorMsg);
void updateStatus(INode *n, const std::string &errorMsg)
{
updateStatus((Server *)n, errorMsg);
}
//@}
// IArchTaskBarReceiver overrides
virtual void showStatus() = 0;
virtual void runMenu(int x, int y) = 0;
virtual void primaryAction() = 0;
virtual void lock() const;
virtual void unlock() const;
virtual Icon getIcon() const = 0;
virtual std::string getToolTip() const;
protected:
using Clients = std::vector<std::string>;
enum EState
{
kNotRunning,
kNotWorking,
kNotConnected,
kConnected,
kMaxState
};
//! Get status
EState getStatus() const;
//! Get error message
const std::string &getErrorMessage() const;
//! Get connected clients
const Clients &getClients() const;
//! Quit app
/*!
Causes the application to quit gracefully
*/
void quit();
//! Status change notification
/*!
Called when status changes. The default implementation does
nothing.
*/
virtual void onStatusChanged(Server *server);
private:
EState m_state;
std::string m_errorMessage;
Clients m_clients;
IEventQueue *m_events;
};
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events);

View File

@ -18,7 +18,6 @@
#include "deskflow/win32/AppUtilWindows.h"
#include "arch/IArchTaskBarReceiver.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/XArchWindows.h"
#include "base/Event.h"

View File

@ -499,7 +499,6 @@ void CoreProcess::cleanup()
bool CoreProcess::addGenericArgs(QStringList &args, const ProcessMode processMode) const
{
args << "-f"
<< "--no-tray"
<< "--debug" << m_appConfig.logLevelText();
args << "--name" << m_appConfig.screenName();

View File

@ -26,7 +26,7 @@
class MockApp : public App
{
public:
MockApp() : App(NULL, NULL, NULL)
MockApp() : App(NULL, NULL)
{
}

View File

@ -216,18 +216,6 @@ TEST_F(GenericArgsParsingTests, parseGenericArgs_versionCmd_showVersion)
EXPECT_EQ(1, i);
}
TEST_F(GenericArgsParsingTests, parseGenericArgs_noTrayCmd_disableTrayTrue)
{
int i = 1;
const int argc = 2;
const char *kNoTrayCmd[argc] = {"stub", "--no-tray"};
m_argParser->parseGenericArgs(argc, kNoTrayCmd, i);
EXPECT_EQ(true, argsBase.m_disableTray);
EXPECT_EQ(1, i);
}
TEST_F(GenericArgsParsingTests, parseGenericArgs_ipcCmd_enableIpcTrue)
{
int i = 1;

View File

@ -29,7 +29,7 @@ using ::testing::NiceMock;
class MockServerApp : public ServerApp
{
public:
MockServerApp() : ServerApp(nullptr, nullptr)
MockServerApp() : ServerApp(nullptr)
{
}
};