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

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