diff options
author | OLFDB <olf@eisenzelt.de> | 2021-02-14 11:47:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-14 11:47:51 +0100 |
commit | c8b98912f6ebce2417758264bb8ce98b05a296c5 (patch) | |
tree | dcac4d77a0ca9059c333c616fc03d694158344eb | |
parent | b20b6f667bb4666dd3b24cad91b7ad0d14de703f (diff) | |
download | navit-c8b98912f6ebce2417758264bb8ce98b05a296c5.tar.gz |
Delete navit.c
-rw-r--r-- | navit.c | 3830 |
1 files changed, 0 insertions, 3830 deletions
diff --git a/navit.c b/navit.c deleted file mode 100644 index bf7086261..000000000 --- a/navit.c +++ /dev/null @@ -1,3830 +0,0 @@ -/** - * Navit, a modular navigation system. - * Copyright (C) 2005-2009 Navit Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * 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 <errno.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <fcntl.h> -#include <glib.h> -#include <math.h> -#include <time.h> -#include "debug.h" -#include "navit.h" -#include "callback.h" -#include "gui.h" -#include "item.h" -#include "xmlconfig.h" -#include "projection.h" -#include "map.h" -#include "mapset.h" -#include "main.h" -#include "coord.h" -#include "point.h" -#include "transform.h" -#include "traffic.h" -#include "param.h" -#include "menu.h" -#include "graphics.h" -#include "popup.h" -#include "data_window.h" -#include "route.h" -#include "navigation.h" -#include "speech.h" -#include "track.h" -#include "vehicle.h" -#include "layout.h" -#include "log.h" -#include "attr.h" -#include "event.h" -#include "file.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 - -/* define string for bookmark handling */ -#define TEXTFILE_COMMENT_NAVI_STOPPED "# navigation stopped\n" - -/** - * @defgroup navit The navit core instance - * @brief navit is the object containing most global data structures. - * - * Among others: - * - a set of maps - * - one or more vehicles - * - a graphics object for rendering the map - * - a gui object for displaying the user interface - * - a route object - * - a navigation object - * @{ - */ - -//! The vehicle used for navigation. -struct navit_vehicle { - int follow; - /*! Limit of the follow counter. See navit_add_vehicle */ - int follow_curr; - /*! Deprecated : follow counter itself. When it reaches 'update' counts, map is recentered*/ - struct coord coord; - int dir; - int speed; - struct coord last; /*< Position of the last update of this vehicle */ - struct vehicle *vehicle; - struct attr callback; - int animate_cursor; -}; - -struct navit { - NAVIT_OBJECT - struct attr self; - GList *mapsets; - GList *layouts; - struct gui *gui; - char *default_layout_name; /*!< The default layout indicated by the config file (if any) */ - struct layout *layout_current; /*!< The current layout theme used to display the map */ - struct graphics *gra; - struct action *action; - struct transformation *trans, *trans_cursor; - struct compass *compass; - struct route *route; - struct navigation *navigation; - struct speech *speech; - struct tracking *tracking; - int ready; - struct window *win; - struct displaylist *displaylist; - int tracking_flag; - int orientation; - int recentdest_count; - int osd_configuration; - GList *vehicles; - GList *windows_items; - struct navit_vehicle *vehicle; - struct callback_list *attr_cbl; - 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; - int button_pressed,moved,popped,zoomed; - int center_timeout; - int autozoom_secs; - int autozoom_min; - int autozoom_max; - int autozoom_active; - int autozoom_paused; - struct event_timeout *button_timeout, *motion_timeout; - struct callback *motion_timeout_callback; - int ignore_button; - int ignore_graphics_events; - struct log *textfile_debug_log; - struct pcoord destination; - int destination_valid; - int blocked; /**< Whether draw operations are currently blocked. This can be a combination of the - following flags: - 1: draw operations are blocked - 2: draw operations are pending, requiring a redraw once draw operations are unblocked */ - int w,h; - int drag_bitmap; - int use_mousewheel; - struct messagelist *messages; - 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; - int waypoints_flag; - struct coord_geo center; - int auto_switch; /*auto switching between day/night layout enabled ?*/ -}; - -struct gui *main_loop_gui; - -struct attr_iter { - void *iter; - union { - GList *list; - struct mapset_handle *mapset_handle; - } u; -}; - -static void navit_vehicle_update_position(struct navit *this_, struct navit_vehicle *nv); -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 keep_orientation, int *dir); -static void navit_set_cursors(struct navit *this_); -static int navit_cmd_zoom_to_route(struct navit *this, char *function, struct attr **in, struct attr ***out); -static int navit_cmd_set_center_cursor(struct navit *this_, char *function, struct attr **in, struct attr ***out); -static int navit_cmd_announcer_toggle(struct navit *this_, char *function, struct attr **in, struct attr ***out); -static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv); -static int navit_set_vehicleprofile(struct navit *this_, struct vehicleprofile *vp); -static int navit_cmd_switch_layout_day_night(struct navit *this_, char *function, struct attr **in, struct attr ***out); -struct object_func navit_func; - -struct navit *global_navit; - -void navit_add_mapset(struct navit *this_, struct mapset *ms) { - this_->mapsets = g_list_append(this_->mapsets, ms); -} - -/** - * @brief Get the current mapset - * - * @param this_ The navit instance - * - * @return A pointer to the current mapset - */ -struct mapset * -navit_get_mapset(struct navit *this_) { - if(this_->mapsets) { - return this_->mapsets->data; - } else { - dbg(lvl_error,"No mapsets enabled! Is it on purpose? Navit can't draw a map. Please check your navit.xml"); - } - return NULL; -} - -/** - * @brief Get the search result map (and create it if it does not exist) - * - * @param this_ The navit instance - * - * @return A pointer to the map named "search_results" or NULL if there wasa failure - */ -struct map *navit_get_search_results_map(struct navit *this_) { - - struct mapset *ms; - struct map *map; - - ms=navit_get_mapset(this_); - - if(!ms) - return NULL; - - map=mapset_get_map_by_name(ms, "search_results"); - if(!map) { - struct attr *attrs[10], attrmap; - enum attr_type types[]= {attr_position_longitude,attr_position_latitude,attr_label,attr_none}; - int i; - - attrs[0]=g_new0(struct attr,1); - attrs[0]->type=attr_type; - attrs[0]->u.str="csv"; - - attrs[1]=g_new0(struct attr,1); - attrs[1]->type=attr_name; - attrs[1]->u.str="search_results"; - - attrs[2]=g_new0(struct attr,1); - attrs[2]->type=attr_charset; - attrs[2]->u.str="utf-8"; - - attrs[3]=g_new0(struct attr,1); - attrs[3]->type=attr_item_type; - attrs[3]->u.num=type_found_item; - - attrs[4]=g_new0(struct attr,1); - attrs[4]->type=attr_attr_types; - attrs[4]->u.attr_types=types; - attrs[5]=NULL; - - attrmap.type=attr_map; - map=attrmap.u.map=map_new(NULL,attrs); - if(map) - mapset_add_attr(ms,&attrmap); - - for(i=0; attrs[i]; i++) - g_free(attrs[i]); - } - return map; -} - -/** - * @brief Populate a map containing one or more search result points - * - * These search results will be displayed as an overlay on the top of the geographic map. - * - * @warning Each call to this function will replace currently displayed results, it will not add to them - * - * @param this_ The navit instance - * @param search_results A GList storing {@code struct lcoord} elements to display on the result map - * If this argument in NULL, all existing results will be removed from the map - * @param[in,out] coord_rect An optional rectangular zone that will be extended to contain all result points - * or NULL if no zone needs to be computed - * @return The number of results actually added to the map - */ -int navit_populate_search_results_map(struct navit *this_, GList *search_results, struct coord_rect *r) { - struct map *map; - struct map_rect *mr; - struct item *item; - GList *curr_result = search_results; - int count; - char *name_label; - - map = navit_get_search_results_map(this_); - if(!map) - return 0; - - mr = map_rect_new(map, NULL); - - if(!mr) - return 0; - - /* Clean the map */ - while((item = map_rect_get_item(mr))!=NULL) { - item_type_set(item,type_none); - } - - if(!search_results) { - map_rect_destroy(mr); - dbg(lvl_warning,"NULL result table - only map clean up is done."); - return 0; - } - - /* Populate the map with search results*/ - for(curr_result = search_results, count=0; curr_result; curr_result=g_list_next(curr_result)) { - struct lcoord *point = curr_result->data; - struct item* it; - if(point->label==NULL) - continue; - dbg(lvl_info,"%s",point->label); - it=map_rect_create_item(mr,type_found_item); - if(it) { - struct attr a; - item_coord_set(it, &(point->c), 1, change_mode_modify); - a.type=attr_label; - name_label = g_strdup(point->label); - square_shape_str(name_label); - a.u.str=name_label; - item_attr_set(it, &a, change_mode_modify); - if (r) { - if(!count++) - r->lu=r->rl=point->c; - else - coord_rect_extend(r,&(point->c)); - } - } - } - map_rect_destroy(mr); - return count; -} - -struct tracking * -navit_get_tracking(struct navit *this_) { - return this_->tracking; -} - -/** - * @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(lvl_debug,"creating dir %s", dir); - if (file_mkdir(dir,0)) { - dbg(lvl_error,"failed creating dir %s", dir); - return NULL; - } - } - return dir; -} - - -void navit_draw_async(struct navit *this_, int async) { - - if (this_->blocked) { - this_->blocked |= 2; - return; - } - transform_setup_source_rect(this_->trans); - 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_) { - if (this_->ready == 3) - navit_draw_async(this_, 0); -} - -int navit_get_ready(struct navit *this_) { - return this_->ready; -} - - - -void navit_draw_displaylist(struct navit *this_) { - if (this_->ready == 3) - 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_redraw_route(struct navit *this_, struct route *route, struct attr *attr) { - int updated; - if (attr->type != attr_route_status) - return; - updated=attr->u.num; - if (this_->ready != 3) - return; - if (updated != route_status_path_done_new) - return; - if (this_->vehicle) { - if (this_->vehicle->follow_curr == 1) - return; - if (this_->vehicle->follow_curr <= this_->vehicle->follow) - this_->vehicle->follow_curr=this_->vehicle->follow; - } - navit_draw(this_); -} - -void navit_handle_resize(struct navit *this_, int w, int h) { - struct map_selection sel; - int callback=(this_->ready == 1); - this_->ready |= 2; - 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_async(this_, 1); -} - -static void navit_resize(void *data, int w, int h) { - struct navit *this=data; - if (!this->ignore_graphics_events) - navit_handle_resize(this, w, h); -} - -int navit_get_width(struct navit *this_) { - return this_->w; -} - - -int navit_get_height(struct navit *this_) { - return this_->h; -} - -static void navit_popup(void *data) { - struct navit *this_=data; - popup(this_, 1, &this_->pressed); - this_->button_timeout=NULL; - this_->popped=1; -} - - -/** - * @brief Sets a flag indicating that the current button event should be ignored by subsequent handlers. - * - * Calling this function will set the {@code ignore_button} member to {@code true} and return its previous state. - * The default handler, {@link navit_handle_button(navit *, int, int, point *, callback *)} calls this function - * just before the actual event handling core and aborts if the result is {@code true}. In order to prevent - * multiple handlers from firing on a single event, custom button click handlers should implement the same logic - * for events they wish to handle. - * - * If a handler wishes to pass down an event to other handlers, it must abort without calling this function. - * - * @param this_ The navit instance - * @return {@code true} if the caller should ignore the button event, {@code false} if it should handle it - */ -int navit_ignore_button(struct navit *this_) { - if (this_->ignore_button) - return 1; - this_->ignore_button=1; - return 0; -} - -void navit_ignore_graphics_events(struct navit *this_, int ignore) { - this_->ignore_graphics_events=ignore; -} - -static int navit_restrict_to_range(int value, int min, int max) { - if (value>max) { - value = max; - } - if (value<min) { - value = min; - } - return value; -} - -static void navit_restrict_map_center_to_world_boundingbox(struct transformation *tr, struct coord *new_center) { - new_center->x = navit_restrict_to_range(new_center->x, WORLD_BOUNDINGBOX_MIN_X, WORLD_BOUNDINGBOX_MAX_X); - new_center->y = navit_restrict_to_range(new_center->y, WORLD_BOUNDINGBOX_MIN_Y, WORLD_BOUNDINGBOX_MAX_Y); -} - -/** - * @brief Change map center position by translating from "old" to "new". - */ -static void update_transformation(struct transformation *tr, struct point *old, struct point *new) { - /* Code for rotation was removed in rev. 5252; see Trac #1078. */ - struct coord coord_old,coord_new; - struct coord center_new,*center_old; - if (!transform_reverse(tr, old, &coord_old)) - return; - if (!transform_reverse(tr, new, &coord_new)) - return; - center_old=transform_get_center(tr); - center_new.x=center_old->x+coord_old.x-coord_new.x; - center_new.y=center_old->y+coord_old.y-coord_new.y; - navit_restrict_map_center_to_world_boundingbox(tr, ¢er_new); - dbg(lvl_debug,"change center from 0x%x,0x%x to 0x%x,0x%x", center_old->x, center_old->y, center_new.x, center_new.y); - transform_set_center(tr, ¢er_new); -} - -void navit_set_timeout(struct navit *this_) { - struct attr follow; - follow.type=attr_follow; - follow.u.num=this_->center_timeout; - navit_set_attr(this_, &follow); -} - -int navit_handle_button(struct navit *this_, int pressed, int button, struct point *p, - struct callback *popup_callback) { - int border=16; - - dbg(lvl_debug,"button %d %s (ignore: %d)",button,pressed?"pressed":"released",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; - return 0; - } - if (pressed) { - this_->pressed=*p; - this_->last=*p; - this_->zoomed=0; - if (button == 1) { - this_->button_pressed=1; - this_->moved=0; - this_->popped=0; - if (popup_callback) - this_->button_timeout=event_add_timeout(500, 0, popup_callback); - } - if (button == 2) - navit_set_center_screen(this_, p, 1); - if (button == 3) - popup(this_, button, p); - if (button == 4 && this_->use_mousewheel) { - this_->zoomed = 1; - navit_zoom_in(this_, 2, p); - } - if (button == 5 && this_->use_mousewheel) { - this_->zoomed = 1; - navit_zoom_out(this_, 2, p); - } - } else { - - this_->button_pressed=0; - if (this_->button_timeout) { - event_remove_timeout(this_->button_timeout); - this_->button_timeout=NULL; - if (! this_->moved && ! transform_within_border(this_->trans, p, border)) { - navit_set_center_screen(this_, p, !this_->zoomed); - } - } - if (this_->motion_timeout) { - event_remove_timeout(this_->motion_timeout); - this_->motion_timeout=NULL; - } - if (this_->moved) { - dbg(lvl_debug, "mouse drag (%d, %d)->(%d, %d)", this_->pressed.x, this_->pressed.y, p->x, p->y); - update_transformation(this_->trans, &this_->pressed, p); - 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_draw(this_); - } else - return 1; - } - return 0; -} - -static void navit_button(void *data, int pressed, int button, struct point *p) { - struct navit *this=data; - dbg(lvl_debug,"enter %d %d ignore %d",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); - navit_handle_button(this, pressed, button, p, this->popup_callback); - } -} - - -static void navit_motion_timeout(struct navit *this_) { - int dx, dy; - - if (this_->drag_bitmap) { - struct point point; - point.x=(this_->current.x-this_->pressed.x); - point.y=(this_->current.y-this_->pressed.y); - if (graphics_draw_drag(this_->gra, &point)) { - graphics_overlay_disable(this_->gra, 1); - graphics_draw_mode(this_->gra, draw_mode_end); - this_->moved=1; - this_->motion_timeout=NULL; - return; - } - } - dx=(this_->current.x-this_->last.x); - dy=(this_->current.y-this_->last.y); - if (dx || dy) { - struct transformation *tr; - this_->last=this_->current; - graphics_overlay_disable(this_->gra, 1); - tr=transform_dup(this_->trans); - update_transformation(tr, &this_->pressed, &this_->current); - graphics_draw_cancel(this_->gra, this_->displaylist); - graphics_displaylist_draw(this_->gra, this_->displaylist, tr, this_->layout_current, this_->graphics_flags|512); - transform_destroy(tr); - this_->moved=1; - } - this_->motion_timeout=NULL; - return; -} - -void navit_handle_motion(struct navit *this_, struct point *p) { - int dx, dy; - - if (this_->button_pressed && !this_->popped) { - 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; - } - this_->current=*p; - if (! this_->motion_timeout_callback) - this_->motion_timeout_callback=callback_new_1(callback_cast(navit_motion_timeout), this_); - if (! this_->motion_timeout) - this_->motion_timeout=event_add_timeout(this_->drag_bitmap?10:100, 0, this_->motion_timeout_callback); - } - } -} - -static void navit_motion(void *data, struct point *p) { - struct navit *this=data; - if (!this->ignore_graphics_events) - navit_handle_motion(this, p); -} - -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); - if (p) { - transform_reverse(this_->trans, p, &c2); - center = transform_center(this_->trans); - center->x += c1.x - c2.x; - center->y += c1.y - c2.y; - } - if (draw) - navit_draw(this_); -} - -/** - * @brief Automatically adjusts zoom level - * - * This function automatically adjusts the current - * zoom level according to the current speed. - * - * @param this_ The navit struct - * @param center The "immovable" point - i.e. the vehicles position if we're centering on the vehicle - * @param speed The vehicles speed in meters per second - * @param dir The direction into which the vehicle moves - */ -static void navit_autozoom(struct navit *this_, struct coord *center, int speed, int draw) { - struct point pc; - int distance,w,h; - double new_scale; - long scale; - - if (! this_->autozoom_active) { - return; - } - - if(this_->autozoom_paused) { - this_->autozoom_paused--; - return; - } - - distance = speed * this_->autozoom_secs; - - transform_get_size(this_->trans, &w, &h); - transform(this_->trans, transform_get_projection(this_->trans), center, &pc, 1, 0, 0, NULL); - scale = transform_get_scale(this_->trans); - - /* We make sure that the point we want to see is within a certain range - * around the vehicle. The radius of this circle is the size of the - * screen. This doesn't necessarily mean the point is visible because of - * perspective etc. Quite rough, but should be enough. */ - - if (w > h) { - new_scale = (double)distance / h * 16; - } else { - new_scale = (double)distance / w * 16; - } - - if (abs((int)new_scale - (int)scale) < 2) { - return; // Smoothing - } - if (new_scale > this_->autozoom_max) - new_scale=this_->autozoom_max; - if (new_scale < this_->autozoom_min) - new_scale=this_->autozoom_min; - if (new_scale != scale) - navit_scale(this_, (long)new_scale, &pc, 0); -} - -/** - * Change the current zoom level, zooming closer to the ground - * - * @param navit The navit instance - * @param factor The zoom factor, usually 2 - * @param p The invariant point (if set to NULL, default to center) - * @returns nothing - */ -void navit_zoom_in(struct navit *this_, int factor, struct point *p) { - long scale=transform_get_scale(this_->trans)/factor; - if(this_->autozoom_active) { - this_->autozoom_paused = 10; - } - if (scale < 1) - scale=1; - navit_scale(this_, scale, p, 1); -} - -/** - * Change the current zoom level - * - * @param navit The navit instance - * @param factor The zoom factor, usually 2 - * @param p The invariant point (if set to NULL, default to center) - * @returns nothing - */ -void navit_zoom_out(struct navit *this_, int factor, struct point *p) { - long scale=transform_get_scale(this_->trans)*factor; - if(this_->autozoom_active) { - this_->autozoom_paused = 10; - } - navit_scale(this_, scale, p, 1); -} - -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)) { - navit_zoom_in(this_, factor, &p); - this_->vehicle->follow_curr=this_->vehicle->follow; - } else - navit_zoom_in(this_, factor, NULL); -} - -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)) { - 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_, char *cmd, struct attr **in, struct attr ***out) { - - navit_zoom_in_cursor(this_, 2); - return 0; -} - -static int navit_cmd_zoom_out(struct navit *this_, char *cmd, struct attr **in, struct attr ***out) { - navit_zoom_out_cursor(this_, 2); - return 0; -} - - -static int navit_cmd_say(struct navit *this, char *function, struct attr **in, struct attr ***out) { - if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) - navit_say(this, in[0]->u.str); - return 0; -} - -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 signature) - * @param in input attributes in[0] is the key string, in[1] is the integer value to store - * @param out output attributes, unused - * @returns 0 - */ -static int navit_cmd_set_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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); - } - return 0; -} - - -/** - * 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 signature) - * @param in input attributes in[0] is the key string, in[1] is the attr* value to store - * @param out output attributes, unused - * @returns 0 - */ -static int navit_cmd_set_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out) { - char*key; - struct attr*val; - if(!cmd_attr_var_hash) { - cmd_attr_var_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)attr_free); - } - - if ( (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && - (in && in[1] )) { - val = attr_dup(in[1]); - key = g_strdup(in[0]->u.str); - g_hash_table_insert(cmd_attr_var_hash, key, val); - } else { - dbg(lvl_warning, "Wrong parameters for set_attr_var() command function"); - } - return 0; -} - - - -/** - * 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 signature) - * @param in input attribute in[0] is the name of the layer - * @param out output unused - * @param valid unused - * @returns 0 - */ -static int navit_cmd_toggle_layer(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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 0; - } - layers=g_list_next(layers); - } - } - } - return 0; -} - -/** - * 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 signature) - * @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 - * @returns 0 - */ -static int navit_cmd_map_add_curr_pos(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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))) { - dbg(lvl_error, "Command function map_add_curr_pos(): there is no active mapset"); - return 0; - } - - if((item_type = item_from_name(in[1]->u.str))==type_none) { - dbg(lvl_error, "Command function map_add_curr_pos(): unknown item type"); - return 0; - } - - curr_map = mapset_get_map_by_name(ms, in[0]->u.str); - - //no map with the given name found - if( ! curr_map) { - dbg(lvl_error, "Command function map_add_curr_pos(): map not found"); - return 0; - } - - 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 { - dbg(lvl_error, "Command function map_add_curr_pos(): vehicle position is not accessible"); - return 0; - } - } else { - dbg(lvl_error, "Command function map_add_curr_pos(): no vehicle"); - return 0; - } - - 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) { - struct attr attr; - attr.type=attr_type_item_begin; - attr.u.item=it; - attr_dup_content(&attr,val); - item_coord_set(it,&curr_coord, 1, change_mode_modify); - } - } - map_rect_destroy(mr); - } - return 0; -} - -/** - * 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 signature) - * @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 - * @returns 0 - */ -static int navit_cmd_map_item_set_attr(struct navit *this, char *function, struct attr **in, struct attr ***out) { - if ( - in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str &&//map name - in[1] && ATTR_IS_ITEM(in[1]->type) && in[2]->u.item &&//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 item *it; - struct map_rect *mr; - - 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 0; - } - - mr=map_rect_new(curr_map,NULL); - it=in[1]->u.item; - it=map_rect_get_item_byid(mr,it->id_hi,it->id_lo); - - if(it) { - item_attr_set(it, &attr_to_set, change_mode_modify); - } - map_rect_destroy(mr); - } else { - dbg(lvl_debug,"Error in command function item_set_attr()"); - dbg(lvl_debug,"Command function item_set_attr(): map cond: %d",(in[0] && ATTR_IS_STRING(in[0]->type) - && in[0]->u.str)?1:0); - dbg(lvl_debug,"Command function item_set_attr(): item cond: %d",(in[1] && ATTR_IS_ITEM(in[1]->type))?1:0); - dbg(lvl_debug,"Command function item_set_attr(): attr type cond: %d",(in[2] && ATTR_IS_STRING(in[2]->type) - && in[2]->u.str)?1:0); - dbg(lvl_debug,"Command function item_set_attr(): attr val cond: %d",(in[3] && ATTR_IS_STRING(in[3]->type) - && in[3]->u.str)?1:0); - } - return 0; -} - -/** - * 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 signature) - * @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 - * @returns 0 - */ -static int navit_cmd_get_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out) { - struct attr **list = g_new0(struct attr *,2); - list[1] = NULL; - *out = list; - if(!cmd_attr_var_hash) { - struct attr*val = g_new0(struct attr,1); - val->type = attr_type_item_begin; - val->u.item = NULL; - list[0] = val; - return 0; - } - 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; - } - } - return 0; -} - - -/** - * Get value given a key string for the command system - * - * @param navit The navit instance - * @param function unused (needed to match command function signature) - * @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 - * @returns 0 - */ -static int navit_cmd_get_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out) { - struct attr **list = g_new0(struct attr *,2); - list[1] = NULL; - *out = list; - if(!cmd_int_var_hash) { - struct attr*val = g_new0(struct attr,1); - val->type = attr_type_int_begin; - val->u.num = 0; - list[0] = val; - return 0; - } - 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; - } - } - return 0; -} - -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 signature) - * @param in input attribute in[0] is the integer attibute to push - * @param out output attributes, unused - * @returns 0 - */ -static int navit_cmd_push_int(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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); - } - return 0; -} - -/** - * Pop an integer from the command system's integer stack - * - * @param navit The navit instance - * @param function unused (needed to match command function signature) - * @param in input attributes unused - * @param out output attribute, the value popped if stack isn't empty or 0 - * @returns 0 - */ -static int navit_cmd_pop_int(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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; - return 0; -} - -/** - * Get current size of command system's integer stack - * - * @param navit The navit instance - * @param function unused (needed to match command function signature) - * @param in input attributes unused - * @param out output attribute, the size of stack - * @returns 0 - */ -static int navit_cmd_int_stack_size(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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); - return 0; -} - -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 int navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out) { - struct pcoord pc; - char *description=NULL; - in=navit_get_coord(this, in, &pc); - if (!in) - return 0; - if (in[0] && ATTR_IS_STRING(in[0]->type)) - description=in[0]->u.str; - navit_set_destination(this, &pc, description, 1); - return 0; -} - - -static int navit_cmd_route_remove_next_waypoint(struct navit *this, char *function, struct attr **in, - struct attr ***out) { - navit_remove_waypoint(this); - return 0; -} - - -static int navit_cmd_route_remove_last_waypoint(struct navit *this, char *function, struct attr **in, - struct attr ***out) { - navit_remove_nth_waypoint(this, navit_get_destination_count(this)-1); - return 0; -} - - -static int navit_cmd_set_center(struct navit *this, char *function, struct attr **in, struct attr ***out) { - struct pcoord pc; - int set_timeout=0; - in=navit_get_coord(this, in, &pc); - if (!in) - return 0; - if(in[0] && ATTR_IS_INT(in[0]->type)) - set_timeout=in[0]->u.num!=0; - navit_set_center(this, &pc, set_timeout); - return 0; -} - - -static int navit_cmd_set_position(struct navit *this, char *function, struct attr **in, struct attr ***out) { - struct pcoord pc; - in=navit_get_coord(this, in, &pc); - if (!in) - return 0; - navit_set_position(this, &pc); - return 0; -} - - -static int navit_cmd_fmt_coordinates(struct navit *this, char *function, struct attr **in, struct attr ***out) { - struct attr attr; - attr.type=attr_type_string_begin; - attr.u.str="Fix me"; - if (out) { - *out=attr_generic_add_attr(*out, &attr); - } - return 0; -} - -/** - * Join several string attributes into one - * - * @param navit The navit instance - * @param function unused (needed to match command function signature) - * @param in input attributes in[0] - separator, in[1..] - attributes to join - * @param out output attribute joined attribute as string - * @returns 0 - */ -static int navit_cmd_strjoin(struct navit *this, char *function, struct attr **in, struct attr ***out) { - 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); - } - return 0; -} - -/** - * Call external program - * - * @param navit The navit instance - * @param function unused (needed to match command function signature) - * @param in input attributes in[0] - name of executable, in[1..] - parameters - * @param out output attribute unused - * @returns 0 - */ -static int navit_cmd_spawn(struct navit *this, char *function, struct attr **in, struct attr ***out) { - int i,j, nparms, nvalid; - 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(lvl_debug,"Parameter #%i is attr_none - skipping",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(lvl_debug,"status %i",st); - // example of blocking wait - //st=spawn_process_check_status(pi,1);dbg(lvl_debug,"status %i",st); - // example of wait after process is finished and status is - // already tested - //st=spawn_process_check_status(pi,1);dbg(lvl_debug,"status %i",st); - // example of wait after process is finished and status is - // already tested - unblocked - //st=spawn_process_check_status(pi,0);dbg(lvl_debug,"status %i",st); - - // End testing suite - spawn_process_info_free(pi); - for(i=0; argv[i]; i++) - g_free(argv[i]); - g_free(argv); - } - return 0; -} - - -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)}, - {"set_position",command_cast(navit_cmd_set_position)}, - {"route_remove_next_waypoint",command_cast(navit_cmd_route_remove_next_waypoint)}, - {"route_remove_last_waypoint",command_cast(navit_cmd_route_remove_last_waypoint)}, - {"set_position",command_cast(navit_cmd_set_position)}, - {"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)}, - {"switch_layout_day_night",command_cast(navit_cmd_switch_layout_day_night)}, -}; - -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) { - struct navit *this_=g_new0(struct navit, 1); - struct pcoord center; - struct coord co; - struct coord_geo g; - enum projection pro=projection_mg; - int zoom = 256; - g.lat=53.13; - g.lng=11.70; - - this_->func=&navit_func; - navit_object_ref((struct navit_object *)this_); - this_->attrs=attr_list_dup(attrs); - this_->self.type=attr_navit; - this_->self.u.navit=this_; - this_->attr_cbl=callback_list_new(); - - this_->orientation=-1; - this_->tracking_flag=1; - this_->recentdest_count=10; - this_->osd_configuration=-1; - this_->default_layout_name=NULL; - - this_->center_timeout = 10; - this_->use_mousewheel = 1; - this_->autozoom_secs = 10; - this_->autozoom_min = 7; - this_->autozoom_active = 0; - this_->autozoom_paused = 0; - this_->zoom_min = 1; - this_->zoom_max = 2097152; - this_->autozoom_max = this_->zoom_max; - this_->follow_cursor = 1; - this_->radius = 30; - this_->border = 16; - this_->auto_switch = TRUE; - - transform_from_geo(pro, &g, &co); - center.x=co.x; - center.y=co.y; - center.pro = pro; - this_->trans = transform_new(¢er, zoom, (this_->orientation != -1) ? this_->orientation : 0); - this_->trans_cursor = transform_new(¢er, zoom, (this_->orientation != -1) ? this_->orientation : 0); - - this_->bookmarks=bookmarks_new(&this_->self, NULL, this_->trans); - - this_->prevTs=0; - - for (; *attrs; attrs++) { - navit_set_attr_do(this_, *attrs, 1); - } - this_->displaylist=graphics_displaylist_new(); - command_add_table(this_->attr_cbl, commands, sizeof(commands)/sizeof(struct command_table), this_); - - this_->messages = messagelist_new(attrs); - - dbg(lvl_debug,"return %p",this_); - - return this_; -} - -static int navit_set_gui(struct navit *this_, struct gui *gui) { - if (this_->gui) - return 0; - this_->gui=gui; - if (gui_has_main_loop(this_->gui)) { - if (! main_loop_gui) { - main_loop_gui=this_->gui; - } else { - dbg(lvl_error,"gui with main loop already active, ignoring this instance"); - return 0; - } - } - return 1; -} - -void navit_add_message(struct navit *this_, const char *message) { - message_new(this_->messages, message); -} - -struct message -*navit_get_messages(struct navit *this_) { - 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); - this_->predraw_callback=callback_new_attr_1(callback_cast(navit_predraw), attr_predraw, this_); - graphics_add_callback(gra, this_->predraw_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, int draw) { - 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); - if (draw) - navit_draw(this_); -} - -static void navit_mark_navigation_stopped(char *former_destination_file) { - FILE *f; - f=fopen(former_destination_file, "a"); - if (f) { - fprintf(f,"%s", TEXTFILE_COMMENT_NAVI_STOPPED); - fclose(f); - } else { - dbg(lvl_error, "Error setting mark in destination file %s: %s", former_destination_file, strerror(errno)); - } -} - - -/** - * Start or add a given set of coordinates for route computing - * - * @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 - * @param async Set to 1 to do route calculation asynchronously - * @return nothing - */ -void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async) { - char *destination_file; - destination_file = bookmarks_get_destination_file(TRUE); - if (c) { - this_->destination=*c; - this_->destination_valid=1; - - dbg(lvl_debug, "c=(%i,%i)", c->x,c->y); - bookmarks_append_destinations(this_->former_destination, destination_file, c, 1, type_former_destination, description, - this_->recentdest_count); - } else { - this_->destination_valid=0; - bookmarks_append_destinations(this_->former_destination, destination_file, NULL, 0, type_former_destination, NULL, - this_->recentdest_count); - navit_mark_navigation_stopped(destination_file); - } - g_free(destination_file); - - if (this_->route) { - struct attr attr; - int dstcount; - struct pcoord *pc; - - navit_get_attr(this_, attr_waypoints_flag, &attr, NULL); - if (this_->waypoints_flag==0 || route_get_destination_count(this_->route)==0) { - route_set_destination(this_->route, c, async); - } else { - route_append_destination(this_->route, c, async); - } - - dstcount=route_get_destination_count(this_->route); - if(dstcount>0) { - destination_file = bookmarks_get_destination_file(TRUE); - pc=g_new(struct pcoord,dstcount); - route_get_destinations(this_->route,pc,dstcount); - bookmarks_append_destinations(this_->former_destination, destination_file, pc, dstcount, type_former_itinerary, - description, this_->recentdest_count); - g_free(pc); - g_free(destination_file); - } - } - - callback_list_call_attr_0(this_->attr_cbl, attr_destination); - - if (this_->route && this_->ready == 3 && !(this_->flags & 4)) - navit_draw(this_); -} - -/** - * Add destination description to the recent dest file. Doesn't start routing. - * - * @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_add_destination_description(struct navit *this_, struct pcoord *c, const char *description) { - char *destination_file; - if (c) { - destination_file = bookmarks_get_destination_file(TRUE); - bookmarks_append_destinations(this_->former_destination, destination_file, c, 1, type_former_destination, description, - this_->recentdest_count); - g_free(destination_file); - } -} - - -/** - * Start the route computing to a given set of coordinates including waypoints - * - * @param this_ 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 - * @param async If routing should be done asynchronously - * @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_destinations(this_->former_destination, destination_file, c, count, type_former_itinerary, description, - this_->recentdest_count); - g_free(destination_file); - } else - this_->destination_valid=0; - if (this_->route) - route_set_destinations(this_->route, c, count, async); - - callback_list_call_attr_0(this_->attr_cbl, attr_destination); - if (this_->route && this_->ready == 3) - navit_draw(this_); -} - -/** - * @brief Retrieves destinations from the route - * - * Prior to calling this method, you may want to retrieve the number of destinations by calling - * {@link navit_get_destination_count(struct navit *)} and assigning a buffer of sufficient capacity. - * - * If the return value equals `count`, the buffer was either just large enough or too small to hold the - * entire list of destinations; there is no way to tell from the result which is the case. - * - * If the Navit instance does not have a route, the result is 0. - * - * @param this_ The Navit instance - * @param pc Pointer to an array of projected coordinates which will receive the destination coordinates - * @param count Capacity of `pc` - * @return The number of destinations stored in `pc`, never greater than `count` - */ -int navit_get_destinations(struct navit *this_, struct pcoord *pc, int count) { - if(!this_->route) - return 0; - return route_get_destinations(this_->route, pc, count); - -} - -/** - * @brief Get the destinations count for the route - * - * @param this The Navit instance - * @return destination count for the route, or 0 if the Navit instance has no route - */ -int navit_get_destination_count(struct navit *this_) { - if(!this_->route) - return 0; - return route_get_destination_count(this_->route); -} - -char* navit_get_destination_description(struct navit *this_, int n) { - if(!this_->route) - return NULL; - return route_get_destination_description(this_->route, n); -} - -void navit_remove_nth_waypoint(struct navit *this_, int n) { - if(!this_->route) - return; - if (route_get_destination_count(this_->route)>1) { - route_remove_nth_waypoint(this_->route, n); - } else { - navit_set_destination(this_, NULL, NULL, 0); - } -} - -void navit_remove_waypoint(struct navit *this_) { - if(!this_->route) - return; - if (route_get_destination_count(this_->route)>1) { - route_remove_waypoint(this_->route); - } else { - navit_set_destination(this_, NULL, NULL, 0); - } -} - -/** - * @brief Checks if a route is calculated - * - * This function checks if a route is calculated. - * - * @param this_ The navit struct whose route should be checked. - * @return True if the route is set, false otherwise. - */ -int navit_check_route(struct navit *this_) { - if (this_->route) { - return route_get_path_set(this_->route); - } - - return 0; -} - -static int navit_former_destinations_active(struct navit *this_) { - char *destination_file_name = bookmarks_get_destination_file(FALSE); - FILE *destination_file; - int active=0; - char lastline[100]; - destination_file=fopen(destination_file_name,"r"); - if (destination_file) { - while(fgets(lastline, sizeof(lastline), destination_file)); - fclose(destination_file); - if ((lastline != NULL) && (strcmp(lastline, TEXTFILE_COMMENT_NAVI_STOPPED))) { - active=1; - } - } - g_free(destination_file_name); - return active; -} - - -struct map* read_former_destinations_from_file() { - struct attr type, data, no_warn, flags, *attrs[5]; - 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; - - no_warn.type=attr_no_warning_if_map_file_missing; - no_warn.u.num=1; - - flags.type=attr_flags; - flags.u.num=1; - - attrs[0]=&type; - attrs[1]=&data; - attrs[2]=&flags; - attrs[3]=&no_warn; - attrs[4]=NULL; - - m=map_new(NULL, attrs); - g_free(destination_file); - return m; -} - -static void navit_add_former_destinations_from_file(struct navit *this_) { - struct item *item; - int i,valid=0,count=0,maxcount=1; - struct coord *c=g_new(struct coord, maxcount); - struct pcoord *pc; - struct map_rect *mr; - - this_->former_destination=read_former_destinations_from_file(); - if (!this_->route || !navit_former_destinations_active(this_) || !this_->vehicle) - return; - mr=map_rect_new(this_->former_destination, NULL); - while ((item=map_rect_get_item(mr))) { - if (item->type == type_former_itinerary || item->type == type_former_itinerary_part) { - count=item_coord_get(item, c, maxcount); - while(count==maxcount) { - maxcount*=2; - c=g_realloc(c, sizeof(struct coord)*maxcount); - count+=item_coord_get(item, &c[count], maxcount-count); - } - if(count) - valid=1; - } - } - map_rect_destroy(mr); - if (valid && count > 0) { - pc=g_new(struct pcoord, count); - 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; - g_free(pc); - } - g_free(c); -} - - -void navit_textfile_debug_log(struct navit *this_, const char *fmt, ...) { - 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", this_->vehicle->coord.x, this_->vehicle->coord.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_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *fmt, ...) { - 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_, const char *text) { - struct attr attr; - if(this_->speech) { - if (!speech_get_attr(this_->speech, attr_active, &attr, NULL)) - attr.u.num = 1; - dbg(lvl_debug, "this_.speech->active %ld", attr.u.num); - if(attr.u.num) - speech_say(this_->speech, text); - } -} - -/** - * @brief Toggles the navigation announcer for navit - * @param this_ The navit object - */ -static int navit_cmd_announcer_toggle(struct navit *this_, char *function, struct attr **in, struct attr ***out) { - struct attr attr, speechattr; - - // search for the speech attribute - if(!navit_get_attr(this_, attr_speech, &speechattr, NULL)) - return 0; - // find out if the corresponding attribute attr_active has been set - if(speech_get_attr(speechattr.u.speech, attr_active, &attr, NULL)) { - // flip it then... - attr.u.num = !attr.u.num; - } else { - // otherwise disable it because voice is enabled by default - attr.type = attr_active; - attr.u.num = 0; - } - - // apply the new state - if(!speech_set_attr(speechattr.u.speech, &attr)) - return 0; - - // announce that the speech attribute has changed - callback_list_call_attr_1(this_->attr_cbl, attr_speech, this_); - return 0; -} - -void navit_speak(struct navit *this_) { - struct navigation *nav=this_->navigation; - struct map *map=NULL; - struct map_rect *mr=NULL; - struct item *item; - struct attr attr; - - if (!speech_get_attr(this_->speech, attr_active, &attr, NULL)) - attr.u.num = 1; - dbg(lvl_debug, "this_.speech->active %ld", attr.u.num); - if(!attr.u.num) - return; - - if (nav) - map=navigation_get_map(nav); - if (map) - mr=map_rect_new(map, NULL); - if (mr) { - while ((item=map_rect_get_item(mr)) && (item->type == type_nav_position || item->type == type_nav_none)); - if (item && item_attr_get(item, attr_navigation_speech, &attr)) { - if (*attr.u.str != '\0') { - speech_say(this_->speech, attr.u.str); - navit_add_message(this_, attr.u.str); - } - navit_textfile_debug_log(this_, "type=announcement label=\"%s\"", attr.u.str); - } - map_rect_destroy(mr); - } -} - -static void navit_window_roadbook_update(struct navit *this_) { - struct navigation *nav=this_->navigation; - struct map *map=NULL; - struct map_rect *mr=NULL; - struct item *item; - struct attr attr; - struct param_list param[5]; - int secs; - - /* Respect the Imperial attribute as we enlighten the user. */ - int imperial = FALSE; /* default to using metric measures. */ - if (navit_get_attr(this_, attr_imperial, &attr, NULL)) - imperial=attr.u.num; - - dbg(lvl_debug,"enter"); - datawindow_mode(this_->roadbook_window, 1); - if (nav) - map=navigation_get_map(nav); - if (map) - mr=map_rect_new(map, NULL); - dbg(lvl_debug,"nav=%p map=%p mr=%p", nav, map, mr); - if (mr) { - dbg(lvl_debug,"while loop"); - while ((item=map_rect_get_item(mr))) { - dbg(lvl_debug,"item=%p", item); - attr.u.str=NULL; - if (item->type != type_nav_position) { - item_attr_get(item, attr_navigation_long, &attr); - if (attr.u.str == NULL) { - continue; - } - dbg(lvl_info, "Command='%s'", attr.u.str); - param[0].value=g_strdup(attr.u.str); - } else - param[0].value=_("Position"); - param[0].name=_("Command"); - - /* Distance to the next maneuver. */ - item_attr_get(item, attr_length, &attr); - dbg(lvl_info, "Length=%ld in meters", attr.u.num); - param[1].name=_("Length"); - - if ( attr.u.num >= 2000 ) { - param[1].value=g_strdup_printf("%5.1f %s", - imperial == TRUE ? (float)attr.u.num * METERS_TO_MILES : (float)attr.u.num / 1000, - imperial == TRUE ? _("mi") : _("km") - ); - } else { - param[1].value=g_strdup_printf("%7.0f %s", - imperial == TRUE ? (attr.u.num * FEET_PER_METER) : attr.u.num, - imperial == TRUE ? _("feet") : _("m") - ); - } - - /* Time to next maneuver. */ - item_attr_get(item, attr_time, &attr); - dbg(lvl_info, "Time=%ld", attr.u.num); - secs=attr.u.num/10; - param[2].name=_("Time"); - if ( secs >= 3600 ) { - param[2].value=g_strdup_printf("%d:%02d:%02d",secs / 60, ( secs / 60 ) % 60, secs % 60); - } else { - param[2].value=g_strdup_printf("%d:%02d",secs / 60, secs % 60); - } - - /* Distance from next maneuver to destination. */ - item_attr_get(item, attr_destination_length, &attr); - dbg(lvl_info, "Destlength=%ld in meters.", attr.u.num); - param[3].name=_("Destination Length"); - if ( attr.u.num >= 2000 ) { - param[3].value=g_strdup_printf("%5.1f %s", - imperial == TRUE ? (float)attr.u.num * METERS_TO_MILES : (float)attr.u.num / 1000, - imperial == TRUE ? _("mi") : _("km") - ); - } else { - param[3].value=g_strdup_printf("%7.0f %s", - imperial == TRUE ? (attr.u.num * FEET_PER_METER) : attr.u.num, - imperial == TRUE ? _("feet") : _("m") - ); - } - - /* Time from next maneuver to destination. */ - item_attr_get(item, attr_destination_time, &attr); - dbg(lvl_info, "Desttime=%ld", attr.u.num); - secs=attr.u.num/10; - param[4].name=_("Destination Time"); - if ( secs >= 3600 ) { - param[4].value=g_strdup_printf("%d:%02d:%02d",secs / 3600, (secs / 60 ) % 60, secs % 60); - } else { - param[4].value=g_strdup_printf("%d:%02d",secs / 60, secs % 60); - } - datawindow_add(this_->roadbook_window, param, 5); - } - map_rect_destroy(mr); - } - datawindow_mode(this_->roadbook_window, 0); -} - -void navit_window_roadbook_destroy(struct navit *this_) { - dbg(lvl_debug, "enter"); - navigation_unregister_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback); - callback_destroy(this_->roadbook_callback); - this_->roadbook_window=NULL; - this_->roadbook_callback=NULL; -} -void navit_window_roadbook_new(struct navit *this_) { - if (!this_->gui || this_->roadbook_callback || this_->roadbook_window) { - return; - } - - this_->roadbook_callback=callback_new_1(callback_cast(navit_window_roadbook_update), this_); - navigation_register_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback); - this_->roadbook_window=gui_datawindow_new(this_->gui, _("Roadbook"), NULL, - callback_new_1(callback_cast(navit_window_roadbook_destroy), this_)); - navit_window_roadbook_update(this_); -} - -int navit_init(struct navit *this_) { - struct mapset *ms; - struct map *map; - int callback; - char *center_file; - struct attr_iter *iter; - struct attr *attr; - struct traffic * traffic; - - dbg(lvl_info,"enter gui %p graphics %p",this_->gui,this_->gra); - - if (!this_->gui && !(this_->flags & 2)) { - dbg(lvl_error,"FATAL: No GUI available."); - exit(1); - } - if (!this_->gra && !(this_->flags & 1)) { - dbg(lvl_error,"FATAL: No graphics subsystem available."); - exit(1); - } - dbg(lvl_info,"Connecting gui to graphics"); - 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); - dbg(lvl_error,"FATAL: Failed to connect graphics '%s' to gui '%s'", attr_type_graphics.u.str, attr_type_gui.u.str); - dbg(lvl_error,"Please see http://wiki.navit-project.org/index.php/Failed_to_connect_graphics_to_gui " - "for explanations and solutions\n"); - exit(1); - } - if (this_->speech && this_->navigation) { - struct attr speech; - speech.type=attr_speech; - speech.u.speech=this_->speech; - navigation_set_attr(this_->navigation, &speech); - } - dbg(lvl_info,"Initializing graphics"); - dbg(lvl_info,"Setting Vehicle"); - navit_set_vehicle(this_, this_->vehicle); - dbg(lvl_info,"Adding dynamic maps to mapset %p",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))) { - 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))) { - 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_->tracking) { - tracking_set_mapset(this_->tracking, ms); - if (this_->route) - tracking_set_route(this_->tracking, this_->route); - } - - attr = g_new0(struct attr, 1); - iter = navit_attr_iter_new(NULL); - map = NULL; - while (navit_get_attr(this_, attr_traffic, attr, iter)) { - traffic = (struct traffic *) attr->u.navit_object; - traffic_set_mapset(traffic, ms); - if (this_->route) - traffic_set_route(traffic, this_->route); - /* add the first map found */ - if (!map && (map = traffic_get_map(traffic))) { - struct attr map_a; - map_a.type = attr_map; - map_a.u.map = map; - mapset_add_attr(ms, &map_a); - } - } - navit_attr_iter_destroy(iter); - g_free(attr); - - if (this_->navigation) { - if ((map=navigation_get_map(this_->navigation))) { - 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))) { - 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_); - } else { - dbg(lvl_error, "FATAL: No mapset available. Please add a (valid) mapset to your configuration."); - exit(1); - } - if (this_->route) { - struct attr callback; - this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_); - callback.type=attr_callback; - callback.u.callback=this_->route_cb; - route_add_attr(this_->route, &callback); - } - if (this_->navigation) { - if (this_->speech) { - this_->nav_speech_cb=callback_new_1(callback_cast(navit_speak), this_); - navigation_register_callback(this_->navigation, attr_navigation_speech, this_->nav_speech_cb); - } - if (this_->route) - navigation_set_route(this_->navigation, this_->route); - } - dbg(lvl_info,"Setting Center"); - center_file = bookmarks_get_center_file(FALSE); - bookmarks_set_center_from_file(this_->bookmarks, center_file); - g_free(center_file); - global_navit=this_; - - 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(lvl_info,"ready=%d",this_->ready); - if (this_->ready == 3) - navit_draw_async(this_, 1); - if (callback) - callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_); - return 0; -} - -void navit_zoom_to_rect(struct navit *this_, struct coord_rect *r) { - struct coord c; - int w,h,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); - transform_get_size(this_->trans, &w, &h); - dbg(lvl_debug,"center 0x%x,0x%x w %d h %d",c.x,c.y,w,h); - dbg(lvl_debug,"%x,%x-%x,%x", r->lu.x,r->lu.y,r->rl.x,r->rl.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(lvl_debug,"%d,%d-%d,%d",p1.x,p1.y,p2.x,p2.y); - if (p1.x < 0 || p2.x < 0 || p1.x > w || p2.x > w || - p1.y < 0 || p2.y < 0 || p1.y > h || p2.y > h) - scale*=2; - else - break; - - } - dbg(lvl_debug,"scale=%d (0x%x) of %d (0x%x)",scale,scale,1<<20,1<<20); - if (this_->ready == 3) - navit_draw_async(this_,0); -} - -void navit_zoom_to_route(struct navit *this_, int orientation) { - struct map *map; - struct map_rect *mr=NULL; - struct item *item; - struct coord c; - struct coord_rect r; - int count=0; - if (! this_->route) - return; - dbg(lvl_debug,"enter"); - map=route_get_map(this_->route); - dbg(lvl_debug,"map=%p",map); - if (map) - mr=map_rect_new(map, NULL); - dbg(lvl_debug,"mr=%p",mr); - if (mr) { - while ((item=map_rect_get_item(mr))) { - dbg(lvl_debug,"item=%s", item_to_name(item->type)); - while (item_coord_get(item, &c, 1)) { - dbg(lvl_debug,"coord"); - if (!count) - r.lu=r.rl=c; - else - coord_rect_extend(&r, &c); - count++; - } - } - map_rect_destroy(mr); - } - if (! count) - return; - if (orientation != -1) - transform_set_yaw(this_->trans, orientation); - navit_zoom_to_rect(this_, &r); -} - -static int navit_cmd_zoom_to_route(struct navit *this, char *function, struct attr **in, struct attr ***out) { - navit_zoom_to_route(this, 0); - return 0; -} - - -/** - * Change the current zoom level - * - * @param navit The navit instance - * @param center The point where to center the map, including its projection - * @returns nothing - */ -void navit_set_center(struct navit *this_, struct pcoord *center, int set_timeout) { - struct coord *c=transform_center(this_->trans); - struct coord c1,c2; - enum projection pro = transform_get_projection(this_->trans); - if (pro != center->pro) { - c1.x = center->x; - c1.y = center->y; - transform_from_to(&c1, center->pro, &c2, pro); - } else { - c2.x = center->x; - c2.y = center->y; - } - *c=c2; - if (set_timeout) - navit_set_timeout(this_); - if (this_->ready == 3) - navit_draw(this_); -} - -static void navit_set_center_coord_screen(struct navit *this_, struct coord *c, struct point *p, int set_timeout) { - int width, height; - struct point po; - transform_set_center(this_->trans, c); - transform_get_size(this_->trans, &width, &height); - po.x=width/2; - po.y=height/2; - update_transformation(this_->trans, &po, p); - if (set_timeout) - navit_set_timeout(this_); -} - -/** - * Links all vehicles to a cursor depending on the current profile. - * - * @param this_ A navit instance - * @author Ralph Sennhauser (10/2009) - */ -static void navit_set_cursors(struct navit *this_) { - struct attr name; - struct navit_vehicle *nv; - struct cursor *c; - GList *v; - - 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)) { - 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, 0); - v=g_list_next(v); - } - return; -} - - -/** - * @brief Calculates the position of the cursor on the screen. - * - * This method considers padding if supported by the graphics plugin. In that case, the inner rectangle - * (i.e. screen size minus padding) will be used to center the cursor and to determine cursor offset (as - * specified in `this_->radius`). - * - * @param this_ The navit object - * @param p Receives the screen coordinates for the cursor - * @param keep_orientation Whether to maintain the current map orientation. If false, the map will be - * rotated so that the bearing of the vehicle is up. - * @param dir Receives the new map orientation as requested by `screen_orientation` (can be `NULL`) - * - * @return Always 1 - */ -static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir) { - int width, height; - struct navit_vehicle *nv=this_->vehicle; - struct padding *padding = NULL; - - 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. - int min_offset_speed = 2; // Speed in km/h - int max_offset_speed = 50; // Speed in km/h - // Calculate cursor offset from the center of the screen, upon speed. - if (nv->speed <= min_offset_speed) { - offset = min_offset; - } else if (nv->speed > max_offset_speed) { - offset = max_offset; - } else { - offset = (max_offset - min_offset) / (max_offset_speed - min_offset_speed) * (nv->speed - min_offset_speed); - } -#endif - - if (this_->gra) { - padding = graphics_get_data(this_->gra, "padding"); - } else - dbg(lvl_warning, "cannot get padding: this->gra is NULL"); - - transform_get_size(this_->trans, &width, &height); - dbg(lvl_debug, "width=%d height=%d", width, height); - - if (padding) { - width -= (padding->left + padding->right); - height -= (padding->top + padding->bottom); - dbg(lvl_debug, "corrected for padding: width=%d height=%d", width, height); - } - - if (this_->orientation == -1 || keep_orientation) { - p->x=50*width/100; - p->y=(50 + offset)*height/100; - if (dir) - *dir=keep_orientation?this_->orientation:nv->dir; - } else { - int mdir; - if (this_->tracking && this_->tracking_flag) { - mdir = tracking_get_angle(this_->tracking) - this_->orientation; - } else { - mdir=nv->dir-this_->orientation; - } - - p->x=(50 - offset*sin(M_PI*mdir/180.))*width/100; - p->y=(50 + offset*cos(M_PI*mdir/180.))*height/100; - if (dir) - *dir=this_->orientation; - } - - if (padding) { - p->x += padding->left; - p->y += padding->top; - } - - dbg(lvl_debug, "x=%d y=%d, offset=%f", p->x, p->y, offset); - - return 1; -} - -/** - * @brief Recalculates the map view so that the vehicle cursor is visible - * - * This function recalculates the parameters which control the visible map area, zoom and orientation. The - * caller is responsible for redrawing the map after the function returns. - * - * If the vehicle supplies a {@code position_valid} attribute and it is {@code attr_position_valid_invalid}, - * the map position is not changed. - * - * @param this_ The navit object - * @param autozoom Whether to set zoom based on current speed. If false, current zoom will be maintained. - * @param keep_orientation Whether to maintain the current map orientation. If false, the map will be rotated - * so that the bearing of the vehicle is up. - */ -void navit_set_center_cursor(struct navit *this_, int autozoom, int keep_orientation) { - int dir; - struct point pn; - struct navit_vehicle *nv=this_->vehicle; - struct attr attr; - if (!nv || !nv->vehicle) { - return; - } - if (vehicle_get_attr(nv->vehicle, attr_position_valid, &attr, NULL) && (attr.u.num == attr_position_valid_invalid)) - return; - 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); - if (autozoom) - navit_autozoom(this_, &nv->coord, nv->speed, 0); -} - -/** - * @brief Recenters the map so that the vehicle cursor is visible - * - * This function first calls {@code navit_set_center_cursor()} to recalculate the map display, then - * triggers a redraw of the map. - * - *@param this_ The navit object - */ -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); -} - -/** - * @brief Recenters the map so that the vehicle cursor is visible - * - * This is the callback function for the {@code set_center_cursor()} command. It is just a wrapper around - * {@code navit_set_center_cursor_draw()}. - * - *@param this_ The navit object - */ -static int navit_cmd_set_center_cursor(struct navit *this_, char *function, struct attr **in, struct attr ***out) { - navit_set_center_cursor_draw(this_); - return 0; -} - -void navit_set_center_screen(struct navit *this_, struct point *p, int set_timeout) { - struct coord c; - struct pcoord pc; - transform_reverse(this_->trans, p, &c); - pc.x = c.x; - pc.y = c.y; - pc.pro = transform_get_projection(this_->trans); - navit_set_center(this_, &pc, set_timeout); -} - -static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init) { - int dir=0, orient_old=0, attr_updated=0; - struct coord co; - long zoom; - GList *l; - struct navit_vehicle *nv; - struct layout *lay; - struct attr active; - active.type=attr_active; - active.u.num=0; - - dbg(lvl_debug, "enter, this_=%p, attr=%p (%s), init=%d", this_, attr, attr_to_name(attr->type), init); - - switch (attr->type) { - case attr_autozoom: - attr_updated=(this_->autozoom_secs != attr->u.num); - this_->autozoom_secs = attr->u.num; - break; - case attr_autozoom_active: - attr_updated=(this_->autozoom_active != attr->u.num); - this_->autozoom_active = attr->u.num; - break; - case attr_center: - transform_from_geo(transform_get_projection(this_->trans), attr->u.coord_geo, &co); - dbg(lvl_debug,"0x%x,0x%x",co.x,co.y); - transform_set_center(this_->trans, &co); - break; - case attr_drag_bitmap: - 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; - attr_updated=(this_->vehicle->follow_curr != attr->u.num); - this_->vehicle->follow_curr = attr->u.num; - break; - case attr_default_layout: - if(!attr->u.str) - return 0; - if(this_->default_layout_name) /* There is already a default layout, ignore this new value */ - g_free(this_->default_layout_name); /* Drop the previous layout name, use the this one instead */ - this_->default_layout_name=g_strdup(attr->u.str); - attr_updated=1; - break; - case attr_layout: - if(!attr->u.layout) - return 0; - dbg(lvl_debug,"setting attr_layout to %s", attr->u.layout->name); - if(this_->layout_current!=attr->u.layout) { - navit_update_current_layout(this_, attr->u.layout); - graphics_font_destroy_all(this_->gra); - navit_set_cursors(this_); - if (this_->ready == 3) - navit_draw(this_); - attr_updated=1; - } - break; - case attr_layout_name: - if(!attr->u.str) - return 0; - dbg(lvl_debug,"setting attr_layout_name to %s", attr->u.str); - 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; - case attr_orientation: - orient_old=this_->orientation; - this_->orientation=attr->u.num; - if (!init) { - if (this_->orientation != -1) { - dir = this_->orientation; - } else { - if (this_->vehicle) { - dir = this_->vehicle->dir; - } - } - 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_osd_configuration: - dbg(lvl_debug,"setting osd_configuration to %ld (was %d)", attr->u.num, this_->osd_configuration); - attr_updated=(this_->osd_configuration != attr->u.num); - this_->osd_configuration=attr->u.num; - break; - case attr_pitch: - attr_updated=(this_->pitch != attr->u.num); - this_->pitch=attr->u.num; - transform_set_pitch(this_->trans, round(this_->pitch*sqrt(240*320)/sqrt( - this_->w*this_->h))); // Pitch corrected for window resolution - if (!init && attr_updated && this_->ready == 3) - navit_draw(this_); - break; - case attr_projection: - if(this_->trans && transform_get_projection(this_->trans) != 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; - break; - case attr_speech: - if(this_->speech && this_->speech != attr->u.speech) { - attr_updated=1; - this_->speech = attr->u.speech; - } - break; - case attr_timeout: - attr_updated=(this_->center_timeout != attr->u.num); - this_->center_timeout = attr->u.num; - break; - case attr_tracking: - 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; - break; - case attr_vehicle: - if (!attr->u.vehicle) { - if (this_->vehicle) { - vehicle_set_attr(this_->vehicle->vehicle, &active); - navit_set_vehicle(this_, NULL); - attr_updated=1; - } - break; - } - l=this_->vehicles; - while(l) { - nv=l->data; - if (nv->vehicle == attr->u.vehicle) { - if (!this_->vehicle || this_->vehicle->vehicle != attr->u.vehicle) { - if (this_->vehicle) - vehicle_set_attr(this_->vehicle->vehicle, &active); - active.u.num=1; - vehicle_set_attr(nv->vehicle, &active); - attr_updated=1; - } - navit_set_vehicle(this_, nv); - } - l=g_list_next(l); - } - break; - case attr_vehicleprofile: - attr_updated=navit_set_vehicleprofile(this_, attr->u.vehicleprofile); - break; - case attr_zoom: - zoom=transform_get_scale(this_->trans); - attr_updated=(zoom != attr->u.num); - transform_set_scale(this_->trans, 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; - case attr_follow_cursor: - 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; - case attr_waypoints_flag: - attr_updated=(this_->waypoints_flag != !!attr->u.num); - this_->waypoints_flag=!!attr->u.num; - break; - default: - dbg(lvl_debug, "calling generic setter method for attribute type %s", attr_to_name(attr->type)) - return navit_object_set_attr((struct navit_object *) this_, attr); - } - if (attr_updated && !init) { - callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr); - if (attr->type == attr_osd_configuration) - graphics_draw_mode(this_->gra, draw_mode_end); - } - return 1; -} - -int navit_set_attr(struct navit *this_, struct attr *attr) { - return navit_set_attr_do(this_, attr, 0); -} - -int navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) { - struct message *msg; - struct coord *c; - int len,offset; - int ret=1; - - switch (type) { - case attr_message: - msg = navit_get_messages(this_); - - if (!msg) { - return 0; - } - - len = 0; - while (msg) { - len += strlen(msg->text) + 1; - msg = msg->next; - } - attr->u.str = g_malloc(len + 1); - - msg = navit_get_messages(this_); - offset = 0; - while (msg) { - g_stpcpy((attr->u.str + offset), msg->text); - offset += strlen(msg->text); - attr->u.str[offset] = '\n'; - offset++; - - msg = msg->next; - } - - 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; - case attr_bookmarks: - attr->u.bookmarks=this_->bookmarks; - break; - case attr_callback_list: - attr->u.callback_list=this_->attr_cbl; - break; - case attr_center: - c=transform_get_center(this_->trans); - transform_to_geo(transform_get_projection(this_->trans), c, &this_->center); - attr->u.coord_geo=&this_->center; - break; - case attr_destination: - if (! this_->destination_valid) - return 0; - attr->u.pcoord=&this_->destination; - break; - 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; - case attr_graphics: - attr->u.graphics=this_->gra; - ret=(attr->u.graphics != NULL); - break; - case attr_gui: - attr->u.gui=this_->gui; - ret=(attr->u.gui != NULL); - break; - case attr_layer: - ret=attr_generic_get_attr(this_->attrs, NULL, type, attr, iter?(struct attr_iter *)&iter->iter:NULL); - break; - case attr_layout: - if (iter) { - if (iter->u.list) { - iter->u.list=g_list_next(iter->u.list); - } else { - iter->u.list=this_->layouts; - } - if (!iter->u.list) - return 0; - attr->u.layout=(struct layout *)iter->u.list->data; - } else { - attr->u.layout=this_->layout_current; - } - break; - case attr_map: - if (iter && this_->mapsets) { - if (!iter->u.mapset_handle) { - iter->u.mapset_handle=mapset_open((struct mapset *)this_->mapsets->data); - } - attr->u.map=mapset_next(iter->u.mapset_handle, 0); - if(!attr->u.map) { - mapset_close(iter->u.mapset_handle); - return 0; - } - } else { - return 0; - } - break; - case attr_mapset: - attr->u.mapset=this_->mapsets->data; - 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_->attrs, NULL, type, attr, iter?(struct attr_iter *)&iter->iter:NULL); - break; - case attr_osd_configuration: - attr->u.num=this_->osd_configuration; - break; - case attr_pitch: - attr->u.num=round(transform_get_pitch(this_->trans)*sqrt(this_->w*this_->h)/sqrt( - 240*320)); // Pitch corrected for window resolution - break; - case attr_projection: - if(this_->trans) { - attr->u.num=transform_get_projection(this_->trans); - } else { - return 0; - } - break; - case attr_route: - attr->u.route=this_->route; - break; - case attr_speech: - if(this_->speech) { - attr->u.speech=this_->speech; - } else { - return 0; - } - break; - case attr_timeout: - attr->u.num=this_->center_timeout; - 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; - case attr_vehicle: - if(iter) { - if(iter->u.list) { - iter->u.list=g_list_next(iter->u.list); - } else { - iter->u.list=this_->vehicles; - } - if(!iter->u.list) - return 0; - attr->u.vehicle=((struct navit_vehicle*)iter->u.list->data)->vehicle; - } else { - if(this_->vehicle) { - attr->u.vehicle=this_->vehicle->vehicle; - } else { - return 0; - } - } - break; - case attr_vehicleprofile: - if (iter) { - if(iter->u.list) { - iter->u.list=g_list_next(iter->u.list); - } else { - iter->u.list=this_->vehicleprofiles; - } - if(!iter->u.list) - return 0; - attr->u.vehicleprofile=iter->u.list->data; - } else { - attr->u.vehicleprofile=this_->vehicleprofile; - } - break; - case attr_zoom: - attr->u.num=transform_get_scale(this_->trans); - break; - case attr_autozoom_active: - attr->u.num=this_->autozoom_active; - break; - case attr_follow_cursor: - attr->u.num=this_->follow_cursor; - break; - case attr_waypoints_flag: - attr->u.num=this_->waypoints_flag; - break; - default: - dbg(lvl_debug, "calling generic getter method for attribute type %s", attr_to_name(type)) - return navit_object_get_attr((struct navit_object *) this_, type, attr, iter); - } - attr->type=type; - return ret; -} - -/** - * @brief Select the default layout by name - * - * @param this_ The navit instance - * @param name The new default layout's name - * - * @return The first layout match (if any), or NULL if there was no match - */ -struct layout *navit_get_layout_by_name(struct navit *this_, const char *layout_name) { - struct attr_iter *iter; - struct attr layout_attr; - struct layout *result = NULL; - - if (!layout_name) - return NULL; - iter=navit_attr_iter_new(NULL); - while (navit_get_attr(this_, attr_layout, &layout_attr, iter)) { - if (strcmp(layout_attr.u.layout->name, layout_name) == 0) { - result = layout_attr.u.layout; - } - } - navit_attr_iter_destroy(iter); - return result; -} - -/** - * @brief Set the current layout - * - * @param this_ The navit instance - * @param layout The layout to set as default (if NULL, we will set the current layout according to the default name stored in this_->default_layout_name - * - * @note If argument @p layout is NULL and the default layout name in the config file does not exist or has not been provided in the config file, the default layout is unchanged - */ -void navit_update_current_layout(struct navit *this_, struct layout *layout) { - struct layout *default_layout = NULL; - - if (layout) { - this_->layout_current=layout; - } else { - if (this_->default_layout_name) { /* If a default layout name was provided */ - default_layout=navit_get_layout_by_name(this_, this_->default_layout_name); - if (default_layout) { - dbg(lvl_debug, "Found the config-specified default layout '%s'", this_->default_layout_name); - this_->layout_current=default_layout; - return; - } else { - dbg(lvl_warning, "No definition exists in config for specified default layout '%s'", this_->default_layout_name); - } - } - } -} - -static int navit_add_log(struct navit *this_, struct log *log) { - struct attr type_attr; - if (!log_get_attr(log, attr_type, &type_attr, NULL)) - return 0; - if (!strcmp(type_attr.u.str, "textfile_debug")) { - char *header = "type=track_tracked\n"; - if (this_->textfile_debug_log) - return 0; - log_set_header(log, header, strlen(header)); - this_->textfile_debug_log=log; - return 1; - } - return 0; -} - -static int navit_add_layout(struct navit *this_, struct layout *layout) { - struct attr active; - int is_default=0; - int is_active=0; - this_->layouts = g_list_append(this_->layouts, layout); - /** check if we want to immediately activate this layout. - * Unfortunately we have concurring conditions about when to activate - * a layout: - * - A layout could bear the "active" property - * - A layout's name could match this_->default_layout_name - * This cannot be fully resolved, as we cannot predict the future, so - * lets set the last parsed layout active, which either matches default_layout_name or - * bears the "active" tag, or is the first layout ever parsed. - */ - if((layout->name != NULL) && (this_->default_layout_name != NULL)) { - if (strcmp(layout->name, this_->default_layout_name) == 0) - is_default = 1; - } - layout_get_attr(layout, attr_active, &active, NULL); - if(active.u.num) - is_active = 1; - dbg(lvl_debug, "add layout '%s' is_default %d, is_active %d", layout->name, is_default, is_active); - if(is_default || is_active || !this_->layout_current) { - this_->layout_current=layout; - return 1; - } - return 0; -} - -int navit_add_attr(struct navit *this_, struct attr *attr) { - int ret=1; - switch (attr->type) { - case attr_callback: - navit_add_callback(this_, attr->u.callback); - break; - case attr_log: - ret=navit_add_log(this_, attr->u.log); - break; - case attr_gui: - ret=navit_set_gui(this_, attr->u.gui); - break; - case attr_graphics: - ret=navit_set_graphics(this_, attr->u.graphics); - break; - case attr_layout: - navit_add_layout(this_, attr->u.layout); - break; - case attr_route: - this_->route=attr->u.route; - break; - case attr_mapset: - this_->mapsets = g_list_append(this_->mapsets, attr->u.mapset); - break; - case attr_navigation: - this_->navigation=attr->u.navigation; - break; - case attr_osd: - break; - case attr_recent_dest: - this_->recentdest_count = attr->u.num; - break; - case attr_speech: - this_->speech=attr->u.speech; - break; - case attr_trackingo: - this_->tracking=attr->u.tracking; - break; - case attr_vehicle: - ret=navit_add_vehicle(this_, attr->u.vehicle); - break; - case attr_vehicleprofile: - this_->vehicleprofiles=g_list_append(this_->vehicleprofiles, attr->u.vehicleprofile); - break; - case attr_autozoom_min: - this_->autozoom_min = attr->u.num; - break; - case attr_autozoom_max: - this_->autozoom_max = attr->u.num; - break; - case attr_layer: - case attr_script: - case attr_traffic: - break; - default: - return 0; - } - if (ret) - this_->attrs=attr_generic_add_attr(this_->attrs, attr); - callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr); - return ret; -} - -int navit_remove_attr(struct navit *this_, struct attr *attr) { - int ret=1; - switch (attr->type) { - case attr_callback: - navit_remove_callback(this_, attr->u.callback); - break; - case attr_vehicle: - case attr_osd: - this_->attrs=attr_generic_remove_attr(this_->attrs, attr); - return 1; - default: - return 0; - } - return ret; -} - -struct attr_iter * -navit_attr_iter_new(void * unused) { - return g_new0(struct attr_iter, 1); -} - -void navit_attr_iter_destroy(struct attr_iter *iter) { - g_free(iter); -} - -void navit_add_callback(struct navit *this_, struct callback *cb) { - callback_list_add(this_->attr_cbl, cb); -} - -void navit_remove_callback(struct navit *this_, struct callback *cb) { - callback_list_remove(this_->attr_cbl, cb); -} - -static int coord_not_set(struct coord c) { - return !(c.x || c.y); -} - -/** - * Toggle the cursor update : refresh the map each time the cursor has moved (instead of only when it reaches a border) - * - * @param this_ The navit instance - * @param nv vehicle to draw - * @param pnt Screen coordinates of the vehicle. If NULL, position stored in nv is used. - * @returns nothing - */ - -static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt) { - struct point cursor_pnt; - enum projection pro; - - if (this_->blocked||coord_not_set(nv->coord)) - return; - if (pnt) - cursor_pnt=*pnt; - else { - 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, nv->dir-transform_get_yaw(this_->trans_cursor), nv->speed); -} - -/** - * @brief Called when the position of a vehicle changes. - * - * This function is called when the position of any configured vehicle changes and triggers all actions - * that need to happen in response, such as: - * <ul> - * <li>Switching between day and night layout (based on the new position timestamp)</li> - * <li>Updating position, bearing and speed of {@code nv} with the data of the active vehicle - * (which may be different from the vehicle reporting the update)</li> - * <li>Invoking callbacks for {@code navit}'s {@code attr_position} and {@code attr_position_coord_geo} - * attributes</li> - * <li>Triggering an update of the vehicle's position on the map and, if needed, an update of the - * visible map area ad orientation</li> - * <li>Logging a new track point, if enabled</li> - * <li>Updating the position on the route</li> - * <li>Stopping navigation if the destination has been reached</li> - * </ul> - * - * @param this_ The navit object - * @param nv The {@code navit_vehicle} which reported a new position - */ -static void navit_vehicle_update_position(struct navit *this_, struct navit_vehicle *nv) { - struct attr attr_valid, attr_dir, attr_speed, attr_pos; - struct pcoord cursor_pc; - struct point cursor_pnt, *pnt=&cursor_pnt; - struct tracking *tracking=NULL; - struct pcoord *pc; - 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; - char *description; - - profile(0,NULL); - if (this_->ready == 3) - navit_layout_switch(this_); - if (this_->vehicle == nv && this_->tracking_flag) - tracking=this_->tracking; - if (tracking) { - tracking_update(tracking, nv->vehicle, this_->vehicleprofile, pro); - attr_object=tracking; - get_attr=(int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))tracking_get_attr; - } else { - attr_object=nv->vehicle; - get_attr=(int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))vehicle_get_attr; - } - if (get_attr(attr_object, attr_position_valid, &attr_valid, NULL)) - if (!attr_valid.u.num != attr_position_valid_invalid) - return; - if (! get_attr(attr_object, attr_position_direction, &attr_dir, NULL) || - ! get_attr(attr_object, attr_position_speed, &attr_speed, NULL) || - ! get_attr(attr_object, attr_position_coord_geo, &attr_pos, NULL)) { - profile(0,"return 2\n"); - return; - } - nv->dir=*attr_dir.u.numd; - nv->speed=*attr_speed.u.numd; - transform_from_geo(pro, attr_pos.u.coord_geo, &nv->coord); - if (nv != this_->vehicle) { - if (this_->ready == 3) - navit_vehicle_draw(this_, nv, NULL); - profile(0,"return 3\n"); - return; - } - cursor_pc.x = nv->coord.x; - cursor_pc.y = nv->coord.y; - cursor_pc.pro = pro; - if (this_->route) { - if (tracking) - route_set_position_from_tracking(this_->route, tracking, pro); - else - route_set_position(this_->route, &cursor_pc); - } - callback_list_call_attr_0(this_->attr_cbl, attr_position); - navit_textfile_debug_log(this_, "type=trackpoint_tracked"); - if (this_->ready == 3) { - if (this_->gui && nv->speed > 2) - navit_disable_suspend(); - - 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, &cursor_pnt, this_->border))) - navit_set_center_cursor_draw(this_); - else - navit_vehicle_draw(this_, nv, pnt); - - if (nv->follow_curr > 1) - nv->follow_curr--; - else - nv->follow_curr=nv->follow; - } - 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) { - switch(route_destination_reached(this_->route)) { - case 1: - description=route_get_destination_description(this_->route, 0); - route_remove_waypoint(this_->route); - count=route_get_destination_count(this_->route); - pc=g_alloca(sizeof(*pc)*count); - route_get_destinations(this_->route, pc, count); - destination_file = bookmarks_get_destination_file(TRUE); - bookmarks_append_destinations(this_->former_destination, destination_file, pc, count, type_former_itinerary_part, - description, this_->recentdest_count); - g_free(destination_file); - g_free(description); - break; - case 2: - destination_file = bookmarks_get_destination_file(TRUE); - bookmarks_append_destinations(this_->former_destination, destination_file, NULL, 0, type_former_itinerary_part, NULL, - this_->recentdest_count); - navit_set_destination(this_, NULL, NULL, 0); - g_free(destination_file); - break; - } - } - profile(0,"return 5\n"); -} - -/** - * @brief Called when a status attribute of a vehicle changes. - * - * This function is called when the {@code position_fix_type}, {@code position_sats_used} or {@code position_hdop} - * attribute of any configured vehicle changes. - * - * The function checks if {@code nv} refers to the active vehicle and if {@code type} is one of the above types. - * If this is the case, it invokes the callback functions for {@code navit}'s respective attributes. - * - * Future actions that need to happen when one of these three attribute changes for any vehicle should be - * implemented here. - * - * @param this_ The navit object - * @param nv The {@code navit_vehicle} which reported a new status attribute - * @param type The type of attribute with has changed - */ -static void navit_vehicle_update_status(struct navit *this_, struct navit_vehicle *nv, enum attr_type type) { - if (this_->vehicle != nv) - return; - switch(type) { - case attr_position_fix_type: - case attr_position_sats_used: - case attr_position_hdop: - callback_list_call_attr_2(this_->attr_cbl, type, this_, nv->vehicle); - break; - default: - return; - } -} - -/** - * Set the position of the vehicle - * - * @param navit The navit instance - * @param c The coordinate to set as position - * @returns nothing - */ - -void navit_set_position(struct navit *this_, struct pcoord *c) { - if (this_->route) { - route_set_position(this_->route, c); - callback_list_call_attr_0(this_->attr_cbl, attr_position); - } - if (this_->ready == 3) - navit_draw(this_); -} - -static int navit_set_vehicleprofile(struct navit *this_, struct vehicleprofile *vp) { - if (this_->vehicleprofile == vp) - return 0; - this_->vehicleprofile=vp; - if (this_->route) - route_set_profile(this_->route, this_->vehicleprofile); - return 1; -} - -int navit_set_vehicleprofile_name(struct navit *this_, char *name) { - struct attr attr; - GList *l; - l=this_->vehicleprofiles; - while (l) { - if (vehicleprofile_get_attr(l->data, attr_name, &attr, NULL)) { - if (!strcmp(attr.u.str, name)) { - navit_set_vehicleprofile(this_, l->data); - return 1; - } - } - l=g_list_next(l); - } - return 0; -} - -static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv) { - struct attr attr; - this_->vehicle=nv; - if (nv && vehicle_get_attr(nv->vehicle, attr_profilename, &attr, NULL)) { - if (navit_set_vehicleprofile_name(this_, attr.u.str)) - return; - } - if (!this_->vehicleprofile) { // When deactivating vehicle, keep the last profile if any - if (!navit_set_vehicleprofile_name(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); - } - } - } else { - if (this_->route) - route_set_profile(this_->route, this_->vehicleprofile); - } -} - -/** - * @brief Registers a new vehicle. - * - * @param this_ The navit instance - * @param v The vehicle to register - * @return True for success - */ -static int navit_add_vehicle(struct navit *this_, struct vehicle *v) { - struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1); - struct attr follow, active, animate; - nv->vehicle=v; - nv->follow=0; - nv->last.x = 0; - nv->last.y = 0; - nv->animate_cursor=0; - if ((vehicle_get_attr(v, attr_follow, &follow, NULL))) - 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) - navit_set_vehicle(this_, nv); - if ((vehicle_get_attr(v, attr_animate, &animate, NULL))) - nv->animate_cursor=animate.u.num; - nv->callback.type=attr_callback; - nv->callback.u.callback=callback_new_attr_2(callback_cast(navit_vehicle_update_position), attr_position_coord_geo, - this_, nv); - vehicle_add_attr(nv->vehicle, &nv->callback); - nv->callback.u.callback=callback_new_attr_3(callback_cast(navit_vehicle_update_status), attr_position_fix_type, this_, - nv, attr_position_fix_type); - vehicle_add_attr(nv->vehicle, &nv->callback); - nv->callback.u.callback=callback_new_attr_3(callback_cast(navit_vehicle_update_status), attr_position_sats_used, this_, - nv, attr_position_sats_used); - vehicle_add_attr(nv->vehicle, &nv->callback); - nv->callback.u.callback=callback_new_attr_3(callback_cast(navit_vehicle_update_status), attr_position_hdop, this_, nv, - attr_position_hdop); - vehicle_add_attr(nv->vehicle, &nv->callback); - vehicle_set_attr(nv->vehicle, &this_->self); - return 1; -} - - - - -struct gui * -navit_get_gui(struct navit *this_) { - return this_->gui; -} - -struct transformation * -navit_get_trans(struct navit *this_) { - return this_->trans; -} - -struct route * -navit_get_route(struct navit *this_) { - return this_->route; -} - -struct navigation * -navit_get_navigation(struct navit *this_) { - return this_->navigation; -} - -struct displaylist * -navit_get_displaylist(struct navit *this_) { - return this_->displaylist; -} - -/*todo : make it switch to nightlayout when we are in a tunnel */ -void navit_layout_switch(struct navit *n) { - - int currTs=0; - struct attr iso8601_attr,geo_attr,valid_attr,layout_attr; - double trise,tset,trise_actual; - struct layout *l; - int year, month, day; - int after_sunrise = FALSE; - int after_sunset = FALSE; - - 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) { - //Ok, we know that we have profile to switch - - //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(lvl_debug,"currTs: %u:%u",currTs%86400/3600,((currTs%86400)%3600)/60); - } - dbg(lvl_debug,"prevTs: %u:%u",n->prevTs%86400/3600,((n->prevTs%86400)%3600)/60); - - if (n->auto_switch == FALSE) - return; - - if (currTs-(n->prevTs)<60) { - //We've have to wait a little - return; - } - - 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 - } - - int *streetflags = tracking_get_current_flags(n->tracking); - - if (streetflags != NULL) { - - dbg(lvl_debug,"streetflags: %i", *streetflags); - - // We are in a tunnel and we have a nightlayout -> switch to nightlayout - if ((*streetflags & AF_UNDERGROUND) && l->nightname) { - navit_set_layout_by_name(n, l->nightname); - dbg(lvl_debug, "tunnel nightlayout"); - return; - } else if (*streetflags & AF_UNDERGROUND) { - // We are already in nightmode, no matter of the sun - return; - } - - } else { - dbg(lvl_debug,"streetflags are NULL"); - } - - if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo,&geo_attr,NULL)!=1) { - //No position - no sun - return; - } - //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) { - dbg(lvl_debug,"near the pole sun never rises/sets, so we should never switch profiles"); - dbg(lvl_debug,"trise: %u:%u",HOURS(trise),MINUTES(trise)); - dbg(lvl_debug,"tset: %u:%u",HOURS(tset),MINUTES(tset)); - n->prevTs=currTs; - return; - } - trise_actual=trise; - dbg(lvl_debug,"trise: %u:%u",HOURS(trise),MINUTES(trise)); - dbg(lvl_debug,"tset: %u:%u",HOURS(tset),MINUTES(tset)); - dbg(lvl_debug,"dayname = %s, name =%s ",l->dayname, l->name); - dbg(lvl_debug,"nightname = %s, name = %s ",l->nightname, l->name); - if (HOURS(trise)*60+MINUTES(trise)<(currTs%86400)/60) { - after_sunrise = TRUE; - } - - if (((HOURS(tset)*60+MINUTES(tset)<(currTs%86400)/60)) || - ((HOURS(trise_actual)*60+MINUTES(trise_actual)>(currTs%86400)/60))) { - after_sunset = TRUE; - } - if (after_sunrise && !after_sunset && l->dayname) { - navit_set_layout_by_name(n,l->dayname); - dbg(lvl_debug,"layout set to day"); - } else if (after_sunset && l->nightname) { - navit_set_layout_by_name(n,l->nightname); - dbg(lvl_debug,"layout set to night"); - } - n->prevTs=currTs; - } -} - -/** - * @brief this command is used to change the layout and enable/disable the automatic layout switcher - * - * @param this_ The navit instance - * @param function unused - * @param in input attributes in[0], a string, see usage below - * @param out output attribute unused - * - * - * usage : - * manual : disable autoswitcher - * auto : enable autoswitcher - * manual_toggle : disable autoswitcher and toggle between day / night layout - * manual_day : disable autoswitcher and set to day layout - * manual_night : disable autoswitcher and set to night layout - * - * todo : make it return the state of the autoswitcher and - * the version of the active layout (day/night/undefined) - */ -static -int navit_cmd_switch_layout_day_night(struct navit *this_, char *function, struct attr **in, struct attr *** out) { - - if (!(in && in[0] && ATTR_IS_STRING(in[0]->type))) { - return 0; - } - - dbg(lvl_debug," called with mode =%s",in[0]->u.str); - - if (!this_->layout_current) - return 0; - - if (!this_->vehicle) - return 0; - - if (!strcmp(in[0]->u.str,"manual")) { - this_->auto_switch = FALSE; - } else if (!strcmp(in[0]->u.str,"auto")) { - this_->auto_switch = TRUE; - this_->prevTs = 0; - navit_layout_switch(this_); - } else if (!strcmp(in[0]->u.str,"manual_toggle")) { - if (this_->layout_current->dayname) { - navit_set_layout_by_name(this_,this_->layout_current->dayname); - this_->auto_switch = FALSE; - dbg(lvl_debug,"toggeled layout to = %s",this_->layout_current->name); - } else if (this_->layout_current->nightname) { - navit_set_layout_by_name(this_,this_->layout_current->nightname); - this_->auto_switch = FALSE; - dbg(lvl_debug,"toggeled layout to = %s",this_->layout_current->name); - } - } else if (!strcmp(in[0]->u.str,"manual_day") && this_->layout_current->dayname) { - navit_set_layout_by_name(this_,this_->layout_current->dayname); - this_->auto_switch = FALSE; - dbg(lvl_debug,"switched layout to = %s",this_->layout_current->name); - } else if (!strcmp(in[0]->u.str,"manual_night") && this_->layout_current->nightname) { - navit_set_layout_by_name(this_,this_->layout_current->nightname); - this_->auto_switch = FALSE; - dbg(lvl_debug,"switched layout to = %s",this_->layout_current->name); - } - - dbg(lvl_debug,"auto = %i",this_->auto_switch); - return 0; -} - -int 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(NULL); - - 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; - struct attr layout_attr; - - iter.u.list=0x00; - - if (navit_get_attr(n,attr_layout,&layout_attr,&iter)!=1) { - return 0; //No layouts - nothing to do - } - if (iter.u.list==NULL) { - return 0; - } - - iter.u.list=g_list_first(iter.u.list); - - while(iter.u.list) { - l=(struct layout*)iter.u.list->data; - if (!strcmp(name,l->name)) { - layout_attr.u.layout=l; - layout_attr.type=attr_layout; - navit_set_attr(n,&layout_attr); - iter.u.list=g_list_first(iter.u.list); - return 1; - } - iter.u.list=g_list_next(iter.u.list); - } - - iter.u.list=g_list_first(iter.u.list); - return 0; -} - -void navit_disable_suspend() { - gui_disable_suspend(global_navit->gui); - callback_list_call_attr_0(global_navit->attr_cbl,attr_unsuspend); -} - -/** - * @brief Blocks or unblocks redraw operations. - * - * The {@code block} parameter specifies the operation to carry out: - * - * {@code block > 0} cancels all draw operations in progress and blocks future operations. It sets flag 1 of the - * {@code blocked} member. If draw operations in progress were canceled, flag 2 is also set. - * - * {@code block = 0} unblocks redraw operations, resetting {@code blocked} to 0. If flag 2 was previously set, - * indicating that draw operations had been previously canceled, a redraw is triggered. - * - * {@code block < 0} unblocks redraw operations and forces a redraw. As above, {@code blocked} is reset to 0. - * - * @param this_ The navit instance - * @param block The operation to perform, see description - * - * @return {@code true} if a redraw operation was triggered, {@code false} if not - */ -int navit_block(struct navit *this_, int block) { - if (block > 0) { - this_->blocked |= 1; - if (graphics_draw_cancel(this_->gra, this_->displaylist)) - this_->blocked |= 2; - return 0; - } - if ((this_->blocked & 2) || block < 0) { - this_->blocked=0; - navit_draw(this_); - return 1; - } - this_->blocked=0; - return 0; -} - -/** - * @brief Returns whether redraw operations are currently blocked. - */ -int navit_get_blocked(struct navit *this_) { - return this_->blocked; -} - -void navit_destroy(struct navit *this_) { - dbg(lvl_debug,"enter %p",this_); - GList *mapsets; - struct map * map; - struct attr attr; - graphics_draw_cancel(this_->gra, this_->displaylist); - - mapsets = this_->mapsets; - while (mapsets) { - GList *maps = NULL; - struct mapset_handle *msh; - msh = mapset_open(mapsets->data); - while (msh && (map = mapset_next(msh, 0))) { - /* Add traffic map (identified by the `attr_traffic` attribute) to list of maps to remove */ - if (map_get_attr(map, attr_traffic, &attr, NULL)) - maps = g_list_append(maps, map); - } - mapset_close(msh); - - /* Remove traffic maps, if any */ - while (maps) { - attr.type = attr_map; - attr.u.map = maps->data; - mapset_remove_attr(mapsets->data, &attr); - attr_free_content(&attr); - maps = g_list_next(maps); - } - if (maps) - g_list_free(maps); - mapsets = g_list_next(mapsets); - } - - callback_list_call_attr_1(this_->attr_cbl, attr_destroy, this_); - attr_list_free(this_->attrs); - - if(cmd_int_var_hash) { - g_hash_table_destroy(cmd_int_var_hash); - cmd_int_var_hash=NULL; - } - if(cmd_attr_var_hash) { - g_hash_table_destroy(cmd_attr_var_hash); - cmd_attr_var_hash=NULL; - } - if(cmd_int_var_stack) { - g_list_foreach(cmd_int_var_stack, (GFunc)attr_free_g, NULL); - g_list_free(cmd_int_var_stack); - cmd_int_var_stack=NULL; - } - - 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); - graphics_remove_callback(this_->gra, this_->button_callback); - graphics_remove_callback(this_->gra, this_->motion_callback); - graphics_remove_callback(this_->gra, this_->predraw_callback); - } - - callback_destroy(this_->resize_callback); - callback_destroy(this_->motion_callback); - callback_destroy(this_->predraw_callback); - - callback_destroy(this_->route_cb); - if (this_->route) - route_destroy(this_->route); - - map_destroy(this_->former_destination); - - graphics_displaylist_destroy(this_->displaylist); - - graphics_free(this_->gra); - - g_free(this_); -} - -struct object_func navit_func = { - attr_navit, - (object_func_new)navit_new, - (object_func_get_attr)navit_get_attr, - (object_func_iter_new)navit_attr_iter_new, - (object_func_iter_destroy)navit_attr_iter_destroy, - (object_func_set_attr)navit_set_attr, - (object_func_add_attr)navit_add_attr, - (object_func_remove_attr)navit_remove_attr, - (object_func_init)navit_init, - (object_func_destroy)navit_destroy, - (object_func_dup)NULL, - (object_func_ref)navit_object_ref, - (object_func_unref)navit_object_unref, -}; - -/** @} */ |