[gromit: 7/13] Import of gromit history
- From: Simon Budig <simon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gromit: 7/13] Import of gromit history
- Date: Tue, 16 Mar 2010 22:24:02 +0000 (UTC)
commit 08b1f35177d43484f9f7e41acace929162eb5231
Author: Simon Budig <simon budig de>
Date: Sun Aug 26 16:07:00 2001 +0200
Import of gromit history
ChangeLog | 5 --
Makefile | 3 -
README | 50 +++++++++-------
gromit.c | 180 +++++++++++++++++++++++++++++++++++++++++--------------
gromitconf | 26 --------
propertywatch.c | 136 -----------------------------------------
sawfish-config | 9 +++
7 files changed, 172 insertions(+), 237 deletions(-)
---
diff --git a/Makefile b/Makefile
index 0613232..4fe7115 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,4 @@
all: gromit
-propertywatch: propertywatch.c
- gcc -o propertywatch propertywatch.c `gtk-config --libs --cflags`
-
gromit: gromit.c
gcc -o gromit gromit.c `gtk-config --libs --cflags`
diff --git a/README b/README
index 24e7a18..06525fd 100644
--- a/README
+++ b/README
@@ -12,8 +12,8 @@ on the screen, ignoring any window-borders.
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 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
@@ -21,8 +21,8 @@ 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
+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
@@ -35,29 +35,32 @@ possible to erase something with the other end of the (Wacom) pen.
Usage:
gromit --quit
- will cause the main gromit process to quit (or "-q")
+ will cause the main Gromit process to quit (or "-q")
gromit --toggle
will toggle the grabbing of the cursor (or "-t")
+ gromit --visibility
+ will toggle the visibility of the window (or "-v")
gromit --clear
will clear the screen (or "-c")
-If activated gromit prevents you from using other programs with the
+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...
-The next "gromit --toggle" will deactivate gromit and you can use your
+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. If you have config-files for other
-window-managers I'd be happy to include them. Please send them to me.
+Shift+Pause) will clear the screen, "Control-Pause" will toccle 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.
Building:
-Gromit is small and lightwight. It needs Gtk to build and the Makefile
+Gromit is small and lightwight. It needs GTK+ 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
@@ -67,9 +70,9 @@ Linux/XFree86, reports from other platforms are welcome.
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:
+which tool. See the file "gromitconf" distributed with this program for
+an example. An overview on the syntax:
# Comments can be either # Shell-Style or
/* C-Style. */
@@ -123,15 +126,20 @@ The descision, which tool to use follows a simple policy:
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
-pattern on screen. Especially terminal-programs tend to scroll
-incredibly slow if something is painted over their window. There is
-nothing I can do about this.
-
-Gromit may disable DnD, since this interferes with the special Selection-Code.
-Unfortunately I have no better idea for the (de)activation of Gromit.
-Hopefully I can find a way to work around this.
+Gromit may drastically slow down your X-Server, especially when you draw
+very thin lines. It makes heavily use of the shape extension, which is
+quite expensive if you paint a complex pattern on screen. Especially
+terminal-programs tend to scroll incredibly slow if something is painted
+over their window. There is nothing I can do about this.
+
+Gromit partially disables DnD, since it lays a transparent window across
+the whole screen and everything gets "dropped" to this (invisible)
+window. Gromit tries to minimize this effect: When you clear the screen
+the shaped window will be hidden. It will be resurrected, when you want
+to paint something again. However: The window does not hide, if you
+erase everything with the eraser tool, you have to clear the screen
+explicitely with the "gromit --clear" command or hide Gromit with
+"gromit --visibility".
This Program is distributed under the Gnu General Public License. See
the file COPYING for details.
diff --git a/gromit.c b/gromit.c
index 1e101f1..119cc5e 100644
--- a/gromit.c
+++ b/gromit.c
@@ -21,6 +21,7 @@
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
+#include <errno.h>
#include <fcntl.h>
#include "paint_cursor.xbm"
@@ -34,7 +35,9 @@
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_MOTION_MASK \
/* | GDK_POINTER_MOTION_HINT_MASK */ )
-
+
+/* #define GROMIT_WINDOW_EVENTS ( GDK_PROPERTY_CHANGE_MASK ) */
+#define GROMIT_WINDOW_EVENTS ( 0 )
/* Atoms used to control Gromit */
#define GA_CONTROL gdk_atom_intern ("Gromit/control", FALSE)
@@ -43,8 +46,10 @@
#define GA_ACTIVATE gdk_atom_intern ("Gromit/activate", FALSE)
#define GA_DEACTIVATE gdk_atom_intern ("Gromit/deactivate", FALSE)
#define GA_TOGGLE gdk_atom_intern ("Gromit/toggle", FALSE)
+#define GA_VISIBILITY gdk_atom_intern ("Gromit/visibility", FALSE)
#define GA_CLEAR gdk_atom_intern ("Gromit/clear", FALSE)
+
typedef enum
{
GROMIT_PEN,
@@ -103,9 +108,15 @@ typedef struct
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);
+
GromitPaintContext *
gromit_paint_context_new (GromitData *data, GromitPaintType type,
GdkColor *fg_color, guint width)
@@ -180,56 +191,115 @@ gromit_paint_context_free (GromitPaintContext *context)
void
-gromit_toggle_grab (GromitData *data)
+gromit_hide_window (GromitData *data)
+{
+ if (!data->hidden)
+ {
+ if (data->hard_grab)
+ data->hidden = 2;
+ else
+ data->hidden = 1;
+ gromit_release_grab (data);
+ gtk_widget_hide (data->win);
+ }
+}
+
+
+void
+gromit_show_window (GromitData *data)
+{
+ gint oldstatus = 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);
+}
+
+
+void
+gromit_toggle_visibility (GromitData *data)
+{
+ if (data->hidden)
+ gromit_show_window (data);
+ else
+ gromit_hide_window (data);
+}
+
+
+void
+gromit_release_grab (GromitData *data)
{
if (data->hard_grab)
{
data->hard_grab = 0;
- /* gtk_grab_remove (gtk_grab_get_current ()); */
- g_printerr ("Ungrabbing pointer\n");
gdk_pointer_ungrab (GDK_CURRENT_TIME);
- /* gdk_pointer_grab (data->area->window, FALSE, GDK_POINTER_MOTION_MASK,
- 0, NULL, GDK_CURRENT_TIME); */
- } else {
- int foo;
- /* gtk_grab_add (data->area); */
- g_printerr ("Grabbing pointer: ");
- foo = 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);
- switch (foo) {
+ }
+ if (!data->painted)
+ gromit_hide_window (data);
+}
+
+
+void
+gromit_aquire_grab (GromitData *data)
+{
+ int result;
+
+ gromit_show_window (data);
+ if (!data->hard_grab)
+ {
+
+ 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);
+ switch (result) {
case Success:
data->hard_grab = 1;
- g_printerr ("Success\n");
break;
case GrabNotViewable:
- g_printerr ("GrabNotViewable\n");
+ g_printerr ("Grabbing Pointer failed: %s\n", "GrabNotViewable");
break;
case AlreadyGrabbed:
- g_printerr ("AlreadyGrabbed\n");
+ g_printerr ("Grabbing Pointer failed: %s\n", "AlreadyGrabbed");
break;
case GrabFrozen:
- g_printerr ("GrabFrozen\n");
+ g_printerr ("Grabbing Pointer failed: %s\n", "GrabFrozen");
break;
case GrabInvalidTime:
- g_printerr ("GrabInvalidTime\n");
+ g_printerr ("Grabbing Pointer failed: %s\n", "GrabInvalidTime");
break;
default:
- g_printerr ("Huh?\n");
+ g_printerr ("Grabbing Pointer failed: %s\n", "Unknown error");
}
- gdk_window_raise (data->win->window);
}
}
void
+gromit_toggle_grab (GromitData *data)
+{
+ if (data->hard_grab)
+ gromit_release_grab (data);
+ else
+ gromit_aquire_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;
}
@@ -248,7 +318,6 @@ reshape (gpointer user_data)
data->delayed = 0;
}
}
-
return 1;
}
@@ -363,11 +432,12 @@ gromit_draw_line (GromitData *data, gint x1, gint y1,
if (data->cur_context->paint_gc)
gtk_widget_draw (data->area, &rect);
+ data->painted = 1;
}
/*
- * Event-Handlers that perform the drawing
+ * Event-Handlers to perform the drawing
*/
gboolean
@@ -377,7 +447,6 @@ proximity_in (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
gint x, y;
GdkModifierType state;
- g_printerr ("proximity_in\n");
gdk_window_get_pointer (data->win->window, &x, &y, &state);
gromit_select_tool (data, ev->deviceid, state);
return 0;
@@ -389,7 +458,6 @@ proximity_out (GtkWidget *win, GdkEventProximity *ev, gpointer user_data)
{
GromitData *data = (GromitData *) user_data;
- g_printerr ("proximity_out\n");
data->cur_context = data->default_pen;
if (data->cur_context->type == GROMIT_ERASER)
@@ -407,7 +475,6 @@ paint (GtkWidget *win, GdkEventButton *ev, gpointer user_data)
{
GromitData *data = (GromitData *) user_data;
- g_printerr ("Button %d\n", ev->button);
/* See GdkModifierType. Am I fixing a Gtk misbehaviour??? */
ev->state |= 1 << (ev->button + 7);
if (ev->state != data->state || ev->deviceid != data->deviceid)
@@ -467,7 +534,6 @@ paintto (GtkWidget *win, GdkEventMotion *ev, gpointer user_data)
g_free (coords);
} else {
if (ev->is_hint) {
- g_printerr ("Hint\n");
gdk_input_window_get_pointer (ev->window, ev->deviceid,
NULL, NULL, NULL, NULL, NULL, NULL);
}
@@ -499,16 +565,6 @@ quiet_print_handler (const gchar *string)
}
-guint
-event_key_snoop (GtkWidget *grab_widget,
- GdkEventKey *event,
- gpointer func_data)
-{
- g_printerr ("Got Key!\n");
- return 0;
-}
-
-
gboolean
event_configure (GtkWidget *widget,
GdkEventExpose *event,
@@ -555,6 +611,8 @@ event_selection_get (GtkWidget *widget,
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)
@@ -662,6 +720,7 @@ gint parse_config (GromitData *data) {
GromitPaintContext *context_template=NULL;
GScanner *scanner;
GTokenType token;
+ gchar *filename;
int file;
gchar *name, *copy;
@@ -672,7 +731,18 @@ gint parse_config (GromitData *data) {
guint buttons, modifier;
+ filename = g_strjoin (G_DIR_SEPARATOR_S, g_get_home_dir(), ".gromit", NULL);
+ file = open (filename, O_RDONLY);
+
+ 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;
@@ -700,7 +770,6 @@ gint parse_config (GromitData *data) {
g_scanner_set_scope (scanner, 0);
scanner->config->scope_0_fallback = 0;
- file = open ("./gromitconf", O_RDONLY);
g_scanner_input_file (scanner, file);
token = g_scanner_get_next_token (scanner);
@@ -828,6 +897,7 @@ gint parse_config (GromitData *data) {
}
g_scanner_destroy (scanner);
close (file);
+ g_free (filename);
g_printerr ("\n-----------------------------\n");
g_hash_table_foreach (data->tool_config, parse_print_help, NULL);
@@ -850,15 +920,19 @@ setup_input_devices ()
while (tmp_list)
{
GdkDeviceInfo *info = (GdkDeviceInfo *) tmp_list->data;
- if (strstr (info->name, "raser")) /* Guess "Eraser"-Type devices */
- gdk_input_set_source (info->deviceid, GDK_SOURCE_ERASER);
- g_printerr ("Enabling No. %d: \"%s\" (Type: %d)\n",
- info->deviceid, info->name, info->source);
+ /* Guess "Eraser"-Type devices */
+ if (strstr (info->name, "raser") ||
+ strstr (info->name, "RASER"))
+ gdk_input_set_source (info->deviceid, GDK_SOURCE_ERASER);
+ /* Dont touch the "SWITCH"-Device - this seems to confuse GDK */
if (! strstr (info->name, "SWITCH"))
- /* Dont touch the "SWITCH"-Device - this seems to confuse Gtk+ */
+ {
+ g_printerr ("Enabling No. %d: \"%s\" (Type: %d)\n",
+ info->deviceid, info->name, info->source);
gdk_input_set_mode (info->deviceid, GDK_MODE_SCREEN);
+ }
tmp_list = tmp_list->next;
}
@@ -877,6 +951,8 @@ setup_client_app (GromitData *data)
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",
@@ -893,6 +969,7 @@ void
setup_main_app (GromitData *data)
{
GdkPixmap *cursor_src, *cursor_mask;
+ Window xwin;
/* COLORMAP */
data->cm = gdk_colormap_get_system ();
@@ -971,7 +1048,12 @@ setup_main_app (GromitData *data)
gtk_widget_shape_combine_mask (data->win, data->shape, 0,0);
- gtk_widget_show_all (data->win);
+ 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->modified = 0;
@@ -979,6 +1061,7 @@ setup_main_app (GromitData *data)
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);
+
/*
* Parse Config file
*/
@@ -994,7 +1077,8 @@ setup_main_app (GromitData *data)
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_CLEAR, 5);
+ 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 ();
}
@@ -1018,6 +1102,9 @@ main_client (int argc, char **argv, GromitData *data)
if (strcmp (arg, "-t") == 0 ||
strcmp (arg, "--toggle") == 0)
action = GA_TOGGLE;
+ else if (strcmp (arg, "-v") == 0 ||
+ strcmp (arg, "--visibility") == 0)
+ action = GA_VISIBILITY;
else if (strcmp (arg, "-q") == 0 ||
strcmp (arg, "--quit") == 0)
action = GA_QUIT;
@@ -1058,6 +1145,7 @@ main (int argc, char **argv)
if (data->client)
return main_client (argc, argv, data);
+ data->client = FALSE;
/* Main application */
setup_main_app (data);
diff --git a/sawfish-config b/sawfish-config
index 2eb56ed..69c5118 100755
--- a/sawfish-config
+++ b/sawfish-config
@@ -23,7 +23,16 @@ sawfish-client -- >/dev/null <<ENDOFSAWFISHCONFIG
(system "cd \"$LOCATION\" ; ./gromit --clear &")
)
+(defun gromit-toggle-visibility ()
+ (interactive)
+ (ungrab-pointer)
+ (ungrab-keyboard)
+ (sync-server)
+ (system "cd \"$LOCATION\" ; ./gromit --visibility &")
+)
+
(bind-keys global-keymap "Pause" 'gromit-toggle-grab)
+(bind-keys global-keymap "C-Pause" 'gromit-toggle-visibility)
(bind-keys global-keymap "Break" 'gromit-clear-screen)
ENDOFSAWFISHCONFIG
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]