41 #include "nsStringGlue.h"
43 #include "gfxImageSurface.h"
44 #include "imgIContainer.h"
45 #include "imgIDecoder.h"
46 #include "nsAutoPtr.h"
47 #include "nsComponentManagerUtils.h"
49 #include "nsIBaseWindow.h"
50 #include "nsIBufferedStreams.h"
51 #include "nsIChannel.h"
52 #include "nsIContent.h"
53 #include "nsIDocShell.h"
54 #include "nsIDocument.h"
55 #include "nsIDOMAbstractView.h"
56 #include "nsIDOMDocument.h"
57 #include "nsIDOMDocumentEvent.h"
58 #include "nsIDOMDocumentView.h"
59 #include "nsIDOMDOMImplementation.h"
60 #include "nsIDOMDocumentType.h"
61 #include "nsIDOMElement.h"
62 #include "nsIDOMEvent.h"
63 #include "nsIDOMEventTarget.h"
64 #include "nsIDOMMouseEvent.h"
65 #include "nsIDOMNodeList.h"
66 #include "nsIDOMWindow.h"
67 #include "nsIInterfaceRequestor.h"
68 #include "nsIInterfaceRequestorUtils.h"
69 #include "nsIIOService.h"
70 #include "nsIPresShell.h"
71 #include "nsIWidget.h"
72 #include "nsIWindowUtil.h"
74 #include "nsIXULDocument.h"
75 #include "nsIXULWindow.h"
76 #include "nsServiceManagerUtils.h"
82 #pragma comment(lib, "shell32.lib")
85 TEXT(
"_SYSTEMTRAYSERVICE_INST");
87 TEXT(
"_SYSTEMTRAYSERVICE_PROC");
91 #define MK_ERROR_OFFSET (0xE0000000 + (__LINE__ * 0x10000))
93 #define MK_ENSURE_NATIVE(res) \
95 NS_ENSURE_TRUE(0 != res || 0 == ::GetLastError(), \
96 ::GetLastError() + MK_ERROR_OFFSET); \
100 #define WM_TRAYICON (WM_USER + 0x17b6)
103 imgILoad, imgIContainerObserver, imgIDecoderObserver)
111 nsSystemTrayService::~nsSystemTrayService()
113 BOOL windowClassUnregistered = ::UnregisterClass(
115 ::GetModuleHandle(NULL));
116 if (windowClassUnregistered)
117 nsSystemTrayService::s_wndClass = NULL;
121 nsSystemTrayService::ShowIcon(
const nsAString& aIconId,
127 NOTIFYICONDATAW notifyIconData;
133 NS_ENSURE_SUCCESS(rv, rv);
135 notifyIconData.hIcon = hicon;
144 nsCOMPtr<nsIDOMDocument> document;
145 rv = aDOMWindow->GetDocument(getter_AddRefs(document));
146 NS_ENSURE_SUCCESS(rv, rv);
148 nsCOMPtr<nsIDOMElement> iconElement;
149 rv = document->GetElementById(aIconId, getter_AddRefs(iconElement));
150 NS_ENSURE_SUCCESS(rv, rv);
152 nsCOMPtr<nsIWindowUtil>
153 windowUtil(do_CreateInstance(
"@mozilla.org/window-util;1", &rv));
154 NS_ENSURE_SUCCESS(rv, rv);
155 rv = windowUtil->Init(aDOMWindow);
156 NS_ENSURE_SUCCESS(rv, rv);
159 rv = windowUtil->GetDocShell(getter_AddRefs(docShell));
160 NS_ENSURE_SUCCESS(rv, rv);
161 nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell, &rv));
162 NS_ENSURE_SUCCESS(rv, rv);
163 nativeWindow theNativeWindow;
164 rv = baseWindow->GetParentNativeWindow( &theNativeWindow );
165 NS_ENSURE_SUCCESS(rv, rv);
167 HWND hWnd =
reinterpret_cast<HWND
>(theNativeWindow);
168 NS_ENSURE_TRUE(hWnd, NS_ERROR_UNEXPECTED);
171 rv =
AddTrayIcon(hWnd, imageURI, aIconId, iconElement);
172 NS_ENSURE_SUCCESS(rv, rv);
178 nsSystemTrayService::HideIcon(
const nsAString& iconId)
180 NOTIFYICONDATAW notifyIconData;
183 return NS_ERROR_NOT_AVAILABLE;
185 if (notifyIconData.hWnd)
186 ::DestroyWindow(notifyIconData.hWnd);
188 Shell_NotifyIcon(NIM_DELETE, ¬ifyIconData);
197 const nsAString& iconId,
198 nsIDOMElement* targetElement)
202 NOTIFYICONDATAW notifyIconData;
203 memset(¬ifyIconData, 0,
sizeof(NOTIFYICONDATAW));
204 notifyIconData.cbSize =
sizeof(NOTIFYICONDATAW);
206 notifyIconData.uID = 1;
207 notifyIconData.uFlags = NIF_MESSAGE | NIF_ICON;
217 if (NS_FAILED(rv) || !hicon)
221 NS_ENSURE_SUCCESS(rv, rv);
224 notifyIconData.hIcon = hicon;
228 NS_ENSURE_SUCCESS(rv, rv);
233 notifyIconData.hWnd = listenerWindow;
243 nsSystemTrayService::SetTitle(
const nsAString& iconId,
const nsAString& title)
245 NOTIFYICONDATAW notifyIconData;
247 return NS_ERROR_NOT_AVAILABLE;
249 notifyIconData.uFlags = NIF_TIP;
250 PRUint32 length = title.Length();
254 wcsncpy(notifyIconData.szTip, PromiseFlatString(title).
get(), length);
267 nsCOMPtr<nsIIOService>
268 ioService(do_GetService(
"@mozilla.org/network/io-service;1", &rv));
269 nsCOMPtr<nsIChannel> channel;
270 rv = ioService->NewChannelFromURI(iconURI, getter_AddRefs(channel));
271 NS_ENSURE_SUCCESS(rv, rv);
276 rv = iconURI->GetSpec(spec);
277 NS_ENSURE_SUCCESS(rv, rv);
278 printf(
"icon URI: %s\n", spec.get());
282 nsCOMPtr<nsIInputStream> inputStream;
283 rv = channel->Open(getter_AddRefs(inputStream));
284 NS_ENSURE_SUCCESS(rv, rv);
287 nsCAutoString sourceMimeType;
288 rv = channel->GetContentType(sourceMimeType);
289 NS_ENSURE_SUCCESS(rv, rv);
292 nsCAutoString decoderContractId =
293 NS_LITERAL_CSTRING(
"@mozilla.org/image/decoder;2?type=");
294 decoderContractId.Append(sourceMimeType);
295 nsCOMPtr<imgIDecoder>
296 decoder(do_CreateInstance(decoderContractId.get(), &rv));
297 NS_ENSURE_SUCCESS(rv, rv);
300 rv = decoder->Init(
this);
301 NS_ENSURE_SUCCESS(rv, rv);
304 rv = inputStream->Available(&available);
305 NS_ENSURE_SUCCESS(rv, rv);
308 nsCOMPtr<nsIBufferedInputStream> bufferedStream(
309 do_CreateInstance(
"@mozilla.org/network/buffered-input-stream;1", &rv));
310 NS_ENSURE_SUCCESS(rv, rv);
312 rv = bufferedStream->Init(inputStream, 4096);
313 NS_ENSURE_SUCCESS(rv, rv);
316 rv = decoder->WriteFrom(bufferedStream, available, &written);
317 NS_ENSURE_SUCCESS(rv, rv);
319 rv = decoder->Close();
320 NS_ENSURE_SUCCESS(rv, rv);
322 nsRefPtr<gfxImageSurface> imageFrame;
323 rv =
mImage->CopyCurrentFrame(getter_AddRefs(imageFrame));
324 NS_ENSURE_SUCCESS(rv, rv);
327 return NS_ERROR_NOT_AVAILABLE;
329 nsCOMPtr<nsIImageToBitmap> imageToBitmap(
330 do_GetService(
"@mozilla.org/widget/image-to-win32-hbitmap;1", &rv));
331 NS_ENSURE_SUCCESS(rv, rv);
333 return imageToBitmap->ConvertImageToIcon(imageFrame, result);
339 result = (
HICON)::SendMessage(hwnd, WM_GETICON, ICON_SMALL, NULL);
342 result = (
HICON)::GetClassLongPtr(hwnd, GCLP_HICONSM);
346 result = ::LoadIcon(NULL, IDI_WINLOGO);
349 return NS_ERROR_FAILURE;
355 nsIDOMElement* targetElement)
358 HINSTANCE hInst = ::GetModuleHandle(NULL);
361 if (!nsSystemTrayService::s_wndClass) {
362 WNDCLASS wndClassDef;
363 wndClassDef.style = CS_NOCLOSE | CS_GLOBALCLASS;
365 wndClassDef.cbClsExtra = 0;
366 wndClassDef.cbWndExtra = 0;
367 wndClassDef.hInstance = hInst;
368 wndClassDef.hIcon = NULL;
369 wndClassDef.hCursor = NULL;
370 wndClassDef.hbrBackground = NULL;
371 wndClassDef.lpszMenuName = NULL;
372 wndClassDef.lpszClassName = TEXT(
"MinimizeToTray:MessageWindowClass");
374 nsSystemTrayService::s_wndClass = ::RegisterClass(&wndClassDef);
380 (LPCTSTR)nsSystemTrayService::s_wndClass,
381 TEXT(
"MinimizeToTray:MessageWindow"),
387 ::GetDesktopWindow(),
392 if (!*listenerWindow) {
393 if (::UnregisterClass((LPCTSTR)nsSystemTrayService::s_wndClass, hInst))
394 nsSystemTrayService::s_wndClass = NULL;
401 (HANDLE) targetElement)
427 if (numberOfCallsIntoWindowProc > 0)
442 nsAutoString typeArg;
452 if (LOWORD(wParam) == WA_INACTIVE)
461 TCHAR classname[256];
462 HWND hNewWnd = (HWND) lParam;
463 ::GetClassName(hNewWnd, classname, 256);
464 if (_tcscmp(classname, _T(
"MozillaDropShadowWindowClass")) == 0)
467 typeArg = NS_LITERAL_STRING(
"blur");
479 nsCOMPtr<nsIDOMElement> targetElement;
483 targetElement = (nsIDOMElement *) GetProp(hwnd,
S_PROPINST);
484 eventTarget = do_QueryInterface(targetElement);
490 nsAutoString syntheticEvent;
497 typeArg = NS_LITERAL_STRING(
"mousedown");
502 typeArg = NS_LITERAL_STRING(
"mousedown");
507 typeArg = NS_LITERAL_STRING(
"mousedown");
512 typeArg = NS_LITERAL_STRING(
"mouseup");
513 syntheticEvent = NS_LITERAL_STRING(
"click");
518 typeArg = NS_LITERAL_STRING(
"mouseup");
519 syntheticEvent = NS_LITERAL_STRING(
"click");
524 typeArg = NS_LITERAL_STRING(
"mouseup");
525 syntheticEvent = NS_LITERAL_STRING(
"click");
530 typeArg = NS_LITERAL_STRING(
"contextmenu");
532 case WM_LBUTTONDBLCLK:
535 typeArg = NS_LITERAL_STRING(
"click");
537 case WM_MBUTTONDBLCLK:
540 typeArg = NS_LITERAL_STRING(
"click");
542 case WM_RBUTTONDBLCLK:
545 typeArg = NS_LITERAL_STRING(
"click");
553 PRBool shiftArg = PR_FALSE;
554 PRBool ctrlArg = PR_FALSE;
555 PRBool altArg = PR_FALSE;
558 GetCursorPos(&mousePos);
560 if (::GetKeyState(VK_CONTROL) & 0x8000)
562 if (::GetKeyState(VK_MENU) & 0x8000)
564 if (::GetKeyState(VK_SHIFT) & 0x8000)
569 ::SetForegroundWindow(hwnd);
572 clientPos.
x = mousePos.
x;
573 clientPos.
y = mousePos.
y;
576 nsCOMPtr<nsIDOMElement>
element(do_QueryInterface(eventTarget, &rv));
577 NS_ENSURE_SUCCESS(rv, rv);
579 nsCOMPtr<nsIDOMDocument> document;
580 rv = element->GetOwnerDocument(getter_AddRefs(document));
581 NS_ENSURE_SUCCESS(rv, rv);
583 nsCOMPtr<nsIDOMDocumentEvent>
584 documentEvent(do_QueryInterface(document, &rv));
585 NS_ENSURE_SUCCESS(rv, rv);
587 nsCOMPtr<nsIDOMDocumentView>
588 documentView(do_QueryInterface(document, &rv));
589 NS_ENSURE_SUCCESS(rv, rv);
591 nsCOMPtr<nsIDOMAbstractView> abstractView;
592 rv = documentView->GetDefaultView(getter_AddRefs(abstractView));
593 NS_ENSURE_SUCCESS(rv, rv);
595 PRBool
ret = PR_TRUE;
596 nsCOMPtr<nsIDOMEvent>
event;
599 rv =
CreateEvent(documentEvent, typeArg, getter_AddRefs(event));
602 mousePos.
x, mousePos.
y, clientPos.
x, clientPos.
y, ctrlArg, altArg,
603 shiftArg, PR_FALSE, button, getter_AddRefs(event));
604 NS_ENSURE_SUCCESS(rv, rv);
606 rv = eventTarget->DispatchEvent(event, &ret);
607 NS_ENSURE_SUCCESS(rv, rv);
609 if (!syntheticEvent.IsEmpty())
612 mousePos.
x, mousePos.
y, clientPos.
x, clientPos.
y, ctrlArg, altArg,
613 shiftArg, PR_FALSE, button, getter_AddRefs(event));
614 NS_ENSURE_SUCCESS(rv, rv);
616 rv = eventTarget->DispatchEvent(event, &ret);
617 NS_ENSURE_SUCCESS(rv, rv);
622 PostMessage(hwnd, WM_NULL, 0, 0);
627 return ::CallWindowProc(
637 const nsAString& typeArg,
641 nsCOMPtr<nsIDOMEvent>
event;
642 rv = documentEvent->CreateEvent(NS_LITERAL_STRING(
"events"),
643 getter_AddRefs(event));
644 NS_ENSURE_SUCCESS(rv, rv);
646 rv =
event->InitEvent(typeArg, PR_FALSE, PR_TRUE);
647 NS_ENSURE_SUCCESS(rv, rv);
656 const nsAString& typeArg,
657 nsIDOMAbstractView* viewArg,
659 PRInt32 screenXArg, PRInt32 screenYArg,
660 PRInt32 clientXArg, PRInt32 clientYArg,
661 PRBool ctrlKeyArg, PRBool altKeyArg,
662 PRBool shiftKeyArg, PRBool metaKeyArg,
667 nsCOMPtr<nsIDOMEvent>
event;
668 rv = documentEvent->CreateEvent(NS_LITERAL_STRING(
"mouseevent"), getter_AddRefs(event));
669 NS_ENSURE_SUCCESS(rv, rv);
671 nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event, &rv));
672 NS_ENSURE_SUCCESS(rv, rv);
674 rv = mouseEvent->InitMouseEvent(typeArg, PR_FALSE, PR_TRUE, viewArg,
675 detailArg, screenXArg, screenYArg, clientXArg, clientYArg, ctrlKeyArg, altKeyArg,
676 shiftKeyArg, metaKeyArg, buttonArg, nsnull);
677 NS_ENSURE_SUCCESS(rv, rv);
679 return CallQueryInterface(mouseEvent, _retval);
688 rv = xulWindow->GetDocShell(getter_AddRefs(docShell));
689 NS_ENSURE_SUCCESS(rv, rv);
691 nsCOMPtr<nsIInterfaceRequestor> requestor(do_QueryInterface(docShell, &rv));
692 NS_ENSURE_SUCCESS(rv, rv);
694 rv = requestor->GetInterface(NS_GET_IID(
nsIDOMWindow), (
void **) _retval);
695 NS_ENSURE_SUCCESS(rv, rv);
702 nsSystemTrayService::GetImage(imgIContainer * *aImage)
705 NS_IF_ADDREF(*aImage);
710 nsSystemTrayService::SetImage(imgIContainer * aImage)
718 nsSystemTrayService::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel)
720 *aIsMultiPartChannel = PR_FALSE;
726 nsSystemTrayService::OnStartRequest(imgIRequest* aRequest)
733 nsSystemTrayService::OnStartDecode(imgIRequest *aRequest)
741 nsSystemTrayService::OnStartContainer(imgIRequest *aRequest,
742 imgIContainer *aContainer)
749 nsSystemTrayService::OnStartFrame(imgIRequest *aRequest,
758 nsSystemTrayService::OnDataAvailable(imgIRequest *aRequest,
759 PRBool aCurrentFrame,
760 const nsIntRect * aRect)
767 nsSystemTrayService::OnStopFrame(imgIRequest *aRequest,
776 nsSystemTrayService::OnStopContainer(imgIRequest *aRequest,
777 imgIContainer *aContainer)
785 nsSystemTrayService::OnStopDecode(imgIRequest *aRequest,
786 nsresult status,
const PRUnichar *statusArg)
793 nsSystemTrayService::OnStopRequest(imgIRequest* aRequest,
802 nsSystemTrayService::FrameChanged(imgIContainer *aContainer,
803 nsIntRect * aDirtyRect)
nsCOMPtr< imgIContainer > mImage
static const TCHAR * S_PROPPROC
nsresult GetIconForWnd(HWND hwnd, HICON &result)
nsresult CreateListenerWindow(HWND *listenerWindow, nsIDOMElement *targetElement)
static nsresult CreateMouseEvent(nsIDOMDocumentEvent *documentEvent, const nsAString &typeArg, nsIDOMAbstractView *viewArg, PRInt32 detailArg, PRInt32 screenXArg, PRInt32 screenYArg, PRInt32 clientXArg, PRInt32 clientYArg, PRBool ctrlKeyArg, PRBool altKeyArg, PRBool shiftKeyArg, PRBool metkeyArg, PRUint16 buttonArg, nsIDOMEvent **_retval)
NS_IMPL_ISUPPORTS4(nsSystemTrayService, nsISystemTrayService, imgILoad, imgIContainerObserver, imgIDecoderObserver) nsSystemTrayService
nsresult AddTrayIcon(HWND hwnd, nsIURI *iconURI, const nsAString &iconId, nsIDOMElement *targetElement)
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
nsresult GetDOMWindow(nsIXULWindow *xulWindow, nsIDOMWindow **_retval)
AutoReentryBlocker(PRUint32 *counter)
nsresult GetIconForURI(nsIURI *iconURI, HICON &result)
#define MK_ENSURE_NATIVE(res)
static PRUint32 numberOfCallsIntoWindowProc
static const TCHAR * S_PROPINST
static nsresult CreateEvent(nsIDOMDocumentEvent *documentEvent, const nsAString &typeArg, nsIDOMEvent **_retval)
nsInterfaceHashtable< nsStringHashKey, nsSystemTrayIconGTK > mIconDataMap