home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / doc / extensions / xinput / porting.ms < prev    next >
Encoding:
Text File  |  1991-07-28  |  39.2 KB  |  969 lines

  1. .\" Input Extension Porting Document
  2. .EH ''''
  3. .OH ''''
  4. .EF ''''
  5. .OF ''''
  6. \0
  7. .sp 10
  8. .ce 50
  9. .ps 20
  10. \fBX11 Input Extension Porting Document
  11. .sp 2
  12. .ps 12
  13. X Version 11, Release 5
  14. .sp 16
  15. .ps 15
  16. George Sachs\0\0\0\0Hewlett-Packard
  17. .ps 12
  18. .ce 0
  19. .bp
  20. \0
  21. .sp 34
  22. .ps 14
  23. \fB\&Notice\fR
  24. .ps 9
  25. .vs 11
  26. .LP
  27. Copyright \(co 1989, 1990, 1991 by Hewlett-Packard Company, and the 
  28. Massachusetts Institute of Technology.
  29. .LP
  30. Permission to use, copy, modify, and distribute this documentation for
  31. any purpose and without fee is hereby granted, provided that the above
  32. copyright notice and this permission notice appear in all copies.
  33. MIT and Hewlett-Packard make no representations about the suitability 
  34. for any purpose of the information in this document.  It is provided "as is" 
  35. without express or implied warranty.  This document is only a draft standard
  36. of the MIT X Consortium and is therefore subject to change.
  37. .bp 1
  38. .EH '\fBX Input Extension Porting Document\fP''\fBX11, Release 5\fP'
  39. .OH '\fBX Input Extension Porting Document\fP''\fBX11, Release 5\fP'
  40. .EF ''\fB % \fP''
  41. .OF ''\fB % \fP''
  42. .\"  Force the heading counter for level 1 to one
  43. .\"
  44. .\"
  45. .\"
  46. .\"  Print table of contents to level 4 headings
  47. .\"
  48. .nr Cl 4
  49. .\"
  50. .\"  Page eject for each level 1 heading
  51. .\"
  52. .nr H1 1
  53. .nr P 1
  54. .\"
  55. .\"  Define Ch to contain the chapter string.
  56. .\"
  57. .ds Ch Porting Overview
  58. .\"
  59. .\"
  60. .\"  Pull in the layout macro package.
  61. .\"
  62. .\"
  63. .tr ~
  64. This document is intended to aid the process of integrating the 
  65. X11 Input Extension into an X server.
  66. .LP
  67. Most of the functionality provided by the input extension is 
  68. device- and implementation-independent, and should require no changes.  
  69. The functionality is implemented by
  70. routines that typically reside in the server source tree directory 
  71. extensions/server/xinput.
  72. This extension includes functions to enable and disable input extension devices,
  73. select input, grab and focus those device, query and change key 
  74. and button mappings, and others.  The only input extension requirements 
  75. for the device-dependent part of X are that the input devices be 
  76. correctly initialized and input events from those devices be correctly
  77. generated.  Device-dependent X is responsible for reading input data from 
  78. the input device hardware and if necessary, reformatting it into X events.
  79. .LP
  80. The process of initializing input extension devices is similar to that used 
  81. for the core devices, and is described in the following sections.  When
  82. multiple input devices are attached to X server, the choice of which devices
  83. to initially use as the core X pointer and keyboard is left 
  84. implementation-dependent.  It is also up to each implementation to decide
  85. whether all input devices will be opened by the server during its 
  86. initialization and kept open for the life of the server.  The alternative is
  87. to open only the X keyboard and X pointer during server initialization, and
  88. open other input devices only when requested by a client to do so.  Either
  89. type of implementation is supported by the input extension.
  90. .LP
  91. Input extension events generated by the X server use the same 32-byte xEvent
  92. wire event as do core input events.  However, additional information must be
  93. sent for input extension devices, requiring that multiple xEvents be generated
  94. each time data is received from an input extension device.  These xEvents are
  95. combined into a single client XEvent by the input extension library.  A later
  96. section of this document describes the format and generation of input extension
  97. events.
  98. .NH 1
  99. Initializing Extension Devices
  100. .LP
  101. Extension input devices are initialized in the same manner as the core 
  102. X input devices.  Device-Independent X provides functions that can be 
  103. called from DDX to initialize these devices.  Which functions are called
  104. and when will vary by implementation, and will depend on whether the 
  105. implementation opens all the input devices available to X when X is initialized,
  106. or waits until a client requests that a device be opened.
  107. In the simplest case, DDX will open all input devices as part of its
  108. initialization, when the InitInput routine is called.
  109. .NH 2
  110. Summary of Calling Sequence
  111. .LP
  112. .DS
  113. Device-Independent X       |  Device-Dependent X
  114. --------------------       |  -------------------             
  115.                            |                                        
  116. InitInput -------------->  |  - do device-specific initialization
  117.                            |                                        
  118.                            |  - call AddInputDevice  (deviceProc,AutoStart)
  119. AddInputDevice             |   
  120.   - creates DeviceIntRec   |
  121.   - records deviceProc     |
  122.   - adds new device to     | 
  123.     list of off_devices.   |
  124. sets dev->startup=AutoStart|           
  125.                            |  - call one of:                       
  126.                            |    - RegisterPointerDevice (X pointer)
  127.                            |      - processInputProc = ProcessPointerEvents
  128.                            |    - RegisterKeyboardDevice (X keyboard)
  129.                            |      - processInputProc = ProcessKeyboardEvents
  130.                            |    - RegisterOtherDevice  (extension device)
  131.                            |      - processInputProc = ProcessOtherEvents
  132.                            |                                        
  133.                            |                                        
  134. InitAndStartDevices -----> |  - calls deviceProc with parameters
  135.                            |    (DEVICE_INIT, AutoStart)
  136. sets dev->inited = return  |
  137.   value from deviceProc    |    
  138.                            |                                        
  139.                            |  - in deviceProc, do one of:                       
  140.                            |    - call InitPointerDeviceStruct (X pointer)
  141.                            |    - call InitKeyboardDeviceStruct (X keybd)
  142.                            |    - init extension device by calling some of:
  143.                            |      - InitKeyClassDeviceStruct
  144.                            |      - InitButtonClassDeviceStruct
  145.                            |      - InitValuatorClassDeviceStruct
  146.                            |      - InitValuatorAxisStruct
  147.                            |      - InitFocusClassDeviceStruct
  148.                            |      - InitProximityClassDeviceStruct
  149.                            |      - InitKbdFeedbackClassDeviceStruct
  150.                            |      - InitPtrFeedbackClassDeviceStruct
  151.                            |      - InitLedFeedbackClassDeviceStruct
  152.                            |      - InitStringFeedbackClassDeviceStruct
  153.                            |      - InitIntegerFeedbackClassDeviceStruct
  154.                            |      - InitBellFeedbackClassDeviceStruct
  155.                            |    - init device name and type by:
  156.                            |      - calling MakeAtom with one of the 
  157.                            |        predefined names
  158.                            |      - calling AssignTypeAndName
  159.                            |                                        
  160.                            |                                        
  161. for each device added      |                                        
  162.     by AddInputDevice,     |                                        
  163.     InitAndStartDevices    |                                        
  164.     calls EnableDevice if  |  - EnableDevice calls deviceProc with 
  165.     dev->startup &         |    (DEVICE_ON, AutoStart)
  166.     dev->inited            |  
  167.                            |                                        
  168. If deviceProc returns      |  - core devices are now enabled, extension
  169.     Success, EnableDevice  |    devices are now available to be accessed
  170.     move the device from   |    through the input extension protocol
  171.     inputInfo.off_devices  |    requests.                           
  172.     to inputInfo.devices   |                                        
  173. .DE
  174. .NH 2
  175. Initialization Called From InitInput
  176. .LP
  177. InitInput is the first DDX input entry point called during X server startup.
  178. This routine is responsible for
  179. device- and implementation- specific initialization, and for calling
  180. AddInputDevice to create and initialize the DeviceIntRec structure for each
  181. input device.  AddInputDevice is passed the address of a procedure to be called
  182. by the DIX routine InitAndStartDevices when input devices are enabled.
  183. This procedure is expected to perform X initialization for the input device.
  184. .LP
  185. If the device is to be used as the X pointer, DDX should then call
  186. RegisterPointerDevice, passing the DeviceIntRec pointer,
  187. to initialize the device as the X pointer.
  188. .LP
  189. If the device is to be used as the X keyboard, DDX should instead call
  190. RegisterKeyboardDevice to initialize the device as the X keyboard.
  191. .LP
  192. If the device is to be used as an extension device, DDX should instead
  193. call RegisterOtherDevice, passing the DeviceIntPtr returned by
  194. AddInputDevice.
  195. .LP
  196. A sample InitInput implementation is shown below.
  197. .LP
  198. .DS
  199. InitInput(argc,argv)
  200.     {
  201.     int i, numdevs, ReadInput();
  202.     DeviceIntPtr dev;
  203.     LocalDevice localdevs[LOCAL_MAX_DEVS];
  204.     DeviceProc kbdproc, ptrproc, extproc;
  205.  
  206.     /**************************************************************
  207.      * Open the appropriate input devices, determine which are 
  208.      * available, and choose an X pointer and X keyboard device
  209.      * in some implementation-dependent manner.
  210.      ***************************************************************/
  211.  
  212.     open_input_devices (&numdevs, localdevs);
  213.  
  214.     /**************************************************************
  215.      * Register a WakeupHandler to handle input when it is generated.
  216.      ***************************************************************/
  217.  
  218.     RegisterBlockAndWakeupHandlers (NoopDDA, ReadInput, NULL);
  219.  
  220.     /**************************************************************
  221.      * Register the input devices with DIX.
  222.      ***************************************************************/
  223.  
  224.     for (i=0; i<numdevs; i++)
  225.         {
  226.         if (localdevs[i].use == IsXKeyboard)
  227.             {
  228.             dev = AddInputDevice (kbdproc, TRUE);
  229.             RegisterKeyboardDevice (dev);
  230.             }
  231.         else if (localdevs[i].use == IsXPointer)
  232.             {
  233.             dev = AddInputDevice (ptrproc, TRUE);
  234.             RegisterPointerDevice (dev);
  235.             }
  236.         else 
  237.             {
  238.             dev = AddInputDevice (extproc, FALSE);
  239.             RegisterOtherDevice (dev);
  240.             }
  241.         if (dev == NULL)
  242.             FatalError ("Too many input devices.");
  243.         dev->devicePrivate = (pointer) &localdevs[i];
  244.         }
  245. .DE
  246. .NH 2
  247. Initialization Called From InitAndStartDevices
  248. .LP
  249. After InitInput has returned,
  250. InitAndStartDevices is the DIX routine that is called to enable input devices. 
  251. It calls the device control routine that was passed to AddInputDevice,
  252. with a mode value of DEVICE_INIT.  The action taken by the device control
  253. routine depends on how the device is to be used.  If the device is to be
  254. the X pointer, the device control routine should call
  255. InitPointerDeviceStruct to initialize it.  If the device is to be the
  256. X keyboard, the device control routine should call
  257. InitKeyboardDeviceStruct.  Since input extension devices may support various
  258. combinations of keys, buttons, valuators, and feedbacks,
  259. each class of input that it supports must be initialized.
  260. Entry points are defined by DIX to initialize each of the supported classes of
  261. input, and are described in the following sections.
  262. .LP
  263. A sample device control routine called from InitAndStartDevices is 
  264. shown below.
  265. .LP
  266. .DS
  267. Bool extproc (dev, mode)
  268.     DeviceIntPtr dev;
  269.     int mode;
  270.     {
  271.     LocalDevice *localdev = (LocalDevice *) dev->devicePrivate;
  272.  
  273.     switch (mode)
  274.         {
  275.         case DEVICE_INIT:
  276.             if (strcmp(localdev->name, XI_TABLET) == 0)
  277.                 {
  278.                 /****************************************************
  279.                  * This device reports proximity, has buttons,
  280.                  * reports two axes of motion, and can be focused.
  281.                  * It also supports the same feedbacks as the X pointer
  282.                  * (acceleration and threshold can be set).
  283.                  ****************************************************/
  284.  
  285.                 InitButtonClassDeviceStruct (dev, button_count, button_map);
  286.                 InitValuatorClassDeviceStruct (dev, localdev->n_axes,);
  287.                     motionproc, MOTION_BUF_SIZE, Absolute);
  288.                 for (i=0; i<localdev->n_axes; i++)
  289.                     InitValuatorAxisStruct (dev, i, min_val, max_val, 
  290.                         resolution);
  291.                 InitFocusClassDeviceStruct (dev);
  292.                 InitProximityClassDeviceStruct (dev);
  293.                 InitPtrFeedbackClassDeviceStruct (dev, p_controlproc);
  294.                 }
  295.             else if (strcmp(localdev->name, XI_BUTTONBOX) == 0)
  296.                 {
  297.                 /****************************************************
  298.                  * This device has keys and LEDs, and can be focused.
  299.                  ****************************************************/
  300.  
  301.                 InitKeyClassDeviceStruct (dev, syms, modmap);
  302.                 InitFocusClassDeviceStruct (dev);
  303.                 InitLedFeedbackClassDeviceStruct (dev, ledcontrol);
  304.                 }
  305.             else if (strcmp(localdev->name, XI_KNOBBOX) == 0)
  306.                 {
  307.                 /****************************************************
  308.                  * This device reports motion.
  309.                  * It can be focused.
  310.                  ****************************************************/
  311.  
  312.                 InitValuatorClassDeviceStruct (dev, localdev->n_axes,);
  313.                     motionproc, MOTION_BUF_SIZE, Absolute);
  314.                 for (i=0; i<localdev->n_axes; i++)
  315.                     InitValuatorAxisStruct (dev, i, min_val, max_val, 
  316.                         resolution);
  317.                 InitFocusClassDeviceStruct (dev);
  318.                 }
  319.             localdev->atom = 
  320.                 MakeAtom(localdev->name, strlen(localdev->name), FALSE);
  321.             AssignTypeAndName (dev, localdev->atom, localdev->name);
  322.             break;
  323.         case DEVICE_ON:
  324.             AddEnabledDevice (localdev->file_ds);
  325.             dev->on = TRUE;
  326.             break;
  327.         case DEVICE_OFF:
  328.             dev->on = FALSE;
  329.             RemoveEnabledDevice (localdev->file_ds);
  330.             break;
  331.         case DEVICE_CLOSE:
  332.             break;
  333.         }
  334.     }
  335. .DE
  336. .LP
  337. The device control routine is called with a mode value of DEVICE_ON
  338. by the DIX routine EnableDevice, which is called from InitAndStartDevices.  
  339. When called with this mode, it should call AddEnabledDevice to cause the 
  340. server to begin checking for available input from this device.
  341. .LP
  342. >From InitAndStartDevices, EnableDevice is called for all devices that have
  343. the "inited" and "startup" fields in the DeviceIntRec set to TRUE.  The
  344. "inited" field is set by InitAndStartDevices to the value returned by
  345. the deviceproc when called with a mode value of DEVICE_INIT.  The "startup"
  346. field is set by AddInputDevice to value of the second parameter (autoStart).
  347. .LP
  348. When the server is first initialized, it should only be checking for input
  349. from the core X keyboard and pointer.  One way to accomplish this is to
  350. call AddInputDevice for the core X keyboard and pointer with an
  351. autoStart value equal to TRUE, while calling AddInputDevice for 
  352. input extension devices with an autoStart value equal to FALSE.  If this is 
  353. done, EnableDevice will skip all input extension devices during server
  354. initialization.  In this case,
  355. the OpenInputDevice routine should set the "startup" field to TRUE
  356. when called for input extension devices.  This will cause ProcXOpenInputDevice
  357. to call EnableDevice for those devices when a client first does an
  358. XOpenDevice request.
  359. .NH 2
  360. DIX Input Class Initialization Routines
  361. .LP
  362. DIX routines are defined to initialize each of the defined input classes.
  363. The defined classes are:
  364. .RS
  365. .in +5n
  366. .IP "-" 3n
  367. KeyClass - the device has keys.
  368. .IP "-" 3n
  369. ButtonClass - the device has buttons.
  370. .IP "-" 3n
  371. ValuatorClass - the device reports motion data or positional data.
  372. .IP "-" 3n
  373. Proximitylass - the device reports proximity information.
  374. .IP "-" 3n
  375. FocusClass - the device can be focused.
  376. .IP "-" 3n
  377. FeedbackClass - the device supports some kind of feedback
  378. .in -5n
  379. .RE
  380. .LP
  381. DIX routines are provided to initialize the X pointer and keyboard, as in
  382. previous releases of X.  During X initialization, InitPointerDeviceStruct 
  383. is called to initialize the X pointer, and InitKeyboardDeviceStruct is
  384. called to initialize the X keyboard.  There is no
  385. corresponding routine for extension input devices, since they do not all
  386. support the same classes of input.  Instead, DDX is responsible for the 
  387. initialization of the input classes supported by extension devices.  
  388. A description of the routines provided by DIX to perform that initialization
  389. follows.
  390. .NH 3
  391. InitKeyClassDeviceStruct
  392. .LP
  393. This function is provided to allocate and initialize a KeyClassRec, and 
  394. should be called for extension devices that have keys.  It is passed a pointer
  395. to the device, and pointers to arrays of keysyms and modifiers reported by
  396. the device.  It returns FALSE if the KeyClassRec could not be allocated,
  397. or if the maps for the keysyms and and modifiers could not be allocated.
  398. Its parameters are:
  399. .LP
  400. .DS
  401. Bool
  402. InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers)
  403.     DeviceIntPtr dev;
  404.     KeySymsPtr pKeySyms;
  405.     CARD8 pModifiers[];
  406. .DE
  407. .LP
  408. The DIX entry point InitKeyboardDeviceStruct calls this routine for the
  409. core X keyboard.  It must be called explicitly for extension devices
  410. that have keys.
  411. .NH 3
  412. InitButtonClassDeviceStruct
  413. .LP
  414. This function is provided to allocate and initialize a ButtonClassRec, and 
  415. should be called for extension devices that have buttons.  It is passed a 
  416. pointer to the device, the number of buttons supported, and a map of the 
  417. reported button codes.  It returns FALSE if the ButtonClassRec could not be 
  418. allocated.  Its parameters are:
  419. .LP
  420. .DS
  421. Bool
  422. InitButtonClassDeviceStruct(dev, numButtons, map)
  423.     register DeviceIntPtr dev;
  424.     int numButtons;
  425.     CARD8 *map;
  426. .DE
  427. .LP
  428. The DIX entry point InitPointerDeviceStruct calls this routine for the
  429. core X pointer.  It must be called explicitly for extension devices that
  430. have buttons.
  431. .NH 3
  432. InitValuatorClassDeviceStruct
  433. .LP
  434. This function is provided to allocate and initialize a ValuatorClassRec, and 
  435. should be called for extension devices that have valuators.  It is passed the
  436. number of axes of motion reported by the device, the address of the motion
  437. history procedure for the device, the size of the motion history buffer,
  438. and the mode (Absolute or Relative) of the device.  It returns FALSE if 
  439. the ValuatorClassRec could not be allocated.  Its parameters are:
  440. .LP
  441. .DS
  442. Bool
  443. InitValuatorClassDeviceStruct(dev, numAxes, motionProc, numMotionEvents, mode)
  444.     DeviceIntPtr dev;
  445.     int (*motionProc)();
  446.     int numAxes;
  447.     int numMotionEvents;
  448.     int mode;
  449. .DE
  450. .LP
  451. The DIX entry point InitPointerDeviceStruct calls this routine for the
  452. core X pointer.  It must be called explicitly for extension devices that
  453. report motion.
  454. .NH 3
  455. InitValuatorAxisStruct
  456. .LP
  457. This function is provided to initialize an XAxisInfoRec, and 
  458. should be called for core and extension devices that have valuators.  
  459. The space for the XAxisInfoRec is allocated by 
  460. the InitValuatorClassDeviceStruct function, but is not initialized.
  461. .LP
  462. InitValuatorAxisStruct should be called once for each axis of motion 
  463. reported by the device.  Each
  464. invocation should be passed the axis number (starting with 0), the
  465. minimum value for that axis, the maximum value for that axis, and the
  466. resolution of the device in counts per meter.  If the device reports
  467. relative motion, 0 should be reported as the minimum and maximum values.
  468. InitValuatorAxisStruct has the following parameters:
  469. .DS
  470. InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution)
  471.     DeviceIntPtr dev;
  472.     int axnum;
  473.     int minval;
  474.     int maxval;
  475.     int resolution;
  476. .DE
  477. .LP
  478. This routine is not called by InitPointerDeviceStruct for the
  479. core X pointer.  It must be called explicitly for core and extension devices 
  480. that report motion.
  481. .NH 3
  482. InitFocusClassDeviceStruct
  483. .LP
  484. This function is provided to allocate and initialize a FocusClassRec, and 
  485. should be called for extension devices that can be focused.  It is passed a
  486. pointer to the device, and returns FALSE if the allocation fails.
  487. It has the following parameter:
  488. .DS
  489. Bool
  490. InitFocusClassDeviceStruct(dev)
  491.     DeviceIntPtr dev;
  492. .DE
  493. .LP
  494. The DIX entry point InitKeyboardDeviceStruct calls this routine for the
  495. core X keyboard.  It must be called explicitly for extension devices
  496. that can be focused.  Whether or not a particular device can be focused
  497. is left implementation-dependent.
  498. .NH 3
  499. InitProximityClassDeviceStruct
  500. .LP
  501. This function is provided to allocate and initialize a ProximityClassRec, and 
  502. should be called for extension absolute pointing devices that report proximity.
  503. It is passed a pointer to the device, and returns FALSE if the allocation fails.
  504. It has the following parameter:
  505. .DS
  506. Bool
  507. InitProximityClassDeviceStruct(dev)
  508.     DeviceIntPtr dev;
  509. .DE
  510. .NH 3
  511. Initializing Feedbacks
  512. .LP
  513. .NH 4
  514. InitKbdFeedbackClassDeviceStruct
  515. .LP
  516. This function is provided to allocate and initialize a KbdFeedbackClassRec, and 
  517. may be called for extension devices that support some or all of the 
  518. feedbacks that the core keyboard supports.  It is passed a
  519. pointer to the device, a pointer to the procedure that sounds the bell,
  520. and a pointer to the device control procedure.
  521. It returns FALSE if the allocation fails, and has the following parameters:
  522. .DS
  523. Bool
  524. InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc)
  525.     DeviceIntPtr dev;
  526.     void (*bellProc)();
  527.     void (*controlProc)();
  528. .DE
  529. The DIX entry point InitKeyboardDeviceStruct calls this routine for the
  530. core X keyboard.  It must be called explicitly for extension devices
  531. that have the same feedbacks as a keyboard.  Some feedbacks, such as LEDs and
  532. bell, can be supported either with a KbdFeedbackClass or with BellFeedbackClass
  533. and LedFeedbackClass feedbacks.
  534. .NH 4
  535. InitPtrFeedbackClassDeviceStruct
  536. .LP
  537. This function is provided to allocate and initialize a PtrFeedbackClassRec, and 
  538. should be called for extension devices that allow the setting of acceleration
  539. and threshold.  It is passed a pointer to the device,
  540. and a pointer to the device control procedure.
  541. It returns FALSE if the allocation fails, and has the following parameters:
  542. .DS
  543. Bool
  544. InitPtrFeedbackClassDeviceStruct(dev, controlProc)
  545.     DeviceIntPtr dev;
  546.     void (*controlProc)();
  547. .DE
  548. .LP
  549. The DIX entry point InitPointerDeviceStruct calls this routine for the
  550. core X pointer.  It must be called explicitly for extension devices
  551. that support the setting of acceleration and threshold.
  552. .NH 4
  553. InitLedFeedbackClassDeviceStruct
  554. .LP
  555. This function is provided to allocate and initialize a LedFeedbackClassRec, and 
  556. should be called for extension devices that have LEDs.
  557. It is passed a pointer to the device,
  558. and a pointer to the device control procedure.
  559. It returns FALSE if the allocation fails, and has the following parameters:
  560. .DS
  561. Bool
  562. InitLedFeedbackClassDeviceStruct(dev, controlProc)
  563.     DeviceIntPtr dev;
  564.     void (*controlProc)();
  565. .DE
  566. .LP
  567. Up to 32 LEDs per feedback can be supported, and a device may have 
  568. multiple feedbacks of the same type.
  569. .NH 4
  570. InitBellFeedbackClassDeviceStruct
  571. .LP
  572. This function is provided to allocate and initialize a BellFeedbackClassRec, 
  573. and should be called for extension devices that have a bell.
  574. It is passed a pointer to the device,
  575. and a pointer to the device control procedure.
  576. It returns FALSE if the allocation fails, and has the following parameters:
  577. .DS
  578. Bool
  579. InitBellFeedbackClassDeviceStruct(dev, bellProc, controlProc)
  580.     DeviceIntPtr dev;
  581.     void (*bellProc)();
  582.     void (*controlProc)();
  583. .DE
  584. .NH 4
  585. InitStringFeedbackClassDeviceStruct
  586. .LP
  587. This function is provided to allocate and initialize a StringFeedbackClassRec, 
  588. and should be called for extension devices that have a display upon which a 
  589. string can be displayed.
  590. It is passed a pointer to the device,
  591. and a pointer to the device control procedure.
  592. It returns FALSE if the allocation fails, and has the following parameters:
  593. .DS
  594. Bool
  595. InitStringFeedbackClassDeviceStruct(dev, controlProc, max_symbols, 
  596.     num_symbols_supported, symbols)
  597.     DeviceIntPtr dev;
  598.     void (*controlProc)();
  599.     int max_symbols:
  600.     int num_symbols_supported;
  601.     KeySym *symbols;
  602. .DE
  603. .NH 4
  604. InitIntegerFeedbackClassDeviceStruct
  605. .LP
  606. This function is provided to allocate and initialize an 
  607. IntegerFeedbackClassRec, 
  608. and should be called for extension devices that have a display upon which an
  609. integer can be displayed.
  610. It is passed a pointer to the device,
  611. and a pointer to the device control procedure.
  612. It returns FALSE if the allocation fails, and has the following parameters:
  613. .DS
  614. Bool
  615. InitIntegerFeedbackClassDeviceStruct(dev, controlProc)
  616.     DeviceIntPtr dev;
  617.     void (*controlProc)();
  618. .DE
  619. .NH 2
  620. Initializing The Device Name And Type
  621. .LP
  622. The device name and type can be initialized by calling AssignTypeAndName
  623. with the following parameters:
  624. .DS
  625. void
  626. AssignTypeAndName(dev, type, name)
  627.     DeviceIntPtr dev;
  628.     Atom type;
  629.     char *name;
  630. .DE
  631. .LP
  632. This will allocate space for the device name and copy the name that was passed.
  633. The device type can be obtained by calling MakeAtom with one of the names
  634. defined for input devices.  MakeAtom has the following parameters:
  635. .DS
  636. Atom
  637. MakeAtom(name, len, makeit)
  638.     char *name;
  639.     int len;
  640.     Bool makeit;
  641. .DE
  642. .LP
  643. Since the atom was already made when the input extension was initialized, the
  644. value of makeit should be FALSE;
  645. .NH 1
  646. Closing Extension Devices
  647. .LP
  648. The DisableDevice entry point is provided by DIX to disable input devices.
  649. It calls the device control routine for the specified
  650. device with a mode value of DEVICE_OFF.  The device control routine should
  651. call RemoveEnabledDevice to stop the server from checking for input from
  652. that device.
  653. .LP
  654. DisableDevice is not called by any input extension routines.  It can be 
  655. called from the CloseInputDevice routine, which is called by
  656. ProcXCloseDevice when a client makes an XCloseDevice request.  If
  657. DisableDevice is called, it should only be called when the last client
  658. using the extension device has terminated or called XCloseDevice.
  659. .NH 1
  660. Implementation-Dependent Routines
  661. .LP
  662. Several input extension protocol requests have 
  663. implementation-dependent  entry points.  Default routines
  664. are defined for these entry points and contained in the source
  665. file extensions/server/xinput/xstubs.c.  Some implementations may
  666. be able to use the default routines without change.
  667. The following sections describe each of these routines.
  668. .NH 2
  669. AddOtherInputDevices
  670. .LP
  671. AddOtherInputDevice is called from ProcXListInputDevices as a result of 
  672. an XListInputDevices protocol request.  It may be needed by
  673. implementations that do not open extension input devices until requested
  674. to do so by some client.  These implementations may not initialize
  675. all devices when the X server starts up, because some of those devices
  676. may be in use.  Since the XListInputDevices
  677. function only lists those devices that have been initialized,
  678. AddOtherInputDevices is called to give DDX a chance to 
  679. initialize any previously unavailable input devices.
  680. .LP
  681. A sample AddOtherInputDevices routine might look like the following:
  682. .DS
  683. void
  684. AddOtherInputDevices ()
  685.     {
  686.     DeviceIntPtr dev;
  687.     int i;
  688.  
  689.     for (i=0; i<MAX_DEVICES; i++) 
  690.         {
  691.         if (!local_dev[i].initialized && available(local_dev[i]))
  692.             {
  693.             dev = (DeviceIntPtr) AddInputDevice (local_dev[i].deviceProc, TRUE);
  694.             dev->public.devicePrivate = local_dev[i];
  695.             RegisterOtherDevice (dev);
  696.             dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
  697.             }
  698.         }
  699.     }
  700. .DE
  701. .LP
  702. The default AddOtherInputDevices routine in xstubs.c does nothing.
  703. If all input extension devices are initialized when the server 
  704. starts up, it can be left as a null routine.
  705. .NH 2
  706. OpenInputDevice
  707. .LP
  708. Some X server implementations open all input devices when the server
  709. is initialized and never close them.  Other implementations may open only
  710. the X pointer and keyboard devices during server initialization,
  711. and open other input devices only when some client makes an
  712. XOpenDevice request.  This entry point is for the latter type of 
  713. implementation.
  714. .LP
  715. If the physical device is not already open, it can be done in this routine.  
  716. In this case, the server must keep track of the fact that one or more clients 
  717. have the device open, and physically close it when the last client that has
  718. it open makes an XCloseDevice request.
  719. .LP
  720. The default implementation is to do nothing (assume all input devices
  721. are opened during X server initialization and kept open).
  722. .NH 2
  723. CloseInputDevice
  724. .LP
  725. Some implementations may close an input device when the last client
  726. using that device requests that it be closed, or terminates.
  727. CloseInputDevice is called from ProcXCloseDevice when a client
  728. makes an XCloseDevice protocol request.
  729. .LP
  730. The default implementation is to do nothing (assume all input devices
  731. are opened during X server initialization and kept open).
  732. .NH 2
  733. SetDeviceMode
  734. .LP
  735. Some implementations support input devices that can report 
  736. either absolute positional data or relative motion.  The XSetDeviceMode
  737. protocol request is provided to allow DDX to change the current mode of 
  738. such a device.
  739. .LP
  740. The default implementation is to always return a BadMatch error.  If the
  741. implementation does not support any input devices that are capable of 
  742. reporting both relative motion and absolute position information, the
  743. default implementation may be left unchanged.
  744. .NH 2
  745. SetDeviceValuators
  746. .LP
  747. Some implementations support input devices that allow their valuators to be 
  748. set to an initial value.  The XSetDeviceValuators 
  749. protocol request is provided to allow DDX to set the valuators of
  750. such a device.
  751. .LP
  752. The default implementation is to always return a BadMatch error.  If the
  753. implementation does not support any input devices that are allow their
  754. valuators to be set, the default implementation may be left unchanged.
  755. .NH 2
  756. ChangePointerDevice
  757. .LP
  758. The XChangePointerDevice protocol request is provided to change which device is
  759. used as the X pointer.  Some implementations may maintain information
  760. specific to the X pointer in the private data structure pointed to by
  761. the DeviceIntRec.  ChangePointerDevice is called to allow such 
  762. implementations to move that information to the new pointer device.
  763. The current location of the X cursor is an example of the type of 
  764. information that might be affected.
  765. .LP
  766. The DeviceIntRec structure that describes the X pointer device does not 
  767. contain a FocusRec.  If the device that has been made into the new X pointer 
  768. was previously a device that could be focused, ProcXChangePointerDevice will 
  769. free the FocusRec associated with that device.
  770. .LP
  771. If the server implementation desires to allow clients to focus the old pointer 
  772. device (which is now accessible through the input extension), it should call
  773. InitFocusClassDeviceStruct for the old pointer device.
  774. .LP
  775. The XChangePointerDevice protocol request also allows the client
  776. to choose which axes of the new pointer device are used to move 
  777. the X cursor in the X- and Y- directions.  If the axes are different
  778. than the default ones, the server implementation should record that fact.
  779. .LP
  780. If the server implementation supports input devices with valuators that 
  781. are not allowed to be used as the X pointer, they should be screened out
  782. by this routine and a  BadDevice error returned.
  783. .LP
  784. The default implementation is to do nothing. 
  785. .NH 2
  786. ChangeKeyboardDevice
  787. .LP
  788. The XChangeKeyboardDevice protocol request is provided to change which device is
  789. used as the X keyboard.  Some implementations may maintain information
  790. specific to the X keyboard in the private data structure pointed to by
  791. the DeviceIntRec.  ChangeKeyboardDevice is called to allow such 
  792. implementations to move that information to the new keyboard device.
  793. .LP
  794. The X keyboard device can be focused, and the DeviceIntRec that describes
  795. that device has a FocusRec.  If the device that has been made into the new X 
  796. keyboard did not previously have a FocusRec, 
  797. ProcXChangeKeyboardDevice will allocate one for it.
  798. .LP
  799. If the implementation does not want clients to be able to focus the old X 
  800. keyboard (which has now become available as an input extension device)
  801. it should call DeleteFocusClassDeviceStruct to free the FocusRec.
  802. .LP
  803. If the implementation supports input devices with keys that are not allowed
  804. to be used as the X keyboard, they should be checked for here, and a
  805. BadDevice error returned.
  806. .LP
  807. The default implementation is to do nothing. 
  808. .NH 1
  809. Input Extension Events
  810. .LP
  811. Events accessed through the input extension are analogous to the core input
  812. events, but have different event types.  They are of types 
  813. \fBDeviceKeyPress\fP, \fBDeviceKeyRelease\fP, \fBDeviceButtonPress\fP,
  814. \fBDeviceButtonRelease\fP, \fBDeviceDeviceMotionNotify\fP,
  815. \fBDeviceProximityIn\fP, \fBDeviceProximityOut\fP, and \fBDeviceValuator\fP.
  816. These event types are not constants.  Instead, they are external integers 
  817. defined by the input extension.  Their actual values will depend on which
  818. extensions are supported by a server, and the order in which they are
  819. initialized.
  820. .LP
  821. The data structures that define these
  822. events are defined in the file \fBextensions/include/XIproto.h\fP.  Other
  823. input extension constants needed by DDX are defined in the file
  824. \fBextensions/include/XI.h\fP.
  825. .LP
  826. Some events defined by the input extension contain more information than can
  827. be contained in the 32-byte xEvent data structure.  To send this information
  828. to clients, DDX must generate two or more 32-byte wire events.  The following
  829. sections describe the contents of these events. 
  830. .NH 2
  831. Device Key Events
  832. .LP
  833. \fBDeviceKeyPresss\fP events contain all the information that is contained in
  834. a core \fBKeyPress\fP event, and also the following additional information:
  835. .LP
  836. .RS
  837. .in +5n
  838. .IP "-" 3n
  839. deviceid - the identifier of the device that generated the event.
  840. .IP "-" 3n
  841. device_state - the state of any modifiers on the device that generated the event
  842. .IP "-" 3n
  843. num_valuators - the number of valuators reported in this event.
  844. .IP "-" 3n
  845. first_valuator - the first valuator reported in this event.
  846. .IP "-" 3n
  847. valuator0 through valuator5 - the values of the valuators.
  848. .in -5n
  849. .RE
  850. .LP
  851. In order to pass this information to the input extension library, two 32-byte
  852. wire events must be generated by DDX.  The first has an event type of 
  853. \fBDeviceKeyPress\fP, and the second has an event type of \fPDeviceValuator\fP.
  854. .LP
  855. The following code fragment shows how the two wire events could be initialized:
  856. .LP
  857. .DS
  858.     extern int DeviceKeyPress;
  859.     DeviceIntPtr dev;
  860.     xEvent xE[2];
  861.     CARD8 id, num_valuators;
  862.     INT16 x, y, pointerx, pointery;
  863.     Time timestamp;
  864.     deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *) xE;
  865.     deviceValuator *xv;
  866.  
  867.     xev->type = DeviceKeyPress;                /* defined by input extension */
  868.     xev->detail = keycode;              /* key pressed on this device */
  869.     xev->time = timestamp;              /* same as for core events    */
  870.     xev->rootX = pointerx;              /* x location of core pointer */
  871.     xev->rootY = pointery;              /* y location of core pointer */
  872.  
  873.     /******************************************************************/
  874.     /*                                                                */
  875.     /* The following field does not exist for core input events.      */
  876.     /* It contains the device id for the device that generated the    */
  877.     /* event, and also indicates whether more than one 32-byte wire   */
  878.     /* event is being sent.                                           */
  879.     /*                                                                */
  880.     /******************************************************************/
  881.  
  882.     xev->deviceid = dev->id | MORE_EVENTS;        /* sending more than 1*/
  883.  
  884.     /******************************************************************/
  885.     /* Fields in the second 32-byte wire event:                       */
  886.     /******************************************************************/
  887.  
  888.     xv = (deviceValuator *) ++xev;
  889.     xv->type = DeviceValuator;          /* event type of second event */
  890.     xv->deviceid = dev->id;             /* id of this device          */
  891.     xv->num_valuators = 0;              /* no valuators being sent    */
  892.     xv->device_state  = 0;              /* will be filled in by DIX   */
  893. .DE
  894. .NH 2
  895. Device Button Events
  896. .LP
  897. \fBDeviceButton\fP events contain all the information that is contained in
  898. a core button event, and also the same additional information that a 
  899. \fBDeviceKey\fP event contains.
  900. .NH 2
  901. Device Motion Events
  902. .LP
  903. \fBDeviceMotion\fP events contain all the information that is contained in
  904. a core motion event, and also additional valuator information.  At least
  905. two wire events are required to contain this information.
  906. The following code fragment shows how the two wire events could be initialized:
  907. .LP
  908. .DS
  909.     extern int DeviceMotionNotify;
  910.     DeviceIntPtr dev;
  911.     xEvent xE[2];
  912.     CARD8 id, num_valuators;
  913.     INT16 x, y, pointerx, pointery;
  914.     Time timestamp;
  915.     deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *) xE;
  916.     deviceValuator *xv;
  917.  
  918.     xev->type = DeviceMotionNotify;     /* defined by input extension */
  919.     xev->detail = keycode;              /* key pressed on this device */
  920.     xev->time = timestamp;              /* same as for core events    */
  921.     xev->rootX = pointerx;              /* x location of core pointer */
  922.     xev->rootY = pointery;              /* y location of core pointer */
  923.  
  924.     /******************************************************************/
  925.     /*                                                                */
  926.     /* The following field does not exist for core input events.      */
  927.     /* It contains the device id for the device that generated the    */
  928.     /* event, and also indicates whether more than one 32-byte wire   */
  929.     /* event is being sent.                                           */
  930.     /*                                                                */
  931.     /******************************************************************/
  932.  
  933.     xev->deviceid = dev->id | MORE_EVENTS;        /* sending more than 1*/
  934.  
  935.     /******************************************************************/
  936.     /* Fields in the second 32-byte wire event:                       */
  937.     /******************************************************************/
  938.  
  939.     xv = (deviceValuator *) ++xev;
  940.     xv->type = DeviceValuator;          /* event type of second event */
  941.     xv->deviceid = dev->id;             /* id of this device          */
  942.     xv->num_valuators = 2;              /* 2 valuators being sent     */
  943.     xv->first_valuator = 0;             /* first valuator being sent  */
  944.     xv->device_state  = 0;              /* will be filled in by DIX   */
  945.     xv->valuator0 = x;                  /* first axis of this device  */
  946.     xv->valuator1 = y;                  /* second axis of this device */
  947. .DE
  948. .LP
  949. Up to six axes can be reported in the deviceValuator event.  If the device
  950. is reporting more than 6 axes, additional pairs of DeviceMotionNotify and
  951. DeviceValuator events should be sent,  with the first_valuator field
  952. set correctly.
  953. .NH 2
  954. Device Proximity Events
  955. .LP
  956. Some input devices that report absolute positional information, such as 
  957. graphics tablets and touchscreens, may report proximity events.  
  958. \fBProximityIn\fP
  959. events are generated when a pointing device like a stylus, or in the case
  960. of a touchscreen, the user's finger, comes into close proximity with the
  961. surface of the input device.  \fBProximityOut\fP events are generated when
  962. the stylus or finger leaves the proximity of the input devices surface.
  963. .LP
  964. \fBProximity\fP events contain almost the same information as button events.
  965. The event type is \fBProximityIn\fP or \fBProximityOut\fP, and there is no
  966. detail information.
  967. .bp
  968. .TC
  969.