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

Contents of /navit/navit/navit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations) (download)
Wed Aug 22 17:01:27 2012 UTC (11 years, 7 months ago) by zoff99
File MIME type: text/plain
File size: 138320 byte(s)
ZANavi 2.0, lots of changes, everything in its own thread, more performance
1 /**
2 * 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 * 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 #include "map.h"
89 #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 struct attr_iter
105 {
106 union
107 {
108 GList *list;
109 struct mapset_handle *mapset_handle;
110 } u;
111 };
112
113 static int dist_to_street = 100000;
114
115 static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv);
116 static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt);
117 static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init);
118 static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir);
119 static void navit_cmd_zoom_to_route(struct navit *this);
120 static void navit_cmd_set_center_cursor(struct navit *this_);
121 static void navit_cmd_announcer_toggle(struct navit *this_);
122 static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv);
123
124 int allow_gui_internal = 0; // disable old GUI internal. it will not work anymore!
125 int routing_mode = 0;
126 int MYSTERY_SPEED = 2;
127 int offline_search_filter_duplicates = 0;
128 int offline_search_break_searching = 0;
129 char *navit_maps_dir;
130 int cancel_drawing_global = 0;
131 int global_speak_streetnames = 1;
132 int allow_large_mapfiles = 1; // allow the use of large (>2GB) mapfiles // -> value unused for now
133 int cache_size_file = 1024 * 1024 * 10; // default value was: 20971520 (~20 MB)
134 int draw_polylines_fast = 0; // default: 0
135 int limit_order_corrected = 4; // remain at this order level for drawing streets etc.
136 int shift_order = 0; // shift order level (for displaying objects) by this values (should only be bigger than zero!!)
137 int global_search_street_size_factor = 1; // make search radius for streets bigger
138 int disable_map_drawing = 0; // dont draw the map and dont read data from file (hopefully saving resources)
139 int enable_water_from_relations = 1; // do you want to draw water where the "tags" come from osm-"relations"
140 int hold_drawing = 0; // 0 -> draw normal , 1 -> dont do any drawing
141 int global_stop_demo_vehicle = 0; // 0 -> demo vehicle can move, 1 -> demo vehicle stands still
142
143 long long draw_lines_count_2 = 0;
144 long long draw_lines_count_3 = 0;
145 long long draw_lines_count_4 = 0;
146
147 int mapdraw_time[11 + 5]; // time to draw map on screen (in 1/1000 of a second) [add 5, just in case we inc it 2 times at same time because of threads]
148 int cur_mapdraw_time_index = 0;
149
150 int route_status_previous = 0;
151
152 void navit_add_mapset(struct navit *this_, struct mapset *ms)
153 {
154 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
155 dbg(0,"+#+:enter\n");
156 #endif
157 ////DBG dbg(0,"EEnter\n");
158 this_->mapsets = g_list_append(this_->mapsets, ms);
159 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
160 dbg(0,"+#+:leave\n");
161 #endif
162 }
163
164 struct mapset *
165 navit_get_mapset(struct navit *this_)
166 {
167 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
168 dbg(0,"+#+:enter\n");
169 #endif
170 ////DBG dbg(0,"EEnter\n");
171 if (this_->mapsets)
172 {
173 return this_->mapsets->data;
174 }
175 else
176 {
177 //DBG dbg(0,"No mapsets enabled! Is it on purpose? Navit can't draw a map. Please check your navit.xml\n");
178 }
179 return NULL;
180 }
181
182 struct tracking *
183 navit_get_tracking(struct navit *this_)
184 {
185 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
186 dbg(0,"+#+:enter\n");
187 #endif
188 ////DBG dbg(0,"EEnter\n");
189 return this_->tracking;
190 }
191
192 /**
193 * @brief Get the user data directory.
194 * @param[in] create - create the directory if it does not exist
195 *
196 * @return char * to the data directory string.
197 *
198 * returns the directory used to store user data files (center.txt,
199 * destination.txt, bookmark.txt, ...)
200 *
201 */
202 char*
203 navit_get_user_data_directory(int create)
204 {
205 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
206 dbg(0,"+#+:enter\n");
207 #endif
208 ////DBG dbg(0,"EEnter\n");
209 char *dir;
210 dir = getenv("NAVIT_USER_DATADIR");
211 if (create && !file_exists(dir))
212 {
213 //DBG dbg(0, "creating dir %s\n", dir);
214 if (file_mkdir(dir, 0))
215 {
216 //DBG dbg(0, "failed creating dir %s\n", dir);
217 return NULL;
218 }
219 }
220 return dir;
221 } /* end: navit_get_user_data_directory(gboolean create) */
222
223 void navit_draw_async(struct navit *this_, int async)
224 {
225 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
226 dbg(0,"+#+:enter\n");
227 #endif
228
229 //dbg(0,"DO__DRAW:ndasync enter, async=%d\n", async);
230
231 //dbg(0,"EEnter this_->blocked=%d\n",this_->blocked);
232 if (this_->blocked)
233 {
234 this_->blocked |= 2;
235 //dbg(0,"set this_->blocked=%d\n",this_->blocked);
236 // dbg(0,"DO__DRAW:ndasync return 001\n");
237 return;
238 }
239 transform_setup_source_rect(this_->trans);
240 //dbg(0,"call graphics_draw\n");
241
242 // dbg(0,"DO__DRAW:gras_draw call\n");
243 graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags | 1);
244 // dbg(0,"DO__DRAW:ndasync leave\n");
245 }
246
247 void navit_draw(struct navit *this_)
248 {
249 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
250 dbg(0,"+#+:enter\n");
251 #endif
252
253 // dbg(0,"DO__DRAW:nd:enter\n");
254
255 //dbg(0,"EEnter this_->ready=%d\n",this_->ready);
256 if (this_->ready == 3)
257 {
258 //dbg(0,"navit_draw_async_001\n");
259 // dbg(0,"DO__DRAW:navit_draw_async call\n");
260 navit_draw_async(this_, 0);
261 }
262
263 // dbg(0,"DO__DRAW:nd:leave\n");
264 }
265
266 int navit_get_ready(struct navit *this_)
267 {
268 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
269 dbg(0,"+#+:enter\n");
270 #endif
271 ////DBG dbg(0,"EEnter\n");
272 return this_->ready;
273 }
274
275 // UNUSED -----
276 // UNUSED -----
277 void navit_draw_displaylist(struct navit *this_)
278 {
279 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
280 dbg(0,"+#+:enter\n");
281 #endif
282 ////DBG dbg(0,"EEnter\n");
283 if (this_->ready == 3)
284 {
285 // //DBG dbg(0,"call graphics_displaylist_draw 2")
286 graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current, this_->graphics_flags | 1);
287 }
288 }
289
290 static void navit_map_progress(struct navit *this_)
291 {
292 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
293 dbg(0,"+#+:enter\n");
294 #endif
295 ////DBG dbg(0,"EEnter\n");
296 struct map *map;
297 struct mapset *ms;
298 struct mapset_handle *msh;
299 struct attr attr;
300 struct point p;
301 if (this_->ready != 3)
302 return;
303 p.x = 10;
304 p.y = 32;
305
306 ms = this_->mapsets->data;
307 msh = mapset_open(ms);
308 while (msh && (map = mapset_next(msh, 0)))
309 {
310 if (map_get_attr(map, attr_progress, &attr, NULL))
311 {
312 char *str = g_strdup_printf("%s ", attr.u.str);
313 graphics_draw_mode(this_->gra, draw_mode_begin);
314 graphics_draw_text_std(this_->gra, 16, str, &p);
315 g_free(str);
316 p.y += 32;
317 graphics_draw_mode(this_->gra, draw_mode_end);
318 }
319 }
320 mapset_close(msh);
321 }
322
323 static void navit_redraw_route(struct navit *this_, struct route *route, struct attr *attr)
324 {
325 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
326 dbg(0,"+#+:enter\n");
327 #endif
328
329 //dbg(0,"enter\n");
330 int updated;
331
332 if ((this_->route) && (this_->route->route_status_was_updated == 1))
333 {
334 this_->route->route_status_was_updated = 0;
335 // send route_status to java
336 #ifdef HAVE_API_ANDROID
337 android_return_generic_int(1, this_->route->route_status);
338 #endif
339 }
340
341 if (attr->type != attr_route_status)
342 {
343 ////DBG dbg(0,"ret 1\n");
344 return;
345 }
346 updated = attr->u.num;
347 ////DBG dbg(0,"updated=%d\n", updated);
348 if (this_->ready != 3)
349 {
350 ////DBG dbg(0,"ret 2\n");
351 return;
352 }
353 if (updated != route_status_path_done_new)
354 {
355 ////DBG dbg(0,"ret 3\n");
356 return;
357 }
358 if (this_->vehicle)
359 {
360 if (this_->vehicle->follow_curr == 1)
361 {
362 ////DBG dbg(0,"ret 4\n");
363 ////DBG dbg(0,"disabled -> we want redraw!!\n");
364 // return;
365 }
366 if (this_->vehicle->follow_curr <= this_->vehicle->follow)
367 {
368 this_->vehicle->follow_curr = this_->vehicle->follow;
369 }
370 }
371 ////DBG dbg(0,"draw s*\n");
372 navit_draw(this_);
373 ////DBG dbg(0,"draw e*\n");
374 }
375
376 void navit_handle_resize(struct navit *this_, int w, int h)
377 {
378 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
379 dbg(0,"+#+:enter\n");
380 #endif
381
382 // dbg(0, "EEnter %p\n", this_);
383 struct map_selection sel;
384 int callback = (this_->ready == 1);
385 // dbg(0, "pre this_->ready=%d\n", this_->ready);
386 this_->ready = this_->ready | 2;
387 // dbg(0, "set this_->ready=%d\n", this_->ready);
388 memset(&sel, 0, sizeof(sel));
389 this_->w = w;
390 this_->h = h;
391 sel.u.p_rect.rl.x = w;
392 sel.u.p_rect.rl.y = h;
393 transform_set_screen_selection(this_->trans, &sel);
394 graphics_init(this_->gra);
395 graphics_set_rect(this_->gra, &sel.u.p_rect);
396 if (callback)
397 {
398 //DBG dbg(0,"callback do\n");
399 callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_);
400 }
401 if (this_->ready == 3)
402 {
403 // dbg(0, "navit_draw_async_002\n");
404 // navit_draw_async(this_, 1);
405 // dbg(0,"DO__DRAW:navit_draw_async call\n");
406 navit_draw_async(this_, 0);
407 }
408
409 // dbg(0, "return\n");
410 }
411
412 void navit_resize(void *data, int w, int h)
413 {
414 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
415 dbg(0,"+#+:enter\n");
416 #endif
417
418 //DBG dbg(0,"EEnter %p\n", data);
419 struct navit *this = data;
420 if (!this->ignore_graphics_events)
421 {
422 //DBG dbg(0,"11\n");
423 navit_handle_resize(this, w, h);
424 }
425 }
426
427 int navit_get_width(struct navit *this_)
428 {
429 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
430 dbg(0,"+#+:enter\n");
431 #endif
432 ////DBG dbg(0,"EEnter\n");
433 return this_->w;
434 }
435
436 int navit_get_height(struct navit *this_)
437 {
438 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
439 dbg(0,"+#+:enter\n");
440 #endif
441 ////DBG dbg(0,"EEnter\n");
442 return this_->h;
443 }
444
445 static void navit_popup(void *data)
446 {
447 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
448 dbg(0,"+#+:enter\n");
449 #endif
450 ////DBG dbg(0,"EEnter\n");
451 struct navit *this_ = data;
452 popup(this_, 1, &this_->pressed);
453 this_->button_timeout = NULL;
454 this_->popped = 1;
455 }
456
457 int navit_ignore_button(struct navit *this_)
458 {
459 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
460 dbg(0,"+#+:enter\n");
461 #endif
462 ////DBG dbg(0,"EEnter\n");
463 if (this_->ignore_button)
464 return 1;
465 this_->ignore_button = 1;
466 return 0;
467 }
468
469 void navit_ignore_graphics_events(struct navit *this_, int ignore)
470 {
471 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
472 dbg(0,"+#+:enter\n");
473 #endif
474 ////DBG dbg(0,"EEnter\n");
475 this_->ignore_graphics_events = ignore;
476 }
477
478 void update_transformation(struct transformation *tr, struct point *old, struct point *new, struct point *rot)
479 {
480 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
481 dbg(0,"+#+:enter\n");
482 #endif
483 ////DBG dbg(0,"EEnter\n");
484 struct coord co, cn;
485 struct coord c, *cp;
486 int yaw;
487 double angleo, anglen;
488
489 if (!transform_reverse(tr, old, &co))
490 return;
491 if (rot)
492 {
493 angleo = atan2(old->y - rot->y, old->x - rot->x) * 180 / M_PI;
494 anglen = atan2(new->y - rot->y, new->x - rot->x) * 180 / M_PI;
495 yaw = transform_get_yaw(tr) + angleo - anglen;
496 transform_set_yaw(tr, yaw % 360);
497 }
498 if (!transform_reverse(tr, new, &cn))
499 return;
500 cp = transform_get_center(tr);
501 c.x = cp->x + co.x - cn.x;
502 c.y = cp->y + co.y - cn.y;
503 // dbg(1, "from 0x%x,0x%x to 0x%x,0x%x\n", cp->x, cp->y, c.x, c.y);
504 transform_set_center(tr, &c);
505 }
506
507 void navit_set_timeout(struct navit *this_)
508 {
509 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
510 dbg(0,"+#+:enter\n");
511 #endif
512
513 // --------- DISABLE -----------
514 return;
515 // --------- DISABLE -----------
516 }
517
518 int navit_handle_button(struct navit *this_, int pressed, int button, struct point *p, struct callback *popup_callback)
519 {
520 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
521 dbg(0,"+#+:enter\n");
522 #endif
523 ////DBG dbg(0,"EEnter\n");
524 int border = 16;
525
526 // dbg(1, "enter %d %d (ignore %d)\n", pressed, button, this_->ignore_button);
527 callback_list_call_attr_4(this_->attr_cbl, attr_button, this_, GINT_TO_POINTER(pressed), GINT_TO_POINTER(button), p);
528 if (this_->ignore_button)
529 {
530 this_->ignore_button = 0;
531 return 0;
532 }
533 if (pressed)
534 {
535 this_->pressed = *p;
536 this_->last = *p;
537 this_->zoomed = 0;
538 if (button == 1)
539 {
540 this_->button_pressed = 1;
541 this_->moved = 0;
542 this_->popped = 0;
543 // ---- DISBALED --------
544 /*
545 if (popup_callback)
546 this_->button_timeout = event_add_timeout(500, 0, popup_callback);
547 */
548 }
549 if (button == 2)
550 navit_set_center_screen(this_, p, 1);
551 if (button == 3)
552 popup(this_, button, p);
553 if (button == 4 && this_->use_mousewheel)
554 {
555 this_->zoomed = 1;
556 navit_zoom_in(this_, 2, p);
557 }
558 if (button == 5 && this_->use_mousewheel)
559 {
560 this_->zoomed = 1;
561 navit_zoom_out(this_, 2, p);
562 }
563 }
564 else
565 {
566
567 this_->button_pressed = 0;
568 if (this_->button_timeout)
569 {
570 event_remove_timeout(this_->button_timeout);
571 this_->button_timeout = NULL;
572 if (!this_->moved && !transform_within_border(this_->trans, p, border))
573 {
574 navit_set_center_screen(this_, p, !this_->zoomed);
575 }
576 }
577 if (this_->motion_timeout)
578 {
579 event_remove_timeout(this_->motion_timeout);
580 this_->motion_timeout = NULL;
581 }
582 if (this_->moved)
583 {
584 struct point pr;
585 pr.x = this_->w / 2;
586 pr.y = this_->h;
587 #if 0
588 update_transformation(this_->trans, &this_->pressed, p, &pr);
589 #else
590 update_transformation(this_->trans, &this_->pressed, p, NULL);
591 #endif
592 graphics_draw_drag(this_->gra, NULL);
593 transform_copy(this_->trans, this_->trans_cursor);
594 graphics_overlay_disable(this_->gra, 0);
595 if (!this_->zoomed)
596 navit_set_timeout(this_);
597 navit_draw(this_);
598 }
599 else
600 return 1;
601 }
602 return 0;
603 }
604
605 static void navit_button(void *data, int pressed, int button, struct point *p)
606 {
607 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
608 dbg(0,"+#+:enter\n");
609 #endif
610 ////DBG dbg(0,"EEnter\n");
611 struct navit *this = data;
612 // dbg(1, "enter %d %d ignore %d\n", pressed, button, this->ignore_graphics_events);
613 if (!this->ignore_graphics_events)
614 {
615 if (!this->popup_callback)
616 {
617 this->popup_callback = callback_new_1(callback_cast(navit_popup), this);
618 callback_add_names(this->popup_callback, "navit_button", "navit_popup");
619 }
620 navit_handle_button(this, pressed, button, p, this->popup_callback);
621 }
622 }
623
624 // UNUSED ---
625 // UNUSED ---
626 static void navit_motion_timeout(struct navit *this_)
627 {
628 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
629 dbg(0,"+#+:enter\n");
630 #endif
631 // dbg(0,"EEnter\n");
632 int dx, dy;
633
634 if (this_->drag_bitmap)
635 {
636 struct point point;
637 point.x = (this_->current.x - this_->pressed.x);
638 point.y = (this_->current.y - this_->pressed.y);
639 if (graphics_draw_drag(this_->gra, &point))
640 {
641 graphics_overlay_disable(this_->gra, 1);
642 graphics_draw_mode(this_->gra, draw_mode_end);
643 this_->moved = 1;
644 this_->motion_timeout = NULL;
645 return;
646 }
647 }
648 dx = (this_->current.x - this_->last.x);
649 dy = (this_->current.y - this_->last.y);
650 if (dx || dy)
651 {
652 struct transformation *tr;
653 struct point pr;
654 this_->last = this_->current;
655 graphics_overlay_disable(this_->gra, 1);
656 tr = transform_dup(this_->trans);
657 pr.x = this_->w / 2;
658 pr.y = this_->h;
659 #if 0
660 update_transformation(tr, &this_->pressed, &this_->current, &pr);
661 #else
662 update_transformation(tr, &this_->pressed, &this_->current, NULL);
663 #endif
664 #if 0
665 graphics_displaylist_move(this_->displaylist, dx, dy);
666 #endif
667 graphics_draw_cancel(this_->gra, this_->displaylist); // --> calls "do_draw" normally
668 graphics_displaylist_draw(this_->gra, this_->displaylist, tr, this_->layout_current, this_->graphics_flags);
669
670 transform_destroy(tr);
671 this_->moved = 1;
672 }
673 this_->motion_timeout = NULL;
674 return;
675 }
676
677 void navit_handle_motion(struct navit *this_, struct point *p)
678 {
679 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
680 dbg(0,"+#+:enter\n");
681 #endif
682 ////DBG dbg(0,"EEnter\n");
683 int dx, dy;
684
685 if (this_->button_pressed && !this_->popped)
686 {
687 dx = (p->x - this_->pressed.x);
688 dy = (p->y - this_->pressed.y);
689 if (dx < -8 || dx > 8 || dy < -8 || dy > 8)
690 {
691 this_->moved = 1;
692 if (this_->button_timeout)
693 {
694 event_remove_timeout(this_->button_timeout);
695 this_->button_timeout = NULL;
696 }
697 this_->current = *p;
698
699 // -------- DISABLE -------
700 // -------- DISABLE -------
701 // -------- DISABLE -------
702 /*
703 if (!this_->motion_timeout_callback)
704 this_->motion_timeout_callback = callback_new_1(callback_cast(navit_motion_timeout), this_);
705 if (!this_->motion_timeout)
706 this_->motion_timeout = event_add_timeout(100, 0, this_->motion_timeout_callback);
707 */
708 // -------- DISABLE -------
709 // -------- DISABLE -------
710 // -------- DISABLE -------
711 }
712 }
713 }
714
715 void navit_motion(void *data, struct point *p)
716 {
717 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
718 dbg(0,"+#+:enter\n");
719 #endif
720 ////DBG dbg(0,"EEnter\n");
721 struct navit *this = data;
722 if (!this->ignore_graphics_events)
723 {
724 navit_handle_motion(this, p);
725 }
726 }
727
728 static void navit_predraw(struct navit *this_)
729 {
730 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
731 dbg(0,"+#+:enter\n");
732 #endif
733 ////DBG dbg(0,"EEnter\n");
734 GList *l;
735 struct navit_vehicle *nv;
736 transform_copy(this_->trans, this_->trans_cursor);
737 l = this_->vehicles;
738 while (l)
739 {
740 nv = l->data;
741 ////DBG dbg(0,"* here *\n");
742 ////DBG dbg(0,"vehicle_draw_004\n");
743 navit_vehicle_draw(this_, nv, NULL);
744 l = g_list_next(l);
745 }
746 }
747
748 static void navit_scale(struct navit *this_, long scale, struct point *p, int draw)
749 {
750 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
751 dbg(0,"+#+:enter\n");
752 #endif
753 //DBG dbg(0,"EEnter\n");
754 struct coord c1, c2, *center;
755
756 if (scale < this_->zoom_min)
757 {
758 scale = this_->zoom_min;
759 }
760
761 if (scale > this_->zoom_max)
762 {
763 scale = this_->zoom_max;
764 }
765
766 // return scale value to android
767 #ifdef HAVE_API_ANDROID
768 android_return_generic_int(3, (int)scale);
769 #endif
770
771 if (p)
772 {
773 transform_reverse(this_->trans, p, &c1);
774 }
775
776 transform_set_scale(this_->trans, scale);
777
778 if (p)
779 {
780 transform_reverse(this_->trans, p, &c2);
781 center = transform_center(this_->trans);
782 center->x += c1.x - c2.x;
783 center->y += c1.y - c2.y;
784 }
785
786 //DBG dbg(0,"aa331\n");
787
788 if (draw)
789 {
790 navit_draw(this_);
791 }
792
793 //DBG dbg(0,"leave\n");
794 }
795
796 /**
797 * @brief Automatically adjusts zoom level
798 *
799 * This function automatically adjusts the current
800 * zoom level according to the current speed.
801 *
802 * @param this_ The navit struct
803 * @param center The "immovable" point - i.e. the vehicles position if we're centering on the vehicle
804 * @param speed The vehicles speed in meters per second
805 * @param dir The direction into which the vehicle moves
806 */
807 static void navit_autozoom(struct navit *this_, struct coord *center, int speed, int draw)
808 {
809 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
810 dbg(0,"+#+:enter\n");
811 #endif
812 struct point pc;
813 int distance, w, h;
814 double new_scale;
815 long scale;
816
817 if (!this_->autozoom_active)
818 {
819 return;
820 }
821
822 distance = speed * this_->autozoom_secs;
823
824 transform_get_size(this_->trans, &w, &h);
825 transform(this_->trans, transform_get_projection(this_->trans), center, &pc, 1, 0, 0, NULL);
826 scale = transform_get_scale(this_->trans);
827
828 /* We make sure that the point we want to see is within a certain range
829 * around the vehicle. The radius of this circle is the size of the
830 * screen. This doesn't necessarily mean the point is visible because of
831 * perspective etc. Quite rough, but should be enough. */
832
833 if (w > h)
834 {
835 new_scale = (double) distance / h * 16;
836 }
837 else
838 {
839 new_scale = (double) distance / w * 16;
840 }
841
842 if (abs(new_scale - scale) < 2)
843 {
844 return; // Smoothing
845 }
846
847 if (new_scale >= this_->autozoom_min)
848 {
849 navit_scale(this_, (long) new_scale, &pc, 0);
850 }
851 else
852 {
853 if (scale != this_->autozoom_min)
854 {
855 navit_scale(this_, this_->autozoom_min, &pc, 0);
856 }
857 }
858 }
859
860 /**
861 * Change the current zoom level, zooming closer to the ground
862 *
863 * @param navit The navit instance
864 * @param factor The zoom factor, usually 2
865 * @param p The invariant point (if set to NULL, default to center)
866 * @returns nothing
867 */
868 void navit_zoom_in(struct navit *this_, int factor, struct point *p)
869 {
870 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
871 dbg(0,"+#+:enter\n");
872 #endif
873 ////DBG dbg(0,"EEnter\n");
874 long scale = transform_get_scale(this_->trans) / factor;
875 if (scale < 1)
876 scale = 1;
877 ////DBG dbg(0,"zoom in -> scale=%d",scale);
878 navit_scale(this_, scale, p, 1);
879 }
880
881 /**
882 * Change the current zoom level
883 *
884 * @param navit The navit instance
885 * @param factor The zoom factor, usually 2
886 * @param p The invariant point (if set to NULL, default to center)
887 * @returns nothing
888 */
889 void navit_zoom_out(struct navit *this_, int factor, struct point *p)
890 {
891 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
892 dbg(0,"+#+:enter\n");
893 #endif
894 ////DBG dbg(0,"EEnter\n");
895 long scale = transform_get_scale(this_->trans) * factor;
896 ////DBG dbg(0,"zoom out -> scale=%d",scale);
897 navit_scale(this_, scale, p, 1);
898 }
899
900 int navit_get_cur_pnt(struct navit *this_, struct point *p)
901 {
902 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
903 dbg(0,"+#+:enter\n");
904 #endif
905 ////DBG dbg(0,"EEnter\n");
906 return navit_get_cursor_pnt(this_, p, 0, NULL);
907 }
908
909 void navit_zoom_in_cursor(struct navit *this_, int factor)
910 {
911 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
912 dbg(0,"+#+:enter\n");
913 #endif
914 ////DBG dbg(0,"EEnter\n");
915 struct point p;
916 if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL))
917 {
918 navit_zoom_in(this_, factor, &p);
919 this_->vehicle->follow_curr = this_->vehicle->follow;
920 }
921 else
922 navit_zoom_in(this_, factor, NULL);
923 }
924
925 void navit_zoom_to_scale(struct navit *this_, int new_scale)
926 {
927 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
928 dbg(0,"+#+:enter\n");
929 #endif
930 //DBG dbg(0,"EEnter\n");
931 long scale = transform_get_scale(this_->trans);
932 long new_scale_long = new_scale;
933 //DBG dbg(0,"zoom to scale -> old scale=%d",scale);
934 //DBG dbg(0,"zoom to scale -> want scale=%d",new_scale_long);
935
936 // only do something if scale changed!
937 if (scale != new_scale_long)
938 {
939 navit_scale(this_, new_scale_long, NULL, 1);
940 }
941 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
942 dbg(0,"+#+:leave\n");
943 #endif
944 }
945
946 void navit_zoom_to_scale_with_center_point(struct navit *this_, int new_scale, struct point *p)
947 {
948 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
949 dbg(0,"+#+:enter\n");
950 #endif
951 //DBG dbg(0,"EEnter\n");
952 long scale = transform_get_scale(this_->trans);
953 long new_scale_long = new_scale;
954 // dbg(0, "zoom to scale -> old scale=%d", scale);
955 // dbg(0, "zoom to scale -> want scale=%d", new_scale_long);
956
957 // only do something if scale changed!
958 if (scale != new_scale_long)
959 {
960 navit_scale(this_, new_scale_long, p, 1);
961 }
962 }
963
964 void navit_zoom_out_cursor(struct navit *this_, int factor)
965 {
966 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
967 dbg(0,"+#+:enter\n");
968 #endif
969 ////DBG dbg(0,"EEnter\n");
970 struct point p;
971 if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL))
972 {
973 navit_zoom_out(this_, 2, &p);
974 this_->vehicle->follow_curr = this_->vehicle->follow;
975 }
976 else
977 navit_zoom_out(this_, 2, NULL);
978 }
979
980 static int navit_cmd_zoom_in(struct navit *this_)
981 {
982 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
983 dbg(0,"+#+:enter\n");
984 #endif
985 ////DBG dbg(0,"EEnter\n");
986 navit_zoom_in_cursor(this_, 2);
987 return 0;
988 }
989
990 static int navit_cmd_zoom_out(struct navit *this_)
991 {
992 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
993 dbg(0,"+#+:enter\n");
994 #endif
995 ////DBG dbg(0,"EEnter\n");
996 navit_zoom_out_cursor(this_, 2);
997 return 0;
998 }
999
1000 static void navit_cmd_say(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1001 {
1002 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1003 dbg(0,"+#+:enter\n");
1004 #endif
1005 ////DBG dbg(0,"EEnter\n");
1006 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1007 {
1008 navit_say(this, in[0]->u.str);
1009 }
1010 }
1011
1012 static GHashTable *cmd_int_var_hash = NULL;
1013 static GHashTable *cmd_attr_var_hash = NULL;
1014
1015 /**
1016 * Store key value pair for the command system (for int typed values)
1017 *
1018 * @param navit The navit instance
1019 * @param function unused (needed to match command function signiture)
1020 * @param in input attributes in[0] is the key string, in[1] is the integer value to store
1021 * @param out output attributes, unused
1022 * @param valid unused
1023 * @returns nothing
1024 */
1025 static void navit_cmd_set_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1026 {
1027 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1028 dbg(0,"+#+:enter\n");
1029 #endif
1030 ////DBG dbg(0,"EEnter\n");
1031 char*key;
1032 struct attr*val;
1033 if (!cmd_int_var_hash)
1034 {
1035 cmd_int_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
1036 }
1037
1038 if ((in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && (in && in[1] && ATTR_IS_NUMERIC(in[1]->type)))
1039 {
1040 val = g_new(struct attr,1);
1041 attr_dup_content(in[1], val);
1042 key = g_strdup(in[0]->u.str);
1043 g_hash_table_insert(cmd_int_var_hash, key, val);
1044 }
1045 }
1046
1047 /**
1048 * Store key value pair for the command system (for attr typed values, can be used as opaque handles)
1049 *
1050 * @param navit The navit instance
1051 * @param function unused (needed to match command function signiture)
1052 * @param in input attributes in[0] is the key string, in[1] is the attr* value to store
1053 * @param out output attributes, unused
1054 * @param valid unused
1055 * @returns nothing
1056 */
1057 //TODO free stored attributes on navit_destroy
1058 static void navit_cmd_set_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1059 {
1060 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1061 dbg(0,"+#+:enter\n");
1062 #endif
1063 ////DBG dbg(0,"EEnter\n");
1064 char*key;
1065 struct attr*val;
1066 if (!cmd_attr_var_hash)
1067 {
1068 cmd_attr_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
1069 }
1070
1071 if ((in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && (in && in[1]))
1072 {
1073 val = attr_dup(in[1]);
1074 //val = in[1];
1075 key = g_strdup(in[0]->u.str);
1076 g_hash_table_insert(cmd_attr_var_hash, key, val);
1077 }
1078 }
1079
1080 /**
1081 * command to toggle the active state of a named layer of the current layout
1082 *
1083 * @param navit The navit instance
1084 * @param function unused (needed to match command function signiture)
1085 * @param in input attribute in[0] is the name of the layer
1086 * @param out output unused
1087 * @param valid unused
1088 * @returns nothing
1089 */
1090 static void navit_cmd_toggle_layer(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1091 {
1092 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1093 dbg(0,"+#+:enter\n");
1094 #endif
1095 ////DBG dbg(0,"EEnter\n");
1096 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1097 {
1098 if (this->layout_current && this->layout_current->layers)
1099 {
1100 GList* layers = this->layout_current->layers;
1101 while (layers)
1102 {
1103 struct layer*l = layers->data;
1104 if (l && !strcmp(l->name, in[0]->u.str))
1105 {
1106 l->active ^= 1;
1107 navit_draw(this);
1108 return;
1109 }
1110 layers = g_list_next(layers);
1111 }
1112 }
1113 }
1114 }
1115
1116 /**
1117 * command to set the active state of a named layer of the current layout
1118 *
1119 * @param navit The navit instance
1120 * @param name name of the layer
1121 * @param active 0 -> inactive, 1 -> active
1122 * @param draw 0 -> dont redraw, 1 -> redraw
1123 * @returns nothing
1124 */
1125 void navit_layer_set_active(struct navit *this, char *name, int active, int draw)
1126 {
1127 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1128 dbg(0,"+#+:enter\n");
1129 #endif
1130 //dbg(0,"EEnter\n");
1131 if (name)
1132 {
1133 if (this->layout_current && this->layout_current->layers)
1134 {
1135 GList* layers = this->layout_current->layers;
1136 while (layers)
1137 {
1138 struct layer *l = layers->data;
1139 if (l && !strcmp(l->name, name))
1140 {
1141 l->active = active;
1142 if (draw == 1)
1143 {
1144 navit_draw(this);
1145 }
1146 return;
1147 }
1148 layers = g_list_next(layers);
1149 }
1150 }
1151 }
1152 }
1153
1154 /**
1155 * adds an item with the current coordinate of the vehicle to a named map
1156 *
1157 * @param navit The navit instance
1158 * @param function unused (needed to match command function signiture)
1159 * @param in input attribute in[0] is the name of the map
1160 * @param out output attribute, 0 on error or the id of the created item on success
1161 * @param valid unused
1162 * @returns nothing
1163 */
1164 static void navit_cmd_map_add_curr_pos(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1165 {
1166 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1167 dbg(0,"+#+:enter\n");
1168 #endif
1169 ////DBG dbg(0,"EEnter\n");
1170 struct attr **list = g_new0(struct attr *,2);
1171 struct attr*val = g_new0(struct attr,1);
1172 struct mapset* ms;
1173 struct map_selection sel;
1174 const int selection_range = 10;
1175 enum item_type item_type;
1176 struct item *it;
1177 struct map* curr_map = NULL;
1178 struct coord curr_coord;
1179 struct map_rect *mr;
1180
1181 val->type = attr_type_item_begin;
1182 val->u.item = NULL; //return invalid item on error
1183 list[0] = val;
1184 list[1] = NULL;
1185 *out = list;
1186 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
1187 in[1] && ATTR_IS_STRING(in[1]->type) && in[1]->u.str //item type
1188 )
1189 {
1190
1191 if (!(ms = navit_get_mapset(this)))
1192 {
1193 return;
1194 }
1195
1196 if ((item_type = item_from_name(in[1]->u.str)) == type_none)
1197 {
1198 return;
1199 }
1200
1201 curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
1202
1203 //no map with the given name found
1204 if (!curr_map)
1205 {
1206 return;
1207 }
1208
1209 if (this->vehicle && this->vehicle->vehicle)
1210 {
1211 struct attr pos_attr;
1212 if (vehicle_get_attr(this->vehicle->vehicle, attr_position_coord_geo, &pos_attr, NULL))
1213 {
1214 transform_from_geo(projection_mg, pos_attr.u.coord_geo, &curr_coord);
1215 }
1216 else
1217 {
1218 return;
1219 }
1220 }
1221 else
1222 {
1223 return;
1224 }
1225
1226 sel.next = NULL;
1227 sel.order = 18;
1228 sel.range.min = type_none;
1229 sel.range.max = type_tec_common;
1230 sel.u.c_rect.lu.x = curr_coord.x - selection_range;
1231 sel.u.c_rect.lu.y = curr_coord.y + selection_range;
1232 sel.u.c_rect.rl.x = curr_coord.x + selection_range;
1233 sel.u.c_rect.rl.y = curr_coord.y - selection_range;
1234
1235 mr = map_rect_new(curr_map, &sel);
1236 if (mr)
1237 {
1238 it = map_rect_create_item(mr, item_type);
1239 item_coord_set(it, &curr_coord, 1, change_mode_modify);
1240 val->u.item = it;
1241 }
1242 map_rect_destroy(mr);
1243 }
1244 }
1245
1246 /**
1247 * sets an attribute (name value pair) of a map item specified by map name and item id
1248 *
1249 * @param navit The navit instance
1250 * @param function unused (needed to match command function signiture)
1251 * @param in input attribute in[0] - name of the map ; in[1] - item ; in[2] - attr name ; in[3] - attr value
1252 * @param out output attribute, 0 on error, 1 on success
1253 * @param valid unused
1254 * @returns nothing
1255 */
1256 static void navit_cmd_map_item_set_attr(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1257 {
1258 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1259 dbg(0,"+#+:enter\n");
1260 #endif
1261 ////DBG dbg(0,"EEnter\n");
1262 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
1263 in[1] && ATTR_IS_ITEM(in[1]->type) && //item
1264 in[2] && ATTR_IS_STRING(in[2]->type) && in[2]->u.str && //attr_type str
1265 in[3] && ATTR_IS_STRING(in[3]->type) && in[3]->u.str //attr_value str
1266 )
1267 {
1268 struct attr attr_to_set;
1269 struct map* curr_map = NULL;
1270 struct mapset *ms;
1271 struct map_selection sel;
1272 const int selection_range = 500;
1273 struct coord curr_coord;
1274 struct item *it;
1275
1276 if (ATTR_IS_STRING(attr_from_name(in[2]->u.str)))
1277 {
1278 attr_to_set.u.str = in[3]->u.str;
1279 attr_to_set.type = attr_from_name(in[2]->u.str);
1280 }
1281 else if (ATTR_IS_INT(attr_from_name(in[2]->u.str)))
1282 {
1283 attr_to_set.u.num = atoi(in[3]->u.str);
1284 attr_to_set.type = attr_from_name(in[2]->u.str);
1285 }
1286 else if (ATTR_IS_DOUBLE(attr_from_name(in[2]->u.str)))
1287 {
1288 double* val = g_new0(double,1);
1289 *val = atof(in[3]->u.str);
1290 attr_to_set.u.numd = val;
1291 attr_to_set.type = attr_from_name(in[2]->u.str);
1292 }
1293
1294 ms = navit_get_mapset(this);
1295
1296 curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
1297
1298 if (!curr_map)
1299 {
1300 return;
1301 }
1302 sel.next = NULL;
1303 sel.order = 18;
1304 sel.range.min = type_none;
1305 sel.range.max = type_tec_common;
1306 sel.u.c_rect.lu.x = curr_coord.x - selection_range;
1307 sel.u.c_rect.lu.y = curr_coord.y + selection_range;
1308 sel.u.c_rect.rl.x = curr_coord.x + selection_range;
1309 sel.u.c_rect.rl.y = curr_coord.y - selection_range;
1310
1311 it = in[1]->u.item;
1312 if (it)
1313 {
1314 item_attr_set(it, &attr_to_set, change_mode_modify);
1315 }
1316 }
1317 }
1318
1319 /**
1320 * Get attr variable given a key string for the command system (for opaque usage)
1321 *
1322 * @param navit The navit instance
1323 * @param function unused (needed to match command function signiture)
1324 * @param in input attribute in[0] is the key string
1325 * @param out output attribute, the attr for the given key string if exists or NULL
1326 * @param valid unused
1327 * @returns nothing
1328 */
1329 static void navit_cmd_get_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1330 {
1331 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1332 dbg(0,"+#+:enter\n");
1333 #endif
1334 ////DBG dbg(0,"EEnter\n");
1335 struct attr **list = g_new0(struct attr *,2);
1336 if (!cmd_int_var_hash)
1337 {
1338 struct attr*val = g_new0(struct attr,1);
1339 val->type = attr_type_item_begin;
1340 val->u.item = NULL;
1341 list[0] = val;
1342 }
1343 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1344 {
1345 struct attr*ret = g_hash_table_lookup(cmd_attr_var_hash, in[0]->u.str);
1346 if (ret)
1347 {
1348 list[0] = attr_dup(ret);
1349 }
1350 else
1351 {
1352 struct attr*val = g_new0(struct attr,1);
1353 val->type = attr_type_int_begin;
1354 val->u.item = NULL;
1355 list[0] = val;
1356 }
1357 }
1358 list[1] = NULL;
1359 *out = list;
1360 }
1361
1362 /**
1363 * Get value given a key string for the command system
1364 *
1365 * @param navit The navit instance
1366 * @param function unused (needed to match command function signiture)
1367 * @param in input attribute in[0] is the key string
1368 * @param out output attribute, the value for the given key string if exists or 0
1369 * @param valid unused
1370 * @returns nothing
1371 */
1372 static void navit_cmd_get_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1373 {
1374 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1375 dbg(0,"+#+:enter\n");
1376 #endif
1377 ////DBG dbg(0,"EEnter\n");
1378 struct attr **list = g_new0(struct attr *,2);
1379 if (!cmd_int_var_hash)
1380 {
1381 struct attr*val = g_new0(struct attr,1);
1382 val->type = attr_type_int_begin;
1383 val->u.num = 0;
1384 list[0] = val;
1385 }
1386 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1387 {
1388 struct attr*ret = g_hash_table_lookup(cmd_int_var_hash, in[0]->u.str);
1389 if (ret)
1390 {
1391 list[0] = ret;
1392 }
1393 else
1394 {
1395 struct attr*val = g_new0(struct attr,1);
1396 val->type = attr_type_int_begin;
1397 val->u.num = 0;
1398 list[0] = val;
1399 }
1400 }
1401 list[1] = NULL;
1402 *out = list;
1403 }
1404
1405 GList *cmd_int_var_stack = NULL;
1406
1407 /**
1408 * Push an integer to the stack for the command system
1409 *
1410 * @param navit The navit instance
1411 * @param function unused (needed to match command function signiture)
1412 * @param in input attribute in[0] is the integer attibute to push
1413 * @param out output attributes, unused
1414 * @param valid unused
1415 * @returns nothing
1416 */
1417 static void navit_cmd_push_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1418 {
1419 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1420 dbg(0,"+#+:enter\n");
1421 #endif
1422 ////DBG dbg(0,"EEnter\n");
1423 if (in && in[0] && ATTR_IS_NUMERIC(in[0]->type))
1424 {
1425 struct attr*val = g_new(struct attr,1);
1426 attr_dup_content(in[0], val);
1427 cmd_int_var_stack = g_list_prepend(cmd_int_var_stack, val);
1428 }
1429 }
1430
1431 /**
1432 * Pop an integer from the command system's integer stack
1433 *
1434 * @param navit The navit instance
1435 * @param function unused (needed to match command function signiture)
1436 * @param in input attributes unused
1437 * @param out output attribute, the value popped if stack isn't empty or 0
1438 * @param valid unused
1439 * @returns nothing
1440 */
1441 static void navit_cmd_pop_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1442 {
1443 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1444 dbg(0,"+#+:enter\n");
1445 #endif
1446 ////DBG dbg(0,"EEnter\n");
1447 struct attr **list = g_new0(struct attr *,2);
1448 if (!cmd_int_var_stack)
1449 {
1450 struct attr*val = g_new0(struct attr,1);
1451 val->type = attr_type_int_begin;
1452 val->u.num = 0;
1453 list[0] = val;
1454 }
1455 else
1456 {
1457 list[0] = cmd_int_var_stack->data;
1458 cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack, cmd_int_var_stack);
1459 }
1460 list[1] = NULL;
1461 *out = list;
1462 }
1463
1464 /**
1465 * Get current size of command system's integer stack
1466 *
1467 * @param navit The navit instance
1468 * @param function unused (needed to match command function signiture)
1469 * @param in input attributes unused
1470 * @param out output attribute, the size of stack
1471 * @param valid unused
1472 * @returns nothing
1473 */
1474 static void navit_cmd_int_stack_size(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1475 {
1476 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1477 dbg(0,"+#+:enter\n");
1478 #endif
1479 ////DBG dbg(0,"EEnter\n");
1480 struct attr **list;
1481 struct attr *attr = g_new0(struct attr ,1);
1482 attr->type = attr_type_int_begin;
1483 if (!cmd_int_var_stack)
1484 {
1485 attr->u.num = 0;
1486 }
1487 else
1488 {
1489 attr->u.num = g_list_length(cmd_int_var_stack);
1490 }list = g_new0(struct attr *,2);
1491 list[0] = attr;
1492 list[1] = NULL;
1493 *out = list;
1494 cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack, cmd_int_var_stack);
1495 }
1496
1497 static void navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1498 {
1499 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1500 dbg(0,"+#+:enter\n");
1501 #endif
1502 ////DBG dbg(0,"EEnter\n");
1503 struct pcoord pc;
1504 char *description = NULL;
1505 if (!in)
1506 return;
1507 if (!in[0])
1508 return;
1509 pc.pro = transform_get_projection(this->trans);
1510 if (ATTR_IS_COORD(in[0]->type))
1511 {
1512 pc.x = in[0]->u.coord->x;
1513 pc.y = in[0]->u.coord->y;
1514 in++;
1515 }
1516 else if (ATTR_IS_PCOORD(in[0]->type))
1517 {
1518 pc = *in[0]->u.pcoord;
1519 in++;
1520 }
1521 else if (in[1] && in[2] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type) && ATTR_IS_INT(in[2]->type))
1522 {
1523 pc.pro = in[0]->u.num;
1524 pc.x = in[1]->u.num;
1525 pc.y = in[2]->u.num;
1526 in += 3;
1527 }
1528 else if (in[1] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type))
1529 {
1530 pc.x = in[0]->u.num;
1531 pc.y = in[1]->u.num;
1532 in += 2;
1533 }
1534 else
1535 {
1536 return;
1537 }
1538 if (in[0] && ATTR_IS_STRING(in[0]->type))
1539 {
1540 description = in[0]->u.str;
1541 }
1542 navit_set_destination(this, &pc, description, 1);
1543 }
1544
1545 static void navit_cmd_fmt_coordinates(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1546 {
1547 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1548 dbg(0,"+#+:enter\n");
1549 #endif
1550 ////DBG dbg(0,"EEnter\n");
1551 struct attr attr;
1552 attr.type = attr_type_string_begin;
1553 attr.u.str = "Fix me";
1554 if (out)
1555 {
1556 *out = attr_generic_add_attr(*out, &attr);
1557 }
1558 }
1559
1560 /**
1561 * Join several string attributes into one
1562 *
1563 * @param navit The navit instance
1564 * @param function unused (needed to match command function signiture)
1565 * @param in input attributes in[0] - separator, in[1..] - attributes to join
1566 * @param out output attribute joined attribute as string
1567 * @param valid unused
1568 * @returns nothing
1569 */
1570 static void navit_cmd_strjoin(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1571 {
1572 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1573 dbg(0,"+#+:enter\n");
1574 #endif
1575 ////DBG dbg(0,"EEnter\n");
1576 struct attr attr;
1577 gchar *ret, *sep;
1578 int i;
1579 attr.type = attr_type_string_begin;
1580 attr.u.str = NULL;
1581 if (in[0] && in[1])
1582 {
1583 sep = attr_to_text(in[0], NULL, 1);
1584 ret = attr_to_text(in[1], NULL, 1);
1585 for (i = 2; in[i]; i++)
1586 {
1587 gchar *in_i = attr_to_text(in[i], NULL, 1);
1588 gchar *r = g_strjoin(sep, ret, in_i, NULL);
1589 g_free(in_i);
1590 g_free(ret);
1591 ret = r;
1592 }
1593 g_free(sep);
1594 attr.u.str = ret;
1595 if (out)
1596 {
1597 *out = attr_generic_add_attr(*out, &attr);
1598 }
1599 g_free(ret);
1600 }
1601 }
1602
1603 /**
1604 * Call external program
1605 *
1606 * @param navit The navit instance
1607 * @param function unused (needed to match command function signiture)
1608 * @param in input attributes in[0] - name of executable, in[1..] - parameters
1609 * @param out output attribute unused
1610 * @param valid unused
1611 * @returns nothing
1612 */
1613 static void navit_cmd_spawn(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1614 {
1615 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1616 dbg(0,"+#+:enter\n");
1617 #endif
1618 ////DBG dbg(0,"EEnter\n");
1619 int i, j, nparms, nvalid;
1620 const char ** argv = NULL;
1621 struct spawn_process_info *pi;
1622
1623 nparms = 0;
1624 nvalid = 0;
1625 if (in)
1626 {
1627 while (in[nparms])
1628 {
1629 if (in[nparms]->type != attr_none)
1630 nvalid++;
1631 nparms++;
1632 }
1633 }
1634
1635 if (nvalid > 0)
1636 {
1637 argv=g_new(char*,nvalid+1);
1638 for (i = 0, j = 0; in[i]; i++)
1639 {
1640 if (in[i]->type != attr_none)
1641 {
1642 argv[j++] = attr_to_text(in[i], NULL, 1);
1643 }
1644 else
1645 {
1646 //DBG dbg(0, "Parameter #%i is attr_none - skipping\n", i);
1647 }
1648 }
1649 argv[j] = NULL;
1650 pi = spawn_process(argv);
1651
1652 // spawn_process() testing suite - uncomment following code to test.
1653 //sleep(3);
1654 // example of non-blocking wait
1655 //int st=spawn_process_check_status(pi,0);//DBG dbg(0,"status %i\n",st);
1656 // example of blocking wait
1657 //st=spawn_process_check_status(pi,1);//DBG dbg(0,"status %i\n",st);
1658 // example of wait after process is finished and status is
1659 // already tested
1660 //st=spawn_process_check_status(pi,1);//DBG dbg(0,"status %i\n",st);
1661 // example of wait after process is finished and status is
1662 // already tested - unblocked
1663 //st=spawn_process_check_status(pi,0);//DBG dbg(0,"status %i\n",st);
1664
1665 // End testing suite
1666 spawn_process_info_free(pi);
1667 for (i = 0; argv[i]; i++)
1668 g_free(argv[i]);
1669 g_free(argv);
1670 }
1671 }
1672
1673 static struct command_table
1674 commands[] =
1675 { { "zoom_in", command_cast(navit_cmd_zoom_in) }, { "zoom_out", command_cast(navit_cmd_zoom_out) }, { "zoom_to_route", command_cast(navit_cmd_zoom_to_route) }, { "say", command_cast(navit_cmd_say) }, { "set_center_cursor", command_cast(navit_cmd_set_center_cursor) }, { "set_destination", command_cast(navit_cmd_set_destination) }, { "announcer_toggle", command_cast(navit_cmd_announcer_toggle) }, { "fmt_coordinates", command_cast(navit_cmd_fmt_coordinates) }, { "set_int_var", command_cast(navit_cmd_set_int_var) }, { "get_int_var", command_cast(navit_cmd_get_int_var) }, { "push_int", command_cast(navit_cmd_push_int) }, { "pop_int", command_cast(navit_cmd_pop_int) }, { "int_stack_size", command_cast(navit_cmd_int_stack_size) }, { "toggle_layer", command_cast(navit_cmd_toggle_layer) }, { "strjoin", command_cast(navit_cmd_strjoin) }, { "spawn", command_cast(navit_cmd_spawn) }, { "map_add_curr_pos", command_cast(navit_cmd_map_add_curr_pos) }, { "map_item_set_attr", command_cast(navit_cmd_map_item_set_attr) }, { "set_attr_var", command_cast(navit_cmd_set_attr_var) }, { "get_attr_var", command_cast(navit_cmd_get_attr_var) }, };
1676
1677 void navit_command_add_table(struct navit*this_, struct command_table *commands, int count)
1678 {
1679 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1680 dbg(0,"+#+:enter\n");
1681 #endif
1682 ////DBG dbg(0,"EEnter\n");
1683 command_add_table(this_->attr_cbl, commands, count, this_);
1684 }
1685
1686 struct navit *
1687 navit_new(struct attr *parent, struct attr **attrs)
1688 {
1689 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1690 dbg(0,"+#+:enter\n");
1691 #endif
1692
1693 struct navit *this_=g_new0(struct navit, 1);
1694 struct pcoord center;
1695 struct coord co;
1696 struct coord_geo g;
1697 enum projection pro = projection_mg;
1698 int zoom = 256;
1699 g.lat = 53.13;
1700 g.lng = 11.70;
1701
1702 this_->self.type = attr_navit;
1703 this_->self.u.navit = this_;
1704 this_->attr_cbl = callback_list_new();
1705
1706 this_->orientation = -1;
1707 this_->tracking_flag = 1;
1708 this_->recentdest_count = 10;
1709 this_->osd_configuration = -1;
1710
1711 // changed default to 1
1712 this_->center_timeout = 1;
1713 this_->use_mousewheel = 1;
1714 this_->autozoom_secs = 10;
1715 this_->autozoom_min = 7;
1716 this_->autozoom_active = 0;
1717 this_->zoom_min = 1;
1718 this_->zoom_max = 1048576; //-> order=-2 // 2097152 -> order=-3;
1719 this_->follow_cursor = 1;
1720 this_->radius = 30;
1721 this_->border = 16;
1722
1723 // dbg(0, "GGGGG:set global_navit\n");
1724 global_navit = this_;
1725
1726 this_->trans = transform_new();
1727 this_->trans_cursor = transform_new();
1728 transform_from_geo(pro, &g, &co);
1729 center.x = co.x;
1730 center.y = co.y;
1731 center.pro = pro;
1732
1733 //DBG dbg(0, "setting center from xmlfile [hardcoded]\n");
1734 transform_setup(this_->trans, &center, zoom, (this_->orientation != -1) ? this_->orientation : 0);
1735
1736 // initialze trans_cursor here
1737 transform_copy(this_->trans, this_->trans_cursor);
1738 // initialze trans_cursor here
1739
1740 this_->bookmarks = bookmarks_new(&this_->self, NULL, this_->trans);
1741
1742 this_->prevTs = 0;
1743
1744 for (; *attrs; attrs++)
1745 {
1746 navit_set_attr_do(this_, *attrs, 1);
1747 }
1748 this_->displaylist = graphics_displaylist_new();
1749 command_add_table(this_->attr_cbl, commands, sizeof(commands) / sizeof(struct command_table), this_);
1750
1751 // this_->messages = messagelist_new(attrs);
1752
1753 ////DBG dbg(0,"111111\n");
1754
1755 return this_;
1756 }
1757
1758 static int navit_set_gui(struct navit *this_, struct gui *gui)
1759 {
1760 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1761 dbg(0,"+#+:enter\n");
1762 #endif
1763 ////DBG dbg(0,"EEnter\n");
1764 if (this_->gui)
1765 return 0;
1766 this_->gui = gui;
1767 if (gui_has_main_loop(this_->gui))
1768 {
1769 if (!main_loop_gui)
1770 {
1771 main_loop_gui = this_->gui;
1772 }
1773 else
1774 {
1775 //DBG dbg(0, "gui with main loop already active, ignoring this instance");
1776 return 0;
1777 }
1778 }
1779 return 1;
1780 }
1781
1782 void navit_add_message(struct navit *this_, char *message)
1783 {
1784 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1785 dbg(0,"+#+:enter\n");
1786 #endif
1787 ////DBG dbg(0,"EEnter\n");
1788 // message_new(this_->messages, message);
1789 }
1790
1791 struct message *navit_get_messages(struct navit *this_)
1792 {
1793 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1794 dbg(0,"+#+:enter\n");
1795 #endif
1796 ////DBG dbg(0,"EEnter\n");
1797 // return message_get(this_->messages);
1798 }
1799
1800 static int navit_set_graphics(struct navit *this_, struct graphics *gra)
1801 {
1802 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1803 dbg(0,"+#+:enter\n");
1804 #endif
1805 ////DBG dbg(0,"EEnter\n");
1806 if (this_->gra)
1807 return 0;
1808 this_->gra = gra;
1809
1810 /*
1811 this_->resize_callback = callback_new_attr_1(callback_cast(navit_resize), attr_resize, this_);
1812 graphics_add_callback(gra, this_->resize_callback);
1813 this_->button_callback = callback_new_attr_1(callback_cast(navit_button), attr_button, this_);
1814 graphics_add_callback(gra, this_->button_callback);
1815 this_->motion_callback = callback_new_attr_1(callback_cast(navit_motion), attr_motion, this_);
1816 graphics_add_callback(gra, this_->motion_callback);
1817 */
1818
1819 // this draw the vehicle // very stupid
1820 this_->predraw_callback = callback_new_attr_1(callback_cast(navit_predraw), attr_predraw, this_);
1821 callback_add_names(this_->predraw_callback, "navit_set_graphics", "navit_predraw");
1822 graphics_add_callback(gra, this_->predraw_callback);
1823
1824 ////DBG dbg(0,"111111111\n");
1825 return 1;
1826 }
1827
1828 struct graphics *
1829 navit_get_graphics(struct navit *this_)
1830 {
1831 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1832 dbg(0,"+#+:enter\n");
1833 #endif
1834 ////DBG dbg(0,"EEnter\n");
1835 return this_->gra;
1836 }
1837
1838 struct vehicleprofile *
1839 navit_get_vehicleprofile(struct navit *this_)
1840 {
1841 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1842 dbg(0,"+#+:enter\n");
1843 #endif
1844 ////DBG dbg(0,"EEnter\n");
1845 return this_->vehicleprofile;
1846 }
1847
1848 GList *
1849 navit_get_vehicleprofiles(struct navit *this_)
1850 {
1851 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1852 dbg(0,"+#+:enter\n");
1853 #endif
1854 ////DBG dbg(0,"EEnter\n");
1855 return this_->vehicleprofiles;
1856 }
1857
1858 static void navit_projection_set(struct navit *this_, enum projection pro, int draw)
1859 {
1860 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1861 dbg(0,"+#+:enter\n");
1862 #endif
1863 ////DBG dbg(0,"EEnter\n");
1864 struct coord_geo g;
1865 struct coord *c;
1866
1867 c = transform_center(this_->trans);
1868 transform_to_geo(transform_get_projection(this_->trans), c, &g);
1869 transform_set_projection(this_->trans, pro);
1870 transform_from_geo(pro, &g, c);
1871 if (draw)
1872 {
1873 navit_draw(this_);
1874 }
1875 }
1876
1877 /**
1878 * Start the route computing to a given set of coordinates
1879 *
1880 * @param navit The navit instance
1881 * @param c The coordinate to start routing to
1882 * @param description A label which allows the user to later identify this destination in the former destinations selection
1883 * @returns nothing
1884 */
1885 void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async)
1886 {
1887 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1888 dbg(0,"+#+:enter\n");
1889 #endif
1890 ////DBG dbg(0,"EEnter\n");
1891 char *destination_file;
1892 if (c)
1893 {
1894 this_->destination = *c;
1895 this_->destination_valid = 1;
1896 //dbg(0, "navit->navit_set_destination %i\n", c->x);
1897 //dbg(0, "navit->navit_set_destination %i\n", c->y);
1898 }
1899 else
1900 {
1901 this_->destination_valid = 0;
1902 }
1903 //destination_file = bookmarks_get_destination_file(TRUE);
1904 //bookmarks_append_coord(this_->bookmarks, destination_file, c, 1, "former_destination", description, NULL, this_->recentdest_count);
1905 //g_free(destination_file);
1906 callback_list_call_attr_0(this_->attr_cbl, attr_destination);
1907 if (this_->route)
1908 {
1909 //dbg(0, "navit->navit_set_destination 2: %i %i\n", c->x, c->y);
1910
1911 route_set_destination(this_->route, c, async);
1912 if (this_->ready == 3)
1913 {
1914 navit_draw(this_);
1915 }
1916 }
1917 }
1918
1919 /**
1920 * add a waypoint to an active route
1921 *
1922 * @param navit The navit instance
1923 * @param c The coordinate of the waypoint
1924 * @param description A dummy string
1925 * @returns nothing
1926 */
1927 void navit_add_waypoint_to_route(struct navit *this_, struct pcoord *c, const char *description, int async)
1928 {
1929 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1930 dbg(0,"+#+:enter\n");
1931 #endif
1932 if (this_->destination_valid == 1)
1933 {
1934 //int count = 0;
1935 //count = g_list_length(this_->route->destinations);
1936 //DBG dbg(0, "count=%d\n", count);
1937
1938 //dbg(0, "navit->navit_add_waypoint_to_route 1: %i %i\n", c->x, c->y);
1939
1940 route_add_destination(this_->route, c, async);
1941
1942 this_->destination = *c;
1943 this_->destination_valid = 1;
1944 }
1945 else
1946 {
1947 //dbg(0, "navit->navit_add_waypoint_to_route 2: %i %i\n", c->x, c->y);
1948 navit_set_destination(this_, c, description, async);
1949 }
1950 }
1951
1952 /**
1953 * Start the route computing to a given set of coordinates including waypoints
1954 *
1955 * @param navit The navit instance
1956 * @param c The coordinate to start routing to
1957 * @param description A label which allows the user to later identify this destination in the former destinations selection
1958 * @returns nothing
1959 */
1960 void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async)
1961 {
1962 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1963 dbg(0,"+#+:enter\n");
1964 #endif
1965 ////DBG dbg(0,"EEnter\n");
1966 char *destination_file;
1967 if (c && count)
1968 {
1969 this_->destination = c[count - 1];
1970 this_->destination_valid = 1;
1971 //dbg(0, "navit->navit_set_destinations 1: %i %i\n", c[count-1].x, c[count-1].y);
1972 }
1973 else
1974 {
1975 this_->destination_valid = 0;
1976 }
1977 //destination_file = bookmarks_get_destination_file(TRUE);
1978 //bookmarks_append_coord(this_->bookmarks, destination_file, c, count, "former_itinerary", description, NULL, this_->recentdest_count);
1979 //g_free(destination_file);
1980 callback_list_call_attr_0(this_->attr_cbl, attr_destination);
1981 if (this_->route)
1982 {
1983 route_set_destinations(this_->route, c, count, async);
1984 if (this_->ready == 3)
1985 {
1986 navit_draw(this_);
1987 }
1988 }
1989 }
1990
1991 /**
1992 * @brief Checks if a route is calculated
1993 *
1994 * This function checks if a route is calculated.
1995 *
1996 * @param this_ The navit struct whose route should be checked.
1997 * @return True if the route is set, false otherwise.
1998 */
1999 int navit_check_route(struct navit *this_)
2000 {
2001 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2002 dbg(0,"+#+:enter\n");
2003 #endif
2004 ////DBG dbg(0,"EEnter\n");
2005 if (this_->route)
2006 {
2007 return route_get_path_set(this_->route);
2008 }
2009
2010 return 0;
2011 }
2012
2013 static int navit_former_destinations_active(struct navit *this_)
2014 {
2015 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2016 dbg(0,"+#+:enter\n");
2017 #endif
2018 ////DBG dbg(0,"EEnter\n");
2019
2020 return 0;
2021 // disable this function!!
2022
2023
2024 char *destination_file = bookmarks_get_destination_file(FALSE);
2025 FILE *f;
2026 int active = 0;
2027 char buffer[3];
2028 f = fopen(destination_file, "r");
2029 if (f)
2030 {
2031 if (!fseek(f, -2, SEEK_END) && fread(buffer, 2, 1, f) == 1 && (buffer[0] != '\n' || buffer[1] != '\n'))
2032 {
2033 active = 1;
2034 }
2035 fclose(f);
2036 }
2037 g_free(destination_file);
2038
2039 return active;
2040 }
2041
2042 static void navit_add_former_destinations_from_file(struct navit *this_)
2043 {
2044 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2045 dbg(0,"+#+:enter\n");
2046 #endif
2047 ////DBG dbg(0,"EEnter\n");
2048 char *destination_file = bookmarks_get_destination_file(FALSE);
2049 struct attr *attrs[4];
2050 struct map_rect *mr;
2051 struct item *item;
2052 int i, valid = 0, count = 0;
2053 struct coord c[16];
2054 struct pcoord pc[16];
2055 struct attr parent;
2056 struct attr type;
2057 struct attr data;
2058 struct attr flags;
2059
2060 parent.type = attr_navit;
2061 parent.u.navit = this_;
2062
2063 type.type = attr_type;
2064 type.u.str = "textfile";
2065
2066 data.type = attr_data;
2067 data.u.str = destination_file;
2068
2069 flags.type = attr_flags;
2070 flags.u.num = 1;
2071
2072 attrs[0] = &type;
2073 attrs[1] = &data;
2074 attrs[2] = &flags;
2075 attrs[3] = NULL;
2076
2077 this_->former_destination = map_new(&parent, attrs);
2078 g_free(destination_file);
2079 if (!this_->route || !navit_former_destinations_active(this_))
2080 return;
2081 mr = map_rect_new(this_->former_destination, NULL);
2082 while ((item = map_rect_get_item(mr)))
2083 {
2084 if ((item->type == type_former_destination || item->type == type_former_itinerary || item->type == type_former_itinerary_part) && (count = item_coord_get(item, c, 16)))
2085 valid = 1;
2086 }
2087 map_rect_destroy(mr);
2088 if (valid && count > 0)
2089 {
2090 for (i = 0; i < count; i++)
2091 {
2092 pc[i].pro = map_projection(this_->former_destination);
2093 pc[i].x = c[i].x;
2094 pc[i].y = c[i].y;
2095 }
2096 if (count == 1)
2097 {
2098 route_set_destination(this_->route, &pc[0], 1);
2099 }
2100 else
2101 {
2102 route_set_destinations(this_->route, pc, count, 1);
2103 }
2104 this_->destination = pc[count - 1];
2105 this_->destination_valid = 1;
2106 }
2107 }
2108
2109 void navit_textfile_debug_log(struct navit *this_, const char *fmt, ...)
2110 {
2111 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2112 dbg(0,"+#+:enter\n");
2113 #endif
2114 ////DBG dbg(0,"EEnter\n");
2115 va_list ap;
2116 char *str1, *str2;
2117 va_start(ap, fmt);
2118 if (this_->textfile_debug_log && this_->vehicle)
2119 {
2120 str1 = g_strdup_vprintf(fmt, ap);
2121 str2 = g_strdup_printf("0x%x 0x%x%s%s\n", this_->vehicle->coord.x, this_->vehicle->coord.y, strlen(str1) ? " " : "", str1);
2122 log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
2123 g_free(str2);
2124 g_free(str1);
2125 }
2126 va_end(ap);
2127 }
2128
2129 void navit_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *fmt, ...)
2130 {
2131 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2132 dbg(0,"+#+:enter\n");
2133 #endif
2134 ////DBG dbg(0,"EEnter\n");
2135 va_list ap;
2136 char *str1, *str2;
2137 va_start(ap, fmt);
2138 if (this_->textfile_debug_log && this_->vehicle)
2139 {
2140 str1 = g_strdup_vprintf(fmt, ap);
2141 str2 = g_strdup_printf("0x%x 0x%x%s%s\n", pc->x, pc->y, strlen(str1) ? " " : "", str1);
2142 log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
2143 g_free(str2);
2144 g_free(str1);
2145 }
2146 va_end(ap);
2147 }
2148
2149 void navit_say(struct navit *this_, char *text)
2150 {
2151 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2152 dbg(0,"+#+:enter\n");
2153 #endif
2154 ////DBG dbg(0,"EEnter\n");
2155 if (this_->speech)
2156 {
2157 speech_say(this_->speech, text);
2158 }
2159 }
2160
2161 /**
2162 * @brief Toggles the navigation announcer for navit
2163 * @param this_ The navit object
2164 */
2165 static void navit_cmd_announcer_toggle(struct navit *this_)
2166 {
2167 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2168 dbg(0,"+#+:enter\n");
2169 #endif
2170 struct attr attr, speechattr;
2171
2172 // search for the speech attribute
2173 if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
2174 return;
2175 // find out if the corresponding attribute attr_active has been set
2176 if (speech_get_attr(speechattr.u.speech, attr_active, &attr, NULL))
2177 {
2178 // flip it then...
2179 attr.u.num = !attr.u.num;
2180 }
2181 else
2182 {
2183 // otherwise disable it because voice is enabled by default
2184 attr.type = attr_active;
2185 attr.u.num = 0;
2186 }
2187
2188 // apply the new state
2189 if (!speech_set_attr(speechattr.u.speech, &attr))
2190 return;
2191
2192 // announce that the speech attribute has changed
2193 callback_list_call_attr_0(this_->attr_cbl, attr_speech);
2194 }
2195
2196 void navit_cmd_announcer_on(struct navit *this_)
2197 {
2198 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2199 dbg(0,"+#+:enter\n");
2200 #endif
2201 struct attr attr, speechattr;
2202
2203 // search for the speech attribute
2204 if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
2205 return;
2206
2207 attr.type = attr_active;
2208 attr.u.num = 1;
2209
2210 // apply the new state
2211 if (!speech_set_attr(speechattr.u.speech, &attr))
2212 return;
2213
2214 // announce that the speech attribute has changed
2215 callback_list_call_attr_0(this_->attr_cbl, attr_speech);
2216 }
2217
2218 void navit_cmd_announcer_off(struct navit *this_)
2219 {
2220 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2221 dbg(0,"+#+:enter\n");
2222 #endif
2223 struct attr attr, speechattr;
2224
2225 // search for the speech attribute
2226 if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
2227 return;
2228
2229 attr.type = attr_active;
2230 attr.u.num = 0;
2231
2232 // apply the new state
2233 if (!speech_set_attr(speechattr.u.speech, &attr))
2234 return;
2235
2236 // announce that the speech attribute has changed
2237 callback_list_call_attr_0(this_->attr_cbl, attr_speech);
2238 }
2239
2240 void navit_speak(struct navit *this_)
2241 {
2242 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2243 dbg(0,"+#+:enter\n");
2244 #endif
2245 ////DBG dbg(0,"EEnter\n");
2246 struct navigation *nav = this_->navigation;
2247 struct map *map = NULL;
2248 struct map_rect *mr = NULL;
2249 struct item *item;
2250 struct attr attr;
2251
2252 if (!speech_get_attr(this_->speech, attr_active, &attr, NULL))
2253 attr.u.num = 1;
2254 // dbg(1, "this_.speech->active %i\n", attr.u.num);
2255 if (!attr.u.num)
2256 return;
2257
2258 if (nav)
2259 map = navigation_get_map(nav);
2260 if (map)
2261 mr = map_rect_new(map, NULL);
2262 if (mr)
2263 {
2264 while ((item = map_rect_get_item(mr)) && (item->type == type_nav_position || item->type == type_nav_none))
2265 ;
2266 if (item && item_attr_get(item, attr_navigation_speech, &attr))
2267 {
2268 speech_say(this_->speech, attr.u.str);
2269 //navit_add_message(this_, attr.u.str);
2270 navit_textfile_debug_log(this_, "type=announcement label=\"%s\"", attr.u.str);
2271 }
2272 map_rect_destroy(mr);
2273 }
2274 }
2275
2276 static void navit_window_roadbook_update(struct navit *this_)
2277 {
2278 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2279 dbg(0,"+#+:enter\n");
2280 #endif
2281 ////DBG dbg(0,"EEnter\n");
2282 struct navigation *nav = this_->navigation;
2283 struct map *map = NULL;
2284 struct map_rect *mr = NULL;
2285 struct item *item;
2286 struct attr attr;
2287 struct param_list param[5];
2288 int secs;
2289
2290 // dbg(1, "enter\n");
2291 datawindow_mode(this_->roadbook_window, 1);
2292 if (nav)
2293 map = navigation_get_map(nav);
2294 if (map)
2295 mr = map_rect_new(map, NULL);
2296 ////DBG dbg(0,"nav=%p map=%p mr=%p\n", nav, map, mr);
2297 if (mr)
2298 {
2299 ////DBG dbg(0,"while loop\n");
2300 while ((item = map_rect_get_item(mr)))
2301 {
2302 ////DBG dbg(0,"item=%p\n", item);
2303 attr.u.str = NULL;
2304 if (item->type != type_nav_position)
2305 {
2306 item_attr_get(item, attr_navigation_long, &attr);
2307 if (attr.u.str == NULL)
2308 {
2309 continue;
2310 }
2311 dbg(2, "Command='%s'\n", attr.u.str);
2312 param[0].value = g_strdup(attr.u.str);
2313 }
2314 else
2315 param[0].value = _("Position");
2316 param[0].name = _("Command");
2317
2318 item_attr_get(item, attr_length, &attr);
2319 dbg(2, "Length=%d\n", attr.u.num);
2320 param[1].name = _("Length");
2321
2322 if (attr.u.num >= 2000)
2323 {
2324 param[1].value = g_strdup_printf("%5.1f %s", (float) attr.u.num / 1000, _("km"));
2325 }
2326 else
2327 {
2328 param[1].value = g_strdup_printf("%7d %s", attr.u.num, _("m"));
2329 }
2330
2331 item_attr_get(item, attr_time, &attr);
2332 dbg(2, "Time=%d\n", attr.u.num);
2333 secs = attr.u.num / 10;
2334 param[2].name = _("Time");
2335 if (secs >= 3600)
2336 {
2337 param[2].value = g_strdup_printf("%d:%02d:%02d", secs / 60, (secs / 60) % 60, secs % 60);
2338 }
2339 else
2340 {
2341 param[2].value = g_strdup_printf("%d:%02d", secs / 60, secs % 60);
2342 }
2343
2344 item_attr_get(item, attr_destination_length, &attr);
2345 dbg(2, "Destlength=%d\n", attr.u.num);
2346 param[3].name = _("Destination Length");
2347 if (attr.u.num >= 2000)
2348 {
2349 param[3].value = g_strdup_printf("%5.1f %s", (float) attr.u.num / 1000, _("km"));
2350 }
2351 else
2352 {
2353 param[3].value = g_strdup_printf("%d %s", attr.u.num, _("m"));
2354 }
2355
2356 item_attr_get(item, attr_destination_time, &attr);
2357 dbg(2, "Desttime=%d\n", attr.u.num);
2358 secs = attr.u.num / 10;
2359 param[4].name = _("Destination Time");
2360 if (secs >= 3600)
2361 {
2362 param[4].value = g_strdup_printf("%d:%02d:%02d", secs / 3600, (secs / 60) % 60, secs % 60);
2363 }
2364 else
2365 {
2366 param[4].value = g_strdup_printf("%d:%02d", secs / 60, secs % 60);
2367 }
2368 datawindow_add(this_->roadbook_window, param, 5);
2369 }
2370 map_rect_destroy(mr);
2371 }
2372 datawindow_mode(this_->roadbook_window, 0);
2373 }
2374
2375 void navit_window_roadbook_destroy(struct navit *this_)
2376 {
2377 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2378 dbg(0,"+#+:enter\n");
2379 #endif
2380 ////DBG dbg(0, "enter\n");
2381 navigation_unregister_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
2382 this_->roadbook_window = NULL;
2383 this_->roadbook_callback = NULL;
2384 }
2385
2386 void navit_window_roadbook_new(struct navit *this_)
2387 {
2388 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2389 dbg(0,"+#+:enter\n");
2390 #endif
2391 if (!this_->gui || this_->roadbook_callback || this_->roadbook_window)
2392 {
2393 return;
2394 }
2395
2396 this_->roadbook_callback = callback_new_1(callback_cast(navit_window_roadbook_update), this_);
2397 navigation_register_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
2398 this_->roadbook_window = gui_datawindow_new(this_->gui, _("Roadbook"), NULL, callback_new_1(callback_cast(navit_window_roadbook_destroy), this_));
2399 navit_window_roadbook_update(this_);
2400 }
2401
2402 void navit_remove_all_maps(struct navit *this_)
2403 {
2404 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2405 dbg(0,"+#+:enter\n");
2406 #endif
2407 struct mapset *ms;
2408 struct map *map3;
2409
2410 // hold map drawing
2411 // this_->ready = 1;
2412
2413 // first: stop navigation!
2414 //if (global_navit->destination_valid != 0)
2415 //{
2416 navit_set_destination(global_navit, NULL, NULL, 0);
2417 //}
2418
2419
2420 if (this_->route)
2421 {
2422 struct attr callback;
2423 // this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
2424 callback.type = attr_callback;
2425 callback.u.callback = this_->route_cb;
2426 route_remove_attr(this_->route, &callback);
2427
2428 this_->route->ms = NULL;
2429 // route_set_mapset(this_->route, ms);
2430 // route_set_projection(this_->route, transform_get_projection(this_->trans));
2431
2432 //*********route_destroy(this_->route);
2433
2434 //route_path_destroy(this_->route->path2,1);
2435 //this_->route->path2 = NULL;
2436 //route_graph_destroy(this_->route->graph);
2437 //this_->route->graph=NULL;
2438 }
2439
2440 /*
2441 map_rect_destroy(displaylist->mr);
2442 if (!route_selection)
2443 map_selection_destroy(displaylist->sel);
2444 mapset_close(displaylist->msh);
2445 displaylist->mr=NULL;
2446 displaylist->sel=NULL;
2447 displaylist->m=NULL;
2448 displaylist->msh=NULL;
2449 profile(1,"callback\n");
2450 callback_call_1(displaylist->cb, cancel);
2451 */
2452
2453 struct displaylist *dl = navit_get_displaylist(this_);
2454 dl->m = NULL;
2455 dl->msh = NULL;
2456
2457 if (this_->mapsets)
2458 {
2459 struct mapset_handle *msh;
2460 ms = this_->mapsets->data;
2461 msh = mapset_open(ms);
2462 ////DBG dbg(0,"removing map bb0\n");
2463 while (msh && (map3 = mapset_next(msh, 0)))
2464 {
2465 ////DBG dbg(0,"removing map bb1\n");
2466 struct attr map_name_attr;
2467 if (map_get_attr(map3, attr_name, &map_name_attr, NULL))
2468 {
2469 //DBG dbg(0, "map name=%s", map_name_attr.u.str);
2470 if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
2471 {
2472 dbg(0, "removing map name=%s", map_name_attr.u.str);
2473 //DBG dbg(0, "removing map a0\n");
2474 struct attr active;
2475 active.type = attr_active;
2476 active.u.num = 0;
2477 //map_set_attr(map3, &active);
2478
2479 //DBG dbg(0, "removing map a1\n");
2480 struct attr map_attr;
2481 map_attr.u.map = map3;
2482 map_attr.type = attr_map;
2483 mapset_remove_attr(ms, &map_attr);
2484
2485 //DBG dbg(0, "removing map a2\n");
2486 map3->refcount = 1;
2487 map_destroy(map3);
2488 //DBG dbg(0, "removing map a3\n");
2489 map3 = NULL;
2490 }
2491 else if (strncmp("-special-:", map_name_attr.u.str, 10) == 0)
2492 {
2493 dbg(0, "removing (special) map name=%s", map_name_attr.u.str);
2494 struct attr active;
2495 active.type = attr_active;
2496 active.u.num = 0;
2497
2498 struct attr map_attr;
2499 map_attr.u.map = map3;
2500 map_attr.type = attr_map;
2501 mapset_remove_attr(ms, &map_attr);
2502
2503 map3->refcount = 1;
2504 map_destroy(map3);
2505 map3 = NULL;
2506 }
2507 }
2508 }
2509 mapset_close(msh);
2510 //DBG dbg(0, "removing map bb4\n");
2511 }
2512
2513 dl->ms = this_->mapsets->data;
2514
2515 // int async = 0;
2516 // transform_setup_source_rect(this_->trans);
2517 // graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
2518 //this_->displaylist->ms=this_->mapsets->data;
2519
2520 }
2521
2522 void navit_map_active_flag(struct navit *this_, int activate, const char *mapname)
2523 {
2524 // activate = 0 -> deactivate
2525 // activate = 1 -> activate
2526
2527 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2528 dbg(0,"+#+:enter\n");
2529 #endif
2530 struct mapset *ms;
2531 struct map *map3;
2532
2533 if (this_->mapsets)
2534 {
2535 struct mapset_handle *msh;
2536 ms = this_->mapsets->data;
2537 msh = mapset_open(ms);
2538 while (msh && (map3 = mapset_next(msh, 0)))
2539 {
2540 struct attr map_name_attr;
2541 if (map_get_attr(map3, attr_name, &map_name_attr, NULL))
2542 {
2543 dbg(0, "map name=%s\n", map_name_attr.u.str);
2544 if (strcmp(mapname, map_name_attr.u.str) == 0)
2545 {
2546 dbg(0, "setting active flag on map:%s\n", map_name_attr.u.str);
2547
2548 struct attr active;
2549 active.type = attr_active;
2550 active.u.num = activate;
2551 map_set_attr(map3, &active);
2552 }
2553 }
2554 }
2555 mapset_close(msh);
2556 }
2557
2558 }
2559
2560 void navit_add_all_maps(struct navit *this_)
2561 {
2562 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2563 dbg(0,"+#+:enter\n");
2564 #endif
2565 struct map *map3;
2566
2567 if (this_->mapsets)
2568 {
2569 //DBG dbg(0, "xADDx all maps - start\n");
2570
2571 struct mapset *ms;
2572 ms = this_->mapsets->data;
2573
2574 struct attr type;
2575 struct attr parent;
2576 struct attr data;
2577 struct attr flags;
2578 struct map *map2;
2579 struct attr map2_attr;
2580 struct attr *attrs[4];
2581 char *map_file;
2582
2583 parent.type = attr_navit;
2584 parent.u.navit = this_;
2585 type.type = attr_type;
2586 type.u.str = "binfile";
2587 data.type = attr_data;
2588 map_file = g_strdup_printf("%sborders.bin", navit_maps_dir);
2589 data.u.str = map_file;
2590
2591 ////DBG dbg(0,"map name=%s",map_file);
2592
2593 flags.type = attr_flags;
2594 flags.u.num = 0;
2595 attrs[0] = &type;
2596 attrs[1] = &data;
2597 attrs[2] = &flags;
2598 attrs[3] = NULL;
2599 map2 = map_new(&parent, attrs);
2600 if (map2)
2601 {
2602 map2_attr.u.data = map2;
2603 map2_attr.type = attr_map;
2604 // mapset_add_attr_name(ms, &map2_attr);
2605 mapset_add_attr_name_str(ms, &map2_attr, "/sdcard/zanavi/maps/borders.bin");
2606 struct attr active;
2607 active.type = attr_active;
2608 active.u.num = 0;
2609 //map_set_attr(map2, &active);
2610 }
2611 g_free(map_file);
2612
2613 parent.type = attr_navit;
2614 parent.u.navit = this_;
2615 type.type = attr_type;
2616 type.u.str = "binfile";
2617 data.type = attr_data;
2618 map_file = g_strdup_printf("%scoastline.bin", navit_maps_dir);
2619 data.u.str = map_file;
2620
2621 ////DBG dbg(0,"map name=%s",map_file);
2622
2623 flags.type = attr_flags;
2624 flags.u.num = 0;
2625 attrs[0] = &type;
2626 attrs[1] = &data;
2627 attrs[2] = &flags;
2628 attrs[3] = NULL;
2629 map2 = map_new(&parent, attrs);
2630 if (map2)
2631 {
2632 map2_attr.u.data = map2;
2633 map2_attr.type = attr_map;
2634 // mapset_add_attr_name(ms, &map2_attr);
2635 mapset_add_attr_name_str(ms, &map2_attr, "/sdcard/zanavi/maps/coastline.bin");
2636 struct attr active;
2637 active.type = attr_active;
2638 active.u.num = 0;
2639 //map_set_attr(map2, &active);
2640 }
2641 g_free(map_file);
2642
2643 // gpx tracks map --------------------
2644 parent.type = attr_navit;
2645 parent.u.navit = this_;
2646 type.type = attr_type;
2647 type.u.str = "textfile";
2648 data.type = attr_data;
2649 map_file = g_strdup_printf("%sgpxtracks.txt", navit_maps_dir);
2650 data.u.str = map_file;
2651
2652 flags.type = attr_flags;
2653 flags.u.num = 0;
2654 attrs[0] = &type;
2655 attrs[1] = &data;
2656 attrs[2] = &flags;
2657 attrs[3] = NULL;
2658 map2 = map_new(&parent, attrs);
2659 if (map2)
2660 {
2661 map2_attr.u.data = map2;
2662 map2_attr.type = attr_map;
2663 mapset_add_attr_name_str(ms, &map2_attr, "-special-:gpxtracks.txt");
2664 struct attr active;
2665 active.type = attr_active;
2666 active.u.num = 0;
2667 //map_set_attr(map2, &active);
2668 }
2669 g_free(map_file);
2670 // gpx tracks map --------------------
2671
2672
2673 // traffic map --------------------
2674 parent.type = attr_navit;
2675 parent.u.navit = this_;
2676 type.type = attr_type;
2677 type.u.str = "textfile";
2678 data.type = attr_data;
2679 map_file = g_strdup_printf("%straffic.txt", navit_maps_dir);
2680 data.u.str = map_file;
2681
2682 flags.type = attr_flags;
2683 flags.u.num = 0;
2684 attrs[0] = &type;
2685 attrs[1] = &data;
2686 attrs[2] = &flags;
2687 attrs[3] = NULL;
2688 map2 = map_new(&parent, attrs);
2689 if (map2)
2690 {
2691 map2_attr.u.data = map2;
2692 map2_attr.type = attr_map;
2693 mapset_add_attr_name_str(ms, &map2_attr, "-special-:traffic.txt");
2694 struct attr active;
2695 active.type = attr_active;
2696 active.u.num = 0;
2697 //map_set_attr(map2, &active);
2698 }
2699 g_free(map_file);
2700 // traffic map --------------------
2701
2702
2703 int i = 1;
2704 for (i = 1; i < 10; i++)
2705 {
2706 struct map *map22;
2707 struct attr map22_attr;
2708 parent.type = attr_navit;
2709 parent.u.navit = this_;
2710 type.type = attr_type;
2711 type.u.str = "binfile";
2712 data.type = attr_data;
2713 map_file = g_strdup_printf("%snavitmap_00%d.bin", navit_maps_dir, i);
2714 data.u.str = map_file;
2715 flags.type = attr_flags;
2716 flags.u.num = 0;
2717 attrs[0] = &type;
2718 attrs[1] = &data;
2719 attrs[2] = &flags;
2720 attrs[3] = NULL;
2721 map22 = map_new(&parent, attrs);
2722 if (map22)
2723 {
2724 //DBG dbg(0, "*add* map name=%s\n", map_file);
2725 map22_attr.u.data = map22;
2726 map22_attr.type = attr_map;
2727 // mapset_add_attr_name(ms, &map22_attr);
2728 char *map_name_str;
2729 map_name_str = g_strdup_printf("/sdcard/zanavi/maps/navitmap_00%d.bin", i);
2730 mapset_add_attr_name_str(ms, &map22_attr, map_name_str);
2731 struct attr active;
2732 active.type = attr_active;
2733 active.u.num = 0;
2734 //map_set_attr(map22, &active);
2735 g_free(map_name_str);
2736 }
2737 g_free(map_file);
2738 }
2739
2740 i = 10;
2741 for (i = 10; i < 21; i++)
2742 {
2743 parent.type = attr_navit;
2744 parent.u.navit = this_;
2745 type.type = attr_type;
2746 type.u.str = "binfile";
2747 data.type = attr_data;
2748 map_file = g_strdup_printf("%snavitmap_0%d.bin", navit_maps_dir, i);
2749 data.u.str = map_file;
2750 ////DBG dbg(0,"map name=%s",map_file);
2751 flags.type = attr_flags;
2752 flags.u.num = 0;
2753 attrs[0] = &type;
2754 attrs[1] = &data;
2755 attrs[2] = &flags;
2756 attrs[3] = NULL;
2757 map2 = map_new(&parent, attrs);
2758 if (map2)
2759 {
2760 map2_attr.u.data = map2;
2761 map2_attr.type = attr_map;
2762 // mapset_add_attr_name(ms, &map2_attr);
2763 char *map_name_str;
2764 map_name_str = g_strdup_printf("/sdcard/zanavi/maps/navitmap_0%d.bin", i);
2765 mapset_add_attr_name_str(ms, &map2_attr, map_name_str);
2766 struct attr active;
2767 active.type = attr_active;
2768 active.u.num = 0;
2769 //map_set_attr(map2, &active);
2770 g_free(map_name_str);
2771 }
2772 g_free(map_file);
2773 }
2774 }
2775
2776 /*
2777 if (this_->mapsets)
2778 {
2779 struct mapset_handle *msh;
2780 struct map *map;
2781 struct mapset *ms;
2782
2783 //DBG dbg(0,"xx ms callbacks xx\n");
2784
2785 ms=this_->mapsets->data;
2786 this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2787 msh=mapset_open(ms);
2788 while (msh && (map=mapset_next(msh, 0)))
2789 {
2790 //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
2791 struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2792 map_add_callback(map, pcb);
2793 }
2794 mapset_close(msh);
2795 }
2796 */
2797
2798 /*
2799 struct attr parent;
2800 parent.type = attr_navit;
2801 parent.u.navit = global_navit;
2802
2803 struct attr *attrs_r[2];
2804 attrs_r[0] = NULL;
2805 attrs_r[1] = NULL;
2806 */
2807
2808 //***this_->route = route_new(&parent, attrs_r);
2809
2810
2811 //int async = 0;
2812 //transform_setup_source_rect(this_->trans);
2813 //graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
2814
2815 struct displaylist *dl = navit_get_displaylist(this_);
2816 dl->ms = this_->mapsets->data;
2817 dl->m = NULL;
2818 dl->msh = NULL;
2819
2820 if (this_->route)
2821 {
2822 struct mapset *ms;
2823 ms = this_->mapsets->data;
2824 route_set_mapset(this_->route, ms);
2825
2826 struct attr callback;
2827 this_->route_cb = callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
2828 callback_add_names(this_->route_cb, "navit_add_all_maps", "navit_redraw_route");
2829 callback.type = attr_callback;
2830 callback.u.callback = this_->route_cb;
2831 route_add_attr(this_->route, &callback);
2832 // ***** route_set_projection(this_->route, transform_get_projection(this_->trans));
2833 }
2834
2835 if (this_->tracking)
2836 {
2837 struct mapset *ms;
2838 ms = this_->mapsets->data;
2839
2840 tracking_set_mapset(this_->tracking, ms);
2841 if (this_->route)
2842 {
2843 tracking_set_route(this_->tracking, this_->route);
2844 }
2845 }
2846
2847 // ready for drawing map
2848 // this_->ready = 3;
2849
2850 // draw map
2851 // navit_draw(this_);
2852 }
2853
2854 void navit_reload_maps(struct navit *this_)
2855 {
2856 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2857 dbg(0,"+#+:enter\n");
2858 #endif
2859 navit_remove_all_maps(this_);
2860 navit_add_all_maps(this_);
2861 }
2862
2863 void navit_init(struct navit *this_)
2864 {
2865 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
2866 dbg(0,"+#+:enter\n");
2867 #endif
2868 ////DBG dbg(0,"EEnter\n");
2869 struct mapset *ms;
2870 struct map *map;
2871 int callback;
2872 char *center_file;
2873
2874 // dbg(0,"GGGGG:set global_navit\n");
2875 // global_navit = this_;
2876
2877 // default value
2878 navit_maps_dir = "/sdcard/zanavi/maps/";
2879
2880 global_img_waypoint = NULL;
2881
2882 //DBG dbg(0, "enter gui %p graphics %p\n", this_->gui, this_->gra);
2883
2884 if (!this_->gui && !(this_->flags & 2))
2885 {
2886 dbg(0, "no gui\n");
2887 navit_destroy(this_);
2888 return;
2889 }
2890
2891 if (!this_->gra && !(this_->flags & 1))
2892 {
2893 dbg(0, "no graphics\n");
2894 navit_destroy(this_);
2895 return;
2896 }
2897
2898 //DBG dbg(0, "Connecting gui to graphics\n");
2899
2900 if (this_->gui && this_->gra && gui_set_graphics(this_->gui, this_->gra))
2901 {
2902 struct attr attr_type_gui, attr_type_graphics;
2903 gui_get_attr(this_->gui, attr_type, &attr_type_gui, NULL);
2904 graphics_get_attr(this_->gra, attr_type, &attr_type_graphics, NULL);
2905
2906 dbg(0, "failed to connect to graphics\n");
2907 navit_destroy(this_);
2908 return;
2909 }
2910
2911 if (this_->speech && this_->navigation)
2912 {
2913 struct attr speech;
2914 speech.type = attr_speech;
2915 speech.u.speech = this_->speech;
2916 navigation_set_attr(this_->navigation, &speech);
2917 }
2918
2919 //DBG dbg(0, "Initializing graphics\n");
2920 //DBG dbg(0, "Setting Vehicle\n");
2921 navit_set_vehicle(this_, this_->vehicle);
2922
2923 //DBG dbg(0, "Adding dynamic maps to mapset %p\n", this_->mapsets);
2924 if (this_->mapsets)
2925 {
2926 struct mapset_handle *msh;
2927 ms = this_->mapsets->data;
2928 // **D** // this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2929 msh = mapset_open(ms);
2930 while (msh && (map = mapset_next(msh, 0)))
2931 {
2932 //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
2933 // **D** // struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
2934 // **D** // map_add_callback(map, pcb);
2935 }
2936 mapset_close(msh);
2937
2938 if (this_->route)
2939 {
2940 if ((map = route_get_map(this_->route)))
2941 {
2942 struct attr map_a, map_name;
2943 map_a.type = attr_map;
2944 map_a.u.map = map;
2945 map_name.type = attr_name;
2946 map_name.u.str = "_ms_route";
2947 map_set_attr(map_a.u.map, &map_name);
2948 mapset_add_attr(ms, &map_a);
2949 }
2950
2951 if ((map = route_get_graph_map(this_->route)))
2952 {
2953 struct attr map_a, active, map_name;
2954 map_a.type = attr_map;
2955 map_a.u.map = map;
2956 active.type = attr_active;
2957 active.u.num = 0;
2958 map_name.type = attr_name;
2959 map_name.u.str = "_ms_route_graph";
2960 map_set_attr(map_a.u.map, &map_name);
2961 mapset_add_attr(ms, &map_a);
2962 map_set_attr(map, &active);
2963 }
2964 route_set_mapset(this_->route, ms);
2965 route_set_projection(this_->route, transform_get_projection(this_->trans));
2966 }
2967
2968 if (this_->tracking)
2969 {
2970 tracking_set_mapset(this_->tracking, ms);
2971 if (this_->route)
2972 {
2973 tracking_set_route(this_->tracking, this_->route);
2974 }
2975 }
2976
2977 if (this_->navigation)
2978 {
2979 if ((map = navigation_get_map(this_->navigation)))
2980 {
2981 struct attr map_a, active, map_name;
2982 map_a.type = attr_map;
2983 map_a.u.map = map;
2984 active.type = attr_active;
2985 active.u.num = 0;
2986 map_name.type = attr_name;
2987 map_name.u.str = "_ms_navigation";
2988 map_set_attr(map_a.u.map, &map_name);
2989 mapset_add_attr(ms, &map_a);
2990 map_set_attr(map, &active);
2991 }
2992 }
2993
2994 if (this_->tracking)
2995 {
2996 if ((map = tracking_get_map(this_->tracking)))
2997 {
2998 struct attr map_a, active, map_name;
2999 map_a.type = attr_map;
3000 map_a.u.map = map;
3001 active.type = attr_active;
3002 active.u.num = 0;
3003 map_name.type = attr_name;
3004 map_name.u.str = "_ms_tracking";
3005 map_set_attr(map_a.u.map, &map_name);
3006 mapset_add_attr(ms, &map_a);
3007 map_set_attr(map, &active);
3008 }
3009 }
3010 // *DISABLED* navit_add_former_destinations_from_file(this_);
3011 }
3012
3013 if (this_->route)
3014 {
3015 struct attr callback;
3016 this_->route_cb = callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
3017 callback_add_names(this_->route_cb, "navit_init", "navit_redraw_route");
3018 callback.type = attr_callback;
3019 callback.u.callback = this_->route_cb;
3020 route_add_attr(this_->route, &callback);
3021 }
3022
3023 if (this_->navigation)
3024 {
3025 if (this_->speech)
3026 {
3027 this_->nav_speech_cb = callback_new_1(callback_cast(navit_speak), this_);
3028 callback_add_names(this_->nav_speech_cb, "navit_init", "navit_speak");
3029 navigation_register_callback(this_->navigation, attr_navigation_speech, this_->nav_speech_cb);
3030 }
3031
3032 if (this_->route)
3033 {
3034 navigation_set_route(this_->navigation, this_->route);
3035 }
3036 }
3037
3038 dbg(0, "Setting Center\n");
3039 center_file = bookmarks_get_center_file(FALSE);
3040 //dbg(0, "g0\n");
3041 bookmarks_set_center_from_file(this_->bookmarks, center_file);
3042 g_free(center_file);
3043
3044 #if 0
3045 if (this_->menubar)
3046 {
3047 men=menu_add(this_->menubar, "Data", menu_type_submenu, NULL);
3048 if (men)
3049 {
3050 navit_add_menu_windows_items(this_, men);
3051 }
3052 }
3053 #endif
3054
3055 #if 0
3056 navit_window_roadbook_new(this_);
3057 navit_window_items_new(this_);
3058 #endif
3059
3060 //dbg(0, "g1\n");
3061 //messagelist_init(this_->messages);
3062
3063 //dbg(0, "g2\n");
3064 navit_set_cursors(this_);
3065
3066 callback_list_call_attr_1(this_->attr_cbl, attr_navit, this_);
3067 callback = (this_->ready == 2);
3068 dbg(0, "pre this_->ready=%d\n", this_->ready);
3069 this_->ready = this_->ready | 1;
3070 dbg(0, "set this_->ready=%d\n", this_->ready);
3071 ////DBG dbg(0,"ready=%d\n",this_->ready);
3072
3073
3074 //if (this_->ready == 3)
3075 //{
3076 // ////DBG dbg(0,"navit_draw_async_003\n");
3077 // navit_draw_async(this_, 1);
3078 //}
3079
3080 dbg(0, "init ready=%d\n", this_->ready);
3081
3082 // draw???????
3083 // dbg(0,"init DRAW 11\n");
3084 // ready to draw map
3085 // navit_draw(this_);
3086 // dbg(0,"init DRAW 22\n");
3087 // draw???????
3088
3089 if (callback)
3090 {
3091 callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_);
3092 }
3093 #if 0
3094 routech_test(this_);
3095 #endif
3096 //dbg(0, "1111111111\n");
3097 }
3098
3099 void navit_zoom_to_rect(struct navit *this_, struct coord_rect *r)
3100 {
3101 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3102 dbg(0,"+#+:enter\n");
3103 #endif
3104 ////DBG dbg(0,"EEnter\n");
3105 struct coord c;
3106 int scale = 16;
3107
3108 c.x = (r->rl.x + r->lu.x) / 2;
3109 c.y = (r->rl.y + r->lu.y) / 2;
3110 transform_set_center(this_->trans, &c);
3111 // dbg(1, "%x,%x-%x,%x\n", r->rl.x, r->rl.y, r->lu.x, r->lu.y);
3112 while (scale < 1 << 20)
3113 {
3114 struct point p1, p2;
3115 transform_set_scale(this_->trans, scale);
3116 transform_setup_source_rect(this_->trans);
3117 transform(this_->trans, transform_get_projection(this_->trans), &r->lu, &p1, 1, 0, 0, NULL);
3118 transform(this_->trans, transform_get_projection(this_->trans), &r->rl, &p2, 1, 0, 0, NULL);
3119 // dbg(1, "%d,%d-%d,%d\n", p1.x, p1.y, p2.x, p2.y);
3120 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)
3121 scale *= 2;
3122 else
3123 break;
3124
3125 }
3126 if (this_->ready == 3)
3127 {
3128 ////DBG dbg(0,"navit_draw_async_004\n");
3129 //dbg(0,"DO__DRAW:navit_draw_async call\n");
3130 navit_draw_async(this_, 0);
3131 }
3132 }
3133
3134 void navit_zoom_to_route(struct navit *this_, int orientation)
3135 {
3136 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3137 dbg(0,"+#+:enter\n");
3138 #endif
3139 ////DBG dbg(0,"EEnter\n");
3140 struct map *map;
3141 struct map_rect *mr = NULL;
3142 struct item *item;
3143 struct coord c;
3144 struct coord_rect r;
3145 int count = 0;
3146 if (!this_->route)
3147 return;
3148 // dbg(1, "enter\n");
3149 map = route_get_map(this_->route);
3150 // dbg(1, "map=%p\n", map);
3151 if (map)
3152 mr = map_rect_new(map, NULL);
3153 // dbg(1, "mr=%p\n", mr);
3154 if (mr)
3155 {
3156 while ((item = map_rect_get_item(mr)))
3157 {
3158 // dbg(1, "item=%s\n", item_to_name(item->type));
3159 while (item_coord_get(item, &c, 1))
3160 {
3161 // dbg(1, "coord\n");
3162 if (!count)
3163 r.lu = r.rl = c;
3164 else
3165 coord_rect_extend(&r, &c);
3166 count++;
3167 }
3168 }
3169 map_rect_destroy(mr);
3170 }
3171 if (!count)
3172 return;
3173 if (orientation != -1)
3174 transform_set_yaw(this_->trans, orientation);
3175 navit_zoom_to_rect(this_, &r);
3176 }
3177
3178 static void navit_cmd_zoom_to_route(struct navit *this)
3179 {
3180 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3181 dbg(0,"+#+:enter\n");
3182 #endif
3183 ////DBG dbg(0,"EEnter\n");
3184 navit_zoom_to_route(this, 0);
3185 }
3186
3187 /**
3188 * show point on map
3189 *
3190 * @param navit The navit instance
3191 * @param center The point where to center the map, including its projection
3192 * @returns nothing
3193 */
3194 void navit_set_center(struct navit *this_, struct pcoord *center, int set_timeout)
3195 {
3196 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3197 dbg(0,"+#+:enter\n");
3198 #endif
3199 ////DBG dbg(0,"EEnter\n");
3200 struct coord *c = transform_center(this_->trans);
3201 struct coord c1, c2;
3202 enum projection pro = transform_get_projection(this_->trans);
3203 if (pro != center->pro)
3204 {
3205 c1.x = center->x;
3206 c1.y = center->y;
3207 transform_from_to(&c1, center->pro, &c2, pro);
3208 }
3209 else
3210 {
3211 c2.x = center->x;
3212 c2.y = center->y;
3213 }
3214 *c = c2;
3215 if (set_timeout)
3216 {
3217 navit_set_timeout(this_);
3218 }
3219 if (this_->ready == 3)
3220 {
3221 navit_draw(this_);
3222 }
3223 }
3224
3225 static void navit_set_center_coord_screen(struct navit *this_, struct coord *c, struct point *p, int set_timeout)
3226 {
3227 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3228 dbg(0,"+#+:enter\n");
3229 #endif
3230 ////DBG dbg(0,"EEnter\n");
3231 int width, height;
3232 struct point po;
3233 transform_set_center(this_->trans, c);
3234 transform_get_size(this_->trans, &width, &height);
3235 po.x = width / 2;
3236 po.y = height / 2;
3237 update_transformation(this_->trans, &po, p, NULL);
3238 if (set_timeout)
3239 {
3240 navit_set_timeout(this_);
3241 }
3242 }
3243
3244 /**
3245 * Links all vehicles to a cursor depending on the current profile.
3246 *
3247 * @param this_ A navit instance
3248 * @author Ralph Sennhauser (10/2009)
3249 */
3250 void navit_set_cursors(struct navit *this_)
3251 {
3252 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3253 dbg(0,"+#+:enter\n");
3254 #endif
3255 struct attr name;
3256 struct navit_vehicle *nv;
3257 struct cursor *c;
3258 GList *v;
3259
3260 //dbg(0, "Enter\n");
3261
3262 v = g_list_first(this_->vehicles); // GList of navit_vehicles
3263 while (v)
3264 {
3265 dbg(0, "* found vehicle *\n");
3266 nv = v->data;
3267 if (vehicle_get_attr(nv->vehicle, attr_cursorname, &name, NULL))
3268 {
3269 if (!strcmp(name.u.str, "none"))
3270 {
3271 c = NULL;
3272 }
3273 else
3274 {
3275 c = layout_get_cursor(this_->layout_current, name.u.str);
3276 }
3277 }
3278 else
3279 {
3280 c = layout_get_cursor(this_->layout_current, "default");
3281 }
3282 vehicle_set_cursor(nv->vehicle, c, 0);
3283 v = g_list_next(v);
3284 }
3285 return;
3286 }
3287
3288 void navit_remove_cursors(struct navit *this_)
3289 {
3290 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3291 dbg(0,"+#+:enter\n");
3292 #endif
3293 struct attr name;
3294 struct navit_vehicle *nv;
3295 struct cursor *c;
3296 GList *v;
3297
3298 //dbg(0, "Enter\n");
3299 name.type = attr_cursor;
3300
3301 v = g_list_first(this_->vehicles); // GList of navit_vehicles
3302 while (v)
3303 {
3304 dbg(0, "* found vehicle *\n");
3305 nv = v->data;
3306 vehicle_remove_attr(nv->vehicle, &name);
3307 v = g_list_next(v);
3308 }
3309 return;
3310 }
3311
3312 static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir)
3313 {
3314 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3315 dbg(0,"+#+:enter\n");
3316 #endif
3317 ////DBG dbg(0,"EEnter\n");
3318 int width, height;
3319 struct navit_vehicle *nv = this_->vehicle;
3320
3321 float offset = this_->radius; // Cursor offset from the center of the screen (percent).
3322 #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 */
3323 float min_offset = 0.; // Percent offset at min_offset_speed.
3324 float max_offset = 30.; // Percent offset at max_offset_speed.
3325 int min_offset_speed = 2; // Speed in km/h
3326 int max_offset_speed = 50; // Speed ini km/h
3327 // Calculate cursor offset from the center of the screen, upon speed.
3328 if (nv->speed <= min_offset_speed)
3329 {
3330 offset = min_offset;
3331 }
3332 else if (nv->speed > max_offset_speed)
3333 {
3334 offset = max_offset;
3335 }
3336 else
3337 {
3338 offset = (max_offset - min_offset) / (max_offset_speed - min_offset_speed) * (nv->speed - min_offset_speed);
3339 }
3340 #endif
3341
3342 transform_get_size(this_->trans, &width, &height);
3343 if (this_->orientation == -1 || keep_orientation)
3344 {
3345 p->x = 50 * width / 100;
3346 p->y = (50 + offset) * height / 100;
3347 if (dir)
3348 {
3349 *dir = keep_orientation ? this_->orientation : nv->dir;
3350 }
3351 }
3352 else
3353 {
3354 int mdir;
3355 if (this_->tracking && this_->tracking_flag)
3356 {
3357 mdir = tracking_get_angle(this_->tracking) - this_->orientation;
3358 }
3359 else
3360 {
3361 mdir = nv->dir - this_->orientation;
3362 }
3363
3364 p->x = (50 - offset * sin(M_PI * mdir / 180.)) * width / 100;
3365 p->y = (50 + offset * cos(M_PI * mdir / 180.)) * height / 100;
3366 if (dir)
3367 {
3368 *dir = this_->orientation;
3369 }
3370 }
3371 return 1;
3372 }
3373
3374 void navit_set_center_cursor(struct navit *this_, int autozoom, int keep_orientation)
3375 {
3376 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3377 dbg(0,"+#+:enter\n");
3378 #endif
3379 ////DBG dbg(0,"EEnter\n");
3380 int dir;
3381 struct point pn;
3382 struct navit_vehicle *nv = this_->vehicle;
3383 navit_get_cursor_pnt(this_, &pn, keep_orientation, &dir);
3384 transform_set_yaw(this_->trans, dir);
3385 navit_set_center_coord_screen(this_, &nv->coord, &pn, 0);
3386 if (autozoom)
3387 {
3388 navit_autozoom(this_, &nv->coord, nv->speed, 0);
3389 }
3390 }
3391
3392 static void navit_set_center_cursor_draw(struct navit *this_)
3393 {
3394 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3395 dbg(0,"+#+:enter\n");
3396 #endif
3397 //dbg(0,"EEnter\n");
3398 navit_set_center_cursor(this_, 1, 0);
3399 if (this_->ready == 3)
3400 {
3401 //dbg(0,"navit_draw_async_005\n");
3402 //dbg(0,"DO__DRAW:navit_draw_async call (AS)\n");
3403 navit_draw_async(this_, 1);
3404 }
3405 }
3406
3407 static void navit_cmd_set_center_cursor(struct navit *this_)
3408 {
3409 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3410 dbg(0,"+#+:enter\n");
3411 #endif
3412 ////DBG dbg(0,"EEnter\n");
3413 navit_set_center_cursor_draw(this_);
3414 }
3415
3416 void navit_set_center_screen(struct navit *this_, struct point *p, int set_timeout)
3417 {
3418 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3419 dbg(0,"+#+:enter\n");
3420 #endif
3421 ////DBG dbg(0,"EEnter\n");
3422 struct coord c;
3423 struct pcoord pc;
3424 transform_reverse(this_->trans, p, &c);
3425 pc.x = c.x;
3426 pc.y = c.y;
3427 pc.pro = transform_get_projection(this_->trans);
3428 navit_set_center(this_, &pc, set_timeout);
3429 }
3430
3431 #if 0
3432 switch((*attrs)->type)
3433 {
3434 case attr_zoom:
3435 zoom=(*attrs)->u.num;
3436 break;
3437 case attr_center:
3438 g=*((*attrs)->u.coord_geo);
3439 break;
3440 #endif
3441
3442 static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init)
3443 {
3444 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3445 dbg(0,"+#+:enter\n");
3446 #endif
3447 ////DBG dbg(0,"EEnter\n");
3448 int dir = 0, orient_old = 0, attr_updated = 0;
3449 struct coord co;
3450 long zoom;
3451 GList *l;
3452 struct navit_vehicle *nv;
3453 struct layout *lay;
3454 struct attr active;
3455 active.type = attr_active;
3456 active.u.num = 0;
3457
3458 switch (attr->type)
3459 {
3460 case attr_autozoom:
3461 attr_updated = (this_->autozoom_secs != attr->u.num);
3462 this_->autozoom_secs = attr->u.num;
3463 break;
3464 case attr_autozoom_active:
3465 attr_updated = (this_->autozoom_active != attr->u.num);
3466 this_->autozoom_active = attr->u.num;
3467 break;
3468 case attr_center:
3469 transform_from_geo(transform_get_projection(this_->trans), attr->u.coord_geo, &co);
3470 // dbg(1, "0x%x,0x%x\n", co.x, co.y);
3471 transform_set_center(this_->trans, &co);
3472 break;
3473 case attr_drag_bitmap:
3474 attr_updated = (this_->drag_bitmap != !!attr->u.num);
3475 this_->drag_bitmap = !!attr->u.num;
3476 break;
3477 case attr_flags:
3478 attr_updated = (this_->flags != attr->u.num);
3479 this_->flags = attr->u.num;
3480 break;
3481 case attr_flags_graphics:
3482 attr_updated = (this_->graphics_flags != attr->u.num);
3483 this_->graphics_flags = attr->u.num;
3484 break;
3485 case attr_follow:
3486 if (!this_->vehicle)
3487 return 0;
3488 attr_updated = (this_->vehicle->follow_curr != attr->u.num);
3489 this_->vehicle->follow_curr = attr->u.num;
3490 break;
3491 case attr_layout:
3492 if (this_->layout_current != attr->u.layout)
3493 {
3494 this_->layout_current = attr->u.layout;
3495 graphics_font_destroy_all(this_->gra);
3496 navit_set_cursors(this_);
3497 if (this_->ready == 3)
3498 navit_draw(this_);
3499 attr_updated = 1;
3500 }
3501 break;
3502 case attr_layout_name:
3503 l = this_->layouts;
3504 while (l)
3505 {
3506 lay = l->data;
3507 if (!strcmp(lay->name, attr->u.str))
3508 {
3509 struct attr attr;
3510 attr.type = attr_layout;
3511 attr.u.layout = lay;
3512 return navit_set_attr_do(this_, &attr, init);
3513 }
3514 l = g_list_next(l);
3515 }
3516 return 0;
3517 case attr_map_border:
3518 if (this_->border != attr->u.num)
3519 {
3520 this_->border = attr->u.num;
3521 attr_updated = 1;
3522 }
3523 break;
3524 case attr_orientation:
3525 orient_old = this_->orientation;
3526 this_->orientation = attr->u.num;
3527 if (!init)
3528 {
3529 if (this_->orientation != -1)
3530 {
3531 dir = this_->orientation;
3532 }
3533 else
3534 {
3535 if (this_->vehicle)
3536 {
3537 dir = this_->vehicle->dir;
3538 }
3539 }
3540 transform_set_yaw(this_->trans, dir);
3541 if (orient_old != this_->orientation)
3542 {
3543 #if 0
3544 if (this_->ready == 3)
3545 navit_draw(this_);
3546 #endif
3547 attr_updated = 1;
3548 }
3549 }
3550 break;
3551 case attr_osd_configuration:
3552 //DBG dbg(0, "setting osd_configuration to %d (was %d)\n", attr->u.num, this_->osd_configuration);
3553 attr_updated = (this_->osd_configuration != attr->u.num);
3554 this_->osd_configuration = attr->u.num;
3555 break;
3556 case attr_pitch:
3557 attr_updated = (this_->pitch != attr->u.num);
3558 this_->pitch = attr->u.num;
3559 transform_set_pitch(this_->trans, this_->pitch);
3560 if (!init && attr_updated && this_->ready == 3)
3561 navit_draw(this_);
3562 break;
3563 case attr_projection:
3564 if (this_->trans && transform_get_projection(this_->trans) != attr->u.projection)
3565 {
3566 navit_projection_set(this_, attr->u.projection, !init);
3567 attr_updated = 1;
3568 }
3569 break;
3570 case attr_radius:
3571 attr_updated = (this_->radius != attr->u.num);
3572 this_->radius = attr->u.num;
3573 break;
3574 case attr_recent_dest:
3575 attr_updated = (this_->recentdest_count != attr->u.num);
3576 this_->recentdest_count = attr->u.num;
3577 break;
3578 case attr_speech:
3579 if (this_->speech && this_->speech != attr->u.speech)
3580 {
3581 attr_updated = 1;
3582 this_->speech = attr->u.speech;
3583 }
3584 break;
3585 case attr_timeout:
3586 attr_updated = (this_->center_timeout != attr->u.num);
3587 this_->center_timeout = attr->u.num;
3588 break;
3589 case attr_tracking:
3590 attr_updated = (this_->tracking_flag != !!attr->u.num);
3591 this_->tracking_flag = !!attr->u.num;
3592 break;
3593 case attr_transformation:
3594 this_->trans = attr->u.transformation;
3595 break;
3596 case attr_use_mousewheel:
3597 attr_updated = (this_->use_mousewheel != !!attr->u.num);
3598 this_->use_mousewheel = !!attr->u.num;
3599 break;
3600 case attr_vehicle:
3601 l = this_->vehicles;
3602 while (l)
3603 {
3604 nv = l->data;
3605 if (nv->vehicle == attr->u.vehicle)
3606 {
3607 if (!this_->vehicle || this_->vehicle->vehicle != attr->u.vehicle)
3608 {
3609 if (this_->vehicle)
3610 {
3611 vehicle_set_attr(this_->vehicle->vehicle, &active);
3612 }
3613 active.u.num = 1;
3614 vehicle_set_attr(nv->vehicle, &active);
3615 attr_updated = 1;
3616 }
3617 navit_set_vehicle(this_, nv);
3618 }
3619 l = g_list_next(l);
3620 }
3621 break;
3622 case attr_zoom:
3623 zoom = transform_get_scale(this_->trans);
3624 attr_updated = (zoom != attr->u.num);
3625 transform_set_scale(this_->trans, attr->u.num);
3626 if (attr_updated && !init)
3627 navit_draw(this_);
3628 break;
3629 case attr_zoom_min:
3630 attr_updated = (attr->u.num != this_->zoom_min);
3631 this_->zoom_min = attr->u.num;
3632 break;
3633 case attr_zoom_max:
3634 attr_updated = (attr->u.num != this_->zoom_max);
3635 this_->zoom_max = attr->u.num;
3636 break;
3637 case attr_message:
3638 //navit_add_message(this_, attr->u.str);
3639 break;
3640 case attr_follow_cursor:
3641 attr_updated = (this_->follow_cursor != !!attr->u.num);
3642 this_->follow_cursor = !!attr->u.num;
3643 break;
3644 case attr_imperial:
3645 attr_updated = (this_->imperial != attr->u.num);
3646 this_->imperial = attr->u.num;
3647 break;
3648 default:
3649 return 0;
3650 }
3651 if (attr_updated && !init)
3652 {
3653 callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
3654 if (attr->type == attr_osd_configuration)
3655 {
3656 graphics_draw_mode(this_->gra, draw_mode_end);
3657 }
3658 }
3659
3660 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3661 dbg(0,"+#+:leave\n");
3662 #endif
3663
3664 return 1;
3665 }
3666
3667 int navit_set_attr(struct navit *this_, struct attr *attr)
3668 {
3669 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3670 dbg(0,"+#+:enter\n");
3671 #endif
3672 ////DBG dbg(0,"EEnter\n");
3673 return navit_set_attr_do(this_, attr, 0);
3674 }
3675
3676 int navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
3677 {
3678 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3679 dbg(0,"+#+:enter\n");
3680 #endif
3681 ////DBG dbg(0,"EEnter\n");
3682 struct message *msg;
3683 int len, offset;
3684 int ret = 1;
3685
3686 switch (type)
3687 {
3688 case attr_message:
3689 return 0;
3690 /*
3691 msg = navit_get_messages(this_);
3692
3693 if (!msg)
3694 {
3695 return 0;
3696 }
3697
3698 len = 0;
3699 while (msg)
3700 {
3701 len += strlen(msg->text) + 1;
3702 msg = msg->next;
3703 }
3704 attr->u.str = g_malloc(len + 1);
3705
3706 msg = navit_get_messages(this_);
3707 offset = 0;
3708 while (msg)
3709 {
3710 g_stpcpy((attr->u.str + offset), msg->text);
3711 offset += strlen(msg->text);
3712 attr->u.str[offset] = '\n';
3713 offset++;
3714
3715 msg = msg->next;
3716 }
3717
3718 attr->u.str[len] = '\0';
3719 */
3720 break;
3721 case attr_imperial:
3722 attr->u.num = this_->imperial;
3723 break;
3724 case attr_bookmark_map:
3725 attr->u.map = bookmarks_get_map(this_->bookmarks);
3726 break;
3727 case attr_bookmarks:
3728 attr->u.bookmarks = this_->bookmarks;
3729 break;
3730 case attr_callback_list:
3731 attr->u.callback_list = this_->attr_cbl;
3732 break;
3733 case attr_destination:
3734 if (!this_->destination_valid)
3735 return 0;
3736 attr->u.pcoord = &this_->destination;
3737 break;
3738 case attr_displaylist:
3739 attr->u.displaylist = this_->displaylist;
3740 return (attr->u.displaylist != NULL);
3741 case attr_follow:
3742 if (!this_->vehicle)
3743 return 0;
3744 attr->u.num = this_->vehicle->follow_curr;
3745 break;
3746 case attr_former_destination_map:
3747 attr->u.map = this_->former_destination;
3748 break;
3749 case attr_graphics:
3750 attr->u.graphics = this_->gra;
3751 ret = (attr->u.graphics != NULL);
3752 break;
3753 case attr_gui:
3754 attr->u.gui = this_->gui;
3755 ret = (attr->u.gui != NULL);
3756 break;
3757 case attr_layout:
3758 if (iter)
3759 {
3760 if (iter->u.list)
3761 {
3762 iter->u.list = g_list_next(iter->u.list);
3763 }
3764 else
3765 {
3766 iter->u.list = this_->layouts;
3767 }
3768 if (!iter->u.list)
3769 {
3770 return 0;
3771 }
3772 attr->u.layout = (struct layout *) iter->u.list->data;
3773 }
3774 else
3775 {
3776 attr->u.layout = this_->layout_current;
3777 }
3778 break;
3779 case attr_map:
3780 if (iter && this_->mapsets)
3781 {
3782 if (!iter->u.mapset_handle)
3783 {
3784 iter->u.mapset_handle = mapset_open((struct mapset *) this_->mapsets->data);
3785 }
3786 attr->u.map = mapset_next(iter->u.mapset_handle, 0);
3787 if (!attr->u.map)
3788 {
3789 mapset_close(iter->u.mapset_handle);
3790 return 0;
3791 }
3792 }
3793 else
3794 {
3795 return 0;
3796 }
3797 break;
3798 case attr_mapset:
3799 attr->u.mapset = this_->mapsets->data;
3800 ret = (attr->u.mapset != NULL);
3801 break;
3802 case attr_navigation:
3803 attr->u.navigation = this_->navigation;
3804 break;
3805 case attr_orientation:
3806 attr->u.num = this_->orientation;
3807 break;
3808 case attr_osd_configuration:
3809 attr->u.num = this_->osd_configuration;
3810 break;
3811 case attr_pitch:
3812 attr->u.num = transform_get_pitch(this_->trans);
3813 break;
3814 case attr_projection:
3815 if (this_->trans)
3816 {
3817 attr->u.num = transform_get_projection(this_->trans);
3818 }
3819 else
3820 {
3821 return 0;
3822 }
3823 break;
3824 case attr_route:
3825 attr->u.route = this_->route;
3826 break;
3827 case attr_speech:
3828 attr->u.speech = this_->speech;
3829 break;
3830 case attr_tracking:
3831 attr->u.num = this_->tracking_flag;
3832 break;
3833 case attr_trackingo:
3834 attr->u.tracking = this_->tracking;
3835 break;
3836 case attr_transformation:
3837 attr->u.transformation = this_->trans;
3838 break;
3839 case attr_vehicle:
3840 if (iter)
3841 {
3842 if (iter->u.list)
3843 {
3844 iter->u.list = g_list_next(iter->u.list);
3845 }
3846 else
3847 {
3848 iter->u.list = this_->vehicles;
3849 }
3850 if (!iter->u.list)
3851 return 0;
3852 attr->u.vehicle = ((struct navit_vehicle*) iter->u.list->data)->vehicle;
3853 }
3854 else
3855 {
3856 if (this_->vehicle)
3857 {
3858 attr->u.vehicle = this_->vehicle->vehicle;
3859 }
3860 else
3861 {
3862 return 0;
3863 }
3864 }
3865 break;
3866 case attr_vehicleprofile:
3867 attr->u.vehicleprofile = this_->vehicleprofile;
3868 break;
3869 case attr_zoom:
3870 attr->u.num = transform_get_scale(this_->trans);
3871 break;
3872 case attr_autozoom_active:
3873 attr->u.num = this_->autozoom_active;
3874 break;
3875 case attr_follow_cursor:
3876 attr->u.num = this_->follow_cursor;
3877 break;
3878 default:
3879 return 0;
3880 }
3881 attr->type = type;
3882
3883 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3884 dbg(0,"+#+:leave\n");
3885 #endif
3886
3887 return ret;
3888 }
3889
3890 static int navit_add_log(struct navit *this_, struct log *log)
3891 {
3892 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3893 dbg(0,"+#+:enter\n");
3894 #endif
3895 struct attr type_attr;
3896 if (!log_get_attr(log, attr_type, &type_attr, NULL))
3897 return 0;
3898 if (!strcmp(type_attr.u.str, "textfile_debug"))
3899 {
3900 char *header = "type=track_tracked\n";
3901 if (this_->textfile_debug_log)
3902 return 0;
3903 log_set_header(log, header, strlen(header));
3904 this_->textfile_debug_log = log;
3905 return 1;
3906 }
3907 return 0;
3908 }
3909
3910 static int navit_add_layout(struct navit *this_, struct layout *layout)
3911 {
3912 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3913 dbg(0,"+#+:enter\n");
3914 #endif
3915 ////DBG dbg(0,"EEnter\n");
3916 struct attr active;
3917 this_->layouts = g_list_append(this_->layouts, layout);
3918 layout_get_attr(layout, attr_active, &active, NULL);
3919 if (active.u.num || !this_->layout_current)
3920 {
3921 this_->layout_current = layout;
3922 return 1;
3923 }
3924 return 0;
3925 }
3926
3927 int navit_add_attr(struct navit *this_, struct attr *attr)
3928 {
3929 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3930 dbg(0,"+#+:enter\n");
3931 #endif
3932 ////DBG dbg(0,"EEnter\n");
3933
3934 int ret = 1;
3935 switch (attr->type)
3936 {
3937 case attr_callback:
3938 navit_add_callback(this_, attr->u.callback);
3939 break;
3940 case attr_log:
3941 ret = navit_add_log(this_, attr->u.log);
3942 break;
3943 case attr_gui:
3944 ret = navit_set_gui(this_, attr->u.gui);
3945 break;
3946 case attr_graphics:
3947 ret = navit_set_graphics(this_, attr->u.graphics);
3948 break;
3949 case attr_layout:
3950 ret = navit_add_layout(this_, attr->u.layout);
3951 break;
3952 case attr_route:
3953 this_->route = attr->u.route;
3954 break;
3955 case attr_mapset:
3956 this_->mapsets = g_list_append(this_->mapsets, attr->u.mapset);
3957 break;
3958 case attr_navigation:
3959 this_->navigation = attr->u.navigation;
3960 break;
3961 case attr_recent_dest:
3962 this_->recentdest_count = attr->u.num;
3963 break;
3964 case attr_speech:
3965 this_->speech = attr->u.speech;
3966 break;
3967 case attr_tracking:
3968 this_->tracking = attr->u.tracking;
3969 break;
3970 case attr_vehicle:
3971 ret = navit_add_vehicle(this_, attr->u.vehicle);
3972 break;
3973 case attr_vehicleprofile:
3974 this_->vehicleprofiles = g_list_prepend(this_->vehicleprofiles, attr->u.vehicleprofile);
3975 break;
3976 case attr_autozoom_min:
3977 this_->autozoom_min = attr->u.num;
3978 break;
3979 default:
3980 return 0;
3981 }
3982 callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
3983
3984 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3985 dbg(0,"+#+:leave\n");
3986 #endif
3987
3988 return ret;
3989 }
3990
3991 int navit_remove_attr(struct navit *this_, struct attr *attr)
3992 {
3993 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
3994 dbg(0,"+#+:enter\n");
3995 #endif
3996 int ret = 1;
3997 switch (attr->type)
3998 {
3999 case attr_callback:
4000 navit_remove_callback(this_, attr->u.callback);
4001 break;
4002 default:
4003 return 0;
4004 }
4005
4006 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4007 dbg(0,"+#+:leave\n");
4008 #endif
4009
4010 return ret;
4011 }
4012
4013 struct attr_iter *
4014 navit_attr_iter_new(void)
4015 {
4016 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4017 dbg(0,"+#+:enter\n");
4018 #endif
4019 return g_new0(struct attr_iter, 1);
4020 }
4021
4022 void navit_attr_iter_destroy(struct attr_iter *iter)
4023 {
4024 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4025 dbg(0,"+#+:enter\n");
4026 #endif
4027 g_free(iter);
4028 }
4029
4030 void navit_add_callback(struct navit *this_, struct callback *cb)
4031 {
4032 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4033 dbg(0,"+#+:enter\n");
4034 #endif
4035 ////DBG dbg(0,"EEnter\n");
4036
4037 callback_list_add(this_->attr_cbl, cb);
4038 }
4039
4040 void navit_remove_callback(struct navit *this_, struct callback *cb)
4041 {
4042 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4043 dbg(0,"+#+:enter\n");
4044 #endif
4045 ////DBG dbg(0,"EEnter\n");
4046
4047 callback_list_remove(this_->attr_cbl, cb);
4048 }
4049
4050 /**
4051 * Toggle the cursor update : refresh the map each time the cursor has moved (instead of only when it reaches a border)
4052 *
4053 * @param navit The navit instance
4054 * @returns nothing
4055 */
4056 static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt)
4057 {
4058 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4059 dbg(0,"+#+:enter\n");
4060 #endif
4061 ////DBG dbg(0,"EEnter\n");
4062
4063 struct point cursor_pnt;
4064 enum projection pro;
4065
4066 if (this_->blocked)
4067 {
4068 return;
4069 }
4070
4071 if (pnt)
4072 {
4073 cursor_pnt = *pnt;
4074 }
4075 else
4076 {
4077 pro = transform_get_projection(this_->trans_cursor);
4078 if (!pro)
4079 {
4080 return;
4081 }
4082 transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
4083 }
4084
4085 //dbg(0,"xx=%d\n",cursor_pnt.x);
4086 //dbg(0,"yy=%d\n",cursor_pnt.y);
4087
4088 global_vehicle_pos_onscreen.x = cursor_pnt.x;
4089 global_vehicle_pos_onscreen.y = cursor_pnt.y;
4090
4091 //dbg(0,"xx=%d\n",cursor_pnt.x);
4092 //dbg(0,"yy=%d\n",cursor_pnt.y);
4093 //dbg(0,"vehicle_draw_001\n");
4094 vehicle_draw(nv->vehicle, this_->gra, &cursor_pnt, 0, nv->dir - transform_get_yaw(this_->trans_cursor), nv->speed);
4095 #if 0
4096 if (pnt)
4097 pnt2=*pnt;
4098 else
4099 {
4100 pro=transform_get_projection(this_->trans);
4101 transform(this_->trans, pro, &nv->coord, &pnt2, 1);
4102 }
4103 #if 1
4104 cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL);
4105 #else
4106 cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, 1);
4107 #endif
4108 #endif
4109 }
4110
4111 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
4112 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
4113 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
4114 static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv)
4115 {
4116 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4117 dbg(0,"+#+:enter\n");
4118 #endif
4119
4120 #ifdef NAVIT_MEASURE_TIME_DEBUG
4121 clock_t s_ = debug_measure_start();
4122 #endif
4123
4124 struct attr attr_valid, attr_dir, attr_speed, attr_pos;
4125 struct pcoord cursor_pc;
4126 struct point cursor_pnt, *pnt = &cursor_pnt;
4127 struct point old_cursor_pnt;
4128 struct tracking *tracking = NULL;
4129 struct pcoord pc[16];
4130 enum projection pro = transform_get_projection(this_->trans_cursor);
4131 int count;
4132 int old_dir;
4133 int old_pos_invalid;
4134 int (*get_attr)(void *, enum attr_type, struct attr *, struct attr_iter *);
4135 void *attr_object;
4136 char *destination_file;
4137
4138 if (this_->ready != 3)
4139 {
4140 //profile(0,"return 1\n");
4141 return;
4142 }
4143
4144 navit_layout_switch(this_);
4145 if (this_->vehicle == nv && this_->tracking_flag)
4146 {
4147 tracking = this_->tracking;
4148 }
4149
4150 if (tracking)
4151 {
4152 tracking_update(tracking, nv->vehicle, this_->vehicleprofile, pro);
4153 attr_object = tracking;
4154 get_attr = (int(*)(void *, enum attr_type, struct attr *, struct attr_iter *)) tracking_get_attr;
4155 }
4156 else
4157 {
4158 attr_object = nv->vehicle;
4159 get_attr = (int(*)(void *, enum attr_type, struct attr *, struct attr_iter *)) vehicle_get_attr;
4160 }
4161
4162 if (get_attr(attr_object, attr_position_valid, &attr_valid, NULL))
4163 {
4164 if (!attr_valid.u.num != attr_position_valid_invalid)
4165 {
4166 return;
4167 }
4168 }
4169
4170 // load attrs with data from vehicle
4171 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))
4172 {
4173 return;
4174 }
4175 // load attrs with data from vehicle
4176
4177
4178 // save old value
4179 old_dir = nv->dir;
4180
4181 nv->dir = *attr_dir.u.numd;
4182 nv->speed = *attr_speed.u.numd;
4183
4184 // old values ---------
4185 if ((global_last_vehicle_pos_geo.lat != 0.0) && (global_last_vehicle_pos_geo.lng != 0.0))
4186 {
4187 transform_from_geo(pro, &global_last_vehicle_pos_geo, &nv->coord);
4188 transform(this_->trans_cursor, pro, &nv->coord, &old_cursor_pnt, 1, 0, 0, NULL);
4189 old_pos_invalid = 0;
4190
4191 // XXX // dbg(0,"old values lat:%f lon:%f px:%d py:%d\n", global_last_vehicle_pos_geo.lat, global_last_vehicle_pos_geo.lng, old_cursor_pnt.x, old_cursor_pnt.y);
4192 }
4193 else
4194 {
4195 old_pos_invalid = 1;
4196 }
4197 // old values ---------
4198
4199
4200 transform_from_geo(pro, attr_pos.u.coord_geo, &nv->coord);
4201
4202 // save this position
4203 global_last_vehicle_pos_geo.lat = attr_pos.u.coord_geo->lat;
4204 global_last_vehicle_pos_geo.lng = attr_pos.u.coord_geo->lng;
4205 // save this position
4206
4207
4208 // XXX // dbg(0,"v1 lat:%f lon:%f x:%d y:%d\n",attr_pos.u.coord_geo->lat, attr_pos.u.coord_geo->lng, nv->coord.x, nv->coord.y);
4209
4210 //if (nv != this_->vehicle)
4211 //{
4212 // if (hold_drawing == 0)
4213 // {
4214 // navit_vehicle_draw(this_, nv, NULL);
4215 // }
4216 // return;
4217 //}
4218 cursor_pc.x = nv->coord.x;
4219 cursor_pc.y = nv->coord.y;
4220 cursor_pc.pro = pro;
4221 if (this_->route)
4222 {
4223 if (tracking)
4224 {
4225 route_set_position_from_tracking(this_->route, tracking, pro);
4226 }
4227 else
4228 {
4229 route_set_position(this_->route, &cursor_pc);
4230 }
4231 }
4232
4233 callback_list_call_attr_0(this_->attr_cbl, attr_position);
4234
4235 // navit_textfile_debug_log(this_, "type=trackpoint_tracked");
4236 /*
4237 if (this_->gui && nv->speed > MYSTERY_SPEED)
4238 {
4239 // stupid!!!! this gets called every second!!! fixme!!!!!!
4240 navit_disable_suspend();
4241 // stupid!!!! this gets called every second!!! fixme!!!!!!
4242 }
4243 */
4244
4245 transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
4246 // XXX // dbg(0,"v2 px:%d py:%d x:%d y:%d\n", cursor_pnt.x, cursor_pnt.y, nv->coord.x, nv->coord.y);
4247
4248
4249 if (old_pos_invalid == 0)
4250 {
4251 int delta_x = cursor_pnt.x - old_cursor_pnt.x;
4252 int delta_y = cursor_pnt.y - old_cursor_pnt.y;
4253 int delta_angle = nv->dir - old_dir;
4254
4255 #ifdef HAVE_API_ANDROID
4256 //dbg(0,"delta x=%d, y=%d, angle=%d\n", delta_x, delta_y, delta_angle);
4257 set_vehicle_values_to_java_delta(delta_x, delta_y, delta_angle);
4258 #endif
4259 }
4260
4261 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)))
4262 {
4263 if (hold_drawing == 0)
4264 {
4265 //dbg(0,"call:navit_set_center_cursor_draw:start\n");
4266 navit_set_center_cursor_draw(this_);
4267 //dbg(0,"call:navit_set_center_cursor_draw:end\n");
4268 }
4269 }
4270 else
4271 {
4272 if (hold_drawing == 0)
4273 {
4274 navit_vehicle_draw(this_, nv, pnt);
4275 }
4276 }
4277
4278 if (nv->follow_curr > 1)
4279 {
4280 nv->follow_curr--;
4281 }
4282 else
4283 {
4284 nv->follow_curr = nv->follow;
4285 }
4286
4287 callback_list_call_attr_2(this_->attr_cbl, attr_position_coord_geo, this_, nv->vehicle);
4288
4289 /* Finally, if we reached our destination, stop navigation. */
4290 if (this_->route)
4291 {
4292 switch (route_destination_reached(this_->route))
4293 {
4294 case 1:
4295 route_remove_waypoint(this_->route);
4296 count = route_get_destinations(this_->route, pc, 16);
4297
4298 // destination_file = bookmarks_get_destination_file(TRUE);
4299 // bookmarks_append_coord(this_->bookmarks, destination_file, pc, count, "former_itinerary_part", NULL, NULL, this_->recentdest_count);
4300
4301 #ifdef HAVE_API_ANDROID
4302 // waypoint reached
4303 android_return_generic_int(5, 1);
4304 #ifdef NAVIT_SAY_DEBUG_PRINT
4305 android_send_generic_text(1,"+*#O:Waypoint reached\n");
4306 #endif
4307 // say it
4308 navit_say(this_, _("Waypoint reached"));
4309 #endif
4310 break;
4311 case 2:
4312 navit_set_destination(this_, NULL, NULL, 0);
4313 // ** inform java that we reached our destination **
4314 #ifdef HAVE_API_ANDROID
4315 android_return_generic_int(4, 1);
4316 #ifdef NAVIT_SAY_DEBUG_PRINT
4317 android_send_generic_text(1,"+*#O:You have reached your destination\n");
4318 #endif
4319 // say it
4320 navit_say(this_, _("You have reached your destination"));
4321 #endif
4322 break;
4323 }
4324 }
4325
4326 if (hold_drawing == 0)
4327 {
4328 // draw???????
4329 // navit_draw(this_);
4330 if (this_->ready == 3)
4331 {
4332 //dbg(0,"location update:draw:start\n");
4333 //navit_draw_async(this_, 1);
4334 //dbg(0,"location update:draw:end\n");
4335 }
4336 // draw???????
4337 }
4338
4339 //dbg(0,"navit_vehicle_update_999\n");
4340
4341 #ifdef NAVIT_MEASURE_TIME_DEBUG
4342 debug_mrp("navit_vehicle_update:", debug_measure_end(s_));
4343 #endif
4344
4345 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4346 dbg(0,"+#+:leave\n");
4347 #endif
4348 }
4349 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
4350 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
4351 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
4352
4353
4354 /**
4355 * Set the position of the vehicle
4356 *
4357 * @param navit The navit instance
4358 * @param c The coordinate to set as position
4359 * @returns nothing
4360 */
4361 void navit_set_position(struct navit *this_, struct pcoord *c)
4362 {
4363 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4364 dbg(0,"+#+:enter\n");
4365 #endif
4366 //DBG dbg(0,"EEnter\n");
4367
4368 if (this_->route)
4369 {
4370 route_set_position(this_->route, c);
4371 callback_list_call_attr_0(this_->attr_cbl, attr_position);
4372 }
4373
4374 if (this_->ready == 3)
4375 {
4376 navit_draw(this_);
4377 }
4378 }
4379
4380 static int navit_set_vehicleprofile(struct navit *this_, char *name)
4381 {
4382 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4383 dbg(0,"+#+:enter\n");
4384 #endif
4385 ////DBG dbg(0,"EEnter\n");
4386
4387 struct attr attr;
4388 GList *l;
4389 l = this_->vehicleprofiles;
4390 while (l)
4391 {
4392 if (vehicleprofile_get_attr(l->data, attr_name, &attr, NULL))
4393 {
4394 if (!strcmp(attr.u.str, name))
4395 {
4396 this_->vehicleprofile = l->data;
4397 if (this_->route)
4398 route_set_profile(this_->route, this_->vehicleprofile);
4399 return 1;
4400 }
4401 }
4402 l = g_list_next(l);
4403 }
4404 return 0;
4405 }
4406
4407 static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv)
4408 {
4409 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4410 dbg(0,"+#+:enter\n");
4411 #endif
4412 ////DBG dbg(0,"EEnter\n");
4413
4414 struct attr attr;
4415 this_->vehicle = nv;
4416
4417 if (nv && vehicle_get_attr(nv->vehicle, attr_profilename, &attr, NULL))
4418 {
4419 if (navit_set_vehicleprofile(this_, attr.u.str))
4420 {
4421 return;
4422 }
4423 }
4424
4425 if (!navit_set_vehicleprofile(this_, "car"))
4426 {
4427 /* We do not have a fallback "car" profile
4428 * so lets set any profile */
4429 GList *l;
4430 l = this_->vehicleprofiles;
4431 if (l)
4432 {
4433 this_->vehicleprofile = l->data;
4434 if (this_->route)
4435 {
4436 route_set_profile(this_->route, this_->vehicleprofile);
4437 }
4438 }
4439 }
4440 }
4441
4442 /**
4443 * Register a new vehicle
4444 *
4445 * @param navit The navit instance
4446 * @param v The vehicle instance
4447 * @returns 1 for success
4448 */
4449 int navit_add_vehicle(struct navit *this_, struct vehicle *v)
4450 {
4451 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4452 dbg(0,"+#+:enter\n");
4453 #endif
4454
4455 struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1);
4456 struct attr follow, active, animate;
4457 nv->vehicle = v;
4458 nv->follow = 0;
4459 nv->last.x = 0;
4460 nv->last.y = 0;
4461
4462 global_last_vehicle_pos_geo.lat = 0;
4463 global_last_vehicle_pos_geo.lng = 0;
4464
4465 nv->animate_cursor = 0;
4466 if ((vehicle_get_attr(v, attr_follow, &follow, NULL)))
4467 nv->follow = follow.u.num;
4468 nv->follow_curr = nv->follow;
4469 this_->vehicles = g_list_append(this_->vehicles, nv);
4470 if ((vehicle_get_attr(v, attr_active, &active, NULL)) && active.u.num)
4471 navit_set_vehicle(this_, nv);
4472 if ((vehicle_get_attr(v, attr_animate, &animate, NULL)))
4473 nv->animate_cursor = animate.u.num;
4474 nv->callback.type = attr_callback;
4475
4476 // gets called via this callback in vehicle_android.c [in function: vehicle_android_callback]
4477 nv->callback.u.callback = callback_new_attr_2(callback_cast(navit_vehicle_update), attr_position_coord_geo, this_, nv);
4478 callback_add_names(nv->callback.u.callback, "navit_add_vehicle", "navit_vehicle_update");
4479
4480 //dbg(0,"EEnter 11\n");
4481 vehicle_add_attr(nv->vehicle, &nv->callback);
4482 //dbg(0,"EEnter 22\n");
4483 vehicle_set_attr(nv->vehicle, &this_->self);
4484 //dbg(0,"EEnter 33\n");
4485
4486 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4487 dbg(0,"+#+:leave\n");
4488 #endif
4489
4490 return 1;
4491 }
4492
4493 struct gui *
4494 navit_get_gui(struct navit *this_)
4495 {
4496 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4497 dbg(0,"+#+:enter\n");
4498 #endif
4499 return this_->gui;
4500 }
4501
4502 struct transformation *
4503 navit_get_trans(struct navit *this_)
4504 {
4505 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4506 dbg(0,"+#+:enter\n");
4507 #endif
4508 return this_->trans;
4509 }
4510
4511 struct route *
4512 navit_get_route(struct navit *this_)
4513 {
4514 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4515 dbg(0,"+#+:enter\n");
4516 #endif
4517 return this_->route;
4518 }
4519
4520 struct navigation *
4521 navit_get_navigation(struct navit *this_)
4522 {
4523 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4524 dbg(0,"+#+:enter\n");
4525 #endif
4526 return this_->navigation;
4527 }
4528
4529 struct displaylist *
4530 navit_get_displaylist(struct navit *this_)
4531 {
4532 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4533 dbg(0,"+#+:enter\n");
4534 #endif
4535 return this_->displaylist;
4536 }
4537
4538 void navit_layout_switch(struct navit *n)
4539 {
4540 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4541 dbg(0,"+#+:enter\n");
4542 #endif
4543 ////DBG dbg(0,"EEnter\n");
4544
4545 int currTs = 0;
4546 struct attr iso8601_attr, geo_attr, valid_attr, layout_attr;
4547 double trise, tset, trise_actual;
4548 struct layout *l;
4549 int year, month, day;
4550
4551 if (navit_get_attr(n, attr_layout, &layout_attr, NULL) != 1)
4552 {
4553 return; //No layout - nothing to switch
4554 }
4555 if (!n->vehicle)
4556 return;
4557 l = layout_attr.u.layout;
4558
4559 if (l->dayname || l->nightname)
4560 {
4561 //Ok, we know that we have profile to switch
4562
4563 //Check that we aren't calculating too fast
4564 if (vehicle_get_attr(n->vehicle->vehicle, attr_position_time_iso8601, &iso8601_attr, NULL) == 1)
4565 {
4566 currTs = iso8601_to_secs(iso8601_attr.u.str);
4567 // dbg(1, "currTs: %u:%u\n", currTs % 86400 / 3600, ((currTs % 86400) % 3600) / 60);
4568 }
4569 if (currTs - (n->prevTs) < 60)
4570 {
4571 //We've have to wait a little
4572 return;
4573 }
4574 if (sscanf(iso8601_attr.u.str, "%d-%02d-%02dT", &year, &month, &day) != 3)
4575 return;
4576 if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &valid_attr, NULL) && valid_attr.u.num == attr_position_valid_invalid)
4577 {
4578 return; //No valid fix yet
4579 }
4580 if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo, &geo_attr, NULL) != 1)
4581 {
4582 //No position - no sun
4583 return;
4584 }
4585
4586 //We calculate sunrise anyway, cause it is needed both for day and for night
4587 if (__sunriset__(year, month, day, geo_attr.u.coord_geo->lng, geo_attr.u.coord_geo->lat, -5, 1, &trise, &tset) != 0)
4588 {
4589 //near the pole sun never rises/sets, so we should never switch profiles
4590 // dbg(1, "trise: %u:%u, sun never visible, never switch profile\n", HOURS(trise), MINUTES(trise));
4591 n->prevTs = currTs;
4592 return;
4593 }
4594
4595 trise_actual = trise;
4596 // dbg(1, "trise: %u:%u\n", HOURS(trise), MINUTES(trise));
4597 if (l->dayname)
4598 {
4599
4600 if ((HOURS(trise) * 60 + MINUTES(trise) == (currTs % 86400) / 60) || (n->prevTs == 0 && ((HOURS(trise) * 60 + MINUTES(trise) < (currTs % 86400) / 60))))
4601 {
4602 //The sun is rising now!
4603 if (strcmp(l->name, l->dayname))
4604 {
4605 navit_set_layout_by_name(n, l->dayname);
4606 }
4607 }
4608 }
4609 if (l->nightname)
4610 {
4611 if (__sunriset__(year, month, day, geo_attr.u.coord_geo->lng, geo_attr.u.coord_geo->lat, -5, 1, &trise, &tset) != 0)
4612 {
4613 //near the pole sun never rises/sets, so we should never switch profiles
4614 // dbg(1,"tset: %u:%u, sun always visible, never switch profile\n",HOURS(tset), MINUTES(tset));
4615 n->prevTs = currTs;
4616 return;
4617 }
4618 // dbg(1, "tset: %u:%u\n", HOURS(tset), MINUTES(tset));
4619 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)))))
4620 {
4621 //Time to sleep
4622 if (strcmp(l->name, l->nightname))
4623 {
4624 navit_set_layout_by_name(n, l->nightname);
4625 }
4626 }
4627 }
4628
4629 n->prevTs = currTs;
4630 }
4631 }
4632
4633 int navit_set_vehicle_by_name(struct navit *n, const char *name)
4634 {
4635 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4636 dbg(0,"+#+:enter\n");
4637 #endif
4638 ////DBG dbg(0,"EEnter\n");
4639
4640 struct vehicle *v;
4641 struct attr_iter *iter;
4642 struct attr vehicle_attr, name_attr;
4643
4644 iter = navit_attr_iter_new();
4645
4646 while (navit_get_attr(n, attr_vehicle, &vehicle_attr, iter))
4647 {
4648 v = vehicle_attr.u.vehicle;
4649 vehicle_get_attr(v, attr_name, &name_attr, NULL);
4650 if (name_attr.type == attr_name)
4651 {
4652 if (!strcmp(name, name_attr.u.str))
4653 {
4654 navit_set_attr(n, &vehicle_attr);
4655 navit_attr_iter_destroy(iter);
4656 return 1;
4657 }
4658 }
4659 }
4660 navit_attr_iter_destroy(iter);
4661 return 0;
4662 }
4663
4664 int navit_set_layout_by_name(struct navit *n, const char *name)
4665 {
4666 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4667 dbg(0,"+#+:enter\n");
4668 #endif
4669 ////DBG dbg(0,"EEnter\n");
4670
4671 struct layout *l;
4672 struct attr_iter iter;
4673 struct attr layout_attr;
4674
4675 iter.u.list = 0x00;
4676
4677 if (navit_get_attr(n, attr_layout, &layout_attr, &iter) != 1)
4678 {
4679 return 0; //No layouts - nothing to do
4680 }
4681 if (iter.u.list == NULL)
4682 {
4683 return 0;
4684 }
4685
4686 iter.u.list = g_list_first(iter.u.list);
4687
4688 while (iter.u.list)
4689 {
4690 l = (struct layout*) iter.u.list->data;
4691 if (!strcmp(name, l->name))
4692 {
4693 layout_attr.u.layout = l;
4694 layout_attr.type = attr_layout;
4695 navit_set_attr(n, &layout_attr);
4696 iter.u.list = g_list_first(iter.u.list);
4697 return 1;
4698 }
4699 iter.u.list = g_list_next(iter.u.list);
4700 }
4701
4702 iter.u.list = g_list_first(iter.u.list);
4703 return 0;
4704 }
4705
4706 void navit_disable_suspend()
4707 {
4708 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4709 dbg(0,"+#+:enter\n");
4710 #endif
4711 ////DBG dbg(0,"EEnter\n");
4712
4713 gui_disable_suspend(global_navit->gui);
4714 callback_list_call_attr_0(global_navit->attr_cbl, attr_unsuspend);
4715 }
4716
4717 /**
4718 * @brief Dumps item attrs to string
4719 *
4720 * @param item item
4721 * @param pretty 0 -> normal, 1 -> pretty output
4722 * @return string with attrs separated by '\n'
4723 */
4724 char* navit_item_dump(struct item *item, int pretty)
4725 {
4726 char *temp_str = NULL;
4727 char *ret_value = NULL;
4728 struct attr attr;
4729 struct attr attr2;
4730 int had_flags = 0;
4731 int *f;
4732 int flags;
4733
4734 if (item == NULL)
4735 {
4736 ret_value = g_strdup_printf("");
4737 return ret_value;
4738 }
4739
4740 if (pretty == 1)
4741 {
4742 ret_value = g_strdup_printf("+*TYPE*+:%s", item_to_name(item->type));
4743 }
4744 else
4745 {
4746 ret_value = g_strdup_printf("type=%s", item_to_name(item->type));
4747 }
4748
4749 while (item_attr_get(item, attr_any, &attr))
4750 {
4751 if (attr.type == attr_flags)
4752 {
4753 had_flags = 1;
4754
4755 flags = attr.u.num;
4756 if (flags == 0)
4757 {
4758 f = item_get_default_flags(item->type);
4759 if (f)
4760 {
4761 flags = *f;
4762 }
4763 else
4764 {
4765 flags = 0;
4766 }
4767 }
4768
4769 if (pretty == 1)
4770 {
4771 temp_str = g_strdup_printf("%s\n%s=%s", ret_value, attr_to_name(attr.type), flags_to_text(flags));
4772 }
4773 else
4774 {
4775 temp_str = g_strdup_printf("%s\n%s='%s'", ret_value, attr_to_name(attr.type), flags_to_text(flags));
4776 }
4777 }
4778 else
4779 {
4780 if (pretty == 1)
4781 {
4782 temp_str = g_strdup_printf("%s\n%s=%s", ret_value, attr_to_name(attr.type), attr_to_text(&attr, NULL, 1));
4783 }
4784 else
4785 {
4786 temp_str = g_strdup_printf("%s\n%s='%s'", ret_value, attr_to_name(attr.type), attr_to_text(&attr, NULL, 1));
4787 }
4788 }
4789 g_free(ret_value);
4790 ret_value = g_strdup(temp_str);
4791 g_free(temp_str);
4792 }
4793
4794 if (had_flags == 0)
4795 {
4796 f = item_get_default_flags(item->type);
4797 if (f)
4798 {
4799 flags = *f;
4800
4801 if (pretty == 1)
4802 {
4803 temp_str = g_strdup_printf("%s\n%s=%s", ret_value, attr_to_name(attr_flags), flags_to_text(flags));
4804 }
4805 else
4806 {
4807 temp_str = g_strdup_printf("%s\n%s='%s'", ret_value, attr_to_name(attr_flags), flags_to_text(flags));
4808 }
4809
4810 g_free(ret_value);
4811 ret_value = g_strdup(temp_str);
4812 g_free(temp_str);
4813 }
4814 }
4815
4816 // g_free(item);
4817
4818 return ret_value;
4819 }
4820
4821 int navit_normal_item(enum item_type type)
4822 {
4823 if ((type > type_none) && (type < type_waypoint))
4824 {
4825 return 1;
4826 }
4827 else if ((type >= type_poi_land_feature) && (type <= type_poi_zoo))
4828 {
4829 return 1;
4830 }
4831 else if ((type >= type_traffic_signals) && (type <= type_poi_cafe))
4832 {
4833 return 1;
4834 }
4835 else if ((type >= type_poi_peak) && (type <= type_poi_ruins))
4836 {
4837 return 1;
4838 }
4839 else if ((type >= type_poi_post_box) && (type <= type_house_number))
4840 {
4841 return 1;
4842 }
4843 else if ((type >= type_poi_playground) && (type <= type_poi_shop_photo))
4844 {
4845 return 1;
4846 }
4847 else if (type == type_place_label)
4848 {
4849 return 1;
4850 }
4851 else if ((type >= type_line) && (type <= type_ferry))
4852 {
4853 return 1;
4854 }
4855 else if (type == type_street_unkn)
4856 {
4857 return 1;
4858 }
4859 else if ((type >= type_aeroway_runway) && (type <= type_footway_and_piste_nordic))
4860 {
4861 return 1;
4862 }
4863 else if ((type >= type_house_number_interpolation_even) && (type <= type_city_wall))
4864 {
4865 return 1;
4866 }
4867 else if ((type >= type_border_city) && (type <= type_border_county))
4868 {
4869 return 1;
4870 }
4871 else if ((type >= type_forest_way_1) && (type <= type_forest_way_4))
4872 {
4873 return 1;
4874 }
4875 else if ((type >= type_area) && (type <= type_poly_museum))
4876 {
4877 return 1;
4878 }
4879 else if ((type >= type_poly_commercial_center) && (type <= type_tundra))
4880 {
4881 return 1;
4882 }
4883 else if ((type >= type_poly_building) && (type <= type_poly_terminal))
4884 {
4885 return 1;
4886 }
4887 else if ((type >= type_poly_sports_centre) && (type <= type_poly_aeroway_runway))
4888 {
4889 return 1;
4890 }
4891
4892 return 0;
4893 }
4894
4895 char* navit_find_nearest_item_dump(struct mapset *ms, struct pcoord *pc, int pretty)
4896 {
4897 int max_dist = 0; // smallest rectangle possible
4898 int dist, mindist = 0, pos;
4899 int mindist_hn = 0;
4900 struct mapset_handle *h;
4901 struct map *m;
4902 struct map_rect *mr;
4903 struct item *item;
4904 struct coord lp;
4905 struct street_data *sd;
4906 struct coord c;
4907 struct coord_geo g;
4908 struct map_selection sel;
4909 struct attr street_name_attr;
4910 struct attr hn_attr;
4911 char *ret_str = NULL;
4912
4913 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4914 dbg(0,"+#+:enter\n");
4915 #endif
4916
4917 mindist = 1000;
4918
4919 h = mapset_open(ms);
4920 if (!h)
4921 {
4922 // dbg(0,"return 1\n");
4923 ret_str = g_strdup_printf("");
4924 return ret_str;
4925 }
4926
4927 while ((m = mapset_next(h, 0)))
4928 {
4929 c.x = pc->x;
4930 c.y = pc->y;
4931 if (map_projection(m) != pc->pro)
4932 {
4933 transform_to_geo(pc->pro, &c, &g);
4934 transform_from_geo(map_projection(m), &g, &c);
4935 }
4936
4937 sel.next = NULL;
4938 sel.order = 18;
4939 sel.range.min = type_none;
4940 sel.range.max = type_last;
4941 sel.u.c_rect.lu.x = c.x - max_dist;
4942 sel.u.c_rect.lu.y = c.y + max_dist;
4943 sel.u.c_rect.rl.x = c.x + max_dist;
4944 sel.u.c_rect.rl.y = c.y - max_dist;
4945
4946 mr = map_rect_new(m, &sel);
4947 if (!mr)
4948 {
4949 continue;
4950 }
4951
4952 while ((item = map_rect_get_item(mr)))
4953 {
4954 if (navit_normal_item(item->type) == 1)
4955 {
4956 //dbg(0,"*type=%s\n", item_to_name(item->type));
4957
4958 struct coord c2[101];
4959 int count22 = item_coord_get(item, c2, 100);
4960 if (count22 == 0)
4961 {
4962 continue;
4963 }
4964 else if (count22 > 1)
4965 {
4966 dist = transform_distance_polyline_sq__v2(c2, count22, &c);
4967 if (dist < mindist)
4968 {
4969 mindist = dist;
4970 if (ret_str != NULL)
4971 {
4972 g_free(ret_str);
4973 }
4974 ret_str = navit_item_dump(item, pretty);
4975 }
4976 }
4977 else
4978 {
4979 dist = transform_distance_sq(&c, &c2);
4980 if (dist <= (mindist + 4))
4981 {
4982 mindist = dist;
4983 if (ret_str != NULL)
4984 {
4985 g_free(ret_str);
4986 }
4987 ret_str = navit_item_dump(item, pretty);
4988 }
4989 }
4990 // dbg(0,"*end\n");
4991 }
4992 }
4993
4994 if (mr)
4995 {
4996 map_rect_destroy(mr);
4997 }
4998 }
4999 mapset_close(h);
5000
5001 if (ret_str == NULL)
5002 {
5003 // dbg(0,"was NULL\n");
5004 ret_str = g_strdup_printf("");
5005 }
5006
5007 return ret_str;
5008 }
5009
5010 /**
5011 * @brief Finds the nearest street to a given coordinate
5012 *
5013 * @param ms The mapset to search in for the street
5014 * @param pc The coordinate to find a street nearby [ input in pcoord(x,y) ]
5015 * @return The nearest street
5016 */
5017 char*
5018 navit_find_nearest_street(struct mapset *ms, struct pcoord *pc)
5019 {
5020 int max_dist = 0; // smallest rectangle possible
5021 int dist, mindist = 0, pos;
5022 struct mapset_handle *h;
5023 struct map *m;
5024 struct map_rect *mr;
5025 struct item *item;
5026 struct coord lp;
5027 struct street_data *sd;
5028 struct coord c;
5029 struct coord_geo g;
5030 struct map_selection sel;
5031 struct attr street_name_attr;
5032 char *street_name = NULL;
5033
5034 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
5035 dbg(0,"+#+:enter\n");
5036 #endif
5037
5038 mindist = 10000; // start with small radius at the beginning!
5039 street_name = g_strdup_printf(" ");
5040
5041 h = mapset_open(ms);
5042
5043 if (!h)
5044 {
5045 // set global value :-(
5046 dist_to_street = mindist;
5047 return street_name;
5048 }
5049
5050 while ((m = mapset_next(h, 0)))
5051 {
5052 c.x = pc->x;
5053 c.y = pc->y;
5054 if (map_projection(m) != pc->pro)
5055 {
5056 transform_to_geo(pc->pro, &c, &g);
5057 transform_from_geo(map_projection(m), &g, &c);
5058 }
5059
5060 sel.next = NULL;
5061 sel.order = 18;
5062 sel.range.min = type_line;
5063 sel.range.max = type_area;
5064 sel.u.c_rect.lu.x = c.x - max_dist;
5065 sel.u.c_rect.lu.y = c.y + max_dist;
5066 sel.u.c_rect.rl.x = c.x + max_dist;
5067 sel.u.c_rect.rl.y = c.y - max_dist;
5068
5069 mr = map_rect_new(m, &sel);
5070 if (!mr)
5071 {
5072 continue;
5073 }
5074
5075 while ((item = map_rect_get_item(mr)))
5076 {
5077 if (item_get_default_flags(item->type))
5078 {
5079 sd = street_get_data(item);
5080 if (!sd)
5081 {
5082 continue;
5083 }
5084 //dbg(0,"6 sd x:%d sd y:%d count:%d\n", sd->c->x, sd->c->y, sd->count);
5085 //dbg(0,"6 c x:%d c y:%d\n", c.x, c.y);
5086 dist = transform_distance_polyline_sq__v2(sd->c, sd->count, &c);
5087 //dbg(0,"mindist:%d dist:%d\n", mindist, dist);
5088 if (dist < mindist)
5089 {
5090 //dbg(0,"6.a\n");
5091 mindist = dist;
5092
5093 if (item_attr_get(item, attr_street_name, &street_name_attr))
5094 {
5095 if (street_name)
5096 {
5097 g_free(street_name);
5098 street_name = NULL;
5099 }
5100 street_name = g_strdup_printf("%s", street_name_attr.u.str);
5101 //dbg(0,"r3 %s\n", street_name);
5102 }
5103 else if (item_attr_get(item, attr_label, &street_name_attr))
5104 {
5105 if (street_name)
5106 {
5107 g_free(street_name);
5108 street_name = NULL;
5109 }
5110 street_name = g_strdup_printf("%s", street_name_attr.u.str);
5111 //dbg(0,"r1 %s\n", street_name);
5112 }
5113 else if (item_attr_get(item, attr_street_name_systematic, &street_name_attr))
5114 {
5115 if (street_name)
5116 {
5117 g_free(street_name);
5118 street_name = NULL;
5119 }
5120 street_name = g_strdup_printf("%s", street_name_attr.u.str);
5121 //dbg(0,"r4 %s\n", street_name);
5122 }
5123 else
5124 {
5125 //if (street_name)
5126 //{
5127 // g_free(street_name);
5128 // street_name = NULL;
5129 //}
5130 //street_name = g_strdup_printf("---");
5131 }
5132 }
5133 street_data_free(sd);
5134 }
5135 }
5136
5137 if (mr)
5138 {
5139 map_rect_destroy(mr);
5140 }
5141 }
5142 mapset_close(h);
5143 // set global value :-(
5144 dist_to_street = mindist;
5145 return street_name;
5146 }
5147
5148 /**
5149 * @brief Finds the nearest street or housenumber to a given coordinate
5150 *
5151 * @param ms The mapset to search in for the street
5152 * @param pc The coordinate to find a street nearby [ input in pcoord(x,y) ]
5153 * @return The nearest street or housenumber
5154 */
5155 char*
5156 navit_find_nearest_street_hn(struct mapset *ms, struct pcoord *pc)
5157 {
5158 int max_dist = 0; // smallest rectangle possible
5159 int dist, mindist = 0, pos;
5160 int mindist_hn = 0;
5161 struct mapset_handle *h;
5162 struct map *m;
5163 struct map_rect *mr;
5164 struct item *item;
5165 struct coord lp;
5166 struct street_data *sd;
5167 struct coord c;
5168 struct coord_geo g;
5169 struct map_selection sel;
5170 struct attr street_name_attr;
5171 struct attr hn_attr;
5172 char *street_name = NULL;
5173 char *street_name_saved = NULL;
5174
5175 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
5176 dbg(0,"+#+:enter\n");
5177 #endif
5178
5179 // first find a street
5180 street_name_saved = navit_find_nearest_street(ms, pc);
5181 // street_name = g_strdup_printf(" ");
5182 street_name = g_strdup(street_name_saved);
5183 // first find a street
5184
5185 mindist = dist_to_street; // start with small radius at the beginning! (only use housenumber of different street, if we are really close to it!!)
5186 // global value -> this is naughty :-)
5187
5188 if (mindist < 8)
5189 {
5190 // so we can find other housenumbers if we are very close
5191 mindist = 8;
5192 }
5193
5194 mindist_hn = 10000;
5195
5196 //dbg(0,"given streetname %s %s dist %d\n", street_name, street_name_saved, dist_to_street);
5197
5198
5199 h = mapset_open(ms);
5200
5201 if (!h)
5202 {
5203 if (street_name_saved)
5204 {
5205 g_free(street_name_saved);
5206 street_name_saved = NULL;
5207 }
5208 return street_name;
5209 }
5210
5211 while ((m = mapset_next(h, 0)))
5212 {
5213 c.x = pc->x;
5214 c.y = pc->y;
5215 if (map_projection(m) != pc->pro)
5216 {
5217 transform_to_geo(pc->pro, &c, &g);
5218 transform_from_geo(map_projection(m), &g, &c);
5219 }
5220
5221 sel.next = NULL;
5222 sel.order = 18;
5223 sel.range.min = type_none;
5224 sel.range.max = type_area;
5225 sel.u.c_rect.lu.x = c.x - max_dist;
5226 sel.u.c_rect.lu.y = c.y + max_dist;
5227 sel.u.c_rect.rl.x = c.x + max_dist;
5228 sel.u.c_rect.rl.y = c.y - max_dist;
5229
5230 mr = map_rect_new(m, &sel);
5231 if (!mr)
5232 {
5233 continue;
5234 }
5235
5236 while ((item = map_rect_get_item(mr)))
5237 {
5238 if (item->type == type_house_number)
5239 {
5240 //dbg(0,"hn found\n");
5241 struct coord c2;
5242 int rrr = item_coord_get(item, &c2, 1);
5243 if (rrr)
5244 {
5245 dist = transform_distance_sq(&c, &c2);
5246 //dbg(0,"dist=%d\n", dist);
5247 if (dist < mindist)
5248 {
5249 if (item_attr_get(item, attr_street_name, &street_name_attr))
5250 {
5251 if (item_attr_get(item, attr_house_number, &hn_attr))
5252 {
5253 if (street_name)
5254 {
5255 g_free(street_name);
5256 street_name = NULL;
5257 }
5258 street_name = g_strdup_printf("%s %s", street_name_attr.u.str, hn_attr.u.str);
5259 //dbg(0,"sn 1\n");
5260 mindist = dist;
5261 mindist_hn = dist;
5262 }
5263 }
5264 }
5265 // else try to find housenumbers for our current street
5266 // just take the nearest housenumber for our current street
5267 else if (dist < mindist_hn)
5268 {
5269 //dbg(0,"sn 2.1\n");
5270 if (item_attr_get(item, attr_street_name, &street_name_attr))
5271 {
5272 //dbg(0,"sn 2.2\n");
5273 if (item_attr_get(item, attr_house_number, &hn_attr))
5274 {
5275 //dbg(0,"sn 2.3\n");
5276 if ((street_name != NULL) && (street_name_saved != NULL))
5277 {
5278 // dbg(0,"sn 2.4 -%s- -%s-\n", street_name_saved, street_name_attr.u.str);
5279 if (!strcmp(street_name_saved, street_name_attr.u.str))
5280 {
5281 g_free(street_name);
5282 street_name = NULL;
5283
5284 // dbg(0,"sn 2.99\n");
5285
5286 street_name = g_strdup_printf("%s %s", street_name_attr.u.str, hn_attr.u.str);
5287 mindist_hn = dist;
5288 }
5289 }
5290 }
5291 }
5292 }
5293 }
5294 }
5295
5296 #if 0
5297 //else if (item->type > type_line)
5298 if (1 == 0) // DISABLED !!!!!!
5299
5300 {
5301 if (item_get_default_flags(item->type))
5302 {
5303 sd = street_get_data(item);
5304 if (!sd)
5305 {
5306 continue;
5307 }
5308 dist = transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos);
5309 if (dist < mindist)
5310 {
5311 mindist = dist;
5312
5313 if (item_attr_get(item, attr_label, &street_name_attr))
5314 {
5315 if (street_name)
5316 {
5317 g_free(street_name);
5318 street_name = NULL;
5319 }
5320 if (street_name_saved)
5321 {
5322 g_free(street_name_saved);
5323 street_name_saved = NULL;
5324 }
5325 street_name = g_strdup_printf("%s", street_name_attr.u.str);
5326 street_name_saved = g_strdup(street_name);
5327 }
5328 else if (item_attr_get(item, attr_street_name, &street_name_attr))
5329 {
5330 if (street_name)
5331 {
5332 g_free(street_name);
5333 street_name = NULL;
5334 }
5335 if (street_name_saved)
5336 {
5337 g_free(street_name_saved);
5338 street_name_saved = NULL;
5339 }
5340 street_name = g_strdup_printf("%s", street_name_attr.u.str);
5341 street_name_saved = g_strdup(street_name);
5342 }
5343 else if (item_attr_get(item, attr_street_name_systematic, &street_name_attr))
5344 {
5345 if (street_name)
5346 {
5347 g_free(street_name);
5348 street_name = NULL;
5349 }
5350 if (street_name_saved)
5351 {
5352 g_free(street_name_saved);
5353 street_name_saved = NULL;
5354 }
5355 street_name = g_strdup_printf("%s", street_name_attr.u.str);
5356 street_name_saved = g_strdup(street_name);
5357 }
5358 }
5359 street_data_free(sd);
5360 }
5361 }
5362 #endif
5363 }
5364
5365 if (mr)
5366 {
5367 map_rect_destroy(mr);
5368 }
5369 }
5370
5371 if (street_name_saved)
5372 {
5373 g_free(street_name_saved);
5374 street_name_saved = NULL;
5375 }
5376
5377 mapset_close(h);
5378 return street_name;
5379 }
5380
5381 /**
5382 * @brief Finds the nearest street to a given coordinate
5383 *
5384 * @param ms The mapset to search in for the street
5385 * @param pc The coordinate to find a street nearby [ input in pcoord(x,y) ]
5386 * @return The nearest street (as a string of coords "0xFFF 0xFFF\n..." seperated by "\n")
5387 */
5388 char*
5389 navit_find_nearest_street_coords(struct mapset *ms, struct pcoord *pc)
5390 {
5391 int max_dist = 0; // smallest rectangle possible
5392 int dist, mindist = 0, pos;
5393 struct mapset_handle *h;
5394 struct map *m;
5395 struct map_rect *mr;
5396 struct item *item;
5397 struct coord lp;
5398 struct street_data *sd = NULL;
5399 struct street_data *sd_copy = NULL;
5400 struct coord c;
5401 struct coord_geo g;
5402 struct map_selection sel;
5403 int i;
5404 int found_good = 0;
5405 struct attr street_name_attr;
5406 char *street_coords = NULL;
5407 char *street_coords_tmp = NULL;
5408
5409 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
5410 dbg(0,"+#+:enter\n");
5411 #endif
5412
5413 mindist = 10000; // start with small radius at the beginning!
5414 street_coords = g_strdup_printf("");
5415
5416 h = mapset_open(ms);
5417
5418 if (!h)
5419 {
5420 return street_coords;
5421 }
5422
5423 while ((m = mapset_next(h, 0)))
5424 {
5425 c.x = pc->x;
5426 c.y = pc->y;
5427 if (map_projection(m) != pc->pro)
5428 {
5429 transform_to_geo(pc->pro, &c, &g);
5430 transform_from_geo(map_projection(m), &g, &c);
5431 }
5432
5433 sel.next = NULL;
5434 sel.order = 18;
5435 sel.range.min = type_line;
5436 sel.range.max = type_area;
5437 sel.u.c_rect.lu.x = c.x - max_dist;
5438 sel.u.c_rect.lu.y = c.y + max_dist;
5439 sel.u.c_rect.rl.x = c.x + max_dist;
5440 sel.u.c_rect.rl.y = c.y - max_dist;
5441
5442 mr = map_rect_new(m, &sel);
5443 if (!mr)
5444 {
5445 continue;
5446 }
5447
5448 while ((item = map_rect_get_item(mr)))
5449 {
5450 if (item_get_default_flags(item->type))
5451 {
5452 sd = street_get_data(item);
5453 if (!sd)
5454 {
5455 continue;
5456 }
5457 found_good = 0;
5458 // OLD // dist = transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos);
5459 dist = transform_distance_polyline_sq__v2(sd->c, sd->count, &c);
5460 if (dist < mindist)
5461 {
5462 mindist = dist;
5463
5464 /*
5465 if (item_attr_get(item, attr_label, &street_name_attr))
5466 {
5467 found_good = 1;
5468 }
5469 else if (item_attr_get(item, attr_street_name, &street_name_attr))
5470 {
5471 found_good = 1;
5472 }
5473 else if (item_attr_get(item, attr_street_name_systematic, &street_name_attr))
5474 {
5475 found_good = 1;
5476 }
5477 */
5478
5479 // allow any street/line, so you can select streets without name also!
5480 found_good = 1;
5481 }
5482
5483 if (found_good == 1)
5484 {
5485 if (sd_copy)
5486 {
5487 street_data_free(sd_copy);
5488 }
5489 sd_copy = street_data_dup(sd);
5490 }
5491 street_data_free(sd);
5492 }
5493 }
5494
5495 if (mr)
5496 {
5497 map_rect_destroy(mr);
5498 }
5499 }
5500 mapset_close(h);
5501
5502 if (sd_copy)
5503 {
5504 //struct coord ca[sd_copy->count];
5505 //item_coord_get(&sd_copy->item, ca, sd_copy->count);
5506
5507 // dbg(0,"sd_copy->count=%d\n", sd_copy->count);
5508
5509 for (i = 0; i < sd_copy->count; i++)
5510 {
5511 /*
5512 unsigned int x;
5513 unsigned int y;
5514 char *sign_x = "";
5515 char *sign_y = "";
5516
5517 if ( c->x < 0 ) {
5518 x = -c->x;
5519 sign_x = "-";
5520 } else {
5521 x = c->x;
5522 }
5523 if ( c->y < 0 ) {
5524 y = -c->y;
5525 sign_y = "-";
5526 } else {
5527 y = c->y;
5528 }
5529 */
5530
5531 street_coords_tmp = street_coords;
5532 if (street_coords == NULL)
5533 {
5534 street_coords = g_strdup_printf("0x%x 0x%x\n", sd_copy->c[i].x, sd_copy->c[i].y);
5535 }
5536 else
5537 {
5538 char *tmp2 = g_strdup_printf("0x%x 0x%x\n", sd_copy->c[i].x, sd_copy->c[i].y);
5539 street_coords = g_strconcat(street_coords_tmp, tmp2, NULL);
5540 g_free(street_coords_tmp);
5541 g_free(tmp2);
5542 }
5543 }
5544
5545 street_data_free(sd_copy);
5546 }
5547
5548 return street_coords;
5549 }
5550
5551 // UNUSDED -------
5552 // UNUSDED -------
5553 int navit_block(struct navit *this_, int block)
5554 {
5555 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
5556 dbg(0,"+#+:enter\n");
5557 #endif
5558 ////DBG dbg(0,"EEnter\n");
5559
5560 if (block > 0)
5561 {
5562 this_->blocked |= 1;
5563 if (graphics_draw_cancel(this_->gra, this_->displaylist))
5564 this_->blocked |= 2;
5565 return 0;
5566 }
5567 if ((this_->blocked & 2) || block < 0)
5568 {
5569 this_->blocked = 0;
5570 navit_draw(this_);
5571 return 1;
5572 }
5573 this_->blocked = 0;
5574 return 0;
5575 }
5576
5577 void navit_destroy(struct navit *this_)
5578 {
5579 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
5580 dbg(0,"+#+:enter\n");
5581 #endif
5582 dbg(0, "EEnter\n");
5583
5584 struct mapset*ms;
5585 callback_list_call_attr_1(this_->attr_cbl, attr_destroy, this_);
5586
5587 // //DBG dbg(0,"enter");
5588
5589 /* TODO: destroy objects contained in this_ */
5590 if (this_->vehicle)
5591 {
5592 vehicle_destroy(this_->vehicle->vehicle);
5593 }
5594
5595 /*
5596 if (this_->bookmarks)
5597 {
5598 dbg(0, "save position to file\n");
5599 char *center_file = bookmarks_get_center_file(TRUE);
5600 bookmarks_write_center_to_file(this_->bookmarks, center_file);
5601 g_free(center_file);
5602 bookmarks_destroy(this_->bookmarks);
5603 dbg(0, "save position to file -> ready\n");
5604 }
5605 */
5606
5607 dbg(0, "ex 001\n");
5608 callback_destroy(this_->nav_speech_cb);
5609 dbg(0, "ex 002\n");
5610 callback_destroy(this_->roadbook_callback);
5611 dbg(0, "ex 003\n");
5612 callback_destroy(this_->popup_callback);
5613 dbg(0, "ex 004\n");
5614 callback_destroy(this_->motion_timeout_callback);
5615 dbg(0, "ex 005\n");
5616 callback_destroy(this_->progress_cb);
5617 dbg(0, "ex 006\n");
5618 /*
5619 if (this_->gra)
5620 graphics_remove_callback(this_->gra, this_->resize_callback);
5621 callback_destroy(this_->resize_callback);
5622 */
5623 dbg(0, "ex 007\n");
5624 /*
5625 if (this_->gra)
5626 graphics_remove_callback(this_->gra, this_->button_callback);
5627 callback_destroy(this_->button_callback);
5628 */
5629 dbg(0, "ex 008\n");
5630 /*
5631 if (this_->gra)
5632 graphics_remove_callback(this_->gra, this_->motion_callback);
5633 callback_destroy(this_->motion_callback);
5634 */
5635 dbg(0, "ex 009\n");
5636 if (this_->gra)
5637 {
5638 graphics_remove_callback(this_->gra, this_->predraw_callback);
5639 }
5640 callback_destroy(this_->predraw_callback);
5641 dbg(0, "ex 010\n");
5642 route_destroy(this_->route);
5643 dbg(0, "ex 011\n");
5644 ms = navit_get_mapset(this_);
5645 dbg(0, "ex 012\n");
5646 if (ms)
5647 {
5648 mapset_destroy(ms);
5649 }
5650 dbg(0, "ex 013\n");
5651 graphics_free(this_->gra);
5652 dbg(0, "ex 014\n");
5653 g_free(this_);
5654 dbg(0, "ex 015\n");
5655 }
5656
5657 /** @} */

   
Visit the ZANavi Wiki