4 * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * DoHyung Hong <don.hong@samsung.com>
8 * SeokYeon Hwang <syeon.hwang@samsung.com>
9 * Hyunjun Son <hj79.son@samsung.com>
10 * SangJin Kim <sangjin3.kim@samsung.com>
11 * MunKyu Im <munkyu.im@samsung.com>
12 * KiTae Kim <kt920.kim@samsung.com>
13 * JinHyung Jo <jinhyung.jo@samsung.com>
14 * SungMin Ha <sungmin82.ha@samsung.com>
15 * JiHye Kim <jihye1128.kim@samsung.com>
16 * GiWoong Kim <giwoong.kim@samsung.com>
17 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
18 * DongKyun Yun <dk77.yun@samsung.com>
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
42 #include <linux/limits.h>
48 #include "dbi_parser.h"
52 //DEFAULT_DEBUG_CHANNEL(tizen);
53 MULTI_DEBUG_CHANNEL(tizen, dbi_parser);
56 static int rotate_keycode[4];
60 * @brief show DBI info
63 static void print_parse_info(void)
66 TRACE(" PHONE.mode_cnt =%d \n",PHONE.mode_cnt );
68 for( i=0;i< PHONE.mode_cnt ; i ++) {
69 for(j=0;j < PHONE.mode[i].lcd_list_cnt ; j ++ ) {
70 TRACE(" PHONE.mode[%d].lcd_list[%d].id =%d \n",i,j,PHONE.mode[i].lcd_list[j].id);
71 TRACE(" PHONE.mode[%d].lcd_list[%d].bitsperpixel =%d \n",i,j,PHONE.mode[i].lcd_list[j].bitsperpixel);
72 TRACE(" PHONE.mode[%d].lcd_list[%d].nonstd =%d \n",i,j,PHONE.mode[i].lcd_list[j].nonstd);
73 TRACE(" PHONE.mode[%d].lcd_list[%d].lcd_region.x =%d \n",i,j,PHONE.mode[i].lcd_list[j].lcd_region.x);
74 TRACE(" PHONE.mode[%d].lcd_list[%d].lcd_region.y =%d \n",i,j,PHONE.mode[i].lcd_list[j].lcd_region.y);
75 TRACE(" PHONE.mode[%d].lcd_list[%d].lcd_region.w =%d \n",i,j,PHONE.mode[i].lcd_list[j].lcd_region.w);
76 TRACE(" PHONE.mode[%d].lcd_list[%d].lcd_region.h =%d \n",i,j,PHONE.mode[i].lcd_list[j].lcd_region.h);
82 static int dbi_atoi(xmlNode *node, const char *field)
84 xmlChar *xml_str = xmlGetProp(node, (const xmlChar*)field);
87 val = atoi((const char*) xml_str);
93 static int dbi_load_mode_list(xmlNode *child_node, mode_list *ml, const gchar *dbi_path)
95 xmlNode *region_child_node;
102 int key_map_chk_cnt = 0;
103 int event_value_chk_cnt = 0;
104 int event_info_chk_cnt = 0;
106 char *pDes_Buf = NULL;
107 int event_info_index = -1;
110 ml->id = dbi_atoi(child_node, "id");
111 pSrc_Buf = (char *)xmlGetProp(child_node, (const xmlChar *)"name");
112 ml->name = strdup(pSrc_Buf);
115 // mode children : image_list, region, lcd_list,
116 // led_list, key_map_list
117 for (region_node = child_node->children; region_node != NULL; region_node = region_node->next) {
118 if (region_node->type != XML_ELEMENT_NODE)
122 if (!xmlStrcmp(region_node->name, (const xmlChar *)"image_list")) {
123 for (image_node = region_node->children; image_node != NULL; image_node = image_node->next) {
124 if (image_node->type != XML_ELEMENT_NODE)
126 if (!xmlStrcmp(image_node->name, (const xmlChar *) "main_image")) {
127 pSrc_Buf = (char *) xmlNodeGetContent(image_node);
129 pDes_Buf = g_strdup_printf("%s/%s", dbi_path, pSrc_Buf);
130 TRACE(" main_image = %s \n", pDes_Buf);
132 ml->image_list.main_image = pDes_Buf;
135 else if (!xmlStrcmp(image_node->name, (const xmlChar *) "keypressed_image")) {
136 pSrc_Buf = (char *) xmlNodeGetContent(image_node);
138 pDes_Buf = g_strdup_printf("%s/%s", dbi_path, pSrc_Buf);
139 TRACE( " keypressed_image = %s \n", pDes_Buf);
141 ml->image_list.keypressed_image = pDes_Buf;
144 else if (!xmlStrcmp(image_node->name, (const xmlChar *) "led_main_image")) {
145 pSrc_Buf = (char *) xmlNodeGetContent(image_node);
147 pDes_Buf = g_strdup_printf("%s/%s", dbi_path, pSrc_Buf);
148 TRACE( " led_main_image = %s \n", pDes_Buf);
150 ml->image_list.led_main_image = pDes_Buf;
153 else if (!xmlStrcmp(image_node->name, (const xmlChar *) "led_keypressed_image")) {
154 pSrc_Buf = (char *) xmlNodeGetContent(image_node);
156 pDes_Buf = g_strdup_printf("%s/%s", dbi_path, pSrc_Buf);
157 TRACE( " led_keypressed_image = %s \n", pDes_Buf);
159 ml->image_list.led_keypressed_image = pDes_Buf;
161 /* To identify dual display split area image(middle bar) */
162 else if (!xmlStrcmp(image_node->name, (const xmlChar *) "splitted_screen_image"))
164 pSrc_Buf = (char *) xmlNodeGetContent(image_node);
166 pDes_Buf = g_strdup_printf("%s/%s", dbi_path, pSrc_Buf);
167 TRACE( " ^^^^^^^^^^^^^^^^^^^^^^^^ = %s \n", pDes_Buf);
169 ml->image_list.splitted_area_image = pDes_Buf;
174 else if (!xmlStrcmp(region_node->name, (const xmlChar *)"region")) {
175 ml->REGION.x = dbi_atoi(region_node, "left");
176 ml->REGION.y = dbi_atoi(region_node, "top");
177 ml->REGION.w = dbi_atoi(region_node, "width");
178 ml->REGION.h = dbi_atoi(region_node, "height");
181 else if (!xmlStrcmp(region_node->name, (const xmlChar *)"lcd_list")) {
182 for (image_node = region_node->children; image_node != NULL; image_node = image_node->next) {
183 if (image_node->type != XML_ELEMENT_NODE)
185 if (!xmlStrcmp(image_node->name, (const xmlChar *)"lcd")) {
186 lcd_list_data *ll = &ml->lcd_list[lcd_chk_cnt];
187 ll->id = dbi_atoi(image_node, "id");
188 ll->bitsperpixel = dbi_atoi(image_node, "bitsperpixel");
189 // hwjang add for overlay
190 ll->nonstd = dbi_atoi(image_node, "nonstd");
192 for (region_child_node = image_node->children; region_child_node != NULL; region_child_node = region_child_node->next) {
193 if (region_node->type != XML_ELEMENT_NODE)
195 if (!xmlStrcmp(region_child_node->name, (const xmlChar *) "region")) {
196 xmlChar *scale = NULL;
197 ll->lcd_region.x = dbi_atoi(region_child_node, "left");
198 ll->lcd_region.y = dbi_atoi(region_child_node, "top");
199 ll->lcd_region.w = dbi_atoi(region_child_node, "width");
200 ll->lcd_region.h = dbi_atoi(region_child_node, "height");
202 scale = xmlGetProp(region_child_node, (const xmlChar *) "scale");
204 ll->lcd_region.s = atof((char *)scale);
206 ll->lcd_region.s = 1.0;
208 ll->lcd_region.split = dbi_atoi(region_child_node, "split");
211 lcd_chk_cnt++; // lcd list count
213 ml->lcd_list_cnt = lcd_chk_cnt;
218 else if (!xmlStrcmp(region_node->name, (const xmlChar *)"led_list")) {
219 for (image_node = region_node->children; image_node != NULL; image_node = image_node->next) {
220 if (region_node->type != XML_ELEMENT_NODE)
222 if (!xmlStrcmp(image_node->name, (const xmlChar *)"led")) {
223 ml->led_list[led_chk_cnt].led_region.x = dbi_atoi(image_node, "left");
224 ml->led_list[led_chk_cnt].led_region.y = dbi_atoi(image_node, "top");
225 ml->led_list[led_chk_cnt].led_region.w = dbi_atoi(image_node, "width");
226 ml->led_list[led_chk_cnt].led_region.h = dbi_atoi(image_node, "height");
228 for (region_child_node = image_node->children; region_child_node != NULL; region_child_node = region_child_node->next) {
229 if (region_child_node->type == XML_ELEMENT_NODE && !xmlStrcmp(region_child_node->name, (const xmlChar *)
231 pSrc_Buf = (char *) xmlGetProp(region_child_node, (const xmlChar *)"id");
232 ml->led_list[led_chk_cnt].id = strdup(pSrc_Buf);
234 pSrc_Buf = (char *) xmlGetProp(region_child_node, (const xmlChar *)"name");
235 ml->led_list[led_chk_cnt].name = strdup(pSrc_Buf);
237 pSrc_Buf = (char *) xmlGetProp(region_child_node, (const xmlChar *) "imagepath");
238 ml->led_list[led_chk_cnt].imagepath = strdup(pSrc_Buf);
242 led_chk_cnt++; // led list count
243 ml->led_list_cnt = led_chk_cnt;
248 else if (!xmlStrcmp(region_node->name, (const xmlChar *) "key_map_list")) {
249 for (image_node = region_node->children; image_node != NULL; image_node = image_node->next) {
250 if (image_node->type != XML_ELEMENT_NODE)
252 if (!xmlStrcmp(image_node->name, (const xmlChar *) "key_map")) {
254 for (region_child_node = image_node->children; region_child_node != NULL; region_child_node = region_child_node->next) {
255 if (region_node->type != XML_ELEMENT_NODE)
257 if (!xmlStrcmp(region_child_node->name, (const xmlChar *) "region")) {
258 region *reg = &ml->key_map_list[key_map_chk_cnt].key_map_region;
259 reg->x = dbi_atoi(region_child_node, "left");
260 reg->y = dbi_atoi(region_child_node, "top");
261 reg->w = dbi_atoi(region_child_node, "width");
262 reg->h = dbi_atoi(region_child_node, "height");
265 else if (!xmlStrcmp(region_child_node->name, (const xmlChar *) "event_info")) {
266 // array[0] VKS_KEY_PRESSED
267 // array[1] VKS_KEY_RELEASED
268 char *temp = (char *) xmlGetProp(region_child_node, (const xmlChar *) "status");
269 if (strcmp(temp, KEY_PRESS) == 0) {
270 event_info_index = 0;
271 } else if (strcmp(temp, KEY_RELEASE) == 0) {
272 event_info_index = 1;
277 for (event_node = region_child_node->children; event_node != NULL; event_node = event_node->next) {
278 event_info_data *ei = &ml->key_map_list[key_map_chk_cnt].event_info[event_info_index];
279 if (region_node->type != XML_ELEMENT_NODE)
283 if (!xmlStrcmp(event_node->name, (const xmlChar *) "event_id")) {
284 pSrc_Buf = (char *) xmlNodeGetContent(event_node);
285 ei->event_id = strdup(pSrc_Buf);
289 else if (!xmlStrcmp(event_node->name, (const xmlChar *) "event_value")) {
291 for (event_value = event_node->children; event_value != NULL; event_value = event_value->next) {
292 event_value_data *ev = &ei->event_value[event_value_chk_cnt];
293 if (region_node->type != XML_ELEMENT_NODE)
295 if (!xmlStrcmp(event_value->name, (const xmlChar *) "key_code")) {
296 ev->key_code = atoi((char *) xmlNodeGetContent(event_value));
299 else if (!xmlStrcmp(event_value->name, (const xmlChar *) "key_name")) {
300 pSrc_Buf = (char *) xmlNodeGetContent(event_value);
301 ev->key_name = strdup(pSrc_Buf);
303 event_value_chk_cnt++;
304 ei->event_value_cnt = event_value_chk_cnt;
309 else if (!xmlStrcmp(event_node->name, (const xmlChar *) "keyboard")) {
310 pSrc_Buf = (char *) xmlNodeGetContent(event_node);
311 ei->keyboard = strdup(pSrc_Buf);
315 event_value_chk_cnt = 0;
316 event_info_chk_cnt++;
317 ml->key_map_list[key_map_chk_cnt].event_info_cnt = event_info_chk_cnt;
320 else if (!xmlStrcmp(region_child_node->name, (const xmlChar *) "tooltip")) {
321 pSrc_Buf = (char *) xmlNodeGetContent(region_child_node->children);
322 if (pSrc_Buf == NULL) {
323 ml->key_map_list[key_map_chk_cnt].tooltip = NULL;
325 ml->key_map_list[key_map_chk_cnt].tooltip = strdup(pSrc_Buf);
331 key_map_chk_cnt++; // key_map list
333 ml->key_map_list_cnt = key_map_chk_cnt;
341 static int dbi_parse_mode_selection(xmlNode *cur_node, const gchar * filename, PHONEMODELINFO * pDeviceData)
344 int mode_chk_cnt = 0;
346 gchar* dbi_path = g_path_get_dirname(filename);
349 for (child_node = cur_node->children; child_node != NULL; child_node = child_node->next) {
350 if (child_node->type == XML_ELEMENT_NODE && !xmlStrcmp(child_node->name, (const xmlChar *)"mode")) {
351 assert (mode_chk_cnt < MODE_MAX);
352 dbi_load_mode_list(child_node, &pDeviceData->mode[mode_chk_cnt], dbi_path);
353 mode_chk_cnt++; // mode count check
354 pDeviceData->mode_cnt = mode_chk_cnt;
357 // Cover mode paser !!!!!
358 if (child_node->type == XML_ELEMENT_NODE && !xmlStrcmp(child_node->name, (const xmlChar *)"cover_mode")) {
359 assert(pDeviceData->cover_mode_cnt == 0);
360 pDeviceData->cover_mode_cnt++;
361 dbi_load_mode_list(child_node, &pDeviceData->cover_mode, dbi_path);
370 * @brief parse DBI file which describes specific phone model outlook
371 * @param filename: dbi file name
372 * @param pDeviceData: pointer to structure saving the device information
373 * @return success : 0 failure : -1
375 int parse_dbi_file(const gchar * filename, PHONEMODELINFO * pDeviceData)
378 int event_menu_cnt = 0;
379 int event_list_cnt = 0;
384 if (filename == NULL || strlen(filename) == 0 || pDeviceData == NULL) {
385 WARN( "Please input skin path (%s)\n", filename);
390 xmlNode *cur_node, *child_node; // node1, node2
391 xmlNode *region_node; // node3
395 doc = xmlParseFile(filename);
398 WARN( "can't parse file %s\n", filename);
402 WARN( "start to parse file %s\n", filename);
404 xmlNode *root = NULL;
405 root = xmlDocGetRootElement(doc);
408 // Must have root element, a name and the name must be "PHONEMODELINFO"
409 if (!root || !root->name || xmlStrcmp(root->name, (const xmlChar *)"device_info")) {
413 // PHONEMODELINFO children
414 for (cur_node = root->children; cur_node != NULL; cur_node = cur_node->next) {
416 /* 1. key mode parsing (old(XOcean), new(mirage))) in 20090330 */
418 if (cur_node->type == XML_ELEMENT_NODE && !xmlStrcmp(cur_node->name, (const xmlChar *)"key_mode")) {
420 /* 1. 1 child_mode */
422 for (child_node = cur_node->children; child_node != NULL; child_node = child_node->next) {
425 if (child_node->type == XML_ELEMENT_NODE && !xmlStrcmp(child_node->name, (const xmlChar *)"key")) {
427 /* 1. 3 key type parsing */
429 rotate_keycode[run_step] = dbi_atoi(child_node, "code");
435 /* New node for enabling dual_display */
436 if (cur_node->type == XML_ELEMENT_NODE && !xmlStrcmp(cur_node->name, (const xmlChar *)"device_information"))
438 for (child_node = cur_node->children; child_node != NULL; child_node = child_node->next)
440 if (child_node->type == XML_ELEMENT_NODE && !xmlStrcmp(child_node->name, (const xmlChar *)"device_name"))
442 strcpy(pDeviceData->model_name,(char *)xmlGetProp(child_node, (const xmlChar *)"name"));
443 if (strcmp(pDeviceData->model_name,"dual_display")==0)
445 pDeviceData->dual_display = 1;
449 pDeviceData->dual_display = 0;
458 if (cur_node->type == XML_ELEMENT_NODE && !xmlStrcmp(cur_node->name, (const xmlChar *)"mode_section")) {
460 r = dbi_parse_mode_selection(cur_node, filename, pDeviceData);
462 return r; /* FIXME: leak memory here */
466 if (cur_node->type == XML_ELEMENT_NODE && !xmlStrcmp(cur_node->name, (const xmlChar *)"event_menu")) {
467 for (child_node = cur_node->children; child_node != NULL; child_node = child_node->next) {
468 if (child_node->type == XML_ELEMENT_NODE && !xmlStrcmp(child_node->name, (const xmlChar *)"menu")) {
469 event_menu_list *em = &pDeviceData->event_menu[event_menu_cnt];
470 pSrc_Buf = (char *)xmlGetProp(child_node, (const xmlChar *)"name");
471 g_strlcpy(em->name, pSrc_Buf, sizeof em->name);
475 for (region_node = child_node->children; region_node != NULL; region_node = region_node->next) {
476 if (region_node->type == XML_ELEMENT_NODE && !xmlStrcmp(region_node->name, (const xmlChar *)"event")) {
477 event_prop *ep = &em->event_list[event_list_cnt];
478 pSrc_Buf = (char *)xmlGetProp(region_node, (const xmlChar *) "id");
479 g_strlcpy(ep->event_eid, pSrc_Buf, sizeof ep->event_eid);
482 pSrc_Buf = (char *)xmlGetProp(region_node, (const xmlChar *) "value");
483 g_strlcpy(ep->event_evalue, pSrc_Buf, sizeof ep->event_evalue);
487 em->event_list_cnt = event_list_cnt;
491 pDeviceData->event_menu_cnt = event_menu_cnt;
503 // free the global variables that way have been allocated by the
509 static void free_modelist(mode_list *ml)
517 g_free(ml->image_list.main_image);
518 g_free(ml->image_list.keypressed_image);
519 g_free(ml->image_list.led_main_image);
520 g_free(ml->image_list.led_keypressed_image);
521 g_free(ml->image_list.splitted_area_image);
523 for (i = 0; i < ml->led_list_cnt; i++) {
524 if (ml->led_list[i].name) {
525 free(ml->led_list[i].name);
527 if (ml->led_list[i].imagepath) {
528 free(ml->led_list[i].imagepath);
532 for (i = 0; i < ml->key_map_list_cnt; i++) {
533 if (ml->key_map_list[i].tooltip) {
534 free(ml->key_map_list[i].tooltip);
540 int free_dbi_file(PHONEMODELINFO *pDeviceData)
544 for (i = 0; i < pDeviceData->mode_cnt; i++) {
545 mode_list *ml = &pDeviceData->mode[i];
553 * vim:set tabstop=4 shiftwidth=4 foldmethod=marker wrap: