OpenWindows Server Device Developer's Guide
  Procure somente este livro
Fazer download desta apostila em PDF

Input Devices

12

This chapter describes how to add an extension input device to the OpenWindows server and access it with the MIT XInput Extension. This extension is an MIT standard that is distributed with X11 Release 5 (X11R5). The OpenWindows server loads input devices dynamically and accesses them through the Input Extension. Dynamic loading reduces the size of the core X server and allows you to develop device drivers independently.

Note - The client interface for accessing input devices in OpenWindows is the Input Extension as defined in X11R5. The design presented here does not change that interface in any way. All client protocol requests in this chapter are as defined in the Input Extension.

The Input Extension includes the following three documents that are prerequisite to this chapter. These documents are on line in the doc/extensions/xinput directory. The associated filename is in parentheses.
  • X11 Input Extension Protocol Specification, Patrick and Sachs, MIT X Consortium. (protocol.ms)
  • X11 Input Extension Library Specification, Patrick and Sachs, MIT X Consortium. (library.ms)
  • X11 Input Extension Porting Document, Sachs, MIT X Consortium. (porting.ms)

Extension Input Device Overview

Figure 12-1 on page 224 shows a block diagram of the device input portion of the OpenWindows server. The diagram also indicates which components must be developed by Independent Hardware Vendors (IHVs) and Independent Software Vendors (ISVs) to add an extension input device to OpenWindows.
The server implements most of the Input Extension capabilities: decoding protocol requests, managing input devices, and distributing events to interested clients. No changes to the server are required to add a new input device.
The device handler reads device events, converts device events to X events, and adds the events to the servers global event queue. Each new input device must have a device handler developed for it.
The device's STREAMS modules convert raw data from the physical input device into event packets that are read by the device handler. A STREAMS module is not required for each input device, but when needed it is developed by the IHV and ISV.

Gráfico

Figure 12-1

Handling of Extension Input Devices

This section provides a high level discussion of how extension input devices are implemented in the OpenWindows environment.

Extension Device Initialization

After server start-up, the core keyboard and core pointer are the only devices that are initialized and generating events. Additional devices can be requested by a client with the XListInputDevices request. Each time a client issues this request, the server executes the following tasks:
  1. Reads the configuration file

    The server parses the OWconfig configuration file, searching for input devices. Each time the OWconfig file is read due to an XListInputDevices request, devices listed in the XDISPLAY class as coreKeyboard and corePointer and at server start-up were not the core pointer and keyboard, are treated as extension devices.

    For more information on the OWconfig file, see Appendix A, "The OWconfig File."

  2. Loads input device

    All devices in the OWconfig file that have not been initialized are loaded. Thus, for the first request after start-up the core keyboard and core pointer have already been initialized; only new devices are loaded.

    Later, upon receipt of another XListInputDevices request, the server again searches the OWconfig file for any devices that have been added since the last request. If it finds new devices, they are loaded.

  3. Initializes the device

    After a device is loaded, its DeviceControlProc function is called with a value of DEVICE_INIT, causing the device to register all of its features with the server. DeviceControlProc is defined on page 252.

    The server can now return a reply to the XListInputDevices request issued by the client. The XListInputDevices request does not turn on the device so the server does not accept input from them yet.

If during initialization the DeviceControlProc routine returns a failure, the server assumes the hardware is not present and unloads the device.

Extension Device Open

After receiving the reply to the XListInputDevices, the client can open an extension device and start receiving input from it with the.XOpenDevice request. When the server receives the first XOpenDevice request for a particular device, it tells the device to start generating events by calling the DeviceControlProc function with a value of DEVICE_ON.
The server keeps a list of clients that currently have the device open. If the device is already opened by a client when an XOpenDevice request is received, the requesting client is added to the client list.
Server start-up is now complete. When input is pending on the device, the server reads the data and puts it into the event stream. The client can now issue any of the standard Input Extension protocol requests to receive events, initiate grabs, and control features of the device.

Reading Input Data

During initialization, devices register a read procedure with the server and set the device STREAM to generate SIGPOLLs when data reaches the STREAM head. The input data flow begins when a SIGPOLL signal is received by the server. The server then loops through the following steps as illustrated in Figure 12-2 on page 227, until no more events are available on any of the input devices:
  1. For each device that is turned on, call the DeviceReadProc function for that device. DeviceReadProc is defined on page 254.

  2. Check to see if there are any events from all of the sources just read.

  • If there are no more events, break out of the loop and return.
  • If there are more events, continue to step 3.
  1. Find the oldest event.

  2. Give the oldest event to the DeviceEnqueueProc for that device. DeviceEnqueueProc is defined on page 253.

The DeviceEnqueueProc procedure takes an event, processes any device-dependent information on the event, converts it to an xEvent, and places it on the global event queue via the mieqEnqueue procedure.
  1. Loop back to Step 1.

Gráfico

Figure 12-2

Extension Device Close

When a client is finished with a device, it issues an XCloseDevice request to the server. The client that issued the XCloseDevice request does not receive any more events from the device. What happens next depends on how many clients have the device open:
  • If other clients have the device open, the server continues to read the device until no clients have the device open. The client that issued the XCloseDevice request does not receive any more events from the device because the event mask for that client is cleared by the Input Extension as part of the XCloseDevice procedure.
  • If the client is the only client with the device open, the server calls the DeviceControlProc with a value of DEVICE_OFF instructing the device to stop generating events.

Restart and Shutdown

Restarting and shutting down the server involve the same actions. All open devices are closed and unloaded. During the close process the input device is notified of the shutdown. The device must free any memory that has been allocated and close the device's file descriptor.
When the server is about to exit or restart, the server calls the DeviceControlProc function with a value of DEVICE_CLOSE. This call instructs the device to free all of its resources because the server is about to exit.

Adding An Extension Input Device

Each device added to the server must have the following components:
  • A device handler shared object
  • An entry in the local OWconfig file
And is recommended to have:
  • A STREAMS module

Writing the Device Handler

All device handlers must have DeviceControlProc, DeviceGetEvents, and DeviceEnqueueProc procedures, as well as device-dependent procedures. This section describes each of these procedures. A sample tablet handler is provided in server/ddx/solaris/reference/sunTablet to aid in the understanding of this chapter.

Device Control Procedure

The DeviceControlProc function allows the server to control an extension device without having to know the capabilities of each particular device. There are four actions that the DeviceControlProc must handle:
  • DEVICE_INIT
  • DEVICE_ON
  • DEVICE_OFF
  • DEVICE_CLOSE
DEVICE_INIT When the DeviceControlProc is called with action DEVICE_INIT, the procedure completes the following tasks:
  1. The device is opened and initialized.

  2. Any private device structures are allocated and initialized.

  3. An atom for the device must be generated and assigned to the device. The device's state is initialized to off by setting the device->on flag to FALSE.

  4. The device registers its DeviceGetEvents and DeviceEnqueueProc by calling RegisterFdIo.

  5. All device-dependent structures must be initialized and device-dependent procedures registered. If the device can become the core pointer or the core keyboard, pointer or keyboard interest must be registered. The initialization and registry functions are listed in "Public Server Functions" on page 233.

DEVICE_ON When the DeviceControlProc is called with action DEVICE_ON, the procedure completes the following tasks:
  1. Call AddEnabledDevice to let the server know the device has been turned on.

  2. Set the devices on state to TRUE.

  3. Cause the device to generate SIGPOLLs with the I_SETSIG ioctl.

DEVICE_OFF When the DeviceControlProc is called with action DEVICE_OFF, the procedure completes the following tasks:
  1. Call RemoveEnabledDevice to let the server know the device has been turned off.

  2. Set the device's on state to FALSE.

DEVICE_CLOSE When the DeviceControlProc is called with action DEVICE_CLOSE, the procedure completes the following tasks:
  1. If the device's on state is TRUE, call RemoveEnabledDevice and set on state to FALSE.

  2. Perform any device specific clean-up.

  3. Close the device.

  4. Free any private device structures.

Device Get Events Procedure

The DeviceGetEvents procedure must read the device, put the events into an XI_event structure, and return a pointer to the event or events. If the DeviceGetEvents procedure allocates memory for the XI_event structure it must be freed in the DeviceEnqueueProc. The example tablet device handler keeps a static array of XI_event structures and passes a pointer to this array each time.

Device Enqueue Procedure

The DeviceEnqueueProc is required to be in all device handlers. The DeviceEnqueueProc takes one XI_eventPtr and enqueues one or more events on the global event queue. The DeviceEnqueueProc is passed a XI_event structure which has an opaque pointer to the event. The DeviceEnqueueProc must typecast this pointer to match the format that the DeviceGetEvents procedure put into the structure. The server does not do any processing on the event before it is passed to the DeviceEnqueueProc. As noted above, if the DeviceGetEvents procedure allocates memory for the XI_event structure it must be freed here.
As stated in X11 Input Extension Protocol Specification, DeviceKeyPress,
DeviceKeyRelease, DeviceButtonPress, DeviceButtonRelease,
ProximityIn, ProximityOut, and DeviceStateNotify events can be

followed by zero or more DeviceValuator events. Devices that have valuators and are reporting absolute motion must follow each of the above events with one or more DeviceValuator events to specify the current state of the valuators. Devices that don't have valuators or have valuators but are reporting relative motion send zero DeviceValuator events following the events listed above. A DeviceMotionNotify event is always followed by one or more DeviceValuator events regardless of the mode of the device (relative or absolute). See the Input Extension Protocol Specification for more details.
Devices that have registered themselves as potential core pointer devices must be able to control the cursor from this procedure. The device must not control the cursor until after the server has notified the device that it is the core pointer. Cursor control is accomplished calling either miPointerDeltaCursor or miPointerAbsoluteCursor depending on whether the device is reporting relative or absolute motion. The device must not enqueue MotionNotify events when it is the core pointer; this is done by the miPointer procedures. It is the responsibility of the device handler to enqueue ButtonPress and ButtonRelease events if the device supports buttons.
Devices that have registered themselves as potential core keyboards enqueue DeviceKeyPress and DeviceKeyRelease events unless the device handler has been notified that it is the core keyboard. Once it becomes the core keyboard it must enqueue KeyPress and KeyRelease events until such time the device is notified it is no longer the core keyboard.

Device-Dependent Procedures

Devices also have to support additional procedures based on the types of input classes a given device supports, such as KEY, BUTTON, and VALUATOR. These procedures are explained in "Device Shared Library Functions" on page 252.

Adding An Entry to the OWconfig File

Appendix A, "The OWconfig File" describes the OWconfig file and the name value attribute pairs that describe each input device. Appendix B, "Packaging and Installation Hints" discusses how a new input device is packaged for installation by users. "DDX Versioning" on page 8" specifies shared object naming and versioning conventions. Read these sections before attempting to add an input device.

Debugging the Device Handler

Since the input device handlers are shared objects, breakpoints cannot be set in the handler until after the server has loaded the shared object. All extension input device handlers are loaded when the first client issues an XListInutDevices.
Breakpoints can be set in an input device handler by following these steps:
  1. Add a line to the OWconfig file for the input device to be debugged. Make sure the new line is directly below the mouse and keyboard lines.

  2. From a remote machine, debug the server (dbx Xsun or debugger Xsun).

  3. Set a breakpoint in AddInputDevice.

  4. Run the server. The AddInputDevice breakpoint hits twice during server initialization; just continue each time.

  5. Start a client that opens the extension input device. This causes the breakpoint to hit again. At this point the input device handler is loaded and you can set breakpoints inside the handler.

Writing The STREAMS Module

A STREAMS module is not required for every input device. For example, the device handler could read, interpret, and format the raw data from the ttya port. This design is least attractive from a performance perspective and it is strongly recommended that the interpreting and formatting of data be handled in a STREAMS module. This method is attractive if you have a limited amount of time to get an input device working, are unfamiliar with STREAMS module development, and are not concerned about performance.
A STREAMS module outputs vuid (virtual user input device) type events. See Appendix C, "Virtual User Input Device Interface" for more information on vuid events.

Note - The DeviceReadProc function returns the XI_eventPtr structure that is a timestamp and an opaque pointer to the devices event. This timestamp could be generated in DeviceReadProc. However it is strongly recommended that the device's STREAMS module timestamp the event and DeviceReadProc use this timestamp for the XI_eventPtr.

Input Library Functions

This section describes new functions in two categories:
  • Public server functions
  • Device-shared library functions

Public Server Functions

The functions in this section are callable from the device shared library.

InitPointerDeviceStruct


  Bool InitPointerDeviceStruct(DevicePtr device, CARD8 *map,  
           int numButtons, DeviceGetMotionProc GetMotionProc,  
           DevicePtrCtrlProc PtrCtrlProc, int numMotionEvents)  

Purpose....This function is provided to allocate and initialize ButtonClassRec, ValuatorClassRec, and
                  PtrFeedbackClassRec.

Used by the initial core pointer device. A call to InitPointerDeviceStruct is equivalent to calling InitButtonClassDeviceStruct (page 236), InitValuatorClassDeviceStruct (page 236), and InitPtrFeedbackClassDeviceStruct page 239).
Called byDeviceControlProc of the core pointer device during the DEVICE_INIT action.
ResultsAllocates and initializes ButtonClassRec, ValuatorClassRec, and PtrFeedbackClassRec.
ReturnsInitKeyboardDeviceStructTRUE on success FALSE on failure
Bool InitKeyboardDeviceStruct(DevicePtr device,
PurposeThis function is provided to allocate and initialize KeyClassRec, FocusClassRec, and
KbdFeedbackClassRec.

Used by the initial core keyboard device. A call to InitKeyboardDeviceStruct is equivalent to calling InitKeyClassDeviceStruct (page 235), InitFocusClassDeviceStruct (page 238), and InitKbdFeedbackClassDeviceStruct (page 239).
Called byDeviceControlProc of the core keyboard device during the DEVICE_INIT action.
ResultsAllocates and initializes KeyClassRec, FocusClassRec, and KbdFeedbackClassRec.
ReturnsInitKeyClassDeviceStructTRUE on success FALSE on failure
Bool InitKeyClassDeviceStruct(DeviceIntPtr dev,
PurposeThis function is provided to allocate and initialize a KeyClassRec, and is 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.
InitKeyboardDeviceStruct calls this routine for the core X keyboard. It must be called explicitly for extension devices that have keys.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes KeyClassRec.
ReturnsTRUE on success FALSE on failure

InitButtonClassDeviceStruct


  Bool InitButtonClassDeviceStruct(DeviceIntPtr dev,  
           int numButtons, CARD8 *map)  

Purpose....This function is provided to allocate and initialize a ButtonClassRec, and is 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.
InitPointerDeviceStruct calls this routine for the core X pointer. It must be called explicitly for extension devices that have buttons.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes ButtonClassRec.
ReturnsInitValuatorClassDeviceStructTRUE on success FALSE on failure
Bool InitValuatorClassDeviceStruct(DeviceIntPtr dev,
PurposeThis function is provided to allocate and initialize a ValuatorClassRec, and is 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.
InitPointerDeviceStruct calls this routine for the core X pointer. It must be called explicitly for extension devices that report motion.
Called by...DeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes ValuatorClassRec.
ReturnsInitValuatorAxisStructTRUE on success FALSE on failure
Bool InitValuatorAxisStruct(DeviceIntPtr dev, int axnum,
PurposeThis function is provided to initialize an XAxisInfoRec, and is called for core and extension devices that have valuators. The space for the XAxisInfoRec is allocated by the InitValuatorClassDeviceStruct function, but is not initialized.
InitValuatorAxisStruct is called once for each axis of motion reported by the device. Each invocation is passed the axis number (starting with 0), the minimum value for the axis, the maximum value for that axis, and the resolution of the device in counts per meter. If the device reports relative motion, 0 is reported as the minimum and maximum values.
This routine is not called by InitPointerDeviceStruct for the core X pointer. It must be explicitly called for core and extension devices that report motion.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsInitializes XAxisInfoRec.
ReturnsTRUE on success FALSE on failure

InitFocusClassDeviceStruct


  Bool InitFocusClassDeviceStruct(DeviceIntPtr dev)  

Purpose....This function is provided to allocate and initialize a FocusClassRec, and is called for extension devices that can be focused. It is passed a pointer to the device.
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 implementation-dependent.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes FocusClassRec.
ReturnsInitProximityClassDeviceStructTRUE on success FALSE on failure
Bool InitProximityClassDeviceStruct(DeviceIntPtr dev)
PurposeThis function is provided to allocate and initialize a ProximityClassRec, and is called for extension absolute pointing devices that report proximity. It is passed a pointer to the device.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes a ProximityClassRec.
ReturnsTRUE on success FALSE on failure

InitKbdFeedbackClassDeviceStruct


  Bool InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev,  
           DeviceBellProc BellProc, DeviceKbdCtrlProc KbdCtrlProc)  

Purpose....This function is provided to allocate and initialize a KbdFeedbackClassRec, and is 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.
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 or LedFeedbackClass feedbacks.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes KbdFeedbackClassRec.
ReturnsInitPtrFeedbackClassDeviceStructTRUE on success FALSE on failure
Bool InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev,
PurposeThis function is provided to allocate and initialize a PtrFeedbackClassRec, and is 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.
InitPointerDeviceStruct() calls this routine for the core X pointer. It must be called explicitly for the extension devices that support the setting of acceleration and threshold.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes PtrFeedbackClassRec.
ReturnsInitLedFeedbackClassDeviceStructTRUE on success FALSE on failure
Bool InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev,
PurposeThis function is provided to allocate and initialize a LedFeedbackClassRec, and is called for extension devices that have LEDs. It is passed a pointer to the device, and a pointer to the device control procedure.
Up to 32 LEDs per feedback can be supported, and a device can have multiple feedbacks of the same type.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes LedFeedbackClassRec.
ReturnsTRUE on success FALSE on failure

InitBellFeedbackClassDeviceStruct


  Bool InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev,  
           DeviceBellCtrlProc BellCtrlProc)  

PurposeThis function is provided to allocate and initialize a BellFeedbackClassRec, and is called for extension devices that have a bell. It is passed a pointer to the device, and a pointer to the device control procedure.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes BellFeedbackClassRec.
ReturnsInitStringFeedbackClassDeviceStructTRUE on success FALSE on failure
Bool InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev,
PurposeThis function is provided to allocate and initialize a StringFeedbackClassRec, and is 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.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes StringFeedbackClassRec.
ReturnsTRUE on success FALSE on failure

InitIntegerFeedbackClassDeviceStruct


  Bool InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev,  
           DeviceIntegerCtrlProc IntegerCtrlProc)  

PurposeThis function is provided to allocate and initialize an IntegerFeedbackClassRec, and is 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.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAllocates and initializes IntegerFeedbackClassRec.
ReturnsRegisterFdIoTRUE on success FALSE on failure
int RegisterFdIo(DevicePtr devptr, int fd,
PurposeThis function is provided to register the device's file descriptor, read function, and enqueue function.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsRegisters the device's file descriptor, read function, and enqueue function with the server. The device's read function is called when there is input pending on the given file descriptor.
ReturnsSuccess on success !Success on failure

RegisterModifierCheckProc


  int RegisterModifierCheckProc(DevicePtr devptr,  
           DeviceModifierCheckProc ModifierCheckProc)  

PurposeThis function is provided to register a function to be called when a keycode needs to be checked for validity by the device. This is only valid for devices that support keys. See "DeviceModifierCheckProc" on page 254.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsIf the device supports keys and this function is not specified, the server assumes that the keycode is valid. If the function is specified, the server calls the function to check validity.
ReturnsRegisterSetDeviceModeProcSuccess on success !Success on failure
int RegisterSetDeviceModeProc(DevicePtr devptr,
PurposeThis function is provided to register a function to be called when a client requests a change in the mode of a device. This refers to the device reporting absolute or relative positions. See "DeviceSetModeProc" on page 255.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsIf this function is not specified, the server assumes that the mode of this device cannot be changed. If the function is present, the server calls it to notify the device that the client requests a mode change.
ReturnsSuccess on success !Success on failure

RegisterSetDeviceValuatorsProc


  int RegisterSetDeviceValuatorsProc(DevicePtr devptr,  
           DeviceSetDeviceValuatorsProc SetDeviceValuatorsProc)  

PurposeThis function is provided to register a function to be called when a client requests a change in the valuators of a device. See "DeviceSetDeviceValuatorsProc" on page 255.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsIf this function is not specified, the server assumes that the valuators of this device cannot be changed. If the function is present, the server calls it to notify the device that the client requests a change to the valuators.
ReturnsRegisterChangeDeviceControlProcSuccess on success !Success on failure
int RegisterChangeDeviceControlProc(DevicePtr devptr,
PurposeThis function is provided to register a function to be called when a client requests a change in the control of a device. This can refer to any control on the device, but is currently limited to just the resolution of the device. See "DeviceChangeDeviceControlProc" on page 256.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsIf this function is not specified, the server assumes that the control of this device cannot be changed. If the function is present, the server calls it to notify the device that the client wishes to change the control.
ReturnsSuccess on success !Success on failure

RegisterXKeyboardInterest


  int RegisterXKeyboardInterest(DevicePtr devptr, Bool focusable,  
           DeviceChangeCoreKeyboardProc ChangeCoreKeyboardProc)  

PurposeThis function is provided to register interest with the server to indicate that the given device can become the core keyboard if a client so requests. The focusable argument specifies whether the device is focusable when it is not the core keyboard. See "DeviceChangeCoreKeyboardProc" on page 256.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsThe device is registered as a possible core keyboard with the focusability that is specified. If the device is not registered as a possible core keyboard, the server assumes that the device cannot become the core keyboard.
ReturnsRegisterXPointerInterestSuccess on success !Success on failure
int RegisterXPointerInterest(DevicePtr devptr, Bool focusable,
PurposeThis function is provided to register interest with the server to indicate that the given device can become the core pointer if a client so requests. The focusable argument specifies whether the device is focusable when it is not the core pointer.
The DevicePointerAxisChangeProc is called when the client requests this device to become the core pointer. See "DevicePointerAxisChangeProc" on page 257.
Called by...DeviceControlProc during the DEVICE_INIT action.
ResultsThe device is registered as a possible core pointer with the focusability that is specified. If the device is not registered as a possible core pointer, the server assumes that the device cannot become the core pointer.
ReturnsmieUpdateKbdPtrSuccess on success !Success on failure
void mieqUpdateKbdPtr(DevicePtr pKbd, DevicePtr pPtr)
PurposeThis function is provided to update the core keyboard or pointer device.
Called byThe device shared libraries calls mieqUpdateKbdPtr from the DeviceChangeCoreKeyboardProc or DevicePointerAxisChangeProc each time the core keyboard or pointer device changes. mieqUpdateKbdPtr is called by the device that is becoming the core keyboard or pointer with it's DevicePtr in the appropriate argument. Set the other argument to NULL.
ResultsThe mi event code treats the new device as the core keyboard or pointer.The old keyboard or pointer are treated as extension devices by the mi event code.
ReturnsmieqEnqueueNone
void mieqEnqueue(xEvent *e)
PurposeThis function is provided to place the xEvent on the server's global event queue.
Called byMany different locations in the server, but for the current design this routine is being called only from the DeviceEnqueueProc in the device shared library.
ResultsThe xEvent is placed on the global event queue.The event is copied from the caller, so the memory can be reused by the DeviceEnqueueProc.
ReturnsmiPointerPositionNone
void miPointerPosition(int *x, int *y)
PurposeThis function is provided to obtain the current location of the cursor. It is passed two pointers that are filled in with the current location of the cursor.
Called byThe device shared libraries when they need to know the current location of the cursor.
ResultsThe *x and *y pointers are set to the current x and y position of the cursor.
ReturnsmiPointerDeltaCursorNone
void miPointerDeltaCursor(int dx, int dy, unsigned long time)
PurposeThis function is provided to move the cursor as a result of device events. It is passed the delta x and y that the cursor is to move relative to its current position as well as the time of the motion event.
Called byDeviceEnqueueProc of the current core pointer in the device shared library.
ResultsThe cursor is moved dx,dy from its previous position.
ReturnsNone

miPointerAbsoluteCursor


  void miPointerAbsoluteCursor(int x, int y, unsigned long time)  

PurposeThis function is provided to move the cursor as a result of device events. It is passed an absolute x and y position to which the cursor moves, as well as the time of the motion event.
Called byDeviceEnqueuProc of the current core pointer in the device shared library.
ResultsThe cursor is moved to x,y.
ReturnsRegisterHandlersNone
int RegisterHandlers(DeviceWakeupHandler wakeupHandler,
PurposeThis function is provided to register wakeup handlers or block handlers or both for the device. The server calls wakeupHandler immediately after it comes out of its select call due to client input or input device activity. The server calls blockHandler right before going into the select call. Some devices such as keyboards might need this functionality to implement features such as auto repeat. It is passed the address of the devices wakeup handler or block handler or both and a pointer to the index of the handler that the device uses to refer to the handler. A NULL can be passed for either handler indicating not to register it.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsA wakeup handler or block handler or both are registered with the server.
ReturnsSuccess on success !Success on failure

RemoveHandlers


  void RemoveHandlers(int index)  

PurposeThis function is provided to remove the device's block handler or wakeup handler or both. It is passed the index to the handlers that was returned in the RegisterHandlers call.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsThe device's block handler or wakeup handler or both are removed.
ReturnsNextWakeupHandlerNone
void NextWakeupHandler(int index, int nscreen, pointer pbdata,
PurposeThis function is provided to call the next wakeupHandler registered. It must be called by a device's wakeupHandler and passes along all the parameters that are passed into the device's DeviceWakeupHandlerProc.
Called byThe device's DeviceWakeupHandlerProc.
ResultsThe wakeup handler that was registered just before the device's DeviceWakeupHandlerProc is called.
ReturnsNone

NextBlockHandler


  void NextBlockHandler(int index, int nscreen, pointer pbdata,  
           struct timeval **pptv, pointer pReadmask)  

PurposeThis function is provided to call the next blockHandler registered. Is must be called by a device's block handler and passes all the parameters that are passed into the device's
DeviceBlockHandlerProc.
Called byThe device's DeviceBlockHandlerProc.
ResultsThe block handler that was registered just before the device's DeviceBlockHandlerProc is called.
ReturnsMakeAtomNone
Atom MakeAtom(char *name, unsigned len, Bool makeit)
PurposeThis function is provided to make an atom for a device to be passed as a parameter to AssignTypeAndName. It is passed a char pointer to the name of the device, the length of the string, and makeit equals FALSE.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsAn atom is found.
ReturnsAtom

AssignTypeAndName


  void AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name)  

PurposeThis function is provided to assign a type and name to a device. It is passed a pointer to the device, the atom returned from MakeAtom, and the char pointer to the name of the device.
Called byDeviceControlProc during the DEVICE_INIT action.
ResultsThe dev->type and dev->name entries are set to the values specified by the arguments.
ReturnsAddEnableDeviceNone
void AddEnabledDevice(int fd)
PurposeThis function is provided to cause the server to start checking for input on the device corresponding to the given file descriptor.
Called byDeviceControlProc during the DEVICE_ON action.
ResultsThe device's file descriptor is selected for pending input.
ReturnsRemoveEnableDeviceNone
void RemoveEnabledDevice(int fd)
PurposeThis function is provided to cause OpenWindows to stop checking for input on the device corresponding to the given file descriptor.
Called byDeviceControlProc during the DEVICE_OFF action.
ResultsThe device's file descriptor is no longer selected for pending input.
ReturnsNone

Device Shared Library Functions

The functions in this section are in the device shared libraries. The *DeviceHandlerCompatible, *DeviceControlProc, *DeviceEnqueueProc, and *DeviceReadProc functions are required for each device library. All other functions are optional and depend on the features a particular device supports.

DeviceHandlerCompatible


  typedef int (*DeviceHandlerCompatible)(int major, int minor,  
           int *myMajor, int *myMinor, int (**pContorlProc)());  

PurposeThis function checks for compatibility and returns the device's major and minor numbers as well as a pointer to
DeviceControlProc.
ResultsCompares the device's version number against the version number passed in. If it is incompatible, return !Success; otherwise, fill in the device major and minor number and a pointer to DeviceControlProc.
ReturnsDeviceControlProcSuccess on success !Success on failure
typedef int (*DeviceControlProc)(DevicePtr devptr, int action);
PurposeThis function allows the server to control the actions of a device.
Results....Results depend upon the given action:
DEVICE_INIT. The device registers all of its features with the server, opens the device, registers how to read it, and initializes itself.
DEVICE_ON. The device turns itself on by calling
                  AddEnabledDevice.

DEVICE_OFF. The device turns itself off by calling
                  RemoveEnabledDevice.

DEVICE_CLOSE. The device cleans up its resources and closes itself. The server is about to exit.
ReturnsDeviceEnqueueProcSuccess on success !Success on failure
typedef void (*DeviceEnqueueProc)(DevicePtr devptr,
PurposeThis function places one or more new xEvents on the global event queue.
ResultsCompletes any device specific processing on a given event, converts the event into an xEvent, and then places the event on the global event queue by calling mieqEnqueue.

Note - The memory associated with the XI_event can be freed after mieqEnqueue has been called to queue the new xEvents.

Returns....None

DeviceReadProc


  typedef XI_eventPtr (*DeviceReadProc)(DevicePtr devptr,  
           int * numev, Bool * again);  

PurposeThis function reads data from a device when there is input pending, and returns a pointer to a list of XI_events. This routine is only used for devices that can read themselves.
ResultsIf there is no data to be read, this function returns NULL, sets numev to 0, and sets again to FALSE.
If there is data to be read, this function returns a pointer to a list of XI_events and sets numev to the number of XI_events returned. The server uses again to determine if the device has more data to be read. If again is set to TRUE, the server calls this function again without reentering select. If again is set to FALSE, the function is not called again without reentering select.

Note - The server passes the list of events back to the device's enqueue function one at a time, so the memory for the XI_events is released after the device has called mieqEnqueue in the DeviceEnqueueProc.

ReturnsDeviceModifierCheckProcA pointer to a list of XI_events or NULL. numev indicating the number of events returned. again indicating the possibility of this device having more data to be read.
typedef Bool (*DeviceModifierCheckProc)(DevicePtr devptr,
PurposeThis function checks the validity of the given keycode. Checking occurs when a client is trying to set the modifier map of a device. This function is only valid for devices that support keys.
ResultsNone
ReturnsDeviceSetModeProcTRUE if the keycode is valid FALSE if the keycode is not valid
typedef int (*DeviceSetModeProc)(DevicePtr devptr, int mode);
PurposeThis function sets the mode of a device. The mode can be either Absolute or Relative. This routine applies only to devices that generate DeviceMotionNotify events.
ResultsOn success, the mode of the device is set to mode. On failure, the mode is unchanged.
ReturnsDeviceSetDeviceValuatorsProcSuccess on success !Success on failure
typedef int (*DeviceSetDeviceValuatorsProc)(DevicePtr devptr,
PurposeThis function sets the valuators of a device to the values in valuators starting with valuator first_valuator and continuing through num_valuators.
ResultsOn success, the value of the specified valuators are changed to valuators.
On failure, the value of the valuators is unchanged.
Returns....Success on success !Success on failure

DeviceChangeDeviceControlProc


  typedef int (*DeviceChangeDeviceControlProc)(DevicePtr devptr,  
           xDeviceCtl *control);  

PurposeThis function changes the specified device controls on the given input device. Currently, only the DEVICE_RESOLUTION control is supported.
ResultsOn success, the specified control is changed. On failure, the control is unchanged.
ReturnsDeviceChangeCoreKeyboardProcSuccess on success !Success on failure
typedef int (*DeviceChangeCoreKeyboardProc)(DevicePtr devptr,
PurposeThis function notifies the device that a client has requested that the device is now the core keyboard (isCore == TRUE) or that it is now not the core keyboard (isCore == FALSE). The DeviceChangeCoreKeyboardProc function must call mieqUpdateKbdPtr to notify the server that the core keyboard has been changed.
ResultsOn success, the specified control is changed. On failure, the control is unchanged.
ReturnsSuccess on success !Success on failure

DevicePointerAxisChangeProc


  typedef int (*DevicePointerAxisChangeProc)(DevicePtr devptr,  
           Bool isCore, unsigned char x, unsigned char y);  

Purpose....This function notifies the device that a client has requested that the device is now the core pointer (isCore == TRUE) or that it is now not the core pointer (isCore == FALSE).
If (isCore == TRUE), axis number x moves the pointer in the X direction and axis number y moves the pointer in the Y direction.
DevicePointerAxisChangeProc must call mieqUpdateKbdPtr() to notify the server that the core keyboard has been changed.
Results....On success, the given device becomes the new core pointer, and the old core device becomes an extension device that has its focusability set by its focusable flag.
On failure, the core pointer is unchanged.
ReturnsDeviceGetMotionProcSuccess on success !Success on failure
typedef int (*DeviceGetMotionProc)(DeviceIntPtr devptr,
PurposeThis function returns any events in the device's motion history buffer that occurred between the start and stop times.
Called byProcGetMotionEvents in dix/devices.c.
ResultsCopies any events in the device's motion history buffer that occurred between the start and stop times to coordinates.
ReturnsDeviceBellProcNumber of events copied to coordinates.
typedef void (*DeviceBellProc)(int newpercent,
PurposeThis function rings the device's bell to the specified percent of maximum.
ResultsThe device's bell is rung.
ReturnsDeviceWakeupHandlerProcNone
typedef void (*DeviceWakeupHandlerProc)(int nscreen,
PurposeDetermined by the device handler implementation.
ResultsDepends on the device handler implementation.
ReturnsDeviceBlockHandlerProcNone
typedef void (*DeviceBlockHandlerProc)(int nscreen,
PurposeDetermined by the device handler implementation.
ResultsDepends on the device handler implementation.
ReturnsNone

DevicePtrCtrlProc


  typedef void (*DevicePtrCtrlProc) (DeviceIntPtr devintptr,  
           PtrCtrl *ctrl);  

PurposeThis function allows the server to control the actions of a pointer device.
ResultsSets the value in the device's PtrCtrl structure.
ReturnsDeviceKbdCtrlProcNone
typedef void (*DeviceKbdCtrlProc) (DeviceIntPtr devintptr,
PurposeThis function allows the server to control the actions of a keyboard device.
ResultsSets the value in the device's KeybdCtrl structure.
ReturnsDeviceLedCtrlProcNone
typedef void (*DeviceLedCtrlProc) (DeviceIntPtr devintptr,
PurposeThis function allows the server to control the actions of a device with LEDs.
ResultsSets the value in the device's LedCtrl structure.
ReturnsNone

DeviceBellCtrlProc


  typedef void (*DeviceBellCtrlProc) (DeviceIntPtr devintptr,  
           BellCtrl *ctrl);  

PurposeThis function allows the server to control the actions of a device with a bell.
ResultsSets the value in the device's BellCtrl structure.
ReturnsDeviceStringCtrlProcNone
typedef void (*DeviceStringCtrlProc) (DeviceIntPtr devintptr,
PurposeThis function allows the server to control the actions of a device with a display upon which a string can be displayed.
ResultsSets the value in the device's StringCtrl structure.
ReturnsDeviceIntegerCtrlProcNone
typedef void (*DeviceIntegerCtrlProc) (DeviceIntPtr devintptr,
PurposeThis function allows the server to control the actions of a device with a display upon which an integer can be displayed.
ResultsSets the value in the device's IntegerCtrl structure.
ReturnsNone