* Boston, MA 02110-1301, USA.
*/
+#define _USE_MATH_DEFINES 1
+#include "config.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
-#include <unistd.h>
#include <fcntl.h>
#include <glib.h>
#include <math.h>
#include <time.h>
-#include "config.h"
#include "debug.h"
#include "navit.h"
#include "callback.h"
#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 <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
struct layout *layout_current;
struct graphics *gra;
struct action *action;
- struct transformation *trans;
+ struct transformation *trans, *trans_cursor;
struct compass *compass;
struct route *route;
struct navigation *navigation;
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 *bookmark;
struct map *former_destination;
- GHashTable *bookmarks_hash;
struct point pressed, last, current;
int button_pressed,moved,popped,zoomed;
int center_timeout;
int drag_bitmap;
int use_mousewheel;
struct messagelist *messages;
- struct callback *resize_callback,*button_callback,*motion_callback;
+ struct callback *resize_callback,*button_callback,*motion_callback,*predraw_callback;
struct vehicleprofile *vehicleprofile;
GList *vehicleprofiles;
int pitch;
int follow_cursor;
int prevTs;
+ int graphics_flags;
+ int zoom_min, zoom_max;
+ int radius;
+ struct bookmarks *bookmarks;
+ int flags;
+ /* 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;
static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt);
static int navit_add_vehicle(struct navit *this_, struct vehicle *v);
static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init);
-static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int *dir);
+static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir);
static void navit_set_cursors(struct navit *this_);
static void navit_cmd_zoom_to_route(struct navit *this);
static void navit_cmd_set_center_cursor(struct navit *this_);
static void navit_cmd_announcer_toggle(struct navit *this_);
static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv);
+struct navit *global_navit;
+
void
navit_add_mapset(struct navit *this_, struct mapset *ms)
{
return this_->tracking;
}
-static void
+/**
+ * @brief Get the user data directory.
+ * @param[in] create - create the directory if it does not exist
+ *
+ * @return char * to the data directory string.
+ *
+ * returns the directory used to store user data files (center.txt,
+ * destination.txt, bookmark.txt, ...)
+ *
+ */
+char*
+navit_get_user_data_directory(int create) {
+ char *dir;
+ dir = getenv("NAVIT_USER_DATADIR");
+ if (create && !file_exists(dir)) {
+ dbg(0,"creating dir %s\n", dir);
+ if (file_mkdir(dir,0)) {
+ dbg(0,"failed creating dir %s\n", dir);
+ return NULL;
+ }
+ }
+ return dir;
+} /* end: navit_get_user_data_directory(gboolean create) */
+
+
+void
navit_draw_async(struct navit *this_, int async)
{
- GList *l;
- struct navit_vehicle *nv;
if (this_->blocked) {
this_->blocked |= 2;
return;
}
transform_setup_source_rect(this_->trans);
- l=this_->vehicles;
- while (l) {
- nv=l->data;
- navit_vehicle_draw(this_, nv, NULL);
- l=g_list_next(l);
- }
- graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL);
+ graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
}
void
navit_draw(struct navit *this_)
{
- navit_draw_async(this_, 0);
+ if (this_->ready == 3)
+ navit_draw_async(this_, 0);
}
int
navit_draw_displaylist(struct navit *this_)
{
if (this_->ready == 3)
- graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current, 1);
+ graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current, this_->graphics_flags|1);
+}
+
+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_handle_resize(struct navit *this_, int w, int h)
{
struct map_selection sel;
+ int callback=(this_->ready == 1);
this_->ready |= 2;
- if (this_->w != w || this_->h != h) {
- memset(&sel, 0, sizeof(sel));
- this_->w=w;
- this_->h=h;
- sel.u.p_rect.rl.x=w;
- sel.u.p_rect.rl.y=h;
- transform_set_screen_selection(this_->trans, &sel);
- graphics_init(this_->gra);
- graphics_set_rect(this_->gra, &sel.u.p_rect);
- }
+ memset(&sel, 0, sizeof(sel));
+ this_->w=w;
+ this_->h=h;
+ sel.u.p_rect.rl.x=w;
+ sel.u.p_rect.rl.y=h;
+ transform_set_screen_selection(this_->trans, &sel);
+ graphics_init(this_->gra);
+ graphics_set_rect(this_->gra, &sel.u.p_rect);
+ 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
int yaw;
double angleo,anglen;
- transform_reverse(tr, old, &co);
+ if (!transform_reverse(tr, old, &co))
+ return;
if (rot) {
angleo=atan2(old->y-rot->y, old->x-rot->x)*180/M_PI;
anglen=atan2(new->y-rot->y, new->x-rot->x)*180/M_PI;
yaw=transform_get_yaw(tr)+angleo-anglen;
transform_set_yaw(tr, yaw % 360);
}
- transform_reverse(tr, new, &cn);
+ if (!transform_reverse(tr, new, &cn))
+ return;
cp=transform_get_center(tr);
c.x=cp->x+co.x-cn.x;
c.y=cp->y+co.y-cn.y;
transform_set_center(tr, &c);
}
-static void
+void
navit_set_timeout(struct navit *this_)
{
struct attr follow;
{
int border=16;
+ dbg(1,"enter %d %d (ignore %d)\n",pressed,button,this_->ignore_button);
callback_list_call_attr_4(this_->attr_cbl, attr_button, this_, GINT_TO_POINTER(pressed), GINT_TO_POINTER(button), p);
if (this_->ignore_button) {
this_->ignore_button=0;
update_transformation(this_->trans, &this_->pressed, p, NULL);
#endif
graphics_draw_drag(this_->gra, NULL);
+ transform_copy(this_->trans, this_->trans_cursor);
graphics_overlay_disable(this_->gra, 0);
if (!this_->zoomed)
navit_set_timeout(this_);
navit_button(void *data, int pressed, int button, struct point *p)
{
struct navit *this=data;
+ dbg(1,"enter %d %d ignore %d\n",pressed,button,this->ignore_graphics_events);
if (!this->ignore_graphics_events) {
if (! this->popup_callback)
this->popup_callback=callback_new_1(callback_cast(navit_popup), this);
graphics_displaylist_move(this_->displaylist, dx, dy);
#endif
graphics_draw_cancel(this_->gra, this_->displaylist);
- graphics_displaylist_draw(this_->gra, this_->displaylist, tr, this_->layout_current, 0);
+ graphics_displaylist_draw(this_->gra, this_->displaylist, tr, this_->layout_current, this_->graphics_flags);
transform_destroy(tr);
this_->moved=1;
}
dx=(p->x-this_->pressed.x);
dy=(p->y-this_->pressed.y);
if (dx < -8 || dx > 8 || dy < -8 || dy > 8) {
+ this_->moved=1;
if (this_->button_timeout) {
event_remove_timeout(this_->button_timeout);
this_->button_timeout=NULL;
}
static void
+navit_predraw(struct navit *this_)
+{
+ GList *l;
+ struct navit_vehicle *nv;
+ transform_copy(this_->trans, this_->trans_cursor);
+ l=this_->vehicles;
+ while (l) {
+ nv=l->data;
+ navit_vehicle_draw(this_, nv, NULL);
+ l=g_list_next(l);
+ }
+}
+
+static void
navit_scale(struct navit *this_, long scale, struct point *p, int draw)
{
struct coord c1, c2, *center;
+ if (scale < this_->zoom_min)
+ scale=this_->zoom_min;
+ if (scale > this_->zoom_max)
+ scale=this_->zoom_max;
if (p)
transform_reverse(this_->trans, p, &c1);
transform_set_scale(this_->trans, scale);
navit_scale(this_, scale, p, 1);
}
-static int
-navit_cmd_zoom_in(struct navit *this_)
+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, NULL)) {
- navit_zoom_in(this_, 2, &p);
+ 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
- navit_zoom_in(this_, 2, NULL);
- return 0;
+ navit_zoom_in(this_, factor, NULL);
}
-static int
-navit_cmd_zoom_out(struct navit *this_)
+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, 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_)
+{
+ navit_zoom_in_cursor(this_, 2);
return 0;
}
+static int
+navit_cmd_zoom_out(struct navit *this_)
+{
+ navit_zoom_out_cursor(this_, 2);
+ return 0;
+}
+
+
+static void
+navit_cmd_say(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)
+ 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_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)
+{
+ if (!in)
+ return NULL;
+ if (!in[0])
+ 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;
+ 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;
+ 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;
+ 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)
+{
+ struct attr attr;
+ attr.type=attr_type_string_begin;
+ attr.u.str="Fix me";
+ if (out) {
+ *out=attr_generic_add_attr(*out, &attr);
+ }
+}
+
+/**
+ * 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)
this_->self.u.navit=this_;
this_->attr_cbl=callback_list_new();
- this_->bookmarks_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-
this_->orientation=-1;
this_->tracking_flag=1;
this_->recentdest_count=10;
this_->autozoom_secs = 10;
this_->autozoom_min = 7;
this_->autozoom_active = 0;
+ this_->zoom_min = 1;
+ this_->zoom_max = 2097152;
this_->follow_cursor = 1;
+ this_->radius = 30;
+ this_->border = 16;
this_->trans = transform_new();
+ this_->trans_cursor = transform_new();
transform_from_geo(pro, &g, &co);
center.x=co.x;
center.y=co.y;
center.pro = pro;
+ transform_setup(this_->trans, ¢er, zoom, (this_->orientation != -1) ? this_->orientation : 0);
+
+ this_->bookmarks=bookmarks_new(&this_->self, NULL, this_->trans);
+
this_->prevTs=0;
- transform_setup(this_->trans, ¢er, zoom, (this_->orientation != -1) ? this_->orientation : 0);
for (;*attrs; attrs++) {
navit_set_attr_do(this_, *attrs, 1);
}
return message_get(this_->messages);
}
-static int
-navit_set_graphics(struct navit *this_, struct graphics *gra)
-{
- if (this_->gra)
- return 0;
- this_->gra=gra;
- this_->resize_callback=callback_new_attr_1(callback_cast(navit_resize), attr_resize, this_);
- graphics_add_callback(gra, this_->resize_callback);
- this_->button_callback=callback_new_attr_1(callback_cast(navit_button), attr_button, this_);
- 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);
- return 1;
-}
-
-struct graphics *
-navit_get_graphics(struct navit *this_)
-{
- return this_->gra;
-}
-
-struct vehicleprofile *
-navit_get_vehicleprofile(struct navit *this_)
-{
- return this_->vehicleprofile;
-}
-
-GList *
-navit_get_vehicleprofiles(struct navit *this_)
-{
- return this_->vehicleprofiles;
-}
-
-static void
-navit_projection_set(struct navit *this_, enum projection pro)
-{
- struct coord_geo g;
- struct coord *c;
-
- c=transform_center(this_->trans);
- transform_to_geo(transform_get_projection(this_->trans), c, &g);
- transform_set_projection(this_->trans, pro);
- transform_from_geo(pro, &g, c);
- navit_draw(this_);
-}
-
-/**
- * @param limit Limits the number of entries in the "backlog". Set to 0 for "infinite"
- */
-static void
-navit_append_coord(struct navit *this_, char *file, struct pcoord *c, const char *type, const char *description, GHashTable *h, int limit)
-{
- FILE *f;
- int offset=0;
- char *buffer;
- int ch,prev,lines=0;
- int numc,readc;
- int fd;
- const char *prostr;
-
- f=fopen(file, "r");
- if (!f)
- goto new_file;
- if (limit != 0) {
- prev = '\n';
- while ((ch = fgetc(f)) != EOF) {
- if ((ch == '\n') && (prev != '\n')) {
- lines++;
- }
- prev = ch;
- }
-
- if (prev != '\n') { // Last line did not end with a newline
- lines++;
- }
-
- fclose(f);
- f = fopen(file, "r+");
- fd = fileno(f);
- while (lines >= limit) { // We have to "scroll up"
- rewind(f);
- numc = 0; // Counts how many bytes we have in our line to scroll up
- while ((ch = fgetc(f)) != EOF) {
- numc++;
- if (ch == '\n') {
- break;
- }
- }
-
- buffer=g_malloc(numc);
- offset = numc; // Offset holds where we currently are
-
- do {
- fseek(f,offset,SEEK_SET);
- readc = fread(buffer,1,numc,f);
-
- fseek(f,-(numc+readc),SEEK_CUR);
- fwrite(buffer,1,readc,f);
-
- offset += readc;
- } while (readc == numc);
-
- g_free(buffer);
- fflush(f);
- ftruncate(fd,(offset-numc));
-#ifdef HAVE_FSYNC
- fsync(fd);
-#endif
-
- lines--;
- }
- fclose(f);
- }
-
-new_file:
- f=fopen(file, "a");
- if (f) {
- if (c) {
- prostr = projection_to_name(c->pro,NULL);
- fprintf(f,"%s%s%s0x%x %s0x%x type=%s label=\"%s\"\n",
- prostr, *prostr ? ":" : "",
- c->x >= 0 ? "":"-", c->x >= 0 ? c->x : -c->x,
- c->y >= 0 ? "":"-", c->y >= 0 ? c->y : -c->y,
- type, description);
- } else
- fprintf(f,"\n");
- }
- fclose(f);
-}
-
-/*
- * navit_get_user_data_directory
- *
- * returns the directory used to store user data files (center.txt,
- * destination.txt, bookmark.txt, ...)
- *
- * arg: gboolean create: create the directory if it does not exist
- */
-static char*
-navit_get_user_data_directory(gboolean create) {
- char *dir;
- dir = getenv("NAVIT_USER_DATADIR");
- if (create && !file_exists(dir)) {
- dbg(0,"creating dir %s\n", dir);
- if (file_mkdir(dir,0)) {
- dbg(0,"failed creating dir %s\n", dir);
- return NULL;
- }
- }
-
- return dir;
-}
-
-/*
- * navit_get_destination_file
- *
- * returns the name of the file used to store destinations with its
- * full path
- *
- * arg: gboolean create: create the directory where the file is stored
- * if it does not exist
- */
-static char*
-navit_get_destination_file(gboolean create)
-{
- return g_strjoin(NULL, navit_get_user_data_directory(create), "/destination.txt", NULL);
-}
-
-/*
- * navit_get_bookmark_file
- *
- * returns the name of the file used to store bookmarks with its
- * full path
- *
- * arg: gboolean create: create the directory where the file is stored
- * if it does not exist
- */
-static char*
-navit_get_bookmark_file(gboolean create)
+static int
+navit_set_graphics(struct navit *this_, struct graphics *gra)
{
- return g_strjoin(NULL, navit_get_user_data_directory(create), "/bookmark.txt", NULL);
+ if (this_->gra)
+ return 0;
+ this_->gra=gra;
+ this_->resize_callback=callback_new_attr_1(callback_cast(navit_resize), attr_resize, this_);
+ graphics_add_callback(gra, this_->resize_callback);
+ this_->button_callback=callback_new_attr_1(callback_cast(navit_button), attr_button, this_);
+ 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_->predraw_callback=callback_new_attr_1(callback_cast(navit_predraw), attr_predraw, this_);
+ graphics_add_callback(gra, this_->predraw_callback);
+ return 1;
}
-
-/*
- * navit_get_bookmark_file
- *
- * returns the name of the file used to store the center file with its
- * full path
- *
- * arg: gboolean create: create the directory where the file is stored
- * if it does not exist
- */
-static char*
-navit_get_center_file(gboolean create)
+struct graphics *
+navit_get_graphics(struct navit *this_)
{
- return g_strjoin(NULL, navit_get_user_data_directory(create), "/center.txt", NULL);
+ return this_->gra;
}
-static void
-navit_set_center_from_file(struct navit *this_, char *file)
+struct vehicleprofile *
+navit_get_vehicleprofile(struct navit *this_)
{
-#ifndef HAVE_API_ANDROID
- FILE *f;
- char *line = NULL;
-
- size_t line_size = 0;
- enum projection pro;
- struct coord *center;
+ return this_->vehicleprofile;
+}
- f = fopen(file, "r");
- if (! f)
- return;
- getline(&line, &line_size, f);
- fclose(f);
- if (line) {
- center = transform_center(this_->trans);
- pro = transform_get_projection(this_->trans);
- coord_parse(g_strchomp(line), pro, center);
- free(line);
- }
- return;
-#endif
+GList *
+navit_get_vehicleprofiles(struct navit *this_)
+{
+ return this_->vehicleprofiles;
}
-
+
static void
-navit_write_center_to_file(struct navit *this_, char *file)
+navit_projection_set(struct navit *this_, enum projection pro, int draw)
{
- FILE *f;
- enum projection pro;
- struct coord *center;
+ struct coord_geo g;
+ struct coord *c;
- f = fopen(file, "w+");
- if (f) {
- center = transform_center(this_->trans);
- pro = transform_get_projection(this_->trans);
- coord_print(pro, center, f);
- fclose(f);
- } else {
- perror(file);
- }
- return;
+ c=transform_center(this_->trans);
+ transform_to_geo(transform_get_projection(this_->trans), c, &g);
+ transform_set_projection(this_->trans, pro);
+ transform_from_geo(pro, &g, c);
+ if (draw)
+ navit_draw(this_);
}
-
/**
* Start the route computing to a given set of coordinates
*
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 = navit_get_destination_file(TRUE);
- navit_append_coord(this_, destination_file, c, "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);
}
/**
+ * Start the route computing to a given set of coordinates including waypoints
+ *
+ * @param navit The navit instance
+ * @param c The coordinate to start routing to
+ * @param description A label which allows the user to later identify this destination in the former destinations selection
+ * @returns nothing
+ */
+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;
+ callback_list_call_attr_0(this_->attr_cbl, attr_destination);
+ if (this_->route) {
+ route_set_destinations(this_->route, c, count, async);
+
+ if (this_->ready == 3)
+ navit_draw(this_);
+ }
+}
+
+/**
* @brief Checks if a route is calculated
*
* This function checks if a route is calculated.
return 0;
}
-/**
- * Record the given set of coordinates as a bookmark
- *
- * @param navit The navit instance
- * @param c The coordinate to store
- * @param description A label which allows the user to later identify this bookmark
- * @returns nothing
- */
-void
-navit_add_bookmark(struct navit *this_, struct pcoord *c, const char *description)
-{
- char *bookmark_file = navit_get_bookmark_file(TRUE);
- navit_append_coord(this_,bookmark_file, c, "bookmark", description, this_->bookmarks_hash,0);
- g_free(bookmark_file);
-
- callback_list_call_attr_0(this_->attr_cbl, attr_bookmark_map);
-}
-
-struct navit *global_navit;
-
-static void
-navit_add_bookmarks_from_file(struct navit *this_)
-{
- char *bookmark_file = navit_get_bookmark_file(FALSE);
- struct attr parent={attr_navit, .u.navit=this_};
- struct attr type={attr_type, {"textfile"}}, data={attr_data, {bookmark_file}};
- struct attr *attrs[]={&type, &data, NULL};
-
- this_->bookmark=map_new(&parent, attrs);
- g_free(bookmark_file);
-}
-
static int
navit_former_destinations_active(struct navit *this_)
{
- char *destination_file = navit_get_destination_file(FALSE);
+ char *destination_file = bookmarks_get_destination_file(FALSE);
FILE *f;
int active=0;
char buffer[3];
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 = navit_get_destination_file(FALSE);
- struct attr parent={attr_navit, .u.navit=this_};
- struct attr type={attr_type, {"textfile"}}, data={attr_data, {destination_file}};
- struct attr *attrs[]={&type, &data, NULL};
- struct map_rect *mr;
struct item *item;
- int valid=0;
- struct coord c;
- struct pcoord pc;
+ 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);
while ((item=map_rect_get_item(mr))) {
- if (item->type == type_former_destination && item_coord_get(item, &c, 1))
+ if ((item->type == type_former_destination || item->type == type_former_itinerary || item->type == type_former_itinerary_part) && (count=item_coord_get(item, c, 16)))
valid=1;
}
map_rect_destroy(mr);
- pc.pro=map_projection(this_->former_destination);
- pc.x=c.x;
- pc.y=c.y;
- if (valid) {
- route_set_destination(this_->route, &pc, 1);
- this_->destination=pc;
+ if (valid && count > 0) {
+ for (i = 0 ; i < count ; i++) {
+ pc[i].pro=map_projection(this_->former_destination);
+ pc[i].x=c[i].x;
+ pc[i].y=c[i].y;
+ }
+ if (count == 1)
+ route_set_destination(this_->route, &pc[0], 1);
+ else
+ route_set_destinations(this_->route, pc, count, 1);
+ this_->destination=pc[count-1];
this_->destination_valid=1;
}
}
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);
+ }
}
/**
{
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;
}
{
struct mapset *ms;
struct map *map;
+ int callback;
+ char *center_file;
dbg(2,"enter gui %p graphics %p\n",this_->gui,this_->gra);
- if (!this_->gui) {
+
+ if (!this_->gui && !(this_->flags & 2)) {
dbg(0,"no gui\n");
navit_destroy(this_);
return;
}
- if (!this_->gra) {
+ if (!this_->gra && !(this_->flags & 1)) {
dbg(0,"no graphics\n");
navit_destroy(this_);
return;
}
dbg(2,"Connecting gui to graphics\n");
- if (gui_set_graphics(this_->gui, this_->gra)) {
+ if (this_->gui && this_->gra && gui_set_graphics(this_->gui, this_->gra)) {
struct attr attr_type_gui, attr_type_graphics;
gui_get_attr(this_->gui, attr_type, &attr_type_gui, NULL);
graphics_get_attr(this_->gra, attr_type, &attr_type_graphics, NULL);
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));
}
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_bookmarks_from_file(this_);
navit_add_former_destinations_from_file(this_);
}
if (this_->route) {
navigation_set_route(this_->navigation, this_->route);
}
dbg(2,"Setting Center\n");
- char *center_file = navit_get_center_file(FALSE);
- navit_set_center_from_file(this_, center_file);
+ center_file = bookmarks_get_center_file(FALSE);
+ bookmarks_set_center_from_file(this_->bookmarks, center_file);
g_free(center_file);
#if 0
if (this_->menubar) {
navit_window_roadbook_new(this_);
navit_window_items_new(this_);
#endif
- callback_list_call_attr_1(this_->attr_cbl, attr_navit, this_);
- this_->ready|=1;
messagelist_init(this_->messages);
navit_set_cursors(this_);
+ callback_list_call_attr_1(this_->attr_cbl, attr_navit, this_);
+ callback=(this_->ready == 2);
+ 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
routech_test(this_);
#endif
}
void
+navit_zoom_to_rect(struct navit *this_, struct coord_rect *r)
+{
+ struct coord c;
+ int scale=16;
+
+ c.x=(r->rl.x+r->lu.x)/2;
+ c.y=(r->rl.y+r->lu.y)/2;
+ transform_set_center(this_->trans, &c);
+ dbg(1,"%x,%x-%x,%x\n", r->rl.x,r->rl.y,r->lu.x,r->lu.y);
+ while (scale < 1<<20) {
+ struct point p1,p2;
+ transform_set_scale(this_->trans, scale);
+ transform_setup_source_rect(this_->trans);
+ transform(this_->trans, transform_get_projection(this_->trans), &r->lu, &p1, 1, 0, 0, NULL);
+ transform(this_->trans, transform_get_projection(this_->trans), &r->rl, &p2, 1, 0, 0, NULL);
+ dbg(1,"%d,%d-%d,%d\n",p1.x,p1.y,p2.x,p2.y);
+ if (p1.x < 0 || p2.x < 0 || p1.x > this_->w || p2.x > this_->w ||
+ p1.y < 0 || p2.y < 0 || p1.y > this_->h || p2.y > this_->h)
+ scale*=2;
+ else
+ break;
+
+ }
+ if (this_->ready == 3)
+ navit_draw_async(this_,0);
+}
+
+void
navit_zoom_to_route(struct navit *this_, int orientation)
{
struct map *map;
struct item *item;
struct coord c;
struct coord_rect r;
- int count=0,scale=16;
+ int count=0;
if (! this_->route)
return;
dbg(1,"enter\n");
count++;
}
}
+ map_rect_destroy(mr);
}
if (! count)
return;
- c.x=(r.rl.x+r.lu.x)/2;
- c.y=(r.rl.y+r.lu.y)/2;
- dbg(1,"count=%d\n",count);
if (orientation != -1)
transform_set_yaw(this_->trans, orientation);
- transform_set_center(this_->trans, &c);
- dbg(1,"%x,%x-%x,%x\n", r.rl.x,r.rl.y,r.lu.x,r.lu.y);
- while (scale < 1<<20) {
- struct point p1,p2;
- transform_set_scale(this_->trans, scale);
- transform_setup_source_rect(this_->trans);
- transform(this_->trans, transform_get_projection(this_->trans), &r.lu, &p1, 1, 0, 0, NULL);
- transform(this_->trans, transform_get_projection(this_->trans), &r.rl, &p2, 1, 0, 0, NULL);
- dbg(1,"%d,%d-%d,%d\n",p1.x,p1.y,p2.x,p2.y);
- if (p1.x < 0 || p2.x < 0 || p1.x > this_->w || p2.x > this_->w ||
- p1.y < 0 || p2.y < 0 || p1.y > this_->h || p2.y > this_->h)
- scale*=2;
- else
- break;
-
- }
- if (this_->ready == 3)
- navit_draw_async(this_,0);
+ navit_zoom_to_rect(this_, &r);
}
static void
v=g_list_first(this_->vehicles); // GList of navit_vehicles
while (v) {
nv=v->data;
- if (vehicle_get_attr(nv->vehicle, attr_cursorname, &name, NULL))
- c=layout_get_cursor(this_->layout_current, name.u.str);
- else
+ if (vehicle_get_attr(nv->vehicle, attr_cursorname, &name, NULL)) {
+ if (!strcmp(name.u.str,"none"))
+ c=NULL;
+ else
+ 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;
}
static int
-navit_get_cursor_pnt(struct navit *this_, struct point *p, int *dir)
+navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir)
{
int width, height;
struct navit_vehicle *nv=this_->vehicle;
- float offset=30; // Cursor offset from the center of the screen (percent).
+ float offset=this_->radius; // Cursor offset from the center of the screen (percent).
#if 0 /* Better improve track.c to get that issue resolved or make it configurable with being off the default, the jumping back to the center is a bit annoying */
float min_offset = 0.; // Percent offset at min_offset_speed.
float max_offset = 30.; // Percent offset at max_offset_speed.
#endif
transform_get_size(this_->trans, &width, &height);
- if (this_->orientation == -1) {
+ if (this_->orientation == -1 || keep_orientation) {
p->x=50*width/100;
p->y=(50 + offset)*height/100;
- if (dir)
- *dir=nv->dir;
+ if (dir)
+ *dir=keep_orientation?this_->orientation:nv->dir;
} else {
int mdir;
if (this_->tracking && this_->tracking_flag) {
return 1;
}
-static void
-navit_set_center_cursor(struct navit *this_)
+void
+navit_set_center_cursor(struct navit *this_, int autozoom, int keep_orientation)
{
int dir;
struct point pn;
struct navit_vehicle *nv=this_->vehicle;
- navit_get_cursor_pnt(this_, &pn, &dir);
+ navit_get_cursor_pnt(this_, &pn, keep_orientation, &dir);
transform_set_yaw(this_->trans, dir);
navit_set_center_coord_screen(this_, &nv->coord, &pn, 0);
- navit_autozoom(this_, &nv->coord, nv->speed, 0);
+ if (autozoom)
+ navit_autozoom(this_, &nv->coord, nv->speed, 0);
+}
+
+static void
+navit_set_center_cursor_draw(struct navit *this_)
+{
+ navit_set_center_cursor(this_,1,0);
if (this_->ready == 3)
navit_draw_async(this_, 1);
}
static void
navit_cmd_set_center_cursor(struct navit *this_)
{
- navit_set_center_cursor(this_);
+ navit_set_center_cursor_draw(this_);
}
void
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)
{
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:
attr_updated=(this_->drag_bitmap != !!attr->u.num);
this_->drag_bitmap=!!attr->u.num;
break;
+ case attr_flags:
+ attr_updated=(this_->flags != attr->u.num);
+ this_->flags=attr->u.num;
+ break;
+ case attr_flags_graphics:
+ attr_updated=(this_->graphics_flags != attr->u.num);
+ this_->graphics_flags=attr->u.num;
+ break;
case attr_follow:
if (!this_->vehicle)
return 0;
this_->layout_current=attr->u.layout;
graphics_font_destroy_all(this_->gra);
navit_set_cursors(this_);
- navit_draw(this_);
+ if (this_->ready == 3)
+ navit_draw(this_);
+ attr_updated=1;
+ }
+ break;
+ case attr_layout_name:
+ l=this_->layouts;
+ while (l) {
+ lay=l->data;
+ if (!strcmp(lay->name,attr->u.str)) {
+ struct attr attr;
+ attr.type=attr_layout;
+ attr.u.layout=lay;
+ return navit_set_attr_do(this_, &attr, init);
+ }
+ l=g_list_next(l);
+ }
+ return 0;
+ case attr_map_border:
+ if (this_->border != attr->u.num) {
+ this_->border=attr->u.num;
attr_updated=1;
}
break;
}
transform_set_yaw(this_->trans, dir);
if (orient_old != this_->orientation) {
+#if 0
if (this_->ready == 3)
navit_draw(this_);
+#endif
attr_updated=1;
}
}
break;
case attr_projection:
if(this_->trans && transform_get_projection(this_->trans) != attr->u.projection) {
- navit_projection_set(this_, attr->u.projection);
+ navit_projection_set(this_, attr->u.projection, !init);
attr_updated=1;
}
break;
+ case attr_radius:
+ attr_updated=(this_->radius != attr->u.num);
+ this_->radius=attr->u.num;
+ break;
case attr_recent_dest:
attr_updated=(this_->recentdest_count != attr->u.num);
this_->recentdest_count=attr->u.num;
attr_updated=(this_->tracking_flag != !!attr->u.num);
this_->tracking_flag=!!attr->u.num;
break;
+ case attr_transformation:
+ this_->trans=attr->u.transformation;
+ break;
case attr_use_mousewheel:
attr_updated=(this_->use_mousewheel != !!attr->u.num);
this_->use_mousewheel=!!attr->u.num;
if (attr_updated && !init)
navit_draw(this_);
break;
+ case attr_zoom_min:
+ attr_updated=(attr->u.num != this_->zoom_min);
+ this_->zoom_min=attr->u.num;
+ break;
+ case attr_zoom_max:
+ attr_updated=(attr->u.num != this_->zoom_max);
+ this_->zoom_max=attr->u.num;
+ break;
case attr_message:
navit_add_message(this_, attr->u.str);
break;
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;
}
attr->u.str[len] = '\0';
break;
+ case attr_imperial:
+ attr->u.num=this_->imperial;
+ break;
case attr_bookmark_map:
- attr->u.map=this_->bookmark;
+ attr->u.map=bookmarks_get_map(this_->bookmarks);
+ break;
+ case attr_bookmarks:
+ attr->u.bookmarks=this_->bookmarks;
break;
case attr_callback_list:
attr->u.callback_list=this_->attr_cbl;
case attr_displaylist:
attr->u.displaylist=this_->displaylist;
return (attr->u.displaylist != NULL);
+ case attr_follow:
+ if (!this_->vehicle)
+ return 0;
+ attr->u.num=this_->vehicle->follow_curr;
+ break;
case attr_former_destination_map:
attr->u.map=this_->former_destination;
break;
break;
case attr_mapset:
attr->u.mapset=this_->mapsets->data;
- return (attr->u.mapset != NULL);
+ ret=(attr->u.mapset != NULL);
+ break;
case attr_navigation:
attr->u.navigation=this_->navigation;
break;
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;
case attr_tracking:
attr->u.num=this_->tracking_flag;
break;
+ case attr_trackingo:
+ attr->u.tracking=this_->tracking;
+ break;
case attr_transformation:
attr->u.transformation=this_->trans;
break;
}
}
break;
+ case attr_vehicleprofile:
+ attr->u.vehicleprofile=this_->vehicleprofile;
+ break;
case attr_zoom:
attr->u.num=transform_get_scale(this_->trans);
break;
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)
{
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;
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;
if (pnt)
cursor_pnt=*pnt;
else {
- pro=transform_get_projection(this_->trans);
- transform(this_->trans, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
+ pro=transform_get_projection(this_->trans_cursor);
+ if (!pro)
+ return;
+ transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
}
- vehicle_draw(nv->vehicle, this_->gra, &cursor_pnt, pnt ? 0:1, nv->dir-transform_get_yaw(this_->trans), nv->speed);
+ vehicle_draw(nv->vehicle, this_->gra, &cursor_pnt, pnt ? 0:1, nv->dir-transform_get_yaw(this_->trans_cursor), nv->speed);
#if 0
if (pnt)
pnt2=*pnt;
struct pcoord cursor_pc;
struct point cursor_pnt, *pnt=&cursor_pnt;
struct tracking *tracking=NULL;
- enum projection pro=transform_get_projection(this_->trans);
- int border=16;
+ struct pcoord pc[16];
+ enum projection pro=transform_get_projection(this_->trans_cursor);
+ int count;
int (*get_attr)(void *, enum attr_type, struct attr *, struct attr_iter *);
void *attr_object;
+ char *destination_file;
profile(0,NULL);
if (this_->ready != 3) {
callback_list_call_attr_0(this_->attr_cbl, attr_position);
navit_textfile_debug_log(this_, "type=trackpoint_tracked");
if (this_->gui && nv->speed > 2)
- gui_disable_suspend(this_->gui);
+ navit_disable_suspend();
- transform(this_->trans, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
+ transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
if (this_->button_pressed != 1 && this_->follow_cursor && nv->follow_curr <= nv->follow &&
- (nv->follow_curr == 1 || !transform_within_border(this_->trans, &cursor_pnt, border)))
- navit_set_center_cursor(this_);
+ (nv->follow_curr == 1 || !transform_within_border(this_->trans_cursor, &cursor_pnt, this_->border)))
+ navit_set_center_cursor_draw(this_);
else
navit_vehicle_draw(this_, nv, pnt);
callback_list_call_attr_2(this_->attr_cbl, attr_position_coord_geo, this_, nv->vehicle);
/* Finally, if we reached our destination, stop navigation. */
- if (this_->route && route_destination_reached(this_->route)) {
- navit_set_destination(this_, NULL, NULL, 0);
+ if (this_->route) {
+ switch(route_destination_reached(this_->route)) {
+ case 1:
+ route_remove_waypoint(this_->route);
+ count=route_get_destinations(this_->route, pc, 16);
+ destination_file = bookmarks_get_destination_file(TRUE);
+ 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);
+ break;
+ }
}
profile(0,"return 5\n");
}
if (navit_set_vehicleprofile(this_, attr.u.str))
return;
}
- navit_set_vehicleprofile(this_,"car");
+ if (!navit_set_vehicleprofile(this_,"car")) {
+ /* We do not have a fallback "car" profile
+ * so lets set any profile */
+ GList *l;
+ l=this_->vehicleprofiles;
+ if (l) {
+ this_->vehicleprofile=l->data;
+ if (this_->route)
+ route_set_profile(this_->route, this_->vehicleprofile);
+ }
+ }
}
/**
nv->last.y = 0;
nv->animate_cursor=0;
if ((vehicle_get_attr(v, attr_follow, &follow, NULL)))
- nv->follow=nv->follow=follow.u.num;
+ nv->follow=follow.u.num;
nv->follow_curr=nv->follow;
this_->vehicles=g_list_append(this_->vehicles, nv);
if ((vehicle_get_attr(v, attr_active, &active, NULL)) && active.u.num)
{
int currTs=0;
- struct attr iso8601_attr,geo_attr,layout_attr;
+ struct attr iso8601_attr,geo_attr,valid_attr,layout_attr;
double trise,tset,trise_actual;
struct layout *l;
int year, month, day;
if (navit_get_attr(n,attr_layout,&layout_attr,NULL)!=1) {
return; //No layout - nothing to switch
}
+ if (!n->vehicle)
+ return;
l=layout_attr.u.layout;
if (l->dayname || l->nightname) {
//Check that we aren't calculating too fast
if (vehicle_get_attr(n->vehicle->vehicle, attr_position_time_iso8601,&iso8601_attr,NULL)==1) {
currTs=iso8601_to_secs(iso8601_attr.u.str);
+ dbg(1,"currTs: %u:%u\n",currTs%86400/3600,((currTs%86400)%3600)/60);
}
if (currTs-(n->prevTs)<60) {
//We've have to wait a little
}
if (sscanf(iso8601_attr.u.str,"%d-%02d-%02dT",&year,&month,&day) != 3)
return;
+ if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &valid_attr,NULL) && valid_attr.u.num==attr_position_valid_invalid) {
+ return; //No valid fix yet
+ }
if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo,&geo_attr,NULL)!=1) {
//No position - no sun
return;
}
- if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &geo_attr,NULL) && geo_attr.u.num==attr_position_valid_invalid) {
- return; //No valid fix yet
- }
- //We calculate sunrise anyway, cause it is need both for day and for night
- if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lat,geo_attr.u.coord_geo->lng,35,1,&trise,&tset)!=0) {
+ //We calculate sunrise anyway, cause it is needed both for day and for night
+ if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lng,geo_attr.u.coord_geo->lat,-5,1,&trise,&tset)!=0) {
//near the pole sun never rises/sets, so we should never switch profiles
+ dbg(1,"trise: %u:%u, sun never visible, never switch profile\n",HOURS(trise),MINUTES(trise));
n->prevTs=currTs;
return;
}
trise_actual=trise;
-
+ dbg(1,"trise: %u:%u\n",HOURS(trise),MINUTES(trise));
if (l->dayname) {
if ((HOURS(trise)*60+MINUTES(trise)==(currTs%86400)/60) ||
}
}
if (l->nightname) {
- if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lat,geo_attr.u.coord_geo->lng,-12,0,&trise,&tset)!=0) {
+ if (__sunriset__(year,month,day,geo_attr.u.coord_geo->lng,geo_attr.u.coord_geo->lat,-5,1,&trise,&tset)!=0) {
//near the pole sun never rises/sets, so we should never switch profiles
+ dbg(1,"tset: %u:%u, sun always visible, never switch profile\n",HOURS(tset),MINUTES(tset));
n->prevTs=currTs;
return;
}
-
+ dbg(1,"tset: %u:%u\n",HOURS(tset),MINUTES(tset));
if (HOURS(tset)*60+MINUTES(tset)==((currTs%86400)/60)
|| (n->prevTs==0 && (((HOURS(tset)*60+MINUTES(tset)<(currTs%86400)/60)) ||
((HOURS(trise_actual)*60+MINUTES(trise_actual)>(currTs%86400)/60))))) {
}
int
-navit_set_layout_by_name(struct navit *n,char *name)
+navit_set_vehicle_by_name(struct navit *n,const char *name)
+{
+ struct vehicle *v;
+ struct attr_iter *iter;
+ struct attr vehicle_attr, name_attr;
+
+ iter=navit_attr_iter_new();
+
+ while (navit_get_attr(n,attr_vehicle,&vehicle_attr,iter)) {
+ v=vehicle_attr.u.vehicle;
+ vehicle_get_attr(v,attr_name,&name_attr,NULL);
+ if (name_attr.type==attr_name) {
+ if (!strcmp(name,name_attr.u.str)) {
+ navit_set_attr(n,&vehicle_attr);
+ navit_attr_iter_destroy(iter);
+ return 1;
+ }
+ }
+ }
+ navit_attr_iter_destroy(iter);
+ return 0;
+}
+
+int
+navit_set_layout_by_name(struct navit *n,const char *name)
{
struct layout *l;
struct attr_iter iter;
return 0;
}
+void
+navit_disable_suspend() {
+ gui_disable_suspend(global_navit->gui);
+ callback_list_call_attr_0(global_navit->attr_cbl,attr_unsuspend);
+}
+
int
navit_block(struct navit *this_, int block)
{
- if (block) {
+ if (block > 0) {
this_->blocked |= 1;
if (graphics_draw_cancel(this_->gra, this_->displaylist))
this_->blocked |= 2;
return 0;
}
- if (this_->blocked & 2) {
+ if ((this_->blocked & 2) || block < 0) {
this_->blocked=0;
navit_draw(this_);
return 1;
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_ */
if (this_->vehicle)
vehicle_destroy(this_->vehicle->vehicle);
- char *center_file = navit_get_center_file(TRUE);
- navit_write_center_to_file(this_, center_file);
- g_free(center_file);
+ if (this_->bookmarks) {
+ char *center_file = bookmarks_get_center_file(TRUE);
+ bookmarks_write_center_to_file(this_->bookmarks, center_file);
+ g_free(center_file);
+ bookmarks_destroy(this_->bookmarks);
+ }
callback_destroy(this_->nav_speech_cb);
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);
if(this_->gra)
graphics_remove_callback(this_->gra, this_->motion_callback);
callback_destroy(this_->motion_callback);
+ if(this_->gra)
+ 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_);
}