[Xfce4-commits] <parole:master> Added XF86 button handler on display.
Ali Abdallah
noreply at xfce.org
Tue Nov 17 09:30:02 CET 2009
Updating branch refs/heads/master
to 1455521efb23df728d589cd781f4429e3481584b (commit)
from 9952d018343cf177cba4dbf06f40f70749004dcb (commit)
commit 1455521efb23df728d589cd781f4429e3481584b
Author: Ali Abdallah <ali at ali-xfce.org>
Date: Mon Nov 16 12:56:11 2009 +0100
Added XF86 button handler on display.
parole/Makefile.am | 10 ++-
parole/parole-button.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++
parole/parole-button.h | 71 ++++++++++++++
parole/parole-player.c | 43 ++++++++
4 files changed, 370 insertions(+), 3 deletions(-)
diff --git a/parole/Makefile.am b/parole/Makefile.am
index 5129d92..995396d 100644
--- a/parole/Makefile.am
+++ b/parole/Makefile.am
@@ -70,7 +70,8 @@ NOINST_HFILES = \
parole-subtitle-encoding.h \
parole-open-location.h \
parole-disc-menu.h \
- parole-session.h
+ parole-session.h \
+ parole-button.h
libparole_headers = \
$(INST_HFILES)
@@ -111,7 +112,8 @@ libparole_la_SOURCES = \
parole-subtitle-encoding.c \
parole-open-location.c \
parole-disc-menu.c \
- parole-session.c
+ parole-session.c \
+ parole-button.c
libparole_la_LDFLAGS = \
$(PAROLE_LDFLAGS)
@@ -133,7 +135,8 @@ parole_glib_enum_headers = \
parole-plugin.h \
parole-pl-parser.h \
parole-stream.h \
- parole-conf.h
+ parole-conf.h \
+ parole-button.h
# Parole Browser Player plugin
@@ -170,6 +173,7 @@ enum-gtypes.c: $(parole_glib_enum_headers) Makefile
--fhead "#include \"parole-pl-parser.h\"\n\n" \
--fhead "#include \"parole-stream.h\"\n\n" \
--fhead "#include \"parole-conf.h\"\n\n" \
+ --fhead "#include \"parole-button.h\"\n\n" \
--fprod "\n/* enumerations from \"@filename@\" */" \
--vhead "GType\n at enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G at Type@Value values[] = {" \
--vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
diff --git a/parole/parole-button.c b/parole/parole-button.c
new file mode 100644
index 0000000..29841ea
--- /dev/null
+++ b/parole/parole-button.c
@@ -0,0 +1,249 @@
+/*
+ * * Copyright (C) 2008-2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+/*
+ * Based on code from gpm-button (gnome power manager)
+ * Copyright (C) 2006-2007 Richard Hughes <richard at hughsie.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_XF86_KEYSYM
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/X.h>
+#include <X11/XF86keysym.h>
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "parole-button.h"
+#include "parole-debug.h"
+#include "enum-gtypes.h"
+
+static void parole_button_finalize (GObject *object);
+
+#define PAROLE_BUTTON_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE((o), PAROLE_TYPE_BUTTON, ParoleButtonPrivate))
+
+static struct
+{
+ ParoleButtonKey key;
+ guint key_code;
+} parole_key_map [PAROLE_KEY_NUMBERS] = { {0, 0}, };
+
+struct ParoleButtonPrivate
+{
+ GdkScreen *screen;
+ GdkWindow *window;
+
+};
+
+enum
+{
+ BUTTON_PRESSED,
+ LAST_SIGNAL
+};
+
+#define DUPLICATE_SHUTDOWN_TIMEOUT 4.0f
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE(ParoleButton, parole_button, G_TYPE_OBJECT)
+
+static guint
+parole_button_get_key (unsigned int keycode)
+{
+ ParoleButtonKey key = PAROLE_KEY_UNKNOWN;
+
+ guint i;
+
+ for ( i = 0; i < G_N_ELEMENTS (parole_key_map); i++)
+ {
+ if ( parole_key_map [i].key_code == keycode )
+ key = parole_key_map [i].key;
+ }
+
+ return key;
+}
+
+static GdkFilterReturn
+parole_button_filter_x_events (GdkXEvent *xevent, GdkEvent *ev, gpointer data)
+{
+ ParoleButtonKey key;
+ ParoleButton *button;
+
+ XEvent *xev = (XEvent *) xevent;
+
+ if ( xev->type != KeyPress )
+ return GDK_FILTER_CONTINUE;
+
+ key = parole_button_get_key (xev->xkey.keycode);
+
+ if ( key != PAROLE_KEY_UNKNOWN )
+ {
+ button = (ParoleButton *) data;
+
+ PAROLE_DEBUG_ENUM ("Key press", key, ENUM_GTYPE_BUTTON_KEY);
+
+ g_signal_emit (G_OBJECT(button), signals[BUTTON_PRESSED], 0, key);
+ return GDK_FILTER_REMOVE;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static gboolean
+parole_button_grab_keystring (ParoleButton *button, guint keycode)
+{
+ Display *display;
+ guint ret;
+ guint modmask = 0;
+
+ display = GDK_DISPLAY ();
+
+ gdk_error_trap_push ();
+
+ ret = XGrabKey (display, keycode, modmask,
+ GDK_WINDOW_XID (button->priv->window), True,
+ GrabModeAsync, GrabModeAsync);
+
+ if ( ret == BadAccess )
+ {
+ g_warning ("Failed to grab modmask=%u, keycode=%li",
+ modmask, (long int) keycode);
+ return FALSE;
+ }
+
+ ret = XGrabKey (display, keycode, LockMask | modmask,
+ GDK_WINDOW_XID (button->priv->window), True,
+ GrabModeAsync, GrabModeAsync);
+
+ if (ret == BadAccess)
+ {
+ g_warning ("Failed to grab modmask=%u, keycode=%li",
+ LockMask | modmask, (long int) keycode);
+ return FALSE;
+ }
+
+ gdk_flush ();
+ gdk_error_trap_pop ();
+ return TRUE;
+}
+
+
+static gboolean
+parole_button_xevent_key (ParoleButton *button, guint keysym , ParoleButtonKey key)
+{
+ guint keycode = XKeysymToKeycode (GDK_DISPLAY(), keysym);
+
+ if ( keycode == 0 )
+ {
+ g_warning ("could not map keysym %x to keycode\n", keysym);
+ return FALSE;
+ }
+
+ if ( !parole_button_grab_keystring(button, keycode))
+ {
+ g_warning ("Failed to grab %i\n", keycode);
+ return FALSE;
+ }
+
+ PAROLE_DEBUG_ENUM_FULL (key, ENUM_GTYPE_BUTTON_KEY, "Grabbed key %li ", (long int) keycode);
+
+ parole_key_map [key].key_code = keycode;
+ parole_key_map [key].key = key;
+
+ return TRUE;
+}
+
+static void
+parole_button_setup (ParoleButton *button)
+{
+ button->priv->screen = gdk_screen_get_default ();
+ button->priv->window = gdk_screen_get_root_window (button->priv->screen);
+
+ parole_button_xevent_key (button, XF86XK_AudioPlay, PAROLE_KEY_AUDIO_PLAY);
+ parole_button_xevent_key (button, XF86XK_AudioStop, PAROLE_KEY_AUDIO_STOP);
+ parole_button_xevent_key (button, XF86XK_AudioPrev, PAROLE_KEY_AUDIO_PREV);
+ parole_button_xevent_key (button, XF86XK_AudioNext, PAROLE_KEY_AUDIO_NEXT);
+
+ gdk_window_add_filter (button->priv->window,
+ parole_button_filter_x_events, button);
+}
+
+static void
+parole_button_class_init(ParoleButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ signals [BUTTON_PRESSED] =
+ g_signal_new ("button-pressed",
+ PAROLE_TYPE_BUTTON,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleButtonClass, button_pressed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1, ENUM_GTYPE_BUTTON_KEY);
+
+ object_class->finalize = parole_button_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParoleButtonPrivate));
+}
+
+static void
+parole_button_init (ParoleButton *button)
+{
+ button->priv = PAROLE_BUTTON_GET_PRIVATE (button);
+
+ button->priv->screen = NULL;
+ button->priv->window = NULL;
+
+ parole_button_setup (button);
+}
+
+static void
+parole_button_finalize (GObject *object)
+{
+ G_OBJECT_CLASS(parole_button_parent_class)->finalize(object);
+}
+
+ParoleButton *
+parole_button_new (void)
+{
+ ParoleButton *button = NULL;
+
+ button = g_object_new (PAROLE_TYPE_BUTTON, NULL);
+
+ return button;
+}
+
+#endif /*HAVE_XF86_KEYSYM*/
diff --git a/parole/parole-button.h b/parole/parole-button.h
new file mode 100644
index 0000000..3eca4a0
--- /dev/null
+++ b/parole/parole-button.h
@@ -0,0 +1,71 @@
+/*
+ * * Copyright (C) 2008-2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_BUTTON_H
+#define __PAROLE_BUTTON_H
+
+#include <glib-object.h>
+
+typedef enum
+{
+ PAROLE_KEY_UNKNOWN,
+ PAROLE_KEY_AUDIO_PLAY,
+ PAROLE_KEY_AUDIO_STOP,
+ PAROLE_KEY_AUDIO_PREV,
+ PAROLE_KEY_AUDIO_NEXT,
+ PAROLE_KEY_NUMBERS,
+
+} ParoleButtonKey;
+
+#ifdef HAVE_XF86_KEYSYM
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_BUTTON (parole_button_get_type () )
+#define PAROLE_BUTTON(o) (G_TYPE_CHECK_INSTANCE_CAST((o), PAROLE_TYPE_BUTTON, ParoleButton))
+#define PAROLE_IS_BUTTON(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), PAROLE_TYPE_BUTTON))
+
+typedef struct ParoleButtonPrivate ParoleButtonPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParoleButtonPrivate *priv;
+
+} ParoleButton;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+ void (*button_pressed) (ParoleButton *button,
+ ParoleButtonKey type);
+
+} ParoleButtonClass;
+
+GType parole_button_get_type (void) G_GNUC_CONST;
+
+ParoleButton *parole_button_new (void);
+
+G_END_DECLS
+
+#endif /*HAVE_XF86_KEYSYM*/
+
+#endif /* __PAROLE_BUTTON_H */
diff --git a/parole/parole-player.c b/parole/parole-player.c
index 322e31d..9255ba4 100644
--- a/parole/parole-player.c
+++ b/parole/parole-player.c
@@ -55,6 +55,8 @@
#include "parole-rc-utils.h"
#include "parole-utils.h"
#include "parole-session.h"
+#include "parole-debug.h"
+#include "parole-button.h"
#include "enum-gtypes.h"
#include "parole-debug.h"
@@ -193,6 +195,9 @@ struct ParolePlayerPrivate
ParoleConf *conf;
ParoleDiscMenu *disc_menu;
ParoleSession *session;
+#ifdef HAVE_XF86_KEYSYM
+ ParoleButton *button;
+#endif
GtkRecentManager *recent;
@@ -1293,6 +1298,10 @@ parole_player_finalize (GObject *object)
g_object_unref (player->priv->conf);
g_object_unref (player->priv->screen_saver);
+#ifdef HAVE_XF86_KEYSYM
+ g_object_unref (player->priv->button);
+#endif
+
gtk_widget_destroy (player->priv->fs_window);
G_OBJECT_CLASS (parole_player_parent_class)->finalize (object);
@@ -1420,6 +1429,34 @@ parole_player_key_press (GtkWidget *widget, GdkEventKey *ev, ParolePlayer *playe
return parole_player_handle_key_press (ev, player);
}
+#ifdef HAVE_XF86_KEYSYM
+static void
+parole_player_button_pressed_cb (ParoleButton *button, ParoleButtonKey key, ParolePlayer *player)
+{
+ PAROLE_DEBUG_ENUM ("Button Press:", key, ENUM_GTYPE_BUTTON_KEY);
+
+ switch (key)
+ {
+ case PAROLE_KEY_AUDIO_PLAY:
+ parole_player_play_pause_clicked (NULL, player);
+ break;
+ case PAROLE_KEY_AUDIO_STOP:
+ parole_player_stop_clicked (NULL, player);
+ break;
+ case PAROLE_KEY_AUDIO_PREV:
+ if ( !parole_disc_menu_seek_prev (player->priv->disc_menu))
+ parole_player_play_prev (player);
+ break;
+ case PAROLE_KEY_AUDIO_NEXT:
+ if ( !parole_disc_menu_seek_next (player->priv->disc_menu))
+ parole_player_play_next (player, FALSE);
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
static void
parole_player_session_die_cb (ParolePlayer *player)
{
@@ -1695,6 +1732,12 @@ parole_player_init (ParolePlayer *player)
g_object_unref (builder);
+#ifdef HAVE_XF86_KEYSYM
+ player->priv->button = parole_button_new ();
+ g_signal_connect (player->priv->button, "button-pressed",
+ G_CALLBACK (parole_player_button_pressed_cb), player);
+#endif
+
parole_player_dbus_init (player);
}
More information about the Xfce4-commits
mailing list