Re: [Banshee-List] Multimediakeys Plugin
- From: Danilo Reinhardt <danilo reinhardt gmx net>
- To: banshee-list gnome org
- Subject: Re: [Banshee-List] Multimediakeys Plugin
- Date: Fri, 27 Jan 2006 10:30:23 +0100
Hello Aaron,
i did no changes to specialkeys.cs file. I copied it over to a new class
MMKeysSpecialKeys. Mainly because i dont know much about c# (it was my
the first try :) ). But you are right, it would be better to modify
specialkeys.cs with my changes. I made a diff/patch but the filename
must be changed inside the patch must be changed :)
I also modified the plugin itself to use the SpecialKeys inside
Banshee.Base, hopefully it works, i did'nt tried it, but if there are
problems they should be only small ones.
Did you plan any other plugins at the moment?
Bye Danilo
Am Donnerstag, den 26.01.2006, 15:52 -0500 schrieb Aaron Bockover:
> Also, I'd like the SpecialKeys.cs code to actually remain in
> Banshee.Base, as it can potentially be used for more than just
> MM-specific bindings. The actual binding of the MM-keys to control
> playback should be done in the plugin, like you have.
>
> Thanks,
> Aaron
>
> On Thu, 2006-01-26 at 19:15 +0100, Danilo Reinhardt wrote:
> > Hello,
> >
> > im new to banshee and this list. I like banshee and it fits my needs.
> > The only thing i missed was the support for x11 multimedia keys. I found
> > this support in the code, but it is commented out. To readd it again
> > i've create a small plugin
> >
> > I have "copied" the commented out code in latest banshee release 0.10.4
> > for multimedia key handling to a separate plugin. My changes are some
> > error handling and code for proper ungrabbing the keys.
> >
> > I dont know why there was a decision to exclude this code from banshee,
> > but i think to add a plugin would be a good solution for the moment (or
> > longer) to get back this x11 integration capability. A least i hope
> > it :) And I hope this plugin will be added to the main plugins.
> >
> > I doesnt tried to compile using the makefiles, maybe is miss something
> > to add in it.
> >
> > Bye Danilo
> >
> > _______________________________________________
> > Banshee-list mailing list
> > Banshee-list gnome org
> > http://mail.gnome.org/mailman/listinfo/banshee-list
>
> _______________________________________________
> Banshee-list mailing list
> Banshee-list gnome org
> http://mail.gnome.org/mailman/listinfo/banshee-list
>
--- Banshee.Base/SpecialKeys.cs 2005-12-04 22:53:16.000000000 +0100
+++ Banshee.Plugins/MMKeys/SpecialKeys.cs 2006-01-27 10:18:14.000000000 +0100
@@ -2,8 +2,8 @@
/***************************************************************************
* SpecialKeys.cs
*
- * Copyright (C) 2005 Novell
- * Written by Aaron Bockover (aaron aaronbock net)
+ * Written by Aaron Bockover (aaron aaronbock net)
+ * Modified by Danilo Reinhardt (danilo reinhardt gmx net)
****************************************************************************/
/* THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW:
@@ -53,46 +53,102 @@
private TimeSpan raise_delay = new TimeSpan(0);
private DateTime last_raise = DateTime.MinValue;
+ private bool keysInited;
+
public SpecialKeys()
{
InitializeKeys();
}
+ ~SpecialKeys() {
+ UnitializeKeys();
+ }
+
public void RegisterHandler(SpecialKeyPressedHandler handler, params SpecialKey [] specialKeys)
{
- foreach(SpecialKey specialKey in specialKeys) {
- int key = (int)key_map[specialKey];
- key_registrations[key] = Delegate.Combine(key_registrations[key] as Delegate, handler);
+ 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) {
- int key = (int)key_map[specialKey];
- key_registrations[key] = Delegate.Remove(key_registrations[key] as Delegate, handler);
+ if (key_map.Contains(specialKey)) {
+ int key = (int)key_map[specialKey];
+ key_registrations[key] = Delegate.Remove(key_registrations[key] as Delegate, handler);
+ }
}
}
+ public void UngrabKeys() {
+ UnitializeKeys();
+ }
+
private void InitializeKeys()
{
- ArrayList kc_list = new ArrayList();
+ if (!keysInited) {
+ 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);
+ }
+ }
+ }
+
+ for(int i = 0; i < Gdk.Display.Default.NScreens; i++) {
+ Gdk.Screen screen = Gdk.Display.Default.GetScreen(i);
+ foreach(int keycode in kc_list)
+ {
+ GrabKey(screen.RootWindow, keycode);
+ }
+ screen.RootWindow.AddFilter(FilterKey);
+ }
+ keysInited = true;
+ }
+
+
+ }
+
+
+ private void UnitializeKeys() {
+ if (keysInited) {
+ 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);
+ }
+ }
+ }
+ for(int i = 0; i < Gdk.Display.Default.NScreens; i++) {
+ Gdk.Screen screen = Gdk.Display.Default.GetScreen(i);
+ foreach(int keycode in kc_list)
+ {
+ UngrabKey(screen.RootWindow, keycode);
+ }
+ screen.RootWindow.RemoveFilter(FilterKey);
+ }
+ keysInited = false;
+ }
- foreach(SpecialKey key in Enum.GetValues(typeof(SpecialKey))) {
- int keycode = XKeysymToKeycode(gdk_x11_get_default_xdisplay(), key);
- key_map[keycode] = key;
- key_map[key] = keycode;
- kc_list.Add(keycode);
- }
-
- for(int i = 0; i < Gdk.Display.Default.NScreens; i++) {
- Gdk.Screen screen = Gdk.Display.Default.GetScreen(i);
- foreach(int keycode in kc_list) {
- GrabKey(screen.RootWindow, keycode);
- }
-
- screen.RootWindow.AddFilter(FilterKey);
- }
}
private void GrabKey(Gdk.Window root, int keycode)
@@ -112,8 +168,31 @@
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}", keycode);
+ 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);
}
}
@@ -131,20 +210,20 @@
last_raise = DateTime.Now;
- 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){
+ 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.Remove;
+ }
return Gdk.FilterReturn.Continue;
}
@@ -185,18 +264,25 @@
[DllImport("libX11")]
extern static void XGrabKey(IntPtr display, int keycode, XModMask modifiers,
IntPtr window, bool owner_events, XGrabMode pointer_mode, XGrabMode keyboard_mode);
+
+ [DllImport("libX11")]
+ extern static void XUngrabKey(IntPtr display, int keycode, XModMask modifiers,
+ IntPtr window);
- [DllImport("gdk-x11-2.0")]
- static extern IntPtr gdk_x11_drawable_get_xid(IntPtr window);
+ [DllImport("libgdk-x11-2.0")]
+ extern static IntPtr gdk_x11_drawable_get_xid(IntPtr window);
+
+ [DllImport("libgdk-x11-2.0")]
+ extern static IntPtr gdk_x11_get_default_xdisplay();
- [DllImport("gdk-x11-2.0")]
- static extern IntPtr gdk_x11_get_default_xdisplay();
+ [DllImport("libgdk-x11-2.0")]
+ extern static void gdk_error_trap_push();
- [DllImport("gdk-x11-2.0")]
- static extern void gdk_error_trap_push();
+ [DllImport("libgdk-x11-2.0")]
+ extern static int gdk_error_trap_pop();
- [DllImport("gdk-x11-2.0")]
- static extern int gdk_error_trap_pop();
+ [DllImport("libgdk-x11-2.0")]
+ extern static void gdk_flush();
[Flags]
private enum XModMask {
/* -*- Mode: csharp; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: t -*- */
/***************************************************************************
* 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;
namespace Banshee.Plugins.MMKeysPlugin
{
public class MMKeysPlugin : Banshee.Plugins.Plugin
{
private Action playAction;
private Action nextTrackAction;
private Action prevTrackAction;
private SpecialKeys special_keys;
protected override string ConfigurationName { get { return "MMKeysPlugin"; } }
public override string DisplayName { get { return "Multimediakeys"; } }
public override string Description {
get {
return Catalog.GetString(
"Adding support for configured gnome multimedia keys."
);
}
}
public override string [] Authors {
get {
return new string [] {
"Danilo Reinhardt"
};
}
}
protected override void PluginInitialize()
{
playAction = Globals.ActionManager["PlayPauseAction"];
nextTrackAction = Globals.ActionManager["NextAction"];
prevTrackAction = Globals.ActionManager["PreviousAction"];
try {
if((bool)Globals.Configuration.Get(GConfKeys.EnableSpecialKeys)) {
special_keys = new SpecialKeys();
special_keys.Delay = new TimeSpan(350 * TimeSpan.TicksPerMillisecond);
special_keys.RegisterHandler(OnSpecialKeysPressed,
SpecialKey.AudioPlay,
SpecialKey.AudioPrev,
SpecialKey.AudioNext
);
}
} catch(GConf.NoSuchKeyException) {
} catch(Exception e) {
special_keys = null;
Console.WriteLine (e.Message);
LogCore.Instance.PushWarning(Catalog.GetString("Could not setup special keys"), e.Message, false);
}
Console.WriteLine ("MMKeys: loaded");
}
private void OnSpecialKeysPressed(object o, SpecialKey key)
{
switch(key) {
case SpecialKey.AudioPlay:
playAction.Activate();
break;
case SpecialKey.AudioNext:
nextTrackAction.Activate();
break;
case SpecialKey.AudioPrev:
prevTrackAction.Activate();
break;
}
}
protected override void PluginDispose()
{
special_keys.UnregisterHandler(OnSpecialKeysPressed,
SpecialKey.AudioPlay,
SpecialKey.AudioPrev,
SpecialKey.AudioNext
);
special_keys.UngrabKeys();
special_keys = null;
playAction = null;
nextTrackAction = null;
prevTrackAction = null;
Console.WriteLine ("MMKeys: unloaded");
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]