f92ae3aeb9ae4a8cbdff60685a67e7824d3d3a97
[src/app-framework-main.git] / wgt-config-xml.c
1 /*
2  Copyright 2015 IoT.bzh
3
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8      http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16
17 #include <unistd.h>
18 #include <string.h>
19 #include <syslog.h>
20 #include <assert.h>
21 #include <errno.h>
22
23 #include <libxml/parser.h>
24 #include <libxml/tree.h>
25 #include <libxml/uri.h>
26
27
28 #include "wgt.h"
29
30 static xmlDocPtr configxml = NULL;
31
32 static xmlNodePtr next(xmlNodePtr node, const char *type)
33 {
34         while (node && node->type != XML_ELEMENT_NODE && strcmp(type, node->name))
35                 node = node->next;
36         return node;
37 }
38
39 static xmlNodePtr first(const char *type)
40 {
41         xmlNodePtr root;
42         if (configxml) {
43                 root = xmlDocGetRootElement(configxml);
44                 if (root)
45                         return next(root->children, type);
46         }
47         return NULL;
48 }
49
50 static int scorelang(xmlNodePtr node)
51 {
52         char *lang = xmlNodeGetLang(node);
53         int score = locales_score(lang);
54         xmlFree(lang);
55         return score;
56 }
57
58 static xmlNodePtr element_based_localisation(const char *type)
59 {
60         xmlNodePtr resu, elem;
61         int sr, s;
62
63         resu = first(type);
64         if (resu) {
65                 sr = scorelang(resu);
66                 elem = next(resu->next, type);
67                 while (resu) {
68                         s = scorelang(elem);
69                         if (s < sr) {
70                                 resu = elem;
71                                 sr = s;
72                         }
73                         elem = next(elem->next, type);
74                 }
75         }
76         return resu;
77 }
78
79 void confixml_close()
80 {
81         if (configxml) {
82                 xmlFreeDoc(configxml);
83                 configxml = NULL;
84         }
85 }
86
87 int confixml_open()
88 {
89         int fd;
90         assert(!configxml);
91         fd = widget_open_read(_config_xml_);
92         if (fd < 0) {
93                 syslog(LOG_ERR, "can't open config file %s", _config_xml_);
94                 return fd;
95         }
96         configxml = xmlReadFd(fd, "_config_xml_", NULL, 0);
97         close(fd);
98         if (configxml == NULL) {
99                 syslog(LOG_ERR, "xml parse of config file %s failed", _config_xml_);
100                 return -1;
101         }
102         return 0;
103 }
104
105 /* elements based on localisation */
106 xmlNodePtr confixml_name()
107 {
108         return element_based_localisation(_name_);
109 }
110
111 xmlNodePtr confixml_description()
112 {
113         return element_based_localisation(_description_);
114 }
115
116 xmlNodePtr confixml_license()
117 {
118         return element_based_localisation(_license_);
119 }
120
121 /* elements based on path localisation */
122 xmlNodePtr confixml_author()
123 {
124         return first(_author_);
125 }
126
127 xmlNodePtr confixml_content()
128 {
129         return first(_content_);
130 }
131
132 /* element multiple */
133
134 xmlNodePtr confixml_first_feature()
135 {
136         return first(_feature_);
137 }
138
139 xmlNodePtr confixml_next_feature(xmlNodePtr node)
140 {
141         return next(node->next, _feature_);
142 }
143
144 xmlNodePtr confixml_first_preference()
145 {
146         return first(_preference_);
147 }
148
149 xmlNodePtr confixml_next_preference(xmlNodePtr node)
150 {
151         return next(node->next, _preference_);
152 }
153
154 xmlNodePtr confixml_first_icon()
155 {
156         return first(_icon_);
157 }
158
159 xmlNodePtr confixml_next_icon(xmlNodePtr node)
160 {
161         return next(node->next, _icon_);
162 }
163
164 /* best sized icon */
165
166 static int score_dim(xmlNodePtr ref, xmlNodePtr x, const char *dim, int request)
167 {
168         int r, iref, ix;
169         char *sref, *sx;
170
171         sref = xmlGetProp(ref, dim);
172         if (sref) {
173                 iref = atoi(sref);
174                 xmlFree(sref);
175                 sx = xmlGetProp(x, dim);
176                 if (sx) {
177                         /* sref && sx */
178                         ix = atoi(sx);
179                         xmlFree(sx);
180                         if (ix >= request) {
181                                 if (iref >= request)
182                                         r = ix - iref;
183                                 else
184                                         r = request - ix;
185                         } else {
186                                 if (iref >= request)
187                                         r = iref - request;
188                                 else
189                                         r = iref - ix;
190                         }
191                 } else {
192                         /* sref && !sx */
193                         if (iref >= request)
194                                 r = iref - request;
195                         else
196                                 r = 0;
197                 }
198         } else {
199                 sx = xmlGetProp(x, dim);
200                 if (sx) {
201                         /* !sref && sx */
202                         ix = atoi(sx);
203                         xmlFree(sx);
204                         if (ix >= request)
205                                 r = request - ix;
206                         else
207                                 r = 0;
208                 } else {
209                         /* !sref && !sx */
210                         r = 0;
211                 }
212         }
213         return r;
214 }
215
216 static int better_icon(xmlNodePtr ref, xmlNodePtr x, int width, int height)
217 {
218         int sw = score_dim(ref, x, _width_, width);
219         int sh = score_dim(ref, x, _height_, height);
220         return sw+sh < 0;
221 }
222
223 xmlNodePtr confixml_icon(int width, int height)
224 {
225         xmlNodePtr resu, icon;
226
227         resu = confixml_first_icon();
228         icon = confixml_next_icon(resu);
229         while (icon) {
230                 if (better_icon(resu, icon, width, height))
231                         resu = icon;
232                 icon = confixml_next_icon(icon);
233         }
234         return resu;
235 }
236