keyboard.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. * Copyright (c) 2009 Openmoko Inc.
  3. *
  4. * Authors Holger Hans Peter Freyther <zecke@openmoko.org>
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "wl-keyboard.h"
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include "guilib.h"
  23. #include "input.h"
  24. #include "wikilib.h"
  25. #include "msg.h"
  26. #include "wiki_info.h"
  27. #include "search.h"
  28. #include "glyph.h"
  29. // definition for all the keyboard images generated by the Makefile
  30. // files line keyboard_abc.png will result in a keyboard_abc_image variable
  31. // included via all_images.h (see mahatma/build for generated headers)
  32. #define LCD_ImageType static struct guilib_image
  33. #define bytes data
  34. #include "all_images.h"
  35. #undef LCD_ImageType
  36. #undef bytes
  37. #define DBG_KEYBOARD 0
  38. /* some control commands */
  39. #define INTERNAL_SHIFT (-23)
  40. #define INTERNAL_NUMBER (-42)
  41. static struct guilib_image *image_data;
  42. int keyboard_type = 0;
  43. /* qwerty keyboard by columns */
  44. #define KEY(l_x, l_y, r_x, r_y, keycode) { .left_x = l_x, .right_x = r_x, .left_y = l_y, .right_y = r_y, .key = keycode, }
  45. /*
  46. static struct keyboard_key qwerty_char[] = {
  47. KEY(0, 126, 23, 152, 'q'),
  48. KEY(0+12, 153, 23+12, 180, 'a'),
  49. KEY(0, 181, 30, 207, ' '),
  50. KEY(24, 126, 47, 152, 'w'),
  51. KEY(24+12, 153, 47+12, 180, 's'),
  52. KEY(24+12, 181, 47+12, 207, 'z'),
  53. KEY(48, 126, 71, 152, 'e'),
  54. KEY(48+12, 153, 71+12, 180, 'd'),
  55. KEY(48+12, 181, 71+12, 207, 'x'),
  56. KEY(72, 126, 95, 152, 'r'),
  57. KEY(72+12, 153, 95+12, 180, 'f'),
  58. KEY(72+12, 181, 95+12, 207, 'c'),
  59. KEY(96, 126, 119, 152, 't'),
  60. KEY(96+12, 153, 119+12, 180, 'g'),
  61. KEY(96+12, 181, 119+12, 207, 'v'),
  62. KEY(120, 126, 143, 152, 'y'),
  63. KEY(120+12, 153, 143+12, 180, 'h'),
  64. KEY(120+12, 181, 143+12, 207, 'b'),
  65. KEY(144, 126, 167, 152, 'u'),
  66. KEY(144+12, 153, 167+12, 180, 'j'),
  67. KEY(144+12, 181, 167+12, 207, 'n'),
  68. KEY(168, 126, 191, 152, 'i'),
  69. KEY(168+12, 153, 191+12, 180, 'k'),
  70. KEY(168+12, 181, 191+12, 207, 'm'),
  71. KEY(192, 126, 215, 152, 'o'),
  72. KEY(192+12, 153, 215+12, 180, 'l'),
  73. KEY(216, 126, 239, 152, 'p'),
  74. KEY(209, 181, 239, 207, WL_KEY_BACKSPACE),
  75. KEY(199, 84, 233, 118, WL_KEY_NLS),
  76. };
  77. */
  78. static struct keyboard_key qwerty_char[] = {
  79. KEY(0, 126, 23, 152, 'q'),
  80. KEY(0, 153, 23, 180, 'a'),
  81. KEY(0, 181, 23, 207, 'z'),
  82. KEY(24, 126, 47, 152, 'w'),
  83. KEY(24, 153, 47, 180, 's'),
  84. KEY(24, 181, 47, 207, 'x'),
  85. KEY(48, 126, 71, 152, 'e'),
  86. KEY(48, 153, 71, 180, 'd'),
  87. KEY(48, 181, 71, 207, 'c'),
  88. KEY(72, 126, 95, 152, 'r'),
  89. KEY(72, 153, 95, 180, 'f'),
  90. KEY(72, 181, 95, 207, 'v'),
  91. KEY(96, 126, 119, 152, 't'),
  92. KEY(96, 153, 119, 180, 'g'),
  93. KEY(96, 181, 143, 207, ' '),
  94. KEY(120, 126, 143, 152, 'y'),
  95. KEY(120, 153, 143, 180, 'h'),
  96. KEY(144, 126, 167, 152, 'u'),
  97. KEY(144, 153, 167, 180, 'j'),
  98. KEY(144, 181, 167, 207, 'b'),
  99. KEY(168, 126, 191, 152, 'i'),
  100. KEY(168, 153, 191, 180, 'k'),
  101. KEY(168, 181, 191, 207, 'n'),
  102. KEY(192, 126, 215, 152, 'o'),
  103. KEY(192, 153, 215, 180, 'l'),
  104. KEY(192, 181, 215, 207, 'm'),
  105. KEY(216, 126, 239, 152, 'p'),
  106. KEY(216, 153, 239, 180, WL_KEY_BACKSPACE),
  107. KEY(216, 181, 239, 207, INTERNAL_NUMBER),
  108. KEY(199, 84, 233, 118, WL_KEY_NLS),
  109. };
  110. static struct keyboard_key qwerty_num[] = {
  111. KEY(0, 126, 23, 152, '1'),
  112. KEY(0, 153, 23, 180, '*'),
  113. KEY(0, 181, 23, 207, '@'),
  114. KEY(24, 126, 47, 152, '2'),
  115. KEY(24, 153, 47, 180, '$'),
  116. KEY(24, 181, 47, 207, '?'),
  117. KEY(48, 126, 71, 152, '3'),
  118. KEY(48, 153, 71, 180, '%'),
  119. KEY(48, 181, 71, 207, '!'),
  120. KEY(72, 126, 95, 152, '4'),
  121. KEY(72, 153, 95, 180, '#'),
  122. KEY(72, 181, 95, 207, '&'),
  123. KEY(96, 126, 119, 152, '5'),
  124. KEY(96, 153, 119, 180, '('),
  125. KEY(96, 181, 143, 207, ' '),
  126. KEY(120, 126, 143, 152, '6'),
  127. KEY(120, 153, 143, 180, ')'),
  128. KEY(144, 126, 167, 152, '7'),
  129. KEY(144, 153, 167, 180, '-'),
  130. KEY(144, 181, 167, 207, ','),
  131. KEY(168, 126, 191, 152, '8'),
  132. KEY(168, 153, 191, 180, '+'),
  133. KEY(168, 181, 191, 207, '.'),
  134. KEY(192, 126, 215, 152, '9'),
  135. KEY(192, 153, 215, 180, '='),
  136. KEY(192, 181, 215, 207, '\''),
  137. KEY(216, 126, 239, 152, '0'),
  138. KEY(216, 153, 239, 180, WL_KEY_BACKSPACE),
  139. KEY(216, 181, 239, 207, INTERNAL_NUMBER),
  140. KEY(199, 84, 233, 118, WL_KEY_NLS),
  141. };
  142. static struct keyboard_key password_char[] = {
  143. KEY(175, 81, 204, 105, 'Y'),
  144. KEY(0, 126, 23, 152, 'q'),
  145. KEY(0, 153, 23, 180, 'a'),
  146. KEY(0, 181, 23, 207, 'z'),
  147. KEY(24, 126, 47, 152, 'w'),
  148. KEY(24, 153, 47, 180, 's'),
  149. KEY(24, 181, 47, 207, 'x'),
  150. KEY(48, 126, 71, 152, 'e'),
  151. KEY(48, 153, 71, 180, 'd'),
  152. KEY(48, 181, 71, 207, 'c'),
  153. KEY(72, 126, 95, 152, 'r'),
  154. KEY(72, 153, 95, 180, 'f'),
  155. KEY(72, 181, 95, 207, 'v'),
  156. KEY(96, 126, 119, 152, 't'),
  157. KEY(96, 153, 119, 180, 'g'),
  158. KEY(96, 181, 143, 207, ' '),
  159. KEY(120, 126, 143, 152, 'y'),
  160. KEY(120, 153, 143, 180, 'h'),
  161. KEY(144, 126, 167, 152, 'u'),
  162. KEY(144, 153, 167, 180, 'j'),
  163. KEY(144, 181, 167, 207, 'b'),
  164. KEY(168, 126, 191, 152, 'i'),
  165. KEY(168, 153, 191, 180, 'k'),
  166. KEY(168, 181, 191, 207, 'n'),
  167. KEY(192, 126, 215, 152, 'o'),
  168. KEY(192, 153, 215, 180, 'l'),
  169. KEY(192, 181, 215, 207, 'm'),
  170. KEY(216, 126, 239, 152, 'p'),
  171. KEY(216, 153, 239, 180, WL_KEY_BACKSPACE),
  172. KEY(216, 181, 239, 207, INTERNAL_NUMBER),
  173. };
  174. static struct keyboard_key password_num[] = {
  175. KEY(175, 81, 204, 105, 'Y'),
  176. KEY(0, 126, 23, 152, '1'),
  177. KEY(0, 153, 23, 180, '*'),
  178. KEY(0, 181, 23, 207, '@'),
  179. KEY(24, 126, 47, 152, '2'),
  180. KEY(24, 153, 47, 180, '$'),
  181. KEY(24, 181, 47, 207, '?'),
  182. KEY(48, 126, 71, 152, '3'),
  183. KEY(48, 153, 71, 180, '%'),
  184. KEY(48, 181, 71, 207, '!'),
  185. KEY(72, 126, 95, 152, '4'),
  186. KEY(72, 153, 95, 180, '#'),
  187. KEY(72, 181, 95, 207, '&'),
  188. KEY(96, 126, 119, 152, '5'),
  189. KEY(96, 153, 119, 180, '('),
  190. KEY(96, 181, 143, 207, ' '),
  191. KEY(120, 126, 143, 152, '6'),
  192. KEY(120, 153, 143, 180, ')'),
  193. KEY(144, 126, 167, 152, '7'),
  194. KEY(144, 153, 167, 180, '-'),
  195. KEY(144, 181, 167, 207, ','),
  196. KEY(168, 126, 191, 152, '8'),
  197. KEY(168, 153, 191, 180, '+'),
  198. KEY(168, 181, 191, 207, '.'),
  199. KEY(192, 126, 215, 152, '9'),
  200. KEY(192, 153, 215, 180, '='),
  201. KEY(192, 181, 215, 207, '\''),
  202. KEY(216, 126, 239, 152, '0'),
  203. KEY(216, 153, 239, 180, WL_KEY_BACKSPACE),
  204. KEY(216, 181, 239, 207, INTERNAL_NUMBER),
  205. };
  206. static struct keyboard_key clear_history[] = {
  207. KEY(147, 181, 192, 207, 'Y'),
  208. KEY(193, 181, 238, 207, 'N'),
  209. };
  210. static struct keyboard_key restriction[] = {
  211. KEY(12, 148, 227, 170, 'Y'),
  212. };
  213. static struct keyboard_key filter_on_off[] = {
  214. KEY(12, 134, 227, 157, 'Y'),
  215. KEY(12, 163, 227, 186, 'N'),
  216. };
  217. static struct keyboard_key filter_option[] = {
  218. KEY(12, 105, 227, 128, 'Y'),
  219. KEY(12, 134, 227, 157, 'N'),
  220. KEY(12, 163, 227, 187, 'P'),
  221. };
  222. /*
  223. * The secret of the position and size of the keyboard
  224. * is shared between search.c and this file.
  225. */
  226. #define KEY_BUBBLE_STEM_UNDER_KEYPAD_PIXELS 4
  227. #define KEY_BUBBLE_TOTAL_HEIGHT 57
  228. #define KEY_BUBBLE_TOTAL_WIDTH 28
  229. #define KEY_BUBBLE_TOTAL_WIDTH_BYTES ((KEY_BUBBLE_TOTAL_WIDTH + 7) / 8 + 1)
  230. #define KEY_BUBBLE_STEM_WIDTH 22
  231. #define KEY_BUBBLE_STEM_HEIGHT 18
  232. #define KEY_BUBBLE_STAY_TIME 0.6
  233. static struct keyboard_key *pre_key = NULL;
  234. static int keyboard_key_invert_dalay = 0;
  235. static char key_bubble_save[KEY_BUBBLE_TOTAL_HEIGHT * KEY_BUBBLE_TOTAL_WIDTH_BYTES];
  236. static int key_bubble_save_x_start_byte;
  237. static int key_bubble_save_y_start;
  238. static int key_bubble_save_width_bytes;
  239. static int kb_mode = KEYBOARD_CHAR;
  240. extern unsigned char *framebuffer;
  241. void keyboard_set_mode(int mode)
  242. {
  243. kb_mode = mode;
  244. if(kb_mode == KEYBOARD_CHAR) {
  245. image_data = &keyboard_abc_image;
  246. } else if(kb_mode == KEYBOARD_NUM) {
  247. image_data = &keyboard_123_image;
  248. // } else if(kb_mode == KEYBOARD_CLEAR_HISTORY) {
  249. // image_data = &image_data_clear_history;
  250. } else {
  251. image_data = NULL;
  252. }
  253. }
  254. int keyboard_get_mode()
  255. {
  256. return kb_mode;
  257. }
  258. int nls_button_enabled()
  259. {
  260. return (get_search_string_len() == 0 && get_wiki_count() > 1);
  261. }
  262. void keyboard_paint()
  263. {
  264. pre_key = NULL;
  265. if(kb_mode == KEYBOARD_CHAR || kb_mode == KEYBOARD_PASSWORD_CHAR) {
  266. image_data = &keyboard_abc_image;
  267. } else if(kb_mode == KEYBOARD_NUM || kb_mode == KEYBOARD_PASSWORD_NUM) {
  268. image_data = &keyboard_123_image;
  269. // } else if(kb_mode == KEYBOARD_CLEAR_HISTORY) {
  270. // image_data = &clear_history_image;
  271. } else {
  272. return;
  273. }
  274. guilib_fb_lock();
  275. guilib_blit_image(image_data, 0, guilib_framebuffer_height() - image_data->height);
  276. if (nls_button_enabled())
  277. guilib_blit_image(&nls_image, 200, guilib_framebuffer_height() - image_data->height - 40);
  278. guilib_fb_unlock();
  279. }
  280. unsigned int keyboard_height()
  281. {
  282. if (!image_data)
  283. return 0;
  284. else
  285. return image_data->height;
  286. }
  287. /**
  288. * Coordinates are screen absolute ones
  289. */
  290. #define KEY_GAP1 1
  291. #define KEY_GAP2 0
  292. #define KEY_GAP3 0
  293. #define KEY_GAP4 1
  294. struct keyboard_key * keyboard_get_data(int x, int y)
  295. {
  296. unsigned int i;
  297. if (kb_mode == KEYBOARD_CHAR) {
  298. for (i = 0; i < ARRAY_SIZE(qwerty_char); ++i) {
  299. if (qwerty_char[i].left_x + KEY_GAP1 <= x && qwerty_char[i].right_x - KEY_GAP2 >= x
  300. && qwerty_char[i].left_y + KEY_GAP3 <= y && qwerty_char[i].right_y - KEY_GAP4 >= y
  301. && (nls_button_enabled() || qwerty_char[i].key != WL_KEY_NLS)) {
  302. DP(DBG_KEYBOARD, ("O Entered '%c'\n", qwerty_char[i].key));
  303. return &qwerty_char[i];
  304. }
  305. }
  306. }
  307. else if (kb_mode == KEYBOARD_NUM) {
  308. for (i = 0; i < ARRAY_SIZE(qwerty_num); ++i) {
  309. if (qwerty_num[i].left_x + KEY_GAP1 <= x && qwerty_num[i].right_x - KEY_GAP2 >= x
  310. && qwerty_num[i].left_y + KEY_GAP3 <= y && qwerty_num[i].right_y - KEY_GAP4 >= y
  311. && (nls_button_enabled() || qwerty_char[i].key != WL_KEY_NLS)) {
  312. DP(DBG_KEYBOARD, ("O Entered '%c'\n", qwerty_num[i].key));
  313. return &qwerty_num[i];
  314. }
  315. }
  316. }
  317. else if (kb_mode == KEYBOARD_CLEAR_HISTORY) {
  318. for (i = 0; i < ARRAY_SIZE(clear_history); ++i) {
  319. if (clear_history[i].left_x + KEY_GAP1 <= x && clear_history[i].right_x - KEY_GAP2 >= x
  320. && clear_history[i].left_y + KEY_GAP3 <= y && clear_history[i].right_y - KEY_GAP4 >= y) {
  321. return &clear_history[i];
  322. }
  323. }
  324. }
  325. else if (kb_mode == KEYBOARD_PASSWORD_CHAR) {
  326. for (i = 0; i < ARRAY_SIZE(password_char); ++i) {
  327. if (password_char[i].left_x + KEY_GAP1 <= x && password_char[i].right_x - KEY_GAP2 >= x
  328. && password_char[i].left_y + KEY_GAP3 <= y && password_char[i].right_y - KEY_GAP4 >= y) {
  329. return &password_char[i];
  330. }
  331. }
  332. }
  333. else if (kb_mode == KEYBOARD_PASSWORD_NUM) {
  334. for (i = 0; i < ARRAY_SIZE(password_num); ++i) {
  335. if (password_num[i].left_x + KEY_GAP1 <= x && password_num[i].right_x - KEY_GAP2 >= x
  336. && password_num[i].left_y + KEY_GAP3 <= y && password_num[i].right_y - KEY_GAP4 >= y) {
  337. return &password_num[i];
  338. }
  339. }
  340. }
  341. else if (kb_mode == KEYBOARD_RESTRICTED) {
  342. for (i = 0; i < ARRAY_SIZE(restriction); ++i) {
  343. if (restriction[i].left_x + KEY_GAP1 <= x && restriction[i].right_x - KEY_GAP2 >= x
  344. && restriction[i].left_y + KEY_GAP3 <= y && restriction[i].right_y - KEY_GAP4 >= y) {
  345. return &restriction[i];
  346. }
  347. }
  348. }
  349. else if (kb_mode == KEYBOARD_FILTER_ON_OFF) {
  350. for (i = 0; i < ARRAY_SIZE(filter_on_off); ++i) {
  351. if (filter_on_off[i].left_x + KEY_GAP1 <= x && filter_on_off[i].right_x - KEY_GAP2 >= x
  352. && filter_on_off[i].left_y + KEY_GAP3 <= y && filter_on_off[i].right_y - KEY_GAP4 >= y) {
  353. return &filter_on_off[i];
  354. }
  355. }
  356. }
  357. else if (kb_mode == KEYBOARD_FILTER_OPTION) {
  358. for (i = 0; i < ARRAY_SIZE(filter_option); ++i) {
  359. if (filter_option[i].left_x + KEY_GAP1 <= x && filter_option[i].right_x - KEY_GAP2 >= x
  360. && filter_option[i].left_y + KEY_GAP3 <= y && filter_option[i].right_y - KEY_GAP4 >= y) {
  361. return &filter_option[i];
  362. }
  363. }
  364. }
  365. return NULL;
  366. }
  367. void draw_key_bubble(int start_x, int start_y, int end_x, int end_y, int key)
  368. {
  369. int i, j;
  370. int bubble_start_x, bubble_start_y, bubble_end_x, bubble_end_y;
  371. int bubble_stem_start_x, bubble_stem_start_y, bubble_stem_end_x, bubble_stem_end_y;
  372. int bubble_stem_left_diff, bubble_stem_right_diff;
  373. char s[2];
  374. int width;
  375. guilib_fb_lock();
  376. bubble_start_x = start_x - (KEY_BUBBLE_TOTAL_WIDTH - (end_x - start_x + 1)) / 2;
  377. if (bubble_start_x < 0)
  378. bubble_start_x = 0;
  379. else if (bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH > LCD_BUF_WIDTH_PIXELS)
  380. bubble_start_x = LCD_BUF_WIDTH_PIXELS - KEY_BUBBLE_TOTAL_WIDTH;
  381. bubble_start_y = start_y + KEY_BUBBLE_STEM_UNDER_KEYPAD_PIXELS + KEY_BUBBLE_STEM_HEIGHT - KEY_BUBBLE_TOTAL_HEIGHT;
  382. bubble_end_x = bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - 1;
  383. bubble_end_y = bubble_start_y + KEY_BUBBLE_TOTAL_HEIGHT - KEY_BUBBLE_STEM_HEIGHT - 1;
  384. bubble_stem_start_x = bubble_start_x + (KEY_BUBBLE_TOTAL_WIDTH - KEY_BUBBLE_STEM_WIDTH) / 2;
  385. if (bubble_stem_start_x < 0)
  386. bubble_stem_start_x = 0;
  387. else if (bubble_stem_start_x + KEY_BUBBLE_STEM_WIDTH > LCD_BUF_WIDTH_PIXELS)
  388. bubble_stem_start_x = LCD_BUF_WIDTH_PIXELS - KEY_BUBBLE_STEM_WIDTH;
  389. bubble_stem_end_x = bubble_stem_start_x + KEY_BUBBLE_STEM_WIDTH - 1;
  390. bubble_stem_start_y = bubble_end_y + 1;
  391. bubble_stem_end_y = bubble_start_y + KEY_BUBBLE_TOTAL_HEIGHT - 1;
  392. bubble_stem_left_diff = bubble_stem_start_x - bubble_start_x;
  393. bubble_stem_right_diff = bubble_end_x - bubble_stem_end_x;
  394. key_bubble_save_x_start_byte = bubble_start_x / 8;
  395. key_bubble_save_y_start = bubble_start_y;
  396. key_bubble_save_width_bytes = KEY_BUBBLE_TOTAL_WIDTH_BYTES;
  397. if (key_bubble_save_x_start_byte + key_bubble_save_width_bytes > LCD_BUF_WIDTH_BYTES)
  398. key_bubble_save_width_bytes = LCD_BUF_WIDTH_BYTES - key_bubble_save_x_start_byte;
  399. for (i = 0; i < KEY_BUBBLE_TOTAL_HEIGHT; i++)
  400. {
  401. memcpy(&key_bubble_save[i * KEY_BUBBLE_TOTAL_WIDTH_BYTES],
  402. &framebuffer[(key_bubble_save_y_start + i) * LCD_BUF_WIDTH_BYTES + key_bubble_save_x_start_byte], key_bubble_save_width_bytes);
  403. }
  404. for (i = 0; i < KEY_BUBBLE_TOTAL_HEIGHT - KEY_BUBBLE_STEM_HEIGHT; i++)
  405. {
  406. if (i == 0 || i == 1)
  407. {
  408. for (j = 2 - i; j < KEY_BUBBLE_TOTAL_WIDTH - 2 + i; j++)
  409. lcd_set_framebuffer_pixel(bubble_start_x + j, bubble_start_y + i);
  410. }
  411. else if (i == 2)
  412. {
  413. lcd_set_framebuffer_pixel(bubble_start_x + 2 - i, bubble_start_y + i);
  414. lcd_set_framebuffer_pixel(bubble_start_x + 3 - i, bubble_start_y + i);
  415. lcd_set_framebuffer_pixel(bubble_start_x + 4 - i, bubble_start_y + i);
  416. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - 3 + i, bubble_start_y + i);
  417. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - 4 + i, bubble_start_y + i);
  418. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - 5 + i, bubble_start_y + i);
  419. for (j = 5 - i; j < KEY_BUBBLE_TOTAL_WIDTH - 5 + i; j++)
  420. lcd_clear_framebuffer_pixel(bubble_start_x + j, bubble_start_y + i);
  421. }
  422. else if (KEY_BUBBLE_TOTAL_HEIGHT - KEY_BUBBLE_STEM_HEIGHT - 3 <= i && i <= KEY_BUBBLE_TOTAL_HEIGHT - KEY_BUBBLE_STEM_HEIGHT - 1 )
  423. {
  424. int left_diff, right_diff;
  425. left_diff = bubble_stem_left_diff / (KEY_BUBBLE_TOTAL_HEIGHT - KEY_BUBBLE_STEM_HEIGHT - i);
  426. if (bubble_stem_left_diff && ! left_diff)
  427. left_diff = 1;
  428. bubble_stem_left_diff -= left_diff;
  429. right_diff = bubble_stem_right_diff / (KEY_BUBBLE_TOTAL_HEIGHT - KEY_BUBBLE_STEM_HEIGHT - i);
  430. if (bubble_stem_right_diff && ! right_diff)
  431. right_diff = 1;
  432. bubble_stem_right_diff -= right_diff;
  433. lcd_set_framebuffer_pixel(bubble_start_x + left_diff, bubble_start_y + i);
  434. lcd_set_framebuffer_pixel(bubble_start_x + left_diff + 1, bubble_start_y + i);
  435. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - right_diff - 1, bubble_start_y + i);
  436. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - right_diff - 2, bubble_start_y + i);
  437. for (j = left_diff + 2; j < KEY_BUBBLE_TOTAL_WIDTH - right_diff - 2; j++)
  438. lcd_clear_framebuffer_pixel(bubble_start_x + j, bubble_start_y + i);
  439. }
  440. else
  441. {
  442. lcd_set_framebuffer_pixel(bubble_start_x, bubble_start_y + i);
  443. lcd_set_framebuffer_pixel(bubble_start_x + 1, bubble_start_y + i);
  444. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - 1, bubble_start_y + i);
  445. lcd_set_framebuffer_pixel(bubble_start_x + KEY_BUBBLE_TOTAL_WIDTH - 2, bubble_start_y + i);
  446. for (j = 2; j < KEY_BUBBLE_TOTAL_WIDTH - 2; j++)
  447. lcd_clear_framebuffer_pixel(bubble_start_x + j, bubble_start_y + i);
  448. }
  449. }
  450. for (i = 0; i < KEY_BUBBLE_STEM_HEIGHT; i++) // drawn from the bottom of the stem
  451. {
  452. if (i == 0) // bottom
  453. {
  454. for (j = 3; j < KEY_BUBBLE_STEM_WIDTH - 3; j++)
  455. lcd_set_framebuffer_pixel(bubble_stem_start_x + j, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  456. }
  457. else if (1 <= i && i <= 2)
  458. {
  459. lcd_set_framebuffer_pixel(bubble_stem_start_x + 3 - i, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  460. lcd_set_framebuffer_pixel(bubble_stem_start_x + KEY_BUBBLE_STEM_WIDTH - 4 + i, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  461. for (j = 4 - i; j < KEY_BUBBLE_STEM_WIDTH - 4 + i; j++)
  462. lcd_clear_framebuffer_pixel(bubble_stem_start_x + j, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  463. }
  464. else
  465. {
  466. lcd_set_framebuffer_pixel(bubble_stem_start_x, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  467. lcd_set_framebuffer_pixel(bubble_stem_start_x + KEY_BUBBLE_STEM_WIDTH - 1, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  468. for (j = 1; j < KEY_BUBBLE_STEM_WIDTH - 1; j++)
  469. lcd_clear_framebuffer_pixel(bubble_stem_start_x + j, bubble_stem_start_y + (KEY_BUBBLE_STEM_HEIGHT - 1 - i));
  470. }
  471. }
  472. s[0] = toupper(key);
  473. s[1] = '\0';
  474. width = get_external_str_pixel_width(s, TITLE_FONT_IDX);
  475. render_string(TITLE_FONT_IDX, bubble_start_x + (KEY_BUBBLE_TOTAL_WIDTH - width) / 2, bubble_start_y + 1, s, 1, 0);
  476. guilib_fb_unlock();
  477. }
  478. void restore_key_bubble(void)
  479. {
  480. int i;
  481. guilib_fb_lock();
  482. for (i = 0; i < KEY_BUBBLE_TOTAL_HEIGHT; i++)
  483. memcpy(&framebuffer[(key_bubble_save_y_start + i) * LCD_BUF_WIDTH_BYTES + key_bubble_save_x_start_byte],
  484. &key_bubble_save[i * KEY_BUBBLE_TOTAL_WIDTH_BYTES], key_bubble_save_width_bytes);
  485. guilib_fb_unlock();
  486. }
  487. void keyboard_process_key_invert(struct keyboard_key *key)
  488. {
  489. int start_x, start_y, end_x, end_y;
  490. start_x = key->left_x + 2;
  491. start_y = key->left_y + 2;
  492. end_x = key->right_x - 2;
  493. end_y = key->right_y - 2;
  494. if (strchr("qaz1*@", key->key))
  495. start_x++;
  496. if (strchr("p0", key->key) || key->key == WL_KEY_BACKSPACE)
  497. end_x--;
  498. if (strchr("asdfghjklzxcvbnm*$%#()-+=<@?!& ,.'", key->key) || key->key == WL_KEY_BACKSPACE)
  499. start_y++;
  500. if (key->key == ' ' || key->key == WL_KEY_BACKSPACE || key->key == WL_KEY_NLS || isupper(key->key))
  501. {
  502. guilib_invert_area(start_x,start_y,end_x,end_y);
  503. guilib_invert_area(start_x,start_y,start_x,start_y);
  504. guilib_invert_area(start_x,end_y,start_x,end_y);
  505. guilib_invert_area(end_x,start_y,end_x,start_y);
  506. guilib_invert_area(end_x,end_y,end_x,end_y);
  507. }
  508. else
  509. {
  510. draw_key_bubble(start_x, start_y, end_x, end_y, key->key);
  511. }
  512. keyboard_key_invert_dalay = 0;
  513. }
  514. int keyboard_key_inverted(void)
  515. {
  516. if (pre_key)
  517. return 1;
  518. else
  519. return 0;
  520. }
  521. void keyboard_key_invert(struct keyboard_key *key)
  522. {
  523. guilib_fb_lock();
  524. if (key && key->key == INTERNAL_NUMBER)
  525. pre_key = NULL;
  526. else
  527. {
  528. if (pre_key)
  529. {
  530. keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_NOW, 0);
  531. }
  532. if (key)
  533. {
  534. keyboard_process_key_invert(key);
  535. pre_key = key;
  536. }
  537. }
  538. guilib_fb_unlock();
  539. keyboard_key_invert_dalay = 0;
  540. }
  541. int keyboard_key_reset_invert(int bFlag, unsigned long ev_time)
  542. {
  543. static unsigned long start_time;
  544. int rc = 0;
  545. if (pre_key)
  546. {
  547. if (bFlag == KEYBOARD_RESET_INVERT_DELAY)
  548. {
  549. start_time = ev_time;
  550. keyboard_key_invert_dalay = 1;
  551. rc = 1;
  552. }
  553. else if (bFlag == KEYBOARD_RESET_INVERT_CHECK && keyboard_key_invert_dalay)
  554. {
  555. if (time_diff(get_time_ticks(), start_time) > seconds_to_ticks(KEY_BUBBLE_STAY_TIME))
  556. bFlag = KEYBOARD_RESET_INVERT_NOW; // reset invert immediately
  557. else
  558. rc = 1;
  559. }
  560. if (bFlag == KEYBOARD_RESET_INVERT_NOW)
  561. {
  562. guilib_fb_lock();
  563. if (pre_key->key == ' ' || pre_key->key == WL_KEY_BACKSPACE || pre_key->key == WL_KEY_NLS || isupper(pre_key->key))
  564. keyboard_process_key_invert(pre_key);
  565. else
  566. restore_key_bubble();
  567. pre_key = NULL;
  568. if (kb_mode == KEYBOARD_CHAR || kb_mode == KEYBOARD_NUM)
  569. search_to_be_reloaded(SEARCH_TO_BE_RELOADED_CHECK, 0);
  570. guilib_fb_unlock();
  571. }
  572. }
  573. return rc;
  574. }
  575. int keyboard_adjacent_keys(struct keyboard_key *key1, struct keyboard_key *key2)
  576. {
  577. if (((key1->left_x == key2->left_x || key1->right_x == key2->right_x) && // same column
  578. (key1->left_y - key2->right_y == 1 || key2->left_y - key1->right_y == 1)) || // adjacent row
  579. ((key1->left_y == key2->left_y || key1->right_y == key2->right_y) && // same row
  580. (key1->left_x - key2->right_x == 1 || key2->left_x - key1->right_x == 1))) // adjancent column
  581. {
  582. return 1;
  583. }
  584. else
  585. {
  586. return 0;
  587. }
  588. }