[gromit: 9/13] 2004-10-14 Simon Budig <simon gimp org>
- From: Simon Budig <simon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gromit: 9/13] 2004-10-14 Simon Budig <simon gimp org>
- Date: Tue, 16 Mar 2010 22:24:12 +0000 (UTC)
commit b6667adfe11c4a0939cf4315013465e139ecb35a
Author: Simon Budig <simon budig de>
Date: Thu Oct 14 21:00:00 2004 +0200
2004-10-14 Simon Budig <simon gimp org>
* gromit.c: - Fix pressure sensitivity
- massive indentation madness.
* README: Adjusted to the XGrabKey change.
2004-10-14 Simon Budig <simon gimp org>
* gromit.c: - Use XGrabKey to grab the "Pause" key of the keyboard.
Use it to control gromits functionality. The selection-hack is no
longer needed (but still available).
2004-10-14 Simon Budig <simon gimp org>
* gromit.c: - Applied a (slightly modified) patch from
Bastien Nocera (hadess hadess net) to port gromit to GTK+ 2. Still
needs some testing with a Tablet.
- removed deprecated stuff
- changed the activation of input devices, having mice as extended
input devices apparently confuses GDK.
2003-03-04 Simon Budig <simon gimp org>
* gromit.c: Make sure that the arrowhead is connected to the line.
Draw black outline around the arrowhead.
Have just one global last coordinate. Tackles some problems when
switching tools while drawing.
Import of gromit history
ChangeLog | 29 +
Makefile | 2 +-
README | 52 +-
gromit.c | 2078 +++++++++++++++++++++++++++++++-------------------------
gromitrc_gsr | 70 ++
sawfish-config | 38 -
6 files changed, 1261 insertions(+), 1008 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index fd5810e..d26f26b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2004-10-14 Simon Budig <simon gimp org>
+
+ * gromit.c: - Fix pressure sensitivity
+ - massive indentation madness.
+
+ * README: Adjusted to the XGrabKey change.
+
+2004-10-14 Simon Budig <simon gimp org>
+
+ * gromit.c: - Use XGrabKey to grab the "Pause" key of the keyboard.
+ Use it to control gromits functionality. The selection-hack is no
+ longer needed (but still available).
+
+2004-10-14 Simon Budig <simon gimp org>
+
+ * gromit.c: - Applied a (slightly modified) patch from
+ Bastien Nocera (hadess hadess net) to port gromit to GTK+ 2. Still
+ needs some testing with a Tablet.
+ - removed deprecated stuff
+ - changed the activation of input devices, having mice as extended
+ input devices apparently confuses GDK.
+
+2003-03-04 Simon Budig <simon gimp org>
+
+ * gromit.c: Make sure that the arrowhead is connected to the line.
+ Draw black outline around the arrowhead.
+ Have just one global last coordinate. Tackles some problems when
+ switching tools while drawing.
+
2001-12-10 Simon Budig <simon gimp org>
* README
diff --git a/Makefile b/Makefile
index 249c8e2..16b0bbb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
all: gromit
gromit: gromit.c Makefile
- gcc -o gromit gromit.c -Wall `gtk-config --libs --cflags`
+ gcc -DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DPANGO_DISABLE_DEPRECATED -DGDK_MULTIHEAD_SAFE -DGTK_MULTIHEAD_SAFE -o gromit gromit.c -Wall `pkg-config --libs --cflags gtk+-2.0`
diff --git a/README b/README
index 74b059c..248cc66 100644
--- a/README
+++ b/README
@@ -15,23 +15,20 @@ Gromit is a first implementation of this program.
The main usage problem of Gromit is its activation. You need a special
command to make Gromit grab the mouse, since you typically want to use
the program you are demonstrating and highlighting something is a short
-interruption of your workflow. It should work *always*, regardless of
-the currently focused window. X11 does not have an easy way to make a
-program sensible for all events of a certain kind. You have to iterate
-over all windows and tell X that you are interested in the events of
-this window. However, this does not affect windows opened later, so you
-have to reiterate this permanently. At this point I decided to use
-another way: You can invoke Gromit with various arguments to control an
-already running Gromit (see below). Configure your favourite
-windowmanager to invoke these commands on your favourite
-key-combination. I included a script that reconfigures the
-sawfish-windowmanager. (If you are interested: Internally this is done
-via a special X-Selection)
+interruption of your workflow.
-Gromit is pressure sensitive, if you are using properly configured
-XInput-Devices you can draw lines with different thickness. It is
-possible to erase something with the other end of the (Wacom) pen.
+Gromit offers two ways to make this possible. It grabs the "Pause" key, so
+that no other application can use it and it is available to Gromit only.
+The available commands are:
+ Pause: toggle painting
+ SHIFT-Pause: clear screen
+ CTRL-Pause: toggle visibility
+ ALT-Pause: Quit Gromit.
+
+Alternatively you can invoke Gromit with various arguments to control an
+already running Gromit (If you are curious: Communication between two
+gromit instances is done via a special X-Selection).
Usage:
gromit --quit
@@ -45,22 +42,20 @@ Usage:
If activated Gromit prevents you from using other programs with the
mouse. You can press the button and paint on the screen. Key presses
-will still reach the currently active window but it may be difficult
-to change the window-focus without mouse...
+(except the "Pause"-Key, see above) will still reach the currently active
+window but it may be difficult to change the window-focus without mouse...
The next "gromit --toggle" will deactivate Gromit and you can use your
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 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.
+Gromit is pressure sensitive, if you are using properly configured
+XInput-Devices you can draw lines with varying width. It is
+possible to erase something with the other end of the (Wacom) pen.
+
Building:
-Gromit is small and lightwight. It needs GTK+ to build and the Makefile
+Gromit is small and lightwight. It needs GTK+ 2.X to build and the Makefile
is straightforward. No need for autoconf/automake yet :-)
Simply type "make" and copy the resulting binary to a convenient place.
Stripping the binary can reduce its size. I just tested it on
@@ -90,10 +85,10 @@ The following Entries copy an existing configuration (in this case
"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]
+have to specify "arrowsize". This is a factor relative to the width
+of the line. For reasonable arrowheads start with 1.
- "blue Pen" = "blue Arrow" (arrowsize=4);
+ "blue Pen" = "blue Arrow" (arrowsize=2);
An "ERASER" is a tool that erases the drawings on screen.
The color parameter is not important.
@@ -152,4 +147,5 @@ the file COPYING for details.
Have fun,
- Simon Budig <Simon Budig unix-ag org>
+ Simon Budig <simon budig de>
+
diff --git a/gromit.c b/gromit.c
index c7423dd..2041fab 100644
--- a/gromit.c
+++ b/gromit.c
@@ -18,6 +18,7 @@
#include <glib.h>
#include <gdk/gdk.h>
+#include <gdk/gdkinput.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
@@ -26,6 +27,7 @@
#include <string.h>
#include <unistd.h>
#include <math.h>
+#include <stdlib.h>
#include "paint_cursor.xbm"
#include "paint_cursor_mask.xbm"
@@ -33,16 +35,17 @@
#include "erase_cursor_mask.xbm"
#define GROMIT_MOUSE_EVENTS ( GDK_PROXIMITY_IN_MASK | \
- GDK_PROXIMITY_OUT_MASK | \
- GDK_BUTTON_MOTION_MASK | \
- GDK_BUTTON_PRESS_MASK | \
- GDK_BUTTON_RELEASE_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 ( GROMIT_PAINT_AREA_EVENTS )
+#define GROMIT_HOTKEY "Pause"
+
/* Atoms used to control Gromit */
#define GA_CONTROL gdk_atom_intern ("Gromit/control", FALSE)
#define GA_STATUS gdk_atom_intern ("Gromit/status", FALSE)
@@ -56,399 +59,409 @@
typedef enum
{
- GROMIT_PEN,
- GROMIT_ERASER,
- GROMIT_RECOLOR
+ GROMIT_PEN,
+ GROMIT_ERASER,
+ GROMIT_RECOLOR
} GromitPaintType;
typedef struct
{
- GromitPaintType type;
- guint width;
- gfloat arrowsize;
- GdkColor *fg_color;
- GdkGC *paint_gc;
- GdkGC *shape_gc;
- gdouble lastx;
- gdouble lasty;
- gdouble pressure;
+ GromitPaintType type;
+ guint width;
+ gfloat arrowsize;
+ GdkColor *fg_color;
+ GdkGC *paint_gc;
+ GdkGC *shape_gc;
+ gdouble pressure;
} GromitPaintContext;
typedef struct
{
- gint x;
- gint y;
- gint width;
+ gint x;
+ gint y;
+ gint width;
} GromitStrokeCoordinate;
typedef struct
{
- GtkWidget *win;
- GtkWidget *area;
- GtkWidget *panel;
- GtkWidget *button;
- GdkCursor *paint_cursor;
- GdkCursor *erase_cursor;
- GdkPixmap *pixmap;
- GdkColormap *cm;
- GdkColor *white;
- GdkColor *black;
- GdkColor *red;
-
- GromitPaintContext *default_pen;
- GromitPaintContext *default_eraser;
- GromitPaintContext *cur_context;
-
- GHashTable *tool_config;
-
- GdkBitmap *shape;
- GdkGC *shape_gc;
- GdkGCValues *shape_gcv;
- GdkColor *transparent;
- GdkColor *opaque;
-
- // gdouble lastx;
- // gdouble lasty;
- guint32 motion_time;
- GList *coordlist;
-
- guint32 deviceid;
- guint state;
-
- guint timeout_id;
- guint modified;
- guint delayed;
- guint maxwidth;
- guint width;
- guint height;
- guint hard_grab;
- guint client;
- guint painted;
- guint hidden;
+ GtkWidget *win;
+ GtkWidget *area;
+ GtkWidget *panel;
+ GtkWidget *button;
+
+ GdkCursor *paint_cursor;
+ GdkCursor *erase_cursor;
+ GdkPixmap *pixmap;
+ GdkDisplay *display;
+ GdkScreen *screen;
+ GdkWindow *root;
+ guint hot_keycode;
+
+ GdkColormap *cm;
+ GdkColor *white;
+ GdkColor *black;
+ GdkColor *red;
+
+ GromitPaintContext *default_pen;
+ GromitPaintContext *default_eraser;
+ GromitPaintContext *cur_context;
+
+ GHashTable *tool_config;
+
+ GdkBitmap *shape;
+ GdkGC *shape_gc;
+ GdkGCValues *shape_gcv;
+ GdkColor *transparent;
+ GdkColor *opaque;
+
+ gdouble lastx;
+ gdouble lasty;
+ guint32 motion_time;
+ GList *coordlist;
+
+ GdkDevice *device;
+ guint state;
+
+ guint timeout_id;
+ guint modified;
+ guint delayed;
+ guint maxwidth;
+ guint width;
+ guint height;
+ guint hard_grab;
+ guint client;
+ guint painted;
+ guint hidden;
} GromitData;
/* I need a prototype... */
void gromit_release_grab (GromitData *data);
-void gromit_aquire_grab (GromitData *data);
+void gromit_acquire_grab (GromitData *data);
GromitPaintContext *
gromit_paint_context_new (GromitData *data, GromitPaintType type,
- GdkColor *fg_color, guint width, guint arrowsize)
+ GdkColor *fg_color, guint width, guint arrowsize)
{
- GromitPaintContext *context;
- GdkGCValues shape_gcv;
+ GromitPaintContext *context;
+ GdkGCValues shape_gcv;
- context = g_malloc (sizeof (GromitPaintContext));
+ context = g_malloc (sizeof (GromitPaintContext));
- context->type = type;
- context->width = width;
- context->arrowsize = arrowsize;
- context->fg_color = fg_color;
-
- if (type == GROMIT_ERASER)
+ context->type = type;
+ context->width = width;
+ context->arrowsize = arrowsize;
+ context->fg_color = fg_color;
+
+ if (type == GROMIT_ERASER)
+ {
context->paint_gc = NULL;
- else {
+ }
+ else
+ {
/* GROMIT_PEN || GROMIT_RECOLOR */
context->paint_gc = gdk_gc_new (data->pixmap);
gdk_gc_set_foreground (context->paint_gc, fg_color);
gdk_gc_set_line_attributes (context->paint_gc, width, GDK_LINE_SOLID,
- GDK_CAP_ROUND, GDK_JOIN_ROUND);
- }
-
- if (type == GROMIT_RECOLOR)
+ GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ }
+
+ if (type == GROMIT_RECOLOR)
+ {
context->shape_gc = NULL;
- else {
+ }
+ else
+ {
/* GROMIT_PEN || GROMIT_ERASER */
context->shape_gc = gdk_gc_new (data->shape);
gdk_gc_get_values (context->shape_gc, &shape_gcv);
-
+
if (type == GROMIT_ERASER)
- gdk_gc_set_foreground (context->shape_gc, &(shape_gcv.foreground));
+ gdk_gc_set_foreground (context->shape_gc, &(shape_gcv.foreground));
else
- /* GROMIT_PEN */
- gdk_gc_set_foreground (context->shape_gc, &(shape_gcv.background));
+ /* GROMIT_PEN */
+ gdk_gc_set_foreground (context->shape_gc, &(shape_gcv.background));
gdk_gc_set_line_attributes (context->shape_gc, width, GDK_LINE_SOLID,
- GDK_CAP_ROUND, GDK_JOIN_ROUND);
- }
-
- return context;
+ GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ }
+
+ return context;
}
void
gromit_paint_context_print (gchar *name, GromitPaintContext *context)
{
- g_printerr ("Tool name: \"%-20s\": ", name);
- switch (context->type)
- {
- case GROMIT_PEN:
- g_printerr ("Pen, "); break;
- case GROMIT_ERASER:
- g_printerr ("Eraser, "); break;
- case GROMIT_RECOLOR:
- g_printerr ("Recolor, "); break;
- default:
- 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);
+ g_printerr ("Tool name: \"%-20s\": ", name);
+ switch (context->type)
+ {
+ case GROMIT_PEN:
+ g_printerr ("Pen, "); break;
+ case GROMIT_ERASER:
+ g_printerr ("Eraser, "); break;
+ case GROMIT_RECOLOR:
+ g_printerr ("Recolor, "); break;
+ default:
+ g_printerr ("UNKNOWN, "); break;
+ }
+
+ g_printerr ("width: %3d, ", context->width);
+ g_printerr ("arrowsize: %.2f, ", context->arrowsize);
+ g_printerr ("color: #%02X%02X%02X\n", context->fg_color->red >> 8,
+ context->fg_color->green >> 8, context->fg_color->blue >> 8);
}
void
gromit_paint_context_free (GromitPaintContext *context)
{
- gdk_gc_unref (context->paint_gc);
- gdk_gc_unref (context->shape_gc);
- g_free (context);
+ g_object_unref (context->paint_gc);
+ g_object_unref (context->shape_gc);
+ g_free (context);
}
void
gromit_coord_list_prepend (GromitData *data, gint x, gint y, gint width)
{
- GromitStrokeCoordinate *point;
+ GromitStrokeCoordinate *point;
- point = g_malloc (sizeof (GromitStrokeCoordinate));
- point->x = x;
- point->y = y;
- point->width = width;
+ point = g_malloc (sizeof (GromitStrokeCoordinate));
+ point->x = x;
+ point->y = y;
+ point->width = width;
- data->coordlist = g_list_prepend (data->coordlist, point);
+ data->coordlist = g_list_prepend (data->coordlist, point);
}
void
gromit_coord_list_free (GromitData *data)
{
- GList *ptr;
+ GList *ptr;
- ptr = data->coordlist;
+ ptr = data->coordlist;
- while (ptr) {
+ while (ptr)
+ {
g_free (ptr->data);
ptr = ptr->next;
- }
+ }
- g_list_free (data->coordlist);
+ g_list_free (data->coordlist);
- data->coordlist = NULL;
+ data->coordlist = NULL;
}
gboolean
gromit_coord_list_get_arrow_param (GromitData *data,
- gint search_radius,
- gint *ret_width,
- gfloat *ret_direction)
+ 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;
+ gint x0, y0, r2, dist;
+ gboolean success = FALSE;
+ GromitStrokeCoordinate *cur_point, *valid_point;
+ GList *ptr = data->coordlist;
+ gfloat width;
- valid_point = NULL;
+ valid_point = NULL;
- if (ptr) {
+ 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;
+ 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 &&
+ (!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)
- {
+ if (!data->hidden)
+ {
if (data->hard_grab)
- data->hidden = 2;
+ data->hidden = 2;
else
- data->hidden = 1;
+ data->hidden = 1;
gromit_release_grab (data);
gtk_widget_hide (data->win);
- }
+ }
}
void
gromit_show_window (GromitData *data)
{
- gint oldstatus = data->hidden;
+ gint oldstatus = data->hidden;
- if (data->hidden)
- {
+ if (data->hidden)
+ {
gtk_widget_show (data->win);
data->hidden = 0;
if (oldstatus == 2)
- gromit_aquire_grab (data);
- }
- gdk_window_raise (data->win->window);
+ gromit_acquire_grab (data);
+ }
+ gdk_window_raise (data->win->window);
}
void
gromit_toggle_visibility (GromitData *data)
{
- if (data->hidden)
- gromit_show_window (data);
- else
- gromit_hide_window (data);
+ if (data->hidden)
+ gromit_show_window (data);
+ else
+ gromit_hide_window (data);
}
void
gromit_release_grab (GromitData *data)
{
- if (data->hard_grab)
- {
+ if (data->hard_grab)
+ {
data->hard_grab = 0;
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ gdk_display_pointer_ungrab (data->display, GDK_CURRENT_TIME);
/* inherit cursor from root window */
gdk_window_set_cursor (data->win->window, NULL);
- }
- if (!data->painted)
- gromit_hide_window (data);
+ }
+
+ if (!data->painted)
+ gromit_hide_window (data);
}
void
-gromit_aquire_grab (GromitData *data)
+gromit_acquire_grab (GromitData *data)
{
- int result;
-
- gromit_show_window (data);
- if (!data->hard_grab)
- {
+ GdkGrabStatus result;
+ gromit_show_window (data);
+ if (!data->hard_grab)
+ {
result = gdk_pointer_grab (data->area->window, FALSE,
- GROMIT_MOUSE_EVENTS, 0,
- NULL /* data->paint_cursor */,
- GDK_CURRENT_TIME);
- switch (result) {
- case Success:
- data->hard_grab = 1;
- break;
- case GrabNotViewable:
- g_printerr ("Grabbing Pointer failed: %s\n", "GrabNotViewable");
- break;
- case AlreadyGrabbed:
- g_printerr ("Grabbing Pointer failed: %s\n", "AlreadyGrabbed");
- break;
- case GrabFrozen:
- g_printerr ("Grabbing Pointer failed: %s\n", "GrabFrozen");
- break;
- case GrabInvalidTime:
- g_printerr ("Grabbing Pointer failed: %s\n", "GrabInvalidTime");
- break;
- default:
- g_printerr ("Grabbing Pointer failed: %s\n", "Unknown error");
+ GROMIT_MOUSE_EVENTS, 0,
+ NULL /* data->paint_cursor */,
+ GDK_CURRENT_TIME);
+
+ switch (result)
+ {
+ case GDK_GRAB_SUCCESS:
+ data->hard_grab = 1;
+ break;
+ case GDK_GRAB_ALREADY_GRABBED:
+ g_printerr ("Grabbing Pointer failed: %s\n", "AlreadyGrabbed");
+ break;
+ case GDK_GRAB_INVALID_TIME:
+ g_printerr ("Grabbing Pointer failed: %s\n", "GrabInvalidTime");
+ break;
+ case GDK_GRAB_NOT_VIEWABLE:
+ g_printerr ("Grabbing Pointer failed: %s\n", "GrabNotViewable");
+ break;
+ case GDK_GRAB_FROZEN:
+ g_printerr ("Grabbing Pointer failed: %s\n", "GrabFrozen");
+ break;
+ 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);
+ gdk_window_set_cursor (data->win->window, data->erase_cursor);
else
- gdk_window_set_cursor (data->win->window, data->paint_cursor);
-
- }
+ gdk_window_set_cursor (data->win->window, data->paint_cursor);
+ }
}
void
gromit_toggle_grab (GromitData *data)
{
- if (data->hard_grab)
- gromit_release_grab (data);
- else
- gromit_aquire_grab (data);
+ if (data->hard_grab)
+ gromit_release_grab (data);
+ else
+ gromit_acquire_grab (data);
}
void
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);
- if (!data->hard_grab)
- gromit_hide_window (data);
- data->painted = 0;
+ 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);
+ if (!data->hard_grab)
+ gromit_hide_window (data);
+ data->painted = 0;
}
gint
reshape (gpointer user_data)
{
- GromitData *data = (GromitData *) user_data;
-
- if (data->modified) {
- if (gtk_events_pending () && data->delayed < 5) {
- data->delayed++ ;
- } else {
- gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);
- data->modified = 0;
- data->delayed = 0;
- }
- }
- return 1;
+ GromitData *data = (GromitData *) user_data;
+
+ if (data->modified)
+ {
+ if (gtk_events_pending () && data->delayed < 5)
+ {
+ data->delayed++ ;
+ }
+ else
+ {
+ gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);
+ data->modified = 0;
+ data->delayed = 0;
+ }
+ }
+ return 1;
}
void
-gromit_select_tool (GromitData *data, guint32 deviceid, guint state)
+gromit_select_tool (GromitData *data, GdkDevice *device, guint state)
{
- GList *dev_list;
- GdkDeviceInfo *info = NULL;
- guint buttons = 0, modifier = 0, len = 0;
- guint req_buttons = 0, req_modifier = 0;
- guint i, j, success = 0;
- GromitPaintContext *context = NULL;
- guchar *name;
-
- dev_list = gdk_input_list_devices ();
- while (dev_list)
- {
- if (((GdkDeviceInfo *) dev_list->data)->deviceid == deviceid) {
- info = (GdkDeviceInfo *) dev_list->data;
- break;
- }
- dev_list = dev_list->next;
- }
+ guint buttons = 0, modifier = 0, len = 0;
+ guint req_buttons = 0, req_modifier = 0;
+ guint i, j, success = 0;
+ GromitPaintContext *context = NULL;
+ guchar *name;
- if (info) {
- len = strlen (info->name);
- name = g_strndup (info->name, len + 3);
+ if (device)
+ {
+ len = strlen (device->name);
+ name = g_strndup (device->name, len + 3);
/* Extract Button/Modifiers from state (see GdkModifierType) */
req_buttons = (state >> 8) & 31;
@@ -462,80 +475,89 @@ gromit_select_tool (GromitData *data, guint32 deviceid, guint state)
/* 0, 1, 3, 7, 15, 31 */
context = NULL;
i=-1;
- do {
- i++;
- buttons = req_buttons & ((1 << i)-1);
- j=-1;
- do {
- j++;
- modifier = req_modifier & ((1 << j)-1);
- name [len+1] = buttons + 64;
- name [len+2] = modifier + 48;
- context = g_hash_table_lookup (data->tool_config, name);
- if (context) {
- data->cur_context = context;
- success = 1;
- }
- } while (j<=3 && req_modifier >= (1 << j));
- } while (i<=5 && req_buttons >= (1 << i));
-
+ do
+ {
+ i++;
+ buttons = req_buttons & ((1 << i)-1);
+ j=-1;
+ do
+ {
+ j++;
+ modifier = req_modifier & ((1 << j)-1);
+ name [len+1] = buttons + 64;
+ name [len+2] = modifier + 48;
+ context = g_hash_table_lookup (data->tool_config, name);
+ if (context)
+ {
+ data->cur_context = context;
+ success = 1;
+ }
+ }
+ while (j<=3 && req_modifier >= (1 << j));
+ }
+ while (i<=5 && req_buttons >= (1 << i));
+
g_free (name);
- if (!success) {
- if (info->source == GDK_SOURCE_ERASER)
- data->cur_context = data->default_eraser;
- else
- data->cur_context = data->default_pen;
- }
- } else {
+ if (!success)
+ {
+ if (device->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);
+ 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;
+ data->state = state;
+ data->device = device;
}
void
gromit_draw_line (GromitData *data, gint x1, gint y1,
- gint x2, gint y2)
+ gint x2, gint y2)
{
- GdkRectangle rect;
-
- rect.x = MIN (x1,x2) - data->maxwidth / 2;
- rect.y = MIN (y1,y2) - data->maxwidth / 2;
- rect.width = ABS (x1-x2) + data->maxwidth;
- rect.height = ABS (y1-y2) + data->maxwidth;
-
- if (data->cur_context->paint_gc)
- gdk_gc_set_line_attributes (data->cur_context->paint_gc,
- data->maxwidth, 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_line (data->pixmap, data->cur_context->paint_gc,
- x1, y1, x2, y2);
-
- if (data->cur_context->shape_gc) {
+ GdkRectangle rect;
+
+ rect.x = MIN (x1,x2) - data->maxwidth / 2;
+ rect.y = MIN (y1,y2) - data->maxwidth / 2;
+ rect.width = ABS (x1-x2) + data->maxwidth;
+ rect.height = ABS (y1-y2) + data->maxwidth;
+
+ if (data->cur_context->paint_gc)
+ gdk_gc_set_line_attributes (data->cur_context->paint_gc,
+ data->maxwidth, 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_line (data->pixmap, data->cur_context->paint_gc,
+ x1, y1, x2, y2);
+
+ if (data->cur_context->shape_gc)
+ {
gdk_draw_line (data->shape, data->cur_context->shape_gc,
- x1, y1, x2, y2);
+ x1, y1, x2, y2);
data->modified = 1;
- }
-
- if (data->cur_context->paint_gc)
- gtk_widget_draw (data->area, &rect);
-
- data->painted = 1;
+ }
+
+ if (data->cur_context->paint_gc)
+ gtk_widget_draw (data->area, &rect);
+
+ data->painted = 1;
}
@@ -543,52 +565,67 @@ 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)
+ 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,
+ 0, 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) {
+ TRUE, arrowhead, 4);
+ gdk_gc_set_foreground (data->cur_context->paint_gc, data->black);
+ gdk_draw_polygon (data->pixmap, data->cur_context->paint_gc,
+ FALSE, arrowhead, 4);
+ gdk_gc_set_foreground (data->cur_context->paint_gc,
+ data->cur_context->fg_color);
+ }
+
+ if (data->cur_context->shape_gc)
+ {
gdk_draw_polygon (data->shape, data->cur_context->shape_gc,
- TRUE, arrowhead, 4);
+ TRUE, arrowhead, 4);
+ gdk_draw_polygon (data->shape, data->cur_context->shape_gc,
+ FALSE, arrowhead, 4);
data->modified = 1;
- }
-
- if (data->cur_context->paint_gc)
- gtk_widget_draw (data->area, &rect);
-
- data->painted = 1;
+ }
+
+ if (data->cur_context->paint_gc)
+ gtk_widget_draw (data->area, &rect);
+
+ data->painted = 1;
}
@@ -599,158 +636,179 @@ gromit_draw_arrow (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 TRUE;
+ 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->device, state);
+
+ return TRUE;
}
gboolean
proximity_out (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
{
- GromitData *data = (GromitData *) user_data;
-
- data->cur_context = data->default_pen;
+ GromitData *data = (GromitData *) user_data;
- 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->cur_context = data->default_pen;
- data->state = 0;
- data->deviceid = 0;
+ 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);
- return FALSE;
+ data->state = 0;
+ data->device = NULL;
+
+ return FALSE;
}
gboolean
paint (GtkWidget *win, GdkEventButton *ev, gpointer user_data)
{
- GromitData *data = (GromitData *) user_data;
-
- 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);
-
- 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);
+ GromitData *data = (GromitData *) user_data;
+ gdouble pressure = 0.5;
+
+ if (!data->hard_grab)
+ return FALSE;
+
+ /* See GdkModifierType. Am I fixing a Gtk misbehaviour??? */
+ ev->state |= 1 << (ev->button + 7);
+ if (ev->state != data->state || ev->device != data->device)
+ gromit_select_tool (data, ev->device, ev->state);
+
+ 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;
+
+ if (ev->device->source == GDK_SOURCE_MOUSE)
+ {
+ data->maxwidth = data->cur_context->width;
+ }
+ else
+ {
+ gdk_event_get_axis ((GdkEvent *) ev, GDK_AXIS_PRESSURE, &pressure);
+ data->maxwidth = (CLAMP (pressure * pressure,0,1) *
+ (double) data->cur_context->width);
+ }
+ if (ev->button <= 5)
+ gromit_draw_line (data, ev->x, ev->y, ev->x, ev->y);
+
+ gromit_coord_list_prepend (data, ev->x, ev->y, data->maxwidth);
+
+ /* if (data->cur_context->shape_gc && !gtk_events_pending ())
+ gtk_widget_shape_combine_mask (data->win, data->shape, 0,0); */
+
+ return TRUE;
+}
- if (ev->button <= 5)
- gromit_draw_line (data, ev->x, ev->y, ev->x, ev->y);
+
+gboolean
+paintto (GtkWidget *win,
+ GdkEventMotion *ev,
+ gpointer user_data)
+{
+ GromitData *data = (GromitData *) user_data;
+ GdkTimeCoord **coords = NULL;
+ int nevents;
+ int i;
+ gboolean ret;
+ gdouble pressure = 0.5;
+
+ if (!data->hard_grab)
+ return FALSE;
+
+ if (ev->state != data->state || ev->device != data->device)
+ gromit_select_tool (data, ev->device, ev->state);
+
+ ret = gdk_device_get_history (ev->device, ev->window,
+ data->motion_time, ev->time,
+ &coords, &nevents);
+
+ /* g_printerr ("Got %d coords\n", nevents); */
+ if (coords)
+ {
+ for (i=0; i < nevents; i++)
+ {
+ gdouble x, y;
+
+ gdk_device_get_axis (ev->device, coords[i]->axes,
+ GDK_AXIS_PRESSURE, &pressure);
+ if (pressure > 0)
+ {
+ if (ev->device->source == GDK_SOURCE_MOUSE)
+ data->maxwidth = data->cur_context->width;
+ else
+ data->maxwidth = (CLAMP (pressure * pressure, 0, 1) *
+ (double) data->cur_context->width);
+
+ gdk_device_get_axis(ev->device, coords[i]->axes,
+ GDK_AXIS_X, &x);
+ gdk_device_get_axis(ev->device, coords[i]->axes,
+ GDK_AXIS_Y, &y);
+
+ gromit_draw_line (data, data->lastx, data->lasty, x, y);
+
+ gromit_coord_list_prepend (data, x, y, data->maxwidth);
+ data->lastx = x;
+ data->lasty = y;
+ }
+ }
+
+ data->motion_time = coords[nevents-1]->time;
+ g_free (coords);
+ }
+
+ /* always paint to the current event coordinate. */
+ gdk_event_get_axis ((GdkEvent *) ev, GDK_AXIS_PRESSURE, &pressure);
+
+ if (pressure > 0)
+ {
+ if (ev->device->source == GDK_SOURCE_MOUSE)
+ data->maxwidth = data->cur_context->width;
+ else
+ data->maxwidth = (CLAMP (pressure * pressure,0,1) *
+ (double) data->cur_context->width);
+ gromit_draw_line (data, data->lastx, data->lasty, ev->x, ev->y);
gromit_coord_list_prepend (data, ev->x, ev->y, data->maxwidth);
+ }
- /* if (data->cur_context->shape_gc && !gtk_events_pending ())
- gtk_widget_shape_combine_mask (data->win, data->shape, 0,0); */
+ data->lastx = ev->x;
+ data->lasty = ev->y;
- return TRUE;
- } else {
- return FALSE;
- }
+ return TRUE;
}
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);
- }
- }
+ GromitData *data = (GromitData *) user_data;
+ gint width = data->cur_context->arrowsize * data->cur_context->width / 2;
+ gfloat direction = 0;
- gromit_coord_list_free (data);
+ if ((ev->x != data->lastx) ||
+ (ev->y != data->lasty))
+ paintto (win, (GdkEventMotion *) ev, user_data);
- return TRUE;
- } else {
- return FALSE;
- }
-}
+ if (!data->hard_grab)
+ return FALSE;
+ if (data->cur_context->arrowsize != 0 &&
+ gromit_coord_list_get_arrow_param (data, width * 3,
+ &width, &direction))
+ gromit_draw_arrow (data, ev->x, ev->y, width, direction);
-gboolean
-paintto (GtkWidget *win, GdkEventMotion *ev, gpointer user_data)
-{
- GromitData *data = (GromitData *) user_data;
- GdkTimeCoord *coords;
- int nevents;
- int i;
-
- 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->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;
- }
- }
-
- data->cur_context->lastx = ev->x;
- data->cur_context->lasty = ev->y;
+ gromit_coord_list_free (data);
- return TRUE;
- } else {
- return FALSE;
- }
+ return TRUE;
}
@@ -761,87 +819,134 @@ paintto (GtkWidget *win, GdkEventMotion *ev, gpointer user_data)
void
quiet_print_handler (const gchar *string)
{
- return;
+ return;
}
gboolean
event_configure (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
+ GdkEventExpose *event,
+ gpointer user_data)
{
- GromitData *data = (GromitData *) user_data;
+ GromitData *data = (GromitData *) user_data;
- data->pixmap = gdk_pixmap_new (data->area->window, data->width,
- data->height, -1);
- gdk_draw_rectangle (data->pixmap, data->area->style->black_gc,
- 1, 0, 0, data->width, data->height);
- gdk_window_set_transient_for (data->area->window, data->win->window);
+ data->pixmap = gdk_pixmap_new (data->area->window, data->width,
+ data->height, -1);
+ gdk_draw_rectangle (data->pixmap, data->area->style->black_gc,
+ 1, 0, 0, data->width, data->height);
+ gdk_window_set_transient_for (data->area->window, data->win->window);
- return TRUE;
+ return TRUE;
}
gboolean
event_expose (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
+ GdkEventExpose *event,
+ gpointer user_data)
{
- GromitData *data = (GromitData *) user_data;
-
- gdk_draw_pixmap (data->area->window,
- data->area->style->fg_gc[GTK_WIDGET_STATE (data->area)],
- data->pixmap, event->area.x, event->area.y,
- event->area.x, event->area.y, event->area.width,
- event->area.height);
- return TRUE;
+ GromitData *data = (GromitData *) user_data;
+
+ gdk_draw_drawable (data->area->window,
+ data->area->style->fg_gc[GTK_WIDGET_STATE (data->area)],
+ data->pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ return TRUE;
}
+/* Keyboard control */
+
+gint
+key_press_event (GtkWidget *grab_widget,
+ GdkEventKey *event,
+ gpointer func_data)
+{
+ GromitData *data = (GromitData *) func_data;
+
+ if (event->type == GDK_KEY_PRESS &&
+ event->hardware_keycode == data->hot_keycode)
+ {
+ if (event->state & GDK_SHIFT_MASK)
+ gromit_clear_screen (data);
+ else if (event->state & GDK_CONTROL_MASK)
+ gromit_toggle_visibility (data);
+ else if (event->state & GDK_MOD1_MASK)
+ gtk_main_quit ();
+ else
+ gromit_toggle_grab (data);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void
+gromit_main_do_event (GdkEventAny *event,
+ GromitData *data)
+{
+ if ((event->type == GDK_KEY_PRESS ||
+ event->type == GDK_KEY_RELEASE) &&
+ event->window == data->root &&
+ ((GdkEventKey *) event)->hardware_keycode == data->hot_keycode)
+ {
+ /* redirect the event to our main window, so that GTK+ doesn't
+ * throw it away (there is no GtkWidget for the root window...)
+ */
+ event->window = data->win->window;
+ g_object_ref (data->win->window);
+ }
+
+ gtk_main_do_event ((GdkEvent *) event);
+}
+
/* Remote control */
-void
+void
event_selection_get (GtkWidget *widget,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
{
- gchar *uri = "OK";
-
- if (selection_data->target == GA_TOGGLE)
- gromit_toggle_grab (data);
- else if (selection_data->target == GA_VISIBILITY)
- gromit_toggle_visibility (data);
- else if (selection_data->target == GA_CLEAR)
- gromit_clear_screen (data);
- else if (selection_data->target == GA_QUIT)
- gtk_main_quit ();
- else
- uri = "NOK";
-
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8, uri, strlen (uri));
+ gchar *uri = "OK";
+
+ if (selection_data->target == GA_TOGGLE)
+ gromit_toggle_grab (data);
+ else if (selection_data->target == GA_VISIBILITY)
+ gromit_toggle_visibility (data);
+ else if (selection_data->target == GA_CLEAR)
+ gromit_clear_screen (data);
+ else if (selection_data->target == GA_QUIT)
+ gtk_main_quit ();
+ else
+ uri = "NOK";
+
+ gtk_selection_data_set (selection_data,
+ selection_data->target,
+ 8, uri, strlen (uri));
}
void
event_selection_received (GtkWidget *widget,
- GtkSelectionData *selection_data,
- guint time,
- gpointer user_data)
+ GtkSelectionData *selection_data,
+ guint time,
+ gpointer user_data)
{
- GromitData *data = (GromitData *) user_data;
+ GromitData *data = (GromitData *) user_data;
- /* If someone has a selection for us, Gromit is already running. */
+ /* If someone has a selection for us, Gromit is already running. */
- if (selection_data->type == GDK_NONE)
- data->client = 0;
- else
- data->client = 1;
+ if (selection_data->type == GDK_NONE)
+ data->client = 0;
+ else
+ data->client = 1;
- gtk_main_quit ();
+ gtk_main_quit ();
}
@@ -849,452 +954,543 @@ event_selection_received (GtkWidget *widget,
* Functions for parsing the Configuration-file
*/
-gchar *parse_name (GScanner *scanner) {
- GTokenType token;
+gchar *
+parse_name (GScanner *scanner)
+{
+ GTokenType token;
+
+ guint buttons = 0;
+ guint modifier = 0;
+ guint len = 0;
+ gchar *name;
- guint buttons = 0;
- guint modifier = 0;
- guint len = 0;
- gchar *name;
+ token = g_scanner_cur_token(scanner);
- token = g_scanner_cur_token(scanner);
-
- if (token != G_TOKEN_STRING) {
+ if (token != G_TOKEN_STRING)
+ {
g_scanner_unexp_token (scanner, G_TOKEN_STRING, NULL,
- NULL, NULL, "aborting", TRUE);
+ NULL, NULL, "aborting", TRUE);
exit (1);
- }
+ }
- len = strlen (scanner->value.v_string);
- name = g_strndup (scanner->value.v_string, len + 3);
+ len = strlen (scanner->value.v_string);
+ name = g_strndup (scanner->value.v_string, len + 3);
- token = g_scanner_get_next_token (scanner);
+ token = g_scanner_get_next_token (scanner);
- /*
- * Are there any options to limit the scope of the definition?
- */
+ /*
+ * Are there any options to limit the scope of the definition?
+ */
- if (token == G_TOKEN_LEFT_BRACE) {
+ if (token == G_TOKEN_LEFT_BRACE)
+ {
g_scanner_set_scope (scanner, 1);
scanner->config->int_2_float = 0;
modifier = buttons = 0;
while ((token = g_scanner_get_next_token (scanner))
- != G_TOKEN_RIGHT_BRACE) {
- if (token == G_TOKEN_SYMBOL) {
- if ((guint) scanner->value.v_symbol < 11)
- buttons |= 1 << ((guint) scanner->value.v_symbol - 1);
- else
- modifier |= 1 << ((guint) scanner->value.v_symbol - 11);
- } else if (token == G_TOKEN_INT) {
- if (scanner->value.v_int <= 5 && scanner->value.v_int > 0) {
- buttons |= 1 << (scanner->value.v_int - 1);
- } else {
- g_printerr ("Only Buttons 1-5 are supported!\n");
- }
- } else {
- g_printerr ("skipped token\n");
- }
- }
+ != G_TOKEN_RIGHT_BRACE)
+ {
+ if (token == G_TOKEN_SYMBOL)
+ {
+ if ((guint) scanner->value.v_symbol < 11)
+ buttons |= 1 << ((guint) scanner->value.v_symbol - 1);
+ else
+ modifier |= 1 << ((guint) scanner->value.v_symbol - 11);
+ }
+ else if (token == G_TOKEN_INT)
+ {
+ if (scanner->value.v_int <= 5 && scanner->value.v_int > 0)
+ buttons |= 1 << (scanner->value.v_int - 1);
+ else
+ g_printerr ("Only Buttons 1-5 are supported!\n");
+ }
+ else
+ {
+ g_printerr ("skipped token\n");
+ }
+ }
g_scanner_set_scope (scanner, 0);
scanner->config->int_2_float = 1;
token = g_scanner_get_next_token (scanner);
- }
+ }
- name [len] = 124;
- name [len+1] = buttons + 64;
- name [len+2] = modifier + 48;
- name [len+3] = 0;
+ name [len] = 124;
+ name [len+1] = buttons + 64;
+ name [len+2] = modifier + 48;
+ name [len+3] = 0;
- return name;
+ return name;
}
-
+
void
parse_print_help (gpointer key, gpointer value, gpointer user_data)
{
- gromit_paint_context_print ((gchar *) key, (GromitPaintContext *) value);
+ gromit_paint_context_print ((gchar *) key, (GromitPaintContext *) value);
}
void
-parse_config (GromitData *data) {
-
- GromitPaintContext *context=NULL;
- GromitPaintContext *context_template=NULL;
- GScanner *scanner;
- GTokenType token;
- gchar *filename;
- int file;
+parse_config (GromitData *data)
+{
+ GromitPaintContext *context=NULL;
+ GromitPaintContext *context_template=NULL;
+ GScanner *scanner;
+ GTokenType token;
+ gchar *filename;
+ int file;
- gchar *name, *copy;
+ gchar *name, *copy;
- GromitPaintType type;
- GdkColor *fg_color=NULL;
- guint width, arrowsize;
+ GromitPaintType type;
+ GdkColor *fg_color=NULL;
+ guint width, arrowsize;
- filename = g_strjoin (G_DIR_SEPARATOR_S, g_get_home_dir(), ".gromitrc", NULL);
- file = open (filename, O_RDONLY);
+ filename = g_strjoin (G_DIR_SEPARATOR_S,
+ g_get_home_dir(), ".gromitrc", NULL);
+ file = open (filename, O_RDONLY);
- if (file < 0)
- {
+ if (file < 0)
+ {
g_printerr ("Could not open %s: %s\n", filename, g_strerror (errno));
g_free (filename);
return;
- }
-
- scanner = g_scanner_new (NULL);
- scanner->input_name = filename;
- scanner->config->case_sensitive = 0;
- scanner->config->scan_octal = 0;
- scanner->config->identifier_2_string = 0;
- scanner->config->char_2_token = 1;
- scanner->config->numbers_2_int = 1;
- scanner->config->int_2_float = 1;
-
- g_scanner_scope_add_symbol (scanner, 0, "PEN", (gpointer) GROMIT_PEN);
- 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, 2, "arrowsize", (gpointer) 3);
-
- g_scanner_set_scope (scanner, 0);
- scanner->config->scope_0_fallback = 0;
-
- g_scanner_input_file (scanner, file);
-
- token = g_scanner_get_next_token (scanner);
- while (token != G_TOKEN_EOF) {
+ }
+
+ scanner = g_scanner_new (NULL);
+ scanner->input_name = filename;
+ scanner->config->case_sensitive = 0;
+ scanner->config->scan_octal = 0;
+ scanner->config->identifier_2_string = 0;
+ scanner->config->char_2_token = 1;
+ scanner->config->numbers_2_int = 1;
+ scanner->config->int_2_float = 1;
+
+ g_scanner_scope_add_symbol (scanner, 0, "PEN", (gpointer) GROMIT_PEN);
+ 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, 2, "arrowsize", (gpointer) 3);
+
+ g_scanner_set_scope (scanner, 0);
+ scanner->config->scope_0_fallback = 0;
+
+ g_scanner_input_file (scanner, file);
+
+ token = g_scanner_get_next_token (scanner);
+ while (token != G_TOKEN_EOF)
+ {
/*
* New tool definition
*/
- if (token == G_TOKEN_STRING) {
- name = parse_name (scanner);
- token = g_scanner_cur_token(scanner);
-
- if (token != G_TOKEN_EQUAL_SIGN) {
- g_scanner_unexp_token (scanner, G_TOKEN_EQUAL_SIGN, NULL,
- NULL, NULL, "aborting", TRUE);
- exit (1);
- }
-
- token = g_scanner_get_next_token (scanner);
-
- /* defaults */
-
- type = GROMIT_PEN;
- width = 7;
- arrowsize = 0;
- fg_color = data->red;
-
- if (token == G_TOKEN_SYMBOL) {
- type = (GromitPaintType) scanner->value.v_symbol;
- token = g_scanner_get_next_token (scanner);
- } else if (token == G_TOKEN_STRING) {
- copy = parse_name (scanner);
- token = g_scanner_cur_token(scanner);
- context_template = g_hash_table_lookup (data->tool_config, copy);
- 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);
- }
- } else {
- g_printerr ("Expected Tool-definition or name of template tool\n");
- exit (1);
- }
-
- /* Are there any tool-options?
- */
-
- if (token == G_TOKEN_LEFT_PAREN) {
- GdkColor *color = NULL;
- g_scanner_set_scope (scanner, 2);
- scanner->config->int_2_float = 1;
- token = g_scanner_get_next_token (scanner);
- while (token != G_TOKEN_RIGHT_PAREN) {
- if (token == G_TOKEN_SYMBOL) {
- if ((guint) scanner->value.v_symbol == 1) {
- 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 Size (float)... aborting\n");
- exit (1);
- }
- width = (guint) (scanner->value.v_float + 0.5);
- } else if ((guint) scanner->value.v_symbol == 2) {
- 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_STRING) {
- g_printerr ("Missing Color (string)... aborting\n");
- exit (1);
- }
- color = g_malloc (sizeof (GdkColor));
- if (gdk_color_parse (scanner->value.v_string, color)) {
- if (gdk_colormap_alloc_color (data->cm, color, 0, 1)) {
- fg_color = color;
- } else {
- g_printerr ("Unable to allocate color. Keeping default!\n");
- g_free (color);
- }
- } else {
- g_printerr ("Unable to parse color. Keeping default.\n");
- g_free (color);
- }
- 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");
- }
- } else {
- g_printerr ("skipped token!!!\n");
- }
- token = g_scanner_get_next_token (scanner);
- }
- g_scanner_set_scope (scanner, 0);
- token = g_scanner_get_next_token (scanner);
- }
-
- /*
- * Finally we expect a semicolon
- */
-
- if (token != ';') {
- g_printerr ("Expected \";\"\n");
- exit (1);
- }
-
- context = gromit_paint_context_new (data, type, fg_color, width, arrowsize);
- g_hash_table_insert (data->tool_config, name, context);
-
- } else {
- g_printerr ("Expected name of Tool to define\n");
- exit(1);
- }
+ if (token == G_TOKEN_STRING)
+ {
+ name = parse_name (scanner);
+ token = g_scanner_cur_token(scanner);
+
+ if (token != G_TOKEN_EQUAL_SIGN)
+ {
+ g_scanner_unexp_token (scanner, G_TOKEN_EQUAL_SIGN, NULL,
+ NULL, NULL, "aborting", TRUE);
+ exit (1);
+ }
+
+ token = g_scanner_get_next_token (scanner);
+
+ /* defaults */
+
+ type = GROMIT_PEN;
+ width = 7;
+ arrowsize = 0;
+ fg_color = data->red;
+
+ if (token == G_TOKEN_SYMBOL)
+ {
+ type = (GromitPaintType) scanner->value.v_symbol;
+ token = g_scanner_get_next_token (scanner);
+ }
+ else if (token == G_TOKEN_STRING)
+ {
+ copy = parse_name (scanner);
+ token = g_scanner_cur_token(scanner);
+ context_template = g_hash_table_lookup (data->tool_config, copy);
+ 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);
+ }
+ }
+ else
+ {
+ g_printerr ("Expected Tool-definition "
+ "or name of template tool\n");
+ exit (1);
+ }
+
+ /* Are there any tool-options?
+ */
+
+ if (token == G_TOKEN_LEFT_PAREN)
+ {
+ GdkColor *color = NULL;
+ g_scanner_set_scope (scanner, 2);
+ scanner->config->int_2_float = 1;
+ token = g_scanner_get_next_token (scanner);
+ while (token != G_TOKEN_RIGHT_PAREN)
+ {
+ if (token == G_TOKEN_SYMBOL)
+ {
+ if ((guint) scanner->value.v_symbol == 1)
+ {
+ 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 Size (float)... aborting\n");
+ exit (1);
+ }
+ width = (guint) (scanner->value.v_float + 0.5);
+ }
+ else if ((guint) scanner->value.v_symbol == 2)
+ {
+ 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_STRING)
+ {
+ g_printerr ("Missing Color (string)... "
+ "aborting\n");
+ exit (1);
+ }
+ color = g_malloc (sizeof (GdkColor));
+ if (gdk_color_parse (scanner->value.v_string,
+ color))
+ {
+ if (gdk_colormap_alloc_color (data->cm,
+ color, 0, 1))
+ {
+ fg_color = color;
+ }
+ else
+ {
+ g_printerr ("Unable to allocate color. "
+ "Keeping default!\n");
+ g_free (color);
+ }
+ }
+ else
+ {
+ g_printerr ("Unable to parse color. "
+ "Keeping default.\n");
+ g_free (color);
+ }
+ 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");
+ }
+ }
+ else
+ {
+ g_printerr ("skipped token!!!\n");
+ }
+ token = g_scanner_get_next_token (scanner);
+ }
+ g_scanner_set_scope (scanner, 0);
+ token = g_scanner_get_next_token (scanner);
+ }
+
+ /*
+ * Finally we expect a semicolon
+ */
+
+ if (token != ';')
+ {
+ g_printerr ("Expected \";\"\n");
+ exit (1);
+ }
+
+ context = gromit_paint_context_new (data, type, fg_color, width, arrowsize);
+ g_hash_table_insert (data->tool_config, name, context);
+ }
+ else
+ {
+ g_printerr ("Expected name of Tool to define\n");
+ exit(1);
+ }
token = g_scanner_get_next_token (scanner);
-
- }
- g_scanner_destroy (scanner);
- close (file);
- g_free (filename);
-
- g_printerr ("\n-----------------------------\n");
- g_hash_table_foreach (data->tool_config, parse_print_help, NULL);
- g_printerr ("-----------------------------\n\n");
+ }
+ g_scanner_destroy (scanner);
+ close (file);
+ g_free (filename);
+
+ g_printerr ("\n-----------------------------\n");
+ g_hash_table_foreach (data->tool_config, parse_print_help, NULL);
+ g_printerr ("-----------------------------\n\n");
}
-
-
/*
* Functions for setting up (parts of) the application
*/
void
-setup_input_devices ()
+setup_input_devices (GromitData *data)
{
- GList *tmp_list;
-
- tmp_list = gdk_input_list_devices ();
- while (tmp_list)
- {
- GdkDeviceInfo *info = (GdkDeviceInfo *) tmp_list->data;
+ GList *tmp_list;
+ GdkDevice *core_pointer;
- /* Guess "Eraser"-Type devices */
- if (strstr (info->name, "raser") ||
- strstr (info->name, "RASER"))
- gdk_input_set_source (info->deviceid, GDK_SOURCE_ERASER);
+ core_pointer = gdk_display_get_core_pointer (data->display);
- /* Dont touch the "SWITCH"-Device - this seems to confuse GDK */
- if (! strstr (info->name, "SWITCH"))
- {
- g_printerr ("Enabling No. %d: \"%s\" (Type: %d)\n",
- info->deviceid, info->name, info->source);
- gdk_input_set_mode (info->deviceid, GDK_MODE_SCREEN);
- }
+ for (tmp_list = gdk_display_list_devices (data->display);
+ tmp_list;
+ tmp_list = tmp_list->next)
+ {
+ GdkDevice *device = (GdkDevice *) tmp_list->data;
- tmp_list = tmp_list->next;
- }
+ /* Guess "Eraser"-Type devices */
+ if (strstr (device->name, "raser") ||
+ strstr (device->name, "RASER"))
+ gdk_device_set_source (device, GDK_SOURCE_ERASER);
+
+ /* Dont touch devices with two or less axis - GDK apparently
+ * gets confused... */
+ if (device->num_axes > 2)
+ {
+ g_printerr ("Enabling No. %p: \"%s\" (Type: %d)\n",
+ device, device->name, device->source);
+ gdk_device_set_mode (device, GDK_MODE_SCREEN);
+ }
+ }
}
void
setup_client_app (GromitData *data)
{
- data->width = gdk_screen_width ();
- data->height = gdk_screen_height ();
- data->hard_grab = 0;
-
- data->win = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_widget_set_usize (GTK_WIDGET (data->win), data->width, data->height);
- gtk_widget_set_uposition (GTK_WIDGET (data->win), 0, 0);
-
- gtk_widget_set_events (data->win, GROMIT_WINDOW_EVENTS);
-
- gtk_signal_connect (GTK_OBJECT (data->win), "delete-event",
- 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), "selection_get",
- GTK_SIGNAL_FUNC (event_selection_get), (gpointer) data);
- gtk_signal_connect (GTK_OBJECT (data->win), "selection_received",
- GTK_SIGNAL_FUNC (event_selection_received),
- (gpointer) data);
+ data->display = gdk_display_get_default ();
+ data->screen = gdk_display_get_default_screen (data->display);
+ data->root = gdk_screen_get_root_window (data->screen);
+ data->width = gdk_screen_get_width (data->screen);
+ data->height = gdk_screen_get_height (data->screen);
+ data->hard_grab = 0;
+
+ data->win = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_widget_set_usize (GTK_WIDGET (data->win), data->width, data->height);
+ gtk_widget_set_uposition (GTK_WIDGET (data->win), 0, 0);
+
+ gtk_widget_set_events (data->win, GROMIT_WINDOW_EVENTS);
+
+ gtk_signal_connect (GTK_OBJECT (data->win), "delete-event",
+ 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), "selection_get",
+ GTK_SIGNAL_FUNC (event_selection_get), (gpointer) data);
+ gtk_signal_connect (GTK_OBJECT (data->win), "selection_received",
+ GTK_SIGNAL_FUNC (event_selection_received),
+ (gpointer) data);
}
void
setup_main_app (GromitData *data)
{
- GdkPixmap *cursor_src, *cursor_mask;
-
- /* COLORMAP */
- data->cm = gdk_colormap_get_system ();
- data->white = g_malloc (sizeof (GdkColor));
- data->black = g_malloc (sizeof (GdkColor));
- data->red = g_malloc (sizeof (GdkColor));
- gdk_color_white (data->cm, data->white);
- gdk_color_black (data->cm, data->black);
- gdk_color_parse ("#FF0000", data->red);
- gdk_colormap_alloc_color (data->cm, data->red, 0, 1);
-
- /* CURSORS */
- cursor_src = gdk_bitmap_create_from_data (NULL, paint_cursor_bits,
- paint_cursor_width,
- paint_cursor_height);
- cursor_mask = gdk_bitmap_create_from_data (NULL, paint_cursor_mask_bits,
- paint_cursor_width,
- paint_cursor_height);
- data->paint_cursor = gdk_cursor_new_from_pixmap (cursor_src, cursor_mask,
- data->white, data->black,
- paint_cursor_x_hot,
- paint_cursor_y_hot);
- gdk_pixmap_unref (cursor_src);
- gdk_pixmap_unref (cursor_mask);
-
- 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);
-
- gdk_window_set_cursor (data->win->window, data->paint_cursor);
-
- /* SHAPE PIXMAP */
- data->shape = gdk_pixmap_new (NULL, data->width, data->height, 1);
- data->shape_gc = gdk_gc_new (data->shape);
- data->shape_gcv = g_malloc (sizeof (GdkGCValues));
- gdk_gc_get_values (data->shape_gc, data->shape_gcv);
- data->transparent = gdk_color_copy (&(data->shape_gcv->foreground));
- data->opaque = gdk_color_copy (&(data->shape_gcv->background));
- gdk_gc_set_foreground (data->shape_gc, data->transparent);
- gdk_draw_rectangle (data->shape, data->shape_gc,
- 1, 0, 0, data->width, data->height);
-
- /* DRAWING AREA */
- data->area = gtk_drawing_area_new ();
- gtk_drawing_area_size (GTK_DRAWING_AREA (data->area),
- data->width, data->height);
-
- gtk_widget_set_events (data->area, GROMIT_PAINT_AREA_EVENTS);
- 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), "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",
- 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);
-
- gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);
-
- gtk_widget_show_all (data->area);
-
- gtk_widget_realize (data->win);
-
- data->painted = 0;
- 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, 0);
- data->default_eraser = gromit_paint_context_new (data, GROMIT_ERASER, data->red, 75, 0);
-
- data->cur_context = data->default_pen;
-
- /*
- * Parse Config file
- */
-
- data->tool_config = g_hash_table_new (g_str_hash, g_str_equal);
- parse_config (data);
- data->state = 0;
-
- gtk_selection_owner_set (data->win, GA_CONTROL, GDK_CURRENT_TIME);
-
- gtk_selection_add_target (data->win, GA_CONTROL, GA_STATUS, 0);
- gtk_selection_add_target (data->win, GA_CONTROL, GA_QUIT, 1);
- gtk_selection_add_target (data->win, GA_CONTROL, GA_ACTIVATE, 2);
- gtk_selection_add_target (data->win, GA_CONTROL, GA_DEACTIVATE, 3);
- gtk_selection_add_target (data->win, GA_CONTROL, GA_TOGGLE, 4);
- gtk_selection_add_target (data->win, GA_CONTROL, GA_VISIBILITY, 5);
- gtk_selection_add_target (data->win, GA_CONTROL, GA_CLEAR, 6);
-
- setup_input_devices ();
+ GdkPixmap *cursor_src, *cursor_mask;
+ GdkKeymap *keymap;
+ GdkKeymapKey *keys;
+ gint n_keys;
+ guint keyval;
+
+ /* COLORMAP */
+ data->cm = gdk_screen_get_default_colormap (data->screen);
+ data->white = g_malloc (sizeof (GdkColor));
+ data->black = g_malloc (sizeof (GdkColor));
+ data->red = g_malloc (sizeof (GdkColor));
+ gdk_color_parse ("#FFFFFF", data->white);
+ gdk_colormap_alloc_color (data->cm, data->white, FALSE, TRUE);
+ gdk_color_parse ("#000000", data->black);
+ gdk_colormap_alloc_color (data->cm, data->black, FALSE, TRUE);
+ gdk_color_parse ("#FF0000", data->red);
+ gdk_colormap_alloc_color (data->cm, data->red, FALSE, TRUE);
+
+ /* CURSORS */
+ cursor_src = gdk_bitmap_create_from_data (NULL, paint_cursor_bits,
+ paint_cursor_width,
+ paint_cursor_height);
+ cursor_mask = gdk_bitmap_create_from_data (NULL, paint_cursor_mask_bits,
+ paint_cursor_width,
+ paint_cursor_height);
+ data->paint_cursor = gdk_cursor_new_from_pixmap (cursor_src, cursor_mask,
+ data->white, data->black,
+ paint_cursor_x_hot,
+ paint_cursor_y_hot);
+ g_object_unref (cursor_src);
+ g_object_unref (cursor_mask);
+
+ 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);
+ g_object_unref (cursor_src);
+ g_object_unref (cursor_mask);
+
+ gdk_window_set_cursor (data->win->window, data->paint_cursor);
+
+ /* SHAPE PIXMAP */
+ data->shape = gdk_pixmap_new (NULL, data->width, data->height, 1);
+ data->shape_gc = gdk_gc_new (data->shape);
+ data->shape_gcv = g_malloc (sizeof (GdkGCValues));
+ gdk_gc_get_values (data->shape_gc, data->shape_gcv);
+ data->transparent = gdk_color_copy (&(data->shape_gcv->foreground));
+ data->opaque = gdk_color_copy (&(data->shape_gcv->background));
+ gdk_gc_set_foreground (data->shape_gc, data->transparent);
+ gdk_draw_rectangle (data->shape, data->shape_gc,
+ 1, 0, 0, data->width, data->height);
+
+ /* DRAWING AREA */
+ data->area = gtk_drawing_area_new ();
+ gtk_drawing_area_size (GTK_DRAWING_AREA (data->area),
+ data->width, data->height);
+
+ gtk_widget_set_events (data->area, GROMIT_PAINT_AREA_EVENTS);
+ 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), "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",
+ 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);
+
+ gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);
+
+ gtk_widget_show_all (data->area);
+
+ gtk_widget_realize (data->win);
+
+ data->painted = 0;
+ 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, 0);
+ data->default_eraser = gromit_paint_context_new (data, GROMIT_ERASER,
+ data->red, 75, 0);
+
+ data->cur_context = data->default_pen;
+
+ /*
+ * Parse Config file
+ */
+
+ data->tool_config = g_hash_table_new (g_str_hash, g_str_equal);
+ parse_config (data);
+ data->state = 0;
+
+ gtk_selection_owner_set (data->win, GA_CONTROL, GDK_CURRENT_TIME);
+
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_STATUS, 0);
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_QUIT, 1);
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_ACTIVATE, 2);
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_DEACTIVATE, 3);
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_TOGGLE, 4);
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_VISIBILITY, 5);
+ gtk_selection_add_target (data->win, GA_CONTROL, GA_CLEAR, 6);
+
+ setup_input_devices (data);
+
+ /* Grab the GROMIT_HOTKEY */
+
+ keymap = gdk_keymap_get_for_display (data->display);
+
+ keyval = gdk_keyval_from_name (GROMIT_HOTKEY);
+
+ if (!keyval || !gdk_keymap_get_entries_for_keyval (keymap, keyval,
+ &keys, &n_keys))
+ {
+ g_printerr ("cannot find the key \"%s\"\n", GROMIT_HOTKEY);
+ exit (1);
+ }
+
+ data->hot_keycode = keys[0].keycode;
+ g_free (keys);
+
+ gdk_event_handler_set ((GdkEventFunc) gromit_main_do_event, data, NULL);
+ gtk_key_snooper_install (key_press_event, data);
+ XGrabKey (GDK_DISPLAY_XDISPLAY (data->display),
+ data->hot_keycode,
+ AnyModifier,
+ GDK_WINDOW_XWINDOW (data->root),
+ TRUE,
+ GrabModeAsync,
+ GrabModeAsync);
}
@@ -1314,61 +1510,61 @@ main_client (int argc, char **argv, GromitData *data)
arg = argv[i];
action = GDK_NONE;
if (strcmp (arg, "-t") == 0 ||
- strcmp (arg, "--toggle") == 0)
- action = GA_TOGGLE;
+ strcmp (arg, "--toggle") == 0)
+ action = GA_TOGGLE;
else if (strcmp (arg, "-v") == 0 ||
- strcmp (arg, "--visibility") == 0)
- action = GA_VISIBILITY;
+ strcmp (arg, "--visibility") == 0)
+ action = GA_VISIBILITY;
else if (strcmp (arg, "-q") == 0 ||
- strcmp (arg, "--quit") == 0)
- action = GA_QUIT;
+ strcmp (arg, "--quit") == 0)
+ action = GA_QUIT;
else if (strcmp (arg, "-c") == 0 ||
- strcmp (arg, "--clear") == 0)
- action = GA_CLEAR;
+ strcmp (arg, "--clear") == 0)
+ action = GA_CLEAR;
if (action != GDK_NONE)
{
- gtk_selection_convert (data->win, GA_CONTROL,
- action, GDK_CURRENT_TIME);
- gtk_main (); /* Wait for the response */
+ gtk_selection_convert (data->win, GA_CONTROL,
+ action, GDK_CURRENT_TIME);
+ gtk_main (); /* Wait for the response */
}
}
- return TRUE;
+ return 0;
}
int
main (int argc, char **argv)
{
- GromitData *data;
+ GromitData *data;
- gtk_init (&argc, &argv);
- data = g_malloc (sizeof (GromitData));
+ gtk_init (&argc, &argv);
+ data = g_malloc (sizeof (GromitData));
- /* g_set_printerr_handler (quiet_print_handler); */
+ /* g_set_printerr_handler (quiet_print_handler); */
- setup_client_app (data);
+ setup_client_app (data);
- /* Try to get a status message. If there is a response gromit
- * is already acive.
- */
+ /* Try to get a status message. If there is a response gromit
+ * is already acive.
+ */
- gtk_selection_convert (data->win, GA_CONTROL, GA_STATUS,
- GDK_CURRENT_TIME);
- gtk_main (); /* Wait for the response */
+ gtk_selection_convert (data->win, GA_CONTROL, GA_STATUS,
+ GDK_CURRENT_TIME);
+ gtk_main (); /* Wait for the response */
- if (data->client)
- return main_client (argc, argv, data);
- data->client = FALSE;
+ if (data->client)
+ return main_client (argc, argv, data);
- /* Main application */
- setup_main_app (data);
- gtk_main ();
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
- gdk_cursor_destroy (data->paint_cursor);
- gdk_cursor_destroy (data->erase_cursor);
- g_free (data);
- return 0;
+ /* Main application */
+ setup_main_app (data);
+ gtk_main ();
+ gdk_display_pointer_ungrab (data->display, GDK_CURRENT_TIME);
+ gdk_cursor_unref (data->paint_cursor);
+ gdk_cursor_unref (data->erase_cursor);
+ g_free (data);
+ return 0;
}
-/* vim: sw=3 ts=8 cindent noai bs=2 cinoptions=(0 */
+/* vim: sw=3 ts=8 cindent noai bs=2 cinoptions=(0
+ */
diff --git a/gromitrc_gsr b/gromitrc_gsr
new file mode 100644
index 0000000..03d12a0
--- /dev/null
+++ b/gromitrc_gsr
@@ -0,0 +1,70 @@
+/* GRaphics Over MIscellaneous Things RC file */
+/* byGSR 2001-12-11 */
+
+/* Pens */
+"red Pen" = PEN (size = 7 color = "red");
+"green Pen" = PEN (size = 7 color = "green");
+"blue Pen" = PEN (size = 7 color = "blue");
+# "yellow Pen" = PEN (size = 7 color = "yellow");
+
+/* Quill */
+"black Quill" = PEN (size = 4 color = "black");
+"gray Quill" = PEN (size = 4 color = "gray50");
+"white Quill" = PEN (size = 4 color = "white");
+
+/* Smart pens */
+"red SmartPen" = PEN (size = 7 color = "red" arrowsize = 7);
+"green SmartPen" = PEN (size = 7 color = "green" arrowsize = 7);
+"blue SmartPen" = PEN (size = 7 color = "blue" arrowsize = 7);
+
+/* Markers */
+"red Marker" = RECOLOR (size = 15 color = "red");
+"green Marker" = RECOLOR (size = 15 color = "green");
+"blue Marker" = RECOLOR (size = 15 color = "blue");
+# "yellow Marker" = RECOLOR (size = 15 color = "yellow");
+
+/* Erasers */
+"big Eraser" = ERASER (size = 75);
+"medium Eraser" = ERASER (size = 50);
+"small Eraser" = ERASER (size = 25);
+# "tiny Eraser" = ERASER (size = 10);
+
+/* Bindings */
+# Lines in MB1, with shift it creates arrows
+"Core Pointer"[Button1] = "red Pen";
+"Core Pointer"[Button1, CONTROL] = "green Pen";
+"Core Pointer"[Button1, META] = "blue Pen";
+"Core Pointer"[Button1, SHIFT] = "red SmartPen";
+"Core Pointer"[Button1, SHIFT, CONTROL] = "green SmartPen";
+"Core Pointer"[Button1, SHIFT, META] = "blue SmartPen";
+
+# Recolor in MB2
+"Core Pointer"[Button2] = "red Marker";
+"Core Pointer"[Button2, CONTROL] = "green Marker";
+"Core Pointer"[Button2, META] = "blue Marker";
+
+# Erase in MB3
+"Core Pointer"[Button3] = "big Eraser";
+"Core Pointer"[Button3, CONTROL] = "medium Eraser";
+"Core Pointer"[Button3, META] = "small Eraser";
+
+# It paints pretty nice this way
+"WacomStylus0"[Button1] = "black Quill";
+"WacomStylus0"[Button1, CONTROL] = "gray Quill";
+"WacomStylus0"[Button1, META] = "white Quill";
+
+# I have only one side button in the Wacom pen
+"WacomStylus0"[Button2] = "red Marker";
+"WacomStylus0"[Button2, CONTROL] = "green Marker";
+"WacomStylus0"[Button2, META] = "blue Marker";
+
+# I use the eraser tip as MB4
+"WacomStylus0"[Button4] = "big Eraser";
+"WacomStylus0"[Button4, CONTROL] = "medium Eraser";
+"WacomStylus0"[Button4, META] = "small Eraser";
+
+# Or remapped to MB3
+"WacomStylus0"[Button3] = "big Eraser";
+"WacomStylus0"[Button3, CONTROL] = "medium Eraser";
+"WacomStylus0"[Button3, META] = "small Eraser";
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]