Ivan's Space

Writing about leadership, management, emotional resiliency, software engineering, tech, gadgets.




read

A few days ago I wanted to make a plugin for Gaim to control Banshee trough. E.g “/bnext” will change the track to the next one and “/bnp” will do a “/me is now playing Artist – Track Name”. Basically childish stuff. I hacked on Banshee and found that the design is really nice and it took me a couple of minutes to find the RemotePlayer dbus interface. (I am slow I know, I know. :) ). Then I was nicely surprised by the fact that there *seemed* to exist mono bindings for gaim. Well actually there was a mono plugin loader, which is broken due to the fact it doesn’t set the ID’s of the plugins and then the unloader goes boom and segfaults. Then the actual mono bindings are missing… well there is something like…

Account account = Accounts.Find ("194073396", "prpl-oscar");

...
namespace Gaim
{
	public class Signal
	{
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		extern private static int _connect(IntPtr handle, object plugin, string signal, object evnt);
		
		public delegate void Handler(object[] args);
		
		public static int connect(IntPtr handle, object plugin, string signal, object evnt)
		{
			return _connect(handle, plugin, signal, evnt);
		}
	}
}

This scared the shit out of me. For more take a look here. I decided to hack on and make proper C# bindings. All fine, but then… the gaim api was exported by the gaim executable itself! I found out about libgaim-client, but then it wasn’t exporting the *_get_handle () functions. One needs the handle in order to connect to a signal for the specific subsystem (e.g accounts, conversations, etc). I guess this could be solved by an InternalCall implementation. Then I tried to code up a simple test like that:

namespace Gaim
{
	
	public class Accounts
	{
		....
		[DllImport("libgaim-client")]
		private static extern IntPtr gaim_accounts_find (string name, string protocolID);
		
		public static Account Find (string name, string protocolID)
		{
			IntPtr account = gaim_accounts_find (name, protocolID);
			
			if (account != IntPtr.Zero) {
				return new Account (account);
			}
			return null;
		}
	}

	public class Account
	{
		private IntPtr _raw = IntPtr.Zero;
		....
		internal Account (IntPtr raw)
		{
			_raw = raw;
		}
		...
	}

}

Account account was set to IntPtr.Zero and gaim debug window showed a complain about a dbus proxy… I checked if there is something dbus-ish in the gaim_accounts_find (…) and there wasn’t. The same thing written in a C plugin (but not linked agains libgaim-client I think) works and the account is retrieved properly…

This is when I said “Gaim# – Naaah”…

Blog Logo

Ivan Zlatev


Published

Image

Ivan's Space

Writing about leadership, management, emotional resiliency, software engineering, tech, gadgets.

Back to Overview