[PATCH] Wheel mice (try one), was: Re: Wheel mice patch, question



Hello,

I spent a while hacking on wheel mouse support and it seems the result is:

- not too stupid in design :-)
- and binary compatible to gtk+-1.2.0 (it would be nice to have this in
  1.2.x, so gimp 1.1.x/1.2.x could use the handler function mentioned
  below and benefit from wheel mice (the patch for gimp is almost ready, 
  but I don't want to put the handler function in gimp itself))

the Changes are:

- the lowlevel button 4 & 5 handling is done in an extern function
  gtk_wheel_event_handler(), the advantage is that applications can use
  this if gtk_main_do_event() is not clever enough to figure things out by
  itself (which widget/adjustment should receive the events, etc.).

- the handler function (which should be gtk_doc compatible) takes an event
  pointer "event" and two pointers to either adjustments or a GtkRange or
  GtkSpinbutton (-derivative) "adj1" and "adj2" and figures out by itself
  which one to use (depends on the value (NULL, not NULL), the visibility
  (if it's a widget) and if gdk_std_modifier_mask (which I introduced for
  this purpose, because hardcoding values didn't seem to be clever enough)
  is set in event->state).

- Introduction of gdk_std_modifier_mask (see above), to be used as a
  standard modifier mask to temporarily toggle things, here: toggling
  between vertical and horizontal scrollbars with wheel mice, one could
  think of gimp toggling the direction of the flip tool, or something like
  that. The preset value is GDK_MOD1_MASK, which should be Alt/Meta on
  the average keyboard.

Changes were made on a pristine gtk+-1.2.0 source tree and affect the
following files:

ChangeLog
gdk/gdkglobals.c
gdk/gdk.h
gtk/gtkmain.c
gtk/Makefile.am

I added two files because I didn't know were to put the handler function,
it didn't seem to fit in one of the existing files:

gtk/gtkwheel_aux.h
gtk/gtkwheel_aux.c

It would be great if some core developer [Owen: I cc'ed you directly,
because you did the wheel handling according to ChangeLog] could approve
this or tell me if I did something wrong which prevents this to get into
the "mainstream".

Have a good night,
Nils
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Nils Philippsen                  @college: nils@fht-esslingen.de
Vogelsangstrasse 115             @home:    nils@wombat.dialup.fht-esslingen.de
D 70197 Stuttgart                phone:    +49-711-6599405
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lottery is a tax on people who are bad at math.
--- gtk+-1.2.0/gdk/gdkglobals.c.orig	Wed Feb 24 11:14:55 1999
+++ gtk+-1.2.0/gdk/gdkglobals.c	Sat Mar 20 16:30:11 1999
@@ -79,3 +79,4 @@
 GdkWindow *gdk_xim_window;	        /* currently using Window */
 #endif
 
+GdkModifierType gdk_std_modifier_mask = GDK_MOD1_MASK; /* std modifier */
--- gtk+-1.2.0/gdk/gdk.h.orig	Wed Feb 24 11:14:55 1999
+++ gtk+-1.2.0/gdk/gdk.h	Mon Mar 22 01:15:14 1999
@@ -982,6 +982,19 @@
 gboolean gdk_event_send_client_message (GdkEvent    *event,
 					guint32      xid);
 
+/*
+ * "Standard" modifier to temporarily toggle behaviour of various actions.
+ * Examples:
+ * - moving the horizontal instead of the vertical scrollbar when using
+ *   the scroll wheel of certain mice
+ * - flip horizontally instead of vertically (and vice versa) when using the
+ *   flip tool of the Gimp [not implemented yet, just a thought]
+ * As of now, the Alt (Mod1, Meta) Key is used.
+ *
+ * Nils
+ */
+extern GdkModifierType gdk_std_modifier_mask;
+
 /* Key values
  */
 gchar*   gdk_keyval_name		  (guint	keyval);
--- gtk+-1.2.0/gtk/gtkmain.c.orig	Wed Feb 24 23:04:00 1999
+++ gtk+-1.2.0/gtk/gtkmain.c	Mon Mar 22 00:08:04 1999
@@ -51,6 +51,7 @@
 #include "config.h"
 #include "gtkdebug.h"
 #include "gtkintl.h"
+#include "gtkwheel_aux.h"
 
 /* Private type definitions
  */
@@ -716,20 +717,19 @@
 	    {
 	      scrollwin = gtk_widget_get_ancestor (event_widget,
 						   GTK_TYPE_SCROLLED_WINDOW);
-	      if (scrollwin)
-		range = GTK_SCROLLED_WINDOW (scrollwin)->vscrollbar;
+	      if (scrollwin) {
+		gtk_wheel_event_handler (event,
+					 GTK_SCROLLED_WINDOW (scrollwin)->vscrollbar,
+					 GTK_SCROLLED_WINDOW (scrollwin)->hscrollbar);
+		break;
+	      }
 	    }
 	  
 	  if (range && GTK_WIDGET_VISIBLE (range))
 	    {
 	      if (event->type == GDK_BUTTON_PRESS)
 		{
-		  GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
-		  gfloat new_value = adj->value + ((event->button.button == 4) ? 
-						   -adj->page_increment / 2: 
-						    adj->page_increment / 2);
-		  new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
-		  gtk_adjustment_set_value (adj, new_value);
+		  gtk_wheel_event_handler (event, range, NULL);
 		}
 	      break;
 	    }
--- gtk+-1.2.0/gtk/gtkwheel_aux.h.orig	Sat Mar 20 16:32:25 1999
+++ gtk+-1.2.0/gtk/gtkwheel_aux.h	Mon Mar 22 00:26:19 1999
@@ -0,0 +1,45 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GTKWHEEL_AUX_H__
+#define __GTKWHEEL_AUX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib.h>
+#include <gdk/gdk.h>
+
+gboolean gtk_wheel_event_handler (const GdkEvent *event,
+				  gpointer adj1,
+				  gpointer adj2);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GTKWHEEL_AUX_H__ */
--- gtk+-1.2.0/gtk/gtkwheel_aux.c.orig	Sat Mar 20 16:32:29 1999
+++ gtk+-1.2.0/gtk/gtkwheel_aux.c	Mon Mar 22 01:14:51 1999
@@ -0,0 +1,132 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/*
+ * This file contains auxiliary stuff for wheel mice. I had no better idea
+ * where to put this.
+ *
+ * Nils
+ */
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include "gtkadjustment.h"
+#include "gtkrange.h"
+#include "gtkspinbutton.h"
+#include "gtkwheel_aux.h"
+
+/**************************************************************************
+ * gtk_wheel_event_handler:
+ *     Dispatch wheel mouse events GtkObjects which are or contain a
+ *     GtkAdjustment object.
+ *     Currently these types are handled:
+ *     - GtkAdjustment -- GtkProgress and derivatives (GtkProgressBar) are
+ *       ignored unless someone has good arguments against it.
+ *     - GtkRange and derivatives (GtkScale, GtkScrollbar)
+ *     - GtkSpinButton
+ *   arguments:
+ *     event: a pointer to a GdkEvent structure, won't be modified
+ *     adj1,adj2: a gpointer (we strongly recommend that this points to an
+ *                object of the types mentioned above, the type should be
+ *                detected automatically), adj2 is used as an alternative
+ *                if adj1 == NULL or not visible or if
+ *                gdk_std_modifier_mask is set in the event (and vice versa)
+ *   results:
+ *     TRUE if a wheel event was caught and handled
+ *     FALSE if no wheel event was present or an error occurred
+ **************************************************************************/ 
+gboolean gtk_wheel_event_handler (const GdkEvent *event,
+				  gpointer adj1,
+				  gpointer adj2)
+{
+  GdkEventButton bevent;
+  GtkAdjustment *adj;
+  gfloat new_value;
+
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  /* g_return_val_if_fail (adj1 != NULL, FALSE); */
+  /* No: we might be handling a scrolledwin, where NULL is legal for adj1: */
+  if (adj1 == NULL)
+    return FALSE;
+
+  g_return_val_if_fail (GTK_IS_ADJUSTMENT (adj1) ||
+			GTK_IS_RANGE (adj1) ||
+			GTK_IS_SPIN_BUTTON (adj1),
+			FALSE);
+
+  if (adj2) {
+    g_return_val_if_fail (GTK_IS_ADJUSTMENT (adj2) ||
+			  GTK_IS_RANGE (adj2) ||
+			  GTK_IS_SPIN_BUTTON (adj2),
+			  FALSE);
+  }
+
+  switch (event->type) {
+  case GDK_BUTTON_PRESS:
+  case GDK_2BUTTON_PRESS:
+  case GDK_3BUTTON_PRESS:
+    bevent = event->button;
+
+    adj = (GtkAdjustment *) adj1;
+
+    if (adj2) {
+      if (bevent.state & gdk_std_modifier_mask) {
+        if (GTK_IS_WIDGET (adj2) && GTK_WIDGET_VISIBLE (adj2))
+          adj = (GtkAdjustment *) adj2;
+      } else {
+        if (GTK_IS_WIDGET (adj1) && (! GTK_WIDGET_VISIBLE (adj1)))
+          adj = (GtkAdjustment *) adj2;
+      }
+    }
+
+    if (GTK_IS_WIDGET (adj) && (! GTK_WIDGET_VISIBLE(adj))) {
+      return TRUE;     /* we tried our best */
+    }
+
+    if (GTK_IS_RANGE (adj)) {
+      adj = GTK_RANGE (adj)->adjustment;
+    } else if (GTK_IS_SPIN_BUTTON (adj)) {
+      adj = GTK_SPIN_BUTTON (adj)->adjustment;
+    }
+
+    if ((bevent.button == 4) || (bevent.button == 5)) {
+      if (event->type == GDK_BUTTON_PRESS) {
+	new_value = adj->value + ((bevent.button == 4) ?
+				  -adj->page_increment / 2:
+				  adj->page_increment / 2);
+	new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
+
+	gtk_adjustment_set_value (adj, new_value);
+      }
+
+      return TRUE;
+    }
+
+  default:
+    return FALSE;
+  }
+}
--- gtk+-1.2.0/gtk/Makefile.am.orig	Wed Feb 24 23:04:00 1999
+++ gtk+-1.2.0/gtk/Makefile.am	Mon Mar 22 00:12:31 1999
@@ -108,6 +108,7 @@
 	gtkvscale.c		\
 	gtkvscrollbar.c		\
 	gtkvseparator.c		\
+	gtkwheel_aux.c		\
 	gtkwidget.c		\
 	gtkwindow.c		\
 	fnmatch.c		\
@@ -226,6 +227,7 @@
 	gtkvscale.h		\
 	gtkvscrollbar.h		\
 	gtkvseparator.h		\
+	gtkwheel_aux.h
 	gtkwidget.h		\
 	gtkwindow.h
 
--- gtk+-1.2.0/ChangeLog.orig	Thu Feb 25 21:10:03 1999
+++ gtk+-1.2.0/ChangeLog	Mon Mar 22 01:18:18 1999
@@ -1,3 +1,11 @@
+Mon Mar 22 01:16:11 CET 1999  Nils Philippsen  <nils@fht-esslingen.de>
+
+	* gdk/gdkglobals.c, gdk/gdk.h: added gdk_std_modifier_mask, defaults
+	  to Alt/Meta (Mod1)
+	* gtk/gtkwheel_aux.[ch] (gtk_wheel_event_handler): added to handle
+	  events by wheel mice
+	* gtk/gtkmain.c (gtk_main_do_event): Use gtk_wheel_event_handler 
+
 Wed Feb 24 05:27:44 CST 1999 Shawn T. Amundson <amundson@gtk.org>
 
 	* Released GTK+ 1.2.0


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