
This file  is a formal description  of the `general  pointer protocol'
implemented by the  kmouse module.  The various  `TODO' notes refer to
the 0.47 version of the module itself.

Other features implemented in  the module (those   not related to  the
protocol, such as  /dev/gpmctl and  the  mouseconfig utility) are  not
described here.


	Rationale
        =========

The basic idea is that applications want to retrieve sound information
from pointing   devices, and don't want   to care with   the different
pointer protocols. The first approach to this has been "gpm", but such
solution features some  bad limits: mainly   a poor performance  and a
limited number of supported buttons/dimensions.

New pointing devices  (pens, tablets and  3D devices) demand for a new
generalized protocol. If X supports this protocol, a few lines of code
will suffice to use any pointing device  with X -- the problem applies
for example to some laptops equipped with a  custom pointing pen: it's
much easier to load a kernel module than changing the whole server.


	The device
	==========

The device is called "/dev/kpointer".  Reading the device returns data
packets. The data structure being used is  described below (``The Data
Structure''). A program  can write to the device  node in order to set
some preferences, as described in ``Writing to The Device'', below.

The  kernel   pointer  is  configured  once  for   all, at  boot time.
Applications  using the  device don't  need  to  set any configuration
value,  only  preferences regarding how  to   report events.  How such
configuration is performed is not described in this document.

TODO: writing doesn't work, currently.


	The Data Structure
	==================

Pointer events are returned in the following data structure:

  typedef struct Kmouse_Packet {
      __u16 magic;    /* two bytes in local-endian */
      __u16 flags;    /* the #buttons, #dim etc. */
      __u16 buttons;  /* up to 16 buttons available */
      __u16 shift;    /* the keyboard modifiers (kbd.h) */
      __s32 x;
      __s32 y;
      __s32 z[0];     /* extra coordinates */
  } Kmouse_Packet;

Data transfer is  only accomplished in  multiples of 4 bytes, and  the
device returns  data   in native-endian    mode.  This  should   avoid
unnecessary conditionals and  byte-swapping. The first longword  tells
how many dimensions  are supported, so   the application can  read the
rest of the packet once it knows how  many dimensions are there.  Each
field is described below in more detail.


	The Magic Number
	----------------

Since packet data  is generated by the kernel  instead of an  external
device, the  possibility    to  loose  track of   the  data  flow   is
theoretically 0. The     module atomically stores  each  data   in the
application's queue, so two applications can't contend for mouse data.

The magic number  is thus an  extra gadget, and no  attempt is made to
avoid the magic number from appearing in the middle of a packet. Since
the  probabilities are 1/64K,   should  an application ever  loose the
packet boundary, it will resync anyways.

The real feature  of the magic number (thanks  to Janos Farkas) is its
being   a  16-bit entity.   If    pointer data  is transferred  across
computers, one can look at the magic number  to tell if the source and
target   architecture feature a   different    endianity. As far    as
applications read /dev/kpointer, anyways,   they can be  assured about
native-endianity of the data packet.

The following inline functions are defined in "kmouse.h":

  #define KMOUSE_MAGIC         0xf00f
  #define KMOUSE_SWAPPED_MAGIC 0x0ff0
  int kmouse_packet_p(void *ptr);
  int kmouse_swapped_packet_p(void *ptr);

They return  true (non-0) if data  pointed by "ptr" features the right
magic number (native  or swapped), and return  fales (0) if  not.  The
inline functions will be turned to preprocessor macros if the protocol
is exported to non-gcc platform.


	The Flags
	---------

The  `flags' field  tells the   number of  dimensions,   the number of
buttons, and  other information.  The   following inline functions are
used to decode the flags;  alternatively you can  look in kmouse.h and
use the bitfields.

int kmouse_nr_buttons (Kmouse_Packet *p);
	This function returns  a value within  1 and  16. Zero buttons
	are not supported: if  a pointer has  zero buttons it  reports
	one, which will never be pressed.

int kmouse_nr_dimensions (Kmouse_Packet *p);
	Returns  a value within  2 and  15.  The dimensions appear  as
	fields x,  y, and z[].  The size  of the packet depends on the
	number of dimensions.  See  ``Handling Many Dimensions'' below
	for problems related to many dimensions.

int kmouse_sizeof(Kmouse_Packet *p);
	The function  looks at the  `flags' field and returns the size
	of the packet. Useful to read the rest  of it after retrieving
	the first doubleword (magic and flags).

int kmouse_absolute_p(Kmouse_Packet *p);
	If true, the packet has absolute coordinates.

int kmouse_special_p(Kmouse_Packet *p);
	If true, the   packet is  a special  packet.  Data  should  be
	discarded by applications looking   for events  only.  Special
	packets are   designed to  implement  future expansion without
	breaking existing applications.

int kmouse_z_pressure_p(Kmouse_Pachet *p);
	If true, the   zed coordinate represents pressure  (useful for
	drawing tablets). An application can thus  know how to use the
	Z information.  TODO: is this the best way to handle pressure?


	The Buttons
	-----------

The field `buttons' is a bit field. Bits are assigned in the
following order:

	0x0004  button 1      (left)     KMOUSE_B_LEFT
	0x0001  button 2 (3)  (right)    KMOUSE_B_RIGHT
	0x0002  button - (2)  (middle)   KMOUSE_B_MIDDLE
	0x0008  button 4
	0x0010  button 5
	 ...
	0x8000  button 16

The  quirk with the second/third button   reflects the normal practice
with mice:  The second button is  considered  the third when  three of
them are there.

This way to number buttons  returns the usual  bit field for the first
three buttons, while extra  buttons are allocated  orderly from LSB to
MSB.


	The Shift State
	---------------

The `shift' field represents the modifier  keys that were pressed when
the event was reported. Should the keyboard  and mouse data streams be
out of sync  due to high machine load,  it's nonetheless important  to
tell "shift-mouse" events   from "mouse-only" ones.  The bitvalues  in
this field are those defined in <linux/keyboard.h>.


	Absolute and Relative Pointers
	------------------------------

Absolute  positions   (like those  reported by    pens or tablets) are
normalized  in the range  0 .. (1<<30 - 1).  Values outside this range
are   used  to represent    out-of-screen  coordinates.   The decoding
application  knows  if the  device is  absolute  or  relative from the
"flags"  field.

The choice  to use 30 significant  bit is meant  to avoid changing the
protocol in  the future: no  absolute pointer is extexted  to digitize
more than one billion pixels in the foreseeable future.

A relative pointer (like mice) just reports its  data as signed valued
in the x,y and z[] fields.

Conversion between absolute and relative messaging is performed by the
module  on request   of   the  application.  See  below  under  ``Data
Conversion''.

TODO: the application can't specify absolute or relative, yet.


	Special Packets
	===============

A packet with the `special' bit set should  be ignored by applications
not  prepared  to deal  with it.  The `number  of dimensions' field is
nonetheless useable to  determine the packet  size. In other words, an
application can issue `kmouse_sizeof()' to know how much data to skip.

Special packets will be  used to report new events  that won't fit  in
the button/dimension abstraction.


	Handling Many Dimensions
	========================

Currently  the number of  dimensions and buttons supported is limited.
If the need arise for more dimensions, a  `special packet' can be used
to return `continuation data' to   integrate information in the   base
packet. 


	Multiple Pointer Devices
	========================

TODO: Currently only the first device is supported

Multiple `kpointer' devices are supported, all of them speak the same
protocol.

The association between physical input devices  and the kernel pointer
is specified by the system administrator. Several physical devices can
feed the same kernel pointer (this  allows using the trackball and the
mouse independently by reporting their events  through the same kernel
pointer).

The first  device ("/dev/kpointer") is   meant to be  the main  system
pointer, and is bound to the system  VC scheme: applications accessing
the device will  only be reported events that  are generated  in their
controlling tty (just like reading  stdin).  This means that a program
running on a Linux VC  can read /dev/kpointer without interfering with
other consoles.

The  second and third  devices are useable  by every program (although
two users can't access the same device  at the same time). This policy
is meant  to devote a  digitizing tablet  to  a single  program, while
being able to use a conventional mouse as main system pointer.


	Data Clustering
	===============

The kpointer devices cluster events by  default: if a new motion event
is  reported before a  client applicatin  reads  the previous one, the
events are clustered to a single event. This doesn't happen for button
press/release events. Event clustering can  greatly contribute to  the
system's responsiveness under load conditions.

If an application needs the complete history  of motion events, it can
instruct the device to disable clustering (see below: ``Writing to the
Device'').


	Data Conversion
	===============

TODO: Currently applications can't choose the data format, although
TODO: the module is able to convert data.

Physical  pointing devices    report either  absolute or   incermental
(relative) positions (those that report both  report either one or the
other). Each application, however, has some preferences about motion
reporting.

The  kpointer device by default reports  events in  the form they come
from  the physical  device:  mice report  incremental positions  while
digitizing  surfaces  report  absolute    positions.  The driver    is
nonetheless able to convert events between the two forms. Applications
are therefore allowed to require  either absolute, relative or  native
(the default) reporting.

In  order to  convert event  between the two   data formats, a scaling
factor is  needed; this parameter is the  number of  incremental steps
that build up to the  complete range of  absolute values. The array of
scaling  factors is defined  by   system administrator,  and the  last
specified value will apply for every additional dimension. The default
values in the module are 1024 for X, 768 for Y and 128 for every other
dimension.

A conversion factor of 1024 means that if an absolute device reports a
movement  spanning  the whole range  of X  values, this corresponds to
1024 incremental steps. On the other side, 1024 incremental steps will
span the complete  range of absolute  reporting. Increasing the number
results in  a `slower' mouse  and a `faster' tablet,  while decreasing
the conversion factor leads to a faster mouse and a slower tablet.


	Writing to the Device
	=====================

TODO: writing ins't yet implemented. I didn't think of the best form
TODO: to define commands, so they're not listed here.

A client application can `configure' the device  being read by writing
command strings to the device.  Configuration commands are used to ask
for relative/absolute/native  event   reporting, as well  as   to turn
on/off data clustering. An  application can also  ask the  nature (the
software protocol or hardware name) of  the physical device(s) driving
the kernel pointer. Such generic features will be reported as `special
packets' and can be useful to exploit `Device Specific Extensions'.

Unrecognized command  strings   return "EINVAL" as  error  code, while
extra  blank  space, newlines  and semicolons   are silently accepted.
Applications  using configuration commands  should  check  the  return
value of write()  to know if their  command has been  accepted or not.
Needless to say, old modules will refuse to accept commands introduced
in more recent revisions of the protocol.


	Device Specific Extensions
	==========================

TODO: This is not implemented.

An application reading the kernel pointer can retrieve device-specific
information by issuing a device-specific ioctl. Device-specfic data is
not transmitted through the data  stream but is returned atomically by
the ioctl call.

Whenever a pointer device has too much information to return, encoding
them in the normal packet is not worth the effort because huge amounts
of information can  only be proficiently used  by software that  knows
the exact nature of the extra dimensions (the problem doesn't apply to
buttons,   because  all the  buttons   are  alike,  and  programs  can
arbitrarily  assign  meaning to the  buttons,  like every program does
with function keys).

Device  specific data will only  be  retrieved by applications able to
deal  with the particular  device (the nature  of the hardware pointer
can be always  queried by a client appliation:  see above ``Writing to
the Device'').


	Compatibility Issues
	====================

The main system pointer (/dev/kpointer) can also be read as either MSC
packets   (/dev/kmouse)  or     GPM   events   (/dev/gpmctl).    These
backward-compatible devices are VC-aware,  like /dev/kpointer. The MSC
device  can be used  by any program able  to decode standard mice (for
example X, svgalib, dosemu), while the GPM node is compatible with any
program linked with libgpm version 1.0 or later.


	
Best regards
/alessandro
--
    __ o La forza dei forti sta nel traversare le traversie con occhio sereno
   _`\<,                                                        (Paperino)
__( )/( )__     alessandro.rubini@linux.it  +39-382-529554
