Back to index

gcompris  8.2.2
imageid.c
Go to the documentation of this file.
00001 /* gcompris - imageid.c
00002  *
00003  * Copyright (C) 2001 Pascal Georges
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include <string.h>
00021 
00022 #include "gcompris/gcompris.h"
00023 
00024 /* libxml includes */
00025 #include <libxml/tree.h>
00026 #include <libxml/parser.h>
00027 
00028 #define SOUNDLISTFILE PACKAGE
00029 
00030 static GcomprisBoard *gcomprisBoard = NULL;
00031 static gboolean board_paused = TRUE;
00032 
00033 static void           start_board (GcomprisBoard *agcomprisBoard);
00034 static void           pause_board (gboolean pause);
00035 static void           end_board (void);
00036 static gboolean              is_our_board (GcomprisBoard *gcomprisBoard);
00037 static void           set_level (guint level);
00038 static int gamewon;
00039 
00040 static void           process_ok(void);
00041 static void           highlight_selected(GnomeCanvasItem *);
00042 static void           game_won(void);
00043 
00044 static void           config_start(GcomprisBoard *agcomprisBoard,
00045                                   GcomprisProfile *aProfile);
00046 static void           config_stop(void);
00047 
00048 typedef struct {
00049   char  *pixmapfile;
00050   char  *text1;
00051   char  *text2;
00052   char  *text3;
00053 } Board;
00054 
00055 /* XML */
00056 static gboolean              read_xml_file(char *fname);
00057 static void           init_xml(void);
00058 static void           add_xml_data(xmlDocPtr doc,xmlNodePtr xmlnode, GNode * child);
00059 static void           parse_doc(xmlDocPtr doc);
00060 static gboolean              read_xml_file(char *fname);
00061 static void           destroy_board_list(void);
00062 static void           destroy_board(Board * board);
00063 
00064 /* This is the list of boards */
00065 static GList *board_list = NULL;
00066 
00067 #define VERTICAL_SEPARATION 30
00068 #define HORIZONTAL_SEPARATION 30
00069 // the values are taken from the backgound image imageid-bg.jpg
00070 #define IMAGE_AREA_X1 280
00071 #define IMAGE_AREA_X2 750
00072 #define IMAGE_AREA_Y1 90
00073 #define IMAGE_AREA_Y2 430
00074 
00075 //NUMBER_OF_SUBLEVELS*NUMBER_OF_LEVELS must equal the number of boards in XML file
00076 #define NUMBER_OF_SUBLEVELS 3
00077 #define NUMBER_OF_LEVELS 4
00078 
00079 #define TEXT_COLOR "white"
00080 
00081 /* ================================================================ */
00082 static int board_number; // between 0 and board_list.length-1
00083 static int right_word; // between 1 and 3, indicates which choice is the right one (the player clicks on it
00084 
00085 static GnomeCanvasGroup *boardRootItem = NULL;
00086 
00087 static GnomeCanvasItem *image_item = NULL;
00088 static GnomeCanvasItem *text1_item = NULL;
00089 static GnomeCanvasItem *text2_item = NULL;
00090 static GnomeCanvasItem *text3_item = NULL;
00091 static GnomeCanvasItem *button1 = NULL, *button2 = NULL, *button3 = NULL, *selected_button = NULL;
00092 
00093 static GnomeCanvasItem *imageid_create_item(GnomeCanvasGroup *parent);
00094 static void imageid_destroy_all_items(void);
00095 static void imageid_next_level(void);
00096 static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
00097 
00098 /* Description of this plugin */
00099 static BoardPlugin menu_bp =
00100   {
00101     NULL,
00102     NULL,
00103     N_("Reading"),
00104     N_("Learn how to read"),
00105     "Pascal Georges pascal.georges1@free.fr>",
00106     NULL,
00107     NULL,
00108     NULL,
00109     NULL,
00110     start_board,
00111     pause_board,
00112     end_board,
00113     is_our_board,
00114     NULL,
00115     process_ok,
00116     set_level,
00117     NULL,
00118     NULL,
00119     config_start,
00120     config_stop
00121   };
00122 
00123 /*
00124  * Main entry point mandatory for each Gcompris's game
00125  * ---------------------------------------------------
00126  *
00127  */
00128 
00129 GET_BPLUGIN_INFO(imageid)
00130 
00131 /*
00132  * in : boolean TRUE = PAUSE : FALSE = CONTINUE
00133  *
00134  */
00135      static void pause_board (gboolean pause)
00136 {
00137   if(gcomprisBoard==NULL)
00138     return;
00139 
00140   if(gamewon == TRUE && pause == FALSE) /* the game is won */
00141     {
00142       game_won();
00143     }
00144 
00145   board_paused = pause;
00146 }
00147 
00148 /*
00149  */
00150 static void start_board (GcomprisBoard *agcomprisBoard)
00151 {
00152   GHashTable *config = gc_db_get_board_conf();
00153 
00154   gc_locale_set(g_hash_table_lookup( config, "locale"));
00155 
00156   g_hash_table_destroy(config);
00157 
00158   if(agcomprisBoard!=NULL)
00159     {
00160       gcomprisBoard=agcomprisBoard;
00161       gc_set_background(gnome_canvas_root(gcomprisBoard->canvas), "imageid/imageid-bg.jpg");
00162       gcomprisBoard->level=1;
00163       gcomprisBoard->maxlevel=NUMBER_OF_LEVELS;
00164       gcomprisBoard->sublevel=1;
00165 
00166       init_xml();
00167 
00168       gcomprisBoard->number_of_sublevel = NUMBER_OF_SUBLEVELS;
00169       g_assert(NUMBER_OF_LEVELS*NUMBER_OF_SUBLEVELS == g_list_length(board_list));
00170       gc_score_start(SCORESTYLE_NOTE,
00171                         50,
00172                         gcomprisBoard->height - 50,
00173                         gcomprisBoard->number_of_sublevel);
00174       gc_bar_set(GC_BAR_CONFIG|GC_BAR_LEVEL);
00175 
00176       imageid_next_level();
00177 
00178       gamewon = FALSE;
00179       pause_board(FALSE);
00180     }
00181 }
00182 
00183 static void
00184 end_board ()
00185 {
00186 
00187   if(gcomprisBoard!=NULL)
00188     {
00189       pause_board(TRUE);
00190       gc_score_end();
00191       imageid_destroy_all_items();
00192       destroy_board_list();
00193     }
00194 
00195   gc_locale_reset();
00196 
00197   gcomprisBoard = NULL;
00198 }
00199 
00200 static void
00201 set_level (guint level)
00202 {
00203 
00204   if(gcomprisBoard!=NULL)
00205     {
00206       gcomprisBoard->level=level;
00207       gcomprisBoard->sublevel=1;
00208       imageid_next_level();
00209     }
00210 }
00211 
00212 static gboolean
00213 is_our_board (GcomprisBoard *gcomprisBoard)
00214 {
00215   if (gcomprisBoard)
00216     {
00217       if(g_strcasecmp(gcomprisBoard->type, "imageid")==0)
00218        {
00219          /* Set the plugin entry */
00220          gcomprisBoard->plugin=&menu_bp;
00221 
00222          return TRUE;
00223        }
00224     }
00225   return FALSE;
00226 }
00227 
00228 /*-------------------------------------------------------------------------------*/
00229 /*-------------------------------------------------------------------------------*/
00230 /* set initial values for the next level */
00231 static void imageid_next_level()
00232 {
00233   gc_bar_set_level(gcomprisBoard);
00234 
00235   imageid_destroy_all_items();
00236   selected_button = NULL;
00237   gamewon = FALSE;
00238 
00239   gc_score_set(gcomprisBoard->sublevel);
00240 
00241   /* Try the next level */
00242   imageid_create_item(gnome_canvas_root(gcomprisBoard->canvas));
00243 
00244 }
00245 /* ==================================== */
00246 /* Destroy all the items */
00247 static void imageid_destroy_all_items()
00248 {
00249   if(boardRootItem!=NULL)
00250     gtk_object_destroy (GTK_OBJECT(boardRootItem));
00251 
00252   boardRootItem = NULL;
00253 }
00254 /* ==================================== */
00255 static GnomeCanvasItem *imageid_create_item(GnomeCanvasGroup *parent)
00256 {
00257   char *buf[3];
00258   int x, y, xp, yp, place;
00259   GdkPixbuf *pixmap = NULL;
00260   GdkPixbuf *button_pixmap = NULL;
00261   char *str = NULL;
00262   Board * board;
00263 
00264   board_number = (gcomprisBoard->level-1) * NUMBER_OF_SUBLEVELS + gcomprisBoard->sublevel-1;
00265   /*  if (board_number >= g_list_length(board_list))
00266       board_number = g_list_length(board_list)-1;
00267   */
00268   g_assert(board_number >= 0  && board_number < g_list_length(board_list));
00269   place = ((int)(3.0*rand()/(RAND_MAX+1.0)));
00270   g_assert(place >= 0  && place < 3);
00271 
00272   right_word = place+1;
00273 
00274   boardRootItem = GNOME_CANVAS_GROUP(
00275                                  gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00276                                                      gnome_canvas_group_get_type (),
00277                                                      "x", (double) 0,
00278                                                      "y", (double) 0,
00279                                                      NULL));
00280 
00281   button_pixmap = gc_skin_pixmap_load("button_large.png");
00282   /* display the image */
00283   board = g_list_nth_data(board_list, board_number);
00284   g_assert(board != NULL);
00285 
00286   str = g_strdup_printf("%s/%s", gcomprisBoard->boarddir, board->pixmapfile);
00287   pixmap = gc_pixmap_load(str);
00288 
00289   x = IMAGE_AREA_X1 + ( IMAGE_AREA_X2 - IMAGE_AREA_X1 - gdk_pixbuf_get_width(pixmap))/2;
00290   y = IMAGE_AREA_Y1 + ( IMAGE_AREA_Y2 - IMAGE_AREA_Y1 - gdk_pixbuf_get_height(pixmap))/2;
00291 
00292   image_item = gnome_canvas_item_new (boardRootItem,
00293                                   gnome_canvas_pixbuf_get_type (),
00294                                   "pixbuf", pixmap,
00295                                   "x", (double) x,
00296                                   "y", (double) y,
00297                                   "width", (double) gdk_pixbuf_get_width(pixmap),
00298                                   "height", (double) gdk_pixbuf_get_height(pixmap),
00299                                   "width_set", TRUE,
00300                                   "height_set", TRUE,
00301                                   NULL);
00302 
00303   gdk_pixbuf_unref(pixmap);
00304   g_free(str);
00305 
00306   /* display the 3 words */
00307   /* the right word is at position 0 : it is swapped with any position depending of place value */
00308 
00309   switch (place) {
00310   case 1 :
00311     buf[0] = board->text2;
00312     buf[1] = board->text1;
00313     buf[2] = board->text3;
00314     break;
00315   case 2 :
00316     buf[0] = board->text3;
00317     buf[1] = board->text2;
00318     buf[2] = board->text1;
00319     break;
00320   default :
00321     buf[0] = board->text1;
00322     buf[1] = board->text2;
00323     buf[2] = board->text3;
00324     break;
00325   }
00326 
00327   xp = HORIZONTAL_SEPARATION;
00328   yp = (gcomprisBoard->height - 3*gdk_pixbuf_get_height(button_pixmap) - 2*VERTICAL_SEPARATION)/2;
00329 
00330   button1 = gnome_canvas_item_new (boardRootItem,
00331                                gnome_canvas_pixbuf_get_type (),
00332                                "pixbuf",  button_pixmap,
00333                                "x",  (double) xp,
00334                                "y",  (double) yp,
00335                                NULL);
00336   gnome_canvas_item_new (boardRootItem,
00337                       gnome_canvas_text_get_type (),
00338                       "text", buf[0],
00339                       "font", gc_skin_font_board_big,
00340                       "x", (double) xp + gdk_pixbuf_get_width(button_pixmap)/2 + 1.0,
00341                       "y", (double) yp + gdk_pixbuf_get_height(button_pixmap)/2 + 1.0,
00342                       "anchor", GTK_ANCHOR_CENTER,
00343                       "fill_color_rgba", gc_skin_color_shadow,
00344                       NULL);
00345   text1_item = gnome_canvas_item_new (boardRootItem,
00346                                   gnome_canvas_text_get_type (),
00347                                   "text", buf[0],
00348                                   "font", gc_skin_font_board_big,
00349                                   "x", (double) xp + gdk_pixbuf_get_width(button_pixmap)/2,
00350                                   "y", (double) yp + gdk_pixbuf_get_height(button_pixmap)/2,
00351                                   "anchor", GTK_ANCHOR_CENTER,
00352                                   "fill_color_rgba", gc_skin_color_text_button,
00353                                   NULL);
00354 
00355   yp += gdk_pixbuf_get_height(button_pixmap) + VERTICAL_SEPARATION;
00356   button2 = gnome_canvas_item_new (boardRootItem,
00357                                gnome_canvas_pixbuf_get_type (),
00358                                "pixbuf",  button_pixmap,
00359                                "x",  (double) xp,
00360                                "y",  (double) yp,
00361                                NULL);
00362   gnome_canvas_item_new (boardRootItem,
00363                       gnome_canvas_text_get_type (),
00364                       "text", buf[1],
00365                       "font", gc_skin_font_board_big,
00366                       "x", (double) xp + gdk_pixbuf_get_width(button_pixmap)/2 + 1.0,
00367                       "y", (double) yp + gdk_pixbuf_get_height(button_pixmap)/2 + 1.0,
00368                       "anchor", GTK_ANCHOR_CENTER,
00369                       "fill_color_rgba", gc_skin_color_shadow,
00370                       NULL);
00371   text2_item = gnome_canvas_item_new (boardRootItem,
00372                                   gnome_canvas_text_get_type (),
00373                                   "text", buf[1],
00374                                   "font", gc_skin_font_board_big,
00375                                   "x", (double) xp + gdk_pixbuf_get_width(button_pixmap)/2,
00376                                   "y", (double) yp + gdk_pixbuf_get_height(button_pixmap)/2,
00377                                   "anchor", GTK_ANCHOR_CENTER,
00378                                   "fill_color_rgba", gc_skin_color_text_button,
00379                                   NULL);
00380 
00381   yp += gdk_pixbuf_get_height(button_pixmap) + VERTICAL_SEPARATION;
00382   button3 = gnome_canvas_item_new (boardRootItem,
00383                                gnome_canvas_pixbuf_get_type (),
00384                                "pixbuf",  button_pixmap,
00385                                "x",  (double) xp,
00386                                "y",  (double) yp,
00387                                NULL);
00388 
00389   gnome_canvas_item_new (boardRootItem,
00390                       gnome_canvas_text_get_type (),
00391                       "text", buf[2],
00392                       "font", gc_skin_font_board_big,
00393                       "x", (double) xp + gdk_pixbuf_get_width(button_pixmap)/2 + 1.0,
00394                       "y", (double) yp + gdk_pixbuf_get_height(button_pixmap)/2 + 1.0,
00395                       "anchor", GTK_ANCHOR_CENTER,
00396                       "fill_color_rgba", gc_skin_color_shadow,
00397                       NULL);
00398   text3_item = gnome_canvas_item_new (boardRootItem,
00399                                   gnome_canvas_text_get_type (),
00400                                   "text", buf[2],
00401                                   "font", gc_skin_font_board_big,
00402                                   "x", (double) xp + gdk_pixbuf_get_width(button_pixmap)/2,
00403                                   "y", (double) yp + gdk_pixbuf_get_height(button_pixmap)/2,
00404                                   "anchor", GTK_ANCHOR_CENTER,
00405                                   "fill_color_rgba", gc_skin_color_text_button,
00406                                   NULL);
00407 
00408   gdk_pixbuf_unref(button_pixmap);
00409 
00410   gtk_signal_connect(GTK_OBJECT(button1), "event",  (GtkSignalFunc) item_event, NULL);
00411   gtk_signal_connect(GTK_OBJECT(button2), "event",  (GtkSignalFunc) item_event, NULL);
00412   gtk_signal_connect(GTK_OBJECT(button3), "event",  (GtkSignalFunc) item_event, NULL);
00413 
00414   gtk_signal_connect(GTK_OBJECT(text1_item), "event", (GtkSignalFunc) item_event, NULL);
00415   gtk_signal_connect(GTK_OBJECT(text2_item), "event", (GtkSignalFunc) item_event, NULL);
00416   gtk_signal_connect(GTK_OBJECT(text3_item), "event", (GtkSignalFunc) item_event, NULL);
00417 
00418   return NULL;
00419 }
00420 /* ==================================== */
00421 static void game_won()
00422 {
00423   gcomprisBoard->sublevel++;
00424   if(gcomprisBoard->sublevel > gcomprisBoard->number_of_sublevel) {
00425     /* Try the next level */
00426     gcomprisBoard->sublevel=1;
00427     gcomprisBoard->level++;
00428     if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
00429       gc_bonus_end_display(BOARD_FINISHED_TUXLOCO);
00430       return;
00431     }
00432   }
00433   imageid_next_level();
00434 }
00435 
00436 /* ==================================== */
00437 static gboolean process_ok_timeout() {
00438   gc_bonus_display(gamewon, BONUS_SMILEY);
00439   return FALSE;
00440 }
00441 
00442 static void process_ok() {
00443   // leave time to display the right answer
00444   g_timeout_add(TIME_CLICK_TO_BONUS, process_ok_timeout, NULL);
00445 }
00446 /* ==================================== */
00447 static gint
00448 item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
00449 {
00450   double item_x, item_y;
00451   GnomeCanvasItem * temp = NULL;
00452   item_x = event->button.x;
00453   item_y = event->button.y;
00454   gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
00455 
00456   if(board_paused)
00457     return FALSE;
00458 
00459   switch (event->type)
00460     {
00461     case GDK_BUTTON_PRESS:
00462       board_paused = TRUE;
00463       temp = item;
00464       if (item == text1_item)
00465        temp = button1;
00466       if (item == text2_item)
00467        temp = button2;
00468       if (item == text3_item)
00469        temp = button3;
00470 
00471       g_assert(temp == button1 || temp == button2 || temp == button3);
00472 
00473       if ( ( temp == button1 && right_word == 1) ||
00474           ( temp == button2 && right_word == 2) ||
00475           ( temp == button3 && right_word == 3) ) {
00476        gamewon = TRUE;
00477       } else {
00478        gamewon = FALSE;
00479       }
00480       highlight_selected(temp);
00481       process_ok();
00482       break;
00483 
00484     case GDK_MOTION_NOTIFY:
00485       break;
00486 
00487     case GDK_BUTTON_RELEASE:
00488       break;
00489 
00490     default:
00491       break;
00492     }
00493   return FALSE;
00494 }
00495 
00496 /* ==================================== */
00497 static void highlight_selected(GnomeCanvasItem * item) {
00498   GdkPixbuf *button_pixmap_selected = NULL, *button_pixmap = NULL;
00499   GnomeCanvasItem *button;
00500 
00501   /* Replace text item by button item */
00502   button = item;
00503   if ( button == text1_item ) {
00504     button = button1;
00505   } else if ( item == text2_item ) {
00506     button = button2;
00507   } else if ( item == text3_item ) {
00508     button = button3;
00509   }
00510 
00511   if (selected_button != NULL && selected_button != button) {
00512     button_pixmap = gc_skin_pixmap_load("button_large.png");
00513     gnome_canvas_item_set(selected_button, "pixbuf", button_pixmap, NULL);
00514     gdk_pixbuf_unref(button_pixmap);
00515   }
00516 
00517   if (selected_button != button) {
00518     button_pixmap_selected = gc_skin_pixmap_load("button_large_selected.png");
00519     gnome_canvas_item_set(button, "pixbuf", button_pixmap_selected, NULL);
00520     selected_button = button;
00521     gdk_pixbuf_unref(button_pixmap_selected);
00522   }
00523 
00524 }
00525 
00526 
00527 /* ===================================
00528  *                XML stuff
00529  *                Ref : shapegame.c
00530  * ==================================== */
00531 /* ======  for DEBUG ========  */
00532 #if 0
00533 static void dump_xml() {
00534   GList *list;
00535   g_warning("XML lentgh = %d\n", g_list_length(board_list));
00536 
00537   for(list = board_list; list != NULL; list = list->next) {
00538     Board * board = list->data;
00539     g_warning("xml = %s %s %s %s\n", board->pixmapfile, board->text1, board->text2, board->text3);
00540   }
00541 }
00542 #endif
00543 
00544 static void init_xml()
00545 {
00546   char *filename;
00547 
00548   filename = gc_file_find_absolute("%s/board1.xml",
00549                                gcomprisBoard->boarddir);
00550 
00551   g_assert(read_xml_file(filename)== TRUE);
00552   g_free(filename);
00553 
00554 }
00555 /* ==================================== */
00556 static void add_xml_data(xmlDocPtr doc, xmlNodePtr xmlnode, GNode * child)
00557 {
00558   gchar *pixmapfile = NULL;
00559   gchar *text1 = NULL, *text2 = NULL, *text3 = NULL;
00560   Board * board = g_new(Board,1);
00561   gboolean found_text1 = FALSE, found_text2 = FALSE, found_text3 = FALSE;
00562 
00563   xmlnode = xmlnode->xmlChildrenNode;
00564 
00565   xmlnode = xmlnode->next;
00566 
00567   while(xmlnode!=NULL) {
00568 
00569     if (!strcmp((char *)xmlnode->name, "pixmapfile"))
00570       pixmapfile = (gchar *)xmlNodeListGetString(doc, xmlnode->xmlChildrenNode, 1);
00571 
00572     if (!found_text1 && !strcmp((char *)xmlnode->name, "text1"))
00573       {
00574        if(text1==NULL)
00575          {
00576            text1 = \
00577              g_strdup(gettext((gchar *)xmlNodeListGetString(doc, xmlnode->xmlChildrenNode, 1)));
00578          }
00579       }
00580 
00581     if (!found_text2 && !strcmp((char *)xmlnode->name, "text2"))
00582       {
00583        if(text2==NULL)
00584          {
00585            text2 = \
00586              g_strdup(gettext((gchar *)xmlNodeListGetString(doc, xmlnode->xmlChildrenNode, 1)));
00587          }
00588       }
00589 
00590     if (!found_text3 && !strcmp((char *)xmlnode->name, "text3"))
00591       {
00592        if(text3==NULL)
00593          {
00594            text3 = \
00595              g_strdup(gettext((gchar *)xmlNodeListGetString(doc, xmlnode->xmlChildrenNode, 1)));
00596          }
00597       }
00598 
00599     xmlnode = xmlnode->next;
00600   }
00601   // I really don't know why this test, but otherwise, the list is doubled
00602   // with 1 line on 2 filled with NULL elements
00603   if ( (pixmapfile == NULL || text1 == NULL || text2 == NULL || text3 == NULL))
00604     return;
00605 
00606   board->pixmapfile = pixmapfile;
00607   board->text1 = text1;
00608   board->text2 = text2;
00609   board->text3 = text3;
00610 
00611   board_list = g_list_append (board_list, board);
00612 }
00613 
00614 /* ==================================== */
00615 static void parse_doc(xmlDocPtr doc)
00616 {
00617   xmlNodePtr node;
00618 
00619   for(node = doc->children->children; node != NULL; node = node->next) {
00620     if ( g_strcasecmp((gchar *)node->name, "Board") == 0 )
00621       add_xml_data(doc, node,NULL);
00622   }
00623 
00624 }
00625 /* ==================================== */
00626 /* read an xml file into our memory structures and update our view,
00627    dump any old data we have in memory if we can load a new set */
00628 static gboolean read_xml_file(char *fname)
00629 {
00630   /* pointer to the new doc */
00631   xmlDocPtr doc;
00632 
00633   g_return_val_if_fail(fname!=NULL,FALSE);
00634 
00635   /* parse the new file and put the result into newdoc */
00636   doc = gc_net_load_xml(fname);
00637 
00638   /* in case something went wrong */
00639   if(!doc)
00640     return FALSE;
00641 
00642   if(/* if there is no root element */
00643      !doc->children ||
00644      /* if it doesn't have a name */
00645      !doc->children->name ||
00646      /* if it isn't a ImageId node */
00647      g_strcasecmp((char *)doc->children->name,"ImageId")!=0) {
00648     xmlFreeDoc(doc);
00649     return FALSE;
00650   }
00651 
00652   parse_doc(doc);
00653   xmlFreeDoc(doc);
00654   return TRUE;
00655 }
00656 /* ======================================= */
00657 static void destroy_board_list() {
00658   Board *board;
00659 
00660   while(g_list_length(board_list)>0)
00661     {
00662       board = g_list_nth_data(board_list, 0);
00663       board_list = g_list_remove (board_list, board);
00664       destroy_board(board);
00665     }
00666 }
00667 
00668 /* ======================================= */
00669 static void destroy_board(Board * board) {
00670   g_free(board->pixmapfile);
00671   g_free(board->text1);
00672   g_free(board->text2);
00673   g_free(board->text3);
00674   g_free(board);
00675 }
00676 
00677 
00678 /* ************************************* */
00679 /* *            Configuration          * */
00680 /* ************************************* */
00681 
00682 
00683 /* ======================= */
00684 /* = config_start        = */
00685 /* ======================= */
00686 
00687 static GcomprisProfile *profile_conf;
00688 static GcomprisBoard   *board_conf;
00689 
00690 /* GHFunc */
00691 static void save_table (gpointer key,
00692                      gpointer value,
00693                      gpointer user_data)
00694 {
00695   gc_db_set_board_conf ( profile_conf,
00696                          board_conf,
00697                          (gchar *) key,
00698                          (gchar *) value);
00699 }
00700 
00701 static GcomprisConfCallback conf_ok(GHashTable *table)
00702 {
00703   if (!table){
00704     if (gcomprisBoard)
00705       pause_board(FALSE);
00706     return NULL;
00707   }
00708 
00709   g_hash_table_foreach(table, (GHFunc) save_table, NULL);
00710 
00711   if (gcomprisBoard) {
00712     gc_locale_reset();
00713 
00714     GHashTable *config;
00715 
00716     if (profile_conf)
00717       config = gc_db_get_board_conf();
00718     else
00719       config = table;
00720 
00721     gc_locale_set(g_hash_table_lookup( config, "locale"));
00722 
00723     if (profile_conf)
00724       g_hash_table_destroy(config);
00725 
00726     destroy_board_list();
00727 
00728     init_xml();
00729 
00730     imageid_next_level();
00731 
00732     pause_board(FALSE);
00733   }
00734 
00735   board_conf = NULL;
00736   profile_conf = NULL;
00737 
00738   return NULL;
00739 }
00740 
00741 static void
00742 config_start(GcomprisBoard *agcomprisBoard,
00743             GcomprisProfile *aProfile)
00744 {
00745   board_conf = agcomprisBoard;
00746   profile_conf = aProfile;
00747 
00748   if (gcomprisBoard)
00749     pause_board(TRUE);
00750 
00751   gchar *label = g_strdup_printf("<b>%s</b> configuration\n for profile <b>%s</b>",
00752                              agcomprisBoard->name,
00753                              aProfile ? aProfile->name : "");
00754 
00755   gc_board_config_window_display( label,
00756                              (GcomprisConfCallback )conf_ok);
00757 
00758   g_free(label);
00759 
00760   /* init the combo to previously saved value */
00761   GHashTable *config = gc_db_get_conf( profile_conf, board_conf);
00762 
00763   gchar *locale = g_hash_table_lookup( config, "locale");
00764 
00765   gc_board_config_combo_locales( locale);
00766 
00767 }
00768 
00769 
00770 /* ======================= */
00771 /* = config_stop        = */
00772 /* ======================= */
00773 static void
00774 config_stop()
00775 {
00776 }
00777