root/core/kbd_common.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_hdmi_hpd_physw_mod
  2. get_analog_av_physw_mod
  3. kbd_force_analog_av
  4. kbd_update_key_state
  5. kbd_update_physw_bits
  6. get_usb_bit
  7. kbd_key_press
  8. kbd_key_release
  9. kbd_key_release_all
  10. kbd_is_key_pressed
  11. kbd_is_key_clicked
  12. kbd_get_pressed_key
  13. kbd_get_clicked_key
  14. kbd_use_zoom_as_mf
  15. kbd_use_zoom_as_mf

   1 /*
   2 common low level keyboard handling functions
   3 
   4 WARNING:
   5 If you change code here, be sure to grep platform_kbd.h files for
   6 KBD_CUSTOM_ and make sure that the cameras special platform specific
   7 requirements are updated if required.
   8 
   9 platform_kbd.h defines
  10 ** controls for kbd.c implementation
  11 * this camera has a totally custom keyboard code, don't build common code
  12 KBD_CUSTOM_ALL
  13 
  14 * non-standard key state update
  15 KBD_CUSTOM_UPDATE_KEY_STATE
  16 
  17 * non-standard manipulation of other physw bits (SD readonly, USB etc)
  18 KBD_CUSTOM_UPDATE_PHYSW_BITS
  19 
  20 
  21 * use logical event to simulate "video" button from script
  22 * for touchscreen cameras without a physical video button
  23 KBD_SIMULATE_VIDEO_KEY
  24 
  25 * For cams without an SD card lock (micro-SD)
  26 KBD_SKIP_READONLY_BIT
  27 
  28 * Cameras that have an MF key and enable ZOOM_FOR_MF detect mf presses and use MF key
  29 KBD_ZOOM_FOR_MF_USE_MF_KEY
  30 
  31 ** defines for hardware bits etc
  32 
  33 * key masks - for keys used by CHDK in alt mode
  34 * bitwise OR of all keymap canon key values
  35 KEYS_MASK0
  36 KEYS_MASK1
  37 KEYS_MASK2
  38 
  39 ** SD card read only bit
  40 SD_READONLY_FLAG
  41 ** physw_status index for readonly bit
  42 SD_READONLY_IDX
  43 
  44 ** USB +5v bit
  45 USB_MASK
  46 ** physw_status index for USB bit
  47 USB_IDX
  48 
  49 ** get_usb_bit should use the following MMIO directly.
  50 ** Otherwise, platform must implement get_usb_bit()
  51 USB_MMIO
  52 
  53 ** battery cover override - requires additional supporting code
  54 BATTCOVER_IDX
  55 BATTCOVER_FLAG 
  56 
  57 * override SD card door for cameras micro-sd cams that use it for autoboot
  58 SD_DOOR_OVERRIDE 1
  59 * bit for SD door
  60 SD_DOOR_FLAG
  61 * physw_status index for SD door
  62 SD_DOOR_IDX
  63 
  64 * HDMI Hot Plug Detect bit (0 = hotplug detected)
  65 HDMI_HPD_FLAG
  66 * HDMI Hot Plug Detect index
  67 HDMI_HPD_IDX
  68 
  69 * Analog AV present bit (0 = present)
  70 ANALOG_AV_FLAG
  71 * Analog AV present index
  72 ANALOG_AV_IDX
  73 
  74 */
  75 #include "platform.h"
  76 #include "core.h"
  77 #include "keyboard.h"
  78 #include "kbd_common.h"
  79 #include "conf.h"
  80 #include "usb_remote.h"
  81 // for draw_suspend
  82 #include "gui_draw.h"
  83 
  84 // for KBD_SIMULATE_VIDEO_KEY
  85 #include "levent.h"
  86 
  87 // if KBD_CUSTOM_ALL, platform kbd.c provides everything, this file is noop
  88 // when adding funtionality, grep KBD_CUSTOM_ALL and update accordingly
  89 #ifndef KBD_CUSTOM_ALL
  90 extern long physw_status[3];
  91 extern int forced_usb_port;
  92 
  93 // get HDMI hotplug status from as seen by canon firmware (possibly modified by CHDK)
  94 int get_hdmi_hpd_physw_mod(void)
  95 {
  96 #ifdef HDMI_HPD_FLAG
  97     if(!(physw_status[HDMI_HPD_IDX] & HDMI_HPD_FLAG)) {
  98         return 1;
  99     }
 100 #endif
 101     return 0;
 102 }
 103 
 104 // get analog AV status from as seen by canon firmware (possibly modified by CHDK)
 105 int get_analog_av_physw_mod(void)
 106 {
 107 #ifdef ANALOG_AV_FLAG
 108     if(!(physw_status[ANALOG_AV_IDX] & ANALOG_AV_FLAG)) {
 109         return 1;
 110     }
 111 #endif
 112     return 0;
 113 }
 114 
 115 #ifdef ANALOG_AV_FLAG
 116 int forced_analog_av;
 117 long prev_analog_av_state;
 118 #endif
 119 
 120 int kbd_force_analog_av(int state)
 121 {
 122 #ifdef ANALOG_AV_FLAG
 123     forced_analog_av = state;
 124     return 1;
 125 #else
 126     return 0;
 127 #endif
 128 }
 129 
 130 #ifndef KBD_CUSTOM_UPDATE_KEY_STATE
 131 
 132 #ifdef CAM_HAS_GPS
 133 int gps_key_trap=0 ;
 134 #endif
 135 
 136 /*
 137  saves & updates key state, runs main CHDK kbd task code in kbd_process,
 138  returns kbd_process value
 139 */
 140 long kbd_update_key_state(void)
 141 {
 142     kbd_prev_state[0] = kbd_new_state[0];
 143     kbd_prev_state[1] = kbd_new_state[1];
 144     kbd_prev_state[2] = kbd_new_state[2];
 145 
 146 #ifdef CAM_TOUCHSCREEN_UI
 147     kbd_prev_state[3] = kbd_new_state[3];
 148 #endif
 149 
 150     // note assumed kbd_pwr_on has been called if needed
 151     kbd_fetch_data(kbd_new_state);
 152 
 153 #ifdef CAM_HAS_GPS
 154     if (gps_key_trap > 0)        // check if gps code is waiting for a specific key press to cancel shutdown
 155     {
 156         if (kbd_get_pressed_key() == gps_key_trap)
 157         {
 158             kbd_key_release(gps_key_trap);
 159             kbd_key_press(0);
 160             gps_key_trap = -1;  // signal the gps task that the specified button was pressed
 161             msleep(1000);       // pause to allow button release so Canon f/w does not see the press
 162         }
 163     }
 164 #endif
 165 
 166     long status = kbd_process();
 167     if (status == 0){
 168         // leave it alone...
 169         physw_status[0] = kbd_new_state[0];
 170         physw_status[1] = kbd_new_state[1];
 171         physw_status[2] = kbd_new_state[2];
 172 
 173 #ifdef CAM_HAS_JOGDIAL
 174         jogdial_control(0);
 175 #endif
 176     } else {
 177         // override keys
 178         // TODO doesn't handle inverted logic yet
 179         physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
 180 
 181         physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
 182 
 183         physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
 184 
 185 #ifdef CAM_HAS_JOGDIAL
 186         if ((jogdial_stopped==0) && !camera_info.state.state_kbd_script_run) {
 187             jogdial_control(1);
 188             get_jogdial_direction();
 189         }
 190         else if (jogdial_stopped && camera_info.state.state_kbd_script_run) {
 191             jogdial_control(0);
 192         }
 193 #endif
 194     }
 195     return status;
 196 }
 197 #endif // KBD_CUSTOM_UPDATE_KEY_STATE
 198 
 199 #ifndef KBD_CUSTOM_UPDATE_PHYSW_BITS
 200 void kbd_update_physw_bits(void)
 201 {
 202     if (conf.remote_enable) {
 203 #ifdef CAM_REMOTE_MULTICHANNEL
 204         switch(conf.remote_input_channel)
 205         {
 206             case REMOTE_INPUT_USB:
 207                 physw_status[USB_IDX] = physw_status[USB_IDX] & ~(USB_MASK);
 208                 break;
 209             #ifdef CAM_REMOTE_HDMI_HPD
 210             case REMOTE_INPUT_HDMI_HPD:
 211                 physw_status[HDMI_HPD_IDX] |= HDMI_HPD_FLAG;
 212                 break;
 213             #endif
 214             #ifdef CAM_REMOTE_ANALOG_AV
 215             case REMOTE_INPUT_ANALOG_AV:
 216                 physw_status[ANALOG_AV_IDX] |= ANALOG_AV_FLAG;
 217                 break;
 218             #endif
 219          }
 220 #else
 221         physw_status[USB_IDX] = physw_status[USB_IDX] & ~(USB_MASK);
 222 #endif
 223     }
 224     // TODO could save the real USB bit to avoid low level calls in get_usb_bit when immediate update not needed
 225     if (forced_usb_port) {
 226         physw_status[USB_IDX] = physw_status[USB_IDX] | USB_MASK;
 227     }
 228 #ifdef ANALOG_AV_FLAG 
 229     // 1 force on, 2 = force off, other = don't touch
 230     if (forced_analog_av == 1) {
 231         physw_status[ANALOG_AV_IDX] &= ~(ANALOG_AV_FLAG);
 232     } else if(forced_analog_av == 2) {
 233         physw_status[ANALOG_AV_IDX] |= ANALOG_AV_FLAG;
 234     }
 235 
 236 // workaround for crashes switching between analog AV out and native display
 237     static long prev_analog_av_state = 0; // default to not present
 238     long new_analog_av_state = get_analog_av_physw_mod();
 239     if(new_analog_av_state != prev_analog_av_state) {
 240         draw_suspend(1000);
 241         prev_analog_av_state = new_analog_av_state;
 242     }
 243 #endif
 244 // microsd cams don't have a read only bit
 245 #ifndef KBD_SKIP_READONLY_BIT
 246     physw_status[SD_READONLY_IDX] = physw_status[SD_READONLY_IDX] & ~SD_READONLY_FLAG;
 247 #endif
 248 
 249 // n and possibly other micro SD cams uses door bit for autoboot, force back to closed (?)
 250 #ifdef SD_DOOR_OVERRIDE
 251     physw_status[SD_DOOR_IDX] |= SD_DOOR_FLAG;                // override SD card door switch
 252 #endif
 253 
 254 #ifdef OPT_RUN_WITH_BATT_COVER_OPEN
 255     physw_status[BATTCOVER_IDX] = physw_status[BATTCOVER_IDX] | BATTCOVER_FLAG;
 256 #endif
 257 
 258 #ifdef CAM_HOTSHOE_OVERRIDE
 259     if (conf.hotshoe_override == 1) {
 260         physw_status[HOTSHOE_IDX] = physw_status[HOTSHOE_IDX] & ~HOTSHOE_FLAG;
 261     } else if (conf.hotshoe_override == 2) {
 262         physw_status[HOTSHOE_IDX] = physw_status[HOTSHOE_IDX] | HOTSHOE_FLAG;
 263     }
 264 #endif
 265 }
 266 #endif // KBD_CUSTOM_UPDATE_PHYSW_BITS
 267 
 268 // if the port reads an MMIO directly to get USB +5v status, use generic get_usb_bit
 269 // others must define in platform kbd.c
 270 #ifdef USB_MMIO
 271 int get_usb_bit() 
 272 {
 273     volatile int *mmio = (void*)USB_MMIO;
 274     return(( *mmio & USB_MASK)==USB_MASK); 
 275 }
 276 #endif
 277 
 278 #ifdef KBD_SIMULATE_VIDEO_KEY
 279 static int is_video_key_pressed = 0;
 280 #endif
 281 
 282 void kbd_key_press(long key)
 283 {
 284 #ifdef KBD_SIMULATE_VIDEO_KEY
 285     if (key == KEY_VIDEO && !is_video_key_pressed)
 286     {
 287         // TODO define for ID would be more efficient
 288         PostLogicalEventToUI(levent_id_for_name("PressMovieButton"),0);
 289         is_video_key_pressed = 1;
 290         // TODO not clear if this should return, or set state too
 291         return;
 292     }    
 293 #endif
 294     int i;
 295     for (i=0;keymap[i].hackkey;i++){
 296         if (keymap[i].hackkey == key){
 297             kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
 298             return;
 299         }
 300     }
 301 }
 302 
 303 void kbd_key_release(long key)
 304 {
 305 #ifdef KBD_SIMULATE_VIDEO_KEY
 306     if (key == KEY_VIDEO && is_video_key_pressed)
 307     {
 308         PostLogicalEventToUI(levent_id_for_name("UnpressMovieButton"),0);
 309         is_video_key_pressed = 0;
 310         return;
 311     }
 312 #endif
 313     int i;
 314     for (i=0;keymap[i].hackkey;i++){
 315         if (keymap[i].hackkey == key){
 316             kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
 317             return;
 318         }
 319     }
 320 }
 321 
 322 void kbd_key_release_all()
 323 {
 324     kbd_mod_state[0] |= KEYS_MASK0;
 325     kbd_mod_state[1] |= KEYS_MASK1;
 326     kbd_mod_state[2] |= KEYS_MASK2;
 327 // touch screen virtual keys
 328 #ifdef CAM_TOUCHSCREEN_UI
 329     kbd_mod_state[3] |= 0xFFFFFFFF;
 330 #endif
 331 }
 332 
 333 long kbd_is_key_pressed(long key)
 334 {
 335     int i;
 336     for (i=0;keymap[i].hackkey;i++){
 337         if (keymap[i].hackkey == key){
 338             return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
 339         }
 340     }
 341     return 0;
 342 }
 343 
 344 long kbd_is_key_clicked(long key)
 345 {
 346     int i;
 347     for (i=0;keymap[i].hackkey;i++){
 348         if (keymap[i].hackkey == key){
 349             return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
 350                     ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
 351         }
 352     }
 353     return 0;
 354 }
 355 
 356 long kbd_get_pressed_key()
 357 {
 358     int i;
 359     for (i=0;keymap[i].hackkey;i++){
 360         if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
 361             return keymap[i].hackkey;
 362         }
 363     }
 364     return 0;
 365 }
 366 
 367 long kbd_get_clicked_key()
 368 {
 369     int i;
 370     for (i=0;keymap[i].hackkey;i++){
 371         if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
 372             ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
 373             return keymap[i].hackkey;
 374         }
 375     }
 376     return 0;
 377 }
 378 
 379 #ifdef CAM_USE_ZOOM_FOR_MF
 380 // cameras with an MF use it (s2, s3, s5 etc)
 381 #ifdef KBD_ZOOM_FOR_MF_USE_MF_KEY
 382 long kbd_use_zoom_as_mf() {
 383     static long zoom_key_pressed = 0;
 384 
 385     if (kbd_is_key_pressed(KEY_ZOOM_IN) && kbd_is_key_pressed(KEY_MF) && camera_info.state.mode_rec) {
 386         if (shooting_get_focus_mode()) {
 387             kbd_key_release_all();
 388             kbd_key_press(KEY_MF);
 389             kbd_key_press(KEY_UP);
 390             zoom_key_pressed = KEY_ZOOM_IN;
 391             return 1;
 392         }
 393     } else {
 394         if (zoom_key_pressed==KEY_ZOOM_IN) {
 395             kbd_key_release(KEY_UP);
 396             zoom_key_pressed = 0;
 397             return 1;
 398         }
 399     }
 400     if (kbd_is_key_pressed(KEY_ZOOM_OUT) && kbd_is_key_pressed(KEY_MF) && camera_info.state.mode_rec) {
 401         if (shooting_get_focus_mode()) {
 402             kbd_key_release_all();
 403             kbd_key_press(KEY_MF);
 404             kbd_key_press(KEY_DOWN);
 405             zoom_key_pressed = KEY_ZOOM_OUT;
 406             return 1;
 407         }
 408     } else {
 409         if (zoom_key_pressed==KEY_ZOOM_OUT) {
 410             kbd_key_release(KEY_DOWN);
 411             zoom_key_pressed = 0;
 412             return 1;
 413         }
 414     }
 415     return 0;
 416 }
 417 #else
 418 long kbd_use_zoom_as_mf() {
 419     static long zoom_key_pressed = 0;
 420 
 421     if (kbd_is_key_pressed(KEY_ZOOM_IN) && camera_info.state.mode_rec) {
 422         if (shooting_get_focus_mode()) {
 423             kbd_key_release_all();
 424             kbd_key_press(KEY_RIGHT);
 425             zoom_key_pressed = KEY_ZOOM_IN;
 426             return 1;
 427         }
 428     } else {
 429         if (zoom_key_pressed==KEY_ZOOM_IN) {
 430             kbd_key_release(KEY_RIGHT);
 431             zoom_key_pressed = 0;
 432             return 1;
 433         }
 434     }
 435     if (kbd_is_key_pressed(KEY_ZOOM_OUT) && camera_info.state.mode_rec) {
 436         if (shooting_get_focus_mode()) {
 437             kbd_key_release_all();
 438             kbd_key_press(KEY_LEFT);
 439             zoom_key_pressed = KEY_ZOOM_OUT;
 440             return 1;
 441         }
 442     } else {
 443         if (zoom_key_pressed==KEY_ZOOM_OUT) {
 444             kbd_key_release(KEY_LEFT);
 445             zoom_key_pressed = 0;
 446             return 1;
 447         }
 448     }
 449     return 0;
 450 }
 451 #endif //KBD_ZOOM_FOR_MF_USE_MF_KEY
 452 #endif // CAM_USE_ZOOM_FOR_MF
 453 #endif // KBD_CUSTOM_ALL

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