diff options
| -rw-r--r-- | configure.in | 53 | ||||
| -rw-r--r-- | qt/Makefile.am | 57 | ||||
| -rw-r--r-- | qt/connection.cpp | 168 | ||||
| -rw-r--r-- | qt/connection.h | 83 | ||||
| -rw-r--r-- | qt/dbus-qt.h | 81 | ||||
| -rw-r--r-- | qt/dbus-qthread.cpp | 163 | ||||
| -rw-r--r-- | qt/integrator.cpp | 244 | ||||
| -rw-r--r-- | qt/integrator.h | 92 | ||||
| -rw-r--r-- | qt/message.cpp | 561 | ||||
| -rw-r--r-- | qt/message.h | 131 | ||||
| -rw-r--r-- | qt/qdbus.h | 31 | ||||
| -rw-r--r-- | qt/qdbusconnection.cpp | 328 | ||||
| -rw-r--r-- | qt/qdbusconnection.h | 78 | ||||
| -rw-r--r-- | qt/qdbusconnection_p.h | 126 | ||||
| -rw-r--r-- | qt/qdbuserror.cpp | 46 | ||||
| -rw-r--r-- | qt/qdbuserror.h | 48 | ||||
| -rw-r--r-- | qt/qdbusintegrator.cpp | 621 | ||||
| -rw-r--r-- | qt/qdbusmacros.h | 34 | ||||
| -rw-r--r-- | qt/qdbusmarshall.cpp | 300 | ||||
| -rw-r--r-- | qt/qdbusmarshall.h | 39 | ||||
| -rw-r--r-- | qt/qdbusmessage.cpp | 233 | ||||
| -rw-r--r-- | qt/qdbusmessage.h | 80 | ||||
| -rw-r--r-- | qt/qdbusmessage_p.h | 46 | ||||
| -rw-r--r-- | qt/qdbusserver.cpp | 59 | ||||
| -rw-r--r-- | qt/qdbusserver.h (renamed from qt/server.h) | 45 | ||||
| -rw-r--r-- | qt/qdbusvariant.h | 40 | ||||
| -rw-r--r-- | qt/server.cpp | 90 | 
27 files changed, 2177 insertions, 1700 deletions
diff --git a/configure.in b/configure.in index 1c72af4c..7ffc429e 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ AC_PREREQ(2.52)  AC_INIT(dbus/dbus.h) -AM_INIT_AUTOMAKE(dbus, 0.51) +AM_INIT_AUTOMAKE(dbus, 0.37)  AM_CONFIG_HEADER(config.h) @@ -859,8 +859,8 @@ AC_SUBST(DBUS_TEST_CFLAGS)  AC_SUBST(DBUS_TEST_LIBS)  # Glib detection -PKG_CHECK_MODULES(DBUS_GLIB, gobject-2.0 >= 2.4, have_glib=yes, have_glib=no) -PKG_CHECK_MODULES(DBUS_GLIB_THREADS, gthread-2.0 >= 2.4, have_glib_threads=yes, have_glib_threads=no) +PKG_CHECK_MODULES(DBUS_GLIB, gobject-2.0, have_glib=yes, have_glib=no) +PKG_CHECK_MODULES(DBUS_GLIB_THREADS, glib-2.0 gthread-2.0, have_glib_threads=yes, have_glib_threads=no)  if test x$have_glib = xno ; then      AC_MSG_WARN([GLib development libraries not found]) @@ -927,28 +927,9 @@ AC_SUBST(DBUS_GTK_LIBS)  AC_SUBST(DBUS_GTK_THREADS_CFLAGS)  AC_SUBST(DBUS_GTK_THREADS_LIBS) -# Qt detection -AC_PATH_PROG(QT_MOC, moc, no) -have_qt=no -AC_MSG_CHECKING([for qglobal.h]) -if test -n "$QTDIR" -a -f "$QTDIR/include/qglobal.h"; then -    have_qt=yes -    DBUS_QT_CXXFLAGS="-I$QTDIR/include" -else -    for dir in "${prefix}/include/qt" "/usr/include/qt-3.1" "/usr/include/qt3" "/usr/include/qt" "/usr/lib/qt/include" "/usr/lib/qt-3.1/include"; do -        if test -f "$dir/qglobal.h"; then -            have_qt=yes -            DBUS_QT_CXXFLAGS="-I$dir" -            DBUS_QT_LIBS="-L$QTDIR/lib -lqt-mt" -       fi -    done -fi -if test x"$have_qt" = x"yes"; then -   AC_MSG_RESULT([found]) -else -   AC_MSG_RESULT([not found]) -fi +dnl Qt detection +PKG_CHECK_MODULES(DBUS_QT, QtCore >= 4.0, have_qt=yes, have_qt=no)  if test x$have_qt = xno ; then      AC_MSG_WARN([Qt development libraries not found]) @@ -962,13 +943,17 @@ fi  if test x$enable_qt = xno; then     have_qt=no; -fi +   fi + +QT_MOC=`$PKG_CONFIG --variable=exec_prefix QtCore` +QT_MOC=${QT_MOC}/bin/moc  AM_CONDITIONAL(HAVE_QT, test x$have_qt = xyes)  dnl Qt flags -AC_SUBST(DBUS_QT_CXXFLAGS) +AC_SUBST(DBUS_QT_CFLAGS)  AC_SUBST(DBUS_QT_LIBS) +AC_SUBST(QT_MOC)  ### X11 detection  AC_PATH_XTRA @@ -1228,21 +1213,13 @@ AC_SUBST(DBUS_SESSION_SOCKET_DIR)  if test x$enable_python = xno; then      have_python=no  else -    have_python_version=2.4      AC_MSG_NOTICE([Checking to see if we can build Python bindings])      have_python=no -    AM_PATH_PYTHON() +    AM_PATH_PYTHON(2.4)      if test -z "$PYTHON" ; then          AC_MSG_WARN([Python not found])      else -        AC_MSG_CHECKING([whether $PYTHON version >= $have_python_version]) -        AM_PYTHON_CHECK_VERSION([$PYTHON], [$have_python_version], -                              [have_python_version="yes"], -                              [have_python_version="too old"]) -     -        AC_MSG_RESULT($have_python_version) -              AC_CHECK_PROGS(PYREX, pyrexc)          if test -z "$PYREX" ; then @@ -1253,16 +1230,16 @@ else          AM_CHECK_PYTHON_HEADERS(have_python_headers=yes,have_python_headers=no) -	if test x$have_pyrex = xyes -a x$have_python_headers = xyes -a "x$have_python_version" = xyes ; then +	if test x$have_pyrex = xyes -a x$have_python_headers = xyes ; then  	    have_python=yes          fi      fi      if test x$have_python = xno ; then          if test x$enable_python = xyes ; then -            AC_MSG_ERROR([Building python explicitly requested, but can't build python bindings because either Pyrex, Python headers or a suitable Python version was not found]) +            AC_MSG_ERROR([Building python explicitly requested, but can't build python bindings])          else -            AC_MSG_WARN([Couldn't find either Pyrex, the Python headers or a suitable version of Python, not building Python bindings]) +            AC_MSG_WARN([Couldn't find either Pyrex or the Python headers, not building Python bindings])          fi      fi                 fi diff --git a/qt/Makefile.am b/qt/Makefile.am index d375bcf3..71ae3527 100644 --- a/qt/Makefile.am +++ b/qt/Makefile.am @@ -1,37 +1,50 @@  if HAVE_QT -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_QT_CXXFLAGS) +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_QT_CFLAGS)  dbusincludedir=$(includedir)/dbus-1.0/dbus  lib_LTLIBRARIES=libdbus-qt-1.la -dbusinclude_HEADERS=				\ -	dbus-qt.h message.h connection.h        \ -	server.h +dbusinclude_HEADERS=	\ +	qdbuserror.h \ +	qdbusmacros.h \ +	qdbusmessage.h \ +	qdbusserver.h \ +	qdbus.h \ +	qdbusmarshall.h \ +	qdbusvariant.h  libdbus_qt_1_la_SOURCES = 			\ -	dbus-qthread.cpp \ -	$(top_srcdir)/qt/message.cpp \ -	$(top_srcdir)/qt/connection.cpp \ -	$(top_srcdir)/qt/integrator.cpp \ -	$(top_srcdir)/qt/server.cpp \ -	$(top_srcdir)/qt/connection.h \ -	$(top_srcdir)/qt/integrator.h \ -	$(top_srcdir)/qt/server.h - - -$(top_srcdir)/qt/connection.cpp: connection.moc -$(top_srcdir)/qt/integrator.cpp: integrator.moc -$(top_srcdir)/qt/server.cpp: server.moc -$(top_srcdir)/qt/connection.h: connection.moc -$(top_srcdir)/qt/integrator.h: integrator.moc -$(top_srcdir)/qt/server.h: server.moc - -CLEANFILES=connection.moc integrator.moc server.moc +	$(top_srcdir)/qt/qdbusconnection.cpp    \ +	$(top_srcdir)/qt/qdbuserror.cpp         \ +	$(top_srcdir)/qt/qdbusintegrator.cpp    \ +	$(top_srcdir)/qt/qdbusmarshall.cpp      \ +	$(top_srcdir)/qt/qdbusmessage.cpp       \ +	$(top_srcdir)/qt/qdbusserver.cpp        \ +	$(top_srcdir)/qt/qdbusconnection.h      \ +	$(top_srcdir)/qt/qdbuserror.h           \ +	$(top_srcdir)/qt/qdbusmacros.h          \ +	$(top_srcdir)/qt/qdbusmessage.h         \ +	$(top_srcdir)/qt/qdbusserver.h          \ +	$(top_srcdir)/qt/qdbusconnection_p.h    \ +	$(top_srcdir)/qt/qdbus.h                \ +	$(top_srcdir)/qt/qdbusmarshall.h        \ +	$(top_srcdir)/qt/qdbusmessage_p.h       \ +	$(top_srcdir)/qt/qdbusvariant.h + + +$(top_srcdir)/qt/qdbusserver.cpp: qdbusserver.moc +$(top_srcdir)/qt/qdbusconnection.cpp: qdbusconnection.moc + +CLEANFILES=qdbusserver.moc qdbusconnection.moc  libdbus_qt_1_la_LIBADD= $(DBUS_QT_LIBS) $(top_builddir)/dbus/libdbus-1.la  libdbus_qt_1_la_LDFLAGS= -version-info 1:0 -no-undefined +# _p.h files are a exception +qdbusconnection.moc: qdbusconnection_p.h +	$(QT_MOC) -o qdbusconnection.moc $(top_srcdir)/qt/qdbusconnection_p.h +  %.moc: %.h  	$(QT_MOC) $< > $@  endif diff --git a/qt/connection.cpp b/qt/connection.cpp deleted file mode 100644 index f426d698..00000000 --- a/qt/connection.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- -/* connection.cpp: Qt wrapper for DBusConnection - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.0 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#include "connection.h" - -using namespace DBusQt; - -#include "integrator.h" -using Internal::Integrator; - -struct Connection::Private -{ -  Private( Connection *qq ); -  void setConnection( DBusConnection *c ); -  DBusConnection *connection; -  int connectionSlot; -  DBusError error; -  Integrator *integrator; -  int timeout; -  Connection *q; -}; - -Connection::Private::Private( Connection *qq ) -  : connection( 0 ), connectionSlot( 0 ), integrator( 0 ), -    timeout( -1 ), q( qq ) -{ -  dbus_error_init( &error ); -} - -void Connection::Private::setConnection( DBusConnection *c ) -{ -  if (!c) { -    qDebug( "error: %s, %s", error.name, error.message ); -    dbus_error_free( &error ); -    return; -  } -  connection = c; -  integrator = new Integrator( c, q ); -  connect( integrator, SIGNAL(readReady()), q, SLOT(dispatchRead()) ); -} - -Connection::Connection( QObject *parent ) -  : QObject( parent ) -{ -  d = new Private( this ); -} - -Connection::Connection( const QString& host, QObject *parent ) -  : QObject( parent ) -{ -  d = new Private( this ); - -  if ( !host.isEmpty() ) -    init( host ); -} - -Connection::Connection( DBusBusType type, QObject* parent ) -  : QObject( parent ) -{ -  d = new Private( this ); -  d->setConnection( dbus_bus_get(type, &d->error) ); -} - -void Connection::init( const QString& host ) -{ -  d->setConnection( dbus_connection_open( host.ascii(), &d->error) ); -  //dbus_connection_allocate_data_slot( &d->connectionSlot ); -  //dbus_connection_set_data( d->connection, d->connectionSlot, 0, 0 ); -} - -bool Connection::isConnected() const -{ -  return dbus_connection_get_is_connected( d->connection ); -} - -bool Connection::isAuthenticated() const -{ -  return dbus_connection_get_is_authenticated( d->connection ); -} - -void Connection::open( const QString& host ) -{ -  if ( host.isEmpty() ) return; - -  init( host ); -} - -void Connection::close() -{ -  dbus_connection_disconnect( d->connection ); -} - -void Connection::flush() -{ -  dbus_connection_flush( d->connection ); -} - -void Connection::dispatchRead() -{ -  while ( dbus_connection_dispatch( d->connection ) == DBUS_DISPATCH_DATA_REMAINS ) -    ; -} - -DBusConnection* Connection::connection() const -{ -  return d->connection; -} - -Connection::Connection( DBusConnection *connection, QObject *parent  ) -  : QObject( parent ) -{ -  d = new Private(this); -  d->setConnection(connection); -} - -void Connection::send( const Message &m ) -{ -    dbus_connection_send(d->connection, m.message(), 0); -} - -void Connection::sendWithReply( const Message& ) -{ -} - -Message Connection::sendWithReplyAndBlock( const Message &m ) -{ -  DBusMessage *reply; -  reply = dbus_connection_send_with_reply_and_block( d->connection, m.message(), d->timeout, &d->error ); -  if (dbus_error_is_set(&d->error)) { -      qDebug("error: %s, %s", d->error.name, d->error.message); -      dbus_error_free(&d->error); -  } -  return Message( reply ); -} - -void* Connection::virtual_hook( int, void*  ) -{ -} - -void Connection::dbus_connection_setup_with_qt_main (DBusConnection *connection) -{ -  d->setConnection( connection ); -} - - - -///////////////////////////////////////////////////////// - -#include "connection.moc" diff --git a/qt/connection.h b/qt/connection.h deleted file mode 100644 index 7cb922e3..00000000 --- a/qt/connection.h +++ /dev/null @@ -1,83 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- -/* connection.h: Qt wrapper for DBusConnection - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#ifndef DBUS_QT_CONNECTION_H -#define DBUS_QT_CONNECTION_H - -#include "message.h" - -#include <qobject.h> -#include <qstring.h> - -#include "dbus/dbus.h" - -namespace DBusQt { -  namespace Internal { -    class Integrator; -  } - -  class Connection : public QObject -  { -    Q_OBJECT -  public: -    Connection( QObject *parent =0 ); -    Connection( const QString& host, -                QObject *parent = 0 ); -    Connection( DBusBusType type, QObject* parent = 0 ); - -    bool isConnected() const; -    bool isAuthenticated() const; - -    Message borrowMessage(); -    Message popMessage(); -    void stealBorrowMessage( const Message& ); -    void dbus_connection_setup_with_qt_main (DBusConnection *connection); - -  public slots: -    void open( const QString& ); -    void close(); -    void flush(); -    void send( const Message& ); -    void sendWithReply( const Message& ); -    Message sendWithReplyAndBlock( const Message& ); - -  protected slots: -    void dispatchRead(); - -  protected: -    void init( const QString& host ); -    virtual void *virtual_hook( int id, void *data ); - -  private: -    friend class Internal::Integrator; -    DBusConnection *connection() const; -    Connection( DBusConnection *connection, QObject *parent ); - -  private: -    struct Private; -    Private *d; -  }; - -} - - -#endif diff --git a/qt/dbus-qt.h b/qt/dbus-qt.h deleted file mode 100644 index 179f5355..00000000 --- a/qt/dbus-qt.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* - * dbus-qt.h Qt integration - * - * Copyright (C)  2002  DBus Developers - * - * Licensed under the Academic Free License version 2.1 - * - * 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.1 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307  USA - * - */ -#ifndef DBUS_QT_H -#define DBUS_QT_H - -#include <dbus/dbus.h> -/* - * Two approaches - one presented below a DBusQtConnection - * object which is a Qt wrapper around DBusConnection -class DBusQtConnection : public QObject { -  Q_OBJECT -public: -  DBusQtConnection( const char *address=0, QObject *parent=0, -                    const char *name=0 ); - -  bool         open( const char *address ); -  bool         isConnected() const; -  int          numMessages() const; - -public slots: -  void disconnect(); -  void flush(); -  void sendMessage( DBusMessage *message ); - -signals: -  void message( DBusMessage* message ); -  void error( const char* error ); -private: -  DBusConnection  *mConnection; -  QSocketNotifier *mReadNotifier; -  QSocketNotifier *mWriteNotifier; -}; - * - * Second approach is to have a static Qt dispatcher like: -class DBusQtNotifier : public QObject { -  Q_OBJECT -public: -  static DBusQtNotifier* dbus_qt_notifier(); -  void addConnection(DBusConnection* connection); -signals: -  void message (DBusConnection* connection, DBusMessage* message); - -private: -  DBusQtNotifier(QObject *parent); -private slots: -  void processNotifiers( int socket ); -private: -  //implemented in terms of QSocketNotifiers -  QAsciiDict<DBusConnection> mReadNotifiers; -  QAsciiDict<DBusConnection> mWriteNotifiers; -}; - * - * First one gives us a full wrapper for DBusConnection (the Qt way), - * the other exposes DBusConnection, so would be easier to maintain - * and keep up while DBus evolves. - * - */ - -#endif /* DBUS_QT_H */ diff --git a/qt/dbus-qthread.cpp b/qt/dbus-qthread.cpp deleted file mode 100644 index 72ccb155..00000000 --- a/qt/dbus-qthread.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-qthread.cpp  Qt threads integration - * - * Copyright (C) 2002  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.0 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ - -#include <dbus/dbus.h> -#include <qmutex.h> - -#if defined(QT_THREAD_SUPPORT) - -static DBusMutex * dbus_qmutex_new    (void); -static void        dbus_qmutex_free   (DBusMutex *mutex); -static dbus_bool_t dbus_qmutex_lock   (DBusMutex *mutex); -static dbus_bool_t dbus_qmutex_unlock (DBusMutex *mutex); - -static DBusCondVar*dbus_qcondvar_new          (void); -static void        dbus_qcondvar_free         (DBusCondVar *cond); -static void        dbus_qcondvar_wait         (DBusCondVar *cond, -					       DBusMutex   *mutex); -static dbus_bool_t dbus_qcondvar_wait_timeout (DBusCondVar *cond, -					       DBusMutex   *mutex. -					       int          timeout_msec); -static void        dbus_qcondvar_wake_one     (DBusCondVar *cond); -static void        dbus_qcondvar_wake_all     (DBusCondVar *cond); - - -static const DBusThreadFunctions functions = -{ -  DBUS_THREAD_FUNCTIONS_NEW_MASK | -  DBUS_THREAD_FUNCTIONS_FREE_MASK | -  DBUS_THREAD_FUNCTIONS_LOCK_MASK | -  DBUS_THREAD_FUNCTIONS_UNLOCK_MASK | -  DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | -  DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | -  DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | -  DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | -  DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| -  DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, -  dbus_qmutex_new, -  dbus_qmutex_free, -  dbus_qmutex_lock, -  dbus_qmutex_unlock -  dbus_qcondvar_new, -  dbus_qcondvar_free, -  dbus_qcondvar_wait, -  dbus_qcondvar_wait_timeout, -  dbus_qcondvar_wake_one, -  dbus_qcondvar_wake_all -}; - -static DBusMutex * -dbus_qmutex_new (void) -{ -  QMutex *mutex; -  mutex = new QMutex; -  return static_cast<DBusMutex*>( mutex ); -} - -static void -dbus_qmutex_free (DBusMutex *mutex) -{ -  QMutex * qmutex = static_cast<QMutex*>(mutex); -  delete mutex; -} - -static dbus_bool_t -dbus_qmutex_lock   (DBusMutex *mutex) -{ -  QMutex *qmutex = static_cast<QMutex*>(mutex); -  qmutex->lock(); -  return TRUE; -} - -static dbus_bool_t -dbus_qmutex_unlock (DBusMutex *mutex) -{ -  QMutex *qmutex = static_cast<QMutex*>(mutex); -  qmutex->unlock(); -  return TRUE; -} - -static DBusCondVar* -dbus_qcondvar_new (void) -{ -  QWaitCondition *cond; -  cond = new QWaitCondition; -  return static_cast<DBusCondVar*>( cond ); -} - -static void -dbus_qcondvar_free (DBusCondVar *cond) -{ -  QWaitCondition *qcond = static_cast<QWaitCondition*>(cond); -  delete qcond; -} - -static void -dbus_qcondvar_wait (DBusCondVar *cond, -		    DBusMutex   *mutex) -{ -  QWaitCondition *qcond = static_cast<QWaitCondition*>(cond); -  QMutex *qmutex = static_cast<QMutex*>(mutex); - -  qcond->wait (qmutex); -} - -static dbus_bool_t -dbus_gcondvar_wait_timeout (DBusCondVar *cond, -			    DBusMutex   *mutex, -			    int         timeout_msec) -{ -  QWaitCondition *qcond = static_cast<QWaitCondition*>(cond); -  QMutex *qmutex = static_cast<QMutex*>(mutex); - -  return qcond->wait (qmutex, timout_msec); -} - -static void -dbus_qcondvar_wake_one (DBusCondVar *cond) -{ -  QWaitCondition *qcond = static_cast<QWaitCondition*>(cond); - -  qcond->wakeOne (qmutex); -} - -static void -dbus_qcondvar_wake_all (DBusCondVar *cond) -{ -  QWaitCondition *qcond = static_cast<QWaitCondition*>(cond); - -  qcond->wakeAll (qmutex); -} - -extern "C" { - -void -dbus_qthread_init (void) -{ -  //Do we want to do anything else here? -  dbus_threads_init (&functions); -} - -} - -#endif // QT_THREAD_SUPPORT diff --git a/qt/integrator.cpp b/qt/integrator.cpp deleted file mode 100644 index fff32b39..00000000 --- a/qt/integrator.cpp +++ /dev/null @@ -1,244 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- -/* integrator.h: integrates D-BUS into Qt event loop - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.0 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#include "integrator.h" -#include "connection.h" - -#include <qtimer.h> -#include <qsocketnotifier.h> -#include <qintdict.h> -#include <qptrlist.h> - -namespace DBusQt -{ -namespace Internal { - -struct Watch { -  Watch(): readSocket( 0 ), writeSocket( 0 ) { } - -  DBusWatch *watch; -  QSocketNotifier *readSocket; -  QSocketNotifier *writeSocket; -}; - -////////////////////////////////////////////////////////////// -dbus_bool_t dbusAddWatch( DBusWatch *watch, void *data ) -{ -  Integrator *con = static_cast<Integrator*>( data ); -  con->addWatch( watch ); -  return true; -} -void dbusRemoveWatch( DBusWatch *watch, void *data ) -{ -  Integrator *con = static_cast<Integrator*>( data ); -  con->removeWatch( watch ); -} - -void dbusToggleWatch( DBusWatch *watch, void *data ) -{ -  Integrator *itg = static_cast<Integrator*>( data ); -  if ( dbus_watch_get_enabled( watch ) ) -    itg->addWatch( watch ); -  else -    itg->removeWatch( watch ); -} - -dbus_bool_t dbusAddTimeout( DBusTimeout *timeout, void *data ) -{ -  if ( !dbus_timeout_get_enabled(timeout) ) -    return true; - -  Integrator *itg = static_cast<Integrator*>( data ); -  itg->addTimeout( timeout ); -  return true; -} - -void dbusRemoveTimeout( DBusTimeout *timeout, void *data ) -{ -  Integrator *itg = static_cast<Integrator*>( data ); -  itg->removeTimeout( timeout ); -} - -void dbusToggleTimeout( DBusTimeout *timeout, void *data ) -{ -  Integrator *itg = static_cast<Integrator*>( data ); - -  if ( dbus_timeout_get_enabled( timeout ) ) -    itg->addTimeout( timeout ); -  else -    itg->removeTimeout( timeout ); -} - -void dbusWakeupMain( void* ) -{ -} - -void dbusNewConnection( DBusServer     *server, -                        DBusConnection *new_connection, -                        void           *data ) -{ -  Integrator *itg = static_cast<Integrator*>( data ); -  itg->handleConnection( new_connection ); -} -///////////////////////////////////////////////////////////// - -Timeout::Timeout( QObject *parent, DBusTimeout *t ) -  : QObject( parent ),  m_timeout( t ) -{ -  m_timer = new QTimer( this ); -  connect( m_timer,  SIGNAL(timeout()), -           SLOT(slotTimeout()) ); -} - -void Timeout::slotTimeout() -{ -  emit timeout( m_timeout ); -} - -void Timeout::start() -{ -  m_timer->start( dbus_timeout_get_interval( m_timeout ) ); -} - -Integrator::Integrator( DBusConnection *conn, QObject *parent ) -  : QObject( parent ), m_connection( conn ) -{ -  m_timeouts.setAutoDelete( true ); - -  dbus_connection_set_watch_functions( m_connection, -                                       dbusAddWatch, -                                       dbusRemoveWatch, -                                       dbusToggleWatch, -                                       this, 0 ); -  dbus_connection_set_timeout_functions( m_connection, -                                         dbusAddTimeout, -                                         dbusRemoveTimeout, -                                         dbusToggleTimeout, -                                         this, 0 ); -  dbus_connection_set_wakeup_main_function( m_connection, -					    dbusWakeupMain, -					    this, 0 ); -} - -Integrator::Integrator( DBusServer *server, QObject *parent ) -  : QObject( parent ), m_server( server ) -{ -  m_connection = reinterpret_cast<DBusConnection*>( m_server ); -  m_timeouts.setAutoDelete( true ); - -  dbus_server_set_watch_functions( m_server, -                                   dbusAddWatch, -                                   dbusRemoveWatch, -                                   dbusToggleWatch, -                                   this, 0 ); -  dbus_server_set_timeout_functions( m_server, -                                     dbusAddTimeout, -                                     dbusRemoveTimeout, -                                     dbusToggleTimeout, -                                     this, 0 ); -  dbus_server_set_new_connection_function( m_server, -                                           dbusNewConnection, -                                           this,  0 ); -} - -void Integrator::slotRead( int fd ) -{ -  QIntDictIterator<Watch>	it( m_watches ); -  for ( ; it.current(); ++it ) -    dbus_watch_handle ( it.current()->watch, DBUS_WATCH_READABLE ); - -  emit readReady(); -} - -void Integrator::slotWrite( int fd ) -{ -  QIntDictIterator<Watch>       it( m_watches ); -  for ( ; it.current(); ++it ) -    dbus_watch_handle ( it.current()->watch, DBUS_WATCH_WRITABLE ); -} - -void Integrator::slotTimeout( DBusTimeout *timeout ) -{ -  dbus_timeout_handle( timeout ); -} - -void Integrator::addWatch( DBusWatch *watch ) -{ -  if ( !dbus_watch_get_enabled( watch ) ) -    return; - -  Watch *qtwatch = new Watch; -  qtwatch->watch = watch; - -  int flags = dbus_watch_get_flags( watch ); -  int fd = dbus_watch_get_fd( watch ); - -  if ( flags & DBUS_WATCH_READABLE ) { -    qtwatch->readSocket = new QSocketNotifier( fd, QSocketNotifier::Read, this ); -    QObject::connect( qtwatch->readSocket, SIGNAL(activated(int)), SLOT(slotRead(int)) ); -  } - -  if (flags & DBUS_WATCH_WRITABLE) { -    qtwatch->writeSocket = new QSocketNotifier( fd, QSocketNotifier::Write, this ); -    QObject::connect( qtwatch->writeSocket, SIGNAL(activated(int)), SLOT(slotWrite(int)) ); -  } - -  m_watches.insert( fd, qtwatch ); -} - -void Integrator::removeWatch( DBusWatch *watch ) -{ -  int key = dbus_watch_get_fd( watch ); - -  Watch *qtwatch = m_watches.take( key ); - -  if ( qtwatch ) { -    delete qtwatch->readSocket;  qtwatch->readSocket = 0; -    delete qtwatch->writeSocket; qtwatch->writeSocket = 0; -    delete qtwatch; -  } -} - -void Integrator::addTimeout( DBusTimeout *timeout ) -{ -  Timeout *mt = new Timeout( this, timeout ); -  m_timeouts.insert( timeout, mt ); -  connect( mt, SIGNAL(timeout(DBusTimeout*)), -           SLOT(slotTimeout(DBusTimeout*)) ); -  mt->start(); -} - -void Integrator::removeTimeout( DBusTimeout *timeout ) -{ -  m_timeouts.remove( timeout ); -} - -void Integrator::handleConnection( DBusConnection *c ) -{ -  Connection *con = new Connection( c, this ); -  emit newConnection( con ); -} - -}//end namespace Internal -}//end namespace DBusQt - -#include "integrator.moc" diff --git a/qt/integrator.h b/qt/integrator.h deleted file mode 100644 index 70e2a7f2..00000000 --- a/qt/integrator.h +++ /dev/null @@ -1,92 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- -/* integrator.h: integrates D-BUS into Qt event loop - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#ifndef DBUS_QT_INTEGRATOR_H -#define DBUS_QT_INTEGRATOR_H - -#include <qobject.h> - -#include <qintdict.h> -#include <qptrdict.h> - -#include "dbus/dbus.h" - -class QTimer; - -namespace DBusQt -{ -  class Connection; - -  namespace Internal -  { -    struct Watch; - -    class Timeout : public QObject -    { -      Q_OBJECT -    public: -      Timeout( QObject *parent, DBusTimeout *t ); -    public: -      void start(); -    signals: -      void timeout( DBusTimeout* ); -    protected slots: -      void slotTimeout(); -    private: -      QTimer *m_timer; -      DBusTimeout *m_timeout; -    }; - -    class Integrator : public QObject -    { -      Q_OBJECT -    public: -      Integrator( DBusConnection *connection, QObject *parent ); -      Integrator( DBusServer *server, QObject *parent ); - -    signals: -      void readReady(); -      void newConnection( Connection* ); - -    protected slots: -      void slotRead( int ); -      void slotWrite( int ); -      void slotTimeout( DBusTimeout *timeout ); - -    public: -      void addWatch( DBusWatch* ); -      void removeWatch( DBusWatch* ); - -      void addTimeout( DBusTimeout* ); -      void removeTimeout( DBusTimeout* ); - -      void handleConnection( DBusConnection* ); -    private: -      QIntDict<Watch> m_watches; -      QPtrDict<Timeout> m_timeouts; -      DBusConnection *m_connection; -      DBusServer *m_server; -    }; -  } -} - -#endif diff --git a/qt/message.cpp b/qt/message.cpp deleted file mode 100644 index 256c2b23..00000000 --- a/qt/message.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- */ -/* message.cpp: Qt wrapper for DBusMessage - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.0 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#include "message.h" - -#include <qmap.h> - -#include <cstdlib> - -namespace DBusQt { - -struct Message::iterator::IteratorData { -  DBusMessageIter *iter; -  QVariant         var; -  bool             end; -  DBusMessage	  *mesg; -}; - -/** - * Iterator. - */ -Message::iterator::iterator() -{ -  d = new IteratorData; -  d->iter = 0; d->end = true; -} - -/** - * Constructs iterator for the message. - * @param msg message whose fields we want to iterate - */ -Message::iterator::iterator( DBusMessage* msg ) -{ -  d = new IteratorData; -  d->mesg = msg; -  d->iter = static_cast<DBusMessageIter *>( malloc( sizeof(DBusMessageIter) ) ); -  dbus_message_iter_init( d->mesg, d->iter ); -  if ( !d->iter ) { -    qDebug("No iterator??"); -  } -  fillVar(); -  d->end = false; -} - -/** - * Copy constructor for the iterator. - * @param itr iterator - */ -Message::iterator::iterator( const iterator& itr ) -{ -  d = new IteratorData; -  d->iter = itr.d->iter; -  d->var  = itr.d->var; -  d->end  = itr.d->end; -} - -/** - * Destructor. - */ -Message::iterator::~iterator() -{ -  free( d->iter ); -  delete d; d=0; -} - -/** - * Creates an iterator equal to the @p itr iterator - * @param itr other iterator - * @return - */ -Message::iterator& -Message::iterator::operator=( const iterator& itr ) -{ -  IteratorData *tmp = new IteratorData; -  tmp->iter = itr.d->iter; -  tmp->var  = itr.d->var; -  tmp->end  = itr.d->end; -  delete d; d=tmp; -  return *this; -} - -/** - * Returns the constant QVariant held by the iterator. - * @return the constant reference to QVariant held by this iterator - */ -const QVariant& -Message::iterator::operator*() const -{ -  return d->var; -} - -/** - * Returns the QVariant held by the iterator. - * @return reference to QVariant held by this iterator - */ -QVariant& -Message::iterator::operator*() -{ -  return d->var; -} - -/** - * Moves to the next field and return a reference to itself after - * incrementing. - * @return reference to self after incrementing - */ -Message::iterator& -Message::iterator::operator++() -{ -  if ( d->end ) -    return *this; - -  if (  dbus_message_iter_next( d->iter ) ) { -    fillVar(); -  } else { -    d->end = true; -    d->var = QVariant(); -  } -  return *this; -} - -/** - * Moves to the next field and returns self before incrementing. - * @return self before incrementing - */ -Message::iterator -Message::iterator::operator++(int) -{ -  iterator itr( *this ); -  operator++(); -  return itr; -} - -/** - * Compares this iterator to @p it iterator. - * @param it the iterator to which we're comparing this one to - * @return true if they're equal, false otherwise - */ -bool -Message::iterator::operator==( const iterator& it ) -{ -  if ( d->end == it.d->end ) { -    if ( d->end == true ) { -      return true; -    } else { -      return d->var == it.d->var; -    } -  } else -    return false; -} - -/** - * Compares two iterators. - * @param it The other iterator. - * @return true if two iterators are not equal, false - *         otherwise - */ -bool -Message::iterator::operator!=( const iterator& it ) -{ -  return !operator==( it ); -} - -QVariant Message::iterator::marshallBaseType( DBusMessageIter* i ) -{ -  QVariant ret; -  switch (dbus_message_iter_get_arg_type(i)) { -  case DBUS_TYPE_INT32: -    { -      dbus_int32_t v; -      dbus_message_iter_get_basic (i, &v); -      ret = QVariant( v ); -    } -    break; -  case DBUS_TYPE_UINT32: -    { -      dbus_uint32_t v; -      dbus_message_iter_get_basic (i, &v); -      ret = QVariant( v ); -    } -    break; -  case DBUS_TYPE_DOUBLE: -    { -      double v; -      dbus_message_iter_get_basic (i, &v); -      ret = QVariant( v ); -    } -    break; -  case DBUS_TYPE_STRING: -    { -      const char *v; -      dbus_message_iter_get_basic (i, &v); -      ret = QVariant( v ); -    } -    break; -  default: -    ret = QVariant(); -    break; -  } -  return ret; -} - -/** - * Fills QVariant based on what current DBusMessageIter helds. - */ -void -Message::iterator::fillVar() -{ -  switch ( dbus_message_iter_get_arg_type( d->iter ) ) { -  case DBUS_TYPE_INT32: -  case DBUS_TYPE_UINT32: -  case DBUS_TYPE_DOUBLE: -  case DBUS_TYPE_STRING: -    d->var = marshallBaseType( d->iter ); -    break; -  case DBUS_TYPE_ARRAY: { -    switch ( dbus_message_iter_get_element_type( d->iter ) ) { -    case DBUS_TYPE_STRING: { -      QStringList tempList; -      DBusMessageIter sub; -      dbus_message_iter_recurse (d->iter, &sub); -      while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) -        { -          const char *v; -          dbus_message_iter_get_basic (&sub, &v); -          tempList.append( QString( v ) ); -          dbus_message_iter_next (&sub); -        } -      d->var = QVariant( tempList ); -      break; -    } -    default: -      qDebug( "Array of type not implemented" ); -      d->var = QVariant(); -      break; -    } -    break; -  } -#if 0 -  /* DICT is gone for now, but expected to be reintroduced, or else -   * reintroduced as a flag on the introspection data that can -   * apply to array of struct of two fields -   */ -  case DBUS_TYPE_DICT: { -    qDebug( "Got a hash!" ); -    QMap<QString, QVariant> tempMap; -    DBusMessageIter dictIter; -    dbus_message_iter_init_dict_iterator( d->iter, &dictIter ); -    do { -      char *key = dbus_message_iter_get_dict_key( &dictIter ); -      tempMap[key] = marshallBaseType( &dictIter ); -      dbus_free( key ); -      dbus_message_iter_next( &dictIter ); -    } while( dbus_message_iter_has_next( &dictIter ) ); -    d->var = QVariant( tempMap ); -    break; -    qDebug( "Hash/Dict type not implemented" ); -    d->var = QVariant(); -    break; -  } -#endif -  default: -    qDebug( "not implemented" ); -    d->var = QVariant(); -    break; -  } -} - -/** - * Returns a QVariant help by this iterator. - * @return QVariant held by this iterator - */ -QVariant -Message::iterator::var() const -{ -  return d->var; -} - -struct Message::Private { -  DBusMessage *msg; -}; - -Message::Message( DBusMessage *m ) -{ -  d = new Private; -  d->msg = m; -} - -/** - * - */ -Message::Message( int messageType ) -{ -  d = new Private; -  d->msg = dbus_message_new( messageType ); -} - -/** - * Constructs a new Message with the given service and name. - * @param service service service that the message should be sent to - * @param name name of the message - */ -Message::Message( const QString& service, const QString& path, -                  const QString& interface, const QString& method ) -{ -  d = new Private; -  d->msg = dbus_message_new_method_call( service.latin1(), path.latin1(), -                                         interface.latin1(), method.latin1() ); -} - -/** - * Constructs a message that is a reply to some other - * message. - * @param name the name of the message - * @param replayingTo original_message the message which the created - * message is a reply to. - */ -Message::Message( const Message& replayingTo ) -{ -  d = new Private; -  d->msg = dbus_message_new_method_return( replayingTo.d->msg ); -} - -Message:: Message( const QString& path, const QString& interface, -                   const QString& name ) -{ -  d = new Private; -  d->msg = dbus_message_new_signal( path.ascii(), interface.ascii(), -                                    name.ascii() ); -} - -Message::Message( const Message& replayingTo, const QString& errorName, -                  const QString& errorMessage ) -{ -  d = new Private; -  d->msg = dbus_message_new_error( replayingTo.d->msg, errorName.utf8(), -                                   errorMessage.utf8() ); -} - -Message Message::operator=( const Message& other ) -{ -  //FIXME: ref the other.d->msg instead of copying it? -} -/** - * Destructs message. - */ -Message::~Message() -{ -  if ( d->msg ) { -    dbus_message_unref( d->msg ); -  } -  delete d; d=0; -} - -int Message::type() const -{ -  return dbus_message_get_type( d->msg ); -} - -void Message::setPath( const QString& path ) -{ -  dbus_message_set_path( d->msg, path.ascii() ); -} - -QString Message::path() const -{ -  return dbus_message_get_path( d->msg ); -} - -void Message::setInterface( const QString& iface ) -{ -  dbus_message_set_interface( d->msg, iface.ascii() ); -} - -QString Message::interface() const -{ -  return dbus_message_get_interface( d->msg ); -} - -void Message::setMember( const QString& member ) -{ -  dbus_message_set_member( d->msg, member.ascii() ); -} - -QString Message::member() const -{ -  return dbus_message_get_member( d->msg ); -} - -void Message::setErrorName( const QString& err ) -{ -  dbus_message_set_error_name( d->msg, err ); -} - -QString Message::errorName() const -{ -  return dbus_message_get_error_name( d->msg ); -} - -void Message::setDestination( const QString& dest ) -{ -  dbus_message_set_destination( d->msg, dest ); -} - -QString Message::destination() const -{ -  return dbus_message_get_destination( d->msg ); -} - -/** - * Sets the message sender. - * @param sender the sender - * @return false if unsuccessful - */ -bool -Message::setSender( const QString& sender ) -{ -  return dbus_message_set_sender( d->msg, sender.latin1() ); -} - -/** - * Returns sender of this message. - * @return sender - */ -QString -Message::sender() const -{ -  return dbus_message_get_sender( d->msg ); -} - -QString Message::signature() const -{ -  return dbus_message_get_signature( d->msg ); -} - - -/** - * Returns the starting iterator for the fields of this - * message. - * @return starting iterator - */ -Message::iterator -Message::begin() const -{ -  return iterator( d->msg ); -} - -/** - * Returns the ending iterator for the fields of this - * message. - * @return ending iterator - */ -Message::iterator -Message::end() const -{ -  return iterator(); -} - -/** - * Returns the field at position @p i - * @param i position of the wanted field - * @return QVariant at position @p i or an empty QVariant - */ -QVariant -Message::at( int i ) -{ -  iterator itr( d->msg ); - -  while ( i-- ) { -    if ( itr == end() ) -      return QVariant();//nothing there -    ++itr; -  } -  return *itr; -} - -/** - * The underlying DBusMessage of this class. - * @return DBusMessage pointer. - */ -DBusMessage* -Message::message() const -{ -  return d->msg; -} - -Message& Message::operator<<( bool b ) -{ -  const dbus_bool_t right_size_bool = b; -  dbus_message_append_args( d->msg, DBUS_TYPE_BOOLEAN, &right_size_bool, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( Q_INT8 byte ) -{ -  dbus_message_append_args( d->msg, DBUS_TYPE_BYTE, &byte, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( Q_INT32 num ) -{ -  dbus_message_append_args( d->msg, DBUS_TYPE_INT32, &num, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( Q_UINT32 num ) -{ -  dbus_message_append_args( d->msg, DBUS_TYPE_UINT32, &num, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( Q_INT64 num ) -{ -  dbus_message_append_args( d->msg, DBUS_TYPE_INT64, &num, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( Q_UINT64 num ) -{ -  dbus_message_append_args( d->msg, DBUS_TYPE_UINT64, &num, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( double num ) -{ -  dbus_message_append_args( d->msg, DBUS_TYPE_DOUBLE, &num, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( const QString& str ) -{ -  const char *u = str.utf8(); -  dbus_message_append_args( d->msg, DBUS_TYPE_STRING, &u, -                            DBUS_TYPE_INVALID ); -} - -Message& Message::operator<<( const QVariant& custom ) -{ -  //FIXME: imeplement -} - -} diff --git a/qt/message.h b/qt/message.h deleted file mode 100644 index 5e26b819..00000000 --- a/qt/message.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- */ -/* message.h: Qt wrapper for DBusMessage - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.1 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#ifndef DBUS_QT_MESSAGE_H -#define DBUS_QT_MESSAGE_H - -#include <qvariant.h> -#include <qstring.h> -#include <qstringlist.h> - -#include "dbus/dbus.h" - -namespace DBusQt { - -  class Message -  { -  public: -    class iterator { -    public: -      iterator(); -      iterator( const iterator& ); -      iterator( DBusMessage* msg ); -      ~iterator(); - -      iterator& operator=( const iterator& ); -      const QVariant& operator*() const; -      QVariant& operator*(); -      iterator& operator++(); -      iterator operator++(int); -      bool operator==( const iterator& it ); -      bool operator!=( const iterator& it ); - -      QVariant var() const; -    protected: -      QVariant marshallBaseType( DBusMessageIter* i ); -      void fillVar(); -      struct IteratorData; -      IteratorData *d; -    }; - -    Message( int messageType ); -    Message( DBusMessage * );//hide this one from the public implementation -    Message( const QString& service, const QString& path, -             const QString& interface, const QString& method ); -    Message( const Message& replayingTo ); -    Message( const QString& path, const QString& interface, -             const QString& name ); -    Message( const Message& replayingTo, const QString& errorName, -             const QString& errorMessage ); - -    Message operator=( const Message& other ); - -    virtual ~Message(); - -    int type() const; - -    void setPath( const QString& ); -    QString path() const; - -    void setInterface( const QString& ); -    QString interface() const; - -    void setMember( const QString& ); -    QString member() const; - -    void setErrorName( const QString& ); -    QString errorName() const; - -    void setDestination( const QString& ); -    QString destination() const; - -    bool    setSender( const QString& sender ); -    QString    sender() const; - -    QString signature() const; - -    iterator begin() const; -    iterator end() const; - -    QVariant at( int i ); - - -  public: -    Message& operator<<( bool ); -    Message& operator<<( Q_INT8 ); -    Message& operator<<( Q_INT32 ); -    Message& operator<<( Q_UINT32 ); -    Message& operator<<( Q_INT64 ); -    Message& operator<<( Q_UINT64 ); -    Message& operator<<( double ); -    Message& operator<<( const QString& ); -    Message& operator<<( const QVariant& ); -    //Message& operator<<(); -    //Message& operator<<(); -    //Message& operator<<(); -    //Message& operator<<(); -    //Message& operator<<(); -    //Message& operator<<(); -    //Message& operator<<(); - -  protected: -    friend class Connection; -    DBusMessage* message() const; - -  private: -    struct Private; -    Private *d; -  }; - -} - -#endif diff --git a/qt/qdbus.h b/qt/qdbus.h new file mode 100644 index 00000000..35454219 --- /dev/null +++ b/qt/qdbus.h @@ -0,0 +1,31 @@ +/* qdbus.h precompiled header + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUS_H +#define QDBUS_H + +#include <QtDBUS/qdbusconnection.h> +#include <QtDBUS/qdbuserror.h> +#include <QtDBUS/qdbusmessage.h> +#include <QtDBUS/qdbusserver.h> + +#endif diff --git a/qt/qdbusconnection.cpp b/qt/qdbusconnection.cpp new file mode 100644 index 00000000..6493ef2a --- /dev/null +++ b/qt/qdbusconnection.cpp @@ -0,0 +1,328 @@ +/* qdbusconnection.cpp + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <QtCore/qdebug.h> +#include <QtCore/qcoreapplication.h> + +#include "qdbusconnection.h" +#include "qdbuserror.h" +#include "qdbusmessage.h" +#include "qdbusconnection_p.h" + +QT_STATIC_CONST_IMPL char *QDBusConnection::default_connection_name = "qt_dbus_default_connection"; + +class QDBusConnectionManager +{ +public: +    QDBusConnectionManager(): default_connection(0) {} +    ~QDBusConnectionManager(); +    void bindToApplication(); +    QDBusConnectionPrivate *connection(const QString &name) const; +    void removeConnection(const QString &name); +    void setConnection(const QString &name, QDBusConnectionPrivate *c); + +private: +    QDBusConnectionPrivate *default_connection; +    QHash<QString, QDBusConnectionPrivate *> connectionHash; +}; + +Q_GLOBAL_STATIC(QDBusConnectionManager, manager); + +QDBusConnectionPrivate *QDBusConnectionManager::connection(const QString &name) const +{ +    return name == QLatin1String(QDBusConnection::default_connection_name) ? +            default_connection : connectionHash.value(name, 0); +} + +void QDBusConnectionManager::removeConnection(const QString &name) +{ +    QDBusConnectionPrivate *d = 0; +    if (name == QLatin1String(QDBusConnection::default_connection_name)) { +        d = default_connection; +        default_connection = 0; +    } else { +        d = connectionHash.take(name); +    } +    if (!d->ref.deref()) +        delete d; +} + +QDBusConnectionManager::~QDBusConnectionManager() +{ +    if (default_connection) { +        delete default_connection; +        default_connection = 0; +    } +    for (QHash<QString, QDBusConnectionPrivate *>::const_iterator it = connectionHash.constBegin(); +         it != connectionHash.constEnd(); ++it) { +             delete it.value(); +    } +    connectionHash.clear(); +} + +void QDBusConnectionManager::bindToApplication() +{ +    if (default_connection) { +        default_connection->bindToApplication(); +    } +    for (QHash<QString, QDBusConnectionPrivate *>::const_iterator it = connectionHash.constBegin(); +         it != connectionHash.constEnd(); ++it) { +             (*it)->bindToApplication(); +    } +} + +void qDBusBindToApplication() +{ +    manager()->bindToApplication(); +} + +void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionPrivate *c) +{ +    if (name == QLatin1String(QDBusConnection::default_connection_name)) +        default_connection = c; +    else +        connectionHash[name] = c; +} + + +QDBusConnection::QDBusConnection(const QString &name) +{ +    d = manager()->connection(name); +    if (d) +        d->ref.ref(); +} + +QDBusConnection::QDBusConnection(const QDBusConnection &other) +{ +    d = other.d; +    if (d) +        d->ref.ref(); +} + +QDBusConnection::~QDBusConnection() +{ +    if (d && !d->ref.deref()) +        delete d; +} + +QDBusConnection &QDBusConnection::operator=(const QDBusConnection &other) +{ +    if (other.d) +        other.d->ref.ref(); +    QDBusConnectionPrivate *old = static_cast<QDBusConnectionPrivate *>( +            q_atomic_set_ptr(&d, other.d)); +    if (old && !old->ref.deref()) +        delete old; + +    return *this; +} + +QDBusConnection QDBusConnection::addConnection(BusType type, const QString &name) +{ +//    Q_ASSERT_X(QCoreApplication::instance(), "QDBusConnection::addConnection", +//               "Cannot create connection without a Q[Core]Application instance"); + +    QDBusConnectionPrivate *d = manager()->connection(name); +    if (d) +        return QDBusConnection(name); + +    d = new QDBusConnectionPrivate; +    DBusConnection *c = 0; +    switch (type) { +        case SystemBus: +            c = dbus_bus_get(DBUS_BUS_SYSTEM, &d->error); +            break; +        case SessionBus: +            c = dbus_bus_get(DBUS_BUS_SESSION, &d->error); +            break; +        case ActivationBus: +            c = dbus_bus_get(DBUS_BUS_STARTER, &d->error); +            break; +    } +    d->setConnection(c); //setConnection does the error handling for us + +    manager()->setConnection(name, d); + +    return QDBusConnection(name); +} + +QDBusConnection QDBusConnection::addConnection(const QString &address, +                    const QString &name) +{ +//    Q_ASSERT_X(QCoreApplication::instance(), "QDBusConnection::addConnection", +//               "Cannot create connection without a Q[Core]Application instance"); + +    QDBusConnectionPrivate *d = manager()->connection(name); +    if (d) +        return QDBusConnection(name); + +    d = new QDBusConnectionPrivate; +    // setConnection does the error handling for us +    d->setConnection(dbus_connection_open(address.toUtf8().constData(), &d->error)); + +    manager()->setConnection(name, d); + +    return QDBusConnection(name); +} + +void QDBusConnection::closeConnection(const QString &name) +{ +    manager()->removeConnection(name); +} + +void QDBusConnectionPrivate::timerEvent(QTimerEvent *e) +{ +    DBusTimeout *timeout = timeouts.value(e->timerId(), 0); +    dbus_timeout_handle(timeout); +} + +bool QDBusConnection::send(const QDBusMessage &message) const +{ +    if (!d || !d->connection) +        return false; + +    DBusMessage *msg = message.toDBusMessage(); +    if (!msg) +        return false; + +    bool isOk = dbus_connection_send(d->connection, msg, 0); +    dbus_message_unref(msg); +    return isOk; +} + +int QDBusConnection::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, +        const char *method) const +{ +    if (!d || !d->connection) +        return 0; + +    return d->sendWithReplyAsync(message, receiver, method); +} + +QDBusMessage QDBusConnection::sendWithReply(const QDBusMessage &message) const +{ +    if (!d || !d->connection) +        return QDBusMessage::fromDBusMessage(0); + +    DBusMessage *msg = message.toDBusMessage(); +    if (!msg) +        return QDBusMessage::fromDBusMessage(0); +    DBusMessage *reply = dbus_connection_send_with_reply_and_block(d->connection, msg, +                                                -1, &d->error); +    d->handleError(); +    dbus_message_unref(msg); + +    return QDBusMessage::fromDBusMessage(reply); +} + +bool QDBusConnection::connect(const QString &path, const QString &interface, +                              const QString &name, QObject *receiver, const char *slot) +{ +    if (!receiver || !slot || !d || !d->connection) +        return false; + +    QDBusConnectionPrivate::SignalHook hook; + +    hook.interface = interface; +    hook.name = name; +    hook.obj = QPointer<QObject>(receiver); +    if (!hook.setSlot(slot + 1)) +        return false; + +    d->signalHooks.insertMulti(path, hook); +    d->connect(receiver, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*))); + +    return true; +} + +bool QDBusConnection::registerObject(const QString &path, const QString &interface, +                                     QObject *object) +{ +    if (!d || !d->connection || !object || path.isEmpty() || interface.isEmpty()) +        return false; + +    QDBusConnectionPrivate::ObjectHook hook; +    hook.interface = interface; +    hook.obj = object; + +    QDBusConnectionPrivate::ObjectHookHash::iterator it = d->objectHooks.find(path); +    while (it != d->objectHooks.end() && it.key() == path) { +        if (it.value().interface == interface) { +            d->objectHooks.erase(it); +            break; +        } +        ++it; +    } + +    d->objectHooks.insert(path, hook); + +    d->connect(object, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*))); +    qDebug("REGISTERED FOR %s", path.toLocal8Bit().constData()); + +    return true; // todo - check for slots etc. +} + +void QDBusConnection::unregisterObject(const QString &path) +{ +    if (!d || !d->connection) +        return; + +    // TODO - check interfaces +    d->objectHooks.remove(path); +} + +bool QDBusConnection::isConnected( ) const +{ +    return d && d->connection && dbus_connection_get_is_connected(d->connection); +} + +QDBusError QDBusConnection::lastError() const +{ +    return d ? d->lastError : QDBusError(); +} + +QString QDBusConnection::baseService() const +{ +    return d && d->connection ? +            QString::fromUtf8(dbus_bus_get_unique_name(d->connection)) +            : QString(); +} + +bool QDBusConnection::requestName(const QString &name, NameRequestMode mode) +{ +    static const int DBusModes[] = { 0, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, +        DBUS_NAME_FLAG_REPLACE_EXISTING }; +    Q_ASSERT(mode == 0 || mode == DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT || +             mode == DBUS_NAME_FLAG_REPLACE_EXISTING); + +    DBusError error; +    dbus_error_init (&error); +    dbus_bus_request_name(d->connection, name.toUtf8(), DBusModes[mode], &error); +    if (dbus_error_is_set (&error)) { +        qDebug("Error %s\n", error.message); +        dbus_error_free (&error); +        return false; +    } +    return true; +} + +#include "qdbusconnection.moc" diff --git a/qt/qdbusconnection.h b/qt/qdbusconnection.h new file mode 100644 index 00000000..16ab2b1a --- /dev/null +++ b/qt/qdbusconnection.h @@ -0,0 +1,78 @@ +/* qdbusconnection.h QDBusConnection object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSCONNECTION_H +#define QDBUSCONNECTION_H + +#include "qdbusmacros.h" +#include <QtCore/qstring.h> + +class QDBusConnectionPrivate; +class QDBusError; +class QDBusMessage; +class QByteArray; +class QObject; + +class QDBUS_EXPORT QDBusConnection +{ +public: +    enum BusType { SessionBus, SystemBus, ActivationBus }; + +    QDBusConnection(const QString &name = QLatin1String(default_connection_name)); +    QDBusConnection(const QDBusConnection &other); +    ~QDBusConnection(); + +    QDBusConnection &operator=(const QDBusConnection &other); + +    bool isConnected() const; +    QDBusError lastError() const; + +    enum NameRequestMode { NoReplace = 0, ProhibitReplace = 1, ReplaceExisting = 2 }; +    bool requestName(const QString &name, NameRequestMode mode = NoReplace); + +    QString baseService() const; + +    bool send(const QDBusMessage &message) const; +    QDBusMessage sendWithReply(const QDBusMessage &message) const; +    int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, +                           const char *slot) const; + +    bool connect(const QString &path, const QString &interface, +                 const QString &name, QObject *receiver, const char *slot); + +    bool registerObject(const QString &path, const QString &interface, +                        QObject *object); +    void unregisterObject(const QString &path); + +    static QDBusConnection addConnection(BusType type, +                               const QString &name = QLatin1String(default_connection_name)); +    static QDBusConnection addConnection(const QString &address, +                               const QString &name = QLatin1String(default_connection_name)); +    static void closeConnection(const QString &name = QLatin1String(default_connection_name)); + +    QT_STATIC_CONST char *default_connection_name; + +private: +    QDBusConnectionPrivate *d; +}; + +#endif diff --git a/qt/qdbusconnection_p.h b/qt/qdbusconnection_p.h new file mode 100644 index 00000000..38acbdc3 --- /dev/null +++ b/qt/qdbusconnection_p.h @@ -0,0 +1,126 @@ +/* qdbusconnection_p.h QDBusConnection private object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +// +//  W A R N I N G +//  ------------- +// +// This file is not part of the public API.  This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + +#include <QtCore/qatomic.h> +#include <QtCore/qhash.h> +#include <QtCore/qobject.h> +#include <QtCore/qpointer.h> +#include <QtCore/qvarlengtharray.h> + +#include <dbus/dbus.h> + +#include "qdbuserror.h" + +class QDBusMessage; +class QSocketNotifier; +class QTimerEvent; + +typedef struct DBusConnection; +typedef struct DBusServer; + +class QDBusConnectionPrivate: public QObject +{ +    Q_OBJECT +public: +    QDBusConnectionPrivate(QObject *parent = 0); +    ~QDBusConnectionPrivate(); + +    void bindToApplication(); + +    void setConnection(DBusConnection *connection); +    void setServer(DBusServer *server); +    void closeConnection(); +    void timerEvent(QTimerEvent *e); + +    bool handleSignal(DBusMessage *msg) const; +    bool handleObjectCall(DBusMessage *message) const; +    bool handleError(); + +public slots: +    void socketRead(int); +    void socketWrite(int); +    void objectDestroyed(QObject *o); + +public: +    DBusError error; +    QDBusError lastError; + +    enum ConnectionMode { InvalidMode, ServerMode, ClientMode }; + +    QAtomic ref; +    ConnectionMode mode; +    DBusConnection *connection; +    DBusServer *server; + +    static int messageMetaType; +    static int registerMessageMetaType(); +    bool handleSignal(const QString &path, const QDBusMessage &msg) const; +    int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, +                           const char *method) const; + +    struct Watcher +    { +        Watcher(): watch(0), read(0), write(0) {} +        DBusWatch *watch; +        QSocketNotifier *read; +        QSocketNotifier *write; +    }; +    typedef QMultiHash<int, Watcher> WatcherHash; +    WatcherHash watchers; + +    typedef QHash<int, DBusTimeout *> TimeoutHash; +    TimeoutHash timeouts; + +    struct SignalHook +    { +        QString interface, name; +        QPointer<QObject> obj; +        int midx; +        QVarLengthArray<int, 10> params; + +        bool setSlot(const char *slotName); +    }; + +    typedef QMultiHash<QString, SignalHook> SignalHookHash; +    SignalHookHash signalHooks; + +    struct ObjectHook +    { +        QString interface; +        QPointer<QObject> obj; +    }; +    typedef QMultiHash<QString, ObjectHook> ObjectHookHash; +    ObjectHookHash objectHooks; +    QList<DBusTimeout *> pendingTimeouts; +}; diff --git a/qt/qdbuserror.cpp b/qt/qdbuserror.cpp new file mode 100644 index 00000000..0f7dc92c --- /dev/null +++ b/qt/qdbuserror.cpp @@ -0,0 +1,46 @@ +/* qdbuserror.h QDBusError object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include "qdbuserror.h" + +#include <QtCore/qdebug.h> + +#include <dbus/dbus.h> + +QDBusError::QDBusError(const DBusError *error) +{ +    if (!error || !dbus_error_is_set(error)) +        return; + +    nm = QString::fromUtf8(error->name); +    msg = QString::fromUtf8(error->message); +} + +#ifndef QT_NO_DEBUG +QDebug operator<<(QDebug dbg, const QDBusError &msg) +{ +    dbg.nospace() << "QDBusError(" << msg.name() << ", " << msg.message() << ")"; +    return dbg.space(); +} +#endif + + diff --git a/qt/qdbuserror.h b/qt/qdbuserror.h new file mode 100644 index 00000000..d554426d --- /dev/null +++ b/qt/qdbuserror.h @@ -0,0 +1,48 @@ +/* qdbuserror.h QDBusError object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSERROR_H +#define QDBUSERROR_H + +#include "qdbusmacros.h" +#include <QtCore/qstring.h> + +struct DBusError; + +class QDBUS_EXPORT QDBusError +{ +public: +    QDBusError(const DBusError *error = 0); + +    inline QString name() const { return nm; } +    inline QString message() const { return msg; } +    inline bool isValid() const { return !nm.isNull() && !msg.isNull(); } + +private: +    QString nm, msg; +}; + +#ifndef QT_NO_DEBUG +QDebug operator<<(QDebug, const QDBusError &); +#endif + +#endif diff --git a/qt/qdbusintegrator.cpp b/qt/qdbusintegrator.cpp new file mode 100644 index 00000000..4a19d33e --- /dev/null +++ b/qt/qdbusintegrator.cpp @@ -0,0 +1,621 @@ +/* qdbusintegrator.cpp QDBusConnection private implementation + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qdebug.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/qsocketnotifier.h> + +#include "qdbusconnection_p.h" +#include "qdbusmessage.h" + +int QDBusConnectionPrivate::messageMetaType = 0; + +static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) +{ +    Q_ASSERT(timeout); +    Q_ASSERT(data); + +  //  qDebug("addTimeout %d", dbus_timeout_get_interval(timeout)); + +    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); + +    if (!dbus_timeout_get_enabled(timeout)) +        return true; + +    if (!QCoreApplication::instance()) { +        d->pendingTimeouts.append(timeout); +        return true; +    } +    int timerId = d->startTimer(dbus_timeout_get_interval(timeout)); +    if (!timerId) +        return false; + +    d->timeouts[timerId] = timeout; +    return true; +} + +static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data) +{ +    Q_ASSERT(timeout); +    Q_ASSERT(data); + +  //  qDebug("removeTimeout"); + +    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); +    d->pendingTimeouts.removeAll(timeout); + +    QDBusConnectionPrivate::TimeoutHash::iterator it = d->timeouts.begin(); +    while (it != d->timeouts.end()) { +        if (it.value() == timeout) { +            d->killTimer(it.key()); +            it = d->timeouts.erase(it); +        } else { +            ++it; +        } +    } +} + +static void qDBusToggleTimeout(DBusTimeout *timeout, void *data) +{ +    Q_ASSERT(timeout); +    Q_ASSERT(data); + +    qDebug("ToggleTimeout"); + +    qDBusRemoveTimeout(timeout, data); +    qDBusAddTimeout(timeout, data); +} + +static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data) +{ +    Q_ASSERT(watch); +    Q_ASSERT(data); + +    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); + +    int flags = dbus_watch_get_flags(watch); +    int fd = dbus_watch_get_fd(watch); + +    QDBusConnectionPrivate::Watcher watcher; +    if (flags & DBUS_WATCH_READABLE) { +        qDebug("addReadWatch %d", fd); +        watcher.watch = watch; +        if (QCoreApplication::instance()) { +            watcher.read = new QSocketNotifier(fd, QSocketNotifier::Read, d); +            d->connect(watcher.read, SIGNAL(activated(int)), SLOT(socketRead(int))); +        } +    } +    if (flags & DBUS_WATCH_WRITABLE) { +        qDebug("addWriteWatch %d", fd); +        watcher.watch = watch; +        if (QCoreApplication::instance()) { +            watcher.write = new QSocketNotifier(fd, QSocketNotifier::Write, d); +            d->connect(watcher.write, SIGNAL(activated(int)), SLOT(socketWrite(int))); +        } +    } +    d->watchers.insertMulti(fd, watcher); + +    return true; +} + +static void qDBusRemoveWatch(DBusWatch *watch, void *data) +{ +    Q_ASSERT(watch); +    Q_ASSERT(data); + +    qDebug("remove watch"); + +    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); +    int fd = dbus_watch_get_fd(watch); + +    QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd); +    while (i != d->watchers.end() && i.key() == fd) { +        if (i.value().watch == watch) { +            delete i.value().read; +            delete i.value().write; +            d->watchers.erase(i); +            return; +        } +        ++i; +    } +} + +static void qDBusToggleWatch(DBusWatch *watch, void *data) +{ +    Q_ASSERT(watch); +    Q_ASSERT(data); + +    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); +    int fd = dbus_watch_get_fd(watch); + +    QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd); +    while (i != d->watchers.end() && i.key() == fd) { +        if (i.value().watch == watch) { +            bool enabled = dbus_watch_get_enabled(watch); +            int flags = dbus_watch_get_flags(watch); + +            qDebug("toggle watch %d to %d (write: %d, read: %d)", dbus_watch_get_fd(watch), enabled, flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE); + +            if (flags & DBUS_WATCH_READABLE && i.value().read) +                i.value().read->setEnabled(enabled); +            if (flags & DBUS_WATCH_WRITABLE && i.value().write) +                i.value().write->setEnabled(enabled); +            return; +        } +        ++i; +    } +} + +static void qDBusNewConnection(DBusServer *server, DBusConnection *c, void *data) +{ +    Q_ASSERT(data); Q_ASSERT(server); Q_ASSERT(c); + +    qDebug("SERVER: GOT A NEW CONNECTION"); // TODO +} + +static DBusHandlerResult qDBusSignalFilter(DBusConnection *connection, +                                           DBusMessage *message, void *data) +{ +    Q_ASSERT(data); +    Q_UNUSED(connection); + +    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); +    if (d->mode == QDBusConnectionPrivate::InvalidMode) +        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +    int msgType = dbus_message_get_type(message); +    bool handled = false; + +    QDBusMessage amsg = QDBusMessage::fromDBusMessage(message); +    qDebug() << "got message: " << dbus_message_get_type(message) << amsg; + +    if (msgType == DBUS_MESSAGE_TYPE_SIGNAL) { +        handled = d->handleSignal(message); +    } else if (msgType == DBUS_MESSAGE_TYPE_METHOD_CALL) { +        handled = d->handleObjectCall(message); +    } + +    return handled ? DBUS_HANDLER_RESULT_HANDLED : +            DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static bool qInvokeDBusSlot(const QDBusConnectionPrivate::SignalHook& hook, const QDBusMessage &msg) +{ +    int count = msg.count(); +    if (!(count == hook.params.count() +        || (count + 1 == hook.params.count() +        && hook.params[count] == QDBusConnectionPrivate::messageMetaType))) +        return false; + +    QVarLengthArray<void *, 16> params; +    params.append(0); // return value +    for (int i = 0; i < msg.count(); ++i) { +        const QVariant &v = msg.at(i); +        if (int(v.type()) != hook.params[i]) { +            return false; +        } +        params.append(const_cast<void *>(v.constData())); +    } +    if (count + 1 == hook.params.count()) +        params.append(const_cast<QDBusMessage *>(&msg)); +    return hook.obj->qt_metacall(QMetaObject::InvokeMetaMethod, hook.midx, params.data()) < 0; +} + +static bool qInvokeDBusSlot(QObject *object, int idx, const QDBusMessage &msg) +{ +    Q_ASSERT(object); + +    const QMetaMethod method = object->metaObject()->method(idx); +    if (!method.signature()) +        return false; + +    QVarLengthArray<void *> params; +    params.append(0); // ### return type + +    QList<QByteArray> parameterTypes = method.parameterTypes(); + +    // check parameters, the slot should have <= parameters than the message +    // also allow the QDBusMessage itself as last parameter slot +    if ((parameterTypes.count() > msg.count()) +       || (parameterTypes.count() + 1 != msg.count()) +          && parameterTypes.last() != "QDBusMessage") { +        qWarning("Cannot deliver asynchronous reply to object named '%s' because of parameter " +                 "mismatch. Please check your sendWithReplyAsync() statements.", +                object->objectName().toLocal8Bit().constData()); +        return false; +    } + +    int i; +    for (i = 0; i < parameterTypes.count(); ++i) { +        const QByteArray param = parameterTypes.at(i); +        if (param == msg.at(i).typeName()) { +            params.append(const_cast<void *>(msg.at(i).constData())); +        } else if (i == parameterTypes.count() - 1 && param == "QDBusMessage") { +            params.append(const_cast<void *>(static_cast<const void *>(&msg))); +        } else { +            qWarning("Parameter mismatch while delivering message, expected '%s', got '%s'", +                     msg.at(i).typeName(), param.constData()); +            return false; +        } +    } +    return object->qt_metacall(QMetaObject::InvokeMetaMethod, idx, params.data()) < 0; +} + +static bool qInvokeDBusSlot(QObject *object, QDBusMessage *msg) +{ +    Q_ASSERT(object); +    Q_ASSERT(msg); + +    const QMetaObject *mo = object->metaObject(); +    QVarLengthArray<void *> params; +    params.append(0); // ### return type + +    /* Try to find a slot with all args and the QDBusMessage */ +    QByteArray slotName = msg->name().toUtf8(); // QVarLengthArray? +    slotName.append("("); +    for (int i = 0; i < msg->count(); ++i) { +        slotName.append(msg->at(i).typeName()).append(","); +        params.append(const_cast<void *>(msg->at(i).constData())); +    } +    slotName.append("QDBusMessage)"); + +    int idx = mo->indexOfSlot(slotName.constData()); +    if (idx >= 0) { +        params.append(msg); +        return object->qt_metacall(QMetaObject::InvokeMetaMethod, idx, params.data()) < 0; +    } + +    /* Try to find only args, without the QDBusMessage */ +    slotName.chop(13); +    slotName[slotName.count() - 1] = ')'; + +    idx = mo->indexOfSlot(slotName.constData()); +    if (idx >= 0 && (mo->method(idx).attributes() & QMetaMethod::Scriptable)) +        return object->qt_metacall(QMetaObject::InvokeMetaMethod, idx, params.data()) < 0; + +    /* Try to find a slot with only QDBusMessage */ +    slotName = msg->name().toUtf8(); +    slotName.append("(QDBusMessage)"); + +    idx = mo->indexOfSlot(slotName.constData()); +    if (idx >= 0) +        return QMetaObject::invokeMethod(object, msg->name().toUtf8().constData(), +                                         Q_ARG(QDBusMessage, *msg)); + +    return false; +} + +int QDBusConnectionPrivate::registerMessageMetaType() +{ +    int tp = messageMetaType = qRegisterMetaType<QDBusMessage>("QDBusMessage"); +    return tp; +} + +bool QDBusConnectionPrivate::SignalHook::setSlot(const char *slotName) +{ +    Q_ASSERT(static_cast<QObject *>(obj)); Q_ASSERT(slotName); + +    QByteArray normalizedName = QMetaObject::normalizedSignature(slotName); +    const QMetaObject *mo = obj->metaObject(); +    midx = mo->indexOfMethod(normalizedName.constData()); +    if (midx < 0) +        return false; + +    const QList<QByteArray> ptypes = mo->method(midx).parameterTypes(); +    for (int i = 0; i < ptypes.count(); ++i) { +        int t = QVariant::nameToType(ptypes.at(i).constData()); +        if (t == QVariant::UserType) +            t = QMetaType::type(ptypes.at(i).constData()); +        if (t == QVariant::Invalid) +            return false; +        params.append(t); +    } + +    return true; +} + +QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *parent) +    : QObject(parent), ref(1), mode(InvalidMode), connection(0), server(0) +{ +    static const int msgType = registerMessageMetaType(); +    Q_UNUSED(msgType); + +    dbus_error_init(&error); +} + +QDBusConnectionPrivate::~QDBusConnectionPrivate() +{ +    if (dbus_error_is_set(&error)) +        dbus_error_free(&error); + +    closeConnection(); +} + +void QDBusConnectionPrivate::closeConnection() +{ +    ConnectionMode oldMode = mode; +    mode = InvalidMode; // prevent reentrancy +    if (oldMode == ServerMode) { +        if (server) { +            dbus_server_disconnect(server); +            dbus_server_unref(server); +            server = 0; +        } +    } else if (oldMode == ClientMode) { +        if (connection) { +            dbus_connection_close(connection); +            // send the "close" message +            while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS) +                ; +            dbus_connection_unref(connection); +            connection = 0; +        } +    } +} + +bool QDBusConnectionPrivate::handleError() +{ +    lastError = QDBusError(&error); +    if (dbus_error_is_set(&error)) +        dbus_error_free(&error); +    return lastError.isValid(); +} + +void QDBusConnectionPrivate::bindToApplication() +{ +    // Yay, now that we have an application we are in business +    // Re-add all watchers +    WatcherHash oldWatchers = watchers; +    watchers.clear(); +    QHashIterator<int, QDBusConnectionPrivate::Watcher> it(oldWatchers); +    while (it.hasNext()) { +        it.next(); +        if (!it.value().read && !it.value().write) { +            qDBusAddWatch(it.value().watch, this); +        } +    } + +    // Re-add all timeouts +    while (!pendingTimeouts.isEmpty()) +       qDBusAddTimeout(pendingTimeouts.takeFirst(), this); +} + +void QDBusConnectionPrivate::socketRead(int fd) +{ +    QHashIterator<int, QDBusConnectionPrivate::Watcher> it(watchers); +    while (it.hasNext()) { +        it.next(); +        if (it.key() == fd && it.value().read && it.value().read->isEnabled()) { +            if (!dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE)) +                qDebug("OUT OF MEM"); +        } +    } +    if (mode == ClientMode) +        while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS); +        // ### break out of loop? +} + +void QDBusConnectionPrivate::socketWrite(int fd) +{ +    QHashIterator<int, QDBusConnectionPrivate::Watcher> it(watchers); +    while (it.hasNext()) { +        it.next(); +        if (it.key() == fd && it.value().write && it.value().write->isEnabled()) { +            if (!dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE)) +                qDebug("OUT OF MEM"); +        } +    } +} + +void QDBusConnectionPrivate::objectDestroyed(QObject *obj) +{ +    ObjectHookHash::iterator it = objectHooks.begin(); +    while (it != objectHooks.end()) { +        if (static_cast<QObject *>(it.value().obj) == obj) +            it = objectHooks.erase(it); +        else +            ++it; +    } +    SignalHookHash::iterator sit = signalHooks.begin(); +    while (sit != signalHooks.end()) { +        if (static_cast<QObject *>(sit.value().obj) == obj) +            sit = signalHooks.erase(sit); +        else +            ++sit; +    } +    obj->disconnect(this); +} + +bool QDBusConnectionPrivate::handleObjectCall(DBusMessage *message) const +{ +    QDBusMessage msg = QDBusMessage::fromDBusMessage(message); + +    ObjectHook hook; +    ObjectHookHash::ConstIterator it = objectHooks.find(msg.path()); +    while (it != objectHooks.constEnd() && it.key() == msg.path()) { +        if (it.value().interface == msg.interface()) { +            hook = it.value(); +            break; +        } else if (it.value().interface.isEmpty()) { +            hook = it.value(); +        } +        ++it; +    } + +    if (!hook.obj) { +        qDebug("NO OBJECT for %s", msg.path().toLocal8Bit().constData()); +        return false; +    } + +    if (!qInvokeDBusSlot(hook.obj, &msg)) { +        qDebug("NO SUCH SLOT: %s(QDBusMessage)", msg.name().toLocal8Bit().constData()); +        return false; +    } + +    return true; +} + +bool QDBusConnectionPrivate::handleSignal(const QString &path, const QDBusMessage &msg) const +{ +    SignalHookHash::const_iterator it = signalHooks.find(path); +    qDebug("looking for: %s", path.toLocal8Bit().constData()); +    qDebug() << signalHooks.keys(); +    while (it != signalHooks.constEnd() && it.key() == path) { +        const SignalHook &hook = it.value(); +        if ((hook.name.isEmpty() || hook.name == msg.name()) +             && (hook.interface.isEmpty() || hook.interface == msg.interface())) +            qInvokeDBusSlot(hook, msg); +        ++it; +    } +    return true; +} + +bool QDBusConnectionPrivate::handleSignal(DBusMessage *message) const +{ +    QDBusMessage msg = QDBusMessage::fromDBusMessage(message); + +    // yes, it is a single "|" below... +    return handleSignal(QString(), msg) | handleSignal(msg.path(), msg); +} + +static dbus_int32_t server_slot = -1; + +void QDBusConnectionPrivate::setServer(DBusServer *s) +{ +    if (!server) { +        handleError(); +        return; +    } + +    server = s; +    mode = ServerMode; + +    dbus_server_allocate_data_slot(&server_slot); +    if (server_slot < 0) +        return; + +    dbus_server_set_watch_functions(server, qDBusAddWatch, qDBusRemoveWatch, +                                    qDBusToggleWatch, this, 0); // ### check return type? +    dbus_server_set_timeout_functions(server, qDBusAddTimeout, qDBusRemoveTimeout, +                                      qDBusToggleTimeout, this, 0); +    dbus_server_set_new_connection_function(server, qDBusNewConnection, this, 0); + +    dbus_server_set_data(server, server_slot, this, 0); +} + +void QDBusConnectionPrivate::setConnection(DBusConnection *dbc) +{ +    if (!dbc) { +        handleError(); +        return; +    } + +    connection = dbc; +    mode = ClientMode; + +    dbus_connection_set_exit_on_disconnect(connection, false); +    dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch, +                                        qDBusToggleWatch, this, 0); +    dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout, +                                          qDBusToggleTimeout, this, 0); +//    dbus_bus_add_match(connection, "type='signal',interface='com.trolltech.dbus.Signal'", &error); +//    dbus_bus_add_match(connection, "type='signal'", &error); + +    dbus_bus_add_match(connection, "type='signal'", &error); +    if (handleError()) { +        closeConnection(); +        return; +    } + +    const char *service = dbus_bus_get_unique_name(connection); +    if (service) { +        QVarLengthArray<char, 56> filter; +        filter.append("destination='", 13); +        filter.append(service, qstrlen(service)); +        filter.append("\'\0", 2); + +        dbus_bus_add_match(connection, filter.constData(), &error); +        if (handleError()) { +            closeConnection(); +            return; +        } +    } else { +        qWarning("QDBusConnectionPrivate::SetConnection: Unable to get base service"); +    } + +    dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0); + +    qDebug("base service: %s", service); +} + +struct QDBusPendingCall +{ +    QPointer<QObject> receiver; +    int methodIdx; +    DBusPendingCall *pending; +}; + +static void qDBusResultReceived(DBusPendingCall *pending, void *user_data) +{ +    QDBusPendingCall *call = reinterpret_cast<QDBusPendingCall *>(user_data); +    Q_ASSERT(call->pending == pending); + +    if (!call->receiver.isNull() && call->methodIdx != -1) { +        DBusMessage *reply = dbus_pending_call_steal_reply(pending); +        qInvokeDBusSlot(call->receiver, call->methodIdx, QDBusMessage::fromDBusMessage(reply)); +    } +    dbus_pending_call_unref(pending); +    delete call; +} + +int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, +        const char *method) const +{ +    DBusMessage *msg = message.toDBusMessage(); +    if (!msg) +        return 0; + +    int slotIdx = -1; +    if (receiver && method && *method) { +        QByteArray normalized = QMetaObject::normalizedSignature(method + 1); +        slotIdx = receiver->metaObject()->indexOfMethod(normalized.constData()); +        if (slotIdx == -1) +            qWarning("QDBusConnection::sendWithReplyAsync: no such method: '%s'", +                     normalized.constData()); +    } + +    DBusPendingCall *pending = 0; +    if (dbus_connection_send_with_reply(connection, msg, &pending, message.timeout())) { +        if (slotIdx != -1) { +            QDBusPendingCall *pcall = new QDBusPendingCall; +            pcall->receiver = receiver; +            pcall->methodIdx = slotIdx; +            pcall->pending = dbus_pending_call_ref(pending); +            dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); +        } +        return dbus_message_get_serial(msg); +    } + +    return 0; +} diff --git a/qt/qdbusmacros.h b/qt/qdbusmacros.h new file mode 100644 index 00000000..ee88cdfa --- /dev/null +++ b/qt/qdbusmacros.h @@ -0,0 +1,34 @@ +/* qdbusmessage.h QDBusMessage object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSMACROS_H +#define QDBUSMACROS_H + +#include <QtCore/qglobal.h> + +#ifdef QDBUS_MAKEDLL +# define QDBUS_EXPORT Q_DECL_EXPORT +#else +# define QDBUS_EXPORT Q_DECL_IMPORT +#endif + +#endif diff --git a/qt/qdbusmarshall.cpp b/qt/qdbusmarshall.cpp new file mode 100644 index 00000000..8afcb9f3 --- /dev/null +++ b/qt/qdbusmarshall.cpp @@ -0,0 +1,300 @@ +/* qdbusmarshall.cpp + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include "qdbusmarshall.h" +#include "qdbusvariant.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qvariant.h> +#include <QtCore/qlist.h> +#include <QtCore/qmap.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qvector.h> + +#include <dbus/dbus.h> + +template <typename T> +inline T qIterGet(DBusMessageIter *it) +{ +    T t; +    dbus_message_iter_get_basic(it, &t); +    return t; +} + +static QStringList qFetchStringList(DBusMessageIter *arrayIt) +{ +    QStringList list; + +    DBusMessageIter it; +    dbus_message_iter_recurse(arrayIt, &it); + +    do { +        list.append(QString::fromUtf8(qIterGet<char *>(&it))); +    } while (dbus_message_iter_next(&it)); + +    return list; +} + +static QVariant qFetchParameter(DBusMessageIter *it) +{ +    switch (dbus_message_iter_get_arg_type(it)) { +    case DBUS_TYPE_BYTE: +        return qIterGet<unsigned char>(it); +    case DBUS_TYPE_INT32: +        return qIterGet<dbus_int32_t>(it); +    case DBUS_TYPE_UINT32: +        return qIterGet<dbus_uint32_t>(it); +    case DBUS_TYPE_DOUBLE: +        return qIterGet<double>(it); +    case DBUS_TYPE_BOOLEAN: +        return qIterGet<dbus_bool_t>(it); +    case DBUS_TYPE_INT64: +        return qIterGet<dbus_int64_t>(it); +    case DBUS_TYPE_UINT64: +        return qIterGet<dbus_uint64_t>(it); +    case DBUS_TYPE_STRING: +    case DBUS_TYPE_OBJECT_PATH: +    case DBUS_TYPE_SIGNATURE: +        return QString::fromUtf8(qIterGet<char *>(it)); +    case DBUS_TYPE_ARRAY: { +        int arrayType = dbus_message_iter_get_element_type(it); +        if (arrayType == DBUS_TYPE_STRING || arrayType == DBUS_TYPE_OBJECT_PATH) { +            return qFetchStringList(it); +        } else if (arrayType == DBUS_TYPE_DICT_ENTRY) { +            // ### support other types of maps? +            QMap<QString, QVariant> map; +            DBusMessageIter sub; +            dbus_message_iter_recurse(it, &sub); +            if (!dbus_message_iter_has_next(&sub)) +                return map; +            do { +                DBusMessageIter itemIter; +                dbus_message_iter_recurse(&sub, &itemIter); +                Q_ASSERT(dbus_message_iter_has_next(&itemIter)); +                QString key = qFetchParameter(&itemIter).toString(); +                dbus_message_iter_next(&itemIter); +                map.insertMulti(key, qFetchParameter(&itemIter)); +            } while (dbus_message_iter_next(&sub)); +            return map; +        } else { +            QList<QVariant> list; +            DBusMessageIter sub; +            dbus_message_iter_recurse(it, &sub); +            if (!dbus_message_iter_has_next(&sub)) +                return list; +            do { +                list.append(qFetchParameter(&sub)); +            } while (dbus_message_iter_next(&sub)); +            return list; +        } +        break; } +    case DBUS_TYPE_VARIANT: { +        QDBusVariant dvariant; +        DBusMessageIter sub; +        dbus_message_iter_recurse(it, &sub); +        dvariant.signature = QString::fromUtf8(dbus_message_iter_get_signature(&sub)); +        dvariant.value = qFetchParameter(&sub); +        return qVariantFromValue(dvariant); +    } +#if 0 +    case DBUS_TYPE_DICT: { +        QMap<QString, QVariant> map; +        DBusMessageIter sub; +        dbus_message +        if (dbus_message_iter_init_dict_iterator(it, &dictIt)) { +            do { +                map[QString::fromUtf8(dbus_message_iter_get_dict_key(&dictIt))] = +                    qFetchParameter(&dictIt); +            } while (dbus_message_iter_next(&dictIt)); +        } +        return map; +        break; } +    case DBUS_TYPE_CUSTOM: +        return qGetCustomValue(it); +        break; +#endif +    default: +        qWarning("Don't know how to handle type %d '%c'", dbus_message_iter_get_arg_type(it), dbus_message_iter_get_arg_type(it)); +        return QVariant(); +        break; +    } +} + +void QDBusMarshall::messageToList(QList<QVariant> &list, DBusMessage *message) +{ +    Q_ASSERT(message); + +    DBusMessageIter it; +    if (!dbus_message_iter_init(message, &it)) +        return; + +    do { +        list.append(qFetchParameter(&it)); +    } while (dbus_message_iter_next(&it)); +} + +#define DBUS_APPEND(type,dtype,var) \ +type dtype##v=(var); \ +dbus_message_append_args(msg, dtype, &dtype##v, DBUS_TYPE_INVALID) +#define DBUS_APPEND_LIST(type,dtype,var,size) \ +type dtype##v=(var); \ +dbus_message_append_args(msg, DBUS_TYPE_ARRAY, dtype, &dtype##v, size, DBUS_TYPE_INVALID) + + +static void qAppendToMessage(DBusMessageIter *it, const QString &str) +{ +    QByteArray ba = str.toUtf8(); +    const char *cdata = ba.constData(); +    dbus_message_iter_append_basic(it, DBUS_TYPE_STRING, &cdata); +} + +static QVariant::Type qVariantListType(const QList<QVariant> &list) +{ +    // TODO - catch lists that have a list as first parameter +    QVariant::Type tp = list.value(0).type(); +    if (tp < QVariant::Int || tp > QVariant::Double) +        return QVariant::Invalid; + +    for (int i = 1; i < list.count(); ++i) { +        const QVariant &var = list.at(i); +        if (var.type() != tp +               && (var.type() != QVariant::List || qVariantListType(var.toList()) != tp)) +            return QVariant::Invalid; +    } +    return tp; +} + +static const char *qDBusListType(const QList<QVariant> &list) +{ +    static const char *DBusArgs[] = { 0, 0, DBUS_TYPE_INT32_AS_STRING, DBUS_TYPE_UINT32_AS_STRING, +            DBUS_TYPE_INT64_AS_STRING, DBUS_TYPE_UINT64_AS_STRING, DBUS_TYPE_DOUBLE_AS_STRING }; + +    return DBusArgs[qVariantListType(list)]; +} + +static void qListToIterator(DBusMessageIter *it, const QList<QVariant> &list); + +static void qVariantToIterator(DBusMessageIter *it, const QVariant &var) +{ +    static const int Variant2DBus[] = { DBUS_TYPE_INVALID, +        DBUS_TYPE_BOOLEAN, DBUS_TYPE_INT32, DBUS_TYPE_UINT32, +        DBUS_TYPE_INT64, DBUS_TYPE_UINT64, DBUS_TYPE_DOUBLE }; + +    // these really are static asserts +    Q_ASSERT(QVariant::Invalid == 0); +    Q_ASSERT(QVariant::Int == 2); +    Q_ASSERT(QVariant::Double == 6); + +    switch (var.type()) { +    case QVariant::Int: +    case QVariant::UInt: +    case QVariant::LongLong: +    case QVariant::ULongLong: +    case QVariant::Double: +        dbus_message_iter_append_basic(it, Variant2DBus[var.type()], +                var.constData()); +        break; +    case QVariant::String: +        qAppendToMessage(it, var.toString()); +        break; +    case QVariant::StringList: { +        const QStringList list = var.toStringList(); +        DBusMessageIter sub; +        dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, +                                         DBUS_TYPE_STRING_AS_STRING, &sub); +        for (int s = 0; s < list.count(); ++s) +            qAppendToMessage(&sub, list.at(s)); +        dbus_message_iter_close_container(it, &sub); +        break; +    } +    case QVariant::List: { +        const QList<QVariant> &list = var.toList(); +        const char *listType = qDBusListType(list); +        if (!listType) { +            qWarning("Don't know how to marshall list."); +            break; +        } +        DBusMessageIter sub; +        dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, listType, &sub); +        qListToIterator(&sub, list); +        dbus_message_iter_close_container(it, &sub); +        break; +    } +    case QVariant::Map: { +        // ### TODO - marshall more than qstring/qstring maps +        const QMap<QString, QVariant> &map = var.toMap(); +        DBusMessageIter sub; +        QVarLengthArray<char, 16> sig; +        sig.append(DBUS_DICT_ENTRY_BEGIN_CHAR); +        sig.append(DBUS_TYPE_STRING); +        sig.append(DBUS_TYPE_STRING); +        sig.append(DBUS_DICT_ENTRY_END_CHAR); +        sig.append('\0'); +        qDebug() << QString::fromAscii(sig.constData()); +        dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.constData(), &sub); +        for (QMap<QString, QVariant>::const_iterator mit = map.constBegin(); +             mit != map.constEnd(); ++mit) { +            DBusMessageIter itemIterator; +            dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, 0, &itemIterator); +            qAppendToMessage(&itemIterator, mit.key()); +            qAppendToMessage(&itemIterator, mit.value().toString()); +            dbus_message_iter_close_container(&sub, &itemIterator); +        } +        dbus_message_iter_close_container(it, &sub); +        break; +    } +    case QVariant::UserType: { +        if (var.userType() == QMetaTypeId<QDBusVariant>::qt_metatype_id()) { +            DBusMessageIter sub; +            QDBusVariant dvariant = qvariant_cast<QDBusVariant>(var); +            dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, +                    dvariant.signature.toUtf8().constData(), &sub); +            qVariantToIterator(&sub, dvariant.value); +            dbus_message_iter_close_container(it, &sub); +            break; +        } +    } +    // fall through +    default: +        qWarning("Don't know how to handle type %s", var.typeName()); +        break; +    } +} + +void qListToIterator(DBusMessageIter *it, const QList<QVariant> &list) +{ +    if (list.isEmpty()) +        return; + +    for (int i = 0; i < list.count(); ++i) +        qVariantToIterator(it, list.at(i)); +} + +void QDBusMarshall::listToMessage(const QList<QVariant> &list, DBusMessage *msg) +{ +    Q_ASSERT(msg); +    DBusMessageIter it; +    dbus_message_iter_init_append(msg, &it); +    qListToIterator(&it, list); +} + diff --git a/qt/qdbusmarshall.h b/qt/qdbusmarshall.h new file mode 100644 index 00000000..4fc1a1ab --- /dev/null +++ b/qt/qdbusmarshall.h @@ -0,0 +1,39 @@ +/* qdbusmarshall.h QDBusMarshall object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSMARSHALL_H +#define QDBUSMARSHALL_H + +struct DBusMessage; + +class QVariant; +template <typename T> +class QList; + +class QDBusMarshall +{ +public: +    static void listToMessage(const QList<QVariant> &list, DBusMessage *message); +    static void messageToList(QList<QVariant> &list, DBusMessage *message); +}; + +#endif diff --git a/qt/qdbusmessage.cpp b/qt/qdbusmessage.cpp new file mode 100644 index 00000000..a77c22f0 --- /dev/null +++ b/qt/qdbusmessage.cpp @@ -0,0 +1,233 @@ +/* qdbusmessage.cpp + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include "qdbusmessage.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qstringlist.h> + +#include <dbus/dbus.h> + +#include "qdbusmarshall.h" +#include "qdbusmessage_p.h" + +QDBusMessagePrivate::QDBusMessagePrivate(QDBusMessage *qq) +    : msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), ref(1) +{ +} + +QDBusMessagePrivate::~QDBusMessagePrivate() +{ +    if (msg) +        dbus_message_unref(msg); +    if (reply) +        dbus_message_unref(reply); +} + +/////////////// + + +QDBusMessage QDBusMessage::signal(const QString &path, const QString &interface, +                                  const QString &name) +{ +    QDBusMessage message; +    message.d->type = DBUS_MESSAGE_TYPE_SIGNAL; +    message.d->path = path; +    message.d->interface = interface; +    message.d->name = name; + +    return message; +} + +QDBusMessage QDBusMessage::methodCall(const QString &service, const QString &path, +                                      const QString &interface, const QString &method) +{ +    QDBusMessage message; +    message.d->type = DBUS_MESSAGE_TYPE_METHOD_CALL; +    message.d->service = service; +    message.d->path = path; +    message.d->interface = interface; +    message.d->method = method; + +    return message; +} + +QDBusMessage QDBusMessage::methodReply(const QDBusMessage &other) +{ +    Q_ASSERT(other.d->msg); + +    QDBusMessage message; +    message.d->type = DBUS_MESSAGE_TYPE_METHOD_RETURN; +    message.d->reply = dbus_message_ref(other.d->msg); + +    return message; +} + +QDBusMessage::QDBusMessage() +{ +    d = new QDBusMessagePrivate(this); +} + +QDBusMessage::QDBusMessage(const QDBusMessage &other) +    : QList<QVariant>(other) +{ +    d = other.d; +    d->ref.ref(); +} + +QDBusMessage::~QDBusMessage() +{ +    if (!d->ref.deref()) +        delete d; +} + +QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other) +{ +    QList<QVariant>::operator=(other); +    qAtomicAssign(d, other.d); +    return *this; +} + +DBusMessage *QDBusMessage::toDBusMessage() const +{ +    DBusMessage *msg = 0; +    switch (d->type) { +    case DBUS_MESSAGE_TYPE_METHOD_CALL: +        msg = dbus_message_new_method_call(d->service.toUtf8().constData(), +                d->path.toUtf8().constData(), d->interface.toUtf8().constData(), +                d->method.toUtf8().constData()); +        break; +    case DBUS_MESSAGE_TYPE_SIGNAL: +        msg = dbus_message_new_signal(d->path.toUtf8().constData(), +                d->interface.toUtf8().constData(), d->name.toUtf8().constData()); +        break; +    case DBUS_MESSAGE_TYPE_METHOD_RETURN: +        msg = dbus_message_new_method_return(d->reply); +        break; +    } +    if (!msg) +        return 0; + +    QDBusMarshall::listToMessage(*this, msg); +    return msg; +} + +QDBusMessage QDBusMessage::fromDBusMessage(DBusMessage *dmsg) +{ +    QDBusMessage message; +    if (!dmsg) +        return message; + +    message.d->type = dbus_message_get_type(dmsg); +    message.d->path = QString::fromUtf8(dbus_message_get_path(dmsg)); +    message.d->interface = QString::fromUtf8(dbus_message_get_interface(dmsg)); +    message.d->name = QString::fromUtf8(dbus_message_get_member(dmsg)); +    message.d->sender = QString::fromUtf8(dbus_message_get_sender(dmsg)); +    message.d->msg = dbus_message_ref(dmsg); + +    QDBusMarshall::messageToList(message, dmsg); + +    return message; +} + +QString QDBusMessage::path() const +{ +    return d->path; +} + +QString QDBusMessage::interface() const +{ +    return d->interface; +} + +QString QDBusMessage::name() const +{ +    return d->name; +} + +QString QDBusMessage::sender() const +{ +    return d->sender; +} + +int QDBusMessage::timeout() const +{ +    return d->timeout; +} + +void QDBusMessage::setTimeout(int ms) +{ +    d->timeout = ms; +} + +/*! +    Returns the unique serial number assigned to this message +    or 0 if the message was not sent yet. + */ +int QDBusMessage::serialNumber() const +{ +    if (!d->msg) +        return 0; +    return dbus_message_get_serial(d->msg); +} + +/*! +    Returns the unique serial number assigned to the message +    that triggered this reply message. + +    If this message is not a reply to another message, 0 +    is returned. + + */ +int QDBusMessage::replySerialNumber() const +{ +    if (!d->msg) +        return 0; +    return dbus_message_get_reply_serial(d->msg); +} + +QDBusMessage::MessageType QDBusMessage::type() const +{ +    switch (d->type) { +    case DBUS_MESSAGE_TYPE_METHOD_CALL: +        return MethodCallMessage; +    case DBUS_MESSAGE_TYPE_METHOD_RETURN: +        return ReplyMessage; +    case DBUS_MESSAGE_TYPE_ERROR: +        return ErrorMessage; +    case DBUS_MESSAGE_TYPE_SIGNAL: +        return SignalMessage; +    default: +        return InvalidMessage; +    } +} + +#ifndef QT_NO_DEBUG +QDebug operator<<(QDebug dbg, const QDBusMessage &msg) +{ +    dbg.nospace() << "QDBusMessage(" << msg.path() << ", " << msg.interface() << ", " +                  << msg.name() << ", " << msg.sender() << ", " +                  << static_cast<QList<QVariant> >(msg) << ")"; +    return dbg.space(); +} +#endif + diff --git a/qt/qdbusmessage.h b/qt/qdbusmessage.h new file mode 100644 index 00000000..5f70182c --- /dev/null +++ b/qt/qdbusmessage.h @@ -0,0 +1,80 @@ +/* qdbusmessage.h QDBusMessage object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSMESSAGE_H +#define QDBUSMESSAGE_H + +#include "qdbusmacros.h" +#include <QtCore/qlist.h> +#include <QtCore/qvariant.h> + +#include <limits.h> + +class QDBusMessagePrivate; +struct DBusMessage; + +class QDBUS_EXPORT QDBusMessage: public QList<QVariant> +{ +    friend class QDBusConnection; +public: +    enum { DefaultTimeout = -1, NoTimeout = INT_MAX}; +    enum MessageType { InvalidMessage, MethodCallMessage, ReplyMessage, +                       ErrorMessage, SignalMessage }; + +    QDBusMessage(); +    QDBusMessage(const QDBusMessage &other); +    ~QDBusMessage(); + +    QDBusMessage &operator=(const QDBusMessage &other); + +    static QDBusMessage signal(const QString &path, const QString &interface, +                               const QString &name); +    static QDBusMessage methodCall(const QString &service, const QString &path, +                                   const QString &interface, const QString &method); +    static QDBusMessage methodReply(const QDBusMessage &other); + +    QString path() const; +    QString interface() const; +    QString name() const; //rename to member? +    QString sender() const; //rename to service? +    MessageType type() const; + +    int timeout() const; +    void setTimeout(int ms); + + +//protected: +    DBusMessage *toDBusMessage() const; +    static QDBusMessage fromDBusMessage(DBusMessage *dmsg); +    int serialNumber() const; +    int replySerialNumber() const; + +private: +    QDBusMessagePrivate *d; +}; + +#ifndef QT_NO_DEBUG +QDebug operator<<(QDebug, const QDBusMessage &); +#endif + +#endif + diff --git a/qt/qdbusmessage_p.h b/qt/qdbusmessage_p.h new file mode 100644 index 00000000..9655c9d9 --- /dev/null +++ b/qt/qdbusmessage_p.h @@ -0,0 +1,46 @@ +/* qdbusmessage.h QDBusMessage private object + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSMESSAGE_P_H +#define QDBUSMESSAGE_P_H + +#include <QtCore/qatomic.h> +#include <QtCore/qstring.h> + +struct DBusMessage; + +class QDBusMessagePrivate +{ +public: +    QDBusMessagePrivate(QDBusMessage *qq); +    ~QDBusMessagePrivate(); + +    QString path, interface, name, service, method, sender; +    DBusMessage *msg; +    DBusMessage *reply; +    QDBusMessage *q; +    int type; +    int timeout; +    QAtomic ref; +}; + +#endif diff --git a/qt/qdbusserver.cpp b/qt/qdbusserver.cpp new file mode 100644 index 00000000..08fea26d --- /dev/null +++ b/qt/qdbusserver.cpp @@ -0,0 +1,59 @@ +/* qdbusserver.cpp + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include "qdbusserver.h" +#include "qdbusconnection_p.h" + +QDBusServer::QDBusServer(const QString &addr, QObject *parent) +    : QObject(parent) +{ +    d = new QDBusConnectionPrivate(this); + +    if (addr.isEmpty()) +        return; + +    d->setServer(dbus_server_listen(addr.toUtf8().constData(), &d->error)); +} + +bool QDBusServer::isConnected() const +{ +    return d->server && dbus_server_get_is_connected(d->server); +} + +QDBusError QDBusServer::lastError() const +{ +    return d->lastError; +} + +QString QDBusServer::address() const +{ +    QString addr; +    if (d->server) { +        char *c = dbus_server_get_address(d->server); +        addr = QString::fromUtf8(c); +        dbus_free(c); +    } + +    return addr; +} + +#include "qdbusserver.moc" diff --git a/qt/server.h b/qt/qdbusserver.h index 36c729ab..55607860 100644 --- a/qt/server.h +++ b/qt/qdbusserver.h @@ -1,7 +1,6 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- -/* server.h: Qt wrapper for DBusServer +/* qdbusserver.h QDBusServer object   * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>   *   * Licensed under the Academic Free License version 2.1   * @@ -20,38 +19,30 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   *   */ -#ifndef DBUS_QT_SERVER_H -#define DBUS_QT_SERVER_H -#include <qobject.h> +#ifndef QDBUSSERVER_H +#define QDBUSSERVER_H -#include "dbus/dbus.h" +#include "qdbusmacros.h" +#include <QtCore/qobject.h> +#include <QtCore/qstring.h> -namespace DBusQt +class QDBusConnectionPrivate; +class QDBusError; + +class QDBUS_EXPORT QDBusServer: public QObject  { -  class Connection; -  class Server : public QObject -  {      Q_OBJECT -  public: -    Server( const QString& addr = QString::null, QObject *parent=0 ); -    ~Server(); +public: +    QDBusServer(const QString &address, QObject *parent = 0);      bool isConnected() const; +    QDBusError lastError() const;      QString address() const; -  public slots: -    void listen( const QString& addr ); -    void disconnect(); -  signals: -    void newConnection( Connection* ); - -  private: -    void init( const QString& addr ); -  private: -    struct Private; -    Private *d; -  }; -} +private: +    Q_DISABLE_COPY(QDBusServer) +    QDBusConnectionPrivate *d; +};  #endif diff --git a/qt/qdbusvariant.h b/qt/qdbusvariant.h new file mode 100644 index 00000000..1a92a600 --- /dev/null +++ b/qt/qdbusvariant.h @@ -0,0 +1,40 @@ +/* qdbusvariant.h DBUS variant struct + * + * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org> + * + * Licensed under the Academic Free License version 2.1 + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#ifndef QDBUSVARIANT_H +#define QDBUSVARIANT_H + +#include "qdbusmacros.h" + +#include <QtCore/qmetatype.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> + +struct QDBUS_EXPORT QDBusVariant +{ +    QString signature; +    QVariant value; +}; +Q_DECLARE_METATYPE(QDBusVariant) + +#endif + diff --git a/qt/server.cpp b/qt/server.cpp deleted file mode 100644 index 5d6c3ba1..00000000 --- a/qt/server.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- -/* server.h: Qt wrapper for DBusServer - * - * Copyright (C) 2003  Zack Rusin <zack@kde.org> - * - * Licensed under the Academic Free License version 2.0 - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#include "server.h" -#include "connection.h" - -#include "integrator.h" -using DBusQt::Internal::Integrator; - -namespace DBusQt -{ - -struct Server::Private { -  Private() : integrator( 0 ), server( 0 ) -    {} - -  Integrator *integrator; -  DBusServer *server; -  DBusError error; -}; - -Server::Server( const QString& addr, QObject *parent ) -  : QObject( parent ) -{ -  d = new Private; - -  if ( !addr.isEmpty() ) { -    init( addr ); -  } -} - -Server::~Server() -{ -  delete d; -} - -bool Server::isConnected() const -{ -  return dbus_server_get_is_connected( d->server ); -} - -void Server::disconnect() -{ -  dbus_server_disconnect( d->server ); -} - -QString Server::address() const -{ -  //FIXME: leak? -  return dbus_server_get_address( d->server ); -} - -void Server::listen( const QString& addr ) -{ -  if ( !d->server ) { -    init( addr ); -  } -} - -void Server::init( const QString& addr ) -{ -  d->server = dbus_server_listen( addr.ascii(),  &d->error ); -  d->integrator = new Integrator( d->server, this ); -  connect( d->integrator, SIGNAL(newConnection(Connection*)), -           SIGNAL(newConnection(Connection*)) ); -} - -} - - -#include "server.moc"  | 
