   This file is a user's and programmer's manual for gpm 1.10.

   Copyright (C) 1994,1995 Alessandro Rubini

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Free Software Foundation.

   This file documents the 1.10 release of the "General Purpose Mouse"
(gpm) server for the Linux text console (July 1996).

gpm-Linux
*********

Overview
********

   The "gpm" package is a mouse server for the Linux console.  It is
meant to provide cooked mouse events to text-only applications, such as
editors and simple menu-based apps. Its roots come from the
`selection-1.5' package, by Andrew Haylett.

   The first application to support the mouse has been "The Midnite
Commander", by Miguel de Icaza.  `mc-0.11' and later releases offer
mouse support if you have the mouse server running on your system.  The
file `t-mouse.el' provides support for using the mouse from within
Emacs. See Emacs Support

   As of release 0.96, a default-handler is released with gpm, and can
be used to handle Control-Mouse events to draw menus on the screen.
The gpm-root program, however, needs kernel 1.1.73 or newer.  See
gpm-root

   Release 1.00 is an incompatible one (is is incompatible with releases
older than 0.97), but is compatible with a future kernel-level mouse
driver. With 1.0 the high level library is availabel, together with a
demonstration/test program. A small utility to help in detecting your
mouse-type is also included.

Compiling and Installing
========================

   Just say `make && make install' to your shell. You'll need gpm
installed to compile the latest release of `The Mouseless Commander'
with mouse support enabled.

   Binaries are no more released with the package, mainly because my
compiler and libraries are quite old, so it's safer for you to compile
the package by yourself.

   If you're reinstalling the package on top of Slackware 2.1 or newer,
meke sure to overwrite or remove the old gpm. The location of gpm
within Slackware is `/usr/bin'. This is the main reason why the default
PREFIX in Makefile is now /usr and not /usr/local.

Server Invocation
*****************

   The `gpm' executable is meant to act like a daemon (thus, gpmd would
be a better name for it), in just the same way as `selection' used to.
This section is meant to describe the command-line options for `gpm',
while its internals are outlined in the next section.  See Gpm Internals.

   Due to restrictions in the ioctl(TIOCLINUX) system call, gpm must be
run by the superuser. The restrictions have been added in the last 1.1
kernels to fix a security hole related to selection and screen dumping.

   The server can be configured to match the user's taste, and any
application using the mouse will inherit the server's attitude.
Beginning from release 1.2, the mouse `feeling' can be reconfigured by
each user logging on the system console. See the description of "-q"
Server Invocation.

   No user-wide configuration file is provided, because the mouse is a
machine-wide resource. If you feel that different users on a Linux
machine could benefit from personal mouse setup at login, feel free to
email me, and I'll look about it. As of this release, only the
`inword()' look up table can be changed without restarting the server
(but to be able to do it, you have to install gpm with the
"set-user-id" bit turned on).

   As of 0.97 the server program puts itself in the background. To kill
gpm you can just reinvoke it with the -k cmdline switch.

Special Commands
================

   Version 1.10 adds the capability to execute special commands on
certain circumstances. Special commands default to rebooting and halting
the system, but the user can specify his/her personal choice. The
capability to invoke commands using the mouse is a handy one for
programmers, because it allows to issue a clean shutdown when the
keyboard is locked and no network is available to restore the system to
a sane state.

   Special commands are toggled by triple-clicking the left and right
button - an unlikely event during normal mouse usage. The easiest way
to triple-click is pressing one of the buttons and triple-click the
other one. When special processing is toggled, a message appears on the
console (and the speaker beeps twice, if you have a speaker); if the
user releases all the buttons and presses one of them again within
three seconds, then the special command corresponding to the button is
executed.

   The default special commands are:

LEFT BUTTON
     Reboot the system by signalling the init process

MIDDLE BUTTON (IF ANY)
     Execute `/sbin/shutdown -h now'

RIGHT BUTTON
     Execute `/sbin/shutdown -r now'

   The -S commandline switch enables special command processing and
allows to change the three special commands. To accept the default
commands use `-S ""' (i.e., specify an empty argument).  To specify
your own commands, use a colon-separated list to specify commands
associated to the left, middle and right button. If any of the commands
is empty, it is interpreted as `send a signal to the init process'. This
particular operation is supported, in addition to executing external
commands, because sometimes bad bugs put the system to the impossibility
to fork; in these rare case the programmer should be able to shutdown
the system anyways, and killing init from a running process is the only
way to do it.

   As an example, `-S ":telinit s:/sbin/halt"', associates killing init
to the left button, going single user to the middle one, and halting
the system to the right button.

   System administrators should obviously be careful about special
commands, as gpm runs with superuser permissions. Special commands are
best suited for computers whose mouse can be physically accessed only by
trusted people.

Command Line Options
====================

   Available command line options are the following:

`-a ACCEL'
     Set the acceleration.

`-b BAUD'
     Set the baud rate.

`-B SEQUENCE'
     Set the button sequence. "123" is the normal sequence, "321" can
     be used by left-handed people, and "132" can be useful with
     two-button mice (especially within Emacs). All the button
     permutations are allowable.

`-d DELTA'
     Set the delta value. When a single motion event is longer than
     DELTA, ACCEL is used as a multiplying factor.

`-D'
     Dirty operation (debug only). It causes gpm to kill an already
     running gpm, if any. The default behaviour is to not kill it.
     See Bugs and Problems.

`-g NUMBER'
     With glidepoint devices, emulate the specified button with tapping.
     nUMBER must be 1, 2, or 3, and refers to the button number before
     the -B button remapping is performed.  This option applies to the
     mman and ps2 decoding. No button is emulated by default because
     the ps2 tapping is incompatible with some normal ps2 mice

`-h'
     Print a summary of command line options.

`-i INTERVAL'
     Set INTERVAL to be used as an upper time limit for multiple
     clicks. If the interval between button-up and button-down events
     is less than LIMIT, the press is considered a double or triple
     click. Time is in milliseconds.

`-k'
     Kill a running gpm. This can be used by busmouse users to kill gpm
     before running X (unless they use -R or the single-open limitation
     is removed from the kernel).

`-K'
     Run kernel-mouse. /dev/kmouse is configured according to the other
     command line options, and the gpm functionality is run in kernel
     space. This requires the kmouse module, currently available from
     tsx-11.mit.edu. This is experimental.

`-l CHARSET'
     Choose the `inword()' look up table. The CHARSET argument is a
     list of characters. `-' is used to specify a range and `\' is used
     to escape the next character or to provide octal codes.  Only
     visible character can appear in CHARSET because control characters
     can't appear in text-mode video memory, whence selection is cut.

`-L CHARSET'
     Modify the  `inword()' look up table. This option is obsolete and
     will be dropped soon. Use "-q -l" instead.

`-m FILENAME'
     Choose the mouse file to open. It defaults to `/dev/mouse'.

`-M'
     Enable multiple mode. The daemon will read two different mouse
     devices.  Any subsequent option will refer to the second device,
     while any preceding option will be used for the first device. This
     option automatically forces the "repeater" (-R) option on.

`-o LINES'
     Toggle modem lines. The LINES argument can be "dtr", "rts" or
     "both". This is needed for some strange serial mice.

`-p'
     Forces the pointer to be visible while selecting. This is the
     behaviour of selection-1.7, but it is sometimes confusing.  The
     default is not to show the pointer, which can be confusing as well.

`-q'
     Quit after changing mouse behaviour. This is intended to allow
     users to change the mouse "feeling" (-a, -B, -d, -i, -l, -p, -r)
     without restarting the server. Since this needs root permissions,
     the system administrators can use the `set-uid' bits to
     enable/disable such capability. Changing mouse parameters is
     nonetheless only allowed from one of the virtual consoles. Options
     are transferred only for the first mouse.

`-r NUMBER'
     Set the responsiveness. A higher responsiveness is used for a
     faster cursor motion.

`-R'
     Causes gpm to act as a repeater: any mouse data received while in
     graphic mode will be produced on the fifo `/dev/gpmdata' in
     mouse-system protocol. This means that you can configure the X
     server to use that fifo as a mouse device. This option is useful
     for bus-mouse owners to override the single-open limitation. It is
     also an easy way to manage those stupid dual-mode mice which force
     you to keep the middle button down while changing video mode. The
     option is forced on by the -M option.

`-s NUMBER'
     Set the sample rate for the mouse device.

`-S COMMANDS'
     Enable special-command processing, and optionally specify custom
     commands as a colon-separated list. See above for a detailed
     description of special commands.

`-t NAME'
     Set the mouse type. Use `-t help' to get a list of allowable
     types. See Mouse Types.

`-v'
     Print version information and exit.

`-2'
     Force two buttons. This means that the middle button, if any, will
     be taken as it was the right one.

`-3'
     Force three buttons. By default the mouse is considered to be a
     2-buttons one, until the middle button is pressed. If three
     buttons are there, the right one is used to extend the selection,
     and the middle one is used to paste it.  Beware: if you use the
     `-3' option with a 2-buttons mouse, you won't be able to paste the
     selection.

Bugs and Problems
=================

   The `gpm' server may have problems interacting with X, and with
`selection'.

   With X11 `gpm' has the same problems as `selection'. If your mouse
is a single-open device (i.e. a bus mouse), you should kill `gpm'
before strating X, or use the "-R" option (see above).  To kill gpm
just invoke gpm -k. This doesn't apply to serial mice.

   gpm and selection can't run together, because they will contend the
mouse. They can control two mice independently, however.

   Two instances of gpm can't run on the same system. If you have two
mice use the "-M" option (see above).

   While the current console is in graphic mode, gpm sleeps until text
mode is back. Thus, it won't reply to clients. Anyways, it is unlikely
that mouse-eager clients will spur out in hidden consoles. This is not
true if gpm acts as a repeater.

   pre-1.0 gpm releases have problems with kernel 1.2.9 and later,
because the clients must have write permission on the node
/var/run/gpmctl. You should invoke chmod on the node or install gpm-1.0
or later (you have this docs, you have the software).

Gpm Internals
*************

   The server is organized as a main loop built around a `select()'
system call. It responds both to mouse events and to input from the
clients, which are connected to the server through a unix domain
socket. The connection is used to tell the server what a client is
interested in, and to get mouse events.

   When no clients are connected to the active console, the server
behaves like the `selection' package by Andrew Haylett, whose code has
been the starting point for gpm.  I chose to embed selection within gpm
because this is the most straightforward approach -- people is used to
have selection running on all the virtual consoles, and my package won't
break with them. Moreover, my implementation of selection is a little
different from selection-1.6 because much of the processing is made by
the server main loop. Selection, then, is a simple and well-designed
application, whose behaviour can be cloned by clients, by telling the
server to inherit the default response for certain mouse events (MOTION
being the most interesting).

Events
======

   Whenever the mouse generates an event, it is dispatched to the active
client for the current console, or to the default handler, if present.
Otherwise selection is run. A default handler is a client process which
gets mouse events form all the virtual consoles. See Default Handlers.

   When a client is involved, it is handled a `Gpm_Event' structure,
built by the server. The fields for `Gpm_Event' are the following:

`unsigned char buttons;'
     An or-mask of the values `GPM_B_LEFT', `GPM_B_MIDDLE' and
     `GPM_B_RIGHT'. It corresponds to the state of the mouse buttons
     when the event is reported. The current implementation of gpm
     allows at most three buttons.

`unsigned char modifiers;'
     The value of the kernel variable `shift_state', as of
     `keyboard.c', when the event is reported. It is a bitmask value,
     and corrsponds to the least significant byte of the value used by
     the `loadkeys' program. Use of symbolic names in source code is
     available after inclusion of `<linux/keyboard.h>', as exemplified
     in `mev.c'.

`unsigned short vc;'
     The number of the active virtual console when the event is
     reported. The client is not expected to use this value, which
     corresponds to the controlling terminal of the client process,
     unless it gets events form multiple consoles. See Default Handlers.

`short x, y;'
     The position of the mouse pointer where the event is reported. Is
     is 1-based, to be compatible with `selection' and `libcurses'.

`short dx, dy;'
     The change in position since the last reported event.

`enum Gpm_Etype type;'
     A bit-mask, representing the type of reported event, as described
     later. See Event Types

`int clicks;'
     A counter, which is valid at button-down, drag or button-up. It
     can be 0, 1 or 2 to mean single, double or triple click.

`enum Gpm_Margin margin;'
     A bit-mask, telling if the pointer has gone out of the visible
     screen. The indivudual bits are named `GPM_TOP', `GPM_BOT',
     `GPM_LFT', `GPM_RGT'. Only one of them is active at a time, to
     allow using `switch' on the value. Vertical outrun takes
     precedence on horizontal outrun.  See Margins

How margins are managed
=======================

   Motion and button-press events are constrained to remain within the
visible screen. This means that the `x' will be within 1 and 80 and `y'
will be within 1 and 25 when the console is 80x25 cells. However, a
client can keep track of movements outside the screen, by using the
`dx' and `dy' fields, which aren't subject to clipping.

   The server helps applications in detecting margin conditions by
filling the `margin' field. Whenever the pointer tries to cross screen
boundaries, it is forced to remain on the border, but a flag is set in
`margin'.

   A different policy is in force for drag and button-release events.
In this case the pointer is allowed to go outside the physical screen
by exactly one position. This allows, for example, selecting to end of
line by dragging down-left. The peculiar situation is nonetheless
signaled through the `margin' flags. The client should be careful to
fit the values within the screen if needed. See Utility Functions.

Event Types
===========

   The `type' field int Gpm_Event is made up of bit-wide flags. The
existing bit masks belong to two groups: bare events and cooked events.
The bit-mask `GPM_BARE_EVENTS' is provided to extract bare events, by
and-ing ('&') it with the type field.  For any event, exactly one bit
will be set in the resulting bitmask.

   Bare events are the following:

`GPM_MOVE'
     A motion event, with all buttons up.

`GPM_DRAG'
     A motion event, but one or more buttons are kept pressed.

`GPM_DOWN'
     A button press event. The buttons field will report which buttons
     are pressed after the event.

`GPM_UP'
     A button release event. The buttons field will report which
     buttons are being released. Nothe that this is different from the
     previous case.

`GPM_ENTER'
     This means "enter in the current Region of Interest", and such
     event can only happen if the high-level library is used.  When the
     type is GPM_ENTER, all the other fields are undefined.  See High Level Lib.

`GPM_LEAVE'
     This is only delivered by the high level library, too. Events of
     type GPM_LEAVE have all other fields undefined.

   Cooked events are the following:

`GPM_SINGLE'
     This bit may be set at button-press, drag and button release
     events, and can be used to identify a single press. The time
     interval used to choose a double click from two single clicks is
     set by a parameter in the daemon (configurable at daemon
     invocation).

`GPM_DOUBLE'
     Used to identify a double click (press, drag, release)

`GPM_TRIPLE'
     Used to identify a triple click (press, drag, release)

`GPM_MFLAG'
     The "motion flag" is true if some dragging happened between
     button-press and button-release. It can be used by those
     applications which respond to events at button release.  It is
     available at drag and release.

Mouse Types
===========

   I chose to isolate anything related to mouse types, because I can't
test them all. The source file `mice.c' is made up of type-specific
functions, as well as a table to dispatch computation. The table offers
a default device name for each mouse type as well, but I lack
information about some of them.  Contributions in this field are
particularly welcome.

   The mouse type is specified on command line with the "-t" option.
The option takes an argument, which can be one of the following strings
(two different strings are available sometimes: one is the old
selection-compatible name, the other is the XFree name)

`bare Microsoft'
     The microsoft protocol, without any extension. It only reports two
     buttons. If your device has three, you shoudl either try toggling
     the DTR and RTS lines ("-o" option) or invoke gpm with "-t msc"
     while keeping the middle button down. Silly, isn't it?

`ms'
     This is the original microsoft protocol, with a middle-button
     extension.  Some old two-button devices send some spurious
     packets, which can be misunderstood as middle-button events. If
     this is your case, use the bare mouse type.

`msc MouseSystems'
     This is the standard protocol for three-button serial devices.

`mman Mouseman'
     The protocol used by the new Logitech devices.

`bm BusMouse'
     Some bus devices use this protocol, including those produced by
     Logitech.

`logi Logitech'
     This is the protocol used by old serial Logitech mice.

`ps2 PS/2'
     The protocol used by most busmice.

`mm MMSeries'
     Title says it all.

`sun'
     An old protocol, retained for compatibility.

Connection Details
==================

   Each virtual console has a stack of clients attached to it. They
talk to gpm by writing to a control socket and get mouse events by
reading it. Only the top-of-stack client can get events from the
server; other clients in the stack are assumed to be waiting for the
top one.  This behaviour sounds sensible, but may upset some really
demanding application. If you're going to write such application,
please call me back.

   In addition to the per-console stacks, another stack is there to
store default-handling clients. xref Default Handlers.

   Each client registers with the server and tells which events it is
interested in. Events not managed by the client can be handled by the
selection mechanism, which is compiled in the server itself. This
approach simplifies writing clients which respond only to button
press/release events, because highlighting the mouse pointer can be
performed by the server. A default handler in turn can respond only to
mouse events associated with modifier keys, so that selection is used
for any mouse-only event.

   Clients are required to fill a `Gpm_Connect' structure and pass it
to the server. The structure is made up by four `unsigned int' fields.
See Open and Close.

`eventMask'
     A bitmask of the events the client wants to receive. Both bare and
     cooked events are allowed to appear in the mask.

`defaultMask'
     A mask to tell wich events allow a default treatment (the
     selection one). These are mouse events, independent of the
     modifier keys.

`minMod'
     The minimum amount of modifiers required by the client. This field
     is used for default-handlers which manage control-mouse events
     whithout interfering with mouse-only ones. See Default Handlers.

`maxMod'
     The maximum amount of modifiers the client is willing to receive.
     Events featuring a modifier key not included in maxMod won't be
     passed to the client.

Two more fields are there to tell about the connection itself, and
you're not asked to fill them, because Gpm_Open will do it for you.

`int pid'
     The `pid' of the connecting application.

`int vc'
     Which virtual console to gain control of.

   Keyboard modifiers are used to multiplex clients on the same virtual
console. You (as a programmer) don't need to care about the internal
workings (which are detailed in ref Default Handlers), but only
need to choose the right values for your application.

   Ecamples:
`minMod=0; maxMod=0;'
     specifies a client which senses mouse-only events, but neither
     shift-mouse nor alt-mouse nor control-mouse.

`minMod=0; maxMod=~0;'
     is a client which gets any mouse event.

`minMod=1<<KG_SHIFT; maxMod=1<<KG_SHIFT;'
     is a client which senses all shift-mouse events and nothing more.

`minMod=1<<KG_SHIFT; maxMod=~0;'
     is a client interested in shift-and-whatever-else mouse events,
     but disregarding mouse-only events.

   If the modifier keys in the event are too few or too many, the event
won't be reported to the client. If the modifiers are right but the
current event is not part of the `eventMask', it is not reported as
well. If the event is not used by the client, it can nonetheless be
passed to another client (a default handler or the internal selection
mechanism), according to the `defaultMask'.  If the event has been
already reported to the current application, it will also be passed
along the chain, if the GPM_HARD bit is set the `defaultMask'.

   Good values for `defaultMask' can thus be the following:

`0'
     To sink any event, even those I don't use.

`~eventMask'
     Pass along any event I don't use.

`~GPM_HARD'
     Just the same, independently of `eventMask'.

`GPM_MOVE|GPM_HARD'
     Pass motion events, even if I use them.  This is the good choice
     for an application which wants information on mouse motion, but
     leaves the task of cursor-drawing to the server.

Default Handlers
================

   In addition to console-specific clients, gpm allows for
console-independent clients - those clients which handle events ignored
by conventional clients

   Keyboard modifiers are used to multiplex the different clients on the
same console, and a default handler should specify a non-zero minimum
modifier set.

   To summarize, events which get to the server can be delivered to the
following "clients", orderly:

   * The current client for the current console, if any.

   * The default handler, if any.

   * The builtin `selection' mechanism.

   A keyboard modifier which connected with a minMod equal to the
"Control" modifier and a maxMod of ~0 (all bits on), will then get any
event including the control key, if the application disregards it.

   This means that if the foreground application gets only the "Meta"
key, control-mouse is sufficient to invoke the default handler. If the
application gets control-mouse but disregards "Meta", conversely,
meta-control-mouse will invoke the default handler, and meta-mouse will
be delivered to selection.

   Both the minMod and maxMod fields are bitmasks, and their values are
bitwise or-ed and and-ed with the current modifier mask.

   gpm-root is an example of default handler. It gets control-mouse
events by default, and reads user-specific conficuration files in order
to draw menus on the background of your screen. See gpm-root.

The Client Library
******************

   The `libgpm.a' archive is meant to provide the mouse protocol at
different levels of abstracion. Applications linking to the gpm server
are expected to benefit from using the library, as compared to managing
the raw socket interface. Any source file using the library should
include `<gpm.h>' to get gpm specific macros and prototypes.

   Delivery of events within the library makes heavy use of the concept
of "Handling Function" (or "handler", for short).

Handling Functions
==================

   A mouse handler is a function which registers itself within the
library, and is called whenever a mouse event is reported to the
application. It is passed two arguments and returns an integer value,
according to the following typedef:

   `typedef int Gpm_Handler(Gpm_Event *EVENT, void *CLIENTDATA);'

   The `event' is used to instantiate the mouse event just received,
and the `clientdata' pointer is needed to implement some higher level
functionality. An handler will be tipically invoked by `Gpm_Getc', or
by the high-level library, and the following discussion assumes the
invoking function is `Gpm_Getc' (the high-level library only runs on
behalf of `Gpm_Getc').

   Handling functions can do whatever they want to, and return to the
caller an integer value, which can be used to generate a keyboard
event. This feature is useful in that often the mouse is a shortcut for
something which could be made by means of the keyboard.

   The application main loop can detect if the keyboard event is a
physical or generated one by looking at the global variable gpm_hflag,
which is not zero only for handler-generated events.

   An handling function can generate more than one key in response of a
single mouse event. If it sets the global variable gpm_morekeys to a
non-zero vairable before returning, it will be invoked again without
waiting for mouse events. You can use gpm_morekeys as a counter of how
many times you want to be called again - the client library only
compares it to zero.

   The return value from an handler is used as follows:

`EOF'
     This value is used to signal a fatal error, and will cause
     `Gpm_Getc' to return the same value to the caller, after setting
     `gpm_hflag' to 1.

`0'
     A zero return value means that `Gpm_Getc' should go on as before,
     without returning to the caller. The event has been eaten by the
     handler and no key-press is simulated.

`ANYTHING-ELSE'
     Any other value is considered a "simulated" character, and is
     returned to the caller after setting `gpm_hflag'.  This allows a
     quick way to implement yes/no boxes abd simple menus without
     interfering with the main body of an existing application.
     Moreover, if return values greater than 255 are used a single
     switch loop can parse both keyboard and mouse events.

A mouse handler is passed as second argument the content of the
`gpm_data' variable, i.e. the current clientdata. The clientdata is
almost unuseful unless you use the high-level library, because it holds
a static value. Delivering the clientdata however allows the high-level
management of mouse events to be a superset of the low-level code,
rather than an incompatible alternative.

Low Level Library
=================

   The library offers utility functions to establish the connection and
to get mouse events. They are designed to work painlessly if the server
is not running on the host machine. Xterm support is available as well.
See Xterm.

Global Variables
----------------

   This is the list of all the global variables present in the client
library:

`int gpm_flag'
     Initially zero, it is used to tell if the process is connected
     with a mouse server or not. It is used as a counter to manage
     multiple opens as well.

`int gpm_tried'
     A flag, used to avoid retrying a connection if the server is not
     available on the system.

`int gpm_fd'
     Initially `-1', it is the file descriptor used to talk with the
     server. If we run under xterm, it will be -2.

`int gpm_zerobased'
     Since selection and curses has always been one-based, this
     variable, zero by default, can be used to trigger zero-based
     coordinates in event reporting. It must be set before opening the
     mouse connection, and never changed later.

`int gpm_visiblepointer'
     If not zero, causes the mouse cursor to be always visible on the
     window. It is zero by default.

`gpm_mx'
`gpm_my'
     These variables are used when fitting events inside the screen.
     They are initalized by Gpm_Open, and never touched any more.  If
     your application installs a signal handler for SIGWINCH, it should
     modify these variables. I don't like my simple client library to
     installa signal handler: if the application won't resize there's
     no need to fix event allowed estate.

`int gpm_hflag'
     Used to signal if a character has been generated by a mouse
     handler. See Handling Functions

`Gpm_Handler *gpm_handler; void *gpm_data'
     Both initially `NULL', they're used to setup asynchronous mouse
     handling, as described below under the `Gpm_Getc()' item.

`gpm_morekeys'
     Used by the mouse handler to provide more than one key: if
     gpm_morekeys is not zero, `Gpm_Getc' will invoke the handler
     without waiting for events. gpm_morekeys is never set by the mouse
     library.

Connecting and Disconnecting
----------------------------

 - Function: int Gpm_Open (Gpm_Connect *CONN, int FLAG);
     Open a connection with the server. The CONN parameter points to the
     connection information for the being-created connection, as
     already described.  It is passed to the server after filling the
     `pid' and `vc' fields.

     FLAG should be `0' for normal applications, those interested in
     events related to their own console. The own console is considered
     to be the one attached to `stdin', and it must match the string
     `/dev/tty*'. A negative value for FLAG is used to make the
     invoking application a default handler Default Handlers,
     while a positive value is used to force connection to a particular
     console, either for debugging issues or whenever `stdin' is not a
     tty when `Gpm_Open' is invoked.

     Multiple opens are allowed, and a stack of `Gpm_Connect' structures
     is managed by the library. You can, thus, re-open the connection in
     order to temporarily change the range of events you're interested
     in. When you invoke an external program, for example, you should
     re-open the connection with `eventMask' zeroed, and `defaultMask',
     `minMod' and `maxMod' all equal to `~0'.

     The return value is either `-1' or the file descriptor used to
     communicate with the server. When run under xterm, a gpm client
     gets event through stdin, and the return calue for Gpm_Open() will
     be -2.  This value is always available withing gpm_fd.

 - Function: int Gpm_Close (void);
     Pops the connection stack. It is used to restore the previous
     situation after a change in the connection masks. Closes the
     actual connection when the stack gets empty. On last close it
     returns 0, -1 otherwise.

Getting Events
--------------

 - Function: int Gpm_GetEvent (Gpm_Event *EVENT);
     Reads an event form `gpm_fd'. It should be called only when the
     `gpm_fd' descriptor is reported as readable by a `select()' system
     call, or it will block until an event arrives (unless you put the
     mouse file in non-blocking mode). It returns 1 on success, -1 on
     failure, and 0 after closing the connection. Failure can happen if
     a signal interrupted the read system call. This function doesn't
     work with xterm mouse reporting and is meant for internal use by
     the library.

 - Function: int Gpm_Getc (FILE *F);
 - Function: int Gpm_Getchar (void);
     These are intended to be replacements for `getc()' and `getchar()'
     to be used by applications which are interested in the mouse.
     Their external behaviour is the same as `getc()', but a mouse
     handler gets invoked whenever an event is available. See
     Handling Functions.  A mouse handler can force `Gpm_Getc' to
     return a specific value to the caller, and the "simulated"
     character is signaled by setting `gpm_hflag' to 1.

 - Function: int Gpm_Wgetch (WINDOW *WIN);
 - Function: int Gpm_Getch (void);
     These are intended to be replacements for `wgetch()' and `getch()'
     to be used by applications which are interested in the mouse. They
     are the curses equivalent of Gpm_Getchar.

Utility Functions
-----------------

 - Function: int Gpm_Repeat (int millisecs);
     It returns 1 if no mouse events arrive in the next millicecs
     milliseconds, 0 otherwise. It is meant to be used by those handlers
     which need to repeat an action as long as the mouse button is
     pressed (while(Gpm_Repeat(200))...).

 - Function: int Gpm_DrawPointer (int X, int Y, int FD);
 - Function: int GPM_DRAWPOINTER (Gpm_Event *EPTR;)
     These are actually macros. They should be used to draw the mouse
     pointer after mangling the screen (while dragging on a menu, say),
     because letting it to the server won't work nicely, due to lack of
     synchronism between client and server. The file descriptor should
     refer to the console. The return value is 0 on success and -1 on
     failure. Gpm_DrawPointer is obsolete, and is retained only for
     compatibility.

 - Function: int Gpm_FitValuesM (int *X, int *Y, int MARGIN);
 - Function: int Gpm_FitValues (X,Y);
 - Function: Gpm_FitEvent (EPTR);
     The first is a function, while the other are macros.  Note that
     Gpm_FitEvent does not return values.  These three procedures
     should be used to fit the pointer inside the visible screen. They
     are needed for drag and release event. A connection bit will be
     available in the future to force the pointer in the visible region.

     Note that fitting uses gpm_mx and gpm_my, which you should update
     when necessary. See Variables.

Extra Functions
---------------

 - Function: char *Gpm_GetLibVersion (int *where);
     This function returns a pointer to a static storage representing
     the version number of the library. It is only available from
     0.98.2 onward, and returns a string like ""0.98.2"". The third
     number is optional, and the second number will always be reported
     as two digits; thus 1.10 is newer thayyn 1.01. The where pointer,
     if not null, is used to store a decimal number representing the
     version - 0.98.2 is 9802 and 1.1.8 is 10108.

 - Function: char *Gpm_GetServerVersion (int *where);
     This function returns a pointer to a static storage representing
     the version number of the server. The version is retrieved through
     popen(), so it could fail (and return NULL)if no gpm program is in
     the current path. Alternatively, it could fail (and return a wrong
     value) if the gpm in the path is not the currently running one.
     The function is only available in the clientlibrary version 0.98.2
     or newer, but it works with any daemon, from 0.01 onward. The
     string returned can be parsed in the same way as for
     Gpm_GetLibVersion(). A preparsed version is stored in *where if
     where is not null. Both these functions do their calculations only
     the first time they are invoked.

 - Function: int Gpm_GetSnapshot (Gpm_Event *ePtr);
     This function gives a non-blocking snapshot of the current
     situation: it returns the number of mouse buttons, as known to the
     server, or -1 if that information is not available (under Xterm,
     or before connecting).  If ePtr is not null, it is filled with
     information about the current state of the mouse. The fields have
     the following meaning: x,y: current position of the cursor; dx,dy
     size of the window; vc,modifiers the current console and the
     current shift state; buttons which buttons are currently help
     down; clicks the number of clicks (0,1,2).  This function is only
     available from 0.98.2 onward, and will return -1 if run with an
     older server.

     Since this information travels on the same file descriptor as the
     events, and applications usually don't want to lose events, the
     function returns 0 if the input queue is not empty.

High Level Library
==================

   The high level library is still part of the main libgpm.a, but it
acts at a different level of abstraction. The high level library depends
in the lowe-level one, so if you link your application with any object
of the high-level library, you're forced to link in the low-level one
too.

   If your application runs under xterm, however gpm-xterm offers all
the needed functionality.

   The main role of the high-level library is to define a way to manage
windows (or "Regions of Interest" on your text screen). The regions are
arranged in a stack, and event are delivered to the different windows
according to their position both on the stack and on the screen.  See
hltest.

Concepts
--------

   The high-level library is completely independent of the low-level
one, so it used gpm_handler and gpm_data as connection point with
Gpm_Getc().

   All the functionality is based on the concept of RoI's. each RoI is
descripted by a Gpm_Roi structure, which is made up by the following
fields:

`short xMin, xMax'
     These numbers identify the upper-left corner of the region.  When
     events are reported to the region, the event coordinate will be
     relative to this position (zero-based).

`short yMin, yMax'
     These numbers identify the lower-right corner of the region.

`unsigned short minMod, maxMod'
     These modifier masks have the same role within the application as
     the same fields have in inter-application multiplexing.

`unsigned short eventMask'
     It is the mask of events which are to be reported to the current
     region.

`unsigned short owned'
     This is a bit, used to know if the region is owned by the library
     or the application, in order to issue free(0 when needed.

`Gpm_Handler *handler'
     The function to be called when events are to be reported to the
     current region.

`void *clientdata'
     The clientdata to be passed to the handler

`Gpm_Roi *next, *prev'
     Links to the RoI chain.

Variables
---------

`Gpm_Roi *gpm_roi'
     The linked list of regions (pointer to the top one).

`Gpm_Roi *gpm_current_roi'
     The region which got the last event (used to generate enter and
     leave events).

`Gpm_Handler *gpm_roi_handler'
     This variabel is meant to be set by the user. It is the catch-all
     region of interest, which will be called for any mouse event not
     falling within any registered region. If NULL, the event will be
     discarded.

`void *gpm_roi_data'
     the client data to be passed to gpm_roi_handler.

Functions
---------

 - Function: Gpm_Roi *Gpm_PushRoi (int xmin, int ymin, int xmax, int
          ymax,
     int mask, Gpm_Handler *fun, void *xtradata);

     This function pushes a Region of Interest on top of the stack,
     after allocating it and filling with the provided values. fun is
     the function which will be called in order to handle events, and
     the roi itself will be passed to the function as clientdata. The
     Roi is represented by a struct Gpm_Roi structure, described in
     gpm.h.  The xtradata field will be used to fill the xtradata field
     in Gpm_Roi.  the return value is the Roi just pushed (i.e. the top
     of stack).

 - Function: char *Gpm_UseRoi (Gpm_Roi *roi);
     While Gpm_PushRoi has to allocate the Region before pushing it,
     this function passes a pre-allocated function to the stack manager.
     The return value is the Roi just used.

 - Function: Gpm_Roi *Gpm_PopRoi (Gpm_Roi *roi);
     Used to extract a Region of Interest from the stack, this function
     will also clear the Region if it is needed.

 - Function: Gpm_Roi *Gpm_RaiseRoi (Gpm_Roi *which, Gpm_Roi *before);
     Raise the specified roi, either before the second Roi or at top-of-
     stack (if before is NULL). The return value is the new
     top-of-stack.

 - Function: Gpm_Roi *Gpm_LowerRoi (Gpm_Roi *which, Gpm_Roi *after);
     Lower the specified roi, either after the second Roi or at
     bottom-of- stack (if before is NULL). The return value is the new
     top-of-stack.

 - Function: Gpm_Roi *Gpm_HandleRoi (Gpm_Event *ePtr, void *
          clientdata);
     This function, which should not be invoked by the user, is the
     dispatching manager within the application for mouse events. This
     function will browse the stack of regions of interest in order to
     notify windows about Enter and Leave events (if they are
     interested in them), and then delivers the current event to the
     relevanto Roi.

     If no Roi is interested in he event the *gpm_roi_handler function
     is invoked (if not null), with null clientdata.

     Reported events are all those in Gpm_Event, and also GPM_ENTER and
     GPM_LEAVE. These can be used to toggle highlighting on a button or
     to drop a menu if the menubutton is entered during a drag.
     Remember that when Enter or Leave is notified, no other
     information in the event item should be used.

Running under xterm
===================

   As of release 0.18, gpm-based applications can run under xterm
without any need for recompilation. The library is designed to convert
xterm mouse events to gpm-style structures, so that the client will get
the same events it got under the Linux console. Moreover, a source file
(gpm-xterm.c) is available to mimick libgpm under a different OS than
Linux. Porting to other text-based consoles is an open issue, but I
myself have Linux alone.

   The goal is to provide a uniform mouse interface with both xterm and
the Linux console. Some features of libgpm would not be available, but
if you run under xterm you know what you get, so you couldn't use them
on the console anyway.

   The sample directory in the distribution tree is meant to show how a
simple mouse-sensitive application can be easily autoconfigured and
compiled. The rmev program has proved to compile and run smoothly under
Linux (both with and without libgpm.a), SunOS-4, Solaris-5, hpux-8.x
and Ultrix-3.0.

Demonstration Clients
*********************

`mev'
=====

   The `mev' program is modeled after `xev'. It prints to `stdout' the
console events it gets, both keyboard and mouse events.

   `mev''s default behaviour is to get anything, but command line
switches can be used to set the various fields in the `Gpm_Connect'
structure, in order to customize the program's behaviour. I'm using
`mev' to handle mouse events to `emacs' Emacs Support.

   Command line switches for `mev' are the following:

`-C NUMBER'
     Select a virtual console to get events from.  This is intended to
     be used for debugging.

`-d NUMBER'
     Choose a default mask. By default the server gets any events not
     belonging to the event mask. The mask can be provided either as a
     decimal number, or as a symbolic string.

`-e NUMBER'
     Choose the event mask. By default any event is received. The mask
     can be provided either as a decimal number, or as a symbolic
     string.

`-E'
     Enter emacs mode. In emacs mode events are reported as lisp forms
     rather than numbers. This is the format used by the t-mouse
     package within emacs.

`-f'
     Fit events inside the screen before reporting them. This options
     re-fits drag events, which are allowed to exit the screen border,
     see Margins.

`-i'
     Interactive. Accepts input from `stdin' to change connection
     parameters.

`-m NUMBER'
     Choose the minimum modifier mask. Any event with fewer modifiers
     will not be reported to `mev'. It defaults to 0.  The mask must be
     provided either as a decimal number, or as a symbolic string.

`-M NUMBER'
     Choose the maximum modifier mask. Any event with more modifier
     than specified will not be reported to `mev'.  It defaults to
     `\~0', i.e. all events are received.  The mask must be provided
     either as a decimal number, or as a symbolic string.

`-p'
     Requests to draw the pointer during drags. This option is used by
     emacs to avoid invoking ioctl() from lisp code.

   When the arguments are not decimal integers, they are considered
lists of alphanumeric characters, separated by a single non-alphanumeric
character. I use the comma "`,'", but any will do.

   Allowed names for events are `move', `drag', `down' or `press', `up'
or `release', `motion' (which is both `move' adn `drag'), and `hard'.

   Allowed names for modifiers are `shift', `leftAlt', `rightAlt',
`anyAlt' (one or the other), `control'.

   When the `-i' switch is specified, `mev' looks at its standard input
as command lines rather than events. The input lines are parsed, and the
commands `push' and `pop' are recognized.

   The `push' command, then, accepts the options `-d', `-e', `-m' and
`-M', with the same meaning described above. Unspecified options retain
the previous value and the resulting masks are used to reopen the
connection with the server. `pop' is used to pop the connection stack.
If an empty stack is popped the program exits.

   The only other commands recognized are `info', used to return the
stack depth, and `quit' to premautrely terminate the program.

`sample/rmev'
=============

   rmev is a reduced version of mev, but it is designed to be as
portable as possible. It uses a subset of the capabilities of libgpm.a,
but works smoothly on both xterm and the Linux console. It is
distributed with gpm to show how a curses based application can support
the mouse with a small effort. Most of the xterm decoding is by Janne
Kukonlehto.  See Xterm.

Emacs Support
=============

   Emacs support is quite complete as of 0.14.  The enclosed file
`t-mouse.el', also available in byte-compiled form, is used to pass
mouse events to emacs.  `t-mouse.elc' is installed in the
`lib/emacs/site-lisp' directory of the install tree (by default `/usr').

   Events with modifiers other than Meta are not managed by the library.
Mouse-only and meta-mouse events are passed to the lisp program, which
converts them to be similar to X mouse events inside emacs. Actions are
then invoked through a local keymap.

   In my own environment I can use mouse-only and meta mouse within
emacs, shift-mouse to run selection and control-mouse to run gpm-root.
See gpm-root.

   I suggest to put the following form in your own `.emacs' file, to
avoid loading `t-mouse' when you aren't working on the Linux console:

     (if (and (string-match ".*-linux" system-configuration)
              (or (string-match "linux" (getenv "TERM"))
                  (string-match "con.*" (getenv "TERM"))))
         (load-library "t-mouse"))

   Mouse events are dispatched through the keymap `t-mouse-keymap',
which tries to mimick the behaviour of emacs under X.

   The scrollbar sits on the last column of the screen, though it is not
visible.  When you click on the last column, a scroll-bar action is
taken.  If this annoys you, please let me know.

   If you kill the `gpm' server, Emacs won't respond to mouse events
any more. If the server is then restarted, you can invoke `M-x
t-mouse-run' to restart mouse responsiveness in the editor.

   The keymap is configured to handle the following events:

`down-mouse-1'
     Jumps to the location of the click, setting the mark.

`drag-mouse-1'
     Drags the emacs pointer to follow your mouse. The mouse cursor is
     displayed as well.

`mouse-1'
     At mouse release, the cursor flashes to the mark (where the button
     was pressed), and point remains at the release location.  The
     region remains set, though emacs doesn't allow highlighting while
     in text mode. If no drag happened, button release has no effect.

`down-mouse-2'
     This event yanks the top item in the `kill-ring', like the
     key-press of `C-y'.

`down-mouse-3'
     Sets point. This can be used after a button-1 event to set the
     region without dragging.

`double-mouse-1'
     Sets the region to a single word, or to all the words surrounding
     the region dragged on. The value of t-mouse-word-syntax is used to
     tell which syntax classes are considered to be part of a word
     (default ""w_"").

`triple-mouse-1'
     Sets the region to a single line, or to all the lines surrounding
     the region dragged on.

`double-mouse-3'
     Kills the region.

`mode-line mouse-1'
     Selects the window.

`mode-line drag-mouse-1'
     Changes the size of the current window to track the mouse.

`mode-line mouse-2'
     Expands the window to the whole frame.

`mode-line mouse-3'
     Deletes the window.

`mode-line M-mouse-2'
     Splits the window horizontally.

`mode-line M-mouse-3'
     Splits the window vertically

`vertical-line drag-mouse-1'
     Changes the size of the current window to track the mouse.

`vertical-line mouse-2'
     Splits the window horizontally

`vertical-line mouse-3'
     Splits the window horizontally

`scroll-bar down-mouse-1'
     Moves the line at the level where you click up to the top of the
     window. By clicking repeatedly in the same place, you can scroll
     by the same distance over and over.

`M-down-mouse-1'
     Meta-mouse on the window acts in the same way as the scrollbar.

`scroll-bar down-mouse-2'
     This does nothing (jumping has proven bad, due to lack of a visible
     scrollbar on screen).

`scroll-bar drag-mouse-2'
     Dragging on the scroll-bar causes the buffer to scroll. The amount
     of scrolling is controlled by the X position of the mouse, in order
     to overcome the coarse granularity of the scroll-bar. In other
     words, horizonatal motion controls the vertical resolution, while
     vertical motion causes actual scrolling. The maximum vertical
     resolution is such that dragging from top to bottom of window can
     scan the whole buffer.

`M-drag-mouse-2'
     Meta-mouse on the window acts in the same way as the scrollbar.
     This means taht you can use the low-resolution scrollbar without
     grabbing the bar on the right and then lowering the resolution.

`scroll-bar down-mouse-3'
     Moves the line at the top of the window down to the level where
     you click. By clicking repeatedly in the same place, you can
     scroll by the same distance over and over.

`M-down-mouse-3'
     Meta-mouse on the window acts in the same way as the scrollbar.

The "gpm-root" program
======================

   The program gpm-root is designed to handle Control-Mouse events to
draw menus on the background of the current tty. The actual menus are
described by a configuration file in the user's home directory.

   Please note that gpm-root needs to run with Linux 1.1.73 or newwer,
because previous kernels lack some screen handling capabilities
required by the program.

   The program uses the files /dev/vcs* to draw to the console screen.
These are available only from kernel 1.1.81 onward. If you miss those
device nodes, you should create them using create_vcs in the
distribution directory. The tool won't run with kernels older than
1.1.81, because they lacked a full screen dump/restore capability.

   Available command line options are the following:

`-m NUMBER'
     Choose the modifier to use (by default: control). The modifier can
     be provided either as a number or as a symbolic string.  Allowed
     strings are "shift", "anyAlt", "leftAlt", "rightAlt", "control".

`-u'
     Deny using user-specific configuration files. With this option on,
     only /etc/gpm-root.conf will be used as a source of configuration
     information. This option is intended for those system
     administrators who fear security could be broken by this daemon.
     Thigs should be sufficiently secure, but if you find a hole please
     tell me about it.

   Each time a menu is drawn, the configuration file is reparsed if it
has changed. This allows modification of personal setup without
reinvoking the daemon.

   The actual configuration file is better introduced by an example:

     # sample configuration file for gpm-root
     # edit it to suit your taste

     button 2 {
       name "system status"
       foreground red
       background black
       border yellow
       head bright yellow

       ""          f.nop
       "load: "    f.load
       "free:"     f.free
       "---------" f.nop
       "disk usage" f.bgcmd  "du | sort -rn > /tmp/du"
     }

     button 3 {
       name "jump"

       foreground black
       background red
       border bright yellow
       head bright yellow

       "tty1"  f.jptty  "1"
       "tty2"  f.jptty  "2"
       "tty3"  f.jptty  "3"
       "tty4"  f.jptty  "4"
       "tty5"  f.jptty  "5"
       "tty6"  f.jptty  "6"
         ""        f.nop
         "more of them..." {
               "tty 17" f.jptty  "17"
               }
      }

   The syntax for the file won't be described here, being it quite
apparent from the example above. Blanks and newlines are unused in
parsing the file, and the layout of the file is free. Comments are
allowed in the file: any hash mark (`#') found at the beginning of the
line or after white space makes the parser discard anything up to the
next line. To insert quotes (") in strings precede them with a
backslash.

   Note that recursive menus are allowed, to any level of recursion.

   Keywords belong to three groups: the "button" keyword, the cfg
keywords and the action keywords. They are all described in the table
below:

`button NUMBER MENU'
     The "button" keyword is used to introduce a menu. It is followed
     by the number of the relevant button (1=left, 2=middle, 3=right),
     an open brace, a menu and a closed brace.  A menu is made up of
     cfg statements, followed by action statements. Cfg statements can
     come in any order, while the order of action statements tells the
     actual order in which actions will appear on the screen, top to
     bottom.

   The following statements belong to the cfg set.

`name STRING'
     If the "name" keyword is present, the specified string will be
     used as the name for the current menu.

`background COLOR'
     This statements is used to specify the background color to be used
     in the current menu. The color can be specified with one of the
     eight canonical strings "black", "red", "cyan" etc. The background
     defaults to black.

`foreground COLOR'
     This statements is used to specify the foreground color for menu
     items. Its value defaults to "white".  An optional "bright"
     keyword can appear before the actual color.

`border COLOR'
     "border" is used to specify the border color for the menu. Its
     value defaults to "white".  An optional "bright" keyword can
     appear before the actual color.

`head COLOR'
     "head" is used to specify the foreground color for the title of
     the menu. Its value defaults to "white".  An optional "bright"
     keyword can appear before the actual color.

   The following statements belong to the `action' set.

`STRING f.fgcmd CMDSTRING'
     When the mouse button is released above the corresponding menu
     item, the `cmdstring' is pasted in the keyboard queue of the
     current console. This is not yet implemented.

`STRING f.bgcmd CMDSTRING'
     When the mouse button is released above the corresponding menu
     item, a shell (/bin/sh) is forked to execute the specified
     command, with stdin connected to `/dev/null', and stdout, stderr
     connected to the active console.

`STRING f.jptty TTYNUMBER'
     When the mouse button is released above the corresponding menu
     item, the console is switched to the one specified. The
     `ttynumber' must be specified as a string. Any tty can be reached
     this way, even those which are not accessible via the keyboard.

`STRING f.mktty TTYNUMBER'
     When the mouse button is released above the corresponding menu
     item, an unused console is selected, and /sbin/agetty is executed
     in it. The current console is switched to the newly opened
     console. I use this command to save kernel memory by opening a
     single console through `/etc/inittab' and requesting the others
     only when i need to login.

`STRING { WHOLE-MENU'
     A menu can directly follow the lable string.  When the mouse
     pointer leaves the menu frame at the level of `string', a second
     menu is posted on screen.

`STRING f.lock'
     When the mouse button is released above the corresponding menu
     item, the keyboard and the screen are locked, and only the locking
     user or the superuser can unlock them. This is not yet implemented.

`STRING f.load'
     The current loadavg when the menu is posted is concatenated to
     `string' to build the actual message displayed on screen. Nothing
     happens at button release.

`STRING f.free'
     The free memory and swap when the menu is posted is concatenated
     to `string' to build the actual message displayed on screen.
     Nothing happens at button release.

`STRING f.time'
     The current time is formatted with strftime(3), according to
     `string'. The resulting string is the actual message displayed on
     screen. Nothing happens at button release.

`STRING f.pipe CMDLINE'
     When the mouse pointer leaves the menu frame at the level of
     `string', a message box is posted on screen showing the last ten
     lines of the output of `cmdline'. The `cmdline' is executed by
     `/bin/sh'. This is not yet implemented.

`STRING f.nop'
     This does nothing, it only displays `string' on the menu.

   The HOME, LOGNAME and USER environment variables are setup to the
values for the invoking user before spawning an external process
(`f.bgcmd', `f.pipe'). The current directory is always /.

   Known bugs have been fixed. In particular, if you invoke gpm-root
right after gpm, it will delasy a few seconds before trying to connect
to the daemon.

hltest
======

   High-level test is a simple sample application using the high-level
library. It implements something like a window manager for text windows,
though it is small and unuseful.

   The application is meant to be read by programmers trying to use the
high-level library. It is equipped with event reporting to help in
understanding the internal workings.

mouse-test
==========

   This experimental and incomplete application tries to help in
detecting which protocol does your mouse speak. It is able to detect
MouseMan devices, and to choose between "-t ms" (three-buttons aware)
and "-t bare" old two-buttons-only serial mice.

   I know the application is buggy, but I only own one mouse device.
If you are interested in this application, just call me and awake me
from my laziness.