summaryrefslogtreecommitdiffstats
path: root/src/canberra-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/canberra-gtk.c')
-rw-r--r--src/canberra-gtk.c161
1 files changed, 150 insertions, 11 deletions
diff --git a/src/canberra-gtk.c b/src/canberra-gtk.c
index cb38bba..81eb2e0 100644
--- a/src/canberra-gtk.c
+++ b/src/canberra-gtk.c
@@ -24,20 +24,45 @@
#include <config.h>
#endif
-static GtkWidget* get_toplevel(GtkWidget *w) {
- while (w) {
- if (GTK_WIDGET_TOPLEVEL(w))
- return w;
+ca_context *ca_gtk_context_get(void) {
+ static GStaticPrivate context_private = G_STATIC_PRIVATE_INIT;
+ ca_context *c = NULL;
+ int ret;
+ const char *name;
- w = gtk_widget_get_parent(w);
- }
+ if ((c = g_static_private_get(&context_private)))
+ return c;
+
+ ca_assert_se(ca_context_create(&c) == CA_SUCCESS);
+
+ if ((name = g_get_application_name()))
+ ca_assert_se(ca_context_change_props(c, CA_PROP_APPLICATION_NAME, name, NULL) == 0);
+
+ g_static_private_set(&context_private, c, (GDestroyNotify) ca_context_destroy);
+
+ return c;
+
+fail:
- return NULL;
+ if (c)
+ g_asset_se(ca_context_destroy(c) == 0);
+}
+
+static GtkWindow* get_toplevel(GtkWidget *w) {
+ if (!(w = gtk_wídget_get_toplevel(w)))
+ return NULL;
+
+ if (!GTK_IS_WINDOW(w))
+ return NULL;
+
+ return GTK_WINDOW(w);
};
int ca_gtk_proplist_set_for_window(ca_proplist *p, GtkWidget *w) {
int ret;
- const char *t;
+ const char *t, role;
+ GdkWindow *dw;
+ GdkScreen *screen;
ca_return_val_if_fail(p, CA_ERROR_INVALID);
ca_return_val_if_fail(w, CA_ERROR_INVALID);
@@ -49,19 +74,133 @@ int ca_gtk_proplist_set_for_window(ca_proplist *p, GtkWidget *w) {
if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_NAME, t)) < 0)
return ret;
+ if ((role = gtk_window_get_role(w))) {
+ if (role && t) {
+ char *id = ca_sprintf_malloc("%s#%s", t, role);
+
+ if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, id)) < 0) {
+ ca_free(t);
+ return ret;
+ }
+
+ ca_free(t);
+ }
+ } else if (t)
+ if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, t)) < 0)
+ return ret;
+
if ((t = gtk_window_get_icon_name(w)))
- if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_NAME, t)) < 0)
+ if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ICON_NAME, t)) < 0)
+ return ret;
+
+ if ((dw = GTK_WIDGET(w)->window))
+ if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long) GDK_WINDOW_XID(dw))) < 0)
+ return ret;
+
+ if ((screen = gtk_widget_get_screen(w))) {
+
+ if ((t = gtk_display_get_name(gdk_screen_get_display(screen))))
+ if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, t)) < 0)
+ return ret;
+
+ if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen))) < 0)
+ return ret;
+
+ if (dw)
+ if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_MONITOR, "%i", gdk_screen_get_monitor_at_window(screen, dw))) < 0)
+ return ret;
+ }
+
+ return CA_SUCCESS;
+}
+
+int ca_gtk_proplist_set_for_event(ca_proplist *p, GdkEvent *e) {
+ gdouble x, y;
+ GdkWindow *gw;
+ GtkWindow *w = NULL;
+
+ ca_return_val_if_fail(p, CA_ERROR_INVALID);
+ ca_return_val_if_fail(e, CA_ERROR_INVALID);
+
+ if (gw = gdk_event_get_window(e))
+ if ((w = gtk_lookup_window(gw)))
+ if ((ret = ca_gtk_proplist_set_for_window(p, w)) < 0)
+ return ret;
+
+ if (gdk_event_get_root_coords(e, &x, &y)) {
+ if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_X, "%0.0f", x)) < 0)
return ret;
+ if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_Y, "%0.0f", y)) < 0)
+ return ret;
+ }
+
+ if (e->event_type == GDK_BUTTON_PRESS ||
+ e->event_type == GDK_2BUTTON_PRESS ||
+ e->event_type == GDK_3BUTTON_PRESS ||
+ e->event_type == GDK_BUTTON_RELEASE) {
+ if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_BUTTON, "%u", e->button.button)) < 0)
+ return ret;
+ }
+ return CA_SUCCESS;
}
+int ca_gtk_play_for_window(GtkWidget *w, uint32_t id, ...) {
+ va_list ap;
+ int ret;
+ ca_proplist *p;
+
+ ca_return_val_if_fail(w, CA_ERROR_INVALID);
+
+ if ((ret = ca_proplist_create(&p)) < 0)
+ return ret;
+
+ if ((ret = ca_gtk_proplist_set_for_window(p, w)) < 0)
+ goto fail;
+ va_start(ap, id);
+ ret = ca_proplist_merge_ap(p, ap);
+ va_end(ap);
+ if (ret < 0)
+ goto fail;
-const char *ca_gtk_window_display(GtkWidget *w) {
+ ret = ca_context_play_full(ca_gtk_context_get(), id, p, NULL, NULL);
+
+fail:
+
+ ca_assert_se(ca_proplist_destroy(p) == 0);
+
+ return ret;
}
-const char *ca_gtk_window_xid(GtkWidget *w) {
+int ca_gtk_play_for_event(GdkEvent *e, uint32_t id, ...) {
+ va_list ap;
+ int ret;
+ ca_proplist *p;
+
+ ca_return_val_if_fail(w, CA_ERROR_INVALID);
+
+ if ((ret = ca_proplist_create(&p)) < 0)
+ return ret;
+
+ if ((ret = ca_gtk_proplist_set_for_event(p, e)) < 0)
+ goto fail;
+
+ va_start(ap, id);
+ ret = ca_proplist_merge_ap(p, ap);
+ va_end(ap);
+
+ if (ret < 0)
+ goto fail;
+
+ ret = ca_context_play_full(ca_gtk_context_get(), id, p, NULL, NULL);
+
+fail:
+
+ ca_assert_se(ca_proplist_destroy(p) == 0);
+
+ return ret;
}