--- /dev/null
+#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;
+}
+