Index: apps/plugins/lib/SOURCES =================================================================== --- apps/plugins/lib/SOURCES (revision 17689) +++ apps/plugins/lib/SOURCES (working copy) @@ -39,3 +39,6 @@ #endif pluginlib_actions.c helper.c +#ifdef HAVE_TOUCHPAD +touchscreen.c +#endif Index: apps/plugins/lib/touchscreen.c =================================================================== --- apps/plugins/lib/touchscreen.c (revision 0) +++ apps/plugins/lib/touchscreen.c (revision 0) @@ -0,0 +1,111 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2008 by Maurus Cuelenaere +* +* All files in this archive are subject to the GNU General Public License. +* See the file COPYING in the source tree root for full license agreement. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#include "plugin.h" + +#ifdef HAVE_TOUCHPAD + +#include "touchscreen.h" + +unsigned int touchscreen_map(struct ts_mappings *map, int x, int y) +{ + int i; + for(i=0; i < map->amount; i++) + { + #define _MAP(x) (map->mappings[x]) + if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width) + && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height)) + return i; + } + + return -1; +} + +unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result) +{ + int res1_x, res2_x, res1_y, res2_y; + + if((x - map->tl_x) < 0 || + (x - map->tl_x) > map->width) + return -1; + res1_x = (x - map->tl_x)/(map->raster_width); + res2_x = (x - map->tl_x)%(map->raster_width); + + if((y - map->tl_y) < 0 || + (y - map->tl_y) > map->height) + return -1; + res1_y = (y - map->tl_y)/(map->raster_height); + res2_y = (y - map->tl_y)%(map->raster_height); + + if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */ + return -2; + else + { + (*result).x = res1_x; + (*result).y = res1_y; + return 1; + } +} + +struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button) +{ + struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}}; + struct ts_raster_result tmp; + + ret.action = TS_ACTION_NONE; + if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1) + return ret; + + if(button & (BUTTON_REPEAT|BUTTON_REL) && map->drag_drop_enable) + { + ret.action = TS_ACTION_DRAG_DROP; + ret.from.x = map->_prev_x; + ret.from.y = map->_prev_y; + ret.to.x = x; + ret.to.y = y; + } + else if(button == BUTTON_REL && map->_prev_x == x && map->_prev_y == y && map->double_click_enable) + { + ret.action = TS_ACTION_DOUBLE_CLICK; + ret.from.x = ret.to.x = x; + ret.from.y = ret.to.y = y; + } + else if(button & BUTTON_REL && map->two_d_movement_enable) + { + if((map->two_d_from.x == x) ^ (map->two_d_from.y == y)) + { + ret.action = TS_ACTION_TWO_D_MOVEMENT; + ret.from.x = map->two_d_from.x; + ret.from.y = map->two_d_from.y; + ret.to.x = map->two_d_from.x + (x > map->two_d_from.x ? 1 : -1); + ret.to.y = map->two_d_from.y + (y > map->two_d_from.y ? 1 : -1); + } + else + ret.action = TS_ACTION_NONE; + } + else if(map->click_progress_enable) + ret.action = TS_ACTION_CLICK; + + map->_prev_x = x; + map->_prev_y = y; + map->_prev_btn_state = button; + return ret; +} + +#endif /* HAVE_TOUCHPAD */ Index: apps/plugins/lib/touchscreen.h =================================================================== --- apps/plugins/lib/touchscreen.h (revision 0) +++ apps/plugins/lib/touchscreen.h (revision 0) @@ -0,0 +1,88 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2008 by Maurus Cuelenaere +* +* All files in this archive are subject to the GNU General Public License. +* See the file COPYING in the source tree root for full license agreement. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#ifndef _PLUGIN_LIB_TOUCHSCREEN_H_ +#define _PLUGIN_LIB_TOUCHSCREEN_H_ + +#ifdef HAVE_TOUCHPAD + +struct ts_mapping +{ + int tl_x; /* top left */ + int tl_y; + int width; + int height; +}; + +struct ts_mappings +{ + struct ts_mapping *mappings; + int amount; +}; + +unsigned int touchscreen_map(struct ts_mappings *map, int x, int y); + +struct ts_raster +{ + int tl_x; /* top left */ + int tl_y; + int width; + int height; + int raster_width; + int raster_height; +}; + +struct ts_raster_result +{ + int x; + int y; +}; + +unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result); + +struct ts_raster_button_mapping +{ + struct ts_raster *raster; + bool drag_drop_enable; /* ... */ + bool double_click_enable; /* ... */ + bool click_progress_enable; /* ... */ + bool two_d_movement_enable; /* ... */ + struct ts_raster_result two_d_from; /* ... */ + int _prev_x; /* Internal: DO NOT MODIFY! */ + int _prev_y; /* Internal: DO NOT MODIFY! */ + int _prev_btn_state; /* Internal: DO NOT MODIFY! */ +}; + +struct ts_raster_button_result +{ + enum{ + TS_ACTION_NONE, + TS_ACTION_CLICK, + TS_ACTION_DOUBLE_CLICK, + TS_ACTION_DRAG_DROP, + TS_ACTION_TWO_D_MOVEMENT + } action; + struct ts_raster_result from; + struct ts_raster_result to; +}; + +struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button); + +#endif /* HAVE_TOUCHPAD */ +#endif /* _PLUGIN_LIB_TOUCHSCREEN_H_ */ Index: apps/plugins/pegbox.c =================================================================== --- apps/plugins/pegbox.c (revision 17689) +++ apps/plugins/pegbox.c (working copy) @@ -323,6 +323,16 @@ #ifndef LVL_DOWN_TEXT #define LVL_DOWN_TEXT "BOTTOMRIGHT" #endif +#include "lib/touchscreen.h" + +static struct ts_mapping main_menu_items[4] = +{ +{(LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2, BMPHEIGHT_pegbox_menu_top, BMPWIDTH_pegbox_menu_items, (BMPHEIGHT_pegbox_menu_items/9)}, +{(LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2, BMPHEIGHT_pegbox_menu_top+(BMPHEIGHT_pegbox_menu_items/9), BMPWIDTH_pegbox_menu_items, (BMPHEIGHT_pegbox_menu_items/9)}, +{(LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2, BMPHEIGHT_pegbox_menu_top+(BMPHEIGHT_pegbox_menu_items/9)*2, BMPWIDTH_pegbox_menu_items, (BMPHEIGHT_pegbox_menu_items/9)}, +{(LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2, BMPHEIGHT_pegbox_menu_top+(BMPHEIGHT_pegbox_menu_items/9)*3, BMPWIDTH_pegbox_menu_items, (BMPHEIGHT_pegbox_menu_items/9)} +}; +static struct ts_mappings main_menu = {main_menu_items, 4}; #endif #if (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) @@ -368,6 +378,11 @@ #define BOARD_Y 0 #endif +#ifdef HAVE_TOUCHPAD +static struct ts_raster pegbox_raster = { BOARD_X, BOARD_Y, COLS*BMPWIDTH_pegbox_pieces, ROWS*BMPWIDTH_pegbox_pieces, BMPWIDTH_pegbox_pieces, BMPWIDTH_pegbox_pieces }; +static struct ts_raster_button_mapping pegbox_raster_btn = { &pegbox_raster, false, false, true, true, {0, 0}, 0, 0, 0 }; +#endif + struct game_context { unsigned int level; unsigned int highlevel; @@ -1053,6 +1068,19 @@ /* handle menu button presses */ button = rb->button_get(true); + +#ifdef HAVE_TOUCHPAD + if(button & BUTTON_TOUCHPAD) + { + unsigned int result = touchscreen_map(&main_menu, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff); + if(result != -1 && button & BUTTON_REL) + { + if(loc == result) + button = PEGBOX_RIGHT; + loc = result; + } + } +#endif switch(button) { case PEGBOX_SAVE: /* start playing */ @@ -1169,6 +1197,17 @@ while (true) { temp_var = rb->button_get(true); +#ifdef HAVE_TOUCHPAD + if(temp_var & BUTTON_TOUCHPAD) + { + pegbox_raster_btn.two_d_from.y = pb->player_row; + pegbox_raster_btn.two_d_from.x = pb->player_col; + struct ts_raster_button_result ret = touchscreen_raster_map_button(&pegbox_raster_btn, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff, temp_var); + DEBUGF("%d: %d %d\n", ret.action, ret.to.x, ret.to.y); + if(ret.action == TS_ACTION_TWO_D_MOVEMENT) + move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y); + } +#endif switch(temp_var){ case PEGBOX_LEFT: /* move cursor left */ case (PEGBOX_LEFT|BUTTON_REPEAT): Index: apps/plugins/chessbox/chessbox.c =================================================================== --- apps/plugins/chessbox/chessbox.c (revision 17689) +++ apps/plugins/chessbox/chessbox.c (working copy) @@ -27,6 +27,10 @@ #include "opening.h" #include "chessbox_pgn.h" +#ifdef CB_TOUCH_INPUT +#include "lib/touchscreen.h" +#endif + /* type definitions */ struct cb_command { int type; @@ -66,7 +70,18 @@ #define COMMAND_SELECT 10 #define COMMAND_NEXT 11 #define COMMAND_PREV 12 +#ifdef CB_TOUCH_INPUT +#define COMMAND_CHANGE_INPUT_MODE 13 +#endif +/* touchpad input mode for plugin */ +#ifdef CB_TOUCH_INPUT + enum touchpad_mode input_mode; + enum touchpad_mode default_mode; + static struct ts_raster cb_raster = { XOFS, YOFS, 8*TILE_WIDTH, 8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT }; + static struct ts_raster_button_mapping cb_raster_btn = { &cb_raster, false, true, true, false, {0, 0}, 0, 0, 0 }; +#endif + short plugin_mode; /* level+1's string */ @@ -112,6 +127,7 @@ } } + /* ---- Draw a complete board ---- */ static void cb_drawboard (void) { short r , c , x , y ; @@ -590,9 +606,20 @@ int result = 0; bool menu_quit = false; - MENUITEM_STRINGLIST(menu,"Chessbox Menu",NULL,"New Game","Resume Game", - "Save Game", "Restore Game", "Quit"); +#ifdef CB_TOUCH_INPUT + /* use the user's default input mode in the menu */ + if (rb->touchpad_get_mode()!=default_mode) { + rb->touchpad_set_mode(default_mode); + } +#endif + MENUITEM_STRINGLIST(menu,"Chessbox Menu",NULL, + "New Game","Resume Game","Save Game", "Restore Game", +#ifdef CB_TOUCH_INPUT + "Change input mode", +#endif + "Quit"); + while(!menu_quit) { switch(rb->do_menu(&menu, &selection, NULL, false)) @@ -614,11 +641,25 @@ menu_quit = true; break; case 4: +#ifdef CB_TOUCH_INPUT + result = COMMAND_CHANGE_INPUT_MODE; + menu_quit = true; + break; + case 5: +#endif result = COMMAND_QUIT; menu_quit = true; break; } } + +#ifdef CB_TOUCH_INPUT + /* switch back to play input mode */ + if (rb->touchpad_get_mode()!=input_mode) { + rb->touchpad_set_mode(input_mode); + } +#endif + return result; } @@ -626,6 +667,10 @@ struct cb_command cb_getcommand (void) { static short x = 4 , y = 3 ; short c , r , l; +#ifdef CB_TOUCH_INPUT + short touch_x, touch_y; + struct ts_raster_button_result btn_result; +#endif int button, lastbutton = BUTTON_NONE; int marked = false , from_marked = false ; short marked_x = 0 , marked_y = 0 ; @@ -714,6 +759,31 @@ cb_switch ( x , y ); } break; +#ifdef CB_TOUCH_INPUT + case CB_TOUCH_INPUT: + if ( !from_marked ) + cb_switch ( x , y ); + touch_x = rb->button_get_data() >> 16; + touch_y = rb->button_get_data() & 0xffff; + btn_result = touchscreen_raster_map_button(&cb_raster_btn, touch_x, touch_y, button); + if(btn_result.action == TS_ACTION_NONE) + break; + else if(btn_result.action == TS_ACTION_DOUBLE_CLICK) + button = CB_SELECT; + + x = btn_result.to.x; + y = btn_result.to.y; + + if ( marked && ( marked_x == x ) && ( marked_y == y ) ) + from_marked = true; + else + { + from_marked = false; + cb_switch ( x , y ); + } + if (button!=CB_SELECT) + break; +#endif case CB_SELECT: #ifdef CB_SELECT_PRE if (lastbutton != CB_SELECT_PRE) @@ -887,6 +957,17 @@ cb_levelup ( ); cb_drawboard(); break; +#ifdef CB_TOUCH_INPUT + case COMMAND_CHANGE_INPUT_MODE: + input_mode = (input_mode == TOUCHPAD_POINT) ? TOUCHPAD_BUTTON : TOUCHPAD_POINT; + rb->touchpad_set_mode(input_mode); + if (input_mode == TOUCHPAD_BUTTON) + rb->splash(50, "Button input"); + else + rb->splash(50, "Direct input"); + cb_drawboard(); + break; +#endif case COMMAND_QUIT: exit = true; break; @@ -911,6 +992,12 @@ rb->lcd_set_backdrop(NULL); #endif +#ifdef CB_TOUCH_INPUT + /* save the user's default touchpad mode */ + default_mode = rb->touchpad_get_mode(); + input_mode = default_mode; +#endif + /* end of plugin init */ /* if the plugin was invoked as a viewer, parse the file and show the game list @@ -922,6 +1009,11 @@ cb_play_game(); } +#ifdef CB_TOUCH_INPUT + /* reset touchpad mode */ + rb->touchpad_set_mode(default_mode); +#endif + return PLUGIN_OK; } Index: apps/plugins/chessbox/chessbox_pgn.h =================================================================== --- apps/plugins/chessbox/chessbox_pgn.h (revision 17689) +++ apps/plugins/chessbox/chessbox_pgn.h (working copy) @@ -312,6 +312,7 @@ #ifndef CB_SCROLL_RIGHT #define CB_SCROLL_RIGHT (BUTTON_MIDRIGHT|BUTTON_REPEAT) #endif +#define CB_TOUCH_INPUT BUTTON_TOUCHPAD #endif /* structure to represent the plies */