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

Contents of /navit/navit/navit.c

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki