From: martin-s Date: Tue, 18 Dec 2007 19:40:39 +0000 (+0000) Subject: Modularized vehicle X-Git-Url: https://vcs.maemo.org/git/?a=commitdiff_plain;h=4c9052fd6946e6761a96c7e1beba07d59c1c75e1;p=navit-package Modularized vehicle git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@650 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- diff --git a/configure.in b/configure.in index f28139c..b7ecaf5 100644 --- a/configure.in +++ b/configure.in @@ -397,6 +397,7 @@ src/speech/speech_dispatcher/Makefile src/vehicle/Makefile src/vehicle/file/Makefile src/vehicle/gpsd/Makefile +src/vehicle/demo/Makefile src/xpm/Makefile src/maps/Makefile intl/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index f09a337..a437b31 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,6 +26,6 @@ navit_SOURCES = attr.c callback.c compass.c coord.c country.c cursor.c data_wind osm2navit_SOURCES = osm2navit.c item.c debug.c zipfile.h -navit_LDADD = @NAVIT_LIBS@ @GPSD_LIBS@ @ZLIB_LIBS@ -Lfib-1.1 -lfib +navit_LDADD = @NAVIT_LIBS@ @ZLIB_LIBS@ -Lfib-1.1 -lfib osm2navit_LDADD = @NAVIT_LIBS@ @ZLIB_LIBS@ diff --git a/src/attr.c b/src/attr.c index 9668b55..8feecd7 100644 --- a/src/attr.c +++ b/src/attr.c @@ -1,8 +1,10 @@ #include #include +#include #include #include "debug.h" #include "item.h" +#include "color.h" #include "attr.h" struct attr_name { @@ -59,13 +61,34 @@ attr_new_from_text(const char *name, const char *value) break; default: if (attr >= attr_type_string_begin && attr <= attr_type_string_end) { - ret->u.str=value; + ret->u.str=(char *)value; break; } if (attr >= attr_type_int_begin && attr <= attr_type_int_end) { ret->u.num=atoi(value); break; } + if (attr >= attr_type_color_begin && attr <= attr_type_color_end) { + struct color *color=g_new0(struct color, 1); + int r,g,b,a; + ret->u.color=color; + if(strlen(value)==7){ + sscanf(value,"#%02x%02x%02x", &r, &g, &b); + color->r = (r << 8) | r; + color->g = (g << 8) | g; + color->b = (b << 8) | b; + color->a = (65535); + } else if(strlen(value)==9){ + sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a); + color->r = (r << 8) | r; + color->g = (g << 8) | g; + color->b = (b << 8) | b; + color->a = (a << 8) | a; + } else { + dbg(0,"color %s has unknown format\n",value); + } + break; + } dbg(1,"default\n"); g_free(ret); ret=NULL; @@ -125,5 +148,7 @@ attr_data_set(struct attr *attr, void *data) void attr_free(struct attr *attr) { + if (attr->type >= attr_type_color_begin && attr->type <= attr_type_color_end) + g_free(attr->u.color); g_free(attr); } diff --git a/src/attr.h b/src/attr.h index 0d0b7df..13b935c 100644 --- a/src/attr.h +++ b/src/attr.h @@ -31,6 +31,12 @@ struct attr { int num; struct item *item; enum item_type item_type; + double * numd; + struct color *color; + struct coord_geo *coord_geo; + struct navit *navit; + struct callback *callback; + struct log *log; } u; }; diff --git a/src/attr_def.h b/src/attr_def.h index 07efff5..b8221ed 100644 --- a/src/attr_def.h +++ b/src/attr_def.h @@ -24,8 +24,14 @@ ATTR(flush_size) ATTR(flush_time) ATTR(zipfile_ref) ATTR(country_id) +ATTR(position_sats) +ATTR(position_sats_used) +ATTR(update) +ATTR(follow) +ATTR2(0x00028000,type_boolean_begin) /* boolean */ ATTR(overwrite) +ATTR(active) ATTR2(0x0002ffff,type_int_end) ATTR2(0x00030000,type_string_begin) ATTR(type) @@ -63,5 +69,23 @@ ATTR(navigation_short) ATTR(navigation_long) ATTR(navigation_long_exact) ATTR(navigation_speech) +ATTR(name) +ATTR(source) ATTR2(0x0003ffff,type_string_end) ATTR(order_limit) +ATTR2(0x00050000,type_double_start) +ATTR(position_height) +ATTR(position_speed) +ATTR(position_direction) +ATTR2(0x0005ffff,type_double_end) +ATTR2(0x00060000,type_coord_geo_start) +ATTR(position_coord_geo) +ATTR2(0x0006ffff,type_coord_geo_end) +ATTR2(0x00070000,type_color_begin) +ATTR(color) +ATTR2(0x0007ffff,type_color_end) +ATTR2(0x00080000,type_object_begin) +ATTR(navit) +ATTR(log) +ATTR(callback) +ATTR2(0x0008ffff,type_object_end) diff --git a/src/cursor.c b/src/cursor.c index ba7051a..109315e 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -26,64 +26,37 @@ struct cursor { struct graphics *gra; struct graphics_gc *cursor_gc; - struct transformation *trans; struct point cursor_pnt; - struct callback_list *update_cbl; - struct vehicle *v; - struct callback *vehicle_cb; - int dir; - int speed; - struct coord pos; - enum projection pro; }; -struct coord * -cursor_pos_get(struct cursor *this) -{ - return &this->pos; -#if 0 - return vehicle_pos_get(this->v); -#endif -} - void -cursor_pos_set(struct cursor *this, struct coord *pos) +cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int force) { - this->pos=*pos; -#if 0 - return vehicle_pos_get(this->v); -#endif -} - - -static void -cursor_draw(struct cursor *this, struct point *pnt, int dir, int draw_dir) -{ - int x=this->cursor_pnt.x; - int y=this->cursor_pnt.y; + int x=this_->cursor_pnt.x; + int y=this_->cursor_pnt.y; int r=12,lw=2; double dx,dy; double fac1,fac2; struct point cpnt[3]; - struct graphics *gra=this->gra; + struct graphics *gra=this_->gra; - if (pnt && x == pnt->x && y == pnt->y) + if (pnt && x == pnt->x && y == pnt->y && !force) return; if (!graphics_ready(gra)) return; - cpnt[0]=this->cursor_pnt; + cpnt[0]=this_->cursor_pnt; cpnt[0].x-=r+lw; cpnt[0].y-=r+lw; graphics_draw_restore(gra, &cpnt[0], (r+lw)*2, (r+lw)*2); if (pnt) { graphics_draw_mode(gra, draw_mode_cursor); - this->cursor_pnt=*pnt; + this_->cursor_pnt=*pnt; x=pnt->x; y=pnt->y; cpnt[0].x=x; cpnt[0].y=y; - graphics_draw_circle(gra, this->cursor_gc, &cpnt[0], r*2); + graphics_draw_circle(gra, this_->cursor_gc, &cpnt[0], r*2); if (draw_dir) { dx=sin(M_PI*dir/180.0); dy=-cos(M_PI*dir/180.0); @@ -96,162 +69,31 @@ cursor_draw(struct cursor *this, struct point *pnt, int dir, int draw_dir) cpnt[1].y=y+dy*r; cpnt[2].x=x-dx*fac1-dy*fac2; cpnt[2].y=y-dy*fac1+dx*fac2; - graphics_draw_lines(gra, this->cursor_gc, cpnt, 3); + graphics_draw_lines(gra, this_->cursor_gc, cpnt, 3); } else { cpnt[1]=cpnt[0]; - graphics_draw_lines(gra, this->cursor_gc, cpnt, 2); + graphics_draw_lines(gra, this_->cursor_gc, cpnt, 2); } graphics_draw_mode(gra, draw_mode_end); } } -void -cursor_redraw(struct cursor *this) -{ - struct point pnt; - transform(this->trans, this->pro, &this->pos, &pnt); - cursor_draw(this, &pnt, this->dir-transform_get_angle(this->trans, 0), this->speed > 2.5); -} - -#if 0 -static void -cursor_map_reposition_screen(struct cursor *this, struct coord *c, double *dir, int x_new, int y_new) -{ - struct coord c_new; - struct transformation tr; - struct point pnt; - unsigned long scale; - long x,y; - int dir_i; - struct container *co=this->co; - - if (dir) - dir_i=*dir; - else - dir_i=0; - - pnt.x=co->trans->width-x_new; - pnt.y=co->trans->height-y_new; - graphics_get_view(co, &x, &y, &scale); - tr=*this->co->trans; - transform_setup(&tr, c->x, c->y, scale, dir_i); - transform_reverse(&tr, &pnt, &c_new); - printf("%lx %lx vs %lx %lx\n", c->x, c->y, c_new.x, c_new.y); - x=c_new.x; - y=c_new.y; - transform_set_angle(co->trans,dir_i); - graphics_set_view(co, &x, &y, &scale); -} - -static void -cursor_map_reposition(struct cursor *this, struct coord *c, double *dir) -{ - if (this->co->flags->orient_north) { - graphics_set_view(this->co, &c->x, &c->y, NULL); - } else { - cursor_map_reposition_screen(this, c, dir, this->co->trans->width/2, this->co->trans->height*0.8); - } -} - -static int -cursor_map_reposition_boundary(struct cursor *this, struct coord *c, double *dir, struct point *pnt) -{ - struct point pnt_new; - struct transformation *t=this->co->trans; - - pnt_new.x=-1; - pnt_new.y=-1; - if (pnt->x < 0.1*t->width) { - pnt_new.x=0.8*t->width; - pnt_new.y=t->height/2; - } - if (pnt->x > 0.9*t->width) { - pnt_new.x=0.2*t->width; - pnt_new.y=t->height/2; - } - if (pnt->y < (this->co->flags->orient_north ? 0.1 : 0.5)*t->height) { - pnt_new.x=t->width/2; - pnt_new.y=0.8*t->height; - } - if (pnt->y > 0.9*t->height) { - pnt_new.x=t->width/2; - pnt_new.y=0.2*t->height; - } - if (pnt_new.x != -1) { - if (this->co->flags->orient_north) { - cursor_map_reposition_screen(this, c, NULL, pnt_new.x, pnt_new.y); - } else { - cursor_map_reposition(this, c, dir); - } - return 1; - } - return 0; -} - -#endif - -int -cursor_get_dir(struct cursor *this) -{ - return this->dir; -} - -int -cursor_get_speed(struct cursor *this) -{ - return this->speed; -} - -static void -cursor_update(struct cursor *this, struct vehicle *v) -{ - struct point pnt; - struct coord *pos; - double *dir; - double *speed; - enum projection pro; - - if (v) { - pos=vehicle_pos_get(v); - dir=vehicle_dir_get(v); - speed=vehicle_speed_get(v); - pro=vehicle_projection(v); - this->dir=*dir; - this->speed=*speed; - this->pos=*pos; - this->pro=pro; - callback_list_call_1(this->update_cbl, this); - transform(this->trans, pro, &this->pos, &pnt); - cursor_draw(this, &pnt, *dir-transform_get_angle(this->trans, 0), *speed > 2.5); - } -#if 0 - compass_draw(this->co->compass, this->co); -#endif -} - struct cursor * -cursor_new(struct graphics *gra, struct vehicle *v, struct color *c, struct transformation *t) +cursor_new(struct graphics *gra, struct color *c) { - dbg(2,"enter gra=%p v=%p c=%p t=%p\n", gra, v, c, t); + dbg(2,"enter gra=%p c=%p\n", gra, c); struct cursor *this=g_new(struct cursor,1); -#if 0 - this->offscreen_cbl=callback_list_new(); -#endif - this->update_cbl=callback_list_new(); this->gra=gra; - this->trans=t; this->cursor_gc=graphics_gc_new(gra); - this->v=v; graphics_gc_set_foreground(this->cursor_gc, c); graphics_gc_set_linewidth(this->cursor_gc, 2); - this->vehicle_cb=callback_new_1(callback_cast(cursor_update), this); - vehicle_callback_add(v, this->vehicle_cb); dbg(2,"ret=%p\n", this); return this; } void -cursor_add_callback(struct cursor *this, struct callback *cb) +cursor_destroy(struct cursor *this_) { - callback_list_add(this->update_cbl, cb); + graphics_gc_destroy(this_->cursor_gc); + g_free(this_); } diff --git a/src/cursor.h b/src/cursor.h index ee64d8f..7e7ec5e 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -2,20 +2,13 @@ #define NAVIT_CURSOR_H /* prototypes */ -struct callback; struct color; -struct coord; struct cursor; struct graphics; -struct transformation; -struct vehicle; -struct coord *cursor_pos_get(struct cursor *this); -void cursor_pos_set(struct cursor *this, struct coord *pos); -void cursor_redraw(struct cursor *this); -int cursor_get_dir(struct cursor *this); -int cursor_get_speed(struct cursor *this); -struct cursor *cursor_new(struct graphics *gra, struct vehicle *v, struct color *c, struct transformation *t); -void cursor_add_callback(struct cursor *this, struct callback *cb); +struct point; +void cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int force); +struct cursor *cursor_new(struct graphics *gra, struct color *c); +void cursor_destroy(struct cursor *this_); /* end of prototypes */ #endif diff --git a/src/graphics.c b/src/graphics.c index 87ac508..5904c4e 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -115,6 +115,12 @@ graphics_gc_new(struct graphics *gra) } void +graphics_gc_destroy(struct graphics_gc *gc) +{ + gc->meth.gc_destroy(gc->priv); +} + +void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c) { gc->meth.gc_set_foreground(gc->priv, c); diff --git a/src/graphics.h b/src/graphics.h index a657e61..33ccd18 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -96,8 +96,6 @@ struct graphics_gc; struct graphics_image; struct item; struct point; -struct route; -struct transformation; struct graphics *graphics_new(const char *type, struct attr **attrs); struct graphics *graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h); void graphics_init(struct graphics *this_); @@ -107,6 +105,7 @@ void graphics_register_button_callback(struct graphics *this_, void (*callback)( void graphics_register_motion_callback(struct graphics *this_, void (*callback)(void *data, struct point *p), void *data); struct graphics_font *graphics_font_new(struct graphics *gra, int size); struct graphics_gc *graphics_gc_new(struct graphics *gra); +void graphics_gc_destroy(struct graphics_gc *gc); void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c); void graphics_gc_set_background(struct graphics_gc *gc, struct color *c); void graphics_gc_set_linewidth(struct graphics_gc *gc, int width); @@ -118,9 +117,7 @@ void graphics_draw_circle(struct graphics *this_, struct graphics_gc *gc, struct void graphics_draw_rectangle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int w, int h); void display_add(struct displaylist *displaylist, struct item *item, int count, struct point *pnt, char *label); int graphics_ready(struct graphics *this_); -void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans, GList *layouts, struct route *route); void graphics_displaylist_move(struct displaylist *displaylist, int dx, int dy); -void graphics_draw(struct graphics *gra, struct displaylist *displaylist, GList *mapsets, struct transformation *trans, GList *layouts, struct route *route); struct displaylist_handle *graphics_displaylist_open(struct displaylist *displaylist); struct displayitem *graphics_displaylist_next(struct displaylist_handle *dlh); void graphics_displaylist_close(struct displaylist_handle *dlh); diff --git a/src/gui/gtk/gui_gtk_action.c b/src/gui/gtk/gui_gtk_action.c index 647e9b9..2a7540a 100644 --- a/src/gui/gtk/gui_gtk_action.c +++ b/src/gui/gtk/gui_gtk_action.c @@ -222,7 +222,7 @@ static GtkActionEntry debug_entries[] = { "VisiblePolysAction", NULL, _n("VisiblePolys"), NULL, NULL, G_CALLBACK(visible_polys_action) }, { "VisibleStreetsAction", NULL, _n("VisibleStreets"), NULL, NULL, G_CALLBACK(visible_streets_action) }, { "VisiblePointsAction", NULL, _n("VisiblePoints"), NULL, NULL, G_CALLBACK(visible_points_action) }, - { "VisiblePointsAction", NULL, _n("RouteGraph"), NULL, NULL, G_CALLBACK(visible_routegraph_action) } + { "VisibleRouteGraphAction", NULL, _n("RouteGraph"), NULL, NULL, G_CALLBACK(visible_routegraph_action) } }; static guint n_debug_entries = G_N_ELEMENTS (debug_entries); @@ -371,6 +371,7 @@ static char layout[] = \ \ \ + \ \ \ \ diff --git a/src/gui/sdl/gui_sdl_window.cpp b/src/gui/sdl/gui_sdl_window.cpp index 143c1d0..19f82a9 100644 --- a/src/gui/sdl/gui_sdl_window.cpp +++ b/src/gui/sdl/gui_sdl_window.cpp @@ -712,16 +712,25 @@ static void init_sdlgui(char * skin_layout,int fullscreen,int tilt) static void vehicle_callback_handler( struct navit *nav, struct vehicle *v){ char buffer [50]; - double speed=*vehicle_speed_get(v); - sprintf (buffer, "%02.02f km/h", speed); + struct attr attr; + int sats=0, sats_used=0; + + if (vehicle_position_attr_get(v, attr_position_speed, &attr)) + sprintf (buffer, "%02.02f km/h", *attr.u.numd); + else + strcpy (buffer, "N/A"); CEGUI::WindowManager::getSingleton().getWindow("OSD/SpeedoMeter")->setText(buffer); - double height=*vehicle_height_get(v); - sprintf (buffer, "%.0f m", height); + if (vehicle_position_attr_get(v, attr_position_speed, &attr)) + sprintf (buffer, ".0f m", *attr.u.numd); + else + strcpy (buffer, "N/A"); CEGUI::WindowManager::getSingleton().getWindow("OSD/Altimeter")->setText(buffer); - int sats=*vehicle_sats_get(v); - int sats_used=*vehicle_sats_used_get(v); + if (vehicle_position_attr_get(v, attr_position_sats, &attr)) + sats=attr.u.num; + if (vehicle_position_attr_get(v, attr_position_sats_used, &attr)) + sats_used=attr.u.num; // printf(" sats : %i, used %i: \n",sats,sats_used); // Sat image hardcoded for now. may break the TaharezSkin // setProperty("Image", CEGUI::PropertyHelper::imageToString( yourImageSet->getImage( "yourImageName" ) ) ); diff --git a/src/navit.c b/src/navit.c index 711804a..d1a01aa 100644 --- a/src/navit.c +++ b/src/navit.c @@ -44,14 +44,18 @@ struct navit_vehicle { int update_curr; int follow; int follow_curr; + struct coord coord; + int dir; + int speed; struct color c; struct menu *menu; struct cursor *cursor; struct vehicle *vehicle; - struct callback *update_cb; + struct attr callback; }; struct navit { + struct attr self; GList *mapsets; GList *layouts; struct gui *gui; @@ -95,7 +99,8 @@ struct navit { struct gui *main_loop_gui; -static void navit_cursor_update(struct navit *this_, struct cursor *cursor); +static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv); +static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt); void navit_add_mapset(struct navit *this_, struct mapset *ms) @@ -132,7 +137,7 @@ navit_draw(struct navit *this_) l=this_->vehicles; while (l) { nv=l->data; - cursor_redraw(nv->cursor); + navit_vehicle_draw(this_, nv, NULL); l=g_list_next(l); } this_->ready=1; @@ -307,6 +312,8 @@ navit_new(struct pcoord *center, int zoom) FILE *f; main_add_navit(this_); + this_->self.type=attr_navit; + this_->self.u.navit=this_; this_->vehicle_cbl=callback_list_new(); this_->init_cbl=callback_list_new(); @@ -977,12 +984,13 @@ navit_init(struct navit *this_) graphics_init(this_->gra); l=this_->vehicles; while (l) { - dbg(0,"parsed one vehicle\n"); + dbg(1,"parsed one vehicle\n"); nv=l->data; - nv->cursor=cursor_new(this_->gra, nv->vehicle, &nv->c, this_->trans); - nv->update_cb=callback_new_1(callback_cast(navit_cursor_update), this_); - cursor_add_callback(nv->cursor, nv->update_cb); - vehicle_set_navit(nv->vehicle, this_); + nv->cursor=cursor_new(this_->gra, &nv->c); + nv->callback.type=attr_callback; + nv->callback.u.callback=callback_new_2(callback_cast(navit_vehicle_update), this_, nv); + vehicle_add_attr(nv->vehicle, &nv->callback, NULL); + vehicle_set_attr(nv->vehicle, &this_->self, NULL); l=g_list_next(l); } if (this_->mapsets) { @@ -1106,68 +1114,90 @@ navit_toggle_orient_north(struct navit *this_) */ static void -navit_cursor_update(struct navit *this_, struct cursor *cursor) +navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt) { - struct point pnt; - struct coord *cursor_c=cursor_pos_get(cursor); - struct pcoord pc; - int dir=cursor_get_dir(cursor); - int speed=cursor_get_speed(cursor); + struct point pnt2; enum projection pro; - int border=30; - - if (!this_->vehicle || this_->vehicle->cursor != cursor) - return; + if (pnt) + pnt2=*pnt; + else { + pro=transform_get_projection(this_->trans); + transform(this_->trans, pro, &nv->coord, &pnt2); + } +#if 1 + cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL); +#else + cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, 1); +#endif +} - cursor_c=cursor_pos_get(cursor); - dir=cursor_get_dir(cursor); - speed=cursor_get_speed(cursor); - pro=vehicle_projection(this_->vehicle->vehicle); +static void +navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv) +{ + struct attr attr_dir, attr_speed, attr_pos; + struct pcoord cursor_pc; + struct point cursor_pnt, *pnt=&cursor_pnt; + enum projection pro; + int border=16; - /* This transform is useless cursor and vehicle are in the same projection */ - if (!transform(this_->trans, pro, cursor_c, &pnt) || !transform_within_border(this_->trans, &pnt, border)) { - if (!this_->cursor_flag) - return; - if (this_->orient_north_flag) - navit_set_center_cursor(this_, cursor_c, 0, 50 - 30.*sin(M_PI*dir/180.), 50 + 30.*cos(M_PI*dir/180.)); - else - navit_set_center_cursor(this_, cursor_c, dir, 50, 80); - transform(this_->trans, pro, cursor_c, &pnt); + if (! vehicle_position_attr_get(nv->vehicle, attr_position_direction, &attr_dir) || + ! vehicle_position_attr_get(nv->vehicle, attr_position_speed, &attr_speed) || + ! vehicle_position_attr_get(nv->vehicle, attr_position_coord_geo, &attr_pos)) + return; + nv->dir=*attr_dir.u.numd; + nv->speed=*attr_speed.u.numd; + pro=transform_get_projection(this_->trans); + transform_from_geo(pro, attr_pos.u.coord_geo, &nv->coord); + if (nv != this_->vehicle) { + navit_vehicle_draw(this_, nv, NULL); + return; } - if (this_->pid && speed > 2) - kill(this_->pid, SIGWINCH); if (this_->tracking && this_->tracking_flag) { - struct coord c=*cursor_c; - if (tracking_update(this_->tracking, &c, dir)) { - cursor_c=&c; - cursor_pos_set(cursor, cursor_c); - if (this_->route && this_->vehicle->update_curr == 1) + if (tracking_update(this_->tracking, &nv->coord, nv->dir)) { + if (this_->route && nv->update_curr == 1) route_set_position_from_tracking(this_->route, this_->tracking); } } else { - if (this_->route && this_->vehicle->update_curr == 1) { - pc.pro = pro; - pc.x = cursor_c->x; - pc.y = cursor_c->y; - route_set_position(this_->route, &pc); + if (this_->route && nv->update_curr == 1) { + cursor_pc.pro = pro; + cursor_pc.x = nv->coord.x; + cursor_pc.y = nv->coord.y; + route_set_position(this_->route, &cursor_pc); + } + } + + if ((!transform(this_->trans, pro, &nv->coord, &cursor_pnt) || !transform_within_border(this_->trans, &cursor_pnt, border))) { + if (!this_->cursor_flag) + return; + if (nv->follow_curr != 1) { + if (this_->orient_north_flag) + navit_set_center_cursor(this_, &nv->coord, 0, 50 - 30.*sin(M_PI*nv->dir/180.), 50 + 30.*cos(M_PI*nv->dir/180.)); + else + navit_set_center_cursor(this_, &nv->coord, nv->dir, 50, 80); + pnt=NULL; } } - if (this_->route && this_->vehicle->update_curr == 1) + + if (this_->pid && nv->speed > 2) + kill(this_->pid, SIGWINCH); + if (this_->route && nv->update_curr == 1) navigation_update(this_->navigation, this_->route); - if (this_->cursor_flag) { - if (this_->vehicle->follow_curr == 1) - navit_set_center_cursor(this_, cursor_c, dir, 50, 80); + if (this_->cursor_flag && nv->follow_curr == 1) { + navit_set_center_cursor(this_, &nv->coord, nv->dir, 50, 80); + pnt=NULL; } - if (this_->vehicle->follow_curr > 1) - this_->vehicle->follow_curr--; + if (nv->follow_curr > 1) + nv->follow_curr--; else - this_->vehicle->follow_curr=this_->vehicle->follow; - if (this_->vehicle->update_curr > 1) - this_->vehicle->update_curr--; + nv->follow_curr=nv->follow; + if (nv->update_curr > 1) + nv->update_curr--; else - this_->vehicle->update_curr=this_->vehicle->update; - callback_list_call_2(this_->vehicle_cbl, this_, this_->vehicle->vehicle); + nv->update_curr=nv->update; + callback_list_call_2(this_->vehicle_cbl, this_, nv->vehicle); + if (pnt) + navit_vehicle_draw(this_, nv, pnt); } /** @@ -1202,16 +1232,24 @@ navit_set_position(struct navit *this_, struct pcoord *c) * @returns a vehicle instance */ struct navit_vehicle * -navit_add_vehicle(struct navit *this_, struct vehicle *v, const char *name, struct color *c, int update, int follow) +navit_add_vehicle(struct navit *this_, struct vehicle *v, struct attr **attrs) { struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1); + struct attr *name,*update,*follow,*color,*active; nv->vehicle=v; - nv->name=g_strdup(name); - nv->update_curr=nv->update=update; - nv->follow_curr=nv->follow=follow; - nv->c=*c; - + if ((name=attr_search(attrs, NULL, attr_name))) + nv->name=g_strdup(name->u.str); + if ((update=attr_search(attrs, NULL, attr_update))) + nv->update_curr=nv->update=update->u.num; + if ((follow=attr_search(attrs, NULL, attr_follow))) + nv->follow_curr=nv->follow=follow->u.num; + if ((color=attr_search(attrs, NULL, attr_color))) { + nv->c=*(color->u.color); + } this_->vehicles=g_list_append(this_->vehicles, nv); + if ((active=attr_search(attrs, NULL, attr_active)) && active->u.num) + navit_set_vehicle(this_, nv); + return nv; } diff --git a/src/navit.h b/src/navit.h index ed7cdaf..812d73d 100644 --- a/src/navit.h +++ b/src/navit.h @@ -7,11 +7,9 @@ extern "C" { extern struct gui *main_loop_gui; /* prototypes */ enum item_type; -enum projection; +struct attr; struct callback; -struct color; struct coord; -struct pcoord; struct displaylist; struct graphics; struct gui; @@ -22,6 +20,7 @@ struct navigation; struct navit; struct navit_vehicle; struct navit_window_items; +struct pcoord; struct point; struct route; struct speech; @@ -65,7 +64,7 @@ void navit_toggle_cursor(struct navit *this_); void navit_toggle_tracking(struct navit *this_); void navit_toggle_orient_north(struct navit *this_); void navit_set_position(struct navit *this_, struct pcoord *c); -struct navit_vehicle *navit_add_vehicle(struct navit *this_, struct vehicle *v, const char *name, struct color *c, int update, int follow); +struct navit_vehicle *navit_add_vehicle(struct navit *this_, struct vehicle *v, struct attr **attrs); void navit_add_vehicle_cb(struct navit *this_, struct callback *cb); void navit_remove_vehicle_cb(struct navit *this_, struct callback *cb); void navit_add_init_cb(struct navit *this_, struct callback *cb); @@ -82,7 +81,6 @@ struct navigation *navit_get_navigation(struct navit *this_); struct displaylist *navit_get_displaylist(struct navit *this_); void navit_destroy(struct navit *this_); void navit_toggle_routegraph_display(struct navit *nav); - /* end of prototypes */ #ifdef __cplusplus } diff --git a/src/plugin_def.h b/src/plugin_def.h index 831dfc9..aadf732 100644 --- a/src/plugin_def.h +++ b/src/plugin_def.h @@ -1,11 +1,12 @@ enum projection; struct attr; +struct navit; +struct callback_list; PLUGIN_FUNC1(draw, struct container *, co) PLUGIN_FUNC3(popup, struct container *, map, struct popup *, p, struct popup_item **, list) -struct navit; PLUGIN_TYPE(graphics, (struct graphics_methods *meth, struct attr **attrs)) PLUGIN_TYPE(gui, (struct navit *nav, struct gui_methods *meth, struct attr **attrs)) PLUGIN_TYPE(map, (struct map_methods *meth, struct attr **attrs)) PLUGIN_TYPE(osd, (struct navit *nav, struct osd_methods *meth, struct attr **attrs)) PLUGIN_TYPE(speech, (char *data, struct speech_methods *meth)) -PLUGIN_TYPE(vehicle, (struct vehicle_methods *meth)) +PLUGIN_TYPE(vehicle, (struct vehicle_methods *meth, struct callback_list *cbl, struct attr **attrs)) diff --git a/src/vehicle.c b/src/vehicle.c index 7467ad2..8d656e1 100644 --- a/src/vehicle.c +++ b/src/vehicle.c @@ -1,769 +1,140 @@ -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#ifdef HAVE_LIBGPS -#include -#endif +#include +#include "config.h" #include "debug.h" #include "coord.h" -#include "callback.h" -#include "transform.h" -#include "projection.h" -#include "statusbar.h" -#include "navit.h" #include "item.h" #include "log.h" +#include "callback.h" +#include "plugin.h" #include "vehicle.h" -#include "item.h" -#include "route.h" - -static void disable_watch(struct vehicle *this_); -static void enable_watch(struct vehicle *this_); - - /* #define INTERPOLATION_TIME 50 */ - -struct callback { - void (*func)(struct vehicle *, void *data); - void *data; -}; struct vehicle { - char *url; - GIOChannel *iochan; - guint watch; - int is_file; - int is_pipe; - int timer_count; - int status; // Do we have a fix? 0=no 1=yes, without DGPS 2=yes, with DGPS - int sats,sats_used; - struct coord_geo geo; - double height; - double dir,speed; - double time; - double pdop; - struct coord current_pos; - struct coord_d curr; - struct coord_d delta; - - double speed_last; - int fd; - FILE *file; -#ifdef HAVE_LIBGPS - struct gps_data_t *gps; -#endif -#define BUFFER_SIZE 256 - char buffer[BUFFER_SIZE]; - int buffer_pos; - + struct vehicle_priv *priv; + struct vehicle_methods meth; struct callback_list *cbl; - struct vehicle *child; - struct callback *child_cb; - - int magic; - int is_udp; - int interval; - struct sockaddr_in rem; struct log *nmea_log, *gpx_log, *textfile_log; - - struct navit *navit; }; -// FIXME : this_ is an ugly hack (dixit cp15 ;) ) -struct vehicle *vehicle_last; - -#if INTERPOLATION_TIME -static int -vehicle_timer(gpointer t) -{ - struct vehicle *this_=t; -/* if (this_->timer_count++ < 1000/INTERPOLATION_TIME) { */ - if (this_->delta.x || this_->delta.y) { - this_->curr.x+=this_->delta.x; - this_->curr.y+=this_->delta.y; - this_->current_pos.x=this_->curr.x; - this_->current_pos.y=this_->curr.y; - if (this_->callback_func) - (*this_->callback_func)(this_, this_->callback_data); - } -/* } */ - return TRUE; -} -#endif - -enum projection -vehicle_projection(struct vehicle *this_) -{ - return projection_mg; -} - -struct coord * -vehicle_pos_get(struct vehicle *this_) -{ - return &this_->current_pos; -} - -double * -vehicle_speed_get(struct vehicle *this_) -{ - return &this_->speed; -} - -double * -vehicle_height_get(struct vehicle *this_) -{ - return &this_->height; -} -double * -vehicle_dir_get(struct vehicle *this_) -{ - return &this_->dir; -} - -int * -vehicle_status_get(struct vehicle *this_) -{ - return &this_->status; -} - -int * -vehicle_sats_get(struct vehicle *this_) -{ - return &this_->sats; -} - -int * -vehicle_sats_used_get(struct vehicle *this_) -{ - return &this_->sats_used; -} - -double * -vehicle_pdop_get(struct vehicle *this_) -{ - return &this_->pdop; -} - -void -vehicle_set_position(struct vehicle *this_, struct coord *pos) -{ - this_->current_pos=*pos; - this_->curr.x=this_->current_pos.x; - this_->curr.y=this_->current_pos.y; - this_->delta.x=0; - this_->delta.y=0; - callback_list_call_1(this_->cbl, this_); -} - static int -enable_watch_timer(gpointer t) -{ - struct vehicle *this_=t; - enable_watch(this_); - - return FALSE; -} - -// FIXME Should this_ function be static ? -void -vehicle_set_navit(struct vehicle *this_,struct navit *nav) { - dbg(0,"vehicle_set_navit called\n"); - this_->navit=nav; -} - -static void -vehicle_parse_gps(struct vehicle *this_, char *buffer) -{ - char *p,*item[16]; - double lat,lng,scale,speed; - int i,bcsum; - int len=strlen(buffer); - unsigned char csum=0; - - dbg(1, "buffer='%s' ", buffer); - if (this_->nmea_log) { - log_write(this_->nmea_log, buffer, len); - log_write(this_->nmea_log, "\n", 1); - } - for (;;) { - if (len < 4) { - dbg(0, "too short\n"); - return; - } - if (buffer[len-1] == '\r' || buffer[len-1] == '\n') - buffer[--len]='\0'; - else - break; - } - if (buffer[0] != '$') { - dbg(0, "no leading $\n"); - return; - } - if (buffer[len-3] != '*') { - dbg(0, "no *XX\n"); - return; - } - for (i = 1 ; i < len-3 ; i++) { - csum ^= (unsigned char)(buffer[i]); - } - if (!sscanf(buffer+len-2, "%x", &bcsum)) { - dbg(0, "no checksum\n"); - return; - } - if (bcsum != csum) { - dbg(0, "wrong checksum\n"); - return; - } - - if (!strncmp(buffer,"$GPGGA",6)) { - /* $GPGGA,184424.505,4924.2811,N,01107.8846,E,1,05,2.5,408.6,M,,,,0000*0C - UTC of Fix,Latitude,N/S,Longitude,E/W,Quality,Satelites,HDOP,Altitude,"M" - */ - i=0; - p=buffer; - while (i < 16) { - item[i++]=p; - while (*p && *p != ',') - p++; - if (! *p) break; - *p++='\0'; - } - - sscanf(item[2],"%lf",&lat); - this_->geo.lat=floor(lat/100); - lat-=this_->geo.lat*100; - this_->geo.lat+=lat/60; - - sscanf(item[4],"%lf",&lng); - this_->geo.lng=floor(lng/100); - lng-=this_->geo.lng*100; - this_->geo.lng+=lng/60; - - sscanf(item[6],"%d",&this_->status); - sscanf(item[7],"%d",&this_->sats); - sscanf(item[9],"%lf",&this_->height); - - if (this_->gpx_log) { - char buffer[256]; - sprintf(buffer,"\n",this_->geo.lat,this_->geo.lng); - log_write(this_->gpx_log, buffer, strlen(buffer)); - - } - if (this_->textfile_log) { - char buffer[256]; - sprintf(buffer,"%f %f type=trackpoint\n",this_->geo.lng,this_->geo.lat); - log_write(this_->textfile_log, buffer, strlen(buffer)); - } - transform_from_geo(projection_mg, &this_->geo, &this_->current_pos); - - this_->curr.x=this_->current_pos.x; - this_->curr.y=this_->current_pos.y; - this_->timer_count=0; - callback_list_call_1(this_->cbl, this_); - if (this_->is_file) { - disable_watch(this_); - g_timeout_add(1000, enable_watch_timer, this_); - } - } - if (!strncmp(buffer,"$GPVTG",6)) { - /* $GPVTG,143.58,T,,M,0.26,N,0.5,K*6A - Course Over Ground Degrees True,"T",Course Over Ground Degrees Magnetic,"M", - Speed in Knots,"N","Speed in KM/H","K",*CHECKSUM */ - - i=0; - p=buffer; - while (i < 16) { - item[i++]=p; - while (*p && *p != ',') - p++; - if (! *p) break; - *p++='\0'; - } - sscanf(item[1],"%lf",&this_->dir); - sscanf(item[7],"%lf",&this_->speed); - - scale=transform_scale(this_->current_pos.y); - speed=this_->speed+(this_->speed-this_->speed_last)/2; -#ifdef INTERPOLATION_TIME - this_->delta.x=sin(M_PI*this_->dir/180)*speed*scale/3600*INTERPOLATION_TIME; - this_->delta.y=cos(M_PI*this_->dir/180)*speed*scale/3600*INTERPOLATION_TIME; -#endif - this_->speed_last=this_->speed; - } - if (!strncmp(buffer,"$GPRMC",6)) { - /* $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A */ - /* Time,Active/Void,lat,N/S,long,W/E,speed in knots,track angle,date,magnetic variation */ - i=0; - p=buffer; - while (i < 16) { - item[i++]=p; - while (*p && *p != ',') - p++; - if (! *p) break; - *p++='\0'; - } - sscanf(item[8],"%lf",&this_->dir); - sscanf(item[7],"%lf",&this_->speed); - this_->speed *= 1.852; - scale=transform_scale(this_->current_pos.y); - speed=this_->speed+(this_->speed-this_->speed_last)/2; -#ifdef INTERPOLATION_TIME - this_->delta.x=sin(M_PI*this_->dir/180)*speed*scale/3600*INTERPOLATION_TIME; - this_->delta.y=cos(M_PI*this_->dir/180)*speed*scale/3600*INTERPOLATION_TIME; -#endif - this_->speed_last=this_->speed; - } -} - -#ifdef HAVE_LIBGPS -static void -vehicle_gps_callback(struct gps_data_t *data, char *buf, size_t len, int level) -{ - // If data->fix.speed is NAN, then the drawing gets jumpy. - if(isnan(data->fix.speed)){ - return; - } - - struct vehicle *this_=vehicle_last; - double scale,speed; -#if INTERPOLATION_TIME - if (! (data->set & TIME_SET)) { - return; - } - data->set &= ~TIME_SET; - if (this_->time == data->fix.time) - return; - this_->time=data->fix.time; -#endif - if (data->set & SPEED_SET) { - this_->speed_last=this_->speed; - this_->speed=data->fix.speed*3.6; - data->set &= ~SPEED_SET; - } - if (data->set & TRACK_SET) { - speed=this_->speed+(this_->speed-this_->speed_last)/2; - this_->dir=data->fix.track; - scale=transform_scale(this_->current_pos.y); -#ifdef INTERPOLATION_TIME - this_->delta.x=sin(M_PI*this_->dir/180)*speed*scale/3600*INTERPOLATION_TIME; - this_->delta.y=cos(M_PI*this_->dir/180)*speed*scale/3600*INTERPOLATION_TIME; -#endif - data->set &= ~TRACK_SET; - } - if (data->set & LATLON_SET) { - this_->geo.lat=data->fix.latitude; - this_->geo.lng=data->fix.longitude; - transform_from_geo(projection_mg, &this_->geo, &this_->current_pos); - this_->curr.x=this_->current_pos.x; - this_->curr.y=this_->current_pos.y; - this_->timer_count=0; - callback_list_call_1(this_->cbl, this_); - data->set &= ~LATLON_SET; - } - if (data->set & ALTITUDE_SET) { - this_->height=data->fix.altitude; - data->set &= ~ALTITUDE_SET; - } - if (data->set & SATELLITE_SET) { - this_->sats=data->satellites; - data->set &= ~SATELLITE_SET; - /* FIXME : the USED_SET check does not work yet. */ - this_->sats_used=data->satellites_used; - } - if (data->set & STATUS_SET) { - this_->status=data->status; - data->set &= ~STATUS_SET; - } - if(data->set & PDOP_SET){ - printf("pdop : %g\n",data->pdop); - } -} -#endif - - -static void -vehicle_close(struct vehicle *this_) +vehicle_add_log(struct vehicle *this_, struct log *log, + struct attr **attrs) { - GError *error=NULL; - - - g_io_channel_shutdown(this_->iochan,0,&error); -#ifdef HAVE_LIBGPS - if (this_->gps) - gps_close(this_->gps); -#endif - if (this_->file) - pclose(this_->file); - if (this_->fd != -1) - close(this_->fd); + struct attr *type; + type = attr_search(attrs, NULL, attr_type); + if (!type) + return 1; + if (!strcmp(type->u.str, "nmea")) { + this_->nmea_log = log; + } else if (!strcmp(type->u.str, "gpx")) { + char *header = + "\n\n\n\n"; + char *trailer = "\n\n\n"; + this_->gpx_log = log; + log_set_header(log, header, strlen(header)); + log_set_trailer(log, trailer, strlen(trailer)); + } else if (!strcmp(type->u.str, "textfile")) { + char *header = "type=track\n"; + this_->textfile_log = log; + log_set_header(log, header, strlen(header)); + } else + return 1; + return 0; } -struct packet { - int magic __attribute__ ((packed)); - unsigned char type; - union { - struct { - int x __attribute__ ((packed)); - int y __attribute__ ((packed)); - unsigned char speed; - unsigned char dir; - } pos; - } u; -} __attribute__ ((packed)) ; - -static void -vehicle_udp_recv(struct vehicle *this_) +struct vehicle * +vehicle_new(struct attr **attrs) { - struct packet pkt; - int size; - - dbg(2,"enter this_=%p\n",this_); - size=recv(this_->fd, &pkt, 15, 0); - if (pkt.magic == this_->magic) { - dbg(3,"magic 0x%x size=%d\n", pkt.magic, size); - this_->current_pos.x=pkt.u.pos.x; - this_->current_pos.y=pkt.u.pos.y; - this_->speed=pkt.u.pos.speed; - this_->dir=pkt.u.pos.dir*2; - callback_list_call_1(this_->cbl, this_); - } -} + struct vehicle *this_; + struct attr *source; + struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods * + meth, + struct callback_list * + cbl, + struct attr ** attrs); + char *type, *colon; + + dbg(0, "enter\n"); + source = attr_search(attrs, NULL, attr_source); + if (!source) { + dbg(0, "no source\n"); + return NULL; + } + + type = g_strdup(source->u.str); + colon = index(type, ':'); + if (colon) + *colon = '\0'; + dbg(0, "source='%s' type='%s'\n", source->u.str, type); + + vehicletype_new = plugin_get_vehicle_type(type); + if (!vehicletype_new) { + dbg(0, "invalid type\n"); + return NULL; + } + this_ = g_new0(struct vehicle, 1); + this_->cbl = callback_list_new(); + this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs); + if (!this_->priv) { + dbg(0, "vehicletype_new failed\n"); + callback_list_destroy(this_->cbl); + g_free(this_); + return NULL; + } + dbg(0, "leave\n"); -static void -vehicle_udp_update(struct vehicle *this_, struct vehicle *child) -{ - struct coord *pos=&child->current_pos; - struct packet pkt; - int speed=child->speed; - int dir=child->dir/2; - if (speed > 255) - speed=255; - pkt.magic=this_->magic; - pkt.type=1; - pkt.u.pos.x=pos->x; - pkt.u.pos.y=pos->y; - pkt.u.pos.speed=speed; - pkt.u.pos.dir=dir; - sendto(this_->fd, &pkt, 15, 0, (struct sockaddr *)&this_->rem, sizeof(this_->rem)); - this_->current_pos=child->current_pos; - this_->speed=child->speed; - this_->dir=child->dir; - callback_list_call_1(this_->cbl, this_); + return this_; } -static int -vehicle_udp_query(void *data) +int +vehicle_position_attr_get(struct vehicle *this_, enum attr_type type, + struct attr *attr) { - struct vehicle *this_=(struct vehicle *)data; - struct packet pkt; - dbg(2,"enter this_=%p\n", this_); - pkt.magic=this_->magic; - pkt.type=2; - sendto(this_->fd, &pkt, 5, 0, (struct sockaddr *)&this_->rem, sizeof(this_->rem)); - dbg(2,"ret=TRUE\n"); - return TRUE; + if (this_->meth.position_attr_get) + return this_->meth.position_attr_get(this_->priv, type, + attr); + return 0; } -static int -vehicle_udp_open(struct vehicle *this_) +int +vehicle_set_attr(struct vehicle *this_, struct attr *attr, + struct attr **attrs) { - char *host,*child,*url,*colon; - int port; - url=g_strdup(this_->url); - colon=index(url+6,':'); - struct sockaddr_in lcl; - - if (! colon || sscanf(colon+1,"%d/%i/%d", &port, &this_->magic, &this_->interval) != 3) { - g_warning("Wrong syntax in %s\n", this_->url); - return 0; - } - host=url+6; - *colon='\0'; - this_->fd=socket(PF_INET, SOCK_DGRAM, 0); - this_->is_udp=1; - memset(&lcl, 0, sizeof(lcl)); - lcl.sin_family = AF_INET; - - this_->rem.sin_family = AF_INET; - inet_aton(host, &this_->rem.sin_addr); - this_->rem.sin_port=htons(port); - - bind(this_->fd, (struct sockaddr *)&lcl, sizeof(lcl)); - child=index(colon+1,' '); - if (child) { - child++; - if (!this_->child) { - dbg(3,"child=%s\n", child); - this_->child=vehicle_new(child); - this_->child_cb=callback_new_1(callback_cast(vehicle_udp_update), this_); - vehicle_callback_add(this_->child, this_->child_cb); - } - } else { - vehicle_udp_query(this_); - g_timeout_add(this_->interval*1000, vehicle_udp_query, this_); - } - g_free(url); return 0; } -static int -vehicle_demo_timer (struct vehicle *this) -{ - struct route_path_coord_handle *h; - struct coord *c; - dbg(1,"###### Entering simulation loop\n"); - if(!this->navit){ - dbg(1,"vehicle->navit is not set. Can't simulate\n"); - return 1; - } - - // Then check whether the route is set, if not return TRUE - struct route * vehicle_route=navit_get_route(this->navit); - if(!vehicle_route){ - dbg(1,"navit_get_route NOK\n"); - return 1; - } - - h=route_path_coord_open(vehicle_route); - if (!h) { - dbg(1,"navit_path_coord_open NOK\n"); - return 1; - } - c=route_path_coord_get(h); - dbg(1,"current pos=%p\n", c); - if (c) - dbg(1,"current pos=0x%x,0x%x\n", c->x, c->y); - c=route_path_coord_get(h); - dbg(1,"next pos=%p\n", c); - if (c) { - dbg(1,"next pos=0x%x,0x%x\n", c->x, c->y); - vehicle_set_position(this,c); +int +vehicle_add_attr(struct vehicle *this_, struct attr *attr, + struct attr **attrs) +{ + switch (attr->type) { + case attr_callback: + callback_list_add(this_->cbl, attr->u.callback); + break; + case attr_log: + return vehicle_add_log(this_, attr->u.log, attrs); + default: + return 0; } return 1; } -static int -vehicle_open(struct vehicle *this_) +int +vehicle_remove_attr(struct vehicle *this_, struct attr *attr) { - struct termios tio; - struct stat st; - int fd=0; - -#ifdef HAVE_LIBGPS - struct gps_data_t *gps=NULL; - char *url_,*colon; -#endif - if (! strncmp(this_->url,"file:",5)) { - fd=open(this_->url+5,O_RDONLY|O_NDELAY); - if (fd < 0) { - g_warning("Failed to open %s", this_->url); - return 0; - } - stat(this_->url+5, &st); - if (S_ISREG (st.st_mode)) { - this_->is_file=1; - } else { - tcgetattr(fd, &tio); - cfmakeraw(&tio); - cfsetispeed(&tio, B4800); - cfsetospeed(&tio, B4800); - tio.c_cc[VMIN]=16; - tio.c_cc[VTIME]=1; - tcsetattr(fd, TCSANOW, &tio); - } - this_->fd=fd; - } else if (! strncmp(this_->url,"pipe:",5)) { - this_->file=popen(this_->url+5, "r"); - this_->is_pipe=1; - if (! this_->file) { - g_warning("Failed to open %s", this_->url); - return 0; - } - fd=fileno(this_->file); - } else if (! strncmp(this_->url,"gpsd://",7)) { -#ifdef HAVE_LIBGPS - url_=g_strdup(this_->url); - colon=index(url_+7,':'); - if (colon) { - *colon=0; - gps=gps_open(url_+7,colon+1); - } else - gps=gps_open(this_->url+7,NULL); - g_free(url_); - if (! gps) { - g_warning("Failed to connect to %s", this_->url); - return 0; - } - gps_query(gps, "w+x\n"); - gps_set_raw_hook(gps, vehicle_gps_callback); - fd=gps->gps_fd; - this_->gps=gps; -#else - g_warning("No support for gpsd compiled in\n"); + switch (attr->type) { + case attr_callback: + callback_list_remove(this_->cbl, attr->u.callback); + break; + default: return 0; -#endif - } else if (! strncmp(this_->url,"udp://",6)) { - vehicle_udp_open(this_); - fd=this_->fd; - } else if (! strncmp(this_->url,"demo://",7)) { - dbg(0,"Creating a demo vehicle\n"); - g_timeout_add(1000, (GSourceFunc) vehicle_demo_timer, this_); } - this_->iochan=g_io_channel_unix_new(fd); - enable_watch(this_); return 1; } - -static gboolean -vehicle_track(GIOChannel *iochan, GIOCondition condition, gpointer t) -{ - struct vehicle *this_=t; - char *str,*tok; - gsize size; - - dbg(1,"enter condition=%d\n", condition); - if (condition == G_IO_IN) { -#ifdef HAVE_LIBGPS - if (this_->gps) { - vehicle_last=this_; - gps_poll(this_->gps); - } else { -#else - { -#endif - if (this_->is_udp) { - vehicle_udp_recv(this_); - return TRUE; - } - size=read(g_io_channel_unix_get_fd(iochan), this_->buffer+this_->buffer_pos, BUFFER_SIZE-this_->buffer_pos-1); - if (size <= 0) { - vehicle_close(this_); - vehicle_open(this_); - return TRUE; - } - this_->buffer_pos+=size; - this_->buffer[this_->buffer_pos]='\0'; - dbg(1,"size=%d pos=%d buffer='%s'\n", size, this_->buffer_pos, this_->buffer); - str=this_->buffer; - while ((tok=index(str, '\n'))) { - *tok++='\0'; - dbg(1,"line='%s'\n", str); - vehicle_parse_gps(this_, str); - str=tok; - } - if (str != this_->buffer) { - size=this_->buffer+this_->buffer_pos-str; - memmove(this_->buffer, str, size+1); - this_->buffer_pos=size; - dbg(1,"now pos=%d buffer='%s'\n", this_->buffer_pos, this_->buffer); - } else if (this_->buffer_pos == BUFFER_SIZE-1) { - dbg(0,"overflow\n"); - this_->buffer_pos=0; - } - - } - - return TRUE; - } - return FALSE; -} - -static void -enable_watch(struct vehicle *this_) -{ - this_->watch=g_io_add_watch(this_->iochan, G_IO_IN|G_IO_ERR|G_IO_HUP, vehicle_track, this_); -} - -static void -disable_watch(struct vehicle *this_) -{ - g_source_remove(this_->watch); -} - -struct vehicle * -vehicle_new(const char *url) -{ - struct vehicle *this_; - this_=g_new0(struct vehicle,1); - - this_->cbl=callback_list_new(); - this_->url=g_strdup(url); - this_->fd=-1; - - vehicle_open(this_); - this_->current_pos.x=0x130000; - this_->current_pos.y=0x600000; - this_->curr.x=this_->current_pos.x; - this_->curr.y=this_->current_pos.y; - this_->delta.x=0; - this_->delta.y=0; -#if INTERPOLATION_TIME - g_timeout_add(INTERPOLATION_TIME, vehicle_timer, this_); -#endif - - return this_; -} - -void -vehicle_callback_add(struct vehicle *this_, struct callback *cb) -{ - callback_list_add(this_->cbl, cb); -} - -void -vehicle_callback_remove(struct vehicle *this_, struct callback *cb) -{ - callback_list_remove(this_->cbl, cb); -} - - -int -vehicle_add_log(struct vehicle *this_, struct log *log, struct attr **attrs) -{ - struct attr *type; - type=attr_search(attrs, NULL, attr_type); - if (! type) - return 1; - if (!strcmp(type->u.str,"nmea")) { - this_->nmea_log=log; - if (this_->child) - this_->child->nmea_log=log; - - } else if (!strcmp(type->u.str,"gpx")) { - char *header="\n\n\n\n"; - char *trailer="\n\n\n"; - this_->gpx_log=log; - if (this_->child) - this_->child->gpx_log=log; - log_set_header(log,header,strlen(header)); - log_set_trailer(log,trailer,strlen(trailer)); - } else if (!strcmp(type->u.str,"textfile")) { - char *header="type=track\n"; - this_->textfile_log=log; - if (this_->child) - this_->child->textfile_log=log; - log_set_header(log,header,strlen(header)); - } else - return 1; - return 0; -} - void vehicle_destroy(struct vehicle *this_) { - vehicle_close(this_); callback_list_destroy(this_->cbl); - g_free(this_->url); g_free(this_); } diff --git a/src/vehicle.h b/src/vehicle.h index 557b927..7c4e5f4 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -4,29 +4,22 @@ #ifdef __cplusplus extern "C" { #endif +struct vehicle_priv; + +struct vehicle_methods { + void (*destroy)(struct vehicle_priv *priv); + int (*position_attr_get)(struct vehicle_priv *priv, enum attr_type type, struct attr *attr); +}; + /* prototypes */ -enum projection; +enum attr_type; struct attr; -struct callback; -struct coord; -struct log; -struct navit; struct vehicle; -enum projection vehicle_projection(struct vehicle *this_); -struct coord *vehicle_pos_get(struct vehicle *this_); -double *vehicle_speed_get(struct vehicle *this_); -double *vehicle_height_get(struct vehicle *this_); -double *vehicle_dir_get(struct vehicle *this_); -int *vehicle_status_get(struct vehicle *this_); -int *vehicle_sats_get(struct vehicle *this_); -int *vehicle_sats_used_get(struct vehicle *this_); -double *vehicle_pdop_get(struct vehicle *this_); -void vehicle_set_position(struct vehicle *this_, struct coord *pos); -void vehicle_set_navit(struct vehicle *this_, struct navit *nav); -struct vehicle *vehicle_new(const char *url); -void vehicle_callback_add(struct vehicle *this_, struct callback *cb); -void vehicle_callback_remove(struct vehicle *this_, struct callback *cb); -int vehicle_add_log(struct vehicle *this_, struct log *log, struct attr **attrs); +struct vehicle *vehicle_new(struct attr **attrs); +int vehicle_position_attr_get(struct vehicle *this_, enum attr_type type, struct attr *attr); +int vehicle_set_attr(struct vehicle *this_, struct attr *attr, struct attr **attrs); +int vehicle_add_attr(struct vehicle *this_, struct attr *attr, struct attr **attrs); +int vehicle_remove_attr(struct vehicle *this_, struct attr *attr); void vehicle_destroy(struct vehicle *this_); /* end of prototypes */ #ifdef __cplusplus diff --git a/src/vehicle/Makefile.am b/src/vehicle/Makefile.am index d65d693..8901833 100644 --- a/src/vehicle/Makefile.am +++ b/src/vehicle/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=file +SUBDIRS=demo file if VEHICLE_GPSD SUBDIRS += gpsd endif diff --git a/src/vehicle/demo/Makefile.am b/src/vehicle/demo/Makefile.am new file mode 100644 index 0000000..1d66f32 --- /dev/null +++ b/src/vehicle/demo/Makefile.am @@ -0,0 +1,4 @@ +include $(top_srcdir)/Makefile.inc +AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=\"vehicle_demo\" +modulevehicle_LTLIBRARIES = libvehicle_demo.la +libvehicle_demo_la_SOURCES = vehicle_demo.c diff --git a/src/vehicle/demo/vehicle_demo.c b/src/vehicle/demo/vehicle_demo.c new file mode 100644 index 0000000..632b9f4 --- /dev/null +++ b/src/vehicle/demo/vehicle_demo.c @@ -0,0 +1,7 @@ +#include "debug.h" + +void +plugin_init(void) +{ + dbg(0,"enter\n"); +} diff --git a/src/vehicle/file/vehicle_file.c b/src/vehicle/file/vehicle_file.c index 32be387..ce9d41f 100644 --- a/src/vehicle/file/vehicle_file.c +++ b/src/vehicle/file/vehicle_file.c @@ -1,6 +1,345 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" +#include "callback.h" #include "plugin.h" +#include "coord.h" +#include "item.h" +#include "vehicle.h" + +static void vehicle_file_disable_watch(struct vehicle_priv *priv); +static void vehicle_file_enable_watch(struct vehicle_priv *priv); + +enum file_type { + file_type_pipe = 1, file_type_device, file_type_file +}; + +static int buffer_size = 256; + +struct vehicle_priv { + char *source; + enum file_type file_type; + struct callback_list *cbl; + int fd; + FILE *file; + guint watch; + GIOChannel *iochan; + char *buffer; + int buffer_pos; + + struct coord_geo geo; + double speed; + double direction; + double height; + int status; + int sats_used; +}; + +static int +vehicle_file_open(struct vehicle_priv *priv) +{ + char *name; + struct stat st; + struct termios tio; + + name = priv->source + 5; + if (!strncmp(priv->source, "file:", 5)) { + priv->fd = open(name, O_RDONLY | O_NDELAY); + if (priv->fd < 0) + return 0; + stat(name, &st); + if (S_ISREG(st.st_mode)) { + priv->file_type = file_type_file; + } else { + tcgetattr(priv->fd, &tio); + cfmakeraw(&tio); + cfsetispeed(&tio, B4800); + cfsetospeed(&tio, B4800); + tio.c_cc[VMIN] = 16; + tio.c_cc[VTIME] = 1; + tcsetattr(priv->fd, TCSANOW, &tio); + priv->file_type = file_type_device; + } + } else { + priv->file = popen(name, "r"); + if (!priv->file) + return 0; + priv->fd = fileno(priv->file); + priv->file_type = file_type_pipe; + } + priv->iochan = g_io_channel_unix_new(priv->fd); + return 1; +} + +static void +vehicle_file_close(struct vehicle_priv *priv) +{ + GError *error = NULL; + if (priv->iochan) { + g_io_channel_shutdown(priv->iochan, 0, &error); + priv->iochan = NULL; + } + if (priv->file) + pclose(priv->file); + else if (priv->fd >= 0) + close(priv->fd); + priv->file = NULL; + priv->fd = -1; +} + +static int +vehicle_file_enable_watch_timer(gpointer t) +{ + struct vehicle_priv *priv = t; + vehicle_file_enable_watch(priv); + dbg(1, "enter\n"); + + return FALSE; +} + + +static void +vehicle_file_parse(struct vehicle_priv *priv, char *buffer) +{ + char *p, *item[16]; + double lat, lng; + int i, bcsum; + int len = strlen(buffer); + unsigned char csum = 0; + + dbg(1, "buffer='%s'\n", buffer); + for (;;) { + if (len < 4) { + dbg(0, "too short\n"); + return; + } + if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n') + buffer[--len] = '\0'; + else + break; + } + if (buffer[0] != '$') { + dbg(0, "no leading $\n"); + return; + } + if (buffer[len - 3] != '*') { + dbg(0, "no *XX\n"); + return; + } + for (i = 1; i < len - 3; i++) { + csum ^= (unsigned char) (buffer[i]); + } + if (!sscanf(buffer + len - 2, "%x", &bcsum)) { + dbg(0, "no checksum\n"); + return; + } + if (bcsum != csum) { + dbg(0, "wrong checksum\n"); + return; + } + + i = 0; + p = buffer; + while (i < 16) { + item[i++] = p; + while (*p && *p != ',') + p++; + if (!*p) + break; + *p++ = '\0'; + } + + if (!strncmp(buffer, "$GPGGA", 6)) { + /* 1 1111 + 0 1 2 3 4 5 6 7 8 9 0 1234 + $GPGGA,184424.505,4924.2811,N,01107.8846,E,1,05,2.5,408.6,M,,,,0000*0C + UTC of Fix[1],Latitude[2],N/S[3],Longitude[4],E/W[5],Quality(0=inv,1=gps,2=dgps)[6],Satelites used[7], + HDOP[8],Altitude[9],"M"[10],height of geoid[11], "M"[12], time since dgps update[13], dgps ref station [14] + */ + sscanf(item[2], "%lf", &lat); + priv->geo.lat = floor(lat / 100); + lat -= priv->geo.lat * 100; + priv->geo.lat += lat / 60; + + sscanf(item[4], "%lf", &lng); + priv->geo.lng = floor(lng / 100); + lng -= priv->geo.lng * 100; + priv->geo.lng += lng / 60; + + sscanf(item[6], "%d", &priv->status); + sscanf(item[7], "%d", &priv->sats_used); + sscanf(item[9], "%lf", &priv->height); + + callback_list_call_0(priv->cbl); + if (priv->file_type == file_type_file) { + vehicle_file_disable_watch(priv); + g_timeout_add(1000, + vehicle_file_enable_watch_timer, + priv); + } + } + if (!strncmp(buffer, "$GPVTG", 6)) { + /* 0 1 2 34 5 6 7 8 + $GPVTG,143.58,T,,M,0.26,N,0.5,K*6A + Course Over Ground Degrees True[1],"T"[2],Course Over Ground Degrees Magnetic[3],"M"[4], + Speed in Knots[5],"N"[6],"Speed in KM/H"[7],"K"[8] + */ + sscanf(item[1], "%lf", &priv->direction); + sscanf(item[7], "%lf", &priv->speed); + } + if (!strncmp(buffer, "$GPRMC", 6)) { + /* 1 1 + 0 1 2 3 4 5 6 7 8 9 0 1 + $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A + Time[1],Active/Void[2],lat[3],N/S[4],long[5],W/E[6],speed in knots[7],track angle[8],date[9], + magnetic variation[10],magnetic variation direction[11] + */ + sscanf(item[8], "%lf", &priv->direction); + sscanf(item[7], "%lf", &priv->speed); + priv->speed *= 1.852; + } +} + +static gboolean +vehicle_file_io(GIOChannel * iochan, GIOCondition condition, gpointer t) +{ + struct vehicle_priv *priv = t; + int size; + char *str, *tok; + + dbg(1, "enter condition=%d\n", condition); + if (condition == G_IO_IN) { + size = + read(g_io_channel_unix_get_fd(iochan), + priv->buffer + priv->buffer_pos, + buffer_size - priv->buffer_pos - 1); + if (size <= 0) { + vehicle_file_close(priv); + vehicle_file_open(priv); + return TRUE; + } + priv->buffer_pos += size; + priv->buffer[priv->buffer_pos] = '\0'; + dbg(1, "size=%d pos=%d buffer='%s'\n", size, + priv->buffer_pos, priv->buffer); + str = priv->buffer; + while ((tok = index(str, '\n'))) { + *tok++ = '\0'; + dbg(1, "line='%s'\n", str); + vehicle_file_parse(priv, str); + str = tok; + } + if (str != priv->buffer) { + size = priv->buffer + priv->buffer_pos - str; + memmove(priv->buffer, str, size + 1); + priv->buffer_pos = size; + dbg(1, "now pos=%d buffer='%s'\n", + priv->buffer_pos, priv->buffer); + } else if (priv->buffer_pos == buffer_size - 1) { + dbg(0, + "Overflow. Most likely wrong baud rate or no nmea protocol\n"); + priv->buffer_pos = 0; + } + return TRUE; + } + return FALSE; +} + +static void +vehicle_file_enable_watch(struct vehicle_priv *priv) +{ + priv->watch = + g_io_add_watch(priv->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP, + vehicle_file_io, priv); +} + +static void +vehicle_file_disable_watch(struct vehicle_priv *priv) +{ + if (priv->watch) + g_source_remove(priv->watch); + priv->watch = 0; +} + + +static void +vehicle_file_destroy(struct vehicle_priv *priv) +{ + vehicle_file_close(priv); + if (priv->source) + g_free(priv->source); + if (priv->buffer) + g_free(priv->buffer); + g_free(priv); +} + +static int +vehicle_file_position_attr_get(struct vehicle_priv *priv, + enum attr_type type, struct attr *attr) +{ + switch (type) { + case attr_position_height: + attr->u.numd = &priv->height; + break; + case attr_position_speed: + attr->u.numd = &priv->speed; + break; + case attr_position_direction: + attr->u.numd = &priv->direction; + break; + case attr_position_sats_used: + attr->u.num = priv->sats_used; + break; + case attr_position_coord_geo: + attr->u.coord_geo = &priv->geo; + break; + default: + return 0; + } + attr->type = type; + return 1; +} + +struct vehicle_methods vehicle_file_methods = { + vehicle_file_destroy, + vehicle_file_position_attr_get, +}; + +static struct vehicle_priv * +vehicle_file_new_file(struct vehicle_methods + *meth, struct callback_list + *cbl, struct attr **attrs) +{ + struct vehicle_priv *ret; + struct attr *source; + + dbg(1, "enter\n"); + source = attr_search(attrs, NULL, attr_source); + ret = g_new0(struct vehicle_priv, 1); + ret->fd = -1; + ret->cbl = cbl; + ret->source = g_strdup(source->u.str); + ret->buffer = g_malloc(buffer_size); + *meth = vehicle_file_methods; + if (vehicle_file_open(ret)) { + vehicle_file_enable_watch(ret); + return ret; + } + dbg(0, "Failed to open '%s'\n", ret->source); + vehicle_file_destroy(ret); + return NULL; +} void plugin_init(void) { + dbg(1, "enter\n"); + plugin_register_vehicle_type("file", vehicle_file_new_file); + plugin_register_vehicle_type("pipe", vehicle_file_new_file); } diff --git a/src/vehicle/gpsd/Makefile.am b/src/vehicle/gpsd/Makefile.am index 50ec71a..c4222e3 100644 --- a/src/vehicle/gpsd/Makefile.am +++ b/src/vehicle/gpsd/Makefile.am @@ -2,3 +2,4 @@ include $(top_srcdir)/Makefile.inc AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=\"vehicle_gpsd\" modulevehicle_LTLIBRARIES = libvehicle_gpsd.la libvehicle_gpsd_la_SOURCES = vehicle_gpsd.c +libvehicle_gpsd_la_LIBADD = @GPSD_LIBS@ diff --git a/src/vehicle/gpsd/vehicle_gpsd.c b/src/vehicle/gpsd/vehicle_gpsd.c index 32be387..569b0e9 100644 --- a/src/vehicle/gpsd/vehicle_gpsd.c +++ b/src/vehicle/gpsd/vehicle_gpsd.c @@ -1,6 +1,202 @@ +#include +#include +#include +#include +#include "debug.h" +#include "callback.h" #include "plugin.h" +#include "coord.h" +#include "item.h" +#include "vehicle.h" + +static struct vehicle_priv { + char *source; + struct callback_list *cbl; + GIOChannel *iochan; + guint watch; + struct gps_data_t *gps; + struct coord_geo geo; + double speed; + double direction; + double height; + int status; + int sats; + int sats_used; +} *vehicle_last; + +static gboolean vehicle_gpsd_io(GIOChannel * iochan, + GIOCondition condition, gpointer t); + + + +static void +vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len, + int level) +{ + struct vehicle_priv *priv = vehicle_last; + // If data->fix.speed is NAN, then the drawing gets jumpy. + if (isnan(data->fix.speed)) { + return; + } + + if (data->set & SPEED_SET) { + priv->speed = data->fix.speed * 3.6; + data->set &= ~SPEED_SET; + } + if (data->set & TRACK_SET) { + priv->direction = data->fix.track; + data->set &= ~TRACK_SET; + } + if (data->set & ALTITUDE_SET) { + priv->height = data->fix.altitude; + data->set &= ~ALTITUDE_SET; + } + if (data->set & SATELLITE_SET) { + priv->sats_used = data->satellites_used; + priv->sats = data->satellites; + data->set &= ~SATELLITE_SET; + } + if (data->set & STATUS_SET) { + priv->status = data->status; + data->set &= ~STATUS_SET; + } + if (data->set & PDOP_SET) { + dbg(0, "pdop : %g\n", data->pdop); + data->set &= ~PDOP_SET; + } + if (data->set & LATLON_SET) { + priv->geo.lat = data->fix.latitude; + priv->geo.lng = data->fix.longitude; + callback_list_call_0(priv->cbl); + data->set &= ~LATLON_SET; + } +} + +static int +vehicle_gpsd_open(struct vehicle_priv *priv) +{ + char *source = g_strdup(priv->source); + char *colon = index(source + 7, ':'); + if (colon) { + *colon = '\0'; + priv->gps = gps_open(source + 7, colon + 1); + } else + priv->gps = gps_open(source + 7, NULL); + g_free(source); + if (!priv->gps) + return 0; + gps_query(priv->gps, "w+x\n"); + gps_set_raw_hook(priv->gps, vehicle_gpsd_callback); + priv->iochan = g_io_channel_unix_new(priv->gps->gps_fd); + priv->watch = + g_io_add_watch(priv->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP, + vehicle_gpsd_io, priv); + return 1; +} + +static void +vehicle_gpsd_close(struct vehicle_priv *priv) +{ + GError *error = NULL; + + if (priv->watch) { + g_source_remove(priv->watch); + priv->watch = 0; + } + if (priv->iochan) { + g_io_channel_shutdown(priv->iochan, 0, &error); + priv->iochan = NULL; + } + if (priv->gps) { + gps_close(priv->gps); + priv->gps = NULL; + } +} + +static gboolean +vehicle_gpsd_io(GIOChannel * iochan, GIOCondition condition, gpointer t) +{ + struct vehicle_priv *priv = t; + + dbg(1, "enter condition=%d\n", condition); + if (condition == G_IO_IN) { + if (priv->gps) { + vehicle_last = priv; + gps_poll(priv->gps); + } + return TRUE; + } + return FALSE; +} + +static void +vehicle_gpsd_destroy(struct vehicle_priv *priv) +{ + vehicle_gpsd_close(priv); + if (priv->source) + g_free(priv->source); + g_free(priv); +} + +static int +vehicle_gpsd_position_attr_get(struct vehicle_priv *priv, + enum attr_type type, struct attr *attr) +{ + switch (type) { + case attr_position_height: + attr->u.numd = &priv->height; + break; + case attr_position_speed: + attr->u.numd = &priv->speed; + break; + case attr_position_direction: + attr->u.numd = &priv->direction; + break; + case attr_position_sats: + attr->u.num = priv->sats; + break; + case attr_position_sats_used: + attr->u.num = priv->sats_used; + break; + case attr_position_coord_geo: + attr->u.coord_geo = &priv->geo; + break; + default: + return 0; + } + attr->type = type; + return 1; +} + +struct vehicle_methods vehicle_gpsd_methods = { + vehicle_gpsd_destroy, + vehicle_gpsd_position_attr_get, +}; + +static struct vehicle_priv * +vehicle_gpsd_new_gpsd(struct vehicle_methods + *meth, struct callback_list + *cbl, struct attr **attrs) +{ + struct vehicle_priv *ret; + struct attr *source; + + dbg(1, "enter\n"); + source = attr_search(attrs, NULL, attr_source); + ret = g_new0(struct vehicle_priv, 1); + ret->source = g_strdup(source->u.str); + ret->cbl = cbl; + *meth = vehicle_gpsd_methods; + if (vehicle_gpsd_open(ret)) + return ret; + dbg(0, "Failed to open '%s'\n", ret->source); + vehicle_gpsd_destroy(ret); + return NULL; +} void plugin_init(void) { + dbg(1, "enter\n"); + plugin_register_vehicle_type("gpsd", vehicle_gpsd_new_gpsd); } diff --git a/src/xmlconfig.c b/src/xmlconfig.c index 50784fc..d1ebd8e 100644 --- a/src/xmlconfig.c +++ b/src/xmlconfig.c @@ -259,40 +259,28 @@ xmlconfig_gui(struct xmlstate *state) static int xmlconfig_vehicle(struct xmlstate *state) { - const char *s=find_attribute(state, "source", 1); - const char *value,*name; - struct color color; - int update=1, follow=0, active; - struct navit_vehicle *nv; + struct attr **attrs; + attrs=convert_to_attrs(state); - if (! s) - return 0; - if (! find_color(state, 1, &color)) - return 0; - state->element_object = vehicle_new(s); + state->element_object = vehicle_new(attrs); if (! state->element_object) return 0; - if ((value=find_attribute(state, "update", 0))) - update=convert_number(value); - if ((value=find_attribute(state, "follow", 0))) - follow=convert_number(value); - active=find_boolean(state, "active", 1, 0); - name=find_attribute(state, "name", 0); - nv=navit_add_vehicle(state->parent->element_object, state->element_object, name, &color, update, follow); - if (active) - navit_set_vehicle(state->parent->element_object, nv); + navit_add_vehicle(state->parent->element_object, state->element_object, attrs); return 1; } static int xmlconfig_log(struct xmlstate *state) { + struct attr attr; struct attr **attrs; attrs=convert_to_attrs(state); state->element_object = log_new(attrs); if (! state->element_object) return 0; - if (vehicle_add_log(state->parent->element_object, state->element_object, attrs)) + attr.type=attr_log; + attr.u.log=state->element_object; + if (vehicle_add_attr(state->parent->element_object, &attr, attrs)) return 0; return 1; } @@ -658,6 +646,7 @@ start_element (GMarkupParseContext *context, struct xmlstate *new=NULL, **parent = user_data; struct element_func *e=elements,*func=NULL; const char *parent_name=NULL; + dbg(2,"name='%s'\n", element_name); while (e->name) { if (!g_ascii_strcasecmp(element_name, e->name)) { func=e; @@ -725,6 +714,7 @@ end_element (GMarkupParseContext *context, { struct xmlstate *curr, **state = user_data; + dbg(2,"name='%s'\n", element_name); curr=*state; if(!g_ascii_strcasecmp("plugins", element_name) && curr->element_object) plugins_init(curr->element_object);