]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/win32/libwin32/trayMonitor.cpp
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / win32 / libwin32 / trayMonitor.cpp
diff --git a/bacula/src/win32/libwin32/trayMonitor.cpp b/bacula/src/win32/libwin32/trayMonitor.cpp
new file mode 100644 (file)
index 0000000..ca0bd04
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2018 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+/* 
+ * 
+ *  Kern Sibbald, August 2007
+ *
+ * This is a generic tray monitor routine, which is used by all three
+ *  of the daemons. Each one compiles it with slightly different
+ *  #defines.
+ *
+ */
+
+#include "bacula.h"
+#include "jcr.h"
+#include "win32.h"
+
+trayMonitor::trayMonitor()
+{
+
+// m_tbcreated_msg = RegisterWindowMessage("TaskbarCreated");
+   
+   /* Create a window to handle tray icon messages */
+   WNDCLASSEX trayclass;
+
+   trayclass.cbSize         = sizeof(trayclass);
+   trayclass.style          = 0;
+   trayclass.lpfnWndProc    = trayMonitor::trayWinProc;
+   trayclass.cbClsExtra     = 0;
+   trayclass.cbWndExtra     = 0;
+   trayclass.hInstance      = appInstance;
+   trayclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
+   trayclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
+   trayclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
+   trayclass.lpszMenuName   = NULL;
+   trayclass.lpszClassName  = APP_NAME;
+   trayclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);
+
+   RegisterClassEx(&trayclass);
+
+   m_hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
+                CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
+                NULL, NULL, appInstance, NULL);
+   if (!m_hwnd) {
+      PostQuitMessage(0);
+      return;
+   }
+
+   /* Save our class pointer */
+   SetWindowLong(m_hwnd, GWL_USERDATA, (LPARAM)this);
+
+
+   // Load the icons for the tray
+   m_idle_icon    = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_IDLE));
+   m_running_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_RUNNING));
+   m_error_icon   = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_JOB_ERROR));
+   m_warn_icon    = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_JOB_WARNING));
+
+   /* Load the menu */
+   m_hmenu = LoadMenu(appInstance, MAKEINTRESOURCE(IDR_TRAYMENU));
+   m_visible = false;
+   m_installed = false;
+
+   /* Install the icon in the tray */
+   install();
+
+   /* Timer to trigger icon updating */
+   SetTimer(m_hwnd, 1, 5000, NULL);
+}
+
+trayMonitor::~trayMonitor()
+{
+   /* Remove the icon from the tray */
+   sendMessage(NIM_DELETE, 0);
+        
+   if (m_hmenu) {
+      DestroyMenu(m_hmenu);
+      m_hmenu = NULL;
+   }
+}
+
+void trayMonitor::install()
+{
+   m_installed = true;
+   sendMessage(NIM_ADD, bacstat);
+}
+
+void trayMonitor::update(int bacstat)
+{
+   if (!m_installed) {
+      install();
+   }
+   (void)bac_status(NULL, 0);
+   sendMessage(NIM_MODIFY, bacstat);
+}
+
+void trayMonitor::sendMessage(DWORD msg, int bacstat)
+{
+   struct s_last_job *job;
+   
+   // Create the tray icon message
+   m_nid.hWnd = m_hwnd;
+   m_nid.cbSize = sizeof(m_nid);
+   m_nid.uID = IDI_BACULA;                  // never changes after construction
+   switch (bacstat) {
+   case 0:
+      m_nid.hIcon = m_idle_icon;
+      break;
+   case JS_Running:
+      m_nid.hIcon = m_running_icon;
+      break;
+   case JS_ErrorTerminated:
+      m_nid.hIcon = m_error_icon;
+      break;
+   default:
+      if (last_jobs->size() > 0) {
+         job = (struct s_last_job *)last_jobs->last();
+         if (job->Errors) {
+            m_nid.hIcon = m_warn_icon;
+         } else {
+            m_nid.hIcon = m_idle_icon;
+         }
+      } else {
+         m_nid.hIcon = m_idle_icon;
+      }
+      break;
+   }
+
+   m_nid.uFlags = NIF_ICON | NIF_MESSAGE;
+   m_nid.uCallbackMessage = WM_TRAYNOTIFY;
+
+
+   /* Use the resource string as tip */
+   if (LoadString(appInstance, IDI_BACULA, m_nid.szTip, sizeof(m_nid.szTip))) {
+       m_nid.uFlags |= NIF_TIP;
+   }
+
+   /* Add the Bacula status to the tip string */
+   if (m_nid.uFlags & NIF_TIP) {
+       bac_status(m_nid.szTip, sizeof(m_nid.szTip));
+   }
+
+   if (Shell_NotifyIcon(msg, &m_nid)) {
+      EnableMenuItem(m_hmenu, ID_CLOSE, MF_ENABLED);
+   }
+}
+
+/*
+ * This is the windows call back for our tray window
+ */
+LRESULT CALLBACK trayMonitor::trayWinProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+   HMENU menu;
+   trayMonitor *mon = (trayMonitor *)GetWindowLong(hwnd, GWL_USERDATA);
+
+   switch (iMsg) {
+
+   /* Every five seconds, a timer message causes the icon to update */
+   case WM_TIMER:
+      if (isAService()) {
+         mon->install();
+      }
+      mon->update(bacstat);
+      break;
+
+   case WM_CREATE:
+      return 0;
+
+   case WM_COMMAND:
+      /* User has clicked an item on the tray monitor menu */
+      switch (LOWORD(wParam)) {
+      case ID_STATUS:
+         /* show the dialog box */
+         mon->m_status.show(true);
+         mon->update(bacstat);
+         break;
+
+      case ID_ABOUT:
+         /* Show the About box */
+         mon->m_about.show(true);
+         break;
+
+      /* This is turned off now */
+#ifdef xxx
+      case ID_CLOSE:
+         /* User selected Close from the tray menu */
+         PostMessage(hwnd, WM_CLOSE, 0, 0);
+         break;
+#endif
+
+      }
+      return 0;
+
+   /* Our special command to check for mouse events */
+   case WM_TRAYNOTIFY:
+      /* Right button click pops up the menu */
+      if (lParam == WM_RBUTTONUP) {
+         POINT mouse;
+         /* Get the menu and pop it up */
+         menu = GetSubMenu(mon->m_hmenu, 0);
+         if (!menu) {
+             return 0;
+         }
+
+         /* The first menu item (Status) is the default */
+         SetMenuDefaultItem(menu, 0, TRUE);
+         GetCursorPos(&mouse);
+         SetForegroundWindow(mon->m_nid.hWnd);  /* display the menu */
+
+         /* Open the menu at the mouse position */
+         TrackPopupMenu(menu, 0, mouse.x, mouse.y, 0, mon->m_nid.hWnd, NULL);
+
+      /* Left double click brings up status dialog directly */
+      } else if (lParam == WM_LBUTTONDBLCLK) {
+         mon->m_status.show(true);
+         mon->update(bacstat);
+      }
+      return 0;
+
+   case WM_CLOSE:
+      if (isAService()) {
+          mon->sendMessage(NIM_DELETE, 0);
+      }
+      terminate_app(0);
+      break;
+
+   case WM_DESTROY:
+      /* zap everything */
+      PostQuitMessage(0);
+      return 0;
+
+   case WM_QUERYENDSESSION:
+      if (!isAService() || lParam == 0) {
+         PostQuitMessage(0);
+         return TRUE;
+      }
+      return TRUE;
+
+    default:
+       /* Need to redraw tray icon */
+//     if (iMsg == mon->m_tbcreated_msg) {
+//        mon->install();    
+//     }
+       break;
+   }
+
+   return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}