File: schemes.c

package info (click to toggle)
lebiniou 3.18-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 5,396 kB
  • sloc: ansic: 20,369; sh: 4,169; makefile: 834; awk: 194
file content (255 lines) | stat: -rw-r--r-- 6,829 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/*
 *  Copyright 1994-2012 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "schemes.h"
#include "globals.h"
#include "xmlutils.h"


static enum PluginOptions
Schemes_parse_one_option(const char *opt)
{
  if (!strcmp(opt, "SFX2D")) return BE_SFX2D;
  if (!strcmp(opt, "SFX3D")) return BE_SFX3D;
  if (!strcmp(opt, "GFX")) return BE_GFX;
  if (!strcmp(opt, "BLUR")) return BE_BLUR;
  if (!strcmp(opt, "DISPLACE")) return BE_DISPLACE;
  if (!strcmp(opt, "LENS")) return BE_LENS;
  if (!strcmp(opt, "SCROLL")) return BE_SCROLL;
  if (!strcmp(opt, "MIRROR")) return BE_MIRROR;
  if (!strcmp(opt, "ROLL")) return BE_ROLL;
  if (!strcmp(opt, "WARP")) return BE_WARP;
  if (!strcmp(opt, "CLEAN")) return BE_CLEAN;
  if (!strcmp(opt, "HOR")) return BEQ_HOR;
  if (!strcmp(opt, "VER")) return BEQ_VER;
  if (!strcmp(opt, "DIAG")) return BEQ_DIAG;
  if (!strcmp(opt, "UP")) return BEQ_UP;
  if (!strcmp(opt, "DOWN")) return BEQ_DOWN;
  if (!strcmp(opt, "LEFT")) return BEQ_LEFT;
  if (!strcmp(opt, "RIGHT")) return BEQ_RIGHT;
  if (!strcmp(opt, "COLORMAP")) return BEQ_COLORMAP;
  if (!strcmp(opt, "PARTICLES")) return BEQ_PARTICLES;
  if (!strcmp(opt, "SPLASH")) return BEQ_SPLASH;
  /*  if (!strcmp(opt, "THREAD")) return BEQ_THREAD; */ /* can not occur in a scheme */
  if (!strcmp(opt, "PICTURE")) return BEQ_PICTURE;
  /*  if (!strcmp(opt, "NORANDOM")) return BEQ_NORANDOM; */ /* can not occur in a scheme */
  /*  if (!strcmp(opt, "DISABLED")) return BEQ_DISABLED; */ /* idem */
  if (!strcmp(opt, "3D")) return BEQ_3D;
  if (!strcmp(opt, "UNIQUE")) return BEQ_UNIQUE;
  if (!strcmp(opt, "TEST")) return BEQ_TEST;
  if (!strcmp(opt, "DEBUG")) return BEQ_DEBUG;
  if (!strcmp(opt, "FIRST")) return BEQ_FIRST;
  if (!strcmp(opt, "FLUSH")) return BEQ_FLUSH;
  /*  if (!strcmp(opt, "NONE")) return BE_NONE; */ /* can not occur in a scheme */

  xerror("[!] Failed to parse option '%s'\n", opt);

  return BE_NONE; /* not reached */
}


static enum PluginOptions
Schemes_parse_option(const char *opt)
{
  int o = 0;
  char *pipe = NULL;

  while ((pipe = strchr(opt, '|')) != NULL) {
    *pipe = '\0';
    if (*opt == '-') {
      opt++;
      o |= -Schemes_parse_one_option(opt);
    } else
      o |= Schemes_parse_one_option(opt);
    opt = pipe + sizeof(char);
  }

  if (*opt == '-') {
    opt++;
    o |= -Schemes_parse_one_option(opt);
  } else
    o |= Schemes_parse_one_option(opt);

  return (enum PluginOptions)o;
}


static u_short
Schemes_parse(Schemes_t *schemes, const xmlDocPtr doc)
{
  xmlNodePtr schemes_node = NULL, scheme_node = NULL;
  u_short size = 0, i;
  xmlChar *wizz;

  /* Start at Root Element */
  schemes_node = xmlDocGetRootElement(doc);
  if (schemes_node == NULL)
    xerror("xmlDocGetRootElement error\n");

  schemes_node = xmlFindElement("schemes", schemes_node);
  if (schemes_node == NULL) {
    printf("[!] No <schemes> found\n");
    return 0;
  }

  wizz = xmlGetProp(schemes_node, (const xmlChar *)"size");
  size = (u_short)getintfield(wizz);
  xmlFree(wizz);
  assert(size > 0);

  schemes->schemes = xcalloc(size, sizeof(SchemeItem_t *));

  scheme_node = schemes_node->xmlChildrenNode;
  for (i = 0; i < size; i++) {
    int length, j;
    xmlNodePtr type_node = NULL;

    scheme_node = xmlFindElement("scheme", scheme_node);
    if (scheme_node == NULL) {
      printf("[!] No <scheme> found\n");
      return 0;
    }

    /* XXX use getinitfield_mandatory */
    wizz = xmlGetProp(scheme_node, (const xmlChar *)"length");
    length = getintfield(wizz);
    xmlFree(wizz);
    assert(length > 0);

    schemes->schemes[i] = xcalloc(length+1, sizeof(SchemeItem_t));

    type_node = scheme_node->xmlChildrenNode;
    for (j = 0; j < length; j++) {
      int res;
      float p;
      enum PluginOptions o;
      xmlChar *token;

      type_node = xmlFindElement("type", type_node);
      if (type_node == NULL) {
	int k;

	printf("[!] No <type> found\n");
	for (k = 0; k <= i; k++)
	  xfree(schemes->schemes[k]);
	xfree(schemes->schemes);

	return 0;
      }

      wizz = xmlGetProp(type_node, (const xmlChar *)"proba");
      res = getfloatfield_optional(wizz, &p);
      xmlFree(wizz);
      if (res == -1)
	p = 1.0;

      token = xmlNodeListGetString(doc, type_node->xmlChildrenNode, 1);
      if (token == NULL)
	xerror("No data in <type> element\n");

      o = Schemes_parse_option((const char *)token);
#ifdef XDEBUG
      printf("%d:%d/%d TOKEN: %f / %s => %d\n", i, j, length, p, token, (int)o);
#endif
      xmlFree(token);

      schemes->schemes[i][j].p = p;
      schemes->schemes[i][j].type = o;

      type_node = type_node->next;
    }
    
    scheme_node = scheme_node->next;
  }

  return size;
}


void
Schemes_new(const char *file)
{
  xmlDocPtr doc = NULL; /* XmlTree */

  if (NULL == file)
    xerror("Schemes_new() called but file is NULL\n");

  schemes = xcalloc(1, sizeof(Schemes_t));

  /* BLA ! */
  xmlKeepBlanksDefault(0);
  
  /*
   * build an XML tree from the file
   */
  doc = xmlParseFile(file);
  if (doc == NULL) {
    printf("[!] xmlParseFile '%s' error\n", file);
    printf("[!] No schemes loaded\n");
    xfree(schemes);
    return;
  }

  schemes->size = Schemes_parse(schemes, doc);
  xmlFreeDoc(doc);

  if (!schemes->size) {
    if (libbiniou_verbose)
      printf("[!] No schemes loaded\n");
    xfree(schemes); /* xfree sets the pointer to NULL */
  } else {
    if (libbiniou_verbose)
      printf("[i] Loaded %d scheme%s\n", schemes->size, (schemes->size == 1) ? "": "s");
  }

  schemes->shuffler = Shuffler_new(schemes->size);
  Shuffler_verbose(schemes->shuffler);
}


void
Schemes_new_default()
{
  schemes = xcalloc(1, sizeof(Schemes_t));
  schemes->size = 1;

  schemes->schemes = xcalloc(1, sizeof(SchemeItem_t *));
  schemes->schemes[0] = xcalloc(2, sizeof(SchemeItem_t));

  schemes->schemes[0][0].p = 1.0;
  schemes->schemes[0][0].type = BEQ_UNIQUE;

  schemes->shuffler = NULL;
}


void
Schemes_delete()
{
  if (schemes != NULL) {
    u_short i;
    
    for (i = 0; i < schemes->size; i++)
      xfree(schemes->schemes[i]);
    xfree(schemes->schemes);
    if (NULL != schemes->shuffler)
      Shuffler_delete(schemes->shuffler);
    xfree(schemes);
  }
}