new-jackctl.cpp

00001 /* -*- mode: c; c-file-style: "bsd"; -*- */
00002 /*
00003     JACK control API implementation
00004 
00005     Copyright (C) 2008 Nedko Arnaudov
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 
00020 */
00021 
00022 #include <stdbool.h>
00023 #include <stdint.h>
00024 #include <string.h>
00025 #include <errno.h>
00026 #include <dirent.h>
00027 #include <stdio.h>
00028 #include <assert.h>
00029 
00030 //#include <config.h>
00031 //#include <jack/internal.h>
00032 //#include <jack/engine.h>
00033 //#include <jack/driver.h
00034 
00035 #include "driver_interface.h"
00036 #include "JackDriverLoader.h"
00037 #include "JackError.h"
00038 #include "jackctl.h"
00039 
00040 //#include "jslist.h"
00041 
00042 
00043 struct jackctl_server
00044 {
00045         char * name;
00046         JSList * drivers;
00047         JSList * parameters;
00048 
00049         //jack_engine_t * engine;
00050 
00051         unsigned int xruns;
00052 
00053         /* bool, whether to be "realtime" */
00054         union jackctl_parameter_value realtime;
00055         union jackctl_parameter_value default_realtime;
00056 
00057         /* int32_t */
00058         union jackctl_parameter_value realtime_priority;
00059         union jackctl_parameter_value default_realtime_priority;
00060 
00061         /* bool, if true - do not attempt to lock memory, even in realtime mode. */
00062         union jackctl_parameter_value no_mem_lock;
00063         union jackctl_parameter_value default_no_mem_lock;
00064 
00065         /* bool, whether to exit once all clients have closed their connections */
00066         union jackctl_parameter_value temporary;
00067         union jackctl_parameter_value default_temporary;
00068 
00069         /* bool, whether to be verbose */
00070         union jackctl_parameter_value verbose;
00071         union jackctl_parameter_value default_verbose;
00072 
00073         /* int32_t, msecs; if zero, use period size. */
00074         union jackctl_parameter_value client_timeout;
00075         union jackctl_parameter_value default_client_timeout;
00076 
00077         /* uint32_t, maximum number of ports the JACK server can manage */
00078         union jackctl_parameter_value port_max;
00079         union jackctl_parameter_value default_port_max;
00080 
00081         /* bool, whether to unlock libraries GTK+, QT, FLTK, Wine */
00082         union jackctl_parameter_value do_unlock;
00083         union jackctl_parameter_value default_do_unlock;
00084 
00085         /* int32_t */
00086         union jackctl_parameter_value frame_time_offset;
00087         union jackctl_parameter_value default_frame_time_offset;
00088 
00089         /* bool, whether to prevent from ever kicking out clients because they were too slow */
00090         union jackctl_parameter_value nozombies;
00091         union jackctl_parameter_value default_nozombies;
00092 };
00093 
00094 struct jackctl_driver
00095 {
00096         char * filename;
00097         jack_driver_desc_t * desc_ptr;
00098         JSList * parameters;
00099         JSList * set_parameters;
00100 };
00101 
00102 struct jackctl_parameter
00103 {
00104         const char * name;
00105         const char * short_description;
00106         const char * long_description;
00107         jackctl_param_type_t type;
00108         bool is_set;
00109         union jackctl_parameter_value * value_ptr;
00110         union jackctl_parameter_value * default_value_ptr;
00111 
00112         union jackctl_parameter_value value;
00113         union jackctl_parameter_value default_value;
00114         struct jackctl_driver * driver_ptr;
00115         char id;
00116         jack_driver_param_t * driver_parameter_ptr;
00117 };
00118 
00119 static
00120 struct jackctl_parameter *
00121 jackctl_add_parameter(
00122         JSList ** parameters_list_ptr_ptr,
00123         const char * name,
00124         const char * short_description,
00125         const char * long_description,
00126         jackctl_param_type_t type,
00127         union jackctl_parameter_value * value_ptr,
00128         union jackctl_parameter_value * default_value_ptr,
00129         union jackctl_parameter_value value)
00130 {
00131         struct jackctl_parameter * parameter_ptr;
00132 
00133         parameter_ptr = (struct jackctl_parameter *)malloc(sizeof(struct jackctl_parameter));
00134         if (parameter_ptr == NULL)
00135         {
00136                 jack_error("Cannot allocate memory for jackctl_parameter structure.");
00137                 goto fail;
00138         }
00139 
00140         parameter_ptr->name = name;
00141         parameter_ptr->short_description = short_description;
00142         parameter_ptr->long_description = long_description;
00143         parameter_ptr->type = type;
00144         parameter_ptr->is_set = false;
00145 
00146         if (value_ptr == NULL)
00147         {
00148                 value_ptr = &parameter_ptr->value;
00149         }
00150 
00151         if (default_value_ptr == NULL)
00152         {
00153                 default_value_ptr = &parameter_ptr->default_value;
00154         }
00155 
00156         parameter_ptr->value_ptr = value_ptr;
00157         parameter_ptr->default_value_ptr = default_value_ptr;
00158 
00159         *value_ptr = *default_value_ptr = value;
00160 
00161         parameter_ptr->driver_ptr = NULL;
00162         parameter_ptr->driver_parameter_ptr = NULL;
00163         parameter_ptr->id = 0;
00164 
00165         *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr);
00166 
00167         return parameter_ptr;
00168 
00169 fail:
00170         return NULL;
00171 }
00172 
00173 static
00174 void
00175 jackctl_free_driver_parameters(
00176         struct jackctl_driver * driver_ptr)
00177 {
00178         JSList * next_node_ptr;
00179 
00180         while (driver_ptr->parameters)
00181         {
00182                 next_node_ptr = driver_ptr->parameters->next;
00183                 free(driver_ptr->parameters->data);
00184                 free(driver_ptr->parameters);
00185                 driver_ptr->parameters = next_node_ptr;
00186         }
00187 
00188         while (driver_ptr->set_parameters)
00189         {
00190                 next_node_ptr = driver_ptr->set_parameters->next;
00191                 free(driver_ptr->set_parameters->data);
00192                 free(driver_ptr->set_parameters);
00193                 driver_ptr->set_parameters = next_node_ptr;
00194         }
00195 }
00196 
00197 static
00198 bool
00199 jackctl_add_driver_parameters(
00200         struct jackctl_driver * driver_ptr)
00201 {
00202         uint32_t i;
00203         union jackctl_parameter_value jackctl_value;
00204         jackctl_param_type_t jackctl_type;
00205         struct jackctl_parameter * parameter_ptr;
00206         jack_driver_param_desc_t * descriptor_ptr;
00207 
00208         for (i = 0 ; i < driver_ptr->desc_ptr->nparams ; i++)
00209         {
00210                 descriptor_ptr = driver_ptr->desc_ptr->params + i;
00211 
00212                 switch (descriptor_ptr->type)
00213                 {
00214                 case JackDriverParamInt:
00215                         jackctl_type = JackParamInt;
00216                         jackctl_value.i = descriptor_ptr->value.i;
00217                         break;
00218                 case JackDriverParamUInt:
00219                         jackctl_type = JackParamUInt;
00220                         jackctl_value.ui = descriptor_ptr->value.ui;
00221                         break;
00222                 case JackDriverParamChar:
00223                         jackctl_type = JackParamChar;
00224                         jackctl_value.c = descriptor_ptr->value.c;
00225                         break;
00226                 case JackDriverParamString:
00227                         jackctl_type = JackParamString;
00228                         strcpy(jackctl_value.str, descriptor_ptr->value.str);
00229                         break;
00230                 case JackDriverParamBool:
00231                         jackctl_type = JackParamBool;
00232                         jackctl_value.b = descriptor_ptr->value.i;
00233                         break;
00234                 default:
00235                         jack_error("unknown driver parameter type %i", (int)descriptor_ptr->type);
00236                         assert(0);
00237                         goto fail;
00238                 }
00239 
00240                 parameter_ptr = jackctl_add_parameter(
00241                         &driver_ptr->parameters,
00242                         descriptor_ptr->name,
00243                         descriptor_ptr->short_desc,
00244                         descriptor_ptr->long_desc,
00245                         jackctl_type,
00246                         NULL,
00247                         NULL,
00248                         jackctl_value);
00249 
00250                 if (parameter_ptr == NULL)
00251                 {
00252                         goto fail;
00253                 }
00254 
00255                 parameter_ptr->driver_ptr = driver_ptr;
00256                 parameter_ptr->id = descriptor_ptr->character;
00257         }
00258 
00259         return true;
00260 
00261 fail:
00262         jackctl_free_driver_parameters(driver_ptr);
00263 
00264         return false;
00265 }
00266 
00267 static
00268 bool
00269 jackctl_load_driver_descriptor(
00270         struct jackctl_server * server_ptr,
00271         struct jackctl_driver * driver_ptr)
00272 {
00273         jack_driver_desc_t * descriptor;
00274         JackDriverDescFunction so_get_descriptor;
00275         void * dlhandle;
00276         const char * dlerr;
00277         int err;
00278 
00279         if (server_ptr->verbose.b) {
00280                 //jack_info ("getting driver descriptor from %s", driver_ptr->filename);
00281                 printf ("getting driver descriptor from %s", driver_ptr->filename); // steph
00282         }
00283 
00284         dlhandle = dlopen(driver_ptr->filename, RTLD_NOW|RTLD_GLOBAL);
00285         if (dlhandle == NULL) {
00286                 jack_error("could not open driver .so '%s': %s", driver_ptr->filename, dlerror());
00287                 return false;
00288         }
00289 
00290         so_get_descriptor = (JackDriverDescFunction)
00291                 dlsym(dlhandle, "driver_get_descriptor");
00292 
00293         dlerr = dlerror();
00294         if (dlerr != NULL) {
00295                 jack_error("cannot find driver_get_descriptor symbol: %s", dlerr);
00296                 dlclose(dlhandle);
00297                 return false;
00298         }
00299 
00300         descriptor = so_get_descriptor();
00301         if (descriptor == NULL) {
00302                 jack_error("driver from '%s' returned NULL descriptor", driver_ptr->filename);
00303                 dlclose(dlhandle);
00304                 return false;
00305         }
00306 
00307         err = dlclose(dlhandle);
00308         if (err != 0) {
00309                 jack_error("error closing driver .so '%s': %s", driver_ptr->filename, dlerror());
00310                 free(descriptor->params);
00311                 free(descriptor);
00312                 return false;
00313         }
00314 
00315         /* for some mad reason we are storing filename in descriptor allocated by driver
00316            instead of reusing dlhandle when another dlsym() call is needed */
00317         snprintf (descriptor->file, sizeof(descriptor->file), "%s", driver_ptr->filename);
00318 
00319         driver_ptr->desc_ptr = descriptor;
00320 
00321         return true;
00322 }
00323 
00324 static int
00325 jack_drivers_load(
00326         struct jackctl_server * server_ptr)
00327 {
00328         struct dirent * dir_entry;
00329         DIR * dir_stream;
00330         const char * ptr;
00331         int err;
00332         char* driver_dir;
00333         struct jackctl_driver * driver_ptr;
00334         struct jackctl_driver * other_driver_ptr;
00335         JSList * node_ptr;
00336         unsigned int drivers_count;
00337 
00338         if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00339                 driver_dir = ADDON_DIR;
00340         }
00341 
00342         if (server_ptr->verbose.b) {
00343                 //jack_info ("searching for drivers in %s", driver_dir);
00344                 printf ("searching for drivers in %s", driver_dir); // steph
00345         }
00346 
00347         /* search through the driver_dir and add get descriptors
00348            from the .so files in it */
00349         dir_stream = opendir (driver_dir);
00350         if (!dir_stream) {
00351                 jack_error ("could not open driver directory %s: %s",
00352                             driver_dir, strerror (errno));
00353                 return false;
00354         }
00355 
00356         drivers_count = 0;
00357 
00358         while ( (dir_entry = readdir (dir_stream)) ) {
00359                 /* check the filename is of the right format */
00360                 if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
00361                         continue;
00362                 }
00363 
00364 #if SETTINGS_PERSISTENCE_USE_LIBXML2
00365                 /* disable ffado driver.
00366                    it is incompatible with using libxml2 by other module,
00367                    be it jackdbus or some other driver.
00368                    libxml2 has global hooks used by libxml++, used by libffado */
00369                 if (strcmp ("jack_firewire.so", dir_entry->d_name) == 0) {
00370                         continue;
00371                 }
00372 #endif
00373 
00374                 ptr = strrchr (dir_entry->d_name, '.');
00375                 if (!ptr) {
00376                         continue;
00377                 }
00378                 ptr++;
00379                 if (strncmp ("so", ptr, 2) != 0) {
00380                         continue;
00381                 }
00382 
00383                 driver_ptr = (struct jackctl_driver *)malloc(sizeof(struct jackctl_driver));
00384                 if (driver_ptr == NULL)
00385                 {
00386                         jack_error("memory allocation of jackctl_driver structure failed.");
00387                         continue;
00388                 }
00389 
00390                 driver_ptr->filename = (char*)malloc(strlen(driver_dir) + 1 + strlen(dir_entry->d_name) + 1);
00391 
00392                 sprintf(driver_ptr->filename, "%s/%s", driver_dir, dir_entry->d_name);
00393 
00394                 if (!jackctl_load_driver_descriptor(server_ptr, driver_ptr))
00395                 {
00396                         goto dealloc_driver;
00397                 }
00398 
00399                 /* check it doesn't exist already */
00400                 for (node_ptr = server_ptr->drivers; node_ptr != NULL; node_ptr = jack_slist_next(node_ptr))
00401                 {
00402                         other_driver_ptr = (struct jackctl_driver *)node_ptr->data;
00403 
00404                         if (strcmp(driver_ptr->desc_ptr->name, other_driver_ptr->desc_ptr->name) == 0)
00405                         {
00406                                 jack_error(
00407                                         "the drivers in '%s' and '%s' both have the name '%s'; using the first",
00408                                         other_driver_ptr->filename,
00409                                         driver_ptr->filename,
00410                                         driver_ptr->desc_ptr->name);
00411                                 goto dealloc_descriptor;
00412                         }
00413                 }
00414 
00415                 driver_ptr->parameters = NULL;
00416                 driver_ptr->set_parameters = NULL;
00417 
00418                 if (!jackctl_add_driver_parameters(driver_ptr))
00419                 {
00420                         assert(driver_ptr->parameters == NULL);
00421                         goto dealloc_descriptor;
00422                 }
00423 
00424                 server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr);
00425                 drivers_count++;
00426 
00427                 continue;
00428 
00429         dealloc_descriptor:
00430                 free(driver_ptr->desc_ptr->params);
00431                 free(driver_ptr->desc_ptr);
00432 
00433         dealloc_driver:
00434                 free(driver_ptr->filename);
00435                 free(driver_ptr);
00436         }
00437 
00438         err = closedir (dir_stream);
00439         if (err) {
00440                 jack_error ("error closing driver directory %s: %s",
00441                             driver_dir, strerror (errno));
00442         }
00443 
00444         if (drivers_count == 0)
00445         {
00446                 jack_error ("could not find any drivers in %s!", driver_dir);
00447                 return false;
00448         }
00449 
00450         return true;
00451 }
00452 
00453 static
00454 void
00455 jackctl_server_free_drivers(
00456         jackctl_server_t* server_ptr)
00457 {
00458         
00459 }
00460 
00461 static
00462 void
00463 jackctl_server_free_parameters(
00464         jackctl_server_t* server_ptr)
00465 {
00466         
00467 }
00468 
00469 
00470 static
00471 int
00472 jackctl_xrun(void *arg)
00473 {
00474         ((struct jackctl_server *)arg)->xruns++;
00475 
00476         return 0;
00477 }
00478 
00479 jackctl_server_t* jackctl_server_create(const char * name)
00480 {
00481         struct jackctl_server * server_ptr;
00482         union jackctl_parameter_value value;
00483 
00484         server_ptr = (struct jackctl_server *) malloc(sizeof(struct jackctl_server));
00485         return (jackctl_server_t*)server_ptr;
00486 }
00487 
00488 void jackctl_server_destroy(jackctl_server_t* server)
00489 {
00490         jackctl_server_free_drivers(server);
00491         jackctl_server_free_parameters(server);
00492         free(((struct jackctl_server *)server)->name);
00493         free(server);
00494 }
00495 
00496 const JSList * jackctl_server_get_drivers_list(jackctl_server_t* server)
00497 {
00498         return ((struct jackctl_server *)server)->drivers;
00499 }
00500 
00501 bool jackctl_server_stop(jackctl_server_t* server)
00502 {
00503         return true;
00504 }
00505 
00506 double jackctl_server_get_load(jackctl_server_t* server)
00507 {
00508         //return ((struct jackctl_server*)server)->engine->control->cpu_load;
00509         return 0;
00510 }
00511 
00512 unsigned int jackctl_server_get_sample_rate(jackctl_server_t* server)
00513 {
00514         //return ((struct jackctl_server*)server)->engine->control->current_time.frame_rate;
00515         return 0;
00516 }
00517 
00518 double jackctl_server_get_latency(jackctl_server_t* server)
00519 {
00520         //return ((struct jackctl_server*)server)->engine->driver->period_usecs / 1000.0;
00521         return 0;
00522 }
00523 
00524 bool jackctl_server_is_realtime(jackctl_server_t* server)
00525 {
00526         return ((struct jackctl_server*)server)->realtime.b;
00527 }
00528 
00529 unsigned int jackctl_server_get_xruns(jackctl_server_t* server)
00530 {
00531         return ((struct jackctl_server*)server)->xruns;
00532 }
00533 
00534 void jackctl_server_reset_xruns(jackctl_server_t* server)
00535 {
00536         ((struct jackctl_server*)server)->xruns = 0;
00537 }
00538 
00539 const JSList * jackctl_server_get_parameters(jackctl_server_t* server)
00540 {
00541         return ((struct jackctl_server*)server)->parameters;
00542 }
00543 
00544 bool jackctl_server_start(jackctl_server_t* server, jackctl_driver_t* driver)
00545 {
00546         int rc;
00547         /*
00548         rc = jack_register_server(((struct jackctl_server*)server)->name);
00549         switch (rc)
00550         {
00551         case EEXIST:
00552                 jack_error("`%s' server already active", ((struct jackctl_server*)server)->name);
00553                 goto fail;
00554         case ENOSPC:
00555                 jack_error("too many servers already active");
00556                 goto fail;
00557         case ENOMEM:
00558                 jack_error("no access to shm registry");
00559                 goto fail;
00560         }
00561 
00562         if (((struct jackctl_server*)server)->verbose.b)
00563         {
00564                 jack_info ("server `%s' registered", ((struct jackctl_server*)server)->name);
00565         }
00566         jack_cleanup_shm();
00567         jack_cleanup_files(((struct jackctl_server*)server)->name);
00568 
00569         if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0)
00570                 server_ptr->client_timeout.i = 500;
00571 
00572         
00573         server_ptr->engine = jack_engine_new(
00574                 server_ptr->realtime.b,
00575                 server_ptr->realtime_priority.i,
00576                 !server_ptr->no_mem_lock.b,
00577                 server_ptr->do_unlock.b,
00578                 server_ptr->name,
00579                 server_ptr->temporary.b,
00580                 server_ptr->verbose.b,
00581                 server_ptr->client_timeout.i,
00582                 server_ptr->port_max.ui,
00583                 getpid(),
00584                 server_ptr->frame_time_offset.i,
00585                 server_ptr->nozombies.b,
00586                 NULL);
00587         if (server_ptr->engine == NULL)
00588         {
00589                 jack_error("Cannot create engine!");
00590                 goto fail_unregister_server;
00591         }
00592 
00593         jack_info("loading driver \"%s\" ...", driver_ptr->desc_ptr->name);
00594 
00595         if (jack_engine_load_driver(server_ptr->engine, driver_ptr->desc_ptr, driver_ptr->set_parameters)) {
00596                 jack_error("cannot load driver module %s", driver_ptr->desc_ptr->name);
00597                 goto fail_delete_engine;
00598         }
00599 
00600         server_ptr->xruns = 0;
00601         server_ptr->engine->driver->internal_client->control->xrun = jackctl_xrun;
00602         server_ptr->engine->driver->internal_client->control->xrun_arg = server_ptr;
00603 
00604         if (server_ptr->engine->driver->start(server_ptr->engine->driver) != 0) {
00605                 jack_error("cannot start \"%s\" driver", driver_ptr->desc_ptr->name);
00606                 goto fail_delete_engine;
00607         }
00608         */
00609 
00610         return true;
00611 
00612 
00613 }
00614 
00615 const char * jackctl_driver_get_name(jackctl_driver_t* driver)
00616 {
00617         return ((struct jackctl_driver*)driver)->desc_ptr->name;
00618 }
00619 
00620 const JSList * jackctl_driver_get_parameters(jackctl_driver_t* driver)
00621 {
00622         return ((struct jackctl_driver*)driver)->parameters;
00623 }
00624 
00625 #undef driver_ptr
00626 
00627 const char * jackctl_parameter_get_name(jackctl_parameter_t* parameter)
00628 {
00629         return ((struct jackctl_parameter*)parameter)->name;
00630 }
00631 
00632 const char * jackctl_parameter_get_short_description(jackctl_parameter_t* parameter)
00633 {
00634         return ((struct jackctl_parameter*)parameter)->short_description;
00635 }
00636 
00637 const char * jackctl_parameter_get_long_description(jackctl_parameter_t* parameter)
00638 {
00639         return ((struct jackctl_parameter*)parameter)->long_description;
00640 }
00641 
00642 jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter_t* parameter)
00643 {
00644         return ((struct jackctl_parameter*)parameter)->type;
00645 }
00646 
00647 bool jackctl_parameter_is_set(jackctl_parameter_t* parameter)
00648 {
00649         return ((struct jackctl_parameter*)parameter)->is_set;
00650 }
00651 
00652 union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter_t* parameter)
00653 {
00654         return *((struct jackctl_parameter*)parameter)->value_ptr;
00655 }
00656 
00657 bool jackctl_parameter_set_value(jackctl_parameter_t* parameter, const union jackctl_parameter_value * value_ptr)
00658 {
00659         bool new_driver_parameter;
00660 
00661         /* for driver parameters, set the parameter by adding jack_driver_param_t in the set_parameters list */
00662         if (((struct jackctl_parameter*)parameter)->driver_ptr != NULL)
00663         {
00664 /*              jack_info("setting driver parameter %p ...", parameter_ptr); */
00665                 new_driver_parameter = ((struct jackctl_parameter*)parameter)->driver_parameter_ptr == NULL;
00666                 if (new_driver_parameter)
00667                 {
00668 /*                      jack_info("new driver parameter..."); */
00669 
00670                         ((struct jackctl_parameter*)parameter)->driver_parameter_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t));
00671                         if (((struct jackctl_parameter*)parameter)->driver_parameter_ptr == NULL)
00672                         {
00673                                 jack_error ("Allocation of jack_driver_param_t structure failed");
00674                                 return false;
00675                         }
00676 
00677                         ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->character = ((struct jackctl_parameter*)parameter)->id;
00678 
00679                         ((struct jackctl_parameter*)parameter)->driver_ptr->set_parameters = jack_slist_append(((struct jackctl_parameter*)parameter)->driver_ptr->set_parameters, ((struct jackctl_parameter*)parameter)->driver_parameter_ptr);
00680                 }
00681 
00682                 switch (((struct jackctl_parameter*)parameter)->type)
00683                 {
00684                 case JackParamInt:
00685                         ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.i = value_ptr->i;
00686                         break;
00687                 case JackParamUInt:
00688                         ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.ui = value_ptr->ui;
00689                         break;
00690                 case JackParamChar:
00691                         ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.c = value_ptr->c;
00692                         break;
00693                 case JackParamString:
00694                         strcpy(((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.str, value_ptr->str);
00695                         break;
00696                 case JackParamBool:
00697                         ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.i = value_ptr->b;
00698                         break;
00699                 default:
00700                         jack_error("unknown parameter type %i", (int)((struct jackctl_parameter*)parameter)->type);
00701                         assert(0);
00702 
00703                         if (new_driver_parameter)
00704                         {
00705                                 jack_slist_remove(((struct jackctl_parameter*)parameter)->driver_ptr->set_parameters, ((struct jackctl_parameter*)parameter)->driver_parameter_ptr);
00706                         }
00707 
00708                         return false;
00709                 }
00710         }
00711 
00712         ((struct jackctl_parameter*)parameter)->is_set = true;
00713         *((struct jackctl_parameter*)parameter)->value_ptr = *value_ptr;
00714 
00715         return true;
00716 }
00717 
00718 union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter_t* parameter)
00719 {
00720         return *((struct jackctl_parameter*)parameter)->default_value_ptr;
00721 }

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1