Mercurial > mplayer.hg
diff m_property.c @ 17911:52f95509cd05
Add the new property API and implement a couple properties.
Move the volume and mute command to the command to property
bridge.
author | albeu |
---|---|
date | Wed, 22 Mar 2006 00:19:02 +0000 |
parents | |
children | f9cb6fc1608a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m_property.c Wed Mar 22 00:19:02 2006 +0000 @@ -0,0 +1,278 @@ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <unistd.h> + +#include "m_option.h" +#include "m_property.h" +#include "help_mp.h" + +#define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5)) + +int m_property_do(m_option_t* prop, int action, void* arg) { + if(!prop) return M_PROPERTY_UNKNOWN; + return ((m_property_ctrl_f)prop->p)(prop,action,arg); +} + + +char* m_property_print(m_option_t* prop) { + m_property_ctrl_f ctrl; + void* val; + char* ret; + + if(!prop) return NULL; + + ctrl = prop->p; + // look if the property have it's own print func + if(ctrl(prop,M_PROPERTY_PRINT,&ret) >= 0) + return ret; + // fallback on the default print for this type + val = calloc(1,prop->type->size); + if(ctrl(prop,M_PROPERTY_GET,val) <= 0) { + free(val); + return NULL; + } + ret = m_option_print(prop,val); + free(val); + return ret == (char*)-1 ? NULL : ret; +} + +int m_property_parse(m_option_t* prop, char* txt) { + m_property_ctrl_f ctrl; + void* val; + int r; + + if(!prop) return M_PROPERTY_UNKNOWN; + + ctrl = prop->p; + // try the property own parsing func + if((r = ctrl(prop,M_PROPERTY_PARSE,txt)) != M_PROPERTY_NOT_IMPLEMENTED) + return r; + // fallback on the default + val = calloc(1,prop->type->size); + if((r = m_option_parse(prop,prop->name,txt,val,M_CONFIG_FILE)) <= 0) { + free(val); + return r; + } + r = ctrl(prop,M_PROPERTY_SET,val); + m_option_free(prop,val); + free(val); + return r; +} + +char* m_properties_expand_string(m_option_t* prop_list,char* str) { + int l,fr=0,pos=0,size=strlen(str)+512; + char *p = NULL,*e,*ret = malloc(size), num_val; + int skip = 0, lvl = 0, skip_lvl = 0; + + while(str[0]) { + if(str[0] == '\\') { + int sl = 1; + switch(str[1]) { + case 'e': + p = "\x1b", l = 1; break; + case 'n': + p = "\n", l = 1; break; + case 'r': + p = "\r", l = 1; break; + case 't': + p = "\t", l = 1; break; + case 'x': + if(str[2]) { + char num[3] = { str[2], str[3], 0 }; + char* end = num; + num_val = strtol(num,&end,16); + sl = end-num; + l = 1; + p = &num_val; + } else + l = 0; + break; + default: + p = str+1, l = 1; + } + str+=1+sl; + } else if(lvl > 0 && str[0] == ')') { + if(skip && lvl <= skip_lvl) skip = 0; + lvl--, str++, l = 0; + } else if(str[0] == '$' && str[1] == '{' && (e = strchr(str+2,'}'))) { + int pl = e-str-2; + char pname[pl+1]; + m_option_t* prop; + memcpy(pname,str+2,pl); + pname[pl] = 0; + if((prop = m_option_list_find(prop_list,pname)) && + (p = m_property_print(prop))) + l = strlen(p), fr = 1; + else + l = 0; + str = e+1; + } else if(str[0] == '?' && str[1] == '(' && (e = strchr(str+2,':'))) { + int pl = e-str-2; + char pname[pl+1]; + m_option_t* prop; + lvl++; + if(!skip) { + memcpy(pname,str+2,pl); + pname[pl] = 0; + if(!(prop = m_option_list_find(prop_list,pname)) || + m_property_do(prop,M_PROPERTY_GET,NULL) < 0) + skip = 1, skip_lvl = lvl; + } + str = e+1, l = 0; + } else + p = str, l = 1, str++; + + if(skip || l <= 0) continue; + + if(pos+l+1 > size) { + size = pos+l+512; + ret = realloc(ret,size); + } + memcpy(ret+pos,p,l); + pos += l; + if(fr) free(p), fr = 0; + } + + ret[pos] = 0; + return ret; +} + +// Some generic property implementations + +int m_property_int_ro(m_option_t* prop,int action, + void* arg,int var) { + switch(action) { + case M_PROPERTY_GET: + if(!arg) return 0; + *(int*)arg = var; + return 1; + } + return M_PROPERTY_NOT_IMPLEMENTED; +} + +int m_property_int_range(m_option_t* prop,int action, + void* arg,int* var) { + switch(action) { + case M_PROPERTY_SET: + if(!arg) return 0; + M_PROPERTY_CLAMP(prop,*(int*)arg); + *var = *(int*)arg; + return 1; + case M_PROPERTY_STEP_UP: + case M_PROPERTY_STEP_DOWN: + *var += (arg ? *(int*)arg : 1) * + (action == M_PROPERTY_STEP_DOWN ? -1 : 1); + M_PROPERTY_CLAMP(prop,*var); + return 1; + } + return m_property_int_ro(prop,action,arg,*var); +} + +int m_property_choice(m_option_t* prop,int action, + void* arg,int* var) { + switch(action) { + case M_PROPERTY_STEP_UP: + case M_PROPERTY_STEP_DOWN: + *var += action == M_PROPERTY_STEP_UP ? 1 : prop->max; + *var %= (int)prop->max+1; + return 1; + } + return m_property_int_range(prop,action,arg,var); +} + +int m_property_flag(m_option_t* prop,int action, + void* arg,int* var) { + switch(action) { + case M_PROPERTY_STEP_UP: + case M_PROPERTY_STEP_DOWN: + *var = *var == prop->min ? prop->max : prop->min; + return 1; + case M_PROPERTY_PRINT: + if(!arg) return 0; + *(char**)arg = strdup((*var > prop->min) ? MSGTR_Enabled : MSGTR_Disabled); + return 1; + } + return m_property_int_range(prop,action,arg,var); +} + +int m_property_float_ro(m_option_t* prop,int action, + void* arg,float var) { + switch(action) { + case M_PROPERTY_GET: + if(!arg) return 0; + *(float*)arg = var; + return 1; + case M_PROPERTY_PRINT: + if(!arg) return 0; + *(char**)arg = malloc(20); + sprintf(*(char**)arg,"%.2f",var); + return 1; + } + return M_PROPERTY_NOT_IMPLEMENTED; +} + +int m_property_float_range(m_option_t* prop,int action, + void* arg,float* var) { + switch(action) { + case M_PROPERTY_SET: + if(!arg) return 0; + M_PROPERTY_CLAMP(prop,*(float*)arg); + *var = *(float*)arg; + return 1; + case M_PROPERTY_STEP_UP: + case M_PROPERTY_STEP_DOWN: + *var += (arg ? *(float*)arg : 0.1) * + (action == M_PROPERTY_STEP_DOWN ? -1 : 1); + M_PROPERTY_CLAMP(prop,*var); + return 1; + } + return m_property_float_ro(prop,action,arg,*var); +} + +int m_property_delay(m_option_t* prop,int action, + void* arg,float* var) { + switch(action) { + case M_PROPERTY_PRINT: + if(!arg) return 0; + *(char**)arg = malloc(20); + sprintf(*(char**)arg,"%d ms",ROUND((*var)*1000)); + return 1; + default: + return m_property_float_range(prop,action,arg,var); + } +} + +int m_property_double_ro(m_option_t* prop,int action, + void* arg,double var) { + switch(action) { + case M_PROPERTY_GET: + if(!arg) return 0; + *(double*)arg = var; + return 1; + case M_PROPERTY_PRINT: + if(!arg) return 0; + *(char**)arg = malloc(20); + sprintf(*(char**)arg,"%.2f",var); + return 1; + } + return M_PROPERTY_NOT_IMPLEMENTED; +} + +int m_property_string_ro(m_option_t* prop,int action,void* arg,char* str) { + switch(action) { + case M_PROPERTY_GET: + if(!arg) return 0; + *(char**)arg = str; + return 1; + case M_PROPERTY_PRINT: + if(!arg) return 0; + *(char**)arg = str ? strdup(str) : NULL; + return 1; + } + return M_PROPERTY_NOT_IMPLEMENTED; +}