Allow xdg-settings to set the default OS handler for url protocols.

This is used by the registerProtocolHandler feature to set Chrome as the default OS
application for protocols which have default handlers in Chrome.

BUG=83557

Review URL: http://codereview.chromium.org/7433003

git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/xdg-utils@93286 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
diff --git a/scripts/desc/xdg-settings.xml b/scripts/desc/xdg-settings.xml
index afcdeba..f9ef291 100644
--- a/scripts/desc/xdg-settings.xml
+++ b/scripts/desc/xdg-settings.xml
@@ -8,7 +8,7 @@
   <refentryinfo>
     <title>xdg-settings Manual</title>
     <copyright>
-      <year>2009</year>
+      <year>2009-2011</year>
     </copyright>
     <author>
       <firstname>Mike</firstname>
@@ -40,6 +40,9 @@
 	<option>property</option>
       </group>
       <group choice="opt">
+        <option>subproperty</option>
+      </group>
+      <group choice="opt">
 	<option>value</option>
       </group>
     </cmdsynopsis>
@@ -108,6 +111,19 @@
       </varlistentry>
     </variablelist>
   </refsect1>
+  <refsect1 id="properties">
+    <title>Properties</title>
+    <para>
+      When using xdg-settings to get, check or set a destkop setting, properties
+      and possibly sub-properties are used to specify the setting to be changed.
+    </para>
+    <para>
+      Some properties (such as default-web-browser) fully describe the setting
+      to be changed. Other properties (such as default-url-scheme-handler) require
+      more information (in this case the actual scheme to set the default handler
+      for) which must be provided in a sub-property.
+    </para>
+  </refsect1>
   <refsect1 id="exitcodes">
     <title>Exit Codes</title>
     <para>
@@ -171,5 +187,11 @@
         xdg-settings set default-web-browser google-chrome.desktop
       </programlisting>
     </para>
+    <para>
+      Set the default mailto URL scheme handler to be evolution.desktop
+      <programlisting>
+        xdg-settings set default-url-scheme-handler mailto evolution.desktop
+      </programlisting>
+    </para>
   </refsect1>
 </refentry>
diff --git a/scripts/html/xdg-settings.html b/scripts/html/xdg-settings.html
index acb6389..380ad2a 100644
--- a/scripts/html/xdg-settings.html
+++ b/scripts/html/xdg-settings.html
@@ -1,4 +1,4 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>xdg-settings</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" title="xdg-settings"><a name="xdg-settings"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>xdg-settings &#8212; get various settings from the desktop environment</p></div><div class="refsynopsisdiv" title="Synopsis"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">xdg-settings</code>  { <code class="option"><em class="replaceable"><code>get</code></em></code>  |   <code class="option"><em class="replaceable"><code>check</code></em></code>  |   <code class="option"><em class="replaceable"><code>set</code></em></code> } {<code class="option">property</code>} [<code class="option">value</code>]</p></div><div class="cmdsynopsis"><p><code class="command">xdg-settings</code>  { <code class="option">--help</code>  |   <code class="option">--list</code>  |   <code class="option">--manual</code>  |   <code class="option">--version</code> }</p></div></div><div class="refsect1" title="Description"><a name="description"></a><h2>Description</h2><p>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>xdg-settings</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" title="xdg-settings"><a name="xdg-settings"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>xdg-settings &#8212; get various settings from the desktop environment</p></div><div class="refsynopsisdiv" title="Synopsis"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">xdg-settings</code>  { <code class="option"><em class="replaceable"><code>get</code></em></code>  |   <code class="option"><em class="replaceable"><code>check</code></em></code>  |   <code class="option"><em class="replaceable"><code>set</code></em></code> } {<code class="option">property</code>} [<code class="option">subproperty</code>] [<code class="option">value</code>]</p></div><div class="cmdsynopsis"><p><code class="command">xdg-settings</code>  { <code class="option">--help</code>  |   <code class="option">--list</code>  |   <code class="option">--manual</code>  |   <code class="option">--version</code> }</p></div></div><div class="refsect1" title="Description"><a name="description"></a><h2>Description</h2><p>
       xdg-settings gets various settings from the desktop environment.
       For instance, desktop environments often provide proxy configuration
       and default web browser settings. Using xdg-settings these parameters
@@ -15,7 +15,15 @@
             Show this manualpage.
           </dd><dt><span class="term"><code class="option">--version</code></span></dt><dd>
             Show the xdg-utils version information.
-          </dd></dl></div></div><div class="refsect1" title="Exit Codes"><a name="exitcodes"></a><h2>Exit Codes</h2><p>
+          </dd></dl></div></div><div class="refsect1" title="Properties"><a name="properties"></a><h2>Properties</h2><p>
+      When using xdg-settings to get, check or set a destkop setting, properties
+      and possibly sub-properties are used to specify the setting to be changed.
+    </p><p>
+      Some properties (such as default-web-browser) fully describe the setting
+      to be changed. Other properties (such as default-url-scheme-handler) require
+      more information (in this case the actual scheme to set the default handler
+      for) which must be provided in a sub-property.
+    </p></div><div class="refsect1" title="Exit Codes"><a name="exitcodes"></a><h2>Exit Codes</h2><p>
       An exit code of 0 indicates success while a non-zero exit code
       indicates failure. The following failure codes can be returned:
     </p><div class="variablelist"><dl><dt><span class="term"><code class="option">1</code></span></dt><dd>
@@ -43,4 +51,9 @@
       </p><pre class="programlisting">
         xdg-settings set default-web-browser google-chrome.desktop
       </pre><p>
+    </p><p>
+      Set the default mailto URL scheme handler to be evolution.desktop
+      </p><pre class="programlisting">
+        xdg-settings set default-url-scheme-handler mailto evolution.desktop
+      </pre><p>
     </p></div></div></body></html>
diff --git a/scripts/man/xdg-settings.1 b/scripts/man/xdg-settings.1
index ddc0113..d02fa2b 100644
--- a/scripts/man/xdg-settings.1
+++ b/scripts/man/xdg-settings.1
@@ -2,12 +2,12 @@
 .\"     Title: xdg-settings
 .\"    Author: Mike Mammarella
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 12/31/2010
+.\"      Date: 07/20/2011
 .\"    Manual: xdg-settings Manual
 .\"    Source: [FIXME: source]
 .\"  Language: English
 .\"
-.TH "XDG\-SETTINGS" "1" "12/31/2010" "[FIXME: source]" "xdg-settings Manual"
+.TH "XDG\-SETTINGS" "1" "07/20/2011" "[FIXME: source]" "xdg-settings Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -31,7 +31,7 @@
 xdg-settings \- get various settings from the desktop environment
 .SH "SYNOPSIS"
 .HP \w'\fBxdg\-settings\fR\ 'u
-\fBxdg\-settings\fR {\fB\fIget\fR\fR | \fB\fIcheck\fR\fR | \fB\fIset\fR\fR} {\fBproperty\fR} [\fBvalue\fR]
+\fBxdg\-settings\fR {\fB\fIget\fR\fR | \fB\fIcheck\fR\fR | \fB\fIset\fR\fR} {\fBproperty\fR} [\fBsubproperty\fR] [\fBvalue\fR]
 .HP \w'\fBxdg\-settings\fR\ 'u
 \fBxdg\-settings\fR {\fB\-\-help\fR | \fB\-\-list\fR | \fB\-\-manual\fR | \fB\-\-version\fR}
 .SH "DESCRIPTION"
@@ -60,6 +60,11 @@
 .RS 4
 Show the xdg\-utils version information\&.
 .RE
+.SH "PROPERTIES"
+.PP
+When using xdg\-settings to get, check or set a destkop setting, properties and possibly sub\-properties are used to specify the setting to be changed\&.
+.PP
+Some properties (such as default\-web\-browser) fully describe the setting to be changed\&. Other properties (such as default\-url\-scheme\-handler) require more information (in this case the actual scheme to set the default handler for) which must be provided in a sub\-property\&.
 .SH "EXIT CODES"
 .PP
 An exit code of 0 indicates success while a non\-zero exit code indicates failure\&. The following failure codes can be returned:
@@ -123,6 +128,19 @@
 .if n \{\
 .RE
 .\}
+.PP
+Set the default mailto URL scheme handler to be evolution\&.desktop
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+        xdg\-settings set default\-url\-scheme\-handler mailto evolution\&.desktop
+      
+.fi
+.if n \{\
+.RE
+.\}
 .sp
 .SH "AUTHOR"
 .PP
@@ -132,5 +150,5 @@
 .RE
 .SH "COPYRIGHT"
 .br
-Copyright \(co 2009
+Copyright \(co 2009-2011
 .br
diff --git a/scripts/xdg-settings b/scripts/xdg-settings
index 18515f2..e101297 100755
--- a/scripts/xdg-settings
+++ b/scripts/xdg-settings
@@ -39,7 +39,7 @@
 
 Synopsis
 
-xdg-settings { get | check | set } {property} [value]
+xdg-settings { get | check | set } {property} [subproperty] [value]
 
 xdg-settings { --help | --list | --manual | --version }
 
@@ -65,6 +65,16 @@
 --version
     Show the xdg-utils version information.
 
+Properties
+
+When using xdg-settings to get, check or set a destkop setting, properties and
+possibly sub-properties are used to specify the setting to be changed.
+
+Some properties (such as default-web-browser) fully describe the setting to be
+changed. Other properties (such as default-url-scheme-handler) require more
+information (in this case the actual scheme to set the default handler for)
+which must be provided in a sub-property.
+
 Exit Codes
 
 An exit code of 0 indicates success while a non-zero exit code indicates
@@ -98,6 +108,11 @@
         xdg-settings set default-web-browser google-chrome.desktop
 
 
+Set the default mailto URL scheme handler to be evolution.desktop
+
+        xdg-settings set default-url-scheme-handler mailto evolution.desktop
+
+
 _MANUALPAGE
 }
 
@@ -108,7 +123,7 @@
 
 Synopsis
 
-xdg-settings { get | check | set } {property} [value]
+xdg-settings { get | check | set } {property} [subproperty] [value]
 
 xdg-settings { --help | --list | --manual | --version }
 
@@ -558,6 +573,30 @@
 }
 
 # }}} MIME utilities
+# {{{ KDE utilities
+
+# Reads the KDE configuration setting, compensating for a bug in some versions of kreadconfig.
+read_kde_config()
+{
+    configfile="$1"
+    configsection="$2"
+    configkey="$3"
+    application="`kreadconfig --file $configfile --group $configsection --key $configkey`"
+    if [ x"$application" != x ]; then
+        echo "$application"
+    else
+        # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so
+        # check by hand if it didn't find anything (oddly kwriteconfig works
+        # fine though).
+        configfile_dir=`kde${KDE_SESSION_VERSION}-config --path config  | cut -d ':' -f 1`
+        configfile_path="$configfile_dir/$configfile"
+        [ ! -f "$configfile_path" ] && return
+        # This will only take the first value if there is more than one.
+        grep "^$configkey"'\[$[^]=]*\]=' "$configfile_path" | head -n 1 | cut -d= -f 2-
+    fi
+}
+
+# }}} KDE utilities
 # {{{ KDE
 
 # Resolves the KDE browser setting to a binary: if prefixed with !, simply removes it;
@@ -591,22 +630,9 @@
     esac
 }
 
-# Reads the KDE browser setting, compensating for a bug in some versions of kreadconfig.
 read_kde_browser()
 {
-    browser="`kreadconfig --file kdeglobals --group General --key BrowserApplication`"
-    if [ x"$browser" != x ]; then
-        echo "$browser"
-    else
-        # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so
-        # check by hand if it didn't find anything (oddly kwriteconfig works
-        # fine though).
-        kdeglobals_dir=`kde${KDE_SESSION_VERSION}-config --path config  | cut -d ':' -f 1`
-        kdeglobals="$kdeglobals_dir/kdeglobals"
-        [ ! -f "$kdeglobals" ] && return
-        # This will only take the first value if there is more than one.
-        grep '^BrowserApplication\[$[^]=]*\]=' "$kdeglobals" | head -n 1 | cut -d= -f 2-
-    fi
+    read_kde_config kdeglobals General BrowserApplication
 }
 
 get_browser_kde()
@@ -862,6 +888,168 @@
 # }}} xfce
 # }}} default browser
 
+# {{{ default url scheme handler
+
+exit_unimplemented_default_handler()
+{
+    exit_failure_operation_impossible "default-url-scheme-handler not implemented for $DE"
+}
+
+# {{{ KDE
+
+# Recent versions of KDE support default scheme handler applications using the
+# mime type of x-scheme-handler/scheme. Older versions will not support this
+# but do have support for setting a default mail handler. There is also a
+# system in KDE where .protocol files can be used, however this is not
+# supported by this script. When reading a scheme handler we will use the
+# default mail handler for the mailto scheme, otherwise we will use the mime
+# type x-scheme-handler/scheme.
+
+get_url_scheme_handler_kde()
+{
+    if [ "$1" = "mailto" ]; then
+        handler="`read_kde_config emaildefaults PROFILE_Default EmailClient | first_word`"
+        echo "handler is $handler"
+        if [ x"$handler" != x ]; then
+            binary_to_desktop_file "$handler"
+        else
+            get_browser_mime "x-scheme-handler/$1"
+        fi
+    else 
+        get_browser_mime "x-scheme-handler/$1"
+    fi
+}
+
+check_url_scheme_handler_kde()
+{
+    check="`desktop_file_to_binary "$2"`"
+    if [ -z "$check" ]; then
+        echo no
+        exit_success
+    fi
+    if [ x"$1" = "mailto" ]; then
+        binary="`read_kde_config emaildefaults PROFILE_Default EmailClient`"
+        if [ x"$binary" != x"$check" ]; then
+            echo no
+            exit_success
+        fi
+    fi
+    handler="`get_browser_mime x-scheme-handler/$1`"
+    binary="`desktop_file_to_binary "$handler"`"
+    if [ x"$binary" != x"$check" ]; then
+        echo no
+        exit_success
+    fi
+    echo yes
+    exit_success
+}
+
+set_url_scheme_handler_kde()
+{
+    set_browser_mime "$2" "x-scheme-handler/$1" || return
+    if [ "$1" = "mailto" ]; then
+        binary="`desktop_file_to_binary "$2"`"
+        kwriteconfig --file emaildefaults --group PROFILE_Default --key EmailClient "$binary"
+    fi
+}
+
+# }}} KDE
+# {{{ GNOME
+
+get_url_scheme_handler_gnome()
+{
+    binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`"
+    if [ x"$binary" != x"" ]; then
+        # gconftool gives the binary (maybe with %s etc. afterward),
+        # but we want the desktop file name, not the binary. So, we
+        # have to find the desktop file to which it corresponds.
+        desktop="`binary_to_desktop_file "$binary"`"
+        basename "$desktop"
+    fi
+}
+
+check_url_scheme_handler_gnome()
+{
+    check="`desktop_file_to_binary "$2"`"
+    if [ -z "$check" ]; then
+        echo no
+        exit_success
+    fi
+    binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`"
+    if [ x"$binary" != x"$check" ]; then
+        echo no
+        exit_success
+    fi
+    echo yes
+    exit_success
+}
+
+set_url_scheme_handler_gnome()
+{
+    binary="`desktop_file_to_binary "$2"`"
+    [ "$binary" ] || exit_failure_file_missing
+
+    gconftool-2 --type string --set /desktop/gnome/url-handlers/$1/command "$binary %s"
+    gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/needs_terminal false
+    gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/enabled true
+}
+
+# }}} GNOME
+# {{{ GNOME 3.x
+
+get_url_scheme_handler_gnome3()
+{
+    get_browser_mime "x-scheme-handler/$1"
+}
+
+check_url_scheme_handler_gnome3()
+{
+    desktop="$2"
+    check="`desktop_file_to_binary "$2"`"
+    if [ -z "$check" ]; then
+        echo no
+        exit_success
+    fi
+    browser="`get_browser_mime "x-scheme-handler/$1"`"
+    if [ x"$browser" != x"$desktop" ]; then
+        echo no
+        exit_success
+    fi
+    echo yes
+    exit_success
+}
+
+set_url_scheme_handler_gnome3()
+{
+    binary="`desktop_file_to_binary "$2"`"
+    [ "$binary" ] || exit_failure_file_missing
+    set_browser_mime "$2" || return
+
+    # Set the default browser.
+    set_browser_mime "$2" "x-scheme-handler/$1" || return
+}
+
+# }}} GNOME 3.x
+# {{{ xfce
+
+get_url_scheme_handler_xfce()
+{
+    exit_unimplemented_default_handler "$1"
+}
+
+check_url_scheme_handler_xfce()
+{
+    exit_unimplemented_default_handler "$1"
+}
+
+set_url_scheme_handler_xfce()
+{
+    exit_unimplemented_default_handler "$1"
+}
+
+# }}} xfce
+# }}} default protocol handler
+
 dispatch_specific()
 {
     # The PROP comments in this function are used to generate the output of
@@ -873,6 +1061,10 @@
             get_browser_$DE
             ;;
 
+          default-url-scheme-handler) # PROP:    Default handler for URL scheme
+            get_url_scheme_handler_$DE "$1"
+            ;;
+
           *)
             exit_failure_syntax
             ;;
@@ -884,18 +1076,29 @@
             check_browser_$DE "$1"
             ;;
 
+          default-url-scheme-handler)
+            check_desktop_filename "$2"
+            check_url_scheme_handler_$DE "$1" "$2"
+            ;;
+
           *)
             exit_failure_syntax
             ;;
         esac
     else # set
-        [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument"
         case "$parm" in
           default-web-browser)
+	    [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument"
             check_desktop_filename "$1"
             set_browser_$DE "$1"
             ;;
 
+          default-url-scheme-handler)
+	    [ $# -eq 2 ] || exit_failure_syntax "unexpected/missing argument"
+            check_desktop_filename "$2"
+            set_url_scheme_handler_$DE "$1" "$2"
+            ;;
+
           *)
             exit_failure_syntax
             ;;
diff --git a/scripts/xdg-settings.in b/scripts/xdg-settings.in
index 8108b12..a503e2b 100644
--- a/scripts/xdg-settings.in
+++ b/scripts/xdg-settings.in
@@ -138,6 +138,30 @@
 }
 
 # }}} MIME utilities
+# {{{ KDE utilities
+
+# Reads the KDE configuration setting, compensating for a bug in some versions of kreadconfig.
+read_kde_config()
+{
+    configfile="$1"
+    configsection="$2"
+    configkey="$3"
+    application="`kreadconfig --file $configfile --group $configsection --key $configkey`"
+    if [ x"$application" != x ]; then
+        echo "$application"
+    else
+        # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so
+        # check by hand if it didn't find anything (oddly kwriteconfig works
+        # fine though).
+        configfile_dir=`kde${KDE_SESSION_VERSION}-config --path config  | cut -d ':' -f 1`
+        configfile_path="$configfile_dir/$configfile"
+        [ ! -f "$configfile_path" ] && return
+        # This will only take the first value if there is more than one.
+        grep "^$configkey"'\[$[^]=]*\]=' "$configfile_path" | head -n 1 | cut -d= -f 2-
+    fi
+}
+
+# }}} KDE utilities
 # {{{ KDE
 
 # Resolves the KDE browser setting to a binary: if prefixed with !, simply removes it;
@@ -171,22 +195,9 @@
     esac
 }
 
-# Reads the KDE browser setting, compensating for a bug in some versions of kreadconfig.
 read_kde_browser()
 {
-    browser="`kreadconfig --file kdeglobals --group General --key BrowserApplication`"
-    if [ x"$browser" != x ]; then
-        echo "$browser"
-    else
-        # kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so
-        # check by hand if it didn't find anything (oddly kwriteconfig works
-        # fine though).
-        kdeglobals_dir=`kde${KDE_SESSION_VERSION}-config --path config  | cut -d ':' -f 1`
-        kdeglobals="$kdeglobals_dir/kdeglobals"
-        [ ! -f "$kdeglobals" ] && return
-        # This will only take the first value if there is more than one.
-        grep '^BrowserApplication\[$[^]=]*\]=' "$kdeglobals" | head -n 1 | cut -d= -f 2-
-    fi
+    read_kde_config kdeglobals General BrowserApplication
 }
 
 get_browser_kde()
@@ -442,6 +453,168 @@
 # }}} xfce
 # }}} default browser
 
+# {{{ default url scheme handler
+
+exit_unimplemented_default_handler()
+{
+    exit_failure_operation_impossible "default-url-scheme-handler not implemented for $DE"
+}
+
+# {{{ KDE
+
+# Recent versions of KDE support default scheme handler applications using the
+# mime type of x-scheme-handler/scheme. Older versions will not support this
+# but do have support for setting a default mail handler. There is also a
+# system in KDE where .protocol files can be used, however this is not
+# supported by this script. When reading a scheme handler we will use the
+# default mail handler for the mailto scheme, otherwise we will use the mime
+# type x-scheme-handler/scheme.
+
+get_url_scheme_handler_kde()
+{
+    if [ "$1" = "mailto" ]; then
+        handler="`read_kde_config emaildefaults PROFILE_Default EmailClient | first_word`"
+        echo "handler is $handler"
+        if [ x"$handler" != x ]; then
+            binary_to_desktop_file "$handler"
+        else
+            get_browser_mime "x-scheme-handler/$1"
+        fi
+    else 
+        get_browser_mime "x-scheme-handler/$1"
+    fi
+}
+
+check_url_scheme_handler_kde()
+{
+    check="`desktop_file_to_binary "$2"`"
+    if [ -z "$check" ]; then
+        echo no
+        exit_success
+    fi
+    if [ x"$1" = "mailto" ]; then
+        binary="`read_kde_config emaildefaults PROFILE_Default EmailClient`"
+        if [ x"$binary" != x"$check" ]; then
+            echo no
+            exit_success
+        fi
+    fi
+    handler="`get_browser_mime x-scheme-handler/$1`"
+    binary="`desktop_file_to_binary "$handler"`"
+    if [ x"$binary" != x"$check" ]; then
+        echo no
+        exit_success
+    fi
+    echo yes
+    exit_success
+}
+
+set_url_scheme_handler_kde()
+{
+    set_browser_mime "$2" "x-scheme-handler/$1" || return
+    if [ "$1" = "mailto" ]; then
+        binary="`desktop_file_to_binary "$2"`"
+        kwriteconfig --file emaildefaults --group PROFILE_Default --key EmailClient "$binary"
+    fi
+}
+
+# }}} KDE
+# {{{ GNOME
+
+get_url_scheme_handler_gnome()
+{
+    binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`"
+    if [ x"$binary" != x"" ]; then
+        # gconftool gives the binary (maybe with %s etc. afterward),
+        # but we want the desktop file name, not the binary. So, we
+        # have to find the desktop file to which it corresponds.
+        desktop="`binary_to_desktop_file "$binary"`"
+        basename "$desktop"
+    fi
+}
+
+check_url_scheme_handler_gnome()
+{
+    check="`desktop_file_to_binary "$2"`"
+    if [ -z "$check" ]; then
+        echo no
+        exit_success
+    fi
+    binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`"
+    if [ x"$binary" != x"$check" ]; then
+        echo no
+        exit_success
+    fi
+    echo yes
+    exit_success
+}
+
+set_url_scheme_handler_gnome()
+{
+    binary="`desktop_file_to_binary "$2"`"
+    [ "$binary" ] || exit_failure_file_missing
+
+    gconftool-2 --type string --set /desktop/gnome/url-handlers/$1/command "$binary %s"
+    gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/needs_terminal false
+    gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/enabled true
+}
+
+# }}} GNOME
+# {{{ GNOME 3.x
+
+get_url_scheme_handler_gnome3()
+{
+    get_browser_mime "x-scheme-handler/$1"
+}
+
+check_url_scheme_handler_gnome3()
+{
+    desktop="$2"
+    check="`desktop_file_to_binary "$2"`"
+    if [ -z "$check" ]; then
+        echo no
+        exit_success
+    fi
+    browser="`get_browser_mime "x-scheme-handler/$1"`"
+    if [ x"$browser" != x"$desktop" ]; then
+        echo no
+        exit_success
+    fi
+    echo yes
+    exit_success
+}
+
+set_url_scheme_handler_gnome3()
+{
+    binary="`desktop_file_to_binary "$2"`"
+    [ "$binary" ] || exit_failure_file_missing
+    set_browser_mime "$2" || return
+
+    # Set the default browser.
+    set_browser_mime "$2" "x-scheme-handler/$1" || return
+}
+
+# }}} GNOME 3.x
+# {{{ xfce
+
+get_url_scheme_handler_xfce()
+{
+    exit_unimplemented_default_handler "$1"
+}
+
+check_url_scheme_handler_xfce()
+{
+    exit_unimplemented_default_handler "$1"
+}
+
+set_url_scheme_handler_xfce()
+{
+    exit_unimplemented_default_handler "$1"
+}
+
+# }}} xfce
+# }}} default protocol handler
+
 dispatch_specific()
 {
     # The PROP comments in this function are used to generate the output of
@@ -453,6 +626,10 @@
             get_browser_$DE
             ;;
 
+          default-url-scheme-handler) # PROP:    Default handler for URL scheme
+            get_url_scheme_handler_$DE "$1"
+            ;;
+
           *)
             exit_failure_syntax
             ;;
@@ -464,18 +641,29 @@
             check_browser_$DE "$1"
             ;;
 
+          default-url-scheme-handler)
+            check_desktop_filename "$2"
+            check_url_scheme_handler_$DE "$1" "$2"
+            ;;
+
           *)
             exit_failure_syntax
             ;;
         esac
     else # set
-        [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument"
         case "$parm" in
           default-web-browser)
+	    [ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument"
             check_desktop_filename "$1"
             set_browser_$DE "$1"
             ;;
 
+          default-url-scheme-handler)
+	    [ $# -eq 2 ] || exit_failure_syntax "unexpected/missing argument"
+            check_desktop_filename "$2"
+            set_url_scheme_handler_$DE "$1" "$2"
+            ;;
+
           *)
             exit_failure_syntax
             ;;