Logo Search packages:      
Sourcecode: yauap version File versions  Download package

yauap-service.c

/*
 * yauap-service.c - DBus frontend for yauap
 * Copyright (c) 2006 Sascha Sommer <ssommer@suse.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */


#include <dbus/dbus-glib.h>
#include <stdio.h>
#include <stdlib.h>


#include "../yauap.h"


/* yauap dbus-service 
   can be used to control yauap over the dbus IPC System 
   see the amarok yauap engine for an example on how to use this
   the available functions and signals are listed in 
   yauap-service.xml and described in the README
*/


/****************************** the yauap Object we export **********************************/
/* what a mess */
typedef struct {
    GObject parent;
    player_t* player;
} yauapObject;

typedef struct {
    GObjectClass parent;
} yauapObjectClass;



enum
{
  METADATA_SIGNAL,
  EOS_SIGNAL,
  ERROR_SIGNAL,
  LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };



#define YAUAP_TYPE_OBJECT              (yauap_object_get_type ())
G_DEFINE_TYPE(yauapObject, yauap_object, G_TYPE_OBJECT)


/* methods: they are basically wrappers for the methods in the yauap struct */


static void yauap_object_init(yauapObject *obj){
}


static void yauap_object_class_init(yauapObjectClass *klass){
    /* only signal the metadata change */
    /* leave it to the client if he wants to call get_metadata */
    /* this way we do not need to create our own marshaller */

    signals[METADATA_SIGNAL] =
        g_signal_new ("metadata_signal",
                  G_OBJECT_CLASS_TYPE (klass),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
                  0,
                  NULL, NULL,
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE, 0, NULL);
    signals[EOS_SIGNAL] =
        g_signal_new ("eos_signal",
                  G_OBJECT_CLASS_TYPE (klass),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
                  0,
                  NULL, NULL,
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE, 0, NULL);
    signals[ERROR_SIGNAL] =
        g_signal_new ("error_signal",
                  G_OBJECT_CLASS_TYPE (klass),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
                  0,
                  NULL, NULL,
                  g_cclosure_marshal_VOID__STRING,
                  G_TYPE_NONE, 1, G_TYPE_STRING);
}



/* methods that should be usefull for amarok */

/* quit the player */
static gboolean yauap_object_quit(yauapObject *obj,GError **error){
    obj->player->quit(obj->player);
    return TRUE;
}

/* stop playback */
static gboolean yauap_object_stop(yauapObject *obj,int* ret,GError **error){
    *ret = obj->player->stop(obj->player);
    return TRUE;
}

/* start playback at offset in ms */
static gboolean yauap_object_start(yauapObject *obj,unsigned int offset,int* ret,GError **error){
    *ret = obj->player->stop(obj->player);
    if(offset > 0)
      *ret = obj->player->seek(obj->player,offset);
    *ret = obj->player->start(obj->player);
    return TRUE;
}

/* load a uri */
static gboolean yauap_object_load(yauapObject *obj,const char* url,int* ret,GError **error){
    *ret = obj->player->load(obj->player,url);
    return TRUE;
}

/* check wether we are able to decode the url */
static gboolean yauap_object_can_decode(yauapObject *obj,const char* url,int* can_decode,GError **error){
    *can_decode = obj->player->can_decode(url);
    printf("can_decode(%s):%i\n",url,*can_decode);
    return TRUE;
}

/* pause playback, call this again to unpause */
static gboolean yauap_object_pause(yauapObject *obj,int* ret,GError **error){
    *ret = obj->player->pause(obj->player);
    return TRUE;
}

/* fetch the metadata */
static gboolean yauap_object_get_metadata(yauapObject *obj, char ***ret, GError **error){
    obj->player->get_metadata(obj->player,ret);
    return TRUE;
}

/* get audio_cd contents */
static gboolean yauap_object_get_audio_cd_contents(yauapObject *obj, char* device, char ***ret, GError **error){
    obj->player->get_audio_cd_contents(obj->player,device,ret);
    return TRUE;
}

/* seek to position in ms */
static gboolean yauap_object_seek(yauapObject *obj,unsigned int position,int* ret,GError **error){
    *ret = obj->player->seek(obj->player,position);
    return TRUE;
}

/* returns the track length in ms (player needs to be in the playing state for this to work) */
static gboolean yauap_object_get_length(yauapObject *obj,unsigned int* length,GError **error){
    *length = obj->player->get_time_length(obj->player);
    return TRUE;
}

/* returns the current position in ms */
static gboolean yauap_object_get_position(yauapObject *obj,unsigned int* pos,GError **error){
    *pos = obj->player->get_time_position(obj->player);
    return TRUE;
}

static gboolean yauap_object_get_volume(yauapObject *obj,unsigned int *volume,GError **error){
    *volume = obj->player->get_volume(obj->player);
    return TRUE;
}

static gboolean yauap_object_set_volume(yauapObject *obj,unsigned int volume,int* ret,GError **error){
    *ret = obj->player->set_volume(obj->player,volume);
    return TRUE;
}


static gboolean yauap_object_get_scopedata(yauapObject *obj,GArray** buf,GError **error){
    *buf = g_array_new(FALSE,FALSE,sizeof(gchar)); 
    *buf = g_array_set_size(*buf,SCOPE_SIZE);
    obj->player->get_scopedata(obj->player,(*buf)->data);
    return TRUE;
}






/* signal cb: informs the client that the updated metadata etc. can be fetched with get_metadata */
static void yauap_emit_metadata_signal(yauap_frontend_t* frontend,unsigned int signal,char* message){
    yauapObject *obj = (yauapObject*)frontend->priv;
    switch(signal){
        case SIGNAL_METADATA:
          g_signal_emit(obj, signals[METADATA_SIGNAL], 0,NULL); 
            break;
        case SIGNAL_EOS:
            g_signal_emit(obj, signals[EOS_SIGNAL], 0,NULL);
            break;
        case SIGNAL_ERROR:
            g_signal_emit(obj, signals[ERROR_SIGNAL], 0, message);
            break;
    }
    if(obj->player->verbose)
        printf("emit signal %i %s\n",signal,message);
}


/* include glue code so that we can actually call these methods via dbus 
   yauap-service-glue.h is autogenerated by dbus-binding-tool from yauap-service.xml
   which contains the interface definition
*/
#include "yauap-service-glue.h"

/********************************* end of yauap object *******************************/


static void dbus_service_free(yauap_frontend_t* frontend){
    if(frontend)
        free(frontend);
}




/* register dbus command interface  */
yauap_frontend_t* init_dbus_service(player_t* player){
    yauap_frontend_t* frontend = NULL;
    DBusGConnection *bus;
    DBusGProxy *bus_proxy;
    GError *error = NULL;
    yauapObject *obj;
    guint request_name_result;

    g_type_init();
    dbus_g_object_type_install_info(YAUAP_TYPE_OBJECT, &dbus_glib_yauap_object_object_info);

    /* connect to the session bus */
    bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
    if(!bus){
        printf("Couldn't connect to session bus %s\n",error->message);
        return NULL;
    }

    bus_proxy = dbus_g_proxy_new_for_name(bus,"org.freedesktop.DBus",
                                              "/org/freedesktop/DBus",
                                    "org.freedesktop.DBus");

    /* Request a name */
    if(!bus_proxy || !dbus_g_proxy_call(bus_proxy, "RequestName", &error,
                          G_TYPE_STRING, "org.yauap.CommandService",
                          G_TYPE_UINT, 0,
                          G_TYPE_INVALID,
                          G_TYPE_UINT, &request_name_result,
                          G_TYPE_INVALID)){
        printf("Failed to acquire org.yauap.CommandService %s\n", error->message);
        return NULL;
    }

    /* create and register our command object */
    obj = g_object_new(YAUAP_TYPE_OBJECT, NULL);
    obj->player = player; 

    /* connect us to yauap */
    frontend = calloc(1,sizeof(yauap_frontend_t)); 
    frontend->signal_cb = yauap_emit_metadata_signal;
    frontend->priv = obj;
    frontend->player = player;
    frontend->free = dbus_service_free;

    dbus_g_connection_register_g_object(bus, "/yauapObject", G_OBJECT(obj));

    if(player->verbose)
        printf ("yauap dbus service running\n");

    return frontend;
}



Generated by  Doxygen 1.6.0   Back to index