[Banshee-List] [PATCH] Multimedia keys extension



Hi all,

Another patch against trunk. Basically, I've ported across a multimedia keys extension. There were two in stable - one in Core, the other as an actual extension; I've used the one in Core, which is the one that uses DBus instead of the X callouts. I did try the original MMKeys plugin, though, the SpecialKeys class seems to be borked, at least on my install. X gets mixed up with some of the requests, and thinks Backspace is F9, among other things.

Fairly simple extension, if there's anything that needs to be fixed up, feel free to nag away. :)

(Since SVN doesn't seem to give any love in the Extensions/ directory, I've got two patches attached - one's an 'svn diff' against the current tree containing the svn rm of the old files, and a few Makefile additions; the second contains the actual plugin code, which was just a bunch of diff -u commands). If there's another way to get it working, please share, heh.

Cheers,
Alex Hixon
Index: src/Extensions/Extensions.mds
===================================================================
--- src/Extensions/Extensions.mds	(revision 3027)
+++ src/Extensions/Extensions.mds	(working copy)
@@ -2,6 +2,7 @@
   <Configurations active="Debug">
     <Configuration name="Debug" ctype="CombineConfiguration">
       <Entry build="True" name="Banshee.NotificationArea" configuration="Debug" />
+      <Entry build="True" name="Banshee.MultimediaKeys" configuration="Debug" />
     </Configuration>
   </Configurations>
   <StartMode startupentry="Banshee.NotificationArea" single="True">
@@ -9,5 +10,6 @@
   </StartMode>
   <Entries>
     <Entry filename="Banshee.NotificationArea/Banshee.NotificationArea.mdp" />
+    <Entry filename="Banshee.MultimediaKeys/Banshee.MultimediaKeys.mdp" />
   </Entries>
-</Combine>
\ No newline at end of file
+</Combine>
Index: src/Extensions/Makefile.am
===================================================================
--- src/Extensions/Makefile.am	(revision 3027)
+++ src/Extensions/Makefile.am	(working copy)
@@ -1,4 +1,5 @@
 SUBDIRS = \
-	Banshee.NotificationArea
+	Banshee.NotificationArea    \
+	Banshee.MultimediaKeys
 
 MAINTAINERCLEANFILES = Makefile.in
Index: src/Plugins/Banshee.Plugins.MMKeys/Banshee.Plugins.MMKeys.mdp
===================================================================
--- src/Plugins/Banshee.Plugins.MMKeys/Banshee.Plugins.MMKeys.mdp	(revision 3027)
+++ src/Plugins/Banshee.Plugins.MMKeys/Banshee.Plugins.MMKeys.mdp	(working copy)
@@ -1,20 +0,0 @@
-<Project name="Banshee.Plugins.MMKeys" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
-  <Configurations active="Debug">
-    <Configuration name="Debug" ctype="DotNetProjectConfiguration">
-      <Output directory="." assembly="Banshee.Plugins.MMKeys" />
-      <Build debugmode="True" target="Library" />
-      <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
-      <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
-    </Configuration>
-  </Configurations>
-  <Contents>
-    <File name="MMKeysConfigPage.cs" subtype="Code" buildaction="Compile" />
-    <File name="MMKeysPlugin.cs" subtype="Code" buildaction="Compile" />
-  </Contents>
-  <References>
-    <ProjectReference type="Project" localcopy="False" refto="Banshee.Base" />
-    <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-    <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
-    <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
-  </References>
-</Project>
\ No newline at end of file
Index: src/Plugins/Banshee.Plugins.MMKeys/MMKeysPlugin.cs
===================================================================
--- src/Plugins/Banshee.Plugins.MMKeys/MMKeysPlugin.cs	(revision 3027)
+++ src/Plugins/Banshee.Plugins.MMKeys/MMKeysPlugin.cs	(working copy)
@@ -1,124 +0,0 @@
-/***************************************************************************
- *  MMKeysPlugin.cs
- *
- *  Written by Danilo Reinhardt (danilo reinhardt gmx net)
- ****************************************************************************/
-
-/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a
- *  copy of this software and associated documentation files (the "Software"),  
- *  to deal in the Software without restriction, including without limitation  
- *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
- *  and/or sell copies of the Software, and to permit persons to whom the  
- *  Software is furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in 
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- *  DEALINGS IN THE SOFTWARE. 
- */
-
-using System;
-using System.IO;
-using Gtk;
-using Gdk;
-using Mono.Unix;
-
-using Banshee.Base;
-using Banshee.Configuration;
-
-public static class PluginModuleEntry
-{
-    public static Type [] GetTypes()
-    {
-        return new Type [] {
-            typeof(Banshee.Plugins.MMKeys.MMKeysPlugin)
-        };
-    }
-}
-
-namespace Banshee.Plugins.MMKeys
-{
-	public class MMKeysPlugin : Banshee.Plugins.Plugin
-	{
-	   protected override string ConfigurationName { get { return "mmkeys"; } }
-        public override string DisplayName { get { return Catalog.GetString("Multimedia Keys"); } }
-	
-		public override string Description {
-            get {
-                return Catalog.GetString(
-                    "Adds support for multimedia keys configured through GNOME."
-                );
-            }
-        }
-
-        public override string [] Authors {
-            get {
-                return new string [] {
-                    "Danilo Reinhardt"
-                };
-            }
-        }
-
-        private SpecialKeys special_keys;
-		
-		protected override void PluginInitialize()
-        {
-            special_keys = new SpecialKeys();
-            special_keys.Delay = new TimeSpan(500 * TimeSpan.TicksPerMillisecond);
-
-            special_keys.RegisterHandler(OnSpecialKeysPressed, 
-                SpecialKey.AudioPlay,
-                SpecialKey.AudioPrev,
-                SpecialKey.AudioNext,
-                SpecialKey.AudioStop
-            );
-        }
-        
-        private void OnSpecialKeysPressed(object o, SpecialKey key)
-        {
-           switch(key) {
-                case SpecialKey.AudioPlay:
-                    Globals.ActionManager["PlayPauseAction"].Activate();
-                    break;
-                case SpecialKey.AudioNext:
-                    Globals.ActionManager["NextAction"].Activate();
-                    break;
-                case SpecialKey.AudioPrev:
-                    Globals.ActionManager["PreviousAction"].Activate();
-                    break;
-                case SpecialKey.AudioStop:
-                    PlayerEngineCore.Close();
-                    break;
-            }
-        }
-        
-        protected override void PluginDispose()
-        {
-            special_keys.UnregisterHandler(OnSpecialKeysPressed, 
-                SpecialKey.AudioPlay, 
-                SpecialKey.AudioPrev,
-                SpecialKey.AudioNext);
-            special_keys.Dispose();
-        }
-        
-        public override Gtk.Widget GetConfigurationWidget()
-        {
-            return new MMKeysConfigPage();
-        }
-        
-        public static readonly SchemaEntry<bool> EnabledSchema = new SchemaEntry<bool>(
-            "plugins.mmkeys", "enabled",
-            false,
-            "Plugin enabled",
-            "Multimedia Keys plugin enabled"
-        );
-	}
-}
Index: src/Plugins/Banshee.Plugins.MMKeys/Makefile.am
===================================================================
--- src/Plugins/Banshee.Plugins.MMKeys/Makefile.am	(revision 3027)
+++ src/Plugins/Banshee.Plugins.MMKeys/Makefile.am	(working copy)
@@ -1,28 +0,0 @@
-include $(top_srcdir)/build/Common.Makefile
-
-ASSEMBLY_NAME = Banshee.Plugins.MMKeys
-ASSEMBLY = $(ASSEMBLY_NAME).dll
-ASSEMBLY_GCONF_SCHEMA = banshee-plugin-mmkeys.schemas.in
-
-fsmondir = $(pkglibdir)/Banshee.Plugins
-fsmon_SCRIPTS = $(ASSEMBLY) $(ASSEMBLY).mdb $(ASSEMBLY).config
-
-ASSEMBLY_SOURCES = \
-	$(top_srcdir)/src/AssemblyInfo.cs \
-	$(srcdir)/MMKeysPlugin.cs \
-	$(srcdir)/MMKeysConfigPage.cs
-
-$(ASSEMBLY): $(ASSEMBLY_SOURCES) 
-	$(BUILD_LIB_BANSHEE_CORE) -out:$@ $(LINK_GTK) $(LINK_MONO_UNIX) $(ASSEMBLY_SOURCES)
-
-include $(top_srcdir)/build/gconf-schema-rules
-
-EXTRA_DIST = \
-	$(ASSEMBLY_SOURCES) \
-	$(ASSEMBLY).config.in \
-	$(ASSEMBLY_GCONF_SCHEMA)
-
-CLEANFILES = $(ASSEMBLY) *.dll *.exe
-DISTCLEANFILES = *.mdb $(schema_DATA)
-MAINTAINERCLEANFILES = Makefile.in
-
Index: src/Plugins/Banshee.Plugins.MMKeys/banshee-plugin-mmkeys.schemas.in
===================================================================
--- src/Plugins/Banshee.Plugins.MMKeys/banshee-plugin-mmkeys.schemas.in	(revision 3027)
+++ src/Plugins/Banshee.Plugins.MMKeys/banshee-plugin-mmkeys.schemas.in	(working copy)
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<gconfschemafile>
-  <schemalist>
-    <schema>
-      <key>/schemas/apps/banshee/plugins/mmkeys/enabled</key>
-      <applyto>/apps/banshee/plugins/mmkeys/enabled</applyto>
-      <owner>banshee</owner>
-      <type>bool</type>
-      <default>false</default>
-      <locale name="C">
-        <short>Plugin enabled</short>
-        <long>Multimedia Keys plugin enabled</long>
-      </locale>
-    </schema>
-  </schemalist>
-</gconfschemafile>
Index: src/Plugins/Banshee.Plugins.MMKeys/Banshee.Plugins.MMKeys.dll.config.in
===================================================================
--- src/Plugins/Banshee.Plugins.MMKeys/Banshee.Plugins.MMKeys.dll.config.in	(revision 3027)
+++ src/Plugins/Banshee.Plugins.MMKeys/Banshee.Plugins.MMKeys.dll.config.in	(working copy)
@@ -1,7 +0,0 @@
-<configuration>
-	<dllmap dll="libglib-2.0.so" target="libglib-2.0.so.0" />
-	<dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0" />
-	<dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" />
-	<dllmap dll="libbonobo-2.so" target="libbonobo-2.so.0" />
-	<dllmap dll="gdk-x11-2.0" target="libgdk-x11-2.0.so.0" />
-</configuration>
Index: src/Plugins/Banshee.Plugins.MMKeys/MMKeysConfigPage.cs
===================================================================
--- src/Plugins/Banshee.Plugins.MMKeys/MMKeysConfigPage.cs	(revision 3027)
+++ src/Plugins/Banshee.Plugins.MMKeys/MMKeysConfigPage.cs	(working copy)
@@ -1,68 +0,0 @@
-
-/***************************************************************************
- *  MMKeysConfigPage.cs
- *
- *  Copyright (C) 2006 Novell, Inc.
- *  Written by Aaron Bockover <aaron aaronbock net>
- ****************************************************************************/
-
-/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a
- *  copy of this software and associated documentation files (the "Software"),  
- *  to deal in the Software without restriction, including without limitation  
- *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
- *  and/or sell copies of the Software, and to permit persons to whom the  
- *  Software is furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in 
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- *  DEALINGS IN THE SOFTWARE.
- */
-
-using System;
-using Gtk;
-using Mono.Unix;
-
-using Banshee.Base;
-using Banshee.Widgets;
-
-namespace Banshee.Plugins.MMKeys 
-{
-    public class MMKeysConfigPage : VBox
-    {
-        public MMKeysConfigPage()
-        {    
-            Spacing = 10;
-            
-            Label title = new Label();
-            title.Markup = String.Format("<big><b>{0}</b></big>", 
-                GLib.Markup.EscapeText(Catalog.GetString("Multimedia Keyboard Shortcuts")));
-            title.Xalign = 0.0f;
-
-            Label label = new Label(Catalog.GetString(
-                "Configuration of multimedia keyboard shortcuts is done through " + 
-                "the Gnome Keyboard Shortcuts configuration applet."));
-            label.Wrap = true;
-            label.Xalign = 0.0f;
-
-            Button button = new Button(Catalog.GetString("Configure Keyboard Shortcuts"));
-            button.Clicked += delegate(object o, EventArgs args) {
-                System.Diagnostics.Process.Start("gnome-keybinding-properties");
-            };
-            
-            PackStart(title, false, false, 0);
-            PackStart(label, false, false, 0);
-            PackStart(button, false, false, 0);
-            
-            ShowAll();
-        }
-    }
-}
Index: src/Core/Banshee.Base/GnomeMMKeys.cs
===================================================================
--- src/Core/Banshee.Base/GnomeMMKeys.cs	(revision 3027)
+++ src/Core/Banshee.Base/GnomeMMKeys.cs	(working copy)
@@ -1,147 +0,0 @@
-/***************************************************************************
- *  GnomeSettingsDaemon.cs
- *
- *  Copyright (C) 2007 Novell, Inc.
- *  Written by Aaron Bockover <aaron abock org>
- *             Jan Arne Petersen <jap gnome org>
- ****************************************************************************/
-
-/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a
- *  copy of this software and associated documentation files (the "Software"),  
- *  to deal in the Software without restriction, including without limitation  
- *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
- *  and/or sell copies of the Software, and to permit persons to whom the  
- *  Software is furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in 
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- *  DEALINGS IN THE SOFTWARE. 
- */
-
-using System;
-
-using Gtk;
-using NDesk.DBus;
-
-namespace Banshee.Base
-{
-    public class GnomeMMKeys : IDisposable
-    {
-        private const string BusName = "org.gnome.SettingsDaemon";
-        private const string ObjectPath = "/org/gnome/SettingsDaemon";
-        
-        private delegate void MediaPlayerKeyPressedHandler(string application, string key);
-        
-        [Interface("org.gnome.SettingsDaemon")]
-        private interface ISettingsDaemon
-        {
-            void GrabMediaPlayerKeys(string application, uint time);
-            void ReleaseMediaPlayerKeys(string application);
-            event MediaPlayerKeyPressedHandler MediaPlayerKeyPressed;
-        }
-        
-        private static GnomeMMKeys instance;
-
-        public static void Initialize()
-        {
-            if(instance == null) {
-                try {
-                    instance = new GnomeMMKeys();
-                    LogCore.Instance.PushDebug("Enabled multimedia keys support", "Using org.gnome.SettingsDaemon");
-                } catch {
-                    instance = null;
-                }
-            }
-        }
-        
-        public static bool IsLoaded {
-            get { return instance != null; }
-        }
-        
-        private const string app_name = "Banshee";
-        
-        private ISettingsDaemon settings_daemon;
-        
-        public GnomeMMKeys()
-        {
-            settings_daemon = Bus.Session.GetObject<ISettingsDaemon>(BusName, new ObjectPath(ObjectPath));;
-
-            settings_daemon.GrabMediaPlayerKeys(app_name, 0);
-            settings_daemon.MediaPlayerKeyPressed += OnMediaPlayerKeyPressed;
-                
-            Globals.ShutdownRequested += OnShutdownRequested;
-
-            if(!Globals.UIManager.IsInitialized) {
-                Globals.UIManager.Initialized += OnInterfaceInitialized;
-            } else {
-                OnInterfaceInitialized(null, null);
-            }
-        }
-        
-        private bool OnShutdownRequested()
-        {
-            Dispose();
-            return true;
-        }
-        
-        private void OnInterfaceInitialized(object o, EventArgs args)
-        {
-            if(InterfaceElements.MainWindow != null) {
-                InterfaceElements.MainWindow.FocusInEvent += OnFocusInEvent;
-            }
-        }
-        
-        public void Dispose()
-        {
-            if(InterfaceElements.MainWindow != null) {
-                InterfaceElements.MainWindow.FocusInEvent -= OnFocusInEvent;
-            }
-            
-            if(settings_daemon == null) {
-                return;
-            }
-            
-            settings_daemon.MediaPlayerKeyPressed -= OnMediaPlayerKeyPressed;
-            settings_daemon.ReleaseMediaPlayerKeys(app_name);
-            settings_daemon = null;
-        }
-        
-        private void OnMediaPlayerKeyPressed(string application, string key)
-        {
-            if(application != app_name) {
-                return;
-            }
-            
-            switch(key) {
-                case "Play":
-                    Globals.ActionManager["PlayPauseAction"].Activate();
-                    break;
-                case "Next":
-                    Globals.ActionManager["NextAction"].Activate();
-                    break;
-                case "Previous":
-                    Globals.ActionManager["PreviousAction"].Activate();
-                    break;
-                case "Stop":
-                    PlayerEngineCore.Close();
-                    break;
-            }
-        }
-        
-        private void OnFocusInEvent(object o, FocusInEventArgs args)
-        {
-            if(settings_daemon != null) {
-                settings_daemon.GrabMediaPlayerKeys(app_name, 0);
-            }
-        }
-    }
-}
Index: src/Core/Banshee.Base/SpecialKeys.cs
===================================================================
--- src/Core/Banshee.Base/SpecialKeys.cs	(revision 3027)
+++ src/Core/Banshee.Base/SpecialKeys.cs	(working copy)
@@ -1,291 +0,0 @@
-
-/***************************************************************************
- *  SpecialKeys.cs
- *
- *  Copyright (C) 2005-2006 Novell, Inc.
- *  Written by Aaron Bockover <aaron aaronbock net>
- *             Danilo Reinhardt <danilo reinhardt gmx net>
- ****************************************************************************/
-
-/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a
- *  copy of this software and associated documentation files (the "Software"),  
- *  to deal in the Software without restriction, including without limitation  
- *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
- *  and/or sell copies of the Software, and to permit persons to whom the  
- *  Software is furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in 
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- *  DEALINGS IN THE SOFTWARE. 
- */
- 
-using System;
-using System.Collections;
-using System.Runtime.InteropServices;
-
-namespace Banshee.Base
-{
-    public delegate void SpecialKeyPressedHandler(object o, SpecialKey key);
-
-    public enum SpecialKey {
-        None = 0,
-        AudioLowerVolume = 0x1008FF11,
-        AudioMute = 0x1008FF12,
-        AudioRaiseVolume = 0x1008FF13,
-        AudioPlay = 0x1008FF14,
-        AudioStop = 0x1008FF15,
-        AudioPrev = 0x1008FF16,
-        AudioNext = 0x1008FF17
-    };
-
-    public class SpecialKeys
-    {
-        private Hashtable key_map = new Hashtable();
-        private Hashtable key_registrations = new Hashtable();
-        private IEnumerable keycode_list;
-        private TimeSpan raise_delay = new TimeSpan(0);
-        private DateTime last_raise = DateTime.MinValue;
-        
-        public SpecialKeys()
-        {
-            keycode_list = BuildKeyCodeList();
-            InitializeKeys();
-        }
-        
-        public void Dispose()
-        {
-            UnitializeKeys();
-        }
-        
-        public void RegisterHandler(SpecialKeyPressedHandler handler, params SpecialKey [] specialKeys)
-        {
-            foreach(SpecialKey specialKey in specialKeys) {
-                if(key_map.Contains(specialKey)) {
-                    int key = (int)key_map[specialKey];
-                    key_registrations[key] = Delegate.Combine(key_registrations[key] as Delegate, handler);
-                }
-            }
-        }
-        
-        public void UnregisterHandler(SpecialKeyPressedHandler handler, params SpecialKey [] specialKeys)
-        {
-            foreach(SpecialKey specialKey in specialKeys) {
-                if(key_map.Contains(specialKey)) {
-                    int key = (int)key_map[specialKey];
-                    key_registrations[key] = Delegate.Remove(key_registrations[key] as Delegate, handler); 
-                }
-            }
-        }
-        
-        private IEnumerable BuildKeyCodeList()
-        {
-            ArrayList kc_list = new ArrayList();
-
-            foreach(SpecialKey key in Enum.GetValues(typeof(SpecialKey))) {
-                IntPtr xdisplay = gdk_x11_get_default_xdisplay();
-                
-                if(!xdisplay.Equals(IntPtr.Zero)) {
-                    int keycode = XKeysymToKeycode(xdisplay, key);
-                    if(keycode != 0) {
-                        key_map[keycode] = key;
-                        key_map[key] = keycode;
-                        kc_list.Add(keycode);
-                    }
-                }
-            }
-            
-            return kc_list;
-        }
-
-        private void InitializeKeys()
-        {
-            for(int i = 0; i < Gdk.Display.Default.NScreens; i++) {
-                Gdk.Screen screen = Gdk.Display.Default.GetScreen(i);
-                foreach(int keycode in keycode_list) {
-                    GrabKey(screen.RootWindow, keycode);
-                }
-                screen.RootWindow.AddFilter(FilterKey);
-            }
-        }
-        
-        private void UnitializeKeys() 
-        {
-            for(int i = 0; i < Gdk.Display.Default.NScreens; i++) {
-                Gdk.Screen screen = Gdk.Display.Default.GetScreen(i);
-                foreach(int keycode in keycode_list) {
-                    UngrabKey(screen.RootWindow, keycode);
-                }
-                screen.RootWindow.RemoveFilter(FilterKey);
-            }
-        }
-        
-        private void GrabKey(Gdk.Window root, int keycode)
-        {
-            IntPtr xid = gdk_x11_drawable_get_xid(root.Handle);
-            IntPtr xdisplay = gdk_x11_get_default_xdisplay();
-            
-            gdk_error_trap_push();
-            
-            XGrabKey(xdisplay, keycode, XModMask.None, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Mod2, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Mod5, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Lock, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Mod2 | XModMask.Mod5, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Mod2 | XModMask.Lock, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Mod5 | XModMask.Lock, xid, true, XGrabMode.Async, XGrabMode.Async);
-            XGrabKey(xdisplay, keycode, XModMask.Mod2 | XModMask.Mod5 | XModMask.Lock, xid, true, 
-                XGrabMode.Async, XGrabMode.Async);
-        
-            gdk_flush();
-            
-            if(gdk_error_trap_pop() != 0) {
-                Console.Error.WriteLine(": Could not grab key {0} (maybe another application has grabbed this key)", keycode);
-            }
-        }
-        
-        private void UngrabKey(Gdk.Window root, int keycode)
-        {
-            IntPtr xid = gdk_x11_drawable_get_xid(root.Handle);
-            IntPtr xdisplay = gdk_x11_get_default_xdisplay();
-            
-            gdk_error_trap_push();
-            
-            XUngrabKey(xdisplay, keycode, XModMask.None, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Mod2, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Mod5, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Lock, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Mod2 | XModMask.Mod5, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Mod2 | XModMask.Lock, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Mod5 | XModMask.Lock, xid);
-            XUngrabKey(xdisplay, keycode, XModMask.Mod2 | XModMask.Mod5 | XModMask.Lock,xid);
-        
-            gdk_flush();
-            
-            if(gdk_error_trap_pop() != 0) {
-                Console.Error.WriteLine(": Could not ungrab key {0} (maybe another application has grabbed this key)", keycode);
-            }
-        }
-        
-        private Gdk.FilterReturn FilterKey(IntPtr xeventPtr, Gdk.Event gdkEvent)
-        {
-            if(DateTime.Now - last_raise < raise_delay) {
-                return Gdk.FilterReturn.Continue;
-            }
-
-            last_raise = DateTime.Now;
-            
-            XKeyEvent xevent = (XKeyEvent)Marshal.PtrToStructure(xeventPtr, typeof(XKeyEvent));
-            
-            if(xevent.type != XEventName.KeyPress) {
-                return Gdk.FilterReturn.Continue;
-            }
-
-            int keycode = (int)xevent.keycode;
-            object x = key_map[keycode];
-            
-            if(x == null) {
-                return Gdk.FilterReturn.Continue;
-            }
-            
-            SpecialKey key = (SpecialKey)key_map[keycode];
-            
-            if(key_registrations[keycode] != null) {
-                x = key_registrations[keycode];
-                if(x is SpecialKeyPressedHandler) {
-                    ((SpecialKeyPressedHandler)x)(this, key);    
-                }
-                return Gdk.FilterReturn.Remove;
-            }
-            
-            return Gdk.FilterReturn.Continue;
-        }
-        
-        public TimeSpan Delay {
-            get {
-                return raise_delay;
-            }
-            
-            set {
-                raise_delay = value;
-            }
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        private struct XKeyEvent
-        {
-            public XEventName type;
-            public IntPtr serial;
-            public bool send_event;
-            public IntPtr display;
-            public IntPtr window;
-            public IntPtr root;
-            public IntPtr subwindow;
-            public IntPtr time;
-            public int x;
-            public int y;
-            public int x_root;
-            public int x_y;
-            public uint state;
-            public uint keycode;
-            public bool same_screen;
-        }
-
-        [DllImport("libX11")]
-        private static extern int XKeysymToKeycode(IntPtr display, SpecialKey keysym);
-
-        [DllImport("libX11")]
-        private static extern void XGrabKey(IntPtr display, int keycode, XModMask modifiers, 
-            IntPtr window, bool owner_events, XGrabMode pointer_mode, XGrabMode keyboard_mode);
-            
-        [DllImport("libX11")]
-        private static extern void XUngrabKey(IntPtr display, int keycode, XModMask modifiers, 
-            IntPtr window);
-
-        [DllImport("gdk-x11-2.0")]
-        private static extern IntPtr gdk_x11_drawable_get_xid(IntPtr window);
-        
-        [DllImport("gdk-x11-2.0")]
-        private static extern IntPtr gdk_x11_get_default_xdisplay();
-        
-        [DllImport("gdk-x11-2.0")]
-        private static extern void gdk_error_trap_push();
-        
-        [DllImport("gdk-x11-2.0")]
-        private static extern int gdk_error_trap_pop();
-        
-        [DllImport("gdk-x11-2.0")]
-        private static extern void gdk_flush();
-        
-        [Flags]
-        private enum XModMask {
-            None    = 0,
-            Shift   = 1 << 0,
-            Lock    = 1 << 1,
-            Control = 1 << 2,
-            Mod1    = 1 << 3,
-            Mod2    = 1 << 4,
-            Mod3    = 1 << 5,
-            Mod4    = 1 << 6,
-            Mod5    = 1 << 7
-        }
-        
-        private enum XGrabMode {
-            Sync  = 0,
-            Async = 1
-        }
-        
-        private enum XEventName {
-            KeyPress   = 2,
-            KeyRelease = 3,
-        }
-    }
-}
Index: build/build.environment.mk
===================================================================
--- build/build.environment.mk	(revision 3027)
+++ build/build.environment.mk	(working copy)
@@ -133,8 +133,10 @@
 DIR_EXTENSIONS = $(top_srcdir)/src/Extensions
 
 DIR_EXTENSION_NOTIFICATIONAREA = $(DIR_EXTENSIONS)/Banshee.NotificationArea
-MONO_ADDINS_PATH += $(DIR_EXTENSION_NOTIFICATIONAREA)
+DIR_EXTENSION_MULTIMEDIAKEYS = $(DIR_EXTENSIONS)/Banshee.MultimediaKeys
+MONO_ADDINS_PATH += $(DIR_EXTENSION_NOTIFICATIONAREA) $(DIR_EXTENSION_MULTIMEDIAKEYS)
 REF_EXTENSION_NOTIFICATIONAREA = $(LINK_BANSHEE_THICKCLIENT_DEPS)
+REF_EXTENSION_MULTIMEDIAKEYS = $(LINK_BANSHEE_THICKCLIENT_DEPS)
 
 
 # Build rules
Index: configure.ac
===================================================================
--- configure.ac	(revision 3027)
+++ configure.ac	(working copy)
@@ -147,6 +147,7 @@
 
 src/Extensions/Makefile
 src/Extensions/Banshee.NotificationArea/Makefile
+src/Extensions/Banshee.MultimediaKeys/Makefile
 
 src/Extras/Makefile
 src/Extras/Boo/Makefile
--- /dev/null	2008-01-27 02:24:35.204001008 +1100
+++ src/Extensions/Banshee.MultimediaKeys/Makefile.am	2008-01-27 06:28:02.000000000 +1100
@@ -0,0 +1,12 @@
+ASSEMBLY = Banshee.MultimediaKeys
+TARGET = library
+LINK = $(REF_EXTENSION_MULTIMEDIAKEYS)
+
+SOURCES =  \
+	Banshee.MultimediaKeys/MultimediaKeysService.cs 
+
+RESOURCES =  \
+	Resources/Banshee.MultimediaKeys.addin.xml
+
+include $(top_srcdir)/build/build.mk
+
--- /dev/null	2008-01-27 02:24:35.204001008 +1100
+++ src/Extensions/Banshee.MultimediaKeys/Resources/Banshee.MultimediaKeys.addin.xml	2008-01-27 07:07:54.000000000 +1100
@@ -0,0 +1,18 @@
+<Addin  id="Banshee.MultimediaKeys"
+        name="Multimedia Keys"
+        description="Provides support for handling playback through the use of keyboard controls."
+        url="http://www.banshee-project.org/";
+        version="1.0">
+
+  <Dependencies>
+    <Addin id="Banshee.Services" version="1.0"/>
+    <!--
+        <Addin id="Banshee.ThickClient" version="1.0"/>
+    -->
+  </Dependencies>
+
+  <Extension path="/Banshee/ServiceManager/Service">
+    <TypeExtensionNode class="Banshee.MultimediaKeys.MultimediaKeysService"/>
+  </Extension>
+  
+</Addin>
--- /dev/null	2008-01-27 02:24:35.204001008 +1100
+++ src/Extensions/Banshee.MultimediaKeys/Banshee.MultimediaKeys/MultimediaKeysService.cs	2008-01-27 07:08:09.000000000 +1100
@@ -0,0 +1,120 @@
+//
+// MultimediaKeyService.cs
+//
+// Author:
+//   Alexander Hixon <hixon alexander mediati org>
+//
+// Based on code by:
+//   Aaron Bockover <aaron abock org>
+//   Jan Arne Petersen <jap gnome org>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Gtk;
+using Mono.Unix;
+
+using Banshee.ServiceStack;
+using Banshee.Configuration;
+using NDesk.DBus;
+
+namespace Banshee.MultimediaKeys
+{
+    public class MultimediaKeysService : IService, IDisposable
+    {
+        private const string BusName = "org.gnome.SettingsDaemon";
+        private const string ObjectPath = "/org/gnome/SettingsDaemon";
+        private ISettingsDaemon settings_daemon;
+        
+        private delegate void MediaPlayerKeyPressedHandler (string application, string key);
+        
+        [Interface("org.gnome.SettingsDaemon")]
+        private interface ISettingsDaemon
+        {
+            void GrabMediaPlayerKeys (string application, uint time);
+            void ReleaseMediaPlayerKeys (string application);
+            event MediaPlayerKeyPressedHandler MediaPlayerKeyPressed;
+        }
+                
+        private const string app_name = "Banshee";
+    
+        public MultimediaKeysService ()
+        {
+            // TODO: Add something like ServiceManager.NotifyStartup ("InterfaceActionService", Initialize);
+            
+            if (ServiceManager.Contains ("InterfaceActionService")) {
+                Initialize ();
+            } else {
+                ServiceManager.ServiceStarted += delegate (ServiceStartedArgs args) {
+                   if (args.Service is Banshee.Gui.InterfaceActionService) {
+                       Initialize ();
+                   }
+                };
+            }
+        }
+        
+        private void Initialize ()
+        {
+            settings_daemon = Bus.Session.GetObject<ISettingsDaemon> (BusName, new ObjectPath (ObjectPath));;
+            settings_daemon.GrabMediaPlayerKeys (app_name, 0);
+            settings_daemon.MediaPlayerKeyPressed += OnMediaPlayerKeyPressed;
+        }
+  
+        public void Dispose()
+        {
+            if (settings_daemon == null) {
+                return;
+            }
+            
+            settings_daemon.MediaPlayerKeyPressed -= OnMediaPlayerKeyPressed;
+            settings_daemon.ReleaseMediaPlayerKeys (app_name);
+            settings_daemon = null;
+        }
+        
+        private void OnMediaPlayerKeyPressed (string application, string key)
+        {
+            if (application != app_name) {
+                return;
+            }
+            
+            switch(key) {
+                case "Play":
+                    ServiceManager.PlayerEngine.TogglePlaying ();
+                    break;
+                case "Next":
+                    ServiceManager.PlaybackController.Next ();
+                    break;
+                case "Previous":
+                    ServiceManager.PlaybackController.Previous ();
+                    break;
+                case "Stop":
+                    ServiceManager.PlayerEngine.Close ();
+                    break;
+            }
+        }
+        
+        string IService.ServiceName {
+            get { return "MultimediaKeysService"; }
+        }
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]