/* gcompris - skin.c * * Copyright (C) 2003 GCompris Developpement Team * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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 this program; if not, see . */ #include "string.h" #include "skin.h" #include #include GHashTable* gc_skin_fonts = NULL; GHashTable* gc_skin_colors = NULL; GHashTable* gc_skin_numbers = NULL; guint32 gc_skin_color_title; guint32 gc_skin_color_text_button; guint32 gc_skin_color_content; guint32 gc_skin_color_subtitle; guint32 gc_skin_color_shadow; gchar* gc_skin_font_title; gchar* gc_skin_font_subtitle; gchar* gc_skin_font_content; gchar* gc_skin_font_board_tiny; gchar* gc_skin_font_board_small; gchar* gc_skin_font_board_medium; gchar* gc_skin_font_board_big; gchar* gc_skin_font_board_big_bold; gchar* gc_skin_font_board_fixed; gchar* gc_skin_font_board_title; gchar* gc_skin_font_board_title_bold; gchar* gc_skin_font_board_huge; gchar* gc_skin_font_board_huge_bold; /* * Given an image name, return an image name * that includes the skin path * eg : xx.png -> skins/default/xx.png * * The caller must free the returned string */ gchar * gc_skin_image_get(gchar *pixmapfile) { GcomprisProperties *properties = gc_prop_get(); gchar *filename; /* First, test if pixmapfile is in the current skin dir */ filename = g_strdup_printf("%s/skins/%s/%s", properties->package_data_dir, properties->skin, pixmapfile); if (g_file_test ((filename), G_FILE_TEST_EXISTS)) { g_free(filename); filename = g_strdup_printf("skins/%s/%s", properties->skin, pixmapfile); return(filename); } g_free(filename); /* Check it's on the server */ filename = gc_net_get_url_from_file("boards/skins/%s/%s", properties->skin, pixmapfile); if(filename) return(filename); /* Return the default skin dir */ filename = g_strdup_printf("skins/%s/%s", DEFAULT_SKIN, pixmapfile); return(filename); } /* * Load a pixmap from the current skin directory * If not found, try in the default skin directory * If not found abort gcompris */ GdkPixbuf * gc_skin_pixmap_load(char *pixmapfile) { gchar *filename; GdkPixbuf *result_pixbuf; filename = gc_skin_image_get(pixmapfile); result_pixbuf = gc_pixmap_load (filename); g_free(filename); return (result_pixbuf); } /* * Utility function used when freeing the memory used by * a hashtable containing strings. */ static void gc_skin_free_string(gpointer data) { g_free(data); } /* * Initialize some common variables * (the one that have to be defined in each skin) */ void gc_skin_setup_vars(void) { gc_skin_color_title = gc_skin_get_color_default("gcompris/title", COLOR_TITLE); gc_skin_color_text_button = gc_skin_get_color_default("gcompris/text button", COLOR_TEXT_BUTTON); gc_skin_color_content = gc_skin_get_color_default("gcompris/content", COLOR_CONTENT); gc_skin_color_subtitle = gc_skin_get_color_default("gcompris/subtitle", COLOR_SUBTITLE); gc_skin_color_shadow = gc_skin_get_color_default("gcompris/shadow", COLOR_SHADOW); gc_skin_font_title = gc_skin_get_font_default("gcompris/title", FONT_TITLE); gc_skin_font_subtitle = gc_skin_get_font_default("gcompris/subtitle", FONT_SUBTITLE); gc_skin_font_content = gc_skin_get_font_default("gcompris/content", FONT_CONTENT); gc_skin_font_board_tiny = gc_skin_get_font_default("gcompris/board/tiny", FONT_BOARD_TINY); gc_skin_font_board_small = gc_skin_get_font_default("gcompris/board/small", FONT_BOARD_SMALL); gc_skin_font_board_medium = gc_skin_get_font_default("gcompris/board/medium", FONT_BOARD_MEDIUM); gc_skin_font_board_big = gc_skin_get_font_default("gcompris/board/big", FONT_BOARD_BIG); gc_skin_font_board_big_bold = gc_skin_get_font_default("gcompris/board/big bold", FONT_BOARD_BIG_BOLD); gc_skin_font_board_fixed = gc_skin_get_font_default("gcompris/board/fixed", FONT_BOARD_FIXED); gc_skin_font_board_title = gc_skin_get_font_default("gcompris/board/title", FONT_BOARD_TITLE); gc_skin_font_board_title_bold = gc_skin_get_font_default("gcompris/board/title bold", FONT_BOARD_TITLE_BOLD); gc_skin_font_board_huge = gc_skin_get_font_default("gcompris/board/huge", FONT_BOARD_HUGE); gc_skin_font_board_huge_bold = gc_skin_get_font_default("gcompris/board/huge bold", FONT_BOARD_HUGE_BOLD); } /* * Convert from string a color expressed in the form 0xRRGGBBAA * to a unsigned 32 bit integer. */ gboolean gc_skin_str_to_color(gchar* data, guint32* color){ char c; int i; int n = 32; guint32 result=0; if(strlen(data)<10) return FALSE; for(i=0; i<8;i++){ c = data[i+2]; n -= 4; switch(c){ case '0': break; case '1': result+=(1<children || /* if it doesn't have a name */ !xmldoc->children->name || /* if it isn't a GCompris node */ g_strcasecmp((gchar *)xmldoc->children->name, "GCompris")!=0) { g_warning("No Gcompris node"); xmlFreeDoc(xmldoc); return; } skinNode = xmldoc->children->children; while((skinNode!=NULL)&&(skinNode->type!=XML_ELEMENT_NODE)) skinNode = skinNode->next; if((skinNode==NULL)|| g_strcasecmp((gchar *)skinNode->name, "Skin")!=0) { g_warning("No Skin node %s", xmldoc->children->children->name); xmlFreeDoc(xmldoc); return; } node = skinNode->children; while(node !=NULL) { if(g_strcasecmp((gchar *)node->name, "color")==0){ key = (gchar *)xmlGetProp(node, BAD_CAST "id"); data =(gchar *) xmlGetProp(node, BAD_CAST "rgba"); if((key!=NULL)&&(data!=NULL)){ if(gc_skin_str_to_color(data, &color)){ g_hash_table_insert(gc_skin_colors, key, GUINT_TO_POINTER(color)); } else { if(key!=NULL) g_free(key); } } if(data!=NULL) g_free(data); } else if(g_strcasecmp((gchar *)node->name, "font")==0){ key = (gchar *)xmlGetProp(node, BAD_CAST "id"); data = (gchar *)xmlGetProp(node, BAD_CAST "name"); if((key!=NULL)&&(data!=NULL)){ g_hash_table_insert(gc_skin_fonts, key, data); } else { if(key!=NULL) g_free(key); if(data!=NULL) g_free(data); } } else if(g_strcasecmp((gchar *)node->name, "number")==0){ key = (gchar *)xmlGetProp(node, BAD_CAST "id"); data = (gchar *)xmlGetProp(node, BAD_CAST "value"); if((key!=NULL)&&(data!=NULL)){ int number = atoi(data); g_hash_table_insert(gc_skin_numbers, key, GUINT_TO_POINTER(number)); g_free(data); } else { if(key!=NULL) g_free(key); if(data!=NULL) g_free(data); } } node = node->next; } xmlFreeDoc(xmldoc); } /* * Parse the default skin.xml file and the one located in the skin * directory then load all skins properties into memory */ void gc_skin_load (gchar* skin) { if(skin==NULL) return; gc_skin_free(); gc_skin_fonts = g_hash_table_new_full(g_str_hash, g_str_equal, gc_skin_free_string, gc_skin_free_string); gc_skin_colors = g_hash_table_new_full(g_str_hash, g_str_equal, gc_skin_free_string, NULL); gc_skin_numbers = g_hash_table_new_full(g_str_hash, g_str_equal, gc_skin_free_string, NULL); skin_xml_load(DEFAULT_SKIN); if(strcmp(skin,DEFAULT_SKIN)!=0) skin_xml_load(skin); gc_skin_setup_vars(); } /* * Free the memory used to store the skin properties. */ void gc_skin_free (void) { if(gc_skin_fonts!=NULL) g_hash_table_destroy(gc_skin_fonts); if(gc_skin_colors!=NULL) g_hash_table_destroy(gc_skin_colors); if(gc_skin_numbers!= NULL) g_hash_table_destroy(gc_skin_numbers); } /* * Get the skin color associated to the id */ guint32 gc_skin_get_color_default(gchar* id, guint32 def) { gpointer result; result = g_hash_table_lookup(gc_skin_colors, (gpointer)id); if(result!=NULL) return GPOINTER_TO_UINT(result); return def; } /* * Get the skin gdkcolor associated to the id * * The color is returned in the given gdkcolor */ void gc_skin_get_gdkcolor_default(gchar* id, guint32 def, GdkColor *gdkcolor) { gchar *tmp; guint32 color; color = gc_skin_get_color_default(id, def); tmp = g_strdup_printf("#%06X", gc_skin_get_color(id) >> 8); gdk_color_parse(tmp, gdkcolor); g_free(tmp); } /* * Get the skin font name associated to the id */ gchar* gc_skin_get_font_default(gchar* id, gchar* def) { gpointer result; result = g_hash_table_lookup(gc_skin_fonts, (gpointer)id); if(result!=NULL) return (gchar*)result; return def; } /* * Get the skin 'number' associated to the id */ guint32 gc_skin_get_number_default(gchar* id, guint32 def) { gpointer result; result = g_hash_table_lookup(gc_skin_numbers, (gpointer)id); if(result!=NULL) return GPOINTER_TO_UINT(result); return def; }