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     (void)state;
 127     return 0;
 128 #endif
 129 }
 130 
 131 #ifndef KBD_CUSTOM_UPDATE_KEY_STATE
 132 
 133 #ifdef CAM_HAS_GPS
 134 int gps_key_trap=0 ;
 135 #endif
 136 
 137 /*
 138  saves & updates key state, runs main CHDK kbd task code in kbd_process,
 139  returns kbd_process value
 140 */
 141 long kbd_update_key_state(void)
 142 {
 143     kbd_prev_state[0] = kbd_new_state[0];
 144     kbd_prev_state[1] = kbd_new_state[1];
 145     kbd_prev_state[2] = kbd_new_state[2];
 146 
 147 #ifdef CAM_TOUCHSCREEN_UI
 148     kbd_prev_state[3] = kbd_new_state[3];
 149 #endif
 150 
 151     // note assumed kbd_pwr_on has been called if needed
 152     kbd_fetch_data(kbd_new_state);
 153 
 154 #ifdef CAM_HAS_GPS
 155     if (gps_key_trap > 0)        // check if gps code is waiting for a specific key press to cancel shutdown
 156     {
 157         if (kbd_get_pressed_key() == gps_key_trap)
 158         {
 159             kbd_key_release(gps_key_trap);
 160             kbd_key_press(0);
 161             gps_key_trap = -1;  // signal the gps task that the specified button was pressed
 162             msleep(1000);       // pause to allow button release so Canon f/w does not see the press
 163         }
 164     }
 165 #endif
 166 
 167     long status = kbd_process();
 168     if (status == 0){
 169         // leave it alone...
 170         physw_status[0] = kbd_new_state[0];
 171         physw_status[1] = kbd_new_state[1];
 172         physw_status[2] = kbd_new_state[2];
 173 
 174 #ifdef CAM_HAS_JOGDIAL
 175         jogdial_control(0);
 176 #endif
 177     } else {
 178         // override keys
 179         // TODO doesn't handle inverted logic yet
 180         physw_status[0] = (kbd_new_state[0] & (~KEYS_MASK0)) | (kbd_mod_state[0] & KEYS_MASK0);
 181 
 182         physw_status[1] = (kbd_new_state[1] & (~KEYS_MASK1)) | (kbd_mod_state[1] & KEYS_MASK1);
 183 
 184         physw_status[2] = (kbd_new_state[2] & (~KEYS_MASK2)) | (kbd_mod_state[2] & KEYS_MASK2);
 185 
 186 #ifdef CAM_HAS_JOGDIAL
 187         if ((jogdial_stopped==0) && !camera_info.state.state_kbd_script_run) {
 188             jogdial_control(1);
 189             get_jogdial_direction();
 190         }
 191         else if (jogdial_stopped && camera_info.state.state_kbd_script_run) {
 192             jogdial_control(0);
 193         }
 194 #endif
 195     }
 196     return status;
 197 }
 198 #endif // KBD_CUSTOM_UPDATE_KEY_STATE
 199 
 200 #ifndef KBD_CUSTOM_UPDATE_PHYSW_BITS
 201 void kbd_update_physw_bits(void)
 202 {
 203     if (conf.remote_enable) {
 204 #ifdef CAM_REMOTE_MULTICHANNEL
 205         switch(conf.remote_input_channel)
 206         {
 207             case REMOTE_INPUT_USB:
 208                 physw_status[USB_IDX] = physw_status[USB_IDX] & ~(USB_MASK);
 209                 break;
 210             #ifdef CAM_REMOTE_HDMI_HPD
 211             case REMOTE_INPUT_HDMI_HPD:
 212                 physw_status[HDMI_HPD_IDX] |= HDMI_HPD_FLAG;
 213                 break;
 214             #endif
 215             #ifdef CAM_REMOTE_ANALOG_AV
 216             case REMOTE_INPUT_ANALOG_AV:
 217                 physw_status[ANALOG_AV_IDX] |= ANALOG_AV_FLAG;
 218                 break;
 219             #endif
 220          }
 221 #else
 222         physw_status[USB_IDX] = physw_status[USB_IDX] & ~(USB_MASK);
 223 #endif
 224     }
 225     // TODO could save the real USB bit to avoid low level calls in get_usb_bit when immediate update not needed
 226     if (forced_usb_port) {
 227         physw_status[USB_IDX] = physw_status[USB_IDX] | USB_MASK;
 228     }
 229 #ifdef ANALOG_AV_FLAG 
 230     // 1 force on, 2 = force off, other = don't touch
 231     if (forced_analog_av == 1) {
 232         physw_status[ANALOG_AV_IDX] &= ~(ANALOG_AV_FLAG);
 233     } else if(forced_analog_av == 2) {
 234         physw_status[ANALOG_AV_IDX] |= ANALOG_AV_FLAG;
 235     }
 236 
 237 // workaround for crashes switching between analog AV out and native display
 238     static long prev_analog_av_state = 0; // default to not present
 239     long new_analog_av_state = get_analog_av_physw_mod();
 240     if(new_analog_av_state != prev_analog_av_state) {
 241         draw_suspend(1000);
 242         prev_analog_av_state = new_analog_av_state;
 243     }
 244 #endif
 245 // microsd cams don't have a read only bit
 246 #ifndef KBD_SKIP_READONLY_BIT
 247     physw_status[SD_READONLY_IDX] = physw_status[SD_READONLY_IDX] & ~SD_READONLY_FLAG;
 248 #endif
 249 
 250 // n and possibly other micro SD cams uses door bit for autoboot, force back to closed (?)
 251 #ifdef SD_DOOR_OVERRIDE
 252     physw_status[SD_DOOR_IDX] |= SD_DOOR_FLAG;                // override SD card door switch
 253 #endif
 254 
 255 #ifdef OPT_RUN_WITH_BATT_COVER_OPEN
 256     physw_status[BATTCOVER_IDX] = physw_status[BATTCOVER_IDX] | BATTCOVER_FLAG;
 257 #endif
 258 
 259 #ifdef CAM_HOTSHOE_OVERRIDE
 260     if (conf.hotshoe_override == 1) {
 261         physw_status[HOTSHOE_IDX] = physw_status[HOTSHOE_IDX] & ~HOTSHOE_FLAG;
 262     } else if (conf.hotshoe_override == 2) {
 263         physw_status[HOTSHOE_IDX] = physw_status[HOTSHOE_IDX] | HOTSHOE_FLAG;
 264     }
 265 #endif
 266 }
 267 #endif // KBD_CUSTOM_UPDATE_PHYSW_BITS
 268 
 269 // if the port reads an MMIO directly to get USB +5v status, use generic get_usb_bit
 270 // others must define in platform kbd.c
 271 #ifdef USB_MMIO
 272 int get_usb_bit() 
 273 {
 274     volatile int *mmio = (void*)USB_MMIO;
 275     return(( *mmio & USB_MASK)==USB_MASK); 
 276 }
 277 #endif
 278 
 279 #ifdef KBD_SIMULATE_VIDEO_KEY
 280 static int is_video_key_pressed = 0;
 281 #endif
 282 
 283 void kbd_key_press(long key)
 284 {
 285 #ifdef KBD_SIMULATE_VIDEO_KEY
 286     if (key == KEY_VIDEO && !is_video_key_pressed)
 287     {
 288         // TODO define for ID would be more efficient
 289         PostLogicalEventToUI(levent_id_for_name("PressMovieButton"),0);
 290         is_video_key_pressed = 1;
 291         // TODO not clear if this should return, or set state too
 292         return;
 293     }    
 294 #endif
 295     int i;
 296     for (i=0;keymap[i].hackkey;i++){
 297         if (keymap[i].hackkey == key){
 298             kbd_mod_state[keymap[i].grp] &= ~keymap[i].canonkey;
 299             return;
 300         }
 301     }
 302 }
 303 
 304 void kbd_key_release(long key)
 305 {
 306 #ifdef KBD_SIMULATE_VIDEO_KEY
 307     if (key == KEY_VIDEO && is_video_key_pressed)
 308     {
 309         PostLogicalEventToUI(levent_id_for_name("UnpressMovieButton"),0);
 310         is_video_key_pressed = 0;
 311         return;
 312     }
 313 #endif
 314     int i;
 315     for (i=0;keymap[i].hackkey;i++){
 316         if (keymap[i].hackkey == key){
 317             kbd_mod_state[keymap[i].grp] |= keymap[i].canonkey;
 318             return;
 319         }
 320     }
 321 }
 322 
 323 void kbd_key_release_all()
 324 {
 325     kbd_mod_state[0] |= KEYS_MASK0;
 326     kbd_mod_state[1] |= KEYS_MASK1;
 327     kbd_mod_state[2] |= KEYS_MASK2;
 328 // touch screen virtual keys
 329 #ifdef CAM_TOUCHSCREEN_UI
 330     kbd_mod_state[3] |= 0xFFFFFFFF;
 331 #endif
 332 }
 333 
 334 long kbd_is_key_pressed(long key)
 335 {
 336     int i;
 337     for (i=0;keymap[i].hackkey;i++){
 338         if (keymap[i].hackkey == key){
 339             return ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0) ? 1:0;
 340         }
 341     }
 342     return 0;
 343 }
 344 
 345 long kbd_is_key_clicked(long key)
 346 {
 347     int i;
 348     for (i=0;keymap[i].hackkey;i++){
 349         if (keymap[i].hackkey == key){
 350             return ((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
 351                     ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0);
 352         }
 353     }
 354     return 0;
 355 }
 356 
 357 long kbd_get_pressed_key()
 358 {
 359     int i;
 360     for (i=0;keymap[i].hackkey;i++){
 361         if ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0){
 362             return keymap[i].hackkey;
 363         }
 364     }
 365     return 0;
 366 }
 367 
 368 long kbd_get_clicked_key()
 369 {
 370     int i;
 371     for (i=0;keymap[i].hackkey;i++){
 372         if (((kbd_prev_state[keymap[i].grp] & keymap[i].canonkey) != 0) &&
 373             ((kbd_new_state[keymap[i].grp] & keymap[i].canonkey) == 0)){
 374             return keymap[i].hackkey;
 375         }
 376     }
 377     return 0;
 378 }
 379 
 380 #ifdef CAM_USE_ZOOM_FOR_MF
 381 // cameras with an MF use it (s2, s3, s5 etc)
 382 #ifdef KBD_ZOOM_FOR_MF_USE_MF_KEY
 383 long kbd_use_zoom_as_mf() {
 384     static long zoom_key_pressed = 0;
 385 
 386     if (kbd_is_key_pressed(KEY_ZOOM_IN) && kbd_is_key_pressed(KEY_MF) && camera_info.state.mode_rec) {
 387         if (shooting_get_focus_mode()) {
 388             kbd_key_release_all();
 389             kbd_key_press(KEY_MF);
 390             kbd_key_press(KEY_UP);
 391             zoom_key_pressed = KEY_ZOOM_IN;
 392             return 1;
 393         }
 394     } else {
 395         if (zoom_key_pressed==KEY_ZOOM_IN) {
 396             kbd_key_release(KEY_UP);
 397             zoom_key_pressed = 0;
 398             return 1;
 399         }
 400     }
 401     if (kbd_is_key_pressed(KEY_ZOOM_OUT) && kbd_is_key_pressed(KEY_MF) && camera_info.state.mode_rec) {
 402         if (shooting_get_focus_mode()) {
 403             kbd_key_release_all();
 404             kbd_key_press(KEY_MF);
 405             kbd_key_press(KEY_DOWN);
 406             zoom_key_pressed = KEY_ZOOM_OUT;
 407             return 1;
 408         }
 409     } else {
 410         if (zoom_key_pressed==KEY_ZOOM_OUT) {
 411             kbd_key_release(KEY_DOWN);
 412             zoom_key_pressed = 0;
 413             return 1;
 414         }
 415     }
 416     return 0;
 417 }
 418 #else
 419 long kbd_use_zoom_as_mf() {
 420     static long zoom_key_pressed = 0;
 421 
 422     if (kbd_is_key_pressed(KEY_ZOOM_IN) && camera_info.state.mode_rec) {
 423         if (shooting_get_focus_mode()) {
 424             kbd_key_release_all();
 425             kbd_key_press(KEY_RIGHT);
 426             zoom_key_pressed = KEY_ZOOM_IN;
 427             return 1;
 428         }
 429     } else {
 430         if (zoom_key_pressed==KEY_ZOOM_IN) {
 431             kbd_key_release(KEY_RIGHT);
 432             zoom_key_pressed = 0;
 433             return 1;
 434         }
 435     }
 436     if (kbd_is_key_pressed(KEY_ZOOM_OUT) && camera_info.state.mode_rec) {
 437         if (shooting_get_focus_mode()) {
 438             kbd_key_release_all();
 439             kbd_key_press(KEY_LEFT);
 440             zoom_key_pressed = KEY_ZOOM_OUT;
 441             return 1;
 442         }
 443     } else {
 444         if (zoom_key_pressed==KEY_ZOOM_OUT) {
 445             kbd_key_release(KEY_LEFT);
 446             zoom_key_pressed = 0;
 447             return 1;
 448         }
 449     }
 450     return 0;
 451 }
 452 #endif //KBD_ZOOM_FOR_MF_USE_MF_KEY
 453 #endif // CAM_USE_ZOOM_FOR_MF
 454 #endif // KBD_CUSTOM_ALL

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