Fix further 'variable set but not used' warnings reported from GCC 4.6.0.
[kugel-rb.git] / apps / plugins / zxbox / zxbox_keyb.c
blob5680a8e32757c38e349205984eca0cee49ea9240
1 #include "zxconfig.h"
3 //#define ZX_WRITE_OUT_TEXT
5 #ifndef O_BINARY
6 #define O_BINARY 0
7 #endif
9 #if CONFIG_KEYPAD == RECORDER_PAD
10 #define BUTTONBAR_HEIGHT 8
11 #else
12 #define BUTTONBAR_HEIGHT 0
13 #endif
15 #define DEFAULT_MARGIN 6
16 #define KBD_BUF_SIZE 500
17 #define kbd_loaded false
18 #define statusbar_size 0
20 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
21 (CONFIG_KEYPAD == IRIVER_H300_PAD)
22 #define KBD_SELECT BUTTON_SELECT
23 #define KBD_ABORT BUTTON_OFF
24 #define KBD_LEFT BUTTON_LEFT
25 #define KBD_RIGHT BUTTON_RIGHT
26 #define KBD_UP BUTTON_UP
27 #define KBD_DOWN BUTTON_DOWN
29 #elif CONFIG_KEYPAD == RECORDER_PAD
30 #define KBD_SELECT BUTTON_PLAY
31 #define KBD_ABORT BUTTON_OFF
32 #define KBD_LEFT BUTTON_LEFT
33 #define KBD_RIGHT BUTTON_RIGHT
34 #define KBD_UP BUTTON_UP
35 #define KBD_DOWN BUTTON_DOWN
37 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
38 #define KBD_SELECT BUTTON_SELECT
39 #define KBD_ABORT BUTTON_OFF
40 #define KBD_LEFT BUTTON_LEFT
41 #define KBD_RIGHT BUTTON_RIGHT
42 #define KBD_UP BUTTON_UP
43 #define KBD_DOWN BUTTON_DOWN
45 #elif CONFIG_KEYPAD == ONDIO_PAD /* restricted Ondio keypad */
46 #define KBD_SELECT BUTTON_MENU
47 #define KBD_ABORT BUTTON_OFF
48 #define KBD_LEFT BUTTON_LEFT
49 #define KBD_RIGHT BUTTON_RIGHT
50 #define KBD_UP BUTTON_UP
51 #define KBD_DOWN BUTTON_DOWN
53 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
54 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
55 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
57 #define KBD_SELECT BUTTON_SELECT
58 #define KBD_ABORT BUTTON_MENU
59 #define KBD_LEFT BUTTON_LEFT
60 #define KBD_RIGHT BUTTON_RIGHT
61 #define KBD_UP BUTTON_SCROLL_BACK
62 #define KBD_DOWN BUTTON_SCROLL_FWD
64 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
66 /* TODO: Check keyboard mappings */
68 #define KBD_SELECT BUTTON_SELECT
69 #define KBD_ABORT BUTTON_PLAY
70 #define KBD_LEFT BUTTON_LEFT
71 #define KBD_RIGHT BUTTON_RIGHT
72 #define KBD_UP BUTTON_UP
73 #define KBD_DOWN BUTTON_DOWN
75 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
77 /* TODO: Check keyboard mappings */
79 #define KBD_SELECT BUTTON_SELECT
80 #define KBD_ABORT BUTTON_REC
81 #define KBD_LEFT BUTTON_LEFT
82 #define KBD_RIGHT BUTTON_RIGHT
83 #define KBD_UP BUTTON_UP
84 #define KBD_DOWN BUTTON_DOWN
86 #elif CONFIG_KEYPAD == GIGABEAT_PAD
88 #define KBD_SELECT BUTTON_SELECT
89 #define KBD_ABORT BUTTON_POWER
90 #define KBD_LEFT BUTTON_LEFT
91 #define KBD_RIGHT BUTTON_RIGHT
92 #define KBD_UP BUTTON_UP
93 #define KBD_DOWN BUTTON_DOWN
95 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
97 #define KBD_SELECT BUTTON_SELECT
98 #define KBD_ABORT BUTTON_POWER
99 #define KBD_LEFT BUTTON_LEFT
100 #define KBD_RIGHT BUTTON_RIGHT
101 #define KBD_UP BUTTON_UP
102 #define KBD_DOWN BUTTON_DOWN
104 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
106 /* TODO: Check keyboard mappings */
108 #define KBD_SELECT BUTTON_REW
109 #define KBD_ABORT BUTTON_FF
110 #define KBD_LEFT BUTTON_LEFT
111 #define KBD_RIGHT BUTTON_RIGHT
112 #define KBD_UP BUTTON_SCROLL_UP
113 #define KBD_DOWN BUTTON_SCROLL_DOWN
115 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
116 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
117 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
118 (CONFIG_KEYPAD == SANSA_M200_PAD) || \
119 (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \
120 (CONFIG_KEYPAD == MROBE100_PAD)
122 /* TODO: Check keyboard mappings */
124 #define KBD_SELECT BUTTON_SELECT
125 #define KBD_ABORT BUTTON_POWER
126 #define KBD_LEFT BUTTON_LEFT
127 #define KBD_RIGHT BUTTON_RIGHT
128 #define KBD_UP BUTTON_UP
129 #define KBD_DOWN BUTTON_DOWN
131 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
133 #define KBD_SELECT BUTTON_RC_PLAY
134 #define KBD_ABORT BUTTON_RC_REC
135 #define KBD_LEFT BUTTON_RC_REW
136 #define KBD_RIGHT BUTTON_RC_FF
137 #define KBD_UP BUTTON_RC_VOL_UP
138 #define KBD_DOWN BUTTON_RC_VOL_DOWN
140 #elif CONFIG_KEYPAD == COWON_D2_PAD
142 #define KBD_ABORT BUTTON_POWER
144 #elif CONFIG_KEYPAD == IAUDIO67_PAD
146 #define KBD_SELECT BUTTON_MENU
147 #define KBD_ABORT BUTTON_POWER
148 #define KBD_LEFT BUTTON_LEFT
149 #define KBD_RIGHT BUTTON_RIGHT
150 #define KBD_UP BUTTON_STOP
151 #define KBD_DOWN BUTTON_PLAY
153 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
155 #define KBD_SELECT BUTTON_SELECT
156 #define KBD_ABORT BUTTON_BACK
157 #define KBD_LEFT BUTTON_LEFT
158 #define KBD_RIGHT BUTTON_RIGHT
159 #define KBD_UP BUTTON_UP
160 #define KBD_DOWN BUTTON_DOWN
162 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
164 #define KBD_SELECT BUTTON_MENU
165 #define KBD_ABORT BUTTON_POWER
166 #define KBD_LEFT BUTTON_LEFT
167 #define KBD_RIGHT BUTTON_RIGHT
168 #define KBD_UP BUTTON_UP
169 #define KBD_DOWN BUTTON_DOWN
171 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
173 #define KBD_SELECT BUTTON_MENU
174 #define KBD_ABORT BUTTON_POWER
175 #define KBD_LEFT BUTTON_LEFT
176 #define KBD_RIGHT BUTTON_RIGHT
177 #define KBD_UP BUTTON_UP
178 #define KBD_DOWN BUTTON_DOWN
180 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
182 #define KBD_SELECT BUTTON_MENU
183 #define KBD_ABORT BUTTON_POWER
184 #define KBD_LEFT BUTTON_PREV
185 #define KBD_RIGHT BUTTON_NEXT
186 #define KBD_UP BUTTON_UP
187 #define KBD_DOWN BUTTON_DOWN
189 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
191 #define KBD_SELECT BUTTON_PLAY
192 #define KBD_ABORT BUTTON_REW
193 #define KBD_LEFT BUTTON_LEFT
194 #define KBD_RIGHT BUTTON_RIGHT
195 #define KBD_UP BUTTON_UP
196 #define KBD_DOWN BUTTON_DOWN
198 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
200 #define KBD_SELECT BUTTON_OK
201 #define KBD_ABORT BUTTON_CANCEL
202 #define KBD_LEFT BUTTON_PREV
203 #define KBD_RIGHT BUTTON_NEXT
204 #define KBD_UP BUTTON_UP
205 #define KBD_DOWN BUTTON_DOWN
207 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
209 #define KBD_SELECT BUTTON_FUNC
210 #define KBD_ABORT BUTTON_REC
211 #define KBD_LEFT BUTTON_VOL_DOWN
212 #define KBD_RIGHT BUTTON_VOL_UP
213 #define KBD_UP BUTTON_REW
214 #define KBD_DOWN BUTTON_FF
216 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
218 #define KBD_SELECT BUTTON_ENTER
219 #define KBD_ABORT BUTTON_MENU
220 #define KBD_LEFT BUTTON_REW
221 #define KBD_RIGHT BUTTON_FF
222 #define KBD_UP BUTTON_UP
223 #define KBD_DOWN BUTTON_DOWN
225 #endif
227 #ifdef HAVE_TOUCHSCREEN
228 #ifndef KBD_SELECT
229 #define KBD_SELECT BUTTON_CENTER
230 #endif
231 #ifndef KBD_ABORT
232 #define KBD_ABORT BUTTON_TOPLEFT
233 #endif
234 #ifndef KBD_LEFT
235 #define KBD_LEFT BUTTON_MIDLEFT
236 #endif
237 #ifndef KBD_RIGHT
238 #define KBD_RIGHT BUTTON_MIDRIGHT
239 #endif
240 #ifndef KBD_UP
241 #define KBD_UP BUTTON_TOPMIDDLE
242 #endif
243 #ifndef KBD_DOWN
244 #define KBD_DOWN BUTTON_BOTTOMMIDDLE
245 #endif
246 #endif
248 struct keyboard_parameters {
249 const unsigned char* default_kbd;
250 int DEFAULT_LINES;
251 unsigned short kbd_buf[KBD_BUF_SIZE];
252 int nchars;
253 int font_w;
254 int font_h;
255 struct font* font;
256 int curfont;
257 int main_x;
258 int main_y;
259 int max_chars;
260 int max_chars_text;
261 int lines;
262 int pages;
263 int keyboard_margin;
264 int old_main_y;
265 int curpos;
266 int leftpos;
267 int page;
268 int x;
269 int y;
272 struct keyboard_parameters param[NB_SCREENS];
274 int zx_kbd_input(char* text/*, int buflen*/)
276 bool done = false;
277 int i, j, k, w, l;
278 int text_w = 0;
279 #ifdef ZX_WRITE_OUT_TEXT
280 int editpos, len_utf8;
281 #endif
282 /* int statusbar_size = global_settings.statusbar ? STATUSBAR_HEIGHT : 0;*/
283 unsigned short ch/*, tmp, hlead = 0, hvowel = 0, htail = 0*/;
284 /*bool hangul = false;*/
285 unsigned char *utf8;
286 const unsigned char *p;
287 bool cur_blink = true;
288 int char_screen = 0;
290 FOR_NB_SCREENS(l)
292 param[l].default_kbd =
293 "1234567890\n"
294 "qwertyuiop\n"
295 "asdfghjkl\n"
296 "zxcvbnm\n"
297 "S\n"
298 "E";
300 param[l].DEFAULT_LINES = 7;
303 char outline[256];
304 int button;
305 FOR_NB_SCREENS(l)
307 /* Copy default keyboard to buffer */
308 i = 0;
309 param[l].curfont = FONT_SYSFIXED;
310 p = param[l].default_kbd;
311 while (*p != 0)
312 p = rb->utf8decode(p, &param[l].kbd_buf[i++]);
313 param[l].nchars = i;
314 /* param[l].curfont = FONT_UI;*/
316 FOR_NB_SCREENS(l)
318 param[l].font = rb->font_get(param[l].curfont);
319 param[l].font_h = param[l].font->height;
321 /* check if FONT_UI fits the screen */
322 if (2*param[l].font_h+3 + BUTTONBAR_HEIGHT >
323 rb->screens[l]->getheight()) {
324 param[l].font = rb->font_get(FONT_SYSFIXED);
325 param[l].font_h = param[l].font->height;
326 param[l].curfont = FONT_SYSFIXED;
329 rb->screens[l]->setfont(param[l].curfont);
330 /* find max width of keyboard glyphs */
331 for (i=0; i<param[l].nchars; i++) {
332 w = rb->font_get_width(param[l].font, param[l].kbd_buf[i]);
333 if (w > param[l].font_w)
334 param[l].font_w = w;
336 /* Since we're going to be adding spaces, make sure that we check
337 * their width too */
338 w = rb->font_get_width( param[l].font, ' ' );
339 if( w > param[l].font_w )
340 param[l].font_w = w;
342 FOR_NB_SCREENS(l)
344 i = 0;
345 /* Pad lines with spaces */
346 while( i < param[l].nchars )
348 if( param[l].kbd_buf[i] == '\n' )
350 k = ( rb->screens[l]->getwidth() / param[l].font_w ) -
351 i % ( rb->screens[l]->getwidth() / param[l].font_w ) - 1;
352 if( k == ( rb->screens[l]->getwidth() / param[l].font_w ) - 1 )
354 param[l].nchars--;
355 for( j = i; j < param[l].nchars; j++ )
357 param[l].kbd_buf[j] = param[l].kbd_buf[j+1];
360 else
362 if( param[l].nchars + k - 1 >= KBD_BUF_SIZE )
363 { /* We don't want to overflow the buffer */
364 k = KBD_BUF_SIZE - param[l].nchars;
366 for( j = param[l].nchars + k - 1; j > i+k; j-- )
368 param[l].kbd_buf[j] = param[l].kbd_buf[j-k];
370 param[l].nchars += k;
371 k++;
372 while( k-- )
374 param[l].kbd_buf[i++] = ' ';
378 else
379 i++;
383 /* find max width for text string */
384 utf8 = text;
385 FOR_NB_SCREENS(l)
387 text_w = param[l].font_w;
388 while (*utf8) {
389 utf8 = (unsigned char*)rb->utf8decode(utf8, &ch);
390 w = rb->font_get_width(param[l].font, ch);
391 if (w > text_w)
392 text_w = w;
394 param[l].max_chars_text = rb->screens[l]->getwidth() / text_w - 2;
396 /* calculate keyboard grid size */
397 param[l].max_chars = rb->screens[l]->getwidth() / param[l].font_w;
398 if (!kbd_loaded) {
399 param[l].lines = param[l].DEFAULT_LINES;
400 param[l].keyboard_margin = DEFAULT_MARGIN;
401 } else {
402 param[l].lines = (rb->screens[l]->lcdheight - BUTTONBAR_HEIGHT -
403 statusbar_size) / param[l].font_h - 1;
404 param[l].keyboard_margin = rb->screens[l]->lcdheight -
405 BUTTONBAR_HEIGHT - statusbar_size -
406 (param[l].lines+1)*param[l].font_h;
407 if (param[l].keyboard_margin < 3) {
408 param[l].lines--;
409 param[l].keyboard_margin += param[l].font_h;
411 if (param[l].keyboard_margin > 6)
412 param[l].keyboard_margin = 6;
415 param[l].pages = (param[l].nchars + (param[l].lines*param[l].max_chars-1))
416 /(param[l].lines*param[l].max_chars);
417 if (param[l].pages == 1 && kbd_loaded)
418 param[l].lines = (param[l].nchars + param[l].max_chars - 1) / param[l].max_chars;
420 param[l].main_y = param[l].font_h*param[l].lines + param[l].keyboard_margin + statusbar_size;
421 param[l].main_x = 0;
422 param[l].keyboard_margin -= param[l].keyboard_margin/2;
425 #ifdef ZX_WRITE_OUT_TEXT
426 editpos = rb->utf8length(text);
427 #endif
429 while(!done)
431 #ifdef ZX_WRITE_OUT_TEXT
432 len_utf8 = rb->utf8length(text);
433 #endif
434 FOR_NB_SCREENS(l)
435 rb->screens[l]->clear_display();
438 /* draw page */
439 FOR_NB_SCREENS(l)
441 rb->screens[l]->setfont(param[l].curfont);
442 k = param[l].page*param[l].max_chars*param[l].lines;
443 for (i=j=0; j < param[l].lines && k < param[l].nchars; k++) {
444 utf8 = rb->utf8encode(param[l].kbd_buf[k], outline);
445 *utf8 = 0;
446 rb->screens[l]->getstringsize(outline, &w, NULL);
447 rb->screens[l]->putsxy(i*param[l].font_w + (param[l].font_w-w)/2, j*param[l].font_h
448 + statusbar_size, outline);
449 if (++i == param[l].max_chars) {
450 i = 0;
451 j++;
457 /* separator */
458 FOR_NB_SCREENS(l)
460 rb->screens[l]->hline(0, rb->screens[l]->getwidth() - 1,
461 param[l].main_y - param[l].keyboard_margin);
463 /* write out the text */
464 #ifdef ZX_WRITE_OUT_TEXT
465 rb->screens[l]->setfont(param[l].curfont);
467 i=j=0;
468 param[l].curpos = MIN(editpos, param[l].max_chars_text
469 - MIN(len_utf8 - editpos, 2));
470 param[l].leftpos = editpos - param[l].curpos;
471 utf8 = text + rb->utf8seek(text, param[l].leftpos);
473 text_w = param[l].font_w;
474 while (*utf8 && i < param[l].max_chars_text) {
475 outline[j++] = *utf8++;
476 if ((*utf8 & MASK) != COMP) {
477 outline[j] = 0;
478 j=0;
479 i++;
480 rb->screens[l]->getstringsize(outline, &w, NULL);
481 rb->screens[l]->putsxy(i*text_w + (text_w-w)/2, param[l].main_y, outline);
485 if (param[l].leftpos) {
486 rb->screens[l]->getstringsize("<", &w, NULL);
487 rb->screens[l]->putsxy(text_w - w, param[l].main_y, "<");
489 if (len_utf8 - param[l].leftpos > param[l].max_chars_text)
490 rb->screens[l]->putsxy(rb->screens[l]->width - text_w, param[l].main_y, ">");
492 /* cursor */
493 i = (param[l].curpos + 1) * text_w;
494 if (cur_blink)
495 rb->screens[l]->vline(i, param[l].main_y, param[l].main_y + param[l].font_h-1);
497 if (hangul) /* draw underbar */
498 rb->screens[l]->hline(param[l].curpos*text_w, (param[l].curpos+1)*text_w,
499 param[l].main_y+param[l].font_h-1);
500 #endif
502 cur_blink = !cur_blink;
505 /* highlight the key that has focus */
506 FOR_NB_SCREENS(l)
508 rb->screens[l]->set_drawmode(DRMODE_COMPLEMENT);
509 rb->screens[l]->fillrect(param[l].font_w * param[l].x,
510 statusbar_size + param[l].font_h * param[l].y,
511 param[l].font_w, param[l].font_h);
512 rb->screens[l]->set_drawmode(DRMODE_SOLID);
515 FOR_NB_SCREENS(l)
516 rb->screens[l]->update();
518 button = rb->button_get_w_tmo(HZ/2);
520 switch ( button ) {
522 case KBD_ABORT:
523 FOR_NB_SCREENS(l)
524 rb->screens[l]->setfont(FONT_UI);
526 return -1;
527 break;
529 case KBD_RIGHT:
530 case KBD_RIGHT | BUTTON_REPEAT:
532 FOR_NB_SCREENS(l)
534 if (++param[l].x == param[l].max_chars) {
535 param[l].x = 0;
536 /* no dedicated flip key - flip page on wrap */
537 if (++param[l].page == param[l].pages)
538 param[l].page = 0;
540 k = (param[l].page*param[l].lines + param[l].y)*param[l].max_chars + param[l].x;
541 /*kbd_spellchar(param[l].kbd_buf[k]);*/
544 break;
545 case KBD_LEFT:
546 case KBD_LEFT | BUTTON_REPEAT:
548 FOR_NB_SCREENS(l)
550 if (param[l].x)
551 param[l].x--;
552 else
554 /* no dedicated flip key - flip page on wrap */
555 if (--param[l].page < 0)
556 param[l].page = (param[l].pages-1);
557 param[l].x = param[l].max_chars - 1;
559 k = (param[l].page*param[l].lines +
560 param[l].y)*param[l].max_chars + param[l].x;
561 /* kbd_spellchar(param[l].kbd_buf[k]);*/
564 break;
566 case KBD_DOWN:
567 case KBD_DOWN | BUTTON_REPEAT:
569 FOR_NB_SCREENS(l)
571 if (param[l].y < param[l].lines - 1)
572 param[l].y++;
573 else
574 param[l].y=0;
576 FOR_NB_SCREENS(l)
578 k = (param[l].page*param[l].lines + param[l].y)*
579 param[l].max_chars + param[l].x;
580 /*kbd_spellchar(param[l].kbd_buf[k]);*/
583 break;
585 case KBD_UP:
586 case KBD_UP | BUTTON_REPEAT:
588 FOR_NB_SCREENS(l)
590 if (param[l].y)
591 param[l].y--;
592 else
593 param[l].y = param[l].lines - 1;
595 FOR_NB_SCREENS(l)
597 k = (param[l].page*param[l].lines + param[l].y)*
598 param[l].max_chars + param[l].x;
599 /*kbd_spellchar(param[l].kbd_buf[k]);*/
602 break;
604 case KBD_SELECT:
606 if (button == KBD_SELECT)
607 char_screen = 0;
609 /* inserts the selected char */
611 /* find input char */
612 k = (param[char_screen].page*param[char_screen].lines +
613 param[char_screen].y)*param[char_screen].max_chars +
614 param[char_screen].x;
615 if (k < param[char_screen].nchars)
616 ch = param[char_screen].kbd_buf[k];
617 else
618 ch = ' ';
619 text[0]=ch;
620 done = true;
622 break;
625 default:
626 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
627 FOR_NB_SCREENS(l)
628 rb->screens[l]->setfont(FONT_SYSFIXED);
629 break;
632 if (button != BUTTON_NONE)
634 cur_blink = true;
637 FOR_NB_SCREENS(l)
638 rb->screens[l]->setfont(FONT_UI);
639 return 0;