2 * headphoned for the Nokia N8x0 and the N900
4 * The headphone daemon watches the state of the headphone
5 * plug (connected, disconnected) and carries out actions
6 * based on these events.
9 * * Send "pause" to the media player on disconnect
10 * * Maintain different volume settings for each state
12 * Initial working version: 2009-10-21
14 * Copyright (c) 2009-2010 Thomas Perl <thpinfo.com>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this package; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include <gconf/gconf-client.h>
36 #include <dbus/dbus.h>
41 #define STATE_FILE "/sys/devices/platform/gpio-switch/headphone/state"
42 #define STATE_CONNECTED_STR "connected"
43 #define STATE_DISCONNECTED_STR "disconnected"
45 #define GCONF_VOLUME_CONTROL "/apps/osso/sound/master_volume"
48 # define MEDIA_SERVER_SRVC "com.nokia.osso_media_server"
49 # define MEDIA_SERVER_PATH "/com/nokia/osso_media_server"
50 # define MEDIA_SERVER_INTF "com.nokia.osso_media_server.music"
52 # define MEDIA_SERVER_SRVC "com.nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer"
53 # define MEDIA_SERVER_PATH "/com/nokia/mafw/renderer/gstrenderer"
54 # define MEDIA_SERVER_INTF "com.nokia.mafw.renderer"
57 #define PANUCCI_SRVC "org.panucci.panucciInterface"
58 #define PANUCCI_PATH "/panucciInterface"
59 #define PANUCCI_INTF "org.panucci.panucciInterface"
61 #define MPLAYER_FIFO "/etc/headphoned/mplayer-input"
63 enum { STATE_UNKNOWN, STATE_CONNECTED, STATE_DISCONNECTED, STATE_COUNT };
67 DBusConnection* session_bus;
70 gint volume[STATE_COUNT];
75 on_volume_changed(GConfClient* client, guint gnxn_id, GConfEntry* entry,
78 Headphoned* headphoned = (Headphoned*)data;
79 headphoned->volume[headphoned->state] =
80 gconf_value_get_int(entry->value);
86 Headphoned* this = g_new0(Headphoned, 1);
89 this->osso = osso_initialize("headphoned", "1.0", FALSE, NULL);
90 assert(this->osso != NULL);
92 #ifdef ENABLE_VOLUME_CONTROL
93 this->client = gconf_client_get_default();
94 gconf_client_add_dir(this->client, GCONF_VOLUME_CONTROL,
95 GCONF_CLIENT_PRELOAD_NONE, NULL);
96 gconf_client_notify_add(this->client, GCONF_VOLUME_CONTROL,
97 on_volume_changed, this, NULL, NULL);
100 this->session_bus = dbus_bus_get(DBUS_BUS_SESSION, NULL);
101 this->initial = TRUE;
107 on_file_changed(GIOChannel* source, GIOCondition condition, gpointer data)
109 Headphoned* headphoned = (Headphoned*)data;
110 #ifdef ENABLE_VOLUME_CONTROL
111 gint volume = headphoned->volume[headphoned->state];
116 g_io_channel_seek_position(source, 0, G_SEEK_SET, NULL);
117 g_io_channel_read_line(source, &result, NULL, NULL, NULL);
120 if (g_ascii_strcasecmp(result, STATE_CONNECTED_STR) == 0) {
121 headphoned->state = STATE_CONNECTED;
123 headphoned->state = STATE_DISCONNECTED;
124 #ifdef ENABLE_PAUSE_ON_DISCONNECT
125 if (headphoned->initial == FALSE) {
126 /* Nokia Media Player */
127 osso_rpc_run(headphoned->osso,
136 if (dbus_bus_name_has_owner(headphoned->session_bus,
139 osso_rpc_run(headphoned->osso,
149 if ((mplayer_fifo = open(MPLAYER_FIFO,
150 O_WRONLY | O_NONBLOCK)) != -1) {
151 write(mplayer_fifo, "pause\n", 6);
158 #ifdef ENABLE_VOLUME_CONTROL
159 gint new_volume = headphoned->volume[headphoned->state];
160 if (new_volume != volume) {
161 gconf_client_set_int(headphoned->client, GCONF_VOLUME_CONTROL,
163 /*gconf_client_suggest_sync(headphoned->client, NULL);
164 gconf_client_clear_cache(headphoned->client);*/
167 headphoned->initial = FALSE;
174 main(int argc, char* argv[])
177 GMainLoop* loop = g_main_loop_new(NULL, FALSE);
179 GIOChannel* state = g_io_channel_new_file(STATE_FILE, "r", NULL);
180 g_io_add_watch(state, G_IO_PRI, on_file_changed, headphoned_new());
182 g_main_loop_run(loop);