aboutsummaryrefslogtreecommitdiffstats
path: root/win/winvnc/STrayIcon.cxx
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2006-05-25 05:12:25 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2006-05-25 05:12:25 +0000
commit729598cb00d791bbdfe23ebe0023d3a1c3962f83 (patch)
treeffe1b87705a0541998b8d7c44ea75dc4702dc515 /win/winvnc/STrayIcon.cxx
parentb30ae7facbdf8273f34f5d67d3d2e9c81db75576 (diff)
downloadtigervnc-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.cxx280
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);
+}
+
+