diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/canberra-gtk.c | 161 | ||||
| -rw-r--r-- | src/canberra-gtk.h | 4 | ||||
| -rw-r--r-- | src/canberra.h | 4 | ||||
| -rw-r--r-- | src/common.c | 30 | ||||
| -rw-r--r-- | src/common.h | 3 | ||||
| -rw-r--r-- | src/test-canberra.c | 6 | 
6 files changed, 183 insertions, 25 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;  } 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"); | 
