/* onebutton.c Subject: Gtk module to remap mouse buttons Date: Tue, 17 Jul 2001 16:13:00 +0800 (WST) From: James Henstridge To: Since I had a bit of spare time, I wrote the small module to perform button remapping for GTK programs (as I suggested on #gnome). It installs an emission hook that will be called everytime an event is about to be handled by a widget. It checks to see if it is a button event, in which case it sets the button number to 1. To compile, run: gcc -fPIC `gtk-config --cflags` -c onebutton.c gcc -shared onebutton.o -o onebutton.so Then set the GTK_MODULES environment variable: export GTK_MODULES=/directory/onebutton.so Now when you start gtk+ programs, they will load onebutton.so, which will install the emission hook. Should be pretty easy to modify if you only want to remap one or two buttons. James. */ #include #include #include #include static guint munge_state (guint type, guint state) { # define BMASKS (GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | \ GDK_BUTTON4_MASK | GDK_BUTTON5_MASK) if (state & BMASKS) { state &= (~ BMASKS); state |= GDK_BUTTON1_MASK; } # undef BMASKS return state; } /* If it is a button press event, modify the event to look like button1 was used. This makes it impossible to right or middle click. */ static gboolean munge_button_events (GtkObject *object, guint signal_id, guint n_params, GtkArg *params, gpointer data) { GdkEvent *event = GTK_VALUE_POINTER(params[0]); switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: event->button.button = 1; event->button.state = munge_state (event->type, event->button.state); break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: event->key.state = munge_state (event->type, event->key.state); break; case GDK_MOTION_NOTIFY: event->motion.state = munge_state (event->type, event->motion.state); break; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: event->crossing.state = munge_state (event->type, event->crossing.state); break; } return TRUE; } /* the init function for this gtk module */ G_MODULE_EXPORT void gtk_module_init (gint *argc, gchar ***argv); void gtk_module_init (gint *argc, gchar ***argv) { guint signal_id = gtk_signal_lookup ("event", GTK_TYPE_WIDGET); gtk_signal_add_emission_hook (signal_id, munge_button_events, NULL); } #if 0 /* hack hack */ #include #include GdkWindow* gdk_window_get_pointer (GdkWindow *window, gint *x, gint *y, GdkModifierType *mask) { GdkWindowPrivate *private; GdkWindow *return_val; Window root; Window child; int rootx, rooty; int winx = 0; int winy = 0; unsigned int xmask = 0; if (!window) window = (GdkWindow*) &gdk_root_parent; private = (GdkWindowPrivate*) window; fprintf (stderr, "#### foo\n"); return_val = NULL; if (!private->destroyed && XQueryPointer (private->xdisplay, private->xwindow, &root, &child, &rootx, &rooty, &winx, &winy, &xmask)) { if (child) return_val = gdk_window_lookup (child); } if (x) *x = winx; if (y) *y = winy; if (mask) *mask = xmask; return return_val; } #endif /* 0 */