Alternative library and kernel for add-in development on fx-9860G and fx-CG50 under Linux.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

keyboard.h 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //---
  2. // gint:keyboard - Keyboard input
  3. //---
  4. #ifndef GINT_KEYBOARD
  5. #define GINT_KEYBOARD
  6. /* Keyboard, key events, keydown() and getkey()
  7. gint's keyboard driver regularly scans the keyboard matrix and produces *key
  8. events*. A key event basically says that a key has been pressed or released
  9. at some point in time. Key events are a faithful description of everything
  10. that happens on the keyboard.
  11. These key events are stored in the *event queue*, from where they can be
  12. retrieved:
  13. * pollevent() fetches the next keyboard event waiting in the queue. Events
  14. will always be returned in chronological order. If there is no keyboard
  15. event pending (ie. if nothing happened since last time events were read),
  16. this function returns a dummy event of type KEYEV_NONE.
  17. * waitevent() fetches the next keyboard event waiting in the queue. If the
  18. queue is empty, it waits until one becomes available or a timeout expires,
  19. whichever comes first. The timeout can be configured.
  20. When events have been read, other functions can be read to check whether a
  21. certain key (or set of keys) is pressed.
  22. * keydown() checks if the specified key is currently pressed. (*)
  23. * keydown_all() checks if all keys of a specified list are pressed. The list
  24. should end with value 0.
  25. * keydown_any() checks if any key of a specified list is pressed. The list
  26. should end with value 0.
  27. (*) The keydown() functions do not report the absolute current state of the
  28. key, but rather the state of the key according to the events that have
  29. been retrieved so far. If the queue contains {KEY_A, KEYEV_DOWN} and
  30. {KEY_A, KEYEV_UP}, the following sequence of events will happen:
  31. keydown(KEY_A) -> 0
  32. pollevent() -> {KEY_A, KEYEV_DOWN}
  33. keydown(KEY_A) -> 1
  34. pollevent() -> {KEY_A, KEYEV_UP}
  35. keydown(KEY_A) -> 0
  36. Synchronizing keydown() and the events increases the accuracy of
  37. keyboard information for fast programs and its reliability for slow
  38. programs.
  39. When all events have been read from the queue, keydown() returns the
  40. absolute current key state, which is what will happen 90% of the time.
  41. Applications that are not interested in event contents but only in pressed
  42. keys can automatically read all events from the queue before they start
  43. using keydown():
  44. * clearevents() reads all pending events from the input queue.
  45. The previous functions are quite low-level. GUI programs that look like the
  46. system applications will prefer using a GetKey()-like functions that return
  47. a single key press at a time, heeds for releases, for SHIFT and ALPHA
  48. modifiers, handles repeats, backlight and return-to-menu.
  49. * getkey_opt() is gint's enhanced GetKey()-like function, with support for
  50. custom repetition and many fine-tunable options.
  51. * getkey() is a specific call to getkey_opt(), that imitates GetKey().
  52. These functions introduce a new type of key event called KEYEV_HOLD which
  53. represents a key repeat. */
  54. #include <gint/defs/types.h>
  55. #include <gint/keycodes.h>
  56. /* key_event_t: Low-level or high-level keyboard event
  57. This structure represents an event that occurs on the keyboard. It is first
  58. produced by the keyboard scanner with limited information, then possibly
  59. enriched by getkey(). Events are produced each time the keyboard is scanned,
  60. which is 128 Hz by default. Hence, a key press and release occuring in less
  61. than 8 ms might not be detected.
  62. getkey() returns enriched events with [mod=1], in whic ase [shift] and
  63. [alpha] indicate whether the key has been modified. Only key press events
  64. returned by getkey() have [mod=1]. Note that you can't have, e.g.
  65. [key=KEY_SHIFT] and [mod=1] at the same time.
  66. The [time] attribute indicates when the event occurred. It is a snapshot of
  67. a time counter that increases at each keyboard scan and *wraps around every
  68. 8 minutes* (at 128 Hz). I expect this attribute to be useful to analyze
  69. combo sequences in games. Make sure you are aware of the two nitpicks:
  70. * Don't keep the time values for too long because of the wrap-around effect.
  71. * 0xffff is "just before" 0x0000, not "long after". */
  72. typedef struct
  73. {
  74. uint time :16; /* Time of event, unique over short periods */
  75. uint :3; /* Reserved for future use */
  76. uint mod :1; /* Whether modifiers are used */
  77. uint shift :1; /* If mod=1, whether SHIFT was pressed */
  78. uint alpha :1; /* If mod=1, whether ALPHA was pressed */
  79. uint type :2; /* Type of key event */
  80. uint key :8; /* Hit key */
  81. } GPACKED(4) key_event_t;
  82. /* Keyboard event types, as in the [type] field of key_event_t */
  83. enum
  84. {
  85. KEYEV_NONE = 0, /* No event available (poll() only) */
  86. KEYEV_DOWN = 1, /* Key was pressed */
  87. KEYEV_UP = 2, /* Key was released */
  88. KEYEV_HOLD = 3, /* A key that was pressed has been held down */
  89. };
  90. /* Size of the buffer event queue, can be customized using gint's configure
  91. script before compiling the library. Better be a power of 2. */
  92. #ifndef KEYBOARD_QUEUE_SIZE
  93. #define KEYBOARD_QUEUE_SIZE 64
  94. #endif
  95. /* Keyboard frequency analysis, must be at least 64 for the keyboard to work,
  96. and at most 32768 for the extra timer to support it. Better if a power of 2.
  97. TODO: Add a configure or runtime setting for KEYBOARD_SCAN_FREQUENCY */
  98. #ifndef KEYBOARD_SCAN_FREQUENCY
  99. #define KEYBOARD_SCAN_FREQUENCY 128
  100. #endif
  101. //---
  102. // Event-level functions
  103. //---
  104. /* pollevent(): Poll the next keyboard event
  105. This function returns the next event from the event queue, chronologically.
  106. If no event is available, it returns a dummy event with type=KEYEV_NONE
  107. and time set to the current driver time. This function always returns events
  108. with mod=0. */
  109. key_event_t pollevent(void);
  110. /* waitevent(): Wait for the next keyboard event
  111. This function works as pollevent() but waits if no event is available. When
  112. timeout=NULL, it waits indefinitely. Otherwise, it waits until *timeout
  113. becomes non-zero. It is particularly suitable to set *timeout to 1 using a
  114. timer with [timer_timeout] as callback. See <gint/timer.h>. */
  115. key_event_t waitevent(volatile int *timeout);
  116. /* clearevents(): Read all events waiting in the queue */
  117. void clearevents(void);
  118. //---
  119. // Key state functions
  120. //---
  121. /* keydown(): Current key state
  122. This function returns zero if the specified key is currently up (according
  123. to the last events that have been processed) and non-zero if it is down. */
  124. int keydown(int key);
  125. /* keydown_all(): Check a set of keys for simultaneous input
  126. Returns non-zero if all provided keys are down. The list should end with a 0
  127. as terminator. */
  128. int keydown_all(int key1, ...);
  129. /* keydown_any(): Check a set of keys for any input
  130. Returns nonzero if any one of the specified keys is currently pressed. The
  131. sequence should be terminated by a 0 integer. */
  132. int keydown_any(int key1, ...);
  133. //---
  134. // High-level functions
  135. //---
  136. /* getkey(): Wait for a key press
  137. This function mimics the behavior of the fxlib GetKey(). It returns a
  138. key_event_t object where [mod=1], and where [shift] and [alpha] indicate
  139. whether SHIFT or ALPHA was pressed before the key was hit. [event] is
  140. KEYEV_DOWN when a new key is pressed and KEYEV_HOLD in case of repeats.
  141. Similarities with GetKey() include:
  142. - Wait for a key to be pressed *after* the call (held keys don't count)
  143. - Supports SHIFT and ALPHA modifiers
  144. - Repeats arrows keys
  145. - Allows return to main menu if the MENU key is pressed
  146. - Controls backlight on models that have a back-lit screen
  147. getkey() is equivalent to getkey_opt(GETKEY_DEFAULT, NULL). */
  148. key_event_t getkey(void);
  149. /* The following are the option bits for getkey_opt(). */
  150. enum {
  151. /* Enable modifiers keys */
  152. GETKEY_MOD_SHIFT = 0x01,
  153. GETKEY_MOD_ALPHA = 0x02,
  154. /* SHIFT + OPTN toggles backlight (requires GETKEY_MOD_SHIFT) */
  155. GETKEY_BACKLIGHT = 0x04,
  156. /* MENU triggers a task switch and displays the main menu */
  157. GETKEY_MENU = 0x08,
  158. /* Repeat arrow keys, or even all keys */
  159. GETKEY_REP_ARROWS = 0x10,
  160. GETKEY_REP_ALL = 0x20,
  161. /* No modifiers */
  162. GETKEY_NONE = 0x00,
  163. /* Default settings of getkey() */
  164. GETKEY_DEFAULT = 0x1f,
  165. };
  166. /* getkey_opt(): Enhanced getkey()
  167. This function enhances getkey() with more general features. An
  168. or-combination of option flags (see above) must be supplied as first
  169. argument; GETKEY_NONE stands for no option. getkey_opt() returns the same
  170. kind of events as getkey().
  171. getkey_opt() supports a generic timeout function in the form of a volatile
  172. pointer [timeout]. If it's NULL, getkey_opt() waits indefinitely. Otherwise,
  173. it waits until *timeout becomes non-zero. It's up to you to change the
  174. value whenever you want to interrupt the call; using a timer with
  175. [timer_timeout] as callback is suitable. See <gint/timer.h>.
  176. @options An or-combination of values from the GETKEY_* enumeration
  177. @timeout Optional pointer to a timeout value
  178. Returns a key event of type KEYEV_DOWN or KEYEV_HOLD with [mod=1]. */
  179. key_event_t getkey_opt(int options, volatile int *timeout);
  180. /* getkey_repeat(): Set repeat delays for getkey()
  181. This function updates the repeat delays of getkey() and getkey_opt(). The
  182. unit of the argument is in milliseconds, but the granularity of the delay is
  183. dependent on the keyboard scan frequency.
  184. In the default setting (128 Hz scans), the possible repeat delays are
  185. approximately 8 ms, 16 ms, 23 ms, 31 ms... the provided arguments will be
  186. rounded to the closest feasible delays to ensure that repetitions are
  187. perfectly regular, rather than approximating the requested frequency.
  188. The system default is (500 ms, 125 ms). With the 128 Hz setting, this
  189. default is reached exactly without approximation.
  190. @first Delay between key press and first repeat (no more than one hour)
  191. @next Delay between subsequent repeats (no more than one hour) */
  192. void getkey_repeat(int first, int next);
  193. #endif /* GINT_KEYBOARD */