static void
next_clicked_cb (MxButton *button, RBShellPlayer *player)
{
    clutter_threads_leave ();
    rb_shell_player_do_next (player, NULL);
    clutter_threads_enter ();
}
static void
notification_next_cb (NotifyNotification *notification,
		      const char *action,
		      RBNotificationPlugin *plugin)
{
	rb_debug ("notification action: %s", action);
	rb_shell_player_do_next (plugin->shell_player, NULL);
}
static void
media_player_key_pressed (GDBusProxy *proxy,
			  const char *sender,
			  const char *signal,
			  GVariant *parameters,
			  RBMMKeysPlugin *plugin)
{
	char *key;
	char *application;

	if (g_strcmp0 (signal, "MediaPlayerKeyPressed") != 0) {
		rb_debug ("got unexpected signal '%s' from media player keys", signal);
		return;
	}

	g_variant_get (parameters, "(ss)", &application, &key);

	rb_debug ("got media key '%s' for application '%s'",
		  key, application);

	if (strcmp (application, "Rhythmbox")) {
		rb_debug ("got media player key signal for unexpected application '%s'", application);
		return;
	}

	if (strcmp (key, "Play") == 0) {
		rb_shell_player_playpause (plugin->shell_player, FALSE, NULL);
	} else if (strcmp (key, "Pause") == 0) {
		rb_shell_player_pause (plugin->shell_player, NULL);
	} else if (strcmp (key, "Stop") == 0) {
		rb_shell_player_stop (plugin->shell_player);
	} else if (strcmp (key, "Previous") == 0) {
		rb_shell_player_do_previous (plugin->shell_player, NULL);
	} else if (strcmp (key, "Next") == 0) {
		rb_shell_player_do_next (plugin->shell_player, NULL);
	} else if (strcmp (key, "Repeat") == 0) {
		gboolean shuffle, repeat;

		if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
			rb_shell_player_set_playback_state (plugin->shell_player, shuffle, !repeat);
		}
	} else if (strcmp (key, "Shuffle") == 0) {
		gboolean shuffle, repeat;

		if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
			rb_shell_player_set_playback_state (plugin->shell_player, !shuffle, repeat);
		}
	} else if (strcmp (key, "FastForward") == 0) {
		rb_shell_player_seek (plugin->shell_player, FFWD_OFFSET, NULL);
	} else if (strcmp (key, "Rewind") == 0) {
		rb_shell_player_seek (plugin->shell_player, -RWD_OFFSET, NULL);
	}

	g_free (key);
	g_free (application);
}
static GdkFilterReturn
filter_mmkeys (GdkXEvent *xevent,
	       GdkEvent *event,
	       gpointer data)
{
	XEvent *xev;
	XKeyEvent *key;
	Display *display;
	RBShellPlayer *player;
	xev = (XEvent *) xevent;
	if (xev->type != KeyPress) {
		return GDK_FILTER_CONTINUE;
	}

	key = (XKeyEvent *) xevent;

	player = (RBShellPlayer *)data;
	display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());

	if (XKeysymToKeycode (display, XF86XK_AudioPlay) == key->keycode) {
		rb_shell_player_playpause (player, FALSE, NULL);
		return GDK_FILTER_REMOVE;
	} else if (XKeysymToKeycode (display, XF86XK_AudioPause) == key->keycode) {
		rb_shell_player_pause (player, NULL);
		return GDK_FILTER_REMOVE;
	} else if (XKeysymToKeycode (display, XF86XK_AudioStop) == key->keycode) {
		rb_shell_player_stop (player);
		return GDK_FILTER_REMOVE;
	} else if (XKeysymToKeycode (display, XF86XK_AudioPrev) == key->keycode) {
		rb_shell_player_do_previous (player, NULL);
		return GDK_FILTER_REMOVE;
	} else if (XKeysymToKeycode (display, XF86XK_AudioNext) == key->keycode) {
		rb_shell_player_do_next (player, NULL);
		return GDK_FILTER_REMOVE;
	} else {
		return GDK_FILTER_CONTINUE;
	}
}
static gboolean
rb_lirc_plugin_read_code (GIOChannel *source,
			  GIOCondition condition,
			  RBLircPlugin *plugin)
{
	char *code;
	char *str = NULL;	/* owned by lirc config, must not be freed */
	int ok;
	gboolean processed = FALSE;

	if (condition & (G_IO_ERR | G_IO_HUP)) {
		/* TODO: retry after a minute? */
		rb_debug ("LIRC connection broken.  sorry.");
		return FALSE;
	}

	lirc_nextcode (&code);
	if (code == NULL) {
		rb_debug ("Got incomplete lirc code");
		return TRUE;
	}

	do {
		ok = lirc_code2char (plugin->lirc_config, code, &str);

		if (ok != 0) {
			rb_debug ("couldn't convert lirc code \"%s\" to string", code);
		} else if (str == NULL) {
			if (processed == FALSE)
				rb_debug ("unknown LIRC code \"%s\"", code);
			break;
		} else if (strcmp (str, RB_IR_COMMAND_PLAY) == 0) {
			gboolean playing;
			rb_shell_player_get_playing (plugin->shell_player, &playing, NULL);
			if (playing == FALSE)
				rb_shell_player_playpause (plugin->shell_player, FALSE, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_PAUSE) == 0) {
			rb_shell_player_pause (plugin->shell_player, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_PLAYPAUSE) == 0) {
			rb_shell_player_playpause (plugin->shell_player, FALSE, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_STOP) == 0) {
			rb_shell_player_stop (plugin->shell_player);
		} else if (strcmp (str, RB_IR_COMMAND_SHUFFLE) == 0) {
			gboolean shuffle;
			gboolean repeat;
			if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
				rb_shell_player_set_playback_state (plugin->shell_player, !shuffle, repeat);
			}
		} else if (strcmp (str, RB_IR_COMMAND_REPEAT) == 0) {
			gboolean shuffle;
			gboolean repeat;
			if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
				rb_shell_player_set_playback_state (plugin->shell_player, shuffle, !repeat);
			}
		} else if (strcmp (str, RB_IR_COMMAND_NEXT) == 0) {
			rb_shell_player_do_next (plugin->shell_player, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_PREVIOUS) == 0) {
			rb_shell_player_do_previous (plugin->shell_player, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_SEEK_FORWARD) == 0) {
			rb_shell_player_seek (plugin->shell_player, FFWD_OFFSET, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_SEEK_BACKWARD) == 0) {
			rb_shell_player_seek (plugin->shell_player, -RWD_OFFSET, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_VOLUME_UP) == 0) {
			rb_shell_player_set_volume_relative (plugin->shell_player, 0.1, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_VOLUME_DOWN) == 0) {
			rb_shell_player_set_volume_relative (plugin->shell_player, -0.1, NULL);
		} else if (strcmp (str, RB_IR_COMMAND_MUTE) == 0) {
			gboolean mute;
			if (rb_shell_player_get_mute (plugin->shell_player, &mute, NULL)) {
				rb_shell_player_set_mute (plugin->shell_player, !mute, NULL);
			}
		} else if (strcmp (str,RB_IR_COMMAND_QUIT) == 0) {
			RBShell *shell;

			g_object_get (plugin, "object", &shell, NULL);
			rb_shell_quit (shell, NULL);
			g_object_unref (shell);
			/* the plugin will have been deactivated, so we can't continue the loop */
			break;
		}
		processed = TRUE;
	} while (ok == 0);
	g_free (code);

	return TRUE;
}