mfbd.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*
  2. * Copyright (c) 2022-2023, smartmx <smartmx@qq.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-02-22 smartmx the first version.
  9. * 2022-03-15 smartmx each mbtn has it's own max multi-click times.
  10. * 2022-04-16 smartmx drop list definitions, use array, each group has all btn types.
  11. * 2022-08-05 smartmx add reset params function.
  12. * 2022-08-15 smartmx fix bugs.
  13. * 2022-09-07 smartmx add default define apis.
  14. * 2023-03-15 smartmx add state declaration.
  15. * 2023-07-03 smartmx add Section Definition option.
  16. * 2023-07-15 smartmx add skip function, to reduce calling of scan functions.
  17. * 2023-09-19 smartmx improve performance, add MFBD_BTN_STATE_SKIP.
  18. *
  19. */
  20. #ifndef _MFBD_H_
  21. #define _MFBD_H_
  22. #include "mfbd_cfg.h"
  23. #if (MFBD_USE_SECTION_DEFINITION == 0)
  24. typedef enum
  25. {
  26. MFBD_BTN_STATE_UP = 0,
  27. MFBD_BTN_STATE_DOWN,
  28. MFBD_BTN_STATE_LONG,
  29. MFBD_BTN_STATE_SKIP = 0xff,
  30. } MFBD_BTN_STATE_t;
  31. #define MFBD_DOWN_CODE_NAME(NAME) NAME##_DOWN_CODE /* when using tbtn/nbtn default define api, this is down-code name. */
  32. #define MFBD_UP_CODE_NAME(NAME) NAME##_UP_CODE /* when using tbtn/nbtn/mbtn default define api, this is up-code name. */
  33. #define MFBD_LONG_CODE_NAME(NAME) NAME##_LONG_CODE /* when using nbtn/mbtn default define api, this is long-code name. */
  34. #define MFBD_DOWN_CODES_NAME(NAME) NAME##_DOWN_CODES /* when using mbtn default define api, this is down-codes name. */
  35. /* tiny button definitions, tiny button functions only support down and up event. */
  36. #if MFBD_PARAMS_SAME_IN_GROUP
  37. typedef struct _mfbd_tbtn_info_struct
  38. {
  39. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  40. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  41. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  42. } mfbd_tbtn_info_t;
  43. #else
  44. typedef struct _mfbd_tbtn_info_struct
  45. {
  46. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  47. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  48. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  49. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  50. } mfbd_tbtn_info_t;
  51. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  52. typedef struct _mfbd_tiny_btn_struct
  53. {
  54. const mfbd_tbtn_info_t *btn_info; /* a pointer to mfbd_tbtn_info_t. */
  55. mfbd_btn_count_t filter_count; /* filter time count when button state changed. */
  56. unsigned char state; /* the state of button, up or down. */
  57. } mfbd_tbtn_t;
  58. #if MFBD_PARAMS_SAME_IN_GROUP
  59. #define MFBD_TBTN_DEFINE(NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE) \
  60. static const mfbd_tbtn_info_t NAME##_info = { \
  61. BTN_DOWN_CODE, \
  62. BTN_UP_CODE, \
  63. BTN_INDEX, \
  64. }; \
  65. mfbd_tbtn_t NAME = { \
  66. &NAME##_info, \
  67. 0, \
  68. 0, \
  69. }
  70. #define MFBD_TBTN_DEFAULT_DEFINE(NAME, BTN_INDEX) \
  71. static const mfbd_tbtn_info_t NAME##_info = { \
  72. NAME##_DOWN_CODE, \
  73. NAME##_UP_CODE, \
  74. BTN_INDEX, \
  75. }; \
  76. mfbd_tbtn_t NAME = { \
  77. &NAME##_info, \
  78. 0, \
  79. 0, \
  80. }
  81. #else
  82. #define MFBD_TBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, BTN_DOWN_CODE, BTN_UP_CODE) \
  83. static const mfbd_tbtn_info_t NAME##_info = { \
  84. BTN_DOWN_CODE, \
  85. BTN_UP_CODE, \
  86. FILTER_TIME, \
  87. BTN_INDEX, \
  88. }; \
  89. mfbd_tbtn_t NAME = { \
  90. &NAME##_info, \
  91. 0, \
  92. 0, \
  93. }
  94. #define MFBD_TBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, FILTER_TIME) \
  95. static const mfbd_tbtn_info_t NAME##_info = { \
  96. NAME##_DOWN_CODE, \
  97. NAME##_UP_CODE, \
  98. FILTER_TIME, \
  99. BTN_INDEX, \
  100. }; \
  101. mfbd_tbtn_t NAME = { \
  102. &NAME##_info, \
  103. 0, \
  104. 0, \
  105. }
  106. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  107. #define MFBD_TBTN_EXTERN(NAME) extern mfbd_tbtn_t NAME
  108. #define MFBD_TBTN_ARRAYLIST(NAME, ...) mfbd_tbtn_t* NAME[] = {__VA_ARGS__, NULL}
  109. /* normal button definitions, normal button functions support down, up and long-press event. */
  110. #if MFBD_PARAMS_SAME_IN_GROUP
  111. typedef struct _mfbd_nbtn_info_struct
  112. {
  113. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  114. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  115. mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code instead. */
  116. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  117. } mfbd_nbtn_info_t;
  118. #else
  119. typedef struct _mfbd_nbtn_info_struct
  120. {
  121. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  122. mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */
  123. mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */
  124. mfbd_btn_code_t btn_down_code; /* keyCode when button down, set to 0 will not report it. */
  125. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  126. mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code instead. */
  127. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  128. } mfbd_nbtn_info_t;
  129. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  130. typedef struct _mfbd_normal_btn_struct
  131. {
  132. const mfbd_nbtn_info_t *btn_info; /* a pointer to mfbd_nbtn_info_t. */
  133. mfbd_btn_count_t filter_count; /* filter time count when button state changed. */
  134. mfbd_btn_count_t long_count; /* long time count when button still down. */
  135. mfbd_btn_count_t repeat_count; /* repeat time count when button still down. */
  136. unsigned char state; /* the state of button, up or down. */
  137. } mfbd_nbtn_t;
  138. #if MFBD_PARAMS_SAME_IN_GROUP
  139. #define MFBD_NBTN_DEFINE(NAME, BTN_INDEX, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) \
  140. static const mfbd_nbtn_info_t NAME##_info = { \
  141. BTN_DOWN_CODE, \
  142. BTN_UP_CODE, \
  143. BTN_LONG_CODE, \
  144. BTN_INDEX, \
  145. }; \
  146. mfbd_nbtn_t NAME = { \
  147. &NAME##_info, \
  148. 0, \
  149. 0, \
  150. 0, \
  151. 0, \
  152. }
  153. #define MFBD_NBTN_DEFAULT_DEFINE(NAME, BTN_INDEX) \
  154. static const mfbd_nbtn_info_t NAME##_info = { \
  155. NAME##_DOWN_CODE, \
  156. NAME##_UP_CODE, \
  157. NAME##_LONG_CODE, \
  158. BTN_INDEX, \
  159. }; \
  160. mfbd_nbtn_t NAME = { \
  161. &NAME##_info, \
  162. 0, \
  163. 0, \
  164. }
  165. #else
  166. #define MFBD_NBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE) \
  167. static const mfbd_nbtn_info_t NAME##_info = { \
  168. FILTER_TIME, \
  169. REPEAT_TIME, \
  170. LONG_TIME, \
  171. BTN_DOWN_CODE, \
  172. BTN_UP_CODE, \
  173. BTN_LONG_CODE, \
  174. BTN_INDEX, \
  175. }; \
  176. mfbd_nbtn_t NAME = { \
  177. &NAME##_info, \
  178. 0, \
  179. 0, \
  180. 0, \
  181. 0, \
  182. }
  183. #define MFBD_NBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME) \
  184. static const mfbd_nbtn_info_t NAME##_info = { \
  185. FILTER_TIME, \
  186. REPEAT_TIME, \
  187. LONG_TIME, \
  188. NAME##_DOWN_CODE, \
  189. NAME##_UP_CODE, \
  190. NAME##_LONG_CODE, \
  191. BTN_INDEX, \
  192. }; \
  193. mfbd_nbtn_t NAME = { \
  194. &NAME##_info, \
  195. 0, \
  196. 0, \
  197. }
  198. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  199. #define MFBD_NBTN_EXTERN(NAME) extern mfbd_nbtn_t NAME
  200. #define MFBD_NBTN_ARRAYLIST(NAME, ...) mfbd_nbtn_t* NAME[] = {__VA_ARGS__, NULL}
  201. /* multi-function button definitions, multi-function button functions support down, up, long-press and multi-click event. */
  202. #if MFBD_PARAMS_SAME_IN_GROUP
  203. typedef struct _mfbd_mbtn_info_struct
  204. {
  205. const mfbd_btn_code_t *btn_down_code; /* pointer to multi-click keyCodes when button down. */
  206. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  207. mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code[0] instead. */
  208. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  209. unsigned char max_multiclick_state; /* max multiclick states. */
  210. } mfbd_mbtn_info_t;
  211. #else
  212. typedef struct _mfbd_mbtn_info_struct
  213. {
  214. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  215. mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */
  216. mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */
  217. mfbd_btn_count_t multiclick_time; /* multi-click time when button still up, set 0 will disable multi-click time count. */
  218. const mfbd_btn_code_t *btn_down_code; /* pointer to multi-click keyCodes when button down. */
  219. mfbd_btn_code_t btn_up_code; /* keyCode when button up, set to 0 will not report it. */
  220. mfbd_btn_code_t btn_long_code; /* keyCode when button down for long_time, set 0 will not report it ,but report btn_down_code[0] instead. */
  221. mfbd_btn_index_t btn_index; /* parameter when calling is_btn_down_func. */
  222. unsigned char max_multiclick_state; /* max multiclick states. */
  223. } mfbd_mbtn_info_t;
  224. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  225. /*
  226. * @Note:
  227. * repeat_count and long_count are conflict to multi-click.
  228. * repeat_count and long_count only check in the first button down event, and will disable in next multi-click event.
  229. * also, if repeat_count and long_count event has happened in the first down event, it will reset multiclick_state.
  230. */
  231. typedef struct _mfbd_multi_fuction_btn_struct
  232. {
  233. const mfbd_mbtn_info_t *btn_info; /* a pointer to mfbd_mbtn_info_t. */
  234. mfbd_btn_count_t filter_count; /* filter time count when button state changed. */
  235. mfbd_btn_count_t long_count; /* long time count when button still down. */
  236. mfbd_btn_count_t repeat_count; /* repeat time count when button still down. */
  237. mfbd_btn_count_t multiclick_count; /* multi-click time count when button is up. */
  238. unsigned char multiclick_state; /* multi-click count when button is in multi-click state. */
  239. unsigned char state; /* the state of button, up or down. */
  240. } mfbd_mbtn_t;
  241. #if MFBD_PARAMS_SAME_IN_GROUP
  242. #define MFBD_MBTN_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) \
  243. static const mfbd_btn_code_t NAME##_down_codes[MAX_MULTICLICK_STATE + 1] = {BTN_DOWN_CODE, __VA_ARGS__}; \
  244. static const mfbd_mbtn_info_t NAME##_info = { \
  245. NAME##_down_codes, \
  246. BTN_UP_CODE, \
  247. BTN_LONG_CODE, \
  248. BTN_INDEX, \
  249. MAX_MULTICLICK_STATE, \
  250. }; \
  251. mfbd_mbtn_t NAME = { \
  252. &NAME##_info, \
  253. 0, \
  254. 0, \
  255. 0, \
  256. 0, \
  257. 0, \
  258. 0, \
  259. }
  260. #define MFBD_MBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, MAX_MULTICLICK_STATE) \
  261. static const mfbd_mbtn_info_t NAME##_info = { \
  262. NAME##_DOWN_CODES, \
  263. NAME##_UP_CODE, \
  264. NAME##_LONG_CODE, \
  265. BTN_INDEX, \
  266. MAX_MULTICLICK_STATE, \
  267. }; \
  268. mfbd_mbtn_t NAME = { \
  269. &NAME##_info, \
  270. 0, \
  271. 0, \
  272. 0, \
  273. 0, \
  274. 0, \
  275. 0, \
  276. }
  277. #else
  278. #define MFBD_MBTN_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE, BTN_DOWN_CODE, BTN_UP_CODE, BTN_LONG_CODE, ...) \
  279. static const mfbd_btn_code_t NAME##_down_codes[MAX_MULTICLICK_STATE + 1] = {BTN_DOWN_CODE, __VA_ARGS__}; \
  280. static const mfbd_mbtn_info_t NAME##_info = { \
  281. FILTER_TIME, \
  282. REPEAT_TIME, \
  283. LONG_TIME, \
  284. MULTICLICK_TIME, \
  285. NAME##_down_codes, \
  286. BTN_UP_CODE, \
  287. BTN_LONG_CODE, \
  288. BTN_INDEX, \
  289. MAX_MULTICLICK_STATE, \
  290. }; \
  291. mfbd_mbtn_t NAME = { \
  292. &NAME##_info, \
  293. 0, \
  294. 0, \
  295. 0, \
  296. 0, \
  297. 0, \
  298. 0, \
  299. }
  300. #define MFBD_MBTN_DEFAULT_DEFINE(NAME, BTN_INDEX, FILTER_TIME, REPEAT_TIME, LONG_TIME, MULTICLICK_TIME, MAX_MULTICLICK_STATE) \
  301. static const mfbd_mbtn_info_t NAME##_info = { \
  302. FILTER_TIME, \
  303. REPEAT_TIME, \
  304. LONG_TIME, \
  305. MULTICLICK_TIME, \
  306. NAME##_DOWN_CODES, \
  307. NAME##_UP_CODE, \
  308. NAME##_LONG_CODE, \
  309. BTN_INDEX, \
  310. MAX_MULTICLICK_STATE, \
  311. }; \
  312. mfbd_mbtn_t NAME = { \
  313. &NAME##_info, \
  314. 0, \
  315. 0, \
  316. 0, \
  317. 0, \
  318. 0, \
  319. 0, \
  320. }
  321. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  322. #define MFBD_MBTN_EXTERN(NAME) extern mfbd_mbtn_t NAME
  323. #define MFBD_MBTN_ARRAYLIST(NAME, ...) mfbd_mbtn_t* NAME[] = {__VA_ARGS__, NULL}
  324. /* mfbd group struct */
  325. typedef struct _mfbd_group_struct
  326. {
  327. /* used to read whether button is down. */
  328. unsigned char (*is_btn_down_func)(mfbd_btn_index_t btn_index);
  329. /* used to report btn_value, must have a legal value, must not be NULL. */
  330. void (*btn_value_report)(mfbd_btn_code_t btn_value);
  331. #if MFBD_USE_TINY_BUTTON
  332. /* pointer to the head of tiny buttons pointer array */
  333. mfbd_tbtn_t **tbtns;
  334. #endif /* MFBD_USE_TINY_BUTTON */
  335. #if MFBD_USE_NORMAL_BUTTON
  336. /* pointer to the head of normal buttons pointer array */
  337. mfbd_nbtn_t **nbtns;
  338. #endif /* MFBD_USE_NORMAL_BUTTON */
  339. #if MFBD_USE_MULTIFUCNTION_BUTTON
  340. /* pointer to the head of multifunction buttons pointer array */
  341. mfbd_mbtn_t **mbtns;
  342. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  343. /* if set MFBD_PARAMS_SAME_IN_GROUP to 1, all btns in group has same params. */
  344. #if MFBD_PARAMS_SAME_IN_GROUP
  345. #if MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON
  346. mfbd_btn_count_t filter_time; /* filter time when button state changed, please do not use 0. */
  347. #endif /* MFBD_USE_TINY_BUTTON || MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */
  348. #if MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON
  349. mfbd_btn_count_t repeat_time; /* repeat time when button still down for over long_time, set 0 will disable repeat time count. */
  350. mfbd_btn_count_t long_time; /* long time when button still down, set 0 will disable long time and repeat time count. */
  351. #endif /* MFBD_USE_NORMAL_BUTTON || MFBD_USE_MULTIFUCNTION_BUTTON */
  352. #if MFBD_USE_MULTIFUCNTION_BUTTON
  353. mfbd_btn_count_t multiclick_time; /* multi-click time when button still up, set 0 will disable multi-click time count. */
  354. #endif /* MFBD_USE_MULTIFUCNTION_BUTTON */
  355. #endif /* MFBD_PARAMS_SAME_IN_GROUP */
  356. #if MFBD_USE_BTN_SCAN_PRE_FUNC
  357. /* prepare function when start to scan buttons for each group. */
  358. void (*btn_scan_prepare)(void);
  359. #endif /* MFBD_USE_BTN_SCAN_PRE_FUNC */
  360. #if MFBD_USE_BTN_SCAN_AFTER_FUNC
  361. /* function after scanning buttons for each group. */
  362. void (*btn_scan_after)(void);
  363. #endif /* MFBD_USE_BTN_SCAN_AFTER_FUNC */
  364. } mfbd_group_t;
  365. extern void mfbd_group_scan(const mfbd_group_t *_pbtn_group);
  366. extern void mfbd_group_skip(const mfbd_group_t *_pbtn_group, mfbd_btn_count_t times);
  367. extern void mfbd_group_reset(const mfbd_group_t *_pbtn_group);
  368. #endif /* (MFBD_USE_SECTION_DEFINITION == 0) */
  369. #endif /* _MFBD_H_ */