<commit_before><chapter>
  <title>Migrating from dbus-glib to GDBus</title>

  <section>
    <title>Conceptual differences</title>

    <para>
      The central concepts of D-Bus are modelled in a very similar way
      in dbus-glib and GDBus. Both have a objects representing connections,
      proxies and method invocations. But there are some important
      differences:
      <itemizedlist>
        <listitem><para>
          dbus-glib uses libdbus, GDBus doesn't. Instead, it relies on GIO
          streams as transport layer, and has its own implementation for the
          the D-Bus connection setup and authentication. Apart from using
          streams as transport, avoiding libdbus also lets GDBus avoid some
          thorny multithreading issues.
        </para></listitem>
        <listitem><para>
          dbus-glib uses the GObject type system for method arguments and
          return values, including a homegrown container specialization
          mechanism. GDBus relies uses the #GVariant type system which is
          explicitly designed to match D-Bus types.
        </para></listitem>
        <listitem><para>
          The typical way to export an object in dbus-glib involves generating
          glue code from XML introspection data using <command>dbus-binding-tool</command>. GDBus does not (yet?) use code generation; you are expected to
          embed the introspection data in your application code.
        </para></listitem>
      </itemizedlist>
    </para>
  </section>

  <section>
    <title>Dbus-glib API conversion</title>

    <table id="dbus-glib-vs-gdbus">
      <title>dbus-glib APIs and their GDBus counterparts</title>
      <tgroup cols="2">
        <thead>
           <row><entry>dbus-glib</entry><entry>GDBus</entry></row>
        </thead>
        <tbody>
          <row><entry>#DBusGConnection</entry><entry>#GDBusConnection</entry></row>
          <row><entry>#DBusGProxy</entry><entry>#GDBusProxy</entry></row>
          <row><entry>#DBusGMethodInvocation</entry><entry>#GDBusMethodInvocatoin</entry></row>
          <row><entry>dbus_g_bus_get()</entry><entry>g_bus_get_sync(), also see
               g_bus_get()</entry></row>
          <row><entry>dbus_g_proxy_new_for_name()</entry><entry>g_dbus_proxy_new_sync(), also see
               g_dbus_proxy_new()</entry></row>
          <row><entry>dbus_g_proxy_add_signal()</entry><entry>not needed, use the generic #GDBusProxy::g-signal</entry></row>
          <row><entry>dbus_g_proxy_connect_signal()</entry><entry>use g_signal_connect() with #GDBusProxy::g-signal</entry></row>
          <row><entry>dbus_g_connection_register_g_object()</entry><entry>g_dbus_connection_register_object()</entry></row>
          <row><entry>dbus_g_connection_unregister_g_object()</entry><entry>g_dbus_connection_unregister_object()</entry></row>
          <row><entry>dbus_g_object_type_install_info()</entry><entry>introspection data is installed while registering
               an object, see g_dbus_connection_register_object()</entry></row>
          <row><entry>dbus_g_proxy_begin_call()</entry><entry>g_dbus_proxy_call()</entry></row>
          <row><entry>dbus_g_proxy_end_call()</entry><entry>g_dbus_proxy_call_finish()</entry></row>
          <row><entry>dbus_g_proxy_call()</entry><entry>g_dbus_proxy_call_sync()</entry></row>
          <row><entry>dbus_g_error_domain_register()</entry><entry>g_dbus_error_register_error_domain()</entry></row>
          <row><entry>dbus_g_error_has_name()</entry><entry>no direct equivalent, see g_dbus_error_get_remote_error()</entry></row>
          <row><entry>dbus_g_method_return()</entry><entry>g_dbus_method_invocation_return_value()</entry></row>
          <row><entry>dbus_g_method_return_error()</entry><entry>g_dbus_method_invocation_return_error() and variants</entry></row>
          <row><entry>dbus_g_method_get_sender()</entry><entry>g_dbus_method_invocation_get_sender()</entry></row>
        </tbody>
      </tgroup>
    </table>
  </section>

  <section>
    <title>Owning bus names</title>
    <para>
      Using dbus-glib, you typically call RequestName manually
      to own a name, like in the following excerpt:
      <informalexample><programlisting><![CDATA[
  error = NULL;
  res = dbus_g_proxy_call (system_bus_proxy,
                           "RequestName",
                           &error,
                           G_TYPE_STRING, NAME_TO_CLAIM,
                           G_TYPE_UINT,   DBUS_NAME_FLAG_ALLOW_REPLACEMENT,
                           G_TYPE_INVALID,
                           G_TYPE_UINT,   &result,
                           G_TYPE_INVALID);
  if (!res)
    {
      if (error != NULL)
        {
          g_warning ("Failed to acquire %s: %s",
                     NAME_TO_CLAIM, error->message);
          g_error_free (error);
        }
      else
        {
          g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
        }
      goto out;
    }

  if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
    {
      if (error != NULL)
        {
          g_warning ("Failed to acquire %s: %s",
                     NAME_TO_CLAIM, error->message);
          g_error_free (error);
        }
      else
        {
          g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
        }
      exit (1);
    }

  dbus_g_proxy_add_signal (system_bus_proxy, "NameLost",
                           G_TYPE_STRING, G_TYPE_INVALID);
  dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost",
                               G_CALLBACK (on_name_lost), NULL, NULL);

  /* further setup ... */
]]>
      </programlisting></informalexample>
    </para>
    <para>
    While you can do things this way with GDBus too, using
    g_dbus_proxy_call_sync(), it is much nicer to use the high-level API
    for this:
    <informalexample><programlisting><![CDATA[
static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  /* further setup ... */
}

/* ... */

  owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
                             NAME_TO_CLAIM,
                             G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
                             on_bus_acquired,
                             on_name_acquired,
                             on_name_lost,
                             NULL,
                             NULL);

  g_main_loop_run (loop);

  g_bus_unown_name (owner_id);
]]>
    </programlisting></informalexample>
    Note that g_bus_own_name() works asynchronously and requires
    you to enter your mainloop to await the on_name_aquired()
    callback. Also note that in order to avoid race conditions (e.g.
    when your service is activated by a method call), you have to export
    your manager object <emphasis>before</emphasis> acquiring the
    name. The on_bus_acquired() callback is the right place to do
    such preparations.
    </para>
  </section>

  <section>
    <title>Creating proxies for well-known names</title>
    <para>
    </para>
  </section>
</chapter>
<commit_msg>Fix a typo<commit_after><chapter>
  <title>Migrating from dbus-glib to GDBus</title>

  <section>
    <title>Conceptual differences</title>

    <para>
      The central concepts of D-Bus are modelled in a very similar way
      in dbus-glib and GDBus. Both have a objects representing connections,
      proxies and method invocations. But there are some important
      differences:
      <itemizedlist>
        <listitem><para>
          dbus-glib uses libdbus, GDBus doesn't. Instead, it relies on GIO
          streams as transport layer, and has its own implementation for the
          the D-Bus connection setup and authentication. Apart from using
          streams as transport, avoiding libdbus also lets GDBus avoid some
          thorny multithreading issues.
        </para></listitem>
        <listitem><para>
          dbus-glib uses the GObject type system for method arguments and
          return values, including a homegrown container specialization
          mechanism. GDBus relies uses the #GVariant type system which is
          explicitly designed to match D-Bus types.
        </para></listitem>
        <listitem><para>
          The typical way to export an object in dbus-glib involves generating
          glue code from XML introspection data using <command>dbus-binding-tool</command>. GDBus does not (yet?) use code generation; you are expected to
          embed the introspection data in your application code.
        </para></listitem>
      </itemizedlist>
    </para>
  </section>

  <section>
    <title>Dbus-glib API conversion</title>

    <table id="dbus-glib-vs-gdbus">
      <title>dbus-glib APIs and their GDBus counterparts</title>
      <tgroup cols="2">
        <thead>
           <row><entry>dbus-glib</entry><entry>GDBus</entry></row>
        </thead>
        <tbody>
          <row><entry>#DBusGConnection</entry><entry>#GDBusConnection</entry></row>
          <row><entry>#DBusGProxy</entry><entry>#GDBusProxy</entry></row>
          <row><entry>#DBusGMethodInvocation</entry><entry>#GDBusMethodInvocation</entry></row>
          <row><entry>dbus_g_bus_get()</entry><entry>g_bus_get_sync(), also see
               g_bus_get()</entry></row>
          <row><entry>dbus_g_proxy_new_for_name()</entry><entry>g_dbus_proxy_new_sync(), also see
               g_dbus_proxy_new()</entry></row>
          <row><entry>dbus_g_proxy_add_signal()</entry><entry>not needed, use the generic #GDBusProxy::g-signal</entry></row>
          <row><entry>dbus_g_proxy_connect_signal()</entry><entry>use g_signal_connect() with #GDBusProxy::g-signal</entry></row>
          <row><entry>dbus_g_connection_register_g_object()</entry><entry>g_dbus_connection_register_object()</entry></row>
          <row><entry>dbus_g_connection_unregister_g_object()</entry><entry>g_dbus_connection_unregister_object()</entry></row>
          <row><entry>dbus_g_object_type_install_info()</entry><entry>introspection data is installed while registering
               an object, see g_dbus_connection_register_object()</entry></row>
          <row><entry>dbus_g_proxy_begin_call()</entry><entry>g_dbus_proxy_call()</entry></row>
          <row><entry>dbus_g_proxy_end_call()</entry><entry>g_dbus_proxy_call_finish()</entry></row>
          <row><entry>dbus_g_proxy_call()</entry><entry>g_dbus_proxy_call_sync()</entry></row>
          <row><entry>dbus_g_error_domain_register()</entry><entry>g_dbus_error_register_error_domain()</entry></row>
          <row><entry>dbus_g_error_has_name()</entry><entry>no direct equivalent, see g_dbus_error_get_remote_error()</entry></row>
          <row><entry>dbus_g_method_return()</entry><entry>g_dbus_method_invocation_return_value()</entry></row>
          <row><entry>dbus_g_method_return_error()</entry><entry>g_dbus_method_invocation_return_error() and variants</entry></row>
          <row><entry>dbus_g_method_get_sender()</entry><entry>g_dbus_method_invocation_get_sender()</entry></row>
        </tbody>
      </tgroup>
    </table>
  </section>

  <section>
    <title>Owning bus names</title>
    <para>
      Using dbus-glib, you typically call RequestName manually
      to own a name, like in the following excerpt:
      <informalexample><programlisting><![CDATA[
  error = NULL;
  res = dbus_g_proxy_call (system_bus_proxy,
                           "RequestName",
                           &error,
                           G_TYPE_STRING, NAME_TO_CLAIM,
                           G_TYPE_UINT,   DBUS_NAME_FLAG_ALLOW_REPLACEMENT,
                           G_TYPE_INVALID,
                           G_TYPE_UINT,   &result,
                           G_TYPE_INVALID);
  if (!res)
    {
      if (error != NULL)
        {
          g_warning ("Failed to acquire %s: %s",
                     NAME_TO_CLAIM, error->message);
          g_error_free (error);
        }
      else
        {
          g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
        }
      goto out;
    }

  if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
    {
      if (error != NULL)
        {
          g_warning ("Failed to acquire %s: %s",
                     NAME_TO_CLAIM, error->message);
          g_error_free (error);
        }
      else
        {
          g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
        }
      exit (1);
    }

  dbus_g_proxy_add_signal (system_bus_proxy, "NameLost",
                           G_TYPE_STRING, G_TYPE_INVALID);
  dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost",
                               G_CALLBACK (on_name_lost), NULL, NULL);

  /* further setup ... */
]]>
      </programlisting></informalexample>
    </para>
    <para>
    While you can do things this way with GDBus too, using
    g_dbus_proxy_call_sync(), it is much nicer to use the high-level API
    for this:
    <informalexample><programlisting><![CDATA[
static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  /* further setup ... */
}

/* ... */

  owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
                             NAME_TO_CLAIM,
                             G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
                             on_bus_acquired,
                             on_name_acquired,
                             on_name_lost,
                             NULL,
                             NULL);

  g_main_loop_run (loop);

  g_bus_unown_name (owner_id);
]]>
    </programlisting></informalexample>
    Note that g_bus_own_name() works asynchronously and requires
    you to enter your mainloop to await the on_name_aquired()
    callback. Also note that in order to avoid race conditions (e.g.
    when your service is activated by a method call), you have to export
    your manager object <emphasis>before</emphasis> acquiring the
    name. The on_bus_acquired() callback is the right place to do
    such preparations.
    </para>
  </section>

  <section>
    <title>Creating proxies for well-known names</title>
    <para>
    </para>
  </section>
</chapter>

{'fraction_non_alphanumeric': 0.10909347841447042, 'fraction_numerical': 0.0002826255917473327, 'mean_word_length': 2.497405485544848, 'pattern_counts': {'":': 0, '<': 363, '<?xml version=': 0, '>': 367, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4109109', 'n_tokens_mistral': 4444, 'n_tokens_neox': 4239, 'n_words': 920}