1 /*
2 * Compiz configuration system library
3 *
4 * Copyright (C) 2007 Dennis Kasprzyk <onestone@opencompositing.org>
5 * Copyright (C) 2007 Danny Baumann <maniac@opencompositing.org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #define _GNU_SOURCE
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdlib.h>
26
27 #include <ccs.h>
28
29 #include "ccs-private.h"
30
31 typedef void (*freeFunc) (void *ptr);
32
33 #define CCSLIST(type,dtype,ocomp,compfunc) \
34 \
35 CCS##type##List ccs##type##ListAppend (CCS##type##List list, dtype *data) \
36 { \
37 CCS##type##List l = list; \
38 CCS##type##List ne = malloc(sizeof(struct _CCS##type##List)); \
39 if (!ne) \
40 return list; \
41 ne->data = data; \
42 ne->next = NULL; \
43 if (!list) \
44 return ne; \
45 while (l->next) l = l->next; \
46 l->next = ne; \
47 return list; \
48 } \
49 \
50 CCS##type##List ccs##type##ListPrepend (CCS##type##List list, dtype *data) \
51 { \
52 CCS##type##List ne = malloc(sizeof(struct _CCS##type##List)); \
53 if (!ne) \
54 return list; \
55 ne->data = data; \
56 ne->next = list; \
57 return ne; \
58 } \
59 \
60 CCS##type##List ccs##type##ListInsert (CCS##type##List list, dtype *data, int position) \
61 { \
62 CCS##type##List l = list; \
63 CCS##type##List ne = malloc(sizeof(struct _CCS##type##List)); \
64 if (!ne) \
65 return list; \
66 ne->data = data; \
67 ne->next = list; \
68 if (!list || !position) \
69 return ne; \
70 position--; \
71 while (l->next && position) \
72 { \
73 l = l->next; \
74 position--; \
75 } \
76 ne->next = l->next; \
77 l->next = ne; \
78 return list; \
79 } \
80 \
81 CCS##type##List ccs##type##ListInsertBefore (CCS##type##List list, CCS##type##List sibling, dtype *data) \
82 { \
83 CCS##type##List l = list; \
84 CCS##type##List ne = malloc(sizeof(struct _CCS##type##List)); \
85 if (!ne) \
86 return list; \
87 while (l && (l != sibling)) l = l->next; \
88 ne->data = data; \
89 ne->next = l; \
90 return ne; \
91 } \
92 \
93 unsigned int ccs##type##ListLength (CCS##type##List list) \
94 { \
95 unsigned int count = 0; \
96 CCS##type##List l = list; \
97 while (l) \
98 { \
99 l = l->next; \
100 count++; \
101 } \
102 return count; \
103 } \
104 \
105 CCS##type##List ccs##type##ListFind (CCS##type##List list, dtype *data) \
106 { \
107 CCS##type##List l = list; \
108 while (l) \
109 { \
110 if (!data && !l->data) break; \
111 if ((ocomp)?(compfunc):(memcmp(l->data, data, sizeof(dtype)) == 0)) break; \
112 l = l->next; \
113 } \
114 return l; \
115 } \
116 \
117 CCS##type##List ccs##type##ListGetItem (CCS##type##List list, unsigned int index) \
118 { \
119 CCS##type##List l = list; \
120 while (l && index) \
121 { \
122 l = l->next; \
123 index--; \
124 } \
125 return l; \
126 } \
127 \
128 CCS##type##List ccs##type##ListRemove (CCS##type##List list, dtype *data, Bool freeObj) \
129 { \
130 CCS##type##List l = list; \
131 CCS##type##List prev = NULL; \
132 Bool found = FALSE; \
133 if (!data) \
134 return list; \
135 while (l) \
136 { \
137 if (!l->data) continue; \
138 if ((ocomp)?(compfunc):(memcmp(l->data, data, sizeof(dtype)) == 0)) \
139 { \
140 found = TRUE; \
141 break; \
142 } \
143 prev = l; \
144 l = l->next; \
145 } \
146 if (!found) \
147 return list; \
148 if (l) \
149 { \
150 if (prev) prev->next = l->next; \
151 else list = l->next; \
152 if (freeObj) \
153 ccsFree##type (l->data); \
154 free (l); \
155 } \
156 return list; \
157 } \
158 \
159 CCS##type##List ccs##type##ListFree (CCS##type##List list, Bool freeObj) \
160 { \
161 CCS##type##List l = list; \
162 CCS##type##List le = NULL; \
163 while (l) \
164 { \
165 le = l; \
166 l = l->next; \
167 if (freeObj) \
168 ccsFree##type (le->data); \
169 free(le); \
170 } \
171 return NULL; \
172 }
173
174 CCSLIST (Plugin, CCSPlugin, FALSE, 0)
175 CCSLIST (Setting, CCSSetting, FALSE, 0)
176 CCSLIST (String, char, TRUE, strcmp (data, l->data) == 0)
177 CCSLIST (Group, CCSGroup, FALSE, 0)
178 CCSLIST (SubGroup, CCSSubGroup, FALSE, 0)
179 CCSLIST (SettingValue, CCSSettingValue, FALSE, 0)
180 CCSLIST (PluginConflict, CCSPluginConflict, FALSE, 0)
181 CCSLIST (BackendInfo, CCSBackendInfo, FALSE, 0)
182 CCSLIST (IntDesc, CCSIntDesc, FALSE, 0)
183 CCSLIST (StrRestriction, CCSStrRestriction, FALSE, 0)
184 CCSLIST (StrExtension, CCSStrExtension, FALSE, 0)
185
ccsGetValueListFromStringList(CCSStringList list,CCSSetting * parent)186 CCSSettingValueList ccsGetValueListFromStringList (CCSStringList list,
187 CCSSetting *parent)
188 {
189 CCSSettingValueList rv = NULL;
190
191 while (list)
192 {
193 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
194 if (!value)
195 return rv;
196
197 value->isListChild = TRUE;
198 value->parent = parent;
199 value->value.asString = strdup (list->data);
200 rv = ccsSettingValueListAppend (rv, value);
201 list = list->next;
202 }
203
204 return rv;
205 }
206
ccsGetStringListFromValueList(CCSSettingValueList list)207 CCSStringList ccsGetStringListFromValueList (CCSSettingValueList list)
208 {
209 CCSStringList rv = NULL;
210
211 while (list)
212 {
213 rv = ccsStringListAppend (rv, strdup (list->data->value.asString) );
214 list = list->next;
215 }
216
217 return rv;
218 }
219
ccsGetStringArrayFromList(CCSStringList list,int * num)220 char ** ccsGetStringArrayFromList (CCSStringList list, int *num)
221 {
222 char ** rv = NULL;
223 int length = ccsStringListLength (list);
224 int i;
225
226 if (length)
227 {
228 rv = calloc (length, sizeof (char *));
229 if (!rv)
230 return NULL;
231 }
232
233 for (i = 0; i < length; i++, list = list->next)
234 rv[i] = strdup (list->data);
235
236 *num = length;
237
238 return rv;
239 }
240
ccsGetListFromStringArray(char ** array,int num)241 CCSStringList ccsGetListFromStringArray (char ** array, int num)
242 {
243 CCSStringList rv = NULL;
244 int i;
245
246 for (i = 0; i < num; i++)
247 rv = ccsStringListAppend (rv, strdup (array[i]) );
248
249 return rv;
250 }
251
ccsGetStringArrayFromValueList(CCSSettingValueList list,int * num)252 char ** ccsGetStringArrayFromValueList (CCSSettingValueList list, int *num)
253 {
254 char ** rv = NULL;
255 int length = ccsSettingValueListLength (list);
256 int i;
257
258 if (length)
259 {
260 rv = calloc (length, sizeof (char *));
261 if (!rv)
262 return NULL;
263 }
264
265 for (i = 0; i < length; i++, list = list->next)
266 rv[i] = strdup (list->data->value.asString);
267
268 *num = length;
269
270 return rv;
271 }
272
ccsGetMatchArrayFromValueList(CCSSettingValueList list,int * num)273 char ** ccsGetMatchArrayFromValueList (CCSSettingValueList list, int *num)
274 {
275 char ** rv = NULL;
276 int length = ccsSettingValueListLength (list);
277 int i;
278
279 if (length)
280 {
281 rv = calloc (length, sizeof (char *));
282 if (!rv)
283 return NULL;
284 }
285
286 for (i = 0; i < length; i++, list = list->next)
287 rv[i] = strdup (list->data->value.asMatch);
288
289 *num = length;
290
291 return rv;
292 }
293
ccsGetIntArrayFromValueList(CCSSettingValueList list,int * num)294 int * ccsGetIntArrayFromValueList (CCSSettingValueList list, int *num)
295 {
296 int * rv = NULL;
297 int length = ccsSettingValueListLength (list);
298 int i;
299
300 if (length)
301 {
302 rv = calloc (length, sizeof (int));
303 if (!rv)
304 return NULL;
305 }
306
307 for (i = 0; i < length; i++, list = list->next)
308 rv[i] = list->data->value.asInt;
309
310 *num = length;
311
312 return rv;
313 }
314
ccsGetFloatArrayFromValueList(CCSSettingValueList list,int * num)315 float * ccsGetFloatArrayFromValueList (CCSSettingValueList list, int *num)
316 {
317 float * rv = NULL;
318 int length = ccsSettingValueListLength (list);
319 int i;
320
321 if (length)
322 {
323 rv = calloc (length, sizeof (float));
324 if (!rv)
325 return NULL;
326 }
327
328 for (i = 0; i < length; i++, list = list->next)
329 rv[i] = list->data->value.asFloat;
330
331 *num = length;
332
333 return rv;
334 }
335
ccsGetBoolArrayFromValueList(CCSSettingValueList list,int * num)336 Bool * ccsGetBoolArrayFromValueList (CCSSettingValueList list, int *num)
337 {
338 Bool * rv = NULL;
339 int length = ccsSettingValueListLength (list);
340 int i;
341
342 if (length)
343 {
344 rv = calloc (length, sizeof (Bool));
345 if (!rv)
346 return NULL;
347 }
348
349 for (i = 0; i < length; i++, list = list->next)
350 rv[i] = list->data->value.asBool;
351
352 *num = length;
353
354 return rv;
355 }
356
ccsGetColorArrayFromValueList(CCSSettingValueList list,int * num)357 CCSSettingColorValue * ccsGetColorArrayFromValueList (CCSSettingValueList list,
358 int *num)
359 {
360 CCSSettingColorValue * rv = NULL;
361 int length = ccsSettingValueListLength (list);
362 int i;
363
364 if (length)
365 {
366 rv = calloc (length, sizeof (CCSSettingColorValue));
367 if (!rv)
368 return NULL;
369 }
370
371 for (i = 0; i < length; i++, list = list->next)
372 memcpy (&rv[i], &list->data->value.asColor,
373 sizeof (CCSSettingColorValue));
374
375 *num = length;
376
377 return rv;
378 }
379
ccsGetValueListFromStringArray(char ** array,int num,CCSSetting * parent)380 CCSSettingValueList ccsGetValueListFromStringArray (char ** array, int num,
381 CCSSetting *parent)
382 {
383 CCSSettingValueList l = NULL;
384 int i;
385
386 for (i = 0; i < num; i++)
387 {
388 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
389 if (!value)
390 return l;
391
392 value->isListChild = TRUE;
393 value->parent = parent;
394 value->value.asString = strdup (array[i]);
395 l = ccsSettingValueListAppend (l, value);
396 }
397
398 return l;
399 }
400
ccsGetValueListFromMatchArray(char ** array,int num,CCSSetting * parent)401 CCSSettingValueList ccsGetValueListFromMatchArray (char ** array, int num,
402 CCSSetting *parent)
403 {
404 CCSSettingValueList l = NULL;
405 int i;
406
407 for (i = 0; i < num; i++)
408 {
409 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
410 if (!value)
411 return l;
412
413 value->isListChild = TRUE;
414 value->parent = parent;
415 value->value.asMatch = strdup (array[i]);
416 l = ccsSettingValueListAppend (l, value);
417 }
418
419 return l;
420 }
421
ccsGetValueListFromIntArray(int * array,int num,CCSSetting * parent)422 CCSSettingValueList ccsGetValueListFromIntArray (int * array, int num,
423 CCSSetting *parent)
424 {
425 CCSSettingValueList l = NULL;
426 int i;
427
428 for (i = 0; i < num; i++)
429 {
430 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
431 if (!value)
432 return l;
433
434 value->isListChild = TRUE;
435 value->parent = parent;
436 value->value.asInt = array[i];
437 l = ccsSettingValueListAppend (l, value);
438 }
439
440 return l;
441 }
442
ccsGetValueListFromFloatArray(float * array,int num,CCSSetting * parent)443 CCSSettingValueList ccsGetValueListFromFloatArray (float * array, int num,
444 CCSSetting *parent)
445 {
446 CCSSettingValueList l = NULL;
447 int i;
448
449 for (i = 0; i < num; i++)
450 {
451 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
452 if (!value)
453 return l;
454
455 value->isListChild = TRUE;
456 value->parent = parent;
457 value->value.asFloat = array[i];
458 l = ccsSettingValueListAppend (l, value);
459 }
460
461 return l;
462 }
463
ccsGetValueListFromBoolArray(Bool * array,int num,CCSSetting * parent)464 CCSSettingValueList ccsGetValueListFromBoolArray (Bool * array, int num,
465 CCSSetting *parent)
466 {
467 CCSSettingValueList l = NULL;
468 int i;
469
470 for (i = 0; i < num; i++)
471 {
472 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
473 if (!value)
474 return l;
475
476 value->isListChild = TRUE;
477 value->parent = parent;
478 value->value.asBool = array[i];
479 l = ccsSettingValueListAppend (l, value);
480 }
481
482 return l;
483 }
484
ccsGetValueListFromColorArray(CCSSettingColorValue * array,int num,CCSSetting * parent)485 CCSSettingValueList ccsGetValueListFromColorArray (CCSSettingColorValue * array,
486 int num, CCSSetting *parent)
487 {
488 CCSSettingValueList l = NULL;
489 int i;
490
491 for (i = 0; i < num; i++)
492 {
493 CCSSettingValue *value = calloc (1, sizeof (CCSSettingValue));
494 if (!value)
495 return l;
496
497 value->isListChild = TRUE;
498 value->parent = parent;
499 value->value.asColor = array[i];
500 l = ccsSettingValueListAppend (l, value);
501 }
502
503 return l;
504 }
505
506