X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=navit%2Fnavit%2Fnavit.c;h=99b5da605b48b8f9da9eeb259a4604354338929c;hb=9eea99403b4fe6be74f693b66c980a1e84597414;hp=261c8c303eebba20e1f7312e4b1ead6bc4843d77;hpb=55b64ac4e4d9e3600a0f4c96264f6329bd60f866;p=profile%2Fivi%2Fnavit.git diff --git a/navit/navit/navit.c b/navit/navit/navit.c index 261c8c3..99b5da6 100644 --- a/navit/navit/navit.c +++ b/navit/navit/navit.c @@ -17,16 +17,19 @@ * Boston, MA 02110-1301, USA. */ +#define _USE_MATH_DEFINES 1 +#include "config.h" +#ifdef HAVE_UNISTD_H +#include +#endif #include #include #include #include -#include #include #include #include #include -#include "config.h" #include "debug.h" #include "navit.h" #include "callback.h" @@ -57,11 +60,19 @@ #include "profile.h" #include "command.h" #include "navit_nls.h" +#include "map.h" #include "util.h" #include "messages.h" #include "vehicleprofile.h" #include "sunriset.h" #include "bookmarks.h" +#ifdef HAVE_API_WIN32_BASE +#include +#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 @@ -108,7 +119,7 @@ struct navit { GList *windows_items; struct navit_vehicle *vehicle; struct callback_list *attr_cbl; - struct callback *nav_speech_cb, *roadbook_callback, *popup_callback, *route_cb; + struct callback *nav_speech_cb, *roadbook_callback, *popup_callback, *route_cb, *progress_cb; struct datawindow *roadbook_window; struct map *former_destination; struct point pressed, last, current; @@ -129,7 +140,7 @@ struct navit { int drag_bitmap; int use_mousewheel; struct messagelist *messages; - struct callback *resize_callback,*button_callback,*motion_callback,*postdraw_callback; + struct callback *resize_callback,*button_callback,*motion_callback,*predraw_callback; struct vehicleprofile *vehicleprofile; GList *vehicleprofiles; int pitch; @@ -143,11 +154,14 @@ struct navit { /* 1=No graphics ok */ /* 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; @@ -250,6 +264,34 @@ navit_draw_displaylist(struct navit *this_) } static void +navit_map_progress(struct navit *this_) +{ + struct map *map; + struct mapset *ms; + struct mapset_handle *msh; + struct attr attr; + struct point p; + if (this_->ready != 3) + return; + p.x=10; + p.y=32; + + ms=this_->mapsets->data; + msh=mapset_open(ms); + while (msh && (map=mapset_next(msh, 0))) { + if (map_get_attr(map, attr_progress, &attr, NULL)) { + char *str=g_strdup_printf("%s ",attr.u.str); + graphics_draw_mode(this_->gra, draw_mode_begin); + graphics_draw_text_std(this_->gra, 16, str, &p); + g_free(str); + p.y+=32; + graphics_draw_mode(this_->gra, draw_mode_end); + } + } + mapset_close(msh); +} + +static void navit_redraw_route(struct navit *this_, struct route *route, struct attr *attr) { int updated; @@ -286,7 +328,7 @@ navit_handle_resize(struct navit *this_, int w, int h) if (callback) callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_); if (this_->ready == 3) - navit_draw(this_); + navit_draw_async(this_, 1); } static void @@ -527,7 +569,7 @@ navit_motion(void *data, struct point *p) } static void -navit_postdraw(struct navit *this_) +navit_predraw(struct navit *this_) { GList *l; struct navit_vehicle *nv; @@ -650,7 +692,7 @@ void navit_zoom_in_cursor(struct navit *this_, int factor) { struct point p; - if (this_->vehicle && this_->vehicle->follow_curr == 1 && navit_get_cursor_pnt(this_, &p, 0, NULL)) { + if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL)) { navit_zoom_in(this_, factor, &p); this_->vehicle->follow_curr=this_->vehicle->follow; } else @@ -661,14 +703,13 @@ void navit_zoom_out_cursor(struct navit *this_, int factor) { struct point p; - if (this_->vehicle && this_->vehicle->follow_curr == 1 && navit_get_cursor_pnt(this_, &p, 0, NULL)) { + if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL)) { navit_zoom_out(this_, 2, &p); this_->vehicle->follow_curr=this_->vehicle->follow; } else navit_zoom_out(this_, 2, NULL); } - static int navit_cmd_zoom_in(struct navit *this_) { @@ -691,39 +732,459 @@ navit_cmd_say(struct navit *this, char *function, struct attr **in, struct attr navit_say(this, in[0]->u.str); } +static GHashTable *cmd_int_var_hash = NULL; +static GHashTable *cmd_attr_var_hash = NULL; + +/** + * 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) + * @param in input attributes in[0] is the key string, in[1] is the integer value to store + * @param out output attributes, unused + * @param valid unused + * @returns nothing + */ static void -navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid) +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))) { + 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 + * + * @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 layer + * @param out output unused + * @param valid unused + * @returns nothing + */ +static void +navit_cmd_toggle_layer(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) { + if(this->layout_current && this->layout_current->layers) { + GList* layers = this->layout_current->layers; + while (layers) { + struct layer*l=layers->data; + if(l && !strcmp(l->name,in[0]->u.str) ) { + l->active ^= 1; + navit_draw(this); + return; + } + layers=g_list_next(layers); + } + } + } +} + +/** + * 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 + * + * @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 value for the given key string if exists or 0 + * @param valid unused + * @returns nothing + */ +static void +navit_cmd_get_int_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_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; + } + 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] = attr_dup(ret); + } + else { + struct attr*val = g_new0(struct attr,1); + val->type = attr_type_int_begin; + val->u.num = 0; + list[0] = val; + } + } + list[1] = NULL; + *out = list; +} + +GList *cmd_int_var_stack = NULL; + +/** + * Push an integer to the stack for the command system + * + * @param navit The navit instance + * @param function unused (needed to match command function signiture) + * @param in input attribute in[0] is the integer attibute to push + * @param out output attributes, unused + * @param valid unused + * @returns nothing + */ +static void +navit_cmd_push_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid) +{ + if (in && in[0] && ATTR_IS_NUMERIC(in[0]->type)) { + struct attr*val = g_new(struct attr,1); + attr_dup_content(in[0],val); + cmd_int_var_stack = g_list_prepend(cmd_int_var_stack, val); + } +} + +/** + * Pop an integer from the command system's integer stack + * + * @param navit The navit instance + * @param function unused (needed to match command function signiture) + * @param in input attributes unused + * @param out output attribute, the value popped if stack isn't empty or 0 + * @param valid unused + * @returns nothing + */ +static void +navit_cmd_pop_int(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_stack) { + struct attr*val = g_new0(struct attr,1); + val->type = attr_type_int_begin; + val->u.num = 0; + list[0] = val; + } + else { + list[0] = cmd_int_var_stack->data; + cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack,cmd_int_var_stack); + } + list[1] = NULL; + *out = list; +} + +/** + * Get current size of command system's integer stack + * + * @param navit The navit instance + * @param function unused (needed to match command function signiture) + * @param in input attributes unused + * @param out output attribute, the size of stack + * @param valid unused + * @returns nothing + */ +static void +navit_cmd_int_stack_size(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid) +{ + struct attr **list; + struct attr *attr = g_new0(struct attr ,1); + attr->type = attr_type_int_begin; + if(!cmd_int_var_stack) { + attr->u.num = 0; + } + else { + attr->u.num = g_list_length(cmd_int_var_stack); + } + list = g_new0(struct attr *,2); + list[0] = attr; + list[1] = NULL; + *out = list; + cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack,cmd_int_var_stack); +} + +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) { @@ -735,17 +1196,133 @@ 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)}, {"fmt_coordinates",command_cast(navit_cmd_fmt_coordinates)}, + {"set_int_var",command_cast(navit_cmd_set_int_var)}, + {"get_int_var",command_cast(navit_cmd_get_int_var)}, + {"push_int",command_cast(navit_cmd_push_int)}, + {"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 +navit_command_add_table(struct navit*this_, struct command_table *commands, int count) +{ + command_add_table(this_->attr_cbl, commands, count, this_); +} struct navit * navit_new(struct attr *parent, struct attr **attrs) @@ -844,8 +1421,8 @@ navit_set_graphics(struct navit *this_, struct graphics *gra) graphics_add_callback(gra, this_->button_callback); this_->motion_callback=callback_new_attr_1(callback_cast(navit_motion), attr_motion, this_); graphics_add_callback(gra, this_->motion_callback); - this_->postdraw_callback=callback_new_attr_1(callback_cast(navit_postdraw), attr_postdraw, this_); - graphics_add_callback(gra, this_->postdraw_callback); + this_->predraw_callback=callback_new_attr_1(callback_cast(navit_predraw), attr_predraw, this_); + graphics_add_callback(gra, this_->predraw_callback); return 1; } @@ -892,14 +1469,17 @@ navit_projection_set(struct navit *this_, enum projection pro, int draw) void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async) { + char *destination_file; if (c) { this_->destination=*c; this_->destination_valid=1; + + 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; - char *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); @@ -920,14 +1500,16 @@ navit_set_destination(struct navit *this_, struct pcoord *c, const char *descrip void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async) { + char *destination_file; 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; - char *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); @@ -972,21 +1554,37 @@ navit_former_destinations_active(struct navit *this_) return active; } +struct map* read_former_destinations_from_file(){ + struct attr type, data, flags, *attrs[4]; + char *destination_file = bookmarks_get_destination_file(FALSE); + struct map *m; + + type.type=attr_type; + type.u.str="textfile"; + + data.type=attr_data; + data.u.str=destination_file; + + flags.type=attr_flags; + flags.u.num=1; + + attrs[0]=&type; attrs[1]=&data; attrs[2]=&flags; attrs[3]=NULL; + + m=map_new(NULL, attrs); + g_free(destination_file); + return m; +} + static void navit_add_former_destinations_from_file(struct navit *this_) { - char *destination_file = bookmarks_get_destination_file(FALSE); - struct attr parent={attr_navit, .u.navit=this_}; - struct attr type={attr_type, {"textfile"}}, data={attr_data, {destination_file}}, flags={attr_flags, {(void *)1}}; - struct attr *attrs[]={&type, &data, &flags, NULL}; - struct map_rect *mr; struct item *item; int i,valid=0,count=0; struct coord c[16]; struct pcoord pc[16]; + struct map_rect *mr; - this_->former_destination=map_new(&parent, attrs); - g_free(destination_file); + 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); @@ -1027,16 +1625,33 @@ navit_textfile_debug_log(struct navit *this_, const char *fmt, ...) va_end(ap); } -int -navit_speech_estimate(struct navit *this_, char *str) +void +navit_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *fmt, ...) { - return speech_estimate_duration(this_->speech, str); + va_list ap; + char *str1,*str2; + va_start(ap, fmt); + if (this_->textfile_debug_log && this_->vehicle) { + str1=g_strdup_vprintf(fmt, ap); + str2=g_strdup_printf("0x%x 0x%x%s%s\n", pc->x, pc->y, strlen(str1) ? " " : "", str1); + log_write(this_->textfile_debug_log, str2, strlen(str2), 0); + g_free(str2); + g_free(str1); + } + va_end(ap); } void navit_say(struct navit *this_, char *text) { - speech_say(this_->speech, text); + struct attr attr; + if(this_->speech) { + 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); + } } /** @@ -1195,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; } @@ -1217,6 +1833,7 @@ navit_init(struct navit *this_) struct mapset *ms; struct map *map; int callback; + char *center_file; dbg(2,"enter gui %p graphics %p\n",this_->gui,this_->gra); @@ -1242,18 +1859,43 @@ navit_init(struct navit *this_) navit_destroy(this_); return; } + if (this_->speech && this_->navigation) { + struct attr speech; + speech.type=attr_speech; + speech.u.speech=this_->speech; + navigation_set_attr(this_->navigation, &speech); + } dbg(2,"Initializing graphics\n"); dbg(2,"Setting Vehicle\n"); navit_set_vehicle(this_, this_->vehicle); dbg(2,"Adding dynamic maps to mapset %p\n",this_->mapsets); if (this_->mapsets) { + struct mapset_handle *msh; ms=this_->mapsets->data; + 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))) { + //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); + if (this_->route) { - if ((map=route_get_map(this_->route))) - mapset_add_attr(ms, &(struct attr){attr_map,.u.map=map}); + if ((map=route_get_map(this_->route))) { + struct attr map_a; + map_a.type=attr_map; + map_a.u.map=map; + mapset_add_attr(ms, &map_a); + } if ((map=route_get_graph_map(this_->route))) { - mapset_add_attr(ms, &(struct attr){attr_map,.u.map=map}); - map_set_attr(map, &(struct attr ){attr_active,.u.num=0}); + struct attr map_a,active; + map_a.type=attr_map; + map_a.u.map=map; + active.type=attr_active; + active.u.num=0; + mapset_add_attr(ms, &map_a); + map_set_attr(map, &active); } route_set_mapset(this_->route, ms); route_set_projection(this_->route, transform_get_projection(this_->trans)); @@ -1265,14 +1907,24 @@ navit_init(struct navit *this_) } if (this_->navigation) { if ((map=navigation_get_map(this_->navigation))) { - mapset_add_attr(ms, &(struct attr){attr_map,.u.map=map}); - map_set_attr(map, &(struct attr ){attr_active,.u.num=0}); + struct attr map_a,active; + map_a.type=attr_map; + map_a.u.map=map; + active.type=attr_active; + active.u.num=0; + mapset_add_attr(ms, &map_a); + map_set_attr(map, &active); } } if (this_->tracking) { if ((map=tracking_get_map(this_->tracking))) { - mapset_add_attr(ms, &(struct attr){attr_map,.u.map=map}); - map_set_attr(map, &(struct attr ){attr_active,.u.num=0}); + struct attr map_a,active; + map_a.type=attr_map; + map_a.u.map=map; + active.type=attr_active; + active.u.num=0; + mapset_add_attr(ms, &map_a); + map_set_attr(map, &active); } } navit_add_former_destinations_from_file(this_); @@ -1293,7 +1945,7 @@ navit_init(struct navit *this_) navigation_set_route(this_->navigation, this_->route); } dbg(2,"Setting Center\n"); - char *center_file = bookmarks_get_center_file(FALSE); + center_file = bookmarks_get_center_file(FALSE); bookmarks_set_center_from_file(this_->bookmarks, center_file); g_free(center_file); #if 0 @@ -1319,7 +1971,7 @@ navit_init(struct navit *this_) this_->ready|=1; dbg(2,"ready=%d\n",this_->ready); if (this_->ready == 3) - navit_draw(this_); + navit_draw_async(this_, 1); if (callback) callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_); #if 0 @@ -1384,6 +2036,7 @@ navit_zoom_to_route(struct navit *this_, int orientation) count++; } } + map_rect_destroy(mr); } if (! count) return; @@ -1465,7 +2118,7 @@ navit_set_cursors(struct navit *this_) c=layout_get_cursor(this_->layout_current, name.u.str); } else c=layout_get_cursor(this_->layout_current, "default"); - vehicle_set_cursor(nv->vehicle, c); + vehicle_set_cursor(nv->vehicle, c, 0); v=g_list_next(v); } return; @@ -1554,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) { @@ -1572,8 +2215,10 @@ navit_set_attr_do(struct navit *this_, struct attr *attr, int init) long zoom; GList *l; struct navit_vehicle *nv; - struct attr active=(struct attr){attr_active,{(void *)0}}; struct layout *lay; + struct attr active; + active.type=attr_active; + active.u.num=0; switch (attr->type) { case attr_autozoom: @@ -1743,6 +2388,10 @@ navit_set_attr_do(struct navit *this_, struct attr *attr, int init) attr_updated=(this_->follow_cursor != !!attr->u.num); this_->follow_cursor=!!attr->u.num; break; + case attr_imperial: + attr_updated=(this_->imperial != attr->u.num); + this_->imperial=attr->u.num; + break; default: return 0; } @@ -1795,6 +2444,9 @@ navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, stru attr->u.str[len] = '\0'; break; + case attr_imperial: + attr->u.num=this_->imperial; + break; case attr_bookmark_map: attr->u.map=bookmarks_get_map(this_->bookmarks); break; @@ -1866,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; @@ -1948,6 +2603,19 @@ navit_add_log(struct navit *this_, struct log *log) return 0; } +static int +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) { + this_->layout_current=layout; + return 1; + } + return 0; +} + int navit_add_attr(struct navit *this_, struct attr *attr) { @@ -1966,9 +2634,7 @@ navit_add_attr(struct navit *this_, struct attr *attr) ret=navit_set_graphics(this_, attr->u.graphics); break; case attr_layout: - this_->layouts = g_list_append(this_->layouts, attr->u.layout); - if(!this_->layout_current) - this_->layout_current=attr->u.layout; + ret=navit_add_layout(this_, attr->u.layout); break; case attr_route: this_->route=attr->u.route; @@ -1979,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; @@ -2162,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); @@ -2464,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_ */ @@ -2479,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); @@ -2489,9 +3160,13 @@ navit_destroy(struct navit *this_) graphics_remove_callback(this_->gra, this_->motion_callback); callback_destroy(this_->motion_callback); if(this_->gra) - graphics_remove_callback(this_->gra, this_->postdraw_callback); - callback_destroy(this_->postdraw_callback); + 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_); }