Re: [Rhythmbox-devel] [PATCH] add lirc support



Hi,

See the attached file. It doesn't compile, nor is complete, but it is
some proof of concept code. The main advantage of using the bonobo
interface is that lirc support doesn't have to be enabled at compile
time, and that rhythmbox doesn't depend on lirc. Instead you get a
separate binary, which interested people can install.
The main drawback with that approach is that the bonobo interface
probably has a few bugs and lacks a few hooks to be able to do all that
your patch does.

Christophe

> How would one interface lirc with bonobo?  The core lirc support is
> already included in the current rhythmbox code.  It simply lacked the
> correct configure.ac environment needed to check for lirc and define
> HAVE_REMOTE and the actual execution of the commands received and parsed
> by the lirc library.
> 
> > > BTW, is there a CVS repository for the .9 branch or is it only available
> > > via arch?
> > 
> > Isn't CVS HEAD (module rhythmbox on cvs.gnome.org or anoncvs.gnome.org)
> > corresponding to the 0.9 branch ?
> 
> It appears as though cvs.gnome.org is the 0.8 branch: 
> http://cvs.gnome.org/viewcvs/rhythmbox/?only_with_tag=HEAD  (from the
> abundance of rhythmbox--main--0.8 imports and lack of 0.9's)
> 
> Regards,
> Jon Oberheide
> jon focalhost com
> 
> 
> _______________________________________________
> rhythmbox-devel mailing list
> rhythmbox-devel gnome org
> http://mail.gnome.org/mailman/listinfo/rhythmbox-devel
/*
 *  arch-tag: Use corba to pass lirc events to Rhythmbox
 */

#include <stdlib.h>
#include <lirc/lirc_client.h>
#include <string.h>
#include <libbonobo.h>
#include "Rhythmbox.h"

#define RB_IID "OAFIID:GNOME_Rhythmbox"

/* strings that we recognize as commands from lirc */
#define RB_IR_COMMAND_PLAY "play"
#define RB_IR_COMMAND_PAUSE "pause"
#define RB_IR_COMMAND_SHUFFLE "shuffle"
#define RB_IR_COMMAND_REPEAT "repeat"
#define RB_IR_COMMAND_NEXT "next"
#define RB_IR_COMMAND_PREVIOUS "previous"
#define RB_IR_COMMAND_SEEK_FORWARD "seek_forward"
#define RB_IR_COMMAND_SEEK_BACKWARD "seek_backward"
#define RB_IR_COMMAND_VOLUME_UP "volume_up"
#define RB_IR_COMMAND_VOLUME_DOWN "volume_down"
#define RB_IR_COMMAND_MUTE "mute"
#define RB_IR_COMMAND_QUIT "quit"

typedef enum {
	RB_REMOTE_COMMAND_UNKNOWN,
	RB_REMOTE_COMMAND_PLAY,
	RB_REMOTE_COMMAND_PAUSE,
	RB_REMOTE_COMMAND_SHUFFLE,
	RB_REMOTE_COMMAND_REPEAT,
	RB_REMOTE_COMMAND_NEXT,
	RB_REMOTE_COMMAND_PREVIOUS,
	RB_REMOTE_COMMAND_SEEK_FORWARD,
	RB_REMOTE_COMMAND_SEEK_BACKWARD,
	RB_REMOTE_COMMAND_VOLUME_UP,
	RB_REMOTE_COMMAND_VOLUME_DOWN,
	RB_REMOTE_COMMAND_MUTE,
	RB_REMOTE_COMMAND_QUIT
} RBRemoteCommand;



static void
rb_lirc_ir_command (GNOME_Rhythmbox rb, const gchar *str)
{
	CORBA_Environment  ev;

	CORBA_exception_init (&ev);

	if (strcmp (str, RB_IR_COMMAND_PLAY) == 0) {
		GNOME_Rhythmbox_playPause (rb, &ev);
		/* FIXME: check exception */
	} else if (strcmp (str, RB_IR_COMMAND_PAUSE) == 0) {
		GNOME_Rhythmbox_playPause (rb, &ev);
		/* FIXME: check exception */
	} else if (strcmp (str, RB_IR_COMMAND_SHUFFLE) == 0) {
		return;
	} else if (strcmp (str, RB_IR_COMMAND_REPEAT) == 0) {
		return;
	} else if (strcmp (str, RB_IR_COMMAND_NEXT) == 0) {
		GNOME_Rhythmbox_next (rb, &ev);
		return;
	} else if (strcmp (str, RB_IR_COMMAND_PREVIOUS) == 0) {
		GNOME_Rhythmbox_previous (rb, &ev);
		return;
	} else if (strcmp (str, RB_IR_COMMAND_SEEK_FORWARD) == 0) {
		return;
	} else if (strcmp (str, RB_IR_COMMAND_SEEK_BACKWARD) == 0) { 
		return;
	} else if (strcmp (str, RB_IR_COMMAND_VOLUME_UP) == 0) {
		return;		
	} else if (strcmp (str, RB_IR_COMMAND_VOLUME_DOWN) == 0) {
		return;
	} else if (strcmp (str, RB_IR_COMMAND_MUTE) == 0) {
		return;
	} else if (strcmp (str, RB_IR_COMMAND_QUIT) == 0) {
		return;
	} else {
		return;
	}
	  /* return RB_REMOTE_COMMAND_UNKNOWN; */ 
	CORBA_exception_free (&ev);
}



static gboolean
rb_remote_read_code (GIOChannel *source, GIOCondition condition,
		     GNOME_Rhythmbox rb)
{
	struct lirc_config *config;
	char *code;
	char *str = NULL;

	/* this _could_ block, but it shouldn't */
	lirc_nextcode (&code);

	if (code == NULL) {
		/* the code was incomplete or something */
		return TRUE;
	}
	
	/* FIXME:  we really should only do this once, but there appears to be
	 * a bug in lirc where it will drop every other key press if we keep
	 * a config struct around for more than one use.
	 */
	if (lirc_readconfig (NULL, &config, NULL) != 0) {
		g_warning ("Couldn't read lirc config.");
		return FALSE;
	}

	if (lirc_code2char (config, code, &str) != 0) {
		g_warning ("Couldn't convert lirc code to string.");
		lirc_freeconfig (config);
		return TRUE;
	}

	if (str == NULL) {
		/* there was no command associated with the code */
		lirc_freeconfig (config);
		g_free (code);
		return TRUE;
	}

	rb_lirc_ir_command (rb, str);

	lirc_freeconfig (config);
	g_free (code);

	/* this causes a crash, so I guess I'm not supposed to free it?
	 * g_free (str);
	 */

	return TRUE;
}


int 
main (int argc, char *argv [])
{
	GNOME_Rhythmbox rb;
	CORBA_Environment  ev;
	GIOChannel *lirc_channel = NULL;

	/*
	 * Initialize bonobo.
	 */
	if (!bonobo_init (&argc, argv))
		g_error ("Could not initialize Bonobo");
	
	CORBA_exception_init (&ev);
	rb = bonobo_activation_activate_from_id (RB_IID, 0, NULL, &ev);


	if (rb == CORBA_OBJECT_NIL) {
		g_warning ("Could not create an instance of Rhythmbox");
		return bonobo_debug_shutdown ();
	}

	if (lirc_channel == NULL) {
		int fd;
		fd = lirc_init ("Rhythmbox", 1);

		if (fd < 0) {
			g_message ("Couldn't initialize lirc.\n");
			return 0;
		}
			
		lirc_channel = g_io_channel_unix_new (fd);

		g_io_add_watch (lirc_channel, G_IO_IN,
				(GIOFunc) rb_remote_read_code, rb);
	}

	CORBA_exception_free (&ev);

	bonobo_main ();
	
	bonobo_object_release_unref (rb, NULL);


	return bonobo_debug_shutdown ();
}

Attachment: signature.asc
Description: Ceci est une partie de message =?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=



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