[Pkg-mozext-commits] [firetray] 27/84: * fix re-creation of text icon * fix: unload gdi32.dll

David Prévot taffit at moszumanska.debian.org
Sun Jul 20 01:42:43 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository firetray.

commit c52b9da60955e20468860e5415b72071b9943d6b
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sun Feb 16 20:14:53 2014 +0100

    * fix re-creation of text icon
    * fix: unload gdi32.dll
---
 src/modules/FiretrayHandler.jsm          |  5 ++-
 src/modules/commons.js                   |  5 ++-
 src/modules/ctypes/winnt/gdi32.jsm       | 69 ++++++++++++++++++++++++++++++++
 src/modules/ctypes/winnt/user32.jsm      | 20 ++++++++-
 src/modules/ctypes/winnt/win32.jsm       | 19 +++++++++
 src/modules/winnt/FiretrayStatusIcon.jsm | 49 +++++++++++++++++------
 6 files changed, 152 insertions(+), 15 deletions(-)

diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index 24f6a2f..0b9e599 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -123,7 +123,7 @@ firetray.Handler = {
           firetray.Chat.init();
       } else {
         let platforms = FIRETRAY_CHAT_SUPPORTED_OS.join(", ");
-        log.error("Only "+platforms+" platform(s) supported at this time. Firetray not loaded");
+        log.error("Only "+platforms+" platform(s) supported at this time. Chat not loaded");
       }
     }
 
@@ -516,6 +516,9 @@ firetray.PrefListener = new PrefListener(
         firetray.Handler.setIconImageDefault();
       }
       break;
+    case 'mail_notification_type':
+      firetray.Messaging.updateIcon();
+      break;
     case 'new_mail_icon_names':
       firetray.StatusIcon.loadThemedIcons();
     case 'only_favorite_folders':
diff --git a/src/modules/commons.js b/src/modules/commons.js
index 2f5cfcb..f03c567 100644
--- a/src/modules/commons.js
+++ b/src/modules/commons.js
@@ -309,7 +309,10 @@ firetray.js = {
       result = result.concat(Object.getOwnPropertyNames(objectToInspect));
     }
     return result;
-  }
+  },
+
+  floatToInt: function(nb) { return nb >> 0; } // bitwise ops on signed int
+
 };
 
 // http://stackoverflow.com/questions/18912/how-to-find-keys-of-a-hash
diff --git a/src/modules/ctypes/winnt/gdi32.jsm b/src/modules/ctypes/winnt/gdi32.jsm
index 82b8fd0..72ea262 100644
--- a/src/modules/ctypes/winnt/gdi32.jsm
+++ b/src/modules/ctypes/winnt/gdi32.jsm
@@ -24,7 +24,42 @@ function gdi32_defines(lib) {
 
   lib.lazy_bind("CreateCompatibleDC", win32.HDC, win32.HDC);
   lib.lazy_bind("DeleteDC", win32.BOOL, win32.HDC);
+  lib.lazy_bind("BitBlt", win32.BOOL, win32.HDC, ctypes.int, ctypes.int, ctypes.int, ctypes.int, win32.HDC, ctypes.int, ctypes.int, win32.DWORD);
+  this.SRCCOPY        = win32.DWORD(0x00CC0020); /* dest = source                   */
+  this.SRCPAINT       = win32.DWORD(0x00EE0086); /* dest = source OR dest           */
+  this.SRCAND         = win32.DWORD(0x008800C6); /* dest = source AND dest          */
+  this.SRCINVERT      = win32.DWORD(0x00660046); /* dest = source XOR dest          */
+  this.SRCERASE       = win32.DWORD(0x00440328); /* dest = source AND (NOT dest )   */
+  this.NOTSRCCOPY     = win32.DWORD(0x00330008); /* dest = (NOT source)             */
+  this.NOTSRCERASE    = win32.DWORD(0x001100A6); /* dest = (NOT src) AND (NOT dest) */
+  this.MERGECOPY      = win32.DWORD(0x00C000CA); /* dest = (source AND pattern)     */
+  this.MERGEPAINT     = win32.DWORD(0x00BB0226); /* dest = (NOT source) OR dest     */
+  this.PATCOPY        = win32.DWORD(0x00F00021); /* dest = pattern                  */
+  this.PATPAINT       = win32.DWORD(0x00FB0A09); /* dest = DPSnoo                   */
+  this.PATINVERT      = win32.DWORD(0x005A0049); /* dest = pattern XOR dest         */
+  this.DSTINVERT      = win32.DWORD(0x00550009); /* dest = (NOT dest)               */
+  this.BLACKNESS      = win32.DWORD(0x00000042); /* dest = BLACK                    */
+  this.WHITENESS      = win32.DWORD(0x00FF0062); /* dest = WHITE                    */
+  this.NOMIRRORBITMAP = win32.DWORD(0x80000000); /* Do not Mirror the bitmap in this call */
+  this.CAPTUREBLT     = win32.DWORD(0x40000000); /* Include layered windows */
   lib.lazy_bind("CreateCompatibleBitmap", win32.HBITMAP, win32.HDC, ctypes.int, ctypes.int);
+  lib.lazy_bind("CreateBitmapIndirect", win32.HBITMAP, win32.BITMAP.ptr);
+  lib.lazy_bind("GetObjectW", ctypes.int, win32.HGDIOBJ, ctypes.int, win32.LPVOID);
+  lib.lazy_bind("GetCurrentObject", win32.HGDIOBJ, win32.HDC, win32.UINT);
+  this.OBJ_PEN         = 1;
+  this.OBJ_BRUSH       = 2;
+  this.OBJ_DC          = 3;
+  this.OBJ_METADC      = 4;
+  this.OBJ_PAL         = 5;
+  this.OBJ_FONT        = 6;
+  this.OBJ_BITMAP      = 7;
+  this.OBJ_REGION      = 8;
+  this.OBJ_METAFILE    = 9;
+  this.OBJ_MEMDC       = 10;
+  this.OBJ_EXTPEN      = 11;
+  this.OBJ_ENHMETADC   = 12;
+  this.OBJ_ENHMETAFILE = 13;
+  this.OBJ_COLORSPACE  = 14;
   lib.lazy_bind("SelectObject", win32.HGDIOBJ, win32.HDC, win32.HGDIOBJ);
   lib.lazy_bind("DeleteObject", win32.BOOL, win32.HGDIOBJ);
   lib.lazy_bind("PatBlt", win32.BOOL, win32.HDC, ctypes.int, ctypes.int, ctypes.int, ctypes.int, win32.DWORD);
@@ -77,6 +112,13 @@ function gdi32_defines(lib) {
 
   lib.lazy_bind("TextOutW", win32.BOOL, win32.HDC, ctypes.int, ctypes.int, win32.LPCTSTR, ctypes.int);
 
+  this.SIZE = ctypes.StructType("SIZE", [
+    { "cx": win32.LONG },
+    { "cy": win32.LONG }
+  ]);
+  this.LPSIZE = this.SIZE.ptr;
+  lib.lazy_bind("GetTextExtentPoint32W", win32.BOOL, win32.HDC, win32.LPCTSTR, ctypes.int, this.LPSIZE);
+
   lib.lazy_bind("GetTextAlign", win32.UINT, win32.HDC);
   lib.lazy_bind("SetTextAlign", win32.UINT, win32.HDC, win32.UINT);
   this.TA_LEFT       = 0;
@@ -88,6 +130,33 @@ function gdi32_defines(lib) {
   this.TA_RTLREADING = 256;
   this.TA_MASK       =(this.TA_BASELINE+this.TA_CENTER+this.TA_UPDATECP+this.TA_RTLREADING);
 
+  this.BITMAPINFOHEADER = ctypes.StructType("BITMAPINFOHEADER", [
+    { "biSize": win32.DWORD },
+    { "biWidth": win32.LONG },
+    { "biHeight": win32.LONG },
+    { "biPlanes": win32.WORD },
+    { "biBitCount": win32.WORD },
+    { "biCompression": win32.DWORD },
+    { "biSizeImage": win32.DWORD },
+    { "biXPelsPerMeter": win32.LONG },
+    { "biYPelsPerMeter": win32.LONG },
+    { "biClrUsed": win32.DWORD },
+    { "biClrImportant": win32.DWORD }
+  ]);
+  this.PBITMAPINFOHEADER = this.BITMAPINFOHEADER.ptr;
+  this.RGBQUAD = ctypes.StructType("RGBQUAD", [
+    { "rgbBlue": win32.BYTE },
+    { "rgbGreen": win32.BYTE },
+    { "rgbRed": win32.BYTE },
+    { "rgbReserved": win32.BYTE }
+  ]);
+  this.BITMAPINFO = ctypes.StructType("BITMAPINFO", [
+    { "bmiHeader": this.BITMAPINFOHEADER },
+    { "bmiColors": this.RGBQUAD.array(1) }
+  ]);
+  this.PBITMAPINFO = this.BITMAPINFO.ptr;
+  lib.lazy_bind("SetDIBits", ctypes.int, win32.HDC, win32.HBITMAP, win32.UINT, win32.UINT, ctypes.voidptr_t, this.BITMAPINFO.ptr, win32.UINT);
+
 }
 
 new ctypes_library(GDI32_LIBNAME, GDI32_ABIS, gdi32_defines, this);
diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm
index 6a0702e..96680c8 100644
--- a/src/modules/ctypes/winnt/user32.jsm
+++ b/src/modules/ctypes/winnt/user32.jsm
@@ -50,6 +50,7 @@ function user32_defines(lib) {
   this.IDI_QUESTION    = win32.MAKEINTRESOURCE(32514);
   this.IDI_EXCLAMATION = win32.MAKEINTRESOURCE(32515);
   this.IDI_ASTERISK    = win32.MAKEINTRESOURCE(32516);
+  lib.lazy_bind("DestroyIcon", win32.BOOL, win32.HICON);
   lib.lazy_bind("LoadImageW", win32.HANDLE, win32.HINSTANCE, win32.LPCTSTR, win32.UINT, ctypes.int, ctypes.int, win32.UINT);
   this.IMAGE_BITMAP        = 0;
   this.IMAGE_ICON          = 1;
@@ -63,7 +64,7 @@ function user32_defines(lib) {
   this.LR_MONOCHROME       = 0x00000001;
   this.LR_SHARED           = 0x00008000;
   this.LR_VGACOLOR         = 0x00000080;
-  lib.lazy_bind("DestroyIcon", win32.BOOL, win32.HICON);
+  lib.lazy_bind("CopyImage", win32.HANDLE, win32.HANDLE, win32.UINT, ctypes.int, ctypes.int, win32.UINT);
 
   lib.lazy_bind("GetPropW", win32.HANDLE, win32.HWND, win32.LPCTSTR);
   lib.lazy_bind("SetPropW", win32.BOOL, win32.HWND, win32.LPCTSTR, win32.HANDLE);
@@ -247,6 +248,23 @@ function user32_defines(lib) {
   lib.lazy_bind("GetDC", win32.HDC, win32.HWND);
   lib.lazy_bind("ReleaseDC", ctypes.int, win32.HWND, win32.HDC);
   lib.lazy_bind("CreateIconIndirect", win32.HICON, win32.PICONINFO);
+  lib.lazy_bind("GetClientRect", win32.BOOL, win32.HWND, win32.PRECT);
+  lib.lazy_bind("DrawTextW", ctypes.int, win32.HDC, win32.LPCTSTR, ctypes.int, win32.PRECT, win32.UINT);
+  this.DT_TOP             = 0x00000000;
+  this.DT_LEFT            = 0x00000000;
+  this.DT_CENTER          = 0x00000001;
+  this.DT_RIGHT           = 0x00000002;
+  this.DT_VCENTER         = 0x00000004;
+  this.DT_BOTTOM          = 0x00000008;
+  this.DT_WORDBREAK       = 0x00000010;
+  this.DT_SINGLELINE      = 0x00000020;
+  this.DT_EXPANDTABS      = 0x00000040;
+  this.DT_TABSTOP         = 0x00000080;
+  this.DT_NOCLIP          = 0x00000100;
+  this.DT_EXTERNALLEADING = 0x00000200;
+  this.DT_CALCRECT        = 0x00000400;
+  this.DT_NOPREFIX        = 0x00000800;
+  this.DT_INTERNAL        = 0x00001000;
 
 }
 
diff --git a/src/modules/ctypes/winnt/win32.jsm b/src/modules/ctypes/winnt/win32.jsm
index ecb7266..dc71e30 100644
--- a/src/modules/ctypes/winnt/win32.jsm
+++ b/src/modules/ctypes/winnt/win32.jsm
@@ -102,6 +102,16 @@ var win32 = new function() {
   this.WM_MOUSELAST     = 0x020D;
   this.WM_MOUSELAST     = 0x020A;
 
+  this.BITMAP = ctypes.StructType("BITMAP", [
+    { "bmType": this.LONG },
+    { "bmWidth": this.LONG },
+    { "bmHeight": this.LONG },
+    { "bmWidthBytes": this.LONG },
+    { "bmPlanes": this.WORD },
+    { "bmBitsPixel": this.WORD },
+    { "bmBits": this.LPVOID }
+  ]);
+
   this.ICONINFO = ctypes.StructType("ICONINFO", [
     { "fIcon": this.BOOL },
     { "xHotspot": this.DWORD },
@@ -110,6 +120,15 @@ var win32 = new function() {
     { "hbmColor": this.HBITMAP }
   ]);
   this.PICONINFO = this.ICONINFO.ptr;
+
+  this.RECT = ctypes.StructType("RECT", [
+    { "left": this.LONG },
+    { "top": this.LONG },
+    { "right": this.LONG },
+    { "bottom": this.LONG }
+  ]);
+  this.PRECT = this.RECT.ptr;
+
 };
 
 // ShellAPI.h
diff --git a/src/modules/winnt/FiretrayStatusIcon.jsm b/src/modules/winnt/FiretrayStatusIcon.jsm
index 8ae1d6a..fb13abd 100644
--- a/src/modules/winnt/FiretrayStatusIcon.jsm
+++ b/src/modules/winnt/FiretrayStatusIcon.jsm
@@ -20,7 +20,7 @@ Cu.import("resource://firetray/ctypes/winnt/shell32.jsm");
 Cu.import("resource://firetray/ctypes/winnt/user32.jsm");
 Cu.import("resource://firetray/winnt/FiretrayWin32.jsm");
 Cu.import("resource://firetray/commons.js");
-firetray.Handler.subscribeLibsForClosing([kernel32, shell32, user32]);
+firetray.Handler.subscribeLibsForClosing([gdi32, kernel32, shell32, user32]);
 
 let log = firetray.Logging.getLogger("firetray.StatusIcon");
 
@@ -194,9 +194,6 @@ firetray.StatusIcon = {
         break;
       case win32.WM_RBUTTONUP:
         log.debug("WM_RBUTTONUP");
-        let hicon = firetray.StatusIcon.createSmallIcon(hWnd, "100", "#990000");
-        log.debug("%%%%%%%%%% ICON="+hicon);
-        firetray.StatusIcon.setImageFromIcon(hicon);
         break;
       case win32.WM_CONTEXTMENU:
         log.debug("WM_CONTEXTMENU");
@@ -269,29 +266,50 @@ firetray.StatusIcon = {
   },
 
   // http://stackoverflow.com/questions/457050/how-to-display-text-in-system-tray-icon-with-win32-api
-  createSmallIcon: function(hWnd, text, color) {
+  createTextIcon: function(hWnd, text, color) {
+    log.debug("createTextIcon hWnd="+hWnd+" text="+text+" color="+color);
+
+    let blank = this.bitmaps.get('blank-icon');
+    let bitmap = new win32.BITMAP();
+    let err = gdi32.GetObjectW(blank, win32.BITMAP.size, bitmap.address()); // get bitmap info
+    let width = bitmap.bmWidth, height = bitmap.bmHeight;
+
     let hdc = user32.GetDC(hWnd); // get device context (DC) for hWnd
     let hdcMem = gdi32.CreateCompatibleDC(hdc); // creates a memory device context (DC) compatible with hdc (need a bitmap)
-    let hBitmap = this.bitmaps.get('blank-icon');
-    let hBitmapMask = gdi32.CreateCompatibleBitmap(hdc, 32, 32);
+    let hBitmap = user32.CopyImage(blank, user32.IMAGE_BITMAP, width, height, 0);
+    let hBitmapMask = gdi32.CreateCompatibleBitmap(hdc, width, height);
     user32.ReleaseDC(hWnd, hdc);
 
-    let hOldBitmap = ctypes.cast(gdi32.SelectObject(hdcMem, hBitmap), // replace bitmap in hdcMem by hBitmap
-                                 win32.HBITMAP);
+    let hBitmapOrig = gdi32.SelectObject(hdcMem, hBitmap);
     // gdi32.PatBlt(hdcMem, 0, 0, 16, 16, gdi32.BLACKNESS); // paint black rectangle
 
+// http://forums.codeguru.com/showthread.php?379565-Windows-SDK-GDI-How-do-I-choose-a-font-size-to-exactly-fit-a-string-in-a
+
     let nHeight = 32, fnWeight = gdi32.FW_BOLD;
     let hFont = gdi32.CreateFontW(nHeight, 0, 0, 0, fnWeight, 0, 0, 0,
       gdi32.ANSI_CHARSET, 0, 0, 0, gdi32.FF_SWISS, "Sans"); // get font
     hFont = ctypes.cast(gdi32.SelectObject(hdcMem, hFont), win32.HFONT); // replace font in bitmap by hFont
     gdi32.SetTextColor(hdcMem, win32.COLORREF(this.cssColorToCOLORREF(color)));
-    // gdi32.SetBkMode(hdcMem, gdi32.TRANSPARENT); // VERY IMPORTANT
+    gdi32.SetBkMode(hdcMem, gdi32.TRANSPARENT); // VERY IMPORTANT
     // gdi32.SetTextAlign(hdcMem, gdi32.GetTextAlign(hdcMem) & (~gdi32.TA_CENTER));
     // gdi32.SetTextAlign(hdcMem, gdi32.TA_CENTER);
     log.debug("   ___ALIGN=(winLastError="+ctypes.winLastError+") "+gdi32.GetTextAlign(hdcMem));
-    gdi32.TextOutW(hdcMem, 0, 0, text, text.length);
 
-    gdi32.SelectObject(hdcMem, hOldBitmap); // always replace new hBitmap with original one
+    let size = new gdi32.SIZE();
+    // GetTextExtentPoint32 is known as more reliable than DrawText(DT_CALCRECT)
+    gdi32.GetTextExtentPoint32W(hdcMem, text, text.length, size.address());
+    let nWidth = size.cx;
+    log.debug("   WIDTH="+nWidth);
+
+    // let rect = new win32.RECT();
+    // let height = user32.DrawTextW(hdcMem, text, text.length, rect.address(), user32.DT_SINGLELINE | user32.DT_CENTER | user32.DT_VCENTER | user32.DT_CALCRECT);
+    // log.debug("   HEIGHT="+height+", rect="+rect);
+
+    let nXStart = firetray.js.floatToInt((width - nWidth)/2),
+        nYStart = firetray.js.floatToInt((height - nHeight)/2);
+    gdi32.TextOutW(hdcMem, nXStart, nYStart, text, text.length); // ref point for alignment
+
+    gdi32.SelectObject(hdcMem, hBitmapOrig);
 
     let iconInfo = win32.ICONINFO();
     iconInfo.fIcon = true;
@@ -301,6 +319,7 @@ firetray.StatusIcon = {
     iconInfo.hbmColor = hBitmap;
 
     let hIcon = user32.CreateIconIndirect(iconInfo.address());
+    log.debug("   CreateIconIndirect hIcon="+hIcon+" lastError="+ctypes.winLastError);
 
     gdi32.DeleteObject(gdi32.SelectObject(hdcMem, hFont));
     gdi32.DeleteDC(hdcMem);
@@ -332,6 +351,12 @@ firetray.Handler.setIconTooltipDefault = function() {
 };
 
 firetray.Handler.setIconText = function(text, color) {
+  let hicon = firetray.StatusIcon.createTextIcon(
+    firetray.StatusIcon.hwndProxy, text, color);
+  log.debug("setIconText icon="+hicon);
+  if (hicon.isNull())
+    log.error("Could not create hicon");
+  firetray.StatusIcon.setImageFromIcon(hicon);
 };
 
 firetray.Handler.setIconVisibility = function(visible) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firetray.git



More information about the Pkg-mozext-commits mailing list