Add:Core:Added c style command evaluation for more flexible osds
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sun, 1 Feb 2009 16:07:50 +0000 (16:07 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sun, 1 Feb 2009 16:07:50 +0000 (16:07 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@1987 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/Makefile.am
navit/attr.c
navit/attr.h
navit/attr_def.h
navit/command.c [new file with mode: 0644]
navit/command.h [new file with mode: 0644]
navit/gui.c
navit/gui/internal/gui_internal.c
navit/navit.c
navit/navit.xml
navit/osd/core/osd_core.c

index da907ac..5139baf 100644 (file)
@@ -22,11 +22,11 @@ pkgdata_DATA = navit.xml
 EXTRA_DIST = navit.xml 
 
 noinst_LTLIBRARIES        = libnavit.la
-libnavit_la_SOURCES = atom.c attr.c cache.c callback.c compass.c coord.c country.c cursor.c data_window.c debug.c \
+libnavit_la_SOURCES = atom.c attr.c cache.c callback.c command.c compass.c coord.c country.c cursor.c data_window.c debug.c \
        event.c event_glib.h file.c graphics.c gui.c item.c layout.c log.c main.c map.c \
        mapset.c maptype.c menu.c navit.c navigation.c osd.c param.c phrase.c plugin.c popup.c \
        profile.c projection.c route.c search.c speech.c transform.c track.c \
-       util.c vehicle.c xmlconfig.c atom.h attr.h attr_def.h cache.h callback.h color.h compass.h coord.h country.h \
+       util.c vehicle.c xmlconfig.c atom.h attr.h attr_def.h cache.h callback.h color.h command.h compass.h coord.h country.h \
        cursor.h data.h data_window.h data_window_int.h debug.h destination.h draw_info.h endianess.h event.h \
        file.h graphics.h gtkext.h gui.h item.h item_def.h keys.h log.h layer.h layout.h main.h map-share.h map.h\
        map_data.h mapset.h maptype.h menu.h navigation.h navit.h osd.h \
index 91bad99..095595f 100644 (file)
@@ -375,7 +375,7 @@ void
 attr_list_free(struct attr **attrs)
 {
        int count=0;
-       while (attrs[count]) {
+       while (attrs && attrs[count]) {
                attr_free(attrs[count++]);
        }
        g_free(attrs);
index ad92921..ff2919f 100644 (file)
@@ -59,6 +59,7 @@ struct attr {
                struct coord_geo *coord_geo;
                struct navit *navit;
                struct callback *callback;
+               struct callback_list *callback_list;
                struct vehicle *vehicle;
                struct layout *layout;
                struct layer *layer;
index 247b9de..13b632b 100644 (file)
@@ -243,6 +243,7 @@ ATTR(plugin)
 ATTR(speech)
 ATTR(coord)
 ATTR(private_data)
+ATTR(callback_list)
 ATTR2(0x0008ffff,type_object_end)
 ATTR2(0x00090000,type_coord_begin)
 ATTR2(0x0009ffff,type_coord_end)
diff --git a/navit/command.c b/navit/command.c
new file mode 100644 (file)
index 0000000..cbf75dd
--- /dev/null
@@ -0,0 +1,673 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "item.h"
+#include "main.h"
+#include "navit.h"
+#include "vehicle.h"
+#include "speech.h"
+#include "gui.h"
+#include "debug.h"
+#include "callback.h"
+#include "command.h"
+
+/*
+gui.fullscreen()
+gui.menu()
+gui.get_data() 
+zoom_in() 
+zoom_out()
+speech.active=!speech.active
+osd_configuration=1
+Not yet:
+osd[type=="xxx"].active=0;osd[type=="yyy"].active=0
+*/
+
+
+struct result {
+       struct attr attr;
+       double val;
+       char *var;
+       int varlen;
+       char *attrn;
+       int attrnlen;
+};
+
+struct context {
+       struct attr *attr;
+       int error;
+       char *expr;
+       struct result res;
+};
+
+enum error {
+       no_error=0,missing_closing_brace, missing_colon, wrong_type, illegal_number_format, illegal_character, missing_closing_bracket, invalid_type
+};
+
+static void eval_comma(struct context *ctx, struct result *res);
+static struct attr ** eval_list(struct context *ctx);
+
+static char *
+get_op(struct context *ctx, int test, ...)
+{
+       char *op,*ret=NULL;
+       va_list ap;
+       va_start(ap, test);
+       while ((op = va_arg(ap, char *))) {
+               if (!strncmp(ctx->expr, op, strlen(op))) {
+                       ret=ctx->expr;
+                       if (! test)
+                               ctx->expr+=strlen(op);
+                       break;
+               }
+       }
+       va_end(ap);
+       return ret;
+}
+
+static int
+is_int(struct result *res)
+{
+       return 1;
+}
+
+static int
+is_double(struct result *res)
+{
+       return 0;
+}
+
+static void
+dump(struct result *res)
+{
+       char object[res->varlen+1];
+       char attribute[res->attrnlen+1];
+       if (res->var)
+               strncpy(object, res->var, res->varlen);
+       object[res->varlen]='\0';
+       if (res->attrn)
+               strncpy(attribute, res->attrn, res->attrnlen);
+       attribute[res->attrnlen]='\0';
+       dbg(0,"type:%s\n", attr_to_name(res->attr.type));
+       dbg(0,"attribute '%s' from '%s'\n", attribute, object);
+}
+
+static enum attr_type
+command_attr_type(struct result *res)
+{
+       char attrn[res->attrnlen+1];
+
+       strncpy(attrn, res->attrn, res->attrnlen);
+       attrn[res->attrnlen]='\0';
+       return attr_from_name(attrn);
+}
+
+static int
+command_object_get_attr(struct attr *object, enum attr_type attr_type, struct attr *ret)
+{
+       switch (object->type) {
+       case attr_gui:
+               return gui_get_attr(object->u.gui, attr_type, ret, NULL);
+       case attr_navit:
+               return navit_get_attr(object->u.navit, attr_type, ret, NULL);
+       case attr_speech:
+               return speech_get_attr(object->u.speech, attr_type, ret, NULL);
+       case attr_vehicle:
+               return vehicle_get_attr(object->u.vehicle, attr_type, ret, NULL);
+       default:
+               return 0;
+       }
+}
+
+static void
+command_get_attr(struct context *ctx, struct result *res)
+{
+       int result;
+       enum attr_type attr_type=command_attr_type(res);
+       result=command_object_get_attr(&res->attr, attr_type, &res->attr);
+       if (result) {
+               res->var=res->attrn;
+               res->varlen=res->attrnlen;
+       } else {
+               res->attr.type=attr_none;
+               res->var=NULL;
+               res->varlen=0;
+       }
+       res->attrn=NULL;
+       res->attrnlen=0;
+       dump(res);
+}
+
+static void
+command_set_attr(struct context *ctx, struct result *res, struct result *newres)
+{
+       int result=0;
+       enum attr_type attr_type=command_attr_type(res);
+       newres->attr.type=attr_type;
+       switch (res->attr.type) {
+       case attr_navit:
+               result=navit_set_attr(res->attr.u.navit, &newres->attr);
+               break;
+       case attr_speech:
+               result=speech_set_attr(res->attr.u.speech, &newres->attr);
+               break;
+       default:
+               break;
+       }
+       *res=*newres;
+}
+
+static void
+resolve_object(struct context *ctx, struct result *res)
+{
+       if (res->attr.type == attr_none && res->varlen) {
+               res->attr=*ctx->attr;
+               res->attrn=res->var;
+               res->attrnlen=res->varlen;
+               res->var=NULL;
+               res->varlen=0;
+       }
+}
+
+static void
+resolve(struct context *ctx, struct result *res, struct attr *parent)
+{
+       resolve_object(ctx, res);
+       if (res->attr.type >= attr_type_object_begin && res->attr.type <= attr_type_object_end) {
+               if (res->attrn)
+                       command_get_attr(ctx, res);
+               return;
+       }
+}
+
+static double
+get_double(struct context *ctx, struct result *res)
+{
+       resolve(ctx, res, NULL);
+       return res->val;
+}
+
+
+
+static int
+get_int(struct context *ctx, struct result *res)
+{
+       resolve(ctx, res, NULL);
+       if (res->attr.type == attr_none)
+               return 0;
+       if (res->attr.type >= attr_type_int_begin && res->attr.type <= attr_type_int_end) {
+               return res->attr.u.num;
+       }
+       if (res->attr.type >= attr_type_double_begin && res->attr.type <= attr_type_double_end) {
+               return (int) (*res->attr.u.numd);
+       }
+       ctx->error=wrong_type;
+       return 0;
+}
+
+
+static char *
+get_string(struct context *ctx, struct result *res)
+{
+       resolve(ctx, res, NULL);
+       return attr_to_text(&res->attr, NULL, 0);
+}
+
+static void
+set_double(struct context *ctx, struct result *res, double val)
+{
+       res->val=val;
+}
+
+static void
+set_int(struct context *ctx, struct result *res, int val)
+{
+       res->attr.type=attr_type_int_begin;
+       res->attr.u.num=val;
+}
+
+
+static void
+eval_value(struct context *ctx, struct result *res) {
+       char *op;
+       int dots=0;
+       op=ctx->expr;
+       res->varlen=0;
+       res->var=NULL;
+       res->attrnlen=0;
+       res->attrn=NULL;
+       if (op[0] >= 'a' && op[0] <= 'z') {
+               res->attr.type=attr_none;
+               res->var=op;
+               while ((op[0] >= 'a' && op[0] <= 'z') || op[0] == '_') {
+                       res->varlen++;
+                       op++;
+               }
+               ctx->expr=op;
+               return;
+       }
+       if ((op[0] >= '0' && op[0] <= '9') ||
+           (op[0] == '.' && op[1] >= '0' && op[1] <= '9')) {
+               while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.') {
+                       if (op[0] == '.')
+                               dots++;
+                       if (dots > 1) {
+                               ctx->error=illegal_number_format;
+                               return;
+                       }
+                       res->varlen++;
+                       op++;
+               }
+               if (dots) {
+                       res->val = strtod(ctx->expr, NULL);
+                       res->attr.type=attr_type_double_begin;
+                       res->attr.u.numd=&res->val;
+               } else {
+                       res->attr.type=attr_type_int_begin;
+                       res->attr.u.num=atoi(ctx->expr);
+               }
+               ctx->expr=op;
+               return;
+       }
+       ctx->error=illegal_character;
+}
+
+static void
+eval_brace(struct context *ctx, struct result *res)
+{
+       if (get_op(ctx,0,"(",NULL)) {
+               eval_comma(ctx, res);
+               if (ctx->error) return;
+               if (!get_op(ctx,0,")",NULL)) 
+                       ctx->error=missing_closing_brace;
+               return;
+       }
+       eval_value(ctx, res);
+}
+
+static void
+command_call_function(struct context *ctx, struct result *res)
+{
+       struct attr cbl,**list=NULL;
+       char function[res->attrnlen+1];
+       if (res->attrn)
+               strncpy(function, res->attrn, res->attrnlen);
+       function[res->attrnlen]='\0';
+       dbg(0,"function=%s\n", function);
+       if (ctx->expr[0] != ')') {
+               list=eval_list(ctx);    
+               if (ctx->error) return;
+       }
+       if (!get_op(ctx,0,")",NULL)) {
+               ctx->error=missing_closing_brace;
+               return;
+       }
+       if (command_object_get_attr(&res->attr, attr_callback_list, &cbl)) {
+               int valid;
+               dbg(0,"function call %s from %s\n",function, attr_to_name(res->attr.type));
+               callback_list_call_attr_4(cbl.u.callback_list, attr_command, function, list, NULL, &valid);
+       }
+       res->var=NULL;
+       res->varlen=0;
+       res->attrn=NULL;
+       res->attrnlen=0;
+       res->attr.type=attr_none;
+}
+
+static void
+eval_postfix(struct context *ctx, struct result *res)
+{
+       struct result tmp;
+       char *op;
+
+       eval_brace(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!(op=get_op(ctx,0,"[","(",".",NULL)))
+                       return;
+               if (op[0] == '.') {
+                       eval_brace(ctx, &tmp);
+                       if (ctx->error) return;
+                       resolve(ctx, res,NULL);
+                       if (ctx->error) return;
+                       res->attrn=tmp.var;
+                       res->attrnlen=tmp.varlen;
+                       dump(res);
+               } else if (op[0] == '[') {
+                       if (!get_op(ctx,0,"]",NULL)) {
+                               ctx->error=missing_closing_bracket;
+                               return;
+                       }
+               } else if (op[0] == '(') {
+                       dbg(0,"function call\n");
+                       resolve_object(ctx, res);
+                       command_call_function(ctx, res);
+               }
+       }
+}
+
+static void
+eval_unary(struct context *ctx, struct result *res) 
+{
+       char *op;
+       op=get_op(ctx,0,"~","!",NULL);
+       if (op) {
+               eval_unary(ctx, res);
+               if (ctx->error) return;
+               if (op[0] == '~')
+                       set_int(ctx, res, ~get_int(ctx, res));
+               else
+                       set_int(ctx, res, !get_int(ctx, res));
+       } else
+               eval_postfix(ctx, res);
+}
+
+static void
+eval_multiplicative(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+       char *op;
+
+       eval_unary(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!(op=get_op(ctx,0,"*","/","%",NULL))) return;
+               eval_unary(ctx, &tmp);
+               if (ctx->error) return;
+               if (is_double(res) || is_double(&tmp)) {
+                       if (op[0] == '*')
+                               set_double(ctx, res, get_double(ctx, res) * get_double(ctx, &tmp));
+                       else if (op[0] == '/')
+                               set_double(ctx, res, get_double(ctx, res) / get_double(ctx, &tmp));
+                       else {
+                               ctx->error=invalid_type;
+                               return;
+                       }
+               } else {
+                       if (op[0] == '*')
+                               set_int(ctx, res, get_int(ctx, res) * get_int(ctx, &tmp));
+                       else if (op[0] == '/')
+                               set_int(ctx, res, get_int(ctx, res) / get_int(ctx, &tmp));
+                       else
+                               set_int(ctx, res, get_int(ctx, res) % get_int(ctx, &tmp));
+               }
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_additive(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+       char *op;
+
+       eval_multiplicative(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!(op=get_op(ctx,0,"-","+",NULL))) return;
+               eval_multiplicative(ctx, &tmp);
+               if (ctx->error) return;
+               if (is_double(res) || is_double(&tmp)) {
+                       if (op[0] == '+')
+                               set_double(ctx, res, get_double(ctx, res) + get_double(ctx, &tmp));
+                       else
+                               set_double(ctx, res, get_double(ctx, res) - get_double(ctx, &tmp));
+               } else {
+                       if (op[0] == '+')
+                               set_int(ctx, res, get_int(ctx, res) + get_int(ctx, &tmp));
+                       else
+                               set_int(ctx, res, get_int(ctx, res) - get_int(ctx, &tmp));
+               }
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_equality(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+       char *op;
+
+       eval_additive(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!(op=get_op(ctx,0,"==","!=",NULL))) return;
+               eval_additive(ctx, &tmp);
+               if (ctx->error) return;
+               if (op[0]  == '=') 
+                       set_int(ctx, res, (get_int(ctx, res) == get_int(ctx, &tmp)));
+               else
+                       set_int(ctx, res, (get_int(ctx, res) != get_int(ctx, &tmp)));
+       }
+}
+
+
+static void
+eval_bitwise_and(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+
+       eval_equality(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (get_op(ctx,1,"&&",NULL)) return;
+               if (!get_op(ctx,0,"&",NULL)) return;
+               eval_equality(ctx, &tmp);
+               if (ctx->error) return;
+               set_int(ctx, res, get_int(ctx, res) & get_int(ctx, &tmp));
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_bitwise_xor(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+
+       eval_bitwise_and(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!get_op(ctx,0,"^",NULL)) return;
+               eval_bitwise_and(ctx, &tmp);
+               if (ctx->error) return;
+               set_int(ctx, res, get_int(ctx, res) ^ get_int(ctx, &tmp));
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_bitwise_or(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+
+       eval_bitwise_xor(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (get_op(ctx,1,"||",NULL)) return;
+               if (!get_op(ctx,0,"|",NULL)) return;
+               eval_bitwise_xor(ctx, &tmp);
+               if (ctx->error) return;
+               set_int(ctx, res, get_int(ctx, res) | get_int(ctx, &tmp));
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_logical_and(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+
+       eval_bitwise_or(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!get_op(ctx,0,"&&",NULL)) return;
+               eval_bitwise_or(ctx, &tmp);
+               if (ctx->error) return;
+               set_int(ctx, res, get_int(ctx, res) && get_int(ctx, &tmp));
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_logical_or(struct context *ctx, struct result *res) 
+{
+       struct result tmp;
+
+       eval_logical_and(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!get_op(ctx,0,"||",NULL)) return;
+               eval_logical_and(ctx, &tmp);
+               if (ctx->error) return;
+               set_int(ctx, res, get_int(ctx, res) || get_int(ctx, &tmp));
+               if (ctx->error) return;
+       }
+}
+
+static void
+eval_conditional(struct context *ctx, struct result *res)
+{
+       struct result tmp;
+       int cond;
+
+       eval_logical_or(ctx, res);
+       if (ctx->error) return;
+       if (!get_op(ctx,0,"?",NULL)) return;
+       cond=!!get_int(ctx, res);
+       if (ctx->error) return;
+       eval_logical_or(ctx, &tmp);
+       if (ctx->error) return;
+       if (cond)
+               *res=tmp;
+       if (!get_op(ctx,0,":",NULL)) {
+               ctx->error=missing_colon;
+               return;
+       }
+       eval_logical_or(ctx, &tmp);
+       if (ctx->error) return;
+       if (!cond)
+               *res=tmp;
+}
+
+/* = *= /= %= += -= >>= <<= &= ^= |= */
+
+static void
+eval_assignment(struct context *ctx, struct result *res)
+{
+       struct result tmp;
+       eval_conditional(ctx, res);
+       if (ctx->error) return;
+       if (!get_op(ctx,0,"=",NULL)) return;
+       eval_conditional(ctx, &tmp);
+       if (ctx->error) return;
+       command_set_attr(ctx, res, &tmp);
+}
+
+/* , */
+static void
+eval_comma(struct context *ctx, struct result *res)
+{
+       struct result tmp;
+
+       eval_assignment(ctx, res);
+       if (ctx->error) return;
+       for (;;) {
+               if (!get_op(ctx,0,",",NULL)) return;
+               eval_assignment(ctx, &tmp);
+               if (ctx->error) return;
+               *res=tmp;
+       }
+}
+
+static struct attr **
+eval_list(struct context *ctx)
+{
+       struct result tmp;
+
+       struct attr **ret=NULL;
+       for (;;) {
+               eval_assignment(ctx, &tmp);
+               if (ctx->error) {
+                       attr_list_free(ret);
+                       return NULL;
+               }
+               ret=attr_generic_add_attr(ret, &tmp.attr);
+               if (!get_op(ctx,0,",",NULL)) return ret;
+       }
+}
+
+#if 0
+
+void command(struct attr *attr, char *expr)
+{
+       struct result res;
+       struct context ctx;
+       memset(&res, 0, sizeof(res));
+       memset(&ctx, 0, sizeof(ctx));
+       ctx.attr=attr;
+       ctx.error=0;
+       ctx.expr=expr;
+       printf("command='%s'\n", expr);
+       eval_comma(&ctx,&res);
+       printf("err=%d %s\n", ctx.error, ctx.expr);
+       dump(&res);
+       printf("***\n");
+       resolve(&ctx, &res, NULL);
+       dump(&res);
+       printf("%s\n", get_string(&ctx, &res));
+}
+
+void
+command_evaluate_to_void(struct attr *attr, char *expr)
+{
+       struct result res;
+       struct context ctx;
+       dbg(0,"command=%s attr.type=%s\n", expr, attr_to_name(attr->type));
+       memset(&res, 0, sizeof(res));
+       memset(&ctx, 0, sizeof(ctx));
+       ctx.attr=attr;
+       ctx.error=0;
+       ctx.expr=expr;
+       eval_comma(&ctx,&res);
+       resolve(&ctx, &res, NULL);
+}
+
+void
+command_interpreter(struct attr *attr)
+{
+                char buffer[4096];
+                int size;
+                for (;;) {
+                size=read(0, buffer, 4095);
+                buffer[size]='\0';
+                if (size) {
+                        buffer[size-1]='\0';
+                }
+                command(attr, buffer);
+                }
+}
+#endif
+
+static void
+command_table_call(struct command_table *table, int count, void *data, char *command, struct attr **in, struct attr ***out, int *valid)
+{
+       int i;
+       for (i = 0 ; i < count ; i++) {
+               if (!strcmp(command,table->command)) {
+                       if (valid)
+                               *valid=1;
+                       table->func(data, command, in, out);
+               }
+               table++;
+       }
+}
+
+void
+command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data)
+{
+       struct callback *cb=callback_new_attr_3(callback_cast(command_table_call),attr_command, table, count, data);
+       callback_list_add(cbl, cb);
+}
+
diff --git a/navit/command.h b/navit/command.h
new file mode 100644 (file)
index 0000000..992115a
--- /dev/null
@@ -0,0 +1,11 @@
+
+struct command_table {
+       char *command;
+       int (*func)(void *data, char *cmd, struct attr **in, struct attr ***out);
+};
+
+#define command_cast(x) (int (*)(void *, char *, struct attr **, struct attr ***))(x)
+
+void command_evaluate_to_void(struct attr *attr, char *expr);
+void command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data);
+
index 662fa38..28b2132 100644 (file)
@@ -20,6 +20,7 @@
 #include <glib.h>
 #include <string.h>
 #include "debug.h"
+#include "callback.h"
 #include "gui.h"
 #include "menu.h"
 #include "data_window.h"
@@ -38,6 +39,7 @@ gui_new(struct attr *parent, struct attr **attrs)
        struct gui *this_;
        struct attr *type_attr;
        struct gui_priv *(*guitype_new)(struct navit *nav, struct gui_methods *meth, struct attr **attrs);
+       struct attr cbl;
        if (! (type_attr=attr_search(attrs, NULL, attr_type))) {
                return NULL;
        }
@@ -47,8 +49,11 @@ gui_new(struct attr *parent, struct attr **attrs)
                 return NULL;
 
        this_=g_new0(struct gui, 1);
-       this_->priv=guitype_new(parent->u.navit, &this_->meth, attrs);
        this_->attrs=attr_list_dup(attrs);
+       cbl.type=attr_callback_list;
+       cbl.u.callback_list=callback_list_new();
+       this_->attrs=attr_generic_add_attr(this_->attrs, &cbl);
+       this_->priv=guitype_new(parent->u.navit, &this_->meth, this_->attrs);
        return this_;
 }
 
index 8bcd6ce..ed3cf79 100644 (file)
@@ -61,6 +61,7 @@
 #include "event.h"
 #include "navit_nls.h"
 #include "gui_internal.h"
+#include "command.h"
 
 struct menu_data {
        struct widget *search_list;
@@ -3067,6 +3068,12 @@ gui_internal_cmd_menu(struct gui_priv *this, struct point *p, int ignore)
 }
 
 static void
+gui_internal_cmd_menu2(struct gui_priv *this)
+{
+       gui_internal_cmd_menu(this, NULL, 1);
+}
+
+static void
 gui_internal_check_exit(struct gui_priv *this)
 {
        struct graphics *gra=this->gra;
@@ -3464,6 +3471,12 @@ static struct gui_internal_widget_methods gui_internal_widget_methods = {
        gui_internal_set_default_background,
 };
 
+static struct command_table commands[] = {
+       {"menu",gui_internal_cmd_menu2},
+       {"fullscreen",gui_internal_cmd_fullscreen},
+       {"get_data",gui_internal_get_data},
+};
+
 
 //##############################################################################################################
 //# Description: 
@@ -3481,10 +3494,10 @@ static struct gui_priv * gui_internal_new(struct navit *nav, struct gui_methods
                this->menu_on_map_click=attr->u.num;
        else
                this->menu_on_map_click=1;
-       navit_command_register(nav,"gui_internal_menu",callback_new_3(callback_cast(gui_internal_cmd_menu),this,NULL,(void *)1));
-       navit_command_register(nav,"gui_internal_fullscreen",callback_new_2(callback_cast(gui_internal_cmd_fullscreen),this,NULL));
-       dbg(0,"register\n");
-       navit_command_register(nav,"gui_internal_get_data",callback_new_1(callback_cast(gui_internal_get_data),this));
+       if ((attr=attr_search(attrs, NULL, attr_callback_list))) {
+               dbg(0,"register\n");
+               command_add_table(attr->u.callback_list, commands, sizeof(commands)/sizeof(struct command_table), this);
+       }
 
        if( (attr=attr_search(attrs,NULL,attr_font_size)))
         {
index 907ad7f..a709a73 100644 (file)
@@ -57,6 +57,7 @@
 #include "event.h"
 #include "file.h"
 #include "profile.h"
+#include "command.h"
 #include "navit_nls.h"
 
 /**
@@ -129,7 +130,6 @@ struct navit {
        int w,h;
        int drag_bitmap;
        int use_mousewheel;
-       GHashTable *commands;
        struct callback *resize_callback,*button_callback,*motion_callback;
 };
 
@@ -145,7 +145,6 @@ struct attr_iter {
 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);
 static int navit_add_vehicle(struct navit *this_, struct vehicle *v);
-static void navit_set_attr_cmd(struct navit *this_, char *command, struct attr **in, struct attr ***out);
 
 void
 navit_add_mapset(struct navit *this_, struct mapset *ms)
@@ -505,6 +504,26 @@ navit_zoom_out(struct navit *this_, int factor, struct point *p)
        navit_scale(this_, scale, p);
 }
 
+static int
+navit_cmd_zoom_in(struct navit *this_)
+{
+       navit_zoom_in(this_, 2, NULL);
+       return 0;
+}
+
+static int
+navit_cmd_zoom_out(struct navit *this_)
+{
+       navit_zoom_out(this_, 2, NULL);
+       return 0;
+}
+
+static struct command_table commands[] = {
+       {"zoom_in",navit_cmd_zoom_in},
+       {"zoom_out",navit_cmd_zoom_out},
+};
+       
+
 struct navit *
 navit_new(struct attr *parent, struct attr **attrs)
 {
@@ -589,11 +608,7 @@ navit_new(struct attr *parent, struct attr **attrs)
        this_->trans=transform_new();
        transform_setup(this_->trans, &center, zoom, (this_->orientation != -1) ? this_->orientation : 0);
        this_->displaylist=graphics_displaylist_new();
-       this_->commands=g_hash_table_new(g_str_hash, g_str_equal);
-       navit_command_register(this_, "zoom_in", callback_new_3(callback_cast(navit_zoom_in), this_, (void *)2, NULL));
-       navit_command_register(this_, "zoom_out", callback_new_3(callback_cast(navit_zoom_out), this_, (void *)2, NULL));
-       navit_command_register(this_, "navit_set_attr", callback_new_1(callback_cast(navit_set_attr_cmd), this_));
-    navit_command_register(this_, "navit_announcer_toggle", callback_new_1(callback_cast(navit_announcer_toggle), this_));
+       command_add_table(this_->attr_cbl, commands, sizeof(commands)/sizeof(struct command_table), this_);
        return this_;
 }
 
@@ -1474,17 +1489,6 @@ navit_set_attr(struct navit *this_, struct attr *attr)
        return 1;
 }
 
-static void
-navit_set_attr_cmd(struct navit *this_, char *command, struct attr **in, struct attr ***out)
-{
-       if (! in)
-               return;
-       while (*in) {
-               navit_set_attr(this_,*in);
-               in++;
-       }
-}
-
 int
 navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
 {
@@ -1492,6 +1496,9 @@ navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, stru
        case attr_bookmark_map:
                attr->u.map=this_->bookmark;
                break;
+       case attr_callback_list:
+               attr->u.callback_list=this_->attr_cbl;
+               break;
        case attr_cursor:
                attr->u.num=this_->cursor_flag;
                break;
@@ -1503,6 +1510,9 @@ navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, stru
        case attr_former_destination_map:
                attr->u.map=this_->former_destination;
                break;
+       case attr_gui:
+               attr->u.gui=this_->gui;
+               break;
        case attr_layout:
                if (iter) {
                        if (iter->u.list) {
@@ -1550,9 +1560,9 @@ navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, stru
        case attr_route:
                attr->u.route=this_->route;
                break;
-    case attr_speech:
-        attr->u.speech=this_->speech;
-        break;
+       case attr_speech:
+               attr->u.speech=this_->speech;
+               break;
        case attr_tracking:
                attr->u.num=this_->tracking_flag;
                break;
@@ -1945,87 +1955,6 @@ navit_block(struct navit *this_, int block)
        return 0;
 }
 
-int
-navit_command_register(struct navit *this_, char *command, struct callback *cb)
-{
-       dbg(1,"registering '%s'\n", command);
-       g_hash_table_insert(this_->commands, command, cb);
-
-       return 0;
-}
-
-struct callback *
-navit_command_unregister(struct navit *this_, char *command)
-{
-       struct callback *ret=g_hash_table_lookup(this_->commands, command);
-       if (ret) {
-               g_hash_table_remove(this_->commands, command);
-       }
-
-       return ret;
-}
-
-int
-navit_command_call_attrs(struct navit *this_, char *command, struct attr **in, struct attr ***out)
-{
-       struct callback *cb=g_hash_table_lookup(this_->commands, command);
-       dbg(0,"calling callback %p for '%s'\n", cb, command);
-       if (! cb)
-               return 1;
-       callback_call_args(cb, 3, command, in, out);
-       return 0;
-}
-
-int
-navit_command_call(struct navit *this_, char *command)
-{
-       int len,ret=1;
-       char *str,*args,*next,*name,*val,sep;
-       struct attr *attr,**attrs=NULL;
-       if (! command)
-               return 1;
-       len=strlen(command);
-       if (! len)
-               return 1;
-       if (command[len-1] != ')') 
-               return navit_command_call_attrs(this_, command, NULL, NULL);
-       str=g_strdup(command);
-       args=strchr(str,'(');
-       if (args) {
-               *args++='\0';
-               args[strlen(args)-1]='\0';
-               next=args;
-               while (next) {
-                       val=strchr(next,'=');
-                       if (val) {
-                               name=next;
-                               *val++='\0';
-                               sep=*val;
-                               if (sep == '"' || sep == '\'') {
-                                       val++;  
-                               } else
-                                       sep=',';
-                               next=strchr(val,sep);
-                               if (next) {
-                                       *next++='\0';
-                                       if (sep != ',' && *next++ != ',')
-                                               next=NULL;
-                               }
-                               attr=attr_new_from_text(name,val);
-                               if (attr) {
-                                       attrs=attr_generic_add_attr(attrs, attr);
-                                       attr_free(attr);
-                               }
-                       } else
-                               break;
-               }
-               ret=navit_command_call_attrs(this_, str, attrs, NULL);
-               attr_list_free(attrs);
-       }
-       g_free(str);
-       return ret;
-}
-
 void
 navit_destroy(struct navit *this_)
 {
@@ -2036,8 +1965,6 @@ navit_destroy(struct navit *this_)
        char *center_file = navit_get_center_file(TRUE);
        navit_write_center_to_file(this_, center_file);
        g_free(center_file);
-       callback_destroy(navit_command_unregister(this_, "zoom_in"));
-       callback_destroy(navit_command_unregister(this_, "zoom_out"));
        callback_destroy(this_->nav_speech_cb);
        callback_destroy(this_->roadbook_callback);
        callback_destroy(this_->popup_callback);
@@ -2048,7 +1975,6 @@ navit_destroy(struct navit *this_)
        callback_destroy(this_->button_callback);
        graphics_remove_callback(this_->gra, this_->motion_callback);
        callback_destroy(this_->motion_callback);
-       g_hash_table_destroy(this_->commands);
        g_free(this_);
 }
 
index 3e74d53..46b4eef 100644 (file)
         <!-- Commands include gui_internal_menu, gui_internal_fullscreen, zoom_in and zoom_out.
              Usage of negative values change the button origins. x="0" y="0" specifies the top left, x="-0" y="-0" the bottom right corner.
              It's always the top left corner of the icon, so you need to consider the icon's size when you enter the values. -->
-        <osd enabled="no" type="button" x="0" y="0" command="gui_internal_fullscreen" src="toggle_fullscreen.xpm"/> 
-        <osd enabled="no" type="button" x="-96" y="0" command="gui_internal_menu" src="menu.xpm"/>
-        <osd enabled="no" type="button" x="-96" y="-96" command="zoom_in" src="zoom_in.xpm"/>
-        <osd enabled="no" type="button" x="0" y="-96" command="zoom_out" src="zoom_out.xpm"/> 
+        <osd enabled="no" type="button" x="0" y="0" command="gui.fullscreen()" src="toggle_fullscreen.xpm"/> 
+        <osd enabled="no" type="button" x="-96" y="0" command="gui.menu()" src="menu.xpm"/>
+        <osd enabled="no" type="button" x="-96" y="-96" command="zoom_in()" src="zoom_in.xpm"/>
+        <osd enabled="no" type="button" x="0" y="-96" command="zoom_out()" src="zoom_out.xpm"/> 
 
         <vehicle name="Local GPS" enabled="yes" active="1" source="gpsd://localhost" gpsd_query="w+xj" color="#0000ff">
             <!-- Navit can write a tracklog in several formats (gpx, nmea or textfile): -->
index 6901b45..247be12 100644 (file)
@@ -41,6 +41,7 @@
 #include "map.h"
 #include "file.h"
 #include "attr.h"
+#include "command.h"
 #include "navit_nls.h"
 
 struct osd_item {
@@ -80,8 +81,11 @@ osd_std_click(struct osd_item *this, struct navit *nav, int pressed, int button,
        navit_ignore_button(nav);
        this->pressed = pressed;
        if (pressed) {
+               struct attr navit;
+               navit.type=attr_navit;
+               navit.u.navit=nav;
                dbg(0, "calling command '%s'\n", this->command);
-               navit_command_call(nav, this->command);
+               command_evaluate_to_void(&navit, this->command);
        }
 }