[gromit: 8/13] * README * gromit.c: Implemented Arrowheads, changed Name of resourcefile to "~/.gromi



commit fa1d50ce7262d6653bf96e84d8e9b0cbe6a433c7
Author: Simon Budig <simon budig de>
Date:   Mon Dec 10 23:25:00 2001 +0100

    * README
    * gromit.c:  Implemented Arrowheads,
                 changed Name of resourcefile to "~/.gromitrc"
    
    Import of gromit history

 ChangeLog |   15 +++
 Makefile  |    4 +-
 README    |   10 ++-
 gromit.c  |  412 ++++++++++++++++++++++++++++++++++++++++++++++---------------
 gromitrc  |   26 ++++
 5 files changed, 364 insertions(+), 103 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..fd5810e
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,15 @@
+2001-12-10  Simon Budig  <simon gimp org>
+
+	* README
+	* gromit.c:  Implemented Arrowheads,
+		     changed Name of resourcefile to "~/.gromitrc"
+
+2001-02-26  Simon Budig  <simon gimp org>
+	
+	* */* Sorry, no real changelog.
+
+2000-08-28  Simon Budig  <simon gimp org>
+
+        * */* First version
+
+
diff --git a/Makefile b/Makefile
index 4fe7115..249c8e2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
 all: gromit
 
-gromit: gromit.c
-	gcc -o gromit gromit.c `gtk-config --libs --cflags`
+gromit: gromit.c Makefile
+	gcc -o gromit gromit.c -Wall `gtk-config --libs --cflags`
diff --git a/README b/README
index 06525fd..74b059c 100644
--- a/README
+++ b/README
@@ -53,7 +53,7 @@ programs as usual - only the painted regions will be obscured.
 I included the (shell-)script "sawfish-config". If you are using the
 sawfish-windowmanager you can simply start this script. The "Pause"-Key
 will be bound to the (de)activation, the "Break"-Key (probably
-Shift+Pause) will clear the screen, "Control-Pause" will toccle the
+Shift+Pause) will clear the screen, "Control-Pause" will toggle the
 visibility of Gromit. If you have config-files for other window-managers
 I'd be happy to include them. Please send them to me.
 
@@ -69,7 +69,7 @@ Linux/XFree86, reports from other platforms are welcome.
 
 Configuration:
 
-Gromit is configurable via the file ".gromit" in your Homedirectory.
+Gromit is configurable via the file ".gromitrc" in your Homedirectory.
 Here you can specify which Device/Button/Modifier combination invokes
 which tool. See the file "gromitconf" distributed with this program for
 an example. An overview on the syntax:
@@ -89,6 +89,12 @@ The following Entries copy an existing configuration (in this case
      "blue Pen" = "red Pen" (color="blue");
      "yellow Pen" = "red Pen" (color="yellow");
 
+You can also draw lines that end in an arrow head. For this you
+have to specify "arrowsize". A good start is width / 2.
+[may be changed to be a factor relative to width]
+
+     "blue Pen" = "blue Arrow" (arrowsize=4);
+
 An "ERASER" is a tool that erases the drawings on screen.
 The color parameter is not important.
 
diff --git a/gromit.c b/gromit.c
index 119cc5e..c7423dd 100644
--- a/gromit.c
+++ b/gromit.c
@@ -23,21 +23,25 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
 
 #include "paint_cursor.xbm"
 #include "paint_cursor_mask.xbm"
 #include "erase_cursor.xbm"
 #include "erase_cursor_mask.xbm"
 
-#define GROMIT_PAINT_AREA_EVENTS  ( GDK_EXPOSURE_MASK | \
-				    GDK_PROXIMITY_IN_MASK | \
-				    GDK_PROXIMITY_OUT_MASK | \
-				    GDK_BUTTON_PRESS_MASK | \
-				    GDK_BUTTON_MOTION_MASK \
-				    /* | GDK_POINTER_MOTION_HINT_MASK */ )
+#define GROMIT_MOUSE_EVENTS ( GDK_PROXIMITY_IN_MASK | \
+			      GDK_PROXIMITY_OUT_MASK | \
+			      GDK_BUTTON_MOTION_MASK | \
+			      GDK_BUTTON_PRESS_MASK | \
+			      GDK_BUTTON_RELEASE_MASK )
+
+#define GROMIT_PAINT_AREA_EVENTS  ( GROMIT_MOUSE_EVENTS | GDK_EXPOSURE_MASK )
  
 /* #define GROMIT_WINDOW_EVENTS ( GDK_PROPERTY_CHANGE_MASK ) */
-#define GROMIT_WINDOW_EVENTS ( 0 )
+#define GROMIT_WINDOW_EVENTS ( GROMIT_PAINT_AREA_EVENTS )
 
 /* Atoms used to control Gromit */
 #define GA_CONTROL    gdk_atom_intern ("Gromit/control", FALSE)
@@ -61,13 +65,25 @@ typedef struct
 {
    GromitPaintType type;
    guint	   width;
+   gfloat	   arrowsize;
    GdkColor	  *fg_color;
    GdkGC	  *paint_gc;
    GdkGC          *shape_gc;
+   gdouble	   lastx;
+   gdouble	   lasty;
+   gdouble	   pressure;
 } GromitPaintContext;
 
 typedef struct
 {
+   gint x;
+   gint y;
+   gint width;
+} GromitStrokeCoordinate;
+
+
+typedef struct
+{
    GtkWidget	*win;
    GtkWidget	*area;
    GtkWidget	*panel;
@@ -92,10 +108,10 @@ typedef struct
    GdkColor	*transparent;
    GdkColor	*opaque;
 
-   gdouble	lastx;
-   gdouble	lasty;
+   // gdouble	lastx;
+   // gdouble	lasty;
    guint32	motion_time;
-   gdouble	count;
+   GList       *coordlist;
    
    guint32	deviceid;
    guint	state;
@@ -119,7 +135,7 @@ void gromit_aquire_grab (GromitData *data);
 
 GromitPaintContext *
 gromit_paint_context_new (GromitData *data, GromitPaintType type,
-			  GdkColor *fg_color, guint width)
+			  GdkColor *fg_color, guint width, guint arrowsize)
 {
    GromitPaintContext *context;
    GdkGCValues   shape_gcv;
@@ -128,6 +144,7 @@ gromit_paint_context_new (GromitData *data, GromitPaintType type,
 
    context->type = type;
    context->width = width;
+   context->arrowsize = arrowsize;
    context->fg_color = fg_color;
    
    if (type == GROMIT_ERASER)
@@ -176,6 +193,7 @@ gromit_paint_context_print (gchar *name, GromitPaintContext *context)
 	 g_printerr ("UNKNOWN, "); break;
    };
    g_printerr ("width: %3d, ", context->width);
+   g_printerr ("arrowsize: %3f, ", context->arrowsize);
    g_printerr ("color: #%02X%02X%02X\n", context->fg_color->red >> 8,
 	       context->fg_color->green >> 8, context->fg_color->blue >> 8);
 }
@@ -191,6 +209,85 @@ gromit_paint_context_free (GromitPaintContext *context)
 
 
 void
+gromit_coord_list_prepend (GromitData *data, gint x, gint y, gint width)
+{
+   GromitStrokeCoordinate *point;
+
+   point = g_malloc (sizeof (GromitStrokeCoordinate));
+   point->x = x;
+   point->y = y;
+   point->width = width;
+
+   data->coordlist = g_list_prepend (data->coordlist, point);
+}
+
+
+void
+gromit_coord_list_free (GromitData *data)
+{
+   GList *ptr;
+
+   ptr = data->coordlist;
+
+   while (ptr) {
+      g_free (ptr->data);
+      ptr = ptr->next;
+   }
+
+   g_list_free (data->coordlist);
+
+   data->coordlist = NULL;
+}
+
+
+gboolean
+gromit_coord_list_get_arrow_param (GromitData *data,
+				   gint        search_radius,
+				   gint       *ret_width,
+				   gfloat     *ret_direction)
+{
+   gint x0, y0, r2, dist;
+   gboolean success = FALSE;
+   GromitStrokeCoordinate  *cur_point, *valid_point;
+   GList *ptr = data->coordlist;
+   gfloat width;
+
+   valid_point = NULL;
+
+   if (ptr) {
+      cur_point = ptr->data;
+      x0 = cur_point->x;
+      y0 = cur_point->y;
+      r2 = search_radius * search_radius;
+      dist = 0;
+
+      while (ptr && dist < r2) {
+         ptr = ptr->next;
+         if (ptr) {
+            cur_point = ptr->data;
+            dist = (cur_point->x - x0) * (cur_point->x - x0) +
+                   (cur_point->y - y0) * (cur_point->y - y0);
+	    width = cur_point->width * data->cur_context->arrowsize;
+	    if (width * 2 <= dist) {
+	       if (!valid_point || valid_point->width < cur_point->width) {
+		  valid_point = cur_point;
+	       }
+	    }
+         }
+      }
+
+      if (valid_point) {
+	 *ret_width = MAX (valid_point->width * data->cur_context->arrowsize, 2);
+         *ret_direction = atan2 (y0 - valid_point->y, x0 - valid_point->x);
+         success = TRUE;
+      }
+   }
+
+   return success;
+}
+
+
+void
 gromit_hide_window (GromitData *data)
 {
    if (!data->hidden)
@@ -238,6 +335,8 @@ gromit_release_grab (GromitData *data)
    {
       data->hard_grab = 0;
       gdk_pointer_ungrab (GDK_CURRENT_TIME);
+      /* inherit cursor from root window */
+      gdk_window_set_cursor (data->win->window, NULL);
    }
    if (!data->painted)
       gromit_hide_window (data);
@@ -254,9 +353,9 @@ gromit_aquire_grab (GromitData *data)
    {
 
       result = gdk_pointer_grab (data->area->window, FALSE,
-	       GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK |
-	       GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK,
-	       0, NULL /* data->paint_cursor */, GDK_CURRENT_TIME);
+				 GROMIT_MOUSE_EVENTS, 0,
+				 NULL /* data->paint_cursor */,
+				 GDK_CURRENT_TIME);
       switch (result) {
        	 case Success:
 	    data->hard_grab = 1;
@@ -276,6 +375,11 @@ gromit_aquire_grab (GromitData *data)
 	 default:
 	    g_printerr ("Grabbing Pointer failed: %s\n", "Unknown error");
       }
+      if (data->cur_context->type == GROMIT_ERASER)
+	 gdk_window_set_cursor (data->win->window, data->erase_cursor);
+      else
+	 gdk_window_set_cursor (data->win->window, data->paint_cursor);
+
    }
 }
 
@@ -307,7 +411,6 @@ gint
 reshape (gpointer user_data)
 {
    GromitData *data = (GromitData *) user_data;
-   static delay_count = 0;
 
    if (data->modified) {
       if (gtk_events_pending () && data->delayed < 5) {
@@ -436,6 +539,59 @@ gromit_draw_line (GromitData *data, gint x1, gint y1,
 }
 
 
+void
+gromit_draw_arrow (GromitData *data, gint x1, gint y1,
+                   gint width, gfloat direction)
+{
+   GdkRectangle rect;
+   GdkPoint arrowhead [4];
+
+   width = width / 2;
+
+   /* I doubt that calculating the boundary box more exact is very useful */
+   rect.x = x1 - 4 * width - 1;
+   rect.y = y1 - 4 * width - 1;
+   rect.width = 8 * width + 2;
+   rect.height = 8 * width + 2;
+   
+   arrowhead [0].x = x1 + 4 * width * cos (direction);
+   arrowhead [0].y = y1 + 4 * width * sin (direction);
+
+   arrowhead [1].x = x1 - 3 * width * cos (direction) + 3 * width * sin (direction);
+   arrowhead [1].y = y1 - 3 * width * cos (direction) - 3 * width * sin (direction);
+
+   arrowhead [2].x = x1 - 2 * width * cos (direction);
+   arrowhead [2].y = y1 - 2 * width * sin (direction);
+
+   arrowhead [3].x = x1 - 3 * width * cos (direction) - 3 * width * sin (direction);
+   arrowhead [3].y = y1 + 3 * width * cos (direction) - 3 * width * sin (direction);
+
+   if (data->cur_context->paint_gc)
+      gdk_gc_set_line_attributes (data->cur_context->paint_gc,
+				  0, GDK_LINE_SOLID,
+				  GDK_CAP_ROUND, GDK_JOIN_ROUND);
+   if (data->cur_context->shape_gc)
+      gdk_gc_set_line_attributes (data->cur_context->shape_gc,
+				  data->maxwidth, GDK_LINE_SOLID,
+				  GDK_CAP_ROUND, GDK_JOIN_ROUND);
+   
+   if (data->cur_context->paint_gc)
+      gdk_draw_polygon (data->pixmap, data->cur_context->paint_gc,
+			TRUE, arrowhead, 4);
+   
+   if (data->cur_context->shape_gc) {
+      gdk_draw_polygon (data->shape, data->cur_context->shape_gc,
+			TRUE, arrowhead, 4);
+      data->modified = 1;
+   }
+   
+   if (data->cur_context->paint_gc)
+      gtk_widget_draw (data->area, &rect);
+   
+   data->painted = 1;
+}
+
+
 /*
  * Event-Handlers to perform the drawing
  */
@@ -449,7 +605,8 @@ proximity_in (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
    
    gdk_window_get_pointer (data->win->window, &x, &y, &state);
    gromit_select_tool (data, ev->deviceid, state);
-   return 0;
+
+   return TRUE;
 }
 
 
@@ -467,6 +624,8 @@ proximity_out (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
 
    data->state = 0;
    data->deviceid = 0;
+
+   return FALSE;
 }
 
 
@@ -475,31 +634,60 @@ paint (GtkWidget *win, GdkEventButton *ev, gpointer user_data)
 {
    GromitData *data = (GromitData *) user_data;
    
-   /* See GdkModifierType. Am I fixing a Gtk misbehaviour???  */
-   ev->state |= 1 << (ev->button + 7); 
-   if (ev->state != data->state || ev->deviceid != data->deviceid)
-      gromit_select_tool (data, ev->deviceid, ev->state);
+   if (data->hard_grab) {
+      /* See GdkModifierType. Am I fixing a Gtk misbehaviour???  */
+      ev->state |= 1 << (ev->button + 7); 
+      if (ev->state != data->state || ev->deviceid != data->deviceid)
+	 gromit_select_tool (data, ev->deviceid, ev->state);
 
-   gdk_window_set_background (data->area->window,
-			      data->cur_context->fg_color);
+      gdk_window_set_background (data->area->window,
+				 data->cur_context->fg_color);
 
-   data->lastx = ev->x;
-   data->lasty = ev->y;
-   data->motion_time = ev->time;
+      data->cur_context->lastx = ev->x;
+      data->cur_context->lasty = ev->y;
+      data->motion_time = ev->time;
 
-   if (ev->source == GDK_SOURCE_MOUSE)
-      data->maxwidth = data->cur_context->width;
-   else
-      data->maxwidth = (CLAMP (ev->pressure * ev->pressure,0,1) *
-			(double) data->cur_context->width);
+      if (ev->source == GDK_SOURCE_MOUSE)
+	 data->maxwidth = data->cur_context->width;
+      else
+	 data->maxwidth = (CLAMP (ev->pressure * ev->pressure,0,1) *
+			   (double) data->cur_context->width);
 
-   if (ev->button <= 5)
-      gromit_draw_line (data, ev->x, ev->y, ev->x, ev->y);
+      if (ev->button <= 5)
+	 gromit_draw_line (data, ev->x, ev->y, ev->x, ev->y);
 
-   /* if (data->cur_context->shape_gc && !gtk_events_pending ())
-      gtk_widget_shape_combine_mask (data->win, data->shape, 0,0); */
+      gromit_coord_list_prepend (data, ev->x, ev->y, data->maxwidth);
 
-   return 1;
+      /* if (data->cur_context->shape_gc && !gtk_events_pending ())
+	 gtk_widget_shape_combine_mask (data->win, data->shape, 0,0); */
+
+      return TRUE;
+   } else {
+      return FALSE;
+   } 
+}
+
+
+gboolean
+paintend (GtkWidget *win, GdkEventButton *ev, gpointer user_data)
+{
+   GromitData *data = (GromitData *) user_data;
+   gint width = data->cur_context->arrowsize * data->cur_context->width / 2;
+   gfloat direction = 0;
+   
+   if (data->hard_grab) {
+      if (data->cur_context->arrowsize != 0) {
+	 if (gromit_coord_list_get_arrow_param (data, width * 4, &width, &direction)) {
+	    gromit_draw_arrow (data, ev->x, ev->y, width, direction);
+	 }
+      }
+
+      gromit_coord_list_free (data);
+
+      return TRUE;
+   } else {
+      return FALSE;
+   }
 }
 
 
@@ -511,46 +699,58 @@ paintto (GtkWidget *win, GdkEventMotion *ev, gpointer user_data)
    int nevents;
    int i;
 
-   if (ev->state != data->state || ev->deviceid != data->deviceid)
-      gromit_select_tool (data, ev->deviceid, ev->state);
+   if (data->hard_grab) {
+      if (ev->state != data->state || ev->deviceid != data->deviceid)
+	 gromit_select_tool (data, ev->deviceid, ev->state);
 
-   coords = gdk_input_motion_events (ev->window, ev->deviceid,
-				     data->motion_time, ev->time, &nevents);
-   /* g_printerr ("Got %d coords\n", nevents); */
-   if (coords)
-   {
-      for (i=0; i<nevents; i++) {
-	 if (ev->source == GDK_SOURCE_MOUSE)
-	    data->maxwidth = data->cur_context->width;
-	 else
-	    data->maxwidth = (CLAMP (coords[i].pressure*coords[i].pressure,0,1)*
-			      (double) data->cur_context->width);
-	 gromit_draw_line (data, data->lastx, data->lasty,
-			   coords[i].x, coords[i].y);
-	 data->lastx = coords[i].x;
-	 data->lasty = coords[i].y;
-      }
-      data->motion_time = coords[nevents-1].time;
-      g_free (coords);
-   } else {
-      if (ev->is_hint) {
-	 gdk_input_window_get_pointer (ev->window, ev->deviceid,
-				       NULL, NULL, NULL, NULL, NULL, NULL);
+      coords = gdk_input_motion_events (ev->window, ev->deviceid,
+					data->motion_time, ev->time, &nevents);
+      /* g_printerr ("Got %d coords\n", nevents); */
+      if (coords)
+      {
+	 for (i=0; i<nevents; i++) {
+	    if (ev->pressure > 0) {
+	       if (ev->source == GDK_SOURCE_MOUSE)
+		  data->maxwidth = data->cur_context->width;
+	       else
+		  data->maxwidth = (CLAMP (coords[i].pressure*coords[i].pressure,0,1)*
+				    (double) data->cur_context->width);
+	       gromit_draw_line (data, data->cur_context->lastx, data->cur_context->lasty,
+				 coords[i].x, coords[i].y);
+
+	       gromit_coord_list_prepend (data, ev->x, ev->y, data->maxwidth);
+	       data->cur_context->lastx = coords[i].x;
+	       data->cur_context->lasty = coords[i].y;
+	    }
+	 }
+	 data->motion_time = coords[nevents-1].time;
+	 g_free (coords);
+      } else {
+	 if (ev->is_hint) {
+	    gdk_input_window_get_pointer (ev->window, ev->deviceid,
+					  NULL, NULL, &(ev->pressure), NULL, NULL, NULL);
+	 }
+	 if (ev->pressure > 0) {
+	    if (ev->source == GDK_SOURCE_MOUSE)
+	       data->maxwidth = data->cur_context->width;
+	    else
+	       data->maxwidth = (CLAMP (ev->pressure * ev->pressure,0,1) *
+				 (double) data->cur_context->width);
+	    gromit_draw_line (data, data->cur_context->lastx, data->cur_context->lasty, ev->x, ev->y);
+
+	    gromit_coord_list_prepend (data, ev->x, ev->y, data->maxwidth);
+	    data->cur_context->lastx = ev->x;
+	    data->cur_context->lasty = ev->y;
+	 }
       }
-      if (ev->source == GDK_SOURCE_MOUSE)
-	 data->maxwidth = data->cur_context->width;
-      else
-	 data->maxwidth = (CLAMP (ev->pressure * ev->pressure,0,1) *
-			   (double) data->cur_context->width);
-      gromit_draw_line (data, data->lastx, data->lasty, ev->x, ev->y);
-      data->lastx = ev->x;
-      data->lasty = ev->y;
-   }
 
-   data->lastx=ev->x;
-   data->lasty=ev->y;
+      data->cur_context->lastx = ev->x;
+      data->cur_context->lasty = ev->y;
 
-   return 0;
+      return TRUE;
+   } else {
+      return FALSE;
+   }
 }
 
 
@@ -578,7 +778,7 @@ event_configure (GtkWidget *widget,
 		       1, 0, 0, data->width, data->height);
    gdk_window_set_transient_for (data->area->window, data->win->window);
 
-   return 1;
+   return TRUE;
 }
 
 
@@ -594,7 +794,7 @@ event_expose (GtkWidget *widget,
 		    data->pixmap, event->area.x, event->area.y,
 		    event->area.x, event->area.y, event->area.width,
 		    event->area.height);
-   return 0;
+   return TRUE;
 }
 
 
@@ -714,7 +914,9 @@ parse_print_help (gpointer key, gpointer value, gpointer user_data)
    gromit_paint_context_print ((gchar *) key, (GromitPaintContext *) value);
 }
 
-gint parse_config (GromitData *data) {
+
+void
+parse_config (GromitData *data) {
 
    GromitPaintContext *context=NULL;
    GromitPaintContext *context_template=NULL;
@@ -727,11 +929,9 @@ gint parse_config (GromitData *data) {
 
    GromitPaintType type;
    GdkColor *fg_color=NULL;
-   guint width;
-
-   guint buttons, modifier;
+   guint width, arrowsize;
 
-   filename = g_strjoin (G_DIR_SEPARATOR_S, g_get_home_dir(), ".gromit", NULL);
+   filename = g_strjoin (G_DIR_SEPARATOR_S, g_get_home_dir(), ".gromitrc", NULL);
    file = open (filename, O_RDONLY);
 
    if (file < 0)
@@ -754,18 +954,19 @@ gint parse_config (GromitData *data) {
    g_scanner_scope_add_symbol (scanner, 0, "ERASER", (gpointer) GROMIT_ERASER);
    g_scanner_scope_add_symbol (scanner, 0, "RECOLOR",(gpointer) GROMIT_RECOLOR);
 
-   g_scanner_scope_add_symbol (scanner, 1, "BUTTON1",(gpointer) 1);
-   g_scanner_scope_add_symbol (scanner, 1, "BUTTON2",(gpointer) 2);
-   g_scanner_scope_add_symbol (scanner, 1, "BUTTON3",(gpointer) 3);
-   g_scanner_scope_add_symbol (scanner, 1, "BUTTON4",(gpointer) 4);
-   g_scanner_scope_add_symbol (scanner, 1, "BUTTON5",(gpointer) 5);
-   g_scanner_scope_add_symbol (scanner, 1, "SHIFT",  (gpointer) 11);
-   g_scanner_scope_add_symbol (scanner, 1, "CONTROL",(gpointer) 12);
-   g_scanner_scope_add_symbol (scanner, 1, "META",   (gpointer) 13);
-   g_scanner_scope_add_symbol (scanner, 1, "ALT",    (gpointer) 13);
-
-   g_scanner_scope_add_symbol (scanner, 2, "size",   (gpointer) 1);
-   g_scanner_scope_add_symbol (scanner, 2, "color",  (gpointer) 2);
+   g_scanner_scope_add_symbol (scanner, 1, "BUTTON1", (gpointer) 1);
+   g_scanner_scope_add_symbol (scanner, 1, "BUTTON2", (gpointer) 2);
+   g_scanner_scope_add_symbol (scanner, 1, "BUTTON3", (gpointer) 3);
+   g_scanner_scope_add_symbol (scanner, 1, "BUTTON4", (gpointer) 4);
+   g_scanner_scope_add_symbol (scanner, 1, "BUTTON5", (gpointer) 5);
+   g_scanner_scope_add_symbol (scanner, 1, "SHIFT",   (gpointer) 11);
+   g_scanner_scope_add_symbol (scanner, 1, "CONTROL", (gpointer) 12);
+   g_scanner_scope_add_symbol (scanner, 1, "META",    (gpointer) 13);
+   g_scanner_scope_add_symbol (scanner, 1, "ALT",     (gpointer) 13);
+
+   g_scanner_scope_add_symbol (scanner, 2, "size",      (gpointer) 1);
+   g_scanner_scope_add_symbol (scanner, 2, "color",     (gpointer) 2);
+   g_scanner_scope_add_symbol (scanner, 2, "arrowsize", (gpointer) 3);
    
    g_scanner_set_scope (scanner, 0);
    scanner->config->scope_0_fallback = 0;
@@ -795,6 +996,7 @@ gint parse_config (GromitData *data) {
 
 	 type = GROMIT_PEN;
 	 width = 7;
+	 arrowsize = 0;
 	 fg_color = data->red;
 
 	 if (token == G_TOKEN_SYMBOL) {
@@ -807,6 +1009,7 @@ gint parse_config (GromitData *data) {
 	    if (context_template) {
 	       type = context_template->type;
 	       width = context_template->width;
+	       arrowsize = context_template->arrowsize;
 	       fg_color = context_template->fg_color;
 	    } else {
 	       g_printerr ("WARNING: Unable to copy \"%s\": not yet defined!\n", copy);
@@ -863,6 +1066,18 @@ gint parse_config (GromitData *data) {
 		     }
 		     color = NULL;
 
+                  } else if ((guint) scanner->value.v_symbol == 3) {
+		     token = g_scanner_get_next_token (scanner);
+		     if (token != G_TOKEN_EQUAL_SIGN) {
+			g_printerr ("Missing \"=\"... aborting\n");
+			exit (1);
+		     }
+		     token = g_scanner_get_next_token (scanner);
+		     if (token != G_TOKEN_FLOAT) {
+			g_printerr ("Missing Arrowsize (float)... aborting\n");
+			exit (1);
+		     }
+		     arrowsize = scanner->value.v_float;
 		  } else {
 		     g_printerr ("Unknown tool type?????\n");
 		  }
@@ -884,7 +1099,7 @@ gint parse_config (GromitData *data) {
 	    exit (1);
 	 }
 
-	 context = gromit_paint_context_new (data, type, fg_color, width);
+	 context = gromit_paint_context_new (data, type, fg_color, width, arrowsize);
 	 g_hash_table_insert (data->tool_config, name, context);
 
       } else {
@@ -944,7 +1159,6 @@ setup_client_app (GromitData *data)
 {
    data->width = gdk_screen_width ();
    data->height = gdk_screen_height ();
-   data->count = 0;
    data->hard_grab = 0;
 
    data->win = gtk_window_new (GTK_WINDOW_POPUP);
@@ -969,7 +1183,6 @@ void
 setup_main_app (GromitData *data)
 {
    GdkPixmap *cursor_src, *cursor_mask;
-   Window xwin;
 
    /* COLORMAP */
    data->cm = gdk_colormap_get_system ();
@@ -1008,9 +1221,6 @@ setup_main_app (GromitData *data)
    gdk_pixmap_unref (cursor_src);
    gdk_pixmap_unref (cursor_mask);
 
-   /* data->paint_cursor = gdk_cursor_new (GDK_PLUS); */
-   /* data->erase_cursor = gdk_cursor_new (GDK_RTL_LOGO); */
-
    gdk_window_set_cursor (data->win->window, data->paint_cursor);
 
    /* SHAPE PIXMAP */
@@ -1038,6 +1248,8 @@ setup_main_app (GromitData *data)
 		       GTK_SIGNAL_FUNC (paintto), (gpointer) data);
    gtk_signal_connect (GTK_OBJECT (data->win), "button_press_event",
 		       GTK_SIGNAL_FUNC (paint), (gpointer) data);
+   gtk_signal_connect (GTK_OBJECT (data->win), "button_release_event",
+		       GTK_SIGNAL_FUNC (paintend), (gpointer) data);
    gtk_signal_connect (GTK_OBJECT (data->win), "proximity_in_event",
 		       GTK_SIGNAL_FUNC (proximity_in), (gpointer) data);
    gtk_signal_connect (GTK_OBJECT (data->win), "proximity_out_event",
@@ -1056,11 +1268,13 @@ setup_main_app (GromitData *data)
    gromit_hide_window (data);
 
    data->timeout_id = gtk_timeout_add (20, reshape, data);
+   data->coordlist = NULL;
    data->modified = 0;
 
-   data->default_pen = gromit_paint_context_new (data, GROMIT_PEN, data->red, 7);
-   data->default_eraser = gromit_paint_context_new (data, GROMIT_ERASER, data->red, 75);
+   data->default_pen = gromit_paint_context_new (data, GROMIT_PEN, data->red, 7, 0);
+   data->default_eraser = gromit_paint_context_new (data, GROMIT_ERASER, data->red, 75, 0);
 
+   data->cur_context = data->default_pen;
 
    /*
     * Parse Config file
@@ -1120,7 +1334,7 @@ main_client (int argc, char **argv, GromitData *data)
       }
    }
 
-   return 0;
+   return TRUE;
 }
 
 int
diff --git a/gromitrc b/gromitrc
new file mode 100644
index 0000000..ec64028
--- /dev/null
+++ b/gromitrc
@@ -0,0 +1,26 @@
+# Configuration file for gromit
+
+# Tools
+
+"roter Stift" = PEN (size=7 color="red");
+"blauer Stift" = "roter Stift" (color="blue");
+"gelber Stift" = "roter Stift" (color="yellow");
+"rosa Stift" = "roter Stift" (color="#ff00aa");
+"Radierer" = ERASER (size = 75);
+"grüner Marker" = RECOLOR (color = "Limegreen");
+
+
+# Mapping to Pointing devices
+
+"Core Pointer" = "roter Stift";
+"Core Pointer"[SHIFT] = "blauer Stift";
+"Core Pointer"[CONTROL] = "gelber Stift";
+"Core Pointer"[META] = "rosa Stift";
+"Core Pointer"[2] = "grüner Marker";
+"Core Pointer"[3] = "Radierer";
+"Core Pointer"[3 SHIFT] = "Radierer" (size = 150);
+"Pen1" = "roter Stift" (size = 15);
+"Pen1"[SHIFT] = "blauer Stift";
+"Pen1"[CONTROL] = "Radierer";
+"Eraser" = "Radierer";
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]