1
+ use once_cell:: sync:: Lazy ;
1
2
use std:: { collections:: HashMap , fs, path:: Path } ;
2
3
3
4
mod meta;
@@ -61,6 +62,14 @@ macro_rules! keyboards {
61
62
// Calls the `keyboards!` macro
62
63
include ! ( concat!( env!( "OUT_DIR" ) , "/keyboards.rs" ) ) ;
63
64
65
+ pub fn is_qmk_basic ( name : & str ) -> bool {
66
+ static QMK_KEYMAP : Lazy < HashMap < String , u16 > > =
67
+ Lazy :: new ( || parse_keymap_json ( layout_data ( "system76/launch_1" ) . unwrap ( ) . 2 ) . 0 ) ;
68
+ QMK_KEYMAP
69
+ . get ( name)
70
+ . map_or ( false , |scancode| * scancode <= 0xff )
71
+ }
72
+
64
73
impl Layout {
65
74
pub fn from_data (
66
75
meta_json : & str ,
@@ -131,35 +140,36 @@ impl Layout {
131
140
132
141
/// Get the scancode number corresponding to a name
133
142
pub fn scancode_to_name ( & self , scancode : u16 ) -> Option < Keycode > {
134
- // XXX only on QMK?
135
- if scancode >= QK_MOD_TAP && scancode <= QK_MOD_TAP_MAX {
136
- let mods = Mods :: from_bits ( ( scancode >> 8 ) & 0x1f ) ?;
137
- let kc = scancode & 0xff ;
138
- let kc_name = self . scancode_names . get ( & kc) ?;
139
- Some ( Keycode :: MT ( mods, kc_name. clone ( ) ) )
140
- } else if scancode >= QK_LAYER_TAP && scancode <= QK_LAYER_TAP_MAX {
141
- let layer = ( ( scancode >> 8 ) & 0xf ) as u8 ;
142
- let kc = scancode & 0xff ;
143
- let kc_name = self . scancode_names . get ( & kc) ?;
144
- Some ( Keycode :: LT ( layer, kc_name. clone ( ) ) )
145
- } else if scancode >= QK_MODS && scancode <= QK_MODS_MAX {
146
- let mods = Mods :: from_bits ( ( scancode >> 8 ) & 0x1f ) ?;
147
- let kc = scancode & 0xff ;
148
- let kc_name = self . scancode_names . get ( & kc) ?;
149
- Some ( Keycode :: Basic ( mods, kc_name. clone ( ) ) )
150
- } else {
151
- let kc_name = self . scancode_names . get ( & scancode) ?;
152
- if let Some ( mods) = Mods :: from_mod_str ( kc_name) {
153
- Some ( Keycode :: Basic ( mods, "NONE" . to_string ( ) ) )
154
- } else {
155
- Some ( Keycode :: Basic ( Mods :: empty ( ) , kc_name. clone ( ) ) )
143
+ if self . meta . is_qmk {
144
+ if scancode >= QK_MOD_TAP && scancode <= QK_MOD_TAP_MAX {
145
+ let mods = Mods :: from_bits ( ( scancode >> 8 ) & 0x1f ) ?;
146
+ let kc = scancode & 0xff ;
147
+ let kc_name = self . scancode_names . get ( & kc) ?;
148
+ return Some ( Keycode :: MT ( mods, kc_name. clone ( ) ) ) ;
149
+ } else if scancode >= QK_LAYER_TAP && scancode <= QK_LAYER_TAP_MAX {
150
+ let layer = ( ( scancode >> 8 ) & 0xf ) as u8 ;
151
+ let kc = scancode & 0xff ;
152
+ let kc_name = self . scancode_names . get ( & kc) ?;
153
+ return Some ( Keycode :: LT ( layer, kc_name. clone ( ) ) ) ;
154
+ } else if scancode >= QK_MODS && scancode <= QK_MODS_MAX {
155
+ let mods = Mods :: from_bits ( ( scancode >> 8 ) & 0x1f ) ?;
156
+ let kc = scancode & 0xff ;
157
+ let kc_name = self . scancode_names . get ( & kc) ?;
158
+ return Some ( Keycode :: Basic ( mods, kc_name. clone ( ) ) ) ;
156
159
}
157
160
}
161
+ let kc_name = self . scancode_names . get ( & scancode) ?;
162
+ if let Some ( mods) = Mods :: from_mod_str ( kc_name) {
163
+ Some ( Keycode :: Basic ( mods, "NONE" . to_string ( ) ) )
164
+ } else {
165
+ Some ( Keycode :: Basic ( Mods :: empty ( ) , kc_name. clone ( ) ) )
166
+ }
158
167
}
159
168
160
169
/// Get the name corresponding to a scancode number
161
170
pub fn scancode_from_name ( & self , name : & Keycode ) -> Option < u16 > {
162
171
match name {
172
+ Keycode :: MT ( _, _) | Keycode :: LT ( _, _) if !self . meta . is_qmk => None ,
163
173
Keycode :: MT ( mods, keycode_name) => {
164
174
let kc = * self . keymap . get ( keycode_name) ?;
165
175
Some ( QK_MOD_TAP | ( mods. bits ( ) << 8 ) | ( kc & 0xff ) )
@@ -174,17 +184,26 @@ impl Layout {
174
184
}
175
185
Keycode :: Basic ( mods, keycode_name) => {
176
186
if mods. is_empty ( ) {
177
- self . keymap . get ( keycode_name) . copied ( )
178
- } else if let Some ( mod_name) = mods. as_mod_str ( ) {
179
- self . keymap . get ( mod_name) . copied ( )
180
- } else {
187
+ return self . keymap . get ( keycode_name) . copied ( ) ;
188
+ } else if keycode_name == "NONE" {
189
+ if let Some ( mod_name) = mods. as_mod_str ( ) {
190
+ return self . keymap . get ( mod_name) . copied ( ) ;
191
+ }
192
+ }
193
+ if self . meta . is_qmk {
181
194
let kc = * self . keymap . get ( keycode_name) ?;
182
195
Some ( ( mods. bits ( ) << 8 ) | ( kc & 0xff ) )
196
+ } else {
197
+ None
183
198
}
184
199
}
185
200
}
186
201
}
187
202
203
+ pub fn has_scancode ( & self , scancode_name : & str ) -> bool {
204
+ self . keymap . get ( scancode_name) . is_some ( )
205
+ }
206
+
188
207
pub fn f_keys ( & self ) -> impl Iterator < Item = & str > {
189
208
self . default . map . iter ( ) . filter_map ( |( k, v) | {
190
209
if let Some ( num) = v[ 0 ] . strip_prefix ( 'F' ) {
0 commit comments