root/platform/n_facebook/kbd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_usb_bit
  2. ts_user_menu_enable
  3. simulate_playback_press
  4. simulate_power_press
  5. ts_exit_alt
  6. ts_run_script
  7. is_button_displayed
  8. is_button_active
  9. show_virtual_buttons
  10. chdk_process_touch
  11. ts_process_touch
  12. virtual_buttons
  13. mykbd_task_proceed
  14. mykbd_task
  15. wrap_kbd_p1_f
  16. kbd_fetch_data
  17. my_kbd_read_keys

   1 #include "lolevel.h"
   2 #include "platform.h"
   3 #include "core.h"
   4 #include "conf.h"
   5 #include "keyboard.h"
   6 #include "touchscreen.h"
   7 #include "gui.h"
   8 #include "gui_draw.h"
   9 #include "gui_osd.h"
  10 #include "gui_menu.h"
  11 #include "gui_user_menu.h"
  12 #include "font.h"
  13 #include "kbd_common.h"
  14 
  15 long kbd_new_state[4]          = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
  16 long kbd_prev_state[4]  = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
  17 long kbd_mod_state[4]   = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
  18 static long touch_panel_state  =   0xFFFFFFFF;
  19 static long touch_panel_button =   0xFFFFFFFF;
  20 
  21 extern void _GetKbdState(long*);
  22 extern int kbd_is_blocked(void);
  23 
  24 int get_usb_bit()
  25 {
  26     long usb_physw[3];
  27     usb_physw[USB_IDX] = 0;
  28     _kbd_read_keys_r2(usb_physw);
  29     return(( usb_physw[USB_IDX] & USB_MASK)==USB_MASK) ;
  30 }
  31 
  32 #define TS_KEY_SCRIPT_RUN   200
  33 #define TS_KEY_TOGGLE_RAW   201
  34 #define TS_KEY_TOGGLE_OSD   202
  35 #define TS_KEY_TOGGLE_OVRD  203
  36 #define TS_KEY_PLAYBACK     204 
  37 #define TS_KEY_POWER        205
  38 #define TS_KEY_EXIT         206
  39 #define TS_KEY_USER_MENU    207
  40 #define TS_KEY_ZOMBIE       0xFFFE
  41 
  42 #define MODE_VID    0x400
  43 
  44 extern const char* gui_on_off_enum(int change, int arg);
  45 extern const char* gui_histo_show_enum(int change, int arg);
  46 extern const char* gui_override_disable_enum(int change, int arg);
  47 extern gui_handler scriptGuiHandler;
  48 
  49 static const char* ts_user_menu_enable(int change, __attribute__ ((unused))int arg) 
  50 { 
  51     extern void gui_menu_init();
  52     extern gui_handler* gui_set_mode(gui_handler *) ;
  53     extern int gui_user_menu_flag ;    
  54     if ( change ) 
  55     {
  56             gui_set_mode(&menuGuiHandler);
  57             gui_user_menu_flag = 0;
  58             gui_menu_init(&user_submenu);
  59     }
  60     return 0;
  61 }
  62 
  63 static const char* simulate_playback_press(int change, __attribute__ ((unused))int arg) 
  64 { 
  65     void levent_set_play(void);
  66     void levent_set_record(void) ;
  67     if ( change ) 
  68     {
  69         int camMode = (get_movie_status()==VIDEO_RECORD_IN_PROGRESS) ? MODE_VID : (mode_get() & MODE_MASK);
  70         if (camMode) levent_set_play(); else levent_set_record() ;
  71     }
  72     return 0; 
  73 } 
  74  
  75 static const char* simulate_power_press(int change, __attribute__ ((unused))int arg) 
  76 { 
  77     void camera_shutdown_in_a_second(void); 
  78     if (change) camera_shutdown_in_a_second(); 
  79     return 0; 
  80 } 
  81 
  82 static const char* ts_exit_alt(int change, __attribute__ ((unused))int arg)
  83 {
  84     if (change) exit_alt() ;
  85     return 0;
  86 }
  87 
  88 static const char* ts_run_script(int change, __attribute__ ((unused))int arg)
  89 {
  90     if (change) 
  91     {
  92         kbd_new_state[2]=kbd_new_state[2]&0xFFFFFFC0 ;      
  93     }
  94     return 0;
  95 }
  96 
  97 KeyMap keymap[] = {
  98     // Order IS important. kbd_get_pressed_key will walk down this table
  99     // and take the first matching mask. Notice that KEY_SHOOT_HALF is
 100     // always pressed if KEY_SHOOT_FULL is.
 101 
 102     { 0, KEY_POWER           ,0x00100000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdba8, levent 0x100
 103     { 2, KEY_SHOOT_FULL      ,0x00000030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdbb8, levent 0x01
 104     { 2, KEY_SHOOT_FULL_ONLY ,0x00000020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdbb8, levent 0x01
 105     { 2, KEY_SHOOT_HALF      ,0x00000010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdbb0, levent 0x00
 106     { 2, KEY_ZOOM_OUT        ,0x00000100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdbc0, levent 0x04
 107     { 2, KEY_ZOOM_IN         ,0x00000200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdbc8, levent 0x03
 108     { 2, KEY_PLAYBACK        ,0x00010000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Found @0xff5bdbd8, levent 0x101
 109     { 2, KEY_PRINT           ,0x00020000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // wifi button - use as default <ALT> key
 110 //  { 0. KEY_TOUCH_NONE      ,0x10000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }. // touch screen not touched
 111 //  { 0, KEY_TOUCH_DOWN      ,0x20000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // touch screen touched
 112 //  { 2, KEY_CUSTOM_SWITCH   ,0x00002000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Custom Mode Switch
 113 //  { 2, KEY_SDCARD_DOOR     ,0x00080000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }. // SD card door switch     
 114 
 115     { 3, KEY_MENU           , 0x00000001,   0,    0, 39,  47,  0, "CHDK", "MENU", GUI_MODE_ALT, 100,          MODE_REC|MODE_PLAY, 0, 0, 0 },
 116     { 3, TS_KEY_EXIT        , 0x00000002,   0,  192, 39, 239,  0, "Exit",  "ALT", GUI_MODE_ALT, 100,          MODE_REC|MODE_PLAY, 0, ts_exit_alt, 0 },
 117     
 118     { 3, TS_KEY_USER_MENU   , 0x00000004,   0,   48, 39,  95,  0, "USER",  "MENU",GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, ts_user_menu_enable, 0 },
 119     { 3, KEY_SET            , 0x00000008,   0,   96, 39, 143,  0, "PRGM",  0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, 0, 0 },
 120 // was DISPLAY but assume blank name means not used, switched to ZOMBIE
 121 //    { 3, KEY_DISPLAY        , 0x00000010,   0,  144, 39, 191,  0, " ",     0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, 0, 0 },
 122     { 3, TS_KEY_ZOMBIE      , 0x00000020,   0,  144, 39, 191,  0, " ",     0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, 0, 0 },
 123 
 124     { 3, TS_KEY_ZOMBIE      , 0x00000020,   0,   48, 39,  95,  0, " ",     0,     GUI_MODE_MENU, GUI_MODE_MENU,  MODE_REC|MODE_PLAY, 0, 0, 0 },
 125     { 3, TS_KEY_ZOMBIE      , 0x00000020,   0,   96, 39, 143,  0, " ",     0,     GUI_MODE_MENU, GUI_MODE_MENU,  MODE_REC|MODE_PLAY, 0, 0, 0 },
 126     { 3, KEY_DISPLAY        , 0x00000010,   0,  144, 39, 191,  0, "BACK",  0,     GUI_MODE_MENU, GUI_MODE_MENU,  MODE_REC|MODE_PLAY, 0, 0, 0 },
 127     
 128     { 3, KEY_DISPLAY        , 0x00000010,   0,  144, 39, 191,  0, "DISP",  0,     GUI_MODE_SCRIPT, GUI_MODE_OSD,  MODE_REC|MODE_PLAY, 0, 0, 0 },
 129     
 130     { 3, KEY_UP             , 0x00000200, 320,   0, 359,  47,  0, "Up",    0,     GUI_MODE_MENU,100, MODE_REC|MODE_PLAY, 0, 0, 0 },
 131     { 3, KEY_LEFT           , 0x00000400, 320,  48, 359,  95,  0, "Left",  0,     GUI_MODE_MENU,100, MODE_REC|MODE_PLAY, 0, 0, 0 },
 132     { 3, KEY_SET            , 0x00000800, 320,  96, 359, 143,  0, " Set",  0,     GUI_MODE_MENU,100, MODE_REC|MODE_PLAY, 0, 0, 0 },
 133     { 3, KEY_RIGHT          , 0x00001000, 320, 144, 359, 191,  0, "Right", 0,     GUI_MODE_MENU,100, MODE_REC|MODE_PLAY, 0, 0, 0 },
 134     { 3, KEY_DOWN           , 0x00002000, 320, 192, 359, 239,  0, "Down",  0,     GUI_MODE_MENU,100, MODE_REC|MODE_PLAY, 0, 0, 0 },
 135     
 136     { 3, TS_KEY_SCRIPT_RUN  , 0x00004000, 320,   0, 359,  47,  0, "RUN",   0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, ts_run_script, 0 },
 137     { 3, TS_KEY_TOGGLE_RAW  , 0x00008000, 320,  48, 359,  95,  1, "RAW",   0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, &conf.save_raw, gui_on_off_enum, &conf.touchscreen_disable_shortcut_controls },
 138 //  { 3, TS_KEY_TOGGLE_OSD  , 0x00010000, 320,  96, 359, 143,  1, "OSD",   0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, &conf.show_osd, gui_on_off_enum, &conf.touchscreen_disable_shortcut_controls },
 139     { 3, TS_KEY_TOGGLE_OVRD , 0x00020000, 320,  96, 359, 143,  1, "OVR",   0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, &conf.override_disable, gui_override_disable_enum, &conf.touchscreen_disable_shortcut_controls },  
 140     { 3, TS_KEY_PLAYBACK    , 0x00040000, 320, 144, 359, 191,  0, "REC/", "PLAY",  GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, simulate_playback_press, 0 }, 
 141     { 3, TS_KEY_POWER       , 0x00080000, 320, 192, 359, 239,  0, "OFF",   0,     GUI_MODE_ALT, GUI_MODE_ALT, MODE_REC|MODE_PLAY, 0, simulate_power_press, 0 }, 
 142   
 143     { 0 }
 144 };
 145 
 146 
 147 // TODO generic touch stuff should be in kbd_common.c or it's own file
 148 static int is_button_displayed(int b, int guiMode, int camMode)
 149 {
 150     return(
 151             (keymap[b].grp == 3) &&
 152             (guiMode >= keymap[b].min_gui_mode) &&
 153             (guiMode <= keymap[b].max_gui_mode) &&
 154             (camMode & keymap[b].cam_mode_mask) &&
 155             ((keymap[b].conf_disable == 0) || (*keymap[b].conf_disable == 0))
 156            );
 157 }
 158 
 159 static int is_button_active(int b, int guiMode, int camMode)
 160 {
 161     return is_button_displayed(b, guiMode, camMode);
 162 }
 163 
 164 int show_virtual_buttons()
 165 {
 166     extern int active_palette_buffer;
 167     return((active_palette_buffer == 0x00) || (active_palette_buffer == 0x10)) ;
 168 }
 169 
 170 int chdk_process_touch()
 171 {
 172     int guiMode = camera_info.state.gui_mode;
 173     int camMode = (get_movie_status()==VIDEO_RECORD_IN_PROGRESS) ? MODE_VID : (mode_get() & MODE_MASK);
 174     
 175     unsigned short tx, ty;                                              // Touch co-ordinate
 176     tx = touch_screen_x * 360 / 0x2FF ;
 177     ty = touch_screen_y *  240 / 0x1FF ;
 178     if (conf.rotate_osd)
 179     {
 180         tx = 360 - tx;
 181         ty = 240 - ty;
 182     }
 183     
 184     if ( touch_screen_active )                                          // Search for CHDK on screen buttons matching co-ordinate
 185     {
 186         int i;
 187         for (i=0; keymap[i].hackkey; i++)
 188         {
 189             if ((tx >= keymap[i].x1) && (tx < keymap[i].x2) && (ty >= keymap[i].y1) && (ty < keymap[i].y2) && is_button_active(i,guiMode,camMode))
 190             {
 191                 touch_panel_button &= ~keymap[i].canonkey;              //
 192             }
 193        }
 194        
 195         // Check if menu touched
 196         int mk = gui_touch_process(tx, ty);
 197         if (mk != 0)
 198         {
 199             for (i=0; keymap[i].hackkey; i++)
 200             {
 201                 if ((keymap[i].hackkey == mk) && is_button_active(i,camera_info.state.gui_mode,camMode))
 202                 {
 203                     touch_panel_state &= ~keymap[i].canonkey;
 204                 }
 205             }
 206         }       
 207     }
 208     else
 209     {
 210         touch_panel_state = touch_panel_button ;                        // on touch release update touch_panel_state
 211         touch_panel_button = 0xFFFFFFFF ;                               // this means there is not key repeat function though
 212     }
 213     return 0;
 214 }
 215 
 216 int ts_process_touch()
 217 {
 218     int rv = 0, i;
 219 
 220     if (touch_panel_state != (long)0xFFFFFFFF)
 221     {
 222         int guiMode = camera_info.state.gui_mode;
 223         int camMode = (get_movie_status()==VIDEO_RECORD_IN_PROGRESS) ? MODE_VID : (mode_get() & MODE_MASK);
 224 
 225         for (i=0; keymap[i].hackkey; i++)
 226         {
 227             if (is_button_active(i, guiMode, camMode))
 228             {
 229                 if (kbd_is_key_clicked(keymap[i].hackkey))
 230                 {
 231                     if (keymap[i].chg_val)
 232                     {
 233                         keymap[i].chg_val(1,(int)keymap[i].conf_val);
 234                         rv = keymap[i].redraw & 1;
 235                     }
 236                     if (keymap[i].redraw & 2) redraw_buttons = 1;
 237                 }
 238             }
 239         }
 240     }
 241     return rv;
 242 }
 243 
 244 int redraw_buttons = 1;
 245 // int menu_key_index = -1;
 246 
 247 void virtual_buttons()
 248 {
 249     int guiMode = camera_info.state.gui_mode;
 250     char buf[30];
 251 
 252     //if(menu_key_index == -1)
 253     //{
 254     //    int i;
 255     //    for (i=0; keymap[i].hackkey != KEY_MENU; i++);
 256     //    menu_key_index = i;
 257     //}
 258 
 259     if (redraw_buttons)
 260     {
 261         int i, x1, y1, x2, y2, ofst;
 262         int camMode = (get_movie_status()==VIDEO_RECORD_IN_PROGRESS) ? MODE_VID : (mode_get() & MODE_MASK);
 263 
 264         twoColors c1 = MAKE_COLOR(COLOR_RED_DK,COLOR_WHITE);        // ALT exit button
 265         twoColors c2 = MAKE_COLOR(COLOR_WHITE, COLOR_BLUE_DK);      // Right side keys
 266         twoColors c3 = MAKE_COLOR(COLOR_WHITE, COLOR_RED_DK);       // Left side keys
 267         twoColors c4 = MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE); // Semi-transparent keys
 268         
 269         for (i=0; keymap[i].hackkey; i++)
 270         {
 271             if (is_button_displayed(i, guiMode, camMode) && keymap[i].nm)
 272             {
 273                 x1 = keymap[i].x1;
 274                 x2 = keymap[i].x2;
 275                 y1 = keymap[i].y1;
 276                 y2 = keymap[i].y2;
 277 
 278                 twoColors clr = c3;
 279                 if ( guiMode == GUI_MODE_SCRIPT ) clr = c4 ;
 280                 else
 281                 {
 282                     if (keymap[i].hackkey == TS_KEY_EXIT) clr = c1;
 283                     else
 284                     {
 285                         if ((x1 >180) || (*keymap[i].conf_val)) clr=c2;
 286                     }
 287                 }
 288                 ofst = 16;
 289 
 290                 draw_rectangle(x1, y1, x2, y2, clr, RECT_BORDER1|DRAW_FILLED|RECT_ROUND_CORNERS);
 291 
 292                 if      (keymap[i].hackkey == KEY_UP)
 293                 {
 294                     rbf_draw_symbol(x1+12, y1+15, 0x53, clr);
 295                 }
 296                 else if (keymap[i].hackkey == KEY_RIGHT)
 297                 {
 298                     rbf_draw_symbol(x1+12, y1+15, 0x52, clr);
 299                 }
 300                 else if (keymap[i].hackkey == KEY_LEFT)
 301                 {
 302                     rbf_draw_symbol(x1+12, y1+15, 0x51, clr);
 303                 }
 304                 else if (keymap[i].hackkey == KEY_DOWN)
 305                 {
 306                     rbf_draw_symbol(x1+12, y1+15, 0x54, clr);
 307                 }
 308                 else
 309                 {
 310                     if (keymap[i].conf_val && keymap[i].chg_val)
 311                     {
 312                         ofst = 7;
 313                         strcpy(buf,(char*)keymap[i].chg_val(0,(int)keymap[i].conf_val));
 314                         buf[3] = 0;
 315                         draw_string(x1+4, y1+25, buf, c3);
 316                     }
 317                     else if (keymap[i].nm2)
 318                     {
 319                         ofst = 7;
 320                         draw_string(x1+4, y1+25, keymap[i].nm2, clr);
 321                     }
 322                     draw_string(x1+4, y1+ofst, keymap[i].nm, clr);
 323                 }
 324             }
 325         }
 326     }
 327 
 328     redraw_buttons = 0;
 329 }
 330 
 331 
 332 long __attribute__((naked)) wrap_kbd_p1_f() ;
 333 
 334 
 335 static void __attribute__((noinline)) mykbd_task_proceed()
 336 {
 337     while (physw_run) {
 338         _SleepTask(physw_sleep_delay);
 339 
 340         if (wrap_kbd_p1_f() == 1) {                                     // autorepeat ?
 341             _kbd_p2_f();
 342         }
 343     }
 344 }
 345 
 346 void __attribute__((naked,noinline)) mykbd_task()                       // no stack manipulation needed here, since we create the task directly
 347 {
 348     mykbd_task_proceed();
 349     _ExitTask();
 350 }
 351 
 352 long __attribute__((naked,noinline)) wrap_kbd_p1_f()
 353 {
 354     asm volatile(
 355         "STMFD   SP!, {R1-R7,LR}\n"
 356         "MOV     R5, #0\n"
 357         "BL        my_kbd_read_keys\n"
 358         "B       _kbd_p1_f_cont\n"
 359     );
 360     return 0;                                                           // bring peace and understanding to the compiler
 361 }
 362 
 363 //static int sdelay = 0 ;
 364 void kbd_fetch_data(long *state) {
 365     _GetKbdState(state);
 366     _kbd_read_keys_r2(state);
 367     // update virtual buttons
 368     if( kbd_is_blocked() )
 369     {
 370        // if (sdelay > 5 )
 371        // {
 372             chdk_process_touch();
 373             virtual_buttons();
 374             kbd_new_state[3] = touch_panel_state;                       // Yes, use virtual button state
 375        // } else sdelay++ ;
 376     }
 377     else
 378     {
 379         kbd_new_state[3] = touch_panel_state = 0xFFFFFFFF;              // No, clear out virtual button state
 380     }
 381 }
 382 
 383 void my_kbd_read_keys()
 384 {
 385     kbd_update_key_state();
 386     kbd_update_physw_bits();
 387 }

/* [<][>][^][v][top][bottom][index][help] */