3 /// \ingroup Properties
14 #include "m_property.h"
18 #define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5))
20 int m_property_do(m_option_t
* prop
, int action
, void* arg
, void *ctx
) {
21 if(!prop
) return M_PROPERTY_UNKNOWN
;
22 return ((m_property_ctrl_f
)prop
->p
)(prop
,action
,arg
,ctx
);
26 char* m_property_print(m_option_t
* prop
, void *ctx
) {
27 m_property_ctrl_f ctrl
;
31 if(!prop
) return NULL
;
34 // look if the property have it's own print func
35 if(ctrl(prop
,M_PROPERTY_PRINT
,&ret
, ctx
) >= 0)
37 // fallback on the default print for this type
38 val
= calloc(1,prop
->type
->size
);
39 if(ctrl(prop
,M_PROPERTY_GET
,val
,ctx
) <= 0) {
43 ret
= m_option_print(prop
,val
);
45 return ret
== (char*)-1 ? NULL
: ret
;
48 int m_property_parse(m_option_t
* prop
, char* txt
, void *ctx
) {
49 m_property_ctrl_f ctrl
;
53 if(!prop
) return M_PROPERTY_UNKNOWN
;
56 // try the property own parsing func
57 if((r
= ctrl(prop
,M_PROPERTY_PARSE
,txt
,ctx
)) != M_PROPERTY_NOT_IMPLEMENTED
)
59 // fallback on the default
60 val
= calloc(1,prop
->type
->size
);
61 if((r
= m_option_parse(prop
,prop
->name
,txt
,val
,M_CONFIG_FILE
)) <= 0) {
65 r
= ctrl(prop
,M_PROPERTY_SET
,val
,ctx
);
66 m_option_free(prop
,val
);
71 char* m_properties_expand_string(m_option_t
* prop_list
,char* str
, void *ctx
) {
72 int l
,fr
=0,pos
=0,size
=strlen(str
)+512;
73 char *p
= NULL
,*e
,*ret
= malloc(size
), num_val
;
74 int skip
= 0, lvl
= 0, skip_lvl
= 0;
81 p
= "\x1b", l
= 1; break;
83 p
= "\n", l
= 1; break;
85 p
= "\r", l
= 1; break;
87 p
= "\t", l
= 1; break;
90 char num
[3] = { str
[2], str
[3], 0 };
92 num_val
= strtol(num
,&end
,16);
103 } else if(lvl
> 0 && str
[0] == ')') {
104 if(skip
&& lvl
<= skip_lvl
) skip
= 0;
106 } else if(str
[0] == '$' && str
[1] == '{' && (e
= strchr(str
+2,'}'))) {
110 memcpy(pname
,str
+2,pl
);
112 if((prop
= m_option_list_find(prop_list
,pname
)) &&
113 (p
= m_property_print(prop
, ctx
)))
114 l
= strlen(p
), fr
= 1;
118 } else if(str
[0] == '?' && str
[1] == '(' && (e
= strchr(str
+2,':'))) {
124 memcpy(pname
,str
+2,pl
);
126 if(!(prop
= m_option_list_find(prop_list
,pname
)) ||
127 m_property_do(prop
,M_PROPERTY_GET
,NULL
, ctx
) < 0)
128 skip
= 1, skip_lvl
= lvl
;
132 p
= str
, l
= 1, str
++;
134 if(skip
|| l
<= 0) continue;
138 ret
= realloc(ret
,size
);
142 if(fr
) free(p
), fr
= 0;
149 void m_properties_print_help_list(m_option_t
* list
) {
150 char min
[50],max
[50];
153 mp_msg(MSGT_CFGPARSER
, MSGL_INFO
, MSGTR_PropertyListHeader
);
154 for(i
= 0 ; list
[i
].name
; i
++) {
155 m_option_t
* opt
= &list
[i
];
156 if(opt
->flags
& M_OPT_MIN
)
157 sprintf(min
,"%-8.0f",opt
->min
);
160 if(opt
->flags
& M_OPT_MAX
)
161 sprintf(max
,"%-8.0f",opt
->max
);
164 mp_msg(MSGT_CFGPARSER
, MSGL_INFO
, " %-20.20s %-15.15s %-10.10s %-10.10s\n",
171 mp_msg(MSGT_CFGPARSER
, MSGL_INFO
, MSGTR_TotalProperties
, count
);
174 // Some generic property implementations
176 int m_property_int_ro(m_option_t
* prop
,int action
,
184 return M_PROPERTY_NOT_IMPLEMENTED
;
187 int m_property_int_range(m_option_t
* prop
,int action
,
188 void* arg
,int* var
) {
192 M_PROPERTY_CLAMP(prop
,*(int*)arg
);
195 case M_PROPERTY_STEP_UP
:
196 case M_PROPERTY_STEP_DOWN
:
197 *var
+= (arg
? *(int*)arg
: 1) *
198 (action
== M_PROPERTY_STEP_DOWN
? -1 : 1);
199 M_PROPERTY_CLAMP(prop
,*var
);
202 return m_property_int_ro(prop
,action
,arg
,*var
);
205 int m_property_choice(m_option_t
* prop
,int action
,
206 void* arg
,int* var
) {
208 case M_PROPERTY_STEP_UP
:
209 case M_PROPERTY_STEP_DOWN
:
210 *var
+= action
== M_PROPERTY_STEP_UP
? 1 : prop
->max
;
211 *var
%= (int)prop
->max
+1;
214 return m_property_int_range(prop
,action
,arg
,var
);
217 int m_property_flag(m_option_t
* prop
,int action
,
218 void* arg
,int* var
) {
220 case M_PROPERTY_STEP_UP
:
221 case M_PROPERTY_STEP_DOWN
:
222 *var
= *var
== prop
->min
? prop
->max
: prop
->min
;
224 case M_PROPERTY_PRINT
:
226 *(char**)arg
= strdup((*var
> prop
->min
) ? MSGTR_Enabled
: MSGTR_Disabled
);
229 return m_property_int_range(prop
,action
,arg
,var
);
232 int m_property_float_ro(m_option_t
* prop
,int action
,
233 void* arg
,float var
) {
239 case M_PROPERTY_PRINT
:
241 *(char**)arg
= malloc(20);
242 sprintf(*(char**)arg
,"%.2f",var
);
245 return M_PROPERTY_NOT_IMPLEMENTED
;
248 int m_property_float_range(m_option_t
* prop
,int action
,
249 void* arg
,float* var
) {
253 M_PROPERTY_CLAMP(prop
,*(float*)arg
);
256 case M_PROPERTY_STEP_UP
:
257 case M_PROPERTY_STEP_DOWN
:
258 *var
+= (arg
? *(float*)arg
: 0.1) *
259 (action
== M_PROPERTY_STEP_DOWN
? -1 : 1);
260 M_PROPERTY_CLAMP(prop
,*var
);
263 return m_property_float_ro(prop
,action
,arg
,*var
);
266 int m_property_delay(m_option_t
* prop
,int action
,
267 void* arg
,float* var
) {
269 case M_PROPERTY_PRINT
:
271 *(char**)arg
= malloc(20);
272 sprintf(*(char**)arg
,"%d ms",ROUND((*var
)*1000));
275 return m_property_float_range(prop
,action
,arg
,var
);
279 int m_property_double_ro(m_option_t
* prop
,int action
,
280 void* arg
,double var
) {
286 case M_PROPERTY_PRINT
:
288 *(char**)arg
= malloc(20);
289 sprintf(*(char**)arg
,"%.2f",var
);
292 return M_PROPERTY_NOT_IMPLEMENTED
;
295 int m_property_string_ro(m_option_t
* prop
,int action
,void* arg
,char* str
) {
301 case M_PROPERTY_PRINT
:
303 *(char**)arg
= str
? strdup(str
) : NULL
;
306 return M_PROPERTY_NOT_IMPLEMENTED
;