Subversion Repositories Kolibri OS

Rev

Rev 4529 | 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. ; Get screen resolution so we can calculate absolute coordinates.
  36.         mov     eax, 14
  37.         int     0x40
  38.         mov     [screen_y], eax
  39.         and     [screen_y], 0xffff
  40.         shr     eax, 16
  41.         mov     [screen_x], eax
  42. ; Just allocate memory; no initialization needed.
  43.         movi    eax, sizeof.mouse_device_data
  44.         call    Kmalloc
  45.         ret
  46. endp
  47.  
  48. ; This procedure is called when HID layer detects disconnect of a previously
  49. ; connected mouse.
  50. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  51. proc mouse_driver_disconnect
  52. ; Free the allocated memory.
  53.         mov     eax, edi
  54.         call    Kfree
  55.         ret
  56. endp
  57.  
  58. ; This procedure is called when HID layer starts processing a new input packet
  59. ; from a mouse.
  60. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  61. proc mouse_driver_begin_packet
  62. ; Zero all variables describing the current state.
  63.         mov     [edi+mouse_device_data.buttons], 0
  64.         mov     [edi+mouse_device_data.dx], 0
  65.         mov     [edi+mouse_device_data.dy], 0
  66.         mov     [edi+mouse_device_data.wheel], 0
  67.         mov     [edi+mouse_device_data.hwheel], 0
  68.         ret
  69. endp
  70.  
  71. ; This procedure is called when HID layer processes every non-empty array field group.
  72. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  73. ; in: ecx = fields count (always nonzero), edx = pointer to fields values
  74. ; in: esi -> report_field_group
  75. ; out: CF set => array is ok, CF cleared => array should be ignored
  76. proc mouse_driver_array_overflow?
  77. ; no array fields, no overflows
  78.         stc
  79.         ret
  80. endp
  81.  
  82. ; This procedure is called from HID layer for every field.
  83. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  84. ; in: ecx = field usage, edx = value, esi -> report_field_group
  85. proc mouse_driver_input_field
  86. ; 1. Determine the handler. We process x/y moving, wheel and up to 32 buttons.
  87. ; Pass other fields to the default handler - default_driver_input_field if
  88. ; HID_DUMP_UNCLAIMED is enabled, just ignore otherwise.
  89.         cmp     ecx, USAGE_GD_X
  90.         jz      .x
  91.         cmp     ecx, USAGE_GD_Y
  92.         jz      .y
  93.         cmp     ecx, USAGE_GD_WHEEL
  94.         jz      .wheel
  95.         cmp     ecx, 0xC0238
  96.         jz      .hwheel
  97.         sub     ecx, USAGE_BUTTON_PAGE + 1
  98.         jb      .unclaimed
  99.         cmp     ecx, 32
  100.         jae     .unclaimed
  101. ; 2. This is a button.
  102. ; If a button is pressed, set the corresponding bit in the state.
  103. ; If a button is not pressed, do nothing.
  104.         test    edx, edx
  105.         jz      @f
  106.         bts     [edi+mouse_device_data.buttons], ecx
  107. @@:
  108. if ~HID_DUMP_UNCLAIMED
  109. .unclaimed:
  110. end if
  111.         ret
  112. if HID_DUMP_UNCLAIMED
  113. .unclaimed:
  114.         add     ecx, USAGE_BUTTON_PAGE + 1
  115.         jmp     default_driver_input_field
  116. end if
  117. .x:
  118. ; 3. This is x moving. For relative fields, store the value in the state.
  119. ; Pass absolute field to the default handler.
  120.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  121.         jz      .absolute_x
  122.         mov     [edi+mouse_device_data.dx], edx
  123.         ret
  124. .y:
  125. ; 4. This is y moving. For relative fields, store the value in the state,
  126. ; changing the sign: HID uses "mathematics" scheme with Y axis increasing from
  127. ; bottom to top, the kernel expects "programming" PS/2-style with Y axis
  128. ; increasing from top to bottom.
  129. ; Pass absolute fields to the default handler.
  130.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  131.         jz      .absolute_y
  132.         neg     edx
  133.         mov     [edi+mouse_device_data.dy], edx
  134.         ret
  135. .wheel:
  136. ; 5. This is wheel event. For relative fields, store the value in the state,
  137. ; changing the sign. Pass absolute fields to the default handler.
  138.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  139.         jz      .unclaimed
  140.         neg     edx
  141.         mov     [edi+mouse_device_data.wheel], edx
  142.         ret
  143. .hwheel:
  144.         test    byte [esi+report_field_group.flags], HID_FIELD_RELATIVE
  145.         jz      .unclaimed
  146.         mov     [edi+mouse_device_data.hwheel], edx
  147.         ret
  148. .absolute_x:
  149.         push    ebx
  150.         mov     eax, [screen_x]
  151.         mul     edx
  152.         mov     ebx, 0x8000
  153.         div     ebx
  154.         mov     [edi+mouse_device_data.dx], eax
  155.         or      [edi+mouse_device_data.buttons], 0x80000000
  156.         pop     ebx
  157.         ret
  158. .absolute_y:
  159.         push    ebx
  160.         mov     eax, [screen_y]
  161.         mul     edx
  162.         mov     ebx, 0x8000
  163.         div     ebx
  164.         mov     [edi+mouse_device_data.dy], eax
  165.         or      [edi+mouse_device_data.buttons], 0x40000000
  166.         pop     ebx
  167.         ret
  168. endp
  169.  
  170. ; This procedure is called when HID layer ends processing a new input packet
  171. ; from a mouse.
  172. ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device)
  173. proc mouse_driver_end_packet
  174. ; Call the kernel, passing collected state.
  175.         stdcall SetMouseData, \
  176.                 [edi+mouse_device_data.buttons], \
  177.                 [edi+mouse_device_data.dx], \
  178.                 [edi+mouse_device_data.dy], \
  179.                 [edi+mouse_device_data.wheel], \
  180.                 [edi+mouse_device_data.hwheel]
  181.         ret
  182. endp
  183.