Patch:Various:Added openmoko patches from carcinoma
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Tue, 16 Dec 2008 21:06:05 +0000 (21:06 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Tue, 16 Dec 2008 21:06:05 +0000 (21:06 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@1816 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/attr_def.h
navit/gui/internal/gui_internal.c
navit/navit.c
navit/osd/core/osd_core.c
navit/vehicle/gpsd/vehicle_gpsd.c

index f6ac322..8b27f30 100644 (file)
@@ -87,6 +87,7 @@ ATTR(position_fix_type)
 ATTR(timeout)
 ATTR(orientation)
 ATTR(keyboard)
+ATTR(position_sats_signal)
 ATTR2(0x00028000,type_boolean_begin)
 /* boolean */
 ATTR(overwrite)
index 58424d4..6c319ce 100644 (file)
@@ -246,7 +246,9 @@ struct gui_priv {
         */
         struct gui_config_settings config;
        struct event_idle *idle;
-       struct callback *motion_cb,*button_cb,*resize_cb,*keypress_cb,*idle_cb;
+       struct callback *motion_cb,*button_cb,*resize_cb,*keypress_cb,*idle_cb, *motion_timeout_callback;
+       struct event_timeout *motion_timeout_event;
+       struct point current;
 };
 
 
@@ -692,9 +694,15 @@ gui_internal_find_widget(struct widget *wi, struct point *p, int flags)
        struct widget *ret,*child;
        GList *l=wi->children;
 
-
-       if (p && (wi->p.x > p->x || wi->p.y > p->y || wi->p.x + wi->w < p->x || wi->p.y + wi->h < p->y)) {
-               return NULL;
+       if (p) { 
+               if (wi->p.x > p->x )
+                       return NULL;
+               if (wi->p.y > p->y )
+                       return NULL;
+               if ( wi->p.x + wi->w < p->x) 
+                       return NULL;
+               if ( wi->p.y + wi->h < p->y) 
+                       return NULL;
        }
        if (wi->state & flags) 
                return wi;
@@ -715,6 +723,8 @@ gui_internal_highlight_do(struct gui_priv *this, struct widget *found)
 {
        if (found == this->highlighted)
                return;
+       
+       graphics_draw_mode(this->gra, draw_mode_begin);
        if (this->highlighted) {
                this->highlighted->state &= ~STATE_HIGHLIGHTED;
                if (this->root.children && this->highlighted_menu == g_list_last(this->root.children)->data) 
@@ -728,22 +738,23 @@ gui_internal_highlight_do(struct gui_priv *this, struct widget *found)
                this->highlighted->state |= STATE_HIGHLIGHTED;
                gui_internal_widget_render(this, this->highlighted);
                dbg(1,"%d,%d %dx%d\n", found->p.x, found->p.y, found->w, found->h);
-       }
+       }       
+       graphics_draw_mode(this->gra, draw_mode_end);
 }
 //##############################################################################################################
 //# Description: 
 //# Comment: 
 //# Authors: Martin Schaller (04/2008)
 //##############################################################################################################
-static void gui_internal_highlight(struct gui_priv *this, struct point *p)
+static void gui_internal_highlight(struct gui_priv *this)
 {
        struct widget *menu,*found=NULL;
-
-       if (p) {
+       if (this->current.x > -1 && this->current.y > -1) {
                menu=g_list_last(this->root.children)->data;
-               found=gui_internal_find_widget(menu, p, STATE_SENSITIVE);
+               found=gui_internal_find_widget(menu, &this->current, STATE_SENSITIVE);
        }
        gui_internal_highlight_do(this, found);
+       this->motion_timeout_event=NULL;
 }
 
 static struct widget *
@@ -795,10 +806,21 @@ static void gui_internal_box_render(struct gui_priv *this, struct widget *w)
 static void gui_internal_box_pack(struct gui_priv *this, struct widget *w)
 {
        struct widget *wc;
-       int x0,x=0,y=0,width=0,height=0,owidth=0,oheight=0,expand=0,count=0,rows=0,cols=w->cols ? w->cols : 3;
+       int x0,x=0,y=0,width=0,height=0,owidth=0,oheight=0,expand=0,count=0,rows=0,cols=w->cols ? w->cols : 0;
        GList *l;
        int orientation=w->flags & 0xffff0000;
 
+       if (!cols) {
+                height=navit_get_height(this->nav);
+                width=navit_get_width(this->nav);
+                if ( (height/width) > 1.0 )
+                        cols=3;
+                else
+                        cols=2;
+                width=0;
+                height=0;
+       }
+
        
        l=w->children;
        while (l) {
@@ -985,7 +1007,8 @@ static void gui_internal_box_pack(struct gui_priv *this, struct widget *w)
        }
 }
 
-static void gui_internal_widget_append(struct widget *parent, struct widget *child)
+static void
+gui_internal_widget_append(struct widget *parent, struct widget *child)
 {
        if (! child->background)
                child->background=parent->background;
@@ -1029,6 +1052,9 @@ static void gui_internal_widget_destroy(struct gui_priv *this, struct widget *w)
 static void
 gui_internal_widget_render(struct gui_priv *this, struct widget *w)
 {
+       if(w->p.x > navit_get_width(this->nav) || w->p.y > navit_get_height(this->nav))
+               return;
+
        switch (w->type) {
        case widget_box:
                gui_internal_box_render(this, w);
@@ -1146,7 +1172,7 @@ gui_internal_top_bar(struct gui_priv *this)
        struct widget *w,*wm,*wh,*wc,*wcn;
        int dots_len, sep_len;
        GList *res=NULL,*l;
-       int width,width_used=0,use_sep,incomplete=0;
+       int width,width_used=0,use_sep=0,incomplete=0;
 
        w=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
        w->bl=this->spacing;
@@ -1527,9 +1553,10 @@ gui_internal_cmd_pois_selector(struct gui_priv *this, struct pcoord *c)
        wl=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
        for (i = 0 ; i < sizeof(selectors)/sizeof(struct selector) ; i++) {
        gui_internal_widget_append(wl, wb=gui_internal_button_new_with_callback(this, NULL,
-               image_new_xs(this, selectors[i].icon), gravity_center|orientation_vertical,
+               image_new_xs(this, selectors[i].icon), gravity_left_center|orientation_vertical,
                gui_internal_cmd_pois, &selectors[i]));
                wb->c=*c;
+               wb->bt=10;
        }
        return wl;
 }
@@ -1542,22 +1569,22 @@ gui_internal_cmd_pois_item(struct gui_priv *this, struct coord *center, struct i
        char *type;
        struct attr attr;
        struct widget *wl;
+       char *text;
 
        wl=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
 
        sprintf(distbuf,"%d", dist/1000);
-       gui_internal_widget_append(wl, gui_internal_label_new(this, distbuf));
        get_direction(dirbuf, transform_get_angle_delta(center, c, 0), 1);
-       gui_internal_widget_append(wl, gui_internal_label_new(this, dirbuf));
        type=item_to_name(item->type);
-       gui_internal_widget_append(wl, gui_internal_label_new(this, type));
        if (item_attr_get(item, attr_label, &attr)) {
                wl->name=g_strdup_printf("%s %s",type,attr.u.str);
        } else {
                attr.u.str="";
                wl->name=g_strdup(type);
        }
-       gui_internal_widget_append(wl, gui_internal_label_new(this, attr.u.str));
+        text=g_strdup_printf("%s %s %s %s", distbuf, dirbuf, type, attr.u.str);
+       gui_internal_widget_append(wl, gui_internal_label_new(this, text));
+       g_free(text);
 
        return wl;
 }
@@ -2079,8 +2106,8 @@ gui_internal_search_changed(struct gui_priv *this, struct widget *wm)
        GList *l;
        struct widget *search_list=gui_internal_menu_data(this)->search_list;
        gui_internal_widget_children_destroy(this, search_list);
-       int minlen=1;
        void *param=(void *)3;
+       int minlen=1;
        if (! strcmp(wm->name,"Country")) {
                param=(void *)4;
                minlen=1;
@@ -2107,25 +2134,24 @@ gui_internal_search_changed(struct gui_priv *this, struct widget *wm)
 }
 
 static struct widget *
-gui_internal_keyboard_key_data(struct gui_priv *this, struct widget *wkbd, char *text, void(*func)(struct gui_priv *priv, struct widget *widget), void *data, void (*data_free)(void *data))
+gui_internal_keyboard_key_data(struct gui_priv *this, struct widget *wkbd, char *text, void(*func)(struct gui_priv *priv, struct widget *widget), void *data, void (*data_free)(void *data), int w, int h)
 {
        struct widget *wk;
-
        gui_internal_widget_append(wkbd, wk=gui_internal_button_new_with_callback(this, text,
                NULL, gravity_center|orientation_vertical, func, data));
        wk->data_free=data_free;
        wk->background=this->background;
-       wk->bl=6;
-       wk->br=6;
-       wk->bt=6;
-       wk->bb=6;
+       wk->bl=w/2;
+       wk->br=0;
+       wk->bt=h/2;
+       wk->bb=0;
        return wk;
 }
 
 static struct widget *
-gui_internal_keyboard_key(struct gui_priv *this, struct widget *wkbd, char *text, char *key)
+gui_internal_keyboard_key(struct gui_priv *this, struct widget *wkbd, char *text, char *key, int w, int h)
 {
-       return gui_internal_keyboard_key_data(this, wkbd, text, gui_internal_cmd_keypress, g_strdup(key), g_free);
+       return gui_internal_keyboard_key_data(this, wkbd, text, gui_internal_cmd_keypress, g_strdup(key), g_free,w,h);
 }
 
 static void gui_internal_keyboard_change(struct gui_priv *this, struct widget *key);
@@ -2135,11 +2161,13 @@ gui_internal_keyboard_do(struct gui_priv *this, struct widget *wkbdb, int mode)
 {
        struct widget *wkbd,*wk;
        struct menu_data *md=gui_internal_menu_data(this);
-       int i;
+       int i, max_w=navit_get_width(this->nav), max_h=navit_get_height(this->nav);
        int render=0;
 
        if (wkbdb) {
-               gui_internal_highlight(this, NULL);
+               this->current.x=-1;
+               this->current.y=-1;
+               gui_internal_highlight(this);
                render=1;
                gui_internal_widget_children_destroy(this, wkbdb);
        } else
@@ -2151,104 +2179,107 @@ gui_internal_keyboard_do(struct gui_priv *this, struct widget *wkbdb, int mode)
        wkbd->cols=8;
        wkbd->spx=3;
        wkbd->spy=3;
+       max_w=max_w/9;
+       max_h=max_h/6;
+
        if (mode >= 0 && mode < 8) {
                for (i = 0 ; i < 26 ; i++) {
                        char text[]={'A'+i,'\0'};
-                       gui_internal_keyboard_key(this, wkbd, text, text);
+                       gui_internal_keyboard_key(this, wkbd, text, text,max_w,max_h);
                }
-               gui_internal_keyboard_key(this, wkbd, "_"," ");
+               gui_internal_keyboard_key(this, wkbd, "_"," ",max_w,max_h);
                if (mode == 0) {
-                       gui_internal_keyboard_key(this, wkbd, "-","-");
-                       gui_internal_keyboard_key(this, wkbd, "'","'");
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
+                       gui_internal_keyboard_key(this, wkbd, "-","-",max_w,max_h);
+                       gui_internal_keyboard_key(this, wkbd, "'","'",max_w,max_h);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
                } else {
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
-                       wk=gui_internal_keyboard_key_data(this, wkbd, "a", gui_internal_keyboard_change, wkbd, NULL);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
+                       wk=gui_internal_keyboard_key_data(this, wkbd, "a", gui_internal_keyboard_change, wkbd, NULL,max_w,max_h);
                        wk->datai=mode+8;
-                       wk=gui_internal_keyboard_key_data(this, wkbd, "1", gui_internal_keyboard_change, wkbd, NULL);
+                       wk=gui_internal_keyboard_key_data(this, wkbd, "1", gui_internal_keyboard_change, wkbd, NULL,max_w,max_h);
                        wk->datai=mode+16;
                }
-               wk=gui_internal_keyboard_key_data(this, wkbd, "Ä",gui_internal_keyboard_change, wkbdb,NULL);
+               wk=gui_internal_keyboard_key_data(this, wkbd, "Ä",gui_internal_keyboard_change, wkbdb,NULL,max_w,max_h);
                wk->datai=mode+24;
-               gui_internal_keyboard_key(this, wkbd, "<-","\b");
+               gui_internal_keyboard_key(this, wkbd, "<-","\b",max_w,max_h);
        }
        if (mode >= 8 && mode < 16) {
                for (i = 0 ; i < 26 ; i++) {
                        char text[]={'a'+i,'\0'};
-                       gui_internal_keyboard_key(this, wkbd, text, text);
+                       gui_internal_keyboard_key(this, wkbd, text, text,max_w,max_h);
                }
-               gui_internal_keyboard_key(this, wkbd, "_"," ");
+               gui_internal_keyboard_key(this, wkbd, "_"," ",max_w,max_h);
                if (mode == 8) {
-                       gui_internal_keyboard_key(this, wkbd, "-","-");
-                       gui_internal_keyboard_key(this, wkbd, "'","'");
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
+                       gui_internal_keyboard_key(this, wkbd, "-","-",max_w,max_h);
+                       gui_internal_keyboard_key(this, wkbd, "'","'",max_w,max_h);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
                } else {
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
-                       wk=gui_internal_keyboard_key_data(this, wkbd, "A", gui_internal_keyboard_change, wkbd, NULL);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
+                       wk=gui_internal_keyboard_key_data(this, wkbd, "A", gui_internal_keyboard_change, wkbd, NULL,max_w,max_h);
                        wk->datai=mode-8;
-                       wk=gui_internal_keyboard_key_data(this, wkbd, "1", gui_internal_keyboard_change, wkbd, NULL);
+                       wk=gui_internal_keyboard_key_data(this, wkbd, "1", gui_internal_keyboard_change, wkbd, NULL,max_w,max_h);
                        wk->datai=mode+8;
                }
-               wk=gui_internal_keyboard_key_data(this, wkbd, "ä",gui_internal_keyboard_change,wkbdb,NULL);
+               wk=gui_internal_keyboard_key_data(this, wkbd, "ä",gui_internal_keyboard_change,wkbdb,NULL,max_w,max_h);
                wk->datai=mode+24;
-               gui_internal_keyboard_key(this, wkbd, "<-","\b");
+               gui_internal_keyboard_key(this, wkbd, "<-","\b",max_w,max_h);
        }
        if (mode >= 16 && mode < 24) {
                for (i = 0 ; i < 10 ; i++) {
                        char text[]={'0'+i,'\0'};
-                       gui_internal_keyboard_key(this, wkbd, text, text);
+                       gui_internal_keyboard_key(this, wkbd, text, text,max_w,max_h);
                }
-               gui_internal_keyboard_key(this, wkbd, ".",".");
-               gui_internal_keyboard_key(this, wkbd, "°","°");
-               gui_internal_keyboard_key(this, wkbd, "'","'");
-               gui_internal_keyboard_key(this, wkbd, "\"","\"");
-               gui_internal_keyboard_key(this, wkbd, "-","-");
-               gui_internal_keyboard_key(this, wkbd, "+","+");
-               gui_internal_keyboard_key(this, wkbd, "*","*");
-               gui_internal_keyboard_key(this, wkbd, "/","/");
-               gui_internal_keyboard_key(this, wkbd, "(","(");
-               gui_internal_keyboard_key(this, wkbd, ")",")");
-               gui_internal_keyboard_key(this, wkbd, "=","=");
-               gui_internal_keyboard_key(this, wkbd, "?","?");
+               gui_internal_keyboard_key(this, wkbd, ".",".",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "°","°",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "'","'",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "\"","\"",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "-","-",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "+","+",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "*","*",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "/","/",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "(","(",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, ")",")",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "=","=",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "?","?",max_w,max_h);
                for (i = 0 ; i < 5 ; i++) {
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
                }
                if (mode == 8) {
-                       gui_internal_keyboard_key(this, wkbd, "-","-");
-                       gui_internal_keyboard_key(this, wkbd, "'","'");
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
+                       gui_internal_keyboard_key(this, wkbd, "-","-",max_w,max_h);
+                       gui_internal_keyboard_key(this, wkbd, "'","'",max_w,max_h);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
                } else {
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
-                       wk=gui_internal_keyboard_key_data(this, wkbd, "A", gui_internal_keyboard_change, wkbd, NULL);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
+                       wk=gui_internal_keyboard_key_data(this, wkbd, "A", gui_internal_keyboard_change, wkbd, NULL,max_w,max_h);
                        wk->datai=mode-16;
-                       wk=gui_internal_keyboard_key_data(this, wkbd, "a", gui_internal_keyboard_change, wkbd, NULL);
+                       wk=gui_internal_keyboard_key_data(this, wkbd, "a", gui_internal_keyboard_change, wkbd, NULL,max_w,max_h);
                        wk->datai=mode-8;
                }
-               wk=gui_internal_keyboard_key_data(this, wkbd, "Ä",gui_internal_keyboard_change,wkbdb,NULL);
+               wk=gui_internal_keyboard_key_data(this, wkbd, "Ä",gui_internal_keyboard_change,wkbdb,NULL,max_w,max_h);
                wk->datai=mode+8;
-               gui_internal_keyboard_key(this, wkbd, "<-","\b");
+               gui_internal_keyboard_key(this, wkbd, "<-","\b",max_w,max_h);
        }
        if (mode >= 24 && mode < 32) {
-               gui_internal_keyboard_key(this, wkbd, "Ä","Ä");
-               gui_internal_keyboard_key(this, wkbd, "Ö","Ö");
-               gui_internal_keyboard_key(this, wkbd, "Ü","Ü");
+               gui_internal_keyboard_key(this, wkbd, "Ä","Ä",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "Ö","Ö",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "Ü","Ü",max_w,max_h);
                for (i = 0 ; i < 27 ; i++) {
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
                }
-               wk=gui_internal_keyboard_key_data(this, wkbd, "A",gui_internal_keyboard_change,wkbdb,NULL);
+               wk=gui_internal_keyboard_key_data(this, wkbd, "A",gui_internal_keyboard_change,wkbdb,NULL,max_w,max_h);
                wk->datai=mode-24;
-               gui_internal_keyboard_key(this, wkbd, "<-","\b");
+               gui_internal_keyboard_key(this, wkbd, "<-","\b",max_w,max_h);
        }
        if (mode >= 32 && mode < 40) {
-               gui_internal_keyboard_key(this, wkbd, "ä","ä");
-               gui_internal_keyboard_key(this, wkbd, "ö","ö");
-               gui_internal_keyboard_key(this, wkbd, "ü","ü");
+               gui_internal_keyboard_key(this, wkbd, "ä","ä",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "ö","ö",max_w,max_h);
+               gui_internal_keyboard_key(this, wkbd, "ü","ü",max_w,max_h);
                for (i = 0 ; i < 27 ; i++) {
-                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL);
+                       gui_internal_keyboard_key_data(this, wkbd, "", NULL, NULL, NULL,max_w,max_h);
                }
-               wk=gui_internal_keyboard_key_data(this, wkbd, "a",gui_internal_keyboard_change,wkbdb,NULL);
+               wk=gui_internal_keyboard_key_data(this, wkbd, "a",gui_internal_keyboard_change,wkbdb,NULL,max_w,max_h);
                wk->datai=mode-24;
-               gui_internal_keyboard_key(this, wkbd, "<-","\b");
+               gui_internal_keyboard_key(this, wkbd, "<-","\b",max_w,max_h);
        }
        gui_internal_widget_append(wkbdb, wkbd);
        if (render) {
@@ -2672,6 +2703,7 @@ gui_internal_cmd_settings(struct gui_priv *this, struct widget *wm)
 //##############################################################################################################
 static void gui_internal_motion(void *data, struct point *p)
 {
+
        struct gui_priv *this=data;
        if (!this->root.children) {
                navit_handle_motion(this->nav, p);
@@ -2679,10 +2711,11 @@ static void gui_internal_motion(void *data, struct point *p)
        }
        if (!this->pressed)
                return;
-       graphics_draw_mode(this->gra, draw_mode_begin);
-       gui_internal_highlight(this, p);
-       graphics_draw_mode(this->gra, draw_mode_end);
-       
+       this->current=*p;
+       if(!this->motion_timeout_callback)
+               this->motion_timeout_callback=callback_new_1(callback_cast(gui_internal_highlight), this);
+       if(!this->motion_timeout_event)
+               this->motion_timeout_event=event_add_timeout(100,0, this->motion_timeout_callback);
 }
 
 
@@ -2773,7 +2806,6 @@ gui_internal_check_exit(struct gui_priv *this)
 static void gui_internal_button(void *data, int pressed, int button, struct point *p)
 {
        struct gui_priv *this=data;
-       struct graphics *gra=this->gra;
        
        // if still on the map (not in the menu, yet):
        if (!this->root.children || this->ignore_button) {
@@ -2789,15 +2821,14 @@ static void gui_internal_button(void *data, int pressed, int button, struct poin
        // if already in the menu:
        if (pressed) {
                this->pressed=1;
-               graphics_draw_mode(gra, draw_mode_begin);
-               gui_internal_highlight(this, p);
-               graphics_draw_mode(gra, draw_mode_end);
+               this->current=*p;
+               gui_internal_highlight(this);
        } else {
                this->pressed=0;
-               graphics_draw_mode(gra, draw_mode_begin);
+               this->current.x=-1;
+               this->current.y=-1;
                gui_internal_call_highlighted(this);
-               gui_internal_highlight(this, NULL);
-               graphics_draw_mode(gra, draw_mode_end);
+               gui_internal_highlight(this);
                gui_internal_check_exit(this);
        }
 }
@@ -2810,6 +2841,10 @@ static void gui_internal_button(void *data, int pressed, int button, struct poin
 static void gui_internal_resize(void *data, int w, int h)
 {
        struct gui_priv *this=data;
+
+       if( this->root.w==w && this->root.h==h)
+                return;
+
        this->root.w=w;
        this->root.h=h;
        dbg(1,"w=%d h=%d children=%p\n", w, h, this->root.children);
index f931e0a..5c96049 100644 (file)
@@ -1338,6 +1338,23 @@ navit_init(struct navit *this_)
                navit_draw(this_);
 }
 
+void
+navit_zoom_to_route(struct navit *this_)
+{
+       struct map *map;
+       struct map_rect *mr;
+       int first=1;
+       if (! this_->route)
+               return;
+       map=route_get_map(this_->route);
+       if (! map)
+               return;
+       mr=map_rect_new(map, NULL);
+       if (! mr)
+               return;
+       
+}
+
 /**
  * Change the current zoom level
  *
index 13c980a..7494721 100644 (file)
 #include "track.h"
 #include "map.h"
 #include "file.h"
+#include "attr.h"
+#include "navit_nls.h"
 
-struct compass {
+struct osd_item {
        struct point p;
-       int w,h;
+       int w, h, fg_line_width, font_size;
+       struct color color_bg, color_white;
        struct graphics *gr;
-       struct graphics_gc *bg;
-       struct graphics_gc *white;
-       struct graphics_gc *green;
+       struct graphics_gc *graphic_bg, *graphic_fg_white;
        struct graphics_font *font;
 };
 
+struct compass {
+       struct osd_item osd_item;
+       struct graphics_gc *green;
+};
+
+static void
+osd_set_std_attr(struct attr **attrs, struct osd_item *item)
+{
+       struct attr *attr;
+       item->p.x = 0;
+       item->p.y = -40;
+       item->w = 150;
+       item->h = 40;
+
+       attr = attr_search(attrs, NULL, attr_w);
+       if (attr)
+               item->w = attr->u.num;
+
+       attr = attr_search(attrs, NULL, attr_h);
+       if (attr)
+               item->h = attr->u.num;
+
+       attr = attr_search(attrs, NULL, attr_x);
+       if (attr)
+               item->p.x = attr->u.num;
+
+       attr = attr_search(attrs, NULL, attr_y);
+       if (attr)
+               item->p.y = attr->u.num;
+
+       attr = attr_search(attrs, NULL, attr_font_size);
+       if (attr)
+               item->font_size = attr->u.num;
+
+       item->color_white.r = 0xffff;
+       item->color_white.g = 0xffff;
+       item->color_white.b = 0xffff;
+       item->color_white.a = 0xffff;
+       item->color_bg.r = 0x0;
+       item->color_bg.g = 0x0;
+       item->color_bg.b = 0x0;
+       item->color_bg.a = 0x5fff;
+}
+
+static void
+osd_set_std_graphic(struct navit *nav, struct osd_item *item)
+{
+       struct graphics *navit_gr;
+
+       navit_gr = navit_get_graphics(nav);
+       item->gr =
+           graphics_overlay_new(navit_gr, &item->p, item->w, item->h,
+                                65535, 1);
+
+       item->graphic_bg = graphics_gc_new(item->gr);
+       graphics_gc_set_foreground(item->graphic_bg, &item->color_bg);
+       graphics_background_gc(item->gr, item->graphic_bg);
+
+       item->graphic_fg_white = graphics_gc_new(item->gr);
+       graphics_gc_set_foreground(item->graphic_fg_white,
+                                  &item->color_white);
+
+       item->font = graphics_font_new(item->gr, item->font_size, 1);
+
+}
 
 static void
-transform_rotate(struct point *center, int angle, struct point *p, int count)
-{
-       int i,x,y;
-       double dx,dy;
-       for (i = 0 ; i < count ; i++)
-       {
-               dx=sin(M_PI*angle/180.0);
-               dy=cos(M_PI*angle/180.0);
-               x=dy*p->x-dx*p->y;      
-               y=dx*p->x+dy*p->y;
-                       
-               p->x=center->x+x;
-               p->y=center->y+y;
+transform_rotate(struct point *center, int angle, struct point *p,
+                int count)
+{
+       int i, x, y;
+       double dx, dy;
+       for (i = 0; i < count; i++) {
+               dx = sin(M_PI * angle / 180.0);
+               dy = cos(M_PI * angle / 180.0);
+               x = dy * p->x - dx * p->y;
+               y = dx * p->x + dy * p->y;
+
+               p->x = center->x + x;
+               p->y = center->y + y;
                p++;
        }
 }
 
 static void
-handle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r, int dir)
+handle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r,
+       int dir)
 {
        struct point ph[3];
-       int l=r*0.4;
+       int l = r * 0.4;
 
-       ph[0].x=0;
-       ph[0].y=r;
-       ph[1].x=0;
-       ph[1].y=-r;
+       ph[0].x = 0;
+       ph[0].y = r;
+       ph[1].x = 0;
+       ph[1].y = -r;
        transform_rotate(p, dir, ph, 2);
        graphics_draw_lines(gr, gc, ph, 2);
-       ph[0].x=-l;
-       ph[0].y=-r+l;
-       ph[1].x=0;
-       ph[1].y=-r;
-       ph[2].x=l;
-       ph[2].y=-r+l;
+       ph[0].x = -l;
+       ph[0].y = -r + l;
+       ph[1].x = 0;
+       ph[1].y = -r;
+       ph[2].x = l;
+       ph[2].y = -r + l;
        transform_rotate(p, dir, ph, 3);
        graphics_draw_lines(gr, gc, ph, 3);
 }
@@ -96,525 +163,939 @@ static void
 format_distance(char *buffer, double distance)
 {
        if (distance >= 100000)
-               sprintf(buffer,"%.0f km", distance/1000);
+               sprintf(buffer, "%.0fkm", distance / 1000);
        else if (distance >= 10000)
-               sprintf(buffer,"%.1f km", distance/1000);
+               sprintf(buffer, "%.1fkm", distance / 1000);
        else if (distance >= 300)
-               sprintf(buffer,"%.0f m", round(distance/25)*25);
-       else if (distance >= 50) 
-               sprintf(buffer,"%.0f m", round(distance/10)*10);
-       else if (distance >= 10) 
-               sprintf(buffer,"%.0f m", distance);
+               sprintf(buffer, "%.0fm", round(distance / 25) * 25);
+       else if (distance >= 50)
+               sprintf(buffer, "%.0fm", round(distance / 10) * 10);
+       else if (distance >= 10)
+               sprintf(buffer, "%.0fm", distance);
        else
-               sprintf(buffer,"%.1f m", distance);
+               sprintf(buffer, "%.1fm", distance);
+}
+
+static void
+format_speed(char *buffer, double speed)
+{
+       printf(buffer, "%.0f", speed);
 }
 
 static void
-osd_compass_draw(struct compass *this, struct navit *nav, struct vehicle *v)
+osd_compass_draw(struct compass *this, struct navit *nav,
+                struct vehicle *v)
 {
        struct point p;
        struct attr attr_dir, destination_attr, position_attr;
-       double dir,vdir=0;
+       double dir, vdir = 0;
        char buffer[16];
        struct coord c1, c2;
        enum projection pro;
 
-       graphics_draw_mode(this->gr, draw_mode_begin);
-       p.x=0;
-       p.y=0;
-       graphics_draw_rectangle(this->gr, this->bg, &p, this->w, this->h);
-       p.x=30;
-       p.y=30;
-       graphics_draw_circle(this->gr, this->white, &p, 50);
-       if (v && vehicle_get_attr(v, attr_position_direction, &attr_dir, NULL)) {
-               vdir=*attr_dir.u.numd;
-               handle(this->gr, this->white, &p, 20, -vdir);
-       }
-       if (navit_get_attr(nav, attr_destination, &destination_attr, NULL) && v && vehicle_get_attr(v, attr_position_coord_geo, &position_attr, NULL)) {
-               pro=destination_attr.u.pcoord->pro;
-               transform_from_geo(pro, position_attr.u.coord_geo, &c1);
-               c2.x=destination_attr.u.pcoord->x;
-               c2.y=destination_attr.u.pcoord->y;
-               dir=atan2(c2.x-c1.x,c2.y-c1.y)*180.0/M_PI;
-               dir-=vdir;
-               handle(this->gr, this->green, &p, 20, dir);
-               format_distance(buffer, transform_distance(pro, &c1, &c2));
-               p.x=8;
-               p.y=72;
-               graphics_draw_text(this->gr, this->green, NULL, this->font, buffer, &p, 0x10000, 0);
+       graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+       p.x = 0;
+       p.y = 0;
+       graphics_draw_rectangle(this->osd_item.gr,
+                               this->osd_item.graphic_bg, &p,
+                               this->osd_item.w, this->osd_item.h);
+       p.x = 30;
+       p.y = 30;
+       graphics_draw_circle(this->osd_item.gr,
+                            this->osd_item.graphic_fg_white, &p, 50);
+       if (v) {
+               if (vehicle_get_attr
+                   (v, attr_position_direction, &attr_dir, NULL)) {
+                       vdir = *attr_dir.u.numd;
+                       handle(this->osd_item.gr,
+                              this->osd_item.graphic_fg_white, &p, 20,
+                              -vdir);
+               }
+
+               if (navit_get_attr
+                   (nav, attr_destination, &destination_attr, NULL)
+                   && vehicle_get_attr(v, attr_position_coord_geo,
+                                       &position_attr, NULL)) {
+                       pro = destination_attr.u.pcoord->pro;
+                       transform_from_geo(pro, position_attr.u.coord_geo,
+                                          &c1);
+                       c2.x = destination_attr.u.pcoord->x;
+                       c2.y = destination_attr.u.pcoord->y;
+                       dir =
+                           atan2(c2.x - c1.x, c2.y - c1.y) * 180.0 / M_PI;
+                       dir -= vdir;
+                       handle(this->osd_item.gr, this->green, &p, 20,
+                              dir);
+                       format_distance(buffer,
+                                       transform_distance(pro, &c1, &c2));
+                       p.x = 8;
+                       p.y = 72;
+                       graphics_draw_text(this->osd_item.gr, this->green,
+                                          NULL, this->osd_item.font,
+                                          buffer, &p, 0x10000, 0);
+               }
        }
-       graphics_draw_mode(this->gr, draw_mode_end);
+       graphics_draw_mode(this->osd_item.gr, draw_mode_end);
 }
 
+
+
 static void
 osd_compass_init(struct compass *this, struct navit *nav)
 {
-       struct graphics *navit_gr;
        struct color c;
-       navit_gr=navit_get_graphics(nav);
-       this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h, 65535, 1);
-
-       this->bg=graphics_gc_new(this->gr);
-       c.r=0; c.g=0; c.b=0; c.a=32767;
-       graphics_gc_set_foreground(this->bg, &c);
-       graphics_background_gc(this->gr, this->bg);
 
-       this->white=graphics_gc_new(this->gr);
-       c.r=65535; c.g=65535; c.b=65535; c.a=65535;
-       graphics_gc_set_foreground(this->white, &c);
-       graphics_gc_set_linewidth(this->white, 2);
+       osd_set_std_graphic(nav, &this->osd_item);
 
-       this->green=graphics_gc_new(this->gr);
-       c.r=0; c.g=65535; c.b=0; c.a=65535;
+       this->green = graphics_gc_new(this->osd_item.gr);
+       c.r = 0;
+       c.g = 65535;
+       c.b = 0;
+       c.a = 65535;
        graphics_gc_set_foreground(this->green, &c);
        graphics_gc_set_linewidth(this->green, 2);
 
-       this->font=graphics_font_new(this->gr, 200, 1);
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_draw), attr_position_coord_geo, this));
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_compass_draw),
+                                              attr_position_coord_geo,
+                                              this));
 
        osd_compass_draw(this, nav, NULL);
 }
 
 static struct osd_priv *
-osd_compass_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+osd_compass_new(struct navit *nav, struct osd_methods *meth,
+               struct attr **attrs)
 {
-       struct compass *this=g_new0(struct compass, 1);
-       struct attr *attr;
-       this->p.x=20;
-       this->p.y=20;
-       this->w=60;
-       this->h=80;
-       attr=attr_search(attrs, NULL, attr_x);
-       if (attr)
-               this->p.x=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_y);
-       if (attr)
-               this->p.y=attr->u.num;
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_init), attr_navit, this));
+       struct compass *this = g_new0(struct compass, 1);
+       osd_set_std_attr(attrs, &this->osd_item);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_compass_init),
+                                              attr_navit, this));
        return (struct osd_priv *) this;
 }
 
-struct eta {
-       struct point p;
-       int w,h;
-       struct graphics *gr;
-       struct graphics_gc *bg;
-       struct graphics_gc *white;
-       struct graphics_font *font;
-       struct graphics_image *flag;
+struct osd_eta {
+       struct osd_item osd_item;
        int active;
+       char *test_text;
        char last_eta[16];
-       char last_distance[16];
 };
 
 static void
-osd_eta_draw(struct eta *this, struct navit *navit, struct vehicle *v)
+osd_eta_draw(struct osd_eta *this, struct navit *navit, struct vehicle *v)
 {
-       struct point p;
+       struct point p, p2[4];
        char eta[16];
-       char distance[16];
-       int days=0,do_draw=0;
+       int days = 0, do_draw = 0;
        time_t etat;
-        struct tm tm,eta_tm,eta_tm0;
+       struct tm tm, eta_tm, eta_tm0;
        struct attr attr;
-       struct navigation *nav=NULL;
-       struct map *map=NULL;
-       struct map_rect *mr=NULL;
-       struct item *item=NULL;
+       struct navigation *nav = NULL;
+       struct map *map = NULL;
+       struct map_rect *mr = NULL;
+       struct item *item = NULL;
 
 
-       eta[0]='\0';
-       distance[0]='\0';
+       eta[0] = '\0';
 
        if (navit)
-                nav=navit_get_navigation(navit);
-        if (nav)
-                map=navigation_get_map(nav);
-        if (map)
-                mr=map_rect_new(map, NULL);
-        if (mr)
-                item=map_rect_get_item(mr);
-        if (item) {
-                if (item_attr_get(item, attr_destination_length, &attr)) {
-                        format_distance(distance, attr.u.num);
-               }
-                if (item_attr_get(item, attr_destination_time, &attr)) {
-                       etat=time(NULL);
-                       tm=*localtime(&etat);
-                        etat+=attr.u.num/10;
-                        eta_tm=*localtime(&etat);
-                       if (tm.tm_year != eta_tm.tm_year || tm.tm_mon != eta_tm.tm_mon || tm.tm_mday != eta_tm.tm_mday) {
-                               eta_tm0=eta_tm;
-                               eta_tm0.tm_sec=0;
-                               eta_tm0.tm_min=0;
-                               eta_tm0.tm_hour=0;
-                               tm.tm_sec=0;
-                               tm.tm_min=0;
-                               tm.tm_hour=0;
-                               days=(mktime(&eta_tm0)-mktime(&tm)+43200)/86400;
+               nav = navit_get_navigation(navit);
+       if (nav)
+               map = navigation_get_map(nav);
+       if (map)
+               mr = map_rect_new(map, NULL);
+
+       if (mr)
+               item = map_rect_get_item(mr);
+
+       if (item) {
+               if (item_attr_get(item, attr_destination_time, &attr)) {
+                       etat = time(NULL);
+                       tm = *localtime(&etat);
+                       etat += attr.u.num / 10;
+                       eta_tm = *localtime(&etat);
+                       if (tm.tm_year != eta_tm.tm_year
+                           || tm.tm_mon != eta_tm.tm_mon
+                           || tm.tm_mday != eta_tm.tm_mday) {
+                               eta_tm0 = eta_tm;
+                               eta_tm0.tm_sec = 0;
+                               eta_tm0.tm_min = 0;
+                               eta_tm0.tm_hour = 0;
+                               tm.tm_sec = 0;
+                               tm.tm_min = 0;
+                               tm.tm_hour = 0;
+                               days =
+                                   (mktime(&eta_tm0) - mktime(&tm) +
+                                    43200) / 86400;
                        }
-                       if (days) 
-                               sprintf(eta, "%d+%02d:%02d", days, eta_tm.tm_hour, eta_tm.tm_min);
+                       if (days)
+                               sprintf(eta, "%d+%02d:%02d", days,
+                                       eta_tm.tm_hour, eta_tm.tm_min);
                        else
-                               sprintf(eta, "  %02d:%02d", eta_tm.tm_hour, eta_tm.tm_min);
-                }
-               if (this->active != 1 || strcmp(this->last_distance, distance) || strcmp(this->last_eta, eta)) {
-                       this->active=1;
-                       strcpy(this->last_distance, distance);
+                               sprintf(eta, "%02d:%02d", eta_tm.tm_hour,
+                                       eta_tm.tm_min);
+               }
+               if (this->active != 1 || strcmp(this->last_eta, eta)) {
+                       this->active = 1;
                        strcpy(this->last_eta, eta);
-                       do_draw=1;
+                       do_draw = 1;
                }
-        } else {
+       } else {
                if (this->active != 0) {
-                       this->active=0;
-                       do_draw=1;
+                       this->active = 0;
+                       do_draw = 1;
                }
        }
-        if (mr)
-                map_rect_destroy(mr);
 
-       if (do_draw) {
-               graphics_draw_mode(this->gr, draw_mode_begin);
-               p.x=0;
-               p.y=0;
-               graphics_draw_rectangle(this->gr, this->bg, &p, this->w, this->h);
-               p.x=6;
-               p.y=6;
-               if (this->flag)
-                       graphics_draw_image(this->gr, this->white, &p, this->flag);
-               if (eta[0]) {
-                       p.x=28;
-                       p.y=28;
-                       graphics_draw_text(this->gr, this->white, NULL, this->font, "ETA", &p, 0x10000, 0);
-                       p.x=6;
-                       p.y=42;
-                       graphics_draw_text(this->gr, this->white, NULL, this->font, eta, &p, 0x10000, 0);
-               }
-               if (distance[0]) {
-                       p.x=6;
-                       p.y=56;
-                       graphics_draw_text(this->gr, this->white, NULL, this->font, distance, &p, 0x10000, 0);
-               }
-               graphics_draw_mode(this->gr, draw_mode_end);
-       }       
+       if (mr)
+               map_rect_destroy(mr);
+
+       if (do_draw || this->test_text) {
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       32767, 32767);
+               if (this->active) {
+                       if (eta) {
+                               graphics_get_text_bbox(this->osd_item.gr,
+                                                      this->osd_item.font,
+                                                      eta, 0x10000, 0x0,
+                                                      p2, 0);
+                               p.y =
+                                   ((p2[0].y - p2[2].y) / 2) +
+                                   (this->osd_item.h / 2);
+                               p.x =
+                                   ((p2[0].x - p2[2].x) / 2) +
+                                   (this->osd_item.w / 2);
+                               graphics_draw_text(this->osd_item.gr,
+                                                  this->osd_item.
+                                                  graphic_fg_white, NULL,
+                                                  this->osd_item.font,
+                                                  eta, &p, 0x10000, 0);
+                       }
+               } else if (this->test_text) {
+                       graphics_get_text_bbox(this->osd_item.gr,
+                                              this->osd_item.font,
+                                              this->test_text, 0x10000,
+                                              0x0, p2, 0);
+                       p.y =
+                           ((p2[0].y - p2[2].y) / 2) +
+                           (this->osd_item.h / 2);
+                       p.x =
+                           ((p2[0].x - p2[2].x) / 2) +
+                           (this->osd_item.w / 2);
+                       graphics_draw_text(this->osd_item.gr,
+                                          this->osd_item.graphic_fg_white,
+                                          NULL, this->osd_item.font,
+                                          this->test_text, &p, 0x10000,
+                                          0);
+               }
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
+       }
+
 }
 
 static void
-osd_eta_init(struct eta *this, struct navit *nav)
+osd_eta_init(struct osd_eta *this, struct navit *nav)
 {
-       struct graphics *navit_gr;
-       struct color c;
-       char *flag=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/flag_wh_bk.xpm", NULL);
-       navit_gr=navit_get_graphics(nav);
-       this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h, 65535, 1);
 
-       this->bg=graphics_gc_new(this->gr);
-       c.r=0; c.g=0; c.b=0; c.a=32767;
-       graphics_gc_set_foreground(this->bg, &c);
-       graphics_background_gc(this->gr, this->bg);
+       osd_set_std_graphic(nav, &this->osd_item);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast(osd_eta_draw),
+                                              attr_position_coord_geo,
+                                              this));
+       osd_eta_draw(this, nav, NULL);
 
-       this->white=graphics_gc_new(this->gr);
-       c.r=65535; c.g=65535; c.b=65535; c.a=65535;
-       graphics_gc_set_foreground(this->white, &c);
-       graphics_gc_set_linewidth(this->white, 2);
+}
 
-       this->font=graphics_font_new(this->gr, 200, 1);
-       this->flag=graphics_image_new(this->gr, flag);
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_eta_draw), attr_position_coord_geo, this));
+static struct osd_priv *
+osd_eta_new(struct navit *nav, struct osd_methods *meth,
+           struct attr **attrs)
+{
+       struct osd_eta *this = g_new0(struct osd_eta, 1);
+       struct attr *attr;
 
-       osd_eta_draw(this, nav, NULL);
-       g_free(flag);
+       osd_set_std_attr(attrs, &this->osd_item);
+
+       this->active = -1;
+
+       attr = attr_search(attrs, NULL, attr_label);
+       if (attr)
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast(osd_eta_init),
+                                              attr_navit, this));
+       return (struct osd_priv *) this;
+}
+
+struct osd_speed {
+       struct osd_item osd_item;
+       int active;
+       char *test_text;
+       double last_speed;
+};
+
+static void
+osd_speed_draw(struct osd_speed *this, struct navit *nav)
+{
+       struct point p, p2[4];
+       struct attr attr;
+       double speed = 0;
+       int speed_max = 0;
+       int do_draw = 0;
+       char buffer[16];
+       struct route *r;
+       int *speedlist;
+       struct tracking *tr;
+       struct item *item;
+       struct vehicle *v;
+
+
+       if (nav) {
+               if (navit_get_attr(nav, attr_vehicle, &attr, NULL)) {
+                       v = attr.u.vehicle;
+               }
+               r = navit_get_route(nav);
+               tr = navit_get_tracking(nav);
+       }
+
+       if (r)
+               speedlist = route_get_speedlist(r);
+
+       if (tr)
+               item = tracking_get_current_item(tr);
+
+       if (item) {
+               speed_max = speedlist[item->type - route_item_first];
+       }
+
+       if (v) {
+               if (vehicle_get_attr(v, attr_position_speed, &attr, NULL)) {
+                       speed = *attr.u.numd;
+               }
+               if (this->active != 1 || this->last_speed != speed) {
+                       this->last_speed = speed;
+                       this->active = 1;
+                       do_draw = 1;
+               }
+       } else {
+               if (this->active != 0) {
+                       this->active = 0;
+                       do_draw = 1;
+               }
+       }
+
+       if (do_draw) {
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       32767, 32767);
+               if (this->active) {
+                       sprintf(buffer, "%.0f/%i", speed, speed_max);
+                       graphics_get_text_bbox(this->osd_item.gr,
+                                              this->osd_item.font, buffer,
+                                              0x10000, 0x0, p2, 0);
+                       p.y =
+                           ((p2[0].y - p2[2].y) / 2) +
+                           (this->osd_item.h / 2);
+                       graphics_draw_text(this->osd_item.gr,
+                                          this->osd_item.graphic_fg_white,
+                                          NULL, this->osd_item.font,
+                                          buffer, &p, 0x10000, 0);
+               }
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
+       }
+}
+
+static void
+osd_speed_init(struct osd_speed *this, struct navit *nav)
+{
+       struct attr attr, attr_cb;
+       struct vehicle *v = NULL;
+
+       osd_set_std_graphic(nav, &this->osd_item);
+
+       if (nav) {
+               if (navit_get_attr(nav, attr_vehicle, &attr, NULL)) {
+                       v = attr.u.vehicle;
+               }
+       }
+
+       if (v) {
+               attr_cb.type = attr_callback;
+               attr_cb.u.callback =
+                   callback_new_attr_2(callback_cast(osd_speed_draw),
+                                       attr_position_speed, this, nav);
+               if (!vehicle_add_attr(v, &attr_cb)) {
+                       dbg(0, "failed register callback\n");
+               }
+       }
+       osd_speed_draw(this, nav);
 }
 
 static struct osd_priv *
-osd_eta_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+osd_speed_new(struct navit *nav, struct osd_methods *meth,
+             struct attr **attrs)
 {
-       struct eta *this=g_new0(struct eta, 1);
+       struct osd_speed *this = g_new0(struct osd_speed, 1);
        struct attr *attr;
-       this->p.x=-80;
-       this->p.y=20;
-       this->w=60;
-       this->h=60;
-       this->active=-1;
-       attr=attr_search(attrs, NULL, attr_x);
+
+       osd_set_std_attr(attrs, &this->osd_item);
+
+       this->active = -1;
+
+       attr = attr_search(attrs, NULL, attr_label);
        if (attr)
-               this->p.x=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_y);
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_speed_init),
+                                              attr_navit, this));
+       return (struct osd_priv *) this;
+}
+
+struct osd_sats {
+       struct osd_item osd_item;
+       int active;
+       char *test_text;
+       int last_sats, last_sats_used, last_sats_signal;
+};
+
+static void
+osd_sats_draw(struct osd_sats *this, struct vehicle *v)
+{
+       struct point p, p2[4];
+       struct attr attr;
+       int satelites = 0, satelites_used = 0, do_draw =
+           0, satelites_signal = 0;
+       char buffer[16];
+
+       if (v) {
+               if (vehicle_get_attr(v, attr_position_qual, &attr, NULL)) {
+                       satelites = attr.u.num;
+               }
+               if (vehicle_get_attr
+                   (v, attr_position_sats_used, &attr, NULL)) {
+                       satelites_used = attr.u.num;
+               }
+               if (vehicle_get_attr
+                   (v, attr_position_sats_signal, &attr, NULL)) {
+                       satelites_signal = attr.u.num;
+               }
+               if (this->active != 1 || this->last_sats != satelites
+                   || this->last_sats_used != satelites_used
+                   || this->last_sats_signal != satelites_signal) {
+                       this->last_sats = satelites;
+                       this->last_sats_used = satelites_used;
+                       this->last_sats_signal = satelites_signal;
+                       this->active = 1;
+                       do_draw = 1;
+               }
+       } else {
+               if (this->active != 0) {
+                       this->active = 0;
+                       do_draw = 1;
+               }
+       }
+
+       if (do_draw) {
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       32767, 32767);
+               if (this->active) {
+                       sprintf(buffer, "%i/%i/%i", satelites_used,
+                               satelites_signal, satelites);
+                       graphics_get_text_bbox(this->osd_item.gr,
+                                              this->osd_item.font, buffer,
+                                              0x10000, 0x0, p2, 0);
+                       p.y =
+                           ((p2[0].y - p2[2].y) / 2) +
+                           (this->osd_item.h / 2);
+                       graphics_draw_text(this->osd_item.gr,
+                                          this->osd_item.graphic_fg_white,
+                                          NULL, this->osd_item.font,
+                                          buffer, &p, 0x10000, 0);
+               }
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
+       }
+}
+
+static void
+osd_sats_init(struct osd_sats *this, struct navit *nav)
+{
+       struct attr attr, attr_cb;
+       struct vehicle *v = NULL;
+
+       osd_set_std_graphic(nav, &this->osd_item);
+
+       if (nav) {
+               if (navit_get_attr(nav, attr_vehicle, &attr, NULL)) {
+                       v = attr.u.vehicle;
+               }
+       }
+
+       if (v) {
+               attr_cb.type = attr_callback;
+               attr_cb.u.callback =
+                   callback_new_attr_2(callback_cast(osd_sats_draw),
+                                       attr_position_sats, this, v);
+               if (!vehicle_add_attr(v, &attr_cb)) {
+                       dbg(0, "failed register callback\n");
+               }
+       }
+       osd_sats_draw(this, v);
+}
+
+static struct osd_priv *
+osd_sats_new(struct navit *nav, struct osd_methods *meth,
+            struct attr **attrs)
+{
+       struct osd_sats *this = g_new0(struct osd_sats, 1);
+       struct attr *attr;
+
+       osd_set_std_attr(attrs, &this->osd_item);
+
+       this->active = -1;
+
+       attr = attr_search(attrs, NULL, attr_label);
        if (attr)
-               this->p.y=attr->u.num;
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_eta_init), attr_navit, this));
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_sats_init), attr_navit,
+                                              this));
        return (struct osd_priv *) this;
 }
 
-struct osd_navigation {
-       struct point p;
-       int w,h;
-       int font_size;
-       char *icon_src;
-       int icon_w, icon_h;
-       struct graphics *gr;
-       struct graphics_gc *bg;
-       struct graphics_gc *white;
-       struct graphics_font *font;
+struct osd_nav_distance_to_target {
+       struct osd_item osd_item;
        int active;
+       char *test_text;
        char last_distance[16];
-       char *last_name;
 };
 
+
 static void
-osd_navigation_draw(struct osd_navigation *this, struct navit *navit, struct vehicle *v)
+osd_nav_distance_to_target_draw(struct osd_nav_distance_to_target *this,
+                               struct navit *navit, struct vehicle *v)
 {
-       struct point p;
+       struct point p, p2[4];
        char distance[16];
-       int do_draw=0;
+       int do_draw = 0;
        struct attr attr;
-       struct navigation *nav=NULL;
-       struct map *map=NULL;
-       struct map_rect *mr=NULL;
-       struct item *item=NULL;
-       struct graphics_image *gr_image;
-       char *image;
-       char *name="unknown";
+       struct navigation *nav = NULL;
+       struct map *map = NULL;
+       struct map_rect *mr = NULL;
+       struct item *item = NULL;
+
 
-       distance[0]='\0';
+       distance[0] = '\0';
 
        if (navit)
-                nav=navit_get_navigation(navit);
-        if (nav)
-                map=navigation_get_map(nav);
-        if (map)
-                mr=map_rect_new(map, NULL);
-        if (mr)
-                while ((item=map_rect_get_item(mr)) && item->type == type_nav_position);
-        if (item) {
-               name=item_to_name(item->type);
-               dbg(1,"name=%s\n", name);
-                if (item_attr_get(item, attr_length, &attr)) {
-                        format_distance(distance, attr.u.num);
-               }
-               if (this->active != 1 || strcmp(this->last_distance, distance) || this->last_name != name) {
-                       this->active=1;
+               nav = navit_get_navigation(navit);
+       if (nav)
+               map = navigation_get_map(nav);
+       if (map)
+               mr = map_rect_new(map, NULL);
+
+       if (mr)
+               item = map_rect_get_item(mr);
+
+       if (item) {
+               if (item_attr_get(item, attr_destination_length, &attr)) {
+                       format_distance(distance, attr.u.num);
+               }
+               if (this->active != 1
+                   || strcmp(this->last_distance, distance)) {
+                       this->active = 1;
                        strcpy(this->last_distance, distance);
-                       this->last_name=name;
-                       do_draw=1;
+                       do_draw = 1;
                }
-        } else {
+       } else {
                if (this->active != 0) {
-                       this->active=0;
-                       do_draw=1;
+                       this->active = 0;
+                       do_draw = 1;
                }
        }
-        if (mr)
-                map_rect_destroy(mr);
 
-       if (do_draw) {
-               graphics_draw_mode(this->gr, draw_mode_begin);
-               p.x=0;
-               p.y=0;
-               graphics_draw_rectangle(this->gr, this->bg, &p, this->w, this->h);
-               if (this->active) {
-                       image=g_strdup_printf(this->icon_src, name);
-                       dbg(0,"image=%s\n", image);
-                       gr_image=graphics_image_new_scaled(this->gr, image, this->icon_w, this->icon_h);
-                       if (! gr_image) {
-                               g_free(image);
-                               image=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/unknown.xpm", NULL);
-                               gr_image=graphics_image_new_scaled(this->gr, image, this->icon_w, this->icon_h);
-                       }
-                       dbg(1,"gr_image=%p\n", gr_image);
-                       if (gr_image) {
-                               p.x=(this->w-gr_image->width)/2;
-                               p.y=(46-gr_image->height)/2;
-                               graphics_draw_image(this->gr, this->white, &p, gr_image);
-                               graphics_image_free(this->gr, gr_image);
+       if (mr)
+               map_rect_destroy(mr);
+
+
+       if (do_draw || this->test_text) {
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       32767, 32767);
+               if (this->active || this->test_text) {
+                       if (this->test_text) {
+                               graphics_get_text_bbox(this->osd_item.gr,
+                                                      this->osd_item.font,
+                                                      this->test_text,
+                                                      0x10000, 0x0, p2,
+                                                      0);
+                               p.y =
+                                   ((p2[0].y - p2[2].y) / 2) +
+                                   (this->osd_item.h / 2);
+                               graphics_draw_text(this->osd_item.gr,
+                                                  this->osd_item.
+                                                  graphic_fg_white, NULL,
+                                                  this->osd_item.font,
+                                                  this->test_text, &p,
+                                                  0x10000, 0);
+                       } else if (distance) {
+                               graphics_get_text_bbox(this->osd_item.gr,
+                                                      this->osd_item.font,
+                                                      distance, 0x10000,
+                                                      0x0, p2, 0);
+                               p.y =
+                                   ((p2[0].y - p2[2].y) / 2) +
+                                   (this->osd_item.h / 2);
+                               graphics_draw_text(this->osd_item.gr,
+                                                  this->osd_item.
+                                                  graphic_fg_white, NULL,
+                                                  this->osd_item.font,
+                                                  distance, &p, 0x10000,
+                                                  0);
                        }
-                       g_free(image);
-                       p.x=12;
-                       p.y=56;
-                       graphics_draw_text(this->gr, this->white, NULL, this->font, distance, &p, 0x10000, 0);
                }
-               graphics_draw_mode(this->gr, draw_mode_end);
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
        }
 }
 
+
 static void
-osd_navigation_init(struct osd_navigation *this, struct navit *nav)
+osd_nav_distance_to_target_init(struct osd_nav_distance_to_target *this,
+                               struct navit *nav)
 {
-       struct graphics *navit_gr;
-       struct color c;
-       navit_gr=navit_get_graphics(nav);
-       this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h, 65535, 1);
 
-       this->bg=graphics_gc_new(this->gr);
-       c.r=0; c.g=0; c.b=0; c.a=32767;
-       graphics_gc_set_foreground(this->bg, &c);
-       graphics_background_gc(this->gr, this->bg);
+       osd_set_std_graphic(nav, &this->osd_item);
 
-       this->white=graphics_gc_new(this->gr);
-       c.r=65535; c.g=65535; c.b=65535; c.a=65535;
-       graphics_gc_set_foreground(this->white, &c);
-       graphics_gc_set_linewidth(this->white, 2);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_distance_to_target_draw),
+                                              attr_position_coord_geo,
+                                              this));
 
-       this->font=graphics_font_new(this->gr, this->font_size*10, 1);
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_navigation_draw), attr_position_coord_geo, this));
+       osd_nav_distance_to_target_draw(this, nav, NULL);
 
-       osd_navigation_draw(this, nav, NULL);
 }
 
 static struct osd_priv *
-osd_navigation_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+osd_nav_distance_to_target_new(struct navit *nav, struct osd_methods *meth,
+                              struct attr **attrs)
 {
-       struct osd_navigation *this=g_new0(struct osd_navigation, 1);
+       struct osd_nav_distance_to_target *this =
+           g_new0(struct osd_nav_distance_to_target, 1);
        struct attr *attr;
-       this->p.x=20;
-       this->p.y=-80;
-       this->w=60;
-       this->h=60;
-       this->icon_w=-1;
-       this->icon_h=-1;
-       this->font_size=20;
-       this->active=-1;
-       attr=attr_search(attrs, NULL, attr_x);
-       if (attr)
-               this->p.x=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_y);
-       if (attr)
-               this->p.y=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_font_size);
-       if (attr)
-               this->font_size=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_icon_w);
+
+       osd_set_std_attr(attrs, &this->osd_item);
+
+       this->active = -1;
+
+       attr = attr_search(attrs, NULL, attr_label);
        if (attr)
-               this->icon_w=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_icon_h);
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_distance_to_target_init),
+                                              attr_navit, this));
+       return (struct osd_priv *) this;
+}
+
+struct osd_nav_distance_to_next {
+       struct osd_item osd_item;
+       int active;
+       char last_distance[16];
+       char *test_text;
+};
+
+static void
+osd_nav_distance_to_next_draw(struct osd_nav_distance_to_next *this,
+                             struct navit *navit, struct vehicle *v)
+{
+       struct point p, p2[4];
+       char distance[16];
+       int do_draw = 0;
+       struct attr attr;
+       struct navigation *nav = NULL;
+       struct map *map = NULL;
+       struct map_rect *mr = NULL;
+       struct item *item = NULL;
+
+       distance[0] = '\0';
+
+       if (navit)
+               nav = navit_get_navigation(navit);
+       if (nav)
+               map = navigation_get_map(nav);
+       if (map)
+               mr = map_rect_new(map, NULL);
+       if (mr)
+               while ((item = map_rect_get_item(mr))
+                      && item->type == type_nav_position);
+
+       if (item) {
+               if (item_attr_get(item, attr_length, &attr)) {
+                       format_distance(distance, attr.u.num);
+               }
+               if (this->active != 1
+                   || strcmp(this->last_distance, distance)) {
+                       this->active = 1;
+                       strcpy(this->last_distance, distance);
+                       do_draw = 1;
+               }
+       } else {
+               if (this->active != 0) {
+                       this->active = 0;
+                       do_draw = 1;
+               }
+       }
+       if (mr)
+               map_rect_destroy(mr);
+
+       if (do_draw || this->test_text) {
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       32767, 32767);
+               if (this->active || this->test_text) {
+                       if (this->test_text) {
+                               graphics_get_text_bbox(this->osd_item.gr,
+                                                      this->osd_item.font,
+                                                      this->test_text,
+                                                      0x10000, 0x0, p2,
+                                                      0);
+                               p.y =
+                                   ((p2[0].y - p2[2].y) / 2) +
+                                   (this->osd_item.h / 2);
+                               graphics_draw_text(this->osd_item.gr,
+                                                  this->osd_item.
+                                                  graphic_fg_white, NULL,
+                                                  this->osd_item.font,
+                                                  this->test_text, &p,
+                                                  0x10000, 0);
+                       } else if (distance) {
+                               graphics_get_text_bbox(this->osd_item.gr,
+                                                      this->osd_item.font,
+                                                      distance, 0x10000,
+                                                      0x0, p2, 0);
+                               p.y =
+                                   ((p2[0].y - p2[2].y) / 2) +
+                                   (this->osd_item.h / 2);
+                               graphics_draw_text(this->osd_item.gr,
+                                                  this->osd_item.
+                                                  graphic_fg_white, NULL,
+                                                  this->osd_item.font,
+                                                  distance, &p, 0x10000,
+                                                  0);
+                       }
+               }
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
+       }
+}
+
+static void
+osd_nav_distance_to_next_init(struct osd_nav_distance_to_next *this,
+                             struct navit *nav)
+{
+       osd_set_std_graphic(nav, &this->osd_item);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_distance_to_next_draw),
+                                              attr_position_coord_geo,
+                                              this));
+       osd_nav_distance_to_next_draw(this, nav, NULL);
+}
+
+static struct osd_priv *
+osd_nav_distance_to_next_new(struct navit *nav, struct osd_methods *meth,
+                            struct attr **attrs)
+{
+       struct osd_nav_distance_to_next *this =
+           g_new0(struct osd_nav_distance_to_next, 1);
+       struct attr *attr;
+
+       osd_set_std_attr(attrs, &this->osd_item);
+       this->active = -1;
+
+       attr = attr_search(attrs, NULL, attr_label);
        if (attr)
-               this->icon_h=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_icon_src);
-       if (attr) {
-               struct file_wordexp *we;
-               char **array;
-               we=file_wordexp_new(attr->u.str);
-               array=file_wordexp_get_array(we);
-               this->icon_src=g_strdup(array[0]);
-               file_wordexp_destroy(we);
-       } else
-               this->icon_src=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/%s_32.xpm", NULL);
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_navigation_init), attr_navit, this));
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_distance_to_next_init),
+                                              attr_navit, this));
        return (struct osd_priv *) this;
 }
 
 struct osd_street_name {
-       struct point p;
-       int w,h;
-       struct graphics *gr;
-       struct graphics_gc *bg;
-       struct graphics_gc *white;
-       struct graphics_font *font;
+       struct osd_item osd_item;
        int active;
        struct item item;
+       char *test_text;
 };
 
 static void
-osd_street_name_draw(struct osd_street_name *this, struct navit *navit, struct vehicle *v)
+osd_street_name_draw(struct osd_street_name *this, struct navit *navit,
+                    struct vehicle *v)
 {
-       struct point p;
+       struct point p, p2[4];
        char distance[16];
-       int do_draw=0;
+       int do_draw = 0;
        struct attr attr_name1, attr_name2;
-       char *name1=NULL,*name2=NULL;
-       struct tracking *tr=NULL;
-       struct map_rect *mr=NULL;
-       struct item *item=NULL;
-       char *name=NULL;
-
-       distance[0]='\0';
-       if (navit) 
-               tr=navit_get_tracking(navit);
+       char *name1 = NULL, *name2 = NULL;
+       struct tracking *tr = NULL;
+       struct map_rect *mr = NULL;
+       struct item *item = NULL;
+       char *name = NULL;
+
+       distance[0] = '\0';
+       if (navit)
+               tr = navit_get_tracking(navit);
+
        if (tr)
-               item=tracking_get_current_item(tr);
-       dbg(1,"navit=%p tr=%p item=%p\n", navit, tr, item);
+               item = tracking_get_current_item(tr);
+
+       dbg(1, "navit=%p tr=%p item=%p\n", navit, tr, item);
        if (item) {
                if (!item_is_equal(*item, this->item)) {
-                       do_draw=1;
-                       this->item=*item;
-                       mr=map_rect_new(item->map,NULL);
-                       item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
-                       if (item_attr_get(item, attr_street_name, &attr_name1))
-                               name1=map_convert_string(item->map, attr_name1.u.str);
-                       if (item_attr_get(item, attr_street_name_systematic, &attr_name2))
-                               name2=map_convert_string(item->map, attr_name2.u.str);
+                       do_draw = 1;
+                       this->item = *item;
+                       mr = map_rect_new(item->map, NULL);
+                       item =
+                           map_rect_get_item_byid(mr, item->id_hi,
+                                                  item->id_lo);
+                       if (item_attr_get
+                           (item, attr_street_name, &attr_name1))
+                               name1 =
+                                   map_convert_string(item->map,
+                                                      attr_name1.u.str);
+                       if (item_attr_get
+                           (item, attr_street_name_systematic,
+                            &attr_name2))
+                               name2 =
+                                   map_convert_string(item->map,
+                                                      attr_name2.u.str);
                        printf("name1=%s name2=%s\n", name1, name2);
-                       map_rect_destroy(mr);
+                       map_rect_destroy(mr);
                        if (name1 && name2)
-                               name=g_strdup_printf("%s/%s", name2,name1);
+                               name =
+                                   g_strdup_printf("%s/%s", name2, name1);
                        else
-                               name=g_strdup(name1?name1:name2);
+                               name = g_strdup(name1 ? name1 : name2);
                        map_convert_free(name1);
                        map_convert_free(name2);
-                       this->active=1;
+                       this->active = 1;
                }
        } else {
                if (this->item.map || this->active)
-                       do_draw=1;
-               this->active=0;
+                       do_draw = 1;
+               this->active = 0;
                memset(&this->item, 0, sizeof(this->item));
-               name=NULL;
+               name = NULL;
        }
+
        if (do_draw) {
-               dbg(1,"name=%s\n", name);
-               graphics_draw_mode(this->gr, draw_mode_begin);
-               p.x=0;
-               p.y=0;
-               graphics_draw_rectangle(this->gr, this->bg, &p, 32767, 32767);
-               if (name) {
-                       p.x=2;
-                       p.y=12;
-                       graphics_draw_text(this->gr, this->white, NULL, this->font, name, &p, 0x10000, 0);
-               }
-               graphics_draw_mode(this->gr, draw_mode_end);
+               dbg(1, "name=%s\n", name);
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       32767, 32767);
+               if (this->test_text) {
+                       graphics_get_text_bbox(this->osd_item.gr,
+                                              this->osd_item.font,
+                                              this->test_text, 0x10000,
+                                              0x0, p2, 0);
+                       p.y =
+                           ((p2[0].y - p2[2].y) / 2) +
+                           (this->osd_item.h / 2);
+                       graphics_draw_text(this->osd_item.gr,
+                                          this->osd_item.graphic_fg_white,
+                                          NULL, this->osd_item.font,
+                                          this->test_text, &p, 0x10000,
+                                          0);
+               } else if (name) {
+                       graphics_get_text_bbox(this->osd_item.gr,
+                                              this->osd_item.font, name,
+                                              0x10000, 0x0, p2, 0);
+                       p.y =
+                           ((p2[0].y - p2[2].y) / 2) +
+                           (this->osd_item.h / 2);
+                       graphics_draw_text(this->osd_item.gr,
+                                          this->osd_item.graphic_fg_white,
+                                          NULL, this->osd_item.font, name,
+                                          &p, 0x10000, 0);
+               }
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
        }
+       g_free(name);
 }
 
 static void
 osd_street_name_init(struct osd_street_name *this, struct navit *nav)
 {
-       struct graphics *navit_gr;
-       struct color c;
-       navit_gr=navit_get_graphics(nav);
-       this->active=-1;
-       this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h, 65535, 1);
-
-       this->bg=graphics_gc_new(this->gr);
-       c.r=0; c.g=0; c.b=0; c.a=32767;
-       graphics_gc_set_foreground(this->bg, &c);
-       graphics_background_gc(this->gr, this->bg);
-
-       this->white=graphics_gc_new(this->gr);
-       c.r=65535; c.g=65535; c.b=65535; c.a=65535;
-       graphics_gc_set_foreground(this->white, &c);
-
-       this->font=graphics_font_new(this->gr, 200, 1);
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_street_name_draw), attr_position_coord_geo, this));
-
+       osd_set_std_graphic(nav, &this->osd_item);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_street_name_draw),
+                                              attr_position_coord_geo,
+                                              this));
        osd_street_name_draw(this, nav, NULL);
 }
 
 static struct osd_priv *
-osd_street_name_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+osd_street_name_new(struct navit *nav, struct osd_methods *meth,
+                   struct attr **attrs)
 {
-       struct osd_street_name *this=g_new0(struct osd_street_name, 1);
+       struct osd_street_name *this = g_new0(struct osd_street_name, 1);
        struct attr *attr;
-       this->p.x=90;
-       this->p.y=-36;
-       this->w=150;
-       this->h=16;
-       attr=attr_search(attrs, NULL, attr_x);
-       if (attr)
-               this->p.x=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_y);
+
+       osd_set_std_attr(attrs, &this->osd_item);
+
+       attr = attr_search(attrs, NULL, attr_label);
        if (attr)
-               this->p.y=attr->u.num;
-       navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_street_name_init), attr_navit, this));
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       this->active = -1;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_street_name_init),
+                                              attr_navit, this));
        return (struct osd_priv *) this;
 }
 
@@ -635,23 +1116,25 @@ static void
 wrap_point(struct point *p, struct navit *nav)
 {
        if (p->x < 0)
-               p->x+=navit_get_width(nav);
+               p->x += navit_get_width(nav);
        if (p->y < 0)
-               p->y+=navit_get_height(nav);
+               p->y += navit_get_height(nav);
 
 }
 
 static void
-osd_button_click(struct osd_button *this, struct navit *nav, int pressed, int button, struct point *p)
+osd_button_click(struct osd_button *this, struct navit *nav, int pressed,
+                int button, struct point *p)
 {
-       struct point bp=this->p;
+       struct point bp = this->p;
        wrap_point(&bp, this->nav);
-       if ((p->x < bp.x || p->y < bp.y || p->x > bp.x+this->img->width || p->y > bp.y+this->img->height) && !this->pressed)
+       if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->img->width
+            || p->y > bp.y + this->img->height) && !this->pressed)
                return;
        navit_ignore_button(nav);
-       this->pressed=pressed;
+       this->pressed = pressed;
        if (pressed) {
-               dbg(0,"calling command '%s'\n", this->command);
+               dbg(0, "calling command '%s'\n", this->command);
                navit_command_call(nav, this->command);
        }
 }
@@ -659,66 +1142,389 @@ osd_button_click(struct osd_button *this, struct navit *nav, int pressed, int bu
 static void
 osd_button_draw(struct osd_button *this)
 {
-       struct point bp=this->p;
+       struct point bp = this->p;
        wrap_point(&bp, this->nav);
-       graphics_draw_image(this->gra,this->gc, &bp, this->img);
+       graphics_draw_image(this->gra, this->gc, &bp, this->img);
 }
 
 static void
 osd_button_init(struct osd_button *this, struct navit *nav)
 {
-       struct graphics *gra=navit_get_graphics(nav);
-       dbg(1,"enter\n");
-       this->nav=nav;
-       this->gra=gra;
-       this->gc=graphics_gc_new(gra);
-       this->img=graphics_image_new(gra, this->src);
-       if (! this->img) {
-               dbg(0,"failed to load '%s'\n", this->src);
+       struct graphics *gra = navit_get_graphics(nav);
+       dbg(1, "enter\n");
+       this->nav = nav;
+       this->gra = gra;
+       this->gc = graphics_gc_new(gra);
+       this->img = graphics_image_new(gra, this->src);
+       if (!this->img) {
+               dbg(0, "failed to load '%s'\n", this->src);
        } else {
-               navit_add_callback(nav, this->navit_init_cb=callback_new_attr_1(callback_cast(osd_button_click), attr_button, this));
-               graphics_add_callback(gra, this->draw_cb=callback_new_attr_1(callback_cast(osd_button_draw), attr_postdraw, this));
+               navit_add_callback(nav, this->navit_init_cb =
+                                  callback_new_attr_1(callback_cast
+                                                      (osd_button_click),
+                                                      attr_button, this));
+               graphics_add_callback(gra, this->draw_cb =
+                                     callback_new_attr_1(callback_cast
+                                                         (osd_button_draw),
+                                                         attr_postdraw,
+                                                         this));
        }
 }
 
 static struct osd_priv *
-osd_button_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+osd_button_new(struct navit *nav, struct osd_methods *meth,
+              struct attr **attrs)
 {
-       struct osd_button *this=g_new0(struct osd_button, 1);
+       struct osd_button *this = g_new0(struct osd_button, 1);
        struct attr *attr;
-       attr=attr_search(attrs, NULL, attr_x);
+       attr = attr_search(attrs, NULL, attr_x);
        if (attr)
-               this->p.x=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_y);
+               this->p.x = attr->u.num;
+       attr = attr_search(attrs, NULL, attr_y);
        if (attr)
-               this->p.y=attr->u.num;
-       attr=attr_search(attrs, NULL, attr_command);
-       if (! attr) {
-               dbg(0,"no command\n");
+               this->p.y = attr->u.num;
+       attr = attr_search(attrs, NULL, attr_command);
+       if (!attr) {
+               dbg(0, "no command\n");
                goto error;
        }
-       this->command=g_strdup(attr->u.str);
-       attr=attr_search(attrs, NULL, attr_src);
-       if (! attr) {
-               dbg(0,"no src\n");
+       this->command = g_strdup(attr->u.str);
+       attr = attr_search(attrs, NULL, attr_src);
+       if (!attr) {
+               dbg(0, "no src\n");
                goto error;
        }
-       this->src=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/", attr->u.str, NULL);
-       navit_add_callback(nav, this->navit_init_cb=callback_new_attr_1(callback_cast(osd_button_init), attr_navit, this));
-       
+       this->src =
+           g_strjoin(NULL, getenv("NAVIT_SHAREDIR"), "/xpm/", attr->u.str,
+                     NULL);
+       navit_add_callback(nav, this->navit_init_cb =
+                          callback_new_attr_1(callback_cast
+                                              (osd_button_init),
+                                              attr_navit, this));
+
        return (struct osd_priv *) this;
-error:
+      error:
        g_free(this);
        return NULL;
 }
 
+struct nav_next_turn {
+       struct osd_item osd_item;
+       char *test_text;
+       char *icon_src;
+       int icon_h, icon_w, active;
+       char *last_name;
+};
+
+static void
+osd_nav_next_turn_draw(struct nav_next_turn *this, struct navit *navit,
+                      struct vehicle *v)
+{
+       struct point p;
+       int do_draw = 0;
+       struct navigation *nav = NULL;
+       struct map *map = NULL;
+       struct map_rect *mr = NULL;
+       struct item *item = NULL;
+       struct graphics_image *gr_image;
+       char *image;
+       char *name = "unknown";
+
+
+       if (navit)
+               nav = navit_get_navigation(navit);
+       if (nav)
+               map = navigation_get_map(nav);
+       if (map)
+               mr = map_rect_new(map, NULL);
+       if (mr)
+               while ((item = map_rect_get_item(mr))
+                      && item->type == type_nav_position);
+
+       if (item && item->type != type_nav_destination) {
+               name = item_to_name(item->type);
+               dbg(0, "name=%s\n", name);
+               if (this->active != 1 || this->last_name != name) {
+                       this->active = 1;
+                       this->last_name = name;
+                       do_draw = 1;
+               }
+       } else {
+               if (this->active != 0) {
+                       this->active = 0;
+                       do_draw = 1;
+               }
+       }
+       if (mr)
+               map_rect_destroy(mr);
+
+       if (do_draw) {
+               graphics_draw_mode(this->osd_item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+               graphics_draw_rectangle(this->osd_item.gr,
+                                       this->osd_item.graphic_bg, &p,
+                                       this->osd_item.w,
+                                       this->osd_item.h);
+               if (this->active) {
+                       image = g_strdup_printf(this->icon_src, name);
+                       dbg(0, "image=%s\n", image);
+                       gr_image =
+                           graphics_image_new_scaled(this->osd_item.gr,
+                                                     image, this->icon_w,
+                                                     this->icon_h);
+                       if (!gr_image) {
+                               g_free(image);
+                               image =
+                                   g_strjoin(NULL,
+                                             getenv("NAVIT_SHAREDIR"),
+                                             "/xpm/unknown.xpm", NULL);
+                               gr_image =
+                                   graphics_image_new_scaled(this->
+                                                             osd_item.gr,
+                                                             image,
+                                                             this->icon_w,
+                                                             this->
+                                                             icon_h);
+                       }
+                       dbg(1, "gr_image=%p\n", gr_image);
+                       if (gr_image) {
+                               p.x =
+                                   (this->osd_item.w -
+                                    gr_image->width) / 2;
+                               p.y =
+                                   (this->osd_item.h -
+                                    gr_image->height) / 2;
+                               graphics_draw_image(this->osd_item.gr,
+                                                   this->osd_item.
+                                                   graphic_fg_white, &p,
+                                                   gr_image);
+                               graphics_image_free(this->osd_item.gr,
+                                                   gr_image);
+                       }
+                       g_free(image);
+               }
+               graphics_draw_mode(this->osd_item.gr, draw_mode_end);
+       }
+}
+
+static void
+osd_nav_next_turn_init(struct nav_next_turn *this, struct navit *nav)
+{
+       osd_set_std_graphic(nav, &this->osd_item);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_next_turn_draw),
+                                              attr_position_coord_geo,
+                                              this));
+       osd_nav_next_turn_draw(this, nav, NULL);
+}
+
+static struct osd_priv *
+osd_nav_next_turn_new(struct navit *nav, struct osd_methods *meth,
+                     struct attr **attrs)
+{
+       struct nav_next_turn *this = g_new0(struct nav_next_turn, 1);
+       struct attr *attr;
+
+       osd_set_std_attr(attrs, &this->osd_item);
+
+       this->icon_w = -1;
+       this->icon_h = -1;
+       this->active = -1;
+
+       attr = attr_search(attrs, NULL, attr_icon_w);
+       if (attr)
+               this->icon_w = attr->u.num;
+
+       attr = attr_search(attrs, NULL, attr_icon_h);
+       if (attr)
+               this->icon_h = attr->u.num;
+
+       attr = attr_search(attrs, NULL, attr_icon_src);
+       if (attr) {
+               struct file_wordexp *we;
+               char **array;
+               we = file_wordexp_new(attr->u.str);
+               array = file_wordexp_get_array(we);
+               this->icon_src = g_strdup(array[0]);
+               file_wordexp_destroy(we);
+       } else
+               this->icon_src =
+                   g_strjoin(NULL, getenv("NAVIT_SHAREDIR"),
+                             "/xpm/%s_32.xpm", NULL);
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_next_turn_init),
+                                              attr_navit, this));
+       return (struct osd_priv *) this;
+}
+
+struct nav_next_street_name {
+       struct osd_item item;
+       int active;
+       char *last_street_name;
+       char *test_text;
+};
+
+static void
+osd_nav_next_street_name_draw(struct nav_next_street_name *this,
+                             struct navit *navit)
+{
+
+       int do_draw = 0;
+       char *name_next = NULL;
+       struct navigation *nav = NULL;
+       struct map *map = NULL;
+       struct map_rect *mr = NULL;
+       struct item *item = NULL;
+       struct attr attr;
+       struct point p, p2[4];
+
+       if (navit)
+               nav = navit_get_navigation(navit);
+
+       if (nav)
+               map = navigation_get_map(nav);
+
+       if (map)
+               mr = map_rect_new(map, NULL);
+
+       if (mr)
+               while ((item = map_rect_get_item(mr))
+                      && item->type == type_nav_position);
+
+       if (item && item_attr_get(item, attr_street_name, &attr)) {
+               if (item->type == type_nav_destination) {
+                       name_next = _("reaching destination");
+               } else {
+                       name_next = attr.u.str;
+               }
+
+               if (this->active != 1
+                   || strcmp(this->last_street_name, name_next)) {
+                       this->active = 1;
+                       if (this->last_street_name)
+                               g_free(this->last_street_name);
+                       this->last_street_name = g_strdup(name_next);
+                       do_draw = 1;
+               }
+       } else {
+               if (this->active != 0) {
+                       this->active = 0;
+                       do_draw = 1;
+               }
+       }
+
+       if (mr)
+               map_rect_destroy(mr);
+
+       if (do_draw || this->test_text) {
+               graphics_draw_mode(this->item.gr, draw_mode_begin);
+               p.x = 0;
+               p.y = 0;
+
+               graphics_draw_rectangle(this->item.gr,
+                                       this->item.graphic_bg, &p, 32767,
+                                       32767);
+               if (this->active) {
+                       if (name_next) {
+                               graphics_get_text_bbox(this->item.gr,
+                                                      this->item.font,
+                                                      name_next, 0x10000,
+                                                      0x0, p2, 0);
+                               p.y =
+                                   ((p2[0].y - p2[2].y) / 2) +
+                                   (this->item.h / 2);
+                               graphics_draw_text(this->item.gr,
+                                                  this->item.
+                                                  graphic_fg_white, NULL,
+                                                  this->item.font,
+                                                  name_next, &p, 0x10000,
+                                                  0);
+                       }
+               } else if (this->test_text) {
+                       graphics_get_text_bbox(this->item.gr,
+                                              this->item.font,
+                                              this->test_text, 0x10000,
+                                              0x0, p2, 0);
+                       p.y =
+                           ((p2[0].y - p2[2].y) / 2) + (this->item.h / 2);
+                       graphics_draw_text(this->item.gr,
+                                          this->item.graphic_fg_white,
+                                          NULL, this->item.font,
+                                          this->test_text, &p, 0x10000,
+                                          0);
+               }
+               graphics_draw_mode(this->item.gr, draw_mode_end);
+       }
+
+}
+
+static void
+osd_nav_next_street_name_init(struct nav_next_street_name *this,
+                             struct navit *nav)
+{
+
+       osd_set_std_graphic(nav, &this->item);
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_next_street_name_draw),
+                                              attr_position_coord_geo,
+                                              this));
+       osd_nav_next_street_name_draw(this, nav);
+}
+
+static struct osd_priv *
+osd_nav_next_street_name_new(struct navit *nav, struct osd_methods *meth,
+                            struct attr **attrs)
+{
+
+       struct nav_next_street_name *this =
+           g_new0(struct nav_next_street_name, 1);
+       struct attr *attr;
+
+       osd_set_std_attr(attrs, &this->item);
+
+       attr = attr_search(attrs, NULL, attr_label);
+       if (attr)
+               this->test_text = g_strdup(attr->u.str);
+       else
+               this->test_text = NULL;
+
+       this->active = -1;
+       this->last_street_name = NULL;
+
+       navit_add_callback(nav,
+                          callback_new_attr_1(callback_cast
+                                              (osd_nav_next_street_name_init),
+                                              attr_navit, this));
+       return (struct osd_priv *) this;
+}
+
 void
 plugin_init(void)
 {
        plugin_register_osd_type("compass", osd_compass_new);
        plugin_register_osd_type("eta", osd_eta_new);
-       plugin_register_osd_type("navigation", osd_navigation_new);
+       plugin_register_osd_type("navigation_distance_to_target",
+                                osd_nav_distance_to_target_new);
+       plugin_register_osd_type("navigation_distance_to_next",
+                                osd_nav_distance_to_next_new);
+       plugin_register_osd_type("navigation_next_turn",
+                                osd_nav_next_turn_new);
        plugin_register_osd_type("street_name", osd_street_name_new);
+       plugin_register_osd_type("navigation_next_street_name",
+                                osd_nav_next_street_name_new);
        plugin_register_osd_type("button", osd_button_new);
-}
+       plugin_register_osd_type("vehicle_gps_satnum", osd_sats_new);
+       plugin_register_osd_type("vehicle_speed", osd_speed_new);
 
+/*
+        plugin_register_osd_type("navigation_distance_to_target", osd_nav_distance_to_target_new);
+        plugin_register_osd_type("navigation_distance_to_next", osd_nav_distance_to_next_new);
+        plugin_register_osd_type("position_max_speed", osd_position_max_speed_new);
+        plugin_register_osd_type("vehicle_pos", osd_vehicle_pos_new);
+*/
+}
index 8f54961..2025fda 100644 (file)
@@ -46,6 +46,7 @@ static struct vehicle_priv {
        int fix_type;
        time_t fix_time;
        int sats;
+        int sats_signal;
        int sats_used;
        char *nmea_data;
        char *nmea_data_buf;
@@ -67,6 +68,8 @@ vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
                      int level)
 {
        char *pos,*nmea_data_buf;
+        int i=0,sats_signal=0;
+       
        struct vehicle_priv *priv = vehicle_last;
        if (buf[0] == '$' && len > 0) {
                char buffer[len+2];
@@ -85,13 +88,10 @@ vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
                }
        }       
        dbg(1,"data->set=0x%x\n", data->set);
-       // If data->fix.speed is NAN, then the drawing gets jumpy. 
-       if (isnan(data->fix.speed)) {
-               return;
-       }
-       dbg(2,"speed ok\n");
        if (data->set & SPEED_SET) {
                priv->speed = data->fix.speed * 3.6;
+               if(!isnan(data->fix.speed))
+                       callback_list_call_attr_0(priv->cbl, attr_position_speed);
                data->set &= ~SPEED_SET;
        }
        if (data->set & TRACK_SET) {
@@ -103,8 +103,19 @@ vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
                data->set &= ~ALTITUDE_SET;
        }
        if (data->set & SATELLITE_SET) {
-               priv->sats_used = data->satellites_used;
-               priv->sats = data->satellites;
+                if(data->satellites > 0) {
+                        sats_signal=0;
+                        for( i=0;i<data->satellites;i++) {
+                               if (data->ss[i] > 0)
+                                        sats_signal++;
+                        }
+                }
+               if (priv->sats_used != data->satellites_used || priv->sats != data->satellites || priv->sats_signal != sats_signal ) {
+                       priv->sats_used = data->satellites_used;
+                       priv->sats = data->satellites;
+                        priv->sats_signal = sats_signal;
+                       callback_list_call_attr_0(priv->cbl, attr_position_sats);
+               }
                data->set &= ~SATELLITE_SET;
        }
        if (data->set & STATUS_SET) {
@@ -131,9 +142,13 @@ vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
                g_free(priv->nmea_data);
                priv->nmea_data=priv->nmea_data_buf;
                priv->nmea_data_buf=NULL;
-               callback_list_call_0(priv->cbl);
                data->set &= ~LATLON_SET;
        }
+       // If data->fix.speed is NAN, then the drawing gets jumpy.
+       if (! isnan(data->fix.speed) && priv->fix_type > 0) {
+               callback_list_call_0(priv->cbl);
+       }
+       dbg(2,"speed ok\n");
 }
 
 /**
@@ -258,6 +273,9 @@ vehicle_gpsd_position_attr_get(struct vehicle_priv *priv,
        case attr_position_qual:
                attr->u.num = priv->sats;
                break;
+       case attr_position_sats_signal:
+               attr->u.num = priv->sats_signal;
+               break;
        case attr_position_sats_used:
                attr->u.num = priv->sats_used;
                break;