00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "fluidsynth_priv.h"
00022 #include "fluid_sys.h"
00023 #include "fluid_hash.h"
00024 #include "fluid_synth.h"
00025 #include "fluid_cmd.h"
00026 #include "fluid_adriver.h"
00027 #include "fluid_mdriver.h"
00028 #include "fluid_settings.h"
00029
00030
00031 #define MAX_SETTINGS_TOKENS 8
00032 #define MAX_SETTINGS_LABEL 256
00033
00034 static void fluid_settings_init(fluid_settings_t* settings);
00035 static void fluid_settings_hash_delete(void* value, int type);
00036 static int fluid_settings_tokenize(char* s, char *buf, char** ptr);
00037
00038
00039 typedef struct {
00040 char* value;
00041 char* def;
00042 int hints;
00043 fluid_list_t* options;
00044 fluid_str_update_t update;
00045 void* data;
00046 } fluid_str_setting_t;
00047
00048 static fluid_str_setting_t*
00049 new_fluid_str_setting(char* value, char* def, int hints, fluid_str_update_t fun, void* data)
00050 {
00051 fluid_str_setting_t* str;
00052 str = FLUID_NEW(fluid_str_setting_t);
00053 str->value = value? FLUID_STRDUP(value) : NULL;
00054 str->def = def? FLUID_STRDUP(def) : NULL;
00055 str->hints = hints;
00056 str->options = NULL;
00057 str->update = fun;
00058 str->data = data;
00059 return str;
00060 }
00061
00062 static void delete_fluid_str_setting(fluid_str_setting_t* str)
00063 {
00064 if (str) {
00065 if (str->value) {
00066 FLUID_FREE(str->value);
00067 }
00068 if (str->def) {
00069 FLUID_FREE(str->def);
00070 }
00071 if (str->options) {
00072 fluid_list_t* list = str->options;
00073
00074 while (list) {
00075 FLUID_FREE (list->data);
00076 list = fluid_list_next(list);
00077 }
00078
00079 delete_fluid_list(str->options);
00080 }
00081 FLUID_FREE(str);
00082 }
00083 }
00084
00085
00086
00087
00088 typedef struct {
00089 double value;
00090 double def;
00091 double min;
00092 double max;
00093 int hints;
00094 fluid_num_update_t update;
00095 void* data;
00096 } fluid_num_setting_t;
00097
00098
00099 static fluid_num_setting_t*
00100 new_fluid_num_setting(double min, double max, double def,
00101 int hints, fluid_num_update_t fun, void* data)
00102 {
00103 fluid_num_setting_t* setting;
00104 setting = FLUID_NEW(fluid_num_setting_t);
00105 setting->value = def;
00106 setting->def = def;
00107 setting->min = min;
00108 setting->max = max;
00109 setting->hints = hints;
00110 setting->update = fun;
00111 setting->data = data;
00112 return setting;
00113 }
00114
00115 static void delete_fluid_num_setting(fluid_num_setting_t* setting)
00116 {
00117 if (setting) {
00118 FLUID_FREE(setting);
00119 }
00120 }
00121
00122
00123
00124
00125 typedef struct {
00126 int value;
00127 int def;
00128 int min;
00129 int max;
00130 int hints;
00131 fluid_int_update_t update;
00132 void* data;
00133 } fluid_int_setting_t;
00134
00135
00136 static fluid_int_setting_t*
00137 new_fluid_int_setting(int min, int max, int def,
00138 int hints, fluid_int_update_t fun, void* data)
00139 {
00140 fluid_int_setting_t* setting;
00141 setting = FLUID_NEW(fluid_int_setting_t);
00142 setting->value = def;
00143 setting->def = def;
00144 setting->min = min;
00145 setting->max = max;
00146 setting->hints = hints;
00147 setting->update = fun;
00148 setting->data = data;
00149 return setting;
00150 }
00151
00152 static void delete_fluid_int_setting(fluid_int_setting_t* setting)
00153 {
00154 if (setting) {
00155 FLUID_FREE(setting);
00156 }
00157 }
00158
00159
00160
00161 fluid_settings_t* new_fluid_settings()
00162 {
00163 fluid_settings_t* settings = new_fluid_hashtable(fluid_settings_hash_delete);
00164 if (settings == NULL) {
00165 return NULL;
00166 }
00167 fluid_settings_init(settings);
00168 return settings;
00169 }
00170
00171 void delete_fluid_settings(fluid_settings_t* settings)
00172 {
00173 delete_fluid_hashtable(settings);
00174 }
00175
00176 void fluid_settings_hash_delete(void* value, int type)
00177 {
00178 switch (type) {
00179 case FLUID_NUM_TYPE:
00180 delete_fluid_num_setting((fluid_num_setting_t*) value);
00181 break;
00182 case FLUID_INT_TYPE:
00183 delete_fluid_int_setting((fluid_int_setting_t*) value);
00184 break;
00185 case FLUID_STR_TYPE:
00186 delete_fluid_str_setting((fluid_str_setting_t*) value);
00187 break;
00188 case FLUID_SET_TYPE:
00189 delete_fluid_hashtable((fluid_hashtable_t*) value);
00190 break;
00191 }
00192 }
00193
00194 void fluid_settings_init(fluid_settings_t* settings)
00195 {
00196 fluid_synth_settings(settings);
00197 fluid_shell_settings(settings);
00198 fluid_audio_driver_settings(settings);
00199 fluid_midi_driver_settings(settings);
00200 }
00201
00202 static int fluid_settings_tokenize(char* s, char *buf, char** ptr)
00203 {
00204 char *tokstr, *tok;
00205 int n = 0;
00206
00207 if (strlen (s) > MAX_SETTINGS_LABEL)
00208 {
00209 FLUID_LOG(FLUID_ERR, "Setting variable name exceeded max length of %d chars",
00210 MAX_SETTINGS_LABEL);
00211 return 0;
00212 }
00213
00214 FLUID_STRCPY(buf, s);
00215 tokstr = buf;
00216
00217 while ((tok = fluid_strtok (&tokstr, ".")))
00218 {
00219 if (n > MAX_SETTINGS_TOKENS)
00220 {
00221 FLUID_LOG(FLUID_ERR, "Setting variable name exceeded max token count of %d",
00222 MAX_SETTINGS_TOKENS);
00223 return 0;
00224 }
00225
00226 ptr[n++] = tok;
00227 }
00228
00229 return n;
00230 }
00231
00233 static int fluid_settings_get(fluid_settings_t* settings,
00234 char** name, int len,
00235 void** value, int* type)
00236 {
00237 fluid_hashtable_t* table = settings;
00238 int t;
00239 void* v;
00240 int n;
00241
00242 for (n = 0; n < len; n++) {
00243
00244 if (table == NULL) {
00245 return 0;
00246 }
00247
00248 if (!fluid_hashtable_lookup(table, name[n], &v, &t)) {
00249 return 0;
00250 }
00251
00252 table = (t == FLUID_SET_TYPE)? (fluid_hashtable_t*) v : NULL;
00253 }
00254
00255 if (value) {
00256 *value = v;
00257 }
00258
00259 if (type) {
00260 *type = t;
00261 }
00262
00263 return 1;
00264 }
00265
00267 static int fluid_settings_set(fluid_settings_t* settings,
00268 char** name, int len,
00269 void* value, int type)
00270 {
00271 fluid_hashtable_t* table = settings;
00272 int t;
00273 void* v;
00274 int n, num = len - 1;
00275
00276 for (n = 0; n < num; n++) {
00277
00278 if (fluid_hashtable_lookup(table, name[n], &v, &t)) {
00279
00280 if (t == FLUID_SET_TYPE) {
00281 table = (fluid_hashtable_t*) v;
00282 } else {
00283
00284 FLUID_LOG(FLUID_WARN, "'%s' is not a node", name[n]);
00285 return 0;
00286 }
00287
00288 } else {
00289
00290 fluid_hashtable_t* tmp;
00291 tmp = new_fluid_hashtable(fluid_settings_hash_delete);
00292 fluid_hashtable_insert(table, name[n], tmp, FLUID_SET_TYPE);
00293 table = tmp;
00294 }
00295 }
00296
00297 fluid_hashtable_replace(table, name[num], value, type);
00298
00299 return 1;
00300 }
00301
00304 int fluid_settings_register_str(fluid_settings_t* settings, char* name, char* def, int hints,
00305 fluid_str_update_t fun, void* data)
00306 {
00307 int type;
00308 void* value;
00309 char* tokens[MAX_SETTINGS_TOKENS];
00310 char buf[MAX_SETTINGS_LABEL+1];
00311 int ntokens;
00312 fluid_str_setting_t* setting;
00313
00314 ntokens = fluid_settings_tokenize(name, buf, tokens);
00315
00316 if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00317 setting = new_fluid_str_setting(def, def, hints, fun, data);
00318 return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_STR_TYPE);
00319
00320 } else {
00321
00322 if (type == FLUID_STR_TYPE) {
00323 setting = (fluid_str_setting_t*) value;
00324 setting->update = fun;
00325 setting->data = data;
00326 setting->def = def? FLUID_STRDUP(def) : NULL;
00327 setting->hints = hints;
00328 return 1;
00329 } else {
00330 FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
00331 return 1;
00332 }
00333 }
00334 }
00335
00338 int fluid_settings_register_num(fluid_settings_t* settings, char* name, double def,
00339 double min, double max, int hints,
00340 fluid_num_update_t fun, void* data)
00341 {
00342 int type;
00343 void* value;
00344 char* tokens[MAX_SETTINGS_TOKENS];
00345 char buf[MAX_SETTINGS_LABEL+1];
00346 int ntokens;
00347
00348 ntokens = fluid_settings_tokenize(name, buf, tokens);
00349
00350 if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00351
00352 fluid_num_setting_t* setting;
00353 setting = new_fluid_num_setting(min, max, def, hints, fun, data);
00354 return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_NUM_TYPE);
00355
00356 } else {
00357 if (type == FLUID_NUM_TYPE) {
00358
00359 fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00360 setting->update = fun;
00361 setting->data = data;
00362 setting->min = min;
00363 setting->max = max;
00364 setting->def = def;
00365 setting->hints = hints;
00366 return 1;
00367
00368 } else {
00369
00370 FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
00371 return 0;
00372 }
00373 }
00374 }
00375
00378 int fluid_settings_register_int(fluid_settings_t* settings, char* name, int def,
00379 int min, int max, int hints,
00380 fluid_int_update_t fun, void* data)
00381 {
00382 int type;
00383 void* value;
00384 char* tokens[MAX_SETTINGS_TOKENS];
00385 char buf[MAX_SETTINGS_LABEL+1];
00386 int ntokens;
00387
00388 ntokens = fluid_settings_tokenize(name, buf, tokens);
00389
00390 if (!fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00391
00392 fluid_int_setting_t* setting;
00393 setting = new_fluid_int_setting(min, max, def, hints, fun, data);
00394 return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_INT_TYPE);
00395
00396 } else {
00397 if (type == FLUID_INT_TYPE) {
00398
00399 fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00400 setting->update = fun;
00401 setting->data = data;
00402 setting->min = min;
00403 setting->max = max;
00404 setting->def = def;
00405 setting->hints = hints;
00406 return 1;
00407
00408 } else {
00409
00410 FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name);
00411 return 0;
00412 }
00413 }
00414 }
00415
00416 int fluid_settings_get_type(fluid_settings_t* settings, char* name)
00417 {
00418 int type;
00419 void* value;
00420 char* tokens[MAX_SETTINGS_TOKENS];
00421 char buf[MAX_SETTINGS_LABEL+1];
00422 int ntokens;
00423
00424 ntokens = fluid_settings_tokenize(name, buf, tokens);
00425
00426 return (fluid_settings_get(settings, tokens, ntokens, &value, &type))? type : FLUID_NO_TYPE;
00427 }
00428
00429 int fluid_settings_get_hints(fluid_settings_t* settings, char* name)
00430 {
00431 int type;
00432 void* value;
00433 char* tokens[MAX_SETTINGS_TOKENS];
00434 char buf[MAX_SETTINGS_LABEL+1];
00435 int ntokens;
00436
00437 ntokens = fluid_settings_tokenize(name, buf, tokens);
00438
00439 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00440 if (type == FLUID_NUM_TYPE) {
00441 fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00442 return setting->hints;
00443 } else if (type == FLUID_STR_TYPE) {
00444 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00445 return setting->hints;
00446 } else {
00447 return 0;
00448 }
00449 } else {
00450 return 0;
00451 }
00452 }
00453
00454 int fluid_settings_is_realtime(fluid_settings_t* settings, char* name)
00455 {
00456 int type;
00457 void* value;
00458 char* tokens[MAX_SETTINGS_TOKENS];
00459 char buf[MAX_SETTINGS_LABEL+1];
00460 int ntokens;
00461
00462 ntokens = fluid_settings_tokenize(name, buf, tokens);
00463
00464 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00465 if (type == FLUID_NUM_TYPE) {
00466 fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00467 return setting->update != NULL;
00468
00469 } else if (type == FLUID_STR_TYPE) {
00470 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00471 return setting->update != NULL;
00472 } else {
00473 return 0;
00474 }
00475 } else {
00476 return 0;
00477 }
00478 }
00479
00480 int fluid_settings_setstr(fluid_settings_t* settings, char* name, char* str)
00481 {
00482 char* tokens[MAX_SETTINGS_TOKENS];
00483 char buf[MAX_SETTINGS_LABEL+1];
00484 int ntokens;
00485 int type;
00486 void* value;
00487 fluid_str_setting_t* setting;
00488
00489 ntokens = fluid_settings_tokenize(name, buf, tokens);
00490
00491 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00492
00493 if (type != FLUID_STR_TYPE) {
00494 return 0;
00495 }
00496
00497 setting = (fluid_str_setting_t*) value;
00498
00499 if (setting->value) {
00500 FLUID_FREE(setting->value);
00501 }
00502 setting->value = str? FLUID_STRDUP(str) : NULL;
00503
00504 if (setting->update) {
00505 (*setting->update)(setting->data, name, setting->value);
00506 }
00507
00508 return 1;
00509
00510 } else {
00511
00512 fluid_str_setting_t* setting;
00513 setting = new_fluid_str_setting(str, NULL, 0, NULL, NULL);
00514 return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_STR_TYPE);
00515 }
00516 }
00517
00518 int fluid_settings_getstr(fluid_settings_t* settings, char* name, char** str)
00519 {
00520 int type;
00521 void* value;
00522 char* tokens[MAX_SETTINGS_TOKENS];
00523 char buf[MAX_SETTINGS_LABEL+1];
00524 int ntokens;
00525
00526 ntokens = fluid_settings_tokenize(name, buf, tokens);
00527
00528 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00529 && (type == FLUID_STR_TYPE)) {
00530 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00531 *str = setting->value;
00532 return 1;
00533 }
00534 *str = NULL;
00535 return 0;
00536 }
00537
00538 int fluid_settings_str_equal(fluid_settings_t* settings, char* name, char* s)
00539 {
00540 int type;
00541 void* value;
00542 char* tokens[MAX_SETTINGS_TOKENS];
00543 char buf[MAX_SETTINGS_LABEL+1];
00544 int ntokens;
00545
00546 ntokens = fluid_settings_tokenize(name, buf, tokens);
00547
00548 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00549 && (type == FLUID_STR_TYPE)) {
00550 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00551 return FLUID_STRCMP(setting->value, s) == 0;
00552 }
00553 return 0;
00554 }
00555
00556 char*
00557 fluid_settings_getstr_default(fluid_settings_t* settings, char* name)
00558 {
00559 int type;
00560 void* value;
00561 char* tokens[MAX_SETTINGS_TOKENS];
00562 char buf[MAX_SETTINGS_LABEL+1];
00563 int ntokens;
00564
00565 ntokens = fluid_settings_tokenize(name, buf, tokens);
00566
00567 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00568 && (type == FLUID_STR_TYPE)) {
00569 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00570 return setting->def;
00571 } else {
00572 return NULL;
00573 }
00574 }
00575
00576 int fluid_settings_add_option(fluid_settings_t* settings, char* name, char* s)
00577 {
00578 int type;
00579 void* value;
00580 char* tokens[MAX_SETTINGS_TOKENS];
00581 char buf[MAX_SETTINGS_LABEL+1];
00582 int ntokens;
00583
00584 ntokens = fluid_settings_tokenize(name, buf, tokens);
00585
00586 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00587 && (type == FLUID_STR_TYPE)) {
00588 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00589 char* copy = FLUID_STRDUP(s);
00590 setting->options = fluid_list_append(setting->options, copy);
00591 return 1;
00592 } else {
00593 return 0;
00594 }
00595 }
00596
00597 int fluid_settings_remove_option(fluid_settings_t* settings, char* name, char* s)
00598 {
00599 int type;
00600 void* value;
00601 char* tokens[MAX_SETTINGS_TOKENS];
00602 char buf[MAX_SETTINGS_LABEL+1];
00603 int ntokens;
00604
00605 ntokens = fluid_settings_tokenize(name, buf, tokens);
00606
00607 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00608 && (type == FLUID_STR_TYPE)) {
00609
00610 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00611 fluid_list_t* list = setting->options;
00612
00613 while (list) {
00614 char* option = (char*) fluid_list_get(list);
00615 if (FLUID_STRCMP(s, option) == 0) {
00616 FLUID_FREE (option);
00617 setting->options = fluid_list_remove_link(setting->options, list);
00618 return 1;
00619 }
00620 list = fluid_list_next(list);
00621 }
00622
00623 return 0;
00624 } else {
00625 return 0;
00626 }
00627 }
00628
00629 int fluid_settings_setnum(fluid_settings_t* settings, char* name, double val)
00630 {
00631 int type;
00632 void* value;
00633 fluid_num_setting_t* setting;
00634 char* tokens[MAX_SETTINGS_TOKENS];
00635 char buf[MAX_SETTINGS_LABEL+1];
00636 int ntokens;
00637
00638 ntokens = fluid_settings_tokenize(name, buf, tokens);
00639
00640 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00641
00642 if (type != FLUID_NUM_TYPE) {
00643 return 0;
00644 }
00645
00646 setting = (fluid_num_setting_t*) value;
00647
00648 if (val < setting->min) {
00649 val = setting->min;
00650 } else if (val > setting->max) {
00651 val = setting->max;
00652 }
00653
00654 setting->value = val;
00655
00656 if (setting->update) {
00657 (*setting->update)(setting->data, name, val);
00658 }
00659
00660 return 1;
00661
00662 } else {
00663
00664 fluid_num_setting_t* setting;
00665 setting = new_fluid_num_setting(-1e10, 1e10, 0.0f, 0, NULL, NULL);
00666 setting->value = val;
00667 return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_NUM_TYPE);
00668 }
00669 }
00670
00671 int fluid_settings_getnum(fluid_settings_t* settings, char* name, double* val)
00672 {
00673 int type;
00674 void* value;
00675 char* tokens[MAX_SETTINGS_TOKENS];
00676 char buf[MAX_SETTINGS_LABEL+1];
00677 int ntokens;
00678
00679 ntokens = fluid_settings_tokenize(name, buf, tokens);
00680
00681 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00682 && (type == FLUID_NUM_TYPE)) {
00683 fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00684 *val = setting->value;
00685 return 1;
00686 }
00687 return 0;
00688 }
00689
00690
00691 void fluid_settings_getnum_range(fluid_settings_t* settings, char* name, double* min, double* max)
00692 {
00693 int type;
00694 void* value;
00695 char* tokens[MAX_SETTINGS_TOKENS];
00696 char buf[MAX_SETTINGS_LABEL+1];
00697 int ntokens;
00698
00699 ntokens = fluid_settings_tokenize(name, buf, tokens);
00700
00701 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00702 && (type == FLUID_NUM_TYPE)) {
00703 fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00704 *min = setting->min;
00705 *max = setting->max;
00706 }
00707 }
00708
00709 double
00710 fluid_settings_getnum_default(fluid_settings_t* settings, char* name)
00711 {
00712 int type;
00713 void* value;
00714 char* tokens[MAX_SETTINGS_TOKENS];
00715 char buf[MAX_SETTINGS_LABEL+1];
00716 int ntokens;
00717
00718 ntokens = fluid_settings_tokenize(name, buf, tokens);
00719
00720 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00721 && (type == FLUID_NUM_TYPE)) {
00722 fluid_num_setting_t* setting = (fluid_num_setting_t*) value;
00723 return setting->def;
00724 } else {
00725 return 0.0f;
00726 }
00727 }
00728
00729
00730 int fluid_settings_setint(fluid_settings_t* settings, char* name, int val)
00731 {
00732 int type;
00733 void* value;
00734 fluid_int_setting_t* setting;
00735 char* tokens[MAX_SETTINGS_TOKENS];
00736 char buf[MAX_SETTINGS_LABEL+1];
00737 int ntokens;
00738
00739 ntokens = fluid_settings_tokenize(name, buf, tokens);
00740
00741 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)) {
00742
00743 if (type != FLUID_INT_TYPE) {
00744 return 0;
00745 }
00746
00747 setting = (fluid_int_setting_t*) value;
00748
00749 if (val < setting->min) {
00750 val = setting->min;
00751 } else if (val > setting->max) {
00752 val = setting->max;
00753 }
00754
00755 setting->value = val;
00756
00757 if (setting->update) {
00758 (*setting->update)(setting->data, name, val);
00759 }
00760
00761 return 1;
00762
00763 } else {
00764
00765 fluid_int_setting_t* setting;
00766 setting = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL);
00767 setting->value = val;
00768 return fluid_settings_set(settings, tokens, ntokens, setting, FLUID_INT_TYPE);
00769 }
00770 }
00771
00772 int fluid_settings_getint(fluid_settings_t* settings, char* name, int* val)
00773 {
00774 int type;
00775 void* value;
00776 char* tokens[MAX_SETTINGS_TOKENS];
00777 char buf[MAX_SETTINGS_LABEL+1];
00778 int ntokens;
00779
00780 ntokens = fluid_settings_tokenize(name, buf, tokens);
00781
00782 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00783 && (type == FLUID_INT_TYPE)) {
00784 fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00785 *val = setting->value;
00786 return 1;
00787 }
00788 return 0;
00789 }
00790
00791
00792 void fluid_settings_getint_range(fluid_settings_t* settings, char* name, int* min, int* max)
00793 {
00794 int type;
00795 void* value;
00796 char* tokens[MAX_SETTINGS_TOKENS];
00797 char buf[MAX_SETTINGS_LABEL+1];
00798 int ntokens;
00799
00800 ntokens = fluid_settings_tokenize(name, buf, tokens);
00801
00802 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00803 && (type == FLUID_INT_TYPE)) {
00804 fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00805 *min = setting->min;
00806 *max = setting->max;
00807 }
00808 }
00809
00810 int
00811 fluid_settings_getint_default(fluid_settings_t* settings, char* name)
00812 {
00813 int type;
00814 void* value;
00815 char* tokens[MAX_SETTINGS_TOKENS];
00816 char buf[MAX_SETTINGS_LABEL+1];
00817 int ntokens;
00818
00819 ntokens = fluid_settings_tokenize(name, buf, tokens);
00820
00821 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00822 && (type == FLUID_INT_TYPE)) {
00823 fluid_int_setting_t* setting = (fluid_int_setting_t*) value;
00824 return setting->def;
00825 } else {
00826 return 0.0f;
00827 }
00828 }
00829
00830
00831
00832
00833 void fluid_settings_foreach_option(fluid_settings_t* settings, char* name, void* data,
00834 fluid_settings_foreach_option_t func)
00835 {
00836 int type;
00837 void* value;
00838 char* tokens[MAX_SETTINGS_TOKENS];
00839 char buf[MAX_SETTINGS_LABEL+1];
00840 int ntokens;
00841
00842 if (!func) {
00843 return;
00844 }
00845
00846 ntokens = fluid_settings_tokenize(name, buf, tokens);
00847
00848 if (fluid_settings_get(settings, tokens, ntokens, &value, &type)
00849 && (type == FLUID_STR_TYPE)) {
00850
00851 fluid_str_setting_t* setting = (fluid_str_setting_t*) value;
00852 fluid_list_t* list = setting->options;
00853
00854 while (list) {
00855 char* option = (char*) fluid_list_get(list);
00856 (*func)(data, name, option);
00857 list = fluid_list_next(list);
00858 }
00859 }
00860 }
00861
00862
00863 static fluid_settings_foreach_t fluid_settings_foreach_func;
00864 static void* fluid_settings_foreach_data;
00865
00866 int fluid_settings_foreach_iter(char* key, void* value, int type, void* data)
00867 {
00868 char path[1024];
00869
00870 if (data == 0) {
00871 snprintf(path, 1024, "%s", key);
00872 } else {
00873 snprintf(path, 1024, "%s.%s", (char*) data, key);
00874 }
00875 path[1023] = 0;
00876
00877 switch (type) {
00878 case FLUID_NUM_TYPE:
00879 case FLUID_INT_TYPE:
00880 case FLUID_STR_TYPE:
00881 (*fluid_settings_foreach_func)(fluid_settings_foreach_data, path, type);
00882 break;
00883 case FLUID_SET_TYPE:
00884 fluid_hashtable_foreach((fluid_hashtable_t*) value, fluid_settings_foreach_iter, &path[0]);
00885 break;
00886 }
00887
00888 return 0;
00889 }
00890
00891 void fluid_settings_foreach(fluid_settings_t* settings, void* data, fluid_settings_foreach_t func)
00892 {
00893 fluid_settings_foreach_func = func;
00894 fluid_settings_foreach_data = data;
00895 fluid_hashtable_foreach(settings, fluid_settings_foreach_iter, 0);
00896 }