Hi,
this patch adds support for Multimedia Keys to Rhythmbox.
You need to add --enable-mmkeys to the configure options to enable the
Multimedia Keys support.
Regards
Jan Arne Petersen
? lib/egg/Makefile.in
? lib/widgets/.rb-link.c.swp
Index: configure.ac
===================================================================
RCS file: /cvs/gnome/rhythmbox/configure.ac,v
retrieving revision 1.21
diff -u -r1.21 configure.ac
--- configure.ac 15 Aug 2003 21:25:26 -0000 1.21
+++ configure.ac 16 Aug 2003 12:56:49 -0000
@@ -222,6 +222,14 @@
fi
AM_CONDITIONAL(HAVE_MUSICBRAINZ,test "x$enable_musicbrainz" = "xyes")
+dnl Multimedia Keys support
+AC_ARG_ENABLE(mmkeys, AC_HELP_STRING([--enable-mmkeys],
+ [build with Multimedia Keys support]))
+if test x"$enable_mmkeys" = xyes; then
+ AC_DEFINE(HAVE_MMKEYS, 1, [define if Multimedia Keys are enabled])
+fi
+AM_CONDITIONAL(HAVE_MMKEYS, test "x$enable_mmkeys" = "xyes")
+
dnl CD Audio support
dnl AC_ARG_ENABLE(audiocd, AC_HELP_STRING([--enable-audiocd],
dnl [build with Audio CD support]),enable_audiocd=yes)
Index: shell/rb-shell-player.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell-player.c,v
retrieving revision 1.67
diff -u -r1.67 rb-shell-player.c
--- shell/rb-shell-player.c 11 Aug 2003 17:46:58 -0000 1.67
+++ shell/rb-shell-player.c 16 Aug 2003 12:56:52 -0000
@@ -31,6 +31,12 @@
#include <libgnome/gnome-i18n.h>
#include <monkey-media.h>
+#ifdef HAVE_MMKEYS
+#include <X11/Xlib.h>
+#include <X11/XF86keysym.h>
+#include <gdk/gdkx.h>
+#endif /* HAVE_MMKEYS */
+
#include "rb-shell-player.h"
#include "rb-stock-icons.h"
#include "rb-glade-helpers.h"
@@ -136,6 +142,14 @@
void buffering_end_cb (MonkeyMediaPlayer *player, gpointer data);
void buffering_begin_cb (MonkeyMediaPlayer *player, gpointer data);
+#ifdef HAVE_MMKEYS
+static void grab_mmkey (int key_code, GdkWindow *root);
+static GdkFilterReturn filter_mmkeys (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data);
+static void rb_shell_player_init_mmkeys (RBShellPlayer *shell_player);
+#endif /* HAVE_MMKEYS */
+
#define MENU_PATH_PLAY "/menu/Controls/Play"
#define TRAY_PATH_PLAY "/popups/TrayPopup/Play"
@@ -411,6 +425,11 @@
eel_gconf_notification_add (CONF_STATE,
(GConfClientNotifyFunc) rb_shell_player_state_changed_cb,
player);
+
+#ifdef HAVE_MMKEYS
+ /* Enable Multimedia Keys */
+ rb_shell_player_init_mmkeys (player);
+#endif /* HAVE_MMKEYS */
}
static void
@@ -1576,3 +1595,113 @@
return shell_player->priv->url;
}
+#ifdef HAVE_MMKEYS
+static void
+grab_mmkey (int key_code, GdkWindow *root)
+{
+ gdk_error_trap_push ();
+
+ XGrabKey (GDK_DISPLAY (), key_code,
+ 0,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ Mod2Mask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ Mod5Mask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ LockMask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ Mod2Mask | Mod5Mask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ Mod2Mask | LockMask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ Mod5Mask | LockMask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey (GDK_DISPLAY (), key_code,
+ Mod2Mask | Mod5Mask | LockMask,
+ GDK_WINDOW_XID (root), True,
+ GrabModeAsync, GrabModeAsync);
+
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ rb_debug ("Error grabbing key");
+ }
+}
+
+static GdkFilterReturn
+filter_mmkeys (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ XEvent *xev;
+ XKeyEvent *key;
+ RBShellPlayer *player;
+
+ xev = (XEvent *) xevent;
+ if (xev->type != KeyPress) {
+ return GDK_FILTER_CONTINUE;
+ }
+
+ key = (XKeyEvent *) xevent;
+
+ player = (RBShellPlayer *)data;
+
+ if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPlay) == key->keycode) {
+ rb_shell_player_playpause (player);
+ return GDK_FILTER_REMOVE;
+ } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioStop) == key->keycode) {
+ rb_shell_player_set_playing_source (player, NULL);
+ return GDK_FILTER_REMOVE;
+ } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev) == key->keycode) {
+ rb_shell_player_do_previous (player);
+ return GDK_FILTER_REMOVE;
+ } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioNext) == key->keycode) {
+ rb_shell_player_do_next (player);
+ return GDK_FILTER_REMOVE;
+ } else {
+ return GDK_FILTER_CONTINUE;
+ }
+}
+
+static void
+rb_shell_player_init_mmkeys (RBShellPlayer *shell_player)
+{
+ gint keycodes[] = {0, 0, 0, 0};
+ GdkDisplay *display;
+ GdkScreen *screen;
+ GdkWindow *root;
+ guint i, j;
+
+ keycodes[0] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPlay);
+ keycodes[1] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioStop);
+ keycodes[2] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev);
+ keycodes[3] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioNext);
+
+ display = gdk_display_get_default ();
+
+ for (i = 0; i < gdk_display_get_n_screens (display); i++) {
+ screen = gdk_display_get_screen (display, i);
+
+ if (screen != NULL) {
+ root = gdk_screen_get_root_window (screen);
+
+ for (j = 0; j < 4 ; j++) {
+ grab_mmkey (keycodes[j], root);
+ }
+
+ gdk_window_add_filter (root, filter_mmkeys,
+ (gpointer) shell_player);
+ }
+ }
+}
+#endif /* HAVE_MMKEYS */
Something like this is sorely needed IMHO. Sure you can right click on
the tray icon, but that takes precision, I need to be able to use my
keyboard's media keys. I do think it should be done through ACME or
what ever the the Gnome-wide way of doing this is, that way key binding
wont be stolen by Rhythmbox if they were already associated with ACME
for some other purpose. Am I on the right track here? I'd like this
to make it into 0.5.0, but I'd rather make sure we do it the right way
and put it into 0.5.1. Speaking of 0.5.1 how often does Rhythmbox
plan to make releases? Will they be times releases or will they be
feature based? Colin?