summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-05-29 15:19:07 +0000
committerLennart Poettering <lennart@poettering.net>2008-05-29 15:19:07 +0000
commit41b9bf9869de2bd12460f03a4ee0d2fb77488301 (patch)
treee45067b43ae93f68a114c60968c9ebe89f737e33
parentfe872a67b78897a00ed61d48529bb9739ca45d27 (diff)
preliminary gtk binding
git-svn-id: file:///home/lennart/svn/public/libcanberra/trunk@36 01b60673-d06a-42c0-afdd-89cb8e0f78ac
-rw-r--r--configure.ac1
-rw-r--r--src/canberra-gtk.c161
-rw-r--r--src/canberra-gtk.h4
-rw-r--r--src/canberra.h4
-rw-r--r--src/common.c30
-rw-r--r--src/common.h3
-rw-r--r--src/test-canberra.c6
-rw-r--r--todo1
8 files changed, 185 insertions, 25 deletions
diff --git a/configure.ac b/configure.ac
index de665de..bac0244 100644
--- a/configure.ac
+++ b/configure.ac
@@ -272,6 +272,7 @@ AC_SUBST(HAVE_PULSE)
AM_CONDITIONAL([HAVE_PULSE], [test "x$HAVE_PULSE" = x1])
PKG_CHECK_MODULES(VORBIS, [ vorbisfile ])
+PKG_CHECK_MODULES(GTK, [ gtk+-2.0 ])
###################################
# Output #
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;
}
diff --git a/src/canberra-gtk.h b/src/canberra-gtk.h
index b5941eb..412cdb2 100644
--- a/src/canberra-gtk.h
+++ b/src/canberra-gtk.h
@@ -29,6 +29,10 @@ ca_context *ca_gtk_context_get(void);
int ca_gtk_play_for_window(GtkWidget *w, uint32_t id, ...) CA_GCC_SENTINEL;
+int ca_gtk_play_for_event(GdkEvent *e, uint32_t id, ...) CA_GCC_SENTINEL;
+
int ca_gtk_proplist_set_for_window(ca_proplist *p, GtkWidget *w);
+int ca_gtk_proplist_set_for_event(ca_proplist *p, GdkEvent *e);
+
#endif
diff --git a/src/canberra.h b/src/canberra.h
index 493cc99..7e7209c 100644
--- a/src/canberra.h
+++ b/src/canberra.h
@@ -95,12 +95,16 @@
#define CA_PROP_EVENT_DESCRIPTION "event.description"
#define CA_PROP_EVENT_MOUSE_X "event.mouse.x"
#define CA_PROP_EVENT_MOUSE_Y "event.mouse.y"
+#define CA_PROP_EVENT_MOUSE_HPOS "event.mouse.hpos"
+#define CA_PROP_EVENT_MOUSE_VPOS "event.mouse.vpos"
#define CA_PROP_EVENT_MOUSE_BUTTON "event.mouse.button"
#define CA_PROP_WINDOW_NAME "window.name"
#define CA_PROP_WINDOW_ID "window.id"
#define CA_PROP_WINDOW_ICON "window.icon"
#define CA_PROP_WINDOW_ICON_NAME "window.icon_name"
#define CA_PROP_WINDOW_X11_DISPLAY "window.x11.display"
+#define CA_PROP_WINDOW_X11_SCREEN "window.x11.screen"
+#define CA_PROP_WINDOW_X11_MONITOR "window.x11.monitor"
#define CA_PROP_WINDOW_X11_XID "window.x11.xid"
#define CA_PROP_APPLICATION_NAME "application.name"
#define CA_PROP_APPLICATION_ID "application.id"
diff --git a/src/common.c b/src/common.c
index db59e27..3207e79 100644
--- a/src/common.c
+++ b/src/common.c
@@ -158,14 +158,10 @@ int ca_context_open(ca_context *c) {
return ret;
}
-static int ca_proplist_from_ap(ca_proplist **_p, va_list ap) {
+int ca_proplist_merge_ap(ca_proplist *p, va_list ap) {
int ret;
- ca_proplist *p;
-
- ca_assert(_p);
- if ((ret = ca_proplist_create(&p)) < 0)
- return ret;
+ ca_return_val_if_fail(p, CA_ERROR_INVALID);
for (;;) {
const char *key, *value;
@@ -173,15 +169,27 @@ static int ca_proplist_from_ap(ca_proplist **_p, va_list ap) {
if (!(key = va_arg(ap, const char*)))
break;
- if (!(value = va_arg(ap, const char*))) {
- ret = CA_ERROR_INVALID;
- goto fail;
- }
+ if (!(value = va_arg(ap, const char*)))
+ return CA_ERROR_INVALID;
if ((ret = ca_proplist_sets(p, key, value)) < 0)
- goto fail;
+ return ret;
}
+ return CA_SUCCESS;
+
+int ca_proplist_from_ap(ca_proplist **_p, va_list ap) {
+ int ret;
+ ca_proplist *p;
+
+ ca_return_val_if_fail(_p, CA_ERROR_INVALID);
+
+ if ((ret = ca_proplist_create(&p)) < 0)
+ return ret;
+
+ if ((ret = ca_proplist_merge_ap(p, ap)) < 0)
+ goto fail;
+
*_p = p;
return CA_SUCCESS;
diff --git a/src/common.h b/src/common.h
index 13139b3..ebf1aeb 100644
--- a/src/common.h
+++ b/src/common.h
@@ -45,6 +45,9 @@ typedef enum ca_cache_control {
CA_CACHE_CONTROL_VOLATILE
} ca_cache_control_t;
+int ca_proplist_merge_ap(ca_proplist *p, va_list ap);
+int ca_proplist_from_ap(ca_proplist **_p, va_list ap);
+
int ca_parse_cache_control(ca_cache_control_t *control, const char *c);
#endif
diff --git a/src/test-canberra.c b/src/test-canberra.c
index 6dd1d5b..266e441 100644
--- a/src/test-canberra.c
+++ b/src/test-canberra.c
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
ret = ca_context_change_props(c,
CA_PROP_APPLICATION_NAME, "An example",
CA_PROP_APPLICATION_ID, "org.freedesktop.libcanberra.Test",
- CA_PROP_WINDOW_X11_DISPLAY, getenv("DISPLAY"),
+ CA_PROP_WINDOW_X11_SCREEN, getenv("DISPLAY"),
NULL);
fprintf(stderr, "change_props: %s\n", ca_strerror(ret));
@@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
/* Now trigger a sound event, the quick version */
ret = ca_context_play(c, 0,
- CA_PROP_EVENT_ID, "desktop-logout",
+ CA_PROP_EVENT_ID, "desktop-login",
CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/bar.wav",
CA_PROP_MEDIA_NAME, "User has logged off from session",
CA_PROP_MEDIA_LANGUAGE, "en_EN",
@@ -83,7 +83,7 @@ int main(int argc, char *argv[]) {
usleep(500000);
/* Stop one sound */
- ret = ca_context_cancel(c, 0);
+/* ret = ca_context_cancel(c, 0); */
fprintf(stderr, "cancel: %s\n", ca_strerror(ret));
fprintf(stderr, "Sleep 2s ...\n");
diff --git a/todo b/todo
index 57b59e0..ca19eb1 100644
--- a/todo
+++ b/todo
@@ -3,3 +3,4 @@
* alsa backend
* dso backend
* lookup cache
+* ca_context_left_to_play()