--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TODO/mozilla-kde.patch Sun Nov 29 14:10:26 2009 +0100
@@ -0,0 +1,1787 @@
+--- mozilla/chrome/src/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/chrome/src/Makefile.in 2009-09-14 10:04:14.000000000 +0200
+@@ -86,6 +86,7 @@ EXTRA_DSO_LDOPTS = \
+
+ ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
+ EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+ endif
+
+ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
+--- mozilla/chrome/src/nsChromeRegistry.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/chrome/src/nsChromeRegistry.cpp 2009-09-14 10:04:14.000000000 +0200
+@@ -114,6 +114,7 @@
+ #include "nsIXULAppInfo.h"
+ #include "nsIXULRuntime.h"
+ #include "nsPresShellIterator.h"
++#include "nsKDEUtils.h"
+
+ #ifdef MOZ_XUL
+ // keep all the RDF stuff together, in case we can remove it in the far future
+@@ -2208,6 +2209,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
+ NS_NAMED_LITERAL_STRING(kOs, "os");
+ NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
++ NS_NAMED_LITERAL_STRING(kDesktop, "desktop");
+
+ nsCOMPtr<nsIIOService> io (do_GetIOService());
+ if (!io) return NS_ERROR_FAILURE;
+@@ -2251,6 +2253,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ nsAutoString osVersion;
++ nsAutoString desktop;
+ #if defined(XP_WIN)
+ OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
+ if (GetVersionEx(&info)) {
+@@ -2258,6 +2261,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ info.dwMajorVersion,
+ info.dwMinorVersion);
+ }
++ desktop = NS_LITERAL_STRING("win");
+ #elif defined(XP_MACOSX)
+ long majorVersion, minorVersion;
+ if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
+@@ -2266,10 +2270,12 @@ nsChromeRegistry::ProcessManifestBuffer(
+ majorVersion,
+ minorVersion);
+ }
++ desktop = NS_LITERAL_STRING("macosx");
+ #elif defined(MOZ_WIDGET_GTK2)
+ nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+ gtk_major_version,
+ gtk_minor_version);
++ desktop = nsKDEUtils::kdeSession() ? NS_LITERAL_STRING("kde") : NS_LITERAL_STRING("gnome"); // TODO others?
+ #endif
+
+ char *token;
+@@ -2313,6 +2319,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOsVersion = eUnspecified;
+ TriState stOs = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2326,6 +2333,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ CheckFlag(kContentAccessible, wtoken, contentAccessible) ||
+ CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2337,7 +2345,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsCOMPtr<nsIURI> resolved;
+@@ -2398,6 +2406,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOs = eUnspecified;
+ TriState stOsVersion = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2408,6 +2417,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2419,7 +2429,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsCOMPtr<nsIURI> resolved;
+@@ -2460,6 +2470,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOs = eUnspecified;
+ TriState stOsVersion = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2470,6 +2481,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2481,7 +2493,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsCOMPtr<nsIURI> resolved;
+@@ -2524,6 +2536,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOs = eUnspecified;
+ TriState stOsVersion = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2534,6 +2547,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2545,7 +2559,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsCOMPtr<nsIURI> baseuri, overlayuri;
+@@ -2580,6 +2594,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOs = eUnspecified;
+ TriState stOsVersion = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2590,6 +2605,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2601,7 +2617,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsCOMPtr<nsIURI> baseuri, overlayuri;
+@@ -2640,6 +2656,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOs = eUnspecified;
+ TriState stOsVersion = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2650,6 +2667,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2661,7 +2679,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsCOMPtr<nsIURI> chromeuri, resolveduri;
+@@ -2702,6 +2720,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ TriState stApp = eUnspecified;
+ TriState stOsVersion = eUnspecified;
+ TriState stOs = eUnspecified;
++ TriState stDesktop = eUnspecified;
+
+ PRBool badFlag = PR_FALSE;
+
+@@ -2712,6 +2731,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
+ continue;
+@@ -2723,7 +2743,7 @@ nsChromeRegistry::ProcessManifestBuffer(
+ }
+
+ if (badFlag || stApp == eBad || stAppVersion == eBad ||
+- stOs == eBad || stOsVersion == eBad)
++ stOs == eBad || stOsVersion == eBad || stDesktop == eBad)
+ continue;
+
+ nsDependentCString host(package);
+--- mozilla/modules/libpref/src/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/modules/libpref/src/Makefile.in 2009-09-14 10:04:14.000000000 +0200
+@@ -97,3 +97,5 @@ nsPrefService.$(OBJ_SUFFIX): nsPrefServi
+ @$(MAKE_DEPS_AUTO_CXX)
+ $(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS:-O2=-O1) $(_VPATH_SRCS)
+ endif
++
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+--- mozilla/modules/libpref/src/nsPrefService.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/modules/libpref/src/nsPrefService.cpp 2009-09-14 10:04:14.000000000 +0200
+@@ -51,6 +51,7 @@
+ #include "nsCOMArray.h"
+ #include "nsXPCOMCID.h"
+ #include "nsAutoPtr.h"
++#include "nsKDEUtils.h"
+
+ #include "nsQuickSort.h"
+ #include "prmem.h"
+@@ -606,7 +607,8 @@ pref_LoadPrefsInDir(nsIFile* aDir, char
+ return rv;
+ }
+
+-static nsresult pref_LoadPrefsInDirList(const char *listId)
++static nsresult pref_LoadPrefsInDirList(const char *listId,
++ char const *const *aSpecialFiles = NULL, PRUint32 aSpecialFilesCount = 0)
+ {
+ nsresult rv;
+ nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
+@@ -625,7 +627,7 @@ static nsresult pref_LoadPrefsInDirList(
+ nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
+ if (dir) {
+ // Do we care if a file provided by this process fails to load?
+- pref_LoadPrefsInDir(dir, nsnull, 0);
++ pref_LoadPrefsInDir(dir, aSpecialFiles, aSpecialFilesCount);
+ }
+ }
+ }
+@@ -676,6 +678,7 @@ static nsresult pref_InitInitialObjects(
+ #if defined(MOZ_WIDGET_PHOTON)
+ , "photon.js"
+ #endif
++ , "" // placeholder for KDE (empty is otherwise harmless)
+ #elif defined(XP_OS2)
+ "os2pref.js"
+ #elif defined(XP_BEOS)
+@@ -683,12 +686,23 @@ static nsresult pref_InitInitialObjects(
+ #endif
+ };
+
++ if( nsKDEUtils::kdeSession()) { // TODO what if some setup actually requires the helper?
++ for( int i = 0;
++ i < NS_ARRAY_LENGTH(specialFiles);
++ ++i ) {
++ if( *specialFiles[ i ] == '\0' ) {
++ specialFiles[ i ] = "kde.js";
++ break;
++ }
++ }
++ }
++
+ rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, NS_ARRAY_LENGTH(specialFiles));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Error parsing application default preferences.");
+ }
+
+- rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST);
++ rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST, specialFiles, NS_ARRAY_LENGTH(specialFiles));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
+--- mozilla/toolkit/components/downloads/src/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/components/downloads/src/Makefile.in 2009-09-14 10:04:14.000000000 +0200
+@@ -100,3 +100,4 @@ include $(topsrcdir)/config/rules.mk
+
+ EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
+
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+--- mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp 2009-09-14 10:04:14.000000000 +0200
+@@ -85,6 +85,7 @@
+ #include "nsDocShellCID.h"
+ #include "nsIPrivateBrowsingService.h"
+ #include "nsNetCID.h"
++#include "nsKDEUtils.h"
+
+ #if defined(XP_WIN) && !defined(WINCE)
+ #include <shlobj.h>
+@@ -2299,6 +2300,15 @@ nsDownload::SetState(DownloadState aStat
+ pref->GetBoolPref(PREF_BDM_SHOWALERTONCOMPLETE, &showTaskbarAlert);
+
+ if (showTaskbarAlert) {
++ if( nsKDEUtils::kdeSupport()) {
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "DOWNLOADFINISHED" ));
++ nsAutoString displayName;
++ GetDisplayName( displayName );
++ command.AppendCString( nsCAutoString( ToNewUTF8String( displayName )));
++ nsKDEUtils::command( command );
++ } else {
++ // begin non-KDE block
+ PRInt32 alertInterval = 2000;
+ if (pref)
+ pref->GetIntPref(PREF_BDM_SHOWALERTINTERVAL, &alertInterval);
+@@ -2334,6 +2344,7 @@ nsDownload::SetState(DownloadState aStat
+ EmptyString());
+ }
+ }
++ } // end non-KDE block
+ }
+ #if defined(XP_WIN) && !defined(WINCE)
+ nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mTarget);
+--- mozilla/toolkit/content/jar.mn.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/content/jar.mn 2009-09-14 10:04:14.000000000 +0200
+@@ -43,6 +43,8 @@ toolkit.jar:
+ *+ content/global/bindings/colorpicker.xml (widgets/colorpicker.xml)
+ *+ content/global/bindings/datetimepicker.xml (widgets/datetimepicker.xml)
+ *+ content/global/bindings/dialog.xml (widgets/dialog.xml)
++*+ content/global/bindings/dialog-kde.xml (widgets/dialog-kde.xml)
++% override chrome://global/content/bindings/dialog.xml chrome://global/content/bindings/dialog-kde.xml desktop=kde
+ *+ content/global/bindings/editor.xml (widgets/editor.xml)
+ * content/global/bindings/expander.xml (widgets/expander.xml)
+ * content/global/bindings/filefield.xml (widgets/filefield.xml)
+@@ -56,6 +58,8 @@ toolkit.jar:
+ *+ content/global/bindings/numberbox.xml (widgets/numberbox.xml)
+ *+ content/global/bindings/popup.xml (widgets/popup.xml)
+ *+ content/global/bindings/preferences.xml (widgets/preferences.xml)
++*+ content/global/bindings/preferences-kde.xml (widgets/preferences-kde.xml)
++% override chrome://global/content/bindings/preferences.xml chrome://global/content/bindings/preferences-kde.xml desktop=kde
+ *+ content/global/bindings/progressmeter.xml (widgets/progressmeter.xml)
+ *+ content/global/bindings/radio.xml (widgets/radio.xml)
+ *+ content/global/bindings/resizer.xml (widgets/resizer.xml)
+--- mozilla/toolkit/content/widgets/dialog-kde.xml.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/content/widgets/dialog-kde.xml 2009-09-14 10:04:14.000000000 +0200
+@@ -19,7 +19,7 @@
+
+ <xul:hbox class="dialog-button-box" anonid="buttons"
+ xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
+-#ifdef XP_UNIX
++#ifdef XP_UNIX_GNOME
+ >
+ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
+@@ -28,6 +28,15 @@
+ <xul:spacer anonid="spacer" flex="1"/>
+ <xul:button dlgtype="cancel" class="dialog-button"/>
+ <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
++#elif XP_UNIX
++ pack="end">
++ <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
++ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
++ <xul:spacer anonid="spacer" flex="1" hidden="true"/>
++ <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
++ <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
++ <xul:button dlgtype="cancel" class="dialog-button"/>
++ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+ #else
+ pack="end">
+ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+--- mozilla/toolkit/content/widgets/preferences-kde.xml.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/content/widgets/preferences-kde.xml 2009-09-14 10:04:14.000000000 +0200
+@@ -573,7 +573,7 @@
+ </xul:deck>
+ </xul:hbox>
+ <xul:hbox anonid="dlg-buttons" class="prefWindow-dlgbuttons"
+-#ifdef XP_UNIX
++#ifdef XP_UNIX_GNOME
+ >
+ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+ <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
+@@ -582,6 +582,15 @@
+ <xul:spacer anonid="spacer" flex="1"/>
+ <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
+ <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
++#elif XP_UNIX
++ pack="end">
++ <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
++ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
++ <xul:spacer anonid="spacer" flex="1"/>
++ <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
++ <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
++ <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
++ <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
+ #else
+ pack="end">
+ <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
+--- mozilla/toolkit/system/unixproxy/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/system/unixproxy/Makefile.in 2009-09-14 10:04:14.000000000 +0200
+@@ -64,4 +64,6 @@ CPPSRCS = \
+ nsUnixSystemProxySettings.cpp \
+ $(NULL)
+
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
++
+ include $(topsrcdir)/config/rules.mk
+--- mozilla/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2009-09-14 10:04:14.000000000 +0200
+@@ -49,6 +49,8 @@
+ #include "nsPrintfCString.h"
+ #include "nsNetUtil.h"
+ #include "nsISupportsPrimitives.h"
++#include "nsVoidArray.h"
++#include "nsKDEUtils.h"
+
+ class nsUnixSystemProxySettings : public nsISystemProxySettings {
+ public:
+@@ -65,6 +67,7 @@ private:
+ PRBool IsProxyMode(const char* aMode);
+ nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, nsACString& aResult);
+ nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
++ nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, PRInt32 aPort, nsACString& aResult);
+ };
+
+ NS_IMPL_ISUPPORTS1(nsUnixSystemProxySettings, nsISystemProxySettings)
+@@ -412,6 +415,9 @@ nsUnixSystemProxySettings::GetProxyForUR
+ rv = aURI->GetPort(&port);
+ NS_ENSURE_SUCCESS(rv, rv);
+
++ if( nsKDEUtils::kdeSupport())
++ return GetProxyFromKDE( scheme, host, port, aResult );
++
+ if (!mGConf)
+ return GetProxyFromEnvironment(scheme, host, port, aResult);
+
+@@ -432,3 +438,28 @@ static const nsModuleComponentInfo compo
+ };
+
+ NS_IMPL_NSGETMODULE(nsUnixProxyModule, components)
++
++nsresult
++nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme,
++ const nsACString& aHost,
++ PRInt32 aPort,
++ nsACString& aResult)
++{
++ nsCAutoString url;
++ url = aScheme;
++ url += "://";
++ url += aHost;
++ if( aPort >= 0 )
++ {
++ url += ":";
++ url += nsPrintfCString("%d", aPort);
++ }
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "GETPROXY" ));
++ command.AppendCString( url );
++ nsCStringArray result;
++ if( !nsKDEUtils::command( command, &result ) || result.Count() != 1 )
++ return NS_ERROR_FAILURE;
++ aResult = *result[ 0 ];
++ return NS_OK;
++}
+--- mozilla/toolkit/xre/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/xre/Makefile.in 2009-09-14 10:04:14.000000000 +0200
+@@ -98,6 +98,7 @@ endif
+ EXPORTS = \
+ xrecore.h \
+ nsXULAppAPI.h \
++ nsKDEUtils.h \
+ $(NULL)
+
+ CPPSRCS = \
+@@ -133,7 +134,7 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
+ CPPSRCS += nsNativeAppSupportBeOS.cpp
+ else
+ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
+-CPPSRCS += nsNativeAppSupportUnix.cpp
++CPPSRCS += nsNativeAppSupportUnix.cpp nsKDEUtils.cpp
+ else
+ CPPSRCS += nsNativeAppSupportDefault.cpp
+ endif
+--- mozilla/toolkit/xre/nsKDEUtils.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/xre/nsKDEUtils.cpp 2009-09-14 10:04:14.000000000 +0200
+@@ -0,0 +1,329 @@
++/* -*- 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):
++ *
++ * 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 "nsKDEUtils.h"
++#include "nsIWidget.h"
++
++#include <gtk/gtkwindow.h>
++#include <gtk/gtkmain.h>
++
++#include <limits.h>
++#include <stdio.h>
++#include <sys/wait.h>
++#include <unistd.h>
++#include <X11/Xlib.h>
++
++//#define DEBUG_KDE
++#ifdef DEBUG_KDE
++#define KMOZILLAHELPER "kmozillahelper"
++#else
++// not need for lib64, it's a binary
++#define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper"
++#endif
++
++#define KMOZILLAHELPER_VERSION 5
++#define MAKE_STR2( n ) #n
++#define MAKE_STR( n ) MAKE_STR2( n )
++
++static bool getKdeSession()
++ {
++ Display* dpy = XOpenDisplay( NULL );
++ if( dpy == NULL )
++ return false;
++ Atom kde_full_session = XInternAtom( dpy, "KDE_FULL_SESSION", True );
++ bool kde = false;
++ if( kde_full_session != None )
++ {
++ int cnt;
++ if( Atom* props = XListProperties( dpy, DefaultRootWindow( dpy ), &cnt ))
++ {
++ for( int i = 0;
++ i < cnt;
++ ++i )
++ {
++ if( props[ i ] == kde_full_session )
++ {
++ kde = true;
++#ifdef DEBUG_KDE
++ fprintf( stderr, "KDE SESSION %d\n", kde );
++#endif
++ break;
++ }
++ }
++ XFree( props );
++ }
++ }
++ XCloseDisplay( dpy );
++ return kde;
++ }
++
++static bool getKdeSupport()
++ {
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "CHECK" ));
++ command.AppendCString( NS_LITERAL_CSTRING( MAKE_STR( KMOZILLAHELPER_VERSION )));
++ bool kde = nsKDEUtils::command( command );
++#ifdef DEBUG_KDE
++ fprintf( stderr, "KDE RUNNING %d\n", kde );
++#endif
++ return kde;
++ }
++
++nsKDEUtils::nsKDEUtils()
++ : commandFile( NULL )
++ , replyFile( NULL )
++ {
++ }
++
++nsKDEUtils::~nsKDEUtils()
++ {
++// closeHelper(); not actually useful, exiting will close the fd too
++ }
++
++nsKDEUtils* nsKDEUtils::self()
++ {
++ static nsKDEUtils s;
++ return &s;
++ }
++
++static bool helperRunning = false;
++static bool helperFailed = false;
++
++bool nsKDEUtils::kdeSession()
++ {
++ static bool session = getKdeSession();
++ return session;
++ }
++
++bool nsKDEUtils::kdeSupport()
++ {
++ static bool support = kdeSession() && getKdeSupport();
++ return support && helperRunning;
++ }
++
++struct nsKDECommandData
++ {
++ FILE* file;
++ nsCStringArray* output;
++ GMainLoop* loop;
++ bool success;
++ };
++
++static gboolean kdeReadFunc( GIOChannel*, GIOCondition, gpointer data )
++ {
++ nsKDECommandData* p = static_cast< nsKDECommandData* >( data );
++ char buf[ 8192 ]; // TODO big enough
++ bool command_done = false;
++ bool command_failed = false;
++ while( !command_done && !command_failed && fgets( buf, 8192, p->file ) != NULL )
++ { // TODO what if the kernel splits a line into two chunks?
++//#ifdef DEBUG_KDE
++// fprintf( stderr, "READ: %s %d\n", buf, feof( p->file ));
++//#endif
++ if( char* eol = strchr( buf, '\n' ))
++ *eol = '\0';
++ command_done = ( strcmp( buf, "\\1" ) == 0 );
++ command_failed = ( strcmp( buf, "\\0" ) == 0 );
++ nsCAutoString line( buf );
++ line.ReplaceSubstring( "\\n", "\n" );
++ line.ReplaceSubstring( "\\" "\\", "\\" ); // \\ -> \ , i.e. unescape
++ if( p->output && !( command_done || command_failed ))
++ p->output->AppendCString( nsCString( buf )); // TODO utf8?
++ }
++ bool quit = false;
++ if( feof( p->file ) || command_failed )
++ {
++ quit = true;
++ p->success = false;
++ }
++ if( command_done )
++ { // reading one reply finished
++ quit = true;
++ p->success = true;
++ }
++ if( quit )
++ {
++ if( p->loop )
++ g_main_loop_quit( p->loop );
++ return FALSE;
++ }
++ return TRUE;
++ }
++
++bool nsKDEUtils::command( const nsCStringArray& command, nsCStringArray* output )
++ {
++ return self()->internalCommand( command, NULL, false, output );
++ }
++
++bool nsKDEUtils::commandBlockUi( const nsCStringArray& command, const GtkWindow* parent, nsCStringArray* output )
++ {
++ return self()->internalCommand( command, parent, true, output );
++ }
++
++bool nsKDEUtils::internalCommand( const nsCStringArray& command, const GtkWindow* parent, bool blockUi,
++ nsCStringArray* output )
++ {
++ if( !startHelper())
++ return false;
++ feedCommand( command );
++ // do not store the data in 'this' but in extra structure, just in case there
++ // is reentrancy (can there be? the event loop is re-entered)
++ nsKDECommandData data;
++ data.file = replyFile;
++ data.output = output;
++ data.success = false;
++ if( blockUi )
++ {
++ data.loop = g_main_loop_new( NULL, FALSE );
++ GtkWidget* window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
++ if( parent && parent->group )
++ gtk_window_group_add_window( parent->group, GTK_WINDOW( window ));
++ gtk_widget_realize( window );
++ gtk_widget_set_sensitive( window, TRUE );
++ gtk_grab_add( window );
++ GIOChannel* channel = g_io_channel_unix_new( fileno( data.file ));
++ g_io_add_watch( channel, static_cast< GIOCondition >( G_IO_IN | G_IO_ERR | G_IO_HUP ), kdeReadFunc, &data );
++ g_io_channel_unref( channel );
++ g_main_loop_run( data.loop );
++ g_main_loop_unref( data.loop );
++ gtk_grab_remove( window );
++ gtk_widget_destroy( window );
++ }
++ else
++ {
++ data.loop = NULL;
++ while( kdeReadFunc( NULL, static_cast< GIOCondition >( 0 ), &data ))
++ ;
++ }
++ return data.success;
++ }
++
++bool nsKDEUtils::startHelper()
++ {
++ if( helperRunning )
++ return true;
++ if( helperFailed )
++ return false;
++ helperFailed = true;
++ int fdcommand[ 2 ];
++ int fdreply[ 2 ];
++ if( pipe( fdcommand ) < 0 )
++ return false;
++ if( pipe( fdreply ) < 0 )
++ {
++ close( fdcommand[ 0 ] );
++ close( fdcommand[ 1 ] );
++ return false;
++ }
++ char* args[ 2 ] = { const_cast< char* >( KMOZILLAHELPER ), NULL };
++ switch( fork())
++ {
++ case -1:
++ {
++ close( fdcommand[ 0 ] );
++ close( fdcommand[ 1 ] );
++ close( fdreply[ 0 ] );
++ close( fdreply[ 1 ] );
++ return false;
++ }
++ case 0: // child
++ {
++ if( dup2( fdcommand[ 0 ], STDIN_FILENO ) < 0 )
++ _exit( 1 );
++ if( dup2( fdreply[ 1 ], STDOUT_FILENO ) < 0 )
++ _exit( 1 );
++ int maxfd = 1024; // close all other fds
++ struct rlimit rl;
++ if( getrlimit( RLIMIT_NOFILE, &rl ) == 0 )
++ maxfd = rl.rlim_max;
++ for( int i = 3;
++ i < maxfd;
++ ++i )
++ close( i );
++#ifdef DEBUG_KDE
++ execvp( KMOZILLAHELPER, args );
++#else
++ execv( KMOZILLAHELPER, args );
++#endif
++ _exit( 1 ); // failed
++ }
++ default: // parent
++ {
++ commandFile = fdopen( fdcommand[ 1 ], "w" );
++ replyFile = fdopen( fdreply[ 0 ], "r" );
++ close( fdcommand[ 0 ] );
++ close( fdreply[ 1 ] );
++ if( commandFile == NULL || replyFile == NULL )
++ {
++ closeHelper();
++ return false;
++ }
++ // ok, helper ready, getKdeRunning() will check if it works
++ }
++ }
++ helperFailed = false;
++ helperRunning = true;
++ return true;
++ }
++
++void nsKDEUtils::closeHelper()
++ {
++ if( commandFile != NULL )
++ fclose( commandFile ); // this will also make the helper quit
++ if( replyFile != NULL )
++ fclose( replyFile );
++ helperRunning = false;
++ }
++
++void nsKDEUtils::feedCommand( const nsCStringArray& command )
++ {
++ for( int i = 0;
++ i < command.Count();
++ ++i )
++ {
++ nsCString line = *command[ i ];
++ line.ReplaceSubstring( "\\", "\\" "\\" ); // \ -> \\ , i.e. escape
++ line.ReplaceSubstring( "\n", "\\n" );
++#ifdef DEBUG_KDE
++ fprintf( stderr, "COMM: %s\n", line.get());
++#endif
++ fputs( line.get(), commandFile );
++ fputs( "\n", commandFile );
++ }
++ fputs( "\\E\n", commandFile ); // done as \E, so it cannot happen in normal data
++ fflush( commandFile );
++ }
+--- mozilla/toolkit/xre/nsKDEUtils.h.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/toolkit/xre/nsKDEUtils.h 2009-09-14 10:04:15.000000000 +0200
+@@ -0,0 +1,77 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
++ *
++ * ***** 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 Communicator client code.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 1998
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either of 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 ***** */
++
++#ifndef nsKDEUtils_h__
++#define nsKDEUtils_h__
++
++#include "nsStringGlue.h"
++#include "nsVoidArray.h"
++#include <stdio.h>
++
++typedef struct _GtkWindow GtkWindow;
++
++class NS_EXPORT nsKDEUtils
++ {
++ public:
++ /* Returns true if running inside a KDE session (regardless of whether there is KDE
++ support available for Firefox). This should be used e.g. when determining
++ dialog button order but not for code that requires the KDE support. */
++ static bool kdeSession();
++ /* Returns true if running inside a KDE session and KDE support is available
++ for Firefox. This should be used everywhere where the external helper is needed. */
++ static bool kdeSupport();
++ /* Executes the given helper command, returns true if helper returned success. */
++ static bool command( const nsCStringArray& command, nsCStringArray* output = NULL );
++ /* Like command(), but additionally blocks the parent widget like if there was
++ a modal dialog shown and enters the event loop (i.e. there are still paint updates,
++ this is for commands that take long). */
++ static bool commandBlockUi( const nsCStringArray& command, const GtkWindow* parent, nsCStringArray* output = NULL );
++ private:
++ nsKDEUtils();
++ ~nsKDEUtils();
++ static nsKDEUtils* self();
++ bool startHelper();
++ void closeHelper();
++ void feedCommand( const nsCStringArray& command );
++ bool internalCommand( const nsCStringArray& command, const GtkWindow* parent, bool isParent,
++ nsCStringArray* output );
++ FILE* commandFile;
++ FILE* replyFile;
++ };
++
++#endif // nsKDEUtils
+--- mozilla/uriloader/exthandler/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/uriloader/exthandler/Makefile.in 2009-09-14 10:04:15.000000000 +0200
+@@ -109,8 +109,9 @@ endif
+ LOCAL_INCLUDES = -I$(srcdir)
+
+ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
+-OSHELPER += nsGNOMERegistry.cpp
++OSHELPER += nsCommonRegistry.cpp nsGNOMERegistry.cpp nsKDERegistry.cpp
+ OSHELPER += nsMIMEInfoUnix.cpp
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+ endif
+
+ ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
+--- mozilla/uriloader/exthandler/unix/nsCommonRegistry.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/uriloader/exthandler/unix/nsCommonRegistry.cpp 2009-09-14 10:04:15.000000000 +0200
+@@ -0,0 +1,87 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* ***** 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 the GNOME helper app implementation.
++ *
++ * The Initial Developer of the Original Code is
++ * IBM Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Brian Ryner <bryner@brianryner.com> (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 "nsCommonRegistry.h"
++
++#include "nsGNOMERegistry.h"
++#include "nsKDERegistry.h"
++#include "nsString.h"
++#include "nsVoidArray.h"
++#include "nsKDEUtils.h"
++
++/* static */ PRBool
++nsCommonRegistry::HandlerExists(const char *aProtocolScheme)
++{
++ if( nsKDEUtils::kdeSupport())
++ return nsKDERegistry::HandlerExists( aProtocolScheme );
++ return nsGNOMERegistry::HandlerExists( aProtocolScheme );
++}
++
++/* static */ nsresult
++nsCommonRegistry::LoadURL(nsIURI *aURL)
++{
++ if( nsKDEUtils::kdeSupport())
++ return nsKDERegistry::LoadURL( aURL );
++ return nsGNOMERegistry::LoadURL( aURL );
++}
++
++/* static */ void
++nsCommonRegistry::GetAppDescForScheme(const nsACString& aScheme,
++ nsAString& aDesc)
++{
++ if( nsKDEUtils::kdeSupport())
++ return nsKDERegistry::GetAppDescForScheme( aScheme, aDesc );
++ return nsGNOMERegistry::GetAppDescForScheme( aScheme, aDesc );
++}
++
++
++/* static */ already_AddRefed<nsMIMEInfoBase>
++nsCommonRegistry::GetFromExtension(const nsACString& aFileExt)
++{
++ if( nsKDEUtils::kdeSupport())
++ return nsKDERegistry::GetFromExtension( aFileExt );
++ return nsGNOMERegistry::GetFromExtension( aFileExt );
++}
++
++/* static */ already_AddRefed<nsMIMEInfoBase>
++nsCommonRegistry::GetFromType(const nsACString& aMIMEType)
++{
++ if( nsKDEUtils::kdeSupport())
++ return nsKDERegistry::GetFromType( aMIMEType );
++ return nsGNOMERegistry::GetFromType( aMIMEType );
++}
+--- mozilla/uriloader/exthandler/unix/nsCommonRegistry.h.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/uriloader/exthandler/unix/nsCommonRegistry.h 2009-09-14 10:04:15.000000000 +0200
+@@ -0,0 +1,56 @@
++/* ***** 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 the GNOME helper app implementation.
++ *
++ * The Initial Developer of the Original Code is
++ * IBM Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Brian Ryner <bryner@brianryner.com> (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 "nsIURI.h"
++#include "nsCOMPtr.h"
++
++class nsMIMEInfoBase;
++
++class nsCommonRegistry
++{
++ public:
++ static PRBool HandlerExists(const char *aProtocolScheme);
++
++ static nsresult LoadURL(nsIURI *aURL);
++
++ static void GetAppDescForScheme(const nsACString& aScheme,
++ nsAString& aDesc);
++
++ static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
++
++ static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
++};
+--- mozilla/uriloader/exthandler/unix/nsKDERegistry.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/uriloader/exthandler/unix/nsKDERegistry.cpp 2009-09-14 10:04:15.000000000 +0200
+@@ -0,0 +1,119 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* ***** 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 the GNOME helper app implementation.
++ *
++ * The Initial Developer of the Original Code is
++ * IBM Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Brian Ryner <bryner@brianryner.com> (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 "nsKDERegistry.h"
++#include "prlink.h"
++#include "prmem.h"
++#include "nsString.h"
++#include "nsILocalFile.h"
++#include "nsMIMEInfoUnix.h"
++#include "nsAutoPtr.h"
++#include "nsKDEUtils.h"
++
++/* static */ PRBool
++nsKDERegistry::HandlerExists(const char *aProtocolScheme)
++{
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "HANDLEREXISTS" ));
++ command.AppendCString( nsCAutoString( aProtocolScheme ));
++ return nsKDEUtils::command( command );
++}
++
++/* static */ nsresult
++nsKDERegistry::LoadURL(nsIURI *aURL)
++{
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
++ nsCString url;
++ aURL->GetSpec( url );
++ command.AppendCString( url );
++ return nsKDEUtils::command( command );
++}
++
++/* static */ void
++nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme,
++ nsAString& aDesc)
++{
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "GETAPPDESCFORSCHEME" ));
++ command.AppendCString( aScheme );
++ nsCStringArray output;
++ if( nsKDEUtils::command( command, &output ) && output.Count() == 1 )
++ CopyUTF8toUTF16( *output[ 0 ], aDesc );
++}
++
++
++/* static */ already_AddRefed<nsMIMEInfoBase>
++nsKDERegistry::GetFromExtension(const nsACString& aFileExt)
++{
++ NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot");
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "GETFROMEXTENSION" ));
++ command.AppendCString( aFileExt );
++ return GetFromHelper( command );
++}
++
++/* static */ already_AddRefed<nsMIMEInfoBase>
++nsKDERegistry::GetFromType(const nsACString& aMIMEType)
++{
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "GETFROMTYPE" ));
++ command.AppendCString( aMIMEType );
++ return GetFromHelper( command );
++}
++
++/* static */ already_AddRefed<nsMIMEInfoBase>
++nsKDERegistry::GetFromHelper(const nsCStringArray& command)
++{
++ nsCStringArray output;
++ if( nsKDEUtils::command( command, &output ) && output.Count() == 3 )
++ {
++ nsCString mimetype = *output[ 0 ];
++ nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix( mimetype );
++ NS_ENSURE_TRUE(mimeInfo, nsnull);
++ nsCString description = *output[ 1 ];
++ mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
++ nsCString handlerAppName = *output[ 2 ];
++ mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName));
++ mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
++ nsMIMEInfoBase* retval;
++ NS_ADDREF((retval = mimeInfo));
++ return retval;
++ }
++ return nsnull;
++}
+--- mozilla/uriloader/exthandler/unix/nsKDERegistry.h.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/uriloader/exthandler/unix/nsKDERegistry.h 2009-09-14 10:04:15.000000000 +0200
+@@ -0,0 +1,61 @@
++/* ***** 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 the GNOME helper app implementation.
++ *
++ * The Initial Developer of the Original Code is
++ * IBM Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Brian Ryner <bryner@brianryner.com> (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 "nsIURI.h"
++#include "nsCOMPtr.h"
++
++class nsMIMEInfoBase;
++class nsCAutoString;
++class nsCStringArray;
++
++class nsKDERegistry
++{
++ public:
++ static PRBool HandlerExists(const char *aProtocolScheme);
++
++ static nsresult LoadURL(nsIURI *aURL);
++
++ static void GetAppDescForScheme(const nsACString& aScheme,
++ nsAString& aDesc);
++
++ static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
++
++ static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
++ private:
++ static already_AddRefed<nsMIMEInfoBase> GetFromHelper(const nsCStringArray& command);
++
++};
+--- mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp.sav 2009-09-14 10:02:42.000000000 +0200
++++ mozilla/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp 2009-09-14 10:07:10.000000000 +0200
+@@ -44,18 +44,19 @@
+
+
+ #include "nsMIMEInfoUnix.h"
+-#include "nsGNOMERegistry.h"
++#include "nsCommonRegistry.h"
+ #include "nsIGnomeVFSService.h"
+ #include "nsAutoPtr.h"
+ #ifdef MOZ_ENABLE_DBUS
+ #include "nsDBusHandlerApp.h"
+ #endif
++#include "nsKDEUtils.h"
+
+
+ nsresult
+ nsMIMEInfoUnix::LoadUriInternal(nsIURI * aURI)
+ {
+- nsresult rv = nsGNOMERegistry::LoadURL(aURI);
++ nsresult rv = nsCommonRegistry::LoadURL(aURI);
+ #ifdef MOZ_PLATFORM_HILDON
+ if (NS_FAILED(rv)){
+ HildonURIAction *action = hildon_uri_get_default_action(mType.get(), nsnull);
+@@ -75,11 +76,11 @@ NS_IMETHODIMP
+ nsMIMEInfoUnix::GetHasDefaultHandler(PRBool *_retval)
+ {
+ *_retval = PR_FALSE;
+- nsRefPtr<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromType(mType);
++ nsRefPtr<nsMIMEInfoBase> mimeInfo = nsCommonRegistry::GetFromType(mType);
+ if (!mimeInfo) {
+ nsCAutoString ext;
+ GetPrimaryExtension(ext);
+- mimeInfo = nsGNOMERegistry::GetFromExtension(ext);
++ mimeInfo = nsCommonRegistry::GetFromExtension(ext);
+ }
+
+ if (mimeInfo)
+@@ -106,6 +107,19 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
+ {
+ nsCAutoString nativePath;
+ aFile->GetNativePath(nativePath);
++
++ if( nsKDEUtils::kdeSupport())
++ {
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
++ command.AppendCString( nativePath );
++ if( nsKDEUtils::command( command ))
++ return NS_OK;
++ if (!mDefaultApplication)
++ return NS_ERROR_FILE_NOT_FOUND;
++
++ return LaunchWithIProcess(mDefaultApplication, nativePath);
++ }
+
+ nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+
+@@ -116,7 +130,7 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
+
+ // If we haven't got an app we try to get a valid one by searching for the
+ // extension mapped type
+- nsRefPtr<nsMIMEInfoBase> mimeInfo = nsGNOMERegistry::GetFromExtension(nativePath);
++ nsRefPtr<nsMIMEInfoBase> mimeInfo = nsCommonRegistry::GetFromExtension(nativePath);
+ if (mimeInfo) {
+ nsCAutoString type;
+ mimeInfo->GetType(type);
+--- mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp.sav 2009-09-14 10:02:42.000000000 +0200
++++ mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp 2009-09-14 10:04:15.000000000 +0200
+@@ -44,7 +44,7 @@
+ #include "nsOSHelperAppService.h"
+ #include "nsMIMEInfoUnix.h"
+ #ifdef MOZ_WIDGET_GTK2
+-#include "nsGNOMERegistry.h"
++#include "nsCommonRegistry.h"
+ #endif
+ #include "nsISupports.h"
+ #include "nsString.h"
+@@ -1210,7 +1210,7 @@ nsresult nsOSHelperAppService::OSProtoco
+
+ #ifdef MOZ_WIDGET_GTK2
+ // Check the GConf registry for a protocol handler
+- *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme);
++ *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme);
+ #endif
+
+ return NS_OK;
+@@ -1219,7 +1219,7 @@ nsresult nsOSHelperAppService::OSProtoco
+ NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
+ {
+ #ifdef MOZ_WIDGET_GTK2
+- nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval);
++ nsCommonRegistry::GetAppDescForScheme(aScheme, _retval);
+ return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK;
+ #else
+ return NS_ERROR_NOT_AVAILABLE;
+@@ -1315,7 +1315,7 @@ nsOSHelperAppService::GetFromExtension(c
+
+ #ifdef MOZ_WIDGET_GTK2
+ LOG(("Looking in GNOME registry\n"));
+- nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromExtension(aFileExt).get();
++ nsMIMEInfoBase *gnomeInfo = nsCommonRegistry::GetFromExtension(aFileExt).get();
+ if (gnomeInfo) {
+ LOG(("Got MIMEInfo from GNOME registry\n"));
+ return gnomeInfo;
+@@ -1441,7 +1441,7 @@ nsOSHelperAppService::GetFromType(const
+ // get back a MIMEInfo without any extensions set. In that case we'll have
+ // to look in our mime.types files for the extensions.
+ LOG(("Looking in GNOME registry\n"));
+- gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType).get();
++ gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType).get();
+ if (gnomeInfo && gnomeInfo->HasExtensions()) {
+ LOG(("Got MIMEInfo from GNOME registry, and it has extensions set\n"));
+ return gnomeInfo;
+--- mozilla/widget/src/gtk2/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/widget/src/gtk2/Makefile.in 2009-09-14 10:04:15.000000000 +0200
+@@ -182,6 +182,8 @@ INCLUDES += \
+ -I$(topsrcdir)/other-licenses/atk-1.0 \
+ $(NULL)
+
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
++
+ test_container: mozdrawingarea.o mozcontainer.o test_container.c
+ $(CC) $(MOZ_GTK2_CFLAGS) -o test_container test_container.c \
+ mozdrawingarea.o mozcontainer.o \
+--- mozilla/widget/src/gtk2/nsFilePicker.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/widget/src/gtk2/nsFilePicker.cpp 2009-09-14 10:04:15.000000000 +0200
+@@ -40,6 +40,7 @@
+ #include <gtk/gtkstock.h>
+ #include <gtk/gtkmessagedialog.h>
+ #include <gtk/gtkimage.h>
++#include <gdk/gdkx.h>
+
+ #include "nsIFileURL.h"
+ #include "nsIURI.h"
+@@ -59,6 +60,7 @@
+
+ #include "nsFilePicker.h"
+ #include "nsAccessibilityHelper.h"
++#include "nsKDEUtils.h"
+
+ #define DECL_FUNC_PTR(func) static _##func##_fn _##func
+ #define GTK_FILE_CHOOSER(widget) ((GtkFileChooser*) widget)
+@@ -95,6 +97,7 @@ typedef GtkWidget* (*_gtk_file_chooser_d
+ GtkFileChooserAction action,
+ const gchar *first_button_text,
+ ...);
++typedef void (*_gtk_dialog_set_alternative_button_order_fn)(GtkDialog *dialog, gint first_response_id, ...);
+ typedef void (*_gtk_file_chooser_set_select_multiple_fn)(GtkFileChooser* chooser, gboolean truth);
+ typedef void (*_gtk_file_chooser_set_do_overwrite_confirmation_fn)(GtkFileChooser* chooser, gboolean do_confirm);
+ typedef void (*_gtk_file_chooser_set_current_name_fn)(GtkFileChooser* chooser, const gchar* name);
+@@ -119,6 +122,7 @@ DECL_FUNC_PTR(gtk_file_chooser_get_filen
+ DECL_FUNC_PTR(gtk_file_chooser_get_uri);
+ DECL_FUNC_PTR(gtk_file_chooser_get_uris);
+ DECL_FUNC_PTR(gtk_file_chooser_dialog_new);
++DECL_FUNC_PTR(gtk_dialog_set_alternative_button_order);
+ DECL_FUNC_PTR(gtk_file_chooser_set_select_multiple);
+ DECL_FUNC_PTR(gtk_file_chooser_set_do_overwrite_confirmation);
+ DECL_FUNC_PTR(gtk_file_chooser_set_current_name);
+@@ -214,6 +218,7 @@ nsFilePicker::LoadSymbolsGTK24()
+ GET_LIBGTK_FUNC(gtk_file_chooser_get_uri);
+ GET_LIBGTK_FUNC(gtk_file_chooser_get_uris);
+ GET_LIBGTK_FUNC(gtk_file_chooser_dialog_new);
++ GET_LIBGTK_FUNC(gtk_dialog_set_alternative_button_order);
+ GET_LIBGTK_FUNC(gtk_file_chooser_set_select_multiple);
+ GET_LIBGTK_FUNC_OPT(gtk_file_chooser_set_do_overwrite_confirmation);
+ GET_LIBGTK_FUNC(gtk_file_chooser_set_current_name);
+@@ -442,7 +447,8 @@ nsFilePicker::AppendFilter(const nsAStri
+ {
+ if (aFilter.EqualsLiteral("..apps")) {
+ // No platform specific thing we can do here, really....
+- return NS_OK;
++ if( mMode != modeOpen || !nsKDEUtils::kdeSupport())
++ return NS_OK;
+ }
+
+ nsCAutoString filter, name;
+@@ -590,6 +596,9 @@ confirm_overwrite_file (GtkWidget *paren
+ NS_IMETHODIMP
+ nsFilePicker::Show(PRInt16 *aReturn)
+ {
++ if( nsKDEUtils::kdeSupport())
++ return kdeFileDialog( aReturn );
++
+ NS_ENSURE_ARG_POINTER(aReturn);
+
+ nsXPIDLCString title;
+@@ -605,6 +614,12 @@ nsFilePicker::Show(PRInt16 *aReturn)
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ accept_button, GTK_RESPONSE_ACCEPT,
+ NULL);
++
++ _gtk_dialog_set_alternative_button_order(GTK_DIALOG(file_chooser),
++ GTK_RESPONSE_ACCEPT,
++ GTK_RESPONSE_CANCEL,
++ -1);
++
+ if (mAllowURLs) {
+ _gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_chooser), FALSE);
+ }
+@@ -727,3 +742,221 @@ nsFilePicker::Show(PRInt16 *aReturn)
+
+ return NS_OK;
+ }
++
++nsCString nsFilePicker::kdeMakeFilter( int index )
++ {
++ nsCString buf = *mFilters[ index ];
++ for( PRUint32 i = 0;
++ i < buf.Length();
++ ++i )
++ if( buf[ i ] == ';' ) // KDE separates just using spaces
++ buf.SetCharAt( ' ', i );
++ if (!mFilterNames[index]->IsEmpty())
++ {
++ buf += "|";
++ buf += mFilterNames[index]->get();
++ }
++ return buf;
++ }
++
++static PRInt32 windowToXid( nsIWidget* widget )
++ {
++ GtkWindow *parent_widget = get_gtk_window_for_nsiwidget( widget );
++ GdkWindow* gdk_window = gtk_widget_get_window( gtk_widget_get_toplevel( GTK_WIDGET( parent_widget )));
++ return GDK_WINDOW_XID( gdk_window );
++ }
++
++NS_IMETHODIMP nsFilePicker::kdeFileDialog(PRInt16 *aReturn)
++ {
++ NS_ENSURE_ARG_POINTER(aReturn);
++
++ if( mMode == modeOpen && mFilters.Count() == 1 && mFilters[ 0 ]->EqualsLiteral( "..apps" ))
++ return kdeAppsDialog( aReturn );
++
++ nsXPIDLCString title;
++ title.Adopt(ToNewUTF8String(mTitle));
++
++ const char* arg = NULL;
++ if( mAllowURLs )
++ {
++ switch( mMode )
++ {
++ case nsIFilePicker::modeOpen:
++ case nsIFilePicker::modeOpenMultiple:
++ arg = "GETOPENURL";
++ break;
++ case nsIFilePicker::modeSave:
++ arg = "GETSAVEURL";
++ break;
++ case nsIFilePicker::modeGetFolder:
++ arg = "GETDIRECTORYURL";
++ break;
++ }
++ }
++ else
++ {
++ switch( mMode )
++ {
++ case nsIFilePicker::modeOpen:
++ case nsIFilePicker::modeOpenMultiple:
++ arg = "GETOPENFILENAME";
++ break;
++ case nsIFilePicker::modeSave:
++ arg = "GETSAVEFILENAME";
++ break;
++ case nsIFilePicker::modeGetFolder:
++ arg = "GETDIRECTORYFILENAME";
++ break;
++ }
++ }
++
++ nsCAutoString directory;
++ if (mDisplayDirectory) {
++ mDisplayDirectory->GetNativePath(directory);
++ } else if (mPrevDisplayDirectory) {
++ mPrevDisplayDirectory->GetNativePath(directory);
++ }
++
++ nsCAutoString startdir;
++ if (!directory.IsEmpty()) {
++ startdir = directory;
++ }
++ if (mMode == nsIFilePicker::modeSave) {
++ if( !startdir.IsEmpty())
++ {
++ startdir += "/";
++ startdir += ToNewUTF8String(mDefault);
++ }
++ else
++ startdir = ToNewUTF8String(mDefault);
++ }
++ if( startdir.IsEmpty())
++ startdir = ".";
++
++ nsCAutoString filters;
++ PRInt32 count = mFilters.Count();
++ if( count == 0 ) //just in case
++ filters = "*";
++ else
++ {
++ filters = kdeMakeFilter( 0 );
++ for (PRInt32 i = 1; i < count; ++i)
++ {
++ filters += "\n";
++ filters += kdeMakeFilter( i );
++ }
++ }
++
++ nsCStringArray command;
++ command.AppendCString( nsCAutoString( arg ));
++ command.AppendCString( startdir );
++ if( mMode != nsIFilePicker::modeGetFolder )
++ {
++ command.AppendCString( filters );
++ nsCAutoString selected;
++ selected.AppendInt( mSelectedType );
++ command.AppendCString( selected );
++ }
++ command.AppendCString( title );
++ if( mMode == nsIFilePicker::modeOpenMultiple )
++ command.AppendCString( NS_LITERAL_CSTRING( "MULTIPLE" ));
++ if( PRInt32 xid = windowToXid( mParentWidget ))
++ {
++ command.AppendCString( NS_LITERAL_CSTRING( "PARENT" ));
++ nsCAutoString parent;
++ parent.AppendInt( xid );
++ command.AppendCString( parent );
++ }
++
++ nsCStringArray output;
++ if( nsKDEUtils::commandBlockUi( command, get_gtk_window_for_nsiwidget( mParentWidget ), &output ))
++ {
++ *aReturn = nsIFilePicker::returnOK;
++ mFiles.Clear();
++ if( mMode != nsIFilePicker::modeGetFolder )
++ {
++ mSelectedType = atoi( output[ 0 ]->get());
++ output.RemoveCStringAt( 0 );
++ }
++ if (mMode == nsIFilePicker::modeOpenMultiple)
++ {
++ mFileURL.Truncate();
++ PRUint32 count = output.Count();
++ for( PRUint32 i = 0;
++ i < count;
++ ++i )
++ {
++ nsCOMPtr<nsILocalFile> localfile;
++ nsresult rv = NS_NewNativeLocalFile( *output[ i ],
++ PR_FALSE,
++ getter_AddRefs(localfile));
++ if (NS_SUCCEEDED(rv))
++ mFiles.AppendObject(localfile);
++ }
++ }
++ else
++ {
++ mFileURL = output.Count() > 0 ? *output[ 0 ] : nsCString();
++ }
++ // Remember last used directory.
++ nsCOMPtr<nsILocalFile> file;
++ GetFile(getter_AddRefs(file));
++ if (file) {
++ nsCOMPtr<nsIFile> dir;
++ file->GetParent(getter_AddRefs(dir));
++ nsCOMPtr<nsILocalFile> localDir(do_QueryInterface(dir));
++ if (localDir) {
++ localDir.swap(mPrevDisplayDirectory);
++ }
++ }
++ if (mMode == nsIFilePicker::modeSave)
++ {
++ nsCOMPtr<nsILocalFile> file;
++ GetFile(getter_AddRefs(file));
++ if (file)
++ {
++ PRBool exists = PR_FALSE;
++ file->Exists(&exists);
++ if (exists) // TODO do overwrite check in the helper app
++ *aReturn = nsIFilePicker::returnReplace;
++ }
++ }
++ }
++ else
++ {
++ *aReturn = nsIFilePicker::returnCancel;
++ }
++ return NS_OK;
++ }
++
++
++NS_IMETHODIMP nsFilePicker::kdeAppsDialog(PRInt16 *aReturn)
++ {
++ NS_ENSURE_ARG_POINTER(aReturn);
++
++ nsXPIDLCString title;
++ title.Adopt(ToNewUTF8String(mTitle));
++
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "APPSDIALOG" ));
++ command.AppendCString( title );
++ if( PRInt32 xid = windowToXid( mParentWidget ))
++ {
++ command.AppendCString( NS_LITERAL_CSTRING( "PARENT" ));
++ nsCAutoString parent;
++ parent.AppendInt( xid );
++ command.AppendCString( parent );
++ }
++
++ nsCStringArray output;
++ if( nsKDEUtils::commandBlockUi( command, get_gtk_window_for_nsiwidget( mParentWidget ), &output ))
++ {
++ *aReturn = nsIFilePicker::returnOK;
++ mFileURL = output.Count() > 0 ? *output[ 0 ] : nsCString();
++ }
++ else
++ {
++ *aReturn = nsIFilePicker::returnCancel;
++ }
++ return NS_OK;
++ }
+--- mozilla/widget/src/gtk2/nsFilePicker.h.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/widget/src/gtk2/nsFilePicker.h 2009-09-14 10:04:15.000000000 +0200
+@@ -98,6 +98,12 @@ protected:
+ private:
+ static nsILocalFile *mPrevDisplayDirectory;
+ static PRLibrary *mGTK24;
++
++ bool kdeRunning();
++ bool getKdeRunning();
++ NS_IMETHODIMP kdeFileDialog(PRInt16 *aReturn);
++ NS_IMETHODIMP kdeAppsDialog(PRInt16 *aReturn);
++ nsCString kdeMakeFilter( int index );
+ };
+
+ #endif
+--- mozilla/widget/src/gtk2/nsPrintDialogGTK.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/widget/src/gtk2/nsPrintDialogGTK.cpp 2009-09-14 10:04:15.000000000 +0200
+@@ -145,6 +145,10 @@ ShowCustomDialog(GtkComboBox *changed_bo
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(prompt_dialog), GTK_RESPONSE_ACCEPT);
++ gtk_dialog_set_alternative_button_order(GTK_DIALOG(prompt_dialog),
++ GTK_RESPONSE_ACCEPT,
++ GTK_RESPONSE_REJECT,
++ -1);
+
+ printBundle->GetStringFromName(NS_LITERAL_STRING("customHeaderFooterPrompt").get(), getter_Copies(intlString));
+ GtkWidget* custom_label = gtk_label_new(NS_ConvertUTF16toUTF8(intlString).get());
+--- mozilla/xpcom/io/Makefile.in.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/xpcom/io/Makefile.in 2009-09-14 10:04:15.000000000 +0200
+@@ -199,3 +199,4 @@ endif
+ endif
+
+ LOCAL_INCLUDES = -I..
++LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
+--- mozilla/xpcom/io/nsLocalFileUnix.cpp.sav 2009-09-14 10:00:21.000000000 +0200
++++ mozilla/xpcom/io/nsLocalFileUnix.cpp 2009-09-14 10:04:15.000000000 +0200
+@@ -84,6 +84,7 @@
+
+ #ifdef MOZ_WIDGET_GTK2
+ #include "nsIGnomeVFSService.h"
++#include "nsKDEUtils.h"
+ #endif
+
+ #include "nsNativeCharsetUtils.h"
+@@ -1666,16 +1667,13 @@ NS_IMETHODIMP
+ nsLocalFile::Reveal()
+ {
+ #ifdef MOZ_WIDGET_GTK2
+- nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+- if (!vfs)
+- return NS_ERROR_FAILURE;
+-
++ nsCAutoString url;
+ PRBool isDirectory;
+ if (NS_FAILED(IsDirectory(&isDirectory)))
+ return NS_ERROR_FAILURE;
+
+ if (isDirectory) {
+- return vfs->ShowURIForInput(mPath);
++ url = mPath;
+ } else {
+ nsCOMPtr<nsIFile> parentDir;
+ nsCAutoString dirPath;
+@@ -1684,8 +1682,21 @@ nsLocalFile::Reveal()
+ if (NS_FAILED(parentDir->GetNativePath(dirPath)))
+ return NS_ERROR_FAILURE;
+
+- return vfs->ShowURIForInput(dirPath);
++ url = dirPath;
+ }
++
++ if( nsKDEUtils::kdeSupport()) {
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
++ command.AppendCString( url );
++ return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
++ }
++
++ nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
++ if (!vfs)
++ return NS_ERROR_FAILURE;
++ return vfs->ShowURIForInput(url);
++
+ #else
+ return NS_ERROR_FAILURE;
+ #endif
+@@ -1695,6 +1706,13 @@ NS_IMETHODIMP
+ nsLocalFile::Launch()
+ {
+ #ifdef MOZ_WIDGET_GTK2
++ if( nsKDEUtils::kdeSupport()) {
++ nsCStringArray command;
++ command.AppendCString( NS_LITERAL_CSTRING( "OPEN" ));
++ command.AppendCString( mPath );
++ return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE;
++ }
++
+ nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+ if (!vfs)
+ return NS_ERROR_FAILURE;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/old/gecko-lockdown.patch Sun Nov 29 14:10:26 2009 +0100
@@ -0,0 +1,319 @@
+From: Robert O'Callahan
+Subject: Lockdown feature for Gecko
+References:
+
+
+Index: extensions/cookie/nsCookiePermission.cpp
+===================================================================
+--- extensions/cookie/nsCookiePermission.cpp.orig
++++ extensions/cookie/nsCookiePermission.cpp
+@@ -86,6 +86,7 @@ static const char kCookiesPrefsMigrated[
+ // obsolete pref names for migration
+ static const char kCookiesLifetimeEnabled[] = "network.cookie.lifetime.enabled";
+ static const char kCookiesLifetimeBehavior[] = "network.cookie.lifetime.behavior";
++static const char kCookiesHonorExceptions[] = "network.cookie.honorExceptions";
+ static const char kCookiesAskPermission[] = "network.cookie.warnAboutCookies";
+
+ static const char kPermissionType[] = "cookie";
+@@ -125,6 +126,7 @@ nsCookiePermission::Init()
+ prefBranch->AddObserver(kCookiesLifetimePolicy, this, PR_FALSE);
+ prefBranch->AddObserver(kCookiesLifetimeDays, this, PR_FALSE);
+ prefBranch->AddObserver(kCookiesAlwaysAcceptSession, this, PR_FALSE);
++ prefBranch->AddObserver(kCookiesHonorExceptions, this, PR_FALSE);
+ #ifdef MOZ_MAIL_NEWS
+ prefBranch->AddObserver(kCookiesDisabledForMailNews, this, PR_FALSE);
+ #endif
+@@ -182,6 +184,10 @@ nsCookiePermission::PrefChanged(nsIPrefB
+ NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesAlwaysAcceptSession, &val)))
+ mCookiesAlwaysAcceptSession = val;
+
++ if (PREF_CHANGED(kCookiesHonorExceptions) &&
++ NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesHonorExceptions, &val)))
++ mCookiesHonorExceptions = val;
++
+ #ifdef MOZ_MAIL_NEWS
+ if (PREF_CHANGED(kCookiesDisabledForMailNews) &&
+ NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesDisabledForMailNews, &val)))
+@@ -232,6 +238,11 @@ nsCookiePermission::CanAccess(nsIURI
+ #endif // MOZ_MAIL_NEWS
+
+ // finally, check with permission manager...
++ if (!mCookiesHonorExceptions) {
++ *aResult = ACCESS_DEFAULT;
++ return NS_OK;
++ }
++
+ nsresult rv = mPermMgr->TestPermission(aURI, kPermissionType, (PRUint32 *) aResult);
+ if (NS_SUCCEEDED(rv)) {
+ switch (*aResult) {
+Index: extensions/cookie/nsCookiePermission.h
+===================================================================
+--- extensions/cookie/nsCookiePermission.h.orig
++++ extensions/cookie/nsCookiePermission.h
+@@ -61,6 +61,7 @@ public:
+ #ifdef MOZ_MAIL_NEWS
+ , mCookiesDisabledForMailNews(PR_TRUE)
+ #endif
++ , mCookiesHonorExceptions(PR_TRUE)
+ {}
+ virtual ~nsCookiePermission() {}
+
+@@ -76,7 +77,7 @@ private:
+ #ifdef MOZ_MAIL_NEWS
+ PRPackedBool mCookiesDisabledForMailNews;
+ #endif
+-
++ PRPackedBool mCookiesHonorExceptions;
+ };
+
+ // {EF565D0A-AB9A-4A13-9160-0644CDFD859A}
+Index: extensions/permissions/nsContentBlocker.cpp
+===================================================================
+--- extensions/permissions/nsContentBlocker.cpp.orig
++++ extensions/permissions/nsContentBlocker.cpp
+@@ -76,6 +76,7 @@ NS_IMPL_ISUPPORTS3(nsContentBlocker,
+ nsContentBlocker::nsContentBlocker()
+ {
+ memset(mBehaviorPref, BEHAVIOR_ACCEPT, NUMBER_OF_TYPES);
++ memset(mHonorExceptions, PR_TRUE, NUMBER_OF_TYPES);
+ }
+
+ nsresult
+@@ -92,6 +93,11 @@ nsContentBlocker::Init()
+ rv = prefService->GetBranch("permissions.default.", getter_AddRefs(prefBranch));
+ NS_ENSURE_SUCCESS(rv, rv);
+
++ nsCOMPtr<nsIPrefBranch> honorExceptionsPrefBranch;
++ rv = prefService->GetBranch("permissions.honorExceptions.",
++ getter_AddRefs(honorExceptionsPrefBranch));
++ NS_ENSURE_SUCCESS(rv, rv);
++
+ // Migrate old image blocker pref
+ nsCOMPtr<nsIPrefBranch> oldPrefBranch;
+ oldPrefBranch = do_QueryInterface(prefService);
+@@ -121,8 +127,15 @@ nsContentBlocker::Init()
+ mPrefBranchInternal = do_QueryInterface(prefBranch, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
++ mHonorExceptionsPrefBranchInternal =
++ do_QueryInterface(honorExceptionsPrefBranch, &rv);
++ NS_ENSURE_SUCCESS(rv, rv);
++
+ rv = mPrefBranchInternal->AddObserver("", this, PR_TRUE);
+- PrefChanged(prefBranch, nsnull);
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ rv = mHonorExceptionsPrefBranchInternal->AddObserver("", this, PR_TRUE);
++ PrefChanged(nsnull);
+
+ return rv;
+ }
+@@ -131,19 +144,22 @@ nsContentBlocker::Init()
+ #define LIMIT(x, low, high, default) ((x) >= (low) && (x) <= (high) ? (x) : (default))
+
+ void
+-nsContentBlocker::PrefChanged(nsIPrefBranch *aPrefBranch,
+- const char *aPref)
++nsContentBlocker::PrefChanged(const char *aPref)
+ {
+- PRInt32 val;
+-
+-#define PREF_CHANGED(_P) (!aPref || !strcmp(aPref, _P))
+-
+- for(PRUint32 i = 0; i < NUMBER_OF_TYPES; ++i) {
+- if (PREF_CHANGED(kTypeString[i]) &&
+- NS_SUCCEEDED(aPrefBranch->GetIntPref(kTypeString[i], &val)))
+- mBehaviorPref[i] = LIMIT(val, 1, 3, 1);
++ for (PRUint32 i = 0; i < NUMBER_OF_TYPES; ++i) {
++ if (!aPref || !strcmp(kTypeString[i], aPref)) {
++ PRInt32 val;
++ PRBool b;
++ if (mPrefBranchInternal &&
++ NS_SUCCEEDED(mPrefBranchInternal->GetIntPref(kTypeString[i], &val))) {
++ mBehaviorPref[i] = LIMIT(val, 1, 3, 1);
++ }
++ if (mHonorExceptionsPrefBranchInternal &&
++ NS_SUCCEEDED(mHonorExceptionsPrefBranchInternal->GetBoolPref(kTypeString[i], &b))) {
++ mHonorExceptions[i] = b;
++ }
++ }
+ }
+-
+ }
+
+ // nsIContentPolicy Implementation
+@@ -268,11 +284,13 @@ nsContentBlocker::TestPermission(nsIURI
+ // default prefs.
+ // Don't forget the aContentType ranges from 1..8, while the
+ // array is indexed 0..7
+- PRUint32 permission;
+- nsresult rv = mPermissionManager->TestPermission(aCurrentURI,
+- kTypeString[aContentType - 1],
+- &permission);
+- NS_ENSURE_SUCCESS(rv, rv);
++ PRUint32 permission = 0;
++ if (mHonorExceptions[aContentType - 1]) {
++ nsresult rv = mPermissionManager->TestPermission(aCurrentURI,
++ kTypeString[aContentType - 1],
++ &permission);
++ NS_ENSURE_SUCCESS(rv, rv);
++ }
+
+ // If there is nothing on the list, use the default.
+ if (!permission) {
+@@ -298,7 +316,7 @@ nsContentBlocker::TestPermission(nsIURI
+ return NS_OK;
+
+ PRBool trustedSource = PR_FALSE;
+- rv = aFirstURI->SchemeIs("chrome", &trustedSource);
++ nsresult rv = aFirstURI->SchemeIs("chrome", &trustedSource);
+ NS_ENSURE_SUCCESS(rv,rv);
+ if (!trustedSource) {
+ rv = aFirstURI->SchemeIs("resource", &trustedSource);
+@@ -363,8 +381,6 @@ nsContentBlocker::Observe(nsISupports
+ {
+ NS_ASSERTION(!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic),
+ "unexpected topic - we only deal with pref changes!");
+-
+- if (mPrefBranchInternal)
+- PrefChanged(mPrefBranchInternal, NS_LossyConvertUTF16toASCII(aData).get());
++ PrefChanged(NS_LossyConvertUTF16toASCII(aData).get());
+ return NS_OK;
+ }
+Index: extensions/permissions/nsContentBlocker.h
+===================================================================
+--- extensions/permissions/nsContentBlocker.h.orig
++++ extensions/permissions/nsContentBlocker.h
+@@ -66,7 +66,7 @@ public:
+ private:
+ ~nsContentBlocker() {}
+
+- void PrefChanged(nsIPrefBranch *, const char *);
++ void PrefChanged(const char *);
+ nsresult TestPermission(nsIURI *aCurrentURI,
+ nsIURI *aFirstURI,
+ PRInt32 aContentType,
+@@ -75,7 +75,9 @@ private:
+
+ nsCOMPtr<nsIPermissionManager> mPermissionManager;
+ nsCOMPtr<nsIPrefBranch2> mPrefBranchInternal;
++ nsCOMPtr<nsIPrefBranch2> mHonorExceptionsPrefBranchInternal;
+ PRUint8 mBehaviorPref[NUMBER_OF_TYPES];
++ PRPackedBool mHonorExceptions[NUMBER_OF_TYPES];
+ };
+
+ #define NS_CONTENTBLOCKER_CID \
+Index: modules/libpref/src/init/all.js
+===================================================================
+--- modules/libpref/src/init/all.js.orig
++++ modules/libpref/src/init/all.js
+@@ -798,6 +798,7 @@ pref("network.automatic-ntlm-auth.truste
+ pref("network.ntlm.send-lm-response", false);
+
+ pref("permissions.default.image", 1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
++pref("permissions.honorExceptions.image", true);
+
+ #ifndef XP_MACOSX
+ #ifdef XP_UNIX
+@@ -825,6 +826,7 @@ pref("network.proxy.no_proxies_on",
+ pref("network.proxy.failover_timeout", 1800); // 30 minutes
+ pref("network.online", true); //online/offline
+ pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
++pref("network.cookie.honorExceptions", true);
+ pref("network.cookie.disableCookieForMailNews", true); // disable all cookies for mail
+ pref("network.cookie.lifetimePolicy", 0); // accept normally, 1-askBeforeAccepting, 2-acceptForSession,3-acceptForNDays
+ pref("network.cookie.alwaysAcceptSessionCookies", false);
+Index: widget/src/gtk2/nsWindow.cpp
+===================================================================
+--- widget/src/gtk2/nsWindow.cpp.orig
++++ widget/src/gtk2/nsWindow.cpp
+@@ -81,6 +81,7 @@
+ #include "nsIServiceManager.h"
+ #include "nsIStringBundle.h"
+ #include "nsGfxCIID.h"
++#include "nsIPrefService.h"
+
+ #ifdef ACCESSIBILITY
+ #include "nsIAccessibilityService.h"
+@@ -91,7 +92,6 @@
+ static PRBool sAccessibilityChecked = PR_FALSE;
+ /* static */
+ PRBool nsWindow::sAccessibilityEnabled = PR_FALSE;
+-static const char sSysPrefService [] = "@mozilla.org/system-preference-service;1";
+ static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
+ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility";
+ #endif
+@@ -3992,18 +3992,18 @@ nsWindow::NativeCreate(nsIWidget
+ sAccessibilityEnabled = atoi(envValue) != 0;
+ LOG(("Accessibility Env %s=%s\n", sAccEnv, envValue));
+ }
+- //check gconf-2 setting
++ //check preference setting
+ else {
+- nsCOMPtr<nsIPrefBranch> sysPrefService =
+- do_GetService(sSysPrefService, &rv);
+- if (NS_SUCCEEDED(rv) && sysPrefService) {
+-
+- // do the work to get gconf setting.
+- // will be done soon later.
+- sysPrefService->GetBoolPref(sAccessibilityKey,
++ nsCOMPtr<nsIPrefService> prefService =
++ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
++ if (NS_SUCCEEDED(rv) && prefService) {
++ nsCOMPtr<nsIPrefBranch> prefBranch;
++ rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch));
++ if (NS_SUCCEEDED(rv) && prefBranch) {
++ prefBranch->GetBoolPref(sAccessibilityKey,
+ &sAccessibilityEnabled);
++ }
+ }
+-
+ }
+ }
+ if (sAccessibilityEnabled) {
+Index: xpinstall/src/nsXPInstallManager.cpp
+===================================================================
+--- xpinstall/src/nsXPInstallManager.cpp.orig
++++ xpinstall/src/nsXPInstallManager.cpp
+@@ -290,6 +290,7 @@ nsXPInstallManager::InitManagerInternal(
+ //-----------------------------------------------------
+ // Get permission to install
+ //-----------------------------------------------------
++ nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID));
+
+ #ifdef ENABLE_SKIN_SIMPLE_INSTALLATION_UI
+ if ( mChromeType == CHROME_SKIN )
+@@ -299,17 +300,26 @@ nsXPInstallManager::InitManagerInternal(
+
+ // skins get a simpler/friendlier dialog
+ // XXX currently not embeddable
+- OKtoInstall = ConfirmChromeInstall( mParentWindow, packageList );
++ PRBool themesDisabled = PR_FALSE;
++ if (pref)
++ pref->GetBoolPref("config.lockdown.disable_themes", &themesDisabled);
++ OKtoInstall = !themesDisabled &&
++ ConfirmChromeInstall( mParentWindow, packageList );
+ }
+ else
+ {
+ #endif
+- rv = dlgSvc->ConfirmInstall( mParentWindow,
+- packageList,
+- numStrings,
+- &OKtoInstall );
+- if (NS_FAILED(rv))
+- OKtoInstall = PR_FALSE;
++ PRBool extensionsDisabled = PR_FALSE;
++ if (pref)
++ pref->GetBoolPref("config.lockdown.disable_extensions", &extensionsDisabled);
++ if (!extensionsDisabled) {
++ rv = dlgSvc->ConfirmInstall( mParentWindow,
++ packageList,
++ numStrings,
++ &OKtoInstall );
++ if (NS_FAILED(rv))
++ OKtoInstall = PR_FALSE;
++ }
+ #ifdef ENABLE_SKIN_SIMPLE_INSTALLATION_UI
+ }
+ #endif