4 * Copyright (C) 2006 Jonathan Matthew
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <glib-object.h>
30 #include <glib/gi18n-lib.h>
32 #include <lirc/lirc_client.h>
34 #include "rb-plugin.h"
37 #include "rb-shell-player.h"
39 #define RB_TYPE_LIRC_PLUGIN (rb_lirc_plugin_get_type ())
40 #define RB_LIRC_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_LIRC_PLUGIN, RBLircPlugin))
41 #define RB_LIRC_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_LIRC_PLUGIN, RBLircPluginClass))
42 #define RB_IS_LIRC_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_LIRC_PLUGIN))
43 #define RB_IS_LIRC_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_LIRC_PLUGIN))
44 #define RB_LIRC_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_LIRC_PLUGIN, RBLircPluginClass))
46 #define RB_IR_COMMAND_PLAY "play"
47 #define RB_IR_COMMAND_PAUSE "pause"
48 #define RB_IR_COMMAND_PLAYPAUSE "playpause"
49 #define RB_IR_COMMAND_STOP "stop"
50 #define RB_IR_COMMAND_SHUFFLE "shuffle"
51 #define RB_IR_COMMAND_REPEAT "repeat"
52 #define RB_IR_COMMAND_NEXT "next"
53 #define RB_IR_COMMAND_PREVIOUS "previous"
54 #define RB_IR_COMMAND_SEEK_FORWARD "seek_forward"
55 #define RB_IR_COMMAND_SEEK_BACKWARD "seek_backward"
56 #define RB_IR_COMMAND_VOLUME_UP "volume_up"
57 #define RB_IR_COMMAND_VOLUME_DOWN "volume_down"
58 #define RB_IR_COMMAND_MUTE "mute"
63 RBShellPlayer
*shell_player
;
64 struct lirc_config
*lirc_config
;
65 GIOChannel
*lirc_channel
;
70 RBPluginClass parent_class
;
73 G_MODULE_EXPORT GType
register_rb_plugin (GTypeModule
*module
);
74 GType
rb_lirc_plugin_get_type (void) G_GNUC_CONST
;
76 static void rb_lirc_plugin_init (RBLircPlugin
*plugin
);
77 static void impl_activate (RBPlugin
*plugin
, RBShell
*shell
);
78 static void impl_deactivate (RBPlugin
*plugin
, RBShell
*shell
);
80 RB_PLUGIN_REGISTER(RBLircPlugin
, rb_lirc_plugin
)
83 rb_lirc_plugin_class_init (RBLircPluginClass
*klass
)
85 RBPluginClass
*plugin_class
= RB_PLUGIN_CLASS (klass
);
86 plugin_class
->activate
= impl_activate
;
87 plugin_class
->deactivate
= impl_deactivate
;
91 rb_lirc_plugin_init (RBLircPlugin
*plugin
)
93 rb_debug ("RBLircPlugin initialising");
97 rb_lirc_plugin_read_code (GIOChannel
*source
,
98 GIOCondition condition
,
102 char *str
= NULL
; /* owned by lirc config, must not be freed */
104 gboolean processed
= FALSE
;
106 if (condition
& (G_IO_ERR
| G_IO_HUP
)) {
107 /* TODO: retry after a minute? */
108 rb_debug ("LIRC connection broken. sorry.");
112 lirc_nextcode (&code
);
114 rb_debug ("Got incomplete lirc code");
119 ok
= lirc_code2char (plugin
->lirc_config
, code
, &str
);
122 rb_debug ("couldn't convert lirc code \"%s\" to string", code
);
123 } else if (str
== NULL
) {
124 if (processed
== FALSE
)
125 rb_debug ("unknown LIRC code \"%s\"", code
);
127 } else if (strcmp (str
, RB_IR_COMMAND_PLAY
) == 0) {
128 rb_shell_player_play (plugin
->shell_player
, NULL
);
129 } else if (strcmp (str
, RB_IR_COMMAND_PAUSE
) == 0) {
130 rb_shell_player_pause (plugin
->shell_player
, NULL
);
131 } else if (strcmp (str
, RB_IR_COMMAND_PLAYPAUSE
) == 0) {
132 rb_shell_player_playpause (plugin
->shell_player
, FALSE
, NULL
);
133 } else if (strcmp (str
, RB_IR_COMMAND_STOP
) == 0) {
134 rb_shell_player_stop (plugin
->shell_player
);
135 } else if (strcmp (str
, RB_IR_COMMAND_SHUFFLE
) == 0) {
138 if (rb_shell_player_get_playback_state (plugin
->shell_player
, &shuffle
, &repeat
)) {
139 rb_shell_player_set_playback_state (plugin
->shell_player
, !shuffle
, repeat
);
141 } else if (strcmp (str
, RB_IR_COMMAND_REPEAT
) == 0) {
144 if (rb_shell_player_get_playback_state (plugin
->shell_player
, &shuffle
, &repeat
)) {
145 rb_shell_player_set_playback_state (plugin
->shell_player
, shuffle
, !repeat
);
147 } else if (strcmp (str
, RB_IR_COMMAND_NEXT
) == 0) {
148 rb_shell_player_do_next (plugin
->shell_player
, NULL
);
149 } else if (strcmp (str
, RB_IR_COMMAND_PREVIOUS
) == 0) {
150 rb_shell_player_do_previous (plugin
->shell_player
, NULL
);
151 } else if (strcmp (str
, RB_IR_COMMAND_SEEK_FORWARD
) == 0) {
152 rb_shell_player_seek (plugin
->shell_player
, 10);
153 } else if (strcmp (str
, RB_IR_COMMAND_SEEK_BACKWARD
) == 0) {
154 rb_shell_player_seek (plugin
->shell_player
, -10);
155 } else if (strcmp (str
, RB_IR_COMMAND_VOLUME_UP
) == 0) {
156 rb_shell_player_set_volume_relative (plugin
->shell_player
, 0.1, NULL
);
157 } else if (strcmp (str
, RB_IR_COMMAND_VOLUME_DOWN
) == 0) {
158 rb_shell_player_set_volume_relative (plugin
->shell_player
, -0.1, NULL
);
159 } else if (strcmp (str
, RB_IR_COMMAND_MUTE
) == 0) {
161 if (rb_shell_player_get_mute (plugin
->shell_player
, &mute
, NULL
)) {
162 rb_shell_player_set_mute (plugin
->shell_player
, !mute
, NULL
);
173 impl_activate (RBPlugin
*rbplugin
,
177 RBLircPlugin
*plugin
= RB_LIRC_PLUGIN (rbplugin
);
179 g_object_get (G_OBJECT (shell
), "shell-player", &plugin
->shell_player
, NULL
);
181 rb_debug ("Activating lirc plugin");
183 fd
= lirc_init ("Rhythmbox", 1);
185 rb_debug ("Couldn't initialize lirc");
189 if (lirc_readconfig (NULL
, &plugin
->lirc_config
, NULL
) == -1) {
191 rb_debug ("Couldn't read lirc configuration");
195 plugin
->lirc_channel
= g_io_channel_unix_new (fd
);
196 g_io_channel_set_encoding (plugin
->lirc_channel
, NULL
, NULL
);
197 g_io_channel_set_buffered (plugin
->lirc_channel
, FALSE
);
198 g_io_add_watch (plugin
->lirc_channel
, G_IO_IN
| G_IO_ERR
| G_IO_HUP
,
199 (GIOFunc
) rb_lirc_plugin_read_code
, plugin
);
203 impl_deactivate (RBPlugin
*rbplugin
,
206 RBLircPlugin
*plugin
= RB_LIRC_PLUGIN (rbplugin
);
207 GError
*error
= NULL
;
209 rb_debug ("Deactivating lirc plugin");
211 if (plugin
->lirc_channel
) {
212 g_io_channel_shutdown (plugin
->lirc_channel
, FALSE
, &error
);
214 g_warning ("Couldn't destroy lirc connection: %s",
216 g_error_free (error
);
218 plugin
->lirc_channel
= NULL
;
221 if (plugin
->lirc_config
) {
222 lirc_freeconfig (plugin
->lirc_config
);
223 plugin
->lirc_config
= NULL
;
228 if (plugin
->shell_player
) {
229 g_object_unref (G_OBJECT (plugin
->shell_player
));
230 plugin
->shell_player
= NULL
;