[Pkg-mozext-commits] [firetray] 05/84: first step to porting to Windows

David Prévot taffit at moszumanska.debian.org
Sun Jul 20 01:42:41 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 bcb7764b8fe6864eaf6818a3a9135c47543498a0
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sat Nov 16 15:39:57 2013 +0100

    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 ?).
---
 src/install.rdf                          |   3 +-
 src/modules/FiretrayHandler.jsm          |   9 +-
 src/modules/ctypes/ctypes-utils.jsm      |  19 +-
 src/modules/ctypes/winnt/kernel32.jsm    |  36 ++++
 src/modules/ctypes/winnt/shell32.jsm     |  53 ++++++
 src/modules/ctypes/winnt/types.jsm       |  51 +++++
 src/modules/ctypes/winnt/user32.jsm      |  45 +++++
 src/modules/logging.jsm                  |  42 ++---
 src/modules/winnt/FiretrayStatusIcon.jsm |  68 +++++++
 src/modules/winnt/FiretrayWindow.jsm     | 310 +++++++++++++++++++++++++++++++
 testing/xtypes.c                         |   1 +
 11 files changed, 606 insertions(+), 31 deletions(-)

diff --git a/src/install.rdf b/src/install.rdf
index 0dd8901..f948aac 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -14,7 +14,8 @@
     <em:optionsURL>chrome://firetray/content/options.xul</em:optionsURL>
     <em:iconURL>chrome://firetray/skin/firetray48.png</em:iconURL>
     <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>
       <Description>
diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index eacbcc4..1b74574 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -69,8 +69,15 @@ firetray.Handler = {
       Cu.import("resource://firetray/linux/FiretrayWindow.jsm");
       log.debug('FiretrayWindow imported');
       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:
-      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;
     }
 
diff --git a/src/modules/ctypes/ctypes-utils.jsm b/src/modules/ctypes/ctypes-utils.jsm
index 3ddfa34..c6b951e 100644
--- a/src/modules/ctypes/ctypes-utils.jsm
+++ b/src/modules/ctypes/ctypes-utils.jsm
@@ -36,13 +36,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+var EXPORTED_SYMBOLS  = [ "ctypes_library", "is64bit" ];
+
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.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");
 
@@ -111,7 +116,10 @@ function ctypes_library(aName, aABIs, aDefines, aGlobal) {
 
     var library;
     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);
       try {
         library = ctypes.open(soname);
@@ -155,7 +163,12 @@ function ctypes_library(aName, aABIs, aDefines, aGlobal) {
         try {
           args = [];
           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)) {
             args.push(arg);
           }
diff --git a/src/modules/ctypes/winnt/kernel32.jsm b/src/modules/ctypes/winnt/kernel32.jsm
new file mode 100644
index 0000000..4495e19
--- /dev/null
+++ b/src/modules/ctypes/winnt/kernel32.jsm
@@ -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);
diff --git a/src/modules/ctypes/winnt/shell32.jsm b/src/modules/ctypes/winnt/shell32.jsm
new file mode 100644
index 0000000..a07f0a2
--- /dev/null
+++ b/src/modules/ctypes/winnt/shell32.jsm
@@ -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);
diff --git a/src/modules/ctypes/winnt/types.jsm b/src/modules/ctypes/winnt/types.jsm
new file mode 100644
index 0000000..8f89e2b
--- /dev/null
+++ b/src/modules/ctypes/winnt/types.jsm
@@ -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); }
+
+};
diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm
new file mode 100644
index 0000000..9d04b56
--- /dev/null
+++ b/src/modules/ctypes/winnt/user32.jsm
@@ -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);
diff --git a/src/modules/logging.jsm b/src/modules/logging.jsm
index 1b03300..0801c31 100644
--- a/src/modules/logging.jsm
+++ b/src/modules/logging.jsm
@@ -6,7 +6,9 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 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_RESET           = "\033[m";
@@ -77,25 +79,10 @@ firetray.Logging = {
   setupLogging: function(loggerName) {
 
     // lifted from log4moz.js
-    function SimpleFormatter(dateFormat) {
-      if (dateFormat)
-        this.dateFormat = dateFormat;
-    }
+    function SimpleFormatter() {}
     SimpleFormatter.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) {
         let messageString = "";
         if (message.hasOwnProperty("message"))
@@ -108,7 +95,9 @@ firetray.Logging = {
                       ([,mo] in Iterator(message.messageObjects))].join(" ");
 
         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 + " " +
           messageString + "\n";
 
@@ -119,10 +108,7 @@ firetray.Logging = {
       }
     };
 
-    function ColorTermFormatter(dateFormat) {
-      if (dateFormat)
-        this.dateFormat = dateFormat;
-    }
+    function ColorTermFormatter() {}
     ColorTermFormatter.prototype = {
       __proto__: SimpleFormatter.prototype,
 
@@ -141,15 +127,19 @@ firetray.Logging = {
     this._logger.level = Log4Moz.Level[FIRETRAY_LOG_LEVEL];
 
     // A console appender outputs to the JS Error Console
-    let dateFormat = "%T";
-    let simpleFormatter = new SimpleFormatter(dateFormat);
+    let simpleFormatter = new SimpleFormatter();
     let capp = new Log4Moz.ConsoleAppender(simpleFormatter);
     capp.level = Log4Moz.Level["Debug"];
     this._logger.addAppender(capp);
 
     // A dump appender outputs to standard out
-    let colorFormatter = new ColorTermFormatter(dateFormat);
-    let dapp = new Log4Moz.DumpAppender(colorFormatter);
+    let dumpFormatter;
+    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"];
     this._logger.addAppender(dapp);
   },
diff --git a/src/modules/winnt/FiretrayStatusIcon.jsm b/src/modules/winnt/FiretrayStatusIcon.jsm
new file mode 100644
index 0000000..f47fa58
--- /dev/null
+++ b/src/modules/winnt/FiretrayStatusIcon.jsm
@@ -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) {
+};
diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm
new file mode 100644
index 0000000..eb6b7fe
--- /dev/null
+++ b/src/modules/winnt/FiretrayWindow.jsm
@@ -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;
+};
diff --git a/testing/xtypes.c b/testing/xtypes.c
index 26e8841..307533a 100644
--- a/testing/xtypes.c
+++ b/testing/xtypes.c
@@ -7,6 +7,7 @@
 int main(int argc, char **argv) {
   printf("sizeof(void*)=%d\n",sizeof(void*));
   printf("sizeof(char)=%d\n",sizeof(char));
+  printf("sizeof(short)=%d\n",sizeof(short));
   printf("sizeof(int)=%d\n",sizeof(int));
   printf("sizeof(long)=%d\n",sizeof(long));
   printf("sizeof(unsigned_long)=%d\n",sizeof(unsigned long));

-- 
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