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

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