/[zanavi_public1]/navit/navit/osd/core/osd_core.c
ZANavi

Contents of /navit/navit/osd/core/osd_core.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 95165 byte(s)
import files
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 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 #include "config.h"
21 #ifdef _MSC_VER
22 #define _USE_MATH_DEFINES 1
23 #endif /* _MSC_VER */
24 #include <stdlib.h>
25 #include <math.h>
26 #include <stdio.h>
27 #include <glib.h>
28 #include <time.h>
29 #ifdef HAVE_SYS_TIME_H
30 #include <sys/time.h>
31 #endif
32 #include <string.h>
33 #include "item.h"
34 #include "point.h"
35 #include "coord.h"
36 #include "graphics.h"
37 #include "transform.h"
38 #include "route.h"
39 #include "navit.h"
40 #include "plugin.h"
41 #include "debug.h"
42 #include "callback.h"
43 #include "color.h"
44 #include "vehicle.h"
45 #include "navigation.h"
46 #include "track.h"
47 #include "map.h"
48 #include "file.h"
49 #include "attr.h"
50 #include "command.h"
51 #include "navit_nls.h"
52 #include "messages.h"
53 #include "vehicleprofile.h"
54 #include "roadprofile.h"
55 #include "osd.h"
56 #include "speech.h"
57 #include "event.h"
58 #include "mapset.h"
59 #include "util.h"
60
61 #ifdef HAVE_API_WIN32_CE
62 #include "libc.h"
63 #endif
64
65 #ifdef _MSC_VER
66 static double round(double x)
67 {
68 if (x >= 0.0)
69 return floor(x + 0.5);
70 else
71 return ceil(x - 0.5);
72 }
73 #endif /* MSC_VER */
74
75 struct odometer;
76
77 static void osd_odometer_reset(struct odometer *this);
78 static void osd_cmd_odometer_reset(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid);
79 static void osd_odometer_draw(struct odometer *this, struct navit *nav, struct vehicle *v);
80 static struct osd_text_item * oti_new(struct osd_text_item * parent);
81
82 static int b_commandtable_added = 0;
83
84 struct compass {
85 struct osd_item osd_item;
86 int width;
87 struct graphics_gc *green;
88 };
89
90 static void
91 transform_rotate(struct point *center, int angle, struct point *p,
92 int count)
93 {
94 //dbg(0,"EEnter\n");
95
96 int i, x, y;
97 double dx, dy;
98 for (i = 0; i < count; i++) {
99 dx = sin(M_PI * angle / 180.0);
100 dy = cos(M_PI * angle / 180.0);
101 x = dy * p->x - dx * p->y;
102 y = dx * p->x + dy * p->y;
103
104 p->x = center->x + x;
105 p->y = center->y + y;
106 p++;
107 }
108 }
109
110 static void
111 handle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r,
112 int dir)
113 {
114 //dbg(0,"EEnter\n");
115
116 struct point ph[3];
117 int l = r * 0.4;
118
119 ph[0].x = 0;
120 ph[0].y = r;
121 ph[1].x = 0;
122 ph[1].y = -r;
123 transform_rotate(p, dir, ph, 2);
124 graphics_draw_lines(gr, gc, ph, 2);
125 ph[0].x = -l;
126 ph[0].y = -r + l;
127 ph[1].x = 0;
128 ph[1].y = -r;
129 ph[2].x = l;
130 ph[2].y = -r + l;
131 transform_rotate(p, dir, ph, 3);
132 graphics_draw_lines(gr, gc, ph, 3);
133 }
134
135 /**
136 * * Format distance, choosing the unit (m or km) and precision depending on distance
137 * *
138 * * @param distance distance in meters
139 * * @param sep separator character to be inserted between distance value and unit
140 * * @returns a pointer to a string containing the formatted distance
141 * */
142 static char *
143 format_distance(double distance, char *sep, int imperial)
144 {
145 //dbg(0,"EEnter\n");
146
147 if (imperial){
148 distance *= FEET_PER_METER;
149 if(distance <= 1500){
150 return g_strdup_printf("%.0f%sft", round(distance / 10) * 10, sep);
151 } else {
152 return g_strdup_printf("%.1f%smi", distance / FEET_PER_MILE, sep);
153 }
154 } else {
155 if (distance >= 100000)
156 return g_strdup_printf("%.0f%skm", distance / 1000, sep);
157 else if (distance >= 10000)
158 return g_strdup_printf("%.1f%skm", distance / 1000, sep);
159 else if (distance >= 300)
160 return g_strdup_printf("%.0f%sm", round(distance / 25) * 25, sep);
161 else if (distance >= 50)
162 return g_strdup_printf("%.0f%sm", round(distance / 10) * 10, sep);
163 else if (distance >= 10)
164 return g_strdup_printf("%.0f%sm", distance, sep);
165 else
166 return g_strdup_printf("%.1f%sm", distance, sep);
167 }
168 }
169
170 /**
171 * * Format time (duration)
172 * *
173 * * @param tm pointer to a tm structure specifying the time
174 * * @param days days
175 * * @returns a pointer to a string containing the formatted time
176 * */
177 static char *
178 format_time(struct tm *tm, int days)
179 {
180 if (days)
181 return g_strdup_printf("%d+%02d:%02d", days, tm->tm_hour, tm->tm_min);
182 else
183 return g_strdup_printf("%02d:%02d", tm->tm_hour, tm->tm_min);
184 }
185
186 /**
187 * * Format speed in km/h
188 * *
189 * * @param speed speed in km/h
190 * * @param sep separator character to be inserted between speed value and unit
191 * * @returns a pointer to a string containing the formatted speed
192 * */
193 static char *
194 format_speed(double speed, char *sep, char *format, int imperial)
195 {
196 char *unit="km/h";
197 if (imperial) {
198 speed = speed*1000*FEET_PER_METER/FEET_PER_MILE;
199 unit="mph";
200 }
201 if (!format || !strcmp(format,"named"))
202 return g_strdup_printf("%.0f%s%s", speed, sep, unit);
203 else if (!strcmp(format,"value") || !strcmp(format,"unit")) {
204 if (!strcmp(format,"value"))
205 return g_strdup_printf("%.0f", speed);
206 else
207 return g_strdup(unit);
208 }
209 return g_strdup("");
210 }
211
212 /*static char *
213 format_float(double num)
214 {
215 return g_strdup_printf("%f", num);
216 }*/
217
218 static char *
219 format_float_0(double num)
220 {
221 return g_strdup_printf("%.0f", num);
222 }
223
224 /**
225 * sets an attribute (name value pair) of a map item specified by map name and item id
226 *
227 * @param navit The navit instance
228 * @param function unused (needed to match command function signiture)
229 * @param in input attribute in[0] - name of the osd ; in[1] - attr name ; in[2] - attr value
230 * @param out output attribute, 0 on error, 1 on success
231 * @param valid unused
232 * @returns nothing
233 */
234 static void
235 osd_cmd_osd_set_attr(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
236 {
237 //dbg(0,"EEnter\n");
238
239 struct attr **list;
240 struct attr*val = g_new0(struct attr,1);
241 val->type = attr_type_int_begin;
242 val->u.num = 0;
243 list = g_new0(struct attr *,2);
244 list[0] = val;
245
246 if (
247 in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str &&//osd name
248 in[1] && ATTR_IS_STRING(in[1]->type) && in[1]->u.str &&//attr_type str
249 in[2] && ATTR_IS_STRING(in[2]->type) && in[2]->u.str //attr_value str
250 ) {
251 struct attr attr_to_set;
252 struct osd* osd;
253
254 if(ATTR_IS_STRING(attr_from_name(in[1]->u.str))) {
255 attr_to_set.u.str = in[2]->u.str;
256 attr_to_set.type = attr_from_name(in[1]->u.str);
257 }
258 else if(ATTR_IS_INT(attr_from_name(in[1]->u.str))) {
259 attr_to_set.u.num = atoi(in[2]->u.str);
260 attr_to_set.type = attr_from_name(in[1]->u.str);
261 }
262 else if(ATTR_IS_DOUBLE(attr_from_name(in[1]->u.str))) {
263 double* val = g_new0(double,1);
264 *val = atof(in[2]->u.str);
265 attr_to_set.u.numd = val;
266 attr_to_set.type = attr_from_name(in[1]->u.str);
267 }
268 osd = osd_get_osd_by_name(in[0]->u.str);
269 if(osd) {
270 osd_set_attr(osd, &attr_to_set);
271 val->u.num = 1;
272 }
273 }
274 list[1] = NULL;
275 *out = list;
276 }
277
278
279
280 static int odometers_saved = 0;
281 static GList* odometer_list = NULL;
282
283 static struct command_table commands[] = {
284 {"odometer_reset",command_cast(osd_cmd_odometer_reset)},
285 {"osd_set_attr" ,command_cast(osd_cmd_osd_set_attr)},
286 };
287
288 struct odometer {
289 struct osd_item osd_item;
290 int width;
291 struct graphics_gc *orange;
292 struct graphics_gc *white;
293 struct callback *click_cb;
294 char *text; //text of label attribute for this osd
295 char *name; //unique name of the odometer (needed for handling multiple odometers persistently)
296 struct color idle_color; //text color when counter is idle
297
298 int bDisableReset;
299 int bAutoStart;
300 int bActive; //counting or not
301 int autosave_period; //autosave period in seconds
302 double sum_dist; //sum of distance ofprevious intervals in meters
303 double sum_time; //sum of time of previous intervals in seconds (needed for avg spd calculation)
304 double time_all;
305 double last_click_time; //time of last click (for double click handling)
306 double last_start_time; //time of last start of counting
307 double last_update_time; //time of last position update
308 struct coord last_coord;
309 double last_speed;
310 double acceleration;
311 };
312
313 static void
314 osd_cmd_odometer_reset(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
315 {
316 //dbg(0,"EEnter\n");
317
318 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) {
319 GList* list = odometer_list;
320 while(list) {
321 if(!strcmp(((struct odometer*)(list->data))->name,in[0]->u.str)) {
322 osd_odometer_reset(list->data);
323 osd_odometer_draw(list->data,this,NULL);
324 }
325 list = g_list_next(list);
326 }
327 }
328 }
329
330 static char*
331 str_replace(char*output, char*input, char*pattern, char*replacement)
332 {
333 //dbg(0,"EEnter\n");
334
335 char *pos;
336 char *pos2;
337 if (!output || !input || !pattern || !replacement) {
338 return NULL;
339 }
340 if(!strcmp(pattern,"")) {
341 return input;
342 }
343
344 pos = &input[0];
345 pos2 = &input[0];
346 output[0] = 0;
347 while ( (pos2=strstr(pos,pattern)) ) {
348 strncat(output,pos,pos2-pos);
349 strcat(output,replacement);
350 pos = pos2 + strlen(pattern);
351 }
352 strcat(output,pos);
353 return NULL;
354 }
355
356 /*
357 * save current odometer state to string
358 */
359 static char *osd_odometer_to_string(struct odometer* this_)
360 {
361 return g_strdup_printf("odometer %s %lf %lf %d\n",this_->name,this_->sum_dist,this_->time_all,this_->bActive);
362 }
363
364 /*
365 * load current odometer state from string
366 */
367 static void osd_odometer_from_string(struct odometer* this_, char*str)
368 {
369 char* tok;
370 char* name_str;
371 char* sum_dist_str;
372 char* sum_time_str;
373 char* active_str;
374 tok = strtok(str, " ");
375 if( !tok || strcmp("odometer",tok)) {
376 return;
377 }
378 name_str = g_strdup(strtok(NULL, " "));
379 if(!name_str) {
380 return;
381 }
382 sum_dist_str = g_strdup(strtok(NULL, " "));
383 if(!sum_dist_str) {
384 g_free(name_str);
385 return;
386 }
387 sum_time_str = g_strdup(strtok(NULL, " "));
388 if(!sum_time_str) {
389 g_free(name_str);
390 g_free(sum_dist_str);
391 return;
392 }
393 active_str = g_strdup(strtok(NULL, " "));
394 if(!active_str) {
395 g_free(name_str);
396 g_free(sum_dist_str);
397 g_free(sum_time_str);
398 return;
399 }
400 this_->name = name_str;
401 this_->sum_dist = atof(sum_dist_str);
402 this_->sum_time = atof(sum_time_str);
403 this_->bActive = atoi(active_str);
404 this_->last_coord.x = -1;
405 g_free(active_str);
406 g_free(sum_dist_str);
407 g_free(sum_time_str);
408 }
409
410 static void osd_odometer_draw(struct odometer *this, struct navit *nav, struct vehicle *v)
411 {
412 struct coord curr_coord;
413 struct graphics_gc *curr_color;
414
415 char *dist_buffer=0;
416 char *spd_buffer=0;
417 char *time_buffer = 0;
418 char *acc_buffer = 0;
419 struct point p, bbox[4];
420 struct attr position_attr,vehicle_attr,imperial_attr,speed_attr;
421 enum projection pro;
422 struct vehicle* curr_vehicle = v;
423 double spd = 0;
424 double curr_spd = 0;
425
426 int remainder;
427 int days;
428 int hours;
429 int mins;
430 int secs;
431 int imperial=0;
432
433 char buffer [256+1]="";
434 char buffer2[256+1]="";
435
436 if(nav) {
437 navit_get_attr(nav, attr_vehicle, &vehicle_attr, NULL);
438 if (navit_get_attr(nav, attr_imperial, &imperial_attr, NULL))
439 imperial=imperial_attr.u.num;
440 }
441 if (vehicle_attr.u.vehicle) {
442 curr_vehicle = vehicle_attr.u.vehicle;
443 }
444
445 if(0==curr_vehicle)
446 return;
447
448 osd_std_draw(&this->osd_item);
449 if(this->bActive) {
450 if(!vehicle_get_attr(curr_vehicle, attr_position_coord_geo,&position_attr, NULL)) {
451 return;
452 }
453 pro = projection_mg;//position_attr.u.pcoord->pro;
454 transform_from_geo(pro, position_attr.u.coord_geo, &curr_coord);
455
456 if (this->last_coord.x != -1 ) {
457 const double cStepDistLimit = 10000;
458 struct timeval tv;
459 double curr_time;
460 double dt;
461 double dCurrDist = 0;
462
463 gettimeofday(&tv,NULL);
464 curr_time = (double)(tv.tv_usec)/1000000.0+tv.tv_sec;
465 //we have valid previous position
466 dt = curr_time-this->last_update_time;
467 dCurrDist = transform_distance(pro, &curr_coord, &this->last_coord);
468 if(dCurrDist<=cStepDistLimit) {
469 this->sum_dist += dCurrDist;
470 }
471 this->time_all = curr_time-this->last_click_time+this->sum_time;
472 spd = 3.6*(double)this->sum_dist/(double)this->time_all;
473 if(dt != 0) {
474 if (curr_coord.x!=this->last_coord.x || curr_coord.y!=this->last_coord.y) {
475 if(vehicle_get_attr(curr_vehicle, attr_position_speed,&speed_attr, NULL)) {
476 double dv;
477 curr_spd = *speed_attr.u.numd;
478 dv = (curr_spd-this->last_speed)/3.6; //speed difference in m/sec
479 this->acceleration = dv/dt;
480 this->last_speed = curr_spd;
481 this->last_update_time = curr_time;
482 }
483 }
484 }
485 }
486 this->last_coord = curr_coord;
487 }
488
489 dist_buffer = format_distance(this->sum_dist,"",imperial);
490 spd_buffer = format_speed(spd,"","value",imperial);
491 acc_buffer = g_strdup_printf("%.3f m/s2",this->acceleration);
492 remainder = (int)this->time_all;
493 days = remainder / (24*60*60);
494 remainder = remainder % (24*60*60);
495 hours = remainder / (60*60);
496 remainder = remainder % (60*60);
497 mins = remainder / (60);
498 remainder = remainder % (60);
499 secs = remainder;
500 if(0<days) {
501 time_buffer = g_strdup_printf("%02dd %02d:%02d:%02d",days,hours,mins,secs);
502 }
503 else {
504 time_buffer = g_strdup_printf("%02d:%02d:%02d",hours,mins,secs);
505 }
506
507 buffer [0] = 0;
508 buffer2[0] = 0;
509 if(this->text) {
510 str_replace(buffer2,this->text,"${avg_spd}",spd_buffer);
511 str_replace(buffer,buffer2,"${distance}",dist_buffer);
512 str_replace(buffer2,buffer,"${time}",time_buffer);
513 str_replace(buffer,buffer2,"${acceleration}",acc_buffer);
514 }
515 g_free(time_buffer);
516
517 graphics_get_text_bbox(this->osd_item.gr, this->osd_item.font, buffer, 0x10000, 0, bbox, 0);
518 p.x=(this->osd_item.w-bbox[2].x)/2;
519 p.y = this->osd_item.h-this->osd_item.h/10;
520 curr_color = this->bActive?this->white:this->orange;
521 graphics_draw_text(this->osd_item.gr, curr_color, NULL, this->osd_item.font, buffer, &p, 0x10000, 0);
522 g_free(dist_buffer);
523 g_free(spd_buffer);
524 g_free(acc_buffer);
525 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
526 }
527
528
529 static void
530 osd_odometer_reset(struct odometer *this)
531 {
532 if(!this->bDisableReset) {
533 this->bActive = 0;
534 this->sum_dist = 0;
535 this->sum_time = 0;
536 this->last_start_time = 0;
537 this->last_coord.x = -1;
538 this->last_coord.y = -1;
539 }
540 }
541
542 static void
543 osd_odometer_click(struct odometer *this, struct navit *nav, int pressed, int button, struct point *p)
544 {
545 struct point bp = this->osd_item.p;
546 struct timeval tv;
547 double curr_time;
548 const double double_click_timewin = .5;
549 osd_wrap_point(&bp, nav);
550 if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->osd_item.w || p->y > bp.y + this->osd_item.h || !this->osd_item.configured ) && !this->osd_item.pressed)
551 return;
552 if (button != 1)
553 return;
554 if (navit_ignore_button(nav))
555 return;
556 if (!!pressed == !!this->osd_item.pressed)
557 return;
558
559 gettimeofday(&tv,NULL);
560 curr_time = (double)(tv.tv_usec)/1000000.0+tv.tv_sec;
561
562 if (pressed) { //single click handling
563 if(this->bActive) { //being stopped
564 this->last_coord.x = -1;
565 this->last_coord.y = -1;
566 this->sum_time += curr_time-this->last_click_time;
567 }
568
569 this->bActive ^= 1; //toggle active flag
570
571 if (curr_time-double_click_timewin <= this->last_click_time) { //double click handling
572 osd_odometer_reset(this);
573 }
574
575 this->last_click_time = curr_time;
576
577 osd_odometer_draw(this, nav,NULL);
578 }
579 }
580
581
582 static int
583 osd_odometer_save(struct navit* nav)
584 {
585 //save odometers that are persistent(ie have name)
586 FILE*f;
587 GList* list = odometer_list;
588 char* fn = g_strdup_printf("%s/odometer.txt",navit_get_user_data_directory(TRUE));
589 f = fopen(fn,"w+");
590 g_free(fn);
591 if(!f) {
592 return TRUE;
593 }
594 while (list) {
595 if( ((struct odometer*)(list->data))->name) {
596 char*odo_str = osd_odometer_to_string(list->data);
597 fprintf(f,"%s",odo_str);
598 g_free(odo_str);
599
600 }
601 list = g_list_next(list);
602 }
603 fclose(f);
604 return TRUE;
605 }
606
607
608 static void
609 osd_odometer_init(struct odometer *this, struct navit *nav)
610 {
611 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
612
613 this->orange = graphics_gc_new(this->osd_item.gr);
614 graphics_gc_set_foreground(this->orange, &this->idle_color);
615 graphics_gc_set_linewidth(this->orange, this->width);
616
617 this->white = graphics_gc_new(this->osd_item.gr);
618 graphics_gc_set_foreground(this->white, &this->osd_item.text_color);
619 graphics_gc_set_linewidth(this->white, this->width);
620
621 graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
622
623 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_draw), attr_position_coord_geo, this));
624
625 navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_odometer_click), attr_button, this));
626
627 if(this->autosave_period>0) {
628 event_add_timeout(this->autosave_period*1000, 1, callback_new_1(callback_cast(osd_odometer_save), NULL));
629 }
630
631 if(this->bAutoStart) {
632 this->bActive = 1;
633 }
634 osd_odometer_draw(this, nav, NULL);
635 }
636
637 static void
638 osd_odometer_destroy(struct navit* nav)
639 {
640 if(!odometers_saved) {
641 odometers_saved = 1;
642 osd_odometer_save(NULL);
643 }
644 }
645
646 static struct osd_priv *
647 osd_odometer_new(struct navit *nav, struct osd_methods *meth,
648 struct attr **attrs)
649 {
650 FILE* f;
651 char* fn;
652
653 struct odometer *this = g_new0(struct odometer, 1);
654 struct attr *attr;
655 struct color orange_color={0xffff,0xa5a5,0x0000,0xffff};
656 this->osd_item.p.x = 120;
657 this->osd_item.p.y = 20;
658 this->osd_item.w = 60;
659 this->osd_item.h = 80;
660 this->osd_item.navit = nav;
661 this->osd_item.font_size = 200;
662 this->osd_item.meth.draw = osd_draw_cast(osd_odometer_draw);
663
664 this->bActive = 0; //do not count on init
665 this->sum_dist = 0;
666 this->last_click_time = time(0);
667 this->last_coord.x = -1;
668 this->last_coord.y = -1;
669
670 attr = attr_search(attrs, NULL, attr_label);
671 //FIXME find some way to free text!!!!
672 if (attr) {
673 this->text = g_strdup(attr->u.str);
674 }
675 else
676 this->text = NULL;
677
678 attr = attr_search(attrs, NULL, attr_name);
679 //FIXME find some way to free text!!!!
680 if (attr) {
681 this->name = g_strdup(attr->u.str);
682 }
683 else
684 this->name = NULL;
685
686 attr = attr_search(attrs, NULL, attr_disable_reset);
687 if (attr)
688 this->bDisableReset = attr->u.num;
689 else
690 this->bDisableReset = 0;
691
692 attr = attr_search(attrs, NULL, attr_autostart);
693 if (attr)
694 this->bAutoStart = attr->u.num;
695 else
696 this->bAutoStart = 0;
697 attr = attr_search(attrs, NULL, attr_autosave_period);
698 if (attr)
699 this->autosave_period = attr->u.num;
700 else
701 this->autosave_period = -1; //disabled by default
702
703 osd_set_std_attr(attrs, &this->osd_item, 2);
704 attr = attr_search(attrs, NULL, attr_width);
705 this->width=attr ? attr->u.num : 2;
706 attr = attr_search(attrs, NULL, attr_idle_color);
707 this->idle_color=attr ? *attr->u.color : orange_color; // text idle_color defaults to orange
708
709 this->last_coord.x = -1;
710 this->last_coord.y = -1;
711 this->sum_dist = 0.0;
712
713 //load state from file
714 fn = g_strdup_printf("%s/odometer.txt",navit_get_user_data_directory(FALSE));
715 f = fopen(fn,"r+");
716
717 if(f) {
718 g_free(fn);
719
720 while(!feof(f)) {
721 char str[128];
722 char *line;
723 if(fgets(str,128,f))
724 {
725 char *tok;
726 line = g_strdup(str);
727 tok = strtok(str," ");
728 if(!strcmp(tok,"odometer")) {
729 tok = strtok(NULL," ");
730 if(this->name && tok && !strcmp(this->name,tok)) {
731 osd_odometer_from_string(this,line);
732 }
733 }
734 g_free(line);
735 }
736 }
737 fclose(f);
738 }
739
740 if(b_commandtable_added == 0) {
741 navit_command_add_table(nav, commands, sizeof(commands)/sizeof(struct command_table));
742 b_commandtable_added = 1;
743 }
744 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_init), attr_graphics_ready, this));
745 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_destroy), attr_destroy, nav));
746 odometer_list = g_list_append(odometer_list, this);
747
748 return (struct osd_priv *) this;
749 }
750
751
752 struct cmd_interface {
753 struct osd_item osd_item;
754 int width;
755 struct graphics_gc *orange,*white;
756 int update_period; //in sec
757 char* text;
758 struct graphics_image *img;
759 char*img_filename;
760 char* command;
761 int bReserved;
762 };
763
764 static void
765 osd_cmd_interface_draw(struct cmd_interface *this, struct navit *nav,
766 struct vehicle *v)
767 {
768 //dbg(0,"EEnter\n");
769
770 struct point p;
771 struct point bbox[4];
772 struct graphics_gc *curr_color;
773 struct attr navit;
774 p.x = 0;
775 p.y = 0;
776 navit.type=attr_navit;
777 navit.u.navit = this->osd_item.navit;
778
779 if(0==this->bReserved) {
780 this->bReserved = 1;
781 command_evaluate(&navit, this->command);
782 this->bReserved = 0;
783 }
784
785 osd_std_draw(&this->osd_item);
786
787 //display image
788 if(this->img) {
789 graphics_draw_image(this->osd_item.gr, this->osd_item.graphic_bg, &p, this->img);
790 }
791
792 //display text
793 graphics_get_text_bbox(this->osd_item.gr, this->osd_item.font, this->text, 0x10000, 0, bbox, 0);
794 p.x=(this->osd_item.w-bbox[2].x)/2;
795 p.y = this->osd_item.h-this->osd_item.h/10;
796 curr_color = this->white;
797 if(this->text)
798 graphics_draw_text(this->osd_item.gr, curr_color, NULL, this->osd_item.font, this->text, &p, 0x10000, 0);
799 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
800 }
801
802
803
804 static void
805 osd_cmd_interface_init(struct cmd_interface *this, struct navit *nav)
806 {
807 //dbg(0,"EEnter\n");
808
809 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
810
811 this->white = graphics_gc_new(this->osd_item.gr);
812 graphics_gc_set_foreground(this->white, &this->osd_item.text_color);
813 graphics_gc_set_linewidth(this->white, this->width);
814
815
816 graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
817
818 if(this->update_period>0) {
819 event_add_timeout(this->update_period*1000, 1, callback_new_1(callback_cast(osd_cmd_interface_draw), this));
820 }
821
822 navit_add_callback(nav, callback_new_attr_1(callback_cast (osd_std_click), attr_button, &this->osd_item));
823
824 this->text = g_strdup("");
825 }
826
827 static int
828 osd_cmd_interface_set_attr(struct cmd_interface *this_, struct attr* attr)
829 {
830 //dbg(0,"EEnter\n");
831
832 struct navit* nav;
833 if(NULL==attr || NULL==this_) {
834 return 0;
835 }
836
837 nav = this_->osd_item.navit;
838
839 if(attr->type == attr_status_text) {
840 if(this_->text) {
841 g_free(this_->text);
842 }
843 if(attr->u.str) {
844 this_->text = g_strdup(attr->u.str);
845 }
846 return 1;
847 }
848 if(attr->type == attr_src) {
849 if(attr->u.str) {
850 if((!this_->img_filename) || strcmp(this_->img_filename, graphics_icon_path(attr->u.str))) {
851 struct graphics *gra = navit_get_graphics(nav);
852 //destroy old img, create new image
853 if(this_->img) {
854 graphics_image_free(this_->osd_item.gr, this_->img);
855 }
856 if(this_->img_filename) {
857 g_free(this_->img_filename);
858 }
859 this_->img_filename = graphics_icon_path(attr->u.str);
860 this_->img = graphics_image_new(this_->osd_item.gr, this_->img_filename);
861 }
862 }
863 return 1;
864 }
865 return 0;
866 }
867
868
869 static struct osd_priv *
870 osd_cmd_interface_new(struct navit *nav, struct osd_methods *meth,
871 struct attr **attrs)
872 {
873 //dbg(0,"EEnter\n");
874
875 struct cmd_interface *this = g_new0(struct cmd_interface, 1);
876 struct attr *attr;
877
878 this->osd_item.p.x = 120;
879 this->osd_item.p.y = 20;
880 this->osd_item.w = 60;
881 this->osd_item.h = 80;
882 this->osd_item.navit = nav;
883 this->osd_item.font_size = 200;
884 this->osd_item.meth.draw = osd_draw_cast(osd_cmd_interface_draw);
885
886 meth->set_attr = osd_cmd_interface_set_attr;
887
888 osd_set_std_attr(attrs, &this->osd_item, 2);
889
890 attr = attr_search(attrs, NULL, attr_width);
891 this->width=attr ? attr->u.num : 2;
892
893 attr = attr_search(attrs, NULL, attr_update_period);
894 this->update_period=attr ? attr->u.num : 5; //default update period is 5 seconds
895
896 attr = attr_search(attrs, NULL, attr_command);
897 this->command = attr ? g_strdup(attr->u.str) : g_strdup("");
898
899 if(b_commandtable_added == 0) {
900 navit_command_add_table(nav, commands, sizeof(commands)/sizeof(struct command_table));
901 b_commandtable_added = 1;
902 }
903 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_cmd_interface_init), attr_graphics_ready, this));
904 return (struct osd_priv *) this;
905 }
906
907
908
909
910 struct stopwatch {
911 struct osd_item osd_item;
912 int width;
913 struct graphics_gc *orange,*white;
914 struct callback *click_cb;
915 struct color idle_color; //text color when counter is idle
916
917 int bDisableReset;
918 int bActive; //counting or not
919 time_t current_base_time; //base time of currently measured time interval
920 time_t sum_time; //sum of previous time intervals (except current intervals)
921 time_t last_click_time; //time of last click (for double click handling)
922 };
923
924 static void
925 osd_stopwatch_draw(struct stopwatch *this, struct navit *nav,
926 struct vehicle *v)
927 {
928 //dbg(0,"EEnter\n");
929
930 struct graphics_gc *curr_color;
931 char buffer[32]="00:00:00";
932 struct point p;
933 struct point bbox[4];
934 time_t total_sec,total_min,total_hours,total_days;
935 total_sec = this->sum_time;
936
937 osd_std_draw(&this->osd_item);
938
939 if(this->bActive) {
940 total_sec += time(0)-this->current_base_time;
941 }
942
943 total_min = total_sec/60;
944 total_hours = total_min/60;
945 total_days = total_hours/24;
946
947 if (total_days==0) {
948 g_snprintf(buffer,32,"%02d:%02d:%02d", (int)total_hours%24, (int)total_min%60, (int)total_sec%60);
949 } else {
950 g_snprintf(buffer,32,"%02dd %02d:%02d:%02d",
951 (int)total_days, (int)total_hours%24, (int)total_min%60, (int)total_sec%60);
952 }
953
954 graphics_get_text_bbox(this->osd_item.gr, this->osd_item.font, buffer, 0x10000, 0, bbox, 0);
955 p.x=(this->osd_item.w-bbox[2].x)/2;
956 p.y = this->osd_item.h-this->osd_item.h/10;
957
958 curr_color = this->bActive?this->white:this->orange;
959 graphics_draw_text(this->osd_item.gr, curr_color, NULL, this->osd_item.font, buffer, &p, 0x10000, 0);
960 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
961 }
962
963
964 static void
965 osd_stopwatch_click(struct stopwatch *this, struct navit *nav, int pressed, int button, struct point *p)
966 {
967 struct point bp = this->osd_item.p;
968 osd_wrap_point(&bp, nav);
969 if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->osd_item.w || p->y > bp.y + this->osd_item.h || !this->osd_item.configured ) && !this->osd_item.pressed)
970 return;
971 if (button != 1)
972 return;
973 if (navit_ignore_button(nav))
974 return;
975 if (!!pressed == !!this->osd_item.pressed)
976 return;
977
978 if (pressed) { //single click handling
979
980 if(this->bActive) {
981 this->sum_time += time(0)-this->current_base_time;
982 this->current_base_time = 0;
983 } else {
984 this->current_base_time = time(0);
985 }
986
987 this->bActive ^= 1; //toggle active flag
988
989 if (this->last_click_time == time(0) && !this->bDisableReset) { //double click handling
990 this->bActive = 0;
991 this->current_base_time = 0;
992 this->sum_time = 0;
993 }
994
995 this->last_click_time = time(0);
996 }
997
998 osd_stopwatch_draw(this, nav,NULL);
999 }
1000
1001
1002 static void
1003 osd_stopwatch_init(struct stopwatch *this, struct navit *nav)
1004 {
1005 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
1006
1007 this->orange = graphics_gc_new(this->osd_item.gr);
1008 graphics_gc_set_foreground(this->orange, &this->idle_color);
1009 graphics_gc_set_linewidth(this->orange, this->width);
1010
1011 this->white = graphics_gc_new(this->osd_item.gr);
1012 graphics_gc_set_foreground(this->white, &this->osd_item.text_color);
1013 graphics_gc_set_linewidth(this->white, this->width);
1014
1015
1016 graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
1017
1018 event_add_timeout(500, 1, callback_new_1(callback_cast(osd_stopwatch_draw), this));
1019
1020 navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_stopwatch_click), attr_button, this));
1021
1022 osd_stopwatch_draw(this, nav, NULL);
1023 }
1024
1025 static struct osd_priv *
1026 osd_stopwatch_new(struct navit *nav, struct osd_methods *meth,
1027 struct attr **attrs)
1028 {
1029 struct stopwatch *this = g_new0(struct stopwatch, 1);
1030 struct attr *attr;
1031 struct color orange_color={0xffff,0xa5a5,0x0000,0xffff};
1032
1033 this->osd_item.p.x = 120;
1034 this->osd_item.p.y = 20;
1035 this->osd_item.w = 60;
1036 this->osd_item.h = 80;
1037 this->osd_item.navit = nav;
1038 this->osd_item.font_size = 200;
1039 this->osd_item.meth.draw = osd_draw_cast(osd_stopwatch_draw);
1040
1041 this->bActive = 0; //do not count on init
1042 this->current_base_time = 0;
1043 this->sum_time = 0;
1044 this->last_click_time = 0;
1045
1046 osd_set_std_attr(attrs, &this->osd_item, 2);
1047 attr = attr_search(attrs, NULL, attr_width);
1048 this->width=attr ? attr->u.num : 2;
1049 attr = attr_search(attrs, NULL, attr_idle_color);
1050 this->idle_color=attr ? *attr->u.color : orange_color; // text idle_color defaults to orange
1051 attr = attr_search(attrs, NULL, attr_disable_reset);
1052 if (attr)
1053 this->bDisableReset = attr->u.num;
1054 else
1055 this->bDisableReset = 0;
1056
1057 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_stopwatch_init), attr_graphics_ready, this));
1058 return (struct osd_priv *) this;
1059 }
1060
1061
1062 static void
1063 osd_compass_draw(struct compass *this, struct navit *nav,
1064 struct vehicle *v)
1065 {
1066 //dbg(0,"EEnter\n");
1067
1068 struct point p,bbox[4];
1069 struct attr attr_dir, destination_attr, position_attr, imperial_attr;
1070 double dir, vdir = 0;
1071 char *buffer;
1072 struct coord c1, c2;
1073 enum projection pro;
1074 int imperial=0;
1075
1076 if (navit_get_attr(nav, attr_imperial, &imperial_attr, NULL))
1077 imperial=imperial_attr.u.num;
1078
1079 //dbg(0,"CCC 1\n");
1080 // **DISABLE** osd_std_draw(&this->osd_item);
1081 // **DISABLE** p.x = this->osd_item.w/2;
1082 // **DISABLE** p.y = this->osd_item.w/2;
1083
1084 // graphics_send_osd_values(this->osd_item.gr,this->osd_item.graphic_fg_white,"compass","draw_circle","","",0,0,0,0,0.0,0.0,0.0);
1085
1086 // **DISABLE** graphics_draw_circle(this->osd_item.gr, this->osd_item.graphic_fg_white, &p, this->osd_item.w*5/6);
1087 //dbg(0,"CCC 2\n");
1088 if (v) {
1089 //dbg(0,"CCC 3\n");
1090 if (vehicle_get_attr(v, attr_position_direction, &attr_dir, NULL)) {
1091 //dbg(0,"CCC 4\n");
1092 vdir = *attr_dir.u.numd;
1093 // **DISABLE** handle(this->osd_item.gr, this->osd_item.graphic_fg_white, &p, this->osd_item.w/3, -vdir);
1094 // dbg(0,"vdir:%f\n",vdir);
1095 //char *buf_value;
1096 //g_snprintf(buf_value, 20, "%f", -vdir);
1097 //dbg(0,"CCC 5\n");
1098 graphics_send_osd_values(this->osd_item.gr,this->osd_item.graphic_fg_white,"compass","direction","","",(int)-vdir,0,0,0,0,0,0);
1099 //g_free(buf_value);
1100 //dbg(0,"CCC 6\n");
1101 }
1102
1103 //dbg(0,"CCC 7\n");
1104 if (navit_get_attr(nav, attr_destination, &destination_attr, NULL)
1105 && vehicle_get_attr(v, attr_position_coord_geo,&position_attr, NULL)) {
1106 pro = destination_attr.u.pcoord->pro;
1107 transform_from_geo(pro, position_attr.u.coord_geo, &c1);
1108 c2.x = destination_attr.u.pcoord->x;
1109 c2.y = destination_attr.u.pcoord->y;
1110 dir = atan2(c2.x - c1.x, c2.y - c1.y) * 180.0 / M_PI;
1111 dir -= vdir;
1112 //dbg(0,"CCC 8\n");
1113 // **DISABLE** handle(this->osd_item.gr, this->green, &p, this->osd_item.w/3, dir);
1114 buffer=format_distance(transform_distance(pro, &c1, &c2),"",imperial);
1115 // **DISABLE** graphics_get_text_bbox(this->osd_item.gr, this->osd_item.font, buffer, 0x10000, 0, bbox, 0);
1116 // **DISABLE** p.x=(this->osd_item.w-bbox[2].x)/2;
1117 // **DISABLE** p.y = this->osd_item.h-this->osd_item.h/10;
1118
1119 // dbg(0,"dir:%f\n",dir);
1120 //char *buf_value;
1121 //g_snprintf(buf_value, 20, "%f", dir);
1122 //dbg(0,"CCC 8\n");
1123 graphics_send_osd_values(this->osd_item.gr,this->osd_item.graphic_fg_white,"compass","text_and_dst_angle",buffer,"",(int)dir,0,0,0,0,0,0);
1124 //dbg(0,"CCC 10\n");
1125 //g_free(buf_value);
1126
1127 // **DISABLE** graphics_draw_text(this->osd_item.gr, this->green, NULL, this->osd_item.font, buffer, &p, 0x10000, 0);
1128 g_free(buffer);
1129 //dbg(0,"CCC 11\n");
1130 }
1131 }
1132
1133 //dbg(0,"CCC 12\n");
1134 // **DISABLE** graphics_draw_mode(this->osd_item.gr, draw_mode_end);
1135 //dbg(0,"CCC 13\n");
1136 }
1137
1138
1139
1140 static void
1141 osd_compass_init(struct compass *this, struct navit *nav)
1142 {
1143 struct color c;
1144
1145 //dbg(0,"CCC 14\n");
1146
1147 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
1148
1149 //dbg(0,"CCC 15\n");
1150
1151 this->green = graphics_gc_new(this->osd_item.gr);
1152 c.r = 0;
1153 c.g = 65535;
1154 c.b = 0;
1155 c.a = 65535;
1156
1157 // **DISABLE** graphics_gc_set_foreground(this->green, &c);
1158 // **DISABLE** graphics_gc_set_linewidth(this->green, this->width);
1159 // **DISABLE** graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
1160
1161 //dbg(0,"CCC 16\n");
1162
1163 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_draw), attr_position_coord_geo, this));
1164
1165 //dbg(0,"CCC 17\n");
1166
1167 osd_compass_draw(this, nav, NULL);
1168
1169 //dbg(0,"CCC 18\n");
1170 }
1171
1172 static struct osd_priv *
1173 osd_compass_new(struct navit *nav, struct osd_methods *meth,
1174 struct attr **attrs)
1175 {
1176 //dbg(0,"EEnter\n");
1177
1178 struct compass *this = g_new0(struct compass, 1);
1179 struct attr *attr;
1180 this->osd_item.p.x = 20;
1181 this->osd_item.p.y = 20;
1182 this->osd_item.w = 60;
1183 this->osd_item.h = 80;
1184 this->osd_item.navit = nav;
1185 this->osd_item.font_size = 200;
1186 this->osd_item.meth.draw = osd_draw_cast(osd_compass_draw);
1187 osd_set_std_attr(attrs, &this->osd_item, 2);
1188 attr = attr_search(attrs, NULL, attr_width);
1189 this->width=attr ? attr->u.num : 2;
1190 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_init), attr_graphics_ready, this));
1191
1192 dbg(0,"11111111111\n");
1193
1194 return (struct osd_priv *) this;
1195 }
1196
1197 struct osd_button {
1198 int use_overlay;
1199 struct osd_item item;
1200 struct callback *draw_cb,*navit_init_cb;
1201 struct graphics_image *img;
1202 char *src;
1203 };
1204
1205 static void
1206 osd_button_draw(struct osd_button *this, struct navit *nav)
1207 {
1208 //dbg(0,"EEnter\n");
1209
1210 struct point bp = this->item.p;
1211 if (!this->item.configured)
1212 return;
1213 osd_wrap_point(&bp, nav);
1214 graphics_draw_image(this->item.gr, this->item.graphic_bg, &bp, this->img);
1215 }
1216
1217 static void
1218 osd_button_init(struct osd_button *this, struct navit *nav)
1219 {
1220 //dbg(0,"EEnter\n");
1221
1222 struct graphics *gra = navit_get_graphics(nav);
1223 dbg(1, "enter\n");
1224 this->img = graphics_image_new(gra, this->src);
1225 if (!this->img) {
1226 dbg(1, "failed to load '%s'\n", this->src);
1227 return;
1228 }
1229 if (!this->item.w)
1230 this->item.w=this->img->width;
1231 if (!this->item.h)
1232 this->item.h=this->img->height;
1233 if (this->use_overlay) {
1234 struct graphics_image *img;
1235 struct point p;
1236 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
1237 img=graphics_image_new(this->item.gr, this->src);
1238 p.x=(this->item.w-this->img->width)/2;
1239 p.y=(this->item.h-this->img->height)/2;
1240 osd_std_draw(&this->item);
1241 graphics_draw_image(this->item.gr, this->item.graphic_bg, &p, img);
1242 graphics_draw_mode(this->item.gr, draw_mode_end);
1243 graphics_image_free(this->item.gr, img);
1244 } else {
1245 osd_set_std_config(nav, &this->item);
1246 this->item.gr=gra;
1247 this->item.graphic_bg=graphics_gc_new(this->item.gr);
1248 graphics_add_callback(gra, this->draw_cb=callback_new_attr_2(callback_cast(osd_button_draw), attr_postdraw, this, nav));
1249 }
1250 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast (osd_std_click), attr_button, &this->item));
1251 osd_button_draw(this,nav);
1252 }
1253
1254 int
1255 osd_button_set_attr(struct osd_button *this_, struct attr* attr)
1256 {
1257 //dbg(0,"EEnter\n");
1258
1259 if(NULL==attr || NULL==this_) {
1260 return 0;
1261 }
1262 if(attr->type == attr_src) {
1263 struct navit *nav;
1264 struct graphics *gra;
1265 if(this_->src) {
1266 g_free(this_->src);
1267 }
1268 if(attr->u.str) {
1269 this_->src = graphics_icon_path(attr->u.str);
1270 }
1271 nav = this_->item.navit;
1272 gra = navit_get_graphics(nav);
1273 this_->img = graphics_image_new(gra, this_->src);
1274 if (!this_->img) {
1275 dbg(1, "failed to load '%s'\n", this_->src);
1276 return 0;
1277 }
1278 if (!this_->item.w)
1279 this_->item.w=this_->img->width;
1280 if (!this_->item.h)
1281 this_->item.h=this_->img->height;
1282
1283 if (this_->use_overlay) {
1284 struct graphics_image *img;
1285 struct point p;
1286 img=graphics_image_new(this_->item.gr, this_->src);
1287 p.x=(this_->item.w-this_->img->width)/2;
1288 p.y=(this_->item.h-this_->img->height)/2;
1289 osd_std_draw(&this_->item);
1290 graphics_draw_image(this_->item.gr, this_->item.graphic_bg, &p, img);
1291 graphics_image_free(this_->item.gr, img);
1292 }
1293 osd_button_draw(this_,nav);
1294 navit_draw(this_->item.navit);
1295 return 1;
1296 }
1297 return 0;
1298 }
1299
1300
1301
1302 static struct osd_priv *
1303 osd_button_new(struct navit *nav, struct osd_methods *meth,
1304 struct attr **attrs)
1305 {
1306 //dbg(0,"EEnter\n");
1307
1308 struct osd_button *this = g_new0(struct osd_button, 1);
1309 struct attr *attr;
1310
1311 this->item.navit = nav;
1312 this->item.meth.draw = osd_draw_cast(osd_button_draw);
1313
1314 meth->set_attr = osd_button_set_attr;
1315
1316 osd_set_std_attr(attrs, &this->item, 1|16);
1317
1318 attr=attr_search(attrs, NULL, attr_use_overlay);
1319 if (attr)
1320 this->use_overlay=attr->u.num;
1321 if (!this->item.command) {
1322 dbg(0, "no command\n");
1323 goto error;
1324 }
1325 attr = attr_search(attrs, NULL, attr_src);
1326 if (!attr) {
1327 dbg(0, "no src\n");
1328 goto error;
1329 }
1330
1331 this->src = graphics_icon_path(attr->u.str);
1332
1333 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast (osd_button_init), attr_graphics_ready, this));
1334
1335 if(b_commandtable_added == 0) {
1336 navit_command_add_table(nav, commands, sizeof(commands)/sizeof(struct command_table));
1337 b_commandtable_added = 1;
1338 }
1339
1340 return (struct osd_priv *) this;
1341 error:
1342 g_free(this);
1343 return NULL;
1344 }
1345
1346 struct osd_image {
1347 int use_overlay;
1348 struct osd_item item;
1349 struct callback *draw_cb,*navit_init_cb;
1350 struct graphics_image *img;
1351 char *src;
1352 };
1353
1354 static void
1355 osd_image_draw(struct osd_image *this, struct navit *nav)
1356 {
1357 //dbg(0,"EEnter\n");
1358
1359 struct point bp = this->item.p;
1360 osd_wrap_point(&bp, nav);
1361 graphics_draw_image(this->item.gr, this->item.graphic_bg, &bp, this->img);
1362 }
1363
1364 static void
1365 osd_image_init(struct osd_image *this, struct navit *nav)
1366 {
1367 //dbg(0,"EEnter\n");
1368
1369 struct graphics *gra = navit_get_graphics(nav);
1370 dbg(1, "enter\n");
1371 this->img = graphics_image_new(gra, this->src);
1372 if (!this->img) {
1373 dbg(1, "failed to load '%s'\n", this->src);
1374 return;
1375 }
1376 if (!this->item.w)
1377 this->item.w=this->img->width;
1378 if (!this->item.h)
1379 this->item.h=this->img->height;
1380 if (this->use_overlay) {
1381 struct graphics_image *img;
1382 struct point p;
1383 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
1384 img=graphics_image_new(this->item.gr, this->src);
1385 p.x=(this->item.w-this->img->width)/2;
1386 p.y=(this->item.h-this->img->height)/2;
1387 osd_std_draw(&this->item);
1388 graphics_draw_image(this->item.gr, this->item.graphic_bg, &p, img);
1389 graphics_draw_mode(this->item.gr, draw_mode_end);
1390 graphics_image_free(this->item.gr, img);
1391 } else {
1392 this->item.configured=1;
1393 this->item.gr=gra;
1394 this->item.graphic_bg=graphics_gc_new(this->item.gr);
1395 graphics_add_callback(gra, this->draw_cb=callback_new_attr_2(callback_cast(osd_button_draw), attr_postdraw, this, nav));
1396 }
1397 osd_image_draw(this,nav);
1398 }
1399
1400 static struct osd_priv *
1401 osd_image_new(struct navit *nav, struct osd_methods *meth,
1402 struct attr **attrs)
1403 {
1404 //dbg(0,"EEnter\n");
1405
1406 struct osd_image *this = g_new0(struct osd_image, 1);
1407 struct attr *attr;
1408
1409 this->item.navit = nav;
1410 this->item.meth.draw = osd_draw_cast(osd_image_draw);
1411
1412 osd_set_std_attr(attrs, &this->item, 1);
1413
1414 attr=attr_search(attrs, NULL, attr_use_overlay);
1415 if (attr)
1416 this->use_overlay=attr->u.num;
1417 attr = attr_search(attrs, NULL, attr_src);
1418 if (!attr) {
1419 dbg(0, "no src\n");
1420 goto error;
1421 }
1422
1423 this->src = graphics_icon_path(attr->u.str);
1424
1425 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast (osd_image_init), attr_graphics_ready, this));
1426
1427 return (struct osd_priv *) this;
1428 error:
1429 g_free(this);
1430 return NULL;
1431 }
1432
1433 struct nav_next_turn {
1434 struct osd_item osd_item;
1435 char *test_text;
1436 char *icon_src;
1437 int icon_h, icon_w, active;
1438 char *last_name;
1439 int level;
1440 };
1441
1442 static void
1443 osd_nav_next_turn_draw(struct nav_next_turn *this, struct navit *navit,
1444 struct vehicle *v)
1445 {
1446 //dbg(0,"EEnter\n");
1447
1448 struct point p;
1449 int do_draw = 0;
1450 struct navigation *nav = NULL;
1451 struct map *map = NULL;
1452 struct map_rect *mr = NULL;
1453 struct item *item = NULL;
1454 struct graphics_image *gr_image = NULL;
1455 char *image;
1456 char *name = "unknown";
1457 int level = this->level;
1458
1459 if (navit)
1460 nav = navit_get_navigation(navit);
1461 if (nav)
1462 map = navigation_get_map(nav);
1463 if (map)
1464 mr = map_rect_new(map, NULL);
1465 if (mr)
1466 while ((item = map_rect_get_item(mr))
1467 && (item->type == type_nav_position || item->type == type_nav_none || level-- > 0));
1468 if (item) {
1469 name = item_to_name(item->type);
1470 dbg(1, "name=%s\n", name);
1471 if (this->active != 1 || this->last_name != name) {
1472 this->active = 1;
1473 this->last_name = name;
1474 do_draw = 1;
1475 }
1476 } else {
1477 if (this->active != 0) {
1478 this->active = 0;
1479 do_draw = 1;
1480 }
1481 }
1482 if (mr)
1483 map_rect_destroy(mr);
1484
1485 if (do_draw) {
1486 // **DISABLE** osd_std_draw(&this->osd_item);
1487 if (this->active)
1488 {
1489 image = g_strdup_printf(this->icon_src, name);
1490 dbg(1, "image=%s\n", image);
1491
1492 graphics_send_osd_values(this->osd_item.gr,this->osd_item.graphic_fg_white,"nav_next_turn","draw_image1",image,"",this->icon_w,this->icon_h,0,0,0.0,0.0,0.0);
1493
1494 // **DISABLE** gr_image = graphics_image_new_scaled(this->osd_item.gr, image, this->icon_w, this->icon_h);
1495 if (!gr_image)
1496 {
1497 // **DISABLE** dbg(0,"failed to load %s in %dx%d\n",image,this->icon_w,this->icon_h);
1498 // **DISABLE** g_free(image);
1499
1500 // **DISABLE** graphics_send_osd_values(this->osd_item.gr,this->osd_item.graphic_fg_white,"nav_next_turn","draw_image2","unknown.xpm","",this->icon_w,this->icon_h,0,0,0.0,0.0,0.0);
1501
1502 // **DISABLE** image = graphics_icon_path("unknown.xpm");
1503 // **DISABLE**
1504 /*
1505 gr_image =
1506 graphics_image_new_scaled(this->
1507 osd_item.gr,
1508 image,
1509 this->icon_w,
1510 this->
1511 icon_h);
1512 */
1513 }
1514 dbg(1, "gr_image=%p\n", gr_image);
1515 if (gr_image)
1516 {
1517 p.x =
1518 (this->osd_item.w -
1519 gr_image->width) / 2;
1520 p.y =
1521 (this->osd_item.h -
1522 gr_image->height) / 2;
1523
1524 // **DISABLE**
1525 /*
1526 graphics_draw_image(this->osd_item.gr,
1527 this->osd_item.
1528 graphic_fg_white, &p,
1529 gr_image);
1530 graphics_image_free(this->osd_item.gr,
1531 gr_image);
1532 */
1533 }
1534 g_free(image);
1535 }
1536 // **DISABLE** graphics_draw_mode(this->osd_item.gr, draw_mode_end);
1537 }
1538 }
1539
1540 static void
1541 osd_nav_next_turn_init(struct nav_next_turn *this, struct navit *nav)
1542 {
1543 //dbg(0,"EEnter\n");
1544
1545 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
1546 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_next_turn_draw), attr_position_coord_geo, this));
1547 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->osd_item));
1548 osd_nav_next_turn_draw(this, nav, NULL);
1549 }
1550
1551 static struct osd_priv *
1552 osd_nav_next_turn_new(struct navit *nav, struct osd_methods *meth,
1553 struct attr **attrs)
1554 {
1555 //dbg(0,"EEnter\n");
1556
1557 struct nav_next_turn *this = g_new0(struct nav_next_turn, 1);
1558 struct attr *attr;
1559
1560 this->osd_item.p.x = 20;
1561 this->osd_item.p.y = -80;
1562 this->osd_item.w = 70;
1563 this->osd_item.navit = nav;
1564 this->osd_item.h = 70;
1565 this->osd_item.font_size = 200;
1566 this->osd_item.meth.draw = osd_draw_cast(osd_nav_next_turn_draw);
1567 osd_set_std_attr(attrs, &this->osd_item, 0);
1568
1569 this->icon_w = -1;
1570 this->icon_h = -1;
1571 this->active = -1;
1572 this->level = 0;
1573
1574 attr = attr_search(attrs, NULL, attr_icon_w);
1575 if (attr)
1576 this->icon_w = attr->u.num;
1577
1578 attr = attr_search(attrs, NULL, attr_icon_h);
1579 if (attr)
1580 this->icon_h = attr->u.num;
1581
1582 attr = attr_search(attrs, NULL, attr_icon_src);
1583 if (attr) {
1584 struct file_wordexp *we;
1585 char **array;
1586 we = file_wordexp_new(attr->u.str);
1587 array = file_wordexp_get_array(we);
1588 this->icon_src = graphics_icon_path(array[0]);
1589 file_wordexp_destroy(we);
1590 } else {
1591 this->icon_src = graphics_icon_path("%s_wh.svg");
1592 }
1593
1594 attr = attr_search(attrs, NULL, attr_level);
1595 if (attr)
1596 this->level=attr->u.num;
1597
1598 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_next_turn_init), attr_graphics_ready, this));
1599 return (struct osd_priv *) this;
1600 }
1601
1602 struct nav_toggle_announcer
1603 {
1604 int w,h;
1605 struct callback *navit_init_cb;
1606 struct osd_item item;
1607 char *icon_src;
1608 int icon_h, icon_w, active, last_state;
1609 };
1610
1611 static void
1612 osd_nav_toggle_announcer_draw(struct nav_toggle_announcer *this, struct navit *navit, struct vehicle *v)
1613 {
1614 struct point p;
1615 int do_draw = 0;
1616 struct graphics_image *gr_image;
1617 char *path;
1618 char *gui_sound_off = "gui_sound_off";
1619 char *gui_sound_on = "gui_sound";
1620 struct attr attr, speechattr;
1621
1622 if (this->last_state == -1)
1623 {
1624 if (!navit_get_attr(navit, attr_speech, &speechattr, NULL))
1625 if (!speech_get_attr(speechattr.u.speech, attr_active, &attr, NULL))
1626 attr.u.num = 1;
1627 this->active = attr.u.num;
1628 } else
1629 this->active = !this->active;
1630
1631 if(this->active != this->last_state)
1632 {
1633 this->last_state = this->active;
1634 do_draw = 1;
1635 }
1636
1637 if (do_draw)
1638 {
1639 graphics_draw_mode(this->item.gr, draw_mode_begin);
1640 p.x = 0;
1641 p.y = 0;
1642 graphics_draw_rectangle(this->item.gr, this->item.graphic_bg, &p, this->item.w, this->item.h);
1643
1644 if (this->active)
1645 path = g_strdup_printf(this->icon_src, gui_sound_on);
1646 else
1647 path = g_strdup_printf(this->icon_src, gui_sound_off);
1648
1649 gr_image = graphics_image_new_scaled(this->item.gr, path, this->icon_w, this->icon_h);
1650 if (!gr_image)
1651 {
1652 g_free(path);
1653 path = graphics_icon_path("unknown.xpm");
1654 gr_image = graphics_image_new_scaled(this->item.gr, path, this->icon_w, this->icon_h);
1655 }
1656
1657 dbg(1, "gr_image=%p\n", gr_image);
1658
1659 if (gr_image)
1660 {
1661 p.x = (this->item.w - gr_image->width) / 2;
1662 p.y = (this->item.h - gr_image->height) / 2;
1663 graphics_draw_image(this->item.gr, this->item.graphic_fg_white, &p, gr_image);
1664 graphics_image_free(this->item.gr, gr_image);
1665 }
1666
1667 g_free(path);
1668 graphics_draw_mode(this->item.gr, draw_mode_end);
1669 }
1670 }
1671
1672 static void
1673 osd_nav_toggle_announcer_init(struct nav_toggle_announcer *this, struct navit *nav)
1674 {
1675 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
1676 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_toggle_announcer_draw), attr_speech, this));
1677 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->item));
1678 osd_nav_toggle_announcer_draw(this, nav, NULL);
1679 }
1680
1681 static struct osd_priv *
1682 osd_nav_toggle_announcer_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
1683 {
1684 struct nav_toggle_announcer *this = g_new0(struct nav_toggle_announcer, 1);
1685 struct attr *attr;
1686 char *command = "announcer_toggle()";
1687
1688 this->item.w = 48;
1689 this->item.h = 48;
1690 this->item.p.x = -64;
1691 this->item.navit = nav;
1692 this->item.p.y = 76;
1693 this->item.meth.draw = osd_draw_cast(osd_nav_toggle_announcer_draw);
1694
1695 osd_set_std_attr(attrs, &this->item, 0);
1696
1697 this->icon_w = -1;
1698 this->icon_h = -1;
1699 this->last_state = -1;
1700
1701 attr = attr_search(attrs, NULL, attr_icon_src);
1702 if (attr) {
1703 struct file_wordexp *we;
1704 char **array;
1705 we = file_wordexp_new(attr->u.str);
1706 array = file_wordexp_get_array(we);
1707 this->icon_src = g_strdup(array[0]);
1708 file_wordexp_destroy(we);
1709 } else
1710 this->icon_src = graphics_icon_path("%s_32.xpm");
1711
1712 this->item.command = g_strdup(command);
1713
1714 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_toggle_announcer_init), attr_graphics_ready, this));
1715 return (struct osd_priv *) this;
1716 }
1717
1718 enum osd_speed_warner_eAnnounceState {eNoWarn=0,eWarningTold=1};
1719 enum camera_t {CAM_FIXED=1, CAM_TRAFFIC_LAMP, CAM_RED, CAM_SECTION, CAM_MOBILE, CAM_RAIL, CAM_TRAFFIPAX};
1720 char*camera_t_strs[] = {"None","Fix","Traffic lamp","Red detect","Section","Mobile","Rail","Traffipax(non persistent)"};
1721 char*camdir_t_strs[] = {"All dir.","UNI-dir","BI-dir"};
1722 enum cam_dir_t {CAMDIR_ALL=0, CAMDIR_ONE, CAMDIR_TWO};
1723
1724 struct osd_speed_cam_entry {
1725 double lon;
1726 double lat;
1727 enum camera_t cam_type;
1728 int speed_limit;
1729 enum cam_dir_t cam_dir;
1730 int direction;
1731 };
1732
1733 struct osd_speed_cam {
1734 struct osd_item item;
1735 int width;
1736 struct graphics_gc *white,*orange;
1737 struct graphics_gc *red;
1738 struct color idle_color;
1739
1740 int announce_on;
1741 enum osd_speed_warner_eAnnounceState announce_state;
1742 char *text; //text of label attribute for this osd
1743 };
1744
1745 static double
1746 angle_diff(int firstAngle,int secondAngle)
1747 {
1748 double difference = secondAngle - firstAngle;
1749 while (difference < -180) difference += 360;
1750 while (difference > 180) difference -= 360;
1751 return difference;
1752 }
1753
1754 static void
1755 osd_speed_cam_draw(struct osd_speed_cam *this_, struct navit *navit, struct vehicle *v)
1756 {
1757 struct attr position_attr,vehicle_attr,imperial_attr;
1758 struct point p, bbox[4];
1759 struct attr speed_attr;
1760 struct vehicle* curr_vehicle = v;
1761 struct coord curr_coord;
1762 struct coord cam_coord;
1763 struct mapset* ms;
1764
1765 double dCurrDist = -1;
1766 int dir_idx = -1;
1767 int dir = -1;
1768 int spd = -1;
1769 int idx = -1;
1770 double speed = -1;
1771 int bFound = 0;
1772
1773 int dst=2000;
1774 int dstsq=dst*dst;
1775 struct map_selection sel;
1776 struct map_rect *mr;
1777 struct mapset_handle *msh;
1778 struct map *map;
1779 struct item *item;
1780
1781 struct attr attr_dir;
1782 struct graphics_gc *curr_color;
1783 int ret_attr = 0;
1784 int imperial=0;
1785
1786 if (navit_get_attr(navit, attr_imperial, &imperial_attr, NULL))
1787 imperial=imperial_attr.u.num;
1788
1789
1790 if(navit) {
1791 navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL);
1792 }
1793 else {
1794 return;
1795 }
1796 if (vehicle_attr.u.vehicle) {
1797 curr_vehicle = vehicle_attr.u.vehicle;
1798 }
1799
1800 if(0==curr_vehicle)
1801 return;
1802
1803 if(!(ms=navit_get_mapset(navit))) {
1804 return;
1805 }
1806
1807 ret_attr = vehicle_get_attr(curr_vehicle, attr_position_coord_geo,&position_attr, NULL);
1808 if(0==ret_attr) {
1809 return;
1810 }
1811
1812 transform_from_geo(projection_mg, position_attr.u.coord_geo, &curr_coord);
1813
1814 sel.next=NULL;
1815 sel.order=18;
1816 sel.range.min=type_tec_common;
1817 sel.range.max=type_tec_common;
1818 sel.u.c_rect.lu.x=curr_coord.x-dst;
1819 sel.u.c_rect.lu.y=curr_coord.y+dst;
1820 sel.u.c_rect.rl.x=curr_coord.x+dst;
1821 sel.u.c_rect.rl.y=curr_coord.y-dst;
1822
1823 msh=mapset_open(ms);
1824 while ((map=mapset_next(msh, 1))) {
1825 struct attr attr;
1826 if(map_get_attr(map, attr_type, &attr, NULL)) {
1827 if( strcmp("csv", attr.u.str) && strcmp("binfile", attr.u.str)) {
1828 continue;
1829 }
1830 }
1831 else {
1832 continue;
1833 }
1834 mr=map_rect_new(map, &sel);
1835 if (!mr)
1836 continue;
1837 while ((item=map_rect_get_item(mr))) {
1838 struct coord cn;
1839 if (item->type == type_tec_common && item_coord_get(item, &cn, 1)) {
1840 int dist=transform_distance_sq(&cn, &curr_coord);
1841 if (dist < dstsq) {
1842 struct attr tec_attr;
1843 bFound = 1;
1844 dstsq=dist;
1845 dCurrDist = sqrt(dist);
1846 cam_coord = cn;
1847 idx = -1;
1848 if(item_attr_get(item,attr_tec_type,&tec_attr)) {
1849 idx = tec_attr.u.num;
1850 }
1851 dir_idx = -1;
1852 if(item_attr_get(item,attr_tec_dirtype,&tec_attr)) {
1853 dir_idx = tec_attr.u.num;
1854 }
1855 dir= 0;
1856 if(item_attr_get(item,attr_tec_direction,&tec_attr)) {
1857 dir = tec_attr.u.num;
1858 }
1859 spd= 0;
1860 if(item_attr_get(item,attr_maxspeed,&tec_attr)) {
1861 spd = tec_attr.u.num;
1862 }
1863 }
1864 }
1865 }
1866 map_rect_destroy(mr);
1867 }
1868 mapset_close(msh);
1869
1870 if(bFound) {
1871 dCurrDist = transform_distance(projection_mg, &curr_coord, &cam_coord);
1872 ret_attr = vehicle_get_attr(curr_vehicle,attr_position_speed,&speed_attr, NULL);
1873 if(0==ret_attr) {
1874 graphics_overlay_disable(this_->item.gr,1);
1875 return;
1876 }
1877 graphics_overlay_disable(this_->item.gr,0);
1878 speed = *speed_attr.u.numd;
1879 if(dCurrDist <= speed*750.0/130.0) { //at speed 130 distance limit is 750m
1880 if(this_->announce_state==eNoWarn && this_->announce_on) {
1881 this_->announce_state=eWarningTold; //warning told
1882 navit_say(navit, _("Look out! Camera!"));
1883 }
1884 }
1885 else {
1886 this_->announce_state=eNoWarn;
1887 }
1888
1889 if(this_->text) {
1890 char buffer [256]="";
1891 char buffer2[256]="";
1892 char dir_str[16];
1893 char spd_str[16];
1894 buffer [0] = 0;
1895 buffer2[0] = 0;
1896
1897 osd_std_draw(&this_->item);
1898
1899 str_replace(buffer,this_->text,"${distance}",format_distance(dCurrDist,"",imperial));
1900 str_replace(buffer2,buffer,"${camera_type}",(0<=idx && idx<=CAM_TRAFFIPAX)?camera_t_strs[idx]:"");
1901 str_replace(buffer,buffer2,"${camera_dir}",(0<=dir_idx && dir_idx<=CAMDIR_TWO)?camdir_t_strs[dir_idx]:"");
1902 sprintf(dir_str,"%d",dir);
1903 sprintf(spd_str,"%d",spd);
1904 str_replace(buffer2,buffer,"${direction}",dir_str);
1905 str_replace(buffer,buffer2,"${speed_limit}",spd_str);
1906
1907 graphics_get_text_bbox(this_->item.gr, this_->item.font, buffer, 0x10000, 0, bbox, 0);
1908 p.x=(this_->item.w-bbox[2].x)/2;
1909 p.y = this_->item.h-this_->item.h/10;
1910 curr_color = this_->orange;
1911 //tolerance is +-20 degrees
1912 if(
1913 dir_idx==CAMDIR_ONE &&
1914 dCurrDist <= speed*750.0/130.0 &&
1915 vehicle_get_attr(v, attr_position_direction, &attr_dir, NULL) &&
1916 fabs(angle_diff(dir,*attr_dir.u.numd))<=20 ) {
1917 curr_color = this_->red;
1918 }
1919 //tolerance is +-20 degrees in both directions
1920 else if(
1921 dir_idx==CAMDIR_TWO &&
1922 dCurrDist <= speed*750.0/130.0 &&
1923 vehicle_get_attr(v, attr_position_direction, &attr_dir, NULL) &&
1924 (fabs(angle_diff(dir,*attr_dir.u.numd))<=20 || fabs(angle_diff(dir+180,*attr_dir.u.numd))<=20 )) {
1925 curr_color = this_->red;
1926 }
1927 else if(dCurrDist <= speed*750.0/130.0) {
1928 curr_color = this_->red;
1929 }
1930 graphics_draw_text(this_->item.gr, curr_color, NULL, this_->item.font, buffer, &p, 0x10000, 0);
1931 graphics_draw_mode(this_->item.gr, draw_mode_end);
1932 }
1933 }
1934 else {
1935 graphics_overlay_disable(this_->item.gr,1);
1936 }
1937 }
1938
1939 static void
1940 osd_speed_cam_init(struct osd_speed_cam *this, struct navit *nav)
1941 {
1942 struct color red_color={0xffff,0x0000,0x0000,0xffff};
1943 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
1944
1945 this->red = graphics_gc_new(this->item.gr);
1946 graphics_gc_set_foreground(this->red, &red_color);
1947 graphics_gc_set_linewidth(this->red, this->width);
1948
1949 this->orange = graphics_gc_new(this->item.gr);
1950 graphics_gc_set_foreground(this->orange, &this->idle_color);
1951 graphics_gc_set_linewidth(this->orange, this->width);
1952
1953 this->white = graphics_gc_new(this->item.gr);
1954 graphics_gc_set_foreground(this->white, &this->item.text_color);
1955 graphics_gc_set_linewidth(this->white, this->width);
1956
1957
1958 graphics_gc_set_linewidth(this->item.graphic_fg_white, this->width);
1959
1960 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_cam_draw), attr_position_coord_geo, this));
1961
1962 }
1963
1964 static struct osd_priv *
1965 osd_speed_cam_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
1966 {
1967
1968 struct color default_color={0xffff,0xa5a5,0x0000,0xffff};
1969
1970 struct osd_speed_cam *this = g_new0(struct osd_speed_cam, 1);
1971 struct attr *attr;
1972 this->item.p.x = 120;
1973 this->item.p.y = 20;
1974 this->item.w = 60;
1975 this->item.h = 80;
1976 this->item.navit = nav;
1977 this->item.font_size = 200;
1978 this->item.meth.draw = osd_draw_cast(osd_speed_cam_draw);
1979
1980 osd_set_std_attr(attrs, &this->item, 2);
1981 attr = attr_search(attrs, NULL, attr_width);
1982 this->width=attr ? attr->u.num : 2;
1983 attr = attr_search(attrs, NULL, attr_idle_color);
1984 this->idle_color=attr ? *attr->u.color : default_color; // text idle_color defaults to orange
1985
1986 attr = attr_search(attrs, NULL, attr_label);
1987 if (attr) {
1988 this->text = g_strdup(attr->u.str);
1989 }
1990 else
1991 this->text = NULL;
1992
1993 attr = attr_search(attrs, NULL, attr_announce_on);
1994 if (attr) {
1995 this->announce_on = attr->u.num;
1996 }
1997 else {
1998 this->announce_on = 1; //announce by default
1999 }
2000
2001 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_cam_init), attr_graphics_ready, this));
2002 return (struct osd_priv *) this;
2003 }
2004
2005 struct osd_speed_warner {
2006 struct osd_item item;
2007 struct graphics_gc *red;
2008 struct graphics_gc *green;
2009 struct graphics_gc *grey;
2010 struct graphics_gc *black;
2011 struct graphics_gc *white;
2012 int width;
2013 int active;
2014 int d;
2015 double speed_exceed_limit_offset;
2016 double speed_exceed_limit_percent;
2017 int announce_on;
2018 enum osd_speed_warner_eAnnounceState announce_state;
2019 int bTextOnly;
2020 struct graphics_image *img_active,*img_passive,*img_off;
2021 char* label_str;
2022 };
2023
2024 static void
2025 osd_speed_warner_draw(struct osd_speed_warner *this, struct navit *navit, struct vehicle *v)
2026 {
2027 struct point p,bbox[4];
2028 char text[16]="";
2029
2030 struct tracking *tracking = NULL;
2031 struct graphics_gc *osd_color=this->grey;
2032 struct graphics_image *img = this->img_off;
2033
2034
2035 osd_std_draw(&this->item);
2036 p.x=this->item.w/2-this->d/4;
2037 p.y=this->item.h/2-this->d/4;
2038 p.x=this->item.w/2;
2039 p.y=this->item.h/2;
2040
2041 if (navit) {
2042 tracking = navit_get_tracking(navit);
2043 }
2044 if (tracking) {
2045
2046 struct attr maxspeed_attr,speed_attr,imperial_attr;
2047 int *flags;
2048 double routespeed = -1;
2049 double tracking_speed = -1;
2050 int osm_data = 0;
2051 struct item *item;
2052 int imperial=0;
2053
2054 item=tracking_get_current_item(tracking);
2055
2056 if(navit) {
2057 if (navit_get_attr(navit, attr_imperial, &imperial_attr, NULL))
2058 imperial=imperial_attr.u.num;
2059 }
2060
2061 flags=tracking_get_current_flags(tracking);
2062 if (flags && (*flags & AF_SPEED_LIMIT) && tracking_get_attr(tracking, attr_maxspeed, &maxspeed_attr, NULL)) {
2063 routespeed = maxspeed_attr.u.num;
2064 osm_data = 1;
2065 }
2066 if (routespeed == -1) {
2067 struct vehicleprofile *prof=navit_get_vehicleprofile(navit);
2068 struct roadprofile *rprof=NULL;
2069 if (prof && item)
2070 rprof=vehicleprofile_get_roadprofile(prof, item->type);
2071 if (rprof) {
2072 if(rprof->maxspeed!=0)
2073 routespeed=rprof->maxspeed;
2074 }
2075 }
2076 tracking_get_attr(tracking, attr_position_speed, &speed_attr, NULL);
2077 tracking_speed = *speed_attr.u.numd;
2078 if( -1 != tracking_speed && -1 != routespeed ) {
2079 char*routespeed_str = format_speed(routespeed,"","value",imperial);
2080 g_snprintf(text,16,"%s%s",osm_data ? "" : "~",routespeed_str);
2081 g_free(routespeed_str);
2082 if( this->speed_exceed_limit_offset+routespeed<tracking_speed &&
2083 (100.0+this->speed_exceed_limit_percent)/100.0*routespeed<tracking_speed ) {
2084 if(this->announce_state==eNoWarn && this->announce_on) {
2085 this->announce_state=eWarningTold; //warning told
2086 navit_say(navit,_("Please decrease your speed"));
2087 }
2088 }
2089 if( tracking_speed <= routespeed ) {
2090 this->announce_state=eNoWarn; //no warning
2091 osd_color = this->green;
2092 img = this->img_passive;
2093 }
2094 else {
2095 osd_color = this->red;
2096 img = this->img_active;
2097 }
2098 } else {
2099 osd_color = this->grey;
2100 img = this->img_off;
2101 this->announce_state = eNoWarn;
2102 }
2103 } else {
2104 //when tracking is not available display grey
2105 osd_color = this->grey;
2106 img = this->img_off;
2107 this->announce_state = eNoWarn;
2108 }
2109 if(this->img_active && this->img_passive && this->img_off) {
2110 struct point p;
2111 p.x=(this->item.w-img->width)/2;
2112 p.y=(this->item.h-img->height)/2;
2113 graphics_draw_image(this->item.gr, this->item.graphic_bg, &p, img);
2114 }
2115 else if(0==this->bTextOnly) {
2116 graphics_draw_circle(this->item.gr, osd_color, &p, this->d-this->width*2 );
2117 }
2118 graphics_get_text_bbox(this->item.gr, this->item.font, text, 0x10000, 0, bbox, 0);
2119 p.x=(this->item.w-bbox[2].x)/2;
2120 p.y=(this->item.h+bbox[2].y)/2-bbox[2].y;
2121 graphics_draw_text(this->item.gr, osd_color, NULL, this->item.font, text, &p, 0x10000, 0);
2122 graphics_draw_mode(this->item.gr, draw_mode_end);
2123 }
2124
2125 static void
2126 osd_speed_warner_init(struct osd_speed_warner *this, struct navit *nav)
2127 {
2128 struct color white_color={0xffff,0xffff,0xffff,0x0000};
2129 struct color red_color={0xffff,0,0,0xffff};
2130 struct color green_color={0,0xffff,0,0xffff};
2131 struct color grey_color={0x8888,0x8888,0x8888,0x8888};
2132 struct color black_color={0x1111,0x1111,0x1111,0x9999};
2133
2134 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
2135 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_warner_draw), attr_position_coord_geo, this));
2136
2137 if(this->label_str && !strncmp("images:",this->label_str,7)) {
2138 char *tok1=NULL, *tok2=NULL, *tok3=NULL;
2139 strtok(this->label_str,":");
2140 tok1 = strtok(NULL,":");
2141 if(tok1) {
2142 tok2 = strtok(NULL,":");
2143 }
2144 if(tok1 && tok2) {
2145 tok3 = strtok(NULL,":");
2146 }
2147 if(tok1 && tok2 && tok3) {
2148 tok1 = graphics_icon_path(tok1);
2149 tok2 = graphics_icon_path(tok2);
2150 tok3 = graphics_icon_path(tok3);
2151 this->img_active = graphics_image_new(this->item.gr, tok1);
2152 this->img_passive = graphics_image_new(this->item.gr, tok2);
2153 this->img_off = graphics_image_new(this->item.gr, tok3);
2154 g_free(tok1);
2155 g_free(tok2);
2156 g_free(tok3);
2157 }
2158 }
2159
2160 g_free(this->label_str);
2161 this->label_str = NULL;
2162
2163 this->white=graphics_gc_new(this->item.gr);
2164 graphics_gc_set_foreground(this->white, &white_color);
2165
2166 graphics_gc_set_linewidth(this->white, this->d/2-2 /*-this->width*/ );
2167
2168 this->red=graphics_gc_new(this->item.gr);
2169 graphics_gc_set_foreground(this->red, &red_color);
2170 graphics_gc_set_linewidth(this->red, this->width);
2171
2172 this->green=graphics_gc_new(this->item.gr);
2173 graphics_gc_set_foreground(this->green, &green_color);
2174 graphics_gc_set_linewidth(this->green, this->width-2);
2175
2176 this->grey=graphics_gc_new(this->item.gr);
2177 graphics_gc_set_foreground(this->grey, &grey_color);
2178 graphics_gc_set_linewidth(this->grey, this->width);
2179
2180 this->black=graphics_gc_new(this->item.gr);
2181 graphics_gc_set_foreground(this->black, &black_color);
2182 graphics_gc_set_linewidth(this->black, this->width);
2183
2184 osd_speed_warner_draw(this, nav, NULL);
2185 }
2186
2187 static struct osd_priv *
2188 osd_speed_warner_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
2189 {
2190 struct osd_speed_warner *this=g_new0(struct osd_speed_warner, 1);
2191 struct attr *attr;
2192 this->item.p.x=-80;
2193 this->item.p.y=20;
2194 this->item.w=60;
2195 this->item.navit = nav;
2196 this->item.h=60;
2197 this->active=-1;
2198 this->item.meth.draw = osd_draw_cast(osd_speed_warner_draw);
2199
2200 attr = attr_search(attrs, NULL, attr_speed_exceed_limit_offset);
2201 if (attr) {
2202 this->speed_exceed_limit_offset = attr->u.num;
2203 } else
2204 this->speed_exceed_limit_offset = 15; //by default 15 km/h
2205
2206 attr = attr_search(attrs, NULL, attr_speed_exceed_limit_percent);
2207 if (attr) {
2208 this->speed_exceed_limit_percent = attr->u.num;
2209 } else
2210 this->speed_exceed_limit_percent = 10; //by default factor of 1.1
2211
2212 this->bTextOnly = 0; //by default display graphics also
2213 attr = attr_search(attrs, NULL, attr_label);
2214 if (attr) {
2215 this->label_str = g_strdup(attr->u.str);
2216 if (!strcmp("text_only",attr->u.str)) {
2217 this->bTextOnly = 1;
2218 }
2219 }
2220
2221 attr = attr_search(attrs, NULL, attr_announce_on);
2222 if (attr)
2223 this->announce_on = attr->u.num;
2224 else
2225 this->announce_on = 1; //announce by default
2226 osd_set_std_attr(attrs, &this->item, 2);
2227 this->d=this->item.w;
2228 if (this->item.h < this->d)
2229 this->d=this->item.h;
2230 this->width=this->d/10;
2231 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_warner_init), attr_graphics_ready, this));
2232 return (struct osd_priv *) this;
2233 }
2234
2235 struct osd_text_item {
2236 int static_text;
2237 char *text;
2238 void *prev;
2239 void *next;
2240 enum attr_type section;
2241 enum attr_type attr_typ;
2242 void *root;
2243 int offset;
2244 char *format;
2245 };
2246
2247 struct osd_text {
2248 struct osd_item osd_item;
2249 int active;
2250 char *text;
2251 int align;
2252 char *last;
2253 struct osd_text_item *items;
2254 };
2255
2256
2257 /**
2258 * @brief Format a text attribute
2259 *
2260 * Returns the formatted current value of an attribute as a string
2261 *
2262 * @param attr Pointer to an attr structure specifying the attribute to be formatted
2263 * @param format Pointer to a string specifying how to format the attribute. Allowed format strings depend on the attribute; this member can be NULL.
2264 * @returns Pointer to a string containing the formatted value
2265 */
2266 static char *
2267 osd_text_format_attr(struct attr *attr, char *format, int imperial)
2268 {
2269 struct tm tm, text_tm, text_tm0;
2270 time_t textt;
2271 int days=0;
2272 char buffer[1024];
2273
2274 switch (attr->type) {
2275 case attr_position_speed:
2276 return format_speed(*attr->u.numd,"",format,imperial);
2277 case attr_position_height:
2278 case attr_position_direction:
2279 return format_float_0(*attr->u.numd);
2280 case attr_position_magnetic_direction:
2281 return g_strdup_printf("%d",attr->u.num);
2282 case attr_position_coord_geo:
2283 if ((!format) || (!strcmp(format,"pos_degminsec")))
2284 {
2285 coord_format(attr->u.coord_geo->lat,attr->u.coord_geo->lng,DEGREES_MINUTES_SECONDS,buffer,sizeof(buffer));
2286 return g_strdup(buffer);
2287 }
2288 else if (!strcmp(format,"pos_degmin"))
2289 {
2290 coord_format(attr->u.coord_geo->lat,attr->u.coord_geo->lng,DEGREES_MINUTES,buffer,sizeof(buffer));
2291 return g_strdup(buffer);
2292 }
2293 else if (!strcmp(format,"pos_deg"))
2294 {
2295 coord_format(attr->u.coord_geo->lat,attr->u.coord_geo->lng,DEGREES_DECIMAL,buffer,sizeof(buffer));
2296 return g_strdup(buffer);
2297 }
2298 else if (!strcmp(format,"lat_degminsec"))
2299 {
2300 coord_format(attr->u.coord_geo->lat,360,DEGREES_MINUTES_SECONDS,buffer,sizeof(buffer));
2301 return g_strdup(buffer);
2302 }
2303 else if (!strcmp(format,"lat_degmin"))
2304 {
2305 coord_format(attr->u.coord_geo->lat,360,DEGREES_MINUTES,buffer,sizeof(buffer));
2306 return g_strdup(buffer);
2307 }
2308 else if (!strcmp(format,"lat_deg"))
2309 {
2310 coord_format(attr->u.coord_geo->lat,360,DEGREES_DECIMAL,buffer,sizeof(buffer));
2311 return g_strdup(buffer);
2312 }
2313 else if (!strcmp(format,"lng_degminsec"))
2314 {
2315 coord_format(360,attr->u.coord_geo->lng,DEGREES_MINUTES_SECONDS,buffer,sizeof(buffer));
2316 return g_strdup(buffer);
2317 }
2318 else if (!strcmp(format,"lng_degmin"))
2319 {
2320 coord_format(360,attr->u.coord_geo->lng,DEGREES_MINUTES,buffer,sizeof(buffer));
2321 return g_strdup(buffer);
2322 }
2323 else if (!strcmp(format,"lng_deg"))
2324 {
2325 coord_format(360,attr->u.coord_geo->lng,DEGREES_DECIMAL,buffer,sizeof(buffer));
2326 return g_strdup(buffer);
2327 }
2328 else
2329 { // fall back to pos_degminsec
2330 coord_format(attr->u.coord_geo->lat,attr->u.coord_geo->lng,DEGREES_MINUTES_SECONDS,buffer,sizeof(buffer));
2331 return g_strdup(buffer);
2332 }
2333 case attr_destination_time:
2334 if (!format || (strcmp(format,"arrival") && strcmp(format,"remaining")))
2335 break;
2336 textt = time(NULL);
2337 tm = *localtime(&textt);
2338 if (!strcmp(format,"remaining")) {
2339 textt-=tm.tm_hour*3600+tm.tm_min*60+tm.tm_sec;
2340 tm = *localtime(&textt);
2341 }
2342 textt += attr->u.num / 10;
2343 text_tm = *localtime(&textt);
2344 if (tm.tm_year != text_tm.tm_year || tm.tm_mon != text_tm.tm_mon || tm.tm_mday != text_tm.tm_mday) {
2345 text_tm0 = text_tm;
2346 text_tm0.tm_sec = 0;
2347 text_tm0.tm_min = 0;
2348 text_tm0.tm_hour = 0;
2349 tm.tm_sec = 0;
2350 tm.tm_min = 0;
2351 tm.tm_hour = 0;
2352 days = (mktime(&text_tm0) - mktime(&tm) + 43200) / 86400;
2353 }
2354 return format_time(&text_tm, days);
2355 case attr_length:
2356 case attr_destination_length:
2357 if (!format)
2358 break;
2359 if (!strcmp(format,"named"))
2360 return format_distance(attr->u.num,"",imperial);
2361 if (!strcmp(format,"value") || !strcmp(format,"unit")) {
2362 char *ret,*tmp=format_distance(attr->u.num," ",imperial);
2363 char *pos=strchr(tmp,' ');
2364 if (! pos)
2365 return tmp;
2366 *pos++='\0';
2367 if (!strcmp(format,"value"))
2368 return tmp;
2369 ret=g_strdup(pos);
2370 g_free(tmp);
2371 return ret;
2372 }
2373 case attr_position_time_iso8601:
2374 if ((!format) || (!strcmp(format,"iso8601")))
2375 {
2376 break;
2377 }
2378 else
2379 {
2380 if (strstr(format, "local;") == format)
2381 {
2382 textt = iso8601_to_secs(attr->u.str);
2383 memcpy ((void *) &tm, (void *) localtime(&textt), sizeof(tm));
2384 strftime(buffer, sizeof(buffer), (char *)(format + 6), &tm);
2385 }
2386 else if ((sscanf(format, "%*c%2d:%2d;", &(text_tm.tm_hour), &(text_tm.tm_min)) == 2) && (strchr("+-", format[0])))
2387 {
2388 if (strchr("-", format[0]))
2389 {
2390 textt = iso8601_to_secs(attr->u.str) - text_tm.tm_hour * 3600 - text_tm.tm_min * 60;
2391 }
2392 else
2393 {
2394 textt = iso8601_to_secs(attr->u.str) + text_tm.tm_hour * 3600 + text_tm.tm_min * 60;
2395 }
2396 memcpy ((void *) &tm, (void *) gmtime(&textt), sizeof(tm));
2397 strftime(buffer, sizeof(buffer), &format[strcspn(format, ";") + 1], &tm);
2398 }
2399 else
2400 {
2401 sscanf(attr->u.str, "%4d-%2d-%2dT%2d:%2d:%2d", &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday), &(tm.tm_hour), &(tm.tm_min), &(tm.tm_sec));
2402 // the tm structure definition is kinda weird and needs some extra voodoo
2403 tm.tm_year-=1900; tm.tm_mon--;
2404 // get weekday and day of the year
2405 mktime(&tm);
2406 strftime(buffer, sizeof(buffer), format, &tm);
2407 }
2408 return g_strdup(buffer);
2409 }
2410 default:
2411 break;
2412 }
2413 return attr_to_text(attr, NULL, 1);
2414 }
2415
2416 /**
2417 * Parse a string of the form key.subkey or key[index].subkey into its components, where subkey can itself have its own index and further subkeys
2418 *
2419 * @param in String to parse (the part before subkey will be modified by the function); upon returning this pointer will point to a string containing key
2420 * @param index Pointer to an address that will receive a pointer to a string containing index or a null pointer if key does not have an index
2421 * @returns If the function succeeds, a pointer to a string containing subkey, i.e. everything following the first period, or a pointer to an empty string if there is nothing left to parse. If the function fails(index with missing closed bracket or passing a null pointer as index argument when an index was encountered), the return value is NULL
2422 */
2423 static char *
2424 osd_text_split(char *in, char **index)
2425 {
2426 char *pos;
2427 int len;
2428 if (index)
2429 *index=NULL;
2430 len=strcspn(in,"[.");
2431 in+=len;
2432 switch (in[0]) {
2433 case '\0':
2434 return in;
2435 case '.':
2436 *in++='\0';
2437 return in;
2438 case '[':
2439 if (!index)
2440 return NULL;
2441 *in++='\0';
2442 *index=in;
2443 pos=strchr(in,']');
2444 if (pos) {
2445 *pos++='\0';
2446 if (*pos == '.') {
2447 *pos++='\0';
2448 }
2449 return pos;
2450 }
2451 return NULL;
2452 }
2453 return NULL;
2454 }
2455
2456 static void
2457 osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v)
2458 {
2459 //dbg(0,"EEnter\n");
2460
2461 struct point p, p2[4];
2462 char *str,*last,*next,*value,*absbegin;
2463 char *id_string=NULL;
2464 int do_draw = 0;
2465 struct attr attr, vehicle_attr, maxspeed_attr, imperial_attr;
2466 struct navigation *nav = NULL;
2467 struct tracking *tracking = NULL;
2468 struct route *route = NULL;
2469 struct map *nav_map = NULL;
2470 struct map_rect *nav_mr = NULL;
2471 struct item *item;
2472 struct osd_text_item *oti;
2473 int offset,lines;
2474 int height=this->osd_item.font_size*13/256;
2475 int yspacing=height/2;
2476 int xspacing=height/4;
2477 int imperial=0;
2478
2479 if (navit_get_attr(navit, attr_imperial, &imperial_attr, NULL))
2480 imperial=imperial_attr.u.num;
2481
2482 vehicle_attr.u.vehicle=NULL;
2483 oti=this->items;
2484 str=NULL;
2485
2486 while (oti)
2487 {
2488
2489 item=NULL;
2490 value=NULL;
2491 id_string=NULL;
2492
2493 if (oti->static_text) {
2494 value=g_strdup(oti->text);
2495 id_string=g_strdup_printf("none:static_text:static_text");
2496 } else if (oti->section == attr_navigation) {
2497 if (navit && !nav)
2498 nav = navit_get_navigation(navit);
2499 if (nav && !nav_map)
2500 nav_map = navigation_get_map(nav);
2501 if (nav_map )
2502 nav_mr = map_rect_new(nav_map, NULL);
2503 if (nav_mr)
2504 item = map_rect_get_item(nav_mr);
2505
2506 offset=oti->offset;
2507 while (item) {
2508 if (item->type == type_nav_none)
2509 item=map_rect_get_item(nav_mr);
2510 else if (!offset)
2511 break;
2512 else {
2513 offset--;
2514 item=map_rect_get_item(nav_mr);
2515 }
2516 }
2517
2518 if (item) {
2519 //dbg(0,"name %s\n", item_to_name(item->type));
2520 //dbg(0,"type %s\n", attr_to_name(oti->attr_typ));
2521 if (item_attr_get(item, oti->attr_typ, &attr))
2522 value=osd_text_format_attr(&attr, oti->format, imperial);
2523 id_string=g_strdup_printf("navigation:%s:%s",item_to_name(item->type),attr_to_name(oti->attr_typ));
2524 }
2525 if (nav_mr)
2526 map_rect_destroy(nav_mr);
2527 } else if (oti->section == attr_vehicle) {
2528 if (navit && !vehicle_attr.u.vehicle) {
2529 navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL);
2530 }
2531 if (vehicle_attr.u.vehicle) {
2532 if (vehicle_get_attr(vehicle_attr.u.vehicle, oti->attr_typ, &attr, NULL)) {
2533 value=osd_text_format_attr(&attr, oti->format, imperial);
2534 }
2535 }
2536 } else if (oti->section == attr_tracking) {
2537 if (navit) {
2538 tracking = navit_get_tracking(navit);
2539 route = navit_get_route(navit);
2540 }
2541 if (tracking) {
2542 item=tracking_get_current_item(tracking);
2543 if (item && (oti->attr_typ == attr_speed)) {
2544 double routespeed = -1;
2545 int *flags=tracking_get_current_flags(tracking);
2546 if (flags && (*flags & AF_SPEED_LIMIT) && tracking_get_attr(tracking, attr_maxspeed, &maxspeed_attr, NULL)) {
2547 routespeed = maxspeed_attr.u.num;
2548 }
2549 if (routespeed == -1) {
2550 struct vehicleprofile *prof=navit_get_vehicleprofile(navit);
2551 struct roadprofile *rprof=NULL;
2552 if (prof)
2553 rprof=vehicleprofile_get_roadprofile(prof, item->type);
2554 if (rprof) {
2555 routespeed=rprof->speed;
2556 }
2557 }
2558
2559 value = format_speed(routespeed,"", oti->format, imperial);
2560 } else if (item) {
2561 if (tracking_get_attr(tracking, oti->attr_typ, &attr, NULL))
2562 value=osd_text_format_attr(&attr, oti->format, imperial);
2563 }
2564 }
2565
2566 } else if (oti->section == attr_navit) {
2567 if (oti->attr_typ == attr_message) {
2568 struct message *msg;
2569 int len,offset;
2570 char *tmp;
2571
2572 msg = navit_get_messages(navit);
2573 len = 0;
2574 while (msg) {
2575 len+= strlen(msg->text) + 2;
2576
2577 msg = msg->next;
2578 }
2579
2580 value = g_malloc(len +1);
2581
2582 msg = navit_get_messages(navit);
2583 offset = 0;
2584 while (msg) {
2585 tmp = g_stpcpy((value+offset), msg->text);
2586 g_stpcpy(tmp, "\\n");
2587 offset += strlen(msg->text) + 2;
2588
2589 msg = msg->next;
2590 }
2591
2592 value[len] = '\0';
2593 }
2594 }
2595
2596
2597
2598 // id_string=g_strdup_printf("%s#+#%s:%s",id_string, str ? str:"",value ? value:" ");
2599 graphics_send_osd_values(this->osd_item.gr, this->osd_item.graphic_fg_text,"osd_text_draw","draw_text",id_string,value ? value : "", 0,0,0,0, 0.0,0.0,0.0);
2600 //dbg(0,"%s\n",id_string);
2601 if (id_string)
2602 g_free(id_string);
2603
2604
2605
2606 next=g_strdup_printf("%s%s",str ? str:"",value ? value:" ");
2607 if (value)
2608 g_free(value);
2609 if (str)
2610 g_free(str);
2611 str=next;
2612 oti=oti->next;
2613 }
2614
2615 if ( this->last && str && !strcmp(this->last, str) ) {
2616 do_draw=0;
2617 } else {
2618 do_draw=1;
2619 if (this->last)
2620 g_free(this->last);
2621 this->last = g_strdup(str);
2622 }
2623
2624 absbegin=str;
2625 if (do_draw) {
2626 // **DISABLE** osd_std_draw(&this->osd_item);
2627 }
2628 if (do_draw && str)
2629 {
2630 lines=0;
2631 next=str;
2632 last=str;
2633 while ((next=strstr(next, "\\n"))) {
2634 last = next;
2635 lines++;
2636 next++;
2637 }
2638
2639 while (*last) {
2640 if (! g_ascii_isspace(*last)) {
2641 lines++;
2642 break;
2643 }
2644 last++;
2645 }
2646
2647 dbg(1,"this->align=%d\n", this->align);
2648 switch (this->align & 51) {
2649 case 1:
2650 p.y=0;
2651 break;
2652 case 2:
2653 p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing);
2654 break;
2655 case 16: // Grow from top to bottom
2656 p.y = 0;
2657 if (lines != 0) {
2658 this->osd_item.h = (lines-1) * (height+yspacing) + height;
2659 } else {
2660 this->osd_item.h = 0;
2661 }
2662
2663 if (do_draw) {
2664 osd_std_resize(&this->osd_item);
2665 }
2666 default:
2667 p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing)/2;
2668 }
2669
2670 while (str)
2671 {
2672 next=strstr(str, "\\n");
2673 if (next) {
2674 *next='\0';
2675 next+=2;
2676 }
2677 graphics_get_text_bbox(this->osd_item.gr,
2678 this->osd_item.font,
2679 str, 0x10000,
2680 0x0, p2, 0);
2681 switch (this->align & 12) {
2682 case 4:
2683 p.x=xspacing;
2684 break;
2685 case 8:
2686 p.x=this->osd_item.w-(p2[2].x-p2[0].x)-xspacing;
2687 break;
2688 default:
2689 p.x = ((p2[0].x - p2[2].x) / 2) + (this->osd_item.w / 2);
2690 }
2691 p.y += height+yspacing;
2692
2693 // graphics_send_osd_values(this->osd_item.gr, this->osd_item.graphic_fg_text,"osd_text_draw","draw_text",str,"", 0,0,0,0, 0.0,0.0,0.0);
2694
2695 // **DISABLE**
2696 /*
2697 graphics_draw_text(this->osd_item.gr,
2698 this->osd_item.graphic_fg_text,
2699 NULL, this->osd_item.font,
2700 str, &p, 0x10000,
2701 0);
2702 */
2703 str=next;
2704 }
2705 }
2706 if(do_draw) {
2707 // **DISABLE** graphics_draw_mode(this->osd_item.gr, draw_mode_end);
2708 }
2709 g_free(absbegin);
2710
2711 }
2712
2713 /**
2714 * @brief Create a new osd_text_item and insert it into a linked list
2715 *
2716 * @param parent Pointer to the preceding osd_text_item structure in the list. If NULL, the new osd_text_item becomes the root element of a new list.
2717 * @returns A pointer to the new osd_text_item element.
2718 */
2719 static struct osd_text_item *
2720 oti_new(struct osd_text_item * parent)
2721 {
2722 //dbg(0,"EEnter\n");
2723
2724 struct osd_text_item *this;
2725 this=g_new0(struct osd_text_item, 1);
2726 this->prev=parent;
2727
2728 if(!parent) {
2729 this->root=this;
2730 } else {
2731 parent->next=this;
2732 this->root=parent->root;
2733 }
2734
2735 return this;
2736 }
2737
2738 /**
2739 * @brief Prepare a text type OSD element
2740 *
2741 * Parses the label string (as specified in the XML file) for a text type OSD element into attributes and static text.
2742 *
2743 * @param this Pointer to an osd_text structure representing the OSD element. The items member of this structure will receive a pointer to a list of osd_text_item structures.
2744 * @param nav Pointer to a navit structure
2745 * @returns nothing
2746 */
2747 static void
2748 osd_text_prepare(struct osd_text *this, struct navit *nav)
2749 {
2750 //dbg(0,"EEnter\n");
2751
2752 char *absbegin,*str,*start,*end,*key,*subkey,*index;
2753 struct osd_text_item *oti;
2754
2755 oti=NULL;
2756 str=g_strdup(this->text);
2757 absbegin=str;
2758
2759 while ((start=strstr(str, "${"))) {
2760
2761 *start='\0';
2762 start+=2;
2763
2764 // find plain text before
2765 if (start!=str) {
2766 oti = oti_new(oti);
2767 oti->static_text=1;
2768 oti->text=g_strdup(str);
2769
2770 }
2771
2772 end=strstr(start,"}");
2773 if (! end)
2774 break;
2775
2776 *end++='\0';
2777 key=start;
2778
2779 subkey=osd_text_split(key,NULL);
2780
2781 oti = oti_new(oti);
2782 oti->section=attr_from_name(key);
2783
2784 if (( oti->section == attr_navigation ||
2785 oti->section == attr_tracking) && subkey) {
2786 key=osd_text_split(subkey,&index);
2787
2788 if (index)
2789 oti->offset=atoi(index);
2790
2791 subkey=osd_text_split(key,&index);
2792
2793 if (!strcmp(key,"route_speed")) {
2794 oti->attr_typ=attr_speed;
2795 } else {
2796 oti->attr_typ=attr_from_name(key);
2797 }
2798 oti->format = g_strdup(index);
2799
2800 } else if ((oti->section == attr_vehicle || oti->section == attr_navit) && subkey) {
2801 key=osd_text_split(subkey,&index);
2802 if (!strcmp(subkey,"messages")) {
2803 oti->attr_typ=attr_message;
2804 } else {
2805 oti->attr_typ=attr_from_name(subkey);
2806 }
2807 oti->format = g_strdup(index);
2808 }
2809
2810 switch(oti->attr_typ) {
2811 default:
2812 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_draw), attr_position_coord_geo, this));
2813 break;
2814 }
2815
2816 str=(end);
2817 }
2818
2819 if(*str!='\0'){
2820 oti = oti_new(oti);
2821 oti->static_text=1;
2822 oti->text=g_strdup(str);
2823 }
2824
2825 if (oti)
2826 this->items=oti->root;
2827 else
2828 this->items=NULL;
2829
2830 g_free(absbegin);
2831
2832 }
2833
2834 static void
2835 osd_text_init(struct osd_text *this, struct navit *nav)
2836 {
2837 //dbg(0,"EEnter\n");
2838
2839 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
2840 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->osd_item));
2841 osd_text_prepare(this,nav);
2842 osd_text_draw(this, nav, NULL);
2843
2844 }
2845
2846 static struct osd_priv *
2847 osd_text_new(struct navit *nav, struct osd_methods *meth,
2848 struct attr **attrs)
2849 {
2850 //dbg(0,"EEnter\n");
2851
2852 struct osd_text *this = g_new0(struct osd_text, 1);
2853 struct attr *attr;
2854
2855 this->osd_item.p.x = -80;
2856 this->osd_item.p.y = 20;
2857 this->osd_item.w = 60;
2858 this->osd_item.h = 20;
2859 this->osd_item.navit = nav;
2860 this->osd_item.font_size = 200;
2861 this->osd_item.meth.draw = osd_draw_cast(osd_text_draw);
2862 osd_set_std_attr(attrs, &this->osd_item, 2);
2863
2864 this->active = -1;
2865 this->last = NULL;
2866
2867 attr = attr_search(attrs, NULL, attr_label);
2868 if (attr)
2869 this->text = g_strdup(attr->u.str);
2870 else
2871 this->text = NULL;
2872 attr = attr_search(attrs, NULL, attr_align);
2873 if (attr)
2874 this->align=attr->u.num;
2875
2876 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_init), attr_graphics_ready, this));
2877 return (struct osd_priv *) this;
2878 }
2879
2880 struct gps_status {
2881 struct osd_item osd_item;
2882 char *icon_src;
2883 int icon_h, icon_w, active;
2884 int strength;
2885 };
2886
2887 static void
2888 osd_gps_status_draw(struct gps_status *this, struct navit *navit,
2889 struct vehicle *v)
2890 {
2891 struct point p;
2892 int do_draw = 0;
2893 struct graphics_image *gr_image;
2894 char *image;
2895 struct attr attr, vehicle_attr;
2896 int strength=-1;
2897
2898 if (navit && navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL)) {
2899 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_position_fix_type, &attr, NULL)) {
2900 switch(attr.u.num) {
2901 case 1:
2902 case 2:
2903 strength=2;
2904 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_position_sats_used, &attr, NULL)) {
2905 dbg(1,"num=%d\n", attr.u.num);
2906 if (attr.u.num >= 3)
2907 strength=attr.u.num-1;
2908 if (strength > 5)
2909 strength=5;
2910 if (strength > 3) {
2911 if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_position_hdop, &attr, NULL)) {
2912 if (*attr.u.numd > 2.0 && strength > 4)
2913 strength=4;
2914 if (*attr.u.numd > 4.0 && strength > 3)
2915 strength=3;
2916 }
2917 }
2918 }
2919 break;
2920 default:
2921 strength=1;
2922 }
2923 }
2924 }
2925 if (this->strength != strength) {
2926 this->strength=strength;
2927 do_draw=1;
2928 }
2929 if (do_draw) {
2930 osd_std_draw(&this->osd_item);
2931 if (this->active) {
2932 image = g_strdup_printf(this->icon_src, strength);
2933 gr_image = graphics_image_new_scaled(this->osd_item.gr, image, this->icon_w, this->icon_h);
2934 if (gr_image) {
2935 p.x = (this->osd_item.w - gr_image->width) / 2;
2936 p.y = (this->osd_item.h - gr_image->height) / 2;
2937 graphics_draw_image(this->osd_item.gr, this->osd_item. graphic_fg_white, &p, gr_image);
2938 graphics_image_free(this->osd_item.gr, gr_image);
2939 }
2940 g_free(image);
2941 }
2942 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
2943 }
2944 }
2945
2946 static void
2947 osd_gps_status_init(struct gps_status *this, struct navit *nav)
2948 {
2949 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
2950 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_gps_status_draw), attr_position_coord_geo, this));
2951 osd_gps_status_draw(this, nav, NULL);
2952 }
2953
2954 static struct osd_priv *
2955 osd_gps_status_new(struct navit *nav, struct osd_methods *meth,
2956 struct attr **attrs)
2957 {
2958 struct gps_status *this = g_new0(struct gps_status, 1);
2959 struct attr *attr;
2960
2961 this->osd_item.p.x = 20;
2962 this->osd_item.p.y = -80;
2963 this->osd_item.w = 60;
2964 this->osd_item.navit = nav;
2965 this->osd_item.h = 40;
2966 this->osd_item.font_size = 200;
2967 this->osd_item.meth.draw = osd_draw_cast(osd_gps_status_draw);
2968 osd_set_std_attr(attrs, &this->osd_item, 0);
2969
2970 this->icon_w = -1;
2971 this->icon_h = -1;
2972 this->active = -1;
2973 this->strength = -2;
2974
2975 attr = attr_search(attrs, NULL, attr_icon_w);
2976 if (attr)
2977 this->icon_w = attr->u.num;
2978
2979 attr = attr_search(attrs, NULL, attr_icon_h);
2980 if (attr)
2981 this->icon_h = attr->u.num;
2982
2983 attr = attr_search(attrs, NULL, attr_icon_src);
2984 if (attr) {
2985 struct file_wordexp *we;
2986 char **array;
2987 we = file_wordexp_new(attr->u.str);
2988 array = file_wordexp_get_array(we);
2989 this->icon_src = g_strdup(array[0]);
2990 file_wordexp_destroy(we);
2991 } else
2992 this->icon_src = graphics_icon_path("gui_strength_%d_32_32.png");
2993
2994 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_gps_status_init), attr_graphics_ready, this));
2995 return (struct osd_priv *) this;
2996 }
2997
2998
2999 struct volume {
3000 struct osd_item osd_item;
3001 char *icon_src;
3002 int icon_h, icon_w, active;
3003 int strength;
3004 struct callback *click_cb;
3005 };
3006
3007 static void
3008 osd_volume_draw(struct volume *this, struct navit *navit)
3009 {
3010 struct point p;
3011 struct graphics_image *gr_image;
3012 char *image;
3013
3014 osd_std_draw(&this->osd_item);
3015 if (this->active) {
3016 image = g_strdup_printf(this->icon_src, this->strength);
3017 gr_image = graphics_image_new_scaled(this->osd_item.gr, image, this->icon_w, this->icon_h);
3018 if (gr_image) {
3019 p.x = (this->osd_item.w - gr_image->width) / 2;
3020 p.y = (this->osd_item.h - gr_image->height) / 2;
3021 graphics_draw_image(this->osd_item.gr, this->osd_item. graphic_fg_white, &p, gr_image);
3022 graphics_image_free(this->osd_item.gr, gr_image);
3023 }
3024 g_free(image);
3025 }
3026 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
3027 }
3028
3029 static void
3030 osd_volume_click(struct volume *this, struct navit *nav, int pressed, int button, struct point *p)
3031 {
3032 struct point bp = this->osd_item.p;
3033 osd_wrap_point(&bp, nav);
3034 if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->osd_item.w || p->y > bp.y + this->osd_item.h) && !this->osd_item.pressed)
3035 return;
3036 navit_ignore_button(nav);
3037 if (pressed) {
3038 if (p->y - bp.y < this->osd_item.h/2)
3039 this->strength++;
3040 else
3041 this->strength--;
3042 if (this->strength < 0)
3043 this->strength=0;
3044 if (this->strength > 5)
3045 this->strength=5;
3046 osd_volume_draw(this, nav);
3047 }
3048 }
3049 static void
3050 osd_volume_init(struct volume *this, struct navit *nav)
3051 {
3052 osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
3053 navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_volume_click), attr_button, this));
3054 osd_volume_draw(this, nav);
3055 }
3056
3057 static struct osd_priv *
3058 osd_volume_new(struct navit *nav, struct osd_methods *meth,
3059 struct attr **attrs)
3060 {
3061 struct volume *this = g_new0(struct volume, 1);
3062 struct attr *attr;
3063
3064 this->osd_item.p.x = 20;
3065 this->osd_item.p.y = -80;
3066 this->osd_item.w = 60;
3067 this->osd_item.navit = nav;
3068 this->osd_item.h = 40;
3069 this->osd_item.font_size = 200;
3070 this->osd_item.meth.draw = osd_draw_cast(osd_volume_draw);
3071 osd_set_std_attr(attrs, &this->osd_item, 0);
3072
3073 this->icon_w = -1;
3074 this->icon_h = -1;
3075 this->active = -1;
3076 this->strength = -1;
3077
3078 attr = attr_search(attrs, NULL, attr_icon_w);
3079 if (attr)
3080 this->icon_w = attr->u.num;
3081
3082 attr = attr_search(attrs, NULL, attr_icon_h);
3083 if (attr)
3084 this->icon_h = attr->u.num;
3085
3086 attr = attr_search(attrs, NULL, attr_icon_src);
3087 if (attr) {
3088 struct file_wordexp *we;
3089 char **array;
3090 we = file_wordexp_new(attr->u.str);
3091 array = file_wordexp_get_array(we);
3092 this->icon_src = g_strdup(array[0]);
3093 file_wordexp_destroy(we);
3094 } else
3095 this->icon_src = graphics_icon_path("gui_strength_%d_32_32.png");
3096
3097 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_volume_init), attr_graphics_ready, this));
3098 return (struct osd_priv *) this;
3099 }
3100
3101 struct osd_scale {
3102 int use_overlay;
3103 struct osd_item item;
3104 struct callback *draw_cb,*navit_init_cb;
3105 struct graphics_gc *black;
3106 };
3107
3108 static void
3109 osd_scale_draw(struct osd_scale *this, struct navit *nav)
3110 {
3111 //dbg(0,"EEnter\n");
3112
3113 struct point bp,bp1,bp2;
3114 struct point p[10],bbox[4];
3115 struct coord c[2];
3116 struct attr transformation, imperial_attr;
3117 int len;
3118 double dist,exp,base,man;
3119 char *text;
3120 int w=this->item.w*9/10;
3121 int o=(this->item.w-w)/2;
3122 int imperial=0;
3123
3124 if (navit_get_attr(nav, attr_imperial, &imperial_attr, NULL))
3125 imperial=imperial_attr.u.num;
3126
3127 if (!navit_get_attr(nav, attr_transformation, &transformation, NULL))
3128 return;
3129 if (this->use_overlay)
3130 {
3131 // **DISABLE** graphics_draw_mode(this->item.gr, draw_mode_begin);
3132 bp.x=0;
3133 bp.y=0;
3134
3135 graphics_send_osd_values(this->item.gr, this->item.graphic_bg,"scale","draw_rectangle1","","",this->item.w, this->item.h,0,0,0.0,0.0,0.0);
3136 // **DISABLE** graphics_draw_rectangle(this->item.gr, this->item.graphic_bg, &bp, this->item.w, this->item.h);
3137 } else {
3138 bp=this->item.p;
3139 osd_wrap_point(&bp, nav);
3140 }
3141 bp1=bp;
3142 bp1.y+=this->item.h/2;
3143 bp1.x+=o;
3144 bp2=bp1;
3145 bp2.x+=w;
3146 p[0]=bp1;
3147 p[1]=bp2;
3148 transform_reverse(transformation.u.transformation, &p[0], &c[0]);
3149 transform_reverse(transformation.u.transformation, &p[1], &c[1]);
3150 dist=transform_distance(transform_get_projection(transformation.u.transformation), &c[0], &c[1]);
3151 exp=floor(log10(dist));
3152 base=pow(10,exp);
3153 man=dist/base;
3154 if (man >= 5)
3155 man=5;
3156 else if (man >= 2)
3157 man=2;
3158 else
3159 man=1;
3160 len=this->item.w-man*base/dist*w;
3161 p[0].x+=len/2;
3162 p[1].x-=len/2;
3163 p[2]=p[0];
3164 p[3]=p[0];
3165 p[2].y-=this->item.h/10;
3166 p[3].y+=this->item.h/10;
3167 p[4]=p[1];
3168 p[5]=p[1];
3169 p[4].y-=this->item.h/10;
3170 p[5].y+=this->item.h/10;
3171 p[6]=p[2];
3172 p[6].x-=2;
3173 p[6].y-=2;
3174 p[7]=p[0];
3175 p[7].y-=2;
3176 p[8]=p[4];
3177 p[8].x-=2;
3178 p[8].y-=2;
3179
3180 graphics_send_osd_values(this->item.gr, this->item.graphic_fg_white,"scale","draw_rectangle2","","",len,this->item.h,0,0,0.0,0.0,0.0);
3181
3182 // **DISABLE** graphics_draw_rectangle(this->item.gr, this->item.graphic_fg_white, p+6, 4,this->item.h/5+4);
3183 // **DISABLE** graphics_draw_rectangle(this->item.gr, this->item.graphic_fg_white, p+7, p[1].x-p[0].x, 4);
3184 // **DISABLE** graphics_draw_rectangle(this->item.gr, this->item.graphic_fg_white, p+8, 4,this->item.h/5+4);
3185 // **DISABLE** graphics_draw_lines(this->item.gr, this->black, p, 2);
3186 // **DISABLE** graphics_draw_lines(this->item.gr, this->black, p+2, 2);
3187 // **DISABLE** graphics_draw_lines(this->item.gr, this->black, p+4, 2);
3188 text=format_distance(man*base, "", imperial);
3189 graphics_get_text_bbox(this->item.gr, this->item.font, text, 0x10000, 0, bbox, 0);
3190 p[0].x=(this->item.w-bbox[2].x)/2+bp.x;
3191 p[0].y=bp.y+this->item.h-this->item.h/10;
3192
3193 graphics_send_osd_values(this->item.gr, this->item.graphic_fg_white,"scale","draw_text",text,"",0,0,0,0,0.0,0.0,0.0);
3194
3195 // **DISABLE** graphics_draw_text(this->item.gr, this->black, this->item.graphic_fg_white, this->item.font, text, &p[0], 0x10000, 0);
3196 g_free(text);
3197 if (this->use_overlay)
3198 {
3199 // **DISABLE** graphics_draw_mode(this->item.gr, draw_mode_end);
3200 }
3201 }
3202
3203 static void
3204 osd_scale_init(struct osd_scale *this, struct navit *nav)
3205 {
3206 struct color color_white={0xffff,0xffff,0xffff,0x0000};
3207 struct color color_black={0x0000,0x0000,0x0000,0x0000};
3208 struct graphics *gra = navit_get_graphics(nav);
3209 dbg(1, "enter\n");
3210 if (this->use_overlay) {
3211 osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
3212 } else {
3213 this->item.configured=1;
3214 this->item.gr=gra;
3215 this->item.font = graphics_font_new(this->item.gr, this->item.font_size, 1);
3216 this->item.graphic_fg_white=graphics_gc_new(this->item.gr);
3217 this->item.color_white=color_white;
3218 graphics_gc_set_foreground(this->item.graphic_fg_white, &this->item.color_white);
3219 }
3220 this->black=graphics_gc_new(this->item.gr);
3221 graphics_gc_set_foreground(this->black, &color_black);
3222 graphics_add_callback(gra, this->draw_cb=callback_new_attr_2(callback_cast(osd_scale_draw), attr_postdraw, this, nav));
3223 if (navit_get_ready(nav) == 3)
3224 osd_scale_draw(this, nav);
3225 }
3226
3227 static struct osd_priv *
3228 osd_scale_new(struct navit *nav, struct osd_methods *meth,
3229 struct attr **attrs)
3230 {
3231 struct osd_scale *this = g_new0(struct osd_scale, 1);
3232 struct attr *attr;
3233
3234 this->item.navit = nav;
3235 this->item.meth.draw = osd_draw_cast(osd_scale_draw);
3236
3237 osd_set_std_attr(attrs, &this->item, 3);
3238
3239 attr=attr_search(attrs, NULL, attr_use_overlay);
3240 if (attr)
3241 this->use_overlay=attr->u.num;
3242
3243 navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast (osd_scale_init), attr_graphics_ready, this));
3244
3245 return (struct osd_priv *) this;
3246 }
3247
3248 struct auxmap {
3249 struct osd_item osd_item;
3250 struct displaylist *displaylist;
3251 struct transformation *ntrans;
3252 struct transformation *trans;
3253 struct layout *layout;
3254 struct callback *postdraw_cb;
3255 struct graphics_gc *red;
3256 struct navit *nav;
3257 };
3258
3259 static void
3260 osd_auxmap_draw(struct auxmap *this)
3261 {
3262 int d=10;
3263 struct point p;
3264 struct attr mapset;
3265
3266 if (!this->osd_item.configured)
3267 return;
3268 if (!navit_get_attr(this->nav, attr_mapset, &mapset, NULL) || !mapset.u.mapset)
3269 return;
3270 p.x=this->osd_item.w/2;
3271 p.y=this->osd_item.h/2;
3272 transform_set_center(this->trans, transform_get_center(this->ntrans));
3273 transform_set_scale(this->trans, 64);
3274 transform_set_yaw(this->trans, transform_get_yaw(this->ntrans));
3275 transform_setup_source_rect(this->trans);
3276 transform_set_projection(this->trans, transform_get_projection(this->ntrans));
3277 #if 0
3278 graphics_displaylist_draw(this->osd_item.gr, this->displaylist, this->trans, this->layout, 4);
3279 #endif
3280 graphics_draw(this->osd_item.gr, this->displaylist, mapset.u.mapset, this->trans, this->layout, 0, NULL, 1);
3281 graphics_draw_circle(this->osd_item.gr, this->red, &p, d);
3282 graphics_draw_mode(this->osd_item.gr, draw_mode_end);
3283
3284 }
3285
3286 static void
3287 osd_auxmap_init(struct auxmap *this, struct navit *nav)
3288 {
3289 struct graphics *gra;
3290 struct attr attr;
3291 struct map_selection sel;
3292 struct color red={0xffff,0x0,0x0,0xffff};
3293
3294 this->nav=nav;
3295 if (! navit_get_attr(nav, attr_graphics, &attr, NULL))
3296 return;
3297 gra=attr.u.graphics;
3298 graphics_add_callback(gra, callback_new_attr_1(callback_cast(osd_auxmap_draw), attr_postdraw, this));
3299 if (! navit_get_attr(nav, attr_transformation, &attr, NULL))
3300 return;
3301 this->ntrans=attr.u.transformation;
3302 if (! navit_get_attr(nav, attr_displaylist, &attr, NULL))
3303 return;
3304 this->displaylist=attr.u.displaylist;
3305 if (! navit_get_attr(nav, attr_layout, &attr, NULL))
3306 return;
3307 this->layout=attr.u.layout;
3308 osd_set_std_graphic(nav, &this->osd_item, NULL);
3309 graphics_init(this->osd_item.gr);
3310 this->red=graphics_gc_new(gra);
3311 graphics_gc_set_foreground(this->red,&red);
3312 graphics_gc_set_linewidth(this->red,3);
3313 this->trans=transform_new();
3314 memset(&sel, 0, sizeof(sel));
3315 sel.u.p_rect.rl.x=this->osd_item.w;
3316 sel.u.p_rect.rl.y=this->osd_item.h;
3317 transform_set_screen_selection(this->trans, &sel);
3318 graphics_set_rect(this->osd_item.gr, &sel.u.p_rect);
3319 #if 0
3320 osd_auxmap_draw(this, nav);
3321 #endif
3322 }
3323
3324 static struct osd_priv *
3325 osd_auxmap_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
3326 {
3327 struct auxmap *this = g_new0(struct auxmap, 1);
3328
3329 this->osd_item.p.x = 20;
3330 this->osd_item.p.y = -80;
3331 this->osd_item.w = 60;
3332 this->osd_item.h = 40;
3333 this->osd_item.font_size = 200;
3334 osd_set_std_attr(attrs, &this->osd_item, 0);
3335
3336 navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_auxmap_init), attr_navit, this));
3337 return (struct osd_priv *) this;
3338 }
3339
3340
3341 void
3342 plugin_init(void)
3343 {
3344 plugin_register_osd_type("compass", osd_compass_new);
3345 plugin_register_osd_type("navigation_next_turn", osd_nav_next_turn_new);
3346 plugin_register_osd_type("button", osd_button_new);
3347 plugin_register_osd_type("toggle_announcer", osd_nav_toggle_announcer_new);
3348 plugin_register_osd_type("speed_warner", osd_speed_warner_new);
3349 plugin_register_osd_type("speed_cam", osd_speed_cam_new);
3350 plugin_register_osd_type("text", osd_text_new);
3351 plugin_register_osd_type("gps_status", osd_gps_status_new);
3352 plugin_register_osd_type("volume", osd_volume_new);
3353 plugin_register_osd_type("scale", osd_scale_new);
3354 plugin_register_osd_type("image", osd_image_new);
3355 plugin_register_osd_type("stopwatch", osd_stopwatch_new);
3356 plugin_register_osd_type("odometer", osd_odometer_new);
3357 plugin_register_osd_type("auxmap", osd_auxmap_new);
3358 plugin_register_osd_type("cmd_interface", osd_cmd_interface_new);
3359 }

   
Visit the ZANavi Wiki