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

Contents of /navit/navit/navit.c

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki