Do you have any ideas how to receive a GDBus signal before the GDBus method 
returns?
When I run the following program, the return of "KeyEvent" is always output faster than 
"CommitText" signal in the client program.
Or do you have any ideas to know if the returned GDBus method emitted a GDBus 
signal in the server side?

--------- start of server -----------------
#include <gio/gio.h>
#include <stdlib.h>

#define DBUS_NAME "org.test.GDBus.Example"
#define DBUS_PATH "/org/test/GDBus/Example"
#define DBUS_IFACE "org.test.GDBus.Example"

#define XML_TEMPLATE \
    "<node>"                                                         \
    "  <interface name= 'org.test.GDBus.Example'>"                   \
    "    <method name= 'X11KeyEvent'>"                               \
    "      <arg type= 'u' name= 'keysym' direction= 'in'/>"          \
    "      <arg type= 'b' name= 'processed' direction= 'out'/>"      \
    "    </method>"                                                  \
    "    <signal name='CommitText'>"                                 \
    "      <arg type='s' name='text' />"                             \
    "    </signal>"                                                  \
    "  </interface>"                                                 \
    "</node>"

static GDBusNodeInfo *introspection_data = NULL;

static void method_call_handler (GDBusConnection *connection,
                                 const gchar *sender,
                                 const gchar *object_path,
                                 const gchar *interface_name,
                                 const gchar *method_name,
                                 GVariant *parameters,
                                 GDBusMethodInvocation *invocation,
                                 gpointer user_data)
{
    if (g_strcmp0 (method_name, "X11KeyEvent") == 0) {
        guint32 keysym = 0;
        gchar buf[10];
        gboolean processed = FALSE;
        GError *error = NULL;

        g_variant_get (parameters, "(u)", &keysym);
        if (g_ascii_isalpha (keysym))
            processed = TRUE;
        if (keysym == '\n' || keysym == ' ') {
            buf[g_unichar_to_utf8 (0x21a9, buf)] = '\0';
            if (!g_dbus_connection_emit_signal (connection,
                                                sender,
                                                object_path,
                                                interface_name,
                                                "CommitText",
                                                g_variant_new ("(s)", buf),
                                                &error)) {
                g_warning ("Error in dbus signal: %s", error->message);
                g_clear_error (&error);
            }
        }

        g_dbus_method_invocation_return_value (
                invocation,
                g_variant_new("(b)", processed));
        g_print ("Got 0x%x\n", keysym);
        return;
    }
}

static const GDBusInterfaceVTable vtable =
{
    method_call_handler
};

static void bus_acquired_handler (GDBusConnection *connection,
                                  const gchar     *name,
                                  gpointer         user_data)
{
    guint registration_id = g_dbus_connection_register_object (
            connection,
            DBUS_PATH,
            introspection_data->interfaces[0],
            &vtable,
            NULL, NULL, NULL);
  g_assert (registration_id > 0);
}

int
main (int argc, char ** argv)
{
    guint id;
    GMainLoop *g_main_loop;
    introspection_data = g_dbus_node_info_new_for_xml (XML_TEMPLATE, NULL);

    id = g_bus_own_name (G_BUS_TYPE_SESSION,
                         DBUS_NAME,
                         G_BUS_NAME_OWNER_FLAGS_NONE,
                         bus_acquired_handler,
                         NULL,
                         NULL,
                         NULL,
                         NULL);

    g_main_loop = g_main_loop_new (NULL, FALSE);
    g_main_loop_run (g_main_loop);

    g_bus_unown_name (id);
    g_dbus_node_info_unref (introspection_data);
    return (0);
}

--------- end of server -----------------

--------- start of client -----------------
#include <gio/gio.h>

#include <stdio.h>
#include <stdlib.h>

#define DBUS_NAME "org.test.GDBus.Example"
#define DBUS_PATH "/org/test/GDBus/Example"
#define DBUS_IFACE "org.test.GDBus.Example"

static int elapsed;
static GMainLoop *loop;

static void
g_signal_cb (GDBusProxy *proxy,
             const gchar *sender_name,
             const gchar *signal_name,
             GVariant    *parameters)
{

    if (!g_strcmp0 (signal_name, "CommitText")) {
        const gchar *text = NULL;
        g_variant_get (parameters, "(&s)", &text);
        printf ("CommitText: %s\n", text);
        elapsed++;
        if (elapsed == 2 && loop) {
            g_main_loop_quit (loop);
            loop = NULL;
        }
        return;
    }
}

int
main (int argc, char ** argv)
{
    GDBusConnection *connection;
    GError *error = NULL;
    GDBusProxy *proxy;
    guint32 keysym = ' ';
    GVariant *result;

    connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
    g_assert_no_error (error);
    g_assert (connection != NULL);
    g_assert (!g_dbus_connection_is_closed (connection));

    error = NULL;
    proxy = g_dbus_proxy_new_sync (connection,
                                   G_DBUS_PROXY_FLAGS_NONE,
                                   NULL,
                                   DBUS_NAME,
                                   DBUS_PATH,
                                   DBUS_IFACE,
                                   NULL,
                                   &error);
    g_assert_no_error (error);

    g_signal_connect (proxy,
                      "g-signal",
                      G_CALLBACK (g_signal_cb),
                      NULL);
    error = NULL;
    result = g_dbus_proxy_call_sync (proxy,
                                     "X11KeyEvent",
                                     g_variant_new("(u)", keysym),
                                     G_DBUS_CALL_FLAGS_NONE,
                                     -1, NULL, &error);
    if (result != NULL) {
        gboolean processed = TRUE;
        g_variant_get (result, "(b)", &processed);
        if (!processed) {
            g_print ("KeyEvent: 0x%x\n", keysym);
        }
        g_variant_unref (result);
    } else {
        g_warning ("Got error: %s", error->message);
        g_clear_pointer (&error, g_error_free);
        g_assert_not_reached ();
    }
    elapsed++;

    if (elapsed < 2) {
        loop = g_main_loop_new (NULL, FALSE);
        g_main_loop_run (loop);
    }

    return 0;
}
--------- end of client -----------------
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

Reply via email to