diff options
author | tmk <nobody@nowhere> | 2012-06-11 10:53:02 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2012-06-11 10:53:02 +0900 |
commit | 62d1ebb91c7b381ce3d88aad9ee0b03bea9fce26 (patch) | |
tree | 6b10864a310f611187e1b61102da7da1db1d2e29 /common/keyboard.c | |
parent | 225de7a847a511d004bf909b1334e19497cf2f9d (diff) | |
parent | 81706d1130fdc3c0d6d110f4d8665c47ffd7fb59 (diff) |
Merge branch 'newdir'
Diffstat (limited to 'common/keyboard.c')
-rw-r--r-- | common/keyboard.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/common/keyboard.c b/common/keyboard.c new file mode 100644 index 0000000000..5c2643c951 --- /dev/null +++ b/common/keyboard.c @@ -0,0 +1,203 @@ +/* +Copyright 2011 Jun Wako <wakojun@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "keyboard.h" +#include "host.h" +#include "layer.h" +#include "matrix.h" +#include "led.h" +#include "usb_keycodes.h" +#include "timer.h" +#include "print.h" +#include "debug.h" +#include "command.h" +#ifdef MOUSEKEY_ENABLE +#include "mousekey.h" +#endif +#ifdef EXTRAKEY_ENABLE +#include <util/delay.h> +#endif + + +static uint8_t last_leds = 0; + + +void keyboard_init(void) +{ + timer_init(); + matrix_init(); +#ifdef PS2_MOUSE_ENABLE + ps2_mouse_init(); +#endif +} + +void keyboard_proc(void) +{ + uint8_t fn_bits = 0; +#ifdef EXTRAKEY_ENABLE + uint16_t consumer_code = 0; +#endif + + matrix_scan(); + + if (matrix_is_modified()) { + if (debug_matrix) matrix_print(); +#ifdef DEBUG_LED + // LED flash for debug + DEBUG_LED_CONFIG; + DEBUG_LED_ON; +#endif + } + + if (matrix_has_ghost()) { + // should send error? + debug("matrix has ghost!!\n"); + return; + } + + host_swap_keyboard_report(); + host_clear_keyboard_report(); + for (int row = 0; row < matrix_rows(); row++) { + for (int col = 0; col < matrix_cols(); col++) { + if (!matrix_is_on(row, col)) continue; + + uint8_t code = layer_get_keycode(row, col); + if (code == KB_NO) { + // do nothing + } else if (IS_MOD(code)) { + host_add_mod_bit(MOD_BIT(code)); + } else if (IS_FN(code)) { + fn_bits |= FN_BIT(code); + } +// TODO: use table or something +#ifdef EXTRAKEY_ENABLE + // System Control + else if (code == KB_SYSTEM_POWER) { +#ifdef HOST_PJRC + if (suspend && remote_wakeup) { + usb_remote_wakeup(); + } else { + host_system_send(SYSTEM_POWER_DOWN); + } +#else + host_system_send(SYSTEM_POWER_DOWN); +#endif + host_system_send(0); + _delay_ms(500); + } else if (code == KB_SYSTEM_SLEEP) { + host_system_send(SYSTEM_SLEEP); + host_system_send(0); + _delay_ms(500); + } else if (code == KB_SYSTEM_WAKE) { + host_system_send(SYSTEM_WAKE_UP); + host_system_send(0); + _delay_ms(500); + } + // Consumer Page + else if (code == KB_AUDIO_MUTE) { + consumer_code = AUDIO_MUTE; + } else if (code == KB_AUDIO_VOL_UP) { + consumer_code = AUDIO_VOL_UP; + } else if (code == KB_AUDIO_VOL_DOWN) { + consumer_code = AUDIO_VOL_DOWN; + } + else if (code == KB_MEDIA_NEXT_TRACK) { + consumer_code = TRANSPORT_NEXT_TRACK; + } else if (code == KB_MEDIA_PREV_TRACK) { + consumer_code = TRANSPORT_PREV_TRACK; + } else if (code == KB_MEDIA_STOP) { + consumer_code = TRANSPORT_STOP; + } else if (code == KB_MEDIA_PLAY_PAUSE) { + consumer_code = TRANSPORT_PLAY_PAUSE; + } else if (code == KB_MEDIA_SELECT) { + consumer_code = AL_CC_CONFIG; + } + else if (code == KB_MAIL) { + consumer_code = AL_EMAIL; + } else if (code == KB_CALCULATOR) { + consumer_code = AL_CALCULATOR; + } else if (code == KB_MY_COMPUTER) { + consumer_code = AL_LOCAL_BROWSER; + } + else if (code == KB_WWW_SEARCH) { + consumer_code = AC_SEARCH; + } else if (code == KB_WWW_HOME) { + consumer_code = AC_HOME; + } else if (code == KB_WWW_BACK) { + consumer_code = AC_BACK; + } else if (code == KB_WWW_FORWARD) { + consumer_code = AC_FORWARD; + } else if (code == KB_WWW_STOP) { + consumer_code = AC_STOP; + } else if (code == KB_WWW_REFRESH) { + consumer_code = AC_REFRESH; + } else if (code == KB_WWW_FAVORITES) { + consumer_code = AC_BOOKMARKS; + } +#endif + else if (IS_KEY(code)) { + host_add_key(code); + } +#ifdef MOUSEKEY_ENABLE + else if (IS_MOUSEKEY(code)) { + mousekey_decode(code); + } +#endif + else { + debug("ignore keycode: "); debug_hex(code); debug("\n"); + } + } + } + + layer_switching(fn_bits); + + if (command_proc()) { + return; + } + + // TODO: should send only when changed from last report + if (matrix_is_modified()) { + host_send_keyboard_report(); +#ifdef EXTRAKEY_ENABLE + host_consumer_send(consumer_code); +#endif +#ifdef DEBUG_LED + // LED flash for debug + DEBUG_LED_CONFIG; + DEBUG_LED_OFF; +#endif + } + +#ifdef MOUSEKEY_ENABLE + mousekey_send(); +#endif + +#ifdef PS2_MOUSE_ENABLE + // TODO: should comform new API + if (ps2_mouse_read() == 0) + ps2_mouse_usb_send(); +#endif + + if (last_leds != host_keyboard_leds()) { + keyboard_set_leds(host_keyboard_leds()); + last_leds = host_keyboard_leds(); + } +} + +void keyboard_set_leds(uint8_t leds) +{ + led_set(leds); +} |