diff options
author | Constantin Kaplinsky <const@tightvnc.com> | 2006-05-25 05:12:25 +0000 |
---|---|---|
committer | Constantin Kaplinsky <const@tightvnc.com> | 2006-05-25 05:12:25 +0000 |
commit | 729598cb00d791bbdfe23ebe0023d3a1c3962f83 (patch) | |
tree | ffe1b87705a0541998b8d7c44ea75dc4702dc515 /win/winvnc/STrayIcon.cxx | |
parent | b30ae7facbdf8273f34f5d67d3d2e9c81db75576 (diff) | |
download | tigervnc-729598cb00d791bbdfe23ebe0023d3a1c3962f83.tar.gz tigervnc-729598cb00d791bbdfe23ebe0023d3a1c3962f83.zip |
Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@591 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'win/winvnc/STrayIcon.cxx')
-rw-r--r-- | win/winvnc/STrayIcon.cxx | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/win/winvnc/STrayIcon.cxx b/win/winvnc/STrayIcon.cxx new file mode 100644 index 00000000..0b10fa5b --- /dev/null +++ b/win/winvnc/STrayIcon.cxx @@ -0,0 +1,280 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software 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 software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// -=- WinVNC Version 4.0 Tray Icon implementation + +#include <winvnc/STrayIcon.h> +#include <winvnc/VNCServerService.h> +#include <winvnc/resource.h> + +#include <rfb/LogWriter.h> +#include <rfb/Configuration.h> +#include <rfb_win32/LaunchProcess.h> +#include <rfb_win32/TrayIcon.h> +#include <rfb_win32/AboutDialog.h> +#include <rfb_win32/MsgBox.h> +#include <rfb_win32/Service.h> +#include <rfb_win32/CurrentUser.h> +#include <winvnc/ControlPanel.h> + +using namespace rfb; +using namespace win32; +using namespace winvnc; + +static LogWriter vlog("STrayIcon"); + +BoolParameter STrayIconThread::disableOptions("DisableOptions", "Disable the Options entry in the VNC Server tray menu.", false); +BoolParameter STrayIconThread::disableClose("DisableClose", "Disable the Close entry in the VNC Server tray menu.", false); + + +// +// -=- AboutDialog global values +// + +const WORD rfb::win32::AboutDialog::DialogId = IDD_ABOUT; +const WORD rfb::win32::AboutDialog::Copyright = IDC_COPYRIGHT; +const WORD rfb::win32::AboutDialog::Version = IDC_VERSION; +const WORD rfb::win32::AboutDialog::BuildTime = IDC_BUILDTIME; +const WORD rfb::win32::AboutDialog::Description = IDC_DESCRIPTION; + + +// +// -=- Internal tray icon class +// + +const UINT WM_SET_TOOLTIP = WM_USER + 1; + + +class winvnc::STrayIcon : public TrayIcon { +public: + STrayIcon(STrayIconThread& t) : thread(t), + vncConfig(_T("vncconfig.exe"), isServiceProcess() ? _T("-noconsole -service") : _T("-noconsole")), + vncConnect(_T("winvnc4.exe"), _T("-noconsole -connect")) { + + // *** + SetWindowText(getHandle(), _T("winvnc::IPC_Interface")); + // *** + + SetTimer(getHandle(), 1, 3000, 0); + PostMessage(getHandle(), WM_TIMER, 1, 0); + PostMessage(getHandle(), WM_SET_TOOLTIP, 0, 0); + CPanel = new ControlPanel(getHandle()); + } + + virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) { + switch(msg) { + + case WM_USER: + { + bool userKnown = CurrentUserToken().canImpersonate(); + bool allowOptions = !STrayIconThread::disableOptions && userKnown; + bool allowClose = !STrayIconThread::disableClose && userKnown; + + switch (lParam) { + case WM_LBUTTONDBLCLK: + SendMessage(getHandle(), WM_COMMAND, ID_CONTR0L_PANEL, 0); + break; + case WM_RBUTTONUP: + HMENU menu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(thread.menu)); + HMENU trayMenu = GetSubMenu(menu, 0); + + + // Default item is Options, if available, or About if not + SetMenuDefaultItem(trayMenu, ID_CONTR0L_PANEL, FALSE); + + // Enable/disable options as required + EnableMenuItem(trayMenu, ID_OPTIONS, (!allowOptions ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND); + EnableMenuItem(trayMenu, ID_CONNECT, (!userKnown ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND); + EnableMenuItem(trayMenu, ID_CLOSE, (!allowClose ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND); + + thread.server.getClientsInfo(&LCInfo); + CheckMenuItem(trayMenu, ID_DISABLE_NEW_CLIENTS, (LCInfo.getDisable() ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND); + + // SetForegroundWindow is required, otherwise Windows ignores the + // TrackPopupMenu because the window isn't the foreground one, on + // some older Windows versions... + SetForegroundWindow(getHandle()); + + // Display the menu + POINT pos; + GetCursorPos(&pos); + TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, getHandle(), 0); + + break; + } + return 0; + } + + // Handle tray icon menu commands + case WM_COMMAND: + switch (LOWORD(wParam)) { + case ID_CONTR0L_PANEL: + CPanel->showDialog(); + break; + case ID_DISABLE_NEW_CLIENTS: + { + thread.server.getClientsInfo(&LCInfo); + LCInfo.setDisable(!LCInfo.getDisable()); + thread.server.setClientsStatus(&LCInfo); + CPanel->UpdateListView(&LCInfo); + } + break; + case ID_OPTIONS: + { + CurrentUserToken token; + if (token.canImpersonate()) + vncConfig.start(isServiceProcess() ? (HANDLE)token : INVALID_HANDLE_VALUE); + else + vlog.error("Options: unknown current user"); + } + break; + case ID_CONNECT: + { + CurrentUserToken token; + if (token.canImpersonate()) + vncConnect.start(isServiceProcess() ? (HANDLE)token : INVALID_HANDLE_VALUE); + else + vlog.error("Options: unknown current user"); + } + break; + case ID_DISCONNECT: + thread.server.disconnectClients("tray menu disconnect"); + break; + case ID_CLOSE: + if (MsgBox(0, _T("Are you sure you want to close the server?"), + MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES) { + if (isServiceProcess()) { + ImpersonateCurrentUser icu; + try { + rfb::win32::stopService(VNCServerService::Name); + } catch (rdr::Exception& e) { + MsgBox(0, TStr(e.str()), MB_ICONERROR | MB_OK); + } + } else { + thread.server.stop(); + } + } + break; + case ID_ABOUT: + AboutDialog::instance.showDialog(); + break; + } + return 0; + + // Handle commands send by other processes + case WM_COPYDATA: + { + COPYDATASTRUCT* command = (COPYDATASTRUCT*)lParam; + switch (command->dwData) { + case 1: + { + CharArray viewer = new char[command->cbData + 1]; + memcpy(viewer.buf, command->lpData, command->cbData); + viewer.buf[command->cbData] = 0; + return thread.server.addNewClient(viewer.buf) ? 1 : 0; + } + case 2: + return thread.server.disconnectClients("IPC disconnect") ? 1 : 0; + case 3: + thread.server.setClientsStatus((rfb::ListConnInfo *)command->cbData); + case 4: + thread.server.getClientsInfo(&LCInfo); + CPanel->UpdateListView(&LCInfo); + break; + }; + }; + break; + + case WM_CLOSE: + PostQuitMessage(0); + break; + + case WM_TIMER: + if (rfb::win32::desktopChangeRequired()) { + SendMessage(getHandle(), WM_CLOSE, 0, 0); + return 0; + } + + thread.server.getClientsInfo(&LCInfo); + CPanel->UpdateListView(&LCInfo); + + setIcon(thread.server.isServerInUse() ? + (!LCInfo.getDisable() ? thread.activeIcon : thread.dis_activeIcon) : + (!LCInfo.getDisable() ? thread.inactiveIcon : thread.dis_inactiveIcon)); + + return 0; + + case WM_SET_TOOLTIP: + { + rfb::Lock l(thread.lock); + if (thread.toolTip.buf) + setToolTip(thread.toolTip.buf); + } + return 0; + + } + + return TrayIcon::processMessage(msg, wParam, lParam); + } + +protected: + LaunchProcess vncConfig; + LaunchProcess vncConnect; + STrayIconThread& thread; + ControlPanel * CPanel; + rfb::ListConnInfo LCInfo; +}; + + +STrayIconThread::STrayIconThread(VNCServerWin32& sm, UINT inactiveIcon_, UINT activeIcon_, + UINT dis_inactiveIcon_, UINT dis_activeIcon_, UINT menu_) +: Thread("TrayIcon"), server(sm), inactiveIcon(inactiveIcon_), activeIcon(activeIcon_), + dis_inactiveIcon(dis_inactiveIcon_), dis_activeIcon(dis_activeIcon_),menu(menu_), + windowHandle(0), runTrayIcon(true) { + start(); +} + + +void STrayIconThread::run() { + while (runTrayIcon) { + if (rfb::win32::desktopChangeRequired() && + !rfb::win32::changeDesktop()) + Sleep(2000); + + STrayIcon icon(*this); + windowHandle = icon.getHandle(); + + MSG msg; + while (runTrayIcon && ::GetMessage(&msg, 0, 0, 0) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + windowHandle = 0; + } +} + +void STrayIconThread::setToolTip(const TCHAR* text) { + if (!windowHandle) return; + Lock l(lock); + delete [] toolTip.buf; + toolTip.buf = tstrDup(text); + PostMessage(windowHandle, WM_SET_TOOLTIP, 0, 0); +} + + |