[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