|
Packit |
3ae693 |
/*-*- Mode: C; c-basic-offset: 8 -*-*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/***
|
|
Packit |
3ae693 |
This file is part of libcanberra.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
Copyright 2008 Lennart Poettering
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
libcanberra is free software; you can redistribute it and/or modify
|
|
Packit |
3ae693 |
it under the terms of the GNU Lesser General Public License as
|
|
Packit |
3ae693 |
published by the Free Software Foundation, either version 2.1 of the
|
|
Packit |
3ae693 |
License, or (at your option) any later version.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
libcanberra is distributed in the hope that it will be useful, but
|
|
Packit |
3ae693 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
3ae693 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
3ae693 |
Lesser General Public License for more details.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
3ae693 |
License along with libcanberra. If not, see
|
|
Packit |
3ae693 |
<http://www.gnu.org/licenses/>.
|
|
Packit |
3ae693 |
***/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
3ae693 |
#include <config.h>
|
|
Packit |
3ae693 |
#endif
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#include <string.h>
|
|
Packit |
3ae693 |
#include <locale.h>
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#include <gtk/gtk.h>
|
|
Packit |
3ae693 |
#include <canberra-gtk.h>
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int ret = 0;
|
|
Packit |
3ae693 |
static ca_proplist *proplist = NULL;
|
|
Packit |
3ae693 |
static int n_loops = 1;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static void callback(ca_context *c, uint32_t id, int error, void *userdata);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static gboolean idle_quit(gpointer userdata) {
|
|
Packit |
3ae693 |
gtk_main_quit();
|
|
Packit |
3ae693 |
return FALSE;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static gboolean idle_play(gpointer userdata) {
|
|
Packit |
3ae693 |
int r;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
g_assert(n_loops > 1);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
n_loops--;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
r = ca_context_play_full(ca_gtk_context_get(), 1, proplist, callback, NULL);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (r < 0) {
|
|
Packit |
3ae693 |
g_printerr("Failed to play sound: %s\n", ca_strerror(r));
|
|
Packit |
3ae693 |
ret = 1;
|
|
Packit |
3ae693 |
gtk_main_quit();
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return FALSE;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static void callback(ca_context *c, uint32_t id, int error, void *userdata) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (error < 0) {
|
|
Packit |
3ae693 |
g_printerr("Failed to play sound (callback): %s\n", ca_strerror(error));
|
|
Packit |
3ae693 |
ret = 1;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
} else if (n_loops > 1) {
|
|
Packit |
3ae693 |
/* So, why don't we call ca_context_play_full() here directly?
|
|
Packit |
3ae693 |
-- Because the context this callback is called from is
|
|
Packit |
3ae693 |
explicitly documented as undefined and no libcanberra function
|
|
Packit |
3ae693 |
may be called from it. */
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
g_idle_add(idle_play, NULL);
|
|
Packit |
3ae693 |
return;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/* So, why don't we call gtk_main_quit() here directly? -- Because
|
|
Packit |
3ae693 |
* otherwise we might end up with a small race condition: this
|
|
Packit |
3ae693 |
* callback might get called before the main loop actually started
|
|
Packit |
3ae693 |
* running */
|
|
Packit |
3ae693 |
g_idle_add(idle_quit, NULL);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static GQuark error_domain(void) {
|
|
Packit |
3ae693 |
return g_quark_from_static_string("canberra-error-quark");
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static gboolean property_callback(
|
|
Packit |
3ae693 |
const gchar *option_name,
|
|
Packit |
3ae693 |
const gchar *value,
|
|
Packit |
3ae693 |
gpointer data,
|
|
Packit |
3ae693 |
GError **error) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
const char *equal;
|
|
Packit |
3ae693 |
char *t;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(equal = strchr(value, '='))) {
|
|
Packit |
3ae693 |
g_set_error(error, error_domain(), 0, "Property lacks '='.");
|
|
Packit |
3ae693 |
return FALSE;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
t = g_strndup(value, equal - value);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (ca_proplist_sets(proplist, t, equal + 1) < 0) {
|
|
Packit |
3ae693 |
g_set_error(error, error_domain(), 0, "Invalid property.");
|
|
Packit |
3ae693 |
g_free(t);
|
|
Packit |
3ae693 |
return FALSE;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
g_free(t);
|
|
Packit |
3ae693 |
return TRUE;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int main (int argc, char *argv[]) {
|
|
Packit |
3ae693 |
GOptionContext *oc;
|
|
Packit |
3ae693 |
static gchar *event_id = NULL, *filename = NULL, *event_description = NULL, *cache_control = NULL, *volume = NULL;
|
|
Packit |
3ae693 |
int r;
|
|
Packit |
3ae693 |
static gboolean version = FALSE;
|
|
Packit |
3ae693 |
GError *error = NULL;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static const GOptionEntry options[] = {
|
|
Packit |
3ae693 |
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display version number and quit", NULL },
|
|
Packit |
3ae693 |
{ "id", 'i', 0, G_OPTION_ARG_STRING, &event_id, "Event sound identifier", "STRING" },
|
|
Packit |
3ae693 |
{ "file", 'f', 0, G_OPTION_ARG_STRING, &filename, "Play file", "PATH" },
|
|
Packit |
3ae693 |
{ "description", 'd', 0, G_OPTION_ARG_STRING, &event_description, "Event sound description", "STRING" },
|
|
Packit |
3ae693 |
{ "cache-control", 'c', 0, G_OPTION_ARG_STRING, &cache_control, "Cache control (permanent, volatile, never)", "STRING" },
|
|
Packit |
3ae693 |
{ "loop", 'l', 0, G_OPTION_ARG_INT, &n_loops, "Loop how many times (detault: 1)", "INTEGER" },
|
|
Packit |
3ae693 |
{ "volume", 'V', 0, G_OPTION_ARG_STRING, &volume, "A floating point dB value for the sample volume (ex: 0.0)", "STRING" },
|
|
Packit |
3ae693 |
{ "property", 0, 0, G_OPTION_ARG_CALLBACK, (void*) property_callback, "An arbitrary property", "STRING" },
|
|
Packit |
3ae693 |
{ NULL, 0, 0, 0, NULL, NULL, NULL }
|
|
Packit |
3ae693 |
};
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
setlocale(LC_ALL, "");
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
g_type_init();
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_proplist_create(&proplist);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
oc = g_option_context_new("- canberra-gtk-play");
|
|
Packit |
3ae693 |
g_option_context_add_main_entries(oc, options, NULL);
|
|
Packit |
3ae693 |
g_option_context_add_group(oc, gtk_get_option_group(TRUE));
|
|
Packit |
3ae693 |
g_option_context_set_help_enabled(oc, TRUE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(g_option_context_parse(oc, &argc, &argv, &error))) {
|
|
Packit |
3ae693 |
g_print("Option parsing failed: %s\n", error->message);
|
|
Packit |
3ae693 |
return 1;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
g_option_context_free(oc);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (version) {
|
|
Packit |
3ae693 |
g_print("canberra-gtk-play from %s\n", PACKAGE_STRING);
|
|
Packit |
3ae693 |
return 0;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!event_id && !filename) {
|
|
Packit |
3ae693 |
g_printerr("No event id or file specified.\n");
|
|
Packit |
3ae693 |
return 1;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_context_change_props(ca_gtk_context_get(),
|
|
Packit |
3ae693 |
CA_PROP_APPLICATION_NAME, "canberra-gtk-play",
|
|
Packit |
3ae693 |
CA_PROP_APPLICATION_VERSION, PACKAGE_VERSION,
|
|
Packit |
3ae693 |
CA_PROP_APPLICATION_ID, "org.freedesktop.libcanberra.gtk-play",
|
|
Packit |
3ae693 |
NULL);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (event_id)
|
|
Packit |
3ae693 |
ca_proplist_sets(proplist, CA_PROP_EVENT_ID, event_id);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (filename)
|
|
Packit |
3ae693 |
ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME, filename);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (cache_control)
|
|
Packit |
3ae693 |
ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL, cache_control);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (event_description)
|
|
Packit |
3ae693 |
ca_proplist_sets(proplist, CA_PROP_EVENT_DESCRIPTION, event_description);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (volume)
|
|
Packit |
3ae693 |
ca_proplist_sets(proplist, CA_PROP_CANBERRA_VOLUME, volume);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
r = ca_context_play_full(ca_gtk_context_get(), 1, proplist, callback, NULL);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (r < 0) {
|
|
Packit |
3ae693 |
g_printerr("Failed to play sound: %s\n", ca_strerror(r));
|
|
Packit |
3ae693 |
ret = 1;
|
|
Packit |
3ae693 |
goto finish;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
gtk_main();
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
finish:
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_proplist_destroy(proplist);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|