git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2342 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -402,6 +402,15 @@ void JackSocketServerChannel::BuildPoolTable() | |||
| } | |||
| } | |||
| bool JackSocketServerChannel::Init() | |||
| { | |||
| sigset_t set; | |||
| sigemptyset(&set); | |||
| sigaddset(&set, SIGPIPE); | |||
| pthread_sigmask(SIG_BLOCK, &set, 0); | |||
| return true; | |||
| } | |||
| bool JackSocketServerChannel::Execute() | |||
| { | |||
| // Global poll | |||
| @@ -227,690 +227,3 @@ JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_control, "org.jackaudio.JackContro | |||
| JACK_DBUS_IFACE_HANDLER(jack_control_run_method) | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| Copyright (C) 2007-2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| #include "controller_internal.h" | |||
| #define controller_ptr ((struct jack_controller *)call->context) | |||
| /* | |||
| * Check if the supplied method name exists in org.jackaudio.JackControl, | |||
| * if it does execute it and return true. Otherwise return false. | |||
| */ | |||
| static | |||
| bool | |||
| jack_control_run_method( | |||
| struct jack_dbus_method_call * call, | |||
| const struct jack_dbus_interface_method_descriptor * methods) | |||
| { | |||
| int ret; | |||
| int type; | |||
| message_arg_t arg; | |||
| /* use empty reply if not overriden in the code that follows */ | |||
| type = DBUS_TYPE_INVALID; | |||
| if (strcmp (call->method_name, "Exit") == 0) | |||
| { | |||
| g_exit_command = TRUE; | |||
| } | |||
| else if (strcmp (call->method_name, "IsStarted") == 0) | |||
| { | |||
| type = DBUS_TYPE_BOOLEAN; | |||
| arg.boolean = (dbus_bool_t) (controller_ptr->started ? TRUE : FALSE); | |||
| } | |||
| else if (strcmp (call->method_name, "StartServer") == 0) | |||
| { | |||
| if (!jack_controller_start_server(controller_ptr, call)) | |||
| { | |||
| jack_error ("Failed to start server"); | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "StopServer") == 0) | |||
| { | |||
| if (!jack_controller_stop_server(controller_ptr, call)) | |||
| { | |||
| jack_error ("Failed to stop server"); | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "GetLoad") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_DOUBLE; | |||
| arg.doubl = jack_cpu_load(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "GetXruns") == 0) | |||
| { | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = controller_ptr->xruns; | |||
| } | |||
| else if (strcmp (call->method_name, "GetSampleRate") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = jack_get_sample_rate(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "GetLatency") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_DOUBLE; | |||
| arg.doubl = ((float)jack_get_buffer_size(controller_ptr->client) / (float)jack_get_sample_rate(controller_ptr->client)) * 1000.0f; | |||
| } | |||
| else if (strcmp (call->method_name, "GetBufferSize") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = jack_get_buffer_size(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "SetBufferSize") == 0) | |||
| { | |||
| dbus_uint32_t buffer_size; | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| if (!jack_dbus_get_method_args(call, DBUS_TYPE_UINT32, &buffer_size, DBUS_TYPE_INVALID)) | |||
| { | |||
| /* jack_dbus_get_method_args() has set reply for us */ | |||
| goto exit; | |||
| } | |||
| ret = jack_set_buffer_size(controller_ptr->client, buffer_size); | |||
| if (ret != 0) | |||
| { | |||
| jack_dbus_error( | |||
| call, | |||
| JACK_DBUS_ERROR_GENERIC, | |||
| "jack_set_buffer_size(%u) failed with error %d", (unsigned int)buffer_size, ret); | |||
| goto exit; | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "IsRealtime") == 0) | |||
| { | |||
| type = DBUS_TYPE_BOOLEAN; | |||
| arg.boolean = jack_is_realtime(controller_ptr->client) ? TRUE : FALSE; | |||
| } | |||
| else if (strcmp (call->method_name, "ResetXruns") == 0) | |||
| { | |||
| controller_ptr->xruns = 0; | |||
| } | |||
| else | |||
| { | |||
| return false; | |||
| } | |||
| jack_dbus_construct_method_return_single(call, type, arg); | |||
| return true; | |||
| not_started: | |||
| jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
| "Can't execute method '%s' with stopped JACK server", call->method_name); | |||
| exit: | |||
| return true; | |||
| } | |||
| #undef controller_ptr | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsStarted) | |||
| JACK_DBUS_METHOD_ARGUMENT("started", "b", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StartServer) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StopServer) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLoad) | |||
| JACK_DBUS_METHOD_ARGUMENT("load", "d", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetXruns) | |||
| JACK_DBUS_METHOD_ARGUMENT("xruns_count", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetSampleRate) | |||
| JACK_DBUS_METHOD_ARGUMENT("sample_rate", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLatency) | |||
| JACK_DBUS_METHOD_ARGUMENT("latency_ms", "d", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetBufferSize) | |||
| JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetBufferSize) | |||
| JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", false) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsRealtime) | |||
| JACK_DBUS_METHOD_ARGUMENT("realtime", "b", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ResetXruns) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(StopServer, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetLoad, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetXruns, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetSampleRate, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetLatency, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetBufferSize, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(SetBufferSize, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL) | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_control, "org.jackaudio.JackControl") | |||
| JACK_DBUS_IFACE_HANDLER(jack_control_run_method) | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| Copyright (C) 2007-2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| #include "controller_internal.h" | |||
| #define controller_ptr ((struct jack_controller *)call->context) | |||
| /* | |||
| * Check if the supplied method name exists in org.jackaudio.JackControl, | |||
| * if it does execute it and return true. Otherwise return false. | |||
| */ | |||
| static | |||
| bool | |||
| jack_control_run_method( | |||
| struct jack_dbus_method_call * call, | |||
| const struct jack_dbus_interface_method_descriptor * methods) | |||
| { | |||
| int ret; | |||
| int type; | |||
| message_arg_t arg; | |||
| /* use empty reply if not overriden in the code that follows */ | |||
| type = DBUS_TYPE_INVALID; | |||
| if (strcmp (call->method_name, "Exit") == 0) | |||
| { | |||
| g_exit_command = TRUE; | |||
| } | |||
| else if (strcmp (call->method_name, "IsStarted") == 0) | |||
| { | |||
| type = DBUS_TYPE_BOOLEAN; | |||
| arg.boolean = (dbus_bool_t) (controller_ptr->started ? TRUE : FALSE); | |||
| } | |||
| else if (strcmp (call->method_name, "StartServer") == 0) | |||
| { | |||
| if (!jack_controller_start_server(controller_ptr, call)) | |||
| { | |||
| jack_error ("Failed to start server"); | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "StopServer") == 0) | |||
| { | |||
| if (!jack_controller_stop_server(controller_ptr, call)) | |||
| { | |||
| jack_error ("Failed to stop server"); | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "GetLoad") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_DOUBLE; | |||
| arg.doubl = jack_cpu_load(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "GetXruns") == 0) | |||
| { | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = controller_ptr->xruns; | |||
| } | |||
| else if (strcmp (call->method_name, "GetSampleRate") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = jack_get_sample_rate(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "GetLatency") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_DOUBLE; | |||
| arg.doubl = ((float)jack_get_buffer_size(controller_ptr->client) / (float)jack_get_sample_rate(controller_ptr->client)) * 1000.0f; | |||
| } | |||
| else if (strcmp (call->method_name, "GetBufferSize") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = jack_get_buffer_size(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "SetBufferSize") == 0) | |||
| { | |||
| dbus_uint32_t buffer_size; | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| if (!jack_dbus_get_method_args(call, DBUS_TYPE_UINT32, &buffer_size, DBUS_TYPE_INVALID)) | |||
| { | |||
| /* jack_dbus_get_method_args() has set reply for us */ | |||
| goto exit; | |||
| } | |||
| ret = jack_set_buffer_size(controller_ptr->client, buffer_size); | |||
| if (ret != 0) | |||
| { | |||
| jack_dbus_error( | |||
| call, | |||
| JACK_DBUS_ERROR_GENERIC, | |||
| "jack_set_buffer_size(%u) failed with error %d", (unsigned int)buffer_size, ret); | |||
| goto exit; | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "IsRealtime") == 0) | |||
| { | |||
| type = DBUS_TYPE_BOOLEAN; | |||
| arg.boolean = jack_is_realtime(controller_ptr->client) ? TRUE : FALSE; | |||
| } | |||
| else if (strcmp (call->method_name, "ResetXruns") == 0) | |||
| { | |||
| controller_ptr->xruns = 0; | |||
| } | |||
| else | |||
| { | |||
| return false; | |||
| } | |||
| jack_dbus_construct_method_return_single(call, type, arg); | |||
| return true; | |||
| not_started: | |||
| jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
| "Can't execute method '%s' with stopped JACK server", call->method_name); | |||
| exit: | |||
| return true; | |||
| } | |||
| #undef controller_ptr | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsStarted) | |||
| JACK_DBUS_METHOD_ARGUMENT("started", "b", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StartServer) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StopServer) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLoad) | |||
| JACK_DBUS_METHOD_ARGUMENT("load", "d", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetXruns) | |||
| JACK_DBUS_METHOD_ARGUMENT("xruns_count", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetSampleRate) | |||
| JACK_DBUS_METHOD_ARGUMENT("sample_rate", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLatency) | |||
| JACK_DBUS_METHOD_ARGUMENT("latency_ms", "d", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetBufferSize) | |||
| JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetBufferSize) | |||
| JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", false) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsRealtime) | |||
| JACK_DBUS_METHOD_ARGUMENT("realtime", "b", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ResetXruns) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(StopServer, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetLoad, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetXruns, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetSampleRate, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetLatency, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetBufferSize, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(SetBufferSize, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL) | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_control, "org.jackaudio.JackControl") | |||
| JACK_DBUS_IFACE_HANDLER(jack_control_run_method) | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| Copyright (C) 2007-2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| #include "controller_internal.h" | |||
| #define controller_ptr ((struct jack_controller *)call->context) | |||
| /* | |||
| * Check if the supplied method name exists in org.jackaudio.JackControl, | |||
| * if it does execute it and return true. Otherwise return false. | |||
| */ | |||
| static | |||
| bool | |||
| jack_control_run_method( | |||
| struct jack_dbus_method_call * call, | |||
| const struct jack_dbus_interface_method_descriptor * methods) | |||
| { | |||
| int ret; | |||
| int type; | |||
| message_arg_t arg; | |||
| /* use empty reply if not overriden in the code that follows */ | |||
| type = DBUS_TYPE_INVALID; | |||
| if (strcmp (call->method_name, "Exit") == 0) | |||
| { | |||
| g_exit_command = TRUE; | |||
| } | |||
| else if (strcmp (call->method_name, "IsStarted") == 0) | |||
| { | |||
| type = DBUS_TYPE_BOOLEAN; | |||
| arg.boolean = (dbus_bool_t) (controller_ptr->started ? TRUE : FALSE); | |||
| } | |||
| else if (strcmp (call->method_name, "StartServer") == 0) | |||
| { | |||
| if (!jack_controller_start_server(controller_ptr, call)) | |||
| { | |||
| jack_error ("Failed to start server"); | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "StopServer") == 0) | |||
| { | |||
| if (!jack_controller_stop_server(controller_ptr, call)) | |||
| { | |||
| jack_error ("Failed to stop server"); | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "GetLoad") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_DOUBLE; | |||
| arg.doubl = jack_cpu_load(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "GetXruns") == 0) | |||
| { | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = controller_ptr->xruns; | |||
| } | |||
| else if (strcmp (call->method_name, "GetSampleRate") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = jack_get_sample_rate(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "GetLatency") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_DOUBLE; | |||
| arg.doubl = ((float)jack_get_buffer_size(controller_ptr->client) / (float)jack_get_sample_rate(controller_ptr->client)) * 1000.0f; | |||
| } | |||
| else if (strcmp (call->method_name, "GetBufferSize") == 0) | |||
| { | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| type = DBUS_TYPE_UINT32; | |||
| arg.uint32 = jack_get_buffer_size(controller_ptr->client); | |||
| } | |||
| else if (strcmp (call->method_name, "SetBufferSize") == 0) | |||
| { | |||
| dbus_uint32_t buffer_size; | |||
| if (!controller_ptr->started) | |||
| { | |||
| goto not_started; | |||
| } | |||
| if (!jack_dbus_get_method_args(call, DBUS_TYPE_UINT32, &buffer_size, DBUS_TYPE_INVALID)) | |||
| { | |||
| /* jack_dbus_get_method_args() has set reply for us */ | |||
| goto exit; | |||
| } | |||
| ret = jack_set_buffer_size(controller_ptr->client, buffer_size); | |||
| if (ret != 0) | |||
| { | |||
| jack_dbus_error( | |||
| call, | |||
| JACK_DBUS_ERROR_GENERIC, | |||
| "jack_set_buffer_size(%u) failed with error %d", (unsigned int)buffer_size, ret); | |||
| goto exit; | |||
| } | |||
| } | |||
| else if (strcmp (call->method_name, "IsRealtime") == 0) | |||
| { | |||
| type = DBUS_TYPE_BOOLEAN; | |||
| arg.boolean = jack_is_realtime(controller_ptr->client) ? TRUE : FALSE; | |||
| } | |||
| else if (strcmp (call->method_name, "ResetXruns") == 0) | |||
| { | |||
| controller_ptr->xruns = 0; | |||
| } | |||
| else | |||
| { | |||
| return false; | |||
| } | |||
| jack_dbus_construct_method_return_single(call, type, arg); | |||
| return true; | |||
| not_started: | |||
| jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
| "Can't execute method '%s' with stopped JACK server", call->method_name); | |||
| exit: | |||
| return true; | |||
| } | |||
| #undef controller_ptr | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsStarted) | |||
| JACK_DBUS_METHOD_ARGUMENT("started", "b", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StartServer) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(StopServer) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLoad) | |||
| JACK_DBUS_METHOD_ARGUMENT("load", "d", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetXruns) | |||
| JACK_DBUS_METHOD_ARGUMENT("xruns_count", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetSampleRate) | |||
| JACK_DBUS_METHOD_ARGUMENT("sample_rate", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetLatency) | |||
| JACK_DBUS_METHOD_ARGUMENT("latency_ms", "d", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetBufferSize) | |||
| JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(SetBufferSize) | |||
| JACK_DBUS_METHOD_ARGUMENT("buffer_size_frames", "u", false) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(IsRealtime) | |||
| JACK_DBUS_METHOD_ARGUMENT("realtime", "b", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(ResetXruns) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHOD_DESCRIBE(IsStarted, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(StartServer, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(StopServer, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetLoad, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetXruns, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetSampleRate, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetLatency, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(GetBufferSize, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(SetBufferSize, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL) | |||
| JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL) | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_control, "org.jackaudio.JackControl") | |||
| JACK_DBUS_IFACE_HANDLER(jack_control_run_method) | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| @@ -150,459 +150,3 @@ jack_controller_introspect_init() | |||
| *g_buffer_ptr = 0; | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007-2008 Nedko Arnaudov | |||
| Copyright (C) 2007-2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| static char g_xml_data[102400]; | |||
| static | |||
| void | |||
| jack_controller_dbus_introspect( | |||
| struct jack_dbus_method_call * call) | |||
| { | |||
| jack_dbus_construct_method_return_single( | |||
| call, | |||
| DBUS_TYPE_STRING, | |||
| (message_arg_t)(const char *)g_xml_data); | |||
| } | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(Introspect) | |||
| JACK_DBUS_METHOD_ARGUMENT("xml_data", "s", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHOD_DESCRIBE(Introspect, jack_controller_dbus_introspect) | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_introspectable, "org.freedesktop.DBus.Introspectable") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| static char * g_buffer_ptr; | |||
| static | |||
| void | |||
| write_line_format(const char * format, ...) | |||
| { | |||
| va_list ap; | |||
| va_start(ap, format); | |||
| g_buffer_ptr += vsprintf(g_buffer_ptr, format, ap); | |||
| va_end(ap); | |||
| } | |||
| static | |||
| void | |||
| write_line(const char * line) | |||
| { | |||
| write_line_format("%s\n", line); | |||
| } | |||
| void jack_controller_introspect_init() __attribute__((constructor)); | |||
| void | |||
| jack_controller_introspect_init() | |||
| { | |||
| struct jack_dbus_interface_descriptor ** interface_ptr_ptr; | |||
| const struct jack_dbus_interface_method_descriptor * method_ptr; | |||
| const struct jack_dbus_interface_method_argument_descriptor * method_argument_ptr; | |||
| const struct jack_dbus_interface_signal_descriptor * signal_ptr; | |||
| const struct jack_dbus_interface_signal_argument_descriptor * signal_argument_ptr; | |||
| g_buffer_ptr = g_xml_data; | |||
| write_line("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\""); | |||
| write_line("\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">"); | |||
| write_line("<node name=\"" JACK_CONTROLLER_OBJECT_PATH "\">"); | |||
| interface_ptr_ptr = g_jackcontroller_interfaces; | |||
| while (*interface_ptr_ptr != NULL) | |||
| { | |||
| write_line_format(" <interface name=\"%s\">\n", (*interface_ptr_ptr)->name); | |||
| if ((*interface_ptr_ptr)->methods != NULL) | |||
| { | |||
| method_ptr = (*interface_ptr_ptr)->methods; | |||
| while (method_ptr->name != NULL) | |||
| { | |||
| write_line_format(" <method name=\"%s\">\n", method_ptr->name); | |||
| method_argument_ptr = method_ptr->arguments; | |||
| while (method_argument_ptr->name != NULL) | |||
| { | |||
| write_line_format( | |||
| " <arg name=\"%s\" type=\"%s\" direction=\"%s\" />\n", | |||
| method_argument_ptr->name, | |||
| method_argument_ptr->type, | |||
| method_argument_ptr->direction_out ? "out" : "in"); | |||
| method_argument_ptr++; | |||
| } | |||
| write_line(" </method>"); | |||
| method_ptr++; | |||
| } | |||
| } | |||
| if ((*interface_ptr_ptr)->signals != NULL) | |||
| { | |||
| signal_ptr = (*interface_ptr_ptr)->signals; | |||
| while (signal_ptr->name != NULL) | |||
| { | |||
| write_line_format(" <signal name=\"%s\">\n", signal_ptr->name); | |||
| signal_argument_ptr = signal_ptr->arguments; | |||
| while (signal_argument_ptr->name != NULL) | |||
| { | |||
| write_line_format( | |||
| " <arg name=\"%s\" type=\"%s\" />\n", | |||
| signal_argument_ptr->name, | |||
| signal_argument_ptr->type); | |||
| signal_argument_ptr++; | |||
| } | |||
| write_line(" </signal>"); | |||
| signal_ptr++; | |||
| } | |||
| } | |||
| write_line(" </interface>"); | |||
| interface_ptr_ptr++; | |||
| } | |||
| write_line("</node>"); | |||
| *g_buffer_ptr = 0; | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007-2008 Nedko Arnaudov | |||
| Copyright (C) 2007-2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| static char g_xml_data[102400]; | |||
| static | |||
| void | |||
| jack_controller_dbus_introspect( | |||
| struct jack_dbus_method_call * call) | |||
| { | |||
| jack_dbus_construct_method_return_single( | |||
| call, | |||
| DBUS_TYPE_STRING, | |||
| (message_arg_t)(const char *)g_xml_data); | |||
| } | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(Introspect) | |||
| JACK_DBUS_METHOD_ARGUMENT("xml_data", "s", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHOD_DESCRIBE(Introspect, jack_controller_dbus_introspect) | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_introspectable, "org.freedesktop.DBus.Introspectable") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| static char * g_buffer_ptr; | |||
| static | |||
| void | |||
| write_line_format(const char * format, ...) | |||
| { | |||
| va_list ap; | |||
| va_start(ap, format); | |||
| g_buffer_ptr += vsprintf(g_buffer_ptr, format, ap); | |||
| va_end(ap); | |||
| } | |||
| static | |||
| void | |||
| write_line(const char * line) | |||
| { | |||
| write_line_format("%s\n", line); | |||
| } | |||
| void jack_controller_introspect_init() __attribute__((constructor)); | |||
| void | |||
| jack_controller_introspect_init() | |||
| { | |||
| struct jack_dbus_interface_descriptor ** interface_ptr_ptr; | |||
| const struct jack_dbus_interface_method_descriptor * method_ptr; | |||
| const struct jack_dbus_interface_method_argument_descriptor * method_argument_ptr; | |||
| const struct jack_dbus_interface_signal_descriptor * signal_ptr; | |||
| const struct jack_dbus_interface_signal_argument_descriptor * signal_argument_ptr; | |||
| g_buffer_ptr = g_xml_data; | |||
| write_line("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\""); | |||
| write_line("\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">"); | |||
| write_line("<node name=\"" JACK_CONTROLLER_OBJECT_PATH "\">"); | |||
| interface_ptr_ptr = g_jackcontroller_interfaces; | |||
| while (*interface_ptr_ptr != NULL) | |||
| { | |||
| write_line_format(" <interface name=\"%s\">\n", (*interface_ptr_ptr)->name); | |||
| if ((*interface_ptr_ptr)->methods != NULL) | |||
| { | |||
| method_ptr = (*interface_ptr_ptr)->methods; | |||
| while (method_ptr->name != NULL) | |||
| { | |||
| write_line_format(" <method name=\"%s\">\n", method_ptr->name); | |||
| method_argument_ptr = method_ptr->arguments; | |||
| while (method_argument_ptr->name != NULL) | |||
| { | |||
| write_line_format( | |||
| " <arg name=\"%s\" type=\"%s\" direction=\"%s\" />\n", | |||
| method_argument_ptr->name, | |||
| method_argument_ptr->type, | |||
| method_argument_ptr->direction_out ? "out" : "in"); | |||
| method_argument_ptr++; | |||
| } | |||
| write_line(" </method>"); | |||
| method_ptr++; | |||
| } | |||
| } | |||
| if ((*interface_ptr_ptr)->signals != NULL) | |||
| { | |||
| signal_ptr = (*interface_ptr_ptr)->signals; | |||
| while (signal_ptr->name != NULL) | |||
| { | |||
| write_line_format(" <signal name=\"%s\">\n", signal_ptr->name); | |||
| signal_argument_ptr = signal_ptr->arguments; | |||
| while (signal_argument_ptr->name != NULL) | |||
| { | |||
| write_line_format( | |||
| " <arg name=\"%s\" type=\"%s\" />\n", | |||
| signal_argument_ptr->name, | |||
| signal_argument_ptr->type); | |||
| signal_argument_ptr++; | |||
| } | |||
| write_line(" </signal>"); | |||
| signal_ptr++; | |||
| } | |||
| } | |||
| write_line(" </interface>"); | |||
| interface_ptr_ptr++; | |||
| } | |||
| write_line("</node>"); | |||
| *g_buffer_ptr = 0; | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007-2008 Nedko Arnaudov | |||
| Copyright (C) 2007-2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| static char g_xml_data[102400]; | |||
| static | |||
| void | |||
| jack_controller_dbus_introspect( | |||
| struct jack_dbus_method_call * call) | |||
| { | |||
| jack_dbus_construct_method_return_single( | |||
| call, | |||
| DBUS_TYPE_STRING, | |||
| (message_arg_t)(const char *)g_xml_data); | |||
| } | |||
| JACK_DBUS_METHOD_ARGUMENTS_BEGIN(Introspect) | |||
| JACK_DBUS_METHOD_ARGUMENT("xml_data", "s", true) | |||
| JACK_DBUS_METHOD_ARGUMENTS_END | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHOD_DESCRIBE(Introspect, jack_controller_dbus_introspect) | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_introspectable, "org.freedesktop.DBus.Introspectable") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| static char * g_buffer_ptr; | |||
| static | |||
| void | |||
| write_line_format(const char * format, ...) | |||
| { | |||
| va_list ap; | |||
| va_start(ap, format); | |||
| g_buffer_ptr += vsprintf(g_buffer_ptr, format, ap); | |||
| va_end(ap); | |||
| } | |||
| static | |||
| void | |||
| write_line(const char * line) | |||
| { | |||
| write_line_format("%s\n", line); | |||
| } | |||
| void jack_controller_introspect_init() __attribute__((constructor)); | |||
| void | |||
| jack_controller_introspect_init() | |||
| { | |||
| struct jack_dbus_interface_descriptor ** interface_ptr_ptr; | |||
| const struct jack_dbus_interface_method_descriptor * method_ptr; | |||
| const struct jack_dbus_interface_method_argument_descriptor * method_argument_ptr; | |||
| const struct jack_dbus_interface_signal_descriptor * signal_ptr; | |||
| const struct jack_dbus_interface_signal_argument_descriptor * signal_argument_ptr; | |||
| g_buffer_ptr = g_xml_data; | |||
| write_line("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\""); | |||
| write_line("\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">"); | |||
| write_line("<node name=\"" JACK_CONTROLLER_OBJECT_PATH "\">"); | |||
| interface_ptr_ptr = g_jackcontroller_interfaces; | |||
| while (*interface_ptr_ptr != NULL) | |||
| { | |||
| write_line_format(" <interface name=\"%s\">\n", (*interface_ptr_ptr)->name); | |||
| if ((*interface_ptr_ptr)->methods != NULL) | |||
| { | |||
| method_ptr = (*interface_ptr_ptr)->methods; | |||
| while (method_ptr->name != NULL) | |||
| { | |||
| write_line_format(" <method name=\"%s\">\n", method_ptr->name); | |||
| method_argument_ptr = method_ptr->arguments; | |||
| while (method_argument_ptr->name != NULL) | |||
| { | |||
| write_line_format( | |||
| " <arg name=\"%s\" type=\"%s\" direction=\"%s\" />\n", | |||
| method_argument_ptr->name, | |||
| method_argument_ptr->type, | |||
| method_argument_ptr->direction_out ? "out" : "in"); | |||
| method_argument_ptr++; | |||
| } | |||
| write_line(" </method>"); | |||
| method_ptr++; | |||
| } | |||
| } | |||
| if ((*interface_ptr_ptr)->signals != NULL) | |||
| { | |||
| signal_ptr = (*interface_ptr_ptr)->signals; | |||
| while (signal_ptr->name != NULL) | |||
| { | |||
| write_line_format(" <signal name=\"%s\">\n", signal_ptr->name); | |||
| signal_argument_ptr = signal_ptr->arguments; | |||
| while (signal_argument_ptr->name != NULL) | |||
| { | |||
| write_line_format( | |||
| " <arg name=\"%s\" type=\"%s\" />\n", | |||
| signal_argument_ptr->name, | |||
| signal_argument_ptr->type); | |||
| signal_argument_ptr++; | |||
| } | |||
| write_line(" </signal>"); | |||
| signal_ptr++; | |||
| } | |||
| } | |||
| write_line(" </interface>"); | |||
| interface_ptr_ptr++; | |||
| } | |||
| write_line("</node>"); | |||
| *g_buffer_ptr = 0; | |||
| } | |||
| @@ -32,105 +32,3 @@ JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_transport, "org.jackaudio.JackTransport") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2008 Nedko Arnaudov | |||
| Copyright (C) 2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_transport, "org.jackaudio.JackTransport") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2008 Nedko Arnaudov | |||
| Copyright (C) 2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_transport, "org.jackaudio.JackTransport") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2008 Nedko Arnaudov | |||
| Copyright (C) 2008 Juuso Alasuutari | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <dbus/dbus.h> | |||
| #include "jackdbus.h" | |||
| JACK_DBUS_METHODS_BEGIN | |||
| JACK_DBUS_METHODS_END | |||
| JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_transport, "org.jackaudio.JackTransport") | |||
| JACK_DBUS_IFACE_EXPOSE_METHODS | |||
| JACK_DBUS_IFACE_END | |||
| @@ -311,942 +311,3 @@ jack_controller_settings_save_driver_options( | |||
| { | |||
| return jack_controller_settings_save_options(context, jackctl_driver_get_parameters(driver), dbus_call_context_ptr); | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <dbus/dbus.h> | |||
| #include "controller_internal.h" | |||
| void | |||
| jack_controller_settings_set_bool_option( | |||
| const char *value_str, | |||
| int *value_ptr) | |||
| { | |||
| if (strcmp(value_str, "true") == 0) | |||
| { | |||
| *value_ptr = true; | |||
| } | |||
| else if (strcmp(value_str, "false") == 0) | |||
| { | |||
| *value_ptr = false; | |||
| } | |||
| else | |||
| { | |||
| jack_error("ignoring unknown bool value \"%s\"", value_str); | |||
| } | |||
| } | |||
| void | |||
| jack_controller_settings_set_sint_option( | |||
| const char *value_str, | |||
| int *value_ptr) | |||
| { | |||
| *value_ptr = atoi(value_str); | |||
| } | |||
| void | |||
| jack_controller_settings_set_uint_option( | |||
| const char *value_str, | |||
| unsigned int *value_ptr) | |||
| { | |||
| *value_ptr = strtoul(value_str, NULL, 10); | |||
| } | |||
| void | |||
| jack_controller_settings_set_char_option( | |||
| const char *value_str, | |||
| char *value_ptr) | |||
| { | |||
| if (value_str[0] == 0 || value_str[1] != 0) | |||
| { | |||
| jack_error("invalid char option value \"%s\"", value_str); | |||
| return; | |||
| } | |||
| *value_ptr = *value_str; | |||
| } | |||
| void | |||
| jack_controller_settings_set_string_option( | |||
| const char *value_str, | |||
| char *value_ptr, | |||
| size_t max_size) | |||
| { | |||
| size_t size; | |||
| size = strlen(value_str); | |||
| if (size >= max_size) | |||
| { | |||
| jack_error("string option value \"%s\" is too long, max is %u chars (including terminating zero)", value_str, (unsigned int)max_size); | |||
| return; | |||
| } | |||
| strcpy(value_ptr, value_str); | |||
| } | |||
| void | |||
| jack_controller_settings_set_driver_option( | |||
| jackctl_driver_t *driver, | |||
| const char *option_name, | |||
| const char *option_value) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| int value_int; | |||
| unsigned int value_uint; | |||
| union jackctl_parameter_value value; | |||
| jack_info("setting driver option \"%s\" to value \"%s\"", option_name, option_value); | |||
| parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), option_name); | |||
| if (parameter == NULL) | |||
| { | |||
| jack_error( | |||
| "Unknown parameter \"%s\" of driver \"%s\"", | |||
| option_name, | |||
| jackctl_driver_get_name(driver)); | |||
| return; | |||
| } | |||
| type = jackctl_parameter_get_type(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| jack_controller_settings_set_sint_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| case JackParamUInt: | |||
| jack_controller_settings_set_uint_option(option_value, &value_uint); | |||
| value.ui = value_uint; | |||
| break; | |||
| case JackParamChar: | |||
| jack_controller_settings_set_char_option(option_value, &value.c); | |||
| break; | |||
| case JackParamString: | |||
| jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); | |||
| break; | |||
| case JackParamBool: | |||
| jack_controller_settings_set_bool_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| default: | |||
| jack_error("Parameter \"%s\" of driver \"%s\" is of unknown type %d", | |||
| jackctl_parameter_get_name(parameter), | |||
| jackctl_driver_get_name(driver), | |||
| type); | |||
| } | |||
| jackctl_parameter_set_value(parameter, &value); | |||
| } | |||
| void | |||
| jack_controller_settings_set_engine_option( | |||
| struct jack_controller *controller_ptr, | |||
| const char *option_name, | |||
| const char *option_value) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| int value_int; | |||
| unsigned int value_uint; | |||
| union jackctl_parameter_value value; | |||
| jack_info("setting engine option \"%s\" to value \"%s\"", option_name, option_value); | |||
| if (strcmp(option_name, "driver") == 0) | |||
| { | |||
| if (!jack_controller_select_driver(controller_ptr, option_value)) | |||
| { | |||
| jack_error("unknown driver '%s'", option_value); | |||
| } | |||
| return; | |||
| } | |||
| parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), option_name); | |||
| if (parameter == NULL) | |||
| { | |||
| jack_error( | |||
| "Unknown engine parameter \"%s\"", | |||
| option_name); | |||
| return; | |||
| } | |||
| type = jackctl_parameter_get_type(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| jack_controller_settings_set_sint_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| case JackParamUInt: | |||
| jack_controller_settings_set_uint_option(option_value, &value_uint); | |||
| value.ui = value_uint; | |||
| break; | |||
| case JackParamChar: | |||
| jack_controller_settings_set_char_option(option_value, &value.c); | |||
| break; | |||
| case JackParamString: | |||
| jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); | |||
| break; | |||
| case JackParamBool: | |||
| jack_controller_settings_set_bool_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| default: | |||
| jack_error("Engine parameter \"%s\" is of unknown type %d", | |||
| jackctl_parameter_get_name(parameter), | |||
| type); | |||
| } | |||
| jackctl_parameter_set_value(parameter, &value); | |||
| } | |||
| static | |||
| bool | |||
| jack_controller_settings_save_options( | |||
| void *context, | |||
| const JSList * parameters_list, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| union jackctl_parameter_value value; | |||
| const char * name; | |||
| char value_str[50]; | |||
| while (parameters_list != NULL) | |||
| { | |||
| parameter = (jackctl_parameter_t *)parameters_list->data; | |||
| if (jackctl_parameter_is_set(parameter)) | |||
| { | |||
| type = jackctl_parameter_get_type(parameter); | |||
| value = jackctl_parameter_get_value(parameter); | |||
| name = jackctl_parameter_get_name(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| sprintf(value_str, "%d", (int)value.i); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamUInt: | |||
| sprintf(value_str, "%u", (unsigned int)value.ui); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamChar: | |||
| sprintf(value_str, "%c", (char)value.c); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamString: | |||
| if (!jack_controller_settings_write_option(context, name, value.str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamBool: | |||
| if (!jack_controller_settings_write_option(context, name, value.b ? "true" : "false", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| default: | |||
| jack_error("parameter of unknown type %d", type); | |||
| } | |||
| } | |||
| parameters_list = jack_slist_next(parameters_list); | |||
| } | |||
| return true; | |||
| } | |||
| bool | |||
| jack_controller_settings_save_engine_options( | |||
| void *context, | |||
| struct jack_controller *controller_ptr, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| if (controller_ptr->driver != NULL) | |||
| { | |||
| if (!jack_controller_settings_write_option( | |||
| context, | |||
| "driver", | |||
| jackctl_driver_get_name(controller_ptr->driver), | |||
| dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| return jack_controller_settings_save_options(context, jackctl_server_get_parameters(controller_ptr->server), dbus_call_context_ptr); | |||
| } | |||
| bool | |||
| jack_controller_settings_save_driver_options( | |||
| void *context, | |||
| jackctl_driver_t *driver, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| return jack_controller_settings_save_options(context, jackctl_driver_get_parameters(driver), dbus_call_context_ptr); | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <dbus/dbus.h> | |||
| #include "controller_internal.h" | |||
| void | |||
| jack_controller_settings_set_bool_option( | |||
| const char *value_str, | |||
| int *value_ptr) | |||
| { | |||
| if (strcmp(value_str, "true") == 0) | |||
| { | |||
| *value_ptr = true; | |||
| } | |||
| else if (strcmp(value_str, "false") == 0) | |||
| { | |||
| *value_ptr = false; | |||
| } | |||
| else | |||
| { | |||
| jack_error("ignoring unknown bool value \"%s\"", value_str); | |||
| } | |||
| } | |||
| void | |||
| jack_controller_settings_set_sint_option( | |||
| const char *value_str, | |||
| int *value_ptr) | |||
| { | |||
| *value_ptr = atoi(value_str); | |||
| } | |||
| void | |||
| jack_controller_settings_set_uint_option( | |||
| const char *value_str, | |||
| unsigned int *value_ptr) | |||
| { | |||
| *value_ptr = strtoul(value_str, NULL, 10); | |||
| } | |||
| void | |||
| jack_controller_settings_set_char_option( | |||
| const char *value_str, | |||
| char *value_ptr) | |||
| { | |||
| if (value_str[0] == 0 || value_str[1] != 0) | |||
| { | |||
| jack_error("invalid char option value \"%s\"", value_str); | |||
| return; | |||
| } | |||
| *value_ptr = *value_str; | |||
| } | |||
| void | |||
| jack_controller_settings_set_string_option( | |||
| const char *value_str, | |||
| char *value_ptr, | |||
| size_t max_size) | |||
| { | |||
| size_t size; | |||
| size = strlen(value_str); | |||
| if (size >= max_size) | |||
| { | |||
| jack_error("string option value \"%s\" is too long, max is %u chars (including terminating zero)", value_str, (unsigned int)max_size); | |||
| return; | |||
| } | |||
| strcpy(value_ptr, value_str); | |||
| } | |||
| void | |||
| jack_controller_settings_set_driver_option( | |||
| jackctl_driver_t *driver, | |||
| const char *option_name, | |||
| const char *option_value) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| int value_int; | |||
| unsigned int value_uint; | |||
| union jackctl_parameter_value value; | |||
| jack_info("setting driver option \"%s\" to value \"%s\"", option_name, option_value); | |||
| parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), option_name); | |||
| if (parameter == NULL) | |||
| { | |||
| jack_error( | |||
| "Unknown parameter \"%s\" of driver \"%s\"", | |||
| option_name, | |||
| jackctl_driver_get_name(driver)); | |||
| return; | |||
| } | |||
| type = jackctl_parameter_get_type(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| jack_controller_settings_set_sint_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| case JackParamUInt: | |||
| jack_controller_settings_set_uint_option(option_value, &value_uint); | |||
| value.ui = value_uint; | |||
| break; | |||
| case JackParamChar: | |||
| jack_controller_settings_set_char_option(option_value, &value.c); | |||
| break; | |||
| case JackParamString: | |||
| jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); | |||
| break; | |||
| case JackParamBool: | |||
| jack_controller_settings_set_bool_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| default: | |||
| jack_error("Parameter \"%s\" of driver \"%s\" is of unknown type %d", | |||
| jackctl_parameter_get_name(parameter), | |||
| jackctl_driver_get_name(driver), | |||
| type); | |||
| } | |||
| jackctl_parameter_set_value(parameter, &value); | |||
| } | |||
| void | |||
| jack_controller_settings_set_engine_option( | |||
| struct jack_controller *controller_ptr, | |||
| const char *option_name, | |||
| const char *option_value) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| int value_int; | |||
| unsigned int value_uint; | |||
| union jackctl_parameter_value value; | |||
| jack_info("setting engine option \"%s\" to value \"%s\"", option_name, option_value); | |||
| if (strcmp(option_name, "driver") == 0) | |||
| { | |||
| if (!jack_controller_select_driver(controller_ptr, option_value)) | |||
| { | |||
| jack_error("unknown driver '%s'", option_value); | |||
| } | |||
| return; | |||
| } | |||
| parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), option_name); | |||
| if (parameter == NULL) | |||
| { | |||
| jack_error( | |||
| "Unknown engine parameter \"%s\"", | |||
| option_name); | |||
| return; | |||
| } | |||
| type = jackctl_parameter_get_type(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| jack_controller_settings_set_sint_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| case JackParamUInt: | |||
| jack_controller_settings_set_uint_option(option_value, &value_uint); | |||
| value.ui = value_uint; | |||
| break; | |||
| case JackParamChar: | |||
| jack_controller_settings_set_char_option(option_value, &value.c); | |||
| break; | |||
| case JackParamString: | |||
| jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); | |||
| break; | |||
| case JackParamBool: | |||
| jack_controller_settings_set_bool_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| default: | |||
| jack_error("Engine parameter \"%s\" is of unknown type %d", | |||
| jackctl_parameter_get_name(parameter), | |||
| type); | |||
| } | |||
| jackctl_parameter_set_value(parameter, &value); | |||
| } | |||
| static | |||
| bool | |||
| jack_controller_settings_save_options( | |||
| void *context, | |||
| const JSList * parameters_list, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| union jackctl_parameter_value value; | |||
| const char * name; | |||
| char value_str[50]; | |||
| while (parameters_list != NULL) | |||
| { | |||
| parameter = (jackctl_parameter_t *)parameters_list->data; | |||
| if (jackctl_parameter_is_set(parameter)) | |||
| { | |||
| type = jackctl_parameter_get_type(parameter); | |||
| value = jackctl_parameter_get_value(parameter); | |||
| name = jackctl_parameter_get_name(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| sprintf(value_str, "%d", (int)value.i); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamUInt: | |||
| sprintf(value_str, "%u", (unsigned int)value.ui); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamChar: | |||
| sprintf(value_str, "%c", (char)value.c); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamString: | |||
| if (!jack_controller_settings_write_option(context, name, value.str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamBool: | |||
| if (!jack_controller_settings_write_option(context, name, value.b ? "true" : "false", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| default: | |||
| jack_error("parameter of unknown type %d", type); | |||
| } | |||
| } | |||
| parameters_list = jack_slist_next(parameters_list); | |||
| } | |||
| return true; | |||
| } | |||
| bool | |||
| jack_controller_settings_save_engine_options( | |||
| void *context, | |||
| struct jack_controller *controller_ptr, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| if (controller_ptr->driver != NULL) | |||
| { | |||
| if (!jack_controller_settings_write_option( | |||
| context, | |||
| "driver", | |||
| jackctl_driver_get_name(controller_ptr->driver), | |||
| dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| return jack_controller_settings_save_options(context, jackctl_server_get_parameters(controller_ptr->server), dbus_call_context_ptr); | |||
| } | |||
| bool | |||
| jack_controller_settings_save_driver_options( | |||
| void *context, | |||
| jackctl_driver_t *driver, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| return jack_controller_settings_save_options(context, jackctl_driver_get_parameters(driver), dbus_call_context_ptr); | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <dbus/dbus.h> | |||
| #include "controller_internal.h" | |||
| void | |||
| jack_controller_settings_set_bool_option( | |||
| const char *value_str, | |||
| int *value_ptr) | |||
| { | |||
| if (strcmp(value_str, "true") == 0) | |||
| { | |||
| *value_ptr = true; | |||
| } | |||
| else if (strcmp(value_str, "false") == 0) | |||
| { | |||
| *value_ptr = false; | |||
| } | |||
| else | |||
| { | |||
| jack_error("ignoring unknown bool value \"%s\"", value_str); | |||
| } | |||
| } | |||
| void | |||
| jack_controller_settings_set_sint_option( | |||
| const char *value_str, | |||
| int *value_ptr) | |||
| { | |||
| *value_ptr = atoi(value_str); | |||
| } | |||
| void | |||
| jack_controller_settings_set_uint_option( | |||
| const char *value_str, | |||
| unsigned int *value_ptr) | |||
| { | |||
| *value_ptr = strtoul(value_str, NULL, 10); | |||
| } | |||
| void | |||
| jack_controller_settings_set_char_option( | |||
| const char *value_str, | |||
| char *value_ptr) | |||
| { | |||
| if (value_str[0] == 0 || value_str[1] != 0) | |||
| { | |||
| jack_error("invalid char option value \"%s\"", value_str); | |||
| return; | |||
| } | |||
| *value_ptr = *value_str; | |||
| } | |||
| void | |||
| jack_controller_settings_set_string_option( | |||
| const char *value_str, | |||
| char *value_ptr, | |||
| size_t max_size) | |||
| { | |||
| size_t size; | |||
| size = strlen(value_str); | |||
| if (size >= max_size) | |||
| { | |||
| jack_error("string option value \"%s\" is too long, max is %u chars (including terminating zero)", value_str, (unsigned int)max_size); | |||
| return; | |||
| } | |||
| strcpy(value_ptr, value_str); | |||
| } | |||
| void | |||
| jack_controller_settings_set_driver_option( | |||
| jackctl_driver_t *driver, | |||
| const char *option_name, | |||
| const char *option_value) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| int value_int; | |||
| unsigned int value_uint; | |||
| union jackctl_parameter_value value; | |||
| jack_info("setting driver option \"%s\" to value \"%s\"", option_name, option_value); | |||
| parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), option_name); | |||
| if (parameter == NULL) | |||
| { | |||
| jack_error( | |||
| "Unknown parameter \"%s\" of driver \"%s\"", | |||
| option_name, | |||
| jackctl_driver_get_name(driver)); | |||
| return; | |||
| } | |||
| type = jackctl_parameter_get_type(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| jack_controller_settings_set_sint_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| case JackParamUInt: | |||
| jack_controller_settings_set_uint_option(option_value, &value_uint); | |||
| value.ui = value_uint; | |||
| break; | |||
| case JackParamChar: | |||
| jack_controller_settings_set_char_option(option_value, &value.c); | |||
| break; | |||
| case JackParamString: | |||
| jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); | |||
| break; | |||
| case JackParamBool: | |||
| jack_controller_settings_set_bool_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| default: | |||
| jack_error("Parameter \"%s\" of driver \"%s\" is of unknown type %d", | |||
| jackctl_parameter_get_name(parameter), | |||
| jackctl_driver_get_name(driver), | |||
| type); | |||
| } | |||
| jackctl_parameter_set_value(parameter, &value); | |||
| } | |||
| void | |||
| jack_controller_settings_set_engine_option( | |||
| struct jack_controller *controller_ptr, | |||
| const char *option_name, | |||
| const char *option_value) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| int value_int; | |||
| unsigned int value_uint; | |||
| union jackctl_parameter_value value; | |||
| jack_info("setting engine option \"%s\" to value \"%s\"", option_name, option_value); | |||
| if (strcmp(option_name, "driver") == 0) | |||
| { | |||
| if (!jack_controller_select_driver(controller_ptr, option_value)) | |||
| { | |||
| jack_error("unknown driver '%s'", option_value); | |||
| } | |||
| return; | |||
| } | |||
| parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), option_name); | |||
| if (parameter == NULL) | |||
| { | |||
| jack_error( | |||
| "Unknown engine parameter \"%s\"", | |||
| option_name); | |||
| return; | |||
| } | |||
| type = jackctl_parameter_get_type(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| jack_controller_settings_set_sint_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| case JackParamUInt: | |||
| jack_controller_settings_set_uint_option(option_value, &value_uint); | |||
| value.ui = value_uint; | |||
| break; | |||
| case JackParamChar: | |||
| jack_controller_settings_set_char_option(option_value, &value.c); | |||
| break; | |||
| case JackParamString: | |||
| jack_controller_settings_set_string_option(option_value, value.str, sizeof(value.str)); | |||
| break; | |||
| case JackParamBool: | |||
| jack_controller_settings_set_bool_option(option_value, &value_int); | |||
| value.i = value_int; | |||
| break; | |||
| default: | |||
| jack_error("Engine parameter \"%s\" is of unknown type %d", | |||
| jackctl_parameter_get_name(parameter), | |||
| type); | |||
| } | |||
| jackctl_parameter_set_value(parameter, &value); | |||
| } | |||
| static | |||
| bool | |||
| jack_controller_settings_save_options( | |||
| void *context, | |||
| const JSList * parameters_list, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| jackctl_parameter_t *parameter; | |||
| jackctl_param_type_t type; | |||
| union jackctl_parameter_value value; | |||
| const char * name; | |||
| char value_str[50]; | |||
| while (parameters_list != NULL) | |||
| { | |||
| parameter = (jackctl_parameter_t *)parameters_list->data; | |||
| if (jackctl_parameter_is_set(parameter)) | |||
| { | |||
| type = jackctl_parameter_get_type(parameter); | |||
| value = jackctl_parameter_get_value(parameter); | |||
| name = jackctl_parameter_get_name(parameter); | |||
| switch (type) | |||
| { | |||
| case JackParamInt: | |||
| sprintf(value_str, "%d", (int)value.i); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamUInt: | |||
| sprintf(value_str, "%u", (unsigned int)value.ui); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamChar: | |||
| sprintf(value_str, "%c", (char)value.c); | |||
| if (!jack_controller_settings_write_option(context, name, value_str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamString: | |||
| if (!jack_controller_settings_write_option(context, name, value.str, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| case JackParamBool: | |||
| if (!jack_controller_settings_write_option(context, name, value.b ? "true" : "false", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| break; | |||
| default: | |||
| jack_error("parameter of unknown type %d", type); | |||
| } | |||
| } | |||
| parameters_list = jack_slist_next(parameters_list); | |||
| } | |||
| return true; | |||
| } | |||
| bool | |||
| jack_controller_settings_save_engine_options( | |||
| void *context, | |||
| struct jack_controller *controller_ptr, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| if (controller_ptr->driver != NULL) | |||
| { | |||
| if (!jack_controller_settings_write_option( | |||
| context, | |||
| "driver", | |||
| jackctl_driver_get_name(controller_ptr->driver), | |||
| dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| return jack_controller_settings_save_options(context, jackctl_server_get_parameters(controller_ptr->server), dbus_call_context_ptr); | |||
| } | |||
| bool | |||
| jack_controller_settings_save_driver_options( | |||
| void *context, | |||
| jackctl_driver_t *driver, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| return jack_controller_settings_save_options(context, jackctl_driver_get_parameters(driver), dbus_call_context_ptr); | |||
| } | |||
| @@ -315,954 +315,3 @@ exit_free_filename: | |||
| exit: | |||
| return; | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <expat.h> | |||
| #include <dbus/dbus.h> | |||
| #include "controller_internal.h" | |||
| #include "jackdbus.h" | |||
| bool | |||
| jack_controller_settings_init() | |||
| { | |||
| return true; | |||
| } | |||
| void | |||
| jack_controller_settings_uninit() | |||
| { | |||
| } | |||
| #define PARSE_CONTEXT_ROOT 0 | |||
| #define PARSE_CONTEXT_JACK 1 | |||
| #define PARSE_CONTEXT_ENGINE 1 | |||
| #define PARSE_CONTEXT_DRIVERS 2 | |||
| #define PARSE_CONTEXT_DRIVER 3 | |||
| #define PARSE_CONTEXT_OPTION 4 | |||
| #define MAX_STACK_DEPTH 10 | |||
| struct parse_context | |||
| { | |||
| struct jack_controller *controller_ptr; | |||
| XML_Bool error; | |||
| unsigned int element[MAX_STACK_DEPTH]; | |||
| signed int depth; | |||
| jackctl_driver_t *driver; | |||
| char option[JACK_PARAM_STRING_MAX+1]; | |||
| int option_used; | |||
| char *name; | |||
| }; | |||
| #define context_ptr ((struct parse_context *)data) | |||
| void | |||
| jack_controller_settings_callback_chrdata(void *data, const XML_Char *s, int len) | |||
| { | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) | |||
| { | |||
| if (context_ptr->option_used + len >= JACK_PARAM_STRING_MAX) | |||
| { | |||
| jack_error("xml parse max char data length reached"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| memcpy(context_ptr->option + context_ptr->option_used, s, len); | |||
| context_ptr->option_used += len; | |||
| } | |||
| } | |||
| void | |||
| jack_controller_settings_callback_elstart(void *data, const char *el, const char **attr) | |||
| { | |||
| jackctl_driver_t *driver; | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| if (context_ptr->depth + 1 >= MAX_STACK_DEPTH) | |||
| { | |||
| jack_error("xml parse max stack depth reached"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| if (strcmp(el, "jack") == 0) | |||
| { | |||
| //jack_info("<jack>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_JACK; | |||
| return; | |||
| } | |||
| if (strcmp(el, "engine") == 0) | |||
| { | |||
| //jack_info("<engine>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ENGINE; | |||
| return; | |||
| } | |||
| if (strcmp(el, "drivers") == 0) | |||
| { | |||
| //jack_info("<drivers>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVERS; | |||
| return; | |||
| } | |||
| if (strcmp(el, "driver") == 0) | |||
| { | |||
| if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) | |||
| { | |||
| jack_error("<driver> XML element must contain exactly one attribute, named \"name\""); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| //jack_info("<driver>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVER; | |||
| driver = jack_controller_find_driver(context_ptr->controller_ptr->server, attr[1]); | |||
| if (driver == NULL) | |||
| { | |||
| jack_error("ignoring settings for unknown driver \"%s\"", attr[1]); | |||
| } | |||
| else | |||
| { | |||
| jack_info("setting for driver \"%s\" found", attr[1]); | |||
| } | |||
| context_ptr->driver = driver; | |||
| return; | |||
| } | |||
| if (strcmp(el, "option") == 0) | |||
| { | |||
| //jack_info("<option>"); | |||
| if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) | |||
| { | |||
| jack_error("<option> XML element must contain exactly one attribute, named \"name\""); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| context_ptr->name = strdup(attr[1]); | |||
| if (context_ptr->name == NULL) | |||
| { | |||
| jack_error("strdup() failed"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_OPTION; | |||
| context_ptr->option_used = 0; | |||
| return; | |||
| } | |||
| jack_error("unknown element \"%s\"", el); | |||
| context_ptr->error = XML_TRUE; | |||
| } | |||
| void | |||
| jack_controller_settings_callback_elend(void *data, const char *el) | |||
| { | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| //jack_info("element end (depth = %d, element = %u)", context_ptr->depth, context_ptr->element[context_ptr->depth]); | |||
| if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) | |||
| { | |||
| context_ptr->option[context_ptr->option_used] = 0; | |||
| if (context_ptr->depth == 2 && | |||
| context_ptr->element[0] == PARSE_CONTEXT_JACK && | |||
| context_ptr->element[1] == PARSE_CONTEXT_ENGINE) | |||
| { | |||
| jack_controller_settings_set_engine_option(context_ptr->controller_ptr, context_ptr->name, context_ptr->option); | |||
| } | |||
| if (context_ptr->depth == 3 && | |||
| context_ptr->element[0] == PARSE_CONTEXT_JACK && | |||
| context_ptr->element[1] == PARSE_CONTEXT_DRIVERS && | |||
| context_ptr->element[2] == PARSE_CONTEXT_DRIVER && | |||
| context_ptr->driver != NULL) | |||
| { | |||
| jack_controller_settings_set_driver_option(context_ptr->driver, context_ptr->name, context_ptr->option); | |||
| } | |||
| } | |||
| context_ptr->depth--; | |||
| if (context_ptr->name != NULL) | |||
| { | |||
| free(context_ptr->name); | |||
| context_ptr->name = NULL; | |||
| } | |||
| } | |||
| #undef context_ptr | |||
| void | |||
| jack_controller_settings_load( | |||
| struct jack_controller * controller_ptr) | |||
| { | |||
| XML_Parser parser; | |||
| int bytes_read; | |||
| void *buffer; | |||
| char *filename; | |||
| size_t conf_len; | |||
| struct stat st; | |||
| int fd; | |||
| enum XML_Status xmls; | |||
| struct parse_context context; | |||
| conf_len = strlen(JACKDBUS_CONF); | |||
| filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); | |||
| if (filename == NULL) | |||
| { | |||
| jack_error("Out of memory."); | |||
| goto exit; | |||
| } | |||
| memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); | |||
| memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); | |||
| filename[g_jackdbus_config_dir_len + conf_len] = 0; | |||
| jack_info("Loading settings from \"%s\" using %s ...", filename, XML_ExpatVersion()); | |||
| if (stat(filename, &st) != 0) | |||
| { | |||
| jack_error("failed to stat \"%s\", error is %d (%s)", filename, errno, strerror(errno)); | |||
| } | |||
| fd = open(filename, O_RDONLY); | |||
| if (fd == -1) | |||
| { | |||
| jack_error("open() failed to open conf filename."); | |||
| goto exit_free_filename; | |||
| } | |||
| parser = XML_ParserCreate(NULL); | |||
| if (parser == NULL) | |||
| { | |||
| jack_error("XML_ParserCreate() failed to create parser object."); | |||
| goto exit_close_file; | |||
| } | |||
| //jack_info("conf file size is %llu bytes", (unsigned long long)st.st_size); | |||
| /* we are expecting that conf file has small enough size to fit in memory */ | |||
| buffer = XML_GetBuffer(parser, st.st_size); | |||
| if (buffer == NULL) | |||
| { | |||
| jack_error("XML_GetBuffer() failed."); | |||
| goto exit_free_parser; | |||
| } | |||
| bytes_read = read(fd, buffer, st.st_size); | |||
| if (bytes_read != st.st_size) | |||
| { | |||
| jack_error("read() returned unexpected result."); | |||
| goto exit_free_parser; | |||
| } | |||
| context.controller_ptr = controller_ptr; | |||
| context.error = XML_FALSE; | |||
| context.depth = -1; | |||
| context.name = NULL; | |||
| XML_SetElementHandler(parser, jack_controller_settings_callback_elstart, jack_controller_settings_callback_elend); | |||
| XML_SetCharacterDataHandler(parser, jack_controller_settings_callback_chrdata); | |||
| XML_SetUserData(parser, &context); | |||
| xmls = XML_ParseBuffer(parser, bytes_read, XML_TRUE); | |||
| if (xmls == XML_STATUS_ERROR) | |||
| { | |||
| jack_error("XML_ParseBuffer() failed."); | |||
| goto exit_free_parser; | |||
| } | |||
| exit_free_parser: | |||
| XML_ParserFree(parser); | |||
| exit_close_file: | |||
| close(fd); | |||
| exit_free_filename: | |||
| free(filename); | |||
| exit: | |||
| return; | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <expat.h> | |||
| #include <dbus/dbus.h> | |||
| #include "controller_internal.h" | |||
| #include "jackdbus.h" | |||
| bool | |||
| jack_controller_settings_init() | |||
| { | |||
| return true; | |||
| } | |||
| void | |||
| jack_controller_settings_uninit() | |||
| { | |||
| } | |||
| #define PARSE_CONTEXT_ROOT 0 | |||
| #define PARSE_CONTEXT_JACK 1 | |||
| #define PARSE_CONTEXT_ENGINE 1 | |||
| #define PARSE_CONTEXT_DRIVERS 2 | |||
| #define PARSE_CONTEXT_DRIVER 3 | |||
| #define PARSE_CONTEXT_OPTION 4 | |||
| #define MAX_STACK_DEPTH 10 | |||
| struct parse_context | |||
| { | |||
| struct jack_controller *controller_ptr; | |||
| XML_Bool error; | |||
| unsigned int element[MAX_STACK_DEPTH]; | |||
| signed int depth; | |||
| jackctl_driver_t *driver; | |||
| char option[JACK_PARAM_STRING_MAX+1]; | |||
| int option_used; | |||
| char *name; | |||
| }; | |||
| #define context_ptr ((struct parse_context *)data) | |||
| void | |||
| jack_controller_settings_callback_chrdata(void *data, const XML_Char *s, int len) | |||
| { | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) | |||
| { | |||
| if (context_ptr->option_used + len >= JACK_PARAM_STRING_MAX) | |||
| { | |||
| jack_error("xml parse max char data length reached"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| memcpy(context_ptr->option + context_ptr->option_used, s, len); | |||
| context_ptr->option_used += len; | |||
| } | |||
| } | |||
| void | |||
| jack_controller_settings_callback_elstart(void *data, const char *el, const char **attr) | |||
| { | |||
| jackctl_driver_t *driver; | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| if (context_ptr->depth + 1 >= MAX_STACK_DEPTH) | |||
| { | |||
| jack_error("xml parse max stack depth reached"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| if (strcmp(el, "jack") == 0) | |||
| { | |||
| //jack_info("<jack>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_JACK; | |||
| return; | |||
| } | |||
| if (strcmp(el, "engine") == 0) | |||
| { | |||
| //jack_info("<engine>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ENGINE; | |||
| return; | |||
| } | |||
| if (strcmp(el, "drivers") == 0) | |||
| { | |||
| //jack_info("<drivers>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVERS; | |||
| return; | |||
| } | |||
| if (strcmp(el, "driver") == 0) | |||
| { | |||
| if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) | |||
| { | |||
| jack_error("<driver> XML element must contain exactly one attribute, named \"name\""); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| //jack_info("<driver>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVER; | |||
| driver = jack_controller_find_driver(context_ptr->controller_ptr->server, attr[1]); | |||
| if (driver == NULL) | |||
| { | |||
| jack_error("ignoring settings for unknown driver \"%s\"", attr[1]); | |||
| } | |||
| else | |||
| { | |||
| jack_info("setting for driver \"%s\" found", attr[1]); | |||
| } | |||
| context_ptr->driver = driver; | |||
| return; | |||
| } | |||
| if (strcmp(el, "option") == 0) | |||
| { | |||
| //jack_info("<option>"); | |||
| if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) | |||
| { | |||
| jack_error("<option> XML element must contain exactly one attribute, named \"name\""); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| context_ptr->name = strdup(attr[1]); | |||
| if (context_ptr->name == NULL) | |||
| { | |||
| jack_error("strdup() failed"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_OPTION; | |||
| context_ptr->option_used = 0; | |||
| return; | |||
| } | |||
| jack_error("unknown element \"%s\"", el); | |||
| context_ptr->error = XML_TRUE; | |||
| } | |||
| void | |||
| jack_controller_settings_callback_elend(void *data, const char *el) | |||
| { | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| //jack_info("element end (depth = %d, element = %u)", context_ptr->depth, context_ptr->element[context_ptr->depth]); | |||
| if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) | |||
| { | |||
| context_ptr->option[context_ptr->option_used] = 0; | |||
| if (context_ptr->depth == 2 && | |||
| context_ptr->element[0] == PARSE_CONTEXT_JACK && | |||
| context_ptr->element[1] == PARSE_CONTEXT_ENGINE) | |||
| { | |||
| jack_controller_settings_set_engine_option(context_ptr->controller_ptr, context_ptr->name, context_ptr->option); | |||
| } | |||
| if (context_ptr->depth == 3 && | |||
| context_ptr->element[0] == PARSE_CONTEXT_JACK && | |||
| context_ptr->element[1] == PARSE_CONTEXT_DRIVERS && | |||
| context_ptr->element[2] == PARSE_CONTEXT_DRIVER && | |||
| context_ptr->driver != NULL) | |||
| { | |||
| jack_controller_settings_set_driver_option(context_ptr->driver, context_ptr->name, context_ptr->option); | |||
| } | |||
| } | |||
| context_ptr->depth--; | |||
| if (context_ptr->name != NULL) | |||
| { | |||
| free(context_ptr->name); | |||
| context_ptr->name = NULL; | |||
| } | |||
| } | |||
| #undef context_ptr | |||
| void | |||
| jack_controller_settings_load( | |||
| struct jack_controller * controller_ptr) | |||
| { | |||
| XML_Parser parser; | |||
| int bytes_read; | |||
| void *buffer; | |||
| char *filename; | |||
| size_t conf_len; | |||
| struct stat st; | |||
| int fd; | |||
| enum XML_Status xmls; | |||
| struct parse_context context; | |||
| conf_len = strlen(JACKDBUS_CONF); | |||
| filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); | |||
| if (filename == NULL) | |||
| { | |||
| jack_error("Out of memory."); | |||
| goto exit; | |||
| } | |||
| memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); | |||
| memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); | |||
| filename[g_jackdbus_config_dir_len + conf_len] = 0; | |||
| jack_info("Loading settings from \"%s\" using %s ...", filename, XML_ExpatVersion()); | |||
| if (stat(filename, &st) != 0) | |||
| { | |||
| jack_error("failed to stat \"%s\", error is %d (%s)", filename, errno, strerror(errno)); | |||
| } | |||
| fd = open(filename, O_RDONLY); | |||
| if (fd == -1) | |||
| { | |||
| jack_error("open() failed to open conf filename."); | |||
| goto exit_free_filename; | |||
| } | |||
| parser = XML_ParserCreate(NULL); | |||
| if (parser == NULL) | |||
| { | |||
| jack_error("XML_ParserCreate() failed to create parser object."); | |||
| goto exit_close_file; | |||
| } | |||
| //jack_info("conf file size is %llu bytes", (unsigned long long)st.st_size); | |||
| /* we are expecting that conf file has small enough size to fit in memory */ | |||
| buffer = XML_GetBuffer(parser, st.st_size); | |||
| if (buffer == NULL) | |||
| { | |||
| jack_error("XML_GetBuffer() failed."); | |||
| goto exit_free_parser; | |||
| } | |||
| bytes_read = read(fd, buffer, st.st_size); | |||
| if (bytes_read != st.st_size) | |||
| { | |||
| jack_error("read() returned unexpected result."); | |||
| goto exit_free_parser; | |||
| } | |||
| context.controller_ptr = controller_ptr; | |||
| context.error = XML_FALSE; | |||
| context.depth = -1; | |||
| context.name = NULL; | |||
| XML_SetElementHandler(parser, jack_controller_settings_callback_elstart, jack_controller_settings_callback_elend); | |||
| XML_SetCharacterDataHandler(parser, jack_controller_settings_callback_chrdata); | |||
| XML_SetUserData(parser, &context); | |||
| xmls = XML_ParseBuffer(parser, bytes_read, XML_TRUE); | |||
| if (xmls == XML_STATUS_ERROR) | |||
| { | |||
| jack_error("XML_ParseBuffer() failed."); | |||
| goto exit_free_parser; | |||
| } | |||
| exit_free_parser: | |||
| XML_ParserFree(parser); | |||
| exit_close_file: | |||
| close(fd); | |||
| exit_free_filename: | |||
| free(filename); | |||
| exit: | |||
| return; | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <expat.h> | |||
| #include <dbus/dbus.h> | |||
| #include "controller_internal.h" | |||
| #include "jackdbus.h" | |||
| bool | |||
| jack_controller_settings_init() | |||
| { | |||
| return true; | |||
| } | |||
| void | |||
| jack_controller_settings_uninit() | |||
| { | |||
| } | |||
| #define PARSE_CONTEXT_ROOT 0 | |||
| #define PARSE_CONTEXT_JACK 1 | |||
| #define PARSE_CONTEXT_ENGINE 1 | |||
| #define PARSE_CONTEXT_DRIVERS 2 | |||
| #define PARSE_CONTEXT_DRIVER 3 | |||
| #define PARSE_CONTEXT_OPTION 4 | |||
| #define MAX_STACK_DEPTH 10 | |||
| struct parse_context | |||
| { | |||
| struct jack_controller *controller_ptr; | |||
| XML_Bool error; | |||
| unsigned int element[MAX_STACK_DEPTH]; | |||
| signed int depth; | |||
| jackctl_driver_t *driver; | |||
| char option[JACK_PARAM_STRING_MAX+1]; | |||
| int option_used; | |||
| char *name; | |||
| }; | |||
| #define context_ptr ((struct parse_context *)data) | |||
| void | |||
| jack_controller_settings_callback_chrdata(void *data, const XML_Char *s, int len) | |||
| { | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) | |||
| { | |||
| if (context_ptr->option_used + len >= JACK_PARAM_STRING_MAX) | |||
| { | |||
| jack_error("xml parse max char data length reached"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| memcpy(context_ptr->option + context_ptr->option_used, s, len); | |||
| context_ptr->option_used += len; | |||
| } | |||
| } | |||
| void | |||
| jack_controller_settings_callback_elstart(void *data, const char *el, const char **attr) | |||
| { | |||
| jackctl_driver_t *driver; | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| if (context_ptr->depth + 1 >= MAX_STACK_DEPTH) | |||
| { | |||
| jack_error("xml parse max stack depth reached"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| if (strcmp(el, "jack") == 0) | |||
| { | |||
| //jack_info("<jack>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_JACK; | |||
| return; | |||
| } | |||
| if (strcmp(el, "engine") == 0) | |||
| { | |||
| //jack_info("<engine>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_ENGINE; | |||
| return; | |||
| } | |||
| if (strcmp(el, "drivers") == 0) | |||
| { | |||
| //jack_info("<drivers>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVERS; | |||
| return; | |||
| } | |||
| if (strcmp(el, "driver") == 0) | |||
| { | |||
| if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) | |||
| { | |||
| jack_error("<driver> XML element must contain exactly one attribute, named \"name\""); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| //jack_info("<driver>"); | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DRIVER; | |||
| driver = jack_controller_find_driver(context_ptr->controller_ptr->server, attr[1]); | |||
| if (driver == NULL) | |||
| { | |||
| jack_error("ignoring settings for unknown driver \"%s\"", attr[1]); | |||
| } | |||
| else | |||
| { | |||
| jack_info("setting for driver \"%s\" found", attr[1]); | |||
| } | |||
| context_ptr->driver = driver; | |||
| return; | |||
| } | |||
| if (strcmp(el, "option") == 0) | |||
| { | |||
| //jack_info("<option>"); | |||
| if ((attr[0] == NULL || attr[2] != NULL) || strcmp(attr[0], "name") != 0) | |||
| { | |||
| jack_error("<option> XML element must contain exactly one attribute, named \"name\""); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| context_ptr->name = strdup(attr[1]); | |||
| if (context_ptr->name == NULL) | |||
| { | |||
| jack_error("strdup() failed"); | |||
| context_ptr->error = XML_TRUE; | |||
| return; | |||
| } | |||
| context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_OPTION; | |||
| context_ptr->option_used = 0; | |||
| return; | |||
| } | |||
| jack_error("unknown element \"%s\"", el); | |||
| context_ptr->error = XML_TRUE; | |||
| } | |||
| void | |||
| jack_controller_settings_callback_elend(void *data, const char *el) | |||
| { | |||
| if (context_ptr->error) | |||
| { | |||
| return; | |||
| } | |||
| //jack_info("element end (depth = %d, element = %u)", context_ptr->depth, context_ptr->element[context_ptr->depth]); | |||
| if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_OPTION) | |||
| { | |||
| context_ptr->option[context_ptr->option_used] = 0; | |||
| if (context_ptr->depth == 2 && | |||
| context_ptr->element[0] == PARSE_CONTEXT_JACK && | |||
| context_ptr->element[1] == PARSE_CONTEXT_ENGINE) | |||
| { | |||
| jack_controller_settings_set_engine_option(context_ptr->controller_ptr, context_ptr->name, context_ptr->option); | |||
| } | |||
| if (context_ptr->depth == 3 && | |||
| context_ptr->element[0] == PARSE_CONTEXT_JACK && | |||
| context_ptr->element[1] == PARSE_CONTEXT_DRIVERS && | |||
| context_ptr->element[2] == PARSE_CONTEXT_DRIVER && | |||
| context_ptr->driver != NULL) | |||
| { | |||
| jack_controller_settings_set_driver_option(context_ptr->driver, context_ptr->name, context_ptr->option); | |||
| } | |||
| } | |||
| context_ptr->depth--; | |||
| if (context_ptr->name != NULL) | |||
| { | |||
| free(context_ptr->name); | |||
| context_ptr->name = NULL; | |||
| } | |||
| } | |||
| #undef context_ptr | |||
| void | |||
| jack_controller_settings_load( | |||
| struct jack_controller * controller_ptr) | |||
| { | |||
| XML_Parser parser; | |||
| int bytes_read; | |||
| void *buffer; | |||
| char *filename; | |||
| size_t conf_len; | |||
| struct stat st; | |||
| int fd; | |||
| enum XML_Status xmls; | |||
| struct parse_context context; | |||
| conf_len = strlen(JACKDBUS_CONF); | |||
| filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); | |||
| if (filename == NULL) | |||
| { | |||
| jack_error("Out of memory."); | |||
| goto exit; | |||
| } | |||
| memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); | |||
| memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); | |||
| filename[g_jackdbus_config_dir_len + conf_len] = 0; | |||
| jack_info("Loading settings from \"%s\" using %s ...", filename, XML_ExpatVersion()); | |||
| if (stat(filename, &st) != 0) | |||
| { | |||
| jack_error("failed to stat \"%s\", error is %d (%s)", filename, errno, strerror(errno)); | |||
| } | |||
| fd = open(filename, O_RDONLY); | |||
| if (fd == -1) | |||
| { | |||
| jack_error("open() failed to open conf filename."); | |||
| goto exit_free_filename; | |||
| } | |||
| parser = XML_ParserCreate(NULL); | |||
| if (parser == NULL) | |||
| { | |||
| jack_error("XML_ParserCreate() failed to create parser object."); | |||
| goto exit_close_file; | |||
| } | |||
| //jack_info("conf file size is %llu bytes", (unsigned long long)st.st_size); | |||
| /* we are expecting that conf file has small enough size to fit in memory */ | |||
| buffer = XML_GetBuffer(parser, st.st_size); | |||
| if (buffer == NULL) | |||
| { | |||
| jack_error("XML_GetBuffer() failed."); | |||
| goto exit_free_parser; | |||
| } | |||
| bytes_read = read(fd, buffer, st.st_size); | |||
| if (bytes_read != st.st_size) | |||
| { | |||
| jack_error("read() returned unexpected result."); | |||
| goto exit_free_parser; | |||
| } | |||
| context.controller_ptr = controller_ptr; | |||
| context.error = XML_FALSE; | |||
| context.depth = -1; | |||
| context.name = NULL; | |||
| XML_SetElementHandler(parser, jack_controller_settings_callback_elstart, jack_controller_settings_callback_elend); | |||
| XML_SetCharacterDataHandler(parser, jack_controller_settings_callback_chrdata); | |||
| XML_SetUserData(parser, &context); | |||
| xmls = XML_ParseBuffer(parser, bytes_read, XML_TRUE); | |||
| if (xmls == XML_STATUS_ERROR) | |||
| { | |||
| jack_error("XML_ParseBuffer() failed."); | |||
| goto exit_free_parser; | |||
| } | |||
| exit_free_parser: | |||
| XML_ParserFree(parser); | |||
| exit_close_file: | |||
| close(fd); | |||
| exit_free_filename: | |||
| free(filename); | |||
| exit: | |||
| return; | |||
| } | |||
| @@ -268,813 +268,3 @@ jack_controller_settings_save_auto( | |||
| { | |||
| jack_controller_settings_save(controller_ptr, NULL); | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <dbus/dbus.h> | |||
| #include <time.h> | |||
| #include "controller_internal.h" | |||
| #include "jackdbus.h" | |||
| bool | |||
| jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr) | |||
| { | |||
| size_t len; | |||
| len = strlen(string); | |||
| if (write(fd, string, len) != len) | |||
| { | |||
| jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file."); | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| struct save_context | |||
| { | |||
| int fd; | |||
| const char *indent; | |||
| }; | |||
| #define save_context_ptr ((struct save_context *)context) | |||
| #define fd (save_context_ptr->fd) | |||
| bool | |||
| jack_controller_settings_write_option( | |||
| void *context, | |||
| const char *name, | |||
| const char *content, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| if (!jack_controller_settings_write_string(fd, save_context_ptr->indent, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<option name=\"", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, name, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "\">", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, content, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "</option>\n", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| #undef fd | |||
| bool | |||
| jack_controller_settings_save( | |||
| struct jack_controller * controller_ptr, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| char *filename; | |||
| size_t conf_len; | |||
| int fd; | |||
| bool ret; | |||
| time_t timestamp; | |||
| char timestamp_str[26]; | |||
| struct save_context context; | |||
| const JSList * node_ptr; | |||
| jackctl_driver_t *driver; | |||
| time(×tamp); | |||
| ctime_r(×tamp, timestamp_str); | |||
| timestamp_str[24] = 0; | |||
| ret = false; | |||
| conf_len = strlen(JACKDBUS_CONF); | |||
| filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); | |||
| if (filename == NULL) | |||
| { | |||
| jack_error("Out of memory."); | |||
| goto exit; | |||
| } | |||
| memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); | |||
| memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); | |||
| filename[g_jackdbus_config_dir_len + conf_len] = 0; | |||
| jack_info("Saving settings to \"%s\" ...", filename); | |||
| fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | |||
| if (fd == -1) | |||
| { | |||
| jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno)); | |||
| goto exit_free_filename; | |||
| } | |||
| context.fd = fd; | |||
| if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| context.indent = " "; | |||
| if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| node_ptr = jackctl_server_get_drivers_list(controller_ptr->server); | |||
| while (node_ptr != NULL) | |||
| { | |||
| driver = (jackctl_driver_t *)node_ptr->data; | |||
| if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| context.indent = " "; | |||
| if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| node_ptr = jack_slist_next(node_ptr); | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| ret = true; | |||
| exit_close: | |||
| close(fd); | |||
| exit_free_filename: | |||
| free(filename); | |||
| exit: | |||
| return ret; | |||
| } | |||
| void | |||
| jack_controller_settings_save_auto( | |||
| struct jack_controller * controller_ptr) | |||
| { | |||
| jack_controller_settings_save(controller_ptr, NULL); | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <dbus/dbus.h> | |||
| #include <time.h> | |||
| #include "controller_internal.h" | |||
| #include "jackdbus.h" | |||
| bool | |||
| jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr) | |||
| { | |||
| size_t len; | |||
| len = strlen(string); | |||
| if (write(fd, string, len) != len) | |||
| { | |||
| jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file."); | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| struct save_context | |||
| { | |||
| int fd; | |||
| const char *indent; | |||
| }; | |||
| #define save_context_ptr ((struct save_context *)context) | |||
| #define fd (save_context_ptr->fd) | |||
| bool | |||
| jack_controller_settings_write_option( | |||
| void *context, | |||
| const char *name, | |||
| const char *content, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| if (!jack_controller_settings_write_string(fd, save_context_ptr->indent, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<option name=\"", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, name, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "\">", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, content, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "</option>\n", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| #undef fd | |||
| bool | |||
| jack_controller_settings_save( | |||
| struct jack_controller * controller_ptr, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| char *filename; | |||
| size_t conf_len; | |||
| int fd; | |||
| bool ret; | |||
| time_t timestamp; | |||
| char timestamp_str[26]; | |||
| struct save_context context; | |||
| const JSList * node_ptr; | |||
| jackctl_driver_t *driver; | |||
| time(×tamp); | |||
| ctime_r(×tamp, timestamp_str); | |||
| timestamp_str[24] = 0; | |||
| ret = false; | |||
| conf_len = strlen(JACKDBUS_CONF); | |||
| filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); | |||
| if (filename == NULL) | |||
| { | |||
| jack_error("Out of memory."); | |||
| goto exit; | |||
| } | |||
| memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); | |||
| memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); | |||
| filename[g_jackdbus_config_dir_len + conf_len] = 0; | |||
| jack_info("Saving settings to \"%s\" ...", filename); | |||
| fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | |||
| if (fd == -1) | |||
| { | |||
| jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno)); | |||
| goto exit_free_filename; | |||
| } | |||
| context.fd = fd; | |||
| if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| context.indent = " "; | |||
| if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| node_ptr = jackctl_server_get_drivers_list(controller_ptr->server); | |||
| while (node_ptr != NULL) | |||
| { | |||
| driver = (jackctl_driver_t *)node_ptr->data; | |||
| if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| context.indent = " "; | |||
| if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| node_ptr = jack_slist_next(node_ptr); | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| ret = true; | |||
| exit_close: | |||
| close(fd); | |||
| exit_free_filename: | |||
| free(filename); | |||
| exit: | |||
| return ret; | |||
| } | |||
| void | |||
| jack_controller_settings_save_auto( | |||
| struct jack_controller * controller_ptr) | |||
| { | |||
| jack_controller_settings_save(controller_ptr, NULL); | |||
| } | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| Copyright (C) 2007,2008 Nedko Arnaudov | |||
| 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. | |||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <errno.h> | |||
| #include <string.h> | |||
| #include <dbus/dbus.h> | |||
| #include <time.h> | |||
| #include "controller_internal.h" | |||
| #include "jackdbus.h" | |||
| bool | |||
| jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr) | |||
| { | |||
| size_t len; | |||
| len = strlen(string); | |||
| if (write(fd, string, len) != len) | |||
| { | |||
| jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file."); | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| struct save_context | |||
| { | |||
| int fd; | |||
| const char *indent; | |||
| }; | |||
| #define save_context_ptr ((struct save_context *)context) | |||
| #define fd (save_context_ptr->fd) | |||
| bool | |||
| jack_controller_settings_write_option( | |||
| void *context, | |||
| const char *name, | |||
| const char *content, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| if (!jack_controller_settings_write_string(fd, save_context_ptr->indent, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<option name=\"", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, name, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "\">", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, content, dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "</option>\n", dbus_call_context_ptr)) | |||
| { | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| #undef fd | |||
| bool | |||
| jack_controller_settings_save( | |||
| struct jack_controller * controller_ptr, | |||
| void *dbus_call_context_ptr) | |||
| { | |||
| char *filename; | |||
| size_t conf_len; | |||
| int fd; | |||
| bool ret; | |||
| time_t timestamp; | |||
| char timestamp_str[26]; | |||
| struct save_context context; | |||
| const JSList * node_ptr; | |||
| jackctl_driver_t *driver; | |||
| time(×tamp); | |||
| ctime_r(×tamp, timestamp_str); | |||
| timestamp_str[24] = 0; | |||
| ret = false; | |||
| conf_len = strlen(JACKDBUS_CONF); | |||
| filename = malloc(g_jackdbus_config_dir_len + conf_len + 1); | |||
| if (filename == NULL) | |||
| { | |||
| jack_error("Out of memory."); | |||
| goto exit; | |||
| } | |||
| memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len); | |||
| memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len); | |||
| filename[g_jackdbus_config_dir_len + conf_len] = 0; | |||
| jack_info("Saving settings to \"%s\" ...", filename); | |||
| fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | |||
| if (fd == -1) | |||
| { | |||
| jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno)); | |||
| goto exit_free_filename; | |||
| } | |||
| context.fd = fd; | |||
| if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| context.indent = " "; | |||
| if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| node_ptr = jackctl_server_get_drivers_list(controller_ptr->server); | |||
| while (node_ptr != NULL) | |||
| { | |||
| driver = (jackctl_driver_t *)node_ptr->data; | |||
| if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| context.indent = " "; | |||
| if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| node_ptr = jack_slist_next(node_ptr); | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr)) | |||
| { | |||
| goto exit_close; | |||
| } | |||
| ret = true; | |||
| exit_close: | |||
| close(fd); | |||
| exit_free_filename: | |||
| free(filename); | |||
| exit: | |||
| return ret; | |||
| } | |||
| void | |||
| jack_controller_settings_save_auto( | |||
| struct jack_controller * controller_ptr) | |||
| { | |||
| jack_controller_settings_save(controller_ptr, NULL); | |||
| } | |||