comparison 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
comparison
equal deleted inserted replaced
17910:5ae29dc47c17 17911:52f95509cd05
1
2 #include "config.h"
3
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <inttypes.h>
8 #include <unistd.h>
9
10 #include "m_option.h"
11 #include "m_property.h"
12 #include "help_mp.h"
13
14 #define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5))
15
16 int m_property_do(m_option_t* prop, int action, void* arg) {
17 if(!prop) return M_PROPERTY_UNKNOWN;
18 return ((m_property_ctrl_f)prop->p)(prop,action,arg);
19 }
20
21
22 char* m_property_print(m_option_t* prop) {
23 m_property_ctrl_f ctrl;
24 void* val;
25 char* ret;
26
27 if(!prop) return NULL;
28
29 ctrl = prop->p;
30 // look if the property have it's own print func
31 if(ctrl(prop,M_PROPERTY_PRINT,&ret) >= 0)
32 return ret;
33 // fallback on the default print for this type
34 val = calloc(1,prop->type->size);
35 if(ctrl(prop,M_PROPERTY_GET,val) <= 0) {
36 free(val);
37 return NULL;
38 }
39 ret = m_option_print(prop,val);
40 free(val);
41 return ret == (char*)-1 ? NULL : ret;
42 }
43
44 int m_property_parse(m_option_t* prop, char* txt) {
45 m_property_ctrl_f ctrl;
46 void* val;
47 int r;
48
49 if(!prop) return M_PROPERTY_UNKNOWN;
50
51 ctrl = prop->p;
52 // try the property own parsing func
53 if((r = ctrl(prop,M_PROPERTY_PARSE,txt)) != M_PROPERTY_NOT_IMPLEMENTED)
54 return r;
55 // fallback on the default
56 val = calloc(1,prop->type->size);
57 if((r = m_option_parse(prop,prop->name,txt,val,M_CONFIG_FILE)) <= 0) {
58 free(val);
59 return r;
60 }
61 r = ctrl(prop,M_PROPERTY_SET,val);
62 m_option_free(prop,val);
63 free(val);
64 return r;
65 }
66
67 char* m_properties_expand_string(m_option_t* prop_list,char* str) {
68 int l,fr=0,pos=0,size=strlen(str)+512;
69 char *p = NULL,*e,*ret = malloc(size), num_val;
70 int skip = 0, lvl = 0, skip_lvl = 0;
71
72 while(str[0]) {
73 if(str[0] == '\\') {
74 int sl = 1;
75 switch(str[1]) {
76 case 'e':
77 p = "\x1b", l = 1; break;
78 case 'n':
79 p = "\n", l = 1; break;
80 case 'r':
81 p = "\r", l = 1; break;
82 case 't':
83 p = "\t", l = 1; break;
84 case 'x':
85 if(str[2]) {
86 char num[3] = { str[2], str[3], 0 };
87 char* end = num;
88 num_val = strtol(num,&end,16);
89 sl = end-num;
90 l = 1;
91 p = &num_val;
92 } else
93 l = 0;
94 break;
95 default:
96 p = str+1, l = 1;
97 }
98 str+=1+sl;
99 } else if(lvl > 0 && str[0] == ')') {
100 if(skip && lvl <= skip_lvl) skip = 0;
101 lvl--, str++, l = 0;
102 } else if(str[0] == '$' && str[1] == '{' && (e = strchr(str+2,'}'))) {
103 int pl = e-str-2;
104 char pname[pl+1];
105 m_option_t* prop;
106 memcpy(pname,str+2,pl);
107 pname[pl] = 0;
108 if((prop = m_option_list_find(prop_list,pname)) &&
109 (p = m_property_print(prop)))
110 l = strlen(p), fr = 1;
111 else
112 l = 0;
113 str = e+1;
114 } else if(str[0] == '?' && str[1] == '(' && (e = strchr(str+2,':'))) {
115 int pl = e-str-2;
116 char pname[pl+1];
117 m_option_t* prop;
118 lvl++;
119 if(!skip) {
120 memcpy(pname,str+2,pl);
121 pname[pl] = 0;
122 if(!(prop = m_option_list_find(prop_list,pname)) ||
123 m_property_do(prop,M_PROPERTY_GET,NULL) < 0)
124 skip = 1, skip_lvl = lvl;
125 }
126 str = e+1, l = 0;
127 } else
128 p = str, l = 1, str++;
129
130 if(skip || l <= 0) continue;
131
132 if(pos+l+1 > size) {
133 size = pos+l+512;
134 ret = realloc(ret,size);
135 }
136 memcpy(ret+pos,p,l);
137 pos += l;
138 if(fr) free(p), fr = 0;
139 }
140
141 ret[pos] = 0;
142 return ret;
143 }
144
145 // Some generic property implementations
146
147 int m_property_int_ro(m_option_t* prop,int action,
148 void* arg,int var) {
149 switch(action) {
150 case M_PROPERTY_GET:
151 if(!arg) return 0;
152 *(int*)arg = var;
153 return 1;
154 }
155 return M_PROPERTY_NOT_IMPLEMENTED;
156 }
157
158 int m_property_int_range(m_option_t* prop,int action,
159 void* arg,int* var) {
160 switch(action) {
161 case M_PROPERTY_SET:
162 if(!arg) return 0;
163 M_PROPERTY_CLAMP(prop,*(int*)arg);
164 *var = *(int*)arg;
165 return 1;
166 case M_PROPERTY_STEP_UP:
167 case M_PROPERTY_STEP_DOWN:
168 *var += (arg ? *(int*)arg : 1) *
169 (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
170 M_PROPERTY_CLAMP(prop,*var);
171 return 1;
172 }
173 return m_property_int_ro(prop,action,arg,*var);
174 }
175
176 int m_property_choice(m_option_t* prop,int action,
177 void* arg,int* var) {
178 switch(action) {
179 case M_PROPERTY_STEP_UP:
180 case M_PROPERTY_STEP_DOWN:
181 *var += action == M_PROPERTY_STEP_UP ? 1 : prop->max;
182 *var %= (int)prop->max+1;
183 return 1;
184 }
185 return m_property_int_range(prop,action,arg,var);
186 }
187
188 int m_property_flag(m_option_t* prop,int action,
189 void* arg,int* var) {
190 switch(action) {
191 case M_PROPERTY_STEP_UP:
192 case M_PROPERTY_STEP_DOWN:
193 *var = *var == prop->min ? prop->max : prop->min;
194 return 1;
195 case M_PROPERTY_PRINT:
196 if(!arg) return 0;
197 *(char**)arg = strdup((*var > prop->min) ? MSGTR_Enabled : MSGTR_Disabled);
198 return 1;
199 }
200 return m_property_int_range(prop,action,arg,var);
201 }
202
203 int m_property_float_ro(m_option_t* prop,int action,
204 void* arg,float var) {
205 switch(action) {
206 case M_PROPERTY_GET:
207 if(!arg) return 0;
208 *(float*)arg = var;
209 return 1;
210 case M_PROPERTY_PRINT:
211 if(!arg) return 0;
212 *(char**)arg = malloc(20);
213 sprintf(*(char**)arg,"%.2f",var);
214 return 1;
215 }
216 return M_PROPERTY_NOT_IMPLEMENTED;
217 }
218
219 int m_property_float_range(m_option_t* prop,int action,
220 void* arg,float* var) {
221 switch(action) {
222 case M_PROPERTY_SET:
223 if(!arg) return 0;
224 M_PROPERTY_CLAMP(prop,*(float*)arg);
225 *var = *(float*)arg;
226 return 1;
227 case M_PROPERTY_STEP_UP:
228 case M_PROPERTY_STEP_DOWN:
229 *var += (arg ? *(float*)arg : 0.1) *
230 (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
231 M_PROPERTY_CLAMP(prop,*var);
232 return 1;
233 }
234 return m_property_float_ro(prop,action,arg,*var);
235 }
236
237 int m_property_delay(m_option_t* prop,int action,
238 void* arg,float* var) {
239 switch(action) {
240 case M_PROPERTY_PRINT:
241 if(!arg) return 0;
242 *(char**)arg = malloc(20);
243 sprintf(*(char**)arg,"%d ms",ROUND((*var)*1000));
244 return 1;
245 default:
246 return m_property_float_range(prop,action,arg,var);
247 }
248 }
249
250 int m_property_double_ro(m_option_t* prop,int action,
251 void* arg,double var) {
252 switch(action) {
253 case M_PROPERTY_GET:
254 if(!arg) return 0;
255 *(double*)arg = var;
256 return 1;
257 case M_PROPERTY_PRINT:
258 if(!arg) return 0;
259 *(char**)arg = malloc(20);
260 sprintf(*(char**)arg,"%.2f",var);
261 return 1;
262 }
263 return M_PROPERTY_NOT_IMPLEMENTED;
264 }
265
266 int m_property_string_ro(m_option_t* prop,int action,void* arg,char* str) {
267 switch(action) {
268 case M_PROPERTY_GET:
269 if(!arg) return 0;
270 *(char**)arg = str;
271 return 1;
272 case M_PROPERTY_PRINT:
273 if(!arg) return 0;
274 *(char**)arg = str ? strdup(str) : NULL;
275 return 1;
276 }
277 return M_PROPERTY_NOT_IMPLEMENTED;
278 }