Back to index

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