mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-05-16 13:40:18 +00:00
Drop dbus-glib deps, port example to GDBus
This commit is contained in:
@@ -1,203 +1,122 @@
|
||||
/* example.c - program to demonstrate some D-BUS stuffs.
|
||||
* Copyright (C) 2006 Claessens Xavier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* Claessens Xavier
|
||||
* xclaesse@gmail.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include "../marshal.c"
|
||||
|
||||
#define DBUS_SERVICE "org.zoitechat.service"
|
||||
#define DBUS_REMOTE "/org/zoitechat/Remote"
|
||||
#define DBUS_REMOTE_CONNECTION_INTERFACE "org.zoitechat.connection"
|
||||
#define DBUS_REMOTE_PLUGIN_INTERFACE "org.zoitechat.plugin"
|
||||
#define DBUS_CONNECTION_PATH "/org/zoitechat"
|
||||
#define DBUS_CONNECTION_INTERFACE "org.zoitechat.connection"
|
||||
#define DBUS_PLUGIN_INTERFACE "org.zoitechat.plugin"
|
||||
|
||||
guint command_id;
|
||||
guint server_id;
|
||||
|
||||
static void
|
||||
write_error (const char *message,
|
||||
GError **error)
|
||||
{
|
||||
if (error == NULL || *error == NULL) {
|
||||
return;
|
||||
}
|
||||
g_printerr ("%s: %s\n", message, (*error)->message);
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_server_cb (DBusGProxy *proxy,
|
||||
char *word[],
|
||||
char *word_eol[],
|
||||
guint hook_id,
|
||||
guint context_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (hook_id == server_id) {
|
||||
g_print ("message: %s\n", word_eol[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_command_cb (DBusGProxy *proxy,
|
||||
char *word[],
|
||||
char *word_eol[],
|
||||
guint hook_id,
|
||||
guint context_id,
|
||||
gpointer user_data)
|
||||
static gboolean
|
||||
call_sync (GDBusProxy *proxy, const char *method, GVariant *params, GVariant **out)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *result;
|
||||
|
||||
if (hook_id == command_id) {
|
||||
if (!dbus_g_proxy_call (proxy, "Unhook",
|
||||
&error,
|
||||
G_TYPE_UINT, hook_id,
|
||||
G_TYPE_INVALID, G_TYPE_INVALID)) {
|
||||
write_error ("Failed to complete unhook", &error);
|
||||
}
|
||||
/* Now if you write "/test blah" again in the ZoiteChat window
|
||||
* you'll get a "Unknown command" error message */
|
||||
g_print ("test command received: %s\n", word_eol[1]);
|
||||
if (!dbus_g_proxy_call (proxy, "Print",
|
||||
&error,
|
||||
G_TYPE_STRING, "test command succeed",
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_INVALID)) {
|
||||
write_error ("Failed to complete Print", &error);
|
||||
}
|
||||
result = g_dbus_proxy_call_sync (proxy,
|
||||
method,
|
||||
params,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
if (!result)
|
||||
{
|
||||
g_printerr ("%s failed: %s\n", method, error->message);
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unload_cb (void)
|
||||
{
|
||||
g_print ("Good bye !\n");
|
||||
exit (EXIT_SUCCESS);
|
||||
if (out)
|
||||
*out = result;
|
||||
else
|
||||
g_variant_unref (result);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
DBusGConnection *connection;
|
||||
DBusGProxy *remote_object;
|
||||
GMainLoop *mainloop;
|
||||
gchar *path;
|
||||
GDBusConnection *connection;
|
||||
GDBusProxy *connection_proxy;
|
||||
GDBusProxy *plugin_proxy;
|
||||
GVariant *connect_result = NULL;
|
||||
gchar *remote_path = NULL;
|
||||
gchar *command = NULL;
|
||||
const char *path_tmp;
|
||||
int status = EXIT_FAILURE;
|
||||
GError *error = NULL;
|
||||
|
||||
#if ! GLIB_CHECK_VERSION (2, 36, 0)
|
||||
g_type_init ();
|
||||
#endif
|
||||
|
||||
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
|
||||
if (connection == NULL) {
|
||||
write_error ("Couldn't connect to session bus", &error);
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (!connection)
|
||||
{
|
||||
g_printerr ("Bus connection failed: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
remote_object = dbus_g_proxy_new_for_name (connection,
|
||||
DBUS_SERVICE,
|
||||
DBUS_REMOTE,
|
||||
DBUS_REMOTE_CONNECTION_INTERFACE);
|
||||
if (!dbus_g_proxy_call (remote_object, "Connect",
|
||||
&error,
|
||||
G_TYPE_STRING, argv[0],
|
||||
G_TYPE_STRING, "example",
|
||||
G_TYPE_STRING, "Example of a D-Bus client",
|
||||
G_TYPE_STRING, "1.0",
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &path, G_TYPE_INVALID)) {
|
||||
write_error ("Failed to complete Connect", &error);
|
||||
|
||||
connection_proxy = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
DBUS_SERVICE,
|
||||
DBUS_CONNECTION_PATH,
|
||||
DBUS_CONNECTION_INTERFACE,
|
||||
NULL,
|
||||
&error);
|
||||
if (!connection_proxy)
|
||||
{
|
||||
g_printerr ("Connection proxy failed: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
g_object_unref (connection);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
g_object_unref (remote_object);
|
||||
|
||||
remote_object = dbus_g_proxy_new_for_name (connection,
|
||||
DBUS_SERVICE,
|
||||
path,
|
||||
DBUS_REMOTE_PLUGIN_INTERFACE);
|
||||
g_free (path);
|
||||
if (!call_sync (connection_proxy,
|
||||
"Connect",
|
||||
g_variant_new ("(ssss)", "example", "example", "GDBus example", "1.0"),
|
||||
&connect_result))
|
||||
goto cleanup;
|
||||
|
||||
if (!dbus_g_proxy_call (remote_object, "HookCommand",
|
||||
&error,
|
||||
G_TYPE_STRING, "test",
|
||||
G_TYPE_INT, 0,
|
||||
G_TYPE_STRING, "Simple D-BUS example",
|
||||
G_TYPE_INT, 1, G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &command_id, G_TYPE_INVALID)) {
|
||||
write_error ("Failed to complete HookCommand", &error);
|
||||
return EXIT_FAILURE;
|
||||
g_variant_get (connect_result, "(&s)", &path_tmp);
|
||||
remote_path = g_strdup (path_tmp);
|
||||
g_variant_unref (connect_result);
|
||||
connect_result = NULL;
|
||||
|
||||
plugin_proxy = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
DBUS_SERVICE,
|
||||
remote_path,
|
||||
DBUS_PLUGIN_INTERFACE,
|
||||
NULL,
|
||||
&error);
|
||||
if (!plugin_proxy)
|
||||
{
|
||||
g_printerr ("Plugin proxy failed: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
goto cleanup;
|
||||
}
|
||||
g_print ("Command hook id=%d\n", command_id);
|
||||
|
||||
if (!dbus_g_proxy_call (remote_object, "HookServer",
|
||||
&error,
|
||||
G_TYPE_STRING, "RAW LINE",
|
||||
G_TYPE_INT, 0,
|
||||
G_TYPE_INT, 0, G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &server_id, G_TYPE_INVALID)) {
|
||||
write_error ("Failed to complete HookServer", &error);
|
||||
return EXIT_FAILURE;
|
||||
if (argc > 1)
|
||||
command = g_strjoinv (" ", &argv[1]);
|
||||
else
|
||||
command = g_strdup ("gui focus");
|
||||
|
||||
if (!call_sync (plugin_proxy, "Command", g_variant_new ("(s)", command), NULL))
|
||||
{
|
||||
g_object_unref (plugin_proxy);
|
||||
goto cleanup;
|
||||
}
|
||||
g_print ("Server hook id=%d\n", server_id);
|
||||
|
||||
dbus_g_object_register_marshaller (
|
||||
_zoitechat_marshal_VOID__POINTER_POINTER_UINT_UINT,
|
||||
G_TYPE_NONE,
|
||||
G_TYPE_STRV, G_TYPE_STRV, G_TYPE_UINT, G_TYPE_UINT,
|
||||
G_TYPE_INVALID);
|
||||
call_sync (connection_proxy, "Disconnect", g_variant_new ("()"), NULL);
|
||||
status = EXIT_SUCCESS;
|
||||
g_object_unref (plugin_proxy);
|
||||
|
||||
dbus_g_object_register_marshaller (
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
dbus_g_proxy_add_signal (remote_object, "CommandSignal",
|
||||
G_TYPE_STRV,
|
||||
G_TYPE_STRV,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (remote_object, "CommandSignal",
|
||||
G_CALLBACK (test_command_cb),
|
||||
NULL, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (remote_object, "ServerSignal",
|
||||
G_TYPE_STRV,
|
||||
G_TYPE_STRV,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (remote_object, "ServerSignal",
|
||||
G_CALLBACK (test_server_cb),
|
||||
NULL, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (remote_object, "UnloadSignal",
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (remote_object, "UnloadSignal",
|
||||
G_CALLBACK (unload_cb),
|
||||
NULL, NULL);
|
||||
|
||||
/* Now you can write on the ZoiteChat windows: "/test arg1 arg2 ..." */
|
||||
mainloop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (mainloop);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
cleanup:
|
||||
g_free (command);
|
||||
g_free (remote_path);
|
||||
g_object_unref (connection_proxy);
|
||||
g_object_unref (connection);
|
||||
return status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user