MozillaFirefox/x11-session.patch

237 lines
8.2 KiB
Diff

From: upstream
Subject: Support X11 session management
References:
https://bugzilla.novell.com/show_bug.cgi?id=227047
https://bugzilla.mozilla.org/show_bug.cgi?id=93789
diff --git a/toolkit/xre/Makefile.in b/toolkit/xre/Makefile.in
index e3dd8d9..4371882 100644
--- a/toolkit/xre/Makefile.in
+++ b/toolkit/xre/Makefile.in
@@ -137,21 +137,25 @@ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_
CPPSRCS += nsNativeAppSupportMac.cpp
else
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
CPPSRCS += nsNativeAppSupportOS2.cpp
else
ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
CPPSRCS += nsNativeAppSupportBeOS.cpp
else
+ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
+CPPSRCS += nsNativeAppSupportUnix.cpp
+else
CPPSRCS += nsNativeAppSupportDefault.cpp
endif
endif
endif
endif
+endif
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
CMSRCS = MacLaunchHelper.m
CPPSRCS += nsCommandLineServiceMac.cpp
LOCAL_INCLUDES += -I$(topsrcdir)/xpfe/bootstrap/appleevents
OS_CXXFLAGS += -fexceptions
SHARED_LIBRARY_LIBS += $(DEPTH)/xpfe/bootstrap/appleevents/$(LIB_PREFIX)appleevents_s.$(LIB_SUFFIX)
endif
diff --git a/toolkit/xre/nsNativeAppSupportUnix.cpp b/toolkit/xre/nsNativeAppSupportUnix.cpp
new file mode 100644
index 0000000..ad73f4c
--- /dev/null
+++ b/toolkit/xre/nsNativeAppSupportUnix.cpp
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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 Unix Native App Support.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Michael Wu <flamingice@sourmilk.net> (original author)
+ *
+ * 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 "nsNativeAppSupportBase.h"
+#include "nsCOMPtr.h"
+#include "nsXPCOM.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIObserverService.h"
+#include "nsIAppStartup.h"
+#include "nsServiceManagerUtils.h"
+#include "prlink.h"
+
+#include <glib.h>
+#include <glib-object.h>
+
+typedef struct _GnomeProgram GnomeProgram;
+typedef struct _GnomeModuleInfo GnomeModuleInfo;
+typedef struct _GnomeClient GnomeClient;
+
+typedef enum {
+ GNOME_SAVE_GLOBAL,
+ GNOME_SAVE_LOCAL,
+ GNOME_SAVE_BOTH
+} GnomeSaveStyle;
+
+typedef enum {
+ GNOME_INTERACT_NONE,
+ GNOME_INTERACT_ERRORS,
+ GNOME_INTERACT_ANY
+} GnomeInteractStyle;
+
+typedef enum {
+ GNOME_DIALOG_ERROR,
+ GNOME_DIALOG_NORMAL
+} GnomeDialogType;
+
+typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *,
+ const GnomeModuleInfo *, int,
+ char **, const char *, ...);
+typedef const GnomeModuleInfo * (*_libgnomeui_module_info_get_fn)();
+typedef GnomeClient * (*_gnome_master_client_fn)(void);
+typedef void (*GnomeInteractFunction)(GnomeClient *, gint, GnomeDialogType,
+ gpointer);
+typedef void (*_gnome_client_request_interaction_fn)(GnomeClient *,
+ GnomeDialogType,
+ GnomeInteractFunction,
+ gpointer);
+typedef void (*_gnome_interaction_key_return_fn)(gint, gboolean);
+
+static _gnome_client_request_interaction_fn gnome_client_request_interaction;
+static _gnome_interaction_key_return_fn gnome_interaction_key_return;
+
+void interact_cb(GnomeClient *client, gint key,
+ GnomeDialogType type, gpointer data)
+{
+ nsCOMPtr<nsIObserverService> obsServ =
+ do_GetService("@mozilla.org/observer-service;1");
+ nsCOMPtr<nsISupportsPRBool> cancelQuit =
+ do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
+
+ cancelQuit->SetData(PR_FALSE);
+
+ obsServ->NotifyObservers(cancelQuit, "quit-application-requested", nsnull);
+
+ PRBool abortQuit;
+ cancelQuit->GetData(&abortQuit);
+
+ gnome_interaction_key_return(key, abortQuit);
+}
+
+gboolean save_yourself_cb(GnomeClient *client, gint phase,
+ GnomeSaveStyle style, gboolean shutdown,
+ GnomeInteractStyle interact, gboolean fast,
+ gpointer user_data)
+{
+ if (interact == GNOME_INTERACT_ANY)
+ gnome_client_request_interaction(client, GNOME_DIALOG_NORMAL,
+ interact_cb, nsnull);
+ return TRUE;
+}
+
+void die_cb(GnomeClient *client, gpointer user_data)
+{
+ nsCOMPtr<nsIObserverService> obsServ =
+ do_GetService("@mozilla.org/observer-service;1");
+ nsCOMPtr<nsIAppStartup> appService =
+ do_GetService("@mozilla.org/toolkit/app-startup;1");
+
+ if (obsServ)
+ obsServ->NotifyObservers(nsnull, "quit-application-granted", nsnull);
+
+ if (appService)
+ appService->Quit(nsIAppStartup::eForceQuit);
+}
+
+class nsNativeAppSupportUnix : public nsNativeAppSupportBase
+{
+public:
+ NS_IMETHOD Start(PRBool* aRetVal);
+};
+
+NS_IMETHODIMP
+nsNativeAppSupportUnix::Start(PRBool *aRetVal)
+{
+ *aRetVal = PR_TRUE;
+
+ PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0");
+ if (!gnomeuiLib)
+ return NS_OK;
+
+ PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0");
+ if (!gnomeLib) {
+ PR_UnloadLibrary(gnomeuiLib);
+ return NS_OK;
+ }
+
+ _gnome_program_init_fn gnome_program_init =
+ (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init");
+ _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get");
+ if (!gnome_program_init || !libgnomeui_module_info_get) {
+ PR_UnloadLibrary(gnomeuiLib);
+ PR_UnloadLibrary(gnomeLib);
+ return NS_OK;
+ }
+
+ char *argv[2] = { "gecko", "--disable-crash-dialog" };
+ gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), 2, argv, NULL);
+
+ // Careful! These libraries cannot be unloaded after this point because
+ // gnome_program_init causes atexit handlers to be registered. Strange
+ // crashes will occur if these libraries are unloaded.
+
+ gnome_client_request_interaction = (_gnome_client_request_interaction_fn)
+ PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_request_interaction");
+ gnome_interaction_key_return = (_gnome_interaction_key_return_fn)
+ PR_FindFunctionSymbol(gnomeuiLib, "gnome_interaction_key_return");
+
+ _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn)
+ PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");
+
+ GnomeClient *client = gnome_master_client();
+ g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), NULL);
+ g_signal_connect(client, "die", G_CALLBACK(die_cb), NULL);
+
+ return NS_OK;
+}
+
+nsresult
+NS_CreateNativeAppSupport(nsINativeAppSupport **aResult)
+{
+ nsNativeAppSupportBase* native = new nsNativeAppSupportUnix();
+ if (!native)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *aResult = native;
+ NS_ADDREF(*aResult);
+
+ return NS_OK;
+}