// gcc -Wall testgtkclient2.c -o testgtkclient2 `pkg-config --cflags --libs gtk+-2.0 dbus-glib-1` #include #include #include #include static GtkWidget *button_dummy; static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; static void lose (const char *str, ...) { va_list args; va_start (args, str); vfprintf (stderr, str, args); fputc ('\n', stderr); va_end (args); exit (1); } static void lose_gerror (const char *prefix, GError *error) { lose ("%s: %s", prefix, error->message); } /* Our usual callback function */ static void button_callback( GtkWidget *widget, gpointer data ) { g_print ("%s\n", __PRETTY_FUNCTION__); DBusGProxy *proxy = data; dbus_g_proxy_call_no_reply (proxy, "handle_key_pressed_event", G_TYPE_INT, 33, G_TYPE_INVALID); } static void on_mode_switched (DBusGProxy *proxy, guint mode_id, gpointer user_data) { printf ("Received signal mode_id=%d\n", mode_id); g_signal_emit_by_name (button_dummy, "clicked"); } static void button_dummy_callback( GtkWidget *widget, gpointer data ) { g_print ("%s\n", __PRETTY_FUNCTION__); gtk_label_set_text ((GtkLabel*)data, "button clicked!"); } int main( int argc, char *argv[] ) { /* GtkWidget is the storage type for widgets */ GtkWidget *window; GtkWidget *box; GtkWidget *button; GtkWidget *label; DBusGConnection *bus; DBusGProxy *remote_object; GError *error = NULL; g_type_init (); bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (!bus) lose_gerror ("Couldn't connect to session bus", error); /* We use _for_name_owner in order to track this particular service * instance, which lets us receive signals. */ remote_object = dbus_g_proxy_new_for_name (bus, "com.acme.test_svc", "/com/acme/test_svc", "com.acme.test_svc"); if (!remote_object) lose_gerror ("Failed to get name owner", error); /* Tell DBus what the type signature of the signal callback is; this * allows us to sanity-check incoming messages before invoking the * callback. You need to do this once for each proxy you create, * not every time you want to connect to the signal. */ dbus_g_proxy_add_signal (remote_object, "_signal_mode_switched", G_TYPE_UINT, G_TYPE_INVALID); /* Actually connect to the signal. Note you can call * dbus_g_proxy_connect_signal multiple times for one invocation of * dbus_g_proxy_add_signal. */ dbus_g_proxy_connect_signal (remote_object, "_signal_mode_switched", G_CALLBACK (on_mode_switched), NULL, NULL); gtk_init (&argc, &argv); /* Create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Example Window"); /* It's a good idea to do this for all windows. */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL); /* Sets the border width of the window. */ gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* Create a new button */ button = gtk_button_new_with_label ("click me!"); button_dummy = gtk_button_new_with_label ("dummy"); label = gtk_label_new ("XXX"); /* Connect the "clicked" signal of the button to our callback */ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (button_callback), (gpointer) remote_object); g_signal_connect (G_OBJECT (button_dummy), "clicked", G_CALLBACK (button_dummy_callback), (gpointer) label); /* This calls our box creating function */ box = gtk_vbox_new (TRUE, 3); /* Pack and show all our widgets */ gtk_container_add (GTK_CONTAINER (box), button); gtk_container_add (GTK_CONTAINER (box), label); gtk_container_add (GTK_CONTAINER (window), box); gtk_widget_show_all (window); /* Rest in gtk_main and wait for the fun to begin! */ gtk_main (); return 0; }