initial version of headphoned
authorThomas Perl <thp@thpinfo.com>
Wed, 21 Oct 2009 11:49:14 +0000 (13:49 +0200)
committerThomas Perl <thp@thpinfo.com>
Fri, 23 Oct 2009 19:19:06 +0000 (21:19 +0200)
makefile [new file with mode: 0644]
src/headphoned.c [new file with mode: 0644]

diff --git a/makefile b/makefile
new file mode 100644 (file)
index 0000000..2c5105e
--- /dev/null
+++ b/makefile
@@ -0,0 +1,12 @@
+OBJS = src/headphoned.o
+PROG = headphoned
+CFLAGS += `pkg-config --cflags glib-2.0 gconf-2.0 libosso` -Os -Wall
+LDFLAGS += `pkg-config --libs glib-2.0 gconf-2.0 libosso`
+
+$(PROG): $(OBJS)
+       $(CC) $(LDFLAGS) $(LIBS) $^ -o $@
+       strip $@
+
+clean:
+       rm -f $(PROG) $(OBJS)
+
diff --git a/src/headphoned.c b/src/headphoned.c
new file mode 100644 (file)
index 0000000..b5cce6e
--- /dev/null
@@ -0,0 +1,113 @@
+#include <stdio.h>
+#include <assert.h>
+#include <glib.h>
+#include <gconf/gconf-client.h>
+#include <libosso.h>
+
+#define STATE_FILE "/sys/devices/platform/gpio-switch/headphone/state"
+#define STATE_CONNECTED_STR "connected"
+#define STATE_DISCONNECTED_STR "disconnected"
+
+#define GCONF_VOLUME_CONTROL "/apps/osso/sound/master_volume"
+
+#define MEDIA_SERVER_SRVC "com.nokia.osso_media_server"
+#define MEDIA_SERVER_PATH "/com/nokia/osso_media_server"
+#define MEDIA_SERVER_INTF "com.nokia.osso_media_server.music"
+#define MEDIA_SERVER_METH "pause"
+
+//#define ENABLE_VOLUME_CONTROL
+#define ENABLE_PAUSE_ON_DISCONNECT
+
+
+enum { STATE_UNKNOWN, STATE_CONNECTED, STATE_DISCONNECTED, STATE_COUNT };
+
+typedef struct {
+       GConfClient* client;
+       osso_context_t* osso;
+       guint state;
+       gint volume[STATE_COUNT];
+} Headphoned;
+
+void
+on_volume_changed(GConfClient* client, guint gnxn_id, GConfEntry* entry,
+               gpointer data)
+{
+       Headphoned* headphoned = (Headphoned*)data;
+       headphoned->volume[headphoned->state] = gconf_value_get_int(entry->value);
+}
+
+Headphoned*
+headphoned_new()
+{
+       Headphoned* this = g_new0(Headphoned, 1);
+       assert(this != NULL);
+
+       this->osso = osso_initialize("headphoned", "1.0", FALSE, NULL);
+       assert(this->osso != NULL);
+
+#ifdef ENABLE_VOLUME_CONTROL
+       this->client = gconf_client_get_default();
+       gconf_client_add_dir(this->client, GCONF_VOLUME_CONTROL,
+                       GCONF_CLIENT_PRELOAD_NONE, NULL);
+       gconf_client_notify_add(this->client, GCONF_VOLUME_CONTROL,
+                       on_volume_changed, this, NULL, NULL);
+#endif
+
+       return this;
+}
+
+gboolean
+on_file_changed(GIOChannel* source, GIOCondition condition, gpointer data)
+{
+       Headphoned* headphoned = (Headphoned*)data;
+#ifdef ENABLE_VOLUME_CONTROL
+       gint volume = headphoned->volume[headphoned->state];
+#endif
+       gchar* result;
+
+       g_io_channel_seek_position(source, 0, G_SEEK_SET, NULL);
+       g_io_channel_read_line(source, &result, NULL, NULL, NULL);
+       g_strstrip(result);
+       
+       if (g_ascii_strcasecmp(result, STATE_CONNECTED_STR) == 0) {
+               headphoned->state = STATE_CONNECTED;
+       } else {
+               headphoned->state = STATE_DISCONNECTED;
+#ifdef ENABLE_PAUSE_ON_DISCONNECT
+               osso_rpc_run(headphoned->osso,
+                               MEDIA_SERVER_SRVC,
+                               MEDIA_SERVER_PATH,
+                               MEDIA_SERVER_INTF,
+                               MEDIA_SERVER_METH,
+                               NULL,
+                               DBUS_TYPE_INVALID);
+#endif
+       }
+
+#ifdef ENABLE_VOLUME_CONTROL
+       gint new_volume = headphoned->volume[headphoned->state];
+       if (new_volume != volume) {
+               gconf_client_set_int(headphoned->client, GCONF_VOLUME_CONTROL,
+                               new_volume, NULL);
+               gconf_client_suggest_sync(headphoned->client, NULL);
+               gconf_client_clear_cache(headphoned->client);
+       }
+#endif
+
+       g_free(result);
+       return TRUE;
+}
+
+int
+main(int argc, char* argv[])
+{
+       g_type_init();
+       GMainLoop* loop = g_main_loop_new(NULL, FALSE);
+
+       GIOChannel* state = g_io_channel_new_file(STATE_FILE, "r", NULL);
+       g_io_add_watch(state, G_IO_PRI, on_file_changed, headphoned_new());
+
+       g_main_loop_run(loop);
+       return 0;
+}
+