/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Christopher Blizzard * Ramiro Estrugo * Chris Lord * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "moz-headless.h" #include "moz-headless-private.h" #include "moz-headless-internal.h" #include "moz-headless-marshal.h" #include "moz-headless-cursors.h" #include "HeadlessPrivate.h" #include "HeadlessWindow.h" // so we can do our get_nsIWebBrowser later... #include "nsIWebBrowser.h" #include "nsIWebBrowserFind.h" #include "nsIWebBrowserFocus.h" #include "nsIWidget.h" #include "nsIContentViewer.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIDOMWindowInternal.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIIOService.h" #include "nsPIDOMWindow.h" #include "nsIWindowWatcher.h" #include "nsISHistoryInternal.h" #include "nsGUIEvent.h" #include "nsNetCID.h" #include "nsServiceManagerUtils.h" #include "moz-drawing-area.h" #define NEW_TOOLKIT_STRING(x) g_strdup(NS_ConvertUTF16toUTF8(x).get()) class nsIDirectoryServiceProvider; G_DEFINE_TYPE (MozHeadless, moz_headless, G_TYPE_OBJECT) #define HEADLESS_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), MOZ_TYPE_HEADLESS, MozHeadlessPrivate)) struct _MozHeadlessPrivate { HeadlessPrivate *priv; MozDrawingArea *area; MozDrawingArea *last_area; gboolean button_down; gboolean can_go_back; gboolean can_go_forward; guint chromeflags; }; guint moz_headless_signals[HEADLESS_LAST_SIGNAL] = { 0 }; enum { PROP_0, PROP_CHROMEFLAGS }; MozHeadlessSetCursorCallback moz_headless_change_cursor_callback = NULL; gpointer moz_headless_change_cursor_user_data = NULL; gchar *moz_headless_app_vendor = NULL; gchar *moz_headless_app_name = NULL; gchar *moz_headless_app_id = NULL; gchar *moz_headless_app_version = NULL; gchar *moz_headless_app_build_id = NULL; gchar *moz_headless_app_platform_version = NULL; gchar *moz_headless_app_platform_build_id = NULL; static void moz_headless_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { case PROP_CHROMEFLAGS : g_value_set_uint (value, MOZ_HEADLESS (object)->priv->chromeflags); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void moz_headless_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { case PROP_CHROMEFLAGS : MOZ_HEADLESS (object)->priv->chromeflags = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void moz_headless_dispose (GObject *object) { MozHeadless *headless = MOZ_HEADLESS (object); MozHeadlessPrivate *priv = headless->priv; if (priv->priv) { priv->priv->Destroy(); delete priv->priv; priv->priv = NULL; } if (priv->area) { g_object_unref (priv->area); priv->area = NULL; } G_OBJECT_CLASS (moz_headless_parent_class)->dispose (object); } static void moz_headless_finalize (GObject *object) { G_OBJECT_CLASS (moz_headless_parent_class)->finalize (object); } static void updated_cb (MozHeadless *self, MozDrawingAreaRect *rect) { g_signal_emit (self, moz_headless_signals[UPDATED], 0, rect->x, rect->y, rect->width, rect->height); } const MozHeadlessCursor * get_special_cursor (MozHeadlessCursorType cursor) { if (cursor < MOZ_HEADLESS_CURSOR_TYPE_N_SPECIAL) return &moz_headless_cursors[cursor]; else return NULL; } static void changed_cursor_cb (MozDrawingArea *area, GParamSpec *pspec, gpointer data) { MozHeadlessCursorType cursor_type; const MozHeadlessCursor *special; if (!moz_headless_change_cursor_callback) return; cursor_type = moz_drawing_area_get_cursor (area); special = get_special_cursor (cursor_type); moz_headless_change_cursor_callback (cursor_type, special, moz_headless_change_cursor_user_data); } #ifdef SUPPORT_IM static void im_reset_cb (MozDrawingArea *area, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[IM_RESET], 0); } static void im_enable_cb (MozDrawingArea *area, gboolean enabled, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[IM_ENABLE], 0, enabled); } static void im_focus_change_cb (MozDrawingArea *area, gboolean in, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[IM_FOCUS_CHANGE], 0, in); } static void im_set_cursor_cb (MozDrawingArea *area, gint x, gint y, gint width, gint height, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[IM_SET_CURSOR], 0, x, y, width, height); } #endif #ifdef MOZ_ENABLE_GTK2_PLUGINS static void plugin_added_cb (MozDrawingArea *area, guint plug_id, gint x, gint y, gint width, gint height, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[PLUGIN_ADDED], 0, plug_id, x, y, width, height); } static void plugin_updated_cb (MozDrawingArea *area, guint plug_id, gint x, gint y, gint width, gint height, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[PLUGIN_UPDATED], 0, plug_id, x, y, width, height); } static void plugin_visibility_cb (MozDrawingArea *area, guint plug_id, gboolean visible, MozHeadless *self) { g_signal_emit (self, moz_headless_signals[PLUGIN_VISIBILITY], 0, plug_id, visible); } #endif static void moz_headless_constructed (GObject *object) { MozHeadless *self = MOZ_HEADLESS (object); MozHeadlessPrivate *priv = self->priv; priv->area = moz_drawing_area_new (NULL, FALSE); g_signal_connect_swapped (priv->area, "updated", G_CALLBACK (updated_cb), self); moz_drawing_area_set_bounds (priv->area, 0, 0, 640, 480); g_signal_connect (priv->area, "notify::cursor", G_CALLBACK (changed_cursor_cb), self); #ifdef SUPPORT_IM g_signal_connect (priv->area, "ime-reset", G_CALLBACK (im_reset_cb), self); g_signal_connect (priv->area, "ime-enable", G_CALLBACK (im_enable_cb), self); g_signal_connect (priv->area, "ime-focus-change", G_CALLBACK (im_focus_change_cb), self); g_signal_connect (priv->area, "ime-set-cursor", G_CALLBACK (im_set_cursor_cb), self); #endif #ifdef MOZ_ENABLE_GTK2_PLUGINS g_signal_connect (priv->area, "plugin-added", G_CALLBACK (plugin_added_cb), self); g_signal_connect (priv->area, "plugin-updated", G_CALLBACK (plugin_updated_cb), self); g_signal_connect (priv->area, "plugin-visibility", G_CALLBACK (plugin_visibility_cb), self); #endif priv->last_area = priv->area; g_object_add_weak_pointer (G_OBJECT (priv->area), (gpointer *)&priv->last_area); priv->priv = new HeadlessPrivate (); nsresult rv = priv->priv->Init (self, priv->chromeflags); g_return_if_fail (NS_SUCCEEDED (rv)); if (priv->priv->mURI.Length()) priv->priv->LoadCurrentURI (); priv->priv->Show (); moz_drawing_area_set_visible (priv->area, TRUE); } static void moz_headless_class_init (MozHeadlessClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (MozHeadlessPrivate)); object_class->constructed = moz_headless_constructed; object_class->get_property = moz_headless_get_property; object_class->set_property = moz_headless_set_property; object_class->dispose = moz_headless_dispose; object_class->finalize = moz_headless_finalize; g_object_class_install_property (object_class, PROP_CHROMEFLAGS, g_param_spec_uint ("chromeflags", "Chrome flags", "The chrome flags " "for the page.", 0, G_MAXUINT, nsIWebBrowserChrome::CHROME_ALL, (GParamFlags)( G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB))); moz_headless_signals[LINK_MESSAGE] = g_signal_new("link_message", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, link_message), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[JS_STATUS] = g_signal_new("js_status", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, js_status), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[LOCATION] = g_signal_new("location", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, location), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[TITLE] = g_signal_new("title", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, title), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[PROGRESS] = g_signal_new("progress", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, progress), NULL, NULL, mozheadless_VOID__INT64_INT64, G_TYPE_NONE, 2, G_TYPE_INT64, G_TYPE_INT64); moz_headless_signals[PROGRESS_ALL] = g_signal_new("progress_all", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, progress_all), NULL, NULL, mozheadless_VOID__STRING_INT64_INT64, G_TYPE_NONE, 3, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_INT64, G_TYPE_INT64); moz_headless_signals[NET_STATE] = g_signal_new("net_state", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, net_state), NULL, NULL, mozheadless_VOID__INT_UINT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT); moz_headless_signals[NET_STATE_ALL] = g_signal_new("net_state_all", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, net_state_all), NULL, NULL, mozheadless_VOID__STRING_INT_UINT, G_TYPE_NONE, 3, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_INT, G_TYPE_UINT); moz_headless_signals[NET_START] = g_signal_new("net_start", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, net_start), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[NET_STOP] = g_signal_new("net_stop", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, net_stop), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[NEW_WINDOW] = g_signal_new("new_window", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, new_window), NULL, NULL, mozheadless_VOID__POINTER_UINT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); moz_headless_signals[VISIBILITY] = g_signal_new("visibility", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, visibility), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); moz_headless_signals[DESTROY_BROWSER] = g_signal_new("destroy_browser", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, destroy_brsr), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[OPEN_URI] = g_signal_new("open_uri", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, open_uri), NULL, NULL, mozheadless_BOOLEAN__STRING, G_TYPE_BOOLEAN, 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); moz_headless_signals[SIZE_TO] = g_signal_new("size_to", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, size_to), NULL, NULL, mozheadless_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); moz_headless_signals[DOM_KEY_DOWN] = g_signal_new("dom_key_down", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_key_down), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_KEY_PRESS] = g_signal_new("dom_key_press", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_key_press), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_KEY_UP] = g_signal_new("dom_key_up", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_key_up), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_MOUSE_DOWN] = g_signal_new("dom_mouse_down", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_mouse_down), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_MOUSE_UP] = g_signal_new("dom_mouse_up", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_mouse_up), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_MOUSE_CLICK] = g_signal_new("dom_mouse_click", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_mouse_click), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_MOUSE_DBL_CLICK] = g_signal_new("dom_mouse_dbl_click", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_mouse_dbl_click), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_MOUSE_OVER] = g_signal_new("dom_mouse_over", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_mouse_over), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_MOUSE_OUT] = g_signal_new("dom_mouse_out", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_mouse_out), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[SECURITY_CHANGE] = g_signal_new("security_change", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, security_change), NULL, NULL, mozheadless_VOID__STRING_UINT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); moz_headless_signals[STATUS_CHANGE] = g_signal_new("status_change", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, status_change), NULL, NULL, mozheadless_VOID__POINTER_INT_POINTER, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_POINTER); moz_headless_signals[DOM_ACTIVATE] = g_signal_new("dom_activate", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_activate), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_FOCUS_IN] = g_signal_new("dom_focus_in", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_focus_in), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[DOM_FOCUS_OUT] = g_signal_new("dom_focus_out", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, dom_focus_out), NULL, NULL, mozheadless_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); moz_headless_signals[UPDATED] = g_signal_new("updated", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, updated), NULL, NULL, mozheadless_VOID__INT_INT_INT_INT, G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); moz_headless_signals[ICON] = g_signal_new("icon", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessClass, icon), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[CAN_GO_BACK] = g_signal_new("can-go-back", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, can_go_back), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); moz_headless_signals[CAN_GO_FORWARD] = g_signal_new("can-go-forward", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, can_go_forward), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); moz_headless_signals[SHOW_TOOLTIP] = g_signal_new("show-tooltip", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, show_tooltip), NULL, NULL, mozheadless_VOID__STRING_INT_INT, G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); moz_headless_signals[HIDE_TOOLTIP] = g_signal_new("hide-tooltip", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, hide_tooltip), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[IM_RESET] = g_signal_new("im-reset", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, im_reset), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); moz_headless_signals[IM_ENABLE] = g_signal_new("im-enable", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, im_enable), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); moz_headless_signals[IM_FOCUS_CHANGE] = g_signal_new("im-focus-change", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, im_focus_change), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); moz_headless_signals[IM_SET_CURSOR] = g_signal_new("im-set-cursor", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, im_set_cursor), NULL, NULL, mozheadless_VOID__INT_INT_INT_INT, G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); moz_headless_signals[PLUGIN_ADDED] = g_signal_new("plugin-added", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, plugin_added), NULL, NULL, mozheadless_VOID__UINT_INT_INT_INT_INT, G_TYPE_NONE, 5, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); moz_headless_signals[PLUGIN_UPDATED] = g_signal_new("plugin-updated", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, plugin_updated), NULL, NULL, mozheadless_VOID__UINT_INT_INT_INT_INT, G_TYPE_NONE, 5, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); moz_headless_signals[PLUGIN_VISIBILITY] = g_signal_new("plugin-visibility", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, plugin_visibility), NULL, NULL, mozheadless_VOID__UINT_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_BOOLEAN); moz_headless_signals[CONTEXT_INFO] = g_signal_new("context-info", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(MozHeadlessClass, context_action), NULL, NULL, mozheadless_VOID__UINT_STRING_STRING_STRING_STRING, G_TYPE_NONE, 5, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); } static void moz_headless_init (MozHeadless *self) { MozHeadlessPrivate *priv = self->priv = HEADLESS_PRIVATE (self); priv->chromeflags = nsIWebBrowserChrome::CHROME_ALL; } MozHeadless* moz_headless_new (void) { return (MozHeadless *)g_object_new (MOZ_TYPE_HEADLESS, NULL); } MozHeadless* moz_headless_new_with_chrome (guint chromeflags) { return (MozHeadless *)g_object_new (MOZ_TYPE_HEADLESS, "chromeflags", chromeflags, NULL); } // Widget methods void moz_headless_push_startup(void) { HeadlessPrivate::PushStartup(); } void moz_headless_pop_startup(void) { HeadlessPrivate::PopStartup(); } void moz_headless_set_path(const char *aPath) { HeadlessPrivate::SetPath(aPath); } void moz_headless_set_comp_path(const char *aPath) { HeadlessPrivate::SetCompPath(aPath); } void moz_headless_add_comp_path(const char *aPath) { HeadlessPrivate::AddCompPath(aPath); } void moz_headless_add_chrome_path(const char *aPath) { HeadlessPrivate::AddChromePath(aPath); } void moz_headless_register_component(gpointer aComp) { HeadlessPrivate::RegisterAppComponent((const nsModuleComponentInfo *)aComp); } void moz_headless_set_profile_path(const char *aDir, const char *aName) { HeadlessPrivate::SetProfilePath(aDir, aName); } void moz_headless_set_directory_service_provider(nsIDirectoryServiceProvider *appFileLocProvider) { HeadlessPrivate::SetDirectoryServiceProvider(appFileLocProvider); } void moz_headless_set_directory (const gchar *key, const gchar *path) { HeadlessPrivate::SetDirectory (key, path); } void moz_headless_load_url(MozHeadless *headless, const char *url) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; headlessPrivate->SetURI(url); headlessPrivate->LoadCurrentURI(); } void moz_headless_stop_load (MozHeadless *headless) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; if (headlessPrivate->mNavigation) headlessPrivate->mNavigation->Stop(nsIWebNavigation::STOP_ALL); } gboolean moz_headless_can_go_back(MozHeadless *headless) { PRBool retval = PR_FALSE; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, FALSE); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), FALSE); headlessPrivate = headless->priv->priv; if (headlessPrivate->mNavigation) headlessPrivate->mNavigation->GetCanGoBack(&retval); return retval; } gboolean moz_headless_can_go_forward(MozHeadless *headless) { PRBool retval = PR_FALSE; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, FALSE); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), FALSE); headlessPrivate = headless->priv->priv; if (headlessPrivate->mNavigation) headlessPrivate->mNavigation->GetCanGoForward(&retval); return retval; } void moz_headless_go_back(MozHeadless *headless) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; if (headlessPrivate->mNavigation) headlessPrivate->mNavigation->GoBack(); } void moz_headless_go_forward(MozHeadless *headless) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; if (headlessPrivate->mNavigation) headlessPrivate->mNavigation->GoForward(); } void moz_headless_render_data(MozHeadless *headless, const char *data, guint32 len, const char *base_uri, const char *mime_type) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; headlessPrivate->OpenStream(base_uri, mime_type); headlessPrivate->AppendToStream((const PRUint8*)data, len); headlessPrivate->CloseStream(); } void moz_headless_open_stream(MozHeadless *headless, const char *base_uri, const char *mime_type) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; headlessPrivate->OpenStream(base_uri, mime_type); } void moz_headless_append_data(MozHeadless *headless, const char *data, guint32 len) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; headlessPrivate->AppendToStream((const PRUint8*)data, len); } void moz_headless_close_stream(MozHeadless *headless) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; headlessPrivate->CloseStream(); } char * moz_headless_get_link_message(MozHeadless *headless) { char *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (char *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (char *)NULL); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) retval = NEW_TOOLKIT_STRING(headlessPrivate->mWindow->mLinkMessage); return retval; } char * moz_headless_get_js_status(MozHeadless *headless) { char *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (char *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (char *)NULL); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) retval = NEW_TOOLKIT_STRING(headlessPrivate->mWindow->mJSStatus); return retval; } char * moz_headless_get_title(MozHeadless *headless) { char *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (char *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (char *)NULL); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) retval = NEW_TOOLKIT_STRING(headlessPrivate->mWindow->mTitle); return retval; } char * moz_headless_get_location(MozHeadless *headless) { char *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (char *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (char *)NULL); headlessPrivate = headless->priv->priv; if (!headlessPrivate->mURI.IsEmpty()) retval = g_strdup(headlessPrivate->mURI.get()); return retval; } char * moz_headless_get_icon(MozHeadless *headless) { char *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (char *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (char *)NULL); headlessPrivate = headless->priv->priv; if (!headlessPrivate->mIcon.IsEmpty()) retval = g_strdup(headlessPrivate->mIcon.get()); return retval; } void moz_headless_reload(MozHeadless *headless, gint32 flags) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; PRUint32 reloadFlags = 0; // map the external API to the internal web navigation API. switch (flags) { case MOZ_HEADLESS_FLAG_RELOADNORMAL: reloadFlags = 0; break; case MOZ_HEADLESS_FLAG_RELOADBYPASSCACHE: reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE; break; case MOZ_HEADLESS_FLAG_RELOADBYPASSPROXY: reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY; break; case MOZ_HEADLESS_FLAG_RELOADBYPASSPROXYANDCACHE: reloadFlags = (nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE); break; case MOZ_HEADLESS_FLAG_RELOADCHARSETCHANGE: reloadFlags = nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE; break; default: reloadFlags = 0; break; } headlessPrivate->Reload(reloadFlags); } void moz_headless_set_chrome_mask(MozHeadless *headless, guint32 flags) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; headlessPrivate->SetChromeMask(flags); } guint32 moz_headless_get_chrome_mask(MozHeadless *headless) { HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, 0); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), 0); headlessPrivate = headless->priv->priv; return headlessPrivate->mChromeMask; } void moz_headless_get_nsIWebBrowser (MozHeadless *headless, nsIWebBrowser **retval) { HeadlessPrivate *headlessPrivate; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) headlessPrivate->mWindow->GetWebBrowser(retval); } PRUnichar * moz_headless_get_title_unichar (MozHeadless *headless) { PRUnichar *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (PRUnichar *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (PRUnichar *)NULL); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) retval = ToNewUnicode(headlessPrivate->mWindow->mTitle); return retval; } PRUnichar * moz_headless_get_js_status_unichar (MozHeadless *headless) { PRUnichar *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (PRUnichar *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (PRUnichar *)NULL); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) retval = ToNewUnicode(headlessPrivate->mWindow->mJSStatus); return retval; } PRUnichar * moz_headless_get_link_message_unichar (MozHeadless *headless) { PRUnichar *retval = nsnull; HeadlessPrivate *headlessPrivate; g_return_val_if_fail(headless != NULL, (PRUnichar *)NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), (PRUnichar *)NULL); headlessPrivate = headless->priv->priv; if (headlessPrivate->mWindow) retval = ToNewUnicode(headlessPrivate->mWindow->mLinkMessage); return retval; } HeadlessPrivate * moz_headless_get_private (MozHeadless *headless) { g_return_val_if_fail (headless != NULL, NULL); g_return_val_if_fail (MOZ_IS_HEADLESS (headless), NULL); return headless->priv->priv; } void moz_headless_set_surface (MozHeadless *headless, gpointer target, gint width, gint height, gint stride) { g_return_if_fail (headless != NULL); g_return_if_fail (MOZ_IS_HEADLESS (headless)); moz_drawing_area_set_surface (headless->priv->area, target, width, height, stride); } void moz_headless_set_xsurface (MozHeadless *headless, gpointer xdisplay, gulong xdrawable, gpointer xvisual, gint width, gint height) { g_return_if_fail (headless != NULL); g_return_if_fail (MOZ_IS_HEADLESS (headless)); #ifdef MOZ_X11 moz_drawing_area_set_xsurface (headless->priv->area, (Display *)xdisplay, (Drawable)xdrawable, (Visual *)xvisual, width, height); #endif } void moz_headless_set_transparent (MozHeadless *headless, gboolean transparent) { g_return_if_fail (headless != NULL); g_return_if_fail (MOZ_IS_HEADLESS (headless)); moz_drawing_area_set_transparent (headless->priv->area, transparent); } MozDrawingArea * moz_headless_get_drawing_area (MozHeadless *headless) { g_return_val_if_fail (headless != NULL, NULL); g_return_val_if_fail (MOZ_IS_HEADLESS (headless), NULL); return headless->priv->area; } void moz_headless_set_size (MozHeadless *headless, gint width, gint height) { MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; priv->priv->Resize (width, height); moz_drawing_area_set_bounds (priv->area, 0, 0, width, height); } void moz_headless_get_size (MozHeadless *headless, gint *width, gint *height) { MozHeadlessPrivate *priv; PRInt32 awidth, aheight; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; priv->priv->mWindow-> GetDimensions (nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER, (PRInt32 *)nsnull, (PRInt32 *)nsnull, &awidth, &aheight); if (width) *width = awidth; if (height) *height = aheight; } void moz_headless_get_document_size (MozHeadless *headless, gint *width, gint *height) { MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; // get the web browser nsCOMPtr webBrowser; priv->priv->mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); // get the content DOM window for that web browser nsCOMPtr domWindow; webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); nsCOMPtr iDomWindow = do_QueryInterface (domWindow); if (!iDomWindow) { if (width) *width = 0; if (height) *height = 0; return; } if (width) { PRInt32 outer_width, scroll_x; iDomWindow->GetOuterWidth(&outer_width); iDomWindow->GetScrollMaxX(&scroll_x); *width = outer_width + scroll_x; } if (height) { PRInt32 outer_height, scroll_y; iDomWindow->GetOuterHeight(&outer_height); iDomWindow->GetScrollMaxY(&scroll_y); *height = outer_height + scroll_y; } } void moz_headless_freeze_updates (MozHeadless *headless, gboolean frozen) { MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; moz_drawing_area_freeze_updates (priv->area, frozen); } void moz_headless_invalidate (MozHeadless *headless, gint x, gint y, guint width, guint height, gboolean now) { MozHeadlessPrivate *priv; nsCOMPtr widget; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; priv->priv->mWindow->mBaseWindow->GetMainWidget(getter_AddRefs(widget)); widget->Invalidate (nsIntRect (x, y, width, height), now); } void moz_headless_purge_session_history (MozHeadless *headless) { nsresult rv; HeadlessPrivate *priv; nsCOMPtr widget; g_return_if_fail (MOZ_IS_HEADLESS (headless)); priv = headless->priv->priv; PRInt32 index, count; rv = priv->mSessionHistory->GetCount (&count); if (NS_FAILED (rv)) return; rv = priv->mSessionHistory->GetIndex (&index); if (NS_FAILED (rv)) return; // place the entry at current index at the end of the history list, // so it won't get removed if (index < count - 1) { nsCOMPtr internalSessionHistory = do_QueryInterface (priv->mSessionHistory, &rv); if (NS_FAILED (rv)) return; nsCOMPtr indexEntry; rv = priv->mSessionHistory-> GetEntryAtIndex (index, PR_FALSE, getter_AddRefs (indexEntry)); if (NS_FAILED (rv)) return; nsCOMPtr sessionEntry = do_QueryInterface (indexEntry, &rv); if (NS_FAILED (rv)) return; rv = internalSessionHistory->AddEntry (sessionEntry, PR_TRUE); if (NS_FAILED (rv)) return; rv = priv->mSessionHistory->GetCount (&count); if (NS_FAILED (rv)) return; } if (count > 1) { priv->mSessionHistory->PurgeHistory(count - 1); moz_headless_update_nav_history (headless); } } /* gboolean moz_headless_get_enabled (MozHeadless *headless) { PRBool enabled; MozHeadlessPrivate *priv; nsCOMPtr widget; g_return_val_if_fail(headless != NULL, FALSE); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), FALSE); priv = headless->priv; priv->priv->mWindow->mBaseWindow->GetMainWidget(getter_AddRefs(widget)); widget->IsEnabled (&enabled); return enabled ? TRUE : FALSE; } */ G_DEFINE_TYPE (MozHeadlessSingle, moz_headless_single, G_TYPE_OBJECT) #define HEADLESS_SINGLE_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), MOZ_TYPE_HEADLESS_SINGLE, \ MozHeadlessSinglePrivate)) // this is a placeholder for later in case we need to stash data at // a later data and maintain backwards compatibility. struct _MozHeadlessSinglePrivate { void *data; }; enum { NEW_WINDOW_ORPHAN, SINGLE_LAST_SIGNAL }; guint moz_headless_single_signals[SINGLE_LAST_SIGNAL] = { 0 }; static void moz_headless_single_class_init(MozHeadlessSingleClass *klass) { g_type_class_add_private (klass, sizeof (MozHeadlessSinglePrivate)); moz_headless_single_signals[NEW_WINDOW_ORPHAN] = g_signal_new("new_window_orphan", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(MozHeadlessSingleClass, new_window_orphan), NULL, NULL, mozheadless_VOID__POINTER_UINT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); } static void moz_headless_single_init(MozHeadlessSingle *single) { single->priv = HEADLESS_SINGLE_PRIVATE (single); } MozHeadlessSingle * moz_headless_single_new(void) { return (MozHeadlessSingle *)g_object_new(MOZ_TYPE_HEADLESS_SINGLE, NULL); } MozHeadlessSingle * moz_headless_single_get(void) { static MozHeadlessSingle *singleton_object = nsnull; if (!singleton_object) { singleton_object = moz_headless_single_new(); } return singleton_object; } // our callback from the window creator service void moz_headless_single_create_window (MozHeadless **aNewHeadless, guint aChromeFlags) { MozHeadlessSingle *single = moz_headless_single_get(); *aNewHeadless = nsnull; if (!single) return; g_signal_emit (G_OBJECT (single), moz_headless_single_signals[NEW_WINDOW_ORPHAN], 0, aNewHeadless, aChromeFlags); } void moz_headless_update_nav_history (MozHeadless *headless) { gboolean back, forward; MozHeadlessPrivate *priv = headless->priv; back = moz_headless_can_go_back (headless); forward = moz_headless_can_go_forward (headless); if (priv->can_go_back != back) { priv->can_go_back = back; g_signal_emit (headless, moz_headless_signals[CAN_GO_BACK], 0, back); } if (priv->can_go_forward != forward) { priv->can_go_forward = forward; g_signal_emit (headless, moz_headless_signals[CAN_GO_FORWARD], 0, forward); } } void moz_headless_motion (MozHeadless *headless, gint x, gint y, MozHeadlessModifier modifiers) { gint surface_x, surface_y; MozHeadlessPrivate *priv = headless->priv; if (priv->button_down) { if (!priv->last_area) return; moz_drawing_area_get_abs_bounds (priv->last_area, &surface_x, &surface_y, NULL, NULL); g_signal_emit_by_name (priv->last_area, "motion", x - surface_x, y - surface_y); } else { MozDrawingArea *child; child = moz_drawing_area_get_area_at_point (priv->area, &x, &y); g_signal_emit_by_name (child, "motion", x, y, modifiers); } } void moz_headless_focus (MozHeadless *headless, gboolean in) { MozHeadlessPrivate *priv = headless->priv; nsCOMPtr focus ( do_GetInterface (priv->priv->mWindow->mWebBrowser)); if (!focus) return; if (in) focus->Activate (); else focus->Deactivate (); } void moz_headless_button_press (MozHeadless *headless, gint x, gint y, gint button, gint click_count, MozHeadlessModifier modifiers) { MozHeadlessPrivate *priv = headless->priv; MozDrawingArea *child; priv->button_down = TRUE; child = moz_drawing_area_get_area_at_point (priv->area, &x, &y); if (priv->last_area != child) { if (priv->last_area) { g_object_remove_weak_pointer (G_OBJECT (priv->last_area), (gpointer *)&priv->last_area); } priv->last_area = child; g_object_add_weak_pointer (G_OBJECT (child), (gpointer *)&priv->last_area); } g_signal_emit_by_name (child, "button-press", x, y, button, click_count, modifiers); } void moz_headless_button_release (MozHeadless *headless, gint x, gint y, gint button, MozHeadlessModifier modifiers) { gint surface_x, surface_y; MozHeadlessPrivate *priv = headless->priv; priv->button_down = FALSE; if (!priv->last_area) return; moz_drawing_area_get_abs_bounds (priv->last_area, &surface_x, &surface_y, NULL, NULL); g_signal_emit_by_name (priv->last_area, "button-release", x - surface_x, y - surface_y, button, modifiers); } void moz_headless_key_press (MozHeadless *headless, MozHeadlessKey key, gunichar unicode_value, MozHeadlessModifier modifiers) { MozDrawingArea *area; MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; area = moz_drawing_area_get_focus (priv->area); if (area) g_signal_emit_by_name (area, "key-press", key, unicode_value, modifiers); } void moz_headless_key_release (MozHeadless *headless, MozHeadlessKey key, MozHeadlessModifier modifiers) { MozDrawingArea *area; MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; area = moz_drawing_area_get_focus (priv->area); if (area) g_signal_emit_by_name (priv->area, "key-release", key, modifiers); } void moz_headless_scroll (MozHeadless *headless, gint dx, gint dy) { MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; // get the web browser nsCOMPtr webBrowser; priv->priv->mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); // get the content DOM window for that web browser nsCOMPtr domWindow; webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); if (domWindow) domWindow->ScrollBy (dx, dy); } void moz_headless_set_scroll_pos (MozHeadless *headless, gint x, gint y) { MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; // get the web browser nsCOMPtr webBrowser; priv->priv->mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); // get the content DOM window for that web browser nsCOMPtr domWindow; webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); if (domWindow) domWindow->ScrollTo (x, y); } void moz_headless_find_set_string (MozHeadless *headless, const gchar *string) { g_return_if_fail (headless != NULL); g_return_if_fail (MOZ_IS_HEADLESS (headless)); MozHeadlessPrivate *priv = headless->priv; nsCOMPtr find(do_GetInterface(priv->priv->mWindow->mWebBrowser)); if (find) find->SetSearchString (NS_ConvertASCIItoUTF16(string).get()); } static gboolean moz_headless_find_dir (MozHeadless *headless, gboolean next) { g_return_val_if_fail (headless != NULL, FALSE); g_return_val_if_fail (MOZ_IS_HEADLESS (headless), FALSE); MozHeadlessPrivate *priv = headless->priv; nsCOMPtr find(do_GetInterface(priv->priv->mWindow->mWebBrowser)); if (find) { PRBool result; find->SetWrapFind (PR_TRUE); find->SetFindBackwards (!next); find->FindNext (&result); return result; } return FALSE; } gboolean moz_headless_find_next (MozHeadless *headless) { return moz_headless_find_dir (headless, TRUE); } gboolean moz_headless_find_prev (MozHeadless *headless) { return moz_headless_find_dir (headless, FALSE); } void moz_headless_get_scroll_pos (MozHeadless *headless, gint *x, gint *y) { PRInt32 scroll_x, scroll_y; MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; // get the web browser nsCOMPtr webBrowser; priv->priv->mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); // get the content DOM window for that web browser nsCOMPtr domWindow; webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); if (!domWindow) { if (x) *x = 0; if (y) *y = 0; return; } if (x) { domWindow->GetScrollX (&scroll_x); *x = scroll_x; } if (y) { domWindow->GetScrollY (&scroll_y); *y = scroll_y; } } gboolean moz_headless_request_close (MozHeadless *headless) { MozHeadlessPrivate *priv; g_return_val_if_fail(headless != NULL, FALSE); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), FALSE); priv = headless->priv; // Get the content viewer for the browser nsCOMPtr docShell (do_GetInterface (priv->priv->mWindow->mWebBrowser)); if (!docShell) return FALSE; // Get content viewer and request close nsCOMPtr cv; docShell->GetContentViewer (getter_AddRefs (cv)); if (cv) { nsresult rv = NS_OK; PRBool canClose = PR_FALSE; rv = cv->PermitUnload (PR_FALSE, &canClose); if (NS_SUCCEEDED (rv) && !canClose) return FALSE; rv = cv->RequestWindowClose (&canClose); if (NS_SUCCEEDED (rv) && !canClose) return FALSE; } return TRUE; } MozHeadless * moz_headless_get_from_dom_window (gpointer aNsIDOMWindow) { /* Copied from photon nsUnknownContentTypeHandler.cpp */ nsCOMPtr chrome; nsIDOMWindow *window = (nsIDOMWindow *)aNsIDOMWindow; MozHeadless *headless = NULL; if (!window) return NULL; nsCOMPtr watcher( do_GetService("@mozilla.org/embedcomp/window-watcher;1")); if (!watcher) return NULL; watcher->GetChromeForWindow(window, getter_AddRefs(chrome)); if (chrome) { nsCOMPtr site(do_QueryInterface(chrome)); if (site) site->GetSiteWindow(reinterpret_cast(&headless)); } return headless; } gpointer moz_headless_get_web_browser (MozHeadless *headless) { g_return_val_if_fail(headless != NULL, NULL); g_return_val_if_fail(MOZ_IS_HEADLESS(headless), NULL); MozHeadlessPrivate *priv = headless->priv; if (priv->priv->mWindow) return priv->priv->mWindow->mWebBrowser; else return NULL; } void moz_headless_set_change_cursor_callback (MozHeadlessSetCursorCallback callback, gpointer user_data) { moz_headless_change_cursor_callback = callback; moz_headless_change_cursor_user_data = user_data; } void moz_headless_set_app_vendor (const gchar *string) { g_free (moz_headless_app_vendor); moz_headless_app_vendor = g_strdup (string); } void moz_headless_set_app_name (const gchar *string) { g_free (moz_headless_app_name); moz_headless_app_name = g_strdup (string); } void moz_headless_set_app_id (const gchar *string) { g_free (moz_headless_app_id); moz_headless_app_id = g_strdup (string); } void moz_headless_set_app_version (const gchar *string) { g_free (moz_headless_app_version); moz_headless_app_version = g_strdup (string); } void moz_headless_set_app_build_id (const gchar *string) { g_free (moz_headless_app_build_id); moz_headless_app_build_id = g_strdup (string); } void moz_headless_set_app_platform_version (const gchar *string) { g_free (moz_headless_app_platform_version); moz_headless_app_platform_version = g_strdup (string); } void moz_headless_set_app_platform_build_id (const gchar *string) { g_free (moz_headless_app_platform_build_id); moz_headless_app_platform_build_id = g_strdup (string); } void moz_headless_im_commit(MozHeadless *headless, gchar* commit_str) { #ifdef SUPPORT_IM MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; if(priv->last_area) g_signal_emit_by_name(priv->last_area, "ime-commit", commit_str); #endif } void moz_headless_im_preedit_changed(MozHeadless *headless, gchar* preedit_str, gint cursor_pos) { #ifdef SUPPORT_IM MozHeadlessPrivate *priv; g_return_if_fail(headless != NULL); g_return_if_fail(MOZ_IS_HEADLESS(headless)); priv = headless->priv; if(priv->last_area) g_signal_emit_by_name(priv->last_area, "ime-preedit-changed", preedit_str, cursor_pos); #endif }