2009-07-26 23:26:29 +03:00
/* -*- Mode: C ; c-basic-offset: 2 -*- */
2009-07-29 20:45:43 +03:00
/*
* LADI Session Handler ( ladish )
2009-07-26 23:26:29 +03:00
*
2010-02-02 21:51:02 +02:00
* Copyright ( C ) 2009 , 2010 Nedko Arnaudov < nedko @ arnaudov . name >
2009-07-26 23:26:29 +03:00
*
2009-07-29 20:45:43 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2009-09-12 14:50:35 +03:00
* This file contains part of the studio singleton object implementation
* Other parts are in the other studio * . c files in same directory .
2009-07-29 20:45:43 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* LADI Session Handler 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 .
*
* LADI Session Handler 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 LADI Session Handler . If not , see < http : //www.gnu.org/licenses/>
* or write to the Free Software Foundation , Inc . ,
* 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2009-07-26 23:26:29 +03:00
# include "common.h"
2009-08-24 01:04:07 +03:00
# include <sys/types.h>
# include <sys/stat.h>
# include <unistd.h>
2009-08-24 01:58:14 +03:00
# include <dirent.h>
2009-08-24 01:04:07 +03:00
2009-09-12 14:50:35 +03:00
# include "studio_internal.h"
2009-08-22 03:07:19 +03:00
# include "../dbus_constants.h"
2009-08-23 01:21:23 +03:00
# include "control.h"
2009-08-23 11:09:15 +03:00
# include "../catdup.h"
2009-08-24 00:25:43 +03:00
# include "dirhelpers.h"
2009-09-07 20:53:56 +03:00
# include "graph_dict.h"
2009-09-12 11:11:52 +03:00
# include "escape.h"
2009-08-24 00:25:43 +03:00
2009-08-24 01:58:14 +03:00
# define STUDIOS_DIR " / studios / "
2009-08-24 00:25:43 +03:00
char * g_studios_dir ;
2009-08-07 23:28:34 +03:00
2009-09-12 14:50:35 +03:00
struct studio g_studio ;
2009-08-23 01:21:23 +03:00
2009-08-23 11:09:15 +03:00
bool studio_name_generate ( char * * name_ptr )
{
time_t now ;
char timestamp_str [ 26 ] ;
char * name ;
time ( & now ) ;
//ctime_r(&now, timestamp_str);
//timestamp_str[24] = 0;
snprintf ( timestamp_str , sizeof ( timestamp_str ) , " %llu " , ( unsigned long long ) now ) ;
name = catdup ( " Studio " , timestamp_str ) ;
if ( name = = NULL )
{
2009-09-20 18:23:42 +03:00
log_error ( " catdup failed to create studio name " ) ;
2009-08-23 11:09:15 +03:00
return false ;
}
* name_ptr = name ;
return true ;
}
2009-07-26 23:26:29 +03:00
bool
2009-08-30 18:38:17 +03:00
studio_publish ( void )
2009-07-26 23:26:29 +03:00
{
2009-09-05 17:27:56 +03:00
dbus_object_path object ;
2009-07-26 23:26:29 +03:00
2009-09-20 18:48:42 +03:00
ASSERT ( g_studio . name ! = NULL ) ;
2009-08-23 11:09:15 +03:00
2009-09-06 00:13:05 +03:00
object = dbus_object_path_new (
STUDIO_OBJECT_PATH ,
& g_interface_studio , & g_studio ,
2009-09-12 22:30:33 +03:00
& g_interface_patchbay , ladish_graph_get_dbus_context ( g_studio . studio_graph ) ,
& g_iface_graph_dict , g_studio . studio_graph ,
2009-11-30 01:22:58 +02:00
& g_iface_app_supervisor , g_studio . app_supervisor ,
2009-09-06 00:13:05 +03:00
NULL ) ;
2009-08-23 01:21:23 +03:00
if ( object = = NULL )
{
2009-09-20 18:23:42 +03:00
log_error ( " dbus_object_path_new() failed " ) ;
2009-08-23 01:21:23 +03:00
return false ;
}
2009-07-26 23:26:29 +03:00
2009-09-04 02:27:05 +03:00
if ( ! dbus_object_path_register ( g_dbus_connection , object ) )
2009-07-26 23:26:29 +03:00
{
2009-09-20 18:23:42 +03:00
log_error ( " object_path_register() failed " ) ;
2009-09-04 02:27:05 +03:00
dbus_object_path_destroy ( g_dbus_connection , object ) ;
2009-07-26 23:26:29 +03:00
return false ;
}
2009-09-20 18:23:42 +03:00
log_info ( " Studio D-Bus object created. \" %s \" " , g_studio . name ) ;
2009-08-23 01:21:23 +03:00
g_studio . dbus_object = object ;
2009-08-21 23:13:19 +03:00
2009-08-23 01:21:23 +03:00
emit_studio_appeared ( ) ;
2009-07-26 23:26:29 +03:00
2009-08-23 01:21:23 +03:00
return true ;
}
2009-07-26 23:26:29 +03:00
2009-12-17 06:34:45 +02:00
void emit_studio_started ( void )
2009-08-23 01:21:23 +03:00
{
2009-09-05 19:12:53 +03:00
dbus_signal_emit ( g_dbus_connection , STUDIO_OBJECT_PATH , IFACE_STUDIO , " StudioStarted " , " " ) ;
2009-08-30 22:40:28 +03:00
}
2009-07-26 23:26:29 +03:00
2009-12-17 06:34:45 +02:00
void emit_studio_crashed ( void )
{
dbus_signal_emit ( g_dbus_connection , STUDIO_OBJECT_PATH , IFACE_STUDIO , " StudioCrashed " , " " ) ;
}
void emit_studio_stopped ( void )
2009-08-30 22:40:28 +03:00
{
2009-09-05 19:12:53 +03:00
dbus_signal_emit ( g_dbus_connection , STUDIO_OBJECT_PATH , IFACE_STUDIO , " StudioStopped " , " " ) ;
2009-08-30 22:40:28 +03:00
}
2009-08-01 19:07:16 +03:00
2010-03-07 13:46:45 +02:00
static bool fill_room_info ( DBusMessageIter * iter_ptr , ladish_room_handle room )
{
DBusMessageIter dict_iter ;
const char * name ;
uuid_t template_uuid ;
ladish_room_handle template ;
const char * template_name ;
const char * opath ;
name = ladish_room_get_name ( room ) ;
opath = ladish_room_get_opath ( room ) ;
if ( ! ladish_room_get_template_uuid ( room , template_uuid ) )
{
template = NULL ;
template_name = NULL ;
}
else
{
template = find_room_template_by_uuid ( template_uuid ) ;
if ( template ! = NULL )
{
template_name = ladish_room_get_name ( template ) ;
}
else
{
template_name = NULL ;
}
}
if ( ! dbus_message_iter_append_basic ( iter_ptr , DBUS_TYPE_STRING , & opath ) )
{
log_error ( " dbus_message_iter_append_basic() failed. " ) ;
return false ;
}
if ( ! dbus_message_iter_open_container ( iter_ptr , DBUS_TYPE_ARRAY , " {sv} " , & dict_iter ) )
{
log_error ( " dbus_message_iter_open_container() failed. " ) ;
return false ;
}
if ( ! dbus_maybe_add_dict_entry_string ( & dict_iter , " template " , template_name ) )
{
log_error ( " dbus_maybe_add_dict_entry_string() failed. " ) ;
return false ;
}
if ( ! dbus_maybe_add_dict_entry_string ( & dict_iter , " name " , name ) )
{
log_error ( " dbus_maybe_add_dict_entry_string() failed. " ) ;
return false ;
}
if ( ! dbus_message_iter_close_container ( iter_ptr , & dict_iter ) )
{
log_error ( " dbus_message_iter_close_container() failed. " ) ;
return false ;
}
return true ;
}
static void emit_room_appeared ( ladish_room_handle room )
{
DBusMessage * message_ptr ;
DBusMessageIter iter ;
message_ptr = dbus_message_new_signal ( STUDIO_OBJECT_PATH , IFACE_STUDIO , " RoomAppeared " ) ;
if ( message_ptr = = NULL )
{
log_error ( " dbus_message_new_signal() failed. " ) ;
return ;
}
dbus_message_iter_init_append ( message_ptr , & iter ) ;
if ( fill_room_info ( & iter , room ) )
{
dbus_signal_send ( g_dbus_connection , message_ptr ) ;
}
dbus_message_unref ( message_ptr ) ;
}
2010-03-13 20:56:55 +02:00
static void emit_room_disappeared ( ladish_room_handle room )
{
DBusMessage * message_ptr ;
DBusMessageIter iter ;
message_ptr = dbus_message_new_signal ( STUDIO_OBJECT_PATH , IFACE_STUDIO , " RoomDisappeared " ) ;
if ( message_ptr = = NULL )
{
log_error ( " dbus_message_new_signal() failed. " ) ;
return ;
}
dbus_message_iter_init_append ( message_ptr , & iter ) ;
if ( fill_room_info ( & iter , room ) )
{
dbus_signal_send ( g_dbus_connection , message_ptr ) ;
}
dbus_message_unref ( message_ptr ) ;
}
2009-08-23 01:21:23 +03:00
void on_event_jack_started ( void )
{
2009-09-12 14:50:35 +03:00
if ( ! studio_fetch_jack_settings ( ) )
2009-07-26 23:26:29 +03:00
{
2009-09-20 18:23:42 +03:00
log_error ( " studio_fetch_jack_settings() failed. " ) ;
2009-08-23 01:21:23 +03:00
return ;
2009-07-26 23:26:29 +03:00
}
2009-09-20 18:23:42 +03:00
log_info ( " jack conf successfully retrieved " ) ;
2009-08-23 01:21:23 +03:00
g_studio . jack_conf_valid = true ;
2009-09-03 05:45:39 +03:00
2009-09-12 09:58:37 +03:00
if ( ! graph_proxy_create ( JACKDBUS_SERVICE_NAME , JACKDBUS_OBJECT_PATH , false , & g_studio . jack_graph_proxy ) )
2009-09-03 05:45:39 +03:00
{
2009-09-20 18:23:42 +03:00
log_error ( " graph_proxy_create() failed for jackdbus " ) ;
2009-09-06 00:13:05 +03:00
}
else
{
2009-11-28 17:23:23 +02:00
if ( ! ladish_virtualizer_create ( g_studio . jack_graph_proxy , g_studio . jack_graph , g_studio . studio_graph , & g_studio . virtualizer ) )
2009-09-06 01:15:25 +03:00
{
2009-11-28 17:23:23 +02:00
log_error ( " ladish_virtualizer_create() failed. " ) ;
2009-09-06 01:15:25 +03:00
}
2009-09-06 00:13:05 +03:00
2009-09-06 01:15:25 +03:00
if ( ! graph_proxy_activate ( g_studio . jack_graph_proxy ) )
{
2009-09-20 18:23:42 +03:00
log_error ( " graph_proxy_activate() failed. " ) ;
2009-09-06 01:15:25 +03:00
}
2009-09-03 05:45:39 +03:00
}
2009-10-08 23:45:03 +03:00
2009-12-05 00:42:40 +02:00
ladish_app_supervisor_autorun ( g_studio . app_supervisor ) ;
2009-10-08 23:45:03 +03:00
emit_studio_started ( ) ;
2009-07-26 23:26:29 +03:00
}
2009-08-01 19:07:16 +03:00
2009-12-17 06:34:45 +02:00
static void on_jack_stopped_internal ( void )
2009-08-01 19:07:16 +03:00
{
2009-11-25 03:42:02 +02:00
if ( g_studio . automatic )
{
log_info ( " Unloading automatic studio. " ) ;
ladish_command_unload_studio ( NULL , & g_studio . cmd_queue ) ;
return ;
}
2009-10-08 23:45:03 +03:00
2009-11-28 17:23:23 +02:00
if ( g_studio . virtualizer )
2009-09-06 01:15:25 +03:00
{
2009-11-28 17:23:23 +02:00
ladish_virtualizer_destroy ( g_studio . virtualizer ) ;
g_studio . virtualizer = NULL ;
2009-09-06 01:15:25 +03:00
}
if ( g_studio . jack_graph_proxy )
{
graph_proxy_destroy ( g_studio . jack_graph_proxy ) ;
g_studio . jack_graph_proxy = NULL ;
}
2009-12-13 19:35:50 +02:00
}
2009-09-03 05:45:39 +03:00
2009-12-17 06:34:45 +02:00
void on_event_jack_stopped ( void )
{
emit_studio_stopped ( ) ;
on_jack_stopped_internal ( ) ;
}
2009-12-13 19:35:50 +02:00
void handle_unexpected_jack_server_stop ( void )
{
2009-12-17 06:34:45 +02:00
emit_studio_crashed ( ) ;
on_jack_stopped_internal ( ) ;
2009-08-23 01:21:23 +03:00
/* TODO: if user wants, restart jack server and reconnect all jack apps to it */
}
void studio_run ( void )
{
2009-11-24 03:10:57 +02:00
bool state ;
2009-08-23 01:21:23 +03:00
2009-11-24 03:10:57 +02:00
ladish_cqueue_run ( & g_studio . cmd_queue ) ;
2009-11-25 15:44:53 +02:00
if ( g_quit )
{ /* if quit is requested, don't bother to process external events */
return ;
}
2009-08-23 01:21:23 +03:00
2009-11-24 03:10:57 +02:00
if ( ladish_environment_consume_change ( & g_studio . env_store , ladish_environment_jack_server_started , & state ) )
{
2009-11-25 03:42:02 +02:00
ladish_cqueue_clear ( & g_studio . cmd_queue ) ;
2009-11-24 03:10:57 +02:00
if ( state )
2009-08-23 01:21:23 +03:00
{
2009-12-17 07:40:52 +02:00
ladish_environment_ignore ( & g_studio . env_store , ladish_environment_jack_server_present ) ;
2009-12-13 19:35:50 +02:00
/* Automatic studio creation on JACK server start */
if ( g_studio . dbus_object = = NULL )
{
ASSERT ( g_studio . name = = NULL ) ;
if ( ! studio_name_generate ( & g_studio . name ) )
{
log_error ( " studio_name_generate() failed. " ) ;
return ;
}
g_studio . automatic = true ;
studio_publish ( ) ;
}
2009-08-23 01:21:23 +03:00
on_event_jack_started ( ) ;
2009-11-24 03:10:57 +02:00
}
else
{
2009-12-13 19:35:50 +02:00
/* JACK stopped but this was not expected. When expected.
* the change will be consumed by the run method of the studio stop command */
log_error ( " JACK stopped unexpectedly. " ) ;
log_error ( " Save your work, then unload and reload the studio. " ) ;
handle_unexpected_jack_server_stop ( ) ;
}
}
if ( ladish_environment_consume_change ( & g_studio . env_store , ladish_environment_jack_server_present , & state ) )
{
if ( g_studio . jack_graph_proxy ! = NULL )
{
ladish_cqueue_clear ( & g_studio . cmd_queue ) ;
/* jack was started, this probably means that jackdbus has crashed */
log_error ( " JACK disappeared unexpectedly. Maybe it crashed. " ) ;
log_error ( " Save your work, then unload and reload the studio. " ) ;
ladish_environment_reset_stealth ( & g_studio . env_store , ladish_environment_jack_server_started ) ;
ladish_graph_clear ( g_studio . studio_graph , false ) ;
ladish_graph_clear ( g_studio . jack_graph , true ) ;
handle_unexpected_jack_server_stop ( ) ;
2009-08-23 01:21:23 +03:00
}
2009-08-01 19:07:16 +03:00
}
2009-11-24 03:10:57 +02:00
ladish_environment_assert_consumed ( & g_studio . env_store ) ;
2009-08-23 01:21:23 +03:00
}
2009-08-01 19:07:16 +03:00
2009-08-23 01:21:23 +03:00
static void on_jack_server_started ( void )
{
2009-09-20 18:23:42 +03:00
log_info ( " JACK server start detected. " ) ;
2009-11-24 03:10:57 +02:00
ladish_environment_set ( & g_studio . env_store , ladish_environment_jack_server_started ) ;
2009-08-23 01:21:23 +03:00
}
static void on_jack_server_stopped ( void )
{
2009-12-13 17:48:29 +02:00
log_info ( " JACK server stop detected. " ) ;
2009-11-24 03:10:57 +02:00
ladish_environment_reset ( & g_studio . env_store , ladish_environment_jack_server_started ) ;
2009-08-23 01:21:23 +03:00
}
static void on_jack_server_appeared ( void )
{
2009-09-20 18:23:42 +03:00
log_info ( " JACK controller appeared. " ) ;
2009-11-24 03:10:57 +02:00
ladish_environment_set ( & g_studio . env_store , ladish_environment_jack_server_present ) ;
2009-08-23 01:21:23 +03:00
}
static void on_jack_server_disappeared ( void )
{
2009-09-20 18:23:42 +03:00
log_info ( " JACK controller disappeared. " ) ;
2009-11-24 03:10:57 +02:00
ladish_environment_reset ( & g_studio . env_store , ladish_environment_jack_server_present ) ;
2009-08-23 01:21:23 +03:00
}
2009-12-26 22:46:20 +02:00
static void on_app_renamed ( const char * old_name , const char * new_app_name )
{
ladish_client_handle client ;
client = ladish_graph_find_client_by_name ( g_studio . jack_graph , old_name ) ;
if ( client ! = NULL )
{
ladish_graph_rename_client ( g_studio . jack_graph , client , new_app_name ) ;
}
client = ladish_graph_find_client_by_name ( g_studio . studio_graph , old_name ) ;
if ( client ! = NULL )
{
ladish_graph_rename_client ( g_studio . studio_graph , client , new_app_name ) ;
}
}
2009-08-23 01:21:23 +03:00
bool studio_init ( void )
{
2009-09-20 18:23:42 +03:00
log_info ( " studio object construct " ) ;
2009-08-23 01:21:23 +03:00
2009-08-24 00:25:43 +03:00
g_studios_dir = catdup ( g_base_dir , STUDIOS_DIR ) ;
if ( g_studios_dir = = NULL )
{
2009-09-20 18:23:42 +03:00
log_error ( " catdup failed for '%s' and '%s' " , g_base_dir , STUDIOS_DIR ) ;
2009-09-06 00:13:05 +03:00
goto fail ;
2009-08-24 00:25:43 +03:00
}
if ( ! ensure_dir_exist ( g_studios_dir , 0700 ) )
{
2009-09-06 00:13:05 +03:00
goto free_studios_dir ;
2009-08-24 00:25:43 +03:00
}
2009-08-23 01:21:23 +03:00
INIT_LIST_HEAD ( & g_studio . all_connections ) ;
INIT_LIST_HEAD ( & g_studio . all_ports ) ;
INIT_LIST_HEAD ( & g_studio . all_clients ) ;
INIT_LIST_HEAD ( & g_studio . jack_connections ) ;
INIT_LIST_HEAD ( & g_studio . jack_ports ) ;
INIT_LIST_HEAD ( & g_studio . jack_clients ) ;
INIT_LIST_HEAD ( & g_studio . rooms ) ;
INIT_LIST_HEAD ( & g_studio . clients ) ;
INIT_LIST_HEAD ( & g_studio . ports ) ;
INIT_LIST_HEAD ( & g_studio . jack_conf ) ;
INIT_LIST_HEAD ( & g_studio . jack_params ) ;
g_studio . dbus_object = NULL ;
2009-08-23 11:09:15 +03:00
g_studio . name = NULL ;
2009-08-24 00:25:43 +03:00
g_studio . filename = NULL ;
2009-08-23 01:21:23 +03:00
2010-03-06 17:03:14 +02:00
g_studio . room_count = 0 ;
2009-09-20 17:30:48 +03:00
if ( ! ladish_graph_create ( & g_studio . jack_graph , NULL ) )
2009-09-06 00:13:05 +03:00
{
2009-09-20 18:23:42 +03:00
log_error ( " ladish_graph_create() failed to create jack graph object. " ) ;
2009-09-06 00:13:05 +03:00
goto free_studios_dir ;
}
2009-09-20 17:30:48 +03:00
if ( ! ladish_graph_create ( & g_studio . studio_graph , STUDIO_OBJECT_PATH ) )
2009-09-12 22:30:33 +03:00
{
2009-09-20 18:23:42 +03:00
log_error ( " ladish_graph_create() failed to create studio graph object. " ) ;
2009-09-12 22:30:33 +03:00
goto jack_graph_destroy ;
}
2009-12-26 22:46:20 +02:00
if ( ! ladish_app_supervisor_create ( & g_studio . app_supervisor , STUDIO_OBJECT_PATH , " studio " , on_app_renamed ) )
2009-11-30 01:22:58 +02:00
{
log_error ( " ladish_app_supervisor_create() failed. " ) ;
goto studio_graph_destroy ;
}
2009-10-19 01:16:59 +03:00
ladish_cqueue_init ( & g_studio . cmd_queue ) ;
2009-11-24 03:10:57 +02:00
ladish_environment_init ( & g_studio . env_store ) ;
2009-10-19 01:16:59 +03:00
2009-08-23 01:21:23 +03:00
if ( ! jack_proxy_init (
on_jack_server_started ,
on_jack_server_stopped ,
on_jack_server_appeared ,
on_jack_server_disappeared ) )
{
2009-09-20 18:23:42 +03:00
log_error ( " jack_proxy_init() failed. " ) ;
2009-11-30 01:22:58 +02:00
goto app_supervisor_destroy ;
2009-08-23 01:21:23 +03:00
}
2009-08-01 19:07:16 +03:00
return true ;
2009-09-06 00:13:05 +03:00
2009-11-30 01:22:58 +02:00
app_supervisor_destroy :
ladish_app_supervisor_destroy ( g_studio . app_supervisor ) ;
2009-09-12 22:30:33 +03:00
studio_graph_destroy :
2009-10-08 23:45:03 +03:00
ladish_graph_destroy ( g_studio . studio_graph , false ) ;
2009-09-12 22:30:33 +03:00
jack_graph_destroy :
2009-10-08 23:45:03 +03:00
ladish_graph_destroy ( g_studio . jack_graph , false ) ;
2009-09-06 00:13:05 +03:00
free_studios_dir :
free ( g_studios_dir ) ;
fail :
return false ;
2009-08-01 19:07:16 +03:00
}
2009-08-07 23:28:34 +03:00
2009-08-23 01:21:23 +03:00
void studio_uninit ( void )
2009-08-07 23:28:34 +03:00
{
2009-10-08 23:45:03 +03:00
log_info ( " studio_uninit() " ) ;
2009-08-23 01:21:23 +03:00
2009-10-08 23:45:03 +03:00
jack_proxy_uninit ( ) ;
2009-09-12 22:30:33 +03:00
2009-11-25 03:42:02 +02:00
ladish_cqueue_clear ( & g_studio . cmd_queue ) ;
2009-10-19 01:16:59 +03:00
2009-12-13 19:35:50 +02:00
ladish_graph_destroy ( g_studio . studio_graph , false ) ;
ladish_graph_destroy ( g_studio . jack_graph , false ) ;
2009-09-03 05:42:35 +03:00
free ( g_studios_dir ) ;
2009-09-20 18:23:42 +03:00
log_info ( " studio object destroy " ) ;
2009-08-07 23:28:34 +03:00
}
2009-11-30 23:45:14 +02:00
void studio_on_child_exit ( pid_t pid )
{
if ( ! ladish_app_supervisor_child_exit ( g_studio . app_supervisor , pid ) )
{
log_error ( " non-studio child exit detected. pid is %llu " , ( unsigned long long ) pid ) ;
}
}
2009-08-23 01:21:23 +03:00
bool studio_is_loaded ( void )
{
return g_studio . dbus_object ! = NULL ;
}
2009-11-25 03:42:02 +02:00
bool studio_is_started ( void )
{
return ladish_environment_get ( & g_studio . env_store , ladish_environment_jack_server_started ) ;
}
2009-09-12 14:50:35 +03:00
bool studio_compose_filename ( const char * name , char * * filename_ptr_ptr , char * * backup_filename_ptr_ptr )
2009-08-24 00:25:43 +03:00
{
size_t len_dir ;
char * p ;
const char * src ;
2009-08-30 13:23:36 +03:00
char * filename_ptr ;
2009-11-20 01:39:37 +02:00
char * backup_filename_ptr = NULL ;
2009-08-24 00:25:43 +03:00
len_dir = strlen ( g_studios_dir ) ;
2009-08-30 13:23:36 +03:00
filename_ptr = malloc ( len_dir + 1 + strlen ( name ) * 3 + 4 + 1 ) ;
if ( filename_ptr = = NULL )
2009-08-24 00:25:43 +03:00
{
2009-09-20 18:23:42 +03:00
log_error ( " malloc failed to allocate memory for studio file path " ) ;
2009-08-24 00:25:43 +03:00
return false ;
}
2009-08-31 04:19:50 +03:00
if ( backup_filename_ptr_ptr ! = NULL )
2009-08-30 13:23:36 +03:00
{
2009-08-31 04:19:50 +03:00
backup_filename_ptr = malloc ( len_dir + 1 + strlen ( name ) * 3 + 4 + 4 + 1 ) ;
if ( backup_filename_ptr = = NULL )
{
2009-09-20 18:23:42 +03:00
log_error ( " malloc failed to allocate memory for studio backup file path " ) ;
2009-08-31 04:19:50 +03:00
free ( filename_ptr ) ;
return false ;
}
2009-08-30 13:23:36 +03:00
}
p = filename_ptr ;
2009-08-24 00:25:43 +03:00
memcpy ( p , g_studios_dir , len_dir ) ;
p + = len_dir ;
* p + + = ' / ' ;
2009-08-30 13:23:36 +03:00
src = name ;
2009-08-24 00:25:43 +03:00
escape ( & src , & p ) ;
strcpy ( p , " .xml " ) ;
2009-08-30 13:23:36 +03:00
* filename_ptr_ptr = filename_ptr ;
2009-08-31 04:19:50 +03:00
if ( backup_filename_ptr_ptr ! = NULL )
{
strcpy ( backup_filename_ptr , filename_ptr ) ;
strcat ( backup_filename_ptr , " .bak " ) ;
* backup_filename_ptr_ptr = backup_filename_ptr ;
}
2009-08-30 13:23:36 +03:00
2009-08-24 00:25:43 +03:00
return true ;
}
2009-08-24 01:58:14 +03:00
bool studios_iterate ( void * call_ptr , void * context , bool ( * callback ) ( void * call_ptr , void * context , const char * studio , uint32_t modtime ) )
{
DIR * dir ;
struct dirent * dentry ;
size_t len ;
struct stat st ;
char * path ;
2009-08-31 04:19:50 +03:00
char * name ;
2009-08-24 01:58:14 +03:00
dir = opendir ( g_studios_dir ) ;
if ( dir = = NULL )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " Cannot open directory '%s': %d (%s) " , g_studios_dir , errno , strerror ( errno ) ) ;
return false ;
}
while ( ( dentry = readdir ( dir ) ) ! = NULL )
{
len = strlen ( dentry - > d_name ) ;
2009-08-31 04:19:50 +03:00
if ( len < = 4 | | strcmp ( dentry - > d_name + ( len - 4 ) , " .xml " ) ! = 0 )
2009-08-24 01:58:14 +03:00
continue ;
path = catdup ( g_studios_dir , dentry - > d_name ) ;
if ( path = = NULL )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " catdup() failed " ) ;
return false ;
}
if ( stat ( path , & st ) ! = 0 )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " failed to stat '%s': %d (%s) " , path , errno , strerror ( errno ) ) ;
free ( path ) ;
return false ;
}
free ( path ) ;
2010-02-02 21:51:02 +02:00
if ( ! S_ISREG ( st . st_mode ) )
{
//log_info("Ignoring direntry that is not regular file. Mode is %07o", st.st_mode);
continue ;
}
2009-08-31 04:19:50 +03:00
name = malloc ( len - 4 + 1 ) ;
2009-12-12 17:12:03 +02:00
if ( name = = NULL )
{
log_error ( " malloc() failed. " ) ;
closedir ( dir ) ;
return false ;
}
2009-08-31 04:19:50 +03:00
name [ unescape ( dentry - > d_name , len - 4 , name ) ] = 0 ;
2009-09-20 18:23:42 +03:00
//log_info("name = '%s'", name);
2009-08-31 04:19:50 +03:00
if ( ! callback ( call_ptr , context , name , st . st_mtime ) )
2009-08-24 01:58:14 +03:00
{
2009-08-31 04:19:50 +03:00
free ( name ) ;
2009-08-24 01:58:14 +03:00
closedir ( dir ) ;
return false ;
}
2009-08-31 04:19:50 +03:00
free ( name ) ;
2009-08-24 01:58:14 +03:00
}
closedir ( dir ) ;
return true ;
}
2009-08-30 14:36:27 +03:00
bool studio_delete ( void * call_ptr , const char * studio_name )
{
char * filename ;
char * bak_filename ;
struct stat st ;
bool ret ;
ret = false ;
2009-09-12 14:50:35 +03:00
if ( ! studio_compose_filename ( studio_name , & filename , & bak_filename ) )
2009-08-30 14:36:27 +03:00
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " failed to compose studio filename " ) ;
goto exit ;
}
2009-09-20 18:23:42 +03:00
log_info ( " Deleting studio ('%s') " , filename ) ;
2009-08-30 14:36:27 +03:00
if ( unlink ( filename ) ! = 0 )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " unlink(%s) failed: %d (%s) " , filename , errno , strerror ( errno ) ) ;
goto free ;
}
/* try to delete the backup file */
if ( stat ( bak_filename , & st ) = = 0 )
{
if ( unlink ( bak_filename ) ! = 0 )
{
/* failing to delete backup file will not case delete command failure */
2009-09-20 18:23:42 +03:00
log_error ( " unlink(%s) failed: %d (%s) " , bak_filename , errno , strerror ( errno ) ) ;
2009-08-30 14:36:27 +03:00
}
}
ret = true ;
free :
free ( filename ) ;
free ( bak_filename ) ;
exit :
return ret ;
}
2009-08-23 12:58:01 +03:00
void emit_studio_renamed ( )
{
2009-09-05 19:12:53 +03:00
dbus_signal_emit ( g_dbus_connection , STUDIO_OBJECT_PATH , IFACE_STUDIO , " StudioRenamed " , " s " , & g_studio . name ) ;
2009-08-23 12:58:01 +03:00
}
2009-09-05 18:18:07 +03:00
static void ladish_get_studio_name ( struct dbus_method_call * call_ptr )
2009-08-23 11:09:15 +03:00
{
method_return_new_single ( call_ptr , DBUS_TYPE_STRING , & g_studio . name ) ;
}
2009-09-05 18:18:07 +03:00
static void ladish_rename_studio ( struct dbus_method_call * call_ptr )
2009-08-23 11:09:15 +03:00
{
const char * new_name ;
char * new_name_dup ;
if ( ! dbus_message_get_args ( call_ptr - > message , & g_dbus_error , DBUS_TYPE_STRING , & new_name , DBUS_TYPE_INVALID ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_INVALID_ARGS , " Invalid arguments to method \" %s \" : %s " , call_ptr - > method_name , g_dbus_error . message ) ;
dbus_error_free ( & g_dbus_error ) ;
return ;
}
2009-09-20 18:23:42 +03:00
log_info ( " Rename studio request (%s) " , new_name ) ;
2009-08-31 01:50:24 +03:00
2009-08-23 11:09:15 +03:00
new_name_dup = strdup ( new_name ) ;
if ( new_name_dup = = NULL )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " strdup() failed to allocate new name. " ) ;
return ;
}
free ( g_studio . name ) ;
g_studio . name = new_name_dup ;
method_return_new_void ( call_ptr ) ;
2009-08-23 12:58:01 +03:00
emit_studio_renamed ( ) ;
2009-08-23 11:09:15 +03:00
}
2009-12-27 00:41:46 +02:00
static bool ladish_save_studio_internal ( struct dbus_method_call * call_ptr , const char * new_studio_name )
2009-08-07 23:28:34 +03:00
{
2009-12-07 23:35:37 +02:00
/* FIXME: this is wrong place to do such check because state before
command execution needs to be checked and not state before
command is submited , but doing it here will show error to
user . Once notification mechanism is implemented , the
studio_is_started ( ) check in save command run menthod
will send a notification and this check must be removed . */
if ( ! studio_is_started ( ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " Cannot save not-started studio " ) ;
2009-12-27 00:41:46 +02:00
return false ;
}
return ladish_command_save_studio ( call_ptr , & g_studio . cmd_queue , new_studio_name ) ;
}
static void ladish_save_studio ( struct dbus_method_call * call_ptr )
{
log_info ( " Save studio request " ) ;
if ( ladish_save_studio_internal ( call_ptr , g_studio . name ) )
{
method_return_new_void ( call_ptr ) ;
}
}
static void ladish_save_as_studio ( struct dbus_method_call * call_ptr )
{
const char * new_name ;
log_info ( " SaveAs studio request " ) ;
if ( ! dbus_message_get_args ( call_ptr - > message , & g_dbus_error , DBUS_TYPE_STRING , & new_name , DBUS_TYPE_INVALID ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_INVALID_ARGS , " Invalid arguments to method \" %s \" : %s " , call_ptr - > method_name , g_dbus_error . message ) ;
dbus_error_free ( & g_dbus_error ) ;
2009-12-07 23:35:37 +02:00
return ;
}
2009-12-27 00:41:46 +02:00
if ( ladish_save_studio_internal ( call_ptr , new_name ) )
2009-08-24 01:04:07 +03:00
{
method_return_new_void ( call_ptr ) ;
}
2009-08-07 23:28:34 +03:00
}
2009-08-20 22:43:11 +03:00
2009-09-05 18:18:07 +03:00
static void ladish_unload_studio ( struct dbus_method_call * call_ptr )
2009-08-30 16:23:19 +03:00
{
2009-09-20 18:23:42 +03:00
log_info ( " Unload studio request " ) ;
2009-08-30 16:13:38 +03:00
2009-11-25 03:42:02 +02:00
if ( ladish_command_unload_studio ( call_ptr , & g_studio . cmd_queue ) )
2009-08-30 16:13:38 +03:00
{
2009-11-25 03:42:02 +02:00
method_return_new_void ( call_ptr ) ;
2009-08-30 16:13:38 +03:00
}
}
2009-09-05 18:18:07 +03:00
static void ladish_stop_studio ( struct dbus_method_call * call_ptr )
2009-08-30 22:40:28 +03:00
{
2009-11-25 03:42:02 +02:00
log_info ( " Stop studio request " ) ;
2009-08-30 22:40:28 +03:00
2009-11-25 03:42:02 +02:00
g_studio . automatic = false ; /* even if it was automatic, it is not anymore because user knows about it */
if ( ladish_command_stop_studio ( call_ptr , & g_studio . cmd_queue ) )
2009-08-30 22:40:28 +03:00
{
method_return_new_void ( call_ptr ) ;
}
}
2009-09-05 18:18:07 +03:00
static void ladish_start_studio ( struct dbus_method_call * call_ptr )
2009-08-30 22:40:28 +03:00
{
2009-11-25 03:42:02 +02:00
log_info ( " Start studio request " ) ;
2009-08-30 22:40:28 +03:00
2009-11-25 03:42:02 +02:00
g_studio . automatic = false ; /* even if it was automatic, it is not anymore because user knows about it */
if ( ladish_command_start_studio ( call_ptr , & g_studio . cmd_queue ) )
2009-08-30 22:40:28 +03:00
{
method_return_new_void ( call_ptr ) ;
}
}
2009-12-06 01:51:25 +02:00
static void ladish_studio_is_started ( struct dbus_method_call * call_ptr )
{
dbus_bool_t started ;
started = g_studio . jack_graph_proxy ! = NULL ;
method_return_new_single ( call_ptr , DBUS_TYPE_BOOLEAN , & started ) ;
}
2010-03-31 01:50:01 +03:00
static
bool
add_room_ports (
void * context ,
ladish_port_handle port_handle ,
const char * port_name ,
uint32_t port_type ,
uint32_t port_flags )
{
//log_info("Studio room port \"%s\"", port_name);
2010-04-03 00:47:05 +03:00
if ( JACKDBUS_PORT_IS_INPUT ( port_flags ) )
{
JACKDBUS_PORT_CLEAR_INPUT ( port_flags ) ;
JACKDBUS_PORT_SET_OUTPUT ( port_flags ) ;
}
else if ( JACKDBUS_PORT_IS_OUTPUT ( port_flags ) )
{
JACKDBUS_PORT_CLEAR_OUTPUT ( port_flags ) ;
JACKDBUS_PORT_SET_INPUT ( port_flags ) ;
}
else
{
log_error ( " room link port with bad flags % " PRIu32 , port_flags ) ;
return false ;
}
2010-03-31 01:50:01 +03:00
return ladish_graph_add_port ( g_studio . studio_graph , context , port_handle , port_name , port_type , port_flags , false ) ;
}
2010-03-21 23:18:04 +02:00
static void ladish_studio_create_room ( struct dbus_method_call * call_ptr )
2010-03-01 02:12:12 +02:00
{
const char * room_name ;
const char * template_name ;
ladish_room_handle room ;
2010-03-06 17:03:14 +02:00
char room_dbus_name [ 1024 ] ;
2010-03-31 01:50:01 +03:00
ladish_client_handle room_client ;
uuid_t room_uuid ;
2010-03-01 02:12:12 +02:00
dbus_error_init ( & g_dbus_error ) ;
if ( ! dbus_message_get_args ( call_ptr - > message , & g_dbus_error , DBUS_TYPE_STRING , & room_name , DBUS_TYPE_STRING , & template_name , DBUS_TYPE_INVALID ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_INVALID_ARGS , " Invalid arguments to method \" %s \" : %s " , call_ptr - > method_name , g_dbus_error . message ) ;
dbus_error_free ( & g_dbus_error ) ;
2010-03-31 01:50:01 +03:00
goto fail ;
2010-03-01 02:12:12 +02:00
}
log_info ( " Request to create new studio room \" %s \" from template \" %s \" . " , room_name , template_name ) ;
room = find_room_template_by_name ( template_name ) ;
if ( room = = NULL )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_INVALID_ARGS , " Unknown room template \" %s \" " , template_name ) ;
2010-03-31 01:50:01 +03:00
goto fail ;
2010-03-01 02:12:12 +02:00
}
2010-03-06 17:03:14 +02:00
g_studio . room_count + + ;
sprintf ( room_dbus_name , DBUS_BASE_PATH " /Room%u " , g_studio . room_count ) ;
if ( ! ladish_room_create ( NULL , room_name , room , room_dbus_name , & room ) )
2010-03-01 02:12:12 +02:00
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " ladish_room_create() failed. " ) ;
2010-03-31 01:50:01 +03:00
goto fail_decrement_room_count ;
}
ladish_room_get_uuid ( room , room_uuid ) ;
if ( ! ladish_client_create ( room_uuid , & room_client ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " ladish_client_create() failed. " ) ;
goto fail_destroy_room ;
}
if ( ! ladish_graph_add_client ( g_studio . studio_graph , room_client , room_name , false ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " ladish_graph_add_client() failed to add room client to studio graph. " ) ;
goto fail_destroy_room_client ;
}
if ( ! ladish_room_iterate_link_ports ( room , room_client , add_room_ports ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_GENERIC , " Creation of studio room link ports failed. " ) ;
goto fail_remove_room_client ;
2010-03-01 02:12:12 +02:00
}
list_add_tail ( ladish_room_get_list_node ( room ) , & g_studio . rooms ) ;
2010-03-07 13:46:45 +02:00
emit_room_appeared ( room ) ;
2010-03-01 02:12:12 +02:00
method_return_new_void ( call_ptr ) ;
2010-03-31 01:50:01 +03:00
return ;
fail_remove_room_client :
ladish_graph_remove_client ( g_studio . studio_graph , room_client , false ) ;
fail_destroy_room_client :
ladish_client_destroy ( room_client ) ;
fail_destroy_room :
ladish_room_destroy ( room ) ;
fail_decrement_room_count :
g_studio . room_count - - ;
fail :
return ;
2010-03-01 02:12:12 +02:00
}
static void ladish_studio_get_room_list ( struct dbus_method_call * call_ptr )
{
DBusMessageIter iter , array_iter ;
DBusMessageIter struct_iter ;
struct list_head * node_ptr ;
ladish_room_handle room ;
call_ptr - > reply = dbus_message_new_method_return ( call_ptr - > message ) ;
if ( call_ptr - > reply = = NULL )
{
goto fail ;
}
dbus_message_iter_init_append ( call_ptr - > reply , & iter ) ;
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (sa{sv}) " , & array_iter ) )
{
goto fail_unref ;
}
list_for_each ( node_ptr , & g_studio . rooms )
{
room = ladish_room_from_list_node ( node_ptr ) ;
if ( ! dbus_message_iter_open_container ( & array_iter , DBUS_TYPE_STRUCT , NULL , & struct_iter ) )
goto fail_unref ;
2010-03-07 13:46:45 +02:00
if ( ! fill_room_info ( & struct_iter , room ) )
2010-03-01 02:12:12 +02:00
goto fail_unref ;
if ( ! dbus_message_iter_close_container ( & array_iter , & struct_iter ) )
goto fail_unref ;
}
if ( ! dbus_message_iter_close_container ( & iter , & array_iter ) )
{
goto fail_unref ;
}
return ;
fail_unref :
dbus_message_unref ( call_ptr - > reply ) ;
call_ptr - > reply = NULL ;
fail :
log_error ( " Ran out of memory trying to construct method return " ) ;
}
static void ladish_studio_delete_room ( struct dbus_method_call * call_ptr )
{
const char * name ;
2010-03-13 20:56:55 +02:00
struct list_head * node_ptr ;
ladish_room_handle room ;
2010-03-31 01:50:01 +03:00
ladish_client_handle room_client ;
2010-03-01 02:12:12 +02:00
dbus_error_init ( & g_dbus_error ) ;
if ( ! dbus_message_get_args ( call_ptr - > message , & g_dbus_error , DBUS_TYPE_STRING , & name , DBUS_TYPE_INVALID ) )
{
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_INVALID_ARGS , " Invalid arguments to method \" %s \" : %s " , call_ptr - > method_name , g_dbus_error . message ) ;
dbus_error_free ( & g_dbus_error ) ;
return ;
}
log_info ( " Delete studio room request (%s) " , name ) ;
2010-03-13 20:56:55 +02:00
list_for_each ( node_ptr , & g_studio . rooms )
2010-03-01 02:12:12 +02:00
{
2010-03-13 20:56:55 +02:00
room = ladish_room_from_list_node ( node_ptr ) ;
if ( strcmp ( ladish_room_get_name ( room ) , name ) = = 0 )
{
list_del ( node_ptr ) ;
g_studio . room_count - - ;
emit_room_disappeared ( room ) ;
2010-03-31 01:50:01 +03:00
room_client = ladish_graph_find_client_by_name ( g_studio . studio_graph , ladish_room_get_name ( room ) ) ;
ASSERT ( room_client ! = NULL ) ;
ladish_graph_remove_client ( g_studio . studio_graph , room_client , false ) ;
ladish_client_destroy ( room_client ) ;
2010-03-13 20:56:55 +02:00
ladish_room_destroy ( room ) ;
method_return_new_void ( call_ptr ) ;
return ;
}
2010-03-01 02:12:12 +02:00
}
2010-03-13 20:56:55 +02:00
lash_dbus_error ( call_ptr , LASH_DBUS_ERROR_INVALID_ARGS , " Invalid arguments to method \" %s \" : Cannot find room with name \" %s \" " , call_ptr - > method_name , name ) ;
return ;
2010-03-01 02:12:12 +02:00
}
2010-03-21 16:48:04 +02:00
void studio_remove_all_rooms ( void )
{
struct list_head * node_ptr ;
ladish_room_handle room ;
while ( ! list_empty ( & g_studio . rooms ) )
{
node_ptr = g_studio . rooms . next ;
list_del ( node_ptr ) ;
room = ladish_room_from_list_node ( node_ptr ) ;
ASSERT ( g_studio . room_count > 0 ) ;
g_studio . room_count - - ;
emit_room_disappeared ( room ) ;
ladish_room_destroy ( room ) ;
}
ASSERT ( g_studio . room_count = = 0 ) ;
}
2009-08-23 11:09:15 +03:00
METHOD_ARGS_BEGIN ( GetName , " Get studio name " )
METHOD_ARG_DESCRIBE_OUT ( " studio_name " , " s " , " Name of studio " )
METHOD_ARGS_END
METHOD_ARGS_BEGIN ( Rename , " Rename studio " )
METHOD_ARG_DESCRIBE_IN ( " studio_name " , " s " , " New name " )
METHOD_ARGS_END
2009-08-23 01:21:23 +03:00
METHOD_ARGS_BEGIN ( Save , " Save studio " )
METHOD_ARGS_END
2009-12-27 00:41:46 +02:00
METHOD_ARGS_BEGIN ( SaveAs , " SaveAs studio " )
METHOD_ARG_DESCRIBE_IN ( " studio_name " , " s " , " New name " )
METHOD_ARGS_END
2009-08-30 16:23:19 +03:00
METHOD_ARGS_BEGIN ( Unload , " Unload studio " )
METHOD_ARGS_END
2009-08-30 22:40:28 +03:00
METHOD_ARGS_BEGIN ( Start , " Start studio " )
METHOD_ARGS_END
METHOD_ARGS_BEGIN ( Stop , " Stop studio " )
METHOD_ARGS_END
2009-12-06 01:51:25 +02:00
METHOD_ARGS_BEGIN ( IsStarted , " Check whether studio is started " )
METHOD_ARG_DESCRIBE_OUT ( " started " , " b " , " Whether studio is started " )
METHOD_ARGS_END
2010-03-21 23:18:04 +02:00
METHOD_ARGS_BEGIN ( CreateRoom , " Create new studio room " )
2010-03-01 02:12:12 +02:00
METHOD_ARG_DESCRIBE_IN ( " room_name " , " s " , " Studio room name " )
METHOD_ARG_DESCRIBE_IN ( " room_template_name " , " s " , " Room template name " )
METHOD_ARGS_END
METHOD_ARGS_BEGIN ( GetRoomList , " Get list of rooms in this studio " )
2010-03-06 17:18:48 +02:00
METHOD_ARG_DESCRIBE_OUT ( " room_list " , " a(sa{sv}) " , " List of studio rooms: opaths and properties " )
2010-03-01 02:12:12 +02:00
METHOD_ARGS_END
METHOD_ARGS_BEGIN ( DeleteRoom , " Delete studio room " )
METHOD_ARG_DESCRIBE_IN ( " room_name " , " s " , " Name of studio room to delete " )
METHOD_ARGS_END
2009-08-20 22:43:11 +03:00
METHODS_BEGIN
2009-08-23 11:09:15 +03:00
METHOD_DESCRIBE ( GetName , ladish_get_studio_name )
METHOD_DESCRIBE ( Rename , ladish_rename_studio )
2009-08-23 01:21:23 +03:00
METHOD_DESCRIBE ( Save , ladish_save_studio )
2009-12-27 00:41:46 +02:00
METHOD_DESCRIBE ( SaveAs , ladish_save_as_studio )
2009-08-30 16:23:19 +03:00
METHOD_DESCRIBE ( Unload , ladish_unload_studio )
2009-08-30 22:40:28 +03:00
METHOD_DESCRIBE ( Start , ladish_start_studio )
METHOD_DESCRIBE ( Stop , ladish_stop_studio )
2009-12-06 01:51:25 +02:00
METHOD_DESCRIBE ( IsStarted , ladish_studio_is_started )
2010-03-21 23:18:04 +02:00
METHOD_DESCRIBE ( CreateRoom , ladish_studio_create_room )
2010-03-01 02:12:12 +02:00
METHOD_DESCRIBE ( GetRoomList , ladish_studio_get_room_list )
METHOD_DESCRIBE ( DeleteRoom , ladish_studio_delete_room )
2009-08-20 22:43:11 +03:00
METHODS_END
2009-08-23 12:58:01 +03:00
SIGNAL_ARGS_BEGIN ( StudioRenamed , " Studio name changed " )
SIGNAL_ARG_DESCRIBE ( " studio_name " , " s " , " New studio name " )
SIGNAL_ARGS_END
2009-08-30 22:40:28 +03:00
SIGNAL_ARGS_BEGIN ( StudioStarted , " Studio started " )
SIGNAL_ARGS_END
2009-12-17 06:34:45 +02:00
SIGNAL_ARGS_BEGIN ( StudioCrashed , " Studio crashed " )
SIGNAL_ARGS_END
2009-08-30 22:40:28 +03:00
SIGNAL_ARGS_BEGIN ( StudioStopped , " Studio stopped " )
SIGNAL_ARGS_END
2009-08-20 22:43:11 +03:00
SIGNAL_ARGS_BEGIN ( RoomAppeared , " Room D-Bus object appeared " )
2010-03-07 13:46:45 +02:00
SIGNAL_ARG_DESCRIBE ( " opath " , " s " , " room object path " )
SIGNAL_ARG_DESCRIBE ( " properties " , " a{sv} " , " room object path and props " )
SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN ( RoomChanged , " Room D-Bus object changed " )
SIGNAL_ARG_DESCRIBE ( " opath " , " s " , " room object path " )
SIGNAL_ARG_DESCRIBE ( " properties " , " a{sv} " , " room object path and props " )
2009-08-20 22:43:11 +03:00
SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN ( RoomDisappeared , " Room D-Bus object disappeared " )
2010-03-07 13:46:45 +02:00
SIGNAL_ARG_DESCRIBE ( " opath " , " s " , " room object path " )
SIGNAL_ARG_DESCRIBE ( " properties " , " a{sv} " , " room object path and props " )
2009-08-20 22:43:11 +03:00
SIGNAL_ARGS_END
SIGNALS_BEGIN
2009-08-23 12:58:01 +03:00
SIGNAL_DESCRIBE ( StudioRenamed )
2009-08-30 22:40:28 +03:00
SIGNAL_DESCRIBE ( StudioStarted )
2009-12-17 06:34:45 +02:00
SIGNAL_DESCRIBE ( StudioCrashed )
2009-08-30 22:40:28 +03:00
SIGNAL_DESCRIBE ( StudioStopped )
2009-08-20 22:43:11 +03:00
SIGNAL_DESCRIBE ( RoomAppeared )
SIGNAL_DESCRIBE ( RoomDisappeared )
2010-03-07 13:46:45 +02:00
SIGNAL_DESCRIBE ( RoomChanged )
2009-08-20 22:43:11 +03:00
SIGNALS_END
2009-08-22 03:07:19 +03:00
INTERFACE_BEGIN ( g_interface_studio , IFACE_STUDIO )
2009-08-20 22:43:11 +03:00
INTERFACE_DEFAULT_HANDLER
INTERFACE_EXPOSE_METHODS
INTERFACE_EXPOSE_SIGNALS
INTERFACE_END