keyboard.c 22 KB

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