Details on gtk+XInput plans




At the risk of getting ahead of the game, I'm planning on going
ahead and adding XInput support to gtk. There will probably be
some work later to merge this into a real release of gtk, but
it should be manageable. (I would be surprised if the basic parts
gtk changed much before the release of v1.0 of the GIMP.)

So with that in mind, here is a description of what I intend to
do: (this sort of assumes you've been following earlier discussion,
and have a little knowledge of XInput.) Sorry if parts of this
are completely coherent - I'll try to answer any questions when
I'm more awake.

Portions of this are based on Raph Levien's mail on the same subject
from a few weeks ago.  Comments in brackets are generally places where
I would appreciate further input. Comments about other parts of this
outline are also welcome.  The function names in here are still
tentative.

Thanks,
                                        Owen

Overview
--------

1. Support for XInput management will be added directly to gdk/gtk
itself. (I've been convinced that this will encourage more use
of the support than putting it in a separate layer like gsumi
does currently, and it isn't really any harder to implement this way.)

Three different compilation options will be supported:

1) No XInput support
2) Core pointer / XInput event sharing using the features present
   in XFree86 3.3 and later.
3) Core pointer / XInput switching via an external daemon. (as is
   done in gsumi 0.3)

Note that for 3), the application has to draw its own cursor, which
means extra complexity to add the support to the GIMP, and would
effectively prevent input-enhanced widgets. The same restriction
applies to using devices in window mapped mode.

[ I don't have a very high estimation of the utility of either gxid
switching or window mapped mode in the Wacom/XFree86 world that we all
seem to be inhabiting, but I think keeping the support flexible is
important. ]

The choice between the options will be done via a table of function
pointers. This will prevent a forest of #ifdef's, without a
significant speed hit. (Most of the differences here are in setup, not
in event processesing).

[ It wouldn't be too hard to make the choice between #2 and #3
at runtime, but it would add application complexity, and I can't
imagine any case in which this would be useful. ]

2. The following assumptions will be made about all supported
devices:

  a. The only input classes of interest are valuators and buttons.
  b. The valuators of interest are a subset of the following
     * X axis
     * Y axis
     * X-tilt
     * Y-tilt
     * pressure

(Effectively, we only support devices that could, at least
theoretically, be controlling the pointer.)

Interface
---------

* Event handling

The GdkEventMotion and GdkEventButton structures will have the
following fields (in addition to other fields unaffected by
the XInput changes)

  gdouble x;
  gdouble y;
  gdouble pressure;
  gdouble xtilt;
  gdouble ytilt;
  GdkInputSource source;
  guint32 deviceid;

where we have

typedef enum
{
  GDK_SOURCE_MOUSE,
  GDK_SOURCE_PEN,
  GDK_SOURCE_ERASER,
  GDK_SOURCE_CURSOR
} GdkInputSource;

(The source field identifies the type of input source in a generic way
- the indentification is modifiable by the user/application.  The
device field uniquely specifies the device. Applications may need
either type of information. [ Should applications just remember the
source from the deviceid? ] For example, an erasable Text widget would
only care whether a device is an ERASER or otherwise, but if there
were two ERASER devices, the GIMP should allow a different tool for
each eraser.)

[ It would be possible here to add separate gtk signals for  different
  sources (to allow connecting to different devices separately)
  but since gtk wasn't really designed with dynamically created event 
  types in mind, this would either involve some trickery or a mess
  of predefined signals. On the other hand, it would avoid having
  the application have to do event dispatching in the handler routine.
  It wouldn't be useful in the case of a program like gsumi or the
  GIMP, which has to support an arbitrary number of separate devices ]

The application needs to specifically request extension events on each
window where they are desired. (This is a performance thing - most
windows in an application won't need them these events.) This is done
by calling the function

void gdk_input_set_extension_events(GdkWindow *window, gint allow_events);

with allow_events set to TRUE

* Bookkeeping:

There will be a standard dialog to allow the user to set up
XInput devices. The information about device set will be stored
in a configuration file (.gtkxirc)

[ details here need to be finalized ]

For applications that want to control the setup themselves, the
following functions will be available:

GList *gdk_input_list_devices();

typedef struct _GdkDeviceInfo {
   guint32 deviceid;
   gchar *name;
   GdkInputSource source;
   GdkInputMode mode;
   gint has_cursor;	/* TRUE if the X pointer follows device motion */
   gint num_axes;
   gint num_buttons;
   GdkAxisUse *axes;    /* Specifies use for each axis */
   gint *buttons;       /* Specifies mapping into logical buttons */
}

[ I'm not sure there really is a need for this layer of button
  mapping - it might be handy but there are already provisions for
  button remapping in XInput. ]

typedef enum {
   GDK_MODE_DISABLED;
   GDK_MODE_SCREEN;
   GDK_MODE_WINDOW;
} GdkInputMode;

typedef enum {
   GDK_AXIS_X;
   GDK_AXIS_Y;
   GDK_AXIS_PRESSURE;
   GDK_AXIS_XTILT;
   GDK_AXIS_YTILT;
} GdkAxisUse;

void gdk_input_set_source(GdkInputSource source)
void gdk_input_set_mode(GdkInputMode mode);
void gdk_input_set_mapping(GdkAxisUse *axes, gint *buttons);

[ The exact details here need finalization as well.

Do we need to provide an interface to:

  * Relative/Absolute mode?
  * Axis min/max/resolution?

 ]

* Motion History

GdkDeviceTimeCoord *gdk_input_motion_events(guint32 deviceid,
		  			   guint32 start,
					   guint32 stop,
					   gint *nevents_return);

typedef struct GdkDeviceTimeCoord_ {
   guint32 time;
   gdouble x;
   gdouble y;
   gdouble pressure;
   gdouble xtilt;
   gdouble ytilt;
}

Outlook
-------

This framework should be sufficient to handle any sort of tablet, and
most other devices that would naturally control a 2-D pointer. It is
not general enough to allow, for instance, use of a spaceball in a 3-D
modelling program, but this degree of flexibility is not, in my
opinion, compatible with achieving a high degree of transparency for
normal applications. For specialized applications, it will still be
possible for gtk-based applications to handle XInput events
directly. The above changes should be almost transparent to
applications that don't care about pressure and tilt.



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