1
0
mirror of https://github.com/moparisthebest/FireTray synced 2024-08-13 15:53:47 -04:00

first step to porting to Windows

Does nothing particular, except get few informations from the registeredwindow.
ctypes-utils.jsm needs to be ironed out (ABI used for .so version and lib type
for .dll), and we'll probably have problems when declaring callbacks
(ctypes.stdcall_abi on 32bits ?).
This commit is contained in:
foudfou 2013-11-16 15:39:57 +01:00
parent 1c76f1c1f9
commit bcb7764b8f
11 changed files with 606 additions and 31 deletions

View File

@ -14,7 +14,8 @@
<em:optionsURL>chrome://firetray/content/options.xul</em:optionsURL> <em:optionsURL>chrome://firetray/content/options.xul</em:optionsURL>
<em:iconURL>chrome://firetray/skin/firetray48.png</em:iconURL> <em:iconURL>chrome://firetray/skin/firetray48.png</em:iconURL>
<em:icon64URL>chrome://firetray/skin/firetray64.png</em:icon64URL> <em:icon64URL>chrome://firetray/skin/firetray64.png</em:icon64URL>
<em:targetPlatform>Linux</em:targetPlatform> <!-- only Linux supported for now --> <em:targetPlatform>Linux</em:targetPlatform>
<em:targetPlatform>WINNT</em:targetPlatform>
<em:targetApplication> <em:targetApplication>
<Description> <Description>

View File

@ -69,8 +69,15 @@ firetray.Handler = {
Cu.import("resource://firetray/linux/FiretrayWindow.jsm"); Cu.import("resource://firetray/linux/FiretrayWindow.jsm");
log.debug('FiretrayWindow imported'); log.debug('FiretrayWindow imported');
break; break;
case "WINNT":
Cu.import("resource://firetray/winnt/FiretrayStatusIcon.jsm");
log.debug('FiretrayStatusIcon imported');
Cu.import("resource://firetray/winnt/FiretrayWindow.jsm");
log.debug('FiretrayWindow imported');
break;
default: default:
log.error("FIRETRAY: only Linux platform supported at this time. Firetray not loaded"); log.error("FIRETRAY: only Linux and WINNT platforms supported at this"
+ "time. Firetray not loaded");
return false; return false;
} }

View File

@ -36,13 +36,18 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
var EXPORTED_SYMBOLS = [ "ctypes_library", "is64bit" ];
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm"); Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://firetray/logging.jsm"); Cu.import("resource://firetray/logging.jsm");
var EXPORTED_SYMBOLS = [ "ctypes_library" ]; const is64bit = ctypes.size_t.size == 8; // firetray.Handler.runtimeABI.indexOf('_64') > -1;
const WinABI = is64bit ? ctypes.default_abi : ctypes.winapi_abi;
const WinCbABI = is64bit ? ctypes.default_abi : ctypes.stdcall_abi;
let log = firetray.Logging.getLogger("firetray.ctypes-utils"); let log = firetray.Logging.getLogger("firetray.ctypes-utils");
@ -111,7 +116,10 @@ function ctypes_library(aName, aABIs, aDefines, aGlobal) {
var library; var library;
for each (let abi in aABIs) { for each (let abi in aABIs) {
let soname = "lib" + aName + ".so." + abi.toString(); // FIXME: ABI is in fact SO_VER. Now we're mixing .so versions and the
// .dll extension :(
let soname = abi === 'dll' ? aName :
"lib" + aName + ".so." + abi.toString();
log.debug("Trying " + soname); log.debug("Trying " + soname);
try { try {
library = ctypes.open(soname); library = ctypes.open(soname);
@ -155,7 +163,12 @@ function ctypes_library(aName, aABIs, aDefines, aGlobal) {
try { try {
args = []; args = [];
args.push(arguments[0]); args.push(arguments[0]);
args.push(ctypes.default_abi); // FIXME: ugly hack. We'll see when we need WinCbABI
if (this.ABI === 'dll') {
args.push(WinABI);
} else {
args.push(ctypes.default_abi);
}
for each (let arg in Array.prototype.slice.call(arguments, 1)) { for each (let arg in Array.prototype.slice.call(arguments, 1)) {
args.push(arg); args.push(arg);
} }

View File

@ -0,0 +1,36 @@
var EXPORTED_SYMBOLS = [ "kernel32" ];
const KERNEL32_LIBNAME = "kernel32";
const KERNEL32_ABIS = [ "dll" ];
const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
Cu.import("resource://firetray/ctypes/winnt/types.jsm");
function kernel32_defines(lib) {
this.OSVERSIONINFOEXW = ctypes.StructType("OSVERSIONINFOEXW", [
{ "dwOSVersionInfoSize": win_t.DWORD },
{ "dwMajorVersion": win_t.DWORD },
{ "dwMinorVersion": win_t.DWORD },
{ "dwBuildNumber": win_t.DWORD },
{ "dwPlatformId": win_t.DWORD },
{ "szCSDVersion": ctypes.ArrayType(win_t.TCHAR, 128) },
{ "wServicePackMajor": win_t.WORD },
{ "wServicePackMinor": win_t.WORD },
{ "wSuiteMask": win_t.WORD },
{ "wProductType": win_t.BYTE },
{ "wReserved": win_t.BYTE }
]);
// lib.lazy_bind("GetLastError", win_t.DWORD); // use ctypes.winLastError instead
lib.lazy_bind("GetVersionExW", win_t.BOOL, this.OSVERSIONINFOEXW.ptr);
lib.lazy_bind("GetConsoleWindow", win_t.HWND);
lib.lazy_bind("GetConsoleTitleW", win_t.DWORD, win_t.LPTSTR, win_t.DWORD);
lib.lazy_bind("GetModuleHandleW", win_t.HMODULE, win_t.LPCTSTR);
}
new ctypes_library(KERNEL32_LIBNAME, KERNEL32_ABIS, kernel32_defines, this);

View File

@ -0,0 +1,53 @@
var EXPORTED_SYMBOLS = [ "shell32" ];
const SHELL32_LIBNAME = "shell32";
const SHELL32_ABIS = [ "dll" ];
const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
Cu.import("resource://firetray/ctypes/winnt/types.jsm");
function shell32_defines(lib) {
// notify icon message
this.NIM_ADD = 0x00000000;
this.NIM_MODIFY = 0x00000001;
this.NIM_DELETE = 0x00000002;
this.NIM_SETFOCUS = 0x00000003;
this.NIM_SETVERSION = 0x00000004;
// for NOTIFYICONDATAW.uFlags
this.NIF_MESSAGE = 0x00000001;
this.NIF_ICON = 0x00000002;
this.NIF_TIP = 0x00000004;
this.NIF_STATE = 0x00000008;
this.NIF_INFO = 0x00000010;
this.NIF_GUID = 0x00000020;
this.NIF_REALTIME = 0x00000040;
this.NIF_SHOWTIP = 0x00000080;
this.NOTIFYICONDATAW = ctypes.StructType("NOTIFYICONDATAW", [
{ "cbSize": win_t.DWORD },
{ "hWnd": win_t.HWND },
{ "uID": win_t.UINT },
{ "uFlags": win_t.UINT },
{ "uCallbackMessage": win_t.UINT },
{ "hIcon": win_t.HICON },
{ "szTip": ctypes.ArrayType(win_t.TCHAR, 64) }, // 128 on win2k+
{ "dwState": win_t.DWORD },
{ "dwStateMask": win_t.DWORD },
{ "szInfo": ctypes.ArrayType(win_t.TCHAR, 256) },
{ "uTimeoutOrVersion": win_t.UINT }, // union
{ "szInfoTitle[64]": win_t.TCHAR },
{ "dwInfoFlags": win_t.DWORD },
{ "guidItem": win_t.GUID },
{ "hBalloonIcon": win_t.HICON }
]);
lib.lazy_bind("Shell_NotifyIconW", win_t.BOOL, win_t.DWORD, this.NOTIFYICONDATAW.ptr);
}
new ctypes_library(SHELL32_LIBNAME, SHELL32_ABIS, shell32_defines, this);

View File

@ -0,0 +1,51 @@
var EXPORTED_SYMBOLS = [ "win_t" ];
const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
const UINT_PTR_T = is64bit ? ctypes.uint64_t : ctypes.unsigned_int;
const LONG_PTR_T = is64bit ? ctypes.int64_t : ctypes.long;
const ULONG_PTR_T = is64bit ? ctypes.uint64_t : ctypes.unsigned_long;
const HANDLE_T = ctypes.voidptr_t; // oder ctypes.intptr_t, ctypes.size_t,
var win_t = {
BOOL: ctypes.bool,
BYTE: ctypes.unsigned_char,
UINT: ctypes.unsigned_int,
WORD: ctypes.unsigned_short,
DWORD: ctypes.unsigned_long,
PVOID: ctypes.voidptr_t,
ULONG_PTR: ULONG_PTR_T,
SIZE_T: ULONG_PTR_T,
HWND: HANDLE_T,
HICON: HANDLE_T,
HINSTANCE: HANDLE_T,
HMODULE: HANDLE_T,
TCHAR: ctypes.jschar, // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t: jschar
LPSTR: ctypes.char.ptr,
LPCSTR: ctypes.char.ptr,
LPTSTR: ctypes.jschar.ptr, // UNICODE
LPCTSTR: ctypes.jschar.ptr,
LPCWSTR: ctypes.jschar.ptr,
LPWSTR: ctypes.jschar.ptr, // WCHAR
LRESULT: LONG_PTR_T,
WPARAM: UINT_PTR_T,
LPARAM: LONG_PTR_T,
GUID: ctypes.StructType("GUID", [
{ "Data1": ctypes.unsigned_long },
{ "Data2": ctypes.unsigned_short },
{ "Data3": ctypes.unsigned_short },
{ "Data4": ctypes.char.array(8) }
]),
/*
* #define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
* #define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
*/
MAKEINTRESOURCE: function(i) {return this.LPWSTR(i); }
};

View File

@ -0,0 +1,45 @@
var EXPORTED_SYMBOLS = [ "user32" ];
const USER32_LIBNAME = "user32";
const USER32_ABIS = [ "dll" ];
const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
Cu.import("resource://firetray/ctypes/winnt/types.jsm");
function user32_defines(lib) {
lib.lazy_bind("GetWindowTextW", ctypes.int, win_t.HWND, win_t.LPTSTR, ctypes.int);
lib.lazy_bind("FindWindowW", win_t.HWND, win_t.LPCTSTR, win_t.LPCTSTR);
lib.lazy_bind("SendMessageW", win_t.LRESULT, win_t.HWND, win_t.UINT, win_t.WPARAM, win_t.WPARAM);
this.WM_GETICON = 0x007F;
this.ICON_SMALL = 0;
this.ICON_BIG = 1;
this.ICON_SMALL2 = 2;
lib.lazy_bind("GetClassLongPtrW", win_t.ULONG_PTR, win_t.HWND, ctypes.int);
lib.lazy_bind("GetClassLongW", win_t.DWORD, win_t.HWND, ctypes.int); // 32-bits
this.GetClassLong = is64bit ? this.GetClassLongPtrW : this.GetClassLongW;
this.GCLP_HICONSM = -34;
lib.lazy_bind("LoadIconW", win_t.HICON, win_t.HINSTANCE, win_t.LPCTSTR); // superseeded by LoadImage
this.IDI_APPLICATION = 32512;
lib.lazy_bind("LoadImageW", win_t.HANDLE, win_t.HINSTANCE, win_t.LPCTSTR,
win_t.UINT, ctypes.int, ctypes.int, win_t.UINT);
this.LR_CREATEDIBSECTION = 0x00002000;
this.LR_DEFAULTCOLOR = 0x00000000;
this.LR_DEFAULTSIZE = 0x00000040;
this.LR_LOADFROMFILE = 0x00000010;
this.LR_LOADMAP3DCOLORS = 0x00001000;
this.LR_LOADTRANSPARENT = 0x00000020;
this.LR_MONOCHROME = 0x00000001;
this.LR_SHARED = 0x00008000;
this.LR_VGACOLOR = 0x00000080;
}
new ctypes_library(USER32_LIBNAME, USER32_ABIS, user32_defines, this);

View File

@ -6,7 +6,9 @@ const Cc = Components.classes;
const Ci = Components.interfaces; const Ci = Components.interfaces;
const Cu = Components.utils; const Cu = Components.utils;
const FIRETRAY_LOG_LEVEL = "Warn"; // "All" for debugging Cu.import("resource://gre/modules/Services.jsm");
const FIRETRAY_LOG_LEVEL = "All"; // "All" for debugging
const COLOR_NORMAL = ""; const COLOR_NORMAL = "";
const COLOR_RESET = "\033[m"; const COLOR_RESET = "\033[m";
@ -77,25 +79,10 @@ firetray.Logging = {
setupLogging: function(loggerName) { setupLogging: function(loggerName) {
// lifted from log4moz.js // lifted from log4moz.js
function SimpleFormatter(dateFormat) { function SimpleFormatter() {}
if (dateFormat)
this.dateFormat = dateFormat;
}
SimpleFormatter.prototype = { SimpleFormatter.prototype = {
__proto__: Log4Moz.Formatter.prototype, __proto__: Log4Moz.Formatter.prototype,
_dateFormat: null,
get dateFormat() {
if (!this._dateFormat)
this._dateFormat = "%Y-%m-%d %H:%M:%S";
return this._dateFormat;
},
set dateFormat(format) {
this._dateFormat = format;
},
format: function(message) { format: function(message) {
let messageString = ""; let messageString = "";
if (message.hasOwnProperty("message")) if (message.hasOwnProperty("message"))
@ -108,7 +95,9 @@ firetray.Logging = {
([,mo] in Iterator(message.messageObjects))].join(" "); ([,mo] in Iterator(message.messageObjects))].join(" ");
let date = new Date(message.time); let date = new Date(message.time);
let stringLog = date.toLocaleFormat(this.dateFormat) + " " + let dateStr = date.getHours() + ":" + date.getMinutes() + ":" +
date.getSeconds() + "." + date.getMilliseconds();
let stringLog = dateStr + " " +
message.levelDesc + " " + message.loggerName + " " + message.levelDesc + " " + message.loggerName + " " +
messageString + "\n"; messageString + "\n";
@ -119,10 +108,7 @@ firetray.Logging = {
} }
}; };
function ColorTermFormatter(dateFormat) { function ColorTermFormatter() {}
if (dateFormat)
this.dateFormat = dateFormat;
}
ColorTermFormatter.prototype = { ColorTermFormatter.prototype = {
__proto__: SimpleFormatter.prototype, __proto__: SimpleFormatter.prototype,
@ -141,15 +127,19 @@ firetray.Logging = {
this._logger.level = Log4Moz.Level[FIRETRAY_LOG_LEVEL]; this._logger.level = Log4Moz.Level[FIRETRAY_LOG_LEVEL];
// A console appender outputs to the JS Error Console // A console appender outputs to the JS Error Console
let dateFormat = "%T"; let simpleFormatter = new SimpleFormatter();
let simpleFormatter = new SimpleFormatter(dateFormat);
let capp = new Log4Moz.ConsoleAppender(simpleFormatter); let capp = new Log4Moz.ConsoleAppender(simpleFormatter);
capp.level = Log4Moz.Level["Debug"]; capp.level = Log4Moz.Level["Debug"];
this._logger.addAppender(capp); this._logger.addAppender(capp);
// A dump appender outputs to standard out // A dump appender outputs to standard out
let colorFormatter = new ColorTermFormatter(dateFormat); let dumpFormatter;
let dapp = new Log4Moz.DumpAppender(colorFormatter); if (Services.appinfo.OS.match(/(^Linux|^Darwin|BSD$)/)) {
dumpFormatter = new ColorTermFormatter();
} else {
dumpFormatter = new SimpleFormatter();
}
let dapp = new Log4Moz.DumpAppender(dumpFormatter);
dapp.level = Log4Moz.Level["Debug"]; dapp.level = Log4Moz.Level["Debug"];
this._logger.addAppender(dapp); this._logger.addAppender(dapp);
}, },

View File

@ -0,0 +1,68 @@
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
var EXPORTED_SYMBOLS = [ "firetray" ];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
// Cu.import("resource://firetray/ctypes/linux/pangocairo.jsm");
Cu.import("resource://firetray/commons.js");
// firetray.Handler.subscribeLibsForClosing([pangocairo]);
let log = firetray.Logging.getLogger("firetray.StatusIcon");
if ("undefined" == typeof(firetray.Handler))
log.error("This module MUST be imported from/after FiretrayHandler !");
firetray.StatusIcon = {
initialized: false,
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
trayIcon: null,
themedIconApp: null,
themedIconNewMail: null,
prefAppIconNames: null,
prefNewMailIconNames: null,
defaultAppIconName: null,
defaultNewMailIconName: null,
init: function() {
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
"chrome://firetray/skin/blank-icon.png");
log.warn("YEAH! From Windobe!");
this.initialized = true;
return true;
},
shutdown: function() {
log.debug("Disabling StatusIcon");
this.initialized = false;
},
}; // firetray.StatusIcon
firetray.Handler.setIconImageDefault = function() {
log.debug("setIconImageDefault");
};
firetray.Handler.setIconImageNewMail = function() {
};
// firetray.Handler.setIconImageFromFile = firetray.StatusIcon.setIconImageFromFile;
firetray.Handler.setIconTooltip = function(toolTipStr) {
};
firetray.Handler.setIconTooltipDefault = function() {
};
firetray.Handler.setIconText = function(text, color) { // FIXME: function too long
};
firetray.Handler.setIconVisibility = function(visible) {
};

View File

@ -0,0 +1,310 @@
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* GdkWindow and GtkWindow are totally different things. A GtkWindow is a
"standalone" window. A GdkWindow is just a region on the screen that can
capture events and has certain attributes (such as a cursor, and a coordinate
system). Basically a GdkWindow is an X window, in the Xlib sense, and
GtkWindow is a widget used for a particular UI effect.
(http://mail.gnome.org/archives/gtk-app-devel-list/1999-January/msg00138.html) */
var EXPORTED_SYMBOLS = [ "firetray" ];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/ctypesMap.jsm");
Cu.import("resource://firetray/ctypes/winnt/types.jsm");
Cu.import("resource://firetray/ctypes/winnt/kernel32.jsm");
Cu.import("resource://firetray/ctypes/winnt/shell32.jsm");
Cu.import("resource://firetray/ctypes/winnt/user32.jsm");
Cu.import("resource://firetray/commons.js");
firetray.Handler.subscribeLibsForClosing([kernel32, shell32, user32]);
let log = firetray.Logging.getLogger("firetray.Window");
if ("undefined" == typeof(firetray.Handler))
log.error("This module MUST be imported from/after FiretrayHandler !");
const Services2 = {};
XPCOMUtils.defineLazyServiceGetter(
Services2,
"uuid",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator"
);
const FIRETRAY_XWINDOW_HIDDEN = 1 << 0; // when minimized also
const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
// // NOTE: storing ctypes pointers into a JS object doesn't work: pointers are
// // "evolving" after a while (maybe due to back and forth conversion). So we
// // need to store them into a real ctypes array !
// firetray.Handler.gtkWindows = new ctypesMap(gtk.GtkWindow.ptr),
firetray.Window = {
signals: {'focus-in': {callback: {}, handler: {}}},
init: function() {
this.initialized = true;
},
shutdown: function() {
this.initialized = false;
},
show: function(xid) {
log.debug("show xid="+xid);
},
hide: function(xid) {
log.debug("hide");
},
startupHide: function(xid) {
log.debug('startupHide: '+xid);
},
setVisibility: function(xid, visibility) {
},
}; // firetray.Window
///////////////////////// firetray.Handler overriding /////////////////////////
/** debug facility */
firetray.Handler.dumpWindows = function() {
log.debug(firetray.Handler.windowsCount);
for (let winId in firetray.Handler.windows) log.info(winId+"="+firetray.Handler.gtkWindows.get(winId));
};
firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
firetray.Handler.registerWindow = function(win) {
log.debug("register window");
// TESTING
let baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
let nativeHandle = baseWin.nativeHandle; // Moz' private pointer to the GdkWindow
log.info("nativeHandle="+nativeHandle);
log.info("size="+ctypes.size_t.size);
log.info("psize="+ctypes.voidptr_t.size);
log.info("osvi size="+kernel32.OSVERSIONINFOEXW.size);
let osvi = new kernel32.OSVERSIONINFOEXW();
osvi.dwOSVersionInfoSize = kernel32.OSVERSIONINFOEXW.size;
if (kernel32.GetVersionExW(osvi.address())) {
log.debug("osvi.dwMajorVersion="+osvi.dwMajorVersion);
log.debug("osvi.dwMinorVersion="+osvi.dwMinorVersion);
}
/*
* Windows 8 6.2
* Windows 7 6.1
* Windows Vista 6.0
* Windows XP 5.1
*/
let version = osvi.dwMajorVersion*10 + osvi.dwMinorVersion; // if (version >= 51)
let nid = new shell32.NOTIFYICONDATAW();
nid.cbSize = shell32.NOTIFYICONDATAW.size;
let hwnd = user32.FindWindowW("MozillaWindowClass", win.document.title);
log.debug("hwnd FindWindow="+hwnd);
/*
let hwnd = new ctypes.voidptr_t(ctypes.UInt64(nativeHandle));
log.debug("hwnd nativeHandle="+hwnd);
*/
const BUF_SIZE = 255;
let buffer_t = ctypes.jschar.array(BUF_SIZE); // LPTSTR
let title = new buffer_t();
let len = user32.GetWindowTextW(hwnd, title, BUF_SIZE);
log.error("errno="+ctypes.errno+" winLastError="+ctypes.winLastError);
if (len) {
log.info("title="+title.readString());
}
/*
let consoleWin = kernel32.GetConsoleWindow();
log.error("errno="+ctypes.errno+" winLastError="+ctypes.winLastError);
log.info("consoleWin="+consoleWin);
len = user32.GetWindowTextW(consoleWin, title, 127);
log.error("errno="+ctypes.errno+" winLastError="+ctypes.winLastError);
log.debug("len="+len);
log.info("title="+title.readString());
len = kernel32.GetConsoleTitleW(title, win_t.DWORD(127));
log.error("errno="+ctypes.errno+" winLastError="+ctypes.winLastError);
log.debug("len="+len);
log.debug("len type="+typeof(len)); // "object" ???
if (len) {
log.info("consoleTitle="+title.readString());
}
*/
let result = user32.SendMessageW(hwnd, user32.WM_GETICON, user32.ICON_SMALL, 0);
// result is a ctypes.Int64. So we need to create a CData from it before
// casting it.
let icon = ctypes.cast(win_t.LRESULT(result), win_t.HICON);
let NULL = win_t.HICON(null);
log.debug("SendMessageW winLastError="+ctypes.winLastError);
if (firetray.js.strEquals(icon, NULL)) { // OS default icon
result = user32.GetClassLong(hwnd, user32.GCLP_HICONSM);
icon = ctypes.cast(win_t.ULONG_PTR(result), win_t.HICON);
log.debug("GetClassLong winLastError="+ctypes.winLastError);
}
if (firetray.js.strEquals(icon, NULL)) { // from the first resource -> ERROR_RESOURCE_TYPE_NOT_FOUND(1813)
icon = user32.LoadIconW(kernel32.GetModuleHandleW(null),
win_t.MAKEINTRESOURCE(0));
log.debug("LoadIconW module winLastError="+ctypes.winLastError);
}
if (firetray.js.strEquals(icon, NULL)) { // OS default icon
icon = user32.LoadIconW(null, win_t.MAKEINTRESOURCE(user32.IDI_APPLICATION));
log.debug("LoadIconW default winLastError="+ctypes.winLastError);
}
log.debug("icon="+icon);
// BOOL mintrayr_CreateIcon(void *handle, mouseevent_callback_t callback)
// {
// HWND hwnd = (HWND)handle;
// if (!hwnd) {
// return FALSE;
// }
// SetupWnd(hwnd);
// NOTIFYICONDATAW *iconData = new(std::nothrow) NOTIFYICONDATAW;
// if (!iconData) {
// return FALSE;
// }
// // Init the icon data according to MSDN
// iconData->cbSize = sizeof(NOTIFYICONDATAW);
// // Copy the title
// if (GetWindowText(hwnd, iconData->szTip, 127)) {
// iconData->szTip[127] = '\0'; // Better be safe than sorry :p
// }
// else{
// iconData->szTip[0] = '\0';
// }
// // Get the window icon
// HICON icon = reinterpret_cast<HICON>(::SendMessageW(hwnd, WM_GETICON, ICON_SMALL, 0));
// if (icon == 0) {
// // Alternative method. Get from the window class
// icon = reinterpret_cast<HICON>(::GetClassLongPtrW(hwnd, GCLP_HICONSM));
// }
// // Alternative method: get the first icon from the main module (executable image of the process)
// if (icon == 0) {
// icon = ::LoadIcon(GetModuleHandleW(0), MAKEINTRESOURCE(0));
// }
// // Alternative method. Use OS default icon
// if (icon == 0) {
// icon = ::LoadIcon(0, IDI_APPLICATION);
// }
// iconData->hIcon = icon;
// // Set the rest of the members
// iconData->hWnd = hwnd;
// iconData->uCallbackMessage = WM_TRAYMESSAGE;
// iconData->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
// iconData->uVersion = 5;
// // Install the icon
// ::Shell_NotifyIconW(NIM_ADD, iconData);
// ::Shell_NotifyIconW(NIM_SETVERSION, iconData);
// SetupWnd(hwnd);
// ::SetPropW(hwnd, kIconData, reinterpret_cast<HANDLE>(iconData));
// ::SetPropW(hwnd, kIconMouseEventProc, reinterpret_cast<HANDLE>(callback));
// ::SetPropW(hwnd, kIcon, reinterpret_cast<HANDLE>(0x1));
return;
// register
let [whndbaseWin, gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
this.windows[xid] = {};
this.windows[xid].chromeWin = win;
this.windows[xid].baseWin = baseWin;
firetray.Window.checkSubscribedEventMasks(xid);
try {
this.gtkWindows.insert(xid, gtkWin);
this.gdkWindows.insert(xid, gdkWin);
firetray.PopupMenu.addWindowItem(xid);
} catch (x) {
if (x.name === "RangeError") // instanceof not working :-(
win.alert(x+"\n\nYou seem to have more than "+FIRETRAY_WINDOW_COUNT_MAX
+" windows open. This breaks FireTray and most probably "
+firetray.Handler.appName+".");
}
this.windowsCount += 1;
// NOTE: no need to check for window state to set visibility because all
// windows *are* shown at startup
firetray.Window.updateVisibility(xid, true);
log.debug("window "+xid+" registered");
// NOTE: shouldn't be necessary to gtk_widget_add_events(gtkWin, gdk.GDK_ALL_EVENTS_MASK);
try {
// NOTE: we could try to catch the "delete-event" here and block
// delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
// provided 'close' JS event
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
if (!firetray.Handler.appStarted) {
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter);
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null);
}
firetray.Window.attachOnFocusInCallback(xid);
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) {
firetray.Chat.attachSelectListeners(win);
}
} catch (x) {
firetray.Window.unregisterWindowByXID(xid);
log.error(x);
return null;
}
log.debug("AFTER"); firetray.Handler.dumpWindows();
return xid;
};
firetray.Handler.unregisterWindow = function(win) {
log.debug("unregister window");
let xid = firetray.Window.getXIDFromChromeWindow(win);
return firetray.Window.unregisterWindowByXID(xid);
};
firetray.Handler.showWindow = firetray.Window.show;
firetray.Handler.hideWindow = firetray.Window.hide;
firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
log.debug("showHideAllWindows: "+userData);
// NOTE: showHideAllWindows being a callback, we need to use
// 'firetray.Handler' explicitely instead of 'this'
log.debug("visibleWindowsCount="+firetray.Handler.visibleWindowsCount);
log.debug("windowsCount="+firetray.Handler.windowsCount);
let visibilityRate = firetray.Handler.visibleWindowsCount/firetray.Handler.windowsCount;
log.debug("visibilityRate="+visibilityRate);
if ((0.5 < visibilityRate) && (visibilityRate < 1)
|| visibilityRate === 0) { // TODO: should be configurable
firetray.Handler.showAllWindows();
} else {
firetray.Handler.hideAllWindows();
}
let stopPropagation = true;
return stopPropagation;
};

View File

@ -7,6 +7,7 @@
int main(int argc, char **argv) { int main(int argc, char **argv) {
printf("sizeof(void*)=%d\n",sizeof(void*)); printf("sizeof(void*)=%d\n",sizeof(void*));
printf("sizeof(char)=%d\n",sizeof(char)); printf("sizeof(char)=%d\n",sizeof(char));
printf("sizeof(short)=%d\n",sizeof(short));
printf("sizeof(int)=%d\n",sizeof(int)); printf("sizeof(int)=%d\n",sizeof(int));
printf("sizeof(long)=%d\n",sizeof(long)); printf("sizeof(long)=%d\n",sizeof(long));
printf("sizeof(unsigned_long)=%d\n",sizeof(unsigned long)); printf("sizeof(unsigned_long)=%d\n",sizeof(unsigned long));