Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; HID mouse driver, part of USBHID driver.
  2.  
  3. ; Global constants.
  4. ; They are assembled in a macro to separate code and data;
  5. ; the code is located at the point of "include 'mouse.inc'",
  6. ; the data are collected when workers_globals is instantiated.
  7. macro workers_globals
  8. {
  9. ; include global constants from previous workers
  10.         workers_globals
  11. align 4
  12. ; Callbacks for HID layer.
  13. mouse_driver:
  14.         dd      mouse_driver_add_device
  15.         dd      mouse_driver_disconnect
  16.         dd      mouse_driver_begin_packet
  17.         dd      mouse_driver_array_overflow?
  18.         dd      mouse_driver_input_field
  19.         dd      mouse_driver_end_packet
  20. }
  21.  
  22. ; Data that are specific for one mouse device.
  23. struct mouse_device_data
  24. buttons         dd      ?       ; buttons that are currently pressed
  25. dx              dd      ?       ; current x moving
  26. dy              dd      ?       ; current y moving
  27. wheel           dd      ?       ; current wheel moving
  28. hwheel          dd      ?
  29. ends
  30.  
  31. ; This procedure is called when HID layer detects a new mouse.
  32. ; in: ebx -> device_data from USB layer, edi -> collection
  33. ; out: eax = device-specific data or NULL on error
  34. proc mouse_driver_add_device
  35. ; Just allocate memory; no initialization needed.
  36.         movi    eax, sizeof.mouse_device_data
  37.         call    Kmalloc
  38.         ret
  39. endp
  40.  
  41. ; This procedure is called when HID layer detects disconnect of a previously
  42. ; connected mouse.
  43. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  44. proc mouse_driver_disconnect
  45. ; Free the allocated memory.
  46.         mov     eax, edi
  47.         call    Kfree
  48.         ret
  49. endp
  50.  
  51. ; This procedure is called when HID layer starts processing a new input packet
  52. ; from a mouse.
  53. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  54. proc mouse_driver_begin_packet
  55. ; Zero all variables describing the current state.
  56.         mov     [edi+mouse_device_data.buttons], 0
  57.         mov     [edi+mouse_device_data.dx], 0
  58.         mov     [edi+mouse_device_data.dy], 0
  59.         mov     [edi+mouse_device_data.wheel], 0
  60.         mov     [edi+mouse_device_data.hwheel], 0
  61.         ret
  62. endp
  63.  
  64. ; This procedure is called when HID layer processes every non-empty array field group.
  65. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  66. ; in: ecx = fields count (always nonzero), edx = pointer to fields values
  67. ; in: esi -> report_field_group
  68. ; out: CF set => array is ok, CF cleared => array should be ignored
  69. proc mouse_driver_array_overflow?
  70. ; no array fields, no overflows
  71.         stc
  72.         ret
  73. endp
  74.  
  75. ; This procedure is called from HID layer for every field.
  76. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  77. ; in: ecx = field usage, edx = value, esi -> report_field_group
  78. proc mouse_driver_input_field
  79. ; 1. Determine the handler. We process x/y moving, wheel and up to 32 buttons.
  80. ; Pass other fields to the default handler - default_driver_input_field if
  81. ; HID_DUMP_UNCLAIMED is enabled, just ignore otherwise.
  82.         cmp     ecx, USAGE_GD_X
  83.         jz      .x
  84.         cmp     ecx, USAGE_GD_Y
  85.         jz      .y
  86.         cmp     ecx, USAGE_GD_WHEEL
  87.         jz      .wheel
  88.         cmp     ecx, 0xC0238
  89.         jz      .hwheel
  90.         sub     ecx, USAGE_BUTTON_PAGE + 1
  91.         jb      .unclaimed
  92.         cmp     ecx, 32
  93.         jae     .unclaimed
  94. ; 2. This is a button.
  95. ; If a button is pressed, set the corresponding bit in the state.
  96. ; If a button is not pressed, do nothing.
  97.         test    edx, edx
  98.         jz      @f
  99.         bts     [edi+mouse_device_data.buttons], ecx
  100. @@:
  101. if ~HID_DUMP_UNCLAIMED
  102. .unclaimed:
  103. end if
  104.         ret
  105. if HID_DUMP_UNCLAIMED
  106. .unclaimed:
  107.         add     ecx, USAGE_BUTTON_PAGE + 1
  108.         jmp     default_driver_input_field
  109. end if
  110. .x:
  111. ; 3. This is x moving. For relative fields, store the value in the state.
  112. ; Pass absolute field to the default handler.
  113.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  114.         jz      .unclaimed
  115.         mov     [edi+mouse_device_data.dx], edx
  116.         ret
  117. .y:
  118. ; 4. This is y moving. For relative fields, store the value in the state,
  119. ; changing the sign: HID uses "mathematics" scheme with Y axis increasing from
  120. ; bottom to top, the kernel expects "programming" PS/2-style with Y axis
  121. ; increasing from top to bottom.
  122. ; Pass absolute fields to the default handler.
  123.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  124.         jz      .unclaimed
  125.         neg     edx
  126.         mov     [edi+mouse_device_data.dy], edx
  127.         ret
  128. .wheel:
  129. ; 5. This is wheel event. For relative fields, store the value in the state,
  130. ; changing the sign. Pass absolute fields to the default handler.
  131.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  132.         jz      .unclaimed
  133.         neg     edx
  134.         mov     [edi+mouse_device_data.wheel], edx
  135.         ret
  136. .hwheel:
  137.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  138.         jz      .unclaimed
  139.         mov     [edi+mouse_device_data.hwheel], edx
  140.         ret
  141. endp
  142.  
  143. ; This procedure is called when HID layer ends processing a new input packet
  144. ; from a mouse.
  145. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  146. proc mouse_driver_end_packet
  147. ; Call the kernel, passing collected state.
  148.         stdcall SetMouseData, \
  149.                 [edi+mouse_device_data.buttons], \
  150.                 [edi+mouse_device_data.dx], \
  151.                 [edi+mouse_device_data.dy], \
  152.                 [edi+mouse_device_data.wheel], \
  153.                 [edi+mouse_device_data.hwheel]
  154.         ret
  155. endp
  156.