mirror of
https://github.com/moparisthebest/FireTray
synced 2024-11-11 03:25:07 -05: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:
parent
1c76f1c1f9
commit
bcb7764b8f
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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]);
|
||||||
|
// FIXME: ugly hack. We'll see when we need WinCbABI
|
||||||
|
if (this.ABI === 'dll') {
|
||||||
|
args.push(WinABI);
|
||||||
|
} else {
|
||||||
args.push(ctypes.default_abi);
|
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);
|
||||||
}
|
}
|
||||||
|
36
src/modules/ctypes/winnt/kernel32.jsm
Normal file
36
src/modules/ctypes/winnt/kernel32.jsm
Normal 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);
|
53
src/modules/ctypes/winnt/shell32.jsm
Normal file
53
src/modules/ctypes/winnt/shell32.jsm
Normal 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);
|
51
src/modules/ctypes/winnt/types.jsm
Normal file
51
src/modules/ctypes/winnt/types.jsm
Normal 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); }
|
||||||
|
|
||||||
|
};
|
45
src/modules/ctypes/winnt/user32.jsm
Normal file
45
src/modules/ctypes/winnt/user32.jsm
Normal 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);
|
@ -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);
|
||||||
},
|
},
|
||||||
|
68
src/modules/winnt/FiretrayStatusIcon.jsm
Normal file
68
src/modules/winnt/FiretrayStatusIcon.jsm
Normal 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) {
|
||||||
|
};
|
310
src/modules/winnt/FiretrayWindow.jsm
Normal file
310
src/modules/winnt/FiretrayWindow.jsm
Normal 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;
|
||||||
|
};
|
@ -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));
|
||||||
|
Loading…
Reference in New Issue
Block a user