/[zanavi_public1]/navit/navit/navit.c
ZANavi

Contents of /navit/navit/navit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (hide annotations) (download)
Mon Apr 9 21:27:36 2012 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 103083 byte(s)
lots of new stuff, tranlsations, bug fixes ...
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3     * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * version 2 as published by the Free Software Foundation.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the
16     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     * Boston, MA 02110-1301, USA.
18     */
19    
20     /**
21 zoff99 2 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2009 Navit Team
23     *
24     * This program is free software; you can redistribute it and/or
25     * modify it under the terms of the GNU General Public License
26     * version 2 as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License
34     * along with this program; if not, write to the
35     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36     * Boston, MA 02110-1301, USA.
37     */
38    
39     #define _USE_MATH_DEFINES 1
40     #include "config.h"
41     #ifdef HAVE_UNISTD_H
42     #include <unistd.h>
43     #endif
44     #include <stdio.h>
45     #include <stdlib.h>
46     #include <signal.h>
47     #include <string.h>
48     #include <fcntl.h>
49     #include <glib.h>
50     #include <math.h>
51     #include <time.h>
52     #include "debug.h"
53     #include "navit.h"
54     #include "callback.h"
55     #include "gui.h"
56     #include "item.h"
57     #include "projection.h"
58     #include "map.h"
59     #include "mapset.h"
60     #include "main.h"
61     #include "coord.h"
62     #include "point.h"
63     #include "transform.h"
64     #include "param.h"
65     #include "menu.h"
66     #include "graphics.h"
67     #include "popup.h"
68     #include "data_window.h"
69     #include "route.h"
70     #include "navigation.h"
71     #include "speech.h"
72     #include "track.h"
73     #include "vehicle.h"
74     #include "layout.h"
75     #include "log.h"
76     #include "attr.h"
77     #include "event.h"
78     #include "file.h"
79     #include "profile.h"
80     #include "command.h"
81     #include "navit_nls.h"
82     #include "map.h"
83     #include "util.h"
84     #include "messages.h"
85     #include "vehicleprofile.h"
86     #include "sunriset.h"
87     #include "bookmarks.h"
88 zoff99 27 #include "map.h"
89 zoff99 2 #ifdef HAVE_API_WIN32_BASE
90     #include <windows.h>
91     #include "util.h"
92     #endif
93     #ifdef HAVE_API_WIN32_CE
94     #include "libc.h"
95     #endif
96    
97     /**
98     * @defgroup navit the navit core instance. navit is the object containing nearly everything: A set of maps, one or more vehicle, a graphics object for rendering the map, a gui object for displaying the user interface, a route object, a navigation object and so on. Be warned that it is theoretically possible to have more than one navit object
99     * @{
100     */
101    
102     struct gui *main_loop_gui;
103    
104 zoff99 27 struct attr_iter
105     {
106     union
107     {
108 zoff99 2 GList *list;
109     struct mapset_handle *mapset_handle;
110     } u;
111     };
112    
113     static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv);
114     static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt);
115     static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init);
116     static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir);
117     static void navit_cmd_zoom_to_route(struct navit *this);
118     static void navit_cmd_set_center_cursor(struct navit *this_);
119     static void navit_cmd_announcer_toggle(struct navit *this_);
120     static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv);
121    
122     int allow_gui_internal = 0;
123     int routing_mode = 0;
124     int MYSTERY_SPEED = 2;
125 zoff99 14 int offline_search_filter_duplicates = 0;
126     int offline_search_break_searching = 0;
127 zoff99 27 char *navit_maps_dir;
128     int cancel_drawing_global = 0;
129     int global_speak_streetnames = 1;
130     int allow_large_mapfiles = 1; // allow the use of large (>2GB) mapfiles // -> value unused for now
131     int cache_size_file = 1024 * 1024 * 10; // default value was: 20971520 (~20 MB)
132     int draw_polylines_fast = 0; // default: 0
133     int limit_order_corrected = 4; // remain at this order level for drawing streets etc.
134     int global_search_street_size_factor = 1; // make search radius for streets bigger
135 zoff99 2
136 zoff99 27 void navit_add_mapset(struct navit *this_, struct mapset *ms)
137 zoff99 2 {
138 zoff99 27 ////DBG dbg(0,"EEnter\n");
139 zoff99 2 this_->mapsets = g_list_append(this_->mapsets, ms);
140     }
141    
142     struct mapset *
143     navit_get_mapset(struct navit *this_)
144     {
145 zoff99 27 ////DBG dbg(0,"EEnter\n");
146     if (this_->mapsets)
147     {
148 zoff99 2 return this_->mapsets->data;
149     }
150 zoff99 27 else
151     {
152     //DBG dbg(0,"No mapsets enabled! Is it on purpose? Navit can't draw a map. Please check your navit.xml\n");
153     }
154 zoff99 2 return NULL;
155     }
156    
157     struct tracking *
158     navit_get_tracking(struct navit *this_)
159     {
160 zoff99 27 ////DBG dbg(0,"EEnter\n");
161 zoff99 2 return this_->tracking;
162     }
163    
164     /**
165     * @brief Get the user data directory.
166     * @param[in] create - create the directory if it does not exist
167     *
168     * @return char * to the data directory string.
169     *
170     * returns the directory used to store user data files (center.txt,
171     * destination.txt, bookmark.txt, ...)
172     *
173     */
174     char*
175 zoff99 27 navit_get_user_data_directory(int create)
176     {
177     ////DBG dbg(0,"EEnter\n");
178 zoff99 2 char *dir;
179     dir = getenv("NAVIT_USER_DATADIR");
180 zoff99 27 if (create && !file_exists(dir))
181     {
182     //DBG dbg(0, "creating dir %s\n", dir);
183     if (file_mkdir(dir, 0))
184     {
185     //DBG dbg(0, "failed creating dir %s\n", dir);
186 zoff99 2 return NULL;
187     }
188     }
189     return dir;
190     } /* end: navit_get_user_data_directory(gboolean create) */
191    
192 zoff99 27 void navit_draw_async(struct navit *this_, int async)
193 zoff99 2 {
194 zoff99 27 //DBG dbg(0,"EEnter this_->blocked=%d\n",this_->blocked);
195 zoff99 2 if (this_->blocked)
196     {
197     this_->blocked |= 2;
198 zoff99 27 ////DBG dbg(0,"set this_->blocked=%d\n",this_->blocked);
199 zoff99 2 return;
200     }
201     transform_setup_source_rect(this_->trans);
202 zoff99 27 graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags | 1);
203 zoff99 2 }
204    
205 zoff99 27 void navit_draw(struct navit *this_)
206 zoff99 2 {
207 zoff99 27 ////DBG dbg(0,"EEnter this_->ready=%d\n",this_->ready);
208 zoff99 2 if (this_->ready == 3)
209     {
210 zoff99 27 ////DBG dbg(0,"navit_draw_async_001\n");
211 zoff99 2 navit_draw_async(this_, 0);
212     }
213     }
214    
215 zoff99 27 int navit_get_ready(struct navit *this_)
216 zoff99 2 {
217 zoff99 27 ////DBG dbg(0,"EEnter\n");
218 zoff99 2 return this_->ready;
219     }
220    
221 zoff99 27 void navit_draw_displaylist(struct navit *this_)
222 zoff99 2 {
223 zoff99 27 ////DBG dbg(0,"EEnter\n");
224 zoff99 2 if (this_->ready == 3)
225     {
226 zoff99 27 // //DBG dbg(0,"call graphics_displaylist_draw 2")
227     graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current, this_->graphics_flags | 1);
228 zoff99 2 }
229     }
230    
231 zoff99 27 static void navit_map_progress(struct navit *this_)
232 zoff99 2 {
233 zoff99 27 ////DBG dbg(0,"EEnter\n");
234 zoff99 2 struct map *map;
235     struct mapset *ms;
236     struct mapset_handle *msh;
237     struct attr attr;
238     struct point p;
239     if (this_->ready != 3)
240     return;
241 zoff99 27 p.x = 10;
242     p.y = 32;
243 zoff99 2
244 zoff99 27 ms = this_->mapsets->data;
245     msh = mapset_open(ms);
246     while (msh && (map = mapset_next(msh, 0)))
247     {
248     if (map_get_attr(map, attr_progress, &attr, NULL))
249     {
250     char *str = g_strdup_printf("%s ", attr.u.str);
251 zoff99 2 graphics_draw_mode(this_->gra, draw_mode_begin);
252     graphics_draw_text_std(this_->gra, 16, str, &p);
253     g_free(str);
254 zoff99 27 p.y += 32;
255 zoff99 2 graphics_draw_mode(this_->gra, draw_mode_end);
256     }
257     }
258     mapset_close(msh);
259     }
260    
261 zoff99 27 static void navit_redraw_route(struct navit *this_, struct route *route, struct attr *attr)
262 zoff99 2 {
263 zoff99 27 ////DBG dbg(0,"EEnter\n");
264 zoff99 2 int updated;
265    
266 zoff99 27 if ((this_->route) && (this_->route->route_status_was_updated == 1))
267 zoff99 2 {
268 zoff99 27 this_->route->route_status_was_updated = 0;
269 zoff99 2 // send route_status to java
270     #ifdef HAVE_API_ANDROID
271     android_return_generic_int(1, this_->route->route_status);
272     #endif
273     }
274    
275     if (attr->type != attr_route_status)
276     {
277 zoff99 27 ////DBG dbg(0,"ret 1\n");
278 zoff99 2 return;
279     }
280 zoff99 27 updated = attr->u.num;
281     ////DBG dbg(0,"updated=%d\n", updated);
282 zoff99 2 if (this_->ready != 3)
283     {
284 zoff99 27 ////DBG dbg(0,"ret 2\n");
285 zoff99 2 return;
286     }
287     if (updated != route_status_path_done_new)
288     {
289 zoff99 27 ////DBG dbg(0,"ret 3\n");
290 zoff99 2 return;
291     }
292     if (this_->vehicle)
293     {
294     if (this_->vehicle->follow_curr == 1)
295     {
296 zoff99 27 ////DBG dbg(0,"ret 4\n");
297     ////DBG dbg(0,"disabled -> we want redraw!!\n");
298 zoff99 2 // return;
299     }
300     if (this_->vehicle->follow_curr <= this_->vehicle->follow)
301     {
302 zoff99 27 this_->vehicle->follow_curr = this_->vehicle->follow;
303 zoff99 2 }
304     }
305 zoff99 27 ////DBG dbg(0,"draw s*\n");
306 zoff99 2 navit_draw(this_);
307 zoff99 27 ////DBG dbg(0,"draw e*\n");
308 zoff99 2 }
309    
310 zoff99 27 void navit_handle_resize(struct navit *this_, int w, int h)
311 zoff99 2 {
312 zoff99 27 //DBG dbg(0,"EEnter\n");
313 zoff99 2 struct map_selection sel;
314 zoff99 27 int callback = (this_->ready == 1);
315     ////DBG dbg(0,"pre this_->ready=%d\n",this_->ready);
316 zoff99 2 this_->ready |= 2;
317 zoff99 27 ////DBG dbg(0,"set this_->ready=%d\n",this_->ready);
318 zoff99 2 memset(&sel, 0, sizeof(sel));
319 zoff99 27 this_->w = w;
320     this_->h = h;
321     sel.u.p_rect.rl.x = w;
322     sel.u.p_rect.rl.y = h;
323 zoff99 2 transform_set_screen_selection(this_->trans, &sel);
324     graphics_init(this_->gra);
325     graphics_set_rect(this_->gra, &sel.u.p_rect);
326 zoff99 27 if (callback)
327     {
328     //DBG dbg(0,"callback do\n");
329 zoff99 2 callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_);
330 zoff99 27 }
331 zoff99 2 if (this_->ready == 3)
332     {
333 zoff99 27 //DBG dbg(0,"navit_draw_async_002\n");
334 zoff99 2 navit_draw_async(this_, 1);
335     }
336     }
337    
338 zoff99 27 void navit_resize(void *data, int w, int h)
339 zoff99 2 {
340 zoff99 27 //DBG dbg(0,"EEnter %p\n", data);
341     struct navit *this = data;
342 zoff99 2 if (!this->ignore_graphics_events)
343 zoff99 27 {
344     //DBG dbg(0,"11\n");
345 zoff99 2 navit_handle_resize(this, w, h);
346 zoff99 27 }
347 zoff99 2 }
348    
349 zoff99 27 int navit_get_width(struct navit *this_)
350 zoff99 2 {
351 zoff99 27 ////DBG dbg(0,"EEnter\n");
352 zoff99 2 return this_->w;
353     }
354    
355 zoff99 27 int navit_get_height(struct navit *this_)
356 zoff99 2 {
357 zoff99 27 ////DBG dbg(0,"EEnter\n");
358 zoff99 2 return this_->h;
359     }
360    
361 zoff99 27 static void navit_popup(void *data)
362 zoff99 2 {
363 zoff99 27 ////DBG dbg(0,"EEnter\n");
364     struct navit *this_ = data;
365 zoff99 2 popup(this_, 1, &this_->pressed);
366 zoff99 27 this_->button_timeout = NULL;
367     this_->popped = 1;
368 zoff99 2 }
369    
370 zoff99 27 int navit_ignore_button(struct navit *this_)
371 zoff99 2 {
372 zoff99 27 ////DBG dbg(0,"EEnter\n");
373 zoff99 2 if (this_->ignore_button)
374     return 1;
375 zoff99 27 this_->ignore_button = 1;
376 zoff99 2 return 0;
377     }
378    
379 zoff99 27 void navit_ignore_graphics_events(struct navit *this_, int ignore)
380 zoff99 2 {
381 zoff99 27 ////DBG dbg(0,"EEnter\n");
382     this_->ignore_graphics_events = ignore;
383 zoff99 2 }
384    
385 zoff99 27 static void update_transformation(struct transformation *tr, struct point *old, struct point *new, struct point *rot)
386 zoff99 2 {
387 zoff99 27 ////DBG dbg(0,"EEnter\n");
388     struct coord co, cn;
389     struct coord c, *cp;
390 zoff99 2 int yaw;
391 zoff99 27 double angleo, anglen;
392 zoff99 2
393     if (!transform_reverse(tr, old, &co))
394     return;
395 zoff99 27 if (rot)
396     {
397     angleo = atan2(old->y - rot->y, old->x - rot->x) * 180 / M_PI;
398     anglen = atan2(new->y - rot->y, new->x - rot->x) * 180 / M_PI;
399     yaw = transform_get_yaw(tr) + angleo - anglen;
400 zoff99 2 transform_set_yaw(tr, yaw % 360);
401     }
402     if (!transform_reverse(tr, new, &cn))
403     return;
404 zoff99 27 cp = transform_get_center(tr);
405     c.x = cp->x + co.x - cn.x;
406     c.y = cp->y + co.y - cn.y;
407     // dbg(1, "from 0x%x,0x%x to 0x%x,0x%x\n", cp->x, cp->y, c.x, c.y);
408 zoff99 2 transform_set_center(tr, &c);
409     }
410    
411 zoff99 27 void navit_set_timeout(struct navit *this_)
412 zoff99 2 {
413 zoff99 27 ////DBG dbg(0,"EEnter\n");
414 zoff99 2 struct attr follow;
415 zoff99 27 follow.type = attr_follow;
416     follow.u.num = this_->center_timeout;
417 zoff99 2 navit_set_attr(this_, &follow);
418     }
419    
420 zoff99 27 int navit_handle_button(struct navit *this_, int pressed, int button, struct point *p, struct callback *popup_callback)
421 zoff99 2 {
422 zoff99 27 ////DBG dbg(0,"EEnter\n");
423     int border = 16;
424 zoff99 2
425 zoff99 27 // dbg(1, "enter %d %d (ignore %d)\n", pressed, button, this_->ignore_button);
426 zoff99 2 callback_list_call_attr_4(this_->attr_cbl, attr_button, this_, GINT_TO_POINTER(pressed), GINT_TO_POINTER(button), p);
427 zoff99 27 if (this_->ignore_button)
428     {
429     this_->ignore_button = 0;
430 zoff99 2 return 0;
431     }
432 zoff99 27 if (pressed)
433     {
434     this_->pressed = *p;
435     this_->last = *p;
436     this_->zoomed = 0;
437     if (button == 1)
438     {
439     this_->button_pressed = 1;
440     this_->moved = 0;
441     this_->popped = 0;
442 zoff99 2 if (popup_callback)
443 zoff99 27 this_->button_timeout = event_add_timeout(500, 0, popup_callback);
444 zoff99 2 }
445     if (button == 2)
446     navit_set_center_screen(this_, p, 1);
447     if (button == 3)
448     popup(this_, button, p);
449 zoff99 27 if (button == 4 && this_->use_mousewheel)
450     {
451 zoff99 2 this_->zoomed = 1;
452     navit_zoom_in(this_, 2, p);
453     }
454 zoff99 27 if (button == 5 && this_->use_mousewheel)
455     {
456 zoff99 2 this_->zoomed = 1;
457     navit_zoom_out(this_, 2, p);
458     }
459 zoff99 27 }
460     else
461     {
462 zoff99 2
463 zoff99 27 this_->button_pressed = 0;
464     if (this_->button_timeout)
465     {
466 zoff99 2 event_remove_timeout(this_->button_timeout);
467 zoff99 27 this_->button_timeout = NULL;
468     if (!this_->moved && !transform_within_border(this_->trans, p, border))
469     {
470 zoff99 2 navit_set_center_screen(this_, p, !this_->zoomed);
471     }
472     }
473 zoff99 27 if (this_->motion_timeout)
474     {
475 zoff99 2 event_remove_timeout(this_->motion_timeout);
476 zoff99 27 this_->motion_timeout = NULL;
477 zoff99 2 }
478 zoff99 27 if (this_->moved)
479     {
480 zoff99 2 struct point pr;
481 zoff99 27 pr.x = this_->w / 2;
482     pr.y = this_->h;
483 zoff99 2 #if 0
484     update_transformation(this_->trans, &this_->pressed, p, &pr);
485     #else
486     update_transformation(this_->trans, &this_->pressed, p, NULL);
487     #endif
488     graphics_draw_drag(this_->gra, NULL);
489     transform_copy(this_->trans, this_->trans_cursor);
490     graphics_overlay_disable(this_->gra, 0);
491 zoff99 27 if (!this_->zoomed)
492 zoff99 2 navit_set_timeout(this_);
493     navit_draw(this_);
494 zoff99 27 }
495     else
496 zoff99 2 return 1;
497     }
498     return 0;
499     }
500    
501 zoff99 27 static void navit_button(void *data, int pressed, int button, struct point *p)
502 zoff99 2 {
503 zoff99 27 ////DBG dbg(0,"EEnter\n");
504     struct navit *this = data;
505     // dbg(1, "enter %d %d ignore %d\n", pressed, button, this->ignore_graphics_events);
506     if (!this->ignore_graphics_events)
507     {
508     if (!this->popup_callback)
509     this->popup_callback = callback_new_1(callback_cast(navit_popup), this);
510 zoff99 2 navit_handle_button(this, pressed, button, p, this->popup_callback);
511     }
512     }
513    
514 zoff99 27 static void navit_motion_timeout(struct navit *this_)
515 zoff99 2 {
516 zoff99 27 ////DBG dbg(0,"EEnter\n");
517 zoff99 2 int dx, dy;
518    
519 zoff99 27 if (this_->drag_bitmap)
520     {
521 zoff99 2 struct point point;
522 zoff99 27 point.x = (this_->current.x - this_->pressed.x);
523     point.y = (this_->current.y - this_->pressed.y);
524     if (graphics_draw_drag(this_->gra, &point))
525     {
526 zoff99 2 graphics_overlay_disable(this_->gra, 1);
527     graphics_draw_mode(this_->gra, draw_mode_end);
528 zoff99 27 this_->moved = 1;
529     this_->motion_timeout = NULL;
530 zoff99 2 return;
531     }
532 zoff99 27 }
533     dx = (this_->current.x - this_->last.x);
534     dy = (this_->current.y - this_->last.y);
535     if (dx || dy)
536     {
537 zoff99 2 struct transformation *tr;
538     struct point pr;
539 zoff99 27 this_->last = this_->current;
540 zoff99 2 graphics_overlay_disable(this_->gra, 1);
541 zoff99 27 tr = transform_dup(this_->trans);
542     pr.x = this_->w / 2;
543     pr.y = this_->h;
544 zoff99 2 #if 0
545     update_transformation(tr, &this_->pressed, &this_->current, &pr);
546     #else
547     update_transformation(tr, &this_->pressed, &this_->current, NULL);
548     #endif
549     #if 0
550     graphics_displaylist_move(this_->displaylist, dx, dy);
551     #endif
552     graphics_draw_cancel(this_->gra, this_->displaylist);
553 zoff99 27 // //DBG dbg(0,"call graphics_displaylist_draw 1")
554 zoff99 2 graphics_displaylist_draw(this_->gra, this_->displaylist, tr, this_->layout_current, this_->graphics_flags);
555     transform_destroy(tr);
556 zoff99 27 this_->moved = 1;
557 zoff99 2 }
558 zoff99 27 this_->motion_timeout = NULL;
559 zoff99 2 return;
560     }
561    
562 zoff99 27 void navit_handle_motion(struct navit *this_, struct point *p)
563 zoff99 2 {
564 zoff99 27 ////DBG dbg(0,"EEnter\n");
565 zoff99 2 int dx, dy;
566    
567 zoff99 27 if (this_->button_pressed && !this_->popped)
568     {
569     dx = (p->x - this_->pressed.x);
570     dy = (p->y - this_->pressed.y);
571     if (dx < -8 || dx > 8 || dy < -8 || dy > 8)
572     {
573     this_->moved = 1;
574     if (this_->button_timeout)
575     {
576 zoff99 2 event_remove_timeout(this_->button_timeout);
577 zoff99 27 this_->button_timeout = NULL;
578 zoff99 2 }
579 zoff99 27 this_->current = *p;
580     if (!this_->motion_timeout_callback)
581     this_->motion_timeout_callback = callback_new_1(callback_cast(navit_motion_timeout), this_);
582     if (!this_->motion_timeout)
583     this_->motion_timeout = event_add_timeout(100, 0, this_->motion_timeout_callback);
584 zoff99 2 }
585     }
586     }
587    
588 zoff99 27 static void navit_motion(void *data, struct point *p)
589 zoff99 2 {
590 zoff99 27 ////DBG dbg(0,"EEnter\n");
591     struct navit *this = data;
592     if (!this->ignore_graphics_events)
593 zoff99 2 navit_handle_motion(this, p);
594     }
595    
596 zoff99 27 static void navit_predraw(struct navit *this_)
597 zoff99 2 {
598 zoff99 27 ////DBG dbg(0,"EEnter\n");
599 zoff99 2 GList *l;
600     struct navit_vehicle *nv;
601     transform_copy(this_->trans, this_->trans_cursor);
602 zoff99 27 l = this_->vehicles;
603 zoff99 2 while (l)
604     {
605 zoff99 27 nv = l->data;
606     ////DBG dbg(0,"* here *\n");
607     ////DBG dbg(0,"vehicle_draw_004\n");
608 zoff99 2 navit_vehicle_draw(this_, nv, NULL);
609 zoff99 27 l = g_list_next(l);
610 zoff99 2 }
611     }
612    
613 zoff99 27 static void navit_scale(struct navit *this_, long scale, struct point *p, int draw)
614 zoff99 2 {
615 zoff99 27 //DBG dbg(0,"EEnter\n");
616 zoff99 2 struct coord c1, c2, *center;
617    
618     if (scale < this_->zoom_min)
619     {
620 zoff99 27 scale = this_->zoom_min;
621 zoff99 2 }
622    
623     if (scale > this_->zoom_max)
624     {
625 zoff99 27 scale = this_->zoom_max;
626 zoff99 2 }
627    
628     // return scale value to android
629     #ifdef HAVE_API_ANDROID
630     android_return_generic_int(3, (int)scale);
631     #endif
632    
633     if (p)
634     {
635     transform_reverse(this_->trans, p, &c1);
636     }
637    
638     transform_set_scale(this_->trans, scale);
639    
640     if (p)
641     {
642     transform_reverse(this_->trans, p, &c2);
643     center = transform_center(this_->trans);
644     center->x += c1.x - c2.x;
645     center->y += c1.y - c2.y;
646     }
647    
648 zoff99 27 //DBG dbg(0,"aa331\n");
649    
650 zoff99 2 if (draw)
651     {
652     navit_draw(this_);
653     }
654 zoff99 27
655     //DBG dbg(0,"leave\n");
656 zoff99 2 }
657    
658     /**
659     * @brief Automatically adjusts zoom level
660     *
661     * This function automatically adjusts the current
662     * zoom level according to the current speed.
663     *
664     * @param this_ The navit struct
665     * @param center The "immovable" point - i.e. the vehicles position if we're centering on the vehicle
666     * @param speed The vehicles speed in meters per second
667     * @param dir The direction into which the vehicle moves
668     */
669 zoff99 27 static void navit_autozoom(struct navit *this_, struct coord *center, int speed, int draw)
670 zoff99 2 {
671     struct point pc;
672 zoff99 27 int distance, w, h;
673 zoff99 2 double new_scale;
674     long scale;
675    
676 zoff99 27 if (!this_->autozoom_active)
677     {
678 zoff99 2 return;
679     }
680    
681     distance = speed * this_->autozoom_secs;
682    
683     transform_get_size(this_->trans, &w, &h);
684     transform(this_->trans, transform_get_projection(this_->trans), center, &pc, 1, 0, 0, NULL);
685     scale = transform_get_scale(this_->trans);
686    
687     /* We make sure that the point we want to see is within a certain range
688     * around the vehicle. The radius of this circle is the size of the
689     * screen. This doesn't necessarily mean the point is visible because of
690     * perspective etc. Quite rough, but should be enough. */
691 zoff99 27
692     if (w > h)
693     {
694     new_scale = (double) distance / h * 16;
695 zoff99 2 }
696 zoff99 27 else
697     {
698     new_scale = (double) distance / w * 16;
699     }
700 zoff99 2
701 zoff99 27 if (abs(new_scale - scale) < 2)
702     {
703 zoff99 2 return; // Smoothing
704     }
705 zoff99 27
706     if (new_scale >= this_->autozoom_min)
707     {
708     navit_scale(this_, (long) new_scale, &pc, 0);
709     }
710     else
711     {
712     if (scale != this_->autozoom_min)
713     {
714 zoff99 2 navit_scale(this_, this_->autozoom_min, &pc, 0);
715     }
716     }
717     }
718    
719     /**
720     * Change the current zoom level, zooming closer to the ground
721     *
722     * @param navit The navit instance
723     * @param factor The zoom factor, usually 2
724     * @param p The invariant point (if set to NULL, default to center)
725     * @returns nothing
726     */
727 zoff99 27 void navit_zoom_in(struct navit *this_, int factor, struct point *p)
728 zoff99 2 {
729 zoff99 27 ////DBG dbg(0,"EEnter\n");
730     long scale = transform_get_scale(this_->trans) / factor;
731 zoff99 2 if (scale < 1)
732 zoff99 27 scale = 1;
733     ////DBG dbg(0,"zoom in -> scale=%d",scale);
734 zoff99 2 navit_scale(this_, scale, p, 1);
735     }
736    
737     /**
738     * Change the current zoom level
739     *
740     * @param navit The navit instance
741     * @param factor The zoom factor, usually 2
742     * @param p The invariant point (if set to NULL, default to center)
743     * @returns nothing
744     */
745 zoff99 27 void navit_zoom_out(struct navit *this_, int factor, struct point *p)
746 zoff99 2 {
747 zoff99 27 ////DBG dbg(0,"EEnter\n");
748     long scale = transform_get_scale(this_->trans) * factor;
749     ////DBG dbg(0,"zoom out -> scale=%d",scale);
750 zoff99 2 navit_scale(this_, scale, p, 1);
751     }
752    
753 zoff99 27 int navit_get_cur_pnt(struct navit *this_, struct point *p)
754 zoff99 2 {
755 zoff99 27 ////DBG dbg(0,"EEnter\n");
756 zoff99 2 return navit_get_cursor_pnt(this_, p, 0, NULL);
757     }
758    
759 zoff99 27 void navit_zoom_in_cursor(struct navit *this_, int factor)
760 zoff99 2 {
761 zoff99 27 ////DBG dbg(0,"EEnter\n");
762 zoff99 2 struct point p;
763 zoff99 27 if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL))
764     {
765 zoff99 2 navit_zoom_in(this_, factor, &p);
766 zoff99 27 this_->vehicle->follow_curr = this_->vehicle->follow;
767     }
768     else
769 zoff99 2 navit_zoom_in(this_, factor, NULL);
770     }
771    
772 zoff99 27 void navit_zoom_to_scale(struct navit *this_, int new_scale)
773 zoff99 2 {
774 zoff99 27 //DBG dbg(0,"EEnter\n");
775     long scale = transform_get_scale(this_->trans);
776     long new_scale_long = new_scale;
777     //DBG dbg(0,"zoom to scale -> old scale=%d",scale);
778     //DBG dbg(0,"zoom to scale -> want scale=%d",new_scale_long);
779 zoff99 2
780     // only do something if scale changed!
781     if (scale != new_scale_long)
782     {
783     navit_scale(this_, new_scale_long, NULL, 1);
784     }
785     }
786    
787 zoff99 27 void navit_zoom_out_cursor(struct navit *this_, int factor)
788 zoff99 2 {
789 zoff99 27 ////DBG dbg(0,"EEnter\n");
790 zoff99 2 struct point p;
791 zoff99 27 if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL))
792     {
793 zoff99 2 navit_zoom_out(this_, 2, &p);
794 zoff99 27 this_->vehicle->follow_curr = this_->vehicle->follow;
795     }
796     else
797 zoff99 2 navit_zoom_out(this_, 2, NULL);
798     }
799    
800 zoff99 27 static int navit_cmd_zoom_in(struct navit *this_)
801 zoff99 2 {
802 zoff99 27 ////DBG dbg(0,"EEnter\n");
803 zoff99 2 navit_zoom_in_cursor(this_, 2);
804     return 0;
805     }
806    
807 zoff99 27 static int navit_cmd_zoom_out(struct navit *this_)
808 zoff99 2 {
809 zoff99 27 ////DBG dbg(0,"EEnter\n");
810 zoff99 2 navit_zoom_out_cursor(this_, 2);
811     return 0;
812     }
813    
814 zoff99 27 static void navit_cmd_say(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
815 zoff99 2 {
816 zoff99 27 ////DBG dbg(0,"EEnter\n");
817     if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
818     {
819 zoff99 2 navit_say(this, in[0]->u.str);
820 zoff99 27 }
821 zoff99 2 }
822    
823     static GHashTable *cmd_int_var_hash = NULL;
824     static GHashTable *cmd_attr_var_hash = NULL;
825    
826     /**
827     * Store key value pair for the command system (for int typed values)
828     *
829     * @param navit The navit instance
830     * @param function unused (needed to match command function signiture)
831     * @param in input attributes in[0] is the key string, in[1] is the integer value to store
832     * @param out output attributes, unused
833     * @param valid unused
834     * @returns nothing
835     */
836 zoff99 27 static void navit_cmd_set_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
837 zoff99 2 {
838 zoff99 27 ////DBG dbg(0,"EEnter\n");
839 zoff99 2 char*key;
840     struct attr*val;
841 zoff99 27 if (!cmd_int_var_hash)
842     {
843 zoff99 2 cmd_int_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
844     }
845    
846 zoff99 27 if ((in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && (in && in[1] && ATTR_IS_NUMERIC(in[1]->type)))
847     {
848 zoff99 2 val = g_new(struct attr,1);
849 zoff99 27 attr_dup_content(in[1], val);
850 zoff99 2 key = g_strdup(in[0]->u.str);
851     g_hash_table_insert(cmd_int_var_hash, key, val);
852 zoff99 27 }
853 zoff99 2 }
854    
855     /**
856     * Store key value pair for the command system (for attr typed values, can be used as opaque handles)
857     *
858     * @param navit The navit instance
859     * @param function unused (needed to match command function signiture)
860     * @param in input attributes in[0] is the key string, in[1] is the attr* value to store
861     * @param out output attributes, unused
862     * @param valid unused
863     * @returns nothing
864     */
865     //TODO free stored attributes on navit_destroy
866 zoff99 27 static void navit_cmd_set_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
867 zoff99 2 {
868 zoff99 27 ////DBG dbg(0,"EEnter\n");
869 zoff99 2 char*key;
870     struct attr*val;
871 zoff99 27 if (!cmd_attr_var_hash)
872     {
873 zoff99 2 cmd_attr_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
874     }
875    
876 zoff99 27 if ((in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && (in && in[1]))
877     {
878 zoff99 2 val = attr_dup(in[1]);
879     //val = in[1];
880     key = g_strdup(in[0]->u.str);
881     g_hash_table_insert(cmd_attr_var_hash, key, val);
882 zoff99 27 }
883 zoff99 2 }
884    
885     /**
886     * command to toggle the active state of a named layer of the current layout
887     *
888     * @param navit The navit instance
889     * @param function unused (needed to match command function signiture)
890     * @param in input attribute in[0] is the name of the layer
891     * @param out output unused
892     * @param valid unused
893     * @returns nothing
894     */
895 zoff99 27 static void navit_cmd_toggle_layer(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
896 zoff99 2 {
897 zoff99 27 ////DBG dbg(0,"EEnter\n");
898     if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
899     {
900     if (this->layout_current && this->layout_current->layers)
901     {
902 zoff99 2 GList* layers = this->layout_current->layers;
903 zoff99 27 while (layers)
904     {
905     struct layer*l = layers->data;
906     if (l && !strcmp(l->name, in[0]->u.str))
907     {
908 zoff99 2 l->active ^= 1;
909     navit_draw(this);
910     return;
911     }
912 zoff99 27 layers = g_list_next(layers);
913 zoff99 2 }
914     }
915 zoff99 27 }
916 zoff99 2 }
917    
918     /**
919     * adds an item with the current coordinate of the vehicle to a named map
920     *
921     * @param navit The navit instance
922     * @param function unused (needed to match command function signiture)
923     * @param in input attribute in[0] is the name of the map
924     * @param out output attribute, 0 on error or the id of the created item on success
925     * @param valid unused
926     * @returns nothing
927     */
928 zoff99 27 static void navit_cmd_map_add_curr_pos(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
929 zoff99 2 {
930 zoff99 27 ////DBG dbg(0,"EEnter\n");
931 zoff99 2 struct attr **list = g_new0(struct attr *,2);
932     struct attr*val = g_new0(struct attr,1);
933     struct mapset* ms;
934     struct map_selection sel;
935     const int selection_range = 10;
936     enum item_type item_type;
937     struct item *it;
938     struct map* curr_map = NULL;
939     struct coord curr_coord;
940     struct map_rect *mr;
941    
942 zoff99 27 val->type = attr_type_item_begin;
943     val->u.item = NULL; //return invalid item on error
944     list[0] = val;
945     list[1] = NULL;
946 zoff99 2 *out = list;
947 zoff99 27 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
948     in[1] && ATTR_IS_STRING(in[1]->type) && in[1]->u.str //item type
949     )
950     {
951 zoff99 2
952 zoff99 27 if (!(ms = navit_get_mapset(this)))
953     {
954 zoff99 2 return;
955     }
956    
957 zoff99 27 if ((item_type = item_from_name(in[1]->u.str)) == type_none)
958     {
959 zoff99 2 return;
960     }
961    
962     curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
963    
964     //no map with the given name found
965 zoff99 27 if (!curr_map)
966     {
967 zoff99 2 return;
968     }
969 zoff99 27
970     if (this->vehicle && this->vehicle->vehicle)
971     {
972 zoff99 2 struct attr pos_attr;
973 zoff99 27 if (vehicle_get_attr(this->vehicle->vehicle, attr_position_coord_geo, &pos_attr, NULL))
974     {
975 zoff99 2 transform_from_geo(projection_mg, pos_attr.u.coord_geo, &curr_coord);
976 zoff99 27 }
977     else
978     {
979 zoff99 2 return;
980     }
981 zoff99 27 }
982     else
983     {
984 zoff99 2 return;
985     }
986    
987 zoff99 27 sel.next = NULL;
988     sel.order = 18;
989     sel.range.min = type_none;
990     sel.range.max = type_tec_common;
991     sel.u.c_rect.lu.x = curr_coord.x - selection_range;
992     sel.u.c_rect.lu.y = curr_coord.y + selection_range;
993     sel.u.c_rect.rl.x = curr_coord.x + selection_range;
994     sel.u.c_rect.rl.y = curr_coord.y - selection_range;
995    
996 zoff99 2 mr = map_rect_new(curr_map, &sel);
997 zoff99 27 if (mr)
998     {
999     it = map_rect_create_item(mr, item_type);
1000     item_coord_set(it, &curr_coord, 1, change_mode_modify);
1001     val->u.item = it;
1002 zoff99 2 }
1003     map_rect_destroy(mr);
1004 zoff99 27 }
1005 zoff99 2 }
1006    
1007     /**
1008     * sets an attribute (name value pair) of a map item specified by map name and item id
1009     *
1010     * @param navit The navit instance
1011     * @param function unused (needed to match command function signiture)
1012     * @param in input attribute in[0] - name of the map ; in[1] - item ; in[2] - attr name ; in[3] - attr value
1013     * @param out output attribute, 0 on error, 1 on success
1014     * @param valid unused
1015     * @returns nothing
1016     */
1017 zoff99 27 static void navit_cmd_map_item_set_attr(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1018 zoff99 2 {
1019 zoff99 27 ////DBG dbg(0,"EEnter\n");
1020     if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
1021     in[1] && ATTR_IS_ITEM(in[1]->type) && //item
1022     in[2] && ATTR_IS_STRING(in[2]->type) && in[2]->u.str && //attr_type str
1023     in[3] && ATTR_IS_STRING(in[3]->type) && in[3]->u.str //attr_value str
1024     )
1025     {
1026 zoff99 2 struct attr attr_to_set;
1027     struct map* curr_map = NULL;
1028     struct mapset *ms;
1029     struct map_selection sel;
1030     const int selection_range = 500;
1031     struct coord curr_coord;
1032     struct item *it;
1033 zoff99 27
1034     if (ATTR_IS_STRING(attr_from_name(in[2]->u.str)))
1035     {
1036 zoff99 2 attr_to_set.u.str = in[3]->u.str;
1037     attr_to_set.type = attr_from_name(in[2]->u.str);
1038     }
1039 zoff99 27 else if (ATTR_IS_INT(attr_from_name(in[2]->u.str)))
1040     {
1041 zoff99 2 attr_to_set.u.num = atoi(in[3]->u.str);
1042     attr_to_set.type = attr_from_name(in[2]->u.str);
1043     }
1044 zoff99 27 else if (ATTR_IS_DOUBLE(attr_from_name(in[2]->u.str)))
1045     {
1046 zoff99 2 double* val = g_new0(double,1);
1047     *val = atof(in[3]->u.str);
1048     attr_to_set.u.numd = val;
1049     attr_to_set.type = attr_from_name(in[2]->u.str);
1050     }
1051    
1052     ms = navit_get_mapset(this);
1053    
1054     curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
1055    
1056 zoff99 27 if (!curr_map)
1057     {
1058 zoff99 2 return;
1059     }
1060 zoff99 27 sel.next = NULL;
1061     sel.order = 18;
1062     sel.range.min = type_none;
1063     sel.range.max = type_tec_common;
1064     sel.u.c_rect.lu.x = curr_coord.x - selection_range;
1065     sel.u.c_rect.lu.y = curr_coord.y + selection_range;
1066     sel.u.c_rect.rl.x = curr_coord.x + selection_range;
1067     sel.u.c_rect.rl.y = curr_coord.y - selection_range;
1068    
1069 zoff99 2 it = in[1]->u.item;
1070 zoff99 27 if (it)
1071     {
1072 zoff99 2 item_attr_set(it, &attr_to_set, change_mode_modify);
1073     }
1074     }
1075     }
1076    
1077     /**
1078     * Get attr variable given a key string for the command system (for opaque usage)
1079     *
1080     * @param navit The navit instance
1081     * @param function unused (needed to match command function signiture)
1082     * @param in input attribute in[0] is the key string
1083     * @param out output attribute, the attr for the given key string if exists or NULL
1084     * @param valid unused
1085     * @returns nothing
1086     */
1087 zoff99 27 static void navit_cmd_get_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1088 zoff99 2 {
1089 zoff99 27 ////DBG dbg(0,"EEnter\n");
1090 zoff99 2 struct attr **list = g_new0(struct attr *,2);
1091 zoff99 27 if (!cmd_int_var_hash)
1092     {
1093 zoff99 2 struct attr*val = g_new0(struct attr,1);
1094 zoff99 27 val->type = attr_type_item_begin;
1095 zoff99 2 val->u.item = NULL;
1096 zoff99 27 list[0] = val;
1097 zoff99 2 }
1098 zoff99 27 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1099     {
1100 zoff99 2 struct attr*ret = g_hash_table_lookup(cmd_attr_var_hash, in[0]->u.str);
1101 zoff99 27 if (ret)
1102     {
1103 zoff99 2 list[0] = attr_dup(ret);
1104     }
1105 zoff99 27 else
1106     {
1107 zoff99 2 struct attr*val = g_new0(struct attr,1);
1108 zoff99 27 val->type = attr_type_int_begin;
1109 zoff99 2 val->u.item = NULL;
1110 zoff99 27 list[0] = val;
1111 zoff99 2 }
1112 zoff99 27 }
1113 zoff99 2 list[1] = NULL;
1114     *out = list;
1115     }
1116    
1117     /**
1118     * Get value given a key string for the command system
1119     *
1120     * @param navit The navit instance
1121     * @param function unused (needed to match command function signiture)
1122     * @param in input attribute in[0] is the key string
1123     * @param out output attribute, the value for the given key string if exists or 0
1124     * @param valid unused
1125     * @returns nothing
1126     */
1127 zoff99 27 static void navit_cmd_get_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1128 zoff99 2 {
1129 zoff99 27 ////DBG dbg(0,"EEnter\n");
1130 zoff99 2 struct attr **list = g_new0(struct attr *,2);
1131 zoff99 27 if (!cmd_int_var_hash)
1132     {
1133 zoff99 2 struct attr*val = g_new0(struct attr,1);
1134 zoff99 27 val->type = attr_type_int_begin;
1135     val->u.num = 0;
1136     list[0] = val;
1137 zoff99 2 }
1138 zoff99 27 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1139     {
1140 zoff99 2 struct attr*ret = g_hash_table_lookup(cmd_int_var_hash, in[0]->u.str);
1141 zoff99 27 if (ret)
1142     {
1143 zoff99 2 list[0] = ret;
1144     }
1145 zoff99 27 else
1146     {
1147 zoff99 2 struct attr*val = g_new0(struct attr,1);
1148 zoff99 27 val->type = attr_type_int_begin;
1149     val->u.num = 0;
1150     list[0] = val;
1151 zoff99 2 }
1152 zoff99 27 }
1153 zoff99 2 list[1] = NULL;
1154     *out = list;
1155     }
1156    
1157     GList *cmd_int_var_stack = NULL;
1158    
1159     /**
1160     * Push an integer to the stack for the command system
1161     *
1162     * @param navit The navit instance
1163     * @param function unused (needed to match command function signiture)
1164     * @param in input attribute in[0] is the integer attibute to push
1165     * @param out output attributes, unused
1166     * @param valid unused
1167     * @returns nothing
1168     */
1169 zoff99 27 static void navit_cmd_push_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1170 zoff99 2 {
1171 zoff99 27 ////DBG dbg(0,"EEnter\n");
1172     if (in && in[0] && ATTR_IS_NUMERIC(in[0]->type))
1173     {
1174 zoff99 2 struct attr*val = g_new(struct attr,1);
1175 zoff99 27 attr_dup_content(in[0], val);
1176 zoff99 2 cmd_int_var_stack = g_list_prepend(cmd_int_var_stack, val);
1177     }
1178     }
1179    
1180     /**
1181     * Pop an integer from the command system's integer stack
1182     *
1183     * @param navit The navit instance
1184     * @param function unused (needed to match command function signiture)
1185     * @param in input attributes unused
1186     * @param out output attribute, the value popped if stack isn't empty or 0
1187     * @param valid unused
1188     * @returns nothing
1189     */
1190 zoff99 27 static void navit_cmd_pop_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1191 zoff99 2 {
1192 zoff99 27 ////DBG dbg(0,"EEnter\n");
1193 zoff99 2 struct attr **list = g_new0(struct attr *,2);
1194 zoff99 27 if (!cmd_int_var_stack)
1195     {
1196 zoff99 2 struct attr*val = g_new0(struct attr,1);
1197     val->type = attr_type_int_begin;
1198 zoff99 27 val->u.num = 0;
1199     list[0] = val;
1200 zoff99 2 }
1201 zoff99 27 else
1202     {
1203 zoff99 2 list[0] = cmd_int_var_stack->data;
1204 zoff99 27 cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack, cmd_int_var_stack);
1205 zoff99 2 }
1206     list[1] = NULL;
1207     *out = list;
1208     }
1209    
1210     /**
1211     * Get current size of command system's integer stack
1212     *
1213     * @param navit The navit instance
1214     * @param function unused (needed to match command function signiture)
1215     * @param in input attributes unused
1216     * @param out output attribute, the size of stack
1217     * @param valid unused
1218     * @returns nothing
1219     */
1220 zoff99 27 static void navit_cmd_int_stack_size(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1221 zoff99 2 {
1222 zoff99 27 ////DBG dbg(0,"EEnter\n");
1223 zoff99 2 struct attr **list;
1224 zoff99 27 struct attr *attr = g_new0(struct attr ,1);
1225     attr->type = attr_type_int_begin;
1226     if (!cmd_int_var_stack)
1227     {
1228     attr->u.num = 0;
1229 zoff99 2 }
1230 zoff99 27 else
1231     {
1232     attr->u.num = g_list_length(cmd_int_var_stack);
1233     }list = g_new0(struct attr *,2);
1234 zoff99 2 list[0] = attr;
1235     list[1] = NULL;
1236     *out = list;
1237 zoff99 27 cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack, cmd_int_var_stack);
1238 zoff99 2 }
1239    
1240 zoff99 27 static void navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1241 zoff99 2 {
1242 zoff99 27 ////DBG dbg(0,"EEnter\n");
1243 zoff99 2 struct pcoord pc;
1244 zoff99 27 char *description = NULL;
1245 zoff99 2 if (!in)
1246     return;
1247     if (!in[0])
1248     return;
1249     pc.pro = transform_get_projection(this->trans);
1250 zoff99 27 if (ATTR_IS_COORD(in[0]->type))
1251     {
1252     pc.x = in[0]->u.coord->x;
1253     pc.y = in[0]->u.coord->y;
1254 zoff99 2 in++;
1255 zoff99 27 }
1256     else if (ATTR_IS_PCOORD(in[0]->type))
1257     {
1258     pc = *in[0]->u.pcoord;
1259 zoff99 2 in++;
1260 zoff99 27 }
1261     else if (in[1] && in[2] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type) && ATTR_IS_INT(in[2]->type))
1262     {
1263     pc.pro = in[0]->u.num;
1264     pc.x = in[1]->u.num;
1265     pc.y = in[2]->u.num;
1266     in += 3;
1267     }
1268     else if (in[1] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type))
1269     {
1270     pc.x = in[0]->u.num;
1271     pc.y = in[1]->u.num;
1272     in += 2;
1273     }
1274     else
1275     {
1276 zoff99 2 return;
1277 zoff99 27 }
1278 zoff99 2 if (in[0] && ATTR_IS_STRING(in[0]->type))
1279 zoff99 27 {
1280     description = in[0]->u.str;
1281     }
1282 zoff99 2 navit_set_destination(this, &pc, description, 1);
1283     }
1284    
1285 zoff99 27 static void navit_cmd_fmt_coordinates(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1286 zoff99 2 {
1287 zoff99 27 ////DBG dbg(0,"EEnter\n");
1288 zoff99 2 struct attr attr;
1289 zoff99 27 attr.type = attr_type_string_begin;
1290     attr.u.str = "Fix me";
1291     if (out)
1292     {
1293     *out = attr_generic_add_attr(*out, &attr);
1294 zoff99 2 }
1295     }
1296    
1297     /**
1298     * Join several string attributes into one
1299     *
1300     * @param navit The navit instance
1301     * @param function unused (needed to match command function signiture)
1302     * @param in input attributes in[0] - separator, in[1..] - attributes to join
1303     * @param out output attribute joined attribute as string
1304     * @param valid unused
1305     * @returns nothing
1306     */
1307 zoff99 27 static void navit_cmd_strjoin(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1308 zoff99 2 {
1309 zoff99 27 ////DBG dbg(0,"EEnter\n");
1310 zoff99 2 struct attr attr;
1311     gchar *ret, *sep;
1312     int i;
1313 zoff99 27 attr.type = attr_type_string_begin;
1314     attr.u.str = NULL;
1315     if (in[0] && in[1])
1316     {
1317     sep = attr_to_text(in[0], NULL, 1);
1318     ret = attr_to_text(in[1], NULL, 1);
1319     for (i = 2; in[i]; i++)
1320     {
1321     gchar *in_i = attr_to_text(in[i], NULL, 1);
1322     gchar *r = g_strjoin(sep, ret, in_i, NULL);
1323 zoff99 2 g_free(in_i);
1324     g_free(ret);
1325 zoff99 27 ret = r;
1326 zoff99 2 }
1327     g_free(sep);
1328 zoff99 27 attr.u.str = ret;
1329     if (out)
1330     {
1331     *out = attr_generic_add_attr(*out, &attr);
1332 zoff99 2 }
1333     g_free(ret);
1334     }
1335     }
1336    
1337     /**
1338     * Call external program
1339     *
1340     * @param navit The navit instance
1341     * @param function unused (needed to match command function signiture)
1342     * @param in input attributes in[0] - name of executable, in[1..] - parameters
1343     * @param out output attribute unused
1344     * @param valid unused
1345     * @returns nothing
1346     */
1347 zoff99 27 static void navit_cmd_spawn(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1348 zoff99 2 {
1349 zoff99 27 ////DBG dbg(0,"EEnter\n");
1350     int i, j, nparms, nvalid;
1351     const char ** argv = NULL;
1352 zoff99 2 struct spawn_process_info *pi;
1353    
1354 zoff99 27 nparms = 0;
1355     nvalid = 0;
1356     if (in)
1357     {
1358     while (in[nparms])
1359     {
1360     if (in[nparms]->type != attr_none)
1361 zoff99 2 nvalid++;
1362     nparms++;
1363     }
1364     }
1365 zoff99 27
1366     if (nvalid > 0)
1367     {
1368 zoff99 2 argv=g_new(char*,nvalid+1);
1369 zoff99 27 for (i = 0, j = 0; in[i]; i++)
1370     {
1371     if (in[i]->type != attr_none)
1372     {
1373     argv[j++] = attr_to_text(in[i], NULL, 1);
1374 zoff99 2 }
1375 zoff99 27 else
1376     {
1377     //DBG dbg(0, "Parameter #%i is attr_none - skipping\n", i);
1378     }
1379 zoff99 2 }
1380 zoff99 27 argv[j] = NULL;
1381     pi = spawn_process(argv);
1382    
1383 zoff99 2 // spawn_process() testing suite - uncomment following code to test.
1384     //sleep(3);
1385     // example of non-blocking wait
1386 zoff99 27 //int st=spawn_process_check_status(pi,0);//DBG dbg(0,"status %i\n",st);
1387 zoff99 2 // example of blocking wait
1388 zoff99 27 //st=spawn_process_check_status(pi,1);//DBG dbg(0,"status %i\n",st);
1389 zoff99 2 // example of wait after process is finished and status is
1390     // already tested
1391 zoff99 27 //st=spawn_process_check_status(pi,1);//DBG dbg(0,"status %i\n",st);
1392 zoff99 2 // example of wait after process is finished and status is
1393     // already tested - unblocked
1394 zoff99 27 //st=spawn_process_check_status(pi,0);//DBG dbg(0,"status %i\n",st);
1395    
1396 zoff99 2 // End testing suite
1397     spawn_process_info_free(pi);
1398 zoff99 27 for (i = 0; argv[i]; i++)
1399 zoff99 2 g_free(argv[i]);
1400     g_free(argv);
1401     }
1402     }
1403    
1404 zoff99 27 static struct command_table commands[] =
1405     {
1406     { "zoom_in", command_cast(navit_cmd_zoom_in) },
1407     { "zoom_out", command_cast(navit_cmd_zoom_out) },
1408     { "zoom_to_route", command_cast(navit_cmd_zoom_to_route) },
1409     { "say", command_cast(navit_cmd_say) },
1410     { "set_center_cursor", command_cast(navit_cmd_set_center_cursor) },
1411     { "set_destination", command_cast(navit_cmd_set_destination) },
1412     { "announcer_toggle", command_cast(navit_cmd_announcer_toggle) },
1413     { "fmt_coordinates", command_cast(navit_cmd_fmt_coordinates) },
1414     { "set_int_var", command_cast(navit_cmd_set_int_var) },
1415     { "get_int_var", command_cast(navit_cmd_get_int_var) },
1416     { "push_int", command_cast(navit_cmd_push_int) },
1417     { "pop_int", command_cast(navit_cmd_pop_int) },
1418     { "int_stack_size", command_cast(navit_cmd_int_stack_size) },
1419     { "toggle_layer", command_cast(navit_cmd_toggle_layer) },
1420     { "strjoin", command_cast(navit_cmd_strjoin) },
1421     { "spawn", command_cast(navit_cmd_spawn) },
1422     { "map_add_curr_pos", command_cast(navit_cmd_map_add_curr_pos) },
1423     { "map_item_set_attr", command_cast(navit_cmd_map_item_set_attr) },
1424     { "set_attr_var", command_cast(navit_cmd_set_attr_var) },
1425     { "get_attr_var", command_cast(navit_cmd_get_attr_var) }, };
1426 zoff99 2
1427 zoff99 27 void navit_command_add_table(struct navit*this_, struct command_table *commands, int count)
1428 zoff99 2 {
1429 zoff99 27 ////DBG dbg(0,"EEnter\n");
1430     command_add_table(this_->attr_cbl, commands, count, this_);
1431 zoff99 2 }
1432    
1433     struct navit *
1434     navit_new(struct attr *parent, struct attr **attrs)
1435     {
1436 zoff99 27 ////DBG dbg(0,"EEnter\n");
1437 zoff99 2 struct navit *this_=g_new0(struct navit, 1);
1438     struct pcoord center;
1439     struct coord co;
1440     struct coord_geo g;
1441 zoff99 27 enum projection pro = projection_mg;
1442 zoff99 2 int zoom = 256;
1443 zoff99 27 g.lat = 53.13;
1444     g.lng = 11.70;
1445 zoff99 2
1446 zoff99 27 this_->self.type = attr_navit;
1447     this_->self.u.navit = this_;
1448     this_->attr_cbl = callback_list_new();
1449 zoff99 2
1450 zoff99 27 this_->orientation = -1;
1451     this_->tracking_flag = 1;
1452     this_->recentdest_count = 10;
1453     this_->osd_configuration = -1;
1454 zoff99 2
1455     // changed default to 1
1456     this_->center_timeout = 1;
1457     this_->use_mousewheel = 1;
1458     this_->autozoom_secs = 10;
1459     this_->autozoom_min = 7;
1460     this_->autozoom_active = 0;
1461     this_->zoom_min = 1;
1462     this_->zoom_max = 1048576; //-> order=-2 // 2097152 -> order=-3;
1463     this_->follow_cursor = 1;
1464     this_->radius = 30;
1465     this_->border = 16;
1466    
1467     this_->trans = transform_new();
1468     this_->trans_cursor = transform_new();
1469     transform_from_geo(pro, &g, &co);
1470 zoff99 27 center.x = co.x;
1471     center.y = co.y;
1472 zoff99 2 center.pro = pro;
1473    
1474 zoff99 27 //DBG dbg(0, "setting center from xmlfile [hardcoded]\n");
1475 zoff99 2 transform_setup(this_->trans, &center, zoom, (this_->orientation != -1) ? this_->orientation : 0);
1476    
1477     // initialze trans_cursor here
1478     transform_copy(this_->trans, this_->trans_cursor);
1479     // initialze trans_cursor here
1480    
1481 zoff99 27 this_->bookmarks = bookmarks_new(&this_->self, NULL, this_->trans);
1482 zoff99 2
1483 zoff99 27 this_->prevTs = 0;
1484 zoff99 2
1485 zoff99 27 for (; *attrs; attrs++)
1486     {
1487 zoff99 2 navit_set_attr_do(this_, *attrs, 1);
1488     }
1489 zoff99 27 this_->displaylist = graphics_displaylist_new();
1490     command_add_table(this_->attr_cbl, commands, sizeof(commands) / sizeof(struct command_table), this_);
1491 zoff99 2
1492 zoff99 27 // this_->messages = messagelist_new(attrs);
1493 zoff99 2
1494 zoff99 27 ////DBG dbg(0,"111111\n");
1495    
1496 zoff99 2 return this_;
1497     }
1498    
1499 zoff99 27 static int navit_set_gui(struct navit *this_, struct gui *gui)
1500 zoff99 2 {
1501 zoff99 27 ////DBG dbg(0,"EEnter\n");
1502 zoff99 2 if (this_->gui)
1503     return 0;
1504 zoff99 27 this_->gui = gui;
1505     if (gui_has_main_loop(this_->gui))
1506     {
1507     if (!main_loop_gui)
1508     {
1509     main_loop_gui = this_->gui;
1510     }
1511     else
1512     {
1513     //DBG dbg(0, "gui with main loop already active, ignoring this instance");
1514 zoff99 2 return 0;
1515     }
1516     }
1517     return 1;
1518     }
1519    
1520 zoff99 27 void navit_add_message(struct navit *this_, char *message)
1521 zoff99 2 {
1522 zoff99 27 ////DBG dbg(0,"EEnter\n");
1523     // message_new(this_->messages, message);
1524 zoff99 2 }
1525    
1526 zoff99 27 struct message *navit_get_messages(struct navit *this_)
1527 zoff99 2 {
1528 zoff99 27 ////DBG dbg(0,"EEnter\n");
1529     // return message_get(this_->messages);
1530 zoff99 2 }
1531    
1532 zoff99 27 static int navit_set_graphics(struct navit *this_, struct graphics *gra)
1533 zoff99 2 {
1534 zoff99 27 ////DBG dbg(0,"EEnter\n");
1535 zoff99 2 if (this_->gra)
1536     return 0;
1537 zoff99 27 this_->gra = gra;
1538     this_->resize_callback = callback_new_attr_1(callback_cast(navit_resize), attr_resize, this_);
1539 zoff99 2 graphics_add_callback(gra, this_->resize_callback);
1540 zoff99 27 this_->button_callback = callback_new_attr_1(callback_cast(navit_button), attr_button, this_);
1541 zoff99 2 graphics_add_callback(gra, this_->button_callback);
1542 zoff99 27 this_->motion_callback = callback_new_attr_1(callback_cast(navit_motion), attr_motion, this_);
1543 zoff99 2 graphics_add_callback(gra, this_->motion_callback);
1544 zoff99 27 this_->predraw_callback = callback_new_attr_1(callback_cast(navit_predraw), attr_predraw, this_);
1545 zoff99 2 graphics_add_callback(gra, this_->predraw_callback);
1546 zoff99 27 ////DBG dbg(0,"111111111\n");
1547 zoff99 2 return 1;
1548     }
1549    
1550     struct graphics *
1551     navit_get_graphics(struct navit *this_)
1552     {
1553 zoff99 27 ////DBG dbg(0,"EEnter\n");
1554 zoff99 2 return this_->gra;
1555     }
1556    
1557     struct vehicleprofile *
1558     navit_get_vehicleprofile(struct navit *this_)
1559     {
1560 zoff99 27 ////DBG dbg(0,"EEnter\n");
1561 zoff99 2 return this_->vehicleprofile;
1562     }
1563    
1564     GList *
1565     navit_get_vehicleprofiles(struct navit *this_)
1566     {
1567 zoff99 27 ////DBG dbg(0,"EEnter\n");
1568 zoff99 2 return this_->vehicleprofiles;
1569     }
1570    
1571 zoff99 27 static void navit_projection_set(struct navit *this_, enum projection pro, int draw)
1572 zoff99 2 {
1573 zoff99 27 ////DBG dbg(0,"EEnter\n");
1574 zoff99 2 struct coord_geo g;
1575     struct coord *c;
1576    
1577 zoff99 27 c = transform_center(this_->trans);
1578 zoff99 2 transform_to_geo(transform_get_projection(this_->trans), c, &g);
1579     transform_set_projection(this_->trans, pro);
1580     transform_from_geo(pro, &g, c);
1581     if (draw)
1582     navit_draw(this_);
1583     }
1584    
1585     /**
1586     * Start the route computing to a given set of coordinates
1587     *
1588     * @param navit The navit instance
1589     * @param c The coordinate to start routing to
1590     * @param description A label which allows the user to later identify this destination in the former destinations selection
1591     * @returns nothing
1592     */
1593 zoff99 27 void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async)
1594 zoff99 2 {
1595 zoff99 27 ////DBG dbg(0,"EEnter\n");
1596 zoff99 2 char *destination_file;
1597 zoff99 27 if (c)
1598     {
1599     this_->destination = *c;
1600     this_->destination_valid = 1;
1601     //dbg(0, "navit->navit_set_destination %i\n", c->x);
1602     //dbg(0, "navit->navit_set_destination %i\n", c->y);
1603     }
1604     else
1605     {
1606     this_->destination_valid = 0;
1607     }
1608     //destination_file = bookmarks_get_destination_file(TRUE);
1609     //bookmarks_append_coord(this_->bookmarks, destination_file, c, 1, "former_destination", description, NULL, this_->recentdest_count);
1610     //g_free(destination_file);
1611     callback_list_call_attr_0(this_->attr_cbl, attr_destination);
1612     if (this_->route)
1613     {
1614     //dbg(0, "navit->navit_set_destination 2: %i %i\n", c->x, c->y);
1615 zoff99 2
1616     route_set_destination(this_->route, c, async);
1617     if (this_->ready == 3)
1618 zoff99 27 {
1619 zoff99 2 navit_draw(this_);
1620 zoff99 27 }
1621 zoff99 2 }
1622     }
1623    
1624     /**
1625 zoff99 27 * add a waypoint to an active route
1626     *
1627     * @param navit The navit instance
1628     * @param c The coordinate of the waypoint
1629     * @param description A dummy string
1630     * @returns nothing
1631     */
1632     void navit_add_waypoint_to_route(struct navit *this_, struct pcoord *c, const char *description, int async)
1633     {
1634     if (this_->destination_valid == 1)
1635     {
1636     //int count = 0;
1637     //count = g_list_length(this_->route->destinations);
1638     //DBG dbg(0, "count=%d\n", count);
1639    
1640     //dbg(0, "navit->navit_add_waypoint_to_route 1: %i %i\n", c->x, c->y);
1641    
1642     route_add_destination(this_->route, c, async);
1643    
1644     this_->destination = *c;
1645     this_->destination_valid = 1;
1646     }
1647     else
1648     {
1649     //dbg(0, "navit->navit_add_waypoint_to_route 2: %i %i\n", c->x, c->y);
1650     navit_set_destination(this_, c, description, async);
1651     }
1652     }
1653    
1654     /**
1655 zoff99 2 * Start the route computing to a given set of coordinates including waypoints
1656     *
1657     * @param navit The navit instance
1658     * @param c The coordinate to start routing to
1659     * @param description A label which allows the user to later identify this destination in the former destinations selection
1660     * @returns nothing
1661     */
1662 zoff99 27 void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async)
1663 zoff99 2 {
1664 zoff99 27 ////DBG dbg(0,"EEnter\n");
1665 zoff99 2 char *destination_file;
1666 zoff99 27 if (c && count)
1667     {
1668     this_->destination = c[count - 1];
1669     this_->destination_valid = 1;
1670     //dbg(0, "navit->navit_set_destinations 1: %i %i\n", c[count-1].x, c[count-1].y);
1671     }
1672     else
1673     {
1674     this_->destination_valid = 0;
1675     }
1676     //destination_file = bookmarks_get_destination_file(TRUE);
1677     //bookmarks_append_coord(this_->bookmarks, destination_file, c, count, "former_itinerary", description, NULL, this_->recentdest_count);
1678     //g_free(destination_file);
1679 zoff99 2 callback_list_call_attr_0(this_->attr_cbl, attr_destination);
1680 zoff99 27 if (this_->route)
1681     {
1682 zoff99 2 route_set_destinations(this_->route, c, count, async);
1683     if (this_->ready == 3)
1684 zoff99 27 {
1685 zoff99 2 navit_draw(this_);
1686 zoff99 27 }
1687 zoff99 2 }
1688     }
1689    
1690     /**
1691     * @brief Checks if a route is calculated
1692     *
1693     * This function checks if a route is calculated.
1694     *
1695     * @param this_ The navit struct whose route should be checked.
1696     * @return True if the route is set, false otherwise.
1697     */
1698 zoff99 27 int navit_check_route(struct navit *this_)
1699 zoff99 2 {
1700 zoff99 27 ////DBG dbg(0,"EEnter\n");
1701     if (this_->route)
1702     {
1703 zoff99 2 return route_get_path_set(this_->route);
1704     }
1705    
1706     return 0;
1707     }
1708    
1709 zoff99 27 static int navit_former_destinations_active(struct navit *this_)
1710 zoff99 2 {
1711 zoff99 27 ////DBG dbg(0,"EEnter\n");
1712    
1713     return 0;
1714     // disable this function!!
1715    
1716    
1717 zoff99 2 char *destination_file = bookmarks_get_destination_file(FALSE);
1718     FILE *f;
1719 zoff99 27 int active = 0;
1720 zoff99 2 char buffer[3];
1721 zoff99 27 f = fopen(destination_file, "r");
1722     if (f)
1723     {
1724     if (!fseek(f, -2, SEEK_END) && fread(buffer, 2, 1, f) == 1 && (buffer[0] != '\n' || buffer[1] != '\n'))
1725     {
1726     active = 1;
1727     }
1728 zoff99 2 fclose(f);
1729     }
1730     g_free(destination_file);
1731 zoff99 27
1732 zoff99 2 return active;
1733     }
1734    
1735 zoff99 27 static void navit_add_former_destinations_from_file(struct navit *this_)
1736 zoff99 2 {
1737 zoff99 27 ////DBG dbg(0,"EEnter\n");
1738 zoff99 2 char *destination_file = bookmarks_get_destination_file(FALSE);
1739     struct attr *attrs[4];
1740     struct map_rect *mr;
1741     struct item *item;
1742 zoff99 27 int i, valid = 0, count = 0;
1743 zoff99 2 struct coord c[16];
1744     struct pcoord pc[16];
1745     struct attr parent;
1746     struct attr type;
1747     struct attr data;
1748     struct attr flags;
1749    
1750 zoff99 27 parent.type = attr_navit;
1751     parent.u.navit = this_;
1752 zoff99 2
1753 zoff99 27 type.type = attr_type;
1754     type.u.str = "textfile";
1755 zoff99 2
1756 zoff99 27 data.type = attr_data;
1757     data.u.str = destination_file;
1758 zoff99 2
1759 zoff99 27 flags.type = attr_flags;
1760     flags.u.num = 1;
1761 zoff99 2
1762 zoff99 27 attrs[0] = &type;
1763     attrs[1] = &data;
1764     attrs[2] = &flags;
1765     attrs[3] = NULL;
1766 zoff99 2
1767 zoff99 27 this_->former_destination = map_new(&parent, attrs);
1768 zoff99 2 g_free(destination_file);
1769     if (!this_->route || !navit_former_destinations_active(this_))
1770 zoff99 27 return;
1771     mr = map_rect_new(this_->former_destination, NULL);
1772     while ((item = map_rect_get_item(mr)))
1773     {
1774     if ((item->type == type_former_destination || item->type == type_former_itinerary || item->type == type_former_itinerary_part) && (count = item_coord_get(item, c, 16)))
1775     valid = 1;
1776 zoff99 2 }
1777     map_rect_destroy(mr);
1778 zoff99 27 if (valid && count > 0)
1779     {
1780     for (i = 0; i < count; i++)
1781     {
1782     pc[i].pro = map_projection(this_->former_destination);
1783     pc[i].x = c[i].x;
1784     pc[i].y = c[i].y;
1785 zoff99 2 }
1786     if (count == 1)
1787 zoff99 27 {
1788 zoff99 2 route_set_destination(this_->route, &pc[0], 1);
1789 zoff99 27 }
1790 zoff99 2 else
1791 zoff99 27 {
1792 zoff99 2 route_set_destinations(this_->route, pc, count, 1);
1793 zoff99 27 }
1794     this_->destination = pc[count - 1];
1795     this_->destination_valid = 1;
1796 zoff99 2 }
1797     }
1798    
1799 zoff99 27 void navit_textfile_debug_log(struct navit *this_, const char *fmt, ...)
1800 zoff99 2 {
1801 zoff99 27 ////DBG dbg(0,"EEnter\n");
1802 zoff99 2 va_list ap;
1803 zoff99 27 char *str1, *str2;
1804 zoff99 2 va_start(ap, fmt);
1805 zoff99 27 if (this_->textfile_debug_log && this_->vehicle)
1806     {
1807     str1 = g_strdup_vprintf(fmt, ap);
1808     str2 = g_strdup_printf("0x%x 0x%x%s%s\n", this_->vehicle->coord.x, this_->vehicle->coord.y, strlen(str1) ? " " : "", str1);
1809 zoff99 2 log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
1810     g_free(str2);
1811     g_free(str1);
1812     }
1813 zoff99 27 va_end(ap);
1814 zoff99 2 }
1815    
1816 zoff99 27 void navit_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *fmt, ...)
1817 zoff99 2 {
1818 zoff99 27 ////DBG dbg(0,"EEnter\n");
1819 zoff99 2 va_list ap;
1820 zoff99 27 char *str1, *str2;
1821 zoff99 2 va_start(ap, fmt);
1822 zoff99 27 if (this_->textfile_debug_log && this_->vehicle)
1823     {
1824     str1 = g_strdup_vprintf(fmt, ap);
1825     str2 = g_strdup_printf("0x%x 0x%x%s%s\n", pc->x, pc->y, strlen(str1) ? " " : "", str1);
1826 zoff99 2 log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
1827     g_free(str2);
1828     g_free(str1);
1829     }
1830 zoff99 27 va_end(ap);
1831 zoff99 2 }
1832    
1833 zoff99 27 void navit_say(struct navit *this_, char *text)
1834 zoff99 2 {
1835 zoff99 27 ////DBG dbg(0,"EEnter\n");
1836     if (this_->speech)
1837     {
1838 zoff99 2 speech_say(this_->speech, text);
1839     }
1840     }
1841    
1842     /**
1843     * @brief Toggles the navigation announcer for navit
1844     * @param this_ The navit object
1845     */
1846 zoff99 27 static void navit_cmd_announcer_toggle(struct navit *this_)
1847 zoff99 2 {
1848 zoff99 27 struct attr attr, speechattr;
1849 zoff99 2
1850 zoff99 27 // search for the speech attribute
1851     if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
1852     return;
1853     // find out if the corresponding attribute attr_active has been set
1854     if (speech_get_attr(speechattr.u.speech, attr_active, &attr, NULL))
1855     {
1856     // flip it then...
1857     attr.u.num = !attr.u.num;
1858     }
1859     else
1860     {
1861     // otherwise disable it because voice is enabled by default
1862     attr.type = attr_active;
1863     attr.u.num = 0;
1864     }
1865 zoff99 2
1866 zoff99 27 // apply the new state
1867     if (!speech_set_attr(speechattr.u.speech, &attr))
1868     return;
1869 zoff99 2
1870 zoff99 27 // announce that the speech attribute has changed
1871     callback_list_call_attr_0(this_->attr_cbl, attr_speech);
1872 zoff99 2 }
1873    
1874 zoff99 27 void navit_cmd_announcer_on(struct navit *this_)
1875 zoff99 2 {
1876 zoff99 27 struct attr attr, speechattr;
1877 zoff99 2
1878 zoff99 27 // search for the speech attribute
1879     if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
1880     return;
1881 zoff99 2
1882     attr.type = attr_active;
1883     attr.u.num = 1;
1884    
1885 zoff99 27 // apply the new state
1886     if (!speech_set_attr(speechattr.u.speech, &attr))
1887     return;
1888 zoff99 2
1889 zoff99 27 // announce that the speech attribute has changed
1890     callback_list_call_attr_0(this_->attr_cbl, attr_speech);
1891 zoff99 2 }
1892    
1893 zoff99 27 void navit_cmd_announcer_off(struct navit *this_)
1894 zoff99 2 {
1895 zoff99 27 struct attr attr, speechattr;
1896 zoff99 2
1897 zoff99 27 // search for the speech attribute
1898     if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
1899     return;
1900 zoff99 2
1901     attr.type = attr_active;
1902     attr.u.num = 0;
1903    
1904 zoff99 27 // apply the new state
1905     if (!speech_set_attr(speechattr.u.speech, &attr))
1906     return;
1907 zoff99 2
1908 zoff99 27 // announce that the speech attribute has changed
1909     callback_list_call_attr_0(this_->attr_cbl, attr_speech);
1910 zoff99 2 }
1911    
1912 zoff99 27 void navit_speak(struct navit *this_)
1913 zoff99 2 {
1914 zoff99 27 ////DBG dbg(0,"EEnter\n");
1915     struct navigation *nav = this_->navigation;
1916     struct map *map = NULL;
1917     struct map_rect *mr = NULL;
1918 zoff99 2 struct item *item;
1919     struct attr attr;
1920    
1921 zoff99 27 if (!speech_get_attr(this_->speech, attr_active, &attr, NULL))
1922     attr.u.num = 1;
1923     // dbg(1, "this_.speech->active %i\n", attr.u.num);
1924     if (!attr.u.num)
1925     return;
1926 zoff99 2
1927     if (nav)
1928 zoff99 27 map = navigation_get_map(nav);
1929 zoff99 2 if (map)
1930 zoff99 27 mr = map_rect_new(map, NULL);
1931     if (mr)
1932     {
1933     while ((item = map_rect_get_item(mr)) && (item->type == type_nav_position || item->type == type_nav_none))
1934     ;
1935     if (item && item_attr_get(item, attr_navigation_speech, &attr))
1936     {
1937 zoff99 2 speech_say(this_->speech, attr.u.str);
1938 zoff99 27 //navit_add_message(this_, attr.u.str);
1939 zoff99 2 navit_textfile_debug_log(this_, "type=announcement label=\"%s\"", attr.u.str);
1940     }
1941     map_rect_destroy(mr);
1942     }
1943     }
1944    
1945 zoff99 27 static void navit_window_roadbook_update(struct navit *this_)
1946 zoff99 2 {
1947 zoff99 27 ////DBG dbg(0,"EEnter\n");
1948     struct navigation *nav = this_->navigation;
1949     struct map *map = NULL;
1950     struct map_rect *mr = NULL;
1951 zoff99 2 struct item *item;
1952     struct attr attr;
1953     struct param_list param[5];
1954     int secs;
1955    
1956 zoff99 27 // dbg(1, "enter\n");
1957 zoff99 2 datawindow_mode(this_->roadbook_window, 1);
1958     if (nav)
1959 zoff99 27 map = navigation_get_map(nav);
1960 zoff99 2 if (map)
1961 zoff99 27 mr = map_rect_new(map, NULL);
1962     ////DBG dbg(0,"nav=%p map=%p mr=%p\n", nav, map, mr);
1963     if (mr)
1964     {
1965     ////DBG dbg(0,"while loop\n");
1966     while ((item = map_rect_get_item(mr)))
1967     {
1968     ////DBG dbg(0,"item=%p\n", item);
1969     attr.u.str = NULL;
1970     if (item->type != type_nav_position)
1971     {
1972 zoff99 2 item_attr_get(item, attr_navigation_long, &attr);
1973 zoff99 27 if (attr.u.str == NULL)
1974     {
1975 zoff99 2 continue;
1976     }
1977     dbg(2, "Command='%s'\n", attr.u.str);
1978 zoff99 27 param[0].value = g_strdup(attr.u.str);
1979     }
1980     else
1981     param[0].value = _("Position");
1982     param[0].name = _("Command");
1983 zoff99 2
1984     item_attr_get(item, attr_length, &attr);
1985     dbg(2, "Length=%d\n", attr.u.num);
1986 zoff99 27 param[1].name = _("Length");
1987 zoff99 2
1988 zoff99 27 if (attr.u.num >= 2000)
1989 zoff99 2 {
1990 zoff99 27 param[1].value = g_strdup_printf("%5.1f %s", (float) attr.u.num / 1000, _("km"));
1991 zoff99 2 }
1992     else
1993     {
1994 zoff99 27 param[1].value = g_strdup_printf("%7d %s", attr.u.num, _("m"));
1995 zoff99 2 }
1996    
1997     item_attr_get(item, attr_time, &attr);
1998     dbg(2, "Time=%d\n", attr.u.num);
1999 zoff99 27 secs = attr.u.num / 10;
2000     param[2].name = _("Time");
2001     if (secs >= 3600)
2002 zoff99 2 {
2003 zoff99 27 param[2].value = g_strdup_printf("%d:%02d:%02d", secs / 60, (secs / 60) % 60, secs % 60);
2004 zoff99 2 }
2005     else
2006     {
2007 zoff99 27 param[2].value = g_strdup_printf("%d:%02d", secs / 60, secs % 60);
2008 zoff99 2 }
2009    
2010     item_attr_get(item, attr_destination_length, &attr);
2011     dbg(2, "Destlength=%d\n", attr.u.num);
2012 zoff99 27 param[3].name = _("Destination Length");
2013     if (attr.u.num >= 2000)
2014 zoff99 2 {
2015 zoff99 27 param[3].value = g_strdup_printf("%5.1f %s", (float) attr.u.num / 1000, _("km"));
2016 zoff99 2 }
2017     else
2018     {
2019 zoff99 27 param[3].value = g_strdup_printf("%d %s", attr.u.num, _("m"));
2020 zoff99 2 }
2021    
2022     item_attr_get(item, attr_destination_time, &attr);
2023     dbg(2, "Desttime=%d\n", attr.u.num);
2024 zoff99 27 secs = attr.u.num / 10;
2025     param[4].name = _("Destination Time");
2026     if (secs >= 3600)
2027 zoff99 2 {
2028 zoff99 27 param[4].value = g_strdup_printf("%d:%02d:%02d", secs / 3600, (secs / 60) % 60, secs % 60);
2029 zoff99 2 }
2030     else
2031     {
2032 zoff99 27 param[4].value = g_strdup_printf("%d:%02d", secs / 60, secs % 60);
2033 zoff99 2 }
2034     datawindow_add(this_->roadbook_window, param, 5);
2035     }
2036     map_rect_destroy(mr);
2037     }
2038     datawindow_mode(this_->roadbook_window, 0);
2039     }
2040    
2041 zoff99 27 void navit_window_roadbook_destroy(struct navit *this_)
2042 zoff99 2 {
2043 zoff99 27 ////DBG dbg(0, "enter\n");
2044 zoff99 2 navigation_unregister_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
2045 zoff99 27 this_->roadbook_window = NULL;
2046     this_->roadbook_callback = NULL;
2047 zoff99 2 }
2048 zoff99 27 void navit_window_roadbook_new(struct navit *this_)
2049 zoff99 2 {
2050 zoff99 27 if (!this_->gui || this_->roadbook_callback || this_->roadbook_window)
2051     {
2052 zoff99 2 return;
2053     }
2054    
2055 zoff99 27 this_->roadbook_callback = callback_new_1(callback_cast(navit_window_roadbook_update), this_);
2056 zoff99 2 navigation_register_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
2057 zoff99 27 this_->roadbook_window = gui_datawindow_new(this_->gui, _("Roadbook"), NULL, callback_new_1(callback_cast(navit_window_roadbook_destroy), this_));
2058 zoff99 2 navit_window_roadbook_update(this_);
2059     }
2060    
2061 zoff99 27 void navit_remove_all_maps(struct navit *this_)
2062 zoff99 2 {
2063     struct mapset *ms;
2064     struct map *map3;
2065    
2066 zoff99 27 // first: stop navigation!
2067     //if (global_navit->destination_valid != 0)
2068     //{
2069     navit_set_destination(global_navit, NULL, NULL, 0);
2070     //}
2071    
2072    
2073     if (this_->route)
2074     {
2075     struct attr callback;
2076     // this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
2077     callback.type=attr_callback;
2078     callback.u.callback=this_->route_cb;
2079     route_remove_attr(this_->route, &callback);
2080    
2081     this_->route->ms = NULL;
2082     // route_set_mapset(this_->route, ms);
2083     // route_set_projection(this_->route, transform_get_projection(this_->trans));
2084    
2085     //*********route_destroy(this_->route);
2086    
2087     //route_path_destroy(this_->route->path2,1);
2088     //this_->route->path2 = NULL;
2089     //route_graph_destroy(this_->route->graph);
2090     //this_->route->graph=NULL;
2091     }
2092    
2093     /*
2094     map_rect_destroy(displaylist->mr);
2095     if (!route_selection)
2096     map_selection_destroy(displaylist->sel);
2097     mapset_close(displaylist->msh);
2098     displaylist->mr=NULL;
2099     displaylist->sel=NULL;
2100     displaylist->m=NULL;
2101     displaylist->msh=NULL;
2102     profile(1,"callback\n");
2103     callback_call_1(displaylist->cb, cancel);
2104     */
2105    
2106     struct displaylist *dl = navit_get_displaylist(this_);
2107     dl->m = NULL;
2108     dl->msh = NULL;
2109    
2110 zoff99 2 if (this_->mapsets)
2111     {
2112     struct mapset_handle *msh;
2113 zoff99 27 ms = this_->mapsets->data;
2114     msh = mapset_open(ms);
2115     ////DBG dbg(0,"removing map bb0\n");
2116     while (msh && (map3 = mapset_next(msh, 0)))
2117 zoff99 2 {
2118 zoff99 27 ////DBG dbg(0,"removing map bb1\n");
2119 zoff99 2 struct attr map_name_attr;
2120 zoff99 27 if (map_get_attr(map3, attr_name, &map_name_attr, NULL))
2121 zoff99 2 {
2122 zoff99 27 //DBG dbg(0, "map name=%s", map_name_attr.u.str);
2123 zoff99 2 if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
2124     {
2125 zoff99 27 //DBG dbg(0, "removing map a0\n");
2126     struct attr active;
2127     active.type = attr_active;
2128     active.u.num = 0;
2129     //map_set_attr(map3, &active);
2130    
2131     //DBG dbg(0, "removing map a1\n");
2132 zoff99 2 struct attr map_attr;
2133 zoff99 27 map_attr.u.map = map3;
2134     map_attr.type = attr_map;
2135 zoff99 2 mapset_remove_attr(ms, &map_attr);
2136 zoff99 27
2137     //DBG dbg(0, "removing map a2\n");
2138     map3->refcount = 1;
2139 zoff99 2 map_destroy(map3);
2140 zoff99 27 //DBG dbg(0, "removing map a3\n");
2141     map3 = NULL;
2142 zoff99 2 }
2143     }
2144     }
2145     mapset_close(msh);
2146 zoff99 27 //DBG dbg(0, "removing map bb4\n");
2147 zoff99 2 }
2148 zoff99 27
2149     dl->ms = this_->mapsets->data;
2150    
2151     // int async = 0;
2152     // transform_setup_source_rect(this_->trans);
2153     // graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
2154     //this_->displaylist->ms=this_->mapsets->data;
2155    
2156 zoff99 2 }
2157    
2158 zoff99 27 void navit_add_all_maps(struct navit *this_)
2159 zoff99 2 {
2160     struct map *map3;
2161    
2162     if (this_->mapsets)
2163     {
2164 zoff99 27 //DBG dbg(0, "xADDx all maps - start\n");
2165 zoff99 2
2166 zoff99 27 struct mapset *ms;
2167     ms = this_->mapsets->data;
2168    
2169 zoff99 2 struct attr type;
2170     struct attr parent;
2171     struct attr data;
2172     struct attr flags;
2173     struct map *map2;
2174     struct attr map2_attr;
2175     struct attr *attrs[4];
2176     char *map_file;
2177    
2178 zoff99 27 parent.type = attr_navit;
2179     parent.u.navit = this_;
2180     type.type = attr_type;
2181     type.u.str = "binfile";
2182     data.type = attr_data;
2183     map_file = g_strdup_printf("%sborders.bin", navit_maps_dir);
2184     data.u.str = map_file;
2185 zoff99 2
2186 zoff99 27 ////DBG dbg(0,"map name=%s",map_file);
2187 zoff99 2
2188 zoff99 27 flags.type = attr_flags;
2189     flags.u.num = 0;
2190     attrs[0] = &type;
2191     attrs[1] = &data;
2192     attrs[2] = &flags;
2193     attrs[3] = NULL;
2194     map2 = map_new(&parent, attrs);
2195 zoff99 2 if (map2)
2196     {
2197 zoff99 27 map2_attr.u.data = map2;
2198     map2_attr.type = attr_map;
2199     // mapset_add_attr_name(ms, &map2_attr);
2200     mapset_add_attr_name_str(ms, &map2_attr, "/sdcard/zanavi/maps/borders.bin");
2201     struct attr active;
2202     active.type = attr_active;
2203     active.u.num = 0;
2204     //map_set_attr(map2, &active);
2205 zoff99 2 }
2206     g_free(map_file);
2207    
2208 zoff99 27 parent.type = attr_navit;
2209     parent.u.navit = this_;
2210     type.type = attr_type;
2211     type.u.str = "binfile";
2212     data.type = attr_data;
2213     map_file = g_strdup_printf("%scoastline.bin", navit_maps_dir);
2214     data.u.str = map_file;
2215 zoff99 2
2216 zoff99 27 ////DBG dbg(0,"map name=%s",map_file);
2217 zoff99 2
2218 zoff99 27 flags.type = attr_flags;
2219     flags.u.num = 0;
2220     attrs[0] = &type;
2221     attrs[1] = &data;
2222     attrs[2] = &flags;
2223     attrs[3] = NULL;
2224     map2 = map_new(&parent, attrs);
2225 zoff99 2 if (map2)
2226     {
2227 zoff99 27 map2_attr.u.data = map2;
2228     map2_attr.type = attr_map;
2229     // mapset_add_attr_name(ms, &map2_attr);
2230     mapset_add_attr_name_str(ms, &map2_attr, "/sdcard/zanavi/maps/coastline.bin");
2231     struct attr active;
2232     active.type = attr_active;
2233     active.u.num = 0;
2234     //map_set_attr(map2, &active);
2235 zoff99 2 }
2236     g_free(map_file);
2237    
2238 zoff99 27 int i = 1;
2239     for (i = 1; i < 10; i++)
2240 zoff99 2 {
2241     struct map *map22;
2242     struct attr map22_attr;
2243 zoff99 27 parent.type = attr_navit;
2244     parent.u.navit = this_;
2245     type.type = attr_type;
2246     type.u.str = "binfile";
2247     data.type = attr_data;
2248     map_file = g_strdup_printf("%snavitmap_00%d.bin", navit_maps_dir, i);
2249     data.u.str = map_file;
2250     flags.type = attr_flags;
2251     flags.u.num = 0;
2252     attrs[0] = &type;
2253     attrs[1] = &data;
2254     attrs[2] = &flags;
2255     attrs[3] = NULL;
2256     map22 = map_new(&parent, attrs);
2257 zoff99 2 if (map22)
2258     {
2259 zoff99 27 //DBG dbg(0, "*add* map name=%s\n", map_file);
2260     map22_attr.u.data = map22;
2261     map22_attr.type = attr_map;
2262     // mapset_add_attr_name(ms, &map22_attr);
2263     char *map_name_str;
2264     map_name_str = g_strdup_printf("/sdcard/zanavi/maps/navitmap_00%d.bin", i);
2265     mapset_add_attr_name_str(ms, &map22_attr, map_name_str);
2266     struct attr active;
2267     active.type = attr_active;
2268     active.u.num = 0;
2269     //map_set_attr(map22, &active);
2270     g_free(map_name_str);
2271 zoff99 2 }
2272     g_free(map_file);
2273     }
2274    
2275 zoff99 27 i = 10;
2276     for (i = 10; i < 21; i++)
2277 zoff99 2 {
2278 zoff99 27 parent.type = attr_navit;
2279     parent.u.navit = this_;
2280     type.type = attr_type;
2281     type.u.str = "binfile";
2282     data.type = attr_data;
2283     map_file = g_strdup_printf("%snavitmap_0%d.bin", navit_maps_dir, i);
2284     data.u.str = map_file;
2285     ////DBG dbg(0,"map name=%s",map_file);
2286     flags.type = attr_flags;
2287     flags.u.num = 0;
2288     attrs[0] = &type;
2289     attrs[1] = &data;
2290     attrs[2] = &flags;
2291     attrs[3] = NULL;
2292     map2 = map_new(&parent, attrs);
2293 zoff99 2 if (map2)
2294     {
2295 zoff99 27 map2_attr.u.data = map2;
2296     map2_attr.type = attr_map;
2297     // mapset_add_attr_name(ms, &map2_attr);
2298     char *map_name_str;
2299     map_name_str = g_strdup_printf("/sdcard/zanavi/maps/navitmap_0%d.bin", i);
2300     mapset_add_attr_name_str(ms, &map2_attr, map_name_str);
2301     struct attr active;
2302     active.type = attr_active;
2303     active.u.num = 0;
2304     //map_set_attr(map2, &active);
2305     g_free(map_name_str);
2306 zoff99 2 }
2307     g_free(map_file);
2308     }
2309     }
2310 zoff99 27
2311     /*
2312     if (this_->mapsets)
2313     {
2314     struct mapset_handle *msh;
2315     struct map *map;
2316     struct mapset *ms;
2317    
2318     //DBG dbg(0,"xx ms callbacks xx\n");
2319    
2320     ms=this_->mapsets->data;
2321     this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2322     msh=mapset_open(ms);
2323     while (msh && (map=mapset_next(msh, 0)))
2324     {
2325     //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
2326     struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2327     map_add_callback(map, pcb);
2328     }
2329     mapset_close(msh);
2330     }
2331     */
2332    
2333     struct attr parent;
2334     parent.type = attr_navit;
2335     parent.u.navit = global_navit;
2336    
2337     struct attr *attrs_r[2];
2338     attrs_r[0] = NULL;
2339     attrs_r[1] = NULL;
2340    
2341     //***this_->route = route_new(&parent, attrs_r);
2342    
2343    
2344     //int async = 0;
2345     //transform_setup_source_rect(this_->trans);
2346     //graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
2347    
2348     struct displaylist *dl = navit_get_displaylist(this_);
2349     dl->ms = this_->mapsets->data;
2350     dl->m = NULL;
2351     dl->msh = NULL;
2352    
2353     if (this_->route)
2354     {
2355     struct mapset *ms;
2356     ms = this_->mapsets->data;
2357     route_set_mapset(this_->route, ms);
2358    
2359     struct attr callback;
2360     this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
2361     callback.type=attr_callback;
2362     callback.u.callback=this_->route_cb;
2363     route_add_attr(this_->route, &callback);
2364     // ***** route_set_projection(this_->route, transform_get_projection(this_->trans));
2365     }
2366    
2367     if (this_->tracking)
2368     {
2369     struct mapset *ms;
2370     ms = this_->mapsets->data;
2371    
2372     tracking_set_mapset(this_->tracking, ms);
2373     if (this_->route)
2374     {
2375     tracking_set_route(this_->tracking, this_->route);
2376     }
2377     }
2378    
2379    
2380 zoff99 2 }
2381    
2382 zoff99 27 void navit_reload_maps(struct navit *this_)
2383 zoff99 2 {
2384     navit_remove_all_maps(this_);
2385     navit_add_all_maps(this_);
2386     }
2387    
2388 zoff99 27 void navit_init(struct navit *this_)
2389 zoff99 2 {
2390 zoff99 27 ////DBG dbg(0,"EEnter\n");
2391 zoff99 2 struct mapset *ms;
2392     struct map *map;
2393     int callback;
2394     char *center_file;
2395    
2396 zoff99 27 // default value
2397     navit_maps_dir = "/sdcard/zanavi/maps/";
2398 zoff99 2
2399 zoff99 27 global_img_waypoint = NULL;
2400    
2401     //DBG dbg(0, "enter gui %p graphics %p\n", this_->gui, this_->gra);
2402    
2403     if (!this_->gui && !(this_->flags & 2))
2404     {
2405     dbg(0, "no gui\n");
2406 zoff99 2 navit_destroy(this_);
2407     return;
2408     }
2409 zoff99 27
2410     if (!this_->gra && !(this_->flags & 1))
2411     {
2412     dbg(0, "no graphics\n");
2413 zoff99 2 navit_destroy(this_);
2414     return;
2415     }
2416 zoff99 27
2417     //DBG dbg(0, "Connecting gui to graphics\n");
2418    
2419     if (this_->gui && this_->gra && gui_set_graphics(this_->gui, this_->gra))
2420     {
2421 zoff99 2 struct attr attr_type_gui, attr_type_graphics;
2422     gui_get_attr(this_->gui, attr_type, &attr_type_gui, NULL);
2423     graphics_get_attr(this_->gra, attr_type, &attr_type_graphics, NULL);
2424 zoff99 27 //DBG dbg(0, "failed to connect graphics '%s' to gui '%s'\n", attr_type_graphics.u.str, attr_type_gui.u.str);
2425     // //DBG dbg(0," Please see http://wiki.navit-project.org/index.php/Failed_to_connect_graphics_to_gui\n");
2426     // //DBG dbg(0," for explanations and solutions\n");
2427 zoff99 2
2428 zoff99 27 dbg(0,"failed to connect to graphics\n");
2429 zoff99 2 navit_destroy(this_);
2430     return;
2431     }
2432 zoff99 27
2433     if (this_->speech && this_->navigation)
2434     {
2435 zoff99 2 struct attr speech;
2436 zoff99 27 speech.type = attr_speech;
2437     speech.u.speech = this_->speech;
2438 zoff99 2 navigation_set_attr(this_->navigation, &speech);
2439     }
2440 zoff99 27
2441     //DBG dbg(0, "Initializing graphics\n");
2442     //DBG dbg(0, "Setting Vehicle\n");
2443 zoff99 2 navit_set_vehicle(this_, this_->vehicle);
2444 zoff99 27 //DBG dbg(0, "Adding dynamic maps to mapset %p\n", this_->mapsets);
2445    
2446     if (this_->mapsets)
2447     {
2448 zoff99 2 struct mapset_handle *msh;
2449 zoff99 27 ms = this_->mapsets->data;
2450     // **D** // this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2451     msh = mapset_open(ms);
2452     while (msh && (map = mapset_next(msh, 0)))
2453     {
2454 zoff99 2 //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
2455 zoff99 27 // **D** // struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2456     // **D** // map_add_callback(map, pcb);
2457 zoff99 2 }
2458     mapset_close(msh);
2459 zoff99 27
2460     if (this_->route)
2461     {
2462     if ((map = route_get_map(this_->route)))
2463     {
2464     struct attr map_a, map_name;
2465     map_a.type = attr_map;
2466     map_a.u.map = map;
2467     map_name.type = attr_name;
2468     map_name.u.str = "_ms_route";
2469 zoff99 2 map_set_attr(map_a.u.map, &map_name);
2470     mapset_add_attr(ms, &map_a);
2471     }
2472 zoff99 27
2473     if ((map = route_get_graph_map(this_->route)))
2474     {
2475     struct attr map_a, active, map_name;
2476     map_a.type = attr_map;
2477     map_a.u.map = map;
2478     active.type = attr_active;
2479     active.u.num = 0;
2480     map_name.type = attr_name;
2481     map_name.u.str = "_ms_route_graph";
2482 zoff99 2 map_set_attr(map_a.u.map, &map_name);
2483     mapset_add_attr(ms, &map_a);
2484     map_set_attr(map, &active);
2485     }
2486     route_set_mapset(this_->route, ms);
2487     route_set_projection(this_->route, transform_get_projection(this_->trans));
2488     }
2489 zoff99 27
2490     if (this_->tracking)
2491     {
2492 zoff99 2 tracking_set_mapset(this_->tracking, ms);
2493     if (this_->route)
2494 zoff99 27 {
2495 zoff99 2 tracking_set_route(this_->tracking, this_->route);
2496 zoff99 27 }
2497 zoff99 2 }
2498 zoff99 27
2499     if (this_->navigation)
2500     {
2501     if ((map = navigation_get_map(this_->navigation)))
2502     {
2503     struct attr map_a, active, map_name;
2504     map_a.type = attr_map;
2505     map_a.u.map = map;
2506     active.type = attr_active;
2507     active.u.num = 0;
2508     map_name.type = attr_name;
2509     map_name.u.str = "_ms_navigation";
2510 zoff99 2 map_set_attr(map_a.u.map, &map_name);
2511     mapset_add_attr(ms, &map_a);
2512     map_set_attr(map, &active);
2513     }
2514     }
2515 zoff99 27
2516     if (this_->tracking)
2517     {
2518     if ((map = tracking_get_map(this_->tracking)))
2519     {
2520     struct attr map_a, active, map_name;
2521     map_a.type = attr_map;
2522     map_a.u.map = map;
2523     active.type = attr_active;
2524     active.u.num = 0;
2525     map_name.type = attr_name;
2526     map_name.u.str = "_ms_tracking";
2527 zoff99 14 map_set_attr(map_a.u.map, &map_name);
2528 zoff99 2 mapset_add_attr(ms, &map_a);
2529     map_set_attr(map, &active);
2530     }
2531     }
2532 zoff99 14 // *DISABLED* navit_add_former_destinations_from_file(this_);
2533 zoff99 2 }
2534 zoff99 27
2535     if (this_->route)
2536     {
2537 zoff99 2 struct attr callback;
2538 zoff99 27 this_->route_cb = callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
2539     callback.type = attr_callback;
2540     callback.u.callback = this_->route_cb;
2541 zoff99 2 route_add_attr(this_->route, &callback);
2542     }
2543 zoff99 27
2544     if (this_->navigation)
2545     {
2546     if (this_->speech)
2547     {
2548     this_->nav_speech_cb = callback_new_1(callback_cast(navit_speak), this_);
2549 zoff99 2 navigation_register_callback(this_->navigation, attr_navigation_speech, this_->nav_speech_cb);
2550     }
2551 zoff99 27
2552 zoff99 2 if (this_->route)
2553 zoff99 27 {
2554 zoff99 2 navigation_set_route(this_->navigation, this_->route);
2555 zoff99 27 }
2556 zoff99 2 }
2557 zoff99 27
2558     dbg(0, "Setting Center\n");
2559 zoff99 2 center_file = bookmarks_get_center_file(FALSE);
2560 zoff99 27 //dbg(0, "g0\n");
2561 zoff99 2 bookmarks_set_center_from_file(this_->bookmarks, center_file);
2562     g_free(center_file);
2563     #if 0
2564 zoff99 27 if (this_->menubar)
2565     {
2566 zoff99 2 men=menu_add(this_->menubar, "Data", menu_type_submenu, NULL);
2567 zoff99 27 if (men)
2568     {
2569 zoff99 2 navit_add_menu_windows_items(this_, men);
2570     }
2571     }
2572     #endif
2573 zoff99 27 global_navit = this_;
2574 zoff99 2 #if 0
2575     navit_window_roadbook_new(this_);
2576     navit_window_items_new(this_);
2577     #endif
2578    
2579 zoff99 27 //dbg(0, "g1\n");
2580     //messagelist_init(this_->messages);
2581 zoff99 2
2582 zoff99 27 //dbg(0, "g2\n");
2583 zoff99 2 navit_set_cursors(this_);
2584    
2585     callback_list_call_attr_1(this_->attr_cbl, attr_navit, this_);
2586 zoff99 27 callback = (this_->ready == 2);
2587     //DBG dbg(0, "pre this_->ready=%d\n", this_->ready);
2588     this_->ready |= 1;
2589     //DBG dbg(0, "set this_->ready=%d\n", this_->ready);
2590     ////DBG dbg(0,"ready=%d\n",this_->ready);
2591 zoff99 2 if (this_->ready == 3)
2592     {
2593 zoff99 27 ////DBG dbg(0,"navit_draw_async_003\n");
2594 zoff99 2 navit_draw_async(this_, 1);
2595     }
2596 zoff99 27
2597 zoff99 2 if (callback)
2598 zoff99 27 {
2599 zoff99 2 callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_);
2600 zoff99 27 }
2601 zoff99 2 #if 0
2602     routech_test(this_);
2603     #endif
2604 zoff99 27 //dbg(0, "1111111111\n");
2605 zoff99 2 }
2606    
2607 zoff99 27 void navit_zoom_to_rect(struct navit *this_, struct coord_rect *r)
2608 zoff99 2 {
2609 zoff99 27 ////DBG dbg(0,"EEnter\n");
2610 zoff99 2 struct coord c;
2611 zoff99 27 int scale = 16;
2612 zoff99 2
2613 zoff99 27 c.x = (r->rl.x + r->lu.x) / 2;
2614     c.y = (r->rl.y + r->lu.y) / 2;
2615 zoff99 2 transform_set_center(this_->trans, &c);
2616 zoff99 27 // dbg(1, "%x,%x-%x,%x\n", r->rl.x, r->rl.y, r->lu.x, r->lu.y);
2617     while (scale < 1 << 20)
2618     {
2619     struct point p1, p2;
2620 zoff99 2 transform_set_scale(this_->trans, scale);
2621     transform_setup_source_rect(this_->trans);
2622     transform(this_->trans, transform_get_projection(this_->trans), &r->lu, &p1, 1, 0, 0, NULL);
2623     transform(this_->trans, transform_get_projection(this_->trans), &r->rl, &p2, 1, 0, 0, NULL);
2624 zoff99 27 // dbg(1, "%d,%d-%d,%d\n", p1.x, p1.y, p2.x, p2.y);
2625     if (p1.x < 0 || p2.x < 0 || p1.x > this_->w || p2.x > this_->w || p1.y < 0 || p2.y < 0 || p1.y > this_->h || p2.y > this_->h)
2626     scale *= 2;
2627 zoff99 2 else
2628     break;
2629 zoff99 27
2630 zoff99 2 }
2631     if (this_->ready == 3)
2632     {
2633 zoff99 27 ////DBG dbg(0,"navit_draw_async_004\n");
2634     navit_draw_async(this_, 0);
2635 zoff99 2 }
2636     }
2637    
2638 zoff99 27 void navit_zoom_to_route(struct navit *this_, int orientation)
2639 zoff99 2 {
2640 zoff99 27 ////DBG dbg(0,"EEnter\n");
2641 zoff99 2 struct map *map;
2642 zoff99 27 struct map_rect *mr = NULL;
2643 zoff99 2 struct item *item;
2644     struct coord c;
2645     struct coord_rect r;
2646 zoff99 27 int count = 0;
2647     if (!this_->route)
2648 zoff99 2 return;
2649 zoff99 27 // dbg(1, "enter\n");
2650     map = route_get_map(this_->route);
2651     // dbg(1, "map=%p\n", map);
2652 zoff99 2 if (map)
2653 zoff99 27 mr = map_rect_new(map, NULL);
2654     // dbg(1, "mr=%p\n", mr);
2655     if (mr)
2656     {
2657     while ((item = map_rect_get_item(mr)))
2658     {
2659     // dbg(1, "item=%s\n", item_to_name(item->type));
2660     while (item_coord_get(item, &c, 1))
2661     {
2662     // dbg(1, "coord\n");
2663     if (!count)
2664     r.lu = r.rl = c;
2665 zoff99 2 else
2666 zoff99 27 coord_rect_extend(&r, &c);
2667 zoff99 2 count++;
2668     }
2669     }
2670     map_rect_destroy(mr);
2671     }
2672 zoff99 27 if (!count)
2673 zoff99 2 return;
2674     if (orientation != -1)
2675     transform_set_yaw(this_->trans, orientation);
2676     navit_zoom_to_rect(this_, &r);
2677     }
2678    
2679 zoff99 27 static void navit_cmd_zoom_to_route(struct navit *this)
2680 zoff99 2 {
2681 zoff99 27 ////DBG dbg(0,"EEnter\n");
2682 zoff99 2 navit_zoom_to_route(this, 0);
2683     }
2684    
2685     /**
2686     * show point on map
2687     *
2688     * @param navit The navit instance
2689     * @param center The point where to center the map, including its projection
2690     * @returns nothing
2691     */
2692 zoff99 27 void navit_set_center(struct navit *this_, struct pcoord *center, int set_timeout)
2693 zoff99 2 {
2694 zoff99 27 ////DBG dbg(0,"EEnter\n");
2695     struct coord *c = transform_center(this_->trans);
2696     struct coord c1, c2;
2697 zoff99 2 enum projection pro = transform_get_projection(this_->trans);
2698 zoff99 27 if (pro != center->pro)
2699     {
2700 zoff99 2 c1.x = center->x;
2701     c1.y = center->y;
2702     transform_from_to(&c1, center->pro, &c2, pro);
2703 zoff99 27 }
2704     else
2705     {
2706 zoff99 2 c2.x = center->x;
2707     c2.y = center->y;
2708     }
2709 zoff99 27 *c = c2;
2710     if (set_timeout)
2711     {
2712 zoff99 2 navit_set_timeout(this_);
2713 zoff99 27 }
2714 zoff99 2 if (this_->ready == 3)
2715 zoff99 27 {
2716 zoff99 2 navit_draw(this_);
2717 zoff99 27 }
2718 zoff99 2 }
2719    
2720 zoff99 27 static void navit_set_center_coord_screen(struct navit *this_, struct coord *c, struct point *p, int set_timeout)
2721 zoff99 2 {
2722 zoff99 27 ////DBG dbg(0,"EEnter\n");
2723 zoff99 2 int width, height;
2724     struct point po;
2725     transform_set_center(this_->trans, c);
2726     transform_get_size(this_->trans, &width, &height);
2727 zoff99 27 po.x = width / 2;
2728     po.y = height / 2;
2729 zoff99 2 update_transformation(this_->trans, &po, p, NULL);
2730     if (set_timeout)
2731 zoff99 27 {
2732 zoff99 2 navit_set_timeout(this_);
2733 zoff99 27 }
2734 zoff99 2 }
2735    
2736     /**
2737     * Links all vehicles to a cursor depending on the current profile.
2738     *
2739     * @param this_ A navit instance
2740     * @author Ralph Sennhauser (10/2009)
2741     */
2742 zoff99 27 void navit_set_cursors(struct navit *this_)
2743 zoff99 2 {
2744     struct attr name;
2745     struct navit_vehicle *nv;
2746     struct cursor *c;
2747     GList *v;
2748    
2749 zoff99 27 //dbg(0, "Enter\n");
2750    
2751     v = g_list_first(this_->vehicles); // GList of navit_vehicles
2752     while (v)
2753     {
2754     dbg(0, "* found vehicle *\n");
2755     nv = v->data;
2756     if (vehicle_get_attr(nv->vehicle, attr_cursorname, &name, NULL))
2757     {
2758     if (!strcmp(name.u.str, "none"))
2759     {
2760     c = NULL;
2761     }
2762 zoff99 2 else
2763 zoff99 27 {
2764     c = layout_get_cursor(this_->layout_current, name.u.str);
2765     }
2766     }
2767     else
2768     {
2769     c = layout_get_cursor(this_->layout_current, "default");
2770     }
2771 zoff99 2 vehicle_set_cursor(nv->vehicle, c, 0);
2772 zoff99 27 v = g_list_next(v);
2773 zoff99 2 }
2774     return;
2775     }
2776    
2777 zoff99 27 void navit_remove_cursors(struct navit *this_)
2778 zoff99 2 {
2779 zoff99 27 struct attr name;
2780     struct navit_vehicle *nv;
2781     struct cursor *c;
2782     GList *v;
2783    
2784     //dbg(0, "Enter\n");
2785     name.type = attr_cursor;
2786    
2787     v = g_list_first(this_->vehicles); // GList of navit_vehicles
2788     while (v)
2789     {
2790     dbg(0, "* found vehicle *\n");
2791     nv = v->data;
2792     vehicle_remove_attr(nv->vehicle, &name);
2793     v = g_list_next(v);
2794     }
2795     return;
2796     }
2797    
2798     static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir)
2799     {
2800     ////DBG dbg(0,"EEnter\n");
2801 zoff99 2 int width, height;
2802 zoff99 27 struct navit_vehicle *nv = this_->vehicle;
2803 zoff99 2
2804 zoff99 27 float offset = this_->radius; // Cursor offset from the center of the screen (percent).
2805 zoff99 2 #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 */
2806 zoff99 27 float min_offset = 0.; // Percent offset at min_offset_speed.
2807     float max_offset = 30.; // Percent offset at max_offset_speed.
2808     int min_offset_speed = 2; // Speed in km/h
2809     int max_offset_speed = 50; // Speed ini km/h
2810     // Calculate cursor offset from the center of the screen, upon speed.
2811     if (nv->speed <= min_offset_speed)
2812     {
2813     offset = min_offset;
2814     }
2815     else if (nv->speed > max_offset_speed)
2816     {
2817     offset = max_offset;
2818     }
2819     else
2820     {
2821     offset = (max_offset - min_offset) / (max_offset_speed - min_offset_speed) * (nv->speed - min_offset_speed);
2822     }
2823 zoff99 2 #endif
2824    
2825     transform_get_size(this_->trans, &width, &height);
2826 zoff99 27 if (this_->orientation == -1 || keep_orientation)
2827     {
2828     p->x = 50 * width / 100;
2829     p->y = (50 + offset) * height / 100;
2830     if (dir)
2831     *dir = keep_orientation ? this_->orientation : nv->dir;
2832     }
2833     else
2834     {
2835 zoff99 2 int mdir;
2836 zoff99 27 if (this_->tracking && this_->tracking_flag)
2837     {
2838 zoff99 2 mdir = tracking_get_angle(this_->tracking) - this_->orientation;
2839     }
2840 zoff99 27 else
2841     {
2842     mdir = nv->dir - this_->orientation;
2843     }
2844 zoff99 2
2845 zoff99 27 p->x = (50 - offset * sin(M_PI * mdir / 180.)) * width / 100;
2846     p->y = (50 + offset * cos(M_PI * mdir / 180.)) * height / 100;
2847 zoff99 2 if (dir)
2848 zoff99 27 *dir = this_->orientation;
2849 zoff99 2 }
2850     return 1;
2851     }
2852    
2853 zoff99 27 void navit_set_center_cursor(struct navit *this_, int autozoom, int keep_orientation)
2854 zoff99 2 {
2855 zoff99 27 ////DBG dbg(0,"EEnter\n");
2856 zoff99 2 int dir;
2857     struct point pn;
2858 zoff99 27 struct navit_vehicle *nv = this_->vehicle;
2859 zoff99 2 navit_get_cursor_pnt(this_, &pn, keep_orientation, &dir);
2860     transform_set_yaw(this_->trans, dir);
2861     navit_set_center_coord_screen(this_, &nv->coord, &pn, 0);
2862     if (autozoom)
2863     navit_autozoom(this_, &nv->coord, nv->speed, 0);
2864     }
2865    
2866 zoff99 27 static void navit_set_center_cursor_draw(struct navit *this_)
2867 zoff99 2 {
2868 zoff99 27 ////DBG dbg(0,"EEnter\n");
2869     navit_set_center_cursor(this_, 1, 0);
2870 zoff99 2 if (this_->ready == 3)
2871     {
2872 zoff99 27 ////DBG dbg(0,"navit_draw_async_005\n");
2873 zoff99 2 navit_draw_async(this_, 1);
2874     }
2875     }
2876    
2877 zoff99 27 static void navit_cmd_set_center_cursor(struct navit *this_)
2878 zoff99 2 {
2879 zoff99 27 ////DBG dbg(0,"EEnter\n");
2880 zoff99 2 navit_set_center_cursor_draw(this_);
2881     }
2882    
2883 zoff99 27 void navit_set_center_screen(struct navit *this_, struct point *p, int set_timeout)
2884 zoff99 2 {
2885 zoff99 27 ////DBG dbg(0,"EEnter\n");
2886 zoff99 2 struct coord c;
2887     struct pcoord pc;
2888     transform_reverse(this_->trans, p, &c);
2889     pc.x = c.x;
2890     pc.y = c.y;
2891     pc.pro = transform_get_projection(this_->trans);
2892     navit_set_center(this_, &pc, set_timeout);
2893     }
2894    
2895     #if 0
2896 zoff99 27 switch((*attrs)->type)
2897     {
2898     case attr_zoom:
2899     zoom=(*attrs)->u.num;
2900     break;
2901     case attr_center:
2902     g=*((*attrs)->u.coord_geo);
2903     break;
2904 zoff99 2 #endif
2905    
2906 zoff99 27 static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init)
2907 zoff99 2 {
2908 zoff99 27 ////DBG dbg(0,"EEnter\n");
2909     int dir = 0, orient_old = 0, attr_updated = 0;
2910 zoff99 2 struct coord co;
2911     long zoom;
2912     GList *l;
2913     struct navit_vehicle *nv;
2914     struct layout *lay;
2915     struct attr active;
2916 zoff99 27 active.type = attr_active;
2917     active.u.num = 0;
2918 zoff99 2
2919 zoff99 27 switch (attr->type)
2920     {
2921     case attr_autozoom:
2922     attr_updated = (this_->autozoom_secs != attr->u.num);
2923     this_->autozoom_secs = attr->u.num;
2924     break;
2925     case attr_autozoom_active:
2926     attr_updated = (this_->autozoom_active != attr->u.num);
2927     this_->autozoom_active = attr->u.num;
2928     break;
2929     case attr_center:
2930     transform_from_geo(transform_get_projection(this_->trans), attr->u.coord_geo, &co);
2931     // dbg(1, "0x%x,0x%x\n", co.x, co.y);
2932     transform_set_center(this_->trans, &co);
2933     break;
2934     case attr_drag_bitmap:
2935     attr_updated = (this_->drag_bitmap != !!attr->u.num);
2936     this_->drag_bitmap = !!attr->u.num;
2937     break;
2938     case attr_flags:
2939     attr_updated = (this_->flags != attr->u.num);
2940     this_->flags = attr->u.num;
2941     break;
2942     case attr_flags_graphics:
2943     attr_updated = (this_->graphics_flags != attr->u.num);
2944     this_->graphics_flags = attr->u.num;
2945     break;
2946     case attr_follow:
2947     if (!this_->vehicle)
2948     return 0;
2949     attr_updated = (this_->vehicle->follow_curr != attr->u.num);
2950     this_->vehicle->follow_curr = attr->u.num;
2951     break;
2952     case attr_layout:
2953     if (this_->layout_current != attr->u.layout)
2954     {
2955     this_->layout_current = attr->u.layout;
2956     graphics_font_destroy_all(this_->gra);
2957     navit_set_cursors(this_);
2958     if (this_->ready == 3)
2959     navit_draw(this_);
2960     attr_updated = 1;
2961     }
2962     break;
2963     case attr_layout_name:
2964     l = this_->layouts;
2965     while (l)
2966     {
2967     lay = l->data;
2968     if (!strcmp(lay->name, attr->u.str))
2969     {
2970     struct attr attr;
2971     attr.type = attr_layout;
2972     attr.u.layout = lay;
2973     return navit_set_attr_do(this_, &attr, init);
2974     }
2975     l = g_list_next(l);
2976     }
2977 zoff99 2 return 0;
2978 zoff99 27 case attr_map_border:
2979     if (this_->border != attr->u.num)
2980     {
2981     this_->border = attr->u.num;
2982     attr_updated = 1;
2983 zoff99 2 }
2984 zoff99 27 break;
2985     case attr_orientation:
2986     orient_old = this_->orientation;
2987     this_->orientation = attr->u.num;
2988     if (!init)
2989     {
2990     if (this_->orientation != -1)
2991     {
2992     dir = this_->orientation;
2993 zoff99 2 }
2994 zoff99 27 else
2995     {
2996     if (this_->vehicle)
2997     {
2998     dir = this_->vehicle->dir;
2999     }
3000     }
3001     transform_set_yaw(this_->trans, dir);
3002     if (orient_old != this_->orientation)
3003     {
3004 zoff99 2 #if 0
3005 zoff99 27 if (this_->ready == 3)
3006 zoff99 2 navit_draw(this_);
3007     #endif
3008 zoff99 27 attr_updated = 1;
3009     }
3010 zoff99 2 }
3011 zoff99 27 break;
3012     case attr_osd_configuration:
3013     //DBG dbg(0, "setting osd_configuration to %d (was %d)\n", attr->u.num, this_->osd_configuration);
3014     attr_updated = (this_->osd_configuration != attr->u.num);
3015     this_->osd_configuration = attr->u.num;
3016     break;
3017     case attr_pitch:
3018     attr_updated = (this_->pitch != attr->u.num);
3019     this_->pitch = attr->u.num;
3020     transform_set_pitch(this_->trans, this_->pitch);
3021     if (!init && attr_updated && this_->ready == 3)
3022     navit_draw(this_);
3023     break;
3024     case attr_projection:
3025     if (this_->trans && transform_get_projection(this_->trans) != attr->u.projection)
3026     {
3027     navit_projection_set(this_, attr->u.projection, !init);
3028     attr_updated = 1;
3029     }
3030     break;
3031     case attr_radius:
3032     attr_updated = (this_->radius != attr->u.num);
3033     this_->radius = attr->u.num;
3034     break;
3035     case attr_recent_dest:
3036     attr_updated = (this_->recentdest_count != attr->u.num);
3037     this_->recentdest_count = attr->u.num;
3038     break;
3039     case attr_speech:
3040     if (this_->speech && this_->speech != attr->u.speech)
3041     {
3042     attr_updated = 1;
3043     this_->speech = attr->u.speech;
3044     }
3045     break;
3046     case attr_timeout:
3047     attr_updated = (this_->center_timeout != attr->u.num);
3048     this_->center_timeout = attr->u.num;
3049     break;
3050     case attr_tracking:
3051     attr_updated = (this_->tracking_flag != !!attr->u.num);
3052     this_->tracking_flag = !!attr->u.num;
3053     break;
3054     case attr_transformation:
3055     this_->trans = attr->u.transformation;
3056     break;
3057     case attr_use_mousewheel:
3058     attr_updated = (this_->use_mousewheel != !!attr->u.num);
3059     this_->use_mousewheel = !!attr->u.num;
3060     break;
3061     case attr_vehicle:
3062     l = this_->vehicles;
3063     while (l)
3064     {
3065     nv = l->data;
3066     if (nv->vehicle == attr->u.vehicle)
3067     {
3068     if (!this_->vehicle || this_->vehicle->vehicle != attr->u.vehicle)
3069     {
3070     if (this_->vehicle)
3071     vehicle_set_attr(this_->vehicle->vehicle, &active);
3072     active.u.num = 1;
3073     vehicle_set_attr(nv->vehicle, &active);
3074     attr_updated = 1;
3075     }
3076     navit_set_vehicle(this_, nv);
3077 zoff99 2 }
3078 zoff99 27 l = g_list_next(l);
3079 zoff99 2 }
3080 zoff99 27 break;
3081     case attr_zoom:
3082     zoom = transform_get_scale(this_->trans);
3083     attr_updated = (zoom != attr->u.num);
3084     transform_set_scale(this_->trans, attr->u.num);
3085     if (attr_updated && !init)
3086     navit_draw(this_);
3087     break;
3088     case attr_zoom_min:
3089     attr_updated = (attr->u.num != this_->zoom_min);
3090     this_->zoom_min = attr->u.num;
3091     break;
3092     case attr_zoom_max:
3093     attr_updated = (attr->u.num != this_->zoom_max);
3094     this_->zoom_max = attr->u.num;
3095     break;
3096     case attr_message:
3097     //navit_add_message(this_, attr->u.str);
3098     break;
3099     case attr_follow_cursor:
3100     attr_updated = (this_->follow_cursor != !!attr->u.num);
3101     this_->follow_cursor = !!attr->u.num;
3102     break;
3103     case attr_imperial:
3104     attr_updated = (this_->imperial != attr->u.num);
3105     this_->imperial = attr->u.num;
3106     break;
3107     default:
3108     return 0;
3109 zoff99 2 }
3110 zoff99 27 if (attr_updated && !init)
3111     {
3112 zoff99 2 callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
3113     if (attr->type == attr_osd_configuration)
3114     graphics_draw_mode(this_->gra, draw_mode_end);
3115     }
3116     return 1;
3117     }
3118    
3119 zoff99 27 int navit_set_attr(struct navit *this_, struct attr *attr)
3120 zoff99 2 {
3121 zoff99 27 ////DBG dbg(0,"EEnter\n");
3122 zoff99 2 return navit_set_attr_do(this_, attr, 0);
3123     }
3124    
3125 zoff99 27 int navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
3126 zoff99 2 {
3127 zoff99 27 ////DBG dbg(0,"EEnter\n");
3128 zoff99 2 struct message *msg;
3129 zoff99 27 int len, offset;
3130     int ret = 1;
3131 zoff99 2
3132 zoff99 27 switch (type)
3133     {
3134     case attr_message:
3135 zoff99 2 return 0;
3136 zoff99 27 /*
3137     msg = navit_get_messages(this_);
3138 zoff99 2
3139 zoff99 27 if (!msg)
3140     {
3141     return 0;
3142     }
3143 zoff99 2
3144 zoff99 27 len = 0;
3145     while (msg)
3146     {
3147     len += strlen(msg->text) + 1;
3148     msg = msg->next;
3149     }
3150     attr->u.str = g_malloc(len + 1);
3151 zoff99 2
3152 zoff99 27 msg = navit_get_messages(this_);
3153     offset = 0;
3154     while (msg)
3155     {
3156     g_stpcpy((attr->u.str + offset), msg->text);
3157     offset += strlen(msg->text);
3158     attr->u.str[offset] = '\n';
3159     offset++;
3160    
3161     msg = msg->next;
3162     }
3163    
3164     attr->u.str[len] = '\0';
3165     */
3166     break;
3167     case attr_imperial:
3168     attr->u.num = this_->imperial;
3169     break;
3170     case attr_bookmark_map:
3171     attr->u.map = bookmarks_get_map(this_->bookmarks);
3172     break;
3173     case attr_bookmarks:
3174     attr->u.bookmarks = this_->bookmarks;
3175     break;
3176     case attr_callback_list:
3177     attr->u.callback_list = this_->attr_cbl;
3178     break;
3179     case attr_destination:
3180     if (!this_->destination_valid)
3181     return 0;
3182     attr->u.pcoord = &this_->destination;
3183     break;
3184     case attr_displaylist:
3185     attr->u.displaylist = this_->displaylist;
3186     return (attr->u.displaylist != NULL);
3187     case attr_follow:
3188     if (!this_->vehicle)
3189     return 0;
3190     attr->u.num = this_->vehicle->follow_curr;
3191     break;
3192     case attr_former_destination_map:
3193     attr->u.map = this_->former_destination;
3194     break;
3195     case attr_graphics:
3196     attr->u.graphics = this_->gra;
3197     ret = (attr->u.graphics != NULL);
3198     break;
3199     case attr_gui:
3200     attr->u.gui = this_->gui;
3201     ret = (attr->u.gui != NULL);
3202     break;
3203     case attr_layout:
3204     if (iter)
3205 zoff99 2 {
3206 zoff99 27 if (iter->u.list)
3207     {
3208     iter->u.list = g_list_next(iter->u.list);
3209     }
3210     else
3211     {
3212     iter->u.list = this_->layouts;
3213     }
3214     if (!iter->u.list)
3215     {
3216     return 0;
3217     }
3218     attr->u.layout = (struct layout *) iter->u.list->data;
3219 zoff99 2 }
3220     else
3221     {
3222 zoff99 27 attr->u.layout = this_->layout_current;
3223 zoff99 2 }
3224 zoff99 27 break;
3225     case attr_map:
3226     if (iter && this_->mapsets)
3227 zoff99 2 {
3228 zoff99 27 if (!iter->u.mapset_handle)
3229     {
3230     iter->u.mapset_handle = mapset_open((struct mapset *) this_->mapsets->data);
3231     }
3232     attr->u.map = mapset_next(iter->u.mapset_handle, 0);
3233     if (!attr->u.map)
3234     {
3235     mapset_close(iter->u.mapset_handle);
3236     return 0;
3237     }
3238     }
3239     else
3240     {
3241 zoff99 2 return 0;
3242     }
3243 zoff99 27 break;
3244     case attr_mapset:
3245     attr->u.mapset = this_->mapsets->data;
3246     ret = (attr->u.mapset != NULL);
3247     break;
3248     case attr_navigation:
3249     attr->u.navigation = this_->navigation;
3250     break;
3251     case attr_orientation:
3252     attr->u.num = this_->orientation;
3253     break;
3254     case attr_osd_configuration:
3255     attr->u.num = this_->osd_configuration;
3256     break;
3257     case attr_pitch:
3258     attr->u.num = transform_get_pitch(this_->trans);
3259     break;
3260     case attr_projection:
3261     if (this_->trans)
3262     {
3263     attr->u.num = transform_get_projection(this_->trans);
3264 zoff99 2 }
3265 zoff99 27 else
3266     {
3267 zoff99 2 return 0;
3268     }
3269 zoff99 27 break;
3270     case attr_route:
3271     attr->u.route = this_->route;
3272     break;
3273     case attr_speech:
3274     attr->u.speech = this_->speech;
3275     break;
3276     case attr_tracking:
3277     attr->u.num = this_->tracking_flag;
3278     break;
3279     case attr_trackingo:
3280     attr->u.tracking = this_->tracking;
3281     break;
3282     case attr_transformation:
3283     attr->u.transformation = this_->trans;
3284     break;
3285     case attr_vehicle:
3286     if (iter)
3287     {
3288     if (iter->u.list)
3289     {
3290     iter->u.list = g_list_next(iter->u.list);
3291     }
3292     else
3293     {
3294     iter->u.list = this_->vehicles;
3295     }
3296     if (!iter->u.list)
3297     return 0;
3298     attr->u.vehicle = ((struct navit_vehicle*) iter->u.list->data)->vehicle;
3299 zoff99 2 }
3300 zoff99 27 else
3301     {
3302     if (this_->vehicle)
3303     {
3304     attr->u.vehicle = this_->vehicle->vehicle;
3305     }
3306     else
3307     {
3308     return 0;
3309     }
3310 zoff99 2 }
3311 zoff99 27 break;
3312     case attr_vehicleprofile:
3313     attr->u.vehicleprofile = this_->vehicleprofile;
3314     break;
3315     case attr_zoom:
3316     attr->u.num = transform_get_scale(this_->trans);
3317     break;
3318     case attr_autozoom_active:
3319     attr->u.num = this_->autozoom_active;
3320     break;
3321     case attr_follow_cursor:
3322     attr->u.num = this_->follow_cursor;
3323     break;
3324     default:
3325     return 0;
3326 zoff99 2 }
3327 zoff99 27 attr->type = type;
3328 zoff99 2 return ret;
3329     }
3330    
3331 zoff99 27 static int navit_add_log(struct navit *this_, struct log *log)
3332 zoff99 2 {
3333     struct attr type_attr;
3334     if (!log_get_attr(log, attr_type, &type_attr, NULL))
3335     return 0;
3336 zoff99 27 if (!strcmp(type_attr.u.str, "textfile_debug"))
3337     {
3338 zoff99 2 char *header = "type=track_tracked\n";
3339     if (this_->textfile_debug_log)
3340     return 0;
3341     log_set_header(log, header, strlen(header));
3342 zoff99 27 this_->textfile_debug_log = log;
3343 zoff99 2 return 1;
3344     }
3345     return 0;
3346     }
3347    
3348 zoff99 27 static int navit_add_layout(struct navit *this_, struct layout *layout)
3349 zoff99 2 {
3350 zoff99 27 ////DBG dbg(0,"EEnter\n");
3351 zoff99 2 struct attr active;
3352     this_->layouts = g_list_append(this_->layouts, layout);
3353     layout_get_attr(layout, attr_active, &active, NULL);
3354 zoff99 27 if (active.u.num || !this_->layout_current)
3355     {
3356     this_->layout_current = layout;
3357 zoff99 2 return 1;
3358     }
3359     return 0;
3360     }
3361    
3362 zoff99 27 int navit_add_attr(struct navit *this_, struct attr *attr)
3363 zoff99 2 {
3364 zoff99 27 ////DBG dbg(0,"EEnter\n");
3365 zoff99 2
3366 zoff99 27 int ret = 1;
3367     switch (attr->type)
3368     {
3369     case attr_callback:
3370     navit_add_callback(this_, attr->u.callback);
3371     break;
3372     case attr_log:
3373     ret = navit_add_log(this_, attr->u.log);
3374     break;
3375     case attr_gui:
3376     ret = navit_set_gui(this_, attr->u.gui);
3377     break;
3378     case attr_graphics:
3379     ret = navit_set_graphics(this_, attr->u.graphics);
3380     break;
3381     case attr_layout:
3382     ret = navit_add_layout(this_, attr->u.layout);
3383     break;
3384     case attr_route:
3385     this_->route = attr->u.route;
3386     break;
3387     case attr_mapset:
3388     this_->mapsets = g_list_append(this_->mapsets, attr->u.mapset);
3389     break;
3390     case attr_navigation:
3391     this_->navigation = attr->u.navigation;
3392     break;
3393     case attr_recent_dest:
3394     this_->recentdest_count = attr->u.num;
3395     break;
3396     case attr_speech:
3397     this_->speech = attr->u.speech;
3398     break;
3399     case attr_tracking:
3400     this_->tracking = attr->u.tracking;
3401     break;
3402     case attr_vehicle:
3403     ret = navit_add_vehicle(this_, attr->u.vehicle);
3404     break;
3405     case attr_vehicleprofile:
3406     this_->vehicleprofiles = g_list_prepend(this_->vehicleprofiles, attr->u.vehicleprofile);
3407     break;
3408     case attr_autozoom_min:
3409     this_->autozoom_min = attr->u.num;
3410     break;
3411     default:
3412     return 0;
3413 zoff99 2 }
3414     callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
3415     return ret;
3416     }
3417    
3418 zoff99 27 int navit_remove_attr(struct navit *this_, struct attr *attr)
3419 zoff99 2 {
3420 zoff99 27 int ret = 1;
3421     switch (attr->type)
3422     {
3423     case attr_callback:
3424     navit_remove_callback(this_, attr->u.callback);
3425     break;
3426     default:
3427     return 0;
3428 zoff99 2 }
3429     return ret;
3430     }
3431    
3432     struct attr_iter *
3433     navit_attr_iter_new(void)
3434     {
3435 zoff99 27 return g_new0(struct attr_iter, 1);
3436 zoff99 2 }
3437    
3438 zoff99 27 void navit_attr_iter_destroy(struct attr_iter *iter)
3439 zoff99 2 {
3440     g_free(iter);
3441     }
3442    
3443 zoff99 27 void navit_add_callback(struct navit *this_, struct callback *cb)
3444 zoff99 2 {
3445 zoff99 27 ////DBG dbg(0,"EEnter\n");
3446 zoff99 2
3447     callback_list_add(this_->attr_cbl, cb);
3448     }
3449    
3450 zoff99 27 void navit_remove_callback(struct navit *this_, struct callback *cb)
3451 zoff99 2 {
3452 zoff99 27 ////DBG dbg(0,"EEnter\n");
3453 zoff99 2
3454     callback_list_remove(this_->attr_cbl, cb);
3455     }
3456    
3457     /**
3458     * Toggle the cursor update : refresh the map each time the cursor has moved (instead of only when it reaches a border)
3459     *
3460     * @param navit The navit instance
3461     * @returns nothing
3462     */
3463    
3464 zoff99 27 static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt)
3465 zoff99 2 {
3466 zoff99 27 ////DBG dbg(0,"EEnter\n");
3467 zoff99 2
3468     struct point cursor_pnt;
3469     enum projection pro;
3470    
3471     if (this_->blocked)
3472     return;
3473     if (pnt)
3474     {
3475 zoff99 27 cursor_pnt = *pnt;
3476 zoff99 2 }
3477     else
3478     {
3479 zoff99 27 pro = transform_get_projection(this_->trans_cursor);
3480 zoff99 2 if (!pro)
3481     return;
3482     transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
3483     }
3484 zoff99 27 ////DBG dbg(0,"xx=%d\n",cursor_pnt.x);
3485     ////DBG dbg(0,"yy=%d\n",cursor_pnt.y);
3486 zoff99 2
3487 zoff99 27 global_vehicle_pos_onscreen.x = cursor_pnt.x;
3488     global_vehicle_pos_onscreen.y = cursor_pnt.y;
3489 zoff99 2
3490 zoff99 27 ////DBG dbg(0,"xx=%d\n",pnt->x);
3491     ////DBG dbg(0,"yy=%d\n",pnt->y);
3492     ////DBG dbg(0,"vehicle_draw_001\n");
3493     vehicle_draw(nv->vehicle, this_->gra, &cursor_pnt, pnt ? 0 : 1, nv->dir - transform_get_yaw(this_->trans_cursor), nv->speed);
3494 zoff99 2 #if 0
3495     if (pnt)
3496 zoff99 27 pnt2=*pnt;
3497     else
3498     {
3499 zoff99 2 pro=transform_get_projection(this_->trans);
3500     transform(this_->trans, pro, &nv->coord, &pnt2, 1);
3501     }
3502     #if 1
3503     cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL);
3504     #else
3505     cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, 1);
3506     #endif
3507     #endif
3508     }
3509    
3510 zoff99 27 static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv)
3511 zoff99 2 {
3512 zoff99 27 //DBG dbg(0,"EEnter\n");
3513 zoff99 2
3514     struct attr attr_valid, attr_dir, attr_speed, attr_pos;
3515     struct pcoord cursor_pc;
3516 zoff99 27 struct point cursor_pnt, *pnt = &cursor_pnt;
3517     struct tracking *tracking = NULL;
3518 zoff99 2 struct pcoord pc[16];
3519 zoff99 27 enum projection pro = transform_get_projection(this_->trans_cursor);
3520 zoff99 2 int count;
3521     int (*get_attr)(void *, enum attr_type, struct attr *, struct attr_iter *);
3522     void *attr_object;
3523     char *destination_file;
3524    
3525 zoff99 27 // //DBG dbg(0,"navit_vehicle_update_001 %d\n",pro);
3526 zoff99 2 //profile(0,NULL);
3527 zoff99 27 if (this_->ready != 3)
3528     {
3529 zoff99 2 //profile(0,"return 1\n");
3530     return;
3531     }
3532     navit_layout_switch(this_);
3533     if (this_->vehicle == nv && this_->tracking_flag)
3534 zoff99 27 tracking = this_->tracking;
3535     if (tracking)
3536     {
3537 zoff99 2 tracking_update(tracking, nv->vehicle, this_->vehicleprofile, pro);
3538 zoff99 27 attr_object = tracking;
3539     get_attr = (int(*)(void *, enum attr_type, struct attr *, struct attr_iter *)) tracking_get_attr;
3540 zoff99 2 }
3541 zoff99 27 else
3542     {
3543     attr_object = nv->vehicle;
3544     get_attr = (int(*)(void *, enum attr_type, struct attr *, struct attr_iter *)) vehicle_get_attr;
3545     }
3546 zoff99 2 if (get_attr(attr_object, attr_position_valid, &attr_valid, NULL))
3547     if (!attr_valid.u.num != attr_position_valid_invalid)
3548     return;
3549 zoff99 27 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))
3550     {
3551 zoff99 2 // profile(0,"return 2\n");
3552     return;
3553     }
3554 zoff99 27 nv->dir = *attr_dir.u.numd;
3555     nv->speed = *attr_speed.u.numd;
3556 zoff99 2 transform_from_geo(pro, attr_pos.u.coord_geo, &nv->coord);
3557     if (nv != this_->vehicle)
3558     {
3559 zoff99 27 ////DBG dbg(0,"---> 2 x=%d\n", nv->coord.x);
3560     ////DBG dbg(0,"---> 2 y=%d\n", nv->coord.y);
3561     // //DBG dbg(0,"vehicle_draw_002\n");
3562 zoff99 2 navit_vehicle_draw(this_, nv, NULL);
3563     // profile(0,"return 3\n");
3564     return;
3565     }
3566     cursor_pc.x = nv->coord.x;
3567     cursor_pc.y = nv->coord.y;
3568     cursor_pc.pro = pro;
3569 zoff99 27 if (this_->route)
3570     {
3571 zoff99 2 if (tracking)
3572     route_set_position_from_tracking(this_->route, tracking, pro);
3573     else
3574     route_set_position(this_->route, &cursor_pc);
3575     }
3576     callback_list_call_attr_0(this_->attr_cbl, attr_position);
3577 zoff99 27 // navit_textfile_debug_log(this_, "type=trackpoint_tracked");
3578 zoff99 2 if (this_->gui && nv->speed > MYSTERY_SPEED)
3579     navit_disable_suspend();
3580     transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
3581 zoff99 27 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)))
3582 zoff99 2 {
3583     navit_set_center_cursor_draw(this_);
3584 zoff99 27 ////DBG dbg(0,"---> xxCENTER\n");
3585     ////DBG dbg(0,"---> 3 x=%d\n", nv->coord.x);
3586     ////DBG dbg(0,"---> 3 y=%d\n", nv->coord.y);
3587 zoff99 2
3588 zoff99 27 ////DBG dbg(0,"---> 4 x=%d\n", cursor_pnt.x);
3589     ////DBG dbg(0,"---> 4 y=%d\n", cursor_pnt.y);
3590 zoff99 2
3591     //global_vehicle_pos_onscreen.x=cursor_pnt.x;
3592     //global_vehicle_pos_onscreen.y=cursor_pnt.y;
3593    
3594     }
3595     else
3596     {
3597 zoff99 27 ////DBG dbg(0,"vehicle_draw_003\n");
3598 zoff99 2 navit_vehicle_draw(this_, nv, pnt);
3599     //global_vehicle_pos_onscreen.x=pnt->x;
3600     //global_vehicle_pos_onscreen.y=pnt->y;
3601 zoff99 27 ////DBG dbg(0,"---> x=%d\n", pnt->x);
3602     ////DBG dbg(0,"---> y=%d\n", pnt->y);
3603 zoff99 2 }
3604    
3605     if (nv->follow_curr > 1)
3606     nv->follow_curr--;
3607     else
3608 zoff99 27 nv->follow_curr = nv->follow;
3609 zoff99 2 callback_list_call_attr_2(this_->attr_cbl, attr_position_coord_geo, this_, nv->vehicle);
3610    
3611     /* Finally, if we reached our destination, stop navigation. */
3612 zoff99 27 if (this_->route)
3613     {
3614     switch (route_destination_reached(this_->route))
3615     {
3616     case 1:
3617     route_remove_waypoint(this_->route);
3618     count = route_get_destinations(this_->route, pc, 16);
3619    
3620     // destination_file = bookmarks_get_destination_file(TRUE);
3621     // bookmarks_append_coord(this_->bookmarks, destination_file, pc, count, "former_itinerary_part", NULL, NULL, this_->recentdest_count);
3622    
3623 zoff99 14 #ifdef HAVE_API_ANDROID
3624 zoff99 27 // waypoint reached
3625     android_return_generic_int(5, 1);
3626     android_send_generic_text(1,"+*#O:Waypoint reached\n");
3627     // say it
3628     navit_say(this_, _("Waypoint reached"));
3629 zoff99 14 #endif
3630 zoff99 27 break;
3631     case 2:
3632     navit_set_destination(this_, NULL, NULL, 0);
3633     // ** inform java that we reached our destination **
3634 zoff99 14 #ifdef HAVE_API_ANDROID
3635 zoff99 27 android_return_generic_int(4, 1);
3636     android_send_generic_text(1,"+*#O:You have reached your destination\n");
3637     // say it
3638     navit_say(this_, _("You have reached your destination"));
3639 zoff99 14 #endif
3640 zoff99 27 break;
3641 zoff99 2 }
3642     }
3643     //profile(0,"return 5\n");
3644 zoff99 27 // //DBG dbg(0,"navit_vehicle_update_999\n");
3645 zoff99 2 }
3646    
3647     /**
3648     * Set the position of the vehicle
3649     *
3650     * @param navit The navit instance
3651     * @param c The coordinate to set as position
3652     * @returns nothing
3653     */
3654    
3655 zoff99 27 void navit_set_position(struct navit *this_, struct pcoord *c)
3656 zoff99 2 {
3657 zoff99 27 //DBG dbg(0,"EEnter\n");
3658 zoff99 2
3659 zoff99 27 if (this_->route)
3660     {
3661 zoff99 2 route_set_position(this_->route, c);
3662     callback_list_call_attr_0(this_->attr_cbl, attr_position);
3663     }
3664     if (this_->ready == 3)
3665     navit_draw(this_);
3666     }
3667    
3668 zoff99 27 static int navit_set_vehicleprofile(struct navit *this_, char *name)
3669 zoff99 2 {
3670 zoff99 27 ////DBG dbg(0,"EEnter\n");
3671 zoff99 2
3672     struct attr attr;
3673     GList *l;
3674 zoff99 27 l = this_->vehicleprofiles;
3675     while (l)
3676     {
3677     if (vehicleprofile_get_attr(l->data, attr_name, &attr, NULL))
3678     {
3679     if (!strcmp(attr.u.str, name))
3680     {
3681     this_->vehicleprofile = l->data;
3682 zoff99 2 if (this_->route)
3683     route_set_profile(this_->route, this_->vehicleprofile);
3684     return 1;
3685     }
3686     }
3687 zoff99 27 l = g_list_next(l);
3688 zoff99 2 }
3689     return 0;
3690     }
3691    
3692 zoff99 27 static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv)
3693 zoff99 2 {
3694 zoff99 27 ////DBG dbg(0,"EEnter\n");
3695 zoff99 2
3696     struct attr attr;
3697 zoff99 27 this_->vehicle = nv;
3698     if (nv && vehicle_get_attr(nv->vehicle, attr_profilename, &attr, NULL))
3699     {
3700 zoff99 2 if (navit_set_vehicleprofile(this_, attr.u.str))
3701 zoff99 27 {
3702 zoff99 2 return;
3703 zoff99 27 }
3704 zoff99 2 }
3705 zoff99 27 if (!navit_set_vehicleprofile(this_, "car"))
3706     {
3707 zoff99 2 /* We do not have a fallback "car" profile
3708 zoff99 27 * so lets set any profile */
3709 zoff99 2 GList *l;
3710 zoff99 27 l = this_->vehicleprofiles;
3711     if (l)
3712     {
3713     this_->vehicleprofile = l->data;
3714     if (this_->route)
3715     {
3716     route_set_profile(this_->route, this_->vehicleprofile);
3717     }
3718 zoff99 2 }
3719     }
3720     }
3721    
3722     /**
3723     * Register a new vehicle
3724     *
3725     * @param navit The navit instance
3726     * @param v The vehicle instance
3727     * @returns 1 for success
3728     */
3729 zoff99 27 int navit_add_vehicle(struct navit *this_, struct vehicle *v)
3730 zoff99 2 {
3731 zoff99 27 ////DBG dbg(0,"EEnter\n");
3732 zoff99 2
3733     struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1);
3734     struct attr follow, active, animate;
3735 zoff99 27 nv->vehicle = v;
3736     nv->follow = 0;
3737 zoff99 2 nv->last.x = 0;
3738     nv->last.y = 0;
3739 zoff99 27 nv->animate_cursor = 0;
3740 zoff99 2 if ((vehicle_get_attr(v, attr_follow, &follow, NULL)))
3741 zoff99 27 nv->follow = follow.u.num;
3742     nv->follow_curr = nv->follow;
3743     this_->vehicles = g_list_append(this_->vehicles, nv);
3744 zoff99 2 if ((vehicle_get_attr(v, attr_active, &active, NULL)) && active.u.num)
3745     navit_set_vehicle(this_, nv);
3746     if ((vehicle_get_attr(v, attr_animate, &animate, NULL)))
3747 zoff99 27 nv->animate_cursor = animate.u.num;
3748     nv->callback.type = attr_callback;
3749     nv->callback.u.callback = callback_new_attr_2(callback_cast(navit_vehicle_update), attr_position_coord_geo, this_, nv);
3750 zoff99 2 vehicle_add_attr(nv->vehicle, &nv->callback);
3751     vehicle_set_attr(nv->vehicle, &this_->self);
3752     return 1;
3753     }
3754    
3755     struct gui *
3756     navit_get_gui(struct navit *this_)
3757     {
3758     return this_->gui;
3759     }
3760    
3761     struct transformation *
3762     navit_get_trans(struct navit *this_)
3763     {
3764     return this_->trans;
3765     }
3766    
3767     struct route *
3768     navit_get_route(struct navit *this_)
3769     {
3770     return this_->route;
3771     }
3772    
3773     struct navigation *
3774     navit_get_navigation(struct navit *this_)
3775     {
3776     return this_->navigation;
3777     }
3778    
3779     struct displaylist *
3780     navit_get_displaylist(struct navit *this_)
3781     {
3782     return this_->displaylist;
3783     }
3784    
3785 zoff99 27 void navit_layout_switch(struct navit *n)
3786 zoff99 2 {
3787 zoff99 27 ////DBG dbg(0,"EEnter\n");
3788 zoff99 2
3789 zoff99 27 int currTs = 0;
3790     struct attr iso8601_attr, geo_attr, valid_attr, layout_attr;
3791     double trise, tset, trise_actual;
3792     struct layout *l;
3793     int year, month, day;
3794    
3795     if (navit_get_attr(n, attr_layout, &layout_attr, NULL) != 1)
3796     {
3797     return; //No layout - nothing to switch
3798 zoff99 2 }
3799 zoff99 27 if (!n->vehicle)
3800 zoff99 2 return;
3801 zoff99 27 l = layout_attr.u.layout;
3802    
3803     if (l->dayname || l->nightname)
3804     {
3805     //Ok, we know that we have profile to switch
3806    
3807     //Check that we aren't calculating too fast
3808     if (vehicle_get_attr(n->vehicle->vehicle, attr_position_time_iso8601, &iso8601_attr, NULL) == 1)
3809     {
3810     currTs = iso8601_to_secs(iso8601_attr.u.str);
3811     // dbg(1, "currTs: %u:%u\n", currTs % 86400 / 3600, ((currTs % 86400) % 3600) / 60);
3812 zoff99 2 }
3813 zoff99 27 if (currTs - (n->prevTs) < 60)
3814     {
3815     //We've have to wait a little
3816     return;
3817 zoff99 2 }
3818 zoff99 27 if (sscanf(iso8601_attr.u.str, "%d-%02d-%02dT", &year, &month, &day) != 3)
3819     return;
3820     if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &valid_attr, NULL) && valid_attr.u.num == attr_position_valid_invalid)
3821     {
3822     return; //No valid fix yet
3823     }
3824     if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo, &geo_attr, NULL) != 1)
3825     {
3826     //No position - no sun
3827     return;
3828     }
3829    
3830     //We calculate sunrise anyway, cause it is needed both for day and for night
3831     if (__sunriset__(year, month, day, geo_attr.u.coord_geo->lng, geo_attr.u.coord_geo->lat, -5, 1, &trise, &tset) != 0)
3832     {
3833     //near the pole sun never rises/sets, so we should never switch profiles
3834     // dbg(1, "trise: %u:%u, sun never visible, never switch profile\n", HOURS(trise), MINUTES(trise));
3835     n->prevTs = currTs;
3836     return;
3837     }
3838    
3839     trise_actual = trise;
3840     // dbg(1, "trise: %u:%u\n", HOURS(trise), MINUTES(trise));
3841     if (l->dayname)
3842     {
3843    
3844     if ((HOURS(trise) * 60 + MINUTES(trise) == (currTs % 86400) / 60) || (n->prevTs == 0 && ((HOURS(trise) * 60 + MINUTES(trise) < (currTs % 86400) / 60))))
3845     {
3846     //The sun is rising now!
3847     if (strcmp(l->name, l->dayname))
3848     {
3849     navit_set_layout_by_name(n, l->dayname);
3850     }
3851     }
3852     }
3853     if (l->nightname)
3854     {
3855     if (__sunriset__(year, month, day, geo_attr.u.coord_geo->lng, geo_attr.u.coord_geo->lat, -5, 1, &trise, &tset) != 0)
3856     {
3857     //near the pole sun never rises/sets, so we should never switch profiles
3858     // dbg(1,"tset: %u:%u, sun always visible, never switch profile\n",HOURS(tset), MINUTES(tset));
3859     n->prevTs = currTs;
3860     return;
3861     }
3862     // dbg(1, "tset: %u:%u\n", HOURS(tset), MINUTES(tset));
3863     if (HOURS(tset) * 60 + MINUTES(tset) == ((currTs % 86400) / 60) || (n->prevTs == 0 && (((HOURS(tset) * 60 + MINUTES(tset) < (currTs % 86400) / 60)) || ((HOURS(trise_actual) * 60 + MINUTES(trise_actual) > (currTs % 86400) / 60)))))
3864     {
3865     //Time to sleep
3866     if (strcmp(l->name, l->nightname))
3867     {
3868     navit_set_layout_by_name(n, l->nightname);
3869     }
3870     }
3871     }
3872    
3873     n->prevTs = currTs;
3874 zoff99 2 }
3875     }
3876    
3877 zoff99 27 int navit_set_vehicle_by_name(struct navit *n, const char *name)
3878 zoff99 2 {
3879 zoff99 27 ////DBG dbg(0,"EEnter\n");
3880 zoff99 2
3881 zoff99 27 struct vehicle *v;
3882     struct attr_iter *iter;
3883     struct attr vehicle_attr, name_attr;
3884 zoff99 2
3885 zoff99 27 iter = navit_attr_iter_new();
3886 zoff99 2
3887 zoff99 27 while (navit_get_attr(n, attr_vehicle, &vehicle_attr, iter))
3888     {
3889     v = vehicle_attr.u.vehicle;
3890     vehicle_get_attr(v, attr_name, &name_attr, NULL);
3891     if (name_attr.type == attr_name)
3892     {
3893     if (!strcmp(name, name_attr.u.str))
3894     {
3895     navit_set_attr(n, &vehicle_attr);
3896 zoff99 2 navit_attr_iter_destroy(iter);
3897     return 1;
3898     }
3899     }
3900     }
3901 zoff99 27 navit_attr_iter_destroy(iter);
3902     return 0;
3903 zoff99 2 }
3904    
3905 zoff99 27 int navit_set_layout_by_name(struct navit *n, const char *name)
3906 zoff99 2 {
3907 zoff99 27 ////DBG dbg(0,"EEnter\n");
3908 zoff99 2
3909 zoff99 27 struct layout *l;
3910     struct attr_iter iter;
3911     struct attr layout_attr;
3912 zoff99 2
3913 zoff99 27 iter.u.list = 0x00;
3914 zoff99 2
3915 zoff99 27 if (navit_get_attr(n, attr_layout, &layout_attr, &iter) != 1)
3916     {
3917     return 0; //No layouts - nothing to do
3918 zoff99 2 }
3919 zoff99 27 if (iter.u.list == NULL)
3920     {
3921     return 0;
3922     }
3923 zoff99 2
3924 zoff99 27 iter.u.list = g_list_first(iter.u.list);
3925    
3926     while (iter.u.list)
3927     {
3928     l = (struct layout*) iter.u.list->data;
3929     if (!strcmp(name, l->name))
3930     {
3931     layout_attr.u.layout = l;
3932     layout_attr.type = attr_layout;
3933     navit_set_attr(n, &layout_attr);
3934     iter.u.list = g_list_first(iter.u.list);
3935     return 1;
3936     }
3937     iter.u.list = g_list_next(iter.u.list);
3938     }
3939    
3940     iter.u.list = g_list_first(iter.u.list);
3941     return 0;
3942 zoff99 2 }
3943    
3944 zoff99 27 void navit_disable_suspend()
3945     {
3946     ////DBG dbg(0,"EEnter\n");
3947 zoff99 2
3948     gui_disable_suspend(global_navit->gui);
3949 zoff99 27 callback_list_call_attr_0(global_navit->attr_cbl, attr_unsuspend);
3950 zoff99 2 }
3951    
3952 zoff99 27 int navit_block(struct navit *this_, int block)
3953 zoff99 2 {
3954 zoff99 27 ////DBG dbg(0,"EEnter\n");
3955 zoff99 2
3956 zoff99 27 if (block > 0)