[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