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

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