?? yauap-engine.cpp
字號(hào):
/*************************************************************************** yauap-engine.h - yauap engine plugincopyright : (C) 2006 by Sascha Sommer <saschasommer@freenet.de>***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <qapplication.h>#include <klocale.h>#include <iostream>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#define DBUS_API_SUBJECT_TO_CHANGE#include <dbus/connection.h>//#define MANUAL_YAUAP_START#define YAUAP_DBUS_SERVICE "org.yauap.CommandService"#define YAUAP_DBUS_PATH "/yauapObject"#define YAUAP_DBUS_INTERFACE "org.yauap.CommandInterface"#include "yauap-engine.h"#include "debug.h"AMAROK_EXPORT_PLUGIN( yauapEngine )/* signal handler for DBus signals */static DBusHandlerResult signal_handler( DBusConnection * /*con*/, DBusMessage *msg, void *data ){ yauapEngine* engine = (yauapEngine*)data; const char *objectpath = dbus_message_get_path(msg); const char *member = dbus_message_get_member(msg); const char *interface = dbus_message_get_interface(msg); bool handled = true; debug() << "SIGNAL member " << member << " interface " << interface << " objpath " << objectpath << endl; if (dbus_message_is_signal( msg, "org.yauap.CommandInterface", "MetadataSignal")) QApplication::postEvent(engine, new QCustomEvent(3004)); else if(dbus_message_is_signal( msg, "org.yauap.CommandInterface", "EosSignal")) { if (engine->m_state == Engine::Playing) QApplication::postEvent(engine, new QCustomEvent(3000)); } else if(dbus_message_is_signal( msg, "org.yauap.CommandInterface", "ErrorSignal")) { char* text = NULL; DBusError error; dbus_error_init(&error); if(dbus_message_get_args( msg, &error, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID)) { QCustomEvent* e = new QCustomEvent(3002); e->setData(new QString(text)); QApplication::postEvent(engine, e); } } else handled = false; return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);}intyauapProcess::commSetupDoneC(){ int r = Amarok::Process::commSetupDoneC(); int fd = open("/dev/null", O_RDWR); dup2(fd, 1); dup2(fd, 2); close(fd); return r;}/* create a qt dbus connection that will receive the signals */bool DBusConnection::open(){ DBusError error; dbus_error_init( &error ); debug() << " connecting to dbus" << endl; // close open connection close(); /* connect to session bus */ dbus_connection = dbus_bus_get_private( DBUS_BUS_SESSION, &error ); /* dbus_bus_get somehow doesn't work here */ if( dbus_error_is_set(&error) ) { debug() << "unable to connect to DBUS." << endl; dbus_error_free(&error); return false; } dbus_connection_set_exit_on_disconnect( dbus_connection, false ); /* create qt connection */ qt_connection = new DBusQt::Connection( this ); qt_connection->dbus_connection_setup_with_qt_main( dbus_connection ); if ( !dbus_connection_add_filter(dbus_connection, signal_handler, context, NULL) ) { debug() << "Failed to add filter function." << endl; return false; } /* Match for DBUS_INTERFACE_DBUS */ dbus_bus_add_match( dbus_connection, "type='signal',interface='org.yauap.CommandInterface'", &error); if ( dbus_error_is_set( &error ) ) { debug() << "Error adding match, " << error.name << " " << error.message; dbus_error_free (&error); return false; } debug() << " connected " << endl; return true;}/* close qt dbus connection */void DBusConnection::close(){ debug() << "close DBusConnection" << endl; if( dbus_connection ) dbus_connection_close( dbus_connection ); if(qt_connection) qt_connection->close(); /* DBusConnection::open () calls dbus_bus_get (), we need to unref the connection */ debug() << "calling dbus connection close" << endl; dbus_connection = NULL; qt_connection = NULL; debug() << "DBusConnection closed" << endl;}DBusConnection::DBusConnection( yauapEngine* c ){ qt_connection = NULL; dbus_connection = NULL; context = c;}DBusConnection::~DBusConnection(){ close();}boolDBusConnection::send(const char *method, int first_arg_type, ...){ dbus_uint32_t serial = 0; bool ret = false; QMutexLocker lock(&m_mutex); DBusMessage* msg = dbus_message_new_method_call( YAUAP_DBUS_SERVICE, YAUAP_DBUS_PATH, YAUAP_DBUS_INTERFACE, method); if (msg) { va_list ap; va_start(ap, first_arg_type); dbus_message_append_args_valist(msg, first_arg_type, ap); va_end(ap); ret = dbus_connection_send(dbus_connection, msg, &serial); dbus_message_unref (msg); } return ret;}intDBusConnection::call(const char *method, int first_arg_type, ...){ dbus_uint32_t ret = -1; va_list ap; va_start (ap, first_arg_type); DBusMessage* msg = send_with_reply(method, first_arg_type, ap); va_end (ap); if (msg) { DBusMessageIter args; if (dbus_message_iter_init(msg, &args) && (DBUS_TYPE_INT32 == dbus_message_iter_get_arg_type(&args) || DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args))) dbus_message_iter_get_basic(&args, &ret); dbus_message_unref (msg); } return ret;}DBusMessage*DBusConnection::send_with_reply(const char* method, int first_arg_type, ...){ va_list ap; va_start(ap, first_arg_type); DBusMessage* msg = send_with_reply(method, first_arg_type, ap); va_end(ap); return msg;}DBusMessage*DBusConnection::send_with_reply(const char* method, int first_arg_type, va_list ap){ QMutexLocker lock(&m_mutex); DBusMessage* msg = dbus_message_new_method_call( YAUAP_DBUS_SERVICE, YAUAP_DBUS_PATH, YAUAP_DBUS_INTERFACE, method); if (msg) { DBusError error; dbus_error_init(&error); dbus_message_append_args_valist(msg, first_arg_type, ap); DBusMessage* oldmsg = msg; msg = dbus_connection_send_with_reply_and_block(dbus_connection, oldmsg, -1, &error); DBusDispatchStatus status; while ((status = dbus_connection_get_dispatch_status(dbus_connection)) == DBUS_DISPATCH_DATA_REMAINS) dbus_connection_dispatch (dbus_connection); dbus_message_unref (oldmsg); if (!msg) debug() << "dbus error while waiting for reply: " << error.message << endl; } return msg;}/* emit state change signal */voidyauapEngine::change_state( Engine::State state ){ m_state = state; emit stateChanged(m_state);}/* destroy engine */yauapEngine::~yauapEngine(){ /* make sure we really stopped */ stop(); /* quit the player */ if ( !con->send("quit", DBUS_TYPE_INVALID) ) debug() << "quit failed " << endl; delete con;}/* fetch metadata from yauap */void yauapEngine::update_metadata(){ Engine::SimpleMetaBundle* bndl = new Engine::SimpleMetaBundle; debug() << " emit metadata change " << endl; DBusMessage* msg = con->send_with_reply("get_metadata", DBUS_TYPE_INVALID); if (msg) { DBusMessageIter args; if (dbus_message_iter_init(msg, &args) && DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&args)) { DBusMessageIter sub; dbus_message_iter_recurse(&args, &sub); dbus_message_iter_next(&args); while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { char* reply_ptr = 0; dbus_message_iter_get_basic(&sub, &reply_ptr); dbus_message_iter_next(&sub); debug() << "reply_ptr: " << reply_ptr << endl;#define ASSIGN(a,b) if(!strncmp(reply_ptr,b,strlen(b)) && strlen(reply_ptr + strlen(b) + 1)){ \ bndl->a = reply_ptr + strlen(b) + 1; \ continue; \ } ASSIGN( title, "title" ) ASSIGN( artist, "artist" ) ASSIGN( album, "album" ) ASSIGN( comment, "comment" ) ASSIGN( genre, "genre" ) ASSIGN( samplerate, "samplerate" ) ASSIGN( year, "date" ) ASSIGN( tracknr, "track-number" ) ASSIGN( length, "length" ) ASSIGN( bitrate, "bitrate" )#undef ASSIGN } } dbus_message_unref(msg); } debug() << "title:" << bndl->title << endl; debug() << "artist:" << bndl->artist << endl; debug() << "album:" << bndl->album << endl; debug() << "comment:" << bndl->comment << endl; debug() << "genre:" << bndl->genre << endl; debug() << "samplerate:" << bndl->samplerate << endl; debug() << "year:" << bndl->year << endl; debug() << "tracknr:" << bndl->tracknr << endl; debug() << "length:" << bndl->length << endl; debug() << "bitrate:" << bndl->bitrate << endl; /* do not overwrite manually generated metadata from audio cds */ if(bndl->title.isEmpty() && loaded_url.protocol() == "cdda") return; QCustomEvent* e = new QCustomEvent(3003); e->setData(bndl); QApplication::postEvent(this, e);}/* fetch current sample buffer from yauap */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -