991 lines
40 KiB
Plaintext
991 lines
40 KiB
Plaintext
|
.\" Input Extension Porting Document
|
||
|
.EH ''''
|
||
|
.OH ''''
|
||
|
.EF ''''
|
||
|
.OF ''''
|
||
|
\0
|
||
|
.sp 10
|
||
|
.ce 50
|
||
|
.ps 20
|
||
|
\fBX11 Input Extension Porting Document
|
||
|
.sp 2
|
||
|
.ps 12
|
||
|
X Version 11, Release 6.8
|
||
|
.sp 16
|
||
|
.ps 15
|
||
|
George Sachs\0\0\0\0Hewlett-Packard
|
||
|
.ps 12
|
||
|
.ce 0
|
||
|
.bp
|
||
|
\0
|
||
|
.sp 10
|
||
|
.ps 9
|
||
|
.vs 11
|
||
|
.LP
|
||
|
Copyright \(co 1989, 1990, 1991 by Hewlett-Packard Company
|
||
|
.LP
|
||
|
Permission to use, copy, modify, and distribute this documentation for
|
||
|
any purpose and without fee is hereby granted, provided that the above
|
||
|
copyright notice and this permission notice appear in all copies.
|
||
|
Hewlett-Packard makes no representations about the suitability
|
||
|
for any purpose of the information in this document. It is provided "as is"
|
||
|
without express or implied warranty. This document is only a draft standard
|
||
|
of the X Consortium and is therefore subject to change.
|
||
|
.sp 5
|
||
|
Copyright \(co 1989, 1990, 1991 X Consortium
|
||
|
.LP
|
||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
of this software and associated documentation files (the ``Software''), to deal
|
||
|
in the Software without restriction, including without limitation the rights
|
||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
copies of the Software, and to permit persons to whom the Software is
|
||
|
furnished to do so, subject to the following conditions:
|
||
|
.LP
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
.LP
|
||
|
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
.LP
|
||
|
Except as contained in this notice, the name of the X Consortium shall not be
|
||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||
|
in this Software without prior written authorization from the X Consortium.
|
||
|
.sp 3
|
||
|
\fIX Window System\fP is a trademark of The Open Group.
|
||
|
.bp 1
|
||
|
.EH '\fBX Input Extension Porting Document\fP''\fBX11, Release 6.8\fP'
|
||
|
.OH '\fBX Input Extension Porting Document\fP''\fBX11, Release 6.8\fP'
|
||
|
.EF ''\fB % \fP''
|
||
|
.OF ''\fB % \fP''
|
||
|
.\" Force the heading counter for level 1 to one
|
||
|
.\"
|
||
|
.\"
|
||
|
.\"
|
||
|
.\" Print table of contents to level 4 headings
|
||
|
.\"
|
||
|
.nr Cl 4
|
||
|
.\"
|
||
|
.\" Page eject for each level 1 heading
|
||
|
.\"
|
||
|
.nr H1 1
|
||
|
.nr P 1
|
||
|
.\"
|
||
|
.\" Define Ch to contain the chapter string.
|
||
|
.\"
|
||
|
.ds Ch Porting Overview
|
||
|
.\"
|
||
|
.\"
|
||
|
.\" Pull in the layout macro package.
|
||
|
.\"
|
||
|
.\"
|
||
|
.tr ~
|
||
|
This document is intended to aid the process of integrating the
|
||
|
X11 Input Extension into an X server.
|
||
|
.LP
|
||
|
Most of the functionality provided by the input extension is
|
||
|
device- and implementation-independent, and should require no changes.
|
||
|
The functionality is implemented by
|
||
|
routines that typically reside in the server source tree directory
|
||
|
extensions/server/xinput.
|
||
|
This extension includes functions to enable and disable input extension devices,
|
||
|
select input, grab and focus those device, query and change key
|
||
|
and button mappings, and others. The only input extension requirements
|
||
|
for the device-dependent part of X are that the input devices be
|
||
|
correctly initialized and input events from those devices be correctly
|
||
|
generated. Device-dependent X is responsible for reading input data from
|
||
|
the input device hardware and if necessary, reformatting it into X events.
|
||
|
.LP
|
||
|
The process of initializing input extension devices is similar to that used
|
||
|
for the core devices, and is described in the following sections. When
|
||
|
multiple input devices are attached to X server, the choice of which devices
|
||
|
to initially use as the core X pointer and keyboard is left
|
||
|
implementation-dependent. It is also up to each implementation to decide
|
||
|
whether all input devices will be opened by the server during its
|
||
|
initialization and kept open for the life of the server. The alternative is
|
||
|
to open only the X keyboard and X pointer during server initialization, and
|
||
|
open other input devices only when requested by a client to do so. Either
|
||
|
type of implementation is supported by the input extension.
|
||
|
.LP
|
||
|
Input extension events generated by the X server use the same 32-byte xEvent
|
||
|
wire event as do core input events. However, additional information must be
|
||
|
sent for input extension devices, requiring that multiple xEvents be generated
|
||
|
each time data is received from an input extension device. These xEvents are
|
||
|
combined into a single client XEvent by the input extension library. A later
|
||
|
section of this document describes the format and generation of input extension
|
||
|
events.
|
||
|
.NH 1
|
||
|
Initializing Extension Devices
|
||
|
.LP
|
||
|
Extension input devices are initialized in the same manner as the core
|
||
|
X input devices. Device-Independent X provides functions that can be
|
||
|
called from DDX to initialize these devices. Which functions are called
|
||
|
and when will vary by implementation, and will depend on whether the
|
||
|
implementation opens all the input devices available to X when X is initialized,
|
||
|
or waits until a client requests that a device be opened.
|
||
|
In the simplest case, DDX will open all input devices as part of its
|
||
|
initialization, when the InitInput routine is called.
|
||
|
.NH 2
|
||
|
Summary of Calling Sequence
|
||
|
.LP
|
||
|
.DS
|
||
|
Device-Independent X | Device-Dependent X
|
||
|
-------------------- | -------------------
|
||
|
|
|
||
|
InitInput --------------> | - do device-specific initialization
|
||
|
|
|
||
|
| - call AddInputDevice (deviceProc,AutoStart)
|
||
|
AddInputDevice |
|
||
|
- creates DeviceIntRec |
|
||
|
- records deviceProc |
|
||
|
- adds new device to |
|
||
|
list of off_devices. |
|
||
|
sets dev->startup=AutoStart|
|
||
|
| - call one of:
|
||
|
| - RegisterPointerDevice (X pointer)
|
||
|
| - processInputProc = ProcessPointerEvents
|
||
|
| - RegisterKeyboardDevice (X keyboard)
|
||
|
| - processInputProc = ProcessKeyboardEvents
|
||
|
| - RegisterOtherDevice (extension device)
|
||
|
| - processInputProc = ProcessOtherEvents
|
||
|
|
|
||
|
|
|
||
|
InitAndStartDevices -----> | - calls deviceProc with parameters
|
||
|
| (DEVICE_INIT, AutoStart)
|
||
|
sets dev->inited = return |
|
||
|
value from deviceProc |
|
||
|
|
|
||
|
| - in deviceProc, do one of:
|
||
|
| - call InitPointerDeviceStruct (X pointer)
|
||
|
| - call InitKeyboardDeviceStruct (X keybd)
|
||
|
| - init extension device by calling some of:
|
||
|
| - InitKeyClassDeviceStruct
|
||
|
| - InitButtonClassDeviceStruct
|
||
|
| - InitValuatorClassDeviceStruct
|
||
|
| - InitValuatorAxisStruct
|
||
|
| - InitFocusClassDeviceStruct
|
||
|
| - InitProximityClassDeviceStruct
|
||
|
| - InitKbdFeedbackClassDeviceStruct
|
||
|
| - InitPtrFeedbackClassDeviceStruct
|
||
|
| - InitLedFeedbackClassDeviceStruct
|
||
|
| - InitStringFeedbackClassDeviceStruct
|
||
|
| - InitIntegerFeedbackClassDeviceStruct
|
||
|
| - InitBellFeedbackClassDeviceStruct
|
||
|
| - init device name and type by:
|
||
|
| - calling MakeAtom with one of the
|
||
|
| predefined names
|
||
|
| - calling AssignTypeAndName
|
||
|
|
|
||
|
|
|
||
|
for each device added |
|
||
|
by AddInputDevice, |
|
||
|
InitAndStartDevices |
|
||
|
calls EnableDevice if | - EnableDevice calls deviceProc with
|
||
|
dev->startup & | (DEVICE_ON, AutoStart)
|
||
|
dev->inited |
|
||
|
|
|
||
|
If deviceProc returns | - core devices are now enabled, extension
|
||
|
Success, EnableDevice | devices are now available to be accessed
|
||
|
move the device from | through the input extension protocol
|
||
|
inputInfo.off_devices | requests.
|
||
|
to inputInfo.devices |
|
||
|
.DE
|
||
|
.NH 2
|
||
|
Initialization Called From InitInput
|
||
|
.LP
|
||
|
InitInput is the first DDX input entry point called during X server startup.
|
||
|
This routine is responsible for
|
||
|
device- and implementation- specific initialization, and for calling
|
||
|
AddInputDevice to create and initialize the DeviceIntRec structure for each
|
||
|
input device. AddInputDevice is passed the address of a procedure to be called
|
||
|
by the DIX routine InitAndStartDevices when input devices are enabled.
|
||
|
This procedure is expected to perform X initialization for the input device.
|
||
|
.LP
|
||
|
If the device is to be used as the X pointer, DDX should then call
|
||
|
RegisterPointerDevice, passing the DeviceIntRec pointer,
|
||
|
to initialize the device as the X pointer.
|
||
|
.LP
|
||
|
If the device is to be used as the X keyboard, DDX should instead call
|
||
|
RegisterKeyboardDevice to initialize the device as the X keyboard.
|
||
|
.LP
|
||
|
If the device is to be used as an extension device, DDX should instead
|
||
|
call RegisterOtherDevice, passing the DeviceIntPtr returned by
|
||
|
AddInputDevice.
|
||
|
.LP
|
||
|
A sample InitInput implementation is shown below.
|
||
|
.LP
|
||
|
.DS
|
||
|
InitInput(argc,argv)
|
||
|
{
|
||
|
int i, numdevs, ReadInput();
|
||
|
DeviceIntPtr dev;
|
||
|
LocalDevice localdevs[LOCAL_MAX_DEVS];
|
||
|
DeviceProc kbdproc, ptrproc, extproc;
|
||
|
|
||
|
/**************************************************************
|
||
|
* Open the appropriate input devices, determine which are
|
||
|
* available, and choose an X pointer and X keyboard device
|
||
|
* in some implementation-dependent manner.
|
||
|
***************************************************************/
|
||
|
|
||
|
open_input_devices (&numdevs, localdevs);
|
||
|
|
||
|
/**************************************************************
|
||
|
* Register a WakeupHandler to handle input when it is generated.
|
||
|
***************************************************************/
|
||
|
|
||
|
RegisterBlockAndWakeupHandlers (NoopDDA, ReadInput, NULL);
|
||
|
|
||
|
/**************************************************************
|
||
|
* Register the input devices with DIX.
|
||
|
***************************************************************/
|
||
|
|
||
|
for (i=0; i<numdevs; i++)
|
||
|
{
|
||
|
if (localdevs[i].use == IsXKeyboard)
|
||
|
{
|
||
|
dev = AddInputDevice (kbdproc, TRUE);
|
||
|
RegisterKeyboardDevice (dev);
|
||
|
}
|
||
|
else if (localdevs[i].use == IsXPointer)
|
||
|
{
|
||
|
dev = AddInputDevice (ptrproc, TRUE);
|
||
|
RegisterPointerDevice (dev);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dev = AddInputDevice (extproc, FALSE);
|
||
|
RegisterOtherDevice (dev);
|
||
|
}
|
||
|
if (dev == NULL)
|
||
|
FatalError ("Too many input devices.");
|
||
|
dev->devicePrivate = (pointer) &localdevs[i];
|
||
|
}
|
||
|
.DE
|
||
|
.NH 2
|
||
|
Initialization Called From InitAndStartDevices
|
||
|
.LP
|
||
|
After InitInput has returned,
|
||
|
InitAndStartDevices is the DIX routine that is called to enable input devices.
|
||
|
It calls the device control routine that was passed to AddInputDevice,
|
||
|
with a mode value of DEVICE_INIT. The action taken by the device control
|
||
|
routine depends on how the device is to be used. If the device is to be
|
||
|
the X pointer, the device control routine should call
|
||
|
InitPointerDeviceStruct to initialize it. If the device is to be the
|
||
|
X keyboard, the device control routine should call
|
||
|
InitKeyboardDeviceStruct. Since input extension devices may support various
|
||
|
combinations of keys, buttons, valuators, and feedbacks,
|
||
|
each class of input that it supports must be initialized.
|
||
|
Entry points are defined by DIX to initialize each of the supported classes of
|
||
|
input, and are described in the following sections.
|
||
|
.LP
|
||
|
A sample device control routine called from InitAndStartDevices is
|
||
|
shown below.
|
||
|
.LP
|
||
|
.DS
|
||
|
Bool extproc (dev, mode)
|
||
|
DeviceIntPtr dev;
|
||
|
int mode;
|
||
|
{
|
||
|
LocalDevice *localdev = (LocalDevice *) dev->devicePrivate;
|
||
|
|
||
|
switch (mode)
|
||
|
{
|
||
|
case DEVICE_INIT:
|
||
|
if (strcmp(localdev->name, XI_TABLET) == 0)
|
||
|
{
|
||
|
/****************************************************
|
||
|
* This device reports proximity, has buttons,
|
||
|
* reports two axes of motion, and can be focused.
|
||
|
* It also supports the same feedbacks as the X pointer
|
||
|
* (acceleration and threshold can be set).
|
||
|
****************************************************/
|
||
|
|
||
|
InitButtonClassDeviceStruct (dev, button_count, button_map);
|
||
|
InitValuatorClassDeviceStruct (dev, localdev->n_axes,);
|
||
|
motionproc, MOTION_BUF_SIZE, Absolute);
|
||
|
for (i=0; i<localdev->n_axes; i++)
|
||
|
InitValuatorAxisStruct (dev, i, min_val, max_val,
|
||
|
resolution);
|
||
|
InitFocusClassDeviceStruct (dev);
|
||
|
InitProximityClassDeviceStruct (dev);
|
||
|
InitPtrFeedbackClassDeviceStruct (dev, p_controlproc);
|
||
|
}
|
||
|
else if (strcmp(localdev->name, XI_BUTTONBOX) == 0)
|
||
|
{
|
||
|
/****************************************************
|
||
|
* This device has keys and LEDs, and can be focused.
|
||
|
****************************************************/
|
||
|
|
||
|
InitKeyClassDeviceStruct (dev, syms, modmap);
|
||
|
InitFocusClassDeviceStruct (dev);
|
||
|
InitLedFeedbackClassDeviceStruct (dev, ledcontrol);
|
||
|
}
|
||
|
else if (strcmp(localdev->name, XI_KNOBBOX) == 0)
|
||
|
{
|
||
|
/****************************************************
|
||
|
* This device reports motion.
|
||
|
* It can be focused.
|
||
|
****************************************************/
|
||
|
|
||
|
InitValuatorClassDeviceStruct (dev, localdev->n_axes,);
|
||
|
motionproc, MOTION_BUF_SIZE, Absolute);
|
||
|
for (i=0; i<localdev->n_axes; i++)
|
||
|
InitValuatorAxisStruct (dev, i, min_val, max_val,
|
||
|
resolution);
|
||
|
InitFocusClassDeviceStruct (dev);
|
||
|
}
|
||
|
localdev->atom =
|
||
|
MakeAtom(localdev->name, strlen(localdev->name), FALSE);
|
||
|
AssignTypeAndName (dev, localdev->atom, localdev->name);
|
||
|
break;
|
||
|
case DEVICE_ON:
|
||
|
AddEnabledDevice (localdev->file_ds);
|
||
|
dev->on = TRUE;
|
||
|
break;
|
||
|
case DEVICE_OFF:
|
||
|
dev->on = FALSE;
|
||
|
RemoveEnabledDevice (localdev->file_ds);
|
||
|
break;
|
||
|
case DEVICE_CLOSE:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
.DE
|
||
|
.LP
|
||
|
The device control routine is called with a mode value of DEVICE_ON
|
||
|
by the DIX routine EnableDevice, which is called from InitAndStartDevices.
|
||
|
When called with this mode, it should call AddEnabledDevice to cause the
|
||
|
server to begin checking for available input from this device.
|
||
|
.LP
|
||
|
>From InitAndStartDevices, EnableDevice is called for all devices that have
|
||
|
the "inited" and "startup" fields in the DeviceIntRec set to TRUE. The
|
||
|
"inited" field is set by InitAndStartDevices to the value returned by
|
||
|
the deviceproc when called with a mode value of DEVICE_INIT. The "startup"
|
||
|
field is set by AddInputDevice to value of the second parameter (autoStart).
|
||
|
.LP
|
||
|
When the server is first initialized, it should only be checking for input
|
||
|
from the core X keyboard and pointer. One way to accomplish this is to
|
||
|
call AddInputDevice for the core X keyboard and pointer with an
|
||
|
autoStart value equal to TRUE, while calling AddInputDevice for
|
||
|
input extension devices with an autoStart value equal to FALSE. If this is
|
||
|
done, EnableDevice will skip all input extension devices during server
|
||
|
initialization. In this case,
|
||
|
the OpenInputDevice routine should set the "startup" field to TRUE
|
||
|
when called for input extension devices. This will cause ProcXOpenInputDevice
|
||
|
to call EnableDevice for those devices when a client first does an
|
||
|
XOpenDevice request.
|
||
|
.NH 2
|
||
|
DIX Input Class Initialization Routines
|
||
|
.LP
|
||
|
DIX routines are defined to initialize each of the defined input classes.
|
||
|
The defined classes are:
|
||
|
.RS
|
||
|
.in +5n
|
||
|
.IP "-" 3n
|
||
|
KeyClass - the device has keys.
|
||
|
.IP "-" 3n
|
||
|
ButtonClass - the device has buttons.
|
||
|
.IP "-" 3n
|
||
|
ValuatorClass - the device reports motion data or positional data.
|
||
|
.IP "-" 3n
|
||
|
Proximitylass - the device reports proximity information.
|
||
|
.IP "-" 3n
|
||
|
FocusClass - the device can be focused.
|
||
|
.IP "-" 3n
|
||
|
FeedbackClass - the device supports some kind of feedback
|
||
|
.in -5n
|
||
|
.RE
|
||
|
.LP
|
||
|
DIX routines are provided to initialize the X pointer and keyboard, as in
|
||
|
previous releases of X. During X initialization, InitPointerDeviceStruct
|
||
|
is called to initialize the X pointer, and InitKeyboardDeviceStruct is
|
||
|
called to initialize the X keyboard. There is no
|
||
|
corresponding routine for extension input devices, since they do not all
|
||
|
support the same classes of input. Instead, DDX is responsible for the
|
||
|
initialization of the input classes supported by extension devices.
|
||
|
A description of the routines provided by DIX to perform that initialization
|
||
|
follows.
|
||
|
.NH 3
|
||
|
InitKeyClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a KeyClassRec, and
|
||
|
should be called for extension devices that have keys. It is passed a pointer
|
||
|
to the device, and pointers to arrays of keysyms and modifiers reported by
|
||
|
the device. It returns FALSE if the KeyClassRec could not be allocated,
|
||
|
or if the maps for the keysyms and and modifiers could not be allocated.
|
||
|
Its parameters are:
|
||
|
.LP
|
||
|
.DS
|
||
|
Bool
|
||
|
InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers)
|
||
|
DeviceIntPtr dev;
|
||
|
KeySymsPtr pKeySyms;
|
||
|
CARD8 pModifiers[];
|
||
|
.DE
|
||
|
.LP
|
||
|
The DIX entry point InitKeyboardDeviceStruct calls this routine for the
|
||
|
core X keyboard. It must be called explicitly for extension devices
|
||
|
that have keys.
|
||
|
.NH 3
|
||
|
InitButtonClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a ButtonClassRec, and
|
||
|
should be called for extension devices that have buttons. It is passed a
|
||
|
pointer to the device, the number of buttons supported, and a map of the
|
||
|
reported button codes. It returns FALSE if the ButtonClassRec could not be
|
||
|
allocated. Its parameters are:
|
||
|
.LP
|
||
|
.DS
|
||
|
Bool
|
||
|
InitButtonClassDeviceStruct(dev, numButtons, map)
|
||
|
register DeviceIntPtr dev;
|
||
|
int numButtons;
|
||
|
CARD8 *map;
|
||
|
.DE
|
||
|
.LP
|
||
|
The DIX entry point InitPointerDeviceStruct calls this routine for the
|
||
|
core X pointer. It must be called explicitly for extension devices that
|
||
|
have buttons.
|
||
|
.NH 3
|
||
|
InitValuatorClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a ValuatorClassRec, and
|
||
|
should be called for extension devices that have valuators. It is passed the
|
||
|
number of axes of motion reported by the device, the address of the motion
|
||
|
history procedure for the device, the size of the motion history buffer,
|
||
|
and the mode (Absolute or Relative) of the device. It returns FALSE if
|
||
|
the ValuatorClassRec could not be allocated. Its parameters are:
|
||
|
.LP
|
||
|
.DS
|
||
|
Bool
|
||
|
InitValuatorClassDeviceStruct(dev, numAxes, motionProc, numMotionEvents, mode)
|
||
|
DeviceIntPtr dev;
|
||
|
int (*motionProc)();
|
||
|
int numAxes;
|
||
|
int numMotionEvents;
|
||
|
int mode;
|
||
|
.DE
|
||
|
.LP
|
||
|
The DIX entry point InitPointerDeviceStruct calls this routine for the
|
||
|
core X pointer. It must be called explicitly for extension devices that
|
||
|
report motion.
|
||
|
.NH 3
|
||
|
InitValuatorAxisStruct
|
||
|
.LP
|
||
|
This function is provided to initialize an XAxisInfoRec, and
|
||
|
should be called for core and extension devices that have valuators.
|
||
|
The space for the XAxisInfoRec is allocated by
|
||
|
the InitValuatorClassDeviceStruct function, but is not initialized.
|
||
|
.LP
|
||
|
InitValuatorAxisStruct should be called once for each axis of motion
|
||
|
reported by the device. Each
|
||
|
invocation should be passed the axis number (starting with 0), the
|
||
|
minimum value for that axis, the maximum value for that axis, and the
|
||
|
resolution of the device in counts per meter. If the device reports
|
||
|
relative motion, 0 should be reported as the minimum and maximum values.
|
||
|
InitValuatorAxisStruct has the following parameters:
|
||
|
.DS
|
||
|
InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution)
|
||
|
DeviceIntPtr dev;
|
||
|
int axnum;
|
||
|
int minval;
|
||
|
int maxval;
|
||
|
int resolution;
|
||
|
.DE
|
||
|
.LP
|
||
|
This routine is not called by InitPointerDeviceStruct for the
|
||
|
core X pointer. It must be called explicitly for core and extension devices
|
||
|
that report motion.
|
||
|
.NH 3
|
||
|
InitFocusClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a FocusClassRec, and
|
||
|
should be called for extension devices that can be focused. It is passed a
|
||
|
pointer to the device, and returns FALSE if the allocation fails.
|
||
|
It has the following parameter:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitFocusClassDeviceStruct(dev)
|
||
|
DeviceIntPtr dev;
|
||
|
.DE
|
||
|
.LP
|
||
|
The DIX entry point InitKeyboardDeviceStruct calls this routine for the
|
||
|
core X keyboard. It must be called explicitly for extension devices
|
||
|
that can be focused. Whether or not a particular device can be focused
|
||
|
is left implementation-dependent.
|
||
|
.NH 3
|
||
|
InitProximityClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a ProximityClassRec, and
|
||
|
should be called for extension absolute pointing devices that report proximity.
|
||
|
It is passed a pointer to the device, and returns FALSE if the allocation fails.
|
||
|
It has the following parameter:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitProximityClassDeviceStruct(dev)
|
||
|
DeviceIntPtr dev;
|
||
|
.DE
|
||
|
.NH 3
|
||
|
Initializing Feedbacks
|
||
|
.LP
|
||
|
.NH 4
|
||
|
InitKbdFeedbackClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a KbdFeedbackClassRec, and
|
||
|
may be called for extension devices that support some or all of the
|
||
|
feedbacks that the core keyboard supports. It is passed a
|
||
|
pointer to the device, a pointer to the procedure that sounds the bell,
|
||
|
and a pointer to the device control procedure.
|
||
|
It returns FALSE if the allocation fails, and has the following parameters:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc)
|
||
|
DeviceIntPtr dev;
|
||
|
void (*bellProc)();
|
||
|
void (*controlProc)();
|
||
|
.DE
|
||
|
The DIX entry point InitKeyboardDeviceStruct calls this routine for the
|
||
|
core X keyboard. It must be called explicitly for extension devices
|
||
|
that have the same feedbacks as a keyboard. Some feedbacks, such as LEDs and
|
||
|
bell, can be supported either with a KbdFeedbackClass or with BellFeedbackClass
|
||
|
and LedFeedbackClass feedbacks.
|
||
|
.NH 4
|
||
|
InitPtrFeedbackClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a PtrFeedbackClassRec, and
|
||
|
should be called for extension devices that allow the setting of acceleration
|
||
|
and threshold. It is passed a pointer to the device,
|
||
|
and a pointer to the device control procedure.
|
||
|
It returns FALSE if the allocation fails, and has the following parameters:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitPtrFeedbackClassDeviceStruct(dev, controlProc)
|
||
|
DeviceIntPtr dev;
|
||
|
void (*controlProc)();
|
||
|
.DE
|
||
|
.LP
|
||
|
The DIX entry point InitPointerDeviceStruct calls this routine for the
|
||
|
core X pointer. It must be called explicitly for extension devices
|
||
|
that support the setting of acceleration and threshold.
|
||
|
.NH 4
|
||
|
InitLedFeedbackClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a LedFeedbackClassRec, and
|
||
|
should be called for extension devices that have LEDs.
|
||
|
It is passed a pointer to the device,
|
||
|
and a pointer to the device control procedure.
|
||
|
It returns FALSE if the allocation fails, and has the following parameters:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitLedFeedbackClassDeviceStruct(dev, controlProc)
|
||
|
DeviceIntPtr dev;
|
||
|
void (*controlProc)();
|
||
|
.DE
|
||
|
.LP
|
||
|
Up to 32 LEDs per feedback can be supported, and a device may have
|
||
|
multiple feedbacks of the same type.
|
||
|
.NH 4
|
||
|
InitBellFeedbackClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a BellFeedbackClassRec,
|
||
|
and should be called for extension devices that have a bell.
|
||
|
It is passed a pointer to the device,
|
||
|
and a pointer to the device control procedure.
|
||
|
It returns FALSE if the allocation fails, and has the following parameters:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitBellFeedbackClassDeviceStruct(dev, bellProc, controlProc)
|
||
|
DeviceIntPtr dev;
|
||
|
void (*bellProc)();
|
||
|
void (*controlProc)();
|
||
|
.DE
|
||
|
.NH 4
|
||
|
InitStringFeedbackClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize a StringFeedbackClassRec,
|
||
|
and should be called for extension devices that have a display upon which a
|
||
|
string can be displayed.
|
||
|
It is passed a pointer to the device,
|
||
|
and a pointer to the device control procedure.
|
||
|
It returns FALSE if the allocation fails, and has the following parameters:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitStringFeedbackClassDeviceStruct(dev, controlProc, max_symbols,
|
||
|
num_symbols_supported, symbols)
|
||
|
DeviceIntPtr dev;
|
||
|
void (*controlProc)();
|
||
|
int max_symbols:
|
||
|
int num_symbols_supported;
|
||
|
KeySym *symbols;
|
||
|
.DE
|
||
|
.NH 4
|
||
|
InitIntegerFeedbackClassDeviceStruct
|
||
|
.LP
|
||
|
This function is provided to allocate and initialize an
|
||
|
IntegerFeedbackClassRec,
|
||
|
and should be called for extension devices that have a display upon which an
|
||
|
integer can be displayed.
|
||
|
It is passed a pointer to the device,
|
||
|
and a pointer to the device control procedure.
|
||
|
It returns FALSE if the allocation fails, and has the following parameters:
|
||
|
.DS
|
||
|
Bool
|
||
|
InitIntegerFeedbackClassDeviceStruct(dev, controlProc)
|
||
|
DeviceIntPtr dev;
|
||
|
void (*controlProc)();
|
||
|
.DE
|
||
|
.NH 2
|
||
|
Initializing The Device Name And Type
|
||
|
.LP
|
||
|
The device name and type can be initialized by calling AssignTypeAndName
|
||
|
with the following parameters:
|
||
|
.DS
|
||
|
void
|
||
|
AssignTypeAndName(dev, type, name)
|
||
|
DeviceIntPtr dev;
|
||
|
Atom type;
|
||
|
char *name;
|
||
|
.DE
|
||
|
.LP
|
||
|
This will allocate space for the device name and copy the name that was passed.
|
||
|
The device type can be obtained by calling MakeAtom with one of the names
|
||
|
defined for input devices. MakeAtom has the following parameters:
|
||
|
.DS
|
||
|
Atom
|
||
|
MakeAtom(name, len, makeit)
|
||
|
char *name;
|
||
|
int len;
|
||
|
Bool makeit;
|
||
|
.DE
|
||
|
.LP
|
||
|
Since the atom was already made when the input extension was initialized, the
|
||
|
value of makeit should be FALSE;
|
||
|
.NH 1
|
||
|
Closing Extension Devices
|
||
|
.LP
|
||
|
The DisableDevice entry point is provided by DIX to disable input devices.
|
||
|
It calls the device control routine for the specified
|
||
|
device with a mode value of DEVICE_OFF. The device control routine should
|
||
|
call RemoveEnabledDevice to stop the server from checking for input from
|
||
|
that device.
|
||
|
.LP
|
||
|
DisableDevice is not called by any input extension routines. It can be
|
||
|
called from the CloseInputDevice routine, which is called by
|
||
|
ProcXCloseDevice when a client makes an XCloseDevice request. If
|
||
|
DisableDevice is called, it should only be called when the last client
|
||
|
using the extension device has terminated or called XCloseDevice.
|
||
|
.NH 1
|
||
|
Implementation-Dependent Routines
|
||
|
.LP
|
||
|
Several input extension protocol requests have
|
||
|
implementation-dependent entry points. Default routines
|
||
|
are defined for these entry points and contained in the source
|
||
|
file extensions/server/xinput/xstubs.c. Some implementations may
|
||
|
be able to use the default routines without change.
|
||
|
The following sections describe each of these routines.
|
||
|
.NH 2
|
||
|
AddOtherInputDevices
|
||
|
.LP
|
||
|
AddOtherInputDevice is called from ProcXListInputDevices as a result of
|
||
|
an XListInputDevices protocol request. It may be needed by
|
||
|
implementations that do not open extension input devices until requested
|
||
|
to do so by some client. These implementations may not initialize
|
||
|
all devices when the X server starts up, because some of those devices
|
||
|
may be in use. Since the XListInputDevices
|
||
|
function only lists those devices that have been initialized,
|
||
|
AddOtherInputDevices is called to give DDX a chance to
|
||
|
initialize any previously unavailable input devices.
|
||
|
.LP
|
||
|
A sample AddOtherInputDevices routine might look like the following:
|
||
|
.DS
|
||
|
void
|
||
|
AddOtherInputDevices ()
|
||
|
{
|
||
|
DeviceIntPtr dev;
|
||
|
int i;
|
||
|
|
||
|
for (i=0; i<MAX_DEVICES; i++)
|
||
|
{
|
||
|
if (!local_dev[i].initialized && available(local_dev[i]))
|
||
|
{
|
||
|
dev = (DeviceIntPtr) AddInputDevice (local_dev[i].deviceProc, TRUE);
|
||
|
dev->public.devicePrivate = local_dev[i];
|
||
|
RegisterOtherDevice (dev);
|
||
|
dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
.DE
|
||
|
.LP
|
||
|
The default AddOtherInputDevices routine in xstubs.c does nothing.
|
||
|
If all input extension devices are initialized when the server
|
||
|
starts up, it can be left as a null routine.
|
||
|
.NH 2
|
||
|
OpenInputDevice
|
||
|
.LP
|
||
|
Some X server implementations open all input devices when the server
|
||
|
is initialized and never close them. Other implementations may open only
|
||
|
the X pointer and keyboard devices during server initialization,
|
||
|
and open other input devices only when some client makes an
|
||
|
XOpenDevice request. This entry point is for the latter type of
|
||
|
implementation.
|
||
|
.LP
|
||
|
If the physical device is not already open, it can be done in this routine.
|
||
|
In this case, the server must keep track of the fact that one or more clients
|
||
|
have the device open, and physically close it when the last client that has
|
||
|
it open makes an XCloseDevice request.
|
||
|
.LP
|
||
|
The default implementation is to do nothing (assume all input devices
|
||
|
are opened during X server initialization and kept open).
|
||
|
.NH 2
|
||
|
CloseInputDevice
|
||
|
.LP
|
||
|
Some implementations may close an input device when the last client
|
||
|
using that device requests that it be closed, or terminates.
|
||
|
CloseInputDevice is called from ProcXCloseDevice when a client
|
||
|
makes an XCloseDevice protocol request.
|
||
|
.LP
|
||
|
The default implementation is to do nothing (assume all input devices
|
||
|
are opened during X server initialization and kept open).
|
||
|
.NH 2
|
||
|
SetDeviceMode
|
||
|
.LP
|
||
|
Some implementations support input devices that can report
|
||
|
either absolute positional data or relative motion. The XSetDeviceMode
|
||
|
protocol request is provided to allow DDX to change the current mode of
|
||
|
such a device.
|
||
|
.LP
|
||
|
The default implementation is to always return a BadMatch error. If the
|
||
|
implementation does not support any input devices that are capable of
|
||
|
reporting both relative motion and absolute position information, the
|
||
|
default implementation may be left unchanged.
|
||
|
.NH 2
|
||
|
SetDeviceValuators
|
||
|
.LP
|
||
|
Some implementations support input devices that allow their valuators to be
|
||
|
set to an initial value. The XSetDeviceValuators
|
||
|
protocol request is provided to allow DDX to set the valuators of
|
||
|
such a device.
|
||
|
.LP
|
||
|
The default implementation is to always return a BadMatch error. If the
|
||
|
implementation does not support any input devices that are allow their
|
||
|
valuators to be set, the default implementation may be left unchanged.
|
||
|
.NH 2
|
||
|
ChangePointerDevice
|
||
|
.LP
|
||
|
The XChangePointerDevice protocol request is provided to change which device is
|
||
|
used as the X pointer. Some implementations may maintain information
|
||
|
specific to the X pointer in the private data structure pointed to by
|
||
|
the DeviceIntRec. ChangePointerDevice is called to allow such
|
||
|
implementations to move that information to the new pointer device.
|
||
|
The current location of the X cursor is an example of the type of
|
||
|
information that might be affected.
|
||
|
.LP
|
||
|
The DeviceIntRec structure that describes the X pointer device does not
|
||
|
contain a FocusRec. If the device that has been made into the new X pointer
|
||
|
was previously a device that could be focused, ProcXChangePointerDevice will
|
||
|
free the FocusRec associated with that device.
|
||
|
.LP
|
||
|
If the server implementation desires to allow clients to focus the old pointer
|
||
|
device (which is now accessible through the input extension), it should call
|
||
|
InitFocusClassDeviceStruct for the old pointer device.
|
||
|
.LP
|
||
|
The XChangePointerDevice protocol request also allows the client
|
||
|
to choose which axes of the new pointer device are used to move
|
||
|
the X cursor in the X- and Y- directions. If the axes are different
|
||
|
than the default ones, the server implementation should record that fact.
|
||
|
.LP
|
||
|
If the server implementation supports input devices with valuators that
|
||
|
are not allowed to be used as the X pointer, they should be screened out
|
||
|
by this routine and a BadDevice error returned.
|
||
|
.LP
|
||
|
The default implementation is to do nothing.
|
||
|
.NH 2
|
||
|
ChangeKeyboardDevice
|
||
|
.LP
|
||
|
The XChangeKeyboardDevice protocol request is provided to change which device is
|
||
|
used as the X keyboard. Some implementations may maintain information
|
||
|
specific to the X keyboard in the private data structure pointed to by
|
||
|
the DeviceIntRec. ChangeKeyboardDevice is called to allow such
|
||
|
implementations to move that information to the new keyboard device.
|
||
|
.LP
|
||
|
The X keyboard device can be focused, and the DeviceIntRec that describes
|
||
|
that device has a FocusRec. If the device that has been made into the new X
|
||
|
keyboard did not previously have a FocusRec,
|
||
|
ProcXChangeKeyboardDevice will allocate one for it.
|
||
|
.LP
|
||
|
If the implementation does not want clients to be able to focus the old X
|
||
|
keyboard (which has now become available as an input extension device)
|
||
|
it should call DeleteFocusClassDeviceStruct to free the FocusRec.
|
||
|
.LP
|
||
|
If the implementation supports input devices with keys that are not allowed
|
||
|
to be used as the X keyboard, they should be checked for here, and a
|
||
|
BadDevice error returned.
|
||
|
.LP
|
||
|
The default implementation is to do nothing.
|
||
|
.NH 1
|
||
|
Input Extension Events
|
||
|
.LP
|
||
|
Events accessed through the input extension are analogous to the core input
|
||
|
events, but have different event types. They are of types
|
||
|
\fBDeviceKeyPress\fP, \fBDeviceKeyRelease\fP, \fBDeviceButtonPress\fP,
|
||
|
\fBDeviceButtonRelease\fP, \fBDeviceDeviceMotionNotify\fP,
|
||
|
\fBDeviceProximityIn\fP, \fBDeviceProximityOut\fP, and \fBDeviceValuator\fP.
|
||
|
These event types are not constants. Instead, they are external integers
|
||
|
defined by the input extension. Their actual values will depend on which
|
||
|
extensions are supported by a server, and the order in which they are
|
||
|
initialized.
|
||
|
.LP
|
||
|
The data structures that define these
|
||
|
events are defined in the file \fBextensions/include/XIproto.h\fP. Other
|
||
|
input extension constants needed by DDX are defined in the file
|
||
|
\fBextensions/include/XI.h\fP.
|
||
|
.LP
|
||
|
Some events defined by the input extension contain more information than can
|
||
|
be contained in the 32-byte xEvent data structure. To send this information
|
||
|
to clients, DDX must generate two or more 32-byte wire events. The following
|
||
|
sections describe the contents of these events.
|
||
|
.NH 2
|
||
|
Device Key Events
|
||
|
.LP
|
||
|
\fBDeviceKeyPresss\fP events contain all the information that is contained in
|
||
|
a core \fBKeyPress\fP event, and also the following additional information:
|
||
|
.LP
|
||
|
.RS
|
||
|
.in +5n
|
||
|
.IP "-" 3n
|
||
|
deviceid - the identifier of the device that generated the event.
|
||
|
.IP "-" 3n
|
||
|
device_state - the state of any modifiers on the device that generated the event
|
||
|
.IP "-" 3n
|
||
|
num_valuators - the number of valuators reported in this event.
|
||
|
.IP "-" 3n
|
||
|
first_valuator - the first valuator reported in this event.
|
||
|
.IP "-" 3n
|
||
|
valuator0 through valuator5 - the values of the valuators.
|
||
|
.in -5n
|
||
|
.RE
|
||
|
.LP
|
||
|
In order to pass this information to the input extension library, two 32-byte
|
||
|
wire events must be generated by DDX. The first has an event type of
|
||
|
\fBDeviceKeyPress\fP, and the second has an event type of \fPDeviceValuator\fP.
|
||
|
.LP
|
||
|
The following code fragment shows how the two wire events could be initialized:
|
||
|
.LP
|
||
|
.DS
|
||
|
extern int DeviceKeyPress;
|
||
|
DeviceIntPtr dev;
|
||
|
xEvent xE[2];
|
||
|
CARD8 id, num_valuators;
|
||
|
INT16 x, y, pointerx, pointery;
|
||
|
Time timestamp;
|
||
|
deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *) xE;
|
||
|
deviceValuator *xv;
|
||
|
|
||
|
xev->type = DeviceKeyPress; /* defined by input extension */
|
||
|
xev->detail = keycode; /* key pressed on this device */
|
||
|
xev->time = timestamp; /* same as for core events */
|
||
|
xev->rootX = pointerx; /* x location of core pointer */
|
||
|
xev->rootY = pointery; /* y location of core pointer */
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* The following field does not exist for core input events. */
|
||
|
/* It contains the device id for the device that generated the */
|
||
|
/* event, and also indicates whether more than one 32-byte wire */
|
||
|
/* event is being sent. */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
xev->deviceid = dev->id | MORE_EVENTS; /* sending more than 1*/
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* Fields in the second 32-byte wire event: */
|
||
|
/******************************************************************/
|
||
|
|
||
|
xv = (deviceValuator *) ++xev;
|
||
|
xv->type = DeviceValuator; /* event type of second event */
|
||
|
xv->deviceid = dev->id; /* id of this device */
|
||
|
xv->num_valuators = 0; /* no valuators being sent */
|
||
|
xv->device_state = 0; /* will be filled in by DIX */
|
||
|
.DE
|
||
|
.NH 2
|
||
|
Device Button Events
|
||
|
.LP
|
||
|
\fBDeviceButton\fP events contain all the information that is contained in
|
||
|
a core button event, and also the same additional information that a
|
||
|
\fBDeviceKey\fP event contains.
|
||
|
.NH 2
|
||
|
Device Motion Events
|
||
|
.LP
|
||
|
\fBDeviceMotion\fP events contain all the information that is contained in
|
||
|
a core motion event, and also additional valuator information. At least
|
||
|
two wire events are required to contain this information.
|
||
|
The following code fragment shows how the two wire events could be initialized:
|
||
|
.LP
|
||
|
.DS
|
||
|
extern int DeviceMotionNotify;
|
||
|
DeviceIntPtr dev;
|
||
|
xEvent xE[2];
|
||
|
CARD8 id, num_valuators;
|
||
|
INT16 x, y, pointerx, pointery;
|
||
|
Time timestamp;
|
||
|
deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *) xE;
|
||
|
deviceValuator *xv;
|
||
|
|
||
|
xev->type = DeviceMotionNotify; /* defined by input extension */
|
||
|
xev->detail = keycode; /* key pressed on this device */
|
||
|
xev->time = timestamp; /* same as for core events */
|
||
|
xev->rootX = pointerx; /* x location of core pointer */
|
||
|
xev->rootY = pointery; /* y location of core pointer */
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* The following field does not exist for core input events. */
|
||
|
/* It contains the device id for the device that generated the */
|
||
|
/* event, and also indicates whether more than one 32-byte wire */
|
||
|
/* event is being sent. */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
xev->deviceid = dev->id | MORE_EVENTS; /* sending more than 1*/
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* Fields in the second 32-byte wire event: */
|
||
|
/******************************************************************/
|
||
|
|
||
|
xv = (deviceValuator *) ++xev;
|
||
|
xv->type = DeviceValuator; /* event type of second event */
|
||
|
xv->deviceid = dev->id; /* id of this device */
|
||
|
xv->num_valuators = 2; /* 2 valuators being sent */
|
||
|
xv->first_valuator = 0; /* first valuator being sent */
|
||
|
xv->device_state = 0; /* will be filled in by DIX */
|
||
|
xv->valuator0 = x; /* first axis of this device */
|
||
|
xv->valuator1 = y; /* second axis of this device */
|
||
|
.DE
|
||
|
.LP
|
||
|
Up to six axes can be reported in the deviceValuator event. If the device
|
||
|
is reporting more than 6 axes, additional pairs of DeviceMotionNotify and
|
||
|
DeviceValuator events should be sent, with the first_valuator field
|
||
|
set correctly.
|
||
|
.NH 2
|
||
|
Device Proximity Events
|
||
|
.LP
|
||
|
Some input devices that report absolute positional information, such as
|
||
|
graphics tablets and touchscreens, may report proximity events.
|
||
|
\fBProximityIn\fP
|
||
|
events are generated when a pointing device like a stylus, or in the case
|
||
|
of a touchscreen, the user's finger, comes into close proximity with the
|
||
|
surface of the input device. \fBProximityOut\fP events are generated when
|
||
|
the stylus or finger leaves the proximity of the input devices surface.
|
||
|
.LP
|
||
|
\fBProximity\fP events contain almost the same information as button events.
|
||
|
The event type is \fBProximityIn\fP or \fBProximityOut\fP, and there is no
|
||
|
detail information.
|
||
|
.bp
|
||
|
.\" .TC
|