[gromit: 4/13] Import of gromit history



commit 4a56c6a3cf248e47f7aa9d2881f0d10e2ca0b587
Author: Simon Budig <simon budig de>
Date:   Wed Nov 1 12:00:00 2000 +0100

    Import of gromit history

 Makefile              |    4 +-
 README                |   65 ++++++++++++--
 erase_cursor.xbm      |   17 ++++
 erase_cursor_mask.xbm |   17 ++++
 gromit.c              |  121 ++++++++++++++++++++------
 gromitconf            |    7 ++-
 gromitconf.final      |   14 ---
 parser.c              |  234 -------------------------------------------------
 parsertest            |    4 -
 9 files changed, 194 insertions(+), 289 deletions(-)
---
diff --git a/Makefile b/Makefile
index 8ff0477..4fe7115 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,4 @@
-all: parser gromit
+all: gromit
 
 gromit: gromit.c
 	gcc -o gromit gromit.c `gtk-config --libs --cflags`
-parser: parser.c
-	gcc -o parser parser.c `gtk-config --libs --cflags`
diff --git a/README b/README
index fb6d991..9bcec97 100644
--- a/README
+++ b/README
@@ -55,7 +55,7 @@ Shift+Pause) will clear the screen. If you have config-files for other
 window-managers I'd be happy to include them. Please send them to me.
 
 
-Building;
+Building:
 
 Gromit is small and lightwight. It needs Gtk to build and the Makefile
 is straightforward. No need for autoconf/automake yet  :-)
@@ -64,11 +64,64 @@ Stripping the binary can reduce its size. I just tested it on
 Linux/XFree86, reports from other platforms are welcome.
 
 
-Problems:
+Configuration:
+
+Gromit is configurable via the file ".gromit" in your Homedirectory.
+### not yet, currently it tries to open "gromitconf" in the current directory
+Here you can specify which Device/Button/Modifier combination invokes
+which tool. Example:
+
+     # Comments can be either # Shell-Style or
+     /* C-Style. */
+
+This entry defines the tool "red Pen", a pen with size 7 and color red.
+You can specify the color in X-Style: e.g. "#FF0033" or
+colors from rgb.txt.
+
+     "red Pen" = PEN (size=7 color="red");
+
+The following Entries copy an existing configuration (in this case
+"red Pen") and modify the color.
+
+     "blue Pen" = "red Pen" (color="blue");
+     "yellow Pen" = "red Pen" (color="yellow");
 
-Gromit does not have a configuration-file yet. This is definitely an
-important thing, but probably the code to handle this is bigger than the
-drawing-code. So at the moment gromit is configurable via source  :-)
+An "ERASER" is a tool that erases the drawings on screen.
+The color parameter is not important.
+
+     "Eraser" = ERASER (size = 75);
+
+A "RECOLOR"-Tool changes the color of the drawing without changing
+the shape. Try it out to see the effect.
+
+     "green Marker" = RECOLOR (color = "Limegreen");
+     
+     
+If you define a tool with the same name as an input-device
+(see the output of "xsetpointer -l", if there is a "SWITCH"-Tool
+it is uninteresting...) this input-device uses this tool.
+Additionally you can limit the Scope to specific combinations of
+Mousebuttons (1,2,3,4,5 or Button1,...,Button5)
+and Modifiers (SHIFT, CONTROL, ALT, META, while ALT==META).
+     
+     "Core Pointer" = "red Pen";
+     "Core Pointer"[SHIFT] = "blue Pen";
+     "Core Pointer"[CONTROL] = "yellow Pen";
+     "Core Pointer"[2] = "green Marker";
+     "Core Pointer"[Button3] = "Eraser";
+
+The descision, which tool to use follows a simple policy:
+  a) Buttons are more important than Modifiers
+  b) Low number Buttons are more important than higher ones
+  c) Modifiers: SHIFT > CONTROL > ALT/META.
+  d) Gromit tries partial matches:
+      If you define "Core Pointer"[] and "Core Pointer"[SHIFT, CONTROL]
+      and only SHIFT actually is pressed, Gromit will use the second
+      definition if there is no "Core Pointer"[SHIFT] definition.
+      Same logic goes for the buttons.
+
+
+Problems:
 
 Gromit may drastically slow down your X-Server. It makes heavily use of
 the shape extension, which is quite expensive if you paint a complex
@@ -81,5 +134,5 @@ This Program is distributed under the Gnu General Public License. See
 the file COPYING for details.
 
 
-Have Fun,
+Have fun,
 	Simon Budig <Simon Budig unix-ag org>
diff --git a/erase_cursor.xbm b/erase_cursor.xbm
new file mode 100644
index 0000000..7211302
--- /dev/null
+++ b/erase_cursor.xbm
@@ -0,0 +1,17 @@
+/* Created with The GIMP */
+#define erase_cursor_width 31
+#define erase_cursor_height 31
+#define erase_cursor_x_hot 14
+#define erase_cursor_y_hot 14
+static unsigned char erase_cursor_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00,
+   0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01,
+   0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x04,
+   0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+   0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+   0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+   0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04,
+   0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01,
+   0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00,
+   0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/erase_cursor_mask.xbm b/erase_cursor_mask.xbm
new file mode 100644
index 0000000..4bd026b
--- /dev/null
+++ b/erase_cursor_mask.xbm
@@ -0,0 +1,17 @@
+/* Created with The GIMP */
+#define erase_cursor_mask_width 31
+#define erase_cursor_mask_height 31
+#define erase_cursor_mask_x_hot 14
+#define erase_cursor_mask_y_hot 14
+static unsigned char erase_cursor_mask_bits[] = {
+   0x00, 0xf8, 0x03, 0x00, 0x00, 0xff, 0x1f, 0x00, 0xc0, 0x07, 0x7c, 0x00,
+   0xe0, 0x00, 0xe0, 0x00, 0x30, 0x00, 0x80, 0x01, 0x18, 0x00, 0x00, 0x03,
+   0x0c, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x0c,
+   0x06, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x18,
+   0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18,
+   0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x18,
+   0x06, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x0c,
+   0x0c, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x06, 0x18, 0x00, 0x00, 0x03,
+   0x30, 0x00, 0x80, 0x01, 0xe0, 0x00, 0xe0, 0x00, 0xc0, 0x07, 0x7c, 0x00,
+   0x00, 0xff, 0x1f, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/gromit.c b/gromit.c
index 49fe03f..3132b07 100644
--- a/gromit.c
+++ b/gromit.c
@@ -25,13 +25,17 @@
 
 #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_LEAVE_NOTIFY_MASK | \
+				    GDK_PROXIMITY_IN_MASK | \
+				    GDK_PROXIMITY_OUT_MASK | \
 				    GDK_BUTTON_PRESS_MASK | \
 				    GDK_BUTTON_MOTION_MASK \
 				    /* | GDK_POINTER_MOTION_HINT_MASK */ )
 
+
 /* Atoms used to control Gromit */
 #define GA_CONTROL    gdk_atom_intern ("Gromit/control", FALSE)
 #define GA_STATUS     gdk_atom_intern ("Gromit/status", FALSE)
@@ -70,7 +74,6 @@ typedef struct
    GdkColor	*white;
    GdkColor	*black;
    GdkColor	*red;
-   GdkColor	*blue;
 
    GromitPaintContext *default_pen;
    GromitPaintContext *default_eraser;
@@ -88,6 +91,10 @@ typedef struct
    gdouble	lasty;
    guint32	motion_time;
    gdouble	count;
+   
+   guint32	deviceid;
+   guint	state;
+
    guint	timeout_id;
    guint	modified;
    guint	delayed;
@@ -188,9 +195,9 @@ gromit_toggle_grab (GromitData *data)
       /* gtk_grab_add (data->area); */
       g_printerr ("Grabbing pointer: ");
       foo = gdk_pointer_grab (data->area->window, FALSE,
-	    /* GDK_POINTER_MOTION_MASK | */
+	    GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK |
 	    GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK,
-	    0, data->paint_cursor, GDK_CURRENT_TIME);
+	    0, NULL /* data->paint_cursor */, GDK_CURRENT_TIME);
       switch (foo) {
        	 case Success:
 	    data->hard_grab = 1;
@@ -225,7 +232,8 @@ gromit_clear_screen (GromitData *data)
    gdk_gc_set_foreground (data->shape_gc, data->transparent);
    gdk_draw_rectangle (data->shape, data->shape_gc, 1,
 		       0, 0, data->width, data->height);
-   gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);}
+   gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);
+}
 
 
 gint
@@ -276,8 +284,8 @@ gromit_select_tool (GromitData *data, guint32 deviceid, guint state)
       /* Extract Button/Modifiers from state (see GdkModifierType) */
       req_buttons = (state >> 8) & 31;
 
-      if (state & GDK_SHIFT_MASK) state |= GDK_LOCK_MASK;
       req_modifier = (state >> 1) & 7;
+      if (state & GDK_SHIFT_MASK) req_modifier |= 1;
 
       name [len] = 124;
       name [len+3] = 0;
@@ -301,19 +309,28 @@ gromit_select_tool (GromitData *data, guint32 deviceid, guint state)
 	    }
 	 } while (j<=3 && req_modifier >= (1 << j));
       } while (i<=5 && req_buttons >= (1 << i));
-
+      
       g_free (name);
-   } else
-      g_printerr ("ERROR: Attempt to select nonexistent device!\n");
 
-   if (!success) {
-      if (info->source == GDK_SOURCE_ERASER)
-	 data->cur_context = data->default_eraser;
-      else
-	 data->cur_context = data->default_pen;
+      if (!success) {
+	 if (info->source == GDK_SOURCE_ERASER)
+	    data->cur_context = data->default_eraser;
+	 else
+	    data->cur_context = data->default_pen;
+      }
+   } else {
+      g_printerr ("ERROR: Attempt to select nonexistent device!\n");
+      data->cur_context = data->default_pen;
    }
-}
 
+   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);
+
+   data->state = state;
+   data->deviceid = deviceid;
+}
 
 
 void
@@ -357,14 +374,44 @@ gromit_draw_line (GromitData *data, gint x1, gint y1,
  */
 
 gboolean
+proximity_in (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
+{
+   GromitData *data = (GromitData *) user_data;
+   gint x, y;
+   GdkModifierType state;
+   
+   gdk_window_get_pointer (data->win->window, &x, &y, &state);
+   gromit_select_tool (data, ev->deviceid, state);
+   return 0;
+}
+
+
+gboolean
+proximity_out (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
+{
+   GromitData *data = (GromitData *) user_data;
+   
+   data->cur_context = data->default_pen;
+
+   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);
+
+   data->state = 0;
+   data->deviceid = 0;
+}
+
+
+gboolean
 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); 
-
-   gromit_select_tool (data, ev->deviceid, ev->state);
+   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);
@@ -397,6 +444,9 @@ 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);
+
    coords = gdk_input_motion_events (ev->window, ev->deviceid,
 				     data->motion_time, ev->time, &nevents);
    /* g_printerr ("Got %d coords\n", nevents); */
@@ -831,10 +881,6 @@ setup_client_app (GromitData *data)
 		       GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
    gtk_signal_connect (GTK_OBJECT (data->win), "destroy", 
 		       GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
-   gtk_signal_connect (GTK_OBJECT (data->win), "motion_notify_event",
-		       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), "selection_get",
 		       GTK_SIGNAL_FUNC (event_selection_get), (gpointer) data);
    gtk_signal_connect (GTK_OBJECT (data->win), "selection_received",
@@ -872,8 +918,23 @@ 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);
+   cursor_src = gdk_bitmap_create_from_data (NULL, erase_cursor_bits,
+					     erase_cursor_width,
+					     erase_cursor_height);
+   cursor_mask = gdk_bitmap_create_from_data (NULL, erase_cursor_mask_bits,
+					      erase_cursor_width,
+					      erase_cursor_height);
+   data->erase_cursor = gdk_cursor_new_from_pixmap (cursor_src, cursor_mask,
+						    data->white, data->black,
+						    erase_cursor_x_hot,
+						    erase_cursor_y_hot);
+   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 */
    data->shape = gdk_pixmap_new (NULL, data->width, data->height, 1);
@@ -892,11 +953,19 @@ setup_main_app (GromitData *data)
 			  data->width, data->height);
 
    gtk_widget_set_events (data->area, GROMIT_PAINT_AREA_EVENTS);
-   gtk_widget_set_extension_events (data->area, GDK_EXTENSION_EVENTS_CURSOR);
    gtk_signal_connect (GTK_OBJECT (data->area), "expose_event",
 		       (GtkSignalFunc) event_expose, (gpointer) data);
    gtk_signal_connect (GTK_OBJECT (data->area),"configure_event",
 		       (GtkSignalFunc) event_configure, (gpointer) data);
+   gtk_signal_connect (GTK_OBJECT (data->win), "motion_notify_event",
+		       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), "proximity_in_event",
+		       GTK_SIGNAL_FUNC (proximity_in), (gpointer) data);
+   gtk_signal_connect (GTK_OBJECT (data->win), "proximity_out_event",
+		       GTK_SIGNAL_FUNC (proximity_out), (gpointer) data);
+   gtk_widget_set_extension_events (data->area, GDK_EXTENSION_EVENTS_ALL);
 
    gtk_container_add (GTK_CONTAINER (data->win), data->area);
 
@@ -916,10 +985,8 @@ setup_main_app (GromitData *data)
 
    data->tool_config = g_hash_table_new (g_str_hash, g_str_equal);
    parse_config (data);
-
+   data->state = 0;
    
-   gtk_key_snooper_install ((GtkKeySnoopFunc) event_key_snoop, NULL);
-
    gtk_selection_owner_set (data->win, GA_CONTROL, GDK_CURRENT_TIME);
 
    gtk_selection_add_target (data->win, GA_CONTROL, GA_STATUS, 0);
diff --git a/gromitconf b/gromitconf
index b559781..b1984b5 100644
--- a/gromitconf
+++ b/gromitconf
@@ -2,7 +2,7 @@
 
 # Tools
 
-"roter Stift" = PEN (size=12 color="red");
+"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");
@@ -18,4 +18,9 @@
 "Core Pointer"[META] = "rosa Stift";
 "Core Pointer"[2] = "grüner Marker";
 "Core Pointer"[3] = "Radierer";
+"Core Pointer"[3 SHIFT] = "Radierer" (size = 150);
+"Artpad Pen" = "roter Stift" (size = 15);
+"Artpad Pen"[SHIFT] = "blauer Stift";
+"Artpad Pen"[CONTROL] = "Radierer";
+"Artpad Eraser" = "Radierer";
 



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