00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CMSWindowsServerTaskBarReceiver.h"
00020 #include "CServer.h"
00021 #include "CMSWindowsClipboard.h"
00022 #include "IEventQueue.h"
00023 #include "LogOutputters.h"
00024 #include "BasicTypes.h"
00025 #include "CArch.h"
00026 #include "CArchTaskBarWindows.h"
00027 #include "resource.h"
00028 #include "CArchMiscWindows.h"
00029 #include "CMSWindowsScreen.h"
00030
00031
00032
00033
00034
00035 const UINT CMSWindowsServerTaskBarReceiver::s_stateToIconID[kMaxState] =
00036 {
00037 IDI_TASKBAR_NOT_RUNNING,
00038 IDI_TASKBAR_NOT_WORKING,
00039 IDI_TASKBAR_NOT_CONNECTED,
00040 IDI_TASKBAR_CONNECTED
00041 };
00042
00043 CMSWindowsServerTaskBarReceiver::CMSWindowsServerTaskBarReceiver(
00044 HINSTANCE appInstance, const CBufferedLogOutputter* logBuffer) :
00045 CServerTaskBarReceiver(),
00046 m_appInstance(appInstance),
00047 m_window(NULL),
00048 m_logBuffer(logBuffer)
00049 {
00050 for (UInt32 i = 0; i < kMaxState; ++i) {
00051 m_icon[i] = loadIcon(s_stateToIconID[i]);
00052 }
00053 m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
00054
00055
00056
00057
00058
00059
00060
00061 ARCH->addReceiver(this);
00062 }
00063
00064 void
00065 CMSWindowsServerTaskBarReceiver::cleanup()
00066 {
00067 ARCH->removeReceiver(this);
00068 for (UInt32 i = 0; i < kMaxState; ++i) {
00069 deleteIcon(m_icon[i]);
00070 }
00071 DestroyMenu(m_menu);
00072 destroyWindow();
00073 }
00074
00075 CMSWindowsServerTaskBarReceiver::~CMSWindowsServerTaskBarReceiver()
00076 {
00077 cleanup();
00078 }
00079
00080 void
00081 CMSWindowsServerTaskBarReceiver::showStatus()
00082 {
00083
00084 createWindow();
00085
00086
00087 lock();
00088
00089
00090 std::string status = getToolTip();
00091
00092
00093 const CClients& clients = getClients();
00094
00095
00096 unlock();
00097
00098
00099 HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
00100 SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
00101 child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_CLIENTS);
00102 SendMessage(child, LB_RESETCONTENT, 0, 0);
00103 for (CClients::const_iterator index = clients.begin();
00104 index != clients.end(); ) {
00105 const char* client = index->c_str();
00106 if (++index == clients.end()) {
00107 SendMessage(child, LB_ADDSTRING, 0, (LPARAM)client);
00108 }
00109 else {
00110 SendMessage(child, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)client);
00111 }
00112 }
00113
00114 if (!IsWindowVisible(m_window)) {
00115
00116 POINT cursorPos;
00117 GetCursorPos(&cursorPos);
00118 RECT windowRect;
00119 GetWindowRect(m_window, &windowRect);
00120 int x = cursorPos.x;
00121 int y = cursorPos.y;
00122 int fw = GetSystemMetrics(SM_CXDLGFRAME);
00123 int fh = GetSystemMetrics(SM_CYDLGFRAME);
00124 int ww = windowRect.right - windowRect.left;
00125 int wh = windowRect.bottom - windowRect.top;
00126 int sw = GetSystemMetrics(SM_CXFULLSCREEN);
00127 int sh = GetSystemMetrics(SM_CYFULLSCREEN);
00128 if (fw < 1) {
00129 fw = 1;
00130 }
00131 if (fh < 1) {
00132 fh = 1;
00133 }
00134 if (x + ww - fw > sw) {
00135 x -= ww - fw;
00136 }
00137 else {
00138 x -= fw;
00139 }
00140 if (x < 0) {
00141 x = 0;
00142 }
00143 if (y + wh - fh > sh) {
00144 y -= wh - fh;
00145 }
00146 else {
00147 y -= fh;
00148 }
00149 if (y < 0) {
00150 y = 0;
00151 }
00152 SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh,
00153 SWP_SHOWWINDOW);
00154 }
00155 }
00156
00157 void
00158 CMSWindowsServerTaskBarReceiver::runMenu(int x, int y)
00159 {
00160
00161
00162
00163
00164
00165 createWindow();
00166 SetForegroundWindow(m_window);
00167 HMENU menu = GetSubMenu(m_menu, 0);
00168 SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
00169 HMENU logLevelMenu = GetSubMenu(menu, 3);
00170 CheckMenuRadioItem(logLevelMenu, 0, 6,
00171 CLOG->getFilter() - kERROR, MF_BYPOSITION);
00172 int n = TrackPopupMenu(menu,
00173 TPM_NONOTIFY |
00174 TPM_RETURNCMD |
00175 TPM_LEFTBUTTON |
00176 TPM_RIGHTBUTTON,
00177 x, y, 0, m_window, NULL);
00178 SendMessage(m_window, WM_NULL, 0, 0);
00179
00180
00181 switch (n) {
00182 case IDC_TASKBAR_STATUS:
00183 showStatus();
00184 break;
00185
00186 case IDC_TASKBAR_LOG:
00187 copyLog();
00188 break;
00189
00190 case IDC_TASKBAR_SHOW_LOG:
00191 ARCH->showConsole(true);
00192 break;
00193
00194 case IDC_RELOAD_CONFIG:
00195 EVENTQUEUE->addEvent(CEvent(getReloadConfigEvent(),
00196 IEventQueue::getSystemTarget()));
00197 break;
00198
00199 case IDC_FORCE_RECONNECT:
00200 EVENTQUEUE->addEvent(CEvent(getForceReconnectEvent(),
00201 IEventQueue::getSystemTarget()));
00202 break;
00203
00204 case ID_SYNERGY_RESETSERVER:
00205 EVENTQUEUE->addEvent(CEvent(getResetServerEvent(),
00206 IEventQueue::getSystemTarget()));
00207 break;
00208
00209 case IDC_TASKBAR_LOG_LEVEL_ERROR:
00210 CLOG->setFilter(kERROR);
00211 break;
00212
00213 case IDC_TASKBAR_LOG_LEVEL_WARNING:
00214 CLOG->setFilter(kWARNING);
00215 break;
00216
00217 case IDC_TASKBAR_LOG_LEVEL_NOTE:
00218 CLOG->setFilter(kNOTE);
00219 break;
00220
00221 case IDC_TASKBAR_LOG_LEVEL_INFO:
00222 CLOG->setFilter(kINFO);
00223 break;
00224
00225 case IDC_TASKBAR_LOG_LEVEL_DEBUG:
00226 CLOG->setFilter(kDEBUG);
00227 break;
00228
00229 case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
00230 CLOG->setFilter(kDEBUG1);
00231 break;
00232
00233 case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
00234 CLOG->setFilter(kDEBUG2);
00235 break;
00236
00237 case IDC_TASKBAR_QUIT:
00238 quit();
00239 break;
00240 }
00241 }
00242
00243 void
00244 CMSWindowsServerTaskBarReceiver::primaryAction()
00245 {
00246 showStatus();
00247 }
00248
00249 const IArchTaskBarReceiver::Icon
00250 CMSWindowsServerTaskBarReceiver::getIcon() const
00251 {
00252 return reinterpret_cast<Icon>(m_icon[getStatus()]);
00253 }
00254
00255 void
00256 CMSWindowsServerTaskBarReceiver::copyLog() const
00257 {
00258 if (m_logBuffer != NULL) {
00259
00260 CString data;
00261 for (CBufferedLogOutputter::const_iterator index = m_logBuffer->begin();
00262 index != m_logBuffer->end(); ++index) {
00263 data += *index;
00264 data += "\n";
00265 }
00266
00267
00268 if (!data.empty()) {
00269 CMSWindowsClipboard clipboard(m_window);
00270 clipboard.open(0);
00271 clipboard.emptyUnowned();
00272 clipboard.add(IClipboard::kText, data);
00273 clipboard.close();
00274 }
00275 }
00276 }
00277
00278 void
00279 CMSWindowsServerTaskBarReceiver::onStatusChanged()
00280 {
00281 if (IsWindowVisible(m_window)) {
00282 showStatus();
00283 }
00284 }
00285
00286 HICON
00287 CMSWindowsServerTaskBarReceiver::loadIcon(UINT id)
00288 {
00289 HANDLE icon = LoadImage(m_appInstance,
00290 MAKEINTRESOURCE(id),
00291 IMAGE_ICON,
00292 0, 0,
00293 LR_DEFAULTCOLOR);
00294 return reinterpret_cast<HICON>(icon);
00295 }
00296
00297 void
00298 CMSWindowsServerTaskBarReceiver::deleteIcon(HICON icon)
00299 {
00300 if (icon != NULL) {
00301 DestroyIcon(icon);
00302 }
00303 }
00304
00305 void
00306 CMSWindowsServerTaskBarReceiver::createWindow()
00307 {
00308
00309 if (m_window != NULL) {
00310 return;
00311 }
00312
00313
00314 m_window = CreateDialogParam(m_appInstance,
00315 MAKEINTRESOURCE(IDD_TASKBAR_STATUS),
00316 NULL,
00317 (DLGPROC)&CMSWindowsServerTaskBarReceiver::staticDlgProc,
00318 reinterpret_cast<LPARAM>(
00319 reinterpret_cast<void*>(this)));
00320
00321
00322
00323 LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
00324 style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
00325 SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
00326
00327
00328 CArchTaskBarWindows::addDialog(m_window);
00329 }
00330
00331 void
00332 CMSWindowsServerTaskBarReceiver::destroyWindow()
00333 {
00334 if (m_window != NULL) {
00335 CArchTaskBarWindows::removeDialog(m_window);
00336 DestroyWindow(m_window);
00337 m_window = NULL;
00338 }
00339 }
00340
00341 BOOL
00342 CMSWindowsServerTaskBarReceiver::dlgProc(HWND hwnd,
00343 UINT msg, WPARAM wParam, LPARAM)
00344 {
00345 switch (msg) {
00346 case WM_INITDIALOG:
00347
00348 return TRUE;
00349
00350 case WM_ACTIVATE:
00351
00352 if (LOWORD(wParam) == WA_INACTIVE) {
00353 ShowWindow(hwnd, SW_HIDE);
00354 }
00355 break;
00356 }
00357 return FALSE;
00358 }
00359
00360 BOOL CALLBACK
00361 CMSWindowsServerTaskBarReceiver::staticDlgProc(HWND hwnd,
00362 UINT msg, WPARAM wParam, LPARAM lParam)
00363 {
00364
00365
00366 CMSWindowsServerTaskBarReceiver* self = NULL;
00367 if (msg == WM_INITDIALOG) {
00368 self = reinterpret_cast<CMSWindowsServerTaskBarReceiver*>(
00369 reinterpret_cast<void*>(lParam));
00370 SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
00371 }
00372 else {
00373
00374 LONG data = (LONG)GetWindowLongPtr(hwnd, GWLP_USERDATA);
00375 if (data != 0) {
00376 self = reinterpret_cast<CMSWindowsServerTaskBarReceiver*>(
00377 reinterpret_cast<void*>(data));
00378 }
00379 }
00380
00381
00382 if (self != NULL) {
00383 return self->dlgProc(hwnd, msg, wParam, lParam);
00384 }
00385 else {
00386 return (msg == WM_INITDIALOG) ? TRUE : FALSE;
00387 }
00388 }
00389
00390 IArchTaskBarReceiver*
00391 createTaskBarReceiver(const CBufferedLogOutputter* logBuffer)
00392 {
00393 CArchMiscWindows::setIcons(
00394 (HICON)LoadImage(CArchMiscWindows::instanceWin32(),
00395 MAKEINTRESOURCE(IDI_SYNERGY),
00396 IMAGE_ICON,
00397 32, 32, LR_SHARED),
00398 (HICON)LoadImage(CArchMiscWindows::instanceWin32(),
00399 MAKEINTRESOURCE(IDI_SYNERGY),
00400 IMAGE_ICON,
00401 16, 16, LR_SHARED));
00402
00403 return new CMSWindowsServerTaskBarReceiver(
00404 CMSWindowsScreen::getWindowInstance(), logBuffer);
00405 }