Fix:Core:Remove out-ifdefed code, which no longer makes sense, but breaks cscope.
[profile/ivi/navit.git] / navit / navit / navit.c
index 50825e8..99b5da6 100644 (file)
 #include "vehicleprofile.h"
 #include "sunriset.h"
 #include "bookmarks.h"
+#ifdef HAVE_API_WIN32_BASE
+#include <windows.h>
+#include "util.h"
+#endif
+#ifdef HAVE_API_WIN32_CE
+#include "libc.h"
+#endif
 
 /**
  * @defgroup navit the navit core instance. navit is the object containing nearly everything: A set of maps, one or more vehicle, a graphics object for rendering the map, a gui object for displaying the user interface, a route object, a navigation object and so on. Be warned that it is theoretically possible to have more than one navit object
@@ -148,11 +155,13 @@ struct navit {
                 /* 2=No gui ok */
        int border;
        int imperial;
+       struct attr **attr_list;
 };
 
 struct gui *main_loop_gui;
 
 struct attr_iter {
+       void *iter;
        union {
                GList *list;
                struct mapset_handle *mapset_handle;
@@ -724,9 +733,10 @@ navit_cmd_say(struct navit *this, char *function, struct attr **in, struct attr
 }
 
 static GHashTable *cmd_int_var_hash = NULL;
+static GHashTable *cmd_attr_var_hash = NULL;
 
 /**
- * Store key value pair for the  command system
+ * Store key value pair for the  command system (for int typed values)
  *
  * @param navit The navit instance
  * @param function unused (needed to match command function signiture)
@@ -738,20 +748,53 @@ static GHashTable *cmd_int_var_hash = NULL;
 static void
 navit_cmd_set_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
 {
+       char*key;
+       struct attr*val;
        if(!cmd_int_var_hash) {
                cmd_int_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
        }
 
        if ( (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) &&
             (in && in[1] && ATTR_IS_NUMERIC(in[1]->type))) {
-               char*key;
-               struct attr*val = g_new(struct attr,1);
+               val = g_new(struct attr,1);
                attr_dup_content(in[1],val);
                key = g_strdup(in[0]->u.str);
                g_hash_table_insert(cmd_int_var_hash, key, val);
         }
 }
 
+
+/**
+ * Store key value pair for the  command system (for attr typed values, can be used as opaque handles)
+ *
+ * @param navit The navit instance
+ * @param function unused (needed to match command function signiture)
+ * @param in input attributes in[0] is the key string, in[1] is the attr* value to store
+ * @param out output attributes, unused 
+ * @param valid unused 
+ * @returns nothing
+ */
+//TODO free stored attributes on navit_destroy
+static void
+navit_cmd_set_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       char*key;
+       struct attr*val;
+       if(!cmd_attr_var_hash) {
+               cmd_attr_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
+       }
+
+       if ( (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) &&
+            (in && in[1] )) {
+               val = attr_dup(in[1]);
+               //val = in[1];
+               key = g_strdup(in[0]->u.str);
+               g_hash_table_insert(cmd_attr_var_hash, key, val);
+        }
+}
+
+
+
 /**
  * command to toggle the active state of a named layer of the current layout
  *
@@ -781,6 +824,191 @@ navit_cmd_toggle_layer(struct navit *this, char *function, struct attr **in, str
         }
 }
 
+/**
+ * adds an item with the current coordinate of the vehicle to a named map
+ *
+ * @param navit The navit instance
+ * @param function unused (needed to match command function signiture)
+ * @param in input attribute in[0] is the name of the map 
+ * @param out output attribute, 0 on error or the id of the created item on success
+ * @param valid unused 
+ * @returns nothing
+ */
+static void
+navit_cmd_map_add_curr_pos(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       struct attr **list = g_new0(struct attr *,2);
+       struct attr*val = g_new0(struct attr,1);
+       struct mapset* ms;
+       struct map_selection sel;
+       const int selection_range = 10;
+       enum item_type item_type;
+       struct item *it;
+       struct map* curr_map = NULL;
+       struct coord curr_coord;
+       struct map_rect *mr;
+       
+       //return invalid item on error
+       val->type   = attr_none;
+       val->u.item  = NULL;    
+       list[0]     = val;
+       list[1]     = NULL;
+       *out = list;
+       if (
+               in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
+                     in[1] && ATTR_IS_STRING(in[1]->type) && in[1]->u.str    //item type
+       ) {
+
+               if(!(ms=navit_get_mapset(this))) {
+                       return;
+               }
+
+               if((item_type = item_from_name(in[1]->u.str))==type_none) {
+                       return;
+               }
+
+               curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
+
+               //no map with the given name found
+               if( ! curr_map) {
+                       return;
+               }
+       
+               if(this->vehicle && this->vehicle->vehicle ) {
+                       struct attr pos_attr;
+                       if(vehicle_get_attr(this->vehicle->vehicle,attr_position_coord_geo,&pos_attr,NULL)) {
+                               transform_from_geo(projection_mg, pos_attr.u.coord_geo, &curr_coord);
+                       } else {
+                               return;
+                       }
+               } else {
+                       return;
+               }
+
+               sel.next=NULL;
+               sel.order=18;
+               sel.range.min=type_none;
+               sel.range.max=type_tec_common;
+               sel.u.c_rect.lu.x=curr_coord.x-selection_range;
+               sel.u.c_rect.lu.y=curr_coord.y+selection_range;
+               sel.u.c_rect.rl.x=curr_coord.x+selection_range;
+               sel.u.c_rect.rl.y=curr_coord.y-selection_range;
+               mr = map_rect_new(curr_map, &sel);
+               if(mr) {
+                       it = map_rect_create_item( mr, item_type);
+                       if (it) {
+                               val->type = attr_type_item_begin;
+                               item_coord_set(it,&curr_coord, 1, change_mode_modify);
+                       }
+                       val->u.item  = it;
+               }
+               map_rect_destroy(mr);
+        }
+}
+
+/**
+ * sets an attribute (name value pair) of a map item specified by map name and item id
+ *
+ * @param navit The navit instance
+ * @param function unused (needed to match command function signiture)
+ * @param in input attribute in[0] - name of the map  ; in[1] - item  ; in[2] - attr name ; in[3] - attr value
+ * @param out output attribute, 0 on error, 1 on success
+ * @param valid unused 
+ * @returns nothing
+ */
+static void
+navit_cmd_map_item_set_attr(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       if (
+               in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str  &&//map name
+                     in[1] && ATTR_IS_ITEM(in[1]->type)   &&                  //item
+                     in[2] && ATTR_IS_STRING(in[2]->type) && in[2]->u.str && //attr_type str
+                     in[3] && ATTR_IS_STRING(in[3]->type) && in[3]->u.str    //attr_value str
+       ) {
+               struct attr attr_to_set;
+               struct map* curr_map = NULL;
+               struct mapset *ms;
+               struct map_selection sel;
+               const int selection_range = 500;
+               struct coord curr_coord;
+               struct item *it;
+               
+               if(ATTR_IS_STRING(attr_from_name(in[2]->u.str))) {
+                       attr_to_set.u.str = in[3]->u.str;
+                       attr_to_set.type = attr_from_name(in[2]->u.str);
+               }
+               else if(ATTR_IS_INT(attr_from_name(in[2]->u.str))) {
+                       attr_to_set.u.num = atoi(in[3]->u.str);
+                       attr_to_set.type = attr_from_name(in[2]->u.str);
+               }
+               else if(ATTR_IS_DOUBLE(attr_from_name(in[2]->u.str))) {
+                       double* val = g_new0(double,1);
+                       *val = atof(in[3]->u.str);
+                       attr_to_set.u.numd = val;
+                       attr_to_set.type = attr_from_name(in[2]->u.str);
+               }
+
+               ms = navit_get_mapset(this);
+
+               curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
+
+               if( ! curr_map) {
+                       return;
+               }
+               sel.next=NULL;
+               sel.order=18;
+               sel.range.min=type_none;
+               sel.range.max=type_tec_common;
+               sel.u.c_rect.lu.x=curr_coord.x-selection_range;
+               sel.u.c_rect.lu.y=curr_coord.y+selection_range;
+               sel.u.c_rect.rl.x=curr_coord.x+selection_range;
+               sel.u.c_rect.rl.y=curr_coord.y-selection_range;
+               it = in[1]->u.item;
+               if(it) {
+                       item_attr_set(it, &attr_to_set, change_mode_modify);
+               }
+       }
+}
+
+/**
+ * Get attr variable given a key string for the command system (for opaque usage)
+ *
+ * @param navit The navit instance
+ * @param function unused (needed to match command function signiture)
+ * @param in input attribute in[0] is the key string
+ * @param out output attribute, the attr for the given key string if exists or NULL  
+ * @param valid unused 
+ * @returns nothing
+ */
+static void
+navit_cmd_get_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       struct attr **list = g_new0(struct attr *,2);
+       if(!cmd_int_var_hash) {
+               struct attr*val = g_new0(struct attr,1);
+               cmd_attr_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
+               val->type   = attr_type_item_begin;
+               val->u.item = NULL;
+               list[0]     = val;
+       }
+       if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) {
+               struct attr*ret = g_hash_table_lookup(cmd_attr_var_hash, in[0]->u.str);
+                if(ret) {
+                       list[0] = attr_dup(ret);
+               }
+               else {
+                       struct attr*val = g_new0(struct attr,1);
+                       val->type   = attr_type_int_begin;
+                       val->u.item = NULL;
+                       list[0]   = val;
+               }
+        }
+       list[1] = NULL;
+       *out = list;
+}
+
 
 /**
  * Get value given a key string for the command system
@@ -798,6 +1026,7 @@ navit_cmd_get_int_var(struct navit *this, char *function, struct attr **in, stru
        struct attr **list = g_new0(struct attr *,2);
        if(!cmd_int_var_hash) {
                struct attr*val = g_new0(struct attr,1);
+               cmd_int_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
                val->type   = attr_type_int_begin;
                val->u.num  = 0;
                list[0]     = val;
@@ -805,7 +1034,7 @@ navit_cmd_get_int_var(struct navit *this, char *function, struct attr **in, stru
        if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) {
                struct attr*ret = g_hash_table_lookup(cmd_int_var_hash, in[0]->u.str);
                 if(ret) {
-                       list[0] = ret;
+                       list[0] = attr_dup(ret);
                }
                else {
                        struct attr*val = g_new0(struct attr,1);
@@ -897,39 +1126,65 @@ navit_cmd_int_stack_size(struct navit *this, char *function, struct attr **in, s
        cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack,cmd_int_var_stack);
 }
 
-static void
-navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+static struct attr **
+navit_get_coord(struct navit *this, struct attr **in, struct pcoord *pc)
 {
-       struct pcoord pc;
-       char *description=NULL;
        if (!in)
-               return;
+               return NULL;
        if (!in[0])
-               return;
-       pc.pro = transform_get_projection(this->trans);
-       if (ATTR_IS_COORD(in[0]->type)) {
-               pc.x=in[0]->u.coord->x;
-               pc.y=in[0]->u.coord->y;
+               return NULL;
+       pc->pro = transform_get_projection(this->trans);
+       if (ATTR_IS_STRING(in[0]->type)) {
+               struct coord c;
+               coord_parse(in[0]->u.str, pc->pro, &c);
+               pc->x=c.x;
+               pc->y=c.y;
+               in++;   
+       } else if (ATTR_IS_COORD(in[0]->type)) {
+               pc->x=in[0]->u.coord->x;
+               pc->y=in[0]->u.coord->y;
                in++;
        } else if (ATTR_IS_PCOORD(in[0]->type)) {
-               pc=*in[0]->u.pcoord;
+               *pc=*in[0]->u.pcoord;
                in++;
        } else if (in[1] && in[2] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type) && ATTR_IS_INT(in[2]->type)) {
-               pc.pro=in[0]->u.num;
-               pc.x=in[1]->u.num;
-               pc.y=in[2]->u.num;
+               pc->pro=in[0]->u.num;
+               pc->x=in[1]->u.num;
+               pc->y=in[2]->u.num;
                in+=3;
        } else if (in[1] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type)) {
-               pc.x=in[0]->u.num;
-               pc.y=in[1]->u.num;
+               pc->x=in[0]->u.num;
+               pc->y=in[1]->u.num;
                in+=2;
        } else
+               return NULL;
+       return in;
+}
+
+static void
+navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       struct pcoord pc;
+       char *description=NULL;
+       in=navit_get_coord(this, in, &pc);
+       if (!in)
                return;
        if (in[0] && ATTR_IS_STRING(in[0]->type))
                description=in[0]->u.str;
        navit_set_destination(this, &pc, description, 1);
 }
 
+
+static void
+navit_cmd_set_center(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       struct pcoord pc;
+       in=navit_get_coord(this, in, &pc);
+       if (!in)
+               return;
+       navit_set_center(this, &pc, 0);
+}
+
 static void
 navit_cmd_fmt_coordinates(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
 {
@@ -941,11 +1196,110 @@ navit_cmd_fmt_coordinates(struct navit *this, char *function, struct attr **in,
        }
 }
 
+/**
+ * Join several string attributes into one
+ *
+ * @param navit The navit instance
+ * @param function unused (needed to match command function signiture)
+ * @param in input attributes in[0] - separator, in[1..] - attributes to join
+ * @param out output attribute joined attribute as string
+ * @param valid unused 
+ * @returns nothing
+ */
+static void
+navit_cmd_strjoin(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       struct attr attr;
+       gchar *ret, *sep;
+       int i;
+       attr.type=attr_type_string_begin;
+       attr.u.str=NULL;
+       if(in[0] && in[1]) {
+               sep=attr_to_text(in[0],NULL,1);
+               ret=attr_to_text(in[1],NULL,1);
+               for(i=2;in[i];i++) {
+                       gchar *in_i=attr_to_text(in[i],NULL,1);
+                       gchar *r=g_strjoin(sep,ret,in_i,NULL);
+                       g_free(in_i);
+                       g_free(ret);
+                       ret=r;
+               }
+               g_free(sep);
+               attr.u.str=ret;
+               if(out) {
+                       *out=attr_generic_add_attr(*out, &attr);
+               }
+               g_free(ret);
+       }
+}
+
+/**
+ * Call external program
+ *
+ * @param navit The navit instance
+ * @param function unused (needed to match command function signiture)
+ * @param in input attributes in[0] - name of executable, in[1..] - parameters
+ * @param out output attribute unused
+ * @param valid unused 
+ * @returns nothing
+ */
+static void
+navit_cmd_spawn(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
+{
+       int i,j, nparms, nvalid;
+       const char ** argv=NULL;
+       struct spawn_process_info *pi;
+
+       nparms=0;
+       nvalid=0;
+       if(in) {
+               while(in[nparms]) {
+                       if (in[nparms]->type!=attr_none) 
+                               nvalid++;
+                       nparms++;
+               }
+       }
+       
+       if(nvalid>0) {
+               argv=g_new(char*,nvalid+1);
+               for(i=0,j=0;in[i];i++) {
+                       if(in[i]->type!=attr_none ) {
+                               argv[j++]=attr_to_text(in[i],NULL,1);
+                       } else {
+                               dbg(0,"Parameter #%i is attr_none - skipping\n",i);
+                       }
+               }
+               argv[j]=NULL;
+               pi=spawn_process(argv);
+               
+               // spawn_process() testing suite - uncomment following code to test.
+               //sleep(3);
+               // example of non-blocking wait
+               //int st=spawn_process_check_status(pi,0);dbg(0,"status %i\n",st);
+               // example of blocking wait
+               //st=spawn_process_check_status(pi,1);dbg(0,"status %i\n",st);
+               // example of wait after process is finished and status is
+               // already tested
+               //st=spawn_process_check_status(pi,1);dbg(0,"status %i\n",st);
+               // example of wait after process is finished and status is
+               // already tested - unblocked
+               //st=spawn_process_check_status(pi,0);dbg(0,"status %i\n",st);
+               
+               // End testing suite
+               spawn_process_info_free(pi);
+               for(i=0;argv[i];i++)
+                       g_free(argv[i]);
+               g_free(argv);
+       }
+}
+
+
 static struct command_table commands[] = {
        {"zoom_in",command_cast(navit_cmd_zoom_in)},
        {"zoom_out",command_cast(navit_cmd_zoom_out)},
        {"zoom_to_route",command_cast(navit_cmd_zoom_to_route)},
        {"say",command_cast(navit_cmd_say)},
+       {"set_center",command_cast(navit_cmd_set_center)},
        {"set_center_cursor",command_cast(navit_cmd_set_center_cursor)},
        {"set_destination",command_cast(navit_cmd_set_destination)},
        {"announcer_toggle",command_cast(navit_cmd_announcer_toggle)},
@@ -956,6 +1310,12 @@ static struct command_table commands[] = {
        {"pop_int",command_cast(navit_cmd_pop_int)},
        {"int_stack_size",command_cast(navit_cmd_int_stack_size)},
        {"toggle_layer",command_cast(navit_cmd_toggle_layer)},
+       {"strjoin",command_cast(navit_cmd_strjoin)},
+       {"spawn",command_cast(navit_cmd_spawn)},
+       {"map_add_curr_pos",command_cast(navit_cmd_map_add_curr_pos)},
+       {"map_item_set_attr",command_cast(navit_cmd_map_item_set_attr)},
+       {"set_attr_var",command_cast(navit_cmd_set_attr_var)},
+       {"get_attr_var",command_cast(navit_cmd_get_attr_var)},
 };
        
 void 
@@ -1114,14 +1474,12 @@ navit_set_destination(struct navit *this_, struct pcoord *c, const char *descrip
                this_->destination=*c;
                this_->destination_valid=1;
 
-           dbg(1, "navit->navit_set_destination %i\n", c->x);
-           dbg(1, "navit->navit_set_destination %i\n", c->y);
-
+               dbg(1, "c=(%i,%i)\n", c->x,c->y);
+               destination_file = bookmarks_get_destination_file(TRUE);
+               bookmarks_append_coord(this_->former_destination, destination_file, c, type_former_destination, description, this_->recentdest_count);
+               g_free(destination_file);
        } else
                this_->destination_valid=0;
-       destination_file = bookmarks_get_destination_file(TRUE);
-       bookmarks_append_coord(this_->bookmarks, destination_file, c, 1, "former_destination", description, NULL, this_->recentdest_count);
-       g_free(destination_file);
        callback_list_call_attr_0(this_->attr_cbl, attr_destination);
        if (this_->route) {
                route_set_destination(this_->route, c, async);
@@ -1146,11 +1504,12 @@ navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const c
        if (c && count) {
                this_->destination=c[count-1];
                this_->destination_valid=1;
+
+               destination_file = bookmarks_get_destination_file(TRUE);
+               bookmarks_append_coord(this_->former_destination, destination_file, c, type_former_itinerary, description, this_->recentdest_count);
+               g_free(destination_file);
        } else
                this_->destination_valid=0;
-       destination_file = bookmarks_get_destination_file(TRUE);
-       bookmarks_append_coord(this_->bookmarks, destination_file, c, count, "former_itinerary", description, NULL, this_->recentdest_count);
-       g_free(destination_file);
        callback_list_call_attr_0(this_->attr_cbl, attr_destination);
        if (this_->route) {
                route_set_destinations(this_->route, c, count, async);
@@ -1195,23 +1554,10 @@ navit_former_destinations_active(struct navit *this_)
        return active;
 }
 
-static void
-navit_add_former_destinations_from_file(struct navit *this_)
-{
+struct map* read_former_destinations_from_file(){
+       struct attr type, data, flags, *attrs[4];
        char *destination_file = bookmarks_get_destination_file(FALSE);
-       struct attr *attrs[4];
-       struct map_rect *mr;
-       struct item *item;
-       int i,valid=0,count=0;
-       struct coord c[16];
-       struct pcoord pc[16];
-       struct attr parent;
-       struct attr type;
-       struct attr data;
-       struct attr flags;
-
-       parent.type=attr_navit;
-       parent.u.navit=this_;
+       struct map *m;
 
        type.type=attr_type;
        type.u.str="textfile";
@@ -1224,8 +1570,21 @@ navit_add_former_destinations_from_file(struct navit *this_)
 
        attrs[0]=&type; attrs[1]=&data; attrs[2]=&flags; attrs[3]=NULL;
 
-       this_->former_destination=map_new(&parent, attrs);
+       m=map_new(NULL, attrs);
        g_free(destination_file);
+       return m;
+}
+
+static void
+navit_add_former_destinations_from_file(struct navit *this_)
+{
+       struct item *item;
+       int i,valid=0,count=0;
+       struct coord c[16];
+       struct pcoord pc[16];
+       struct map_rect *mr;
+
+       this_->former_destination=read_former_destinations_from_file();
        if (!this_->route || !navit_former_destinations_active(this_))
                return; 
        mr=map_rect_new(this_->former_destination, NULL);
@@ -1285,8 +1644,13 @@ navit_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *
 void
 navit_say(struct navit *this_, char *text)
 {
+       struct attr attr;
        if(this_->speech) {
-               speech_say(this_->speech, text);
+               if (!speech_get_attr(this_->speech, attr_active, &attr, NULL))
+                       attr.u.num = 1;
+               dbg(1, "this_.speech->active %i\n", attr.u.num);
+               if(attr.u.num)
+                       speech_say(this_->speech, text);
        }
 }
 
@@ -1446,6 +1810,7 @@ navit_window_roadbook_destroy(struct navit *this_)
 {
        dbg(0, "enter\n");
        navigation_unregister_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
+       callback_destroy(this_->roadbook_callback);
        this_->roadbook_window=NULL;
        this_->roadbook_callback=NULL;
 }
@@ -1510,7 +1875,9 @@ navit_init(struct navit *this_)
                this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
                msh=mapset_open(ms);
                while (msh && (map=mapset_next(msh, 0))) {
-                       map_add_callback(map, this_->progress_cb);
+                       //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
+                       struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
+                       map_add_callback(map, pcb);
                }
                mapset_close(msh);
                
@@ -1669,6 +2036,7 @@ navit_zoom_to_route(struct navit *this_, int orientation)
                                count++;
                        }
                }
+               map_rect_destroy(mr);
        }
        if (! count)
                return;
@@ -1839,16 +2207,6 @@ navit_set_center_screen(struct navit *this_, struct point *p, int set_timeout)
        navit_set_center(this_, &pc, set_timeout);
 }
 
-#if 0
-               switch((*attrs)->type) {
-               case attr_zoom:
-                       zoom=(*attrs)->u.num;
-                       break;
-               case attr_center:
-                       g=*((*attrs)->u.coord_geo);
-                       break;
-#endif
-
 static int
 navit_set_attr_do(struct navit *this_, struct attr *attr, int init)
 {
@@ -2160,6 +2518,9 @@ navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, stru
        case attr_orientation:
                attr->u.num=this_->orientation;
                break;
+       case attr_osd:
+               ret=attr_generic_get_attr(this_->attr_list, NULL, type, attr, iter?(struct attr_iter *)&iter->iter:NULL);
+               break;
        case attr_osd_configuration:
                attr->u.num=this_->osd_configuration;
                break;
@@ -2248,8 +2609,11 @@ navit_add_layout(struct navit *this_, struct layout *layout)
        struct attr active;
        this_->layouts = g_list_append(this_->layouts, layout);
        layout_get_attr(layout, attr_active, &active, NULL);
-       if(active.u.num || !this_->layout_current) 
+       if(active.u.num || !this_->layout_current) 
                this_->layout_current=layout;
+               return 1;
+       }
+       return 0;
 }
 
 int
@@ -2281,6 +2645,9 @@ navit_add_attr(struct navit *this_, struct attr *attr)
        case attr_navigation:
                this_->navigation=attr->u.navigation;
                break;
+       case attr_osd:
+               this_->attr_list=attr_generic_add_attr(this_->attr_list, attr);
+               break;
        case attr_recent_dest:
                this_->recentdest_count = attr->u.num;
                break;
@@ -2464,7 +2831,7 @@ navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv)
                        route_remove_waypoint(this_->route);
                        count=route_get_destinations(this_->route, pc, 16);
                        destination_file = bookmarks_get_destination_file(TRUE);
-                       bookmarks_append_coord(this_->bookmarks, destination_file, pc, count, "former_itinerary_part", NULL, NULL, this_->recentdest_count);
+                       bookmarks_append_coord(this_->former_destination, destination_file, pc, type_former_itinerary_part, NULL, this_->recentdest_count);
                        break;  
                case 2:
                        navit_set_destination(this_, NULL, NULL, 0);
@@ -2766,6 +3133,7 @@ navit_block(struct navit *this_, int block)
 void
 navit_destroy(struct navit *this_)
 {
+       struct mapset*ms;
        callback_list_call_attr_1(this_->attr_cbl, attr_destroy, this_);
 
        /* TODO: destroy objects contained in this_ */
@@ -2781,6 +3149,7 @@ navit_destroy(struct navit *this_)
        callback_destroy(this_->roadbook_callback);
        callback_destroy(this_->popup_callback);
        callback_destroy(this_->motion_timeout_callback);
+       callback_destroy(this_->progress_cb);
        if(this_->gra)
          graphics_remove_callback(this_->gra, this_->resize_callback);
        callback_destroy(this_->resize_callback);
@@ -2794,6 +3163,9 @@ navit_destroy(struct navit *this_)
          graphics_remove_callback(this_->gra, this_->predraw_callback);
        callback_destroy(this_->predraw_callback);
        route_destroy(this_->route);
+       ms = navit_get_mapset(this_);
+       if(ms)
+               mapset_destroy(ms);
        graphics_free(this_->gra);
        g_free(this_);
 }