Merge branch 'master' into port_register_notification_defer
[jack2.git] / dbus / controller_iface_configure.c
blobdfa56703453e17232a86a31fbe0cffe0f794402e
1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
2 /*
3 Copyright (C) 2007,2008 Nedko Arnaudov
4 Copyright (C) 2007-2008 Juuso Alasuutari
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #if defined(HAVE_CONFIG_H)
22 #include "config.h"
23 #endif
25 #include <stdint.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <dbus/dbus.h>
30 #include "jackdbus.h"
31 #include "controller_internal.h"
32 #include "xml.h"
34 #define PTNODE_ENGINE "engine"
35 #define PTNODE_DRIVER "driver"
36 #define PTNODE_DRIVERS "drivers"
37 #define PTNODE_INTERNALS "internals"
39 #define ENGINE_DRIVER_PARAMETER_NAME "driver"
40 #define ENGINE_DRIVER_PARAMETER_TYPE JackParamString
41 #define ENGINE_DRIVER_PARAMETER_SHORT_DESCR "Driver to use"
42 #define ENGINE_DRIVER_PARAMETER_LONG_DESCR ""
44 struct parameter_info
46 unsigned char type;
47 const char * name;
48 const char * short_decr;
49 const char * long_descr;
52 unsigned char jack_controller_dbus_types[JACK_PARAM_MAX] =
54 [JackParamInt] = DBUS_TYPE_INT32,
55 [JackParamUInt] = DBUS_TYPE_UINT32,
56 [JackParamChar] = DBUS_TYPE_BYTE,
57 [JackParamString] = DBUS_TYPE_STRING,
58 [JackParamBool] = DBUS_TYPE_BOOLEAN,
61 const char *jack_controller_dbus_type_signatures[JACK_PARAM_MAX] =
63 [JackParamInt] = DBUS_TYPE_INT32_AS_STRING,
64 [JackParamUInt] = DBUS_TYPE_UINT32_AS_STRING,
65 [JackParamChar] = DBUS_TYPE_BYTE_AS_STRING,
66 [JackParamString] = DBUS_TYPE_STRING_AS_STRING,
67 [JackParamBool] = DBUS_TYPE_BOOLEAN_AS_STRING,
70 #define PARAM_TYPE_JACK_TO_DBUS(_) jack_controller_dbus_types[_]
71 #define PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(_) jack_controller_dbus_type_signatures[_]
73 static
74 bool
75 jack_controller_jack_to_dbus_variant(
76 jackctl_param_type_t type,
77 const union jackctl_parameter_value *value_ptr,
78 message_arg_t *dbusv_ptr)
80 switch (type)
82 case JackParamInt:
83 dbusv_ptr->int32 = (dbus_int32_t)value_ptr->i;
84 return true;
85 case JackParamUInt:
86 dbusv_ptr->uint32 = (dbus_uint32_t)value_ptr->ui;
87 return true;
88 case JackParamChar:
89 dbusv_ptr->byte = value_ptr->c;
90 return true;
91 case JackParamString:
92 dbusv_ptr->string = value_ptr->str;
93 return true;
94 case JackParamBool:
95 dbusv_ptr->boolean = (dbus_bool_t)value_ptr->b;
96 return true;
99 jack_error("Unknown JACK parameter type %i", (int)type);
100 assert(0);
101 return false;
104 static
105 bool
106 jack_controller_dbus_to_jack_variant(
107 int type,
108 const message_arg_t *dbusv_ptr,
109 union jackctl_parameter_value *value_ptr)
111 size_t len;
113 switch (type)
115 case DBUS_TYPE_INT32:
116 value_ptr->i = dbusv_ptr->int32;
117 return true;
118 case DBUS_TYPE_UINT32:
119 value_ptr->ui = dbusv_ptr->uint32;
120 return true;
121 case DBUS_TYPE_BYTE:
122 value_ptr->c = dbusv_ptr->byte;
123 return true;
124 case DBUS_TYPE_STRING:
125 len = strlen(dbusv_ptr->string);
126 if (len > JACK_PARAM_STRING_MAX)
128 jack_error("Parameter string value is too long (%u)", (unsigned int)len);
129 return false;
131 memcpy(value_ptr->str, dbusv_ptr->string, len + 1);
133 return true;
134 case DBUS_TYPE_BOOLEAN:
135 value_ptr->b = dbusv_ptr->boolean;
136 return true;
139 jack_error("Unknown D-Bus parameter type %i", (int)type);
140 return false;
144 * Construct a return message for a Get[Driver|Engine]ParameterValue method call.
146 * The operation can only fail due to lack of memory, in which case
147 * there's no sense in trying to construct an error return. Instead,
148 * call->reply will be set to NULL and handled in send_method_return().
150 static void
151 jack_dbus_construct_method_return_parameter(
152 struct jack_dbus_method_call * call,
153 dbus_bool_t is_set,
154 int type,
155 const char *signature,
156 message_arg_t default_value,
157 message_arg_t value)
159 DBusMessageIter iter;
161 /* Create a new method return message. */
162 call->reply = dbus_message_new_method_return (call->message);
163 if (!call->reply)
165 goto fail;
168 dbus_message_iter_init_append (call->reply, &iter);
170 /* Append the is_set argument. */
171 if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, (const void *) &is_set))
173 goto fail_unref;
176 /* Append the 'default' and 'value' arguments. */
177 if (!jack_dbus_message_append_variant(&iter, type, signature, &default_value))
179 goto fail_unref;
181 if (!jack_dbus_message_append_variant(&iter, type, signature, &value))
183 goto fail_unref;
186 return;
188 fail_unref:
189 dbus_message_unref (call->reply);
190 call->reply = NULL;
192 fail:
193 jack_error ("Ran out of memory trying to construct method return");
196 static
197 bool
198 jack_controller_dbus_get_parameter_address_ex(
199 struct jack_dbus_method_call * call,
200 DBusMessageIter * iter_ptr,
201 const char ** address_array)
203 const char * signature;
204 DBusMessageIter array_iter;
205 int type;
206 int index;
208 if (!dbus_message_iter_init(call->message, iter_ptr))
210 jack_dbus_error(
211 call,
212 JACK_DBUS_ERROR_INVALID_ARGS,
213 "Invalid arguments to method '%s'. No input arguments found.",
214 call->method_name);
215 return false;
218 signature = dbus_message_iter_get_signature(iter_ptr);
219 if (signature == NULL)
221 jack_error("dbus_message_iter_get_signature() failed");
222 return false;
225 if (strcmp(signature, "as") != 0)
227 jack_dbus_error(
228 call,
229 JACK_DBUS_ERROR_INVALID_ARGS,
230 "Invalid arguments to method '%s'. Input arguments signature '%s', must begin with 'as'.",
231 call->method_name,
232 signature);
233 return false;
236 dbus_message_iter_recurse(iter_ptr, &array_iter);
238 index = 0;
239 while ((type = dbus_message_iter_get_arg_type(&array_iter)) != DBUS_TYPE_INVALID)
241 if (index == 3)
243 jack_dbus_error(
244 call,
245 JACK_DBUS_ERROR_INVALID_ARGS,
246 "Invalid arguments to method '%s'. Parameter address array must contain not more than three elements.",
247 call->method_name);
248 return false;
252 if (type != DBUS_TYPE_STRING)
254 jack_dbus_error(
255 call,
256 JACK_DBUS_ERROR_FATAL,
257 "Internal error when parsing parameter address of method '%s'. Address array element type '%c' is not string type.",
258 call->method_name,
259 type);
260 return false;
263 dbus_message_iter_get_basic(&array_iter, address_array + index);
264 //jack_info("address component: '%s'", address_array[index]);
266 dbus_message_iter_next(&array_iter);
267 index++;
270 while (index < 3)
272 address_array[index] = NULL;
273 index++;
276 return true;
279 static
280 bool
281 jack_controller_dbus_get_parameter_address(
282 struct jack_dbus_method_call * call,
283 const char ** address_array)
285 DBusMessageIter iter;
286 bool ret;
288 ret = jack_controller_dbus_get_parameter_address_ex(call, &iter, address_array);
289 if (ret && dbus_message_iter_has_next(&iter))
291 jack_dbus_error(
292 call,
293 JACK_DBUS_ERROR_INVALID_ARGS,
294 "Invalid arguments to method '%s'. Input arguments signature must be 'as'.",
295 call->method_name);
296 return false;
299 return ret;
302 #define controller_ptr ((struct jack_controller *)call->context)
304 static
305 bool
306 jack_controller_fill_parameter_names(
307 struct jack_dbus_method_call * call,
308 DBusMessageIter * iter_ptr,
309 const char * special_first,
310 const JSList * parameters_list)
312 DBusMessageIter array_iter;
313 const char * param_name;
315 if (!dbus_message_iter_open_container(iter_ptr, DBUS_TYPE_ARRAY, "s", &array_iter))
317 return false;
320 if (special_first != NULL)
322 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &special_first))
324 dbus_message_iter_close_container(iter_ptr, &array_iter);
325 return false;
329 /* Append parameter descriptions to the array. */
330 while (parameters_list != NULL)
332 param_name = jackctl_parameter_get_name(parameters_list->data);
333 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &param_name))
335 dbus_message_iter_close_container(iter_ptr, &array_iter);
336 return false;
339 parameters_list = jack_slist_next(parameters_list);
342 return dbus_message_iter_close_container(iter_ptr, &array_iter);
345 static
346 void
347 jack_controller_dbus_read_container(
348 struct jack_dbus_method_call * call)
350 const char * address[3];
351 dbus_bool_t leaf;
352 DBusMessageIter iter;
353 DBusMessageIter array_iter;
354 const char * child_name;
355 unsigned int index;
356 jackctl_internal_t * internal;
357 jackctl_driver_t * driver;
359 //jack_info("jack_controller_dbus_read_container() called");
361 if (!jack_controller_dbus_get_parameter_address(call, address))
363 /* The method call had invalid arguments meaning that
364 * jack_controller_dbus_get_parameter_address() has
365 * constructed an error for us. */
366 return;
369 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
371 /* Create a new method return message. */
372 call->reply = dbus_message_new_method_return(call->message);
373 if (!call->reply)
375 goto oom;
378 dbus_message_iter_init_append(call->reply, &iter);
380 if (address[0] == NULL) /* root node */
382 //jack_info("reading root container");
384 leaf = false;
385 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf))
387 goto oom_unref;
390 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter))
392 goto oom_unref;
395 child_name = PTNODE_ENGINE;
396 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name))
398 goto oom_close_unref;
401 child_name = PTNODE_DRIVER;
402 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name))
404 goto oom_close_unref;
407 child_name = PTNODE_DRIVERS;
408 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name))
410 goto oom_close_unref;
413 child_name = PTNODE_INTERNALS;
414 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &child_name))
416 goto oom_close_unref;
419 dbus_message_iter_close_container(&iter, &array_iter);
421 return;
424 if (address[0] != NULL &&
425 address[1] == NULL &&
426 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
428 //jack_info("reading engine params container");
430 leaf = true;
431 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf))
433 goto oom_unref;
436 if (!jack_controller_fill_parameter_names(
437 call,
438 &iter,
439 ENGINE_DRIVER_PARAMETER_NAME,
440 jackctl_server_get_parameters(controller_ptr->server)))
442 goto oom_unref;
445 return;
448 if (address[0] != NULL &&
449 address[1] == NULL &&
450 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
452 //jack_info("reading current driver params container");
454 leaf = true;
455 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf))
457 goto oom_unref;
460 if (!jack_controller_fill_parameter_names(
461 call,
462 &iter,
463 NULL,
464 jackctl_driver_get_parameters(controller_ptr->driver)))
466 goto oom_unref;
469 return;
472 if (address[0] != NULL &&
473 strcmp(address[0], PTNODE_DRIVERS) == 0)
475 leaf = address[1] != NULL;
476 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf))
478 goto oom_unref;
481 if (!leaf) /* available drivers requested */
483 //jack_info("reading drivers container");
485 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter))
487 goto oom_unref;
490 for (index = 0; index < controller_ptr->drivers_count; index++)
492 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, controller_ptr->driver_names + index))
494 goto oom_close_unref;
498 dbus_message_iter_close_container(&iter, &array_iter);
500 else /* specified driver parameters requested */
502 //jack_info("reading driver '%s' params container", address[1]);
504 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
505 if (driver == NULL)
507 jack_dbus_error(
508 call,
509 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
510 "Unknown driver '%s'",
511 address[1]);
512 return;
515 if (!jack_controller_fill_parameter_names(
516 call,
517 &iter,
518 NULL,
519 jackctl_driver_get_parameters(driver)))
521 goto oom_unref;
525 return;
528 if (address[0] != NULL &&
529 strcmp(address[0], PTNODE_INTERNALS) == 0)
531 leaf = address[1] != NULL;
532 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &leaf))
534 goto oom_unref;
537 if (!leaf) /* available internals requested */
539 //jack_info("reading internals container");
541 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &array_iter))
543 goto oom_unref;
546 for (index = 0; index < controller_ptr->internals_count; index++)
548 if (!dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, controller_ptr->internal_names + index))
550 goto oom_close_unref;
554 dbus_message_iter_close_container(&iter, &array_iter);
556 else /* specified driver parameters requested */
558 //jack_info("reading internal '%s' params container", address[1]);
560 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
561 if (internal == NULL)
563 jack_dbus_error(
564 call,
565 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
566 "Unknown internal '%s'",
567 address[1]);
568 return;
571 if (!jack_controller_fill_parameter_names(
572 call,
573 &iter,
574 NULL,
575 jackctl_internal_get_parameters(internal)))
577 goto oom_unref;
581 return;
584 jack_dbus_error(
585 call,
586 JACK_DBUS_ERROR_INVALID_ARGS,
587 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
588 address[0],
589 address[1],
590 address[2],
591 call->method_name);
593 return;
595 oom_close_unref:
596 dbus_message_iter_close_container(&iter, &array_iter);
598 oom_unref:
599 dbus_message_unref(call->reply);
600 call->reply = NULL;
602 oom:
603 jack_error ("Ran out of memory trying to construct method return");
606 static
607 void
608 jack_controller_get_parameters_info(
609 struct jack_dbus_method_call * call,
610 struct parameter_info * special_parameter_info_ptr,
611 const JSList * parameters_list)
613 DBusMessageIter iter, array_iter, struct_iter;
614 unsigned char type;
615 const char *str;
617 call->reply = dbus_message_new_method_return (call->message);
618 if (!call->reply)
620 goto fail;
623 dbus_message_iter_init_append (call->reply, &iter);
625 /* Open the array. */
626 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ysss)", &array_iter))
628 goto fail_unref;
631 if (special_parameter_info_ptr != NULL)
633 /* Open the struct. */
634 if (!dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
636 goto fail_close_unref;
639 /* Append parameter type. */
640 type = PARAM_TYPE_JACK_TO_DBUS(special_parameter_info_ptr->type);
641 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_BYTE, &type))
643 goto fail_close2_unref;
646 /* Append parameter name. */
647 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &special_parameter_info_ptr->name))
649 goto fail_close2_unref;
652 /* Append parameter short description. */
653 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &special_parameter_info_ptr->short_decr))
655 goto fail_close2_unref;
658 /* Append parameter long description. */
659 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &special_parameter_info_ptr->long_descr))
661 goto fail_close2_unref;
664 /* Close the struct. */
665 if (!dbus_message_iter_close_container (&array_iter, &struct_iter))
667 goto fail_close_unref;
671 /* Append parameter descriptions to the array. */
672 while (parameters_list != NULL)
674 /* Open the struct. */
675 if (!dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
677 goto fail_close_unref;
680 /* Append parameter type. */
681 type = PARAM_TYPE_JACK_TO_DBUS(jackctl_parameter_get_type(parameters_list->data));
682 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_BYTE, &type))
684 goto fail_close2_unref;
687 /* Append parameter name. */
688 str = jackctl_parameter_get_name(parameters_list->data);
689 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &str))
691 goto fail_close2_unref;
694 /* Append parameter short description. */
695 str = jackctl_parameter_get_short_description(parameters_list->data);
696 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &str))
698 goto fail_close2_unref;
701 /* Append parameter long description. */
702 str = jackctl_parameter_get_long_description(parameters_list->data);
703 if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &str))
705 goto fail_close2_unref;
708 /* Close the struct. */
709 if (!dbus_message_iter_close_container (&array_iter, &struct_iter))
711 goto fail_close_unref;
714 parameters_list = jack_slist_next(parameters_list);
717 /* Close the array. */
718 if (!dbus_message_iter_close_container (&iter, &array_iter))
720 goto fail_unref;
723 return;
725 fail_close2_unref:
726 dbus_message_iter_close_container (&iter, &struct_iter);
728 fail_close_unref:
729 dbus_message_iter_close_container (&iter, &array_iter);
731 fail_unref:
732 dbus_message_unref (call->reply);
733 call->reply = NULL;
735 fail:
736 jack_error ("Ran out of memory trying to construct method return");
739 static
740 void
741 jack_controller_dbus_get_parameters_info(
742 struct jack_dbus_method_call * call)
744 const char * address[3];
745 jackctl_internal_t * internal;
746 jackctl_driver_t * driver;
747 struct parameter_info driver_parameter_info;
749 //jack_info("jack_controller_dbus_get_parameters_info() called");
751 if (!jack_controller_dbus_get_parameter_address(call, address))
753 /* The method call had invalid arguments meaning that
754 * jack_controller_dbus_get_parameter_address() has
755 * constructed an error for us. */
756 return;
759 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
761 if (address[0] != NULL &&
762 address[1] == NULL &&
763 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
765 driver_parameter_info.type = ENGINE_DRIVER_PARAMETER_TYPE;
766 driver_parameter_info.name = ENGINE_DRIVER_PARAMETER_NAME;
767 driver_parameter_info.short_decr = ENGINE_DRIVER_PARAMETER_SHORT_DESCR;
768 driver_parameter_info.long_descr = ENGINE_DRIVER_PARAMETER_LONG_DESCR;
770 jack_controller_get_parameters_info(
771 call,
772 &driver_parameter_info,
773 jackctl_server_get_parameters(controller_ptr->server));
775 return;
778 if (address[0] != NULL &&
779 address[1] == NULL &&
780 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
782 jack_controller_get_parameters_info(
783 call,
784 NULL,
785 jackctl_driver_get_parameters(controller_ptr->driver));
787 return;
790 if (address[0] != NULL &&
791 address[1] != NULL &&
792 address[2] == NULL &&
793 strcmp(address[0], PTNODE_DRIVERS) == 0)
795 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
796 if (driver == NULL)
798 jack_dbus_error(
799 call,
800 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
801 "Unknown driver '%s'",
802 address[1]);
803 return;
806 jack_controller_get_parameters_info(
807 call,
808 NULL,
809 jackctl_driver_get_parameters(driver));
811 return;
814 if (address[0] != NULL &&
815 address[1] != NULL &&
816 address[2] == NULL &&
817 strcmp(address[0], PTNODE_INTERNALS) == 0)
819 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
820 if (internal == NULL)
822 jack_dbus_error(
823 call,
824 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
825 "Unknown internal '%s'",
826 address[1]);
827 return;
830 jack_controller_get_parameters_info(
831 call,
832 NULL,
833 jackctl_internal_get_parameters(internal));
835 return;
838 jack_dbus_error(
839 call,
840 JACK_DBUS_ERROR_INVALID_ARGS,
841 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
842 address[0],
843 address[1],
844 address[2],
845 call->method_name);
848 static
849 void
850 jack_controller_get_parameter_info_ex(
851 struct jack_dbus_method_call * call,
852 struct parameter_info * info_ptr)
854 DBusMessageIter iter, struct_iter;
855 unsigned char type;
857 call->reply = dbus_message_new_method_return(call->message);
858 if (!call->reply)
860 goto fail;
863 dbus_message_iter_init_append(call->reply, &iter);
865 /* Open the struct. */
866 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
868 goto fail_unref;
871 /* Append parameter type. */
872 type = PARAM_TYPE_JACK_TO_DBUS(info_ptr->type);
873 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE, &type))
875 goto fail_close_unref;
878 /* Append parameter name. */
879 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &info_ptr->name))
881 goto fail_close_unref;
884 /* Append parameter short description. */
885 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &info_ptr->short_decr))
887 goto fail_close_unref;
890 /* Append parameter long description. */
891 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &info_ptr->long_descr))
893 goto fail_close_unref;
896 /* Close the struct. */
897 if (!dbus_message_iter_close_container(&iter, &struct_iter))
899 goto fail_unref;
902 return;
904 fail_close_unref:
905 dbus_message_iter_close_container(&iter, &struct_iter);
907 fail_unref:
908 dbus_message_unref(call->reply);
909 call->reply = NULL;
911 fail:
912 jack_error("Ran out of memory trying to construct method return");
915 static
916 void
917 jack_controller_get_parameter_info(
918 struct jack_dbus_method_call * call,
919 jackctl_parameter_t * parameter)
921 struct parameter_info info;
923 info.type = jackctl_parameter_get_type(parameter);
924 info.name = jackctl_parameter_get_name(parameter);
925 info.short_decr = jackctl_parameter_get_short_description(parameter);
926 info.long_descr = jackctl_parameter_get_long_description(parameter);
928 jack_controller_get_parameter_info_ex(call, &info);
931 static
932 void
933 jack_controller_dbus_get_parameter_info(
934 struct jack_dbus_method_call * call)
936 const char * address[3];
937 jackctl_internal_t * internal;
938 jackctl_driver_t * driver;
939 jackctl_parameter_t * parameter;
940 struct parameter_info driver_parameter_info;
942 //jack_info("jack_controller_dbus_get_parameter_info() called");
944 if (!jack_controller_dbus_get_parameter_address(call, address))
946 /* The method call had invalid arguments meaning that
947 * jack_controller_dbus_get_parameter_address() has
948 * constructed an error for us. */
949 return;
952 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
954 if (address[0] != NULL &&
955 address[1] != NULL &&
956 address[2] == NULL &&
957 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
959 if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0)
961 driver_parameter_info.type = ENGINE_DRIVER_PARAMETER_TYPE;
962 driver_parameter_info.name = ENGINE_DRIVER_PARAMETER_NAME;
963 driver_parameter_info.short_decr = ENGINE_DRIVER_PARAMETER_SHORT_DESCR;
964 driver_parameter_info.long_descr = ENGINE_DRIVER_PARAMETER_LONG_DESCR;
966 jack_controller_get_parameter_info_ex(call, &driver_parameter_info);
968 return;
971 parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]);
972 if (parameter == NULL)
974 jack_dbus_error(
975 call,
976 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
977 "Unknown engine parameter '%s'",
978 address[1]);
979 return;
982 jack_controller_get_parameter_info(call, parameter);
984 return;
987 if (address[0] != NULL &&
988 address[1] != NULL &&
989 address[2] == NULL &&
990 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
992 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]);
993 if (parameter == NULL)
995 jack_dbus_error(
996 call,
997 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
998 "Unknown parameter '%s' for driver '%s'",
999 address[1],
1000 jackctl_driver_get_name(controller_ptr->driver));
1001 return;
1004 jack_controller_get_parameter_info(call, parameter);
1006 return;
1009 if (address[0] != NULL &&
1010 address[1] != NULL &&
1011 address[2] != NULL &&
1012 strcmp(address[0], PTNODE_DRIVERS) == 0)
1014 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
1015 if (driver == NULL)
1017 jack_dbus_error(
1018 call,
1019 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1020 "Unknown driver '%s'",
1021 address[1]);
1022 return;
1025 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]);
1026 if (parameter == NULL)
1028 jack_dbus_error(
1029 call,
1030 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1031 "Unknown parameter '%s' for driver '%s'",
1032 address[2],
1033 address[1]);
1034 return;
1037 jack_controller_get_parameter_info(call, parameter);
1039 return;
1042 if (address[0] != NULL &&
1043 address[1] != NULL &&
1044 address[2] != NULL &&
1045 strcmp(address[0], PTNODE_INTERNALS) == 0)
1047 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
1048 if (internal == NULL)
1050 jack_dbus_error(
1051 call,
1052 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1053 "Unknown internal '%s'",
1054 address[1]);
1055 return;
1058 parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]);
1059 if (parameter == NULL)
1061 jack_dbus_error(
1062 call,
1063 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1064 "Unknown parameter '%s' for internal '%s'",
1065 address[2],
1066 address[1]);
1067 return;
1070 jack_controller_get_parameter_info(call, parameter);
1072 return;
1075 jack_dbus_error(
1076 call,
1077 JACK_DBUS_ERROR_INVALID_ARGS,
1078 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
1079 address[0],
1080 address[1],
1081 address[2],
1082 call->method_name);
1085 static
1086 void
1087 jack_controller_get_parameter_constraint(
1088 struct jack_dbus_method_call * call,
1089 jackctl_parameter_t * parameter)
1091 uint32_t index;
1092 uint32_t count;
1093 union jackctl_parameter_value min;
1094 union jackctl_parameter_value max;
1095 union jackctl_parameter_value jackctl_value;
1096 DBusMessageIter iter, array_iter, struct_iter;
1097 const char * descr;
1098 jackctl_param_type_t type;
1099 message_arg_t value;
1100 bool is_range;
1102 type = jackctl_parameter_get_type(parameter);
1104 call->reply = dbus_message_new_method_return(call->message);
1105 if (!call->reply)
1107 goto fail;
1110 dbus_message_iter_init_append(call->reply, &iter);
1112 is_range = jackctl_parameter_has_range_constraint(parameter);
1113 value.boolean = is_range;
1114 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value))
1116 goto fail_unref;
1119 value.boolean = jackctl_parameter_constraint_is_strict(parameter);
1120 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value))
1122 goto fail_unref;
1125 value.boolean = jackctl_parameter_constraint_is_fake_value(parameter);
1126 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &value))
1128 goto fail_unref;
1131 /* Open the array. */
1132 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(vs)", &array_iter))
1134 goto fail_unref;
1137 if (is_range)
1139 jackctl_parameter_get_range_constraint(parameter, &min, &max);
1141 /* Open the struct. */
1142 if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
1144 goto fail_close_unref;
1147 jack_controller_jack_to_dbus_variant(type, &min, &value);
1149 if (!jack_dbus_message_append_variant(&struct_iter, PARAM_TYPE_JACK_TO_DBUS(type), PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), &value))
1151 goto fail_close2_unref;
1154 descr = "min";
1156 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &descr))
1158 goto fail_close2_unref;
1161 /* Close the struct. */
1162 if (!dbus_message_iter_close_container(&array_iter, &struct_iter))
1164 goto fail_close_unref;
1167 /* Open the struct. */
1168 if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
1170 goto fail_close_unref;
1173 jack_controller_jack_to_dbus_variant(type, &max, &value);
1175 if (!jack_dbus_message_append_variant(&struct_iter, PARAM_TYPE_JACK_TO_DBUS(type), PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), &value))
1177 goto fail_close2_unref;
1180 descr = "max";
1182 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &descr))
1184 goto fail_close2_unref;
1187 /* Close the struct. */
1188 if (!dbus_message_iter_close_container(&array_iter, &struct_iter))
1190 goto fail_close_unref;
1193 else
1195 count = jackctl_parameter_get_enum_constraints_count(parameter);
1197 /* Append enum values to the array. */
1198 for (index = 0 ; index < count ; index++)
1200 jackctl_value = jackctl_parameter_get_enum_constraint_value(parameter, index);
1201 descr = jackctl_parameter_get_enum_constraint_description(parameter, index);
1203 jack_controller_jack_to_dbus_variant(type, &jackctl_value, &value);
1205 /* Open the struct. */
1206 if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
1208 goto fail_close_unref;
1211 if (!jack_dbus_message_append_variant(&struct_iter, PARAM_TYPE_JACK_TO_DBUS(type), PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type), &value))
1213 goto fail_close2_unref;
1216 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &descr))
1218 goto fail_close2_unref;
1221 /* Close the struct. */
1222 if (!dbus_message_iter_close_container(&array_iter, &struct_iter))
1224 goto fail_close_unref;
1229 /* Close the array. */
1230 if (!dbus_message_iter_close_container(&iter, &array_iter))
1232 goto fail_unref;
1235 return;
1237 fail_close2_unref:
1238 dbus_message_iter_close_container(&array_iter, &struct_iter);
1240 fail_close_unref:
1241 dbus_message_iter_close_container(&iter, &array_iter);
1243 fail_unref:
1244 dbus_message_unref(call->reply);
1245 call->reply = NULL;
1247 fail:
1248 jack_error ("Ran out of memory trying to construct method return");
1251 static
1252 void
1253 jack_controller_get_parameter_constraint_engine_driver(
1254 struct jack_dbus_method_call * call)
1256 unsigned int index;
1257 DBusMessageIter iter, array_iter, struct_iter;
1258 jackctl_param_type_t type;
1259 dbus_bool_t bval;
1260 message_arg_t value;
1262 type = ENGINE_DRIVER_PARAMETER_TYPE;
1264 call->reply = dbus_message_new_method_return(call->message);
1265 if (!call->reply)
1267 goto fail;
1270 dbus_message_iter_init_append(call->reply, &iter);
1272 /* is_range */
1273 bval = false;
1274 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &bval))
1276 goto fail_unref;
1279 /* is_strict */
1280 bval = true;
1281 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &bval))
1283 goto fail_unref;
1286 /* is_fake_value */
1287 bval = true;
1288 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &bval))
1290 goto fail_unref;
1293 /* Open the array. */
1294 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(vs)", &array_iter))
1296 goto fail_unref;
1299 /* Append enum values to the array. */
1300 for (index = 0 ; index < controller_ptr->drivers_count ; index++)
1302 /* Open the struct. */
1303 if (!dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter))
1305 goto fail_close_unref;
1308 value.string = controller_ptr->driver_names[index];
1309 if (!jack_dbus_message_append_variant(
1310 &struct_iter,
1311 PARAM_TYPE_JACK_TO_DBUS(type),
1312 PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type),
1313 &value))
1315 goto fail_close2_unref;
1318 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &value))
1320 goto fail_close2_unref;
1323 /* Close the struct. */
1324 if (!dbus_message_iter_close_container(&array_iter, &struct_iter))
1326 goto fail_close_unref;
1330 /* Close the array. */
1331 if (!dbus_message_iter_close_container(&iter, &array_iter))
1333 goto fail_unref;
1336 return;
1338 fail_close2_unref:
1339 dbus_message_iter_close_container(&array_iter, &struct_iter);
1341 fail_close_unref:
1342 dbus_message_iter_close_container(&iter, &array_iter);
1344 fail_unref:
1345 dbus_message_unref(call->reply);
1346 call->reply = NULL;
1348 fail:
1349 jack_error ("Ran out of memory trying to construct method return");
1352 static
1353 void
1354 jack_controller_dbus_get_parameter_constraint(
1355 struct jack_dbus_method_call * call)
1357 const char * address[3];
1358 jackctl_internal_t * internal;
1359 jackctl_driver_t * driver;
1360 jackctl_parameter_t * parameter;
1362 //jack_info("jack_controller_dbus_get_parameter_constraint() called");
1364 if (!jack_controller_dbus_get_parameter_address(call, address))
1366 /* The method call had invalid arguments meaning that
1367 * jack_controller_dbus_get_parameter_address() has
1368 * constructed an error for us. */
1369 return;
1372 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
1374 if (address[0] != NULL &&
1375 address[1] != NULL &&
1376 address[2] == NULL &&
1377 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
1379 if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0)
1381 jack_controller_get_parameter_constraint_engine_driver(call);
1383 return;
1386 parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]);
1387 if (parameter == NULL)
1389 jack_dbus_error(
1390 call,
1391 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1392 "Unknown engine parameter '%s'",
1393 address[1]);
1394 return;
1397 jack_controller_get_parameter_constraint(call, parameter);
1399 return;
1402 if (address[0] != NULL &&
1403 address[1] != NULL &&
1404 address[2] == NULL &&
1405 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
1407 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]);
1408 if (parameter == NULL)
1410 jack_dbus_error(
1411 call,
1412 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1413 "Unknown parameter '%s' for driver '%s'",
1414 address[1],
1415 jackctl_driver_get_name(controller_ptr->driver));
1416 return;
1419 jack_controller_get_parameter_constraint(call, parameter);
1421 return;
1424 if (address[0] != NULL &&
1425 address[1] != NULL &&
1426 address[2] != NULL &&
1427 strcmp(address[0], PTNODE_DRIVERS) == 0)
1429 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
1430 if (driver == NULL)
1432 jack_dbus_error(
1433 call,
1434 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1435 "Unknown driver '%s'",
1436 address[1]);
1437 return;
1440 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]);
1441 if (parameter == NULL)
1443 jack_dbus_error(
1444 call,
1445 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1446 "Unknown parameter '%s' for driver '%s'",
1447 address[2],
1448 address[1]);
1449 return;
1452 jack_controller_get_parameter_constraint(call, parameter);
1454 return;
1457 if (address[0] != NULL &&
1458 address[1] != NULL &&
1459 address[2] != NULL &&
1460 strcmp(address[0], PTNODE_INTERNALS) == 0)
1462 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
1463 if (internal == NULL)
1465 jack_dbus_error(
1466 call,
1467 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1468 "Unknown internal '%s'",
1469 address[1]);
1470 return;
1473 parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]);
1474 if (parameter == NULL)
1476 jack_dbus_error(
1477 call,
1478 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1479 "Unknown parameter '%s' for internal '%s'",
1480 address[2],
1481 address[1]);
1482 return;
1485 jack_controller_get_parameter_constraint(call, parameter);
1487 return;
1490 jack_dbus_error(
1491 call,
1492 JACK_DBUS_ERROR_INVALID_ARGS,
1493 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
1494 address[0],
1495 address[1],
1496 address[2],
1497 call->method_name);
1500 static
1501 void
1502 jack_controller_get_parameter_value(
1503 struct jack_dbus_method_call * call,
1504 jackctl_parameter_t * parameter)
1506 int type;
1507 union jackctl_parameter_value jackctl_value;
1508 union jackctl_parameter_value jackctl_default_value;
1509 message_arg_t value;
1510 message_arg_t default_value;
1512 type = jackctl_parameter_get_type(parameter);
1513 jackctl_default_value = jackctl_parameter_get_default_value(parameter);
1514 jackctl_value = jackctl_parameter_get_value(parameter);
1516 jack_controller_jack_to_dbus_variant(type, &jackctl_value, &value);
1517 jack_controller_jack_to_dbus_variant(type, &jackctl_default_value, &default_value);
1519 /* Construct the reply. */
1520 jack_dbus_construct_method_return_parameter(
1521 call,
1522 (dbus_bool_t)(jackctl_parameter_is_set(parameter) ? TRUE : FALSE),
1523 PARAM_TYPE_JACK_TO_DBUS(type),
1524 PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(type),
1525 default_value,
1526 value);
1529 static
1530 void
1531 jack_controller_get_parameter_value_engine_driver(
1532 struct jack_dbus_method_call * call)
1534 message_arg_t value;
1535 message_arg_t default_value;
1537 default_value.string = DEFAULT_DRIVER;
1538 value.string = jackctl_driver_get_name(controller_ptr->driver);
1540 /* Construct the reply. */
1541 jack_dbus_construct_method_return_parameter(
1542 call,
1543 controller_ptr->driver_set,
1544 DBUS_TYPE_STRING,
1545 DBUS_TYPE_STRING_AS_STRING,
1546 default_value,
1547 value);
1551 static void
1552 jack_controller_dbus_get_parameter_value(
1553 struct jack_dbus_method_call * call)
1555 const char * address[3];
1556 jackctl_internal_t * internal;
1557 jackctl_driver_t * driver;
1558 jackctl_parameter_t * parameter;
1560 //jack_info("jack_controller_dbus_get_parameter_value() called");
1562 if (!jack_controller_dbus_get_parameter_address(call, address))
1564 /* The method call had invalid arguments meaning that
1565 * jack_controller_dbus_get_parameter_address() has
1566 * constructed an error for us. */
1567 return;
1570 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
1572 if (address[0] != NULL &&
1573 address[1] != NULL &&
1574 address[2] == NULL &&
1575 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
1577 if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0)
1579 jack_controller_get_parameter_value_engine_driver(call);
1581 return;
1584 parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]);
1585 if (parameter == NULL)
1587 jack_dbus_error(
1588 call,
1589 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1590 "Unknown engine parameter '%s'",
1591 address[1]);
1592 return;
1595 jack_controller_get_parameter_value(call, parameter);
1597 return;
1600 if (address[0] != NULL &&
1601 address[1] != NULL &&
1602 address[2] == NULL &&
1603 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
1605 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]);
1606 if (parameter == NULL)
1608 jack_dbus_error(
1609 call,
1610 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1611 "Unknown parameter '%s' for driver '%s'",
1612 address[1],
1613 jackctl_driver_get_name(controller_ptr->driver));
1614 return;
1617 jack_controller_get_parameter_value(call, parameter);
1619 return;
1622 if (address[0] != NULL &&
1623 address[1] != NULL &&
1624 address[2] != NULL &&
1625 strcmp(address[0], PTNODE_DRIVERS) == 0)
1627 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
1628 if (driver == NULL)
1630 jack_dbus_error(
1631 call,
1632 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1633 "Unknown driver '%s'",
1634 address[1]);
1635 return;
1638 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]);
1639 if (parameter == NULL)
1641 jack_dbus_error(
1642 call,
1643 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1644 "Unknown parameter '%s' for driver '%s'",
1645 address[2],
1646 address[1]);
1647 return;
1650 jack_controller_get_parameter_value(call, parameter);
1652 return;
1655 if (address[0] != NULL &&
1656 address[1] != NULL &&
1657 address[2] != NULL &&
1658 strcmp(address[0], PTNODE_INTERNALS) == 0)
1660 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
1661 if (internal == NULL)
1663 jack_dbus_error(
1664 call,
1665 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1666 "Unknown internal '%s'",
1667 address[1]);
1668 return;
1671 parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]);
1672 if (parameter == NULL)
1674 jack_dbus_error(
1675 call,
1676 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1677 "Unknown parameter '%s' for internal '%s'",
1678 address[2],
1679 address[1]);
1680 return;
1683 jack_controller_get_parameter_value(call, parameter);
1685 return;
1688 jack_dbus_error(
1689 call,
1690 JACK_DBUS_ERROR_INVALID_ARGS,
1691 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
1692 address[0],
1693 address[1],
1694 address[2],
1695 call->method_name);
1698 static
1699 void
1700 jack_controller_set_parameter_value(
1701 struct jack_dbus_method_call * call,
1702 jackctl_parameter_t * parameter,
1703 message_arg_t * arg_ptr,
1704 int arg_type)
1706 jackctl_param_type_t type;
1707 union jackctl_parameter_value value;
1709 type = jackctl_parameter_get_type(parameter);
1711 if (PARAM_TYPE_JACK_TO_DBUS(type) != arg_type)
1713 jack_dbus_error(
1714 call,
1715 JACK_DBUS_ERROR_INVALID_ARGS,
1716 "Parameter value type mismatch: was expecting '%c', got '%c'",
1717 (char)PARAM_TYPE_JACK_TO_DBUS(type),
1718 (char)arg_type);
1719 return;
1722 if (!jack_controller_dbus_to_jack_variant(
1723 arg_type,
1724 arg_ptr,
1725 &value))
1727 jack_dbus_error(
1728 call,
1729 JACK_DBUS_ERROR_INVALID_ARGS,
1730 "Cannot convert parameter value");
1731 return;
1734 jackctl_parameter_set_value(parameter, &value);
1736 jack_controller_settings_save_auto(controller_ptr);
1738 jack_dbus_construct_method_return_empty(call);
1741 static
1742 void
1743 jack_controller_set_parameter_value_engine_driver(
1744 struct jack_dbus_method_call * call,
1745 message_arg_t * arg_ptr,
1746 int arg_type)
1748 union jackctl_parameter_value value;
1750 if (arg_type != DBUS_TYPE_STRING)
1752 jack_dbus_error(
1753 call,
1754 JACK_DBUS_ERROR_INVALID_ARGS,
1755 "Engine parameter value type mismatch: was expecting '%c', got '%c'",
1756 (char)DBUS_TYPE_STRING,
1757 (char)arg_type);
1758 return;
1761 if (!jack_controller_dbus_to_jack_variant(
1762 arg_type,
1763 arg_ptr,
1764 &value))
1766 jack_dbus_error(
1767 call,
1768 JACK_DBUS_ERROR_INVALID_ARGS,
1769 "Cannot convert engine parameter value");
1770 return;
1773 if (!jack_controller_select_driver(controller_ptr, value.str))
1775 /* Couldn't find driver with the specified name. */
1776 jack_dbus_error(
1777 call,
1778 JACK_DBUS_ERROR_UNKNOWN_DRIVER,
1779 "Unknown driver '%s'",
1780 value.str);
1781 return;
1784 jack_controller_settings_save_auto(controller_ptr);
1786 jack_dbus_construct_method_return_empty(call);
1789 static
1790 void
1791 jack_controller_dbus_set_parameter_value(
1792 struct jack_dbus_method_call * call)
1794 const char * address[3];
1795 DBusMessageIter iter;
1796 DBusMessageIter variant_iter;
1797 message_arg_t arg;
1798 int arg_type;
1799 jackctl_internal_t * internal;
1800 jackctl_driver_t * driver;
1801 jackctl_parameter_t * parameter;
1803 //jack_info("jack_controller_dbus_set_parameter_value() called");
1805 if (!jack_controller_dbus_get_parameter_address_ex(call, &iter, address))
1807 /* The method call had invalid arguments meaning that
1808 * jack_controller_dbus_get_parameter_address() has
1809 * constructed an error for us. */
1810 return;
1813 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
1815 dbus_message_iter_next(&iter);
1817 if (dbus_message_iter_has_next(&iter))
1819 jack_dbus_error(
1820 call,
1821 JACK_DBUS_ERROR_INVALID_ARGS,
1822 "Invalid arguments to method '%s'. Too many arguments.",
1823 call->method_name);
1824 return;
1827 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1829 jack_dbus_error(
1830 call,
1831 JACK_DBUS_ERROR_INVALID_ARGS,
1832 "Invalid arguments to method '%s'. Value to set must be variant.",
1833 call->method_name);
1834 return;
1837 dbus_message_iter_recurse (&iter, &variant_iter);
1838 dbus_message_iter_get_basic(&variant_iter, &arg);
1839 arg_type = dbus_message_iter_get_arg_type(&variant_iter);
1841 //jack_info("argument of type '%c'", arg_type);
1843 if (address[0] != NULL &&
1844 address[1] != NULL &&
1845 address[2] == NULL &&
1846 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
1848 if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0)
1850 jack_controller_set_parameter_value_engine_driver(call, &arg, arg_type);
1852 return;
1855 parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]);
1856 if (parameter == NULL)
1858 jack_dbus_error(
1859 call,
1860 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1861 "Unknown engine parameter '%s'",
1862 address[1]);
1863 return;
1866 jack_controller_set_parameter_value(call, parameter, &arg, arg_type);
1868 return;
1871 if (address[0] != NULL &&
1872 address[1] != NULL &&
1873 address[2] == NULL &&
1874 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
1876 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]);
1877 if (parameter == NULL)
1879 jack_dbus_error(
1880 call,
1881 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1882 "Unknown parameter '%s' for driver '%s'",
1883 address[1],
1884 jackctl_driver_get_name(controller_ptr->driver));
1885 return;
1888 jack_controller_set_parameter_value(call, parameter, &arg, arg_type);
1890 return;
1893 if (address[0] != NULL &&
1894 address[1] != NULL &&
1895 address[2] != NULL &&
1896 strcmp(address[0], PTNODE_DRIVERS) == 0)
1898 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
1899 if (driver == NULL)
1901 jack_dbus_error(
1902 call,
1903 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1904 "Unknown driver '%s'",
1905 address[1]);
1906 return;
1909 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]);
1910 if (parameter == NULL)
1912 jack_dbus_error(
1913 call,
1914 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1915 "Unknown parameter '%s' for driver '%s'",
1916 address[2],
1917 address[1]);
1918 return;
1921 jack_controller_set_parameter_value(call, parameter, &arg, arg_type);
1923 return;
1926 if (address[0] != NULL &&
1927 address[1] != NULL &&
1928 address[2] != NULL &&
1929 strcmp(address[0], PTNODE_INTERNALS) == 0)
1931 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
1932 if (internal == NULL)
1934 jack_dbus_error(
1935 call,
1936 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
1937 "Unknown internal '%s'",
1938 address[1]);
1939 return;
1942 parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]);
1943 if (parameter == NULL)
1945 jack_dbus_error(
1946 call,
1947 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
1948 "Unknown parameter '%s' for internal '%s'",
1949 address[2],
1950 address[1]);
1951 return;
1954 jack_controller_set_parameter_value(call, parameter, &arg, arg_type);
1956 return;
1959 jack_dbus_error(
1960 call,
1961 JACK_DBUS_ERROR_INVALID_ARGS,
1962 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
1963 address[0],
1964 address[1],
1965 address[2],
1966 call->method_name);
1969 static
1970 void
1971 jack_controller_reset_parameter_value(
1972 struct jack_dbus_method_call * call,
1973 jackctl_parameter_t * parameter)
1975 jackctl_parameter_reset(parameter);
1977 jack_controller_settings_save_auto(controller_ptr);
1979 jack_dbus_construct_method_return_empty(call);
1982 static
1983 void
1984 jack_controller_reset_parameter_value_engine_driver(
1985 struct jack_dbus_method_call * call)
1987 if (!jack_controller_select_driver(controller_ptr, DEFAULT_DRIVER))
1989 /* Couldn't find driver with the specified name. */
1990 jack_dbus_error(
1991 call,
1992 JACK_DBUS_ERROR_UNKNOWN_DRIVER,
1993 "Default driver '%s' is unknown",
1994 DEFAULT_DRIVER);
1995 return;
1998 controller_ptr->driver_set = false;
2000 jack_controller_settings_save_auto(controller_ptr);
2002 jack_dbus_construct_method_return_empty(call);
2005 static
2006 void
2007 jack_controller_dbus_reset_parameter_value(
2008 struct jack_dbus_method_call * call)
2010 const char * address[3];
2011 jackctl_internal_t * internal;
2012 jackctl_driver_t * driver;
2013 jackctl_parameter_t * parameter;
2015 //jack_info("jack_controller_dbus_reset_parameter_value() called");
2017 if (!jack_controller_dbus_get_parameter_address(call, address))
2019 /* The method call had invalid arguments meaning that
2020 * jack_controller_dbus_get_parameter_address() has
2021 * constructed an error for us. */
2022 return;
2025 //jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
2027 if (address[0] != NULL &&
2028 address[1] != NULL &&
2029 address[2] == NULL &&
2030 strcmp(address[0], PTNODE_ENGINE) == 0) /* engine parameters requested */
2032 if (strcmp(address[1], ENGINE_DRIVER_PARAMETER_NAME) == 0)
2034 jack_controller_reset_parameter_value_engine_driver(call);
2036 return;
2039 parameter = jack_controller_find_parameter(jackctl_server_get_parameters(controller_ptr->server), address[1]);
2040 if (parameter == NULL)
2042 jack_dbus_error(
2043 call,
2044 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
2045 "Unknown engine parameter '%s'",
2046 address[1]);
2047 return;
2050 jack_controller_reset_parameter_value(call, parameter);
2052 return;
2055 if (address[0] != NULL &&
2056 address[1] != NULL &&
2057 address[2] == NULL &&
2058 strcmp(address[0], PTNODE_DRIVER) == 0) /* current driver parameters requested */
2060 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(controller_ptr->driver), address[1]);
2061 if (parameter == NULL)
2063 jack_dbus_error(
2064 call,
2065 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
2066 "Unknown parameter '%s' for driver '%s'",
2067 address[1],
2068 jackctl_driver_get_name(controller_ptr->driver));
2069 return;
2072 jack_controller_reset_parameter_value(call, parameter);
2074 return;
2077 if (address[0] != NULL &&
2078 address[1] != NULL &&
2079 address[2] != NULL &&
2080 strcmp(address[0], PTNODE_DRIVERS) == 0)
2082 driver = jack_controller_find_driver(controller_ptr->server, address[1]);
2083 if (driver == NULL)
2085 jack_dbus_error(
2086 call,
2087 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
2088 "Unknown driver '%s'",
2089 address[1]);
2090 return;
2093 parameter = jack_controller_find_parameter(jackctl_driver_get_parameters(driver), address[2]);
2094 if (parameter == NULL)
2096 jack_dbus_error(
2097 call,
2098 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
2099 "Unknown parameter '%s' for driver '%s'",
2100 address[2],
2101 address[1]);
2102 return;
2105 jack_controller_reset_parameter_value(call, parameter);
2107 return;
2110 if (address[0] != NULL &&
2111 address[1] != NULL &&
2112 address[2] != NULL &&
2113 strcmp(address[0], PTNODE_INTERNALS) == 0)
2115 internal = jack_controller_find_internal(controller_ptr->server, address[1]);
2116 if (internal == NULL)
2118 jack_dbus_error(
2119 call,
2120 JACK_DBUS_ERROR_UNKNOWN_INTERNAL,
2121 "Unknown internal '%s'",
2122 address[1]);
2123 return;
2126 parameter = jack_controller_find_parameter(jackctl_internal_get_parameters(internal), address[2]);
2127 if (parameter == NULL)
2129 jack_dbus_error(
2130 call,
2131 JACK_DBUS_ERROR_UNKNOWN_PARAMETER,
2132 "Unknown parameter '%s' for internal '%s'",
2133 address[2],
2134 address[1]);
2135 return;
2138 jack_controller_reset_parameter_value(call, parameter);
2140 return;
2143 jack_dbus_error(
2144 call,
2145 JACK_DBUS_ERROR_INVALID_ARGS,
2146 "Invalid container address '%s':'%s':'%s' supplied to method '%s'.",
2147 address[0],
2148 address[1],
2149 address[2],
2150 call->method_name);
2153 #undef controller_ptr
2155 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(ReadContainer, "Get names of child parameters or containers")
2156 JACK_DBUS_METHOD_ARGUMENT_IN("parent", "as", "Address of parent container")
2157 JACK_DBUS_METHOD_ARGUMENT_OUT("leaf", "b", "Whether children are parameters (true) or containers (false)")
2158 JACK_DBUS_METHOD_ARGUMENT_OUT("children", "as", "Array of child names")
2159 JACK_DBUS_METHOD_ARGUMENTS_END
2161 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(GetParametersInfo, "Retrieve info about parameters")
2162 JACK_DBUS_METHOD_ARGUMENT_IN("parent", "as", "Address of parameters parent")
2163 JACK_DBUS_METHOD_ARGUMENT_OUT("parameter_info_array", "a(ysss)", "Array of parameter info structs. Each info struct contains: type char, name, short and long description")
2164 JACK_DBUS_METHOD_ARGUMENTS_END
2166 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(GetParameterInfo, "Retrieve info about parameter")
2167 JACK_DBUS_METHOD_ARGUMENT_IN("parameter", "as", "Address of parameter")
2168 JACK_DBUS_METHOD_ARGUMENT_OUT("parameter_info", "(ysss)", "Parameter info struct that contains: type char, name, short and long description")
2169 JACK_DBUS_METHOD_ARGUMENTS_END
2171 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(GetParameterConstraint, "Get constraint of parameter")
2172 JACK_DBUS_METHOD_ARGUMENT_IN("parameter", "as", "Address of parameter")
2173 JACK_DBUS_METHOD_ARGUMENT_OUT("is_range", "b", "Whether constrinat is a range. If so, values parameter will contain two values, min and max")
2174 JACK_DBUS_METHOD_ARGUMENT_OUT("is_strict", "b", "Whether enum constraint is strict. I.e. value not listed in values array will not work")
2175 JACK_DBUS_METHOD_ARGUMENT_OUT("is_fake_value", "b", "Whether enum values are fake. I.e. have no user meaningful meaning")
2176 JACK_DBUS_METHOD_ARGUMENT_OUT("values", "a(vs)", "Values. If there is no constraint, this array will be empty. For range constraint there will be two values, min and max. For enum constraint there will be 2 or more values.")
2177 JACK_DBUS_METHOD_ARGUMENTS_END
2179 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(GetParameterValue, "Get value of parameter")
2180 JACK_DBUS_METHOD_ARGUMENT_IN("parameter", "as", "Address of parameter")
2181 JACK_DBUS_METHOD_ARGUMENT_OUT("is_set", "b", "Whether parameter is set or its default value is used")
2182 JACK_DBUS_METHOD_ARGUMENT_OUT("default", "v", "Default value of parameter")
2183 JACK_DBUS_METHOD_ARGUMENT_OUT("value", "v", "Actual value of parameter")
2184 JACK_DBUS_METHOD_ARGUMENTS_END
2186 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(SetParameterValue, "Set value of parameter")
2187 JACK_DBUS_METHOD_ARGUMENT_IN("parameter", "as", "Address of parameter")
2188 JACK_DBUS_METHOD_ARGUMENT_IN("value", "v", "New value for parameter")
2189 JACK_DBUS_METHOD_ARGUMENTS_END
2191 JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX(ResetParameterValue, "Reset parameter to default value")
2192 JACK_DBUS_METHOD_ARGUMENT_IN("parameter", "as", "Address of parameter")
2193 JACK_DBUS_METHOD_ARGUMENTS_END
2195 JACK_DBUS_METHODS_BEGIN
2196 JACK_DBUS_METHOD_DESCRIBE(ReadContainer, jack_controller_dbus_read_container)
2197 JACK_DBUS_METHOD_DESCRIBE(GetParametersInfo, jack_controller_dbus_get_parameters_info)
2198 JACK_DBUS_METHOD_DESCRIBE(GetParameterInfo, jack_controller_dbus_get_parameter_info)
2199 JACK_DBUS_METHOD_DESCRIBE(GetParameterConstraint, jack_controller_dbus_get_parameter_constraint)
2200 JACK_DBUS_METHOD_DESCRIBE(GetParameterValue, jack_controller_dbus_get_parameter_value)
2201 JACK_DBUS_METHOD_DESCRIBE(SetParameterValue, jack_controller_dbus_set_parameter_value)
2202 JACK_DBUS_METHOD_DESCRIBE(ResetParameterValue, jack_controller_dbus_reset_parameter_value)
2203 JACK_DBUS_METHODS_END
2206 * Parameter addresses:
2208 * "engine"
2209 * "engine", "driver"
2210 * "engine", "realtime"
2211 * "engine", ...more engine parameters
2213 * "driver", "device"
2214 * "driver", ...more driver parameters
2216 * "drivers", "alsa", "device"
2217 * "drivers", "alsa", ...more alsa driver parameters
2219 * "drivers", ...more drivers
2221 * "internals", "netmanager", "multicast_ip"
2222 * "internals", "netmanager", ...more netmanager parameters
2224 * "internals", ...more internals
2228 JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_configure, "org.jackaudio.Configure")
2229 JACK_DBUS_IFACE_EXPOSE_METHODS
2230 JACK_DBUS_IFACE_END