summaryrefslogtreecommitdiffstats
path: root/m_property.c
diff options
context:
space:
mode:
authoralbeu <albeu@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-03-22 00:19:02 +0000
committeralbeu <albeu@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-03-22 00:19:02 +0000
commit7ccf4830263c1d7eaaf42a50dd7a602a6b6e8a31 (patch)
tree3205d003b77e8092d5067f34f3fd317fd9a5be7d /m_property.c
parent87323740ede2b6ac4eda035eaaee03a658c4e255 (diff)
downloadmpv-7ccf4830263c1d7eaaf42a50dd7a602a6b6e8a31.tar.bz2
mpv-7ccf4830263c1d7eaaf42a50dd7a602a6b6e8a31.tar.xz
Add the new property API and implement a couple properties.
Move the volume and mute command to the command to property bridge. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@17912 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'm_property.c')
-rw-r--r--m_property.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/m_property.c b/m_property.c
new file mode 100644
index 0000000000..14f5c7943f
--- /dev/null
+++ b/m_property.c
@@ -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;
+}