src/vehicle/Makefile
src/vehicle/file/Makefile
src/vehicle/gpsd/Makefile
+src/vehicle/demo/Makefile
src/xpm/Makefile
src/maps/Makefile
intl/Makefile
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@
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
#include <glib.h>
#include "debug.h"
#include "item.h"
+#include "color.h"
#include "attr.h"
struct attr_name {
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;
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);
}
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;
};
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)
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)
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);
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_);
}
#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
}
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);
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_);
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);
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);
{ "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);
<menuitem name=\"Visible Polys\" action=\"VisiblePolysAction\" />\
<menuitem name=\"Visible Streets\" action=\"VisibleStreetsAction\" />\
<menuitem name=\"Visible Points\" action=\"VisiblePointsAction\" />\
+ <menuitem name=\"Visible Routegraph\" action=\"VisibleRouteGraphAction\" />\
<placeholder name=\"DataMenuAdditions\" />\
</menu>\
<menu name=\"Route\" action=\"RouteMenuAction\">\
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" ) ) );
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;
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)
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;
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();
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) {
*/
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);
}
/**
* @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;
}
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;
struct navit;
struct navit_vehicle;
struct navit_window_items;
+struct pcoord;
struct point;
struct route;
struct speech;
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);
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
}
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))
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <math.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include <glib.h>
-#ifdef HAVE_LIBGPS
-#include <gps.h>
-#endif
+#include <string.h>
+#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,"<trkpt lat=\"%f\" lon=\"%f\" />\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 =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gpx version=\"1.0\" creator=\"Navit http://navit.sourceforge.net\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n<trk>\n<trkseg>\n";
+ char *trailer = "</trkseg>\n</trk>\n</gpx>\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;
- }
-
- // <cp15> 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="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gpx version=\"1.0\" creator=\"Navit http://navit.sourceforge.net\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n<trk>\n<trkseg>\n";
- char *trailer="</trkseg>\n</trk>\n</gpx>\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_);
}
#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
-SUBDIRS=file
+SUBDIRS=demo file
if VEHICLE_GPSD
SUBDIRS += gpsd
endif
--- /dev/null
+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
--- /dev/null
+#include "debug.h"
+
+void
+plugin_init(void)
+{
+ dbg(0,"enter\n");
+}
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <glib.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <math.h>
+#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);
}
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@
+#include <gps.h>
+#include <string.h>
+#include <glib.h>
+#include <math.h>
+#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);
}
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;
}
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;
{
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);