]> git.donarmstrong.com Git - qmk_firmware.git/blob - users/edvorakjp/edvorakjp.c
Merge branch 'master' of github.com:qmk/qmk_firmware into hf/shinydox
[qmk_firmware.git] / users / edvorakjp / edvorakjp.c
1 #include "eeprom.h"
2 #include "edvorakjp.h"
3
4 bool japanese_mode;
5 uint16_t time_on_pressed;
6
7 edvorakjp_config_t edvorakjp_config;
8
9 uint8_t eeconfig_read_edvorakjp(void) {
10   return eeprom_read_byte(EECONFIG_EDVORAK);
11 }
12
13 void eeconfig_update_edvorakjp(uint8_t val) {
14   eeprom_update_byte(EECONFIG_EDVORAK, val);
15 }
16
17 void dvorakj_layer_off(void) {
18   layer_off(_EDVORAKJ1);
19   layer_off(_EDVORAKJ2);
20 }
21
22 void update_japanese_mode(bool new_state) {
23   japanese_mode = new_state;
24   if (japanese_mode) {
25     if (edvorakjp_config.enable_kc_lang) {
26       SEND_STRING(SS_TAP(X_LANG1));
27     } else {
28       SEND_STRING(SS_LALT("`"));
29     }
30   } else {
31     dvorakj_layer_off();
32     if (edvorakjp_config.enable_kc_lang) {
33       SEND_STRING(SS_TAP(X_LANG2));
34     } else {
35       SEND_STRING(SS_LALT("`"));
36     }
37   }
38 }
39
40 void matrix_init_user(void) {
41   japanese_mode = false;
42   time_on_pressed = 0;
43   edvorakjp_config.raw = eeconfig_read_edvorakjp();
44
45   matrix_init_keymap();
46 }
47
48 __attribute__ ((weak))
49 void matrix_init_keymap() {}
50
51 uint32_t layer_state_set_user(uint32_t state) {
52   state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
53   return layer_state_set_keymap(state);
54 }
55
56 __attribute__ ((weak))
57 uint32_t layer_state_set_keymap(uint32_t state) {
58   return state;
59 }
60
61 /*
62  * Each process_record_* methods defined here are
63  * return false if handle edvorak_keycodes, or return true others.
64  */
65 __attribute__ ((weak))
66 bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
67   return true;
68 }
69
70 bool process_record_edvorakjp_ext(uint16_t keycode, keyrecord_t *record) {
71   if (!(edvorakjp_config.enable_jp_extra_layer &&\
72         (default_layer_state == 1UL<<_EDVORAK) &&\
73         japanese_mode &&\
74         record->event.pressed)) {
75     return true;
76   }
77
78   // consonant keys
79   // layer_on(J1) or layer_on(J2) are defined based on key positions.
80   switch (keycode) {
81     // right hand's left side w/o N
82     case KC_F:
83     case KC_G:
84     case KC_R:
85     case KC_D:
86     case KC_T:
87     case KC_B:
88     case KC_H:
89     case KC_J:
90       layer_on(_EDVORAKJ1);
91       register_code(keycode);
92       unregister_code(keycode);
93       return false;
94
95     // N: toggle layer
96     case KC_N:
97       biton32(layer_state) == _EDVORAK ? layer_on(_EDVORAKJ1) : dvorakj_layer_off();
98       register_code(keycode);
99       unregister_code(keycode);
100       return false;
101
102     // left hand and right hand's right side
103     case KC_X:
104     case KC_C:
105     case KC_V:
106     case KC_Z:
107     case KC_P:
108     case KC_Y:
109     case KC_W:
110     case KC_Q:
111     case KC_S:
112     case KC_M:
113     case KC_K:
114     case KC_L:
115       layer_on(_EDVORAKJ2);
116       register_code(keycode);
117       unregister_code(keycode);
118       return false;
119   }
120
121   // vowel keys, symbol keys and modifier keys
122   dvorakj_layer_off();
123   switch (keycode) {
124     // combination vowel keys
125     case KC_AI:
126       SEND_STRING("ai");
127       return false;
128     case KC_OU:
129       SEND_STRING("ou");
130       return false;
131     case KC_EI:
132       SEND_STRING("ei");
133       return false;
134     case KC_ANN:
135       SEND_STRING("ann");
136       return false;
137     case KC_ONN:
138       SEND_STRING("onn");
139       return false;
140     case KC_ENN:
141       SEND_STRING("enn");
142       return false;
143     case KC_INN:
144       SEND_STRING("inn");
145       return false;
146     case KC_UNN:
147       SEND_STRING("unn");
148       return false;
149
150     // AOEIU and other (symbol, modifier) keys
151     default:
152       return true;
153   }
154 }
155
156 bool process_record_edvorakjp_config(uint16_t keycode, keyrecord_t *record) {
157   switch (keycode) {
158     case KC_MAC:
159       edvorakjp_config.enable_kc_lang = true;
160       eeconfig_update_edvorakjp(edvorakjp_config.raw);
161       return false;
162     case KC_WIN:
163       edvorakjp_config.enable_kc_lang = false;
164       eeconfig_update_edvorakjp(edvorakjp_config.raw);
165       return false;
166     case KC_EXTON:
167       edvorakjp_config.enable_jp_extra_layer = true;
168       eeconfig_update_edvorakjp(edvorakjp_config.raw);
169       return false;
170     case KC_EXTOFF:
171       edvorakjp_config.enable_jp_extra_layer = false;
172       eeconfig_update_edvorakjp(edvorakjp_config.raw);
173       return false;
174   }
175   return true;
176 }
177
178 bool process_record_layer(uint16_t keycode, keyrecord_t *record) {
179   switch (keycode) {
180     case EDVORAK:
181       if (record->event.pressed) {
182         set_single_persistent_default_layer(_EDVORAK);
183       }
184       return false;
185     case QWERTY:
186       if (record->event.pressed) {
187         dvorakj_layer_off();
188         set_single_persistent_default_layer(_QWERTY);
189       }
190       return false;
191     case LOWER:
192       if (record->event.pressed) {
193         layer_on(_LOWER);
194         time_on_pressed = record->event.time;
195       } else {
196         layer_off(_LOWER);
197
198         if (TIMER_DIFF_16(record->event.time, time_on_pressed) < TAPPING_TERM) {
199           update_japanese_mode(false);
200         }
201         time_on_pressed = 0;
202       }
203       return false;
204     case RAISE:
205       if (record->event.pressed) {
206         layer_on(_RAISE);
207         time_on_pressed = record->event.time;
208       } else {
209         layer_off(_RAISE);
210
211         if (TIMER_DIFF_16(record->event.time, time_on_pressed) < TAPPING_TERM) {
212           update_japanese_mode(true);
213         }
214         time_on_pressed = 0;
215       }
216       return false;
217     default:
218       return true;
219   }
220 }
221
222 bool process_record_ime(uint16_t keycode, keyrecord_t *record) {
223   switch (keycode) {
224     case KC_JPN:
225       if (record->event.pressed) {
226         update_japanese_mode(true);
227       }
228       return false;
229     case KC_ENG:
230       if (record->event.pressed) {
231         update_japanese_mode(false);
232       }
233       return false;
234     default:
235       return true;
236   }
237 }
238
239 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
240
241   return process_record_keymap(keycode, record) &&\
242          process_record_edvorakjp_ext(keycode, record) &&\
243          process_record_edvorakjp_config(keycode, record) &&\
244          process_record_layer(keycode, record) &&\
245          process_record_ime(keycode, record);
246 }