[GRASS-dev] Modules

Glynn Clements glynn at gclements.plus.com
Thu Feb 22 16:37:07 EST 2007


Maciej Sieczka wrote:

> > The attached patch completely eliminates the use of the raster library
> > and display drivers by v.digit, in favour of a Tk canvas widget. The
> > patch needs to be applied from within the v.digit directory.
> > 
> > Testing and comments would be appreciated.
> 
> It builds and works. Buts:
> - centroids/nodes/points sometimes huge, sometimes tiny, depending on
> zoom level,

Found, fixed.

> - slower than before when zooming,

Quite possibly; ultimately, that will depend upon the speed of the Tk
canvas widget versus the speed of XDRIVER.

There may be things which can be done to improve matters here, but I'm
more interested in getting it working correctly than in performance
right now.

> - one has to absolutely not move the mouse for the mouse keys to work;
> otherwise it seems mouse keys stopped responding

"mouse keys"?

> I'm reffering only to this patch. Other your recent fixes committed to
> CVS didn't yield any problems.
> 
> If that's not asking too much, could you maybe look into these bugs BTW
> working on v.digit, ?

Remind me later once the dust has settled.

Anyhow, I have another version which entirely removes the modal loops
from C. It's now a "typical" event-driven Tk application. The attached
patch supersedes the previous patch, so should be applied to the clean
(unpatched) version from CVS HEAD.

The remaining step is to reinstate the bgcmd= option.

-- 
Glynn Clements <glynn at gclements.plus.com>

-------------- next part --------------
? OBJ.i686-pc-linux-gnu
? changes.diff
? round.diff
Index: attr.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/attr.c,v
retrieving revision 1.12
diff -u -r1.12 attr.c
--- attr.c	21 Feb 2007 22:15:41 -0000	1.12
+++ attr.c	22 Feb 2007 21:35:19 -0000
@@ -255,11 +255,11 @@
     return 1;
 }
 
-int display_cats(void)
+void display_cats(void)
 {
-    struct display_cats dc;
+    static struct display_cats dc;
 
-    return do_tool(display_cats_begin, display_cats_update, display_cats_end, &dc);
+    set_tool(display_cats_begin, display_cats_update, display_cats_end, &dc);
 }
 
 /* Copy categories from one feature to another */
@@ -398,11 +398,11 @@
     return 1;
 }
 
-int copy_cats(void)
+void copy_cats(void)
 {
-    struct copy_cats cc;
+    static struct copy_cats cc;
 
-    return do_tool(copy_cats_begin, copy_cats_update, copy_cats_end, &cc);
+    set_tool(copy_cats_begin, copy_cats_update, copy_cats_end, &cc);
 }
 
 /* Display attributes */
@@ -549,11 +549,11 @@
     return 1;
 }
 
-int display_attributes(void)
+void display_attributes(void)
 {
-    struct display_attributes da;
+    static struct display_attributes da;
 
-    return do_tool(display_attributes_begin, display_attributes_update, display_attributes_end, &da);
+    set_tool(display_attributes_begin, display_attributes_update, display_attributes_end, &da);
 }
 
 /* 
Index: c_face.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/c_face.c,v
retrieving revision 1.17
diff -u -r1.17 c_face.c
--- c_face.c	4 May 2006 19:37:26 -0000	1.17
+++ c_face.c	22 Feb 2007 21:35:19 -0000
@@ -20,7 +20,7 @@
 c_cancel ( ClientData cdata, Tcl_Interp *interp, int argc, char *argv[])
 {
     G_debug (3, "c_cancel()");
-    R_set_cancel ( 1 );
+    cancel_tool ();
     Tool_next = TOOL_NOTHING;
     return TCL_OK;
 }
@@ -90,8 +90,9 @@
     G_debug (2, "  Tool_next = %d", Tool_next);
     
     /* Stop running if any */
-    R_set_cancel ( 1 );
-    
+    cancel_tool ();
+    next_tool();
+
     return TCL_OK;
 }
 
Index: centre.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/centre.c,v
retrieving revision 1.16
diff -u -r1.16 centre.c
--- centre.c	31 Aug 2006 05:59:20 -0000	1.16
+++ centre.c	22 Feb 2007 21:35:19 -0000
@@ -18,149 +18,167 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <grass/config.h>
-#ifdef HAVE_NANOSLEEP
-#include <time.h>
-#endif
 #include <grass/gis.h>
 #include <grass/display.h>
+#include <grass/glocale.h>
 #include "global.h"
 #include "proto.h"
 
 /* This function is started from the GUI, it regularly updates GUI and checks GUI requirements. 
 *  If Tool_next is set by GUI, the tool is started by the tool_centre()
 */
-int
+void
 tool_centre ( void )
 {
-    int go = 1;
+    symb_init_gui ();
+    i_prompt ( "Select tool");
 
-    symb_init_gui ( );
+    /* Init variables */
+    var_init ();
+
+    /* Init snap */
+    var_seti ( VAR_SNAP, 1 );
+    var_seti ( VAR_SNAP_MODE, SNAP_SCREEN );
+    var_seti ( VAR_SNAP_SCREEN, 10 );
+    var_setd ( VAR_SNAP_MAP, 10 );
+
+    G_get_window(&window);
+
+    /* Set tool */
+    Tool_next = TOOL_NOTHING;
     
-    while ( go ) {
-        G_debug (5, "Tool centre: Tool_next = %d", Tool_next);
-        i_update(); /* Let GUI set requests */
-	switch ( Tool_next ) {
-	    case TOOL_EXIT :
-                G_debug (2, "Quit" );
-		go = 0;
-		break;
-	    case TOOL_NEW_POINT :
-		/* Tool_next = TOOL_NOTHING; */ /* Commented -> Draw next one once first is done */
-		new_line ( GV_POINT );
-		break;
-	    case TOOL_NEW_LINE :
-		new_line ( GV_LINE );
-		break;
-	    case TOOL_NEW_BOUNDARY :
-		new_line ( GV_BOUNDARY );
-		break;
-	    case TOOL_NEW_CENTROID :
-		new_line ( GV_CENTROID );
-		break;
-	    case TOOL_MOVE_VERTEX :
-		Tool_next = TOOL_NOTHING;
-		move_vertex ();
-		break;
-	    case TOOL_ADD_VERTEX :
-		Tool_next = TOOL_NOTHING;
-		add_vertex ();
-		break;
-	    case TOOL_RM_VERTEX :
-		Tool_next = TOOL_NOTHING;
-		rm_vertex ();
-		break;
-	    case TOOL_SPLIT_LINE :
-		Tool_next = TOOL_NOTHING;
-		split_line ();
-		break;
-	    case TOOL_EDIT_LINE :
-		Tool_next = TOOL_NOTHING;
-		edit_line ();
-		break;
-	    case TOOL_MOVE_LINE :
-		Tool_next = TOOL_NOTHING;
-		move_line ();
-		break;
-	    case TOOL_DELETE_LINE :
-		Tool_next = TOOL_NOTHING;
-		delete_line ();
-		break;
-	    case TOOL_DISPLAY_CATS :
-		Tool_next = TOOL_NOTHING;
-		display_cats ();
-		break;
-	    case TOOL_COPY_CATS :
-		Tool_next = TOOL_NOTHING;
-		copy_cats ();
-		break;
-	    case TOOL_DISPLAY_ATTRIBUTES :
-		Tool_next = TOOL_NOTHING;
-		display_attributes ();
-		break;
-	    case TOOL_DISPLAY_SETTINGS :
-		Tool_next = TOOL_NOTHING;
-		Tcl_Eval(Toolbox, "settings");
-		break;
-	    case TOOL_ZOOM_WINDOW :
-		Tool_next = TOOL_NOTHING;
-		zoom_window ();
-		break;
-	    case TOOL_ZOOM_OUT_CENTRE :
-		Tool_next = TOOL_NOTHING;
-		zoom_centre ( 2 );
-		break;
-	    case TOOL_ZOOM_PAN :
-		Tool_next = TOOL_NOTHING;
-		zoom_pan ();
-		break;
-	    case TOOL_ZOOM_DEFAULT :
-		Tool_next = TOOL_NOTHING;
-		zoom_default ();
-		break;
-	    case TOOL_ZOOM_REGION :
-		Tool_next = TOOL_NOTHING;
-		zoom_region ();
-		break;
-	    case TOOL_REDRAW :
-		Tool_next = TOOL_NOTHING;
-		driver_open();
-		display_redraw();
-		driver_close();
-		break;
-	    case TOOL_NOTHING :
-#ifdef HAVE_NANOSLEEP
-                {
-		   struct timespec tm;
-		   tm.tv_sec = 0;
-		   tm.tv_nsec = 200000000;
-
-                   nanosleep ( &tm, NULL );
-                }
-#endif
-                break;
-	}
-	i_prompt ( "Select tool");
-	/* sleep ( 1 ); */
+    /* Display the map */
+    symb_init ();
+    G_get_window(&window);
+    driver_open ();
+    display_erase ();
+    display_bg ();
+    display_map ();
+    driver_close ();
+}
+
+void next_tool(void)
+{
+    switch ( Tool_next )
+    {
+    case TOOL_EXIT :
+	G_debug (2, "Quit" );
+	end();
+	break;
+    case TOOL_NEW_POINT :
+	/* Tool_next = TOOL_NOTHING; */ /* Commented -> Draw next one once first is done */
+	new_line ( GV_POINT );
+	break;
+    case TOOL_NEW_LINE :
+	new_line ( GV_LINE );
+	break;
+    case TOOL_NEW_BOUNDARY :
+	new_line ( GV_BOUNDARY );
+	break;
+    case TOOL_NEW_CENTROID :
+	new_line ( GV_CENTROID );
+	break;
+    case TOOL_MOVE_VERTEX :
+	Tool_next = TOOL_NOTHING;
+	move_vertex ();
+	break;
+    case TOOL_ADD_VERTEX :
+	Tool_next = TOOL_NOTHING;
+	add_vertex ();
+	break;
+    case TOOL_RM_VERTEX :
+	Tool_next = TOOL_NOTHING;
+	rm_vertex ();
+	break;
+    case TOOL_SPLIT_LINE :
+	Tool_next = TOOL_NOTHING;
+	split_line ();
+	break;
+    case TOOL_EDIT_LINE :
+	Tool_next = TOOL_NOTHING;
+	edit_line ();
+	break;
+    case TOOL_MOVE_LINE :
+	Tool_next = TOOL_NOTHING;
+	move_line ();
+	break;
+    case TOOL_DELETE_LINE :
+	Tool_next = TOOL_NOTHING;
+	delete_line ();
+	break;
+    case TOOL_DISPLAY_CATS :
+	Tool_next = TOOL_NOTHING;
+	display_cats ();
+	break;
+    case TOOL_COPY_CATS :
+	Tool_next = TOOL_NOTHING;
+	copy_cats ();
+	break;
+    case TOOL_DISPLAY_ATTRIBUTES :
+	Tool_next = TOOL_NOTHING;
+	display_attributes ();
+	break;
+    case TOOL_DISPLAY_SETTINGS :
+	Tool_next = TOOL_NOTHING;
+	Tcl_Eval(Toolbox, "settings");
+	break;
+    case TOOL_ZOOM_WINDOW :
+	Tool_next = TOOL_NOTHING;
+	zoom_window ();
+	break;
+    case TOOL_ZOOM_OUT_CENTRE :
+	Tool_next = TOOL_NOTHING;
+	zoom_centre ( 2 );
+	break;
+    case TOOL_ZOOM_PAN :
+	Tool_next = TOOL_NOTHING;
+	zoom_pan ();
+	break;
+    case TOOL_ZOOM_DEFAULT :
+	Tool_next = TOOL_NOTHING;
+	zoom_default ();
+	break;
+    case TOOL_ZOOM_REGION :
+	Tool_next = TOOL_NOTHING;
+	zoom_region ();
+	break;
+    case TOOL_REDRAW :
+	Tool_next = TOOL_NOTHING;
+	driver_open();
+	display_redraw();
+	driver_close();
+	break;
+    case TOOL_NOTHING :
+	break;
     }
-    end();
-    return 1;
 }
 
 /* This function is regularly called from R_get_location_*() functions to enable GUI to kill running tool */
-int update ( int wx, int wy ) {
+void update ( int wx, int wy )
+{
     double x, y;
     
     G_debug (5, "Update function wx = %d wy = %d", wx, wy);
-    i_update ();
 
     if ( wx != COOR_NULL && wy != COOR_NULL ) {
         x = D_d_to_u_col ( wx ); 
 	y = D_d_to_u_row ( wy );
         i_coor ( x, y);
     }
-    
-    return 1;
 }
 
+void end ( void ) 
+{
+    G_debug (1, "end()");
+    Vect_build_partial (&Map, GV_BUILD_NONE, NULL);
+    Vect_build ( &Map, stdout );
+    Vect_close (&Map);
 
+    if( 1 == G_put_window(&GRegion) )
+	G_message(_("Region restored to original extent."));
 
+    /* clear the screen */
+    Tcl_Eval(Toolbox, ".screen.canvas delete all");
+
+    exit(EXIT_SUCCESS);
+}
Index: display.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/display.c,v
retrieving revision 1.12
diff -u -r1.12 display.c
--- display.c	18 Feb 2007 20:16:33 -0000	1.12
+++ display.c	22 Feb 2007 21:35:19 -0000
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h> 
+#include <math.h> 
 #include <grass/gis.h>
 #include <grass/Vect.h>
 #include <grass/raster.h>
@@ -24,13 +25,11 @@
     
     G_debug (2, "display_points()");
 
-    R_line_width ( var_geti( VAR_LINEWIDTH ) );
+    driver_line_width ( var_geti( VAR_LINEWIDTH ) );
     for(i=1; i < Points->n_points; i++) {
         G_plot_line ( Points->x[i-1], Points->y[i-1], Points->x[i], Points->y[i]);
     }
-    R_line_width ( 0 );
-   
-    if ( flsh ) R_flush();
+    driver_line_width( 0 );
 }
 
 /* Display icon */
@@ -38,11 +37,9 @@
 {
     G_debug (2, "display_icon()");
 
-    R_line_width ( var_geti( VAR_LINEWIDTH ) );
+    driver_line_width ( var_geti( VAR_LINEWIDTH ) );
     G_plot_icon(x, y, icon, angle, Scale * size);
-    R_line_width ( 0 );
-
-    if ( flsh ) R_flush();
+    driver_line_width ( 0 );
 }
 
 /* Display vector line 
@@ -91,7 +88,6 @@
         if ( !Vect_line_alive ( &Map, line ) ) continue;
         display_line ( line, symb, 0 );
    }
-   R_flush();
 }
 
 /* Display node, color may be given but shape and size is read from symbology table,
@@ -130,7 +126,6 @@
 	if ( NodeSymb[node] == SYMB_NODE_0 ) continue;
 	display_node ( node, symb, 0);
     }
-    R_flush();
 }
 
 /* Display vector map */
@@ -155,7 +150,6 @@
 	if ( !Symb[symb].on ) continue;
 	display_line ( i , SYMB_DEFAULT, 0 );
     }
-    R_flush();
     
     /* Nodes: first nodes with more than 1 line, then nodes with only 1 line, 
      *   so that dangles are not hidden, and nodes without lines (points, 
@@ -169,7 +163,6 @@
 	    if ( NodeSymb[i] != SYMB_NODE_2 ) continue;
 	    display_node(i, NodeSymb[i], 0);
 	}
-	R_flush();
     }
 
     if ( Symb[SYMB_NODE_1].on ) {
@@ -180,33 +173,29 @@
 	    if ( NodeSymb[i] != SYMB_NODE_1 ) continue;
 	    display_node(i, NodeSymb[i], 0);
         }
-	R_flush();
     }
 }
 
 /* Display bacground */
 void display_bg ( void )
 {
+#if 0
     int i;
     
     G_debug (2, "display_bg()");
 
-    driver_close();
     for(i=0; i < nbgcmd; i++) {
 	if ( Bgcmd[i].on ) 
 	    system ( Bgcmd[i].cmd );
     }
-    driver_open();
+#endif
 }
 
 /* Erase */
 void display_erase ( void )
 {
-    char command[128];
-    
     driver_close();
-    sprintf(command, "d.erase color=white");
-    system( command ); /* It does everything and command is registered */
+    Tcl_Eval(Toolbox, ".screen.canvas delete all");
     driver_open();
 
     /* As erase must be run after each zoom by v.digit, here is good place to reset plot.
Index: driver.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/driver.c,v
retrieving revision 1.6
diff -u -r1.6 driver.c
--- driver.c	18 Feb 2007 20:16:33 -0000	1.6
+++ driver.c	22 Feb 2007 21:35:19 -0000
@@ -5,57 +5,100 @@
 #include "global.h"
 #include "proto.h"
 
+static char color[16];
+static int width;
+
+void driver_rgb_color(int r, int g, int b)
+{
+    sprintf(color, "#%02x%02x%02x", r, g, b);
+}
+
+void driver_line_width(int w)
+{
+    width = w ? w : 1;
+}
+
+static int curx, cury;
+
+static int driver_move_abs(int x, int y)
+{
+    curx = x;
+    cury = y;
+    return 0;
+}
+
+static int driver_cont_abs(int x, int y)
+{
+    char buf[1024];
+
+    sprintf(buf, ".screen.canvas create line %d %d %d %d -width %d -fill %s",
+	    curx, cury, x, y, width, color);
+    Tcl_Eval(Toolbox, buf);
+
+    curx = x;
+    cury = y;
+    return 0;
+}
+
+static void get_window(int *t, int *b, int *l, int *r)
+{
+    Tcl_Eval(Toolbox, "list 0 [winfo height .screen.canvas] 0 [winfo width .screen.canvas]");
+    sscanf(Toolbox->result, "%d %d %d %d", t, b, l, r);
+
+    if (*b > 1 || *r > 1)
+	    return;
+
+    Tcl_Eval(Toolbox, "list 0 [.screen.canvas cget -height] 0 [.screen.canvas cget -width]");
+    sscanf(Toolbox->result, "%d %d %d %d", t, b, l, r);
+}
+
+static void setup(void)
+{
+    struct Cell_head region;
+    int t, b, l, r;
+
+    get_window(&t, &b, &l, &r);
+
+    /* Set the map region associated with graphics frame */
+    G_get_set_window(&region);
+    if(G_set_window(&region) < 0)
+	G_fatal_error ("Invalid graphics coordinates");
+
+    /* Determine conversion factors */
+    if (D_do_conversions(&region, t, b, l, r))
+	G_fatal_error("Error calculating graphics-region conversions") ;
+}
 
 int driver_refresh (void)
 {
-    D_setup (0);
+    setup();
     G_setup_plot (D_get_d_north(), D_get_d_south(), D_get_d_west(), D_get_d_east(),
-		                  D_move_abs, D_cont_abs);
+		  driver_move_abs, driver_cont_abs);
     return 1;
 }
-    
+   
 int driver_open (void)
 {
-    int top, bot, left, right;
     double n, s, e, w;
     
-    G_debug (5, "driver_open()");
-    if (R_open_driver() != 0) G_fatal_error ("No graphics device selected");
-    G_debug (5, " -> opened");
-
-    D_setup (0);
-    D_get_screen_window ( &top, &bot, &left, &right); 
-    G_debug (2, "top = %d bot = %d, left = %d right = %d", top, bot, left, right);
+    Tcl_Eval(Toolbox, "create_screen");
 
-    
-    G_debug (2, "n = %f s = %f, w = %f e = %f", D_get_d_north(), D_get_d_south(), D_get_d_west(), D_get_d_east() );
-    n = D_d_to_u_row ( D_get_d_north() ); 
-    s = D_d_to_u_row ( D_get_d_south() ); 
-    w = D_d_to_u_col ( D_get_d_west() );
-    e = D_d_to_u_col (  D_get_d_east() );
-    G_debug (2, "n = %f s = %f, w = %f e = %f", n, s, w, e );
-    
-    Scale = (n - s) / ( D_get_d_south() - D_get_d_north() );
-    G_debug (2, "Scale = %f", Scale);
-    /*
-    Xscale = ( GRegion.east - GRegion.west ) / ( right - left );
-    Yscale = ( GRegion.north - GRegion.south ) / ( top - bot );
+    setup();
 
-    G_debug (2, "Xscale = %f Yscale = %f", Xscale, Yscale);
-    */
-    G_setup_plot (D_get_d_north(), D_get_d_south(), D_get_d_west(), D_get_d_east(),
-                  D_move_abs, D_cont_abs);
-    
-    D_set_clip_window_to_map_window ();
+    n = D_d_to_u_row(D_get_d_north());
+    s = D_d_to_u_row(D_get_d_south());
+    w = D_d_to_u_col(D_get_d_west());
+    e = D_d_to_u_col(D_get_d_east());
+
+    Scale = (n - s) / ( D_get_d_south() - D_get_d_north() );
     
+    G_setup_plot (D_get_d_north(), D_get_d_south(), D_get_d_west(), D_get_d_east(),
+		  driver_move_abs, driver_cont_abs);
     return 1;
 }
 
 int driver_close (void)
 {
-    G_debug (5, "driver_close()");
-    R_close_driver();
-    G_debug (5, " -> closed");
     return 1;
 }
 
Index: i_face.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/i_face.c,v
retrieving revision 1.9
diff -u -r1.9 i_face.c
--- i_face.c	29 Jun 2006 02:40:49 -0000	1.9
+++ i_face.c	22 Feb 2007 21:35:20 -0000
@@ -77,13 +77,6 @@
     return 1;
 }
     
-/* This function should be regularly called from C to get GUI requests */
-int i_update ( void ) {
-    G_debug (5, "i_update");
-    Tcl_Eval ( Toolbox, "update" );
-    return 1;
-}
-
 /* create: 1 - create, 0 - destroy */
 void i_new_line_options ( int create ) {
     int i;
Index: line.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/line.c,v
retrieving revision 1.19
diff -u -r1.19 line.c
--- line.c	21 Feb 2007 22:15:41 -0000	1.19
+++ line.c	22 Feb 2007 21:35:20 -0000
@@ -228,13 +228,13 @@
     return 1;
 }
 
-int new_line(int type)
+void new_line(int type)
 {
-    struct new_line nl;
+    static struct new_line nl;
 
     nl.type = type;
 
-    return do_tool(new_line_begin, new_line_update, new_line_end, &nl);
+    set_tool(new_line_begin, new_line_update, new_line_end, &nl);
 }
 
 /* Continue work on the end of a line */
@@ -407,11 +407,11 @@
     return 1;
 }
 
-int edit_line(void)
+void edit_line(void)
 {
-    struct edit_line el;
+    static struct edit_line el;
 
-    return do_tool(edit_line_begin, edit_line_update, edit_line_end, &el);
+    set_tool(edit_line_begin, edit_line_update, edit_line_end, &el);
 }
 
 /* Delete line */
@@ -538,11 +538,11 @@
     return 1;
 }
 
-int delete_line(void)
+void delete_line(void)
 {
-    struct delete_line dl;
+    static struct delete_line dl;
 
-    return do_tool(delete_line_begin, delete_line_update, delete_line_end, &dl);
+    set_tool(delete_line_begin, delete_line_update, delete_line_end, &dl);
 }
 
 /* Move line */
@@ -669,10 +669,10 @@
     return 1;
 }
 
-int move_line(void)
+void move_line(void)
 {
-    struct move_line ml;
+    static struct move_line ml;
 
-    return do_tool(move_line_begin, move_line_update, move_line_end, &ml);
+    set_tool(move_line_begin, move_line_update, move_line_end, &ml);
 }
 
Index: main.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/main.c,v
retrieving revision 1.25
diff -u -r1.25 main.c
--- main.c	19 Aug 2006 12:52:24 -0000	1.25
+++ main.c	22 Feb 2007 21:35:20 -0000
@@ -25,7 +25,6 @@
 int Tcl_AppInit(Tcl_Interp* interp)
 {
     int ret;
-    char buf[1024];
 
     G_debug (3, "v.digit Tcl_AppInit (...)");
     
@@ -62,27 +61,11 @@
 			      (Tcl_CmdDeleteProc*) NULL);
     Tcl_CreateCommand(interp, "c_add_cat", (Tcl_CmdProc*) c_add_cat, (ClientData) NULL, 
 			      (Tcl_CmdDeleteProc*) NULL);
+    Tcl_CreateCommand(interp, "c_update_tool", (Tcl_CmdProc*) c_update_tool, (ClientData) NULL, 
+			      (Tcl_CmdDeleteProc*) NULL);
 
-    /* Init variables */
-    var_init ();
-
-    /* Init snap */
-    var_seti ( VAR_SNAP, 1 );
-    var_seti ( VAR_SNAP_MODE, SNAP_SCREEN );
-    var_seti ( VAR_SNAP_SCREEN, 10 );
-    var_setd ( VAR_SNAP_MAP, 10 );
-    
     G_debug (3, "Starting toolbox.tcl");
 
-    sprintf(buf,"%s/etc/v.digit/toolbox.tcl", G_gisbase());
-    ret = Tcl_EvalFile(interp, buf);
-    if ( ret == TCL_ERROR) {
-	if (interp->result != NULL) 
-	    G_fatal_error(_("Cannot open toolbox: %s"), interp->result);
-	else 
-	    G_fatal_error(_("Cannot open toolbox."));
-    }
-
     return TCL_OK;
 }
 
@@ -94,7 +77,8 @@
     struct Flag *new_f;
     char   *mapset;
     char   **tokens;
-    char *fake_argv[2];
+    char *fake_argv[4];
+    char toolbox[GPATH_MAX];
     
     G_gisinit(argv[0]);
 
@@ -138,13 +122,6 @@
     G_debug (1, "Region: N = %f S = %f E = %f W = %f", GRegion.north,
 	GRegion.south, GRegion.east, GRegion.west);
     
-    /* Check driver */
-    if (R_open_driver() != 0)
-	G_fatal_error(_("No graphics device selected"));
-    R_close_driver();
-
-    G_debug (1, "Driver opened");
-    
     /* Open map */
     mapset = G_find_vector2 (map_opt->answer, G_mapset()); 
     if ( mapset == NULL ) {
@@ -174,47 +151,17 @@
     symb_lines_init (); 
     symb_nodes_init (); 
 
-    /* Display the map */
-    symb_init ();
-    G_get_window(&window);
-    driver_open ();
-    display_erase ();
-    display_bg ();
-    display_map ();
-    driver_close ();
-
-    G_get_window(&window);
-
-    /* Set tool */
-    Tool_next = TOOL_NEW_POINT;
-
     G_debug (3, "Starting Tk_Main.");
     
     /* Open toolbox */
+    sprintf(toolbox, "%s/etc/v.digit/toolbox.tcl", G_gisbase());
     fake_argv[0] = argv[0];
-    fake_argv[1] = NULL;
-    Tk_Main(1, fake_argv, Tcl_AppInit);
+    fake_argv[1] = "-f";
+    fake_argv[2] = toolbox;
+    fake_argv[3] = NULL;
+    Tk_Main(3, fake_argv, Tcl_AppInit);
     
     /* Not reached */
     exit(EXIT_SUCCESS) ;
 }
 
-int
-end ( void ) 
-{
-    G_debug (1, "end()");
-    Vect_build_partial (&Map, GV_BUILD_NONE, NULL);
-    Vect_build ( &Map, stdout );
-    Vect_close (&Map);
-
-    if( 1 == G_put_window(&GRegion) )
-	G_message(_("Region restored to original extent."));
-
-    /* clear the screen */
-    R_open_driver();
-    D_setup(TRUE);
-    D_clear_window();
-    R_close_driver();
-
-    return 1;
-}
Index: proto.h
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/proto.h,v
retrieving revision 1.14
diff -u -r1.14 proto.h
--- proto.h	21 Feb 2007 22:15:41 -0000	1.14
+++ proto.h	22 Feb 2007 21:35:21 -0000
@@ -2,11 +2,15 @@
 int driver_open (void); 
 int driver_close (void); 
 int driver_refresh (void);
+void driver_rgb_color(int r, int g, int b);
+void driver_line_width(int w);
+void driver_plot_line(double x1, double y1, double x2, double y2);
 
 /* Miscellaneous */
-int update (int, int);
-int tool_centre (void);
-int end (void);
+void tool_centre (void);
+void next_tool(void);
+void update (int, int);
+void end (void);
 
 /* Symbology */
 int get_symb_code ( char *); 
@@ -29,21 +33,21 @@
 
 /* Edit */
 int snap ( double *, double * );
-int new_line (int);
-int move_vertex (void);
-int add_vertex (void);
-int rm_vertex (void);
-int split_line (void);
-int move_line (void);
-int delete_line (void);
-int edit_line (void);
+void new_line (int);
+void move_vertex (void);
+void add_vertex (void);
+void rm_vertex (void);
+void split_line (void);
+void move_line (void);
+void delete_line (void);
+void edit_line (void);
 
 /* Attributes */
-int copy_cats (void);
-int display_cats (void);
+void copy_cats (void);
+void display_cats (void);
 int del_cat (int, int, int);
 int add_cat (int, int, int);
-int display_attributes (void);
+void display_attributes (void);
 int new_record (int, int);
 int check_record (int, int);
 
@@ -60,9 +64,9 @@
 void display_redraw ( void );
 
 /* Zoom */
-int zoom_window (void);
+void zoom_window (void);
 int zoom_centre (double factor);
-int zoom_pan (void);
+void zoom_pan (void);
 int zoom_default (void);
 int zoom_region (void);
 
@@ -120,13 +124,14 @@
 char *get_line_type_name ( int type);
 void set_location(int x, int y);
 void set_mode(int m);
-void get_location(int *sxn, int *syn, int *button);
 
 typedef int tool_func_begin(void *closure);
 typedef int tool_func_update(void *closure, int sxn, int syn, int button);
 typedef int tool_func_end(void *closure);
 
-int do_tool(tool_func_begin *begin,
-	    tool_func_update *update,
-	    tool_func_end *end,
-	    void *closure);
+void set_tool(tool_func_begin *begin,
+	      tool_func_update *update,
+	      tool_func_end *end,
+	      void *closure);
+void cancel_tool(void);
+int c_update_tool (ClientData , Tcl_Interp *, int, char **);
Index: symb.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/symb.c,v
retrieving revision 1.6
diff -u -r1.6 symb.c
--- symb.c	11 Feb 2007 20:26:19 -0000	1.6
+++ symb.c	22 Feb 2007 21:35:21 -0000
@@ -110,7 +110,7 @@
 {
     G_debug ( 2, "set color to symb %d: %d %d %d", code, Symb[code].r, Symb[code].g, Symb[code].b );
     
-    R_RGB_color ( Symb[code].r, Symb[code].g, Symb[code].b);
+    driver_rgb_color ( Symb[code].r, Symb[code].g, Symb[code].b);
 }
 
 
Index: toolbox.tcl
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/toolbox.tcl,v
retrieving revision 1.25
diff -u -r1.25 toolbox.tcl
--- toolbox.tcl	9 Oct 2006 01:46:10 -0000	1.25
+++ toolbox.tcl	22 Feb 2007 21:35:21 -0000
@@ -25,6 +25,29 @@
 set prompt_right [G_msg "Right mouse button"]
 set coor ""
 
+proc get_update_line {ox oy x y} {
+    .screen.canvas delete active
+    .screen.canvas create line $ox $oy $x $y -tags active -dash {4 4}
+}
+
+proc get_update_box {ox oy x y} {
+    .screen.canvas delete active
+    .screen.canvas create line $ox $oy $ox $y $x $y $x $oy $ox $oy -tags active -dash {4 4}
+}
+
+proc create_screen {} {
+    if {[winfo exists .screen]} return
+
+    toplevel .screen
+    canvas .screen.canvas -background white -width 640 -height 480
+    pack .screen.canvas -fill both -expand yes
+    bind .screen.canvas <ButtonPress> { c_update_tool %x %y %b }
+    bind .screen.canvas <Motion> { c_update_tool %x %y -1 }
+    wm withdraw .screen.canvas
+    wm deiconify .screen.canvas
+    update
+}
+
 # GVariable stores variables by key, this variables are (should be) synchronized with
 # variables in Variable array in C (synchronization should be done somehow better). Key is
 # 'name' in VAR structure in C. Variables are initialized by var_init() on startup.
@@ -236,14 +259,10 @@
 Label .coorf.prompt -width 50 -padx 3 -pady 2 -relief flat -anchor w -textvariable coor
 pack .coorf.prompt -fill x  -side left
 
-set destroyed 0
-bind . <Destroy> { if { "%W" == "."} { c_next_tool exit; set destroyed 1 } }
+bind . <Destroy> { if { "%W" == "."} { c_next_tool exit } }
 
-# Strart tool centre in C and wait until the end
+# Start tool centre in C
 c_tool_centre
 
-# Exit
-#puts "Exit destroyed = $destroyed"
-if { $destroyed == 0 } {
-  destroy .
-}
+tkwait window .
+exit
Index: util.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/util.c,v
retrieving revision 1.4
diff -u -r1.4 util.c
--- util.c	21 Feb 2007 22:15:41 -0000	1.4
+++ util.c	22 Feb 2007 21:35:21 -0000
@@ -47,55 +47,105 @@
     mode = m;
 }
 
-void get_location(int *sxn, int *syn, int *button)
+static tool_func_update *tool_update;
+static tool_func_end *tool_end;
+static void *tool_closure;
+
+static void end_tool(void)
+{
+    Tcl_Eval(Toolbox, ".screen.canvas configure -cursor {}");
+    Tcl_Eval(Toolbox, ".screen.canvas delete active");
+
+    if (tool_end)
+	    (*tool_end)(tool_closure);
+
+    tool_update = NULL;
+    tool_end = NULL;
+    tool_closure = NULL;
+
+    driver_close();
+}
+
+void cancel_tool(void)
+{
+    end_tool();
+}
+
+int c_update_tool( ClientData cdata, Tcl_Interp *interp, int argc, char *argv[])
 {
-    R_set_update_function (update);
+    char buf[100];
+    int x, y, b;
+
+    G_debug (3, "c_update_tool()");
+
+    if ( argc < 4 )
+    {
+	Tcl_SetResult(interp,"Usage: c_update_tool x y b", TCL_VOLATILE);
+	return (TCL_ERROR);
+    }
+
+    if (!tool_update)
+	return TCL_OK;
+
+    Tcl_GetInt(interp, argv[1], &x);
+    Tcl_GetInt(interp, argv[2], &y);
+    Tcl_GetInt(interp, argv[3], &b);
 
     switch (mode)
     {
     case MOUSE_POINT:
-	R_get_location_with_pointer (sxn, syn, button);
 	break;
     case MOUSE_LINE:
-	R_get_location_with_line (sxo, syo, sxn, syn, button); 
+	sprintf(buf, "get_update_line %d %d %d %d", sxo, syo, x, y);
+	Tcl_Eval(Toolbox, buf);
 	break;
     case MOUSE_BOX:
-	R_get_location_with_box (sxo, syo, sxn, syn, button); 
+	sprintf(buf, "get_update_box %d %d %d %d", sxo, syo, x, y);
+	Tcl_Eval(Toolbox, buf);
 	break;
     }
+
+    if (b < 0)
+    {
+	update(x, y);
+	return TCL_OK;
+    }
+
+    if (b == 0)
+    {
+	end_tool();
+	return TCL_OK;
+    }
+
+    if ((*tool_update)(tool_closure, x, y, b))
+    {
+	end_tool();
+	return TCL_OK;
+    }
+
+    return TCL_OK;
 }
 
-int do_tool(tool_func_begin *begin, tool_func_update *update, tool_func_end *end, void *closure)
+void set_tool(tool_func_begin *begin_fn, tool_func_update *update_fn, tool_func_end *end_fn, void *closure)
 {
-    int sxn = COOR_NULL;
-    int syn = COOR_NULL;
-    int button;
     int ret;
 
+    if (tool_update)
+	end_tool();
+
     driver_open();
-    ret = (*begin)(closure);
+    ret = (*begin_fn)(closure);
 
     if (ret)
     {
 	driver_close();
-	return ret;
-    }
-
-    while (1)
-    {
-	/* Get next coordinate */
-        get_location(&sxn, &syn, &button); 
-
-	if (button == 0)
-	    break;
-
-	if ((*update)(closure, sxn, syn, button))
-	    break;
+	return;
     }
+   
+    tool_update = update_fn;
+    tool_end = end_fn;
+    tool_closure = closure;
 
-    ret = (*end)(closure);
-    driver_close();
-
-    return ret;
+    Tcl_Eval(Toolbox, ".screen.canvas configure -cursor crosshair");
 }
 
Index: vertex.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/vertex.c,v
retrieving revision 1.6
diff -u -r1.6 vertex.c
--- vertex.c	21 Feb 2007 22:15:41 -0000	1.6
+++ vertex.c	22 Feb 2007 21:35:21 -0000
@@ -159,11 +159,11 @@
     return 1;
 }
 
-int split_line(void)
+void split_line(void)
 {
-    struct split_line sl;
+    static struct split_line sl;
 
-    return do_tool(split_line_begin, split_line_update, split_line_end, &sl);
+    set_tool(split_line_begin, split_line_update, split_line_end, &sl);
 }
 
 /* Remove line vertex */
@@ -309,11 +309,11 @@
     return 1;
 }
 
-int rm_vertex(void)
+void rm_vertex(void)
 {
-    struct rm_vertex rv;
+    static struct rm_vertex rv;
 
-    return do_tool(rm_vertex_begin, rm_vertex_update, rm_vertex_end, &rv);
+    set_tool(rm_vertex_begin, rm_vertex_update, rm_vertex_end, &rv);
 }
 
 /* Add new vertex to line */
@@ -487,11 +487,11 @@
     return 1;
 }
 
-int add_vertex(void)
+void add_vertex(void)
 {
-    struct add_vertex av;
+    static struct add_vertex av;
 
-    return do_tool(add_vertex_begin, add_vertex_update, add_vertex_end, &av);
+    set_tool(add_vertex_begin, add_vertex_update, add_vertex_end, &av);
 }
 
 /* Move vertex */
@@ -625,10 +625,10 @@
     return 1;
 }
 
-int move_vertex(void)
+void move_vertex(void)
 {
-    struct move_vertex mv;
+    static struct move_vertex mv;
 
-    return do_tool(move_vertex_begin, move_vertex_update, move_vertex_end, &mv);
+    set_tool(move_vertex_begin, move_vertex_update, move_vertex_end, &mv);
 }
 
Index: zoom.c
===================================================================
RCS file: /grassrepository/grass6/vector/v.digit/zoom.c,v
retrieving revision 1.7
diff -u -r1.7 zoom.c
--- zoom.c	21 Feb 2007 22:15:41 -0000	1.7
+++ zoom.c	22 Feb 2007 21:35:21 -0000
@@ -96,11 +96,11 @@
     return 1;
 }
 
-int zoom_window(void)
+void zoom_window(void)
 {
-    struct zoom_window zw;
+    static struct zoom_window zw;
 
-    return do_tool(zoom_window_begin, zoom_window_update, zoom_window_end, &zw);
+    set_tool(zoom_window_begin, zoom_window_update, zoom_window_end, &zw);
 }
 
 /* Zoom - in / out (centre unchanged) */
@@ -201,11 +201,11 @@
     return 1;
 }
 
-int zoom_pan(void)
+void zoom_pan(void)
 {
-    struct zoom_pan zp;
+    static struct zoom_pan zp;
 
-    return do_tool(zoom_pan_begin, zoom_pan_update, zoom_pan_end, &zp);
+    set_tool(zoom_pan_begin, zoom_pan_update, zoom_pan_end, &zp);
 }
 
 /* Zoom - default region */


More information about the grass-dev mailing list