Merge branch 'native-handle'

This commit is contained in:
foudfou 2012-07-28 15:19:04 +02:00
commit 3c572aa5fc
11 changed files with 185 additions and 21 deletions

View File

@ -2,6 +2,7 @@ content firetray chrome/content/
skin firetray classic/1.0 chrome/skin/
locale firetray en-US chrome/locale/en-US/
resource firetray modules/
resource firetray modules/
overlay chrome://browser/content/browser.xul chrome://firetray/content/overlay.xul
overlay chrome://messenger/content/messenger.xul chrome://firetray/content/overlay.xul

43
src/lib/linux/Makefile Normal file
View File

@ -0,0 +1,43 @@
deps = gdk-2.0 gdk-pixbuf-2.0 atk
platform = $(shell uname -p)
CC = gcc
GCCVERSION = $(shell gcc -dumpversion | cut -f1 -d.)
CFLAGS += -O3 -fPIC -g -mtune=generic $(shell pkg-config --cflags $(deps))
LDFLAGS += -shared -rdynamic
#-Wl,--version-script -Wl,export-versionscript
#-Wl,-soname,libmystuff.so.1 -o libgnome.so.1.0.1
LIBS += $(shell pkg-config --libs $(deps))
libs = firetray_$(platform)-gcc$(GCCVERSION).so
all: $(libs)
@echo
@echo add this line to chrome.manifest:
@echo -e "resource\tfiretray-lib\t\t\tlib/linux/$(libs)"
@echo
@echo and use
@echo 'Cu.import("resource://firetray/ctypes/libfiretray.jsm");'
@echo 'libfiretray.init();'
@echo '//...'
@echo 'libfiretray.shutdown();'
@echo
$(libs): firetray.o
$(CC) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
strip: $(libs)
strip $<
clean:
rm -rf $(libs) *.o
cp:
cp $(libs) ../../lib/
install: clean all strip cp
.PHONY: all clean strip cp install

16
src/lib/linux/firetray.c Normal file
View File

@ -0,0 +1,16 @@
/* pkg-config --libs --cflags gtk+-2.0 */
#include <gtk/gtk.h>
#include "firetray.h"
int gdk_is_window(void* obj) {
return GDK_IS_WINDOW(obj) ? 1 : 0;
}
int gtk_is_window(void* obj) {
return GTK_IS_WINDOW(obj) ? 1 : 0;
}
int gtk_is_widget(void* obj) {
return GTK_IS_WIDGET(obj) ? 1 : 0;
}

3
src/lib/linux/firetray.h Normal file
View File

@ -0,0 +1,3 @@
extern int gdk_is_window(void* obj);
extern int gtk_is_window(void* obj);
extern int gtk_is_widget(void* obj);

View File

@ -8,8 +8,6 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
Cu.import("resource://firetray/ctypes/linux/gtk.jsm");
Cu.import("resource://firetray/commons.js");
Cu.import("resource://firetray/PrefListener.jsm");
Cu.import("resource://firetray/VersionChange.jsm");
@ -35,10 +33,6 @@ firetray.Handler = {
FILENAME_NEWMAIL: null,
initialized: false,
appId: (function(){return Services.appinfo.ID;})(),
appName: (function(){return Services.appinfo.name;})(),
runtimeABI: (function(){return Services.appinfo.XPCOMABI;})(),
runtimeOS: (function(){return Services.appinfo.OS;})(), // "WINNT", "Linux", "Darwin"
inMailApp: false,
inBrowserApp: false,
appStarted: false,
@ -46,6 +40,19 @@ firetray.Handler = {
windowsCount: 0,
visibleWindowsCount: 0,
appId: (function(){return Services.appinfo.ID;})(),
appName: (function(){return Services.appinfo.name;})(),
runtimeABI: (function(){return Services.appinfo.XPCOMABI;})(),
runtimeOS: (function(){return Services.appinfo.OS;})(), // "WINNT", "Linux", "Darwin"
addonRootDir: (function(){
let uri = Services.io.newURI(Components.stack.filename, null, null);
if (uri instanceof Ci.nsIFileURL) {
F.LOG("_directory="+uri.file.parent.parent.path);
return uri.file.parent.parent;
}
throw new Error("not resolved");
})(),
init: function() { // does creates icon
firetray.PrefListener.register(false);
@ -121,8 +128,7 @@ firetray.Handler = {
firetray.Messaging.shutdown();
firetray.StatusIcon.shutdown();
firetray.Window.shutdown();
firetray.Utils.tryCloseLibs([gobject, glib, gtk]);
// watchout order and sufficiency of lib closings (tryCloseLibs())
Services.obs.removeObserver(this, this.getAppStartupTopic(this.appId), false);
Services.obs.removeObserver(this, "xpcom-will-shutdown", false);

View File

@ -0,0 +1,60 @@
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
var EXPORTED_SYMBOLS = ["libfiretray"];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://firetray/logging.jsm");
const _path = (function(){
var uri = Services.io.newURI('resource://firetray-lib', null, null);
if (uri instanceof Ci.nsIFileURL)
return uri.file.path;
throw new Error("path not resolved");
})();
var libfiretray = {
_lib: null,
init: function() {
// If ctypes doesn't exist, try to get it
Cu.import("resource://gre/modules/ctypes.jsm");
// If we still don't have ctypes, this isn't going to work...
if (typeof(ctypes) == "undefined") {
throw ("Could not load JS-Ctypes");
}
try {
// Try to start up dependencies - if they fail, they'll throw
// exceptions. ex: GObjectLib.init();
this._lib = ctypes.open(_path);
if (!this._lib)
throw ("Could not load " + _path);
} catch (e) {
this.shutdown();
throw(e);
}
// Ok, we got everything - let's declare.
this._declare();
},
shutdown: function() {
// Close our connection to the library.
if (this._lib)
this._lib.close();
},
_declare: function() {
this.gdk_is_window = this._lib.declare("gdk_is_window", ctypes.default_abi, ctypes.int, ctypes.void_t.ptr);
this.gtk_is_window = this._lib.declare("gtk_is_window", ctypes.default_abi, ctypes.int, ctypes.void_t.ptr);
this.gtk_is_widget = this._lib.declare("gtk_is_widget", ctypes.default_abi, ctypes.int, ctypes.void_t.ptr);
}
};

View File

@ -288,6 +288,7 @@ function gdk_defines(lib) {
lib.lazy_bind("gdk_drawable_get_size", ctypes.void_t, this.GdkDrawable.ptr, gobject.gint.ptr, gobject.gint.ptr);
// lib.lazy_bind("gdk_window_get_geometry", ctypes.void_t, this.GdkWindow.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gint.ptr);
lib.lazy_bind("gdk_window_move_resize", ctypes.void_t, this.GdkWindow.ptr, gobject.gint, gobject.gint, gobject.gint, gobject.gint);
lib.lazy_bind("gdk_window_get_user_data", ctypes.void_t, this.GdkWindow.ptr, gobject.gpointer.ptr);
lib.lazy_bind("gdk_atom_intern", this.GdkAtom, gobject.gchar.ptr, gobject.gboolean);
lib.lazy_bind("gdk_property_change", ctypes.void_t, this.GdkWindow.ptr, this.GdkAtom, this.GdkAtom, gobject.gint, this.GdkPropMode, gobject.guchar.ptr, gobject.gint);

View File

@ -117,6 +117,7 @@ function gtk_defines(lib) {
lib.lazy_bind("gtk_widget_get_events", gobject.gint, this.GtkWidget.ptr);
lib.lazy_bind("gtk_widget_get_events", gobject.gint, this.GtkWidget.ptr);
lib.lazy_bind("gtk_widget_add_events", ctypes.void_t, this.GtkWidget.ptr, gobject.gint);
lib.lazy_bind("gtk_widget_get_toplevel", this.GtkWidget.ptr, this.GtkWidget.ptr);
lib.lazy_bind("gtk_window_get_type", gobject.GType);
lib.lazy_bind("gtk_window_get_position", ctypes.void_t, this.GtkWindow.ptr, gobject.gint.ptr, gobject.gint.ptr);
lib.lazy_bind("gtk_window_move", ctypes.void_t, this.GtkWindow.ptr, gobject.gint, gobject.gint);

View File

@ -69,7 +69,8 @@ firetray.StatusIcon = {
},
shutdown: function() {
firetray.Utils.tryCloseLibs([cairo, gobject, gdk, gtk, pango, pangocairo]);
firetray.PopupMenu.shutdown();
firetray.Utils.tryCloseLibs([cairo, gobject, gdk, gio, gtk, pango, pangocairo]);
this.initialized = false;
},

View File

@ -61,7 +61,7 @@ firetray.Window = {
},
shutdown: function() {
firetray.Utils.tryCloseLibs([gobject, gdk, gtk, libc, x11]);
firetray.Utils.tryCloseLibs([gobject, gdk, gtk, libc, x11, glib]);
this.initialized = false;
},
@ -73,7 +73,7 @@ firetray.Window = {
* @param window nsIDOMWindow from Services.wm
* @return a gtk.GtkWindow.ptr
*/
getGtkWindowHandle: function(window) {
getGtkWindowFromChromeWindow: function(window) {
let baseWindow = window
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
@ -97,9 +97,9 @@ firetray.Window = {
gobject.g_list_foreach(widgets, findGtkWindowByTitleCb, userData);
gobject.g_list_free(widgets);
if (userData.contents.outWindow.isNull()) {
if (userData.contents.outWindow.isNull())
throw new Error("Window not found!");
}
F.LOG("found window: "+userData.contents.outWindow);
} catch (x) {
F.ERROR(x);
@ -154,13 +154,44 @@ firetray.Window = {
return null;
},
/** consider using getXIDFromChromeWindow() if you only need the XID */
addrPointedByInHex: function(ptr) {
return "0x"+ctypes.cast(ptr, ctypes.uintptr_t.ptr).contents.toString(16);
},
getGdkWindowFromNativeHandle: function(nativeHandle) {
let gdkw = new gdk.GdkWindow.ptr(ctypes.UInt64(nativeHandle)); // a new pointer to the GdkWindow
F.LOG("gdkw="+gdkw+" *gdkw="+this.addrPointedByInHex(gdkw));
return gdkw;
},
getGtkWindowFromGdkWindow: function(gdkWin) {
let gptr = new gobject.gpointer;
gdk.gdk_window_get_user_data(gdkWin, gptr.address());
F.LOG("gptr="+gptr+" *gptr="+this.addrPointedByInHex(gptr));
let gtkw = ctypes.cast(gptr, gtk.GtkWindow.ptr);
let gtkw_voidp = ctypes.cast(gtkw, ctypes.void_t.ptr);
let gtkwid_top = gtk.gtk_widget_get_toplevel(ctypes.cast(gtkw, gtk.GtkWidget.ptr));
gtkw = ctypes.cast(gtkwid_top, gtk.GtkWindow.ptr);
F.LOG("gtkw="+gtkw+" *gtkw="+this.addrPointedByInHex(gtkw));
return gtkw;
},
/* consider using getXIDFromChromeWindow() if you only need the XID */
getWindowsFromChromeWindow: function(win) {
let gtkWin = firetray.Window.getGtkWindowHandle(win);
let gdkWin = firetray.Window.getGdkWindowFromGtkWindow(gtkWin);
let baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
let nativeHandle = baseWin.nativeHandle; // Moz' private pointer to the GdkWindow
F.LOG("nativeHandle="+nativeHandle);
let gtkWin, gdkWin;
if (nativeHandle) { // Gecko 17+
gdkWin = firetray.Window.getGdkWindowFromNativeHandle(nativeHandle);
gtkWin = firetray.Window.getGtkWindowFromGdkWindow(gdkWin);
} else {
gtkWin = firetray.Window.getGtkWindowFromChromeWindow(win);
gdkWin = firetray.Window.getGdkWindowFromGtkWindow(gtkWin);
}
let xid = firetray.Window.getXIDFromGdkWindow(gdkWin);
F.LOG("XID="+xid);
return [gtkWin, gdkWin, xid];
return [baseWin, gtkWin, gdkWin, xid];
},
getXIDFromChromeWindow: function(win) {
@ -446,7 +477,7 @@ firetray.Window = {
getWindowTitle: function(xid) {
let title = firetray.Handler.windows[xid].baseWin.title;
F.LOG("baseWin.title="+title);
F.LOG("|baseWin.title="+title+"|");
let tailIndex = title.indexOf(" - Mozilla "+firetray.Handler.appName);
if (tailIndex !== -1)
return title.substring(0, tailIndex);
@ -533,11 +564,11 @@ firetray.Handler.registerWindow = function(win) {
F.LOG("register window");
// register
let [gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
firetray.Window.checkSubscribedEventMasks(xid);
let [baseWin, gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
this.windows[xid] = {};
this.windows[xid].chromeWin = win;
this.windows[xid].baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
this.windows[xid].baseWin = baseWin;
firetray.Window.checkSubscribedEventMasks(xid);
try {
this.gtkWindows.insert(xid, gtkWin);
this.gdkWindows.insert(xid, gdkWin);

View File

@ -5,6 +5,7 @@
#include <X11/Xmd.h>
int main(int argc, char **argv) {
printf("sizeof(void*)=%d\n",sizeof(void*));
printf("sizeof(char)=%d\n",sizeof(char));
printf("sizeof(int)=%d\n",sizeof(int));
printf("sizeof(long)=%d\n",sizeof(long));