added: signal dbusserver to stop before joining the thread (other servers might follow)
[xbmc:paulepanters-xbmc.git] / XBMC / xbmc / utils / DbusServer.h
1 #ifndef __DBUS_SERVER_H__
2 #define __DBUS_SERVER_H__
3
4 /*
5  *      Copyright (C) 2009 Azur Digital Networks
6  *      http://www.azurdigitalnetworks.net
7  *
8  *  This Program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2, or (at your option)
11  *  any later version.
12  *
13  *  This Program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with XBMC; see the file COPYING.  If not, write to
20  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  *  http://www.gnu.org/copyleft/gpl.html
22  *
23  */
24
25 #include "system.h"
26 #include "Thread.h"
27 #include "CriticalSection.h"
28 #include <map>
29 #include <queue>
30 #include <dbus/dbus.h>
31
32 #ifdef HAS_DBUS_SERVER
33
34 /* MPRIS VERSION */
35 #define XBMC_MPRIS_VERSION_MAJOR     1
36 #define XBMC_MPRIS_VERSION_MINOR     0
37
38 /* PACKAGE/VERSION */
39 #define XBMC_MPRIS_VERSION     "0.9.04"
40 #define XBMC_MPRIS_PACKAGE     "xbmc"
41
42 /* DBUS IDENTIFIERS */
43
44 /* name registered on the session bus */
45 #define XBMC_MPRIS_DBUS_SERVICE     "org.mpris.xbmc"
46 #define XBMC_MPRIS_DBUS_INTROSPECT  "Introspect"
47 #define MPRIS_DBUS_INTERFACE        "org.freedesktop.MediaPlayer"
48 #define MPRIS_DBUS_ROOT_PATH        "/"
49 #define MPRIS_DBUS_PLAYER_PATH      "/Player"
50 #define MPRIS_DBUS_TRACKLIST_PATH   "/TrackList"
51
52 /* MACROS */
53
54 #define DBUS_METHOD( method_function ) \
55     DBusHandlerResult method_function( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
56
57 #define DBUS_METHOD_IMPL( method_function ) \
58     DBusHandlerResult CDbusServer::method_function( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
59
60 #define DBUS_SIGNAL( signal_function ) \
61     DBusHandlerResult signal_function( DBusConnection *p_conn, void *p_data )
62
63 #define REPLY_INIT \
64     DBusMessage* p_msg = dbus_message_new_method_return( message ); \
65     if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \
66
67 #define REPLY_SEND \
68     if( !dbus_connection_send( p_conn, p_msg, NULL ) ) \
69         return DBUS_HANDLER_RESULT_NEED_MEMORY; \
70     dbus_connection_flush( p_conn ); \
71     dbus_message_unref( p_msg ); \
72     return DBUS_HANDLER_RESULT_HANDLED
73
74 #define SIGNAL_INIT( signal ) \
75     DBusMessage *p_msg = dbus_message_new_signal( MPRIS_DBUS_PLAYER_PATH, \
76         MPRIS_DBUS_INTERFACE, signal ); \
77     if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \
78
79 #define SIGNAL_SEND \
80     if( !dbus_connection_send( p_conn, p_msg, NULL ) ) \
81         return DBUS_HANDLER_RESULT_NEED_MEMORY; \
82     dbus_message_unref( p_msg ); \
83     dbus_connection_flush( p_conn ); \
84     return DBUS_HANDLER_RESULT_HANDLED
85
86 #define OUT_ARGUMENTS \
87     DBusMessageIter args; \
88     dbus_message_iter_init_append( p_msg, &args )
89
90 #define DBUS_ADD( dbus_type, value ) \
91     if( !dbus_message_iter_append_basic( &args, dbus_type, value ) ) \
92         return DBUS_HANDLER_RESULT_NEED_MEMORY
93
94 #define ADD_STRING( s ) DBUS_ADD( DBUS_TYPE_STRING, s )
95 #define ADD_BOOL( b ) DBUS_ADD( DBUS_TYPE_BOOLEAN, b )
96 #define ADD_INT32( i ) DBUS_ADD( DBUS_TYPE_INT32, i )
97 #define ADD_BYTE( b ) DBUS_ADD( DBUS_TYPE_BYTE, b )
98
99
100 /* Handle  messages reception */
101 #define METHOD_FUNC( method, function ) \
102     else if( dbus_message_is_method_call( p_from, MPRIS_DBUS_INTERFACE, method ) )\
103         return function( p_conn, p_from, p_this )
104
105 #endif
106
107 class CApplication;
108
109 namespace DBUSSERVER
110 {
111
112   /**********************************************************************/
113   /* DBUSServer Class                                                   */
114   /**********************************************************************/
115   class CDbusServer : public IRunnable
116   {
117   public:
118     static void RemoveInstance();
119     static CDbusServer* GetInstance();
120     virtual ~CDbusServer() {}
121
122     // IRunnable entry point for thread
123     virtual void  Run();
124
125     bool Running()
126     {
127       return m_bRunning;
128     }
129
130     // start / stop server
131     void StartServer(CApplication* );
132     void StopServer(bool bWait);
133
134     // get events
135     bool ExecuteNextAction();
136
137     friend DBusHandlerResult xbmc_dbus_message_handler_root(DBusConnection *, DBusMessage *, void *);
138     DBusHandlerResult got_message_root(DBusConnection *, DBusMessage *);
139
140     friend DBusHandlerResult xbmc_dbus_message_handler_player(DBusConnection *, DBusMessage *, void *);
141     DBusHandlerResult got_message_player(DBusConnection *, DBusMessage *);
142
143     friend DBusHandlerResult xbmc_dbus_message_handler_tracklist(DBusConnection *, DBusMessage *, void *);
144     DBusHandlerResult got_message_tracklist(DBusConnection *, DBusMessage *);
145
146   protected:
147     CDbusServer();
148     void ProcessEvents();
149     CThread*         m_pThread;
150     static CDbusServer* m_pInstance;
151     bool             m_bStop;
152     bool             m_bRunning;
153     CCriticalSection m_critSection;
154     CApplication     *p_application;
155
156   private:
157     DBusHandlerResult handle_introspect_root( DBusConnection *, DBusMessage * );
158     DBusHandlerResult handle_introspect_player( DBusConnection *, DBusMessage * );
159     DBusHandlerResult handle_introspect_tracklist( DBusConnection *, DBusMessage * );
160     DBusHandlerResult root_Identity( DBusConnection *, DBusMessage * );
161     DBusHandlerResult root_MprisVersion( DBusConnection *, DBusMessage * );
162     DBusHandlerResult player_VolumeSet( DBusConnection *, DBusMessage * );
163     DBusHandlerResult player_VolumeGet( DBusConnection *, DBusMessage * );
164     DBusHandlerResult player_GetStatus( DBusConnection *, DBusMessage * );
165     DBusHandlerResult player_Stop( DBusConnection *, DBusMessage * );
166     DBusHandlerResult player_Pause( DBusConnection *, DBusMessage * );
167
168     bool connect(DBusConnection **);
169     DBusConnection *p_conn;
170     bool _ok;
171
172   };
173
174 }
175
176 #endif // __DBUS_SERVER_H__