Repository: trustcrypto/OnlyKey-Firmware Branch: master Commit: 9600daa8ffc8 Files: 12 Total size: 475.3 KB Directory structure: gitextract_wrctxzzj/ ├── .gitignore ├── OnlyKey/ │ └── OnlyKey.ino ├── README.md ├── keylayouts.c ├── keylayouts.h ├── usb_desc.c ├── usb_desc.h ├── usb_dev.c ├── usb_dev.h ├── usb_keyboard.c ├── usb_rawhid.c └── usb_rawhid.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msm *.msp # Windows shortcuts *.lnk # ========================= # Operating System Files # ========================= # OSX # ========================= .DS_Store .AppleDouble .LSOverride # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk OnlyKey_NOPIN/OnlyKey_NOPIN.ino ================================================ FILE: OnlyKey/OnlyKey.ino ================================================ /* * Copyright (c) 2015-2022, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*************************************/ //Firmware Build Options /*************************************/ #define DEBUG //Enable Serial Monitor, debug firmware #define STD_VERSION //Define for STD edition firmare, undefine for IN TRVL edition firmware #define OK_Color //Define for hardware with color LED //#define FACTORYKEYS2 // Attestation key and other keys encrypted using CHIP ID and RNG for unique per device #ifndef STD_VERSION #undef FACTORYKEYS2 #endif /*************************************/ //Standard Libraries /*************************************/ #include "sha256.h" #include "EEPROM.h" #include "T3MacLib.h" #include "SoftTimer.h" #include "password.h" #include "sha1.h" #include "totp.h" #include "Time.h" #include "onlykey.h" #include "flashkinetis.h" #include "RNG.h" #include "base64.h" #include "ADC.h" #include "usb_dev.h" /*************************************/ //Color LED Libraries /*************************************/ #ifdef OK_Color #include "Adafruit_NeoPixel.h" #endif /*************************************/ //Additional Libraries to Load for STD firmware version //These libraries will only be used if STD_VERSION is defined /*************************************/ extern uint8_t profilemode; #ifdef STD_VERSION #define OKSOLO //Using FIDO2 from SOLO #include "yksim.h" #include "uECC.h" #include "ykcore.h" #include "AES.h" #include "GCM.h" #include "rsa.h" #include "tweetnacl.h" /*************************************/ //FIDO2 Libraries /*************************************/ #ifdef OKSOLO #include "ctap.h" #include "ctaphid.h" #include "cbor.h" #include "ctap_parse.h" #include "ctap_errors.h" #include "device.h" #include "storage.h" #include "wallet.h" #include "solo.h" #include "extensions.h" #include "ok_extension.h" #include "crypto.h" #include "u2f.h" #endif #endif /*************************************/ //LED Assignments /*************************************/ extern uint8_t NEO_Color; extern uint8_t NEO_Brightness[1]; extern uint8_t touchoffset; extern uint8_t Profile_Offset; /*************************************/ //RNG Assignments /*************************************/ bool calibrating = false; extern char ID[36]; /*************************************/ //PIN Assigment Variables /*************************************/ extern uint8_t BLINKPIN; extern uint8_t TOUCHPIN1; extern uint8_t TOUCHPIN2; extern uint8_t TOUCHPIN3; extern uint8_t TOUCHPIN4; extern uint8_t TOUCHPIN5; extern uint8_t TOUCHPIN6; extern uint8_t ANALOGPIN1; extern uint8_t ANALOGPIN2; extern unsigned int sumofall; /*************************************/ //Keypad / Password Assignments /*************************************/ extern int button_selected; //Key selected 1-6 static int pass_keypress = 1; //The number key presses in current password attempt static int session_attempts = 0; //The number of password attempts this session static bool firsttime = true; extern Password password; extern uint8_t TIMEOUT[1]; extern uint8_t TYPESPEED[1]; extern uint8_t KeyboardLayout[1]; extern uint8_t mod_keys_enabled; /*************************************/ //Capacitive Touch Variables /*************************************/ extern unsigned int touchread1; extern unsigned int touchread2; extern unsigned int touchread3; extern unsigned int touchread4; extern unsigned int touchread5; extern unsigned int touchread6; extern unsigned int touchread1ref; extern unsigned int touchread2ref; extern unsigned int touchread3ref; extern unsigned int touchread4ref; extern unsigned int touchread5ref; extern unsigned int touchread6ref; /*************************************/ //Keys, Hashes, Integrity Counters /*************************************/ extern uint8_t profilekey[32]; extern uint8_t p1hash[32]; extern uint8_t sdhash[32]; extern uint8_t p2hash[32]; extern uint8_t nonce[32]; extern int initcheck; extern int integrityctr1; extern int integrityctr2; /*************************************/ //SoftTimer Tasks /*************************************/ #define TIME_POLL 50 // poll "key" every 50 ms Task taskKey(TIME_POLL, checkKey); Task taskKB(50, sendKey); // Default send kb codes every 50 ms Task taskInitialized(1000, sendInitialized); /*************************************/ //CRYPTO /*************************************/ extern uint8_t Challenge_button1; extern uint8_t Challenge_button2; extern uint8_t Challenge_button3; extern uint8_t CRYPTO_AUTH; extern int packet_buffer_offset; extern uint8_t packet_buffer_details[5]; extern uint8_t outputmode; extern uint8_t derived_key_challenge_mode; extern uint8_t stored_key_challenge_mode; /*************************************/ //Other /*************************************/ extern uint8_t recv_buffer[64]; char keybuffer[EElen_url+EElen_addchar+EElen_delay+EElen_addchar+EElen_username+EElen_delay+EElen_addchar+EElen_password+EElen_addchar+EElen_2FAtype+64+EElen_addchar+EElen_addchar+10]; //Buffer to hold all keystrokes char *pos; extern uint8_t isfade; #ifdef STD_VERSION extern uint8_t ctap_buffer[CTAPHID_BUFFER_SIZE]; #endif extern uint8_t pending_operation; uint8_t modkey; extern uint8_t onlykeyhw; extern uint8_t Duo_config[2]; extern "C" { int _getpid(){ return -1;} int _kill(int pid, int sig){ return -1; } int _write(){return -1;} } /*************************************/ //Arduino Setup /*************************************/ void setup() { // Delay may be needed for serial debug // delay(3000); analogReadResolution(16); #ifdef DEBUG Serial.begin(9600); #endif #ifdef STD_VERSION profilemode = STDPROFILE1; #else profilemode = NONENCRYPTEDPROFILE; #endif /*************************************/ //PIN Assigments /*************************************/ BLINKPIN=6; TOUCHPIN1=1; // #define CORE_PIN1_CONFIG PORTB_PCR17 TOUCHPIN2=22; //#define CORE_PIN22_CONFIG PORTC_PCR1 TOUCHPIN3=23; //#define CORE_PIN23_CONFIG PORTC_PCR2 OnlyKey DUO Button #1 TOUCHPIN4=17; //#define CORE_PIN17_CONFIG PORTB_PCR1 TOUCHPIN5=15; //#define CORE_PIN15_CONFIG PORTC_PCR0 OnlyKey DUO Button #2 TOUCHPIN6=16; //#define CORE_PIN16_CONFIG PORTB_PCR0 ANALOGPIN1=A0; //#define CORE_PIN14_CONFIG PORTD_PCR1 ANALOGPIN2=A7; //#define CORE_PIN21_CONFIG PORTD_PCR6 /*************************************/ initcheck = okcore_flashget_noncehash ((uint8_t*)nonce, 32); //Check if first time use CHIP_ID(); // Get Unique chip ID from ROM unsigned int analog1 = analogRead(ANALOGPIN1); unsigned int analog2 = analogRead(ANALOGPIN2); integrityctr1++; /* //dump flash storage, useful for verifying contents Serial.println(initcheck); char temp[32]; wipeEEPROM(); unsigned long readadr = flashstorestart; while (readadr <= flashend) { for(int i =0; i<=2048; i=i+4){ sprintf (temp, "%.8X", *((unsigned int*)readadr)); Serial.print(temp); readadr = readadr + 4; } Serial.println(); } */ //FSEC currently set to 0x44, everything disabled except mass erase https://forum.pjrc.com/threads/28783-Upload-Hex-file-from-Teensy-3-1 if (FTFL_FSEC!=0x44) { // First time starting up, three steps to complete: // 1) Read factory loaded device keys and generate custom device keys // Get factory default flash contents #ifdef FACTORYKEYS2 okcore_flashget_common(ctap_buffer, (unsigned long *)factorysectoradr, 1025); #ifdef DEBUG Serial.println("Factory Key Values"); byteprint(ctap_buffer, 1025); #endif if (ctap_buffer[480] != 0xFF) { // Attestation key loaded // Hash factory bytes with unique chip ID and random SHA256_CTX hash; for (int i=0; i<=14; i++) { analog1 = analogRead(ANALOGPIN1); analog2 = analogRead(ANALOGPIN1); sha256_init(&hash); sha256_update(&hash, ctap_buffer+(32*i), 32); sha256_update(&hash, ctap_buffer+(32*(i+1)), 32); sha256_update(&hash, (uint8_t*)ID, 36); sha256_update(&hash, (uint8_t*)&analog1, 4); sha256_update(&hash, (uint8_t*)&analog2, 4); sha256_final(&hash, ctap_buffer+(32*i)); } #ifdef DEBUG Serial.println("KDF Hashed Factory Values"); byteprint(ctap_buffer, 512); #endif // Write everything to flash if (*certified_hw != 1) { // Encrypt attestation key with generated KEK ctap_buffer[435]=3; //Write keys okcore_flashset_common(ctap_buffer, (unsigned long *)enckeysectoradr, 436); okcrypto_aes_gcm_encrypt2(ctap_buffer+480, ctap_buffer+436, ctap_buffer+448, 32, true); //Write encrypted contents to flash okcore_flashset_common(ctap_buffer, (unsigned long *)enckeysectoradr, 513); // Set write flag ctap_buffer[435]=1; // Write flag to flash okcore_flashset_common(ctap_buffer, (unsigned long *)enckeysectoradr, 513); } // Erase factory keys memset(ctap_buffer, 0, 2048); okcore_flashset_common(ctap_buffer, (unsigned long *)factorysectoradr, 512); } #endif // end FACTORYKEYS // 2) Store factory firmware hash for integrity verification //create hash of firmware in hash buffer #ifdef STD_VERSION fw_hash(ctap_buffer); for (int i = 0; i < crypto_hash_BYTES; i++) { //write 64byte hash to eeprom eeprom_write_byte((unsigned char*)(2+i), ctap_buffer[i]); // 2-65 used for fw integrity hash } memset(ctap_buffer, 0, 2048); #endif // 3) Enable flash security after writing int nn = 0; nn=flashSecurityLockBits(); #ifdef DEBUG Serial.print("Flash security bits "); if(nn) Serial.print("not "); Serial.println("written successfully"); #endif } if(!initcheck) { wipeEEPROM(); eeprom_write_byte((unsigned char *)1984, (OKversionmaj[0] - '0')); //write fwvermaj, prevents downgrade to previous majver okeeprom_eeset_timeout((uint8_t*)TIMEOUT); //Default lockout 30 min unlocked = true; //Flash is not protected, First time use initialized = false; #ifdef DEBUG Serial.println("UNLOCKED, NO PIN SET"); #endif } else if(FTFL_FSEC==0x44 && initcheck) { okcore_flashget_pinhashpublic ((uint8_t*)p1hash, 32); //store PIN hash okcore_flashget_selfdestructhash ((uint8_t*)sdhash); //store self destruct PIN hash okcore_flashget_2ndpinhashpublic ((uint8_t*)p2hash); //store plausible deniability PIN hash okeeprom_eeget_typespeed((uint8_t*)TYPESPEED, 0); okeeprom_eeget_modkey(&mod_keys_enabled); #ifdef DEBUG Serial.println("typespeed = "); Serial.println(TYPESPEED[0]); #endif if (TYPESPEED[0] == 0) { TYPESPEED[0] = 4; } else if (TYPESPEED[0] <= 10) { } okeeprom_eeget_ledbrightness((uint8_t*)NEO_Brightness); okeeprom_eeget_touchoffset(&touchoffset); okeeprom_eeget_timeout((uint8_t*)TIMEOUT); okeeprom_eeget_keyboardlayout((uint8_t*)KeyboardLayout); #ifdef DEBUG Serial.println("KeyboardLayout = "); Serial.println(KeyboardLayout[0]); #endif update_keyboard_layout(); unlocked = false; initialized = true; #ifdef DEBUG Serial.println("INITIALIZED"); #endif SoftTimer.add(&taskInitialized); } else { //Glitch detect, somehow device is initialized but flash security is not on CPU_RESTART(); } integrityctr2++; /*************************************/ //Initialize the random number generator with analog noise, stored NONCE, and chip ID /*************************************/ RNG.begin(OKversion, 2045); //Start RNG with the device version RNG.stir((uint8_t *)&analog1, 2, 4); RNG.stir((uint8_t *)&analog2, 2, 4); #ifdef DEBUG Serial.print("EEPROM Used "); Serial.println(EEpos_slottypespeed+12); Serial.println(FTFL_FSEC, HEX); #endif rngloop(); //Start RNG #ifdef OK_Color initColor(); rainbowCycle(); #else pinMode(BLINKPIN, OUTPUT); fadein();//Additional delay to make sure button is not pressed during plug into USB fadeout(); fadein(); fadeout(); #endif SoftTimer.add(&taskKey); if (!initcheck) { //Default set to no challenge code required for OnlyKey Agent //User can enable challenge code in OnlyKey app preferences derived_key_challenge_mode = 1; stored_key_challenge_mode = 1; okeeprom_eeset_derived_key_challenge_mode(&derived_key_challenge_mode); okeeprom_eeset_stored_key_challenge_mode(&stored_key_challenge_mode); } if (onlykeyhw==OK_HW_DUO) { if (initialized == true && password.profile1hashevaluate()) { payload(10); } } } extern elapsedMillis idletimer; /*************************************/ //Main Loop, Read Key Press Using Capacitive Touch //Called every 50ms /*************************************/ void checkKey(Task* me) { //Check for bootloader trigger if (!digitalRead(33)) { //Trigger bootloader to load firmware by PTA4 low for 3 sec elapsedMillis waiting; int jumptobootloader = 0; while (waiting < 3000) { delay(100); jumptobootloader = jumptobootloader + digitalRead(33); } if (jumptobootloader==0) { eeprom_write_byte(0x00, 1); //Go to bootloader eeprom_write_byte((unsigned char *)0x01, 1); //Firmware ready to load CPU_RESTART(); //Reboot } } #ifndef STD_VERSION // Disable OK_HW_DUO hardware for IN_TRVL firmware if (onlykeyhw==OK_HW_DUO) { eeprom_write_byte(0x00, 1); //Go to bootloader eeprom_write_byte((unsigned char *)0x01, 1); //Firmware ready to load CPU_RESTART(); //Reboot } #endif if (setBuffer[8] == 1 && (!isfade || configmode)) //Done receiving packets { if (outputmode != KEYBOARD_USB) changeoutputmode(KEYBOARD_USB); //Keyboard USB process_setreport(); } //Check integrity counters and recv usb data integrityctr1++; delay(sumofall % 6); //delay 0 - 5 ms if (unlocked) { integrityctr2++; recvmsg(0); if(initialized && initcheck) { #ifdef STD_VERSION yubikey_incr_time(); #endif if (TIMEOUT[0] && idletimer >= (TIMEOUT[0]*60000)) { unlocked = false; firsttime = true; password.reset(); //reset the guessed password to NULL pass_keypress=1; memset(profilekey, 0, 32); SoftTimer.add(&taskInitialized); CPU_RESTART(); } } } else{ integrityctr2++; } if(configmode && unlocked && !isfade) { #ifdef OK_Color NEO_Color = 1; //Red #endif fadeon(1); } #ifdef DEBUG // Auto set default PINs and passphrase for testing //if (!initialized) { // okeeprom_eeset_timeout(0); //Disable lockout // okcore_quick_setup(AUTO_PIN_SET); //} #endif int press_duration = touch_sense_loop(); if (pending_operation==0xF6 || pending_operation==0xF7) { //CTAP2_ERR_DATA_READY or CTAP2_ERR_DATA_WIPE setcolor(45); //yellow } else { if (press_duration) payload(press_duration); } } /*************************************/ //Type out on Keyboard the contents of Keybuffer /*************************************/ void sendKey(Task* me) { while ( isfade && NEO_Color == 170 && (uint8_t)*pos != 00 && (uint8_t)*pos != 9 ) { pos++; } int delay1 = (TYPESPEED[0]*TYPESPEED[0]/3)*8; int delay2 = ((TYPESPEED[0]*TYPESPEED[0])*2); if ((uint8_t)*pos == 00) { #ifdef DEBUG Serial.print(pos); #endif Keyboard.end(); SoftTimer.remove(&taskKB); SoftTimer.add(&taskKey); // Set back to default type speed okeeprom_eeget_typespeed((uint8_t*)TYPESPEED, 0); if (TYPESPEED[0]==0) TYPESPEED[0] = 4; return; } else if ((uint8_t)*pos == 1) { if (!isfade) { Keyboard.press(KEY_TAB); delay(delay1); Keyboard.releaseAll(); delay(delay2); } pos++; } else if ((uint8_t)*pos == 2) { if (!isfade) { Keyboard.press(KEY_RETURN); delay(delay1); Keyboard.releaseAll(); delay(delay2); } pos++; } else if ((uint8_t)*pos == 9) { if(profilemode==NONENCRYPTEDPROFILE) return; #ifdef STD_VERSION #ifdef DEBUG Serial.println("Starting U2F..."); #endif u2f_button = 1; unsigned long u2fwait = millis() + 4000; while(u2f_button && millis() < u2fwait) { recvmsg(0); } u2f_button = 0; Keyboard.end(); SoftTimer.remove(&taskKB); SoftTimer.add(&taskKey); #endif return; } else if ((uint8_t)*pos >= 10 && (uint8_t)*pos <= 31) { if (!isfade) { delay((*pos - 10)*1000); pos++; } } else if ((uint8_t)*pos == ' ' && (uint8_t)*(pos+1) == 0x5c) { pos++; if (!isfade) { while(*pos) { if ((uint8_t)*pos == 0x5c) { //modifier/special key comes next pos++; keymap_press(0); delay(delay1); } else { //regular key keymap_press(1); delay(delay1); } pos++; if ((uint8_t)*pos == ' ' || (uint8_t)*pos == 0) { if ((uint8_t)*pos == ' ') pos++; Keyboard.releaseAll(); delay(delay1); Keyboard.releaseAll(); resetkeys(); delay(delay2); return; } } } } else if (*pos){ if (!isfade) { Keyboard.press(*pos); delay(delay1); Keyboard.releaseAll(); delay(delay2); } pos++; } } /*************************************/ //Password Checking Loop /*************************************/ void payload(int duration) { if (!unlocked) { // OnlyKey Go has only 3 buttons, longer press to enter PIN of 4 - 6 if (onlykeyhw==OK_HW_DUO && duration >= 21) { // <1 sec OK_HW_DUO buttons 1,2,3 = 4,5,6 button_selected = button_selected + 3; } #ifdef OK_Color setcolor(45); // NEO Pixel ON Yellow #else analogWrite(BLINKPIN, 255); //LED ON #endif } else { #ifdef OK_Color setcolor(0); // NEO Pixel OFF #else analogWrite(BLINKPIN, 0); //LED OFF #endif } uint8_t pass_attempts[1]; uint8_t sincelastregularlogin[1]; if (session_attempts >= 3) { //Limit 3 password attempts per session to make sure that someone does not accidentally wipe device exceeded_login_attempts(); return; } integrityctr1++; if (firsttime) //Get failed login counter from eeprom and increment for new login attempt { okeeprom_eeget_failedlogins ((uint8_t*)pass_attempts); if (pass_attempts[0]) { okeeprom_eeget_sincelastregularlogin ((uint8_t*)sincelastregularlogin); if (sincelastregularlogin[0] >= 20) { for (int i =0; i<32; i++) { p1hash[i] = 0xFF; } okcore_flashset_pinhashpublic ((uint8_t*)p1hash); //permanently wipe pinhash okeeprom_eeset_sincelastregularlogin (0); } else { sincelastregularlogin[0]++; okeeprom_eeset_sincelastregularlogin ((uint8_t*)sincelastregularlogin); } #ifdef DEBUG Serial.println("Failed PIN attempts since last successful regular PIN entry"); Serial.println(sincelastregularlogin[0]); #endif } integrityctr2++; pass_attempts[0]++; integrityctr1++; if (pass_attempts[0] > 10) { #ifdef DEBUG Serial.println("Password attempts exhausted"); Serial.println(pass_attempts[0]); #endif factorydefault(); pass_attempts[0] = 0; return; } okeeprom_eeset_failedlogins ((uint8_t*)pass_attempts); firsttime = false; } integrityctr2++; password.append(button_selected); integrityctr1++; delay((sumofall % 4)+(sumofall % 3)); //delay 0 - 5 ms if (unlocked || password.profile1hashevaluate() || password.profile2hashevaluate()) { integrityctr2++; if (unlocked != true) { //A correct PIN was just entered do the following for first login okeeprom_eeset_failedlogins(0); //Set failed login counter to 0 password.reset(); //reset the guessed password to NULL session_attempts=0; if (!configmode) hidprint(HW_MODEL(UNLOCKED)); SoftTimer.remove(&taskInitialized); #ifdef DEBUG Serial.println("UNLOCKED"); #endif fadeon(NEO_Color); fadeoff(85); if (profilemode!=NONENCRYPTEDPROFILE) { #ifdef STD_VERSION U2Finit(); okeeprom_eeset_sincelastregularlogin(0); //Set failed logins since last regular login to 0 fw_version_changes(); #endif } idletimer=0; unlocked = true; if (configmode) { #ifdef OK_Color NEO_Color = 1; //Red #endif fadeon(1); } unsigned long wait = millis() + 200; while(millis() < wait) { //Process waiting messages recvmsg(0); } wipe_usb_buffer(); // Wipe old responses return; } else if (!initialized && duration >= 85 && button_selected=='1' && profilemode!=NONENCRYPTEDPROFILE) { if (onlykeyhw==OK_HW_DUO) okcore_quick_setup(KEYBOARD_ONLYKEY_DUO_NO_BACKUP); else okcore_quick_setup(KEYBOARD_MANUAL_PIN_SET); return; } else if (!initialized && duration >= 85 && button_selected=='2' && profilemode!=NONENCRYPTEDPROFILE) { if (onlykeyhw==OK_HW_DUO) okcore_quick_setup(KEYBOARD_ONLYKEY_DUO_BACKUP); else okcore_quick_setup(KEYBOARD_AUTO_PIN_SET); return; } else if (!initialized && duration >= 85 && button_selected=='3' && profilemode!=NONENCRYPTEDPROFILE) { okcore_quick_setup(0); //Setup with keyboard prompt return; } else if (pin_set==0 && !initcheck) { return; } else if (pin_set==0) { } else if (pin_set<=3) { #ifdef DEBUG Serial.print("password appended with "); Serial.println(button_selected-'0'); #endif if (configmode) { NEO_Color = 45; blink(1); NEO_Color = 1; } return; } else if (pin_set<=6) { #ifdef DEBUG Serial.print("SD password appended with "); Serial.println(button_selected-'0'); #endif if (configmode) { NEO_Color = 45; blink(1); NEO_Color = 1; } return; } else if (pin_set<=9) { if(profilemode!=NONENCRYPTEDPROFILE){ #ifdef STD_VERSION #ifdef DEBUG Serial.print("2nd profile password appended with "); Serial.println(button_selected-'0'); #endif #endif } if (configmode) { NEO_Color = 45; blink(1); NEO_Color = 1; } return; } else if (pin_set==10) { cancelfadeoffafter20(); if (button_selected=='1') okcore_quick_setup(KEYBOARD_MANUAL_PIN_SET); //Manual else okcore_quick_setup(KEYBOARD_AUTO_PIN_SET); //Manual return; } Keyboard.begin(); *keybuffer = '\0'; #ifdef DEBUG Serial.print("Button selected "); Serial.println(button_selected-'0'); #endif idletimer=0; if (profilemode!=NONENCRYPTEDPROFILE) { #ifdef STD_VERSION if (CRYPTO_AUTH == 1 && button_selected==Challenge_button1 && isfade) { #ifdef DEBUG Serial.print("Challenge1 entered"); Serial.println(button_selected-'0'); #endif CRYPTO_AUTH++; return; } else if (CRYPTO_AUTH == 2 && button_selected==Challenge_button2 && isfade) { #ifdef DEBUG Serial.print("Challenge2 entered"); Serial.println(button_selected-'0'); #endif CRYPTO_AUTH++; return; } else if ((CRYPTO_AUTH == 3 && button_selected==Challenge_button3 && isfade && packet_buffer_details[0]) || (derived_key_challenge_mode==1 && isfade && packet_buffer_details[0]) || (stored_key_challenge_mode==1 && isfade && packet_buffer_details[0]) || (CRYPTO_AUTH == 3 && packet_buffer_details[0] == OKHMAC && isfade) || (packet_buffer_details[0] == OKWEBAUTHN && isfade)) { #ifdef DEBUG Serial.print("Challenge3 entered"); Serial.println(button_selected-'0'); #endif CRYPTO_AUTH = 4; derived_key_challenge_mode = 0; stored_key_challenge_mode = 0; if(packet_buffer_details[0] == OKSIGN) { recv_buffer[4] = packet_buffer_details[0]; recv_buffer[5] = packet_buffer_details[1]; okcrypto_sign(recv_buffer); } else if (packet_buffer_details[0] == OKDECRYPT) { recv_buffer[4] = packet_buffer_details[0]; recv_buffer[5] = packet_buffer_details[1]; okcrypto_decrypt(recv_buffer); } else if (packet_buffer_details[0] == OKHMAC) { okcrypto_hmacsha1(); } else if (packet_buffer_details[0] == OKWEBAUTHN) { u2f_button = 1; unsigned long u2fwait = millis() + 4000; while(u2f_button && millis() < u2fwait) { recvmsg(0); } u2f_button = 0; } CRYPTO_AUTH = 0; packet_buffer_details[0]=0; fadeoff(0); return; } else if (CRYPTO_AUTH) { //Wrong challenge was entered CRYPTO_AUTH = 0; Challenge_button1 = 0; Challenge_button2 = 0; Challenge_button3 = 0; fadeoff(1); hidprint("Error incorrect challenge was entered"); analogWrite(BLINKPIN, 255); //LED ON return; } else if (duration < 180 && duration >= 72 && button_selected=='1' && !isfade) { // Backup <4 sec SoftTimer.remove(&taskKey); backup(); SoftTimer.add(&taskKey); return; } else if (onlykeyhw==OK_HW_DUO && duration >= 360 && button_selected=='2' && configmode==true) { factorydefault(); } else if (duration >= 72 && button_selected=='2' && !isfade) { // Slot Labels <4 sec get_slot_labels(1); if (duration >= 140) get_key_labels(1); return; } else if (duration >= 72 && button_selected=='3' && !isfade) { // Lock and/or switch profiles <4 sec if (onlykeyhw==OK_HW_DUO && duration < 180) { if (Duo_config[1] == 0){ // Profile 1 Profile_Offset = 84; //Profile 2 Blue Duo_config[1] = 1; } else if (Duo_config[1] == 1){ // Profile 2 Profile_Offset = -42; //Profile 3 Yellow Duo_config[1] = 2; } else if (Duo_config[1] == 2){ // Profile 3 Profile_Offset = 128; //Profile 4 Purple Duo_config[1] = 3; } else if (Duo_config[1] == 3){ // Profile 4 Profile_Offset = 0; //Profile 1 Green Duo_config[1] = 0; } return; } unlocked = false; firsttime = true; password.reset(); //reset the guessed password to NULL pass_keypress=1; memset(profilekey, 0, 32); SoftTimer.add(&taskInitialized); button_selected=0; CPU_RESTART(); return; } else if (((onlykeyhw==OK_HW_DUO && duration >= 180 && button_selected=='1') || (onlykeyhw!=OK_HW_DUO && duration >= 72 && button_selected=='6')) && !isfade) { // Config mode integrityctr1++; configmode=true; if (Duo_config[0]!=1) { unlocked = false; firsttime = true; password.reset(); //reset the guessed password to NULL pass_keypress=1; SoftTimer.add(&taskInitialized); } integrityctr2++; return; } #endif } #ifdef OK_Color setcolor(0); // NEO Pixel OFF #else analogWrite(BLINKPIN, 0); //LED OFF #endif if (duration <= 20 && !configmode) { gen_press(); } else if (duration >= 21 && duration < 90 && !configmode) { gen_hold(); } else if (duration >= 90 && !configmode) { NEO_Color = 1; blink(2); } pos = keybuffer; SoftTimer.remove(&taskKey); SoftTimer.add(&taskKB, (unsigned long)TYPESPEED[0]); return; } else if (password.sdhashevaluate()) { #ifdef DEBUG Serial.println("Self Destruct PIN entered"); #endif factorydefault(); } else { integrityctr2++; if (pass_keypress < 10) { #ifdef DEBUG Serial.print("password appended with "); Serial.println(button_selected-'0'); Serial.print("Number of keys entered for this passcode = "); Serial.println(pass_keypress); #endif pass_keypress++; return; } else { firsttime = true; session_attempts++; #ifdef OK_Color NEO_Color = 1; #endif blink(3); #ifdef DEBUG Serial.print("Login Failed, there are "); #endif okeeprom_eeget_failedlogins ((uint8_t*)pass_attempts); #ifdef DEBUG Serial.print(10 - pass_attempts[0]); Serial.println(" remaining attempts before a factory reset will occur"); Serial.println("WARNING: This will render all device information unrecoverable"); #endif password.reset(); //reset the guessed password to NULL pass_keypress=1; if (session_attempts >= 3) { //Limit 3 password attempts per session to make sure that someone does not accidentally wipe device exceeded_login_attempts(); } return; } } } /*************************************/ //Trigger on short button press /*************************************/ void gen_press(void) { int slot; if (profilemode || Duo_config[1] == 2) { slot=(button_selected-'0')+12; } else if (Duo_config[1] == 1) { slot=(button_selected-'0')+6; } else if (Duo_config[1] == 3) { slot=(button_selected-'0')+18; } else { slot=button_selected-'0'; } process_slot(slot); } /*************************************/ //Trigger on long button press /*************************************/ void gen_hold(void) { int slot; if (profilemode || Duo_config[1] == 2) { slot=(button_selected-'0')+12; } else if (Duo_config[1] == 1) { slot=(button_selected-'0')+6; } else if (Duo_config[1] == 3) { slot=(button_selected-'0')+18; } else { slot=button_selected-'0'; } if (onlykeyhw==OK_HW_DUO){ process_slot(slot+3); } else { process_slot(slot+6); } } /*************************************/ //Load Set Values to Keybuffer /*************************************/ void process_slot(int s) { long GMT; char* newcode; static uint8_t index; uint8_t temp[64]; int urllength; int usernamelength; int passwordlength; int otplength; uint8_t addchar1; uint8_t addchar2; uint8_t addchar3; uint8_t addchar4; uint8_t addchar5; uint8_t addchar6; uint8_t autolockslot; int delay1 = 0; int delay2 = 0; int delay3 = 0; uint8_t *ptr; int slot=s; bool scripted_mode = false; index = 0; okeeprom_eeget_autolockslot(&autolockslot); if ((profilemode==STDPROFILE1 && (slot==(autolockslot & 0xF))) || (profilemode==STDPROFILE2 && slot==((autolockslot >> 4) & 0xF)+12)) { lock_ok_and_screen (); return; } okeeprom_eeget_typespeed((uint8_t*)TYPESPEED, slot); if (TYPESPEED[0]==0) okeeprom_eeget_typespeed((uint8_t*)TYPESPEED, 0); if (TYPESPEED[0]==0) TYPESPEED[0] = 4; okeeprom_eeget_addchar(&addchar5, slot); #ifdef DEBUG Serial.println("Additional Character"); Serial.println(addchar5); #endif addchar1 = addchar5 & 0x3; //After Username addchar2 = (addchar5 >> 4) & 0x3; //After Password addchar3 = (addchar5 >> 6) & 0x1; //After OTP addchar6 = (addchar5 >> 7) & 0x1; //After OTP 2 addchar4 = (addchar5 >> 2) & 0x1; //Before Username addchar5 = (addchar5 >> 3) & 0x1; //Before OTP if (isfade) return; #ifdef DEBUG Serial.print("Slot Number "); Serial.println(button_selected-'0'); #endif memset(temp, 0, 64); //Wipe all data from buffer memset(keybuffer, 0, sizeof(keybuffer)); //Wipe all data from keybuffer ptr = temp; urllength = okcore_flashget_url(ptr, slot); if(urllength > 0) { #ifdef DEBUG Serial.println("Reading URL from Flash..."); Serial.print("URL Length = "); Serial.println(urllength); #endif #ifdef DEBUG Serial.println("Encrypted"); byteprint(temp, urllength); #endif okcore_aes_gcm_decrypt(temp, slot, 15, profilekey, urllength); if (temp[0]==0x08) { // Scripted Mode scripted_mode=true; ByteToChar2(temp+1, keybuffer, urllength-1, index); index=urllength-1; } else { ByteToChar2(temp, keybuffer, urllength, index); index=urllength; keybuffer[index] = 2; index++; #ifdef DEBUG Serial.println("Unencrypted"); byteprint(temp, urllength); Serial.println("Setting RETURN after URL"); #endif } } memset(temp, 0, 64); //Wipe all data from buffer okeeprom_eeget_delay1(ptr, slot); if(temp[0] > 0 && !scripted_mode) { #ifdef DEBUG Serial.println("Reading Delay1 from EEPROM..."); Serial.print("Delay "); Serial.print(temp[0]); Serial.println(" Seconds before entering username"); #endif if (temp[0] <= 30) { delay1=temp[0]; keybuffer[index] = temp[0] + 10; index++; } } if(addchar4 && !scripted_mode) { #ifdef DEBUG Serial.println("Reading before Username addchar..."); #endif keybuffer[index] = 1; #ifdef DEBUG Serial.println("TAB"); #endif index++; } usernamelength = okcore_flashget_username(ptr, slot); if(usernamelength > 0) { #ifdef DEBUG Serial.println("Reading Username from Flash..."); Serial.print("Username Length = "); Serial.println(usernamelength); byteprint(temp, usernamelength); #endif okcore_aes_gcm_decrypt(temp, slot, 2, profilekey, usernamelength); ByteToChar2(temp, keybuffer, usernamelength, index); #ifdef DEBUG byteprint(temp, usernamelength); #endif index=usernamelength+index; } memset(temp, 0, 64); //Wipe all data from buffer if(addchar1 && !scripted_mode) { if(addchar1 == 1) { #ifdef DEBUG Serial.println("Reading after username addchar..."); #endif keybuffer[index] = 1; #ifdef DEBUG Serial.println("TAB"); #endif index++; } else if(addchar1 == 2) { #ifdef DEBUG Serial.println("Reading after username addchar..."); #endif keybuffer[index] = 2; #ifdef DEBUG Serial.println("RETURN"); #endif index++; } } memset(temp, 0, 64); //Wipe all data from buffer okeeprom_eeget_delay2(ptr, slot); if(temp[0] > 0 && !scripted_mode) { #ifdef DEBUG Serial.println("Reading Delay2 from EEPROM..."); Serial.print("Delay "); Serial.print(temp[0]); Serial.println(" Seconds before entering password"); #endif if (temp[0] <= 30) { delay2=temp[0]; keybuffer[index] = temp[0] + 10; index++; } } passwordlength = okeeprom_eeget_password(ptr, slot); if(passwordlength > 0) { #ifdef DEBUG Serial.println("Reading Password from EEPROM..."); Serial.print("Password Length = "); Serial.println(passwordlength); Serial.println("Encrypted"); byteprint(temp, passwordlength); #endif okcore_aes_gcm_decrypt(temp, slot, 5, profilekey, passwordlength); ByteToChar2(temp, keybuffer, passwordlength, index); #ifdef DEBUG Serial.println("Unencrypted"); byteprint(temp, passwordlength); #endif index=passwordlength+index; } memset(temp, 0, 64); //Wipe all data from buffer if(addchar2 && !scripted_mode) { #ifdef DEBUG Serial.println("Reading after password addchar..."); #endif if(addchar2 == 1) { keybuffer[index] = 1; #ifdef DEBUG Serial.println("TAB"); #endif index++; } else if(addchar2 == 2) { keybuffer[index] = 2; #ifdef DEBUG Serial.println("RETURN"); #endif index++; } } memset(temp, 0, 64); //Wipe all data from buffer okeeprom_eeget_delay3(ptr, slot); if(temp[0] > 0 && !scripted_mode) { #ifdef DEBUG Serial.println("Reading Delay3 from EEPROM..."); Serial.print("Delay "); Serial.print(temp[0]); Serial.println(" Seconds before entering 2FA"); #endif if (temp[0] <= 30) { delay3=temp[0]; keybuffer[index] = temp[0] + 10; index++; } } memset(temp, 0, 64); //Wipe all data from buffer if(addchar5 && !scripted_mode) { #ifdef DEBUG Serial.println("Reading before OTP addchar..."); #endif keybuffer[index] = 1; #ifdef DEBUG Serial.println("TAB"); #endif index++; } otplength = okeeprom_eeget_2FAtype(ptr, slot); if(temp[0] > 0) { if(temp[0] == MFAGOOGLEAUTH) { //Google Auth #ifdef DEBUG Serial.println("Reading TOTP Key from Flash..."); #endif otplength = okcore_flashget_2fa_key(ptr, slot); #ifdef DEBUG Serial.println("Encrypted"); byteprint(temp, otplength); Serial.print("TOTP Key Length = "); Serial.println(otplength); #endif okcore_aes_gcm_decrypt(temp, slot, 9, profilekey, otplength); ByteToChar2(temp, keybuffer, otplength, index); #ifdef DEBUG Serial.println("Unencrypted"); byteprint(temp, otplength); #endif TOTP totp1 = TOTP(temp, otplength); GMT = now(); GMT = GMT + delay1 + delay2 + delay3; #ifdef DEBUG Serial.println(GMT); #endif newcode = totp1.getCode(GMT); if (timeStatus() == timeNotSet) { keybuffer[index]='N'; keybuffer[index+1]='O'; keybuffer[index+2]='T'; keybuffer[index+3]='S'; keybuffer[index+4]='E'; keybuffer[index+5]='T'; } else { keybuffer[index]=*newcode; keybuffer[index+1]=*(newcode+1); keybuffer[index+2]=*(newcode+2); keybuffer[index+3]=*(newcode+3); keybuffer[index+4]=*(newcode+4); keybuffer[index+5]=*(newcode+5); } index=index+6; memset(temp, 0, 64); //Wipe all data from buffer } if(temp[0] == MFAOLDYUBIOTP && profilemode!=NONENCRYPTEDPROFILE) { #ifdef DEBUG Serial.println("Generating Yubico OTP Legacy..."); #endif #ifdef STD_VERSION yubikeysim(keybuffer + index, 0); index=index+44; #endif } if((temp[0] == MFAYUBIOTPandHMACSHA1 || temp[0] == MFAYUBIOTP) && profilemode!=NONENCRYPTEDPROFILE) { #ifdef DEBUG Serial.println("Generating Yubico OTP..."); #endif #ifdef STD_VERSION int publen; publen = yubikeysim(keybuffer + index, slot); index=index+32+(publen*2); #endif } if(temp[0] == MFAOLDU2F && profilemode!=NONENCRYPTEDPROFILE) { //U2F keybuffer[index] = 9; index++; } } if(addchar6) { #ifdef DEBUG Serial.println("Reading after OTP addchar..."); #endif keybuffer[index] = 1; #ifdef DEBUG Serial.println("TAB"); #endif index++; } if(addchar3) { #ifdef DEBUG Serial.println("Reading after OTP addchar..."); #endif keybuffer[index] = 2; #ifdef DEBUG Serial.println("RETURN"); #endif index++; } keybuffer[index] = 0; #ifdef DEBUG Serial.println("Displaying Full Keybuffer"); for (int i=0; keybuffer[i]!=0x00; i++) { Serial.print (keybuffer[i]); } #endif } void sendInitialized(Task* me) { if (onlykeyhw==OK_HW_DUO){ int n = RawHID.recv(recv_buffer, 0); // 0 timeout = do not wait if (n && recv_buffer[4] == OKPIN && recv_buffer[5]>='0' && initialized == true && unlocked == false && onlykeyhw==OK_HW_DUO) { unlocked = false; firsttime = true; password.reset(); //reset the guessed password to NULL okcore_pin_login(); // Received PIN Login Attempt for OnlyKey Duo pass_keypress=10; button_selected=0; payload(10); // Try the PIN memset(recv_buffer, 0, sizeof(recv_buffer)); if (unlocked == true) { hidprint(HW_MODEL(UNLOCKED)); } } else { hidprint("INITIALIZED-D"); } } else hidprint("INITIALIZED"); #ifdef DEBUG Serial.println("INITIALIZED"); #endif } void resetkeys () { delay(200); Keyboard.set_key1(0); Keyboard.set_key2(0); Keyboard.set_key3(0); Keyboard.set_key4(0); Keyboard.set_key5(0); Keyboard.set_key6(0); Keyboard.set_modifier(0); Keyboard.set_media(0); Keyboard.send_now(); } void ctrl_alt_del () { //Keyboard.set_modifier(MODIFIERKEY_CTRL); // Keyboard.send_now(); // Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT); Keyboard.send_now(); // Keyboard.set_key1(KEY_DELETE); Keyboard.send_now(); resetkeys(); // Keyboard.set_key1(KEY_ESC); Keyboard.send_now(); resetkeys(); } void lock_ok_and_screen () { unlocked = false; firsttime = true; password.reset(); //reset the guessed password to NULL pass_keypress=1; memset(profilekey, 0, 32); //Lock Windows and Linux (Gnome Super+L to lock) Keyboard.set_modifier(MODIFIERKEY_GUI); Keyboard.send_now(); Keyboard.set_key1(KEY_L); Keyboard.send_now(); resetkeys(); //Lock Mac Keyboard.set_modifier(MODIFIERKEY_CTRL); Keyboard.send_now(); Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_GUI); Keyboard.send_now(); Keyboard.set_key1(KEY_Q); Keyboard.send_now(); delay(500); // Mac OS-X will not recognize a very short eject press Keyboard.set_media(0); Keyboard.send_now(); resetkeys(); CPU_RESTART(); } void fw_hash(unsigned char* hashptr) { #ifdef STD_VERSION unsigned char smesg[17000]; unsigned long adr = fwstartadr; //Hash current fw in hashptr while (adr <= 0x36060) { //13 blocks of 16384 bytes, last block 0x36060 - 0x3A060 okcore_flashget_common (smesg, (unsigned long*)adr, 16384); //Read each block if (adr == (unsigned long)fwstartadr) { crypto_hash(hashptr,smesg,16384); //hash this block } else { //if not first block, hash with previous block hash memcpy(smesg + 16384, hashptr, crypto_hash_BYTES); crypto_hash(hashptr,smesg,(16384+crypto_hash_BYTES)); } adr = adr + 16384; } return; #endif } void keymap_press (char key) { extern uint8_t keyboard_modifier_keys; extern uint8_t keyboard_keys[6]; if ((uint8_t)*pos>'0' && (uint8_t)*pos<='9') { delay((*(pos)-'0')*1000); } else if ((uint8_t)*pos=='t' || (uint8_t)*pos=='r') { if (key) { Keyboard.press(*pos); key=0; } else if ((uint8_t)*pos=='t') { key = KEY_TAB; } else if ((uint8_t)*pos=='r') { key = KEY_RETURN; } } else if (mod_keys_enabled) { if (key) { Keyboard.press(*pos); key=0; } else { if ((uint8_t)*pos=='p') key = KEY_PRINTSCREEN; else if ((uint8_t)*pos=='h') key = KEY_HOME; else if ((uint8_t)*pos=='u') key = KEY_PAGE_UP; else if ((uint8_t)*pos=='o') key = KEY_PAGE_DOWN; else if ((uint8_t)*pos=='e') key = KEY_END; else if ((uint8_t)*pos=='d') key = KEY_DELETE; else if ((uint8_t)*pos=='b') key = KEY_BACKSPACE; else if ((uint8_t)*pos=='L') key = KEY_LEFT; else if ((uint8_t)*pos=='R') key = KEY_RIGHT; else if ((uint8_t)*pos=='U') key = KEY_UP; else if ((uint8_t)*pos=='D') key = KEY_DOWN; else if ((uint8_t)*pos=='E') key = KEY_ESC; if ((uint8_t)*pos=='c') keyboard_modifier_keys |= MODIFIERKEY_CTRL; else if ((uint8_t)*pos=='s') keyboard_modifier_keys |= MODIFIERKEY_SHIFT; else if ((uint8_t)*pos=='a') keyboard_modifier_keys |= MODIFIERKEY_ALT; else if ((uint8_t)*pos=='g') keyboard_modifier_keys |= MODIFIERKEY_GUI; } } if (keyboard_keys[0] == 0) keyboard_keys[0] = key; else if (keyboard_keys[1] == 0) keyboard_keys[1] = key; else if (keyboard_keys[2] == 0) keyboard_keys[2] = key; else if (keyboard_keys[3] == 0) keyboard_keys[3] = key; else if (keyboard_keys[4] == 0) keyboard_keys[4] = key; else if (keyboard_keys[5] == 0) keyboard_keys[5] = key; Keyboard.send_now(); } void exceeded_login_attempts() { #ifdef DEBUG Serial.print("password attempts for this session exceeded, remove OnlyKey and reinsert to attempt login"); #endif while(1==1) { hidprint("Error password attempts for this session exceeded, remove OnlyKey and reinsert to attempt login"); #ifdef OK_Color NEO_Color = 1; //Red #endif blink(5); } } ================================================ FILE: README.md ================================================ # OnlyKey Firmware This is the official firmware for **OnlyKey** OnlyKey can be purchased here: [OnlyKey order](https://onlykey.io) ## Getting Started Just getting started with OnlyKey? [Start here](https://onlykey.io/start) ## About The firmware is the software that runs on the OnlyKey itself. In order to load firmware follow the instructions in the [User's Guide here](https://docs.crp.to/usersguide.html#loading-onlykey-firmware) ## Development OnlyKey firmware is open source and new features are added with each firmware release. A list of of supported features are available [here](https://docs.crp.to/features.html) ## Support Check out the [OnlyKey Support Forum](https://forum.onlykey.io) Check out the [OnlyKey Documentation](https://docs.crp.to) ## Libraries OnlyKey firmware uses additional libraries that are available [here](https://github.com/trustcrypto/libraries). # Legal things ## Cryptography Notice This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See for more information. The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code. The following cryptographic software is included in this distribution: "MBED TLS PROJECT" - https://github.com/ARMmbed/mbedtls "MICRO-ECC PROJECT" - https://github.com/kmackay/micro-ecc "ARDUINOLIBS PROJECT" - https://rweather.github.io/arduinolibs/crypto.html "YUBICO-C PROJECT" - https://github.com/Yubico/yubico-c For more information on export restrictions see: http://www.apache.org/licenses/exports/ ## Source [OnlyKey Firmware on Github](https://github.com/trustcrypto/OnlyKey-Firmware) ================================================ FILE: keylayouts.c ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include "keylayouts.h" #ifdef M #undef M #endif #define M(n) ((n) & KEYCODE_MASK) KEYCODE_TYPE keycodes_ascii[96] = {0}; KEYCODE_TYPE keycodes_iso_8859_1[96] = {0}; uint8_t KeyboardLayout[1]; uint16_t SHIFT_MASK = 0; uint16_t ALTGR_MASK = 0; uint16_t RCTRL_MASK = 0; uint16_t KEY_NON_US_100 = 0; uint16_t DEADKEYS_MASK = 0; uint16_t CIRCUMFLEX_BITS = 0; uint16_t ACUTE_ACCENT_BITS = 0; uint16_t GRAVE_ACCENT_BITS = 0; uint16_t TILDE_BITS = 0; uint16_t DIAERESIS_BITS = 0; uint16_t DEADKEY_CIRCUMFLEX = 0; uint16_t DEADKEY_ACUTE_ACCENT = 0; uint16_t DEADKEY_GRAVE_ACCENT = 0; uint16_t DEADKEY_TILDE = 0; uint16_t DEADKEY_DIAERESIS = 0; uint16_t UNICODE_20AC = 0; uint16_t CEDILLA_BITS = 0; uint16_t DEADKEY_CEDILLA = 0; uint16_t RING_ABOVE_BITS = 0; uint16_t DEADKEY_RING_ABOVE = 0; uint16_t DEGREE_SIGN_BITS = 0; uint16_t CARON_BITS = 0; uint16_t BREVE_BITS = 0; uint16_t OGONEK_BITS = 0; uint16_t DOT_ABOVE_BITS = 0; uint16_t DOUBLE_ACUTE_BITS = 0; uint16_t DEADKEY_DEGREE_SIGN = 0; uint16_t DEADKEY_CARON = 0; uint16_t DEADKEY_BREVE = 0; uint16_t DEADKEY_OGONEK = 0; uint16_t DEADKEY_DOT_ABOVE = 0; uint16_t DEADKEY_DOUBLE_ACUTE = 0; uint16_t UNICODE_EXTRA0A = 0; uint16_t KEYCODE_EXTRA0A = 0; uint16_t ISO_8859_1_A0 = 0; uint16_t UNICODE_EXTRA00 = 0; uint16_t UNICODE_EXTRA01 = 0; uint16_t UNICODE_EXTRA02 = 0; uint16_t UNICODE_EXTRA03 = 0; uint16_t UNICODE_EXTRA04 = 0; uint16_t UNICODE_EXTRA05 = 0; uint16_t UNICODE_EXTRA06 = 0; uint16_t UNICODE_EXTRA07 = 0; uint16_t UNICODE_EXTRA08 = 0; uint16_t UNICODE_EXTRA09 = 0; uint16_t KEYCODE_EXTRA00 = 0; uint16_t KEYCODE_EXTRA01 = 0; uint16_t KEYCODE_EXTRA02 = 0; uint16_t KEYCODE_EXTRA03 = 0; uint16_t KEYCODE_EXTRA04 = 0; uint16_t KEYCODE_EXTRA05 = 0; uint16_t KEYCODE_EXTRA06 = 0; uint16_t KEYCODE_EXTRA07 = 0; uint16_t KEYCODE_EXTRA08 = 0; uint16_t KEYCODE_EXTRA09 = 0; uint16_t KEYCODE_MASK = 0; void update_keyboard_layout() { SHIFT_MASK = 0; ALTGR_MASK = 0; RCTRL_MASK = 0; KEY_NON_US_100 = 0; DEADKEYS_MASK = 0; CIRCUMFLEX_BITS = 0; ACUTE_ACCENT_BITS = 0; GRAVE_ACCENT_BITS = 0; TILDE_BITS = 0; DIAERESIS_BITS = 0; DEADKEY_CIRCUMFLEX = 0; DEADKEY_ACUTE_ACCENT = 0; DEADKEY_GRAVE_ACCENT = 0; DEADKEY_TILDE = 0; DEADKEY_DIAERESIS = 0; UNICODE_20AC = 0; CEDILLA_BITS = 0; DEADKEY_CEDILLA = 0; RING_ABOVE_BITS = 0; DEADKEY_RING_ABOVE = 0; DEGREE_SIGN_BITS = 0; CARON_BITS = 0; BREVE_BITS = 0; OGONEK_BITS = 0; DOT_ABOVE_BITS = 0; DOUBLE_ACUTE_BITS = 0; DEADKEY_DEGREE_SIGN = 0; DEADKEY_CARON = 0; DEADKEY_BREVE = 0; DEADKEY_OGONEK = 0; DEADKEY_DOT_ABOVE = 0; DEADKEY_DOUBLE_ACUTE = 0; UNICODE_EXTRA0A = 0; KEYCODE_EXTRA0A = 0; uint16_t ASCII_20 = 0; uint16_t ASCII_21 = 0; uint16_t ASCII_22 = 0; uint16_t ASCII_23 = 0; uint16_t ASCII_24 = 0; uint16_t ASCII_25 = 0; uint16_t ASCII_26 = 0; uint16_t ASCII_27 = 0; uint16_t ASCII_28 = 0; uint16_t ASCII_29 = 0; uint16_t ASCII_2A = 0; uint16_t ASCII_2B = 0; uint16_t ASCII_2C = 0; uint16_t ASCII_2D = 0; uint16_t ASCII_2E = 0; uint16_t ASCII_2F = 0; uint16_t ASCII_30 = 0; uint16_t ASCII_31 = 0; uint16_t ASCII_32 = 0; uint16_t ASCII_33 = 0; uint16_t ASCII_34 = 0; uint16_t ASCII_35 = 0; uint16_t ASCII_36 = 0; uint16_t ASCII_37 = 0; uint16_t ASCII_38 = 0; uint16_t ASCII_39 = 0; uint16_t ASCII_3A = 0; uint16_t ASCII_3B = 0; uint16_t ASCII_3C = 0; uint16_t ASCII_3D = 0; uint16_t ASCII_3E = 0; uint16_t ASCII_3F = 0; uint16_t ASCII_40 = 0; uint16_t ASCII_41 = 0; uint16_t ASCII_42 = 0; uint16_t ASCII_43 = 0; uint16_t ASCII_44 = 0; uint16_t ASCII_45 = 0; uint16_t ASCII_46 = 0; uint16_t ASCII_47 = 0; uint16_t ASCII_48 = 0; uint16_t ASCII_49 = 0; uint16_t ASCII_4A = 0; uint16_t ASCII_4B = 0; uint16_t ASCII_4C = 0; uint16_t ASCII_4D = 0; uint16_t ASCII_4E = 0; uint16_t ASCII_4F = 0; uint16_t ASCII_50 = 0; uint16_t ASCII_51 = 0; uint16_t ASCII_52 = 0; uint16_t ASCII_53 = 0; uint16_t ASCII_54 = 0; uint16_t ASCII_55 = 0; uint16_t ASCII_56 = 0; uint16_t ASCII_57 = 0; uint16_t ASCII_58 = 0; uint16_t ASCII_59 = 0; uint16_t ASCII_5A = 0; uint16_t ASCII_5B = 0; uint16_t ASCII_5C = 0; uint16_t ASCII_5D = 0; uint16_t ASCII_5E = 0; uint16_t ASCII_5F = 0; uint16_t ASCII_60 = 0; uint16_t ASCII_61 = 0; uint16_t ASCII_62 = 0; uint16_t ASCII_63 = 0; uint16_t ASCII_64 = 0; uint16_t ASCII_65 = 0; uint16_t ASCII_66 = 0; uint16_t ASCII_67 = 0; uint16_t ASCII_68 = 0; uint16_t ASCII_69 = 0; uint16_t ASCII_6A = 0; uint16_t ASCII_6B = 0; uint16_t ASCII_6C = 0; uint16_t ASCII_6D = 0; uint16_t ASCII_6E = 0; uint16_t ASCII_6F = 0; uint16_t ASCII_70 = 0; uint16_t ASCII_71 = 0; uint16_t ASCII_72 = 0; uint16_t ASCII_73 = 0; uint16_t ASCII_74 = 0; uint16_t ASCII_75 = 0; uint16_t ASCII_76 = 0; uint16_t ASCII_77 = 0; uint16_t ASCII_78 = 0; uint16_t ASCII_79 = 0; uint16_t ASCII_7A = 0; uint16_t ASCII_7B = 0; uint16_t ASCII_7C = 0; uint16_t ASCII_7D = 0; uint16_t ASCII_7E = 0; uint16_t ASCII_7F = 0; ISO_8859_1_A0 = 0; uint16_t ISO_8859_1_A1 = 0; uint16_t ISO_8859_1_A2 = 0; uint16_t ISO_8859_1_A3 = 0; uint16_t ISO_8859_1_A4 = 0; uint16_t ISO_8859_1_A5 = 0; uint16_t ISO_8859_1_A6 = 0; uint16_t ISO_8859_1_A7 = 0; uint16_t ISO_8859_1_A8 = 0; uint16_t ISO_8859_1_A9 = 0; uint16_t ISO_8859_1_AA = 0; uint16_t ISO_8859_1_AB = 0; uint16_t ISO_8859_1_AC = 0; uint16_t ISO_8859_1_AD = 0; uint16_t ISO_8859_1_AE = 0; uint16_t ISO_8859_1_AF = 0; uint16_t ISO_8859_1_B0 = 0; uint16_t ISO_8859_1_B1 = 0; uint16_t ISO_8859_1_B2 = 0; uint16_t ISO_8859_1_B3 = 0; uint16_t ISO_8859_1_B4 = 0; uint16_t ISO_8859_1_B5 = 0; uint16_t ISO_8859_1_B6 = 0; uint16_t ISO_8859_1_B7 = 0; uint16_t ISO_8859_1_B8 = 0; uint16_t ISO_8859_1_B9 = 0; uint16_t ISO_8859_1_BA = 0; uint16_t ISO_8859_1_BB = 0; uint16_t ISO_8859_1_BC = 0; uint16_t ISO_8859_1_BD = 0; uint16_t ISO_8859_1_BE = 0; uint16_t ISO_8859_1_BF = 0; uint16_t ISO_8859_1_C0 = 0; uint16_t ISO_8859_1_C1 = 0; uint16_t ISO_8859_1_C2 = 0; uint16_t ISO_8859_1_C3 = 0; uint16_t ISO_8859_1_C4 = 0; uint16_t ISO_8859_1_C5 = 0; uint16_t ISO_8859_1_C6 = 0; uint16_t ISO_8859_1_C7 = 0; uint16_t ISO_8859_1_C8 = 0; uint16_t ISO_8859_1_C9 = 0; uint16_t ISO_8859_1_CA = 0; uint16_t ISO_8859_1_CB = 0; uint16_t ISO_8859_1_CC = 0; uint16_t ISO_8859_1_CD = 0; uint16_t ISO_8859_1_CE = 0; uint16_t ISO_8859_1_CF = 0; uint16_t ISO_8859_1_D0 = 0; uint16_t ISO_8859_1_D1 = 0; uint16_t ISO_8859_1_D2 = 0; uint16_t ISO_8859_1_D3 = 0; uint16_t ISO_8859_1_D4 = 0; uint16_t ISO_8859_1_D5 = 0; uint16_t ISO_8859_1_D6 = 0; uint16_t ISO_8859_1_D7 = 0; uint16_t ISO_8859_1_D8 = 0; uint16_t ISO_8859_1_D9 = 0; uint16_t ISO_8859_1_DA = 0; uint16_t ISO_8859_1_DB = 0; uint16_t ISO_8859_1_DC = 0; uint16_t ISO_8859_1_DD = 0; uint16_t ISO_8859_1_DE = 0; uint16_t ISO_8859_1_DF = 0; uint16_t ISO_8859_1_E0 = 0; uint16_t ISO_8859_1_E1 = 0; uint16_t ISO_8859_1_E2 = 0; uint16_t ISO_8859_1_E3 = 0; uint16_t ISO_8859_1_E4 = 0; uint16_t ISO_8859_1_E5 = 0; uint16_t ISO_8859_1_E6 = 0; uint16_t ISO_8859_1_E7 = 0; uint16_t ISO_8859_1_E8 = 0; uint16_t ISO_8859_1_E9 = 0; uint16_t ISO_8859_1_EA = 0; uint16_t ISO_8859_1_EB = 0; uint16_t ISO_8859_1_EC = 0; uint16_t ISO_8859_1_ED = 0; uint16_t ISO_8859_1_EE = 0; uint16_t ISO_8859_1_EF = 0; uint16_t ISO_8859_1_F0 = 0; uint16_t ISO_8859_1_F1 = 0; uint16_t ISO_8859_1_F2 = 0; uint16_t ISO_8859_1_F3 = 0; uint16_t ISO_8859_1_F4 = 0; uint16_t ISO_8859_1_F5 = 0; uint16_t ISO_8859_1_F6 = 0; uint16_t ISO_8859_1_F7 = 0; uint16_t ISO_8859_1_F8 = 0; uint16_t ISO_8859_1_F9 = 0; uint16_t ISO_8859_1_FA = 0; uint16_t ISO_8859_1_FB = 0; uint16_t ISO_8859_1_FC = 0; uint16_t ISO_8859_1_FD = 0; uint16_t ISO_8859_1_FE = 0; uint16_t ISO_8859_1_FF = 0; UNICODE_EXTRA00 = 0; UNICODE_EXTRA01 = 0; UNICODE_EXTRA02 = 0; UNICODE_EXTRA03 = 0; UNICODE_EXTRA04 = 0; UNICODE_EXTRA05 = 0; UNICODE_EXTRA06 = 0; UNICODE_EXTRA07 = 0; UNICODE_EXTRA08 = 0; UNICODE_EXTRA09 = 0; uint16_t UNICODE_EXTRA10 = 0; uint16_t UNICODE_EXTRA11 = 0; uint16_t UNICODE_EXTRA12 = 0; uint16_t UNICODE_EXTRA13 = 0; uint16_t UNICODE_EXTRA14 = 0; uint16_t UNICODE_EXTRA15 = 0; uint16_t UNICODE_EXTRA16 = 0; uint16_t UNICODE_EXTRA17 = 0; uint16_t UNICODE_EXTRA18 = 0; uint16_t UNICODE_EXTRA19 = 0; uint16_t UNICODE_EXTRA20 = 0; uint16_t UNICODE_EXTRA21 = 0; uint16_t UNICODE_EXTRA22 = 0; uint16_t UNICODE_EXTRA23 = 0; uint16_t UNICODE_EXTRA24 = 0; uint16_t UNICODE_EXTRA25 = 0; uint16_t UNICODE_EXTRA26 = 0; uint16_t UNICODE_EXTRA27 = 0; uint16_t UNICODE_EXTRA28 = 0; uint16_t UNICODE_EXTRA29 = 0; uint16_t UNICODE_EXTRA30 = 0; uint16_t UNICODE_EXTRA31 = 0; uint16_t UNICODE_EXTRA32 = 0; uint16_t UNICODE_EXTRA33 = 0; uint16_t UNICODE_EXTRA34 = 0; uint16_t UNICODE_EXTRA35 = 0; uint16_t UNICODE_EXTRA36 = 0; uint16_t UNICODE_EXTRA37 = 0; uint16_t UNICODE_EXTRA38 = 0; uint16_t UNICODE_EXTRA39 = 0; uint16_t UNICODE_EXTRA40 = 0; uint16_t UNICODE_EXTRA41 = 0; uint16_t UNICODE_EXTRA42 = 0; uint16_t UNICODE_EXTRA43 = 0; uint16_t UNICODE_EXTRA44 = 0; uint16_t UNICODE_EXTRA45 = 0; uint16_t UNICODE_EXTRA46 = 0; uint16_t UNICODE_EXTRA47 = 0; uint16_t UNICODE_EXTRA48 = 0; uint16_t UNICODE_EXTRA49 = 0; uint16_t UNICODE_EXTRA50 = 0; uint16_t UNICODE_EXTRA51 = 0; KEYCODE_EXTRA00 = 0; KEYCODE_EXTRA01 = 0; KEYCODE_EXTRA02 = 0; KEYCODE_EXTRA03 = 0; KEYCODE_EXTRA04 = 0; KEYCODE_EXTRA05 = 0; KEYCODE_EXTRA06 = 0; KEYCODE_EXTRA07 = 0; KEYCODE_EXTRA08 = 0; KEYCODE_EXTRA09 = 0; uint16_t KEYCODE_EXTRA10 = 0; uint16_t KEYCODE_EXTRA11 = 0; uint16_t KEYCODE_EXTRA12 = 0; uint16_t KEYCODE_EXTRA13 = 0; uint16_t KEYCODE_EXTRA14 = 0; uint16_t KEYCODE_EXTRA15 = 0; uint16_t KEYCODE_EXTRA16 = 0; uint16_t KEYCODE_EXTRA17 = 0; uint16_t KEYCODE_EXTRA18 = 0; uint16_t KEYCODE_EXTRA19 = 0; uint16_t KEYCODE_EXTRA20 = 0; uint16_t KEYCODE_EXTRA21 = 0; uint16_t KEYCODE_EXTRA22 = 0; uint16_t KEYCODE_EXTRA23 = 0; uint16_t KEYCODE_EXTRA24 = 0; uint16_t KEYCODE_EXTRA25 = 0; uint16_t KEYCODE_EXTRA26 = 0; uint16_t KEYCODE_EXTRA27 = 0; uint16_t KEYCODE_EXTRA28 = 0; uint16_t KEYCODE_EXTRA29 = 0; uint16_t KEYCODE_EXTRA30 = 0; uint16_t KEYCODE_EXTRA31 = 0; uint16_t KEYCODE_EXTRA32 = 0; uint16_t KEYCODE_EXTRA33 = 0; uint16_t KEYCODE_EXTRA34 = 0; uint16_t KEYCODE_EXTRA35 = 0; uint16_t KEYCODE_EXTRA36 = 0; uint16_t KEYCODE_EXTRA37 = 0; uint16_t KEYCODE_EXTRA38 = 0; uint16_t KEYCODE_EXTRA39 = 0; uint16_t KEYCODE_EXTRA40 = 0; uint16_t KEYCODE_EXTRA41 = 0; uint16_t KEYCODE_EXTRA42 = 0; uint16_t KEYCODE_EXTRA43 = 0; uint16_t KEYCODE_EXTRA44 = 0; uint16_t KEYCODE_EXTRA45 = 0; uint16_t KEYCODE_EXTRA46 = 0; uint16_t KEYCODE_EXTRA47 = 0; uint16_t KEYCODE_EXTRA48 = 0; uint16_t KEYCODE_EXTRA49 = 0; uint16_t KEYCODE_EXTRA50 = 0; uint16_t KEYCODE_EXTRA51 = 0; if (KeyboardLayout[0] == LAYOUT_USA_ENGLISH || KeyboardLayout[0] == LAYOUT_DVORAK || KeyboardLayout[0] == 0x00) { SHIFT_MASK=0x0040; //KEYCODE_TYPE=uint8_t KEYCODE_MASK=0x007F; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_QUOTE + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=KEY_QUOTE;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_8 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_SLASH;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SEMICOLON + SHIFT_MASK;// 58 : ASCII_3B=KEY_SEMICOLON;// 59 ; ASCII_3C=KEY_COMMA + SHIFT_MASK;// 60 < ASCII_3D=KEY_EQUAL;// 61 )= ASCII_3E=KEY_PERIOD + SHIFT_MASK;// 62 > ASCII_3F=KEY_SLASH + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + SHIFT_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE;// 91 [ ASCII_5C=KEY_BACKSLASH;// 92 ASCII_5D=KEY_RIGHT_BRACE;// 93 ] ASCII_5E=KEY_6 + SHIFT_MASK;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=KEY_TILDE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_LEFT_BRACE + SHIFT_MASK;// 123 { ASCII_7C=KEY_BACKSLASH + SHIFT_MASK;// 124 | ASCII_7D=KEY_RIGHT_BRACE + SHIFT_MASK;// 125 } ASCII_7E=KEY_TILDE + SHIFT_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 if (KeyboardLayout[0] == LAYOUT_DVORAK) { ASCII_2D=KEY_QUOTE; // - ASCII_5F=KEY_QUOTE + SHIFT_MASK; // _ ASCII_3D=KEY_RIGHT_BRACE; // = ASCII_2B=KEY_RIGHT_BRACE + SHIFT_MASK; // + ASCII_71=KEY_X; // q ASCII_51=KEY_X + SHIFT_MASK;// Q ASCII_77=KEY_COMMA; // w ASCII_57=KEY_COMMA + SHIFT_MASK; // W ASCII_65=KEY_D; // e ASCII_45=KEY_D + SHIFT_MASK; // E ASCII_72=KEY_O; // r ASCII_52=KEY_O + SHIFT_MASK; // R ASCII_74=KEY_K; // t ASCII_54=KEY_K + SHIFT_MASK; // T ASCII_79=KEY_T; // y ASCII_59=KEY_T + SHIFT_MASK; // Y ASCII_75=KEY_F; // u ASCII_55=KEY_F + SHIFT_MASK; // U ASCII_69=KEY_G; // i ASCII_49=KEY_G + SHIFT_MASK; // I ASCII_6F=KEY_S; // o ASCII_4F=KEY_S + SHIFT_MASK; // O ASCII_70=KEY_R; // p ASCII_50=KEY_R + SHIFT_MASK; // P ASCII_5B=KEY_MINUS; // [ ASCII_7B=KEY_MINUS + SHIFT_MASK; // { ASCII_5D=KEY_EQUAL; // ] ASCII_7D=KEY_EQUAL + SHIFT_MASK; // } ASCII_73=KEY_SEMICOLON; // s ASCII_53=KEY_SEMICOLON + SHIFT_MASK; // S ASCII_64=KEY_H; // d ASCII_44=KEY_H + SHIFT_MASK; // D ASCII_66=KEY_Y; // f ASCII_46=KEY_Y + SHIFT_MASK; // F ASCII_67=KEY_U; // g ASCII_47=KEY_U + SHIFT_MASK; // G ASCII_68=KEY_J; // h ASCII_48=KEY_J + SHIFT_MASK; // H ASCII_6A=KEY_C; // j ASCII_4A=KEY_C + SHIFT_MASK; // J ASCII_6B=KEY_V; // k ASCII_4B=KEY_V + SHIFT_MASK; // K ASCII_6C=KEY_P; // l ASCII_4C=KEY_P + SHIFT_MASK; // L ASCII_3B=KEY_Z; // ; ASCII_3A=KEY_Z + SHIFT_MASK; // : ASCII_27=KEY_Q; // ' ASCII_22=KEY_Q + SHIFT_MASK; // " ASCII_7A=KEY_SLASH; // z ASCII_5A=KEY_SLASH + SHIFT_MASK; // Z ASCII_78=KEY_B; // x ASCII_58=KEY_B + SHIFT_MASK; // X ASCII_63=KEY_I; // c ASCII_43=KEY_I + SHIFT_MASK; // C ASCII_76=KEY_PERIOD; // v ASCII_56=KEY_PERIOD + SHIFT_MASK; // V ASCII_62=KEY_N; // b ASCII_42=KEY_N + SHIFT_MASK; // B ASCII_6E=KEY_L; // n ASCII_4E=KEY_L + SHIFT_MASK; // N ASCII_2C=KEY_W; // , ASCII_3C=KEY_W + SHIFT_MASK; // < ASCII_2E=KEY_E; // . ASCII_3E=KEY_E + SHIFT_MASK; // > ASCII_2F=KEY_LEFT_BRACE; // / ASCII_3F=KEY_LEFT_BRACE + SHIFT_MASK; // ? } // LAYOUT_USA_ENGLISH } else if (KeyboardLayout[0] == LAYOUT_US_INTERNATIONAL) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; //KEYCODE_TYPE=uint16_t KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_6 + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_QUOTE; DEADKEY_GRAVE_ACCENT=KEY_TILDE; DEADKEY_TILDE=KEY_TILDE + SHIFT_MASK; DEADKEY_DIAERESIS=KEY_QUOTE + SHIFT_MASK; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=DIAERESIS_BITS + KEY_SPACE;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=ACUTE_ACCENT_BITS + KEY_SPACE;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_8 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_SLASH;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SEMICOLON + SHIFT_MASK;// 58 : ASCII_3B=KEY_SEMICOLON;// 59 ; ASCII_3C=KEY_COMMA + SHIFT_MASK;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_PERIOD + SHIFT_MASK;// 62 > ASCII_3F=KEY_SLASH + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + SHIFT_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE;// 91 [ ASCII_5C=KEY_BACKSLASH;// 92 ASCII_5D=KEY_RIGHT_BRACE;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_LEFT_BRACE + SHIFT_MASK;// 123 { ASCII_7C=KEY_BACKSLASH + SHIFT_MASK;// 124 | ASCII_7D=KEY_RIGHT_BRACE + SHIFT_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=KEY_1 + ALTGR_MASK;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_C + ALTGR_MASK + SHIFT_MASK;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_4 + ALTGR_MASK + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_4 + ALTGR_MASK;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=KEY_MINUS + ALTGR_MASK;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_BACKSLASH + ALTGR_MASK + SHIFT_MASK;// 166 ¦ BROKEN BAR;?? ISO_8859_1_A7=KEY_S + ALTGR_MASK + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=KEY_QUOTE + ALTGR_MASK + SHIFT_MASK;// 168 ¨ DIAERESIS ISO_8859_1_A9=KEY_C + ALTGR_MASK;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_LEFT_BRACE + ALTGR_MASK;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_BACKSLASH + ALTGR_MASK;// 172 ¬ NOT SIGN;?? ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=KEY_R + ALTGR_MASK;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_SEMICOLON + ALTGR_MASK + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_2 + ALTGR_MASK;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=KEY_3 + ALTGR_MASK;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=KEY_QUOTE + ALTGR_MASK;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=KEY_SEMICOLON + ALTGR_MASK;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=KEY_1 + ALTGR_MASK + SHIFT_MASK;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_RIGHT_BRACE + ALTGR_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=KEY_6 + ALTGR_MASK;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_7 + ALTGR_MASK;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=KEY_8 + ALTGR_MASK;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=KEY_SLASH + ALTGR_MASK;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=KEY_A + ALTGR_MASK + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=KEY_Q + ALTGR_MASK + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=KEY_W + ALTGR_MASK + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_Z + ALTGR_MASK + SHIFT_MASK;// 198 Æ AE ISO_8859_1_C7=KEY_COMMA + ALTGR_MASK + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=KEY_E + ALTGR_MASK + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=KEY_I + ALTGR_MASK + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + ALTGR_MASK + SHIFT_MASK;// 208 Ð ETH ISO_8859_1_D1=KEY_N + ALTGR_MASK + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=KEY_O + ALTGR_MASK + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=KEY_P + ALTGR_MASK + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=KEY_EQUAL + ALTGR_MASK;// 215 × MULTIPLICATION ISO_8859_1_D8=KEY_L + ALTGR_MASK + SHIFT_MASK;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=KEY_U + ALTGR_MASK + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=KEY_Y + ALTGR_MASK + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_T + ALTGR_MASK + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=KEY_S + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=KEY_A + ALTGR_MASK;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=KEY_W + ALTGR_MASK;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_Z + ALTGR_MASK;// 230 æ ae ISO_8859_1_E7=KEY_COMMA + ALTGR_MASK;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=KEY_I + ALTGR_MASK;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_D + ALTGR_MASK;// 240 ð ETH ISO_8859_1_F1=KEY_N + ALTGR_MASK;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=KEY_O + ALTGR_MASK;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O ;// 245 õ o TILDE ISO_8859_1_F6=KEY_P + ALTGR_MASK;// 246 ö o DIAERESIS ISO_8859_1_F7=KEY_EQUAL + ALTGR_MASK + SHIFT_MASK;// 247 ÷ DIVISION ISO_8859_1_F8=KEY_L + ALTGR_MASK;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=KEY_U + ALTGR_MASK;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_Y + ALTGR_MASK;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_T + ALTGR_MASK;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_5 + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_5 + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_US_INTERNATIONAL } else if (KeyboardLayout[0] == LAYOUT_GERMAN) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0300; ACUTE_ACCENT_BITS=0x0400; GRAVE_ACCENT_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_TILDE; DEADKEY_ACUTE_ACCENT=KEY_EQUAL; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_BACKSLASH;// 35 #=?? ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_BACKSLASH + SHIFT_MASK;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_RIGHT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_RIGHT_BRACE;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_Q + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_MINUS + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=KEY_RIGHT_BRACE + ALTGR_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent Sign ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=KEY_E + ALTGR_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_3 + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_TILDE + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_2 + ALTGR_MASK;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=KEY_3 + ALTGR_MASK;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=0;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=KEY_QUOTE + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=0;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=0;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=KEY_SEMICOLON + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=KEY_LEFT_BRACE + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=KEY_MINUS;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=KEY_QUOTE;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=0;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=0;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=KEY_SEMICOLON;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_LEFT_BRACE;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Z;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_GERMAN } else if (KeyboardLayout[0] == LAYOUT_GERMAN_MAC) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; ACUTE_ACCENT_BITS=0x0100; GRAVE_ACCENT_BITS=0x0200; CIRCUMFLEX_BITS=0x0300; DIAERESIS_BITS=0x0400; TILDE_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_ACUTE_ACCENT=KEY_EQUAL; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_CIRCUMFLEX=KEY_6 + SHIFT_MASK + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_U + ALTGR_MASK; DEADKEY_TILDE=KEY_N + ALTGR_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_BACKSLASH;// 35 #=?? ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_BACKSLASH + SHIFT_MASK;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_RIGHT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_RIGHT_BRACE;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_TILDE;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_TILDE + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_L + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_5 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_7 + ALTGR_MASK + SHIFT_MASK;// 92 ASCII_5D=KEY_6 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_8 + ALTGR_MASK;// 123 { ASCII_7C=KEY_7 + ALTGR_MASK;// 124 | ASCII_7D=KEY_9 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=KEY_1 + ALTGR_MASK;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_4 + ALTGR_MASK;// 162 ¢ Cent Sign ISO_8859_1_A3=KEY_4 + SHIFT_MASK + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_E + ALTGR_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=KEY_Z + ALTGR_MASK;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_3 + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=KEY_G + ALTGR_MASK;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=KEY_H + ALTGR_MASK;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_Q + ALTGR_MASK;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=KEY_R + ALTGR_MASK;// 174 ® REGISTERED SIGN ISO_8859_1_AF=KEY_0 + SHIFT_MASK + ALTGR_MASK;// 175 ¯ MACRON ISO_8859_1_B0=KEY_LEFT_BRACE + ALTGR_MASK + SHIFT_MASK; // 176 ° DEGREE SIGN ISO_8859_1_B1=KEY_RIGHT_BRACE + ALTGR_MASK;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=KEY_3 + ALTGR_MASK;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=KEY_9 + SHIFT_MASK + ALTGR_MASK;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=KEY_J + ALTGR_MASK;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_Q + SHIFT_MASK + ALTGR_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=KEY_MINUS + ALTGR_MASK;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=KEY_QUOTE + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=KEY_A + ALTGR_MASK + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_QUOTE + ALTGR_MASK + SHIFT_MASK;// 198 Æ AE ISO_8859_1_C7=KEY_C + ALTGR_MASK + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=KEY_SEMICOLON + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=KEY_O + ALTGR_MASK + SHIFT_MASK;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=KEY_LEFT_BRACE + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=KEY_MINUS;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=KEY_QUOTE;// 228 ä a DIAERESIS ISO_8859_1_E5=KEY_A + ALTGR_MASK;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_QUOTE + ALTGR_MASK;// 230 æ ae ISO_8859_1_E7=KEY_C + ALTGR_MASK;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=KEY_SEMICOLON;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=KEY_O + ALTGR_MASK;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_LEFT_BRACE;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Z;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Z;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_GERMAN_MAC } else if (KeyboardLayout[0] == LAYOUT_CANADIAN_FRENCH) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; DIAERESIS_BITS=0x0400; CEDILLA_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_LEFT_BRACE; DEADKEY_ACUTE_ACCENT=KEY_SLASH + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_QUOTE; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_CEDILLA=KEY_RIGHT_BRACE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_TILDE + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=KEY_COMMA + SHIFT_MASK;// 39 ' //ASCII_27=ACUTE_ACCENT_BITS + KEY_SPACE;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_8 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_3 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SEMICOLON + SHIFT_MASK;// 58 : ASCII_3B=KEY_SEMICOLON;// 59 ; ASCII_3C=KEY_BACKSLASH;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_BACKSLASH + SHIFT_MASK;// 62 > ASCII_3F=KEY_6 + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE + ALTGR_MASK;// 91 [ ASCII_5C=KEY_TILDE + ALTGR_MASK;// 92 ASCII_5D=KEY_RIGHT_BRACE + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_QUOTE + ALTGR_MASK;// 123 { ASCII_7C=KEY_TILDE + SHIFT_MASK;// 124 | ASCII_7D=KEY_BACKSLASH + ALTGR_MASK;// 125 } ASCII_7E=KEY_SEMICOLON + ALTGR_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_4 + ALTGR_MASK;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_5 + ALTGR_MASK;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_7 + ALTGR_MASK;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_O + ALTGR_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_NON_US_100;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_6 + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=KEY_PERIOD + ALTGR_MASK;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=KEY_COMMA + ALTGR_MASK;// 175 ¯ MACRON ISO_8859_1_B0=KEY_NON_US_100 + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=KEY_1 + ALTGR_MASK;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_8 + ALTGR_MASK;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=KEY_9 + ALTGR_MASK;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=0;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=KEY_P + ALTGR_MASK;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_NON_US_100 + SHIFT_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=KEY_0 + ALTGR_MASK;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_MINUS + ALTGR_MASK;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=KEY_EQUAL + ALTGR_MASK;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=CEDILLA_BITS + KEY_C + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=KEY_SLASH + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=CEDILLA_BITS + KEY_C;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=KEY_SLASH;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS // LAYOUT_CANADIAN_FRENCH } else if (KeyboardLayout[0] == LAYOUT_CANADIAN_MULTILINGUAL) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; RCTRL_MASK=0x0800; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; DIAERESIS_BITS=0x0200; ACUTE_ACCENT_BITS=0x0300; CEDILLA_BITS=0x0400; GRAVE_ACCENT_BITS=0x0500; TILDE_BITS=0x0600; RING_ABOVE_BITS=0x0700; KEYCODE_MASK=0x0FFF; DEADKEY_CIRCUMFLEX=KEY_LEFT_BRACE; DEADKEY_DIAERESIS=KEY_LEFT_BRACE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_SEMICOLON + RCTRL_MASK; DEADKEY_CEDILLA=KEY_EQUAL + RCTRL_MASK; DEADKEY_GRAVE_ACCENT=KEY_LEFT_BRACE + ALTGR_MASK; DEADKEY_TILDE=KEY_RIGHT_BRACE + ALTGR_MASK; DEADKEY_RING_ABOVE=KEY_LEFT_BRACE + SHIFT_MASK + RCTRL_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_PERIOD + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=KEY_COMMA + SHIFT_MASK;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_8 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_TILDE;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SEMICOLON + SHIFT_MASK;// 58 : ASCII_3B=KEY_SEMICOLON;// 59 ; ASCII_3C=KEY_COMMA + ALTGR_MASK;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_PERIOD + ALTGR_MASK;// 62 > ASCII_3F=KEY_6 + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + SHIFT_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_9 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_TILDE + SHIFT_MASK;// 92 ASCII_5D=KEY_0 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_TILDE + ALTGR_MASK;// 124 | ASCII_7D=KEY_8 + ALTGR_MASK;// 125 } ASCII_7E=KEY_RIGHT_BRACE + RCTRL_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE + ALTGR_MASK;// 160 Nonbreakng Space ISO_8859_1_A1=KEY_1 + SHIFT_MASK + RCTRL_MASK;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_C + RCTRL_MASK;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + SHIFT_MASK + RCTRL_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_4 + SHIFT_MASK + RCTRL_MASK;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=KEY_Y + SHIFT_MASK + RCTRL_MASK;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_NON_US_100 + SHIFT_MASK + RCTRL_MASK; // 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_S + SHIFT_MASK + RCTRL_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=KEY_C + SHIFT_MASK + RCTRL_MASK;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=KEY_F + SHIFT_MASK + RCTRL_MASK;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_Z + ALTGR_MASK;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_EQUAL + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=KEY_TILDE + SHIFT_MASK + RCTRL_MASK;// 173 SOFT HYPHEN ISO_8859_1_AE=KEY_R + SHIFT_MASK + RCTRL_MASK;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0; // special dead key - no implemented=// 175 ¯ MACRON ISO_8859_1_B0=KEY_SEMICOLON + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=KEY_9 + SHIFT_MASK + RCTRL_MASK;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_2 + RCTRL_MASK;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=KEY_3 + RCTRL_MASK;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + RCTRL_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=KEY_R + RCTRL_MASK;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=CEDILLA_BITS + KEY_SPACE;// 184 ¸ CEDILLA ISO_8859_1_B9=KEY_1 + RCTRL_MASK;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=KEY_M + SHIFT_MASK + RCTRL_MASK;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_X + ALTGR_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=KEY_4 + RCTRL_MASK;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_5 + RCTRL_MASK;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=KEY_6 + RCTRL_MASK;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=KEY_MINUS + SHIFT_MASK + RCTRL_MASK;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=KEY_BACKSLASH + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=RING_ABOVE_BITS + KEY_A + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_A + SHIFT_MASK + RCTRL_MASK;// 198 Æ AE ISO_8859_1_C7=KEY_RIGHT_BRACE + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=KEY_QUOTE + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=KEY_SLASH + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + SHIFT_MASK + RCTRL_MASK;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=KEY_COMMA + SHIFT_MASK + RCTRL_MASK;// 215 × MULTIPLICATION ISO_8859_1_D8=KEY_O + SHIFT_MASK + RCTRL_MASK;// 216 Ø O STROKE ISO_8859_1_D9=KEY_NON_US_100 + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_P + RCTRL_MASK + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=KEY_S + RCTRL_MASK;// 223 ß SHARP S ISO_8859_1_E0=KEY_BACKSLASH;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=RING_ABOVE_BITS + KEY_A;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_A + RCTRL_MASK;// 230 æ ae ISO_8859_1_E7=KEY_RIGHT_BRACE;// 231 ç c CEDILLA ISO_8859_1_E8=KEY_QUOTE;// 232 è e GRAVE ISO_8859_1_E9=KEY_SLASH;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_D + RCTRL_MASK;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=KEY_PERIOD + SHIFT_MASK + RCTRL_MASK;// 247 ÷ DIVISION ISO_8859_1_F8=KEY_O + RCTRL_MASK;// 248 ø o STROKE ISO_8859_1_F9=KEY_NON_US_100;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_P + RCTRL_MASK;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS // LAYOUT_CANADIAN_MULTILINGUAL } else if (KeyboardLayout[0] == LAYOUT_UNITED_KINGDOM) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; KEYCODE_MASK=0x00FF; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_BACKSLASH;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=KEY_QUOTE;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_8 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_SLASH;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SEMICOLON + SHIFT_MASK;// 58 : ASCII_3B=KEY_SEMICOLON;// 59 ; ASCII_3C=KEY_COMMA + SHIFT_MASK;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_PERIOD + SHIFT_MASK;// 62 > ASCII_3F=KEY_SLASH + SHIFT_MASK;// 63 ? ASCII_40=KEY_QUOTE + SHIFT_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE;// 91 [ ASCII_5C=KEY_NON_US_100;// 92 ASCII_5D=KEY_RIGHT_BRACE;// 93 ] ASCII_5E=KEY_6 + SHIFT_MASK;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=KEY_TILDE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_LEFT_BRACE + SHIFT_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + SHIFT_MASK;// 124 | ASCII_7D=KEY_RIGHT_BRACE + SHIFT_MASK;// 125 } ASCII_7E=KEY_BACKSLASH + SHIFT_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_TILDE + ALTGR_MASK;// 166 ¦ BROKEN BAR ISO_8859_1_A7=0;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_TILDE + SHIFT_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=0;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=0;// 192 À A GRAVE ISO_8859_1_C1=KEY_A + ALTGR_MASK + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=0;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=0;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=0;// 200 È E GRAVE ISO_8859_1_C9=KEY_E + ALTGR_MASK + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=0;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=0;// 203 Ë E DIAERESIS ISO_8859_1_CC=0;// 204 Ì I GRAVE ISO_8859_1_CD=KEY_I + ALTGR_MASK + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=0;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=0;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=0;// 210 Ò O GRAVE ISO_8859_1_D3=KEY_O + ALTGR_MASK + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=0;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=0;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=0;// 217 Ù U GRAVE ISO_8859_1_DA=KEY_U + ALTGR_MASK + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=0;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=0;// 220 Ü U DIAERESIS ISO_8859_1_DD=0;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=0;// 224 à a GRAVE ISO_8859_1_E1=KEY_A + ALTGR_MASK;// 225 á a ACUTE ISO_8859_1_E2=0;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=0;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=0;// 232 è e GRAVE ISO_8859_1_E9=KEY_E + ALTGR_MASK;// 233 é e ACUTE ISO_8859_1_EA=0;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=0;// 235 ë e DIAERESIS ISO_8859_1_EC=0;// 236 ì i GRAVE ISO_8859_1_ED=KEY_I + ALTGR_MASK;// 237 í i ACUTE ISO_8859_1_EE=0;// 238 î i CIRCUMFLEX ISO_8859_1_EF=0;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=0;// 242 ò o GRAVE ISO_8859_1_F3=KEY_O + ALTGR_MASK;// 243 ó o ACUTE ISO_8859_1_F4=0;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=0;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=0;// 249 ù u GRAVE ISO_8859_1_FA=KEY_U + ALTGR_MASK;// 250 ú u ACUTE ISO_8859_1_FB=0;// 251 û u CIRCUMFLEX ISO_8859_1_FC=0;// 252 ü u DIAERESIS ISO_8859_1_FD=0;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_4 + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_4 + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_UNITED_KINGDOM } else if (KeyboardLayout[0] == LAYOUT_FINNISH) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_EQUAL; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_TILDE=KEY_RIGHT_BRACE + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + ALTGR_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_BACKSLASH;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_BACKSLASH + SHIFT_MASK;// 42 * ASCII_2B=KEY_MINUS;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_MINUS + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE + ALTGR_MASK;// 160 Nonbreakng Space ISO_8859_1_A1=KEY_1 + SHIFT_MASK + ALTGR_MASK;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_4 + SHIFT_MASK;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_TILDE;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_4 + ALTGR_MASK + SHIFT_MASK;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=KEY_SLASH + ALTGR_MASK;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_0 + ALTGR_MASK + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=KEY_X + ALTGR_MASK + SHIFT_MASK;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_3 + ALTGR_MASK + SHIFT_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_TILDE + SHIFT_MASK;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=KEY_MINUS + ALTGR_MASK + SHIFT_MASK;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=KEY_QUOTE + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=KEY_LEFT_BRACE + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_QUOTE + ALTGR_MASK + SHIFT_MASK;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + ALTGR_MASK + SHIFT_MASK;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=KEY_SEMICOLON + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=KEY_X + ALTGR_MASK;// 215 × MULTIPLICATION ISO_8859_1_D8=KEY_SEMICOLON + ALTGR_MASK + SHIFT_MASK;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_T + ALTGR_MASK + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=KEY_S + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=KEY_QUOTE;// 228 ä a DIAERESIS ISO_8859_1_E5=KEY_LEFT_BRACE;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_QUOTE + ALTGR_MASK;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_D + ALTGR_MASK;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=KEY_SEMICOLON;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=KEY_SEMICOLON + ALTGR_MASK;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_T + ALTGR_MASK;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // TODO: Finnish Multilingual layout can type many more glyphs // but we currently don't have tables tables to store them... // LAYOUT_FINNISH } else if (KeyboardLayout[0] == LAYOUT_FRENCH) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; GRAVE_ACCENT_BITS=0x0200; DIAERESIS_BITS=0x0300; TILDE_BITS=0x0400; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_LEFT_BRACE; DEADKEY_GRAVE_ACCENT=KEY_7 + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_LEFT_BRACE + SHIFT_MASK; DEADKEY_TILDE=KEY_2 + ALTGR_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_SLASH;// 33 ! ASCII_22=KEY_3;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_RIGHT_BRACE;// 36 $ ASCII_25=KEY_QUOTE + SHIFT_MASK;// 37 % ASCII_26=KEY_1;// 38 & ASCII_27=KEY_4;// 39 ' ASCII_28=KEY_5;// 40 ( ASCII_29=KEY_MINUS;// 41 ) ASCII_2A=KEY_BACKSLASH;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_M;// 44 , ASCII_2D=KEY_6;// 45 - ASCII_2E=KEY_COMMA + SHIFT_MASK;// 46 . ASCII_2F=KEY_PERIOD + SHIFT_MASK;// 47 / ASCII_30=KEY_0 + SHIFT_MASK;// 48 0 ASCII_31=KEY_1 + SHIFT_MASK;// 49 1 ASCII_32=KEY_2 + SHIFT_MASK;// 50 2 ASCII_33=KEY_3 + SHIFT_MASK;// 51 3 ASCII_34=KEY_4 + SHIFT_MASK;// 52 4 ASCII_35=KEY_5 + SHIFT_MASK;// 53 5 ASCII_36=KEY_6 + SHIFT_MASK;// 54 6 ASCII_37=KEY_7 + SHIFT_MASK;// 55 7 ASCII_38=KEY_8 + SHIFT_MASK;// 55 8 ASCII_39=KEY_9 + SHIFT_MASK;// 57 9 ASCII_3A=KEY_PERIOD;// 58 : ASCII_3B=KEY_COMMA;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_M + SHIFT_MASK;// 63 ? ASCII_40=KEY_0 + ALTGR_MASK;// 64 @ ASCII_41=KEY_Q + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_SEMICOLON + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_A + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_Z + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_W + SHIFT_MASK;// 90 Z ASCII_5B=KEY_5 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_8 + ALTGR_MASK;// 92 ASCII_5D=KEY_MINUS + ALTGR_MASK;// 93 ] ASCII_5E=KEY_9 + ALTGR_MASK;// 94 ^ ASCII_5F=KEY_8;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_Q;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_SEMICOLON;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_A;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_Z;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_W;// 122 z ASCII_7B=KEY_4 + ALTGR_MASK;// 123 { ASCII_7C=KEY_6 + ALTGR_MASK;// 124 | ASCII_7D=KEY_EQUAL + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_RIGHT_BRACE + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_RIGHT_BRACE + ALTGR_MASK;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_SLASH + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_MINUS + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_TILDE;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=0;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_BACKSLASH + SHIFT_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_Q + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=0;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_Q + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_Q + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_Q + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=0;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=0;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=0;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=0;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U;// 220 Ü U DIAERESIS ISO_8859_1_DD=0;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=KEY_0;// 224 à a GRAVE ISO_8859_1_E1=0;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_Q;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_Q;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_Q;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_9;// 231 ç c CEDILLA ISO_8859_1_E8=KEY_7;// 232 è e GRAVE ISO_8859_1_E9=KEY_2;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=0;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=0;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=KEY_SEMICOLON;// 249 ù u GRAVE ISO_8859_1_FA=0;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=0;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_FRENCH } else if (KeyboardLayout[0] == LAYOUT_DANISH || KeyboardLayout[0] == LAYOUT_DANISH_MAC) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_EQUAL; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_TILDE=KEY_RIGHT_BRACE + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + ALTGR_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_BACKSLASH;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_BACKSLASH + SHIFT_MASK;// 42 * ASCII_2B=KEY_MINUS;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_NON_US_100 + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_EQUAL + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_4 + SHIFT_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_TILDE + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_4;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_TILDE;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=KEY_LEFT_BRACE + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_SEMICOLON + SHIFT_MASK;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + ALTGR_MASK + SHIFT_MASK;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=KEY_QUOTE + SHIFT_MASK;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_T + ALTGR_MASK + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=KEY_S + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=KEY_LEFT_BRACE;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_SEMICOLON;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_D + ALTGR_MASK;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=KEY_QUOTE;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_T + ALTGR_MASK;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign if (KeyboardLayout[0] == LAYOUT_DANISH_MAC) { ASCII_24=KEY_3 + SHIFT_MASK + ALTGR_MASK;// 36 $ ASCII_3C=KEY_TILDE;// 60 < ASCII_3E=KEY_TILDE + SHIFT_MASK;// 62 > ASCII_40=KEY_BACKSLASH + ALTGR_MASK;// 64 @ ASCII_5C=KEY_7 + ALTGR_MASK + SHIFT_MASK;// 92 \ ASCII_7B=KEY_8 + ALTGR_MASK + SHIFT_MASK;// 123 { ASCII_7D=KEY_9 + ALTGR_MASK + SHIFT_MASK;// 125 } ISO_8859_1_A1=KEY_1 + ALTGR_MASK;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_4 + ALTGR_MASK + SHIFT_MASK;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_4 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A5=KEY_Y + ALTGR_MASK;// 165 ¥ YEN SIGN ISO_8859_1_A7=0;// 167 § SECTION SIGN?? ISO_8859_1_A9=KEY_G + ALTGR_MASK;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=KEY_A + ALTGR_MASK;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_H + ALTGR_MASK;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_L + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AE=KEY_R + ALTGR_MASK;// 174 ® REGISTERED SIGN ISO_8859_1_AF=KEY_0 + SHIFT_MASK + ALTGR_MASK;// 175 ¯ MACRON ISO_8859_1_B0=KEY_Q + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=KEY_MINUS + ALTGR_MASK;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B6=KEY_7 + ALTGR_MASK;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=KEY_PERIOD + ALTGR_MASK;// 183 · MIDDLE DOT ISO_8859_1_BA=KEY_BACKSLASH + SHIFT_MASK + ALTGR_MASK;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_H + SHIFT_MASK + ALTGR_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BF=KEY_MINUS + SHIFT_MASK + ALTGR_MASK;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C7=KEY_C + ALTGR_MASK + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_E7=KEY_C + ALTGR_MASK;// 231 ç c CEDILLA ISO_8859_1_FE=0;// 254 þ THORN } // LAYOUT_DANISH } else if (KeyboardLayout[0] == LAYOUT_NORWEGIAN) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_EQUAL + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_TILDE=KEY_RIGHT_BRACE + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + ALTGR_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_BACKSLASH;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_BACKSLASH + SHIFT_MASK;// 42 * ASCII_2B=KEY_MINUS;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_EQUAL;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_TILDE;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_4 + SHIFT_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_TILDE + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_4;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_TILDE;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=KEY_LEFT_BRACE + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_QUOTE + SHIFT_MASK;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + ALTGR_MASK + SHIFT_MASK;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=KEY_SEMICOLON + SHIFT_MASK;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_T + ALTGR_MASK + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=KEY_S + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=KEY_LEFT_BRACE;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_QUOTE;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_D + ALTGR_MASK;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=KEY_SEMICOLON;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_T + ALTGR_MASK;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_NORWEGIAN } else if (KeyboardLayout[0] == LAYOUT_SWEDISH) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_EQUAL; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_TILDE=KEY_RIGHT_BRACE + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + ALTGR_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_BACKSLASH;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_BACKSLASH + SHIFT_MASK;// 42 * ASCII_2B=KEY_MINUS;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_MINUS + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=KEY_4 + SHIFT_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_TILDE;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_4;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_TILDE + SHIFT_MASK;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=KEY_QUOTE + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=KEY_LEFT_BRACE + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + ALTGR_MASK + SHIFT_MASK;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=KEY_SEMICOLON + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_T + ALTGR_MASK + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=KEY_S + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=KEY_QUOTE;// 228 ä a DIAERESIS ISO_8859_1_E5=KEY_LEFT_BRACE;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_D + ALTGR_MASK;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=KEY_SEMICOLON;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_T + ALTGR_MASK;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_SWEDISH } else if (KeyboardLayout[0] == LAYOUT_SPANISH) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_LEFT_BRACE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_QUOTE; DEADKEY_GRAVE_ACCENT=KEY_LEFT_BRACE; DEADKEY_TILDE=KEY_4 + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_QUOTE + SHIFT_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_RIGHT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_RIGHT_BRACE;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE + ALTGR_MASK;// 91 [ ASCII_5C=KEY_TILDE + ALTGR_MASK;// 92 ASCII_5D=KEY_RIGHT_BRACE + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_QUOTE + ALTGR_MASK;// 123 { ASCII_7C=KEY_1 + ALTGR_MASK;// 124 | ASCII_7D=KEY_BACKSLASH + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=KEY_EQUAL;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=0;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=KEY_TILDE + SHIFT_MASK;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_6 + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=KEY_3 + SHIFT_MASK;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=KEY_TILDE;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=KEY_EQUAL;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=KEY_BACKSLASH + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=KEY_SEMICOLON + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_BACKSLASH;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=KEY_SEMICOLON;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_5 + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_5 + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_SPANISH } else if (KeyboardLayout[0] == LAYOUT_PORTUGUESE) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_BACKSLASH; DEADKEY_ACUTE_ACCENT=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_GRAVE_ACCENT=KEY_RIGHT_BRACE + SHIFT_MASK; DEADKEY_TILDE=KEY_BACKSLASH; DEADKEY_DIAERESIS=KEY_LEFT_BRACE + SHIFT_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_LEFT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_LEFT_BRACE;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_TILDE + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_TILDE + SHIFT_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_4 + ALTGR_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=KEY_QUOTE + SHIFT_MASK;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=KEY_EQUAL;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=KEY_QUOTE;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=KEY_EQUAL + SHIFT_MASK;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=KEY_SEMICOLON + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_SEMICOLON;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_PORTUGUESE } else if (KeyboardLayout[0] == LAYOUT_ITALIAN) { SHIFT_MASK=0x40; ALTGR_MASK=0x80; KEYCODE_MASK=0x00FF; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_QUOTE + ALTGR_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_RIGHT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_RIGHT_BRACE;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_SEMICOLON + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE + ALTGR_MASK;// 91 [ ASCII_5C=KEY_TILDE;// 92 ASCII_5D=KEY_RIGHT_BRACE + ALTGR_MASK;// 93 ] ASCII_5E=KEY_EQUAL + SHIFT_MASK;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=0;// 96 ` (how to type this on Italian?) ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_LEFT_BRACE + SHIFT_MASK + ALTGR_MASK; // 123 { ASCII_7C=KEY_TILDE + SHIFT_MASK;// 124 | ASCII_7D=KEY_RIGHT_BRACE + SHIFT_MASK + ALTGR_MASK; // 125 } ASCII_7E=0;// 126 ~ (how to type this on Italian?) ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent Sign ISO_8859_1_A3=KEY_3 + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_BACKSLASH + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_QUOTE + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=0;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=0;// 192 À A GRAVE ISO_8859_1_C1=0;// 193 Á A ACUTE ISO_8859_1_C2=0;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=0;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=0;// 200 È E GRAVE ISO_8859_1_C9=0;// 201 É E ACUTE ISO_8859_1_CA=0;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=0;// 203 Ë E DIAERESIS ISO_8859_1_CC=0;// 204 Ì I GRAVE ISO_8859_1_CD=0;// 205 Í I ACUTE ISO_8859_1_CE=0;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=0;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=0;// 210 Ò O GRAVE ISO_8859_1_D3=0;// 211 Ó O ACUTE ISO_8859_1_D4=0;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=0;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=0;// 217 Ù U GRAVE ISO_8859_1_DA=0;// 218 Ú U ACUTE ISO_8859_1_DB=0;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=0;// 220 Ü U DIAERESIS ISO_8859_1_DD=0;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=KEY_QUOTE;// 224 à a GRAVE ISO_8859_1_E1=0;// 225 á a ACUTE ISO_8859_1_E2=0;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=0;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_SEMICOLON + SHIFT_MASK;// 231 ç c CEDILLA ISO_8859_1_E8=KEY_LEFT_BRACE;// 232 è e GRAVE ISO_8859_1_E9=KEY_LEFT_BRACE + SHIFT_MASK;// 233 é e ACUTE ISO_8859_1_EA=0;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=0;// 235 ë e DIAERESIS ISO_8859_1_EC=KEY_EQUAL;// 236 ì i GRAVE ISO_8859_1_ED=0;// 237 í i ACUTE ISO_8859_1_EE=0;// 238 î i CIRCUMFLEX ISO_8859_1_EF=0;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=KEY_SEMICOLON;// 242 ò o GRAVE ISO_8859_1_F3=0;// 243 ó o ACUTE ISO_8859_1_F4=0;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=0;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=KEY_BACKSLASH;// 249 ù u GRAVE ISO_8859_1_FA=0;// 250 ú u ACUTE ISO_8859_1_FB=0;// 251 û u CIRCUMFLEX ISO_8859_1_FC=0;// 252 ü u DIAERESIS ISO_8859_1_FD=0;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS // LAYOUT_ITALIAN } else if (KeyboardLayout[0] == LAYOUT_PORTUGUESE_BRAZILIAN) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_QUOTE + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_LEFT_BRACE; DEADKEY_GRAVE_ACCENT=KEY_LEFT_BRACE + SHIFT_MASK; DEADKEY_TILDE=KEY_QUOTE; DEADKEY_DIAERESIS=KEY_6 + SHIFT_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_TILDE + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=KEY_TILDE;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_7 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_Q + ALTGR_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SLASH + SHIFT_MASK;// 58 : ASCII_3B=KEY_SLASH;// 59 ; ASCII_3C=KEY_COMMA + SHIFT_MASK;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_PERIOD + SHIFT_MASK;// 62 > ASCII_3F=KEY_W + ALTGR_MASK;// 63 ? ASCII_40=KEY_2 + SHIFT_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_RIGHT_BRACE;// 91 [ ASCII_5C=KEY_NON_US_100;// 92 ASCII_5D=KEY_BACKSLASH;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_RIGHT_BRACE + SHIFT_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + SHIFT_MASK;// 124 | ASCII_7D=KEY_BACKSLASH + SHIFT_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_5 + ALTGR_MASK;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_4 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_EQUAL + ALTGR_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=KEY_RIGHT_BRACE + ALTGR_MASK;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_6 + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_E + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_2 + ALTGR_MASK;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=KEY_2 + ALTGR_MASK;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=KEY_1 + ALTGR_MASK;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=KEY_BACKSLASH + ALTGR_MASK;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS // LAYOUT_PORTUGUESE_BRAZILIAN } else if (KeyboardLayout[0] == LAYOUT_FRENCH_BELGIAN) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; GRAVE_ACCENT_BITS=0x0200; DIAERESIS_BITS=0x0300; TILDE_BITS=0x0400; ACUTE_ACCENT_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_LEFT_BRACE; DEADKEY_ACUTE_ACCENT=KEY_QUOTE + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_BACKSLASH + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_LEFT_BRACE + SHIFT_MASK; DEADKEY_TILDE=KEY_SLASH + ALTGR_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_8;// 33 ! ASCII_22=KEY_3;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_RIGHT_BRACE;// 36 $ ASCII_25=KEY_QUOTE + SHIFT_MASK;// 37 % ASCII_26=KEY_1;// 38 & ASCII_27=KEY_4;// 39 ' ASCII_28=KEY_5;// 40 ( ASCII_29=KEY_MINUS;// 41 ) ASCII_2A=KEY_RIGHT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_SLASH + SHIFT_MASK;// 43 + ASCII_2C=KEY_M;// 44 , ASCII_2D=KEY_EQUAL;// 45 - ASCII_2E=KEY_COMMA + SHIFT_MASK;// 46 . ASCII_2F=KEY_PERIOD + SHIFT_MASK;// 47 / ASCII_30=KEY_0 + SHIFT_MASK;// 48 0 ASCII_31=KEY_1 + SHIFT_MASK;// 49 1 ASCII_32=KEY_2 + SHIFT_MASK;// 50 2 ASCII_33=KEY_3 + SHIFT_MASK;// 51 3 ASCII_34=KEY_4 + SHIFT_MASK;// 52 4 ASCII_35=KEY_5 + SHIFT_MASK;// 53 5 ASCII_36=KEY_6 + SHIFT_MASK;// 54 6 ASCII_37=KEY_7 + SHIFT_MASK;// 55 7 ASCII_38=KEY_8 + SHIFT_MASK;// 55 8 ASCII_39=KEY_9 + SHIFT_MASK;// 57 9 ASCII_3A=KEY_PERIOD;// 58 : ASCII_3B=KEY_COMMA;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_SLASH;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_M + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_Q + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_SEMICOLON + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_A + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_Z + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_W + SHIFT_MASK;// 90 Z ASCII_5B=KEY_RIGHT_BRACE + ALTGR_MASK;// 91 [ ASCII_5C=KEY_NON_US_100 + ALTGR_MASK;// 92 ASCII_5D=KEY_LEFT_BRACE + ALTGR_MASK;// 93 ] ASCII_5E=KEY_6 + ALTGR_MASK;// 94 ^ ASCII_5F=KEY_EQUAL + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_Q;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_SEMICOLON;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_A;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_Z;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_W;// 122 z ASCII_7B=KEY_9 + ALTGR_MASK;// 123 { ASCII_7C=KEY_1 + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_BACKSLASH + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_6;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_MINUS + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=KEY_TILDE;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=KEY_TILDE + SHIFT_MASK;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_BACKSLASH;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_Q + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_Q + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_Q + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_Q + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_Q + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=KEY_0;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_Q;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_Q;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_Q;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_Q;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_9;// 231 ç c CEDILLA ISO_8859_1_E8=KEY_7;// 232 è e GRAVE ISO_8859_1_E9=KEY_2;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=KEY_QUOTE;// 249 ù u GRAVE - TODO; check FRENCH ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_FRENCH_BELGIAN } else if (KeyboardLayout[0] == LAYOUT_GERMAN_SWISS) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; GRAVE_ACCENT_BITS=0x0200; DIAERESIS_BITS=0x0300; TILDE_BITS=0x0400; ACUTE_ACCENT_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_EQUAL; DEADKEY_ACUTE_ACCENT=KEY_MINUS + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE; DEADKEY_TILDE=KEY_EQUAL + ALTGR_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_RIGHT_BRACE + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_BACKSLASH;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_3 + SHIFT_MASK;// 42 * ASCII_2B=KEY_1 + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE + ALTGR_MASK;// 91 [ ASCII_5C=KEY_NON_US_100 + ALTGR_MASK;// 92 ASCII_5D=KEY_RIGHT_BRACE + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_QUOTE + ALTGR_MASK;// 123 { ASCII_7C=KEY_7 + ALTGR_MASK;// 124 | ASCII_7D=KEY_BACKSLASH + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_8 + ALTGR_MASK;// 162 ¢ Cent Sign ISO_8859_1_A3=KEY_BACKSLASH + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_1 + ALTGR_MASK;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_5 + ALTGR_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_6 + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_4 + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=KEY_QUOTE + SHIFT_MASK;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=KEY_QUOTE;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_4 + SHIFT_MASK;// 231 ç c CEDILLA ISO_8859_1_E8=KEY_LEFT_BRACE + SHIFT_MASK;// 232 è e GRAVE ISO_8859_1_E9=KEY_SEMICOLON + SHIFT_MASK;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS TODO: check this ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=KEY_SEMICOLON;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_LEFT_BRACE;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_GERMAN_SWISS } else if (KeyboardLayout[0] == LAYOUT_FRENCH_SWISS) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; GRAVE_ACCENT_BITS=0x0200; DIAERESIS_BITS=0x0300; TILDE_BITS=0x0400; ACUTE_ACCENT_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_EQUAL; DEADKEY_ACUTE_ACCENT=KEY_MINUS + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_EQUAL + SHIFT_MASK; DEADKEY_DIAERESIS=KEY_RIGHT_BRACE; DEADKEY_TILDE=KEY_EQUAL + ALTGR_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_RIGHT_BRACE + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_BACKSLASH;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_3 + SHIFT_MASK;// 42 * ASCII_2B=KEY_1 + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_2 + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE + ALTGR_MASK;// 91 [ ASCII_5C=KEY_NON_US_100 + ALTGR_MASK;// 92 ASCII_5D=KEY_RIGHT_BRACE + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_QUOTE + ALTGR_MASK;// 123 { ASCII_7C=KEY_7 + ALTGR_MASK;// 124 | ASCII_7D=KEY_BACKSLASH + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=KEY_8 + ALTGR_MASK;// 162 ¢ Cent Sign ISO_8859_1_A3=KEY_BACKSLASH + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_1 + ALTGR_MASK;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_5 + ALTGR_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_6 + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_4 + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=KEY_QUOTE;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=KEY_QUOTE + SHIFT_MASK;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_4 + SHIFT_MASK;// 231 ç c CEDILLA ISO_8859_1_E8=KEY_LEFT_BRACE;// 232 è e GRAVE ISO_8859_1_E9=KEY_SEMICOLON;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O;// 245 õ o TILDE ISO_8859_1_F6=KEY_SEMICOLON + SHIFT_MASK;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_LEFT_BRACE + SHIFT_MASK;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_FRENCH_SWISS } else if (KeyboardLayout[0] == LAYOUT_SPANISH_LATIN_AMERICA) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; DIAERESIS_BITS=0x0400; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_QUOTE + ALTGR_MASK; DEADKEY_ACUTE_ACCENT=KEY_LEFT_BRACE; DEADKEY_GRAVE_ACCENT=KEY_BACKSLASH + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_LEFT_BRACE + SHIFT_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_RIGHT_BRACE + SHIFT_MASK;// 42 * ASCII_2B=KEY_RIGHT_BRACE;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_Q + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_QUOTE + SHIFT_MASK;// 91 [ ASCII_5C=KEY_MINUS + ALTGR_MASK;// 92 ASCII_5D=KEY_BACKSLASH + SHIFT_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_QUOTE;// 123 { ASCII_7C=KEY_TILDE;// 124 | ASCII_7D=KEY_BACKSLASH;// 125 } ASCII_7E=KEY_RIGHT_BRACE + ALTGR_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=KEY_EQUAL + SHIFT_MASK;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=0;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_TILDE + ALTGR_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_TILDE + SHIFT_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=KEY_EQUAL;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=KEY_SEMICOLON + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=KEY_SEMICOLON;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS // LAYOUT_SPANISH_LATIN_AMERICA } else if (KeyboardLayout[0] == LAYOUT_IRISH) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0300; GRAVE_ACCENT_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; KEYCODE_MASK=0x03FF; DEADKEY_ACUTE_ACCENT=KEY_QUOTE + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_TILDE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_BACKSLASH;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_7 + SHIFT_MASK;// 38 & ASCII_27=KEY_QUOTE;// 39 ' ASCII_28=KEY_9 + SHIFT_MASK;// 40 ( ASCII_29=KEY_0 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_8 + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_MINUS;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_SLASH;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SEMICOLON + SHIFT_MASK;// 58 : ASCII_3B=KEY_SEMICOLON;// 59 ; ASCII_3C=KEY_COMMA + SHIFT_MASK;// 60 < ASCII_3D=KEY_EQUAL;// 61 = ASCII_3E=KEY_PERIOD + SHIFT_MASK;// 62 > ASCII_3F=KEY_SLASH + SHIFT_MASK;// 63 ? ASCII_40=KEY_QUOTE + SHIFT_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_LEFT_BRACE;// 91 [ ASCII_5C=KEY_NON_US_100;// 92 ASCII_5D=KEY_RIGHT_BRACE;// 93 ] ASCII_5E=KEY_6 + SHIFT_MASK;// 94 ^ ASCII_5F=KEY_MINUS + SHIFT_MASK;// 95 _ ASCII_60=KEY_QUOTE + SHIFT_MASK + ALTGR_MASK;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_LEFT_BRACE + SHIFT_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + SHIFT_MASK;// 124 | ASCII_7D=KEY_RIGHT_BRACE + SHIFT_MASK;// 125 } ASCII_7E=KEY_BACKSLASH + SHIFT_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_3 + SHIFT_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=KEY_TILDE + ALTGR_MASK;// 166 ¦ BROKEN BAR ISO_8859_1_A7=0;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=KEY_TILDE + SHIFT_MASK;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=0;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A;// 192 À A GRAVE ISO_8859_1_C1=KEY_A + ALTGR_MASK + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=0;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=0;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E;// 200 È E GRAVE ISO_8859_1_C9=KEY_E + ALTGR_MASK + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=0;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=0;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I;// 204 Ì I GRAVE ISO_8859_1_CD=KEY_I + ALTGR_MASK + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=0;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=0;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O;// 210 Ò O GRAVE ISO_8859_1_D3=KEY_O + ALTGR_MASK + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=0;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=0;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U;// 217 Ù U GRAVE ISO_8859_1_DA=KEY_U + ALTGR_MASK + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=0;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=0;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=KEY_A + ALTGR_MASK;// 225 á a ACUTE ISO_8859_1_E2=0;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=0;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=KEY_E + ALTGR_MASK;// 233 é e ACUTE ISO_8859_1_EA=0;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=0;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=KEY_I + ALTGR_MASK;// 237 í i ACUTE ISO_8859_1_EE=0;// 238 î i CIRCUMFLEX ISO_8859_1_EF=0;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=KEY_O + ALTGR_MASK;// 243 ó o ACUTE ISO_8859_1_F4=0;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=0;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=KEY_U + ALTGR_MASK;// 250 ú u ACUTE ISO_8859_1_FB=0;// 251 û u CIRCUMFLEX ISO_8859_1_FC=0;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_4 + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_4 + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_IRISH } else if (KeyboardLayout[0] == LAYOUT_ICELANDIC) { SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; DIAERESIS_BITS=0x0400; RING_ABOVE_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_QUOTE + ALTGR_MASK; DEADKEY_ACUTE_ACCENT=KEY_QUOTE; DEADKEY_GRAVE_ACCENT=KEY_BACKSLASH + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_TILDE + SHIFT_MASK; DEADKEY_RING_ABOVE=KEY_TILDE; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_QUOTE + SHIFT_MASK;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_BACKSLASH + SHIFT_MASK;// 42 * ASCII_2B=KEY_BACKSLASH;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_EQUAL;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_RIGHT_BRACE + SHIFT_MASK;// 63 ? ASCII_40=KEY_Q + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_MINUS + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_EQUAL + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=KEY_RIGHT_BRACE + ALTGR_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR;?? ISO_8859_1_A7=0;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN;?? ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=KEY_TILDE + ALTGR_MASK;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=KEY_M + ALTGR_MASK;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + ALTGR_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=RING_ABOVE_BITS + KEY_A + SHIFT_MASK;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_SEMICOLON + SHIFT_MASK;// 198 Æ AE ISO_8859_1_C7=0;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_LEFT_BRACE + SHIFT_MASK;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=KEY_SLASH + SHIFT_MASK;// 222 Þ THORN ISO_8859_1_DF=0;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=RING_ABOVE_BITS + KEY_A;// 229 å a RING ABOVE ISO_8859_1_E6=KEY_SEMICOLON;// 230 æ ae ISO_8859_1_E7=0;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=KEY_LEFT_BRACE;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=KEY_SLASH;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_5 + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_5 + ALTGR_MASK;// 20AC € Euro Sign // LAYOUT_ICELANDIC } else if (KeyboardLayout[0] == LAYOUT_TURKISH) { // http://forum.pjrc.com/threads/18781-Turkish-Language-Support SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0700; CIRCUMFLEX_BITS=0x0100; ACUTE_ACCENT_BITS=0x0200; GRAVE_ACCENT_BITS=0x0300; TILDE_BITS=0x0400; DIAERESIS_BITS=0x0500; KEYCODE_MASK=0x07FF; DEADKEY_CIRCUMFLEX=KEY_3 + SHIFT_MASK; DEADKEY_ACUTE_ACCENT=KEY_SEMICOLON + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_BACKSLASH + ALTGR_MASK; DEADKEY_TILDE=KEY_RIGHT_BRACE + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_LEFT_BRACE + ALTGR_MASK; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_TILDE;// 34 " ASCII_23=KEY_3 + ALTGR_MASK;// 35 # ASCII_24=KEY_4 + ALTGR_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_2 + SHIFT_MASK;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_MINUS;// 42 * ASCII_2B=KEY_4 + SHIFT_MASK;// 43 + ASCII_2C=KEY_BACKSLASH;// 44 , ASCII_2D=KEY_EQUAL;// 45 - ASCII_2E=KEY_SLASH;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_SLASH + SHIFT_MASK;// 58 : ASCII_3B=KEY_BACKSLASH + SHIFT_MASK;// 59 ; ASCII_3C=KEY_TILDE + ALTGR_MASK;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_1 + ALTGR_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_Q + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Y + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Z + SHIFT_MASK;// 90 Z ASCII_5B=KEY_8 + ALTGR_MASK;// 91 [ ASCII_5C=KEY_MINUS + ALTGR_MASK;// 92 ASCII_5D=KEY_9 + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_EQUAL + SHIFT_MASK;// 95 _ ASCII_60=GRAVE_ACCENT_BITS + KEY_SPACE;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_QUOTE;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Y;// 121 y ASCII_7A=KEY_Z;// 122 z ASCII_7B=KEY_7 + ALTGR_MASK;// 123 { ASCII_7C=KEY_EQUAL + ALTGR_MASK;// 124 | ASCII_7D=KEY_0 + ALTGR_MASK;// 125 } ASCII_7E=TILDE_BITS + KEY_SPACE;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent SIGN ISO_8859_1_A3=KEY_2 + ALTGR_MASK;// 163 £ Pound Sign ISO_8859_1_A4=0;// 164 ¤ Currency or Euro Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR;?? ISO_8859_1_A7=0;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN;?? ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=0;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=0;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=KEY_5 + ALTGR_MASK;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=TILDE_BITS + KEY_A + SHIFT_MASK;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=KEY_A + ALTGR_MASK;// 198 Æ AE ISO_8859_1_C7=KEY_PERIOD + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=TILDE_BITS + KEY_N + SHIFT_MASK;// 209 Ñ N TILDE ISO_8859_1_D2=GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=TILDE_BITS + KEY_O + SHIFT_MASK;// 213 Õ O TILDE ISO_8859_1_D6=KEY_COMMA + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=0;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=KEY_RIGHT_BRACE + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=KEY_S + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=GRAVE_ACCENT_BITS + KEY_A;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=TILDE_BITS + KEY_A;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=KEY_PERIOD;// 231 ç c CEDILLA ISO_8859_1_E8=GRAVE_ACCENT_BITS + KEY_E;// 232 è e GRAVE ISO_8859_1_E9=KEY_TILDE + SHIFT_MASK;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=GRAVE_ACCENT_BITS + KEY_I;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=TILDE_BITS + KEY_N;// 241 ñ n TILDE ISO_8859_1_F2=GRAVE_ACCENT_BITS + KEY_O;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=TILDE_BITS + KEY_O ;// 245 õ o TILDE ISO_8859_1_F6=KEY_COMMA;// 246 ö o DIAERESIS ISO_8859_1_F7=0;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=GRAVE_ACCENT_BITS + KEY_U;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_RIGHT_BRACE;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Y;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=DIAERESIS_BITS + KEY_Y;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign // not yet implemented UNICODE_EXTRA00=0x20AC; KEYCODE_EXTRA00=KEY_E + ALTGR_MASK;// 20AC € Euro Sign UNICODE_EXTRA01=0x011E; KEYCODE_EXTRA01=KEY_LEFT_BRACE + SHIFT_MASK;// 011E Ğ Latin capital letter G with breve UNICODE_EXTRA02=0x011F; KEYCODE_EXTRA02=KEY_LEFT_BRACE;// 011F ğ Latin small letter g with breve UNICODE_EXTRA03=0x0130; KEYCODE_EXTRA03=KEY_QUOTE + SHIFT_MASK;// 0130 İ Latin captial letter I with dot above UNICODE_EXTRA04=0x0131; KEYCODE_EXTRA04=KEY_I;// 0131 ı Latin small letter dotless i UNICODE_EXTRA05=0x015E; KEYCODE_EXTRA05=KEY_SEMICOLON + SHIFT_MASK;// 015E Ş Latin capital letter S with cedilla UNICODE_EXTRA06=0x0151; KEYCODE_EXTRA06=KEY_SEMICOLON;// 0151 ş Latin small letter s with cedilla // LAYOUT_TURKISH } else if (KeyboardLayout[0] == LAYOUT_CZECH) { // http://forum.pjrc.com/threads/24495-Czech-keyboard SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0F00; ACUTE_ACCENT_BITS=0x0100; // TODO: the Czech might not support some DEGREE_SIGN_BITS=0x0200; // of these deadkeys, perhaps not any??? CARON_BITS=0x0300; //CIRCUMFLEX_BITS=0x0400; BREVE_BITS=0x0500; OGONEK_BITS=0x0600; //GRAVE_ACCENT_BITS=0x0700 DOT_ABOVE_BITS=0x0800; DOUBLE_ACUTE_BITS=0x0900; //DIAERESIS_BITS=0x0A00 CEDILLA_BITS=0x0B00; KEYCODE_MASK=0x0FFF; DEADKEY_ACUTE_ACCENT=KEY_EQUAL; // TODO: is it KEY_9 + ALTGR_MASK; DEADKEY_DEGREE_SIGN=KEY_TILDE + SHIFT_MASK; // TODO: is it KEY_5 + ALTGR_MASK; DEADKEY_CARON=KEY_EQUAL + SHIFT_MASK; // TODO: is it KEY_2 + ALTGR_MASK; //DEADKEY_CIRCUMFLEX=KEY_3 + ALTGR_MASK; DEADKEY_BREVE=KEY_4 + ALTGR_MASK; DEADKEY_OGONEK=KEY_6 + ALTGR_MASK; //DEADKEY_GRAVE_ACCENT=KEY_7 + ALTGR_MASK; DEADKEY_DOT_ABOVE=KEY_8 + ALTGR_MASK; DEADKEY_DOUBLE_ACUTE=KEY_0 + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_MINUS + ALTGR_MASK; DEADKEY_CEDILLA=KEY_EQUAL + ALTGR_MASK; KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_QUOTE + SHIFT_MASK;// 33 ! ASCII_22=KEY_SEMICOLON + SHIFT_MASK;// 34 " ASCII_23=KEY_X + ALTGR_MASK;// 35 # ASCII_24=KEY_SEMICOLON + ALTGR_MASK;// 36 $ ASCII_25=KEY_MINUS + SHIFT_MASK;// 37 % ASCII_26=KEY_C + ALTGR_MASK;// 38 & ASCII_27=KEY_BACKSLASH + SHIFT_MASK;// 39 ' ASCII_28=KEY_RIGHT_BRACE + SHIFT_MASK;// 40 ( ASCII_29=KEY_RIGHT_BRACE;// 41 ) ASCII_2A=KEY_SLASH + ALTGR_MASK;// 42 * ASCII_2B=KEY_1;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_LEFT_BRACE + SHIFT_MASK;// 47 / ASCII_30=KEY_0 + SHIFT_MASK;// 48 0 ASCII_31=KEY_1 + SHIFT_MASK;// 49 1 ASCII_32=KEY_2 + SHIFT_MASK;// 50 2 ASCII_33=KEY_3 + SHIFT_MASK;// 51 3 ASCII_34=KEY_4 + SHIFT_MASK;// 52 4 ASCII_35=KEY_5 + SHIFT_MASK;// 53 5 ASCII_36=KEY_6 + SHIFT_MASK;// 54 6 ASCII_37=KEY_7 + SHIFT_MASK;// 55 7 ASCII_38=KEY_8 + SHIFT_MASK;// 55 8 ASCII_39=KEY_9 + SHIFT_MASK;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_TILDE;// 59 ; ASCII_3C=KEY_COMMA + ALTGR_MASK;// 60 < ASCII_3D=KEY_MINUS;// 61 = ASCII_3E=KEY_PERIOD + ALTGR_MASK;// 62 > ASCII_3F=KEY_COMMA + SHIFT_MASK;// 63 ? ASCII_40=KEY_V + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_F + ALTGR_MASK;// 91 [ ASCII_5C=KEY_NON_US_100;// 92 ASCII_5D=KEY_G + ALTGR_MASK;// 93 ] ASCII_5E=KEY_3 + ALTGR_MASK;// 94 ^ TODO: testme ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=KEY_7 + ALTGR_MASK;// 96 ` TODO: testme ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_B + ALTGR_MASK;// 123 { ASCII_7C=KEY_NON_US_100 + SHIFT_MASK;// 124 | ASCII_7D=KEY_N + ALTGR_MASK;// 125 } ASCII_7E=KEY_1 + ALTGR_MASK;// 126 ~ TODO: fixme ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent Sign ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=KEY_BACKSLASH + ALTGR_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_QUOTE;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=DEGREE_SIGN_BITS + KEY_SPACE;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=CEDILLA_BITS + KEY_SPACE;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=0;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=0;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=0;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=CEDILLA_BITS + KEY_C + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=0;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=0;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=0;// 203 Ë E DIAERESIS ISO_8859_1_CC=0;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=0;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=0;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=0;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=0;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=0;// 214 Ö O DIAERESIS ISO_8859_1_D7=KEY_RIGHT_BRACE + ALTGR_MASK;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=0;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=0;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=0;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=KEY_QUOTE + ALTGR_MASK;// 223 ß SHARP S TODO: testme ISO_8859_1_E0=0;// 224 à a GRAVE ISO_8859_1_E1=KEY_8;// 225 á a ACUTE ISO_8859_1_E2=0;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=0;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=CEDILLA_BITS + KEY_C;// 231 ç c CEDILLA ISO_8859_1_E8=0;// 232 è e GRAVE ISO_8859_1_E9=KEY_0;// 233 é e ACUTE ISO_8859_1_EA=0;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=0;// 235 ë e DIAERESIS ISO_8859_1_EC=0;// 236 ì i GRAVE ISO_8859_1_ED=KEY_9;// 237 í i ACUTE ISO_8859_1_EE=0;// 238 î i CIRCUMFLEX ISO_8859_1_EF=0;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=0;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=0;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=0;// 246 ö o DIAERESIS ISO_8859_1_F7=KEY_LEFT_BRACE + ALTGR_MASK;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=0;// 249 ù u GRAVE ISO_8859_1_FA=KEY_LEFT_BRACE;// 250 ú u ACUTE ISO_8859_1_FB=0;// 251 û u CIRCUMFLEX ISO_8859_1_FC=0;// 252 ü u DIAERESIS ISO_8859_1_FD=KEY_7;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign UNICODE_EXTRA00=0x011B;// ě Small Letter E with caron KEYCODE_EXTRA00=KEY_2; UNICODE_EXTRA01=0x0161;// š Small Letter S with caron KEYCODE_EXTRA01=KEY_3; UNICODE_EXTRA02=0x010D;// č Small Letter C with caron KEYCODE_EXTRA02=KEY_4; UNICODE_EXTRA03=0x0159;// ř Small Letter R with caron KEYCODE_EXTRA03=KEY_5; UNICODE_EXTRA04=0x017E;// ž Small Letter Z with caron KEYCODE_EXTRA04=KEY_6; UNICODE_EXTRA05=0x016F;// ů Small Letter U with ring above KEYCODE_EXTRA05=KEY_SEMICOLON; UNICODE_EXTRA06=0x0111;// đ Small Letter D with stroke KEYCODE_EXTRA06=KEY_S + ALTGR_MASK; UNICODE_EXTRA07=0x0110;// Đ Capital Letter D with stroke KEYCODE_EXTRA07=KEY_D + ALTGR_MASK; UNICODE_EXTRA08=0x0142;// ł Small Letter L with stroke KEYCODE_EXTRA08=KEY_K + ALTGR_MASK; UNICODE_EXTRA09=0x0141;// Ł Capital Letter L with stroke KEYCODE_EXTRA09=KEY_L + ALTGR_MASK; UNICODE_EXTRA0A=0x20AC;// € Euro Sign KEYCODE_EXTRA0A=KEY_E + ALTGR_MASK; // LAYOUT_CZECH } else if (KeyboardLayout[0] == LAYOUT_SERBIAN_LATIN_ONLY) { // http://forum.pjrc.com/threads/27032-Serbian-Keyboard-Layout SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0F00; CEDILLA_BITS=0x0100; CARON_BITS=0x0200; CIRCUMFLEX_BITS=0x0300; BREVE_BITS=0x0400; DEGREE_SIGN_BITS=0x0500; OGONEK_BITS=0x0600; DOT_ABOVE_BITS=0x0700; ACUTE_ACCENT_BITS=0x0800; DOUBLE_ACUTE_BITS=0x0900; DIAERESIS_BITS=0x0A00; KEYCODE_MASK=0x0FFF; DEADKEY_CEDILLA=KEY_TILDE; DEADKEY_CARON=KEY_2 + ALTGR_MASK; DEADKEY_CIRCUMFLEX=KEY_3 + ALTGR_MASK; DEADKEY_BREVE=KEY_4 + ALTGR_MASK; DEADKEY_DEGREE_SIGN=KEY_5 + ALTGR_MASK; DEADKEY_OGONEK=KEY_6 + ALTGR_MASK; DEADKEY_DOT_ABOVE=KEY_8 + ALTGR_MASK; DEADKEY_ACUTE_ACCENT=KEY_9 + ALTGR_MASK; DEADKEY_DOUBLE_ACUTE=KEY_0 + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_MINUS + ALTGR_MASK; //DEADKEY_CEDILLA=KEY_EQUAL + ALTGR_MASK; <-- TODO: why are there 2 Cedilla deadkeys? KEY_NON_US_100=63; ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_1 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_3 + SHIFT_MASK;// 35 # ASCII_24=KEY_4 + SHIFT_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_6 + SHIFT_MASK;// 38 & ASCII_27=KEY_MINUS;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_EQUAL + SHIFT_MASK;// 42 * ASCII_2B=KEY_EQUAL;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - TODO: verify ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_7 + SHIFT_MASK;// 47 / ASCII_30=KEY_0;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + SHIFT_MASK;// 59 ; ASCII_3C=KEY_NON_US_100;// 60 < ASCII_3D=KEY_0 + SHIFT_MASK;// 61 = ASCII_3E=KEY_NON_US_100 + SHIFT_MASK;// 62 > ASCII_3F=KEY_MINUS + SHIFT_MASK;// 63 ? ASCII_40=KEY_V + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_F + ALTGR_MASK;// 91 [ ASCII_5C=KEY_Q + ALTGR_MASK;// 92 ASCII_5D=KEY_G + ALTGR_MASK;// 93 ] ASCII_5E=CIRCUMFLEX_BITS + KEY_SPACE;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ TODO: verify ASCII_60=KEY_7 + ALTGR_MASK;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_B + ALTGR_MASK;// 123 { ASCII_7C=KEY_W + ALTGR_MASK;// 124 | ASCII_7D=KEY_N + ALTGR_MASK;// 125 } ASCII_7E=KEY_1 + ALTGR_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent Sign ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=KEY_BACKSLASH + ALTGR_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_M + ALTGR_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=DIAERESIS_BITS + KEY_SPACE;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=DEGREE_SIGN_BITS + KEY_SPACE;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ACUTE ACCENT ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=CEDILLA_BITS + KEY_SPACE;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=0;// 192 À A GRAVE ISO_8859_1_C1=ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=CIRCUMFLEX_BITS=+ KEY_A + SHIFT_MASK;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=DIAERESIS_BITS + KEY_A + SHIFT_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=CEDILLA_BITS + KEY_C + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=0;// 200 È E GRAVE ISO_8859_1_C9=ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=DIAERESIS_BITS + KEY_E + SHIFT_MASK;// 203 Ë E DIAERESIS ISO_8859_1_CC=0;// 204 Ì I GRAVE ISO_8859_1_CD=ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=DIAERESIS_BITS + KEY_I + SHIFT_MASK;// 207 Ï I DIAERESIS ISO_8859_1_D0=0;// 208 Ð ETH ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=0;// 210 Ò O GRAVE ISO_8859_1_D3=ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=DIAERESIS_BITS + KEY_O + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=KEY_RIGHT_BRACE + ALTGR_MASK;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=0;// 217 Ù U GRAVE ISO_8859_1_DA=ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=DIAERESIS_BITS + KEY_U + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=KEY_QUOTE + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=0;// 224 à a GRAVE ISO_8859_1_E1=ACUTE_ACCENT_BITS + KEY_A;// 225 á a ACUTE ISO_8859_1_E2=CIRCUMFLEX_BITS + KEY_A;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=DIAERESIS_BITS + KEY_A;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=CEDILLA_BITS + KEY_C;// 231 ç c CEDILLA ISO_8859_1_E8=0;// 232 è e GRAVE ISO_8859_1_E9=ACUTE_ACCENT_BITS + KEY_E;// 233 é e ACUTE ISO_8859_1_EA=CIRCUMFLEX_BITS + KEY_E;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=DIAERESIS_BITS + KEY_E;// 235 ë e DIAERESIS ISO_8859_1_EC=0;// 236 ì i GRAVE ISO_8859_1_ED=ACUTE_ACCENT_BITS + KEY_I;// 237 í i ACUTE ISO_8859_1_EE=CIRCUMFLEX_BITS + KEY_I;// 238 î i CIRCUMFLEX ISO_8859_1_EF=DIAERESIS_BITS + KEY_I;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=0;// 242 ò o GRAVE ISO_8859_1_F3=ACUTE_ACCENT_BITS + KEY_O;// 243 ó o ACUTE ISO_8859_1_F4=CIRCUMFLEX_BITS + KEY_O;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=DIAERESIS_BITS + KEY_O;// 246 ö o DIAERESIS ISO_8859_1_F7=KEY_LEFT_BRACE + ALTGR_MASK;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=0;// 249 ù u GRAVE ISO_8859_1_FA=ACUTE_ACCENT_BITS + KEY_U;// 250 ú u ACUTE ISO_8859_1_FB=CIRCUMFLEX_BITS + KEY_U;// 251 û u CIRCUMFLEX ISO_8859_1_FC=DIAERESIS_BITS + KEY_U;// 252 ü u DIAERESIS ISO_8859_1_FD=ACUTE_ACCENT_BITS + KEY_Z;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS UNICODE_20AC=KEY_E + ALTGR_MASK;// € Euro Sign UNICODE_EXTRA00=0x0160; // S caron KEYCODE_EXTRA00=KEY_LEFT_BRACE + SHIFT_MASK; UNICODE_EXTRA01=0x0161; // s caron KEYCODE_EXTRA01=KEY_LEFT_BRACE; UNICODE_EXTRA02=0x0110; // D with stroke KEYCODE_EXTRA02=KEY_RIGHT_BRACE + SHIFT_MASK; UNICODE_EXTRA03=0x0111; // d with stroke KEYCODE_EXTRA03=KEY_RIGHT_BRACE; UNICODE_EXTRA04=0x010C; // C with caron KEYCODE_EXTRA04=KEY_SEMICOLON + SHIFT_MASK; UNICODE_EXTRA05=0x010D; // c with caron KEYCODE_EXTRA05=KEY_SEMICOLON; UNICODE_EXTRA06=0x0106; // C with acute KEYCODE_EXTRA06=KEY_QUOTE + SHIFT_MASK; UNICODE_EXTRA07=0x0107; // c with acute KEYCODE_EXTRA07=KEY_QUOTE; UNICODE_EXTRA08=0x017D; // Z with caron KEYCODE_EXTRA08=KEY_BACKSLASH + SHIFT_MASK; UNICODE_EXTRA09=0x017E; // z with caron KEYCODE_EXTRA09=KEY_BACKSLASH; UNICODE_EXTRA10=0x0141; // L with stroke KEYCODE_EXTRA10=KEY_L + ALTGR_MASK; UNICODE_EXTRA11=0x0142; // l with stroke KEYCODE_EXTRA11=KEY_K + ALTGR_MASK; UNICODE_EXTRA12=0x010E; // D with caron KEYCODE_EXTRA12=CARON_BITS + KEY_D + SHIFT_MASK; UNICODE_EXTRA13=0x010F; // d with caron KEYCODE_EXTRA13=CARON_BITS + KEY_D; UNICODE_EXTRA14=0x011A; // E with caron KEYCODE_EXTRA14=CARON_BITS + KEY_E + SHIFT_MASK; UNICODE_EXTRA15=0x011B; // e with caron KEYCODE_EXTRA15=CARON_BITS + KEY_E; UNICODE_EXTRA16=0x013D; // L with caron KEYCODE_EXTRA16=CARON_BITS + KEY_L + SHIFT_MASK; UNICODE_EXTRA17=0x013E; // l with caron KEYCODE_EXTRA17=CARON_BITS + KEY_L; UNICODE_EXTRA18=0x0147; // N with caron KEYCODE_EXTRA18=CARON_BITS + KEY_N + SHIFT_MASK; UNICODE_EXTRA19=0x0148; // n with caron KEYCODE_EXTRA19=CARON_BITS + KEY_N; UNICODE_EXTRA20=0x0158; // R with caron KEYCODE_EXTRA20=CARON_BITS + KEY_R + SHIFT_MASK; UNICODE_EXTRA21=0x0159; // r with caron KEYCODE_EXTRA21=CARON_BITS + KEY_R; UNICODE_EXTRA22=0x0164; // T with caron KEYCODE_EXTRA22=CARON_BITS + KEY_T + SHIFT_MASK; UNICODE_EXTRA23=0x0165; // t with caron KEYCODE_EXTRA23=CARON_BITS + KEY_T; UNICODE_EXTRA24=0x0102; // A with breve KEYCODE_EXTRA24=BREVE_BITS + KEY_A + SHIFT_MASK; UNICODE_EXTRA25=0x0103; // a with breve KEYCODE_EXTRA25=BREVE_BITS + KEY_A; UNICODE_EXTRA26=0x016E; // U with ring above TODO: verify KEYCODE_EXTRA26=DEADKEY_DEGREE_SIGN + KEY_U + SHIFT_MASK; UNICODE_EXTRA27=0x016F; // u with ring above TODO: verify KEYCODE_EXTRA27=DEADKEY_DEGREE_SIGN + KEY_U; UNICODE_EXTRA28=0x0104; // A with ogonek KEYCODE_EXTRA28=OGONEK_BITS + KEY_A + SHIFT_MASK; UNICODE_EXTRA29=0x0105; // a with ogonek KEYCODE_EXTRA29=OGONEK_BITS + KEY_A; UNICODE_EXTRA30=0x0118; // E with ogonek KEYCODE_EXTRA30=OGONEK_BITS + KEY_E + SHIFT_MASK; UNICODE_EXTRA31=0x0119; // e with ogonek KEYCODE_EXTRA31=OGONEK_BITS + KEY_E; UNICODE_EXTRA32=0x017B; // Z with dot above KEYCODE_EXTRA32=DEADKEY_DOT_ABOVE + KEY_Z + SHIFT_MASK; UNICODE_EXTRA33=0x017C; // z with dot above KEYCODE_EXTRA33=DEADKEY_DOT_ABOVE + KEY_Z; UNICODE_EXTRA34=0x0139; // L with acute KEYCODE_EXTRA34=ACUTE_ACCENT_BITS + KEY_L + SHIFT_MASK; UNICODE_EXTRA35=0x013A; // l with acute KEYCODE_EXTRA35=ACUTE_ACCENT_BITS + KEY_L; UNICODE_EXTRA36=0x0143; // N with acute KEYCODE_EXTRA36=ACUTE_ACCENT_BITS + KEY_N + SHIFT_MASK; UNICODE_EXTRA37=0x0144; // n with acute KEYCODE_EXTRA37=ACUTE_ACCENT_BITS + KEY_N; UNICODE_EXTRA38=0x0154; // R with acute KEYCODE_EXTRA38=ACUTE_ACCENT_BITS + KEY_R + SHIFT_MASK; UNICODE_EXTRA39=0x0155; // r with acute KEYCODE_EXTRA39=ACUTE_ACCENT_BITS + KEY_R; UNICODE_EXTRA40=0x015A; // S with acute KEYCODE_EXTRA40=ACUTE_ACCENT_BITS + KEY_S + SHIFT_MASK; UNICODE_EXTRA41=0x015B; // s with acute KEYCODE_EXTRA41=ACUTE_ACCENT_BITS + KEY_S; UNICODE_EXTRA42=0x0179; // Z with acute KEYCODE_EXTRA42=ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK; UNICODE_EXTRA43=0x017A; // z with acute KEYCODE_EXTRA43=ACUTE_ACCENT_BITS + KEY_Z; UNICODE_EXTRA44=0x0150; // O with double acute KEYCODE_EXTRA44=DOUBLE_ACUTE_BITS + KEY_O + SHIFT_MASK; UNICODE_EXTRA45=0x0151; // o with double acute KEYCODE_EXTRA45=DOUBLE_ACUTE_BITS + KEY_O; UNICODE_EXTRA46=0x0170; // U with double acute KEYCODE_EXTRA46=DOUBLE_ACUTE_BITS + KEY_U + SHIFT_MASK; UNICODE_EXTRA47=0x0171; // u with double acute KEYCODE_EXTRA47=DOUBLE_ACUTE_BITS + KEY_U; UNICODE_EXTRA48=0x015E; // S with cedilla KEYCODE_EXTRA48=CEDILLA_BITS + KEY_S + SHIFT_MASK; UNICODE_EXTRA49=0x015F; // s with cedilla KEYCODE_EXTRA49=CEDILLA_BITS + KEY_S; UNICODE_EXTRA50=0x201A; // single low quote KEYCODE_EXTRA50=KEY_TILDE; UNICODE_EXTRA51=0x20AC; // euro sign KEYCODE_EXTRA51=KEY_E + ALTGR_MASK; // LAYOUT_SERBIAN_LATIN_ONLY } else if (KeyboardLayout[0] == LAYOUT_HUNGARIAN) { // Based on own hungarian keyboard, // modified the Czech layout, since they are similar. // Using https://www.viris.si/2013/10/implementacija-slovenske-tipkovnice-za-teensy/ // for reference. // Code masks // All of these are enabled, since they are available, // but may not be neccessary SHIFT_MASK=0x0040; ALTGR_MASK=0x0080; DEADKEYS_MASK=0x0F00; ACUTE_ACCENT_BITS=0x0100; DEGREE_SIGN_BITS=0x0200; CARON_BITS=0x0300; CIRCUMFLEX_BITS=0x0400; BREVE_BITS=0x0500; OGONEK_BITS=0x0600; GRAVE_ACCENT_BITS=0x0700; DOT_ABOVE_BITS=0x0800; DOUBLE_ACUTE_BITS=0x0900; DIAERESIS_BITS=0x0A00; CEDILLA_BITS=0x0B00; KEYCODE_MASK=0x0FFF; // Deadkeys // All of these deadkeys work with a Hungarian keyboard // on Windows, but not all do on Ubuntu DEADKEY_ACUTE_ACCENT=KEY_0 + ALTGR_MASK; DEADKEY_DEGREE_SIGN=KEY_5 + ALTGR_MASK; DEADKEY_CARON=KEY_EQUAL + SHIFT_MASK; DEADKEY_CIRCUMFLEX=KEY_3 + ALTGR_MASK; DEADKEY_BREVE=KEY_4 + ALTGR_MASK; DEADKEY_OGONEK=KEY_6 + ALTGR_MASK; DEADKEY_GRAVE_ACCENT=KEY_7 + ALTGR_MASK; DEADKEY_DOT_ABOVE=KEY_8 + ALTGR_MASK; DEADKEY_DOUBLE_ACUTE=KEY_0 + ALTGR_MASK; DEADKEY_DIAERESIS=KEY_MINUS + ALTGR_MASK; DEADKEY_CEDILLA=KEY_EQUAL + ALTGR_MASK; // Individual ASCII keys KEY_NON_US_100=63; // UNCLEAR meaning, but probably OK ASCII_20=KEY_SPACE;// 32 ASCII_21=KEY_4 + SHIFT_MASK;// 33 ! ASCII_22=KEY_2 + SHIFT_MASK;// 34 " ASCII_23=KEY_X + ALTGR_MASK;// 35 # ASCII_24=KEY_SEMICOLON + ALTGR_MASK;// 36 $ ASCII_25=KEY_5 + SHIFT_MASK;// 37 % ASCII_26=KEY_C + ALTGR_MASK;// 38 & ASCII_27=KEY_1 + SHIFT_MASK;// 39 ' ASCII_28=KEY_8 + SHIFT_MASK;// 40 ( ASCII_29=KEY_9 + SHIFT_MASK;// 41 ) ASCII_2A=KEY_SLASH + ALTGR_MASK;// 42 * ASCII_2B=KEY_3 + SHIFT_MASK;// 43 + ASCII_2C=KEY_COMMA;// 44 , ASCII_2D=KEY_SLASH;// 45 - ASCII_2E=KEY_PERIOD;// 46 . ASCII_2F=KEY_6 + SHIFT_MASK;// 47 / ASCII_30=KEY_TILDE;// 48 0 ASCII_31=KEY_1;// 49 1 ASCII_32=KEY_2;// 50 2 ASCII_33=KEY_3;// 51 3 ASCII_34=KEY_4;// 52 4 ASCII_35=KEY_5;// 53 5 ASCII_36=KEY_6;// 54 6 ASCII_37=KEY_7;// 55 7 ASCII_38=KEY_8;// 55 8 ASCII_39=KEY_9;// 57 9 ASCII_3A=KEY_PERIOD + SHIFT_MASK;// 58 : ASCII_3B=KEY_COMMA + ALTGR_MASK;// 59 ; ASCII_3C=KEY_NON_US_100 + ALTGR_MASK;// 60 ASCII_3D=KEY_7 + SHIFT_MASK;// 61 = ASCII_3E=KEY_Z + ALTGR_MASK;// 62 > ASCII_3F=KEY_COMMA + SHIFT_MASK;// 63 ? ASCII_40=KEY_V + ALTGR_MASK;// 64 @ ASCII_41=KEY_A + SHIFT_MASK;// 65 A ASCII_42=KEY_B + SHIFT_MASK;// 66 B ASCII_43=KEY_C + SHIFT_MASK;// 67 C ASCII_44=KEY_D + SHIFT_MASK;// 68 D ASCII_45=KEY_E + SHIFT_MASK;// 69 E ASCII_46=KEY_F + SHIFT_MASK;// 70 F ASCII_47=KEY_G + SHIFT_MASK;// 71 G ASCII_48=KEY_H + SHIFT_MASK;// 72 H ASCII_49=KEY_I + SHIFT_MASK;// 73 I ASCII_4A=KEY_J + SHIFT_MASK;// 74 J ASCII_4B=KEY_K + SHIFT_MASK;// 75 K ASCII_4C=KEY_L + SHIFT_MASK;// 76 L ASCII_4D=KEY_M + SHIFT_MASK;// 77 M ASCII_4E=KEY_N + SHIFT_MASK;// 78 N ASCII_4F=KEY_O + SHIFT_MASK;// 79 O ASCII_50=KEY_P + SHIFT_MASK;// 80 P ASCII_51=KEY_Q + SHIFT_MASK;// 81 Q ASCII_52=KEY_R + SHIFT_MASK;// 82 R ASCII_53=KEY_S + SHIFT_MASK;// 83 S ASCII_54=KEY_T + SHIFT_MASK;// 84 T ASCII_55=KEY_U + SHIFT_MASK;// 85 U ASCII_56=KEY_V + SHIFT_MASK;// 86 V ASCII_57=KEY_W + SHIFT_MASK;// 87 W ASCII_58=KEY_X + SHIFT_MASK;// 88 X ASCII_59=KEY_Z + SHIFT_MASK;// 89 Y ASCII_5A=KEY_Y + SHIFT_MASK;// 90 Z ASCII_5B=KEY_F + ALTGR_MASK;// 91 [ ASCII_5C=KEY_Q + ALTGR_MASK;// 92 backslash ASCII_5D=KEY_G + ALTGR_MASK;// 93 ] ASCII_5E=KEY_3 + ALTGR_MASK;// 94 ^ ASCII_5F=KEY_SLASH + SHIFT_MASK;// 95 _ ASCII_60=KEY_7 + ALTGR_MASK;// 96 ` ASCII_61=KEY_A;// 97 a ASCII_62=KEY_B;// 98 b ASCII_63=KEY_C;// 99 c ASCII_64=KEY_D;// 100 d ASCII_65=KEY_E;// 101 e ASCII_66=KEY_F;// 102 f ASCII_67=KEY_G;// 103 g ASCII_68=KEY_H;// 104 h ASCII_69=KEY_I;// 105 i ASCII_6A=KEY_J;// 106 j ASCII_6B=KEY_K;// 107 k ASCII_6C=KEY_L;// 108 l ASCII_6D=KEY_M;// 109 m ASCII_6E=KEY_N;// 110 n ASCII_6F=KEY_O;// 111 o ASCII_70=KEY_P;// 112 p ASCII_71=KEY_Q;// 113 q ASCII_72=KEY_R;// 114 r ASCII_73=KEY_S;// 115 s ASCII_74=KEY_T;// 116 t ASCII_75=KEY_U;// 117 u ASCII_76=KEY_V;// 118 v ASCII_77=KEY_W;// 119 w ASCII_78=KEY_X;// 120 x ASCII_79=KEY_Z;// 121 y ASCII_7A=KEY_Y;// 122 z ASCII_7B=KEY_B + ALTGR_MASK;// 123 { ASCII_7C=KEY_W + ALTGR_MASK;// 124 | ASCII_7D=KEY_N + ALTGR_MASK;// 125 } ASCII_7E=KEY_1 + ALTGR_MASK;// 126 ~ ASCII_7F=KEY_BACKSPACE;// 127 // Individual ISO 8859-1 keys ISO_8859_1_A0=KEY_SPACE;// 160 Nonbreakng Space ISO_8859_1_A1=0;// 161 ¡ Inverted Exclamation ISO_8859_1_A2=0;// 162 ¢ Cent Sign ISO_8859_1_A3=0;// 163 £ Pound Sign ISO_8859_1_A4=KEY_BACKSLASH + ALTGR_MASK;// 164 ¤ Currency Sign ISO_8859_1_A5=0;// 165 ¥ YEN SIGN ISO_8859_1_A6=0;// 166 ¦ BROKEN BAR ISO_8859_1_A7=KEY_TILDE + SHIFT_MASK;// 167 § SECTION SIGN ISO_8859_1_A8=0;// 168 ¨ DIAERESIS ISO_8859_1_A9=0;// 169 © COPYRIGHT SIGN ISO_8859_1_AA=0;// 170 ª FEMININE ORDINAL ISO_8859_1_AB=0;// 171 « LEFT DOUBLE ANGLE QUOTE ISO_8859_1_AC=0;// 172 ¬ NOT SIGN ISO_8859_1_AD=0;// 173 SOFT HYPHEN ISO_8859_1_AE=0;// 174 ® REGISTERED SIGN ISO_8859_1_AF=0;// 175 ¯ MACRON ISO_8859_1_B0=DEGREE_SIGN_BITS + KEY_SPACE;// 176 ° DEGREE SIGN ISO_8859_1_B1=0;// 177 ± PLUS-MINUS SIGN ISO_8859_1_B2=0;// 178 ² SUPERSCRIPT TWO ISO_8859_1_B3=0;// 179 ³ SUPERSCRIPT THREE ISO_8859_1_B4=ACUTE_ACCENT_BITS + KEY_SPACE;// 180 ´ ISO_8859_1_B5=0;// 181 µ MICRO SIGN ISO_8859_1_B6=0;// 182 ¶ PILCROW SIGN ISO_8859_1_B7=0;// 183 · MIDDLE DOT ISO_8859_1_B8=CEDILLA_BITS + KEY_SPACE;// 184 ¸ CEDILLA ISO_8859_1_B9=0;// 185 ¹ SUPERSCRIPT ONE ISO_8859_1_BA=0;// 186 º MASCULINE ORDINAL ISO_8859_1_BB=0;// 187 » RIGHT DOUBLE ANGLE QUOTE ISO_8859_1_BC=0;// 188 ¼ FRACTION ONE QUARTER ISO_8859_1_BD=0;// 189 ½ FRACTION ONE HALF ISO_8859_1_BE=0;// 190 ¾ FRACTION THREE QUARTERS ISO_8859_1_BF=0;// 191 ¿ INVERTED QUESTION MARK ISO_8859_1_C0=0;// 192 À A GRAVE ISO_8859_1_C1=KEY_QUOTE + SHIFT_MASK;// 193 Á A ACUTE ISO_8859_1_C2=0;// 194 Â A CIRCUMFLEX ISO_8859_1_C3=0;// 195 Ã A TILDE ISO_8859_1_C4=KEY_E + ALTGR_MASK;// 196 Ä A DIAERESIS ISO_8859_1_C5=0;// 197 Å A RING ABOVE ISO_8859_1_C6=0;// 198 Æ AE ISO_8859_1_C7=CEDILLA_BITS + KEY_C + SHIFT_MASK;// 199 Ç C CEDILLA ISO_8859_1_C8=0;// 200 È E GRAVE ISO_8859_1_C9=KEY_SEMICOLON + SHIFT_MASK;// 201 É E ACUTE ISO_8859_1_CA=0;// 202 Ê E CIRCUMFLEX ISO_8859_1_CB=0;// 203 Ë E DIAERESIS ISO_8859_1_CC=0;// 204 Ì I GRAVE ISO_8859_1_CD=KEY_NON_US_100 + SHIFT_MASK;// 205 Í I ACUTE ISO_8859_1_CE=0;// 206 Î I CIRCUMFLEX ISO_8859_1_CF=0;// 207 Ï I DIAERESIS ISO_8859_1_D0=KEY_D + ALTGR_MASK;// 208 Ð ETH // for some reason this does not work, just like the unicode characters ISO_8859_1_D1=0;// 209 Ñ N TILDE ISO_8859_1_D2=0;// 210 Ò O GRAVE ISO_8859_1_D3=KEY_EQUAL + SHIFT_MASK;// 211 Ó O ACUTE ISO_8859_1_D4=0;// 212 Ô O CIRCUMFLEX ISO_8859_1_D5=0;// 213 Õ O TILDE ISO_8859_1_D6=KEY_0 + SHIFT_MASK;// 214 Ö O DIAERESIS ISO_8859_1_D7=KEY_RIGHT_BRACE + ALTGR_MASK;// 215 × MULTIPLICATION ISO_8859_1_D8=0;// 216 Ø O STROKE ISO_8859_1_D9=0;// 217 Ù U GRAVE ISO_8859_1_DA=KEY_RIGHT_BRACE + SHIFT_MASK;// 218 Ú U ACUTE ISO_8859_1_DB=0;// 219 Û U CIRCUMFLEX ISO_8859_1_DC=KEY_MINUS + SHIFT_MASK;// 220 Ü U DIAERESIS ISO_8859_1_DD=0;// 221 Ý Y ACUTE ISO_8859_1_DE=0;// 222 Þ THORN ISO_8859_1_DF=KEY_QUOTE + ALTGR_MASK;// 223 ß SHARP S ISO_8859_1_E0=0;// 224 à a GRAVE ISO_8859_1_E1=KEY_QUOTE;// 225 á a ACUTE ISO_8859_1_E2=0;// 226 â a CIRCUMFLEX ISO_8859_1_E3=0;// 227 ã a TILDE ISO_8859_1_E4=KEY_A + ALTGR_MASK;// 228 ä a DIAERESIS ISO_8859_1_E5=0;// 229 å a RING ABOVE ISO_8859_1_E6=0;// 230 æ ae ISO_8859_1_E7=CEDILLA_BITS + KEY_C;// 231 ç c CEDILLA ISO_8859_1_E8=0;// 232 è e GRAVE ISO_8859_1_E9=KEY_SEMICOLON;// 233 é e ACUTE ISO_8859_1_EA=0;// 234 ê e CIRCUMFLEX ISO_8859_1_EB=0;// 235 ë e DIAERESIS ISO_8859_1_EC=0;// 236 ì i GRAVE ISO_8859_1_ED=KEY_NON_US_100;// 237 í i ACUTE ISO_8859_1_EE=0;// 238 î i CIRCUMFLEX ISO_8859_1_EF=0;// 239 ï i DIAERESIS ISO_8859_1_F0=0;// 240 ð ETH ISO_8859_1_F1=0;// 241 ñ n TILDE ISO_8859_1_F2=0;// 242 ò o GRAVE ISO_8859_1_F3=KEY_EQUAL;// 243 ó o ACUTE ISO_8859_1_F4=0;// 244 ô o CIRCUMFLEX ISO_8859_1_F5=0;// 245 õ o TILDE ISO_8859_1_F6=KEY_0;// 246 ö o DIAERESIS ISO_8859_1_F7=KEY_LEFT_BRACE + ALTGR_MASK;// 247 ÷ DIVISION ISO_8859_1_F8=0;// 248 ø o STROKE ISO_8859_1_F9=0;// 249 ù u GRAVE ISO_8859_1_FA=KEY_RIGHT_BRACE;// 250 ú u ACUTE ISO_8859_1_FB=0;// 251 û u CIRCUMFLEX ISO_8859_1_FC=KEY_MINUS;// 252 ü u DIAERESIS ISO_8859_1_FD=0;// 253 ý y ACUTE ISO_8859_1_FE=0;// 254 þ THORN ISO_8859_1_FF=0;// 255 ÿ y DIAERESIS //unimplemented? UNICODE_EXTRA00=0x0151;// ő Small letter o, double acute KEYCODE_EXTRA00=KEY_LEFT_BRACE; UNICODE_EXTRA01=0x0150;// Ő Capital letter O, double acute KEYCODE_EXTRA01=KEY_LEFT_BRACE + SHIFT_MASK; UNICODE_EXTRA02=0x0171;// ű Small letter u, double acute KEYCODE_EXTRA02=KEY_BACKSLASH; UNICODE_EXTRA03=0x0170;// Ű Small letter u, double acute KEYCODE_EXTRA03=KEY_BACKSLASH + SHIFT_MASK; UNICODE_EXTRA04=0x0111;// đ Small letter D with stroke KEYCODE_EXTRA04=KEY_D + ALTGR_MASK; UNICODE_EXTRA05=0x0110;// Đ Capital letter D with stroke KEYCODE_EXTRA05=KEY_S + ALTGR_MASK; UNICODE_EXTRA06=0x0142;// ł Small letter L with stroke KEYCODE_EXTRA06=KEY_K + ALTGR_MASK; UNICODE_EXTRA07=0x0141;// Ł Capital Letter L with stroke KEYCODE_EXTRA07=KEY_L + ALTGR_MASK; UNICODE_EXTRA08=0x20AC;// € Euro Sign KEYCODE_EXTRA08=KEY_U + ALTGR_MASK; // LAYOUT_HUNGARIAN } keycodes_ascii[0] = M(ASCII_20); keycodes_ascii[1] = M(ASCII_21); keycodes_ascii[2] = M(ASCII_22); keycodes_ascii[3] = M(ASCII_23); keycodes_ascii[4] = M(ASCII_24); keycodes_ascii[5] = M(ASCII_25); keycodes_ascii[6] = M(ASCII_26); keycodes_ascii[7] = M(ASCII_27); keycodes_ascii[8] = M(ASCII_28); keycodes_ascii[9] = M(ASCII_29); keycodes_ascii[10] = M(ASCII_2A); keycodes_ascii[11] = M(ASCII_2B); keycodes_ascii[12] = M(ASCII_2C); keycodes_ascii[13] = M(ASCII_2D); keycodes_ascii[14] = M(ASCII_2E); keycodes_ascii[15] = M(ASCII_2F); keycodes_ascii[16] = M(ASCII_30); keycodes_ascii[17] = M(ASCII_31); keycodes_ascii[18] = M(ASCII_32); keycodes_ascii[19] = M(ASCII_33); keycodes_ascii[20] = M(ASCII_34); keycodes_ascii[21] = M(ASCII_35); keycodes_ascii[22] = M(ASCII_36); keycodes_ascii[23] = M(ASCII_37); keycodes_ascii[24] = M(ASCII_38); keycodes_ascii[25] = M(ASCII_39); keycodes_ascii[26] = M(ASCII_3A); keycodes_ascii[27] = M(ASCII_3B); keycodes_ascii[28] = M(ASCII_3C); keycodes_ascii[29] = M(ASCII_3D); keycodes_ascii[30] = M(ASCII_3E); keycodes_ascii[31] = M(ASCII_3F); keycodes_ascii[32] = M(ASCII_40); keycodes_ascii[33] = M(ASCII_41); keycodes_ascii[34] = M(ASCII_42); keycodes_ascii[35] = M(ASCII_43); keycodes_ascii[36] = M(ASCII_44); keycodes_ascii[37] = M(ASCII_45); keycodes_ascii[38] = M(ASCII_46); keycodes_ascii[39] = M(ASCII_47); keycodes_ascii[40] = M(ASCII_48); keycodes_ascii[41] = M(ASCII_49); keycodes_ascii[42] = M(ASCII_4A); keycodes_ascii[43] = M(ASCII_4B); keycodes_ascii[44] = M(ASCII_4C); keycodes_ascii[45] = M(ASCII_4D); keycodes_ascii[46] = M(ASCII_4E); keycodes_ascii[47] = M(ASCII_4F); keycodes_ascii[48] = M(ASCII_50); keycodes_ascii[49] = M(ASCII_51); keycodes_ascii[50] = M(ASCII_52); keycodes_ascii[51] = M(ASCII_53); keycodes_ascii[52] = M(ASCII_54); keycodes_ascii[53] = M(ASCII_55); keycodes_ascii[54] = M(ASCII_56); keycodes_ascii[55] = M(ASCII_57); keycodes_ascii[56] = M(ASCII_58); keycodes_ascii[57] = M(ASCII_59); keycodes_ascii[58] = M(ASCII_5A); keycodes_ascii[59] = M(ASCII_5B); keycodes_ascii[60] = M(ASCII_5C); keycodes_ascii[61] = M(ASCII_5D); keycodes_ascii[62] = M(ASCII_5E); keycodes_ascii[63] = M(ASCII_5F); keycodes_ascii[64] = M(ASCII_60); keycodes_ascii[65] = M(ASCII_61); keycodes_ascii[66] = M(ASCII_62); keycodes_ascii[67] = M(ASCII_63); keycodes_ascii[68] = M(ASCII_64); keycodes_ascii[69] = M(ASCII_65); keycodes_ascii[70] = M(ASCII_66); keycodes_ascii[71] = M(ASCII_67); keycodes_ascii[72] = M(ASCII_68); keycodes_ascii[73] = M(ASCII_69); keycodes_ascii[74] = M(ASCII_6A); keycodes_ascii[75] = M(ASCII_6B); keycodes_ascii[76] = M(ASCII_6C); keycodes_ascii[77] = M(ASCII_6D); keycodes_ascii[78] = M(ASCII_6E); keycodes_ascii[79] = M(ASCII_6F); keycodes_ascii[80] = M(ASCII_70); keycodes_ascii[81] = M(ASCII_71); keycodes_ascii[82] = M(ASCII_72); keycodes_ascii[83] = M(ASCII_73); keycodes_ascii[84] = M(ASCII_74); keycodes_ascii[85] = M(ASCII_75); keycodes_ascii[86] = M(ASCII_76); keycodes_ascii[87] = M(ASCII_77); keycodes_ascii[88] = M(ASCII_78); keycodes_ascii[89] = M(ASCII_79); keycodes_ascii[90] = M(ASCII_7A); keycodes_ascii[91] = M(ASCII_7B); keycodes_ascii[92] = M(ASCII_7C); keycodes_ascii[93] = M(ASCII_7D); keycodes_ascii[94] = M(ASCII_7E); keycodes_ascii[95] = M(ASCII_7F); keycodes_iso_8859_1[0] = M(ISO_8859_1_A0); keycodes_iso_8859_1[1] = M(ISO_8859_1_A1); keycodes_iso_8859_1[2] = M(ISO_8859_1_A2); keycodes_iso_8859_1[3] = M(ISO_8859_1_A3); keycodes_iso_8859_1[4] = M(ISO_8859_1_A4); keycodes_iso_8859_1[5] = M(ISO_8859_1_A5); keycodes_iso_8859_1[6] = M(ISO_8859_1_A6); keycodes_iso_8859_1[7] = M(ISO_8859_1_A7); keycodes_iso_8859_1[8] = M(ISO_8859_1_A8); keycodes_iso_8859_1[9] = M(ISO_8859_1_A9); keycodes_iso_8859_1[10] = M(ISO_8859_1_AA); keycodes_iso_8859_1[11] = M(ISO_8859_1_AB); keycodes_iso_8859_1[12] = M(ISO_8859_1_AC); keycodes_iso_8859_1[13] = M(ISO_8859_1_AD); keycodes_iso_8859_1[14] = M(ISO_8859_1_AE); keycodes_iso_8859_1[15] = M(ISO_8859_1_AF); keycodes_iso_8859_1[16] = M(ISO_8859_1_B0); keycodes_iso_8859_1[17] = M(ISO_8859_1_B1); keycodes_iso_8859_1[18] = M(ISO_8859_1_B2); keycodes_iso_8859_1[19] = M(ISO_8859_1_B3); keycodes_iso_8859_1[20] = M(ISO_8859_1_B4); keycodes_iso_8859_1[21] = M(ISO_8859_1_B5); keycodes_iso_8859_1[22] = M(ISO_8859_1_B6); keycodes_iso_8859_1[23] = M(ISO_8859_1_B7); keycodes_iso_8859_1[24] = M(ISO_8859_1_B8); keycodes_iso_8859_1[25] = M(ISO_8859_1_B9); keycodes_iso_8859_1[26] = M(ISO_8859_1_BA); keycodes_iso_8859_1[27] = M(ISO_8859_1_BB); keycodes_iso_8859_1[28] = M(ISO_8859_1_BC); keycodes_iso_8859_1[29] = M(ISO_8859_1_BD); keycodes_iso_8859_1[30] = M(ISO_8859_1_BE); keycodes_iso_8859_1[31] = M(ISO_8859_1_BF); keycodes_iso_8859_1[32] = M(ISO_8859_1_C0); keycodes_iso_8859_1[33] = M(ISO_8859_1_C1); keycodes_iso_8859_1[34] = M(ISO_8859_1_C2); keycodes_iso_8859_1[35] = M(ISO_8859_1_C3); keycodes_iso_8859_1[36] = M(ISO_8859_1_C4); keycodes_iso_8859_1[37] = M(ISO_8859_1_C5); keycodes_iso_8859_1[38] = M(ISO_8859_1_C6); keycodes_iso_8859_1[39] = M(ISO_8859_1_C7); keycodes_iso_8859_1[40] = M(ISO_8859_1_C8); keycodes_iso_8859_1[41] = M(ISO_8859_1_C9); keycodes_iso_8859_1[42] = M(ISO_8859_1_CA); keycodes_iso_8859_1[43] = M(ISO_8859_1_CB); keycodes_iso_8859_1[44] = M(ISO_8859_1_CC); keycodes_iso_8859_1[45] = M(ISO_8859_1_CD); keycodes_iso_8859_1[46] = M(ISO_8859_1_CE); keycodes_iso_8859_1[47] = M(ISO_8859_1_CF); keycodes_iso_8859_1[48] = M(ISO_8859_1_D0); keycodes_iso_8859_1[49] = M(ISO_8859_1_D1); keycodes_iso_8859_1[50] = M(ISO_8859_1_D2); keycodes_iso_8859_1[51] = M(ISO_8859_1_D3); keycodes_iso_8859_1[52] = M(ISO_8859_1_D4); keycodes_iso_8859_1[53] = M(ISO_8859_1_D5); keycodes_iso_8859_1[54] = M(ISO_8859_1_D6); keycodes_iso_8859_1[55] = M(ISO_8859_1_D7); keycodes_iso_8859_1[56] = M(ISO_8859_1_D8); keycodes_iso_8859_1[57] = M(ISO_8859_1_D9); keycodes_iso_8859_1[58] = M(ISO_8859_1_DA); keycodes_iso_8859_1[59] = M(ISO_8859_1_DB); keycodes_iso_8859_1[60] = M(ISO_8859_1_DC); keycodes_iso_8859_1[61] = M(ISO_8859_1_DD); keycodes_iso_8859_1[62] = M(ISO_8859_1_DE); keycodes_iso_8859_1[63] = M(ISO_8859_1_DF); keycodes_iso_8859_1[64] = M(ISO_8859_1_E0); keycodes_iso_8859_1[65] = M(ISO_8859_1_E1); keycodes_iso_8859_1[66] = M(ISO_8859_1_E2); keycodes_iso_8859_1[67] = M(ISO_8859_1_E3); keycodes_iso_8859_1[68] = M(ISO_8859_1_E4); keycodes_iso_8859_1[69] = M(ISO_8859_1_E5); keycodes_iso_8859_1[70] = M(ISO_8859_1_E6); keycodes_iso_8859_1[71] = M(ISO_8859_1_E7); keycodes_iso_8859_1[72] = M(ISO_8859_1_E8); keycodes_iso_8859_1[73] = M(ISO_8859_1_E9); keycodes_iso_8859_1[74] = M(ISO_8859_1_EA); keycodes_iso_8859_1[75] = M(ISO_8859_1_EB); keycodes_iso_8859_1[76] = M(ISO_8859_1_EC); keycodes_iso_8859_1[77] = M(ISO_8859_1_ED); keycodes_iso_8859_1[78] = M(ISO_8859_1_EE); keycodes_iso_8859_1[79] = M(ISO_8859_1_EF); keycodes_iso_8859_1[80] = M(ISO_8859_1_F0); keycodes_iso_8859_1[81] = M(ISO_8859_1_F1); keycodes_iso_8859_1[82] = M(ISO_8859_1_F2); keycodes_iso_8859_1[83] = M(ISO_8859_1_F3); keycodes_iso_8859_1[84] = M(ISO_8859_1_F4); keycodes_iso_8859_1[85] = M(ISO_8859_1_F5); keycodes_iso_8859_1[86] = M(ISO_8859_1_F6); keycodes_iso_8859_1[87] = M(ISO_8859_1_F7); keycodes_iso_8859_1[88] = M(ISO_8859_1_F8); keycodes_iso_8859_1[89] = M(ISO_8859_1_F9); keycodes_iso_8859_1[90] = M(ISO_8859_1_FA); keycodes_iso_8859_1[91] = M(ISO_8859_1_FB); keycodes_iso_8859_1[92] = M(ISO_8859_1_FC); keycodes_iso_8859_1[93] = M(ISO_8859_1_FD); keycodes_iso_8859_1[94] = M(ISO_8859_1_FE); keycodes_iso_8859_1[95] = M(ISO_8859_1_FF); } ================================================ FILE: keylayouts.h ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef KEYLAYOUTS_H__ #define KEYLAYOUTS_H__ #include #include #ifdef __cplusplus extern "C"{ #endif #define LAYOUT_USA_ENGLISH 0x01 #define LAYOUT_CANADIAN_FRENCH 0x02 #define LAYOUT_CANADIAN_MULTILINGUAL 0x03 #define LAYOUT_DANISH 0x04 #define LAYOUT_FINNISH 0x05 #define LAYOUT_FRENCH 0x06 #define LAYOUT_FRENCH_BELGIAN 0x07 #define LAYOUT_FRENCH_SWISS 0x08 #define LAYOUT_GERMAN 0x09 #define LAYOUT_GERMAN_MAC 0x0A #define LAYOUT_GERMAN_SWISS 0x0B #define LAYOUT_ICELANDIC 0x0C #define LAYOUT_IRISH 0x0D #define LAYOUT_ITALIAN 0x0E #define LAYOUT_NORWEGIAN 0x0F #define LAYOUT_PORTUGUESE 0x10 #define LAYOUT_PORTUGUESE_BRAZILIAN 0x11 #define LAYOUT_SPANISH 0x12 #define LAYOUT_SPANISH_LATIN_AMERICA 0x13 #define LAYOUT_SWEDISH 0x14 #define LAYOUT_TURKISH 0x15 #define LAYOUT_UNITED_KINGDOM 0x16 #define LAYOUT_US_INTERNATIONAL 0x17 #define LAYOUT_CZECH 0x18 #define LAYOUT_SERBIAN_LATIN_ONLY 0x19 #define LAYOUT_HUNGARIAN 0x1A #define LAYOUT_DANISH_MAC 0x1B #define LAYOUT_DVORAK 0x1C // http://en.wikipedia.org/wiki/Keyboard_layout #define MODIFIERKEY_CTRL ( 0x01 | 0xE000 ) #define MODIFIERKEY_SHIFT ( 0x02 | 0xE000 ) #define MODIFIERKEY_ALT ( 0x04 | 0xE000 ) #define MODIFIERKEY_GUI ( 0x08 | 0xE000 ) #define MODIFIERKEY_LEFT_CTRL ( 0x01 | 0xE000 ) #define MODIFIERKEY_LEFT_SHIFT ( 0x02 | 0xE000 ) #define MODIFIERKEY_LEFT_ALT ( 0x04 | 0xE000 ) #define MODIFIERKEY_LEFT_GUI ( 0x08 | 0xE000 ) #define MODIFIERKEY_RIGHT_CTRL ( 0x10 | 0xE000 ) #define MODIFIERKEY_RIGHT_SHIFT ( 0x20 | 0xE000 ) #define MODIFIERKEY_RIGHT_ALT ( 0x40 | 0xE000 ) #define MODIFIERKEY_RIGHT_GUI ( 0x80 | 0xE000 ) #define KEY_SYSTEM_POWER_DOWN ( 0x81 | 0xE200 ) #define KEY_SYSTEM_SLEEP ( 0x82 | 0xE200 ) #define KEY_SYSTEM_WAKE_UP ( 0x83 | 0xE200 ) #define KEY_MEDIA_EJECT 0x80 #define KEY_MEDIA_VOLUME_INC 0x01 #define KEY_A ( 4 | 0xF000 ) #define KEY_B ( 5 | 0xF000 ) #define KEY_C ( 6 | 0xF000 ) #define KEY_D ( 7 | 0xF000 ) #define KEY_E ( 8 | 0xF000 ) #define KEY_F ( 9 | 0xF000 ) #define KEY_G ( 10 | 0xF000 ) #define KEY_H ( 11 | 0xF000 ) #define KEY_I ( 12 | 0xF000 ) #define KEY_J ( 13 | 0xF000 ) #define KEY_K ( 14 | 0xF000 ) #define KEY_L ( 15 | 0xF000 ) #define KEY_M ( 16 | 0xF000 ) #define KEY_N ( 17 | 0xF000 ) #define KEY_O ( 18 | 0xF000 ) #define KEY_P ( 19 | 0xF000 ) #define KEY_Q ( 20 | 0xF000 ) #define KEY_R ( 21 | 0xF000 ) #define KEY_S ( 22 | 0xF000 ) #define KEY_T ( 23 | 0xF000 ) #define KEY_U ( 24 | 0xF000 ) #define KEY_V ( 25 | 0xF000 ) #define KEY_W ( 26 | 0xF000 ) #define KEY_X ( 27 | 0xF000 ) #define KEY_Y ( 28 | 0xF000 ) #define KEY_Z ( 29 | 0xF000 ) #define KEY_1 ( 30 | 0xF000 ) #define KEY_2 ( 31 | 0xF000 ) #define KEY_3 ( 32 | 0xF000 ) #define KEY_4 ( 33 | 0xF000 ) #define KEY_5 ( 34 | 0xF000 ) #define KEY_6 ( 35 | 0xF000 ) #define KEY_7 ( 36 | 0xF000 ) #define KEY_8 ( 37 | 0xF000 ) #define KEY_9 ( 38 | 0xF000 ) #define KEY_0 ( 39 | 0xF000 ) #define KEY_ENTER ( 40 | 0xF000 ) #define KEY_ESC ( 41 | 0xF000 ) #define KEY_BACKSPACE ( 42 | 0xF000 ) #define KEY_TAB ( 43 | 0xF000 ) #define KEY_SPACE ( 44 | 0xF000 ) #define KEY_MINUS ( 45 | 0xF000 ) #define KEY_EQUAL ( 46 | 0xF000 ) #define KEY_LEFT_BRACE ( 47 | 0xF000 ) #define KEY_RIGHT_BRACE ( 48 | 0xF000 ) #define KEY_BACKSLASH ( 49 | 0xF000 ) #define KEY_NON_US_NUM ( 50 | 0xF000 ) #define KEY_SEMICOLON ( 51 | 0xF000 ) #define KEY_QUOTE ( 52 | 0xF000 ) #define KEY_TILDE ( 53 | 0xF000 ) #define KEY_COMMA ( 54 | 0xF000 ) #define KEY_PERIOD ( 55 | 0xF000 ) #define KEY_SLASH ( 56 | 0xF000 ) #define KEY_CAPS_LOCK ( 57 | 0xF000 ) #define KEY_F1 ( 58 | 0xF000 ) #define KEY_F2 ( 59 | 0xF000 ) #define KEY_F3 ( 60 | 0xF000 ) #define KEY_F4 ( 61 | 0xF000 ) #define KEY_F5 ( 62 | 0xF000 ) #define KEY_F6 ( 63 | 0xF000 ) #define KEY_F7 ( 64 | 0xF000 ) #define KEY_F8 ( 65 | 0xF000 ) #define KEY_F9 ( 66 | 0xF000 ) #define KEY_F10 ( 67 | 0xF000 ) #define KEY_F11 ( 68 | 0xF000 ) #define KEY_F12 ( 69 | 0xF000 ) #define KEY_PRINTSCREEN ( 70 | 0xF000 ) #define KEY_SCROLL_LOCK ( 71 | 0xF000 ) #define KEY_PAUSE ( 72 | 0xF000 ) #define KEY_INSERT ( 73 | 0xF000 ) #define KEY_HOME ( 74 | 0xF000 ) #define KEY_PAGE_UP ( 75 | 0xF000 ) #define KEY_DELETE ( 76 | 0xF000 ) #define KEY_END ( 77 | 0xF000 ) #define KEY_PAGE_DOWN ( 78 | 0xF000 ) #define KEY_RIGHT ( 79 | 0xF000 ) #define KEY_LEFT ( 80 | 0xF000 ) #define KEY_DOWN ( 81 | 0xF000 ) #define KEY_UP ( 82 | 0xF000 ) #define KEY_NUM_LOCK ( 83 | 0xF000 ) #define KEYPAD_SLASH ( 84 | 0xF000 ) #define KEYPAD_ASTERIX ( 85 | 0xF000 ) #define KEYPAD_MINUS ( 86 | 0xF000 ) #define KEYPAD_PLUS ( 87 | 0xF000 ) #define KEYPAD_ENTER ( 88 | 0xF000 ) #define KEYPAD_1 ( 89 | 0xF000 ) #define KEYPAD_2 ( 90 | 0xF000 ) #define KEYPAD_3 ( 91 | 0xF000 ) #define KEYPAD_4 ( 92 | 0xF000 ) #define KEYPAD_5 ( 93 | 0xF000 ) #define KEYPAD_6 ( 94 | 0xF000 ) #define KEYPAD_7 ( 95 | 0xF000 ) #define KEYPAD_8 ( 96 | 0xF000 ) #define KEYPAD_9 ( 97 | 0xF000 ) #define KEYPAD_0 ( 98 | 0xF000 ) #define KEYPAD_PERIOD ( 99 | 0xF000 ) #define KEY_NON_US_BS ( 100 | 0xF000 ) #define KEY_MENU ( 101 | 0xF000 ) #define KEY_F13 ( 104 | 0xF000 ) #define KEY_F14 ( 105 | 0xF000 ) #define KEY_F15 ( 106 | 0xF000 ) #define KEY_F16 ( 107 | 0xF000 ) #define KEY_F17 ( 108 | 0xF000 ) #define KEY_F18 ( 109 | 0xF000 ) #define KEY_F19 ( 110 | 0xF000 ) #define KEY_F20 ( 111 | 0xF000 ) #define KEY_F21 ( 112 | 0xF000 ) #define KEY_F22 ( 113 | 0xF000 ) #define KEY_F23 ( 114 | 0xF000 ) #define KEY_F24 ( 115 | 0xF000 ) // for compatibility with Leonardo's slightly different names #define KEY_UP_ARROW KEY_UP #define KEY_DOWN_ARROW KEY_DOWN #define KEY_LEFT_ARROW KEY_LEFT #define KEY_RIGHT_ARROW KEY_RIGHT #define KEY_RETURN KEY_ENTER #define KEY_LEFT_CTRL MODIFIERKEY_LEFT_CTRL #define KEY_LEFT_SHIFT MODIFIERKEY_LEFT_SHIFT #define KEY_LEFT_ALT MODIFIERKEY_LEFT_ALT #define KEY_LEFT_GUI MODIFIERKEY_LEFT_GUI #define KEY_RIGHT_CTRL MODIFIERKEY_RIGHT_CTRL #define KEY_RIGHT_SHIFT MODIFIERKEY_RIGHT_SHIFT #define KEY_RIGHT_ALT MODIFIERKEY_RIGHT_ALT #define KEY_RIGHT_GUI MODIFIERKEY_RIGHT_GUI #define KEYCODE_TYPE uint16_t extern void update_keyboard_layout(); extern KEYCODE_TYPE keycodes_ascii[]; extern KEYCODE_TYPE keycodes_iso_8859_1[]; #ifdef __cplusplus } // extern "C" #endif #endif ================================================ FILE: usb_desc.c ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #if F_CPU >= 20000000 #define USB_DESC_LIST_DEFINE #include "usb_desc.h" #ifdef NUM_ENDPOINTS #include "usb_names.h" #include "kinetis.h" #include "avr_functions.h" // USB Descriptors are binary data which the USB host reads to // automatically detect a USB device's capabilities. The format // and meaning of every field is documented in numerous USB // standards. When working with USB descriptors, despite the // complexity of the standards and poor writing quality in many // of those documents, remember descriptors are nothing more // than constant binary data that tells the USB host what the // device can do. Computers will load drivers based on this data. // Those drivers then communicate on the endpoints specified by // the descriptors. // To configure a new combination of interfaces or make minor // changes to existing configuration (eg, change the name or ID // numbers), usually you would edit "usb_desc.h". This file // is meant to be configured by the header, so generally it is // only edited to add completely new USB interfaces or features. // ************************************************************** // USB Device // ************************************************************** #define LSB(n) ((n) & 255) #define MSB(n) (((n) >> 8) & 255) // USB Device Descriptor. The USB host reads this first, to learn // what type of device is connected. static uint8_t device_descriptor[] = { 18, // bLength 1, // bDescriptorType 0x00, 0x02, // bcdUSB #ifdef DEVICE_CLASS DEVICE_CLASS, // bDeviceClass #else 0, #endif #ifdef DEVICE_SUBCLASS DEVICE_SUBCLASS, // bDeviceSubClass #else 0, #endif #ifdef DEVICE_PROTOCOL DEVICE_PROTOCOL, // bDeviceProtocol #else 0, #endif EP0_SIZE, // bMaxPacketSize0 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct 0x00, 0x01, // bcdDevice 1, // iManufacturer 2, // iProduct 3, // iSerialNumber 1 // bNumConfigurations }; // These descriptors must NOT be "const", because the USB DMA // has trouble accessing flash memory with enough bandwidth // while the processor is executing from flash. // ************************************************************** // HID Report Descriptors // ************************************************************** // Each HID interface needs a special report descriptor that tells // the meaning and format of the data. #ifdef KEYBOARD_INTERFACE // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 static uint8_t keyboard_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x06, // Usage (Keyboard), 0xA1, 0x01, // Collection (Application), 0x05, 0x07, // Usage Page (Key Codes), 0x19, 0xE0, // Usage Minimum (224), 0x29, 0xE7, // Usage Maximum (231), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), 0x75, 0x01, // Report Size (1), 0x95, 0x08, // Report Count (8), 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte 0x95, 0x01, // Report Count (1), 0x75, 0x08, // Report Size (8), 0x05, 0x0C, // Usage Page (Consumer), 0x09, 0xB8, // Usage (Eject), 0x81, 0x01, // Input (Data, Variable, Absolute), ;Media keys 0x95, 0x05, // Report Count (5), 0x75, 0x01, // Report Size (1), 0x05, 0x08, // Usage Page (LEDs), 0x19, 0x01, // Usage Minimum (1), 0x29, 0x05, // Usage Maximum (5), 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report 0x95, 0x01, // Report Count (1), 0x75, 0x03, // Report Size (3), 0x91, 0x01, // Output (Constant), ;LED report padding 0x95, 0x06, // Report Count (6), 0x75, 0x08, // Report Size (8), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x7F, // Logical Maximum(104), 0x05, 0x07, // Usage Page (Key Codes), 0x19, 0x00, // Usage Minimum (0), 0x29, 0x7F, // Usage Maximum (104), 0x81, 0x00, // Input (Data, Array), ;Normal keys 0x09, 0x76, // usage (local) 0x95, 0x08, // Report Count (8), 0x75, 0x08, // Report Size (8), 0xB1, 0x02, // Feature 0xC0 // End Collection }; //Old report desc /* 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x06, // Usage (Keyboard), 0xA1, 0x01, // Collection (Application), 0x75, 0x01, // Report Size (1), 0x95, 0x08, // Report Count (8), 0x05, 0x07, // Usage Page (Key Codes), 0x19, 0xE0, // Usage Minimum (224), 0x29, 0xE7, // Usage Maximum (231), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte 0x95, 0x08, // Report Count (8), 0x75, 0x01, // Report Size (1), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x01, // Logical Maximum (1), 0x05, 0x0C, // Usage Page (Consumer), 0x09, 0xB8, // Usage (Eject), 0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys 0x95, 0x05, // Report Count (5), 0x75, 0x01, // Report Size (1), 0x05, 0x08, // Usage Page (LEDs), 0x19, 0x01, // Usage Minimum (1), 0x29, 0x05, // Usage Maximum (5), 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report 0x95, 0x01, // Report Count (1), 0x75, 0x03, // Report Size (3), 0x91, 0x03, // Output (Constant), ;LED report padding 0x95, 0x06, // Report Count (6), 0x75, 0x08, // Report Size (8), 0x15, 0x00, // Logical Minimum (0), 0x25, 0x7F, // Logical Maximum(104), 0x05, 0x07, // Usage Page (Key Codes), 0x19, 0x00, // Usage Minimum (0), 0x29, 0x7F, // Usage Maximum (104), 0x81, 0x00, // Input (Data, Array), ;Normal keys 0x95, 0x08, // report count (global) 0x09, 0x76, // usage (local) 0xB1, 0x02, // Feature 0xc0 // End Collection }; */ #endif #ifdef MOUSE_INTERFACE // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension static uint8_t mouse_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x02, // Usage (Mouse) 0xA1, 0x01, // Collection (Application) 0x85, 0x01, // REPORT_ID (1) 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (Button #1) 0x29, 0x08, // Usage Maximum (Button #8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x95, 0x08, // Report Count (8) 0x75, 0x01, // Report Size (1) 0x81, 0x02, // Input (Data, Variable, Absolute) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x09, 0x38, // Usage (Wheel) 0x15, 0x81, // Logical Minimum (-127) 0x25, 0x7F, // Logical Maximum (127) 0x75, 0x08, // Report Size (8), 0x95, 0x03, // Report Count (3), 0x81, 0x06, // Input (Data, Variable, Relative) 0xC0, // End Collection 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x02, // Usage (Mouse) 0xA1, 0x01, // Collection (Application) 0x85, 0x02, // REPORT_ID (2) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x7F, // Logical Maximum (32767) 0x75, 0x10, // Report Size (16), 0x95, 0x02, // Report Count (2), 0x81, 0x02, // Input (Data, Variable, Absolute) 0xC0 // End Collection }; #endif #ifdef JOYSTICK_INTERFACE static uint8_t joystick_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x04, // Usage (Joystick) 0xA1, 0x01, // Collection (Application) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x20, // Report Count (32) 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (Button #1) 0x29, 0x20, // Usage Maximum (Button #32) 0x81, 0x02, // Input (variable,absolute) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x07, // Logical Maximum (7) 0x35, 0x00, // Physical Minimum (0) 0x46, 0x3B, 0x01, // Physical Maximum (315) 0x75, 0x04, // Report Size (4) 0x95, 0x01, // Report Count (1) 0x65, 0x14, // Unit (20) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x39, // Usage (Hat switch) 0x81, 0x42, // Input (variable,absolute,null_state) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection () 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x03, // Logical Maximum (1023) 0x75, 0x0A, // Report Size (10) 0x95, 0x04, // Report Count (4) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x09, 0x32, // Usage (Z) 0x09, 0x35, // Usage (Rz) 0x81, 0x02, // Input (variable,absolute) 0xC0, // End Collection 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x03, // Logical Maximum (1023) 0x75, 0x0A, // Report Size (10) 0x95, 0x02, // Report Count (2) 0x09, 0x36, // Usage (Slider) 0x09, 0x36, // Usage (Slider) 0x81, 0x02, // Input (variable,absolute) 0xC0 // End Collection }; #endif #ifdef SEREMU_INTERFACE static uint8_t seremu_report_desc[] = { 0x06, 0xC9, 0xFF, // Usage Page 0xFFC9 (vendor defined) 0x09, 0x04, // Usage 0x04 0xA1, 0x5C, // Collection 0x5C 0x75, 0x08, // report size = 8 bits (global) 0x15, 0x00, // logical minimum = 0 (global) 0x26, 0xFF, 0x00, // logical maximum = 255 (global) 0x95, SEREMU_TX_SIZE, // report count (global) 0x09, 0x75, // usage (local) 0x81, 0x02, // Input 0x95, SEREMU_RX_SIZE, // report count (global) 0x09, 0x76, // usage (local) 0x91, 0x02, // Output 0x95, 0x04, // report count (global) 0x09, 0x76, // usage (local) 0xB1, 0x02, // Feature 0xC0 // end collection }; #endif #ifdef RAWHID_INTERFACE static uint8_t rawhid_report_desc[] = { 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), //Usage Page 06 D0 F1 0x09, LSB(RAWHID_USAGE), // Usage 09 01 0xA1, 0x01, // Collection 0x01 0x09, 0x20, // Usage 0x15, 0x00, // logical minimum = 0 0x26, 0xFF, 0x00, // logical maximum = 255 0x75, 0x08, // report count 0x95, 0x40, // usage 0x81, 0x02, // Input (array) 0x09, 0x21, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 0x02, 0xC0, // end collection }; #endif #ifdef RAWHID_INTERFACE2 static uint8_t rawhid_report_desc2[] = { 0x06, LSB(RAWHID_USAGE_PAGE2), MSB(RAWHID_USAGE_PAGE2), //Usage Page 06 D0 F1 0x09, LSB(RAWHID_USAGE2), // Usage 09 01 0xA1, 0x01, // Collection 0x01 0x09, 0x20, // Usage 0x15, 0x00, // logical minimum = 0 0x26, 0xFF, 0x00, // logical maximum = 255 0x75, 0x08, // report count 0x95, 0x40, // usage 0x81, 0x02, // Input (array) 0x09, 0x21, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 0x02, 0xC0, // end collection }; #endif #ifdef FLIGHTSIM_INTERFACE static uint8_t flightsim_report_desc[] = { 0x06, 0x1C, 0xFF, // Usage page = 0xFF1C 0x0A, 0x39, 0xA7, // Usage = 0xA739 0xA1, 0x01, // Collection 0x01 0x75, 0x08, // report size = 8 bits 0x15, 0x00, // logical minimum = 0 0x26, 0xFF, 0x00, // logical maximum = 255 0x95, FLIGHTSIM_TX_SIZE, // report count 0x09, 0x01, // usage 0x81, 0x02, // Input (array) 0x95, FLIGHTSIM_RX_SIZE, // report count 0x09, 0x02, // usage 0x91, 0x02, // Output (array) 0xC0 // end collection }; #endif // ************************************************************** // USB Descriptor Sizes // ************************************************************** // pre-compute the size and position of everything in the config descriptor // #define CONFIG_HEADER_DESCRIPTOR_SIZE 9 #define CDC_IAD_DESCRIPTOR_POS CONFIG_HEADER_DESCRIPTOR_SIZE #ifdef CDC_IAD_DESCRIPTOR #define CDC_IAD_DESCRIPTOR_SIZE 8 #else #define CDC_IAD_DESCRIPTOR_SIZE 0 #endif #define CDC_DATA_INTERFACE_DESC_POS CDC_IAD_DESCRIPTOR_POS+CDC_IAD_DESCRIPTOR_SIZE #ifdef CDC_DATA_INTERFACE #define CDC_DATA_INTERFACE_DESC_SIZE 9+5+5+4+5+7+9+7+7 #else #define CDC_DATA_INTERFACE_DESC_SIZE 0 #endif #define MIDI_INTERFACE_DESC_POS CDC_DATA_INTERFACE_DESC_POS+CDC_DATA_INTERFACE_DESC_SIZE #ifdef MIDI_INTERFACE #define MIDI_INTERFACE_DESC_SIZE 9+7+6+6+9+9+9+5+9+5 #else #define MIDI_INTERFACE_DESC_SIZE 0 #endif #define KEYBOARD_INTERFACE_DESC_POS MIDI_INTERFACE_DESC_POS+MIDI_INTERFACE_DESC_SIZE #ifdef KEYBOARD_INTERFACE #define KEYBOARD_INTERFACE_DESC_SIZE 9+9+7 #define KEYBOARD_HID_DESC_OFFSET KEYBOARD_INTERFACE_DESC_POS+9 #else #define KEYBOARD_INTERFACE_DESC_SIZE 0 #endif #define MOUSE_INTERFACE_DESC_POS KEYBOARD_INTERFACE_DESC_POS+KEYBOARD_INTERFACE_DESC_SIZE #ifdef MOUSE_INTERFACE #define MOUSE_INTERFACE_DESC_SIZE 9+9+7 #define MOUSE_HID_DESC_OFFSET MOUSE_INTERFACE_DESC_POS+9 #else #define MOUSE_INTERFACE_DESC_SIZE 0 #endif #define RAWHID_INTERFACE_DESC_POS MOUSE_INTERFACE_DESC_POS+MOUSE_INTERFACE_DESC_SIZE #ifdef RAWHID_INTERFACE #define RAWHID_INTERFACE_DESC_SIZE 9+9+7+7 #define RAWHID_HID_DESC_OFFSET RAWHID_INTERFACE_DESC_POS+9 #else #define RAWHID_INTERFACE_DESC_SIZE 0 #endif #define RAWHID_INTERFACE_DESC_POS2 RAWHID_INTERFACE_DESC_POS+RAWHID_INTERFACE_DESC_SIZE #ifdef RAWHID_INTERFACE2 #define RAWHID_INTERFACE_DESC_SIZE2 9+9+7+7 #define RAWHID_HID_DESC_OFFSET2 RAWHID_INTERFACE_DESC_POS2+9 #else #define RAWHID_INTERFACE_DESC_SIZE2 0 #endif #define FLIGHTSIM_INTERFACE_DESC_POS RAWHID_INTERFACE_DESC_POS2+RAWHID_INTERFACE_DESC_SIZE2 #ifdef FLIGHTSIM_INTERFACE #define FLIGHTSIM_INTERFACE_DESC_SIZE 9+9+7+7 #define FLIGHTSIM_HID_DESC_OFFSET FLIGHTSIM_INTERFACE_DESC_POS+9 #else #define FLIGHTSIM_INTERFACE_DESC_SIZE 0 #endif #define SEREMU_INTERFACE_DESC_POS FLIGHTSIM_INTERFACE_DESC_POS+FLIGHTSIM_INTERFACE_DESC_SIZE #ifdef SEREMU_INTERFACE #define SEREMU_INTERFACE_DESC_SIZE 9+9+7+7 #define SEREMU_HID_DESC_OFFSET SEREMU_INTERFACE_DESC_POS+9 #else #define SEREMU_INTERFACE_DESC_SIZE 0 #endif #define JOYSTICK_INTERFACE_DESC_POS SEREMU_INTERFACE_DESC_POS+SEREMU_INTERFACE_DESC_SIZE #ifdef JOYSTICK_INTERFACE #define JOYSTICK_INTERFACE_DESC_SIZE 9+9+7 #define JOYSTICK_HID_DESC_OFFSET JOYSTICK_INTERFACE_DESC_POS+9 #else #define JOYSTICK_INTERFACE_DESC_SIZE 0 #endif #define MTP_INTERFACE_DESC_POS JOYSTICK_INTERFACE_DESC_POS+JOYSTICK_INTERFACE_DESC_SIZE #ifdef MTP_INTERFACE #define MTP_INTERFACE_DESC_SIZE 9+7+7+7 #else #define MTP_INTERFACE_DESC_SIZE 0 #endif #define CONFIG_DESC_SIZE MTP_INTERFACE_DESC_POS+MTP_INTERFACE_DESC_SIZE // ************************************************************** // USB Configuration // ************************************************************** // USB Configuration Descriptor. This huge descriptor tells all // of the devices capbilities. static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 9, // bLength; 2, // bDescriptorType; LSB(CONFIG_DESC_SIZE), // wTotalLength MSB(CONFIG_DESC_SIZE), NUM_INTERFACE, // bNumInterfaces 1, // bConfigurationValue 0, // iConfiguration 0x80, // bmAttributes 50, // bMaxPower #ifdef CDC_IAD_DESCRIPTOR // interface association descriptor, USB ECN, Table 9-Z 8, // bLength 11, // bDescriptorType CDC_STATUS_INTERFACE, // bFirstInterface 2, // bInterfaceCount 0x02, // bFunctionClass 0x02, // bFunctionSubClass 0x01, // bFunctionProtocol 4, // iFunction #endif #ifdef CDC_DATA_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType CDC_STATUS_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 1, // bNumEndpoints 0x02, // bInterfaceClass 0x02, // bInterfaceSubClass 0x01, // bInterfaceProtocol 0, // iInterface // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 5, // bFunctionLength 0x24, // bDescriptorType 0x00, // bDescriptorSubtype 0x10, 0x01, // bcdCDC // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 5, // bFunctionLength 0x24, // bDescriptorType 0x01, // bDescriptorSubtype 0x01, // bmCapabilities 1, // bDataInterface // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 4, // bFunctionLength 0x24, // bDescriptorType 0x02, // bDescriptorSubtype 0x06, // bmCapabilities // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 5, // bFunctionLength 0x24, // bDescriptorType 0x06, // bDescriptorSubtype CDC_STATUS_INTERFACE, // bMasterInterface CDC_DATA_INTERFACE, // bSlaveInterface0 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) CDC_ACM_SIZE, 0, // wMaxPacketSize 64, // bInterval // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType CDC_DATA_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 2, // bNumEndpoints 0x0A, // bInterfaceClass 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0, // iInterface // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType CDC_RX_ENDPOINT, // bEndpointAddress 0x02, // bmAttributes (0x02=bulk) CDC_RX_SIZE, 0, // wMaxPacketSize 0, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType CDC_TX_ENDPOINT | 0x80, // bEndpointAddress 0x02, // bmAttributes (0x02=bulk) CDC_TX_SIZE, 0, // wMaxPacketSize 0, // bInterval #endif // CDC_DATA_INTERFACE #ifdef MIDI_INTERFACE // Standard MS Interface Descriptor, 9, // bLength 4, // bDescriptorType MIDI_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 2, // bNumEndpoints 0x01, // bInterfaceClass (0x01 = Audio) 0x03, // bInterfaceSubClass (0x03 = MIDI) 0x00, // bInterfaceProtocol (unused for MIDI) 0, // iInterface // MIDI MS Interface Header, USB MIDI 6.1.2.1, page 21, Table 6-2 7, // bLength 0x24, // bDescriptorType = CS_INTERFACE 0x01, // bDescriptorSubtype = MS_HEADER 0x00, 0x01, // bcdMSC = revision 01.00 0x41, 0x00, // wTotalLength // MIDI IN Jack Descriptor, B.4.3, Table B-7 (embedded), page 40 6, // bLength 0x24, // bDescriptorType = CS_INTERFACE 0x02, // bDescriptorSubtype = MIDI_IN_JACK 0x01, // bJackType = EMBEDDED 1, // bJackID, ID = 1 0, // iJack // MIDI IN Jack Descriptor, B.4.3, Table B-8 (external), page 40 6, // bLength 0x24, // bDescriptorType = CS_INTERFACE 0x02, // bDescriptorSubtype = MIDI_IN_JACK 0x02, // bJackType = EXTERNAL 2, // bJackID, ID = 2 0, // iJack // MIDI OUT Jack Descriptor, B.4.4, Table B-9, page 41 9, 0x24, // bDescriptorType = CS_INTERFACE 0x03, // bDescriptorSubtype = MIDI_OUT_JACK 0x01, // bJackType = EMBEDDED 3, // bJackID, ID = 3 1, // bNrInputPins = 1 pin 2, // BaSourceID(1) = 2 1, // BaSourcePin(1) = first pin 0, // iJack // MIDI OUT Jack Descriptor, B.4.4, Table B-10, page 41 9, 0x24, // bDescriptorType = CS_INTERFACE 0x03, // bDescriptorSubtype = MIDI_OUT_JACK 0x02, // bJackType = EXTERNAL 4, // bJackID, ID = 4 1, // bNrInputPins = 1 pin 1, // BaSourceID(1) = 1 1, // BaSourcePin(1) = first pin 0, // iJack // Standard Bulk OUT Endpoint Descriptor, B.5.1, Table B-11, pae 42 9, // bLength 5, // bDescriptorType = ENDPOINT MIDI_RX_ENDPOINT, // bEndpointAddress 0x02, // bmAttributes (0x02=bulk) MIDI_RX_SIZE, 0, // wMaxPacketSize 0, // bInterval 0, // bRefresh 0, // bSynchAddress // Class-specific MS Bulk OUT Endpoint Descriptor, B.5.2, Table B-12, page 42 5, // bLength 0x25, // bDescriptorSubtype = CS_ENDPOINT 0x01, // bJackType = MS_GENERAL 1, // bNumEmbMIDIJack = 1 jack 1, // BaAssocJackID(1) = jack ID #1 // Standard Bulk IN Endpoint Descriptor, B.5.1, Table B-11, pae 42 9, // bLength 5, // bDescriptorType = ENDPOINT MIDI_TX_ENDPOINT | 0x80, // bEndpointAddress 0x02, // bmAttributes (0x02=bulk) MIDI_TX_SIZE, 0, // wMaxPacketSize 0, // bInterval 0, // bRefresh 0, // bSynchAddress // Class-specific MS Bulk IN Endpoint Descriptor, B.5.2, Table B-12, page 42 5, // bLength 0x25, // bDescriptorSubtype = CS_ENDPOINT 0x01, // bJackType = MS_GENERAL 1, // bNumEmbMIDIJack = 1 jack 3, // BaAssocJackID(1) = jack ID #3 #endif // MIDI_INTERFACE #ifdef KEYBOARD_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType KEYBOARD_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 1, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x01, // bInterfaceSubClass (0x01 = Boot) 0x01, // bInterfaceProtocol (0x01 = Keyboard) 0x02, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(keyboard_report_desc)), // wDescriptorLength MSB(sizeof(keyboard_report_desc)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) KEYBOARD_SIZE, 0, // wMaxPacketSize KEYBOARD_INTERVAL, // bInterval #endif // KEYBOARD_INTERFACE #ifdef MOUSE_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType MOUSE_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 1, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass (0x01 = Boot) 0x00, // bInterfaceProtocol (0x02 = Mouse) 0, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(mouse_report_desc)), // wDescriptorLength MSB(sizeof(mouse_report_desc)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType MOUSE_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) MOUSE_SIZE, 0, // wMaxPacketSize MOUSE_INTERVAL, // bInterval #endif // MOUSE_INTERFACE #ifdef RAWHID_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType RAWHID_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 2, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0x02, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(rawhid_report_desc)), // wDescriptorLength MSB(sizeof(rawhid_report_desc)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType RAWHID_TX_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) RAWHID_TX_SIZE, 0, // wMaxPacketSize RAWHID_TX_INTERVAL, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType RAWHID_RX_ENDPOINT, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) RAWHID_RX_SIZE, 0, // wMaxPacketSize RAWHID_RX_INTERVAL, // bInterval #endif // RAWHID_INTERFACE #ifdef RAWHID_INTERFACE2 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType RAWHID_INTERFACE2, // bInterfaceNumber 0, // bAlternateSetting 2, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0x02, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(rawhid_report_desc2)), // wDescriptorLength MSB(sizeof(rawhid_report_desc2)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType RAWHID_TX_ENDPOINT2 | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) RAWHID_TX_SIZE, 0, // wMaxPacketSize RAWHID_TX_INTERVAL, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType RAWHID_RX_ENDPOINT2, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) RAWHID_RX_SIZE, 0, // wMaxPacketSize RAWHID_RX_INTERVAL, // bInterval #endif // RAWHID_INTERFACE #ifdef FLIGHTSIM_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType FLIGHTSIM_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 2, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(flightsim_report_desc)), // wDescriptorLength MSB(sizeof(flightsim_report_desc)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType FLIGHTSIM_TX_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) FLIGHTSIM_TX_SIZE, 0, // wMaxPacketSize FLIGHTSIM_TX_INTERVAL, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType FLIGHTSIM_RX_ENDPOINT, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) FLIGHTSIM_RX_SIZE, 0, // wMaxPacketSize FLIGHTSIM_RX_INTERVAL, // bInterval #endif // FLIGHTSIM_INTERFACE #ifdef SEREMU_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType SEREMU_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 2, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(seremu_report_desc)), // wDescriptorLength MSB(sizeof(seremu_report_desc)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType SEREMU_TX_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) SEREMU_TX_SIZE, 0, // wMaxPacketSize SEREMU_TX_INTERVAL, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType SEREMU_RX_ENDPOINT, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) SEREMU_RX_SIZE, 0, // wMaxPacketSize SEREMU_RX_INTERVAL, // bInterval #endif // SEREMU_INTERFACE #ifdef JOYSTICK_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType JOYSTICK_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 1, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol 0, // iInterface // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID 0, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(joystick_report_desc)), // wDescriptorLength MSB(sizeof(joystick_report_desc)), // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) JOYSTICK_SIZE, 0, // wMaxPacketSize JOYSTICK_INTERVAL, // bInterval #endif // JOYSTICK_INTERFACE #ifdef MTP_INTERFACE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType MTP_INTERFACE, // bInterfaceNumber 0, // bAlternateSetting 3, // bNumEndpoints 0x06, // bInterfaceClass (0x06 = still image) 0x01, // bInterfaceSubClass 0x01, // bInterfaceProtocol 0, // iInterface // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType MTP_TX_ENDPOINT | 0x80, // bEndpointAddress 0x02, // bmAttributes (0x02=bulk) MTP_TX_SIZE, 0, // wMaxPacketSize 0, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType MTP_RX_ENDPOINT, // bEndpointAddress 0x02, // bmAttributes (0x02=bulk) MTP_RX_SIZE, 0, // wMaxPacketSize 0, // bInterval // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength 5, // bDescriptorType MTP_EVENT_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) MTP_EVENT_SIZE, 0, // wMaxPacketSize MTP_EVENT_INTERVAL, // bInterval #endif // MTP_INTERFACE }; // ************************************************************** // String Descriptors // ************************************************************** // The descriptors above can provide human readable strings, // referenced by index numbers. These descriptors are the // actual string data /* defined in usb_names.h struct usb_string_descriptor_struct { uint8_t bLength; uint8_t bDescriptorType; uint16_t wString[]; }; */ extern struct usb_string_descriptor_struct usb_string_manufacturer_name __attribute__ ((weak, alias("usb_string_manufacturer_name_default"))); extern struct usb_string_descriptor_struct usb_string_product_name __attribute__ ((weak, alias("usb_string_product_name_default"))); extern struct usb_string_descriptor_struct usb_string_serial_number __attribute__ ((weak, alias("usb_string_serial_number_default"))); struct usb_string_descriptor_struct string0 = { 4, 3, {0x0409} }; struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { 2 + MANUFACTURER_NAME_LEN * 2, 3, MANUFACTURER_NAME }; struct usb_string_descriptor_struct usb_string_product_name_default = { 2 + PRODUCT_NAME_LEN * 2, 3, PRODUCT_NAME }; struct usb_string_descriptor_struct usb_string_serial_number_default = { 12, 3, {0,0,0,0,0,0,0,0,0,0} }; void usb_init_serialnumber(void) { char buf[11]; uint32_t i, num = 1000000000; //__disable_irq(); //FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL; //FTFL_FCCOB0 = 0x41; //FTFL_FCCOB1 = 15; //FTFL_FSTAT = FTFL_FSTAT_CCIF; //while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait //num = 1000000000; //__enable_irq(); // add extra zero to work around OS-X CDC-ACM driver bug //if (num < 10000000) num = num * 10; ultoa(num, buf, 10); for (i=0; i<10; i++) { char c = buf[i]; if (!c) break; usb_string_serial_number_default.wString[i] = c; } usb_string_serial_number_default.bLength = i * 2 + 2; } // ************************************************************** // Descriptors List // ************************************************************** // This table provides access to all the descriptor data above. const usb_descriptor_list_t usb_descriptor_list[] = { //wValue, wIndex, address, length {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, #ifdef SEREMU_INTERFACE {0x2200, SEREMU_INTERFACE, seremu_report_desc, sizeof(seremu_report_desc)}, {0x2100, SEREMU_INTERFACE, config_descriptor+SEREMU_HID_DESC_OFFSET, 9}, #endif #ifdef KEYBOARD_INTERFACE {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, {0x2100, KEYBOARD_INTERFACE, config_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, #endif #ifdef MOUSE_INTERFACE {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, {0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_HID_DESC_OFFSET, 9}, #endif #ifdef JOYSTICK_INTERFACE {0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)}, {0x2100, JOYSTICK_INTERFACE, config_descriptor+JOYSTICK_HID_DESC_OFFSET, 9}, #endif #ifdef RAWHID_INTERFACE {0x2200, RAWHID_INTERFACE, rawhid_report_desc, sizeof(rawhid_report_desc)}, {0x2100, RAWHID_INTERFACE, config_descriptor+RAWHID_HID_DESC_OFFSET, 9}, #endif #ifdef RAWHID_INTERFACE2 {0x2200, RAWHID_INTERFACE2, rawhid_report_desc2, sizeof(rawhid_report_desc2)}, {0x2100, RAWHID_INTERFACE2, config_descriptor+RAWHID_HID_DESC_OFFSET2, 9}, #endif #ifdef FLIGHTSIM_INTERFACE {0x2200, FLIGHTSIM_INTERFACE, flightsim_report_desc, sizeof(flightsim_report_desc)}, {0x2100, FLIGHTSIM_INTERFACE, config_descriptor+FLIGHTSIM_HID_DESC_OFFSET, 9}, #endif //{0x0201, 0x0000, (const uint8_t *)&string0, 0}, {0x0300, 0x0000, (const uint8_t *)&string0, 0}, {0x0300, 0x0409, (const uint8_t *)&string0, 0}, {0x0201, 0x0000, (const uint8_t *)&string0, 0}, {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, {0, 0, NULL, 0} }; // ************************************************************** // Endpoint Configuration // ************************************************************** #if 0 // 0x00 = not used // 0x19 = Recieve only // 0x15 = Transmit only // 0x1D = Transmit & Recieve // const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = { 0x00, 0x15, 0x19, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; #endif const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = { #if (defined(ENDPOINT1_CONFIG) && NUM_ENDPOINTS >= 1) ENDPOINT1_CONFIG, #elif (NUM_ENDPOINTS >= 1) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT2_CONFIG) && NUM_ENDPOINTS >= 2) ENDPOINT2_CONFIG, #elif (NUM_ENDPOINTS >= 2) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT3_CONFIG) && NUM_ENDPOINTS >= 3) ENDPOINT3_CONFIG, #elif (NUM_ENDPOINTS >= 3) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT4_CONFIG) && NUM_ENDPOINTS >= 4) ENDPOINT4_CONFIG, #elif (NUM_ENDPOINTS >= 4) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT5_CONFIG) && NUM_ENDPOINTS >= 5) ENDPOINT5_CONFIG, #elif (NUM_ENDPOINTS >= 5) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT6_CONFIG) && NUM_ENDPOINTS >= 6) ENDPOINT6_CONFIG, #elif (NUM_ENDPOINTS >= 6) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT7_CONFIG) && NUM_ENDPOINTS >= 7) ENDPOINT7_CONFIG, #elif (NUM_ENDPOINTS >= 7) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT8_CONFIG) && NUM_ENDPOINTS >= 8) ENDPOINT8_CONFIG, #elif (NUM_ENDPOINTS >= 8) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT9_CONFIG) && NUM_ENDPOINTS >= 9) ENDPOINT9_CONFIG, #elif (NUM_ENDPOINTS >= 9) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT10_CONFIG) && NUM_ENDPOINTS >= 10) ENDPOINT10_CONFIG, #elif (NUM_ENDPOINTS >= 10) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT11_CONFIG) && NUM_ENDPOINTS >= 11) ENDPOINT11_CONFIG, #elif (NUM_ENDPOINTS >= 11) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT12_CONFIG) && NUM_ENDPOINTS >= 12) ENDPOINT12_CONFIG, #elif (NUM_ENDPOINTS >= 12) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT13_CONFIG) && NUM_ENDPOINTS >= 13) ENDPOINT13_CONFIG, #elif (NUM_ENDPOINTS >= 13) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT14_CONFIG) && NUM_ENDPOINTS >= 14) ENDPOINT14_CONFIG, #elif (NUM_ENDPOINTS >= 14) ENDPOINT_UNUSED, #endif #if (defined(ENDPOINT15_CONFIG) && NUM_ENDPOINTS >= 15) ENDPOINT15_CONFIG, #elif (NUM_ENDPOINTS >= 15) ENDPOINT_UNUSED, #endif }; #endif // NUM_ENDPOINTS #endif // F_CPU >= 20 MHz ================================================ FILE: usb_desc.h ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef _usb_desc_h_ #define _usb_desc_h_ // This header is NOT meant to be included when compiling // user sketches in Arduino. The low-level functions // provided by usb_dev.c are meant to be called only by // code which provides higher-level interfaces to the user. #include #include #define ENDPOINT_UNUSED 0x00 #define ENDPOINT_TRANSIMIT_ONLY 0x15 #define ENDPOINT_RECEIVE_ONLY 0x19 #define ENDPOINT_TRANSMIT_AND_RECEIVE 0x1D /* Each group of #define lines below corresponds to one of the settings in the Tools > USB Type menu. This file defines what type of USB device is actually created for each of those menu options. Each "interface" is a set of functionality your PC or Mac will use and treat as if it is a unique device. Within each interface, the "endpoints" are the actual communication channels. Most interfaces use 1, 2 or 3 endpoints. By editing only this file, you can customize the USB Types to be any collection of interfaces. To modify a USB Type, delete the XYZ_INTERFACE lines for any interfaces you wish to remove, and copy them from another USB Type for any you want to add. Give each interface a unique number, and edit NUM_INTERFACE to reflect the total number of interfaces. Next, assign unique endpoint numbers to all the endpoints across all the interfaces your device has. You can reuse an endpoint number for transmit and receive, but the same endpoint number must not be used twice to transmit, or twice to receive. Most endpoints also require their maximum size, and some also need an interval specification (the number of milliseconds the PC will check for data from that endpoint). For existing interfaces, usually these other settings should not be changed. Edit NUM_ENDPOINTS to be at least the largest endpoint number used. Edit NUM_USB_BUFFERS to control how much memory the USB stack will allocate. At least 2 should be used for each endpoint. More memory will allow higher throughput for user programs that have high latency (eg, spending time doing things other than interacting with the USB). Edit the ENDPOINT*_CONFIG lines so each endpoint is configured the proper way (transmit, receive, or both). If you are using existing interfaces (making your own device with a different set of interfaces) the code in all other files should automatically adapt to the new endpoints you specify here. If you need to create a new type of interface, you'll need to write the code which sends and receives packets, and presents an API to the user. Usually, a pair of files are added for the actual code, and code is also added in usb_dev.c for any control transfers, interrupt-level code, or other very low-level stuff not possible from the packet send/receive functons. Code also is added in usb_inst.c to create an instance of your C++ object. You may edit the Vendor and Product ID numbers, and strings. If the numbers are changed, Teensyduino may not be able to automatically find and reboot your board when you click the Upload button in the Arduino IDE. You will need to press the Program button on Teensy to initiate programming. Some operating systems, especially Windows, may cache USB device info. Changes to the device name may not update on the same computer unless the vendor or product ID numbers change, or the "bcdDevice" revision code is increased. If these instructions are missing steps or could be improved, please let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports */ #if defined(USB_SERIAL) #define VENDOR_ID 0x16C0 #define PRODUCT_ID 0x0483 #define DEVICE_CLASS 2 // 2 = Communication Class #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'U','S','B',' ','S','e','r','i','a','l'} #define PRODUCT_NAME_LEN 10 #define EP0_SIZE 64 #define NUM_ENDPOINTS 4 #define NUM_USB_BUFFERS 12 #define NUM_INTERFACE 2 #define CDC_STATUS_INTERFACE 0 #define CDC_DATA_INTERFACE 1 #define CDC_ACM_ENDPOINT 2 #define CDC_RX_ENDPOINT 3 #define CDC_TX_ENDPOINT 4 #define CDC_ACM_SIZE 16 #define CDC_RX_SIZE 64 #define CDC_TX_SIZE 64 #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY #elif defined(USB_HID) #define VENDOR_ID 0x16C0 #define PRODUCT_ID 0x0482 #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'K','e','y','b','o','a','r','d','/','M','o','u','s','e','/','J','o','y','s','t','i','c','k'} #define PRODUCT_NAME_LEN 23 #define EP0_SIZE 64 #define NUM_ENDPOINTS 5 #define NUM_USB_BUFFERS 24 #define NUM_INTERFACE 4 #define SEREMU_INTERFACE 2 // Serial emulation #define SEREMU_TX_ENDPOINT 1 #define SEREMU_TX_SIZE 64 #define SEREMU_TX_INTERVAL 1 #define SEREMU_RX_ENDPOINT 2 #define SEREMU_RX_SIZE 32 #define SEREMU_RX_INTERVAL 2 #define KEYBOARD_INTERFACE 0 // Keyboard #define KEYBOARD_ENDPOINT 3 #define KEYBOARD_SIZE 8 #define KEYBOARD_INTERVAL 1 #define MOUSE_INTERFACE 1 // Mouse #define MOUSE_ENDPOINT 5 #define MOUSE_SIZE 8 #define MOUSE_INTERVAL 1 #define JOYSTICK_INTERFACE 3 // Joystick #define JOYSTICK_ENDPOINT 4 #define JOYSTICK_SIZE 16 #define JOYSTICK_INTERVAL 2 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY #elif defined(USB_SERIAL_HID) #define VENDOR_ID 0x16C0 #define PRODUCT_ID 0x0487 #define DEVICE_CLASS 0xEF #define DEVICE_SUBCLASS 0x02 #define DEVICE_PROTOCOL 0x01 #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'S','e','r','i','a','l','/','K','e','y','b','o','a','r','d','/','M','o','u','s','e','/','J','o','y','s','t','i','c','k'} #define PRODUCT_NAME_LEN 30 #define EP0_SIZE 64 #define NUM_ENDPOINTS 6 #define NUM_USB_BUFFERS 30 #define NUM_INTERFACE 5 #define CDC_IAD_DESCRIPTOR 1 #define CDC_STATUS_INTERFACE 0 #define CDC_DATA_INTERFACE 1 // Serial #define CDC_ACM_ENDPOINT 2 #define CDC_RX_ENDPOINT 3 #define CDC_TX_ENDPOINT 4 #define CDC_ACM_SIZE 16 #define CDC_RX_SIZE 64 #define CDC_TX_SIZE 64 #define KEYBOARD_INTERFACE 2 // Keyboard #define KEYBOARD_ENDPOINT 1 #define KEYBOARD_SIZE 8 #define KEYBOARD_INTERVAL 1 #define MOUSE_INTERFACE 3 // Mouse #define MOUSE_ENDPOINT 5 #define MOUSE_SIZE 8 #define MOUSE_INTERVAL 2 #define JOYSTICK_INTERFACE 4 // Joystick #define JOYSTICK_ENDPOINT 6 #define JOYSTICK_SIZE 16 #define JOYSTICK_INTERVAL 1 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY #elif defined(USB_MIDI) #define VENDOR_ID 0x16C0 #define PRODUCT_ID 0x0485 #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'T','e','e','n','s','y',' ','M','I','D','I'} #define PRODUCT_NAME_LEN 11 #define EP0_SIZE 64 #define NUM_ENDPOINTS 4 #define NUM_USB_BUFFERS 16 #define NUM_INTERFACE 2 #define SEREMU_INTERFACE 1 // Serial emulation #define SEREMU_TX_ENDPOINT 1 #define SEREMU_TX_SIZE 64 #define SEREMU_TX_INTERVAL 1 #define SEREMU_RX_ENDPOINT 2 #define SEREMU_RX_SIZE 32 #define SEREMU_RX_INTERVAL 2 #define MIDI_INTERFACE 0 // MIDI #define MIDI_TX_ENDPOINT 3 #define MIDI_TX_SIZE 64 #define MIDI_RX_ENDPOINT 4 #define MIDI_RX_SIZE 64 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY #elif defined(USB_RAWHID) #define VENDOR_ID 0x1d50 #define PRODUCT_ID 0x60fc #define RAWHID_USAGE_PAGE 0xf1d0 // Changed for FIDO support #define RAWHID_USAGE 0x01 // Changed for FIDO support #define RAWHID_USAGE_PAGE2 0xffab #define RAWHID_USAGE2 0x02 #define MANUFACTURER_NAME {'C','R','Y','P','T','O','T','R','U','S','T'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'O','N','L','Y','K','E','Y'} #define PRODUCT_NAME_LEN 7 #define EP0_SIZE 64 #define NUM_ENDPOINTS 7 #define NUM_USB_BUFFERS 30 #define NUM_INTERFACE 4 #define RAWHID_INTERFACE 1 // RawHID #define RAWHID_TX_ENDPOINT 3 #define RAWHID_TX_SIZE 64 #define RAWHID_TX_INTERVAL 5 #define RAWHID_RX_ENDPOINT 4 #define RAWHID_RX_SIZE 64 #define RAWHID_RX_INTERVAL 5 #define RAWHID_INTERFACE2 2 // RawHID2 #define RAWHID_TX_ENDPOINT2 5 #define RAWHID_RX_ENDPOINT2 6 #define SEREMU_INTERFACE 3 // Serial emulation #define SEREMU_TX_ENDPOINT 1 #define SEREMU_TX_SIZE 64 #define SEREMU_TX_INTERVAL 5 #define SEREMU_RX_ENDPOINT 2 #define SEREMU_RX_SIZE 32 #define SEREMU_RX_INTERVAL 2 #define KEYBOARD_INTERFACE 0 // Keyboard #define KEYBOARD_ENDPOINT 7 #define KEYBOARD_SIZE 8 #define KEYBOARD_INTERVAL 5 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY /* #define VENDOR_ID 0x1d50 #define PRODUCT_ID 0x60fc #define RAWHID_USAGE_PAGE 0xf1d0 // Changed for FIDO support #define RAWHID_USAGE 0x01 // Changed for FIDO support #define RAWHID_USAGE_PAGE2 0xffab #define RAWHID_USAGE2 0x02 #define MANUFACTURER_NAME {'C','R','Y','P','T','O','T','R','U','S','T'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'O','N','L','Y','K','E','Y'} #define PRODUCT_NAME_LEN 7 #define EP0_SIZE 64 #define NUM_ENDPOINTS 5 #define NUM_USB_BUFFERS 30 #define NUM_INTERFACE 3 #define RAWHID_INTERFACE 1 // RawHID #define RAWHID_TX_ENDPOINT 1 #define RAWHID_TX_SIZE 64 #define RAWHID_TX_INTERVAL 1 #define RAWHID_RX_ENDPOINT 2 #define RAWHID_RX_SIZE 64 #define RAWHID_RX_INTERVAL 1 #define RAWHID_INTERFACE2 2 // RawHID2 #define RAWHID_TX_ENDPOINT2 3 #define RAWHID_RX_ENDPOINT2 4 #define KEYBOARD_INTERFACE 0 // Keyboard #define KEYBOARD_ENDPOINT 5 #define KEYBOARD_SIZE 8 #define KEYBOARD_INTERVAL 1 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY */ #elif defined(USB_FLIGHTSIM) #define VENDOR_ID 0x16C0 #define PRODUCT_ID 0x0488 #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'T','e','e','n','s','y',' ','F','l','i','g','h','t',' ','S','i','m',' ','C','o','n','t','r','o','l','s'} #define PRODUCT_NAME_LEN 26 #define EP0_SIZE 64 #define NUM_ENDPOINTS 4 #define NUM_USB_BUFFERS 20 #define NUM_INTERFACE 2 #define FLIGHTSIM_INTERFACE 0 // Flight Sim Control #define FLIGHTSIM_TX_ENDPOINT 3 #define FLIGHTSIM_TX_SIZE 64 #define FLIGHTSIM_TX_INTERVAL 1 #define FLIGHTSIM_RX_ENDPOINT 4 #define FLIGHTSIM_RX_SIZE 64 #define FLIGHTSIM_RX_INTERVAL 1 #define SEREMU_INTERFACE 1 // Serial emulation #define SEREMU_TX_ENDPOINT 1 #define SEREMU_TX_SIZE 64 #define SEREMU_TX_INTERVAL 1 #define SEREMU_RX_ENDPOINT 2 #define SEREMU_RX_SIZE 32 #define SEREMU_RX_INTERVAL 2 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY #elif defined(USB_MTPDISK) #define VENDOR_ID 0x16C0 #define PRODUCT_ID 0x0489 #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} #define MANUFACTURER_NAME_LEN 11 #define PRODUCT_NAME {'T','e','e','n','s','y',' ','M','T','P',' ','D','i','s','k'} #define PRODUCT_NAME_LEN 15 #define EP0_SIZE 64 #define NUM_ENDPOINTS 4 #define NUM_USB_BUFFERS 20 #define NUM_INTERFACE 2 #define MTP_INTERFACE 0 // MTP Disk #define MTP_TX_ENDPOINT 3 #define MTP_TX_SIZE 64 #define MTP_RX_ENDPOINT 3 #define MTP_RX_SIZE 64 #define MTP_EVENT_ENDPOINT 4 #define MTP_EVENT_SIZE 16 #define MTP_EVENT_INTERVAL 10 #define SEREMU_INTERFACE 1 // Serial emulation #define SEREMU_TX_ENDPOINT 1 #define SEREMU_TX_SIZE 64 #define SEREMU_TX_INTERVAL 1 #define SEREMU_RX_ENDPOINT 2 #define SEREMU_RX_SIZE 32 #define SEREMU_RX_INTERVAL 2 #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT3_CONFIG ENDPOINT_TRANSMIT_AND_RECEIVE #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY #endif #ifdef USB_DESC_LIST_DEFINE #if defined(NUM_ENDPOINTS) && NUM_ENDPOINTS > 0 // NUM_ENDPOINTS = number of non-zero endpoints (0 to 15) extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS]; typedef struct { uint16_t wValue; uint16_t wIndex; const uint8_t *addr; uint16_t length; } usb_descriptor_list_t; extern const usb_descriptor_list_t usb_descriptor_list[]; #endif // NUM_ENDPOINTS #endif // USB_DESC_LIST_DEFINE #endif ================================================ FILE: usb_dev.c ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "usb_dev.h" #if F_CPU >= 20000000 && defined(NUM_ENDPOINTS) #include "kinetis.h" //#include "HardwareSerial.h" #include "usb_mem.h" // buffer descriptor table typedef struct { uint32_t desc; void * addr; } bdt_t; __attribute__ ((section(".usbdescriptortable"), used)) static bdt_t table[(NUM_ENDPOINTS+1)*4]; static usb_packet_t *rx_first[NUM_ENDPOINTS]; static usb_packet_t *rx_last[NUM_ENDPOINTS]; static usb_packet_t *tx_first[NUM_ENDPOINTS]; static usb_packet_t *tx_last[NUM_ENDPOINTS]; uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS]; static uint8_t tx_state[NUM_ENDPOINTS]; #define TX_STATE_BOTH_FREE_EVEN_FIRST 0 #define TX_STATE_BOTH_FREE_ODD_FIRST 1 #define TX_STATE_EVEN_FREE 2 #define TX_STATE_ODD_FREE 3 #define TX_STATE_NONE_FREE_EVEN_FIRST 4 #define TX_STATE_NONE_FREE_ODD_FIRST 5 #define BDT_OWN 0x80 #define BDT_DATA1 0x40 #define BDT_DATA0 0x00 #define BDT_DTS 0x08 #define BDT_STALL 0x04 #define BDT_PID(n) (((n) >> 2) & 15) #define BDT_DESC(count, data) (BDT_OWN | BDT_DTS \ | ((data) ? BDT_DATA1 : BDT_DATA0) \ | ((count) << 16)) #define TX 1 #define RX 0 #define ODD 1 #define EVEN 0 #define DATA0 0 #define DATA1 1 #define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd)) #define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) static union { struct { union { struct { uint8_t bmRequestType; uint8_t bRequest; }; uint16_t wRequestAndType; }; uint16_t wValue; uint16_t wIndex; uint16_t wLength; }; struct { uint32_t word1; uint32_t word2; }; } setup; #define GET_STATUS 0 #define CLEAR_FEATURE 1 #define SET_FEATURE 3 #define SET_ADDRESS 5 #define GET_DESCRIPTOR 6 #define SET_DESCRIPTOR 7 #define GET_CONFIGURATION 8 #define SET_CONFIGURATION 9 #define GET_INTERFACE 10 #define SET_INTERFACE 11 #define SYNCH_FRAME 12 // SETUP always uses a DATA0 PID for the data field of the SETUP transaction. // transactions in the data phase start with DATA1 and toggle (figure 8-12, USB1.1) // Status stage uses a DATA1 PID. static uint8_t ep0_rx0_buf[EP0_SIZE] __attribute__ ((aligned (4))); static uint8_t ep0_rx1_buf[EP0_SIZE] __attribute__ ((aligned (4))); static const uint8_t *ep0_tx_ptr = NULL; static uint16_t ep0_tx_len; static uint8_t ep0_tx_bdt_bank = 0; static uint8_t ep0_tx_data_toggle = 0; //Added from https://forum.pjrc.com/archive/index.php/t-24256.html static uint8_t *ep0_rx_ptr = NULL; static uint16_t ep0_rx_len; static uint8_t ep0_rx_bdt_bank = 0; static uint8_t ep0_rx_data_toggle = 0; // uint8_t usb_rx_memory_needed = 0; volatile uint8_t usb_configuration = 0; volatile uint8_t usb_reboot_timer = 0; static void endpoint0_stall(void) { USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; } static uint8_t endpoint0_receive(uint8_t *data) { //9,26,46,f7,56 uint8_t *inc=table[index(0,RX,ep0_rx_bdt_bank)].addr; uint32_t desc=table[index(0,RX,ep0_rx_bdt_bank)].desc; uint8_t size=(desc>>16); uint8_t origsize=size; while (size--) {*data++=*inc++;} table[index(0,RX,ep0_rx_bdt_bank)].desc=BDT_DESC(EP0_SIZE,ep0_rx_data_toggle); ep0_rx_data_toggle ^= 1; ep0_rx_bdt_bank ^= 1; return origsize; } static void endpoint0_transmit(const void *data, uint32_t len) { #if 0 serial_print("tx0:"); serial_phex32((uint32_t)data); serial_print(","); serial_phex16(len); serial_print(ep0_tx_bdt_bank ? ", odd" : ", even"); serial_print(ep0_tx_data_toggle ? ", d1\n" : ", d0\n"); #endif table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data; table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle); ep0_tx_data_toggle ^= 1; ep0_tx_bdt_bank ^= 1; } static uint8_t reply_buffer[8]; static void endpoint0_ack(void) { table[index(0,TX,ep0_tx_bdt_bank)].addr=0; table[index(0,TX,ep0_tx_bdt_bank)].desc=BDT_DESC(0,ep0_tx_data_toggle); ep0_tx_data_toggle ^= 1; ep0_tx_bdt_bank ^= 1; } void wipe_usb_buffer() { volatile uint8_t *reg; uint8_t epconf; const uint8_t *cfg; reg = &USB0_ENDPT1; cfg = usb_endpoint_config_table; int i; for (i=4; i < (NUM_ENDPOINTS+1)*4; i++) { if (table[i].desc & BDT_OWN) { usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8)); } } // free all queued packets for (i=0; i < NUM_ENDPOINTS; i++) { usb_packet_t *p, *n; p = rx_first[i]; while (p) { n = p->next; usb_free(p); p = n; } rx_first[i] = NULL; rx_last[i] = NULL; p = tx_first[i]; while (p) { n = p->next; usb_free(p); p = n; } tx_first[i] = NULL; tx_last[i] = NULL; usb_rx_byte_count_data[i] = 0; switch (tx_state[i]) { case TX_STATE_EVEN_FREE: case TX_STATE_NONE_FREE_EVEN_FIRST: tx_state[i] = TX_STATE_BOTH_FREE_EVEN_FIRST; break; case TX_STATE_ODD_FREE: case TX_STATE_NONE_FREE_ODD_FIRST: tx_state[i] = TX_STATE_BOTH_FREE_ODD_FIRST; break; default: break; } } usb_rx_memory_needed = 0; for (i=1; i <= NUM_ENDPOINTS; i++) { epconf = *cfg++; *reg = epconf; reg += 4; if (epconf & USB_ENDPT_EPRXEN) { usb_packet_t *p; p = usb_malloc(); if (p) { table[index(i, RX, EVEN)].addr = p->buf; table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0); } else { table[index(i, RX, EVEN)].desc = 0; usb_rx_memory_needed++; } p = usb_malloc(); if (p) { table[index(i, RX, ODD)].addr = p->buf; table[index(i, RX, ODD)].desc = BDT_DESC(64, 1); } else { table[index(i, RX, ODD)].desc = 0; usb_rx_memory_needed++; } } table[index(i, TX, EVEN)].desc = 0; table[index(i, TX, ODD)].desc = 0; } } static void usb_setup(void) { const uint8_t *data = NULL; uint32_t datalen = 0; const usb_descriptor_list_t *list; uint32_t size; volatile uint8_t *reg; uint8_t epconf; const uint8_t *cfg; int i; switch (setup.wRequestAndType) { case 0x0500: // SET_ADDRESS break; case 0x0900: // SET_CONFIGURATION //serial_print("configure\n"); usb_configuration = setup.wValue; reg = &USB0_ENDPT1; cfg = usb_endpoint_config_table; // clear all BDT entries, free any allocated memory... for (i=4; i < (NUM_ENDPOINTS+1)*4; i++) { if (table[i].desc & BDT_OWN) { usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8)); } } // free all queued packets for (i=0; i < NUM_ENDPOINTS; i++) { usb_packet_t *p, *n; p = rx_first[i]; while (p) { n = p->next; usb_free(p); p = n; } rx_first[i] = NULL; rx_last[i] = NULL; p = tx_first[i]; while (p) { n = p->next; usb_free(p); p = n; } tx_first[i] = NULL; tx_last[i] = NULL; usb_rx_byte_count_data[i] = 0; switch (tx_state[i]) { case TX_STATE_EVEN_FREE: case TX_STATE_NONE_FREE_EVEN_FIRST: tx_state[i] = TX_STATE_BOTH_FREE_EVEN_FIRST; break; case TX_STATE_ODD_FREE: case TX_STATE_NONE_FREE_ODD_FIRST: tx_state[i] = TX_STATE_BOTH_FREE_ODD_FIRST; break; default: break; } } usb_rx_memory_needed = 0; for (i=1; i <= NUM_ENDPOINTS; i++) { epconf = *cfg++; *reg = epconf; reg += 4; if (epconf & USB_ENDPT_EPRXEN) { usb_packet_t *p; p = usb_malloc(); if (p) { table[index(i, RX, EVEN)].addr = p->buf; table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0); } else { table[index(i, RX, EVEN)].desc = 0; usb_rx_memory_needed++; } p = usb_malloc(); if (p) { table[index(i, RX, ODD)].addr = p->buf; table[index(i, RX, ODD)].desc = BDT_DESC(64, 1); } else { table[index(i, RX, ODD)].desc = 0; usb_rx_memory_needed++; } } table[index(i, TX, EVEN)].desc = 0; table[index(i, TX, ODD)].desc = 0; } break; case 0x0880: // GET_CONFIGURATION reply_buffer[0] = usb_configuration; datalen = 1; data = reply_buffer; break; case 0x0080: // GET_STATUS (device) reply_buffer[0] = 0; reply_buffer[1] = 0; datalen = 2; data = reply_buffer; break; case 0x0082: // GET_STATUS (endpoint) if (setup.wIndex > NUM_ENDPOINTS) { // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); return; } reply_buffer[0] = 0; reply_buffer[1] = 0; if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1; data = reply_buffer; datalen = 2; break; case 0x0102: // CLEAR_FEATURE (endpoint) i = setup.wIndex & 0x7F; if (i > NUM_ENDPOINTS || setup.wValue != 0) { // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); return; } (*(uint8_t *)(&USB0_ENDPT0 + i * 4)) &= ~0x02; // TODO: do we need to clear the data toggle here? break; case 0x0302: // SET_FEATURE (endpoint) i = setup.wIndex & 0x7F; if (i > NUM_ENDPOINTS || setup.wValue != 0) { // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); return; } (*(uint8_t *)(&USB0_ENDPT0 + i * 4)) |= 0x02; // TODO: do we need to clear the data toggle here? break; case 0x0680: // GET_DESCRIPTOR case 0x0681: //serial_print("desc:"); //serial_phex16(setup.wValue); //serial_print("\n"); for (list = usb_descriptor_list; 1; list++) { if (list->addr == NULL) break; //if (setup.wValue == list->wValue && //(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) { if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) { data = list->addr; if ((setup.wValue >> 8) == 3) { // for string descriptors, use the descriptor's // length field, allowing runtime configured // length. datalen = *(list->addr); } else { datalen = list->length; } #if 0 serial_print("Desc found, "); serial_phex32((uint32_t)data); serial_print(","); serial_phex16(datalen); serial_print(","); serial_phex(data[0]); serial_phex(data[1]); serial_phex(data[2]); serial_phex(data[3]); serial_phex(data[4]); serial_phex(data[5]); serial_print("\n"); #endif goto send; } } //serial_print("desc: not found\n"); endpoint0_stall(); return; #if defined(CDC_STATUS_INTERFACE) case 0x2221: // CDC_SET_CONTROL_LINE_STATE usb_cdc_line_rtsdtr_millis = systick_millis_count; usb_cdc_line_rtsdtr = setup.wValue; //serial_print("set control line state\n"); break; case 0x2321: // CDC_SEND_BREAK break; case 0x2021: // CDC_SET_LINE_CODING //serial_print("set coding, waiting...\n"); return; #endif #if defined(MTP_INTERFACE) case 0x2164: // Cancel Request (PTP spec, 5.2.1, page 8) // TODO: required by PTP spec endpoint0_stall(); return; case 0x2166: // Device Reset (PTP spec, 5.2.3, page 10) // TODO: required by PTP spec endpoint0_stall(); return; case 0x2167: // Get Device Statis (PTP spec, 5.2.4, page 10) // TODO: required by PTP spec endpoint0_stall(); return; #endif // TODO: this does not work... why? #if defined(SEREMU_INTERFACE) || defined(KEYBOARD_INTERFACE) case 0x0921: // HID SET_REPORT if (setup.wLength) { ep0_rx_ptr=setBuffer; ep0_rx_len=8; } break; case 0x0A21: // HID SET_IDLE break; case 0x0B21: // ? break; case 0x01a1: // HID GET_REPORT data = getBuffer; if (setBuffer[7] >= 0x80 && setBuffer[7] <= 0x89) { for(i=0; i<7; i++) { keyboard_buffer[i+((setBuffer[7]-0x80)*7)]=setBuffer[i]; } } // HMACSHA1 Message Types // Default Report = RD 00 00 02 02 03 03 03 05 00 // Reset/Done/ACK - Operation complete if (setBuffer[7] == 0x8f || (setBuffer[7] < 0x89 && setBuffer[7] > 0x80)) { getBuffer[1] = 0x02; getBuffer[2] = 0x02; getBuffer[3] = 0x03; getBuffer[4] = sess_counter; //slot 1 and 2 configured getBuffer[5] = 0x03; getBuffer[6] = may_block; getBuffer[7] = 0x00; getBuffer[8] = 0x00; if (setBuffer[7] == 0x8f) { for(i=0; i<80; i++) { keyboard_buffer[i]=0; } } setBuffer[7] = 0; } // Get Serial Number - https://github.com/Yubico/yubikey-personalization/blob/7b1d7130617d652359a2226de3734f0b99edd550/ykcore/ykcore.c#L154 else if (setBuffer[1] == 0x10 && setBuffer[2] == 0x6b && setBuffer[3] == 0x5b) { getBuffer[1] = 0x10; //10C8DF = Serial number 1099999 getBuffer[2] = 0xbf; getBuffer[3] = 0x91; getBuffer[4] = 0xed; getBuffer[5] = 0x45; getBuffer[6] = 0x00; getBuffer[7] = 0xc0; setBuffer[7] = 0; } else if (getBuffer[7] >= 0xa1) { // Waiting for button press if (getBuffer[8] == 0x43 || getBuffer[8] == 0xA9) { getBuffer[8]++; data = keyboard_buffer; // Send second C0 //Reset getBuffer getBuffer[1] = 0x02; getBuffer[2] = 0x02; getBuffer[3] = 0x03; getBuffer[4] = sess_counter; getBuffer[5] = 0x03; getBuffer[6] = may_block; getBuffer[7] = 0x00; getBuffer[8] = 0x00; setBuffer[7] = 0x8f; } else if (getBuffer[8]) { // Already sent first C0 getBuffer[8]++; data = keyboard_buffer + ((getBuffer[8]&0x0F)*8); } else if (keyboard_buffer[79] == 0xC9) { getBuffer[8] = 0xA0; // 10 messages to send data = keyboard_buffer; // Send 1st message (C0) } else if (keyboard_buffer[31] == 0xC3) { getBuffer[8] = 0x40; // 4 messages to send data = keyboard_buffer; // Send 1st message (C0) } } else if (setBuffer[7] == 0x89 && (getBuffer[6] == 0x05 || getBuffer[6] == 0x07)) { //Received all packets getBuffer[7] = 0x89; setBuffer[8] = 1; // Process packets } datalen = 8; goto send; endpoint0_stall(); return; // case 0xC940: #endif default: endpoint0_stall(); return; } send: //serial_print("setup send "); //serial_phex32(data); //serial_print(","); //serial_phex16(datalen); //serial_print("\n"); if (datalen > setup.wLength) datalen = setup.wLength; size = datalen; if (size > EP0_SIZE) size = EP0_SIZE; endpoint0_transmit(data, size); data += size; datalen -= size; if (datalen == 0 && size < EP0_SIZE) return; size = datalen; if (size > EP0_SIZE) size = EP0_SIZE; endpoint0_transmit(data, size); data += size; datalen -= size; if (datalen == 0 && size < EP0_SIZE) return; ep0_tx_ptr = data; ep0_tx_len = datalen; } //A bulk endpoint's toggle sequence is initialized to DATA0 when the endpoint //experiences any configuration event (configuration events are explained in //Sections 9.1.1.5 and 9.4.5). //Configuring a device or changing an alternate setting causes all of the status //and configuration values associated with endpoints in the affected interfaces //to be set to their default values. This includes setting the data toggle of //any endpoint using data toggles to the value DATA0. //For endpoints using data toggle, regardless of whether an endpoint has the //Halt feature set, a ClearFeature(ENDPOINT_HALT) request always results in the //data toggle being reinitialized to DATA0. // #define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) static void usb_control(uint32_t stat) { bdt_t *b; uint32_t pid, size; uint8_t *buf; const uint8_t *data; b = stat2bufferdescriptor(stat); pid = BDT_PID(b->desc); //count = b->desc >> 16; buf = b->addr; //serial_print("pid:"); //serial_phex(pid); //serial_print(", count:"); //serial_phex(count); //serial_print("\n"); switch (pid) { case 0x0D: // Setup received from host //serial_print("PID=Setup\n"); //if (count != 8) ; // panic? // grab the 8 byte setup info setup.word1 = *(uint32_t *)(buf); setup.word2 = *(uint32_t *)(buf + 4); // give the buffer back if ((!(setup.bmRequestType & 0x80)) && (setup.wLength>0)) { ep0_rx_bdt_bank = (stat&0x04)?0:1; table[index(0, RX, ep0_rx_bdt_bank)].desc = BDT_DESC(EP0_SIZE,DATA1); table[index(0, RX, ep0_rx_bdt_bank^1)].desc = BDT_DESC(EP0_SIZE,DATA0); ep0_rx_data_toggle = 1; } else { b->desc = BDT_DESC(EP0_SIZE, DATA1); //table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1); //table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1); // clear any leftover pending IN transactions } ep0_rx_ptr = NULL; if (ep0_tx_data_toggle) { } //if (table[index(0, TX, EVEN)].desc & 0x80) { //serial_print("leftover tx even\n"); //} //if (table[index(0, TX, ODD)].desc & 0x80) { //serial_print("leftover tx odd\n"); //} table[index(0, TX, EVEN)].desc = 0; table[index(0, TX, ODD)].desc = 0; // first IN after Setup is always DATA1 ep0_tx_data_toggle = 1; #if 0 serial_print("bmRequestType:"); serial_phex(setup.bmRequestType); serial_print(", bRequest:"); serial_phex(setup.bRequest); serial_print(", wValue:"); serial_phex16(setup.wValue); serial_print(", wIndex:"); serial_phex16(setup.wIndex); serial_print(", len:"); serial_phex16(setup.wLength); serial_print("\n"); #endif // actually "do" the setup request usb_setup(); // unfreeze the USB, now that we're ready USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit break; case 0x01: // OUT transaction received from host if (ep0_rx_ptr) { //if there is a pending OUT transfer uint8_t size=endpoint0_receive(ep0_rx_ptr); //receives current packet ep0_rx_ptr+=size; //moves pointer ahead by received byte count ep0_rx_len-=size; //decreases remaining transaction size by received byte count if (!ep0_rx_len) { //if we've got the whole thing //do whatever you need to here } } else { b->desc = BDT_DESC(EP0_SIZE, DATA1); //if no pending transfer we just free the buffer, same as we used to } break; case 0x02: //serial_print("PID=OUT\n"); #ifdef CDC_STATUS_INTERFACE if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) { int i; uint8_t *dst = (uint8_t *)usb_cdc_line_coding; //serial_print("set line coding "); for (i=0; i<7; i++) { //serial_phex(*buf); *dst++ = *buf++; } //serial_phex32(usb_cdc_line_coding[0]); //serial_print("\n"); if (usb_cdc_line_coding[0] == 134) usb_reboot_timer = 15; endpoint0_transmit(NULL, 0); } #endif #ifdef KEYBOARD_INTERFACE if (setup.word1 == 0x02000921 && setup.word2 == ((1<<16)|KEYBOARD_INTERFACE)) { keyboard_leds = buf[0]; endpoint0_transmit(NULL, 0); } #endif #ifdef SEREMU_INTERFACE if (setup.word1 == 0x03000921 && setup.word2 == ((4<<16)|SEREMU_INTERFACE) && buf[0] == 0xA9 && buf[1] == 0x45 && buf[2] == 0xC2 && buf[3] == 0x6B) { usb_reboot_timer = 5; endpoint0_transmit(NULL, 0); } #endif // give the buffer back b->desc = BDT_DESC(EP0_SIZE, DATA1); break; case 0x09: // IN transaction completed to host //serial_print("PID=IN:"); //serial_phex(stat); //serial_print("\n"); // send remaining data, if any... data = ep0_tx_ptr; if (data) { size = ep0_tx_len; if (size > EP0_SIZE) size = EP0_SIZE; endpoint0_transmit(data, size); data += size; ep0_tx_len -= size; ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL; } if (setup.bRequest == 5 && setup.bmRequestType == 0) { setup.bRequest = 0; //serial_print("set address: "); //serial_phex16(setup.wValue); //serial_print("\n"); USB0_ADDR = setup.wValue; } break; //default: //serial_print("PID=unknown:"); //serial_phex(pid); //serial_print("\n"); } USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit } usb_packet_t *usb_rx(uint32_t endpoint) { usb_packet_t *ret; endpoint--; if (endpoint >= NUM_ENDPOINTS) return NULL; __disable_irq(); ret = rx_first[endpoint]; if (ret) { rx_first[endpoint] = ret->next; usb_rx_byte_count_data[endpoint] -= ret->len; } __enable_irq(); //serial_print("rx, epidx="); //serial_phex(endpoint); //serial_print(", packet="); //serial_phex32(ret); //serial_print("\n"); return ret; } static uint32_t usb_queue_byte_count(const usb_packet_t *p) { uint32_t count=0; __disable_irq(); for ( ; p; p = p->next) { count += p->len; } __enable_irq(); return count; } // TODO: make this an inline function... /* uint32_t usb_rx_byte_count(uint32_t endpoint) { endpoint--; if (endpoint >= NUM_ENDPOINTS) return 0; return usb_rx_byte_count_data[endpoint]; //return usb_queue_byte_count(rx_first[endpoint]); } */ uint32_t usb_tx_byte_count(uint32_t endpoint) { endpoint--; if (endpoint >= NUM_ENDPOINTS) return 0; return usb_queue_byte_count(tx_first[endpoint]); } uint32_t usb_tx_packet_count(uint32_t endpoint) { const usb_packet_t *p; uint32_t count=0; endpoint--; if (endpoint >= NUM_ENDPOINTS) return 0; __disable_irq(); for (p = tx_first[endpoint]; p; p = p->next) count++; __enable_irq(); return count; } // Called from usb_free, but only when usb_rx_memory_needed > 0, indicating // receive endpoints are starving for memory. The intention is to give // endpoints needing receive memory priority over the user's code, which is // likely calling usb_malloc to obtain memory for transmitting. When the // user is creating data very quickly, their consumption could starve reception // without this prioritization. The packet buffer (input) is assigned to the // first endpoint needing memory. // void usb_rx_memory(usb_packet_t *packet) { unsigned int i; const uint8_t *cfg; cfg = usb_endpoint_config_table; //serial_print("rx_mem:"); __disable_irq(); for (i=1; i <= NUM_ENDPOINTS; i++) { if (*cfg++ & USB_ENDPT_EPRXEN) { if (table[index(i, RX, EVEN)].desc == 0) { table[index(i, RX, EVEN)].addr = packet->buf; table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0); usb_rx_memory_needed--; __enable_irq(); //serial_phex(i); //serial_print(",even\n"); return; } if (table[index(i, RX, ODD)].desc == 0) { table[index(i, RX, ODD)].addr = packet->buf; table[index(i, RX, ODD)].desc = BDT_DESC(64, 1); usb_rx_memory_needed--; __enable_irq(); //serial_phex(i); //serial_print(",odd\n"); return; } } } __enable_irq(); // we should never reach this point. If we get here, it means // usb_rx_memory_needed was set greater than zero, but no memory // was actually needed. usb_rx_memory_needed = 0; usb_free(packet); return; } //#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd)) //#define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) void usb_tx(uint32_t endpoint, usb_packet_t *packet) { bdt_t *b = &table[index(endpoint, TX, EVEN)]; uint8_t next; endpoint--; if (endpoint >= NUM_ENDPOINTS) return; __disable_irq(); //serial_print("txstate="); //serial_phex(tx_state[endpoint]); //serial_print("\n"); switch (tx_state[endpoint]) { case TX_STATE_BOTH_FREE_EVEN_FIRST: next = TX_STATE_ODD_FREE; break; case TX_STATE_BOTH_FREE_ODD_FIRST: b++; next = TX_STATE_EVEN_FREE; break; case TX_STATE_EVEN_FREE: next = TX_STATE_NONE_FREE_ODD_FIRST; break; case TX_STATE_ODD_FREE: b++; next = TX_STATE_NONE_FREE_EVEN_FIRST; break; default: if (tx_first[endpoint] == NULL) { tx_first[endpoint] = packet; } else { tx_last[endpoint]->next = packet; } tx_last[endpoint] = packet; __enable_irq(); return; } tx_state[endpoint] = next; b->addr = packet->buf; b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0); __enable_irq(); } void _reboot_Teensyduino_(void) { // TODO: initialize R0 with a code.... __asm__ volatile("bkpt"); } void usb_isr(void) { uint8_t status, stat, t; //serial_print("isr"); //status = USB0_ISTAT; //serial_phex(status); //serial_print("\n"); restart: status = USB0_ISTAT; if ((status & USB_ISTAT_SOFTOK /* 04 */ )) { if (usb_configuration) { t = usb_reboot_timer; if (t) { usb_reboot_timer = --t; if (!t) _reboot_Teensyduino_(); } #ifdef CDC_DATA_INTERFACE t = usb_cdc_transmit_flush_timer; if (t) { usb_cdc_transmit_flush_timer = --t; if (t == 0) usb_serial_flush_callback(); } #endif #ifdef SEREMU_INTERFACE t = usb_seremu_transmit_flush_timer; if (t) { usb_seremu_transmit_flush_timer = --t; if (t == 0) usb_seremu_flush_callback(); } #endif #ifdef MIDI_INTERFACE usb_midi_flush_output(); #endif #ifdef FLIGHTSIM_INTERFACE usb_flightsim_flush_callback(); #endif } USB0_ISTAT = USB_ISTAT_SOFTOK; } if ((status & USB_ISTAT_TOKDNE /* 08 */ )) { uint8_t endpoint; stat = USB0_STAT; //serial_print("token: ep="); //serial_phex(stat >> 4); //serial_print(stat & 0x08 ? ",tx" : ",rx"); //serial_print(stat & 0x04 ? ",odd\n" : ",even\n"); endpoint = stat >> 4; if (endpoint == 0) { usb_control(stat); } else { bdt_t *b = stat2bufferdescriptor(stat); usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8); #if 0 serial_print("ep:"); serial_phex(endpoint); serial_print(", pid:"); serial_phex(BDT_PID(b->desc)); serial_print(((uint32_t)b & 8) ? ", odd" : ", even"); serial_print(", count:"); serial_phex(b->desc >> 16); serial_print("\n"); #endif endpoint--; // endpoint is index to zero-based arrays if (stat & 0x08) { // transmit usb_free(packet); packet = tx_first[endpoint]; if (packet) { //serial_print("tx packet\n"); tx_first[endpoint] = packet->next; b->addr = packet->buf; switch (tx_state[endpoint]) { case TX_STATE_BOTH_FREE_EVEN_FIRST: tx_state[endpoint] = TX_STATE_ODD_FREE; break; case TX_STATE_BOTH_FREE_ODD_FIRST: tx_state[endpoint] = TX_STATE_EVEN_FREE; break; case TX_STATE_EVEN_FREE: tx_state[endpoint] = TX_STATE_NONE_FREE_ODD_FIRST; break; case TX_STATE_ODD_FREE: tx_state[endpoint] = TX_STATE_NONE_FREE_EVEN_FIRST; break; default: break; } b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0); } else { //serial_print("tx no packet\n"); switch (tx_state[endpoint]) { case TX_STATE_BOTH_FREE_EVEN_FIRST: case TX_STATE_BOTH_FREE_ODD_FIRST: break; case TX_STATE_EVEN_FREE: tx_state[endpoint] = TX_STATE_BOTH_FREE_EVEN_FIRST; break; case TX_STATE_ODD_FREE: tx_state[endpoint] = TX_STATE_BOTH_FREE_ODD_FIRST; break; default: tx_state[endpoint] = ((uint32_t)b & 8) ? TX_STATE_ODD_FREE : TX_STATE_EVEN_FREE; break; } } } else { // receive packet->len = b->desc >> 16; if (packet->len > 0) { packet->index = 0; packet->next = NULL; if (rx_first[endpoint] == NULL) { //serial_print("rx 1st, epidx="); //serial_phex(endpoint); //serial_print(", packet="); //serial_phex32((uint32_t)packet); //serial_print("\n"); rx_first[endpoint] = packet; } else { //serial_print("rx Nth, epidx="); //serial_phex(endpoint); //serial_print(", packet="); //serial_phex32((uint32_t)packet); //serial_print("\n"); rx_last[endpoint]->next = packet; } rx_last[endpoint] = packet; usb_rx_byte_count_data[endpoint] += packet->len; // TODO: implement a per-endpoint maximum # of allocated packets // so a flood of incoming data on 1 endpoint doesn't starve // the others if the user isn't reading it regularly packet = usb_malloc(); if (packet) { b->addr = packet->buf; b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0); } else { //serial_print("starving "); //serial_phex(endpoint + 1); //serial_print(((uint32_t)b & 8) ? ",odd\n" : ",even\n"); b->desc = 0; usb_rx_memory_needed++; } } else { b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0); } } } USB0_ISTAT = USB_ISTAT_TOKDNE; goto restart; } if (status & USB_ISTAT_USBRST /* 01 */ ) { //serial_print("reset\n"); // initialize BDT toggle bits USB0_CTL = USB_CTL_ODDRST; ep0_tx_bdt_bank = 0; // set up buffers to receive Setup and OUT packets table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 0); table[index(0, RX, EVEN)].addr = ep0_rx0_buf; table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 0); table[index(0, RX, ODD)].addr = ep0_rx1_buf; table[index(0, TX, EVEN)].desc = 0; table[index(0, TX, ODD)].desc = 0; // activate endpoint 0 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; // clear all ending interrupts USB0_ERRSTAT = 0xFF; USB0_ISTAT = 0xFF; // set the address to zero during enumeration USB0_ADDR = 0; // enable other interrupts USB0_ERREN = 0xFF; USB0_INTEN = USB_INTEN_TOKDNEEN | USB_INTEN_SOFTOKEN | USB_INTEN_STALLEN | USB_INTEN_ERROREN | USB_INTEN_USBRSTEN | USB_INTEN_SLEEPEN; // is this necessary? USB0_CTL = USB_CTL_USBENSOFEN; return; } if ((status & USB_ISTAT_STALL /* 80 */ )) { //serial_print("stall:\n"); USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; USB0_ISTAT = USB_ISTAT_STALL; } if ((status & USB_ISTAT_ERROR /* 02 */ )) { uint8_t err = USB0_ERRSTAT; USB0_ERRSTAT = err; //serial_print("err:"); //serial_phex(err); //serial_print("\n"); USB0_ISTAT = USB_ISTAT_ERROR; } if ((status & USB_ISTAT_SLEEP /* 10 */ )) { //serial_print("sleep\n"); USB0_ISTAT = USB_ISTAT_SLEEP; } } void usb_init(void) { int i; //serial_begin(BAUD2DIV(115200)); //serial_print("usb_init\n"); usb_init_serialnumber(); for (i=0; i <= NUM_ENDPOINTS*4; i++) { table[i].desc = 0; table[i].addr = 0; } // this basically follows the flowchart in the Kinetis // Quick Reference User Guide, Rev. 1, 03/2012, page 141 // assume 48 MHz clock already running // SIM - enable clock SIM_SCGC4 |= SIM_SCGC4_USBOTG; #ifdef HAS_KINETIS_MPU MPU_RGDAAC0 |= 0x03000000; #endif // reset USB module //USB0_USBTRC0 = USB_USBTRC_USBRESET; //while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end // set desc table base addr USB0_BDTPAGE1 = ((uint32_t)table) >> 8; USB0_BDTPAGE2 = ((uint32_t)table) >> 16; USB0_BDTPAGE3 = ((uint32_t)table) >> 24; // clear all ISR flags USB0_ISTAT = 0xFF; USB0_ERRSTAT = 0xFF; USB0_OTGISTAT = 0xFF; //USB0_USBTRC0 |= 0x40; // undocumented bit // enable USB USB0_CTL = USB_CTL_USBENSOFEN; USB0_USBCTRL = 0; // enable reset interrupt USB0_INTEN = USB_INTEN_USBRSTEN; // enable interrupt in NVIC... NVIC_SET_PRIORITY(IRQ_USBOTG, 112); NVIC_ENABLE_IRQ(IRQ_USBOTG); // enable d+ pullup USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG; } #else // F_CPU < 20 MHz && defined(NUM_ENDPOINTS) void usb_init(void) { } #endif // F_CPU >= 20 MHz && defined(NUM_ENDPOINTS) ================================================ FILE: usb_dev.h ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef _usb_dev_h_ #define _usb_dev_h_ #define USB_DESC_LIST_DEFINE #include "usb_desc.h" #if F_CPU >= 20000000 && !defined(USB_DISABLED) // This header is NOT meant to be included when compiling // user sketches in Arduino. The low-level functions // provided by usb_dev.c are meant to be called only by // code which provides higher-level interfaces to the user. #include "usb_mem.h" #ifdef __cplusplus extern "C" { #endif extern uint8_t setBuffer[9]; extern uint8_t getBuffer[9]; extern uint8_t keyboard_buffer[80]; extern uint8_t sess_counter; extern uint8_t may_block; extern void wipe_usb_buffer(); void usb_init(void); void usb_init_serialnumber(void); void usb_isr(void); usb_packet_t *usb_rx(uint32_t endpoint); uint32_t usb_tx_byte_count(uint32_t endpoint); uint32_t usb_tx_packet_count(uint32_t endpoint); void usb_tx(uint32_t endpoint, usb_packet_t *packet); void usb_tx_isr(uint32_t endpoint, usb_packet_t *packet); extern volatile uint8_t usb_configuration; extern uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS]; static inline uint32_t usb_rx_byte_count(uint32_t endpoint) __attribute__((always_inline)); static inline uint32_t usb_rx_byte_count(uint32_t endpoint) { endpoint--; if (endpoint >= NUM_ENDPOINTS) return 0; return usb_rx_byte_count_data[endpoint]; } #ifdef CDC_DATA_INTERFACE extern uint32_t usb_cdc_line_coding[2]; extern volatile uint32_t usb_cdc_line_rtsdtr_millis; extern volatile uint32_t systick_millis_count; extern volatile uint8_t usb_cdc_line_rtsdtr; extern volatile uint8_t usb_cdc_transmit_flush_timer; extern void usb_serial_flush_callback(void); #endif #ifdef SEREMU_INTERFACE extern volatile uint8_t usb_seremu_transmit_flush_timer; extern void usb_seremu_flush_callback(void); #endif #ifdef KEYBOARD_INTERFACE extern uint8_t keyboard_modifier_keys; extern uint8_t keyboard_keys[6]; extern uint8_t keyboard_protocol; extern uint8_t keyboard_idle_config; extern uint8_t keyboard_idle_count; extern volatile uint8_t keyboard_leds; #endif #ifdef MIDI_INTERFACE extern void usb_midi_flush_output(void); #endif #ifdef FLIGHTSIM_INTERFACE extern void usb_flightsim_flush_callback(void); #endif #ifdef __cplusplus } #endif #else // F_CPU < 20000000 #ifdef __cplusplus extern "C" { #endif void usb_init(void); #ifdef __cplusplus } #endif #endif // F_CPU #endif ================================================ FILE: usb_keyboard.c ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "usb_dev.h" #include "usb_keyboard.h" #include "core_pins.h" // for yield() #include "keylayouts.h" //#include "HardwareSerial.h" #include // for memcpy() #ifdef KEYBOARD_INTERFACE // defined by usb_dev.h -> usb_desc.h #if F_CPU >= 20000000 // which modifier keys are currently pressed // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui uint8_t keyboard_modifier_keys=0; // which media keys are currently pressed uint8_t keyboard_media_keys=0; // which keys are currently pressed, up to 6 keys may be down at once uint8_t keyboard_keys[6]={0,0,0,0,0,0}; // protocol setting from the host. We use exactly the same report // either way, so this variable only stores the setting since we // are required to be able to report which setting is in use. uint8_t keyboard_protocol=1; // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed uint8_t keyboard_idle_config=125; // count until idle timeout uint8_t keyboard_idle_count=0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana volatile uint8_t keyboard_leds=0; static KEYCODE_TYPE unicode_to_keycode(uint16_t cpoint); static void write_key(KEYCODE_TYPE keycode); static uint8_t keycode_to_modifier(KEYCODE_TYPE keycode); static uint8_t keycode_to_key(KEYCODE_TYPE keycode); static void usb_keyboard_press_key(uint8_t key, uint8_t modifier); static void usb_keyboard_release_key(uint8_t key, uint8_t modifier); static KEYCODE_TYPE deadkey_to_keycode(KEYCODE_TYPE keycode); extern uint16_t SHIFT_MASK; extern uint16_t ALTGR_MASK; extern uint16_t RCTRL_MASK; extern uint16_t KEY_NON_US_100; extern uint16_t DEADKEYS_MASK; extern uint16_t CIRCUMFLEX_BITS; extern uint16_t ACUTE_ACCENT_BITS; extern uint16_t GRAVE_ACCENT_BITS; extern uint16_t TILDE_BITS; extern uint16_t DIAERESIS_BITS; extern uint16_t DEADKEY_CIRCUMFLEX; extern uint16_t DEADKEY_ACUTE_ACCENT; extern uint16_t DEADKEY_GRAVE_ACCENT; extern uint16_t DEADKEY_TILDE; extern uint16_t DEADKEY_DIAERESIS; extern uint16_t UNICODE_20AC; extern uint16_t CEDILLA_BITS; extern uint16_t DEADKEY_CEDILLA; extern uint16_t RING_ABOVE_BITS; extern uint16_t DEADKEY_RING_ABOVE; extern uint16_t DEGREE_SIGN_BITS; extern uint16_t CARON_BITS; extern uint16_t BREVE_BITS; extern uint16_t OGONEK_BITS; extern uint16_t DOT_ABOVE_BITS; extern uint16_t DOUBLE_ACUTE_BITS; extern uint16_t DEADKEY_DEGREE_SIGN; extern uint16_t DEADKEY_CARON; extern uint16_t DEADKEY_BREVE; extern uint16_t DEADKEY_OGONEK; extern uint16_t DEADKEY_DOT_ABOVE; extern uint16_t DEADKEY_DOUBLE_ACUTE; extern uint16_t UNICODE_EXTRA0A; extern uint16_t KEYCODE_EXTRA0A; extern uint16_t ISO_8859_1_A0; extern uint16_t UNICODE_EXTRA00; extern uint16_t UNICODE_EXTRA01; extern uint16_t UNICODE_EXTRA02; extern uint16_t UNICODE_EXTRA03; extern uint16_t UNICODE_EXTRA04; extern uint16_t UNICODE_EXTRA05; extern uint16_t UNICODE_EXTRA06; extern uint16_t UNICODE_EXTRA07; extern uint16_t UNICODE_EXTRA08; extern uint16_t UNICODE_EXTRA09; extern uint16_t KEYCODE_EXTRA00; extern uint16_t KEYCODE_EXTRA01; extern uint16_t KEYCODE_EXTRA02; extern uint16_t KEYCODE_EXTRA03; extern uint16_t KEYCODE_EXTRA04; extern uint16_t KEYCODE_EXTRA05; extern uint16_t KEYCODE_EXTRA06; extern uint16_t KEYCODE_EXTRA07; extern uint16_t KEYCODE_EXTRA08; extern uint16_t KEYCODE_EXTRA09; extern uint16_t KEYCODE_MASK; // Step #1, decode UTF8 to Unicode code points // void usb_keyboard_write(uint8_t c) { static int utf8_state=0; static uint16_t unicode_wchar=0; if (c < 0x80) { // single byte encoded, 0x00 to 0x7F utf8_state = 0; usb_keyboard_write_unicode(c); } else if (c < 0xC0) { // 2nd, 3rd or 4th byte, 0x80 to 0xBF c &= 0x3F; if (utf8_state == 1) { utf8_state = 0; usb_keyboard_write_unicode(unicode_wchar | c); } else if (utf8_state == 2) { unicode_wchar |= ((uint16_t)c << 6); utf8_state = 1; } } else if (c < 0xE0) { // begin 2 byte sequence, 0xC2 to 0xDF // or illegal 2 byte sequence, 0xC0 to 0xC1 unicode_wchar = (uint16_t)(c & 0x1F) << 6; utf8_state = 1; } else if (c < 0xF0) { // begin 3 byte sequence, 0xE0 to 0xEF unicode_wchar = (uint16_t)(c & 0x0F) << 12; utf8_state = 2; } else { // begin 4 byte sequence (not supported), 0xF0 to 0xF4 // or illegal, 0xF5 to 0xFF utf8_state = 255; } } // Step #2: translate Unicode code point to keystroke sequence // static KEYCODE_TYPE unicode_to_keycode(uint16_t cpoint) { // Unicode code points beyond U+FFFF are not supported // technically this input should probably be called UCS-2 if (cpoint < 32) { if (cpoint == 10) return KEY_ENTER & KEYCODE_MASK; if (cpoint == 11) return KEY_TAB & KEYCODE_MASK; return 0; } if (cpoint < 128) { return keycodes_ascii[cpoint - 0x20]; } if (ISO_8859_1_A0) { if (cpoint >= 0xA0 && cpoint < 0x100) { return keycodes_iso_8859_1[cpoint - 0xA0]; } } //#ifdef UNICODE_20AC //if (cpoint == 0x20AC) return UNICODE_20AC & 0x3FFF; //#endif if (KEYCODE_EXTRA00) if (cpoint == UNICODE_EXTRA00) return (KEYCODE_EXTRA00) & 0x3FFF; if (KEYCODE_EXTRA01) if (cpoint == UNICODE_EXTRA01) return (KEYCODE_EXTRA01) & 0x3FFF; if (KEYCODE_EXTRA02) if (cpoint == UNICODE_EXTRA02) return (KEYCODE_EXTRA02) & 0x3FFF; if (KEYCODE_EXTRA03) if (cpoint == UNICODE_EXTRA03) return (KEYCODE_EXTRA03) & 0x3FFF; if (KEYCODE_EXTRA04) if (cpoint == UNICODE_EXTRA04) return (KEYCODE_EXTRA04) & 0x3FFF; if (KEYCODE_EXTRA05) if (cpoint == UNICODE_EXTRA05) return (KEYCODE_EXTRA05) & 0x3FFF; if (KEYCODE_EXTRA06) if (cpoint == UNICODE_EXTRA06) return (KEYCODE_EXTRA06) & 0x3FFF; if (KEYCODE_EXTRA07) if (cpoint == UNICODE_EXTRA07) return (KEYCODE_EXTRA07) & 0x3FFF; if (KEYCODE_EXTRA08) if (cpoint == UNICODE_EXTRA08) return (KEYCODE_EXTRA08) & 0x3FFF; if (KEYCODE_EXTRA09) if (cpoint == UNICODE_EXTRA09) return (KEYCODE_EXTRA09) & 0x3FFF; if (KEYCODE_EXTRA0A) if (cpoint == UNICODE_EXTRA0A) return (KEYCODE_EXTRA0A) & 0x3FFF; return 0; } // Step #3: execute keystroke sequence // static KEYCODE_TYPE deadkey_to_keycode(KEYCODE_TYPE keycode) { if(DEADKEYS_MASK) { keycode &= DEADKEYS_MASK; if (keycode == 0) return 0; if(ACUTE_ACCENT_BITS) if (keycode == ACUTE_ACCENT_BITS) return DEADKEY_ACUTE_ACCENT; if(CEDILLA_BITS) if (keycode == CEDILLA_BITS) return DEADKEY_CEDILLA; if(CIRCUMFLEX_BITS) if (keycode == CIRCUMFLEX_BITS) return DEADKEY_CIRCUMFLEX; if(DIAERESIS_BITS) if (keycode == DIAERESIS_BITS) return DEADKEY_DIAERESIS; if(GRAVE_ACCENT_BITS) if (keycode == GRAVE_ACCENT_BITS) return DEADKEY_GRAVE_ACCENT; if(TILDE_BITS) if (keycode == TILDE_BITS) return DEADKEY_TILDE; if(RING_ABOVE_BITS) if (keycode == RING_ABOVE_BITS) return DEADKEY_RING_ABOVE; if(DEGREE_SIGN_BITS) if (keycode == DEGREE_SIGN_BITS) return DEADKEY_DEGREE_SIGN; if(CARON_BITS) if (keycode == CARON_BITS) return DEADKEY_CARON; if(BREVE_BITS) if (keycode == BREVE_BITS) return DEADKEY_BREVE; if(OGONEK_BITS) if (keycode == OGONEK_BITS) return DEADKEY_OGONEK; if(DOT_ABOVE_BITS) if (keycode == DOT_ABOVE_BITS) return DEADKEY_DOT_ABOVE; if(DOUBLE_ACUTE_BITS) if (keycode == DOUBLE_ACUTE_BITS) return DEADKEY_DOUBLE_ACUTE; } return 0; } void usb_keyboard_write_unicode(uint16_t cpoint) { KEYCODE_TYPE keycode; keycode = unicode_to_keycode(cpoint); if (keycode) { if(DEADKEYS_MASK) { KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode); if (deadkeycode) write_key(deadkeycode); } write_key(keycode); } } // Step #4: do each keystroke // static void write_key(KEYCODE_TYPE keycode) { /* uint8_t key, modifier=0; #ifdef SHIFT_MASK if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT; #endif #ifdef ALTGR_MASK if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT; #endif #ifdef RCTRL_MASK if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL; #endif key = keycode & 0x3F; #ifdef KEY_NON_US_100 if (key == KEY_NON_US_100) key = 100; #endif usb_keyboard_press(key, modifier); */ usb_keyboard_press(keycode_to_key(keycode), keycode_to_modifier(keycode)); } static uint8_t keycode_to_modifier(KEYCODE_TYPE keycode) { uint8_t modifier=0; if (SHIFT_MASK) if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT; if (ALTGR_MASK) if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT; if (RCTRL_MASK) if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL; return modifier; } static uint8_t keycode_to_key(KEYCODE_TYPE keycode) { uint8_t key = keycode & 0x3F; if (KEY_NON_US_100) if (key == KEY_NON_US_100) key = 100; return key; } // Input can be: // 32 - 127 ASCII direct (U+0020 to U+007F) <-- uses layout // 128 - 0xC1FF Unicode direct (U+0080 to U+C1FF) <-- uses layout // 0xC200 - 0xDFFF Unicode UTF8 packed (U+0080 to U+07FF) <-- uses layout // 0xE000 - 0xE0FF Modifier key (bitmap, 8 keys, shift/ctrl/alt/gui) // 0xE200 - 0xE2FF System key (HID usage code, within usage page 1) // 0xE400 - 0xE7FF Media/Consumer key (HID usage code, within usage page 12) // 0xF000 - 0xFFFF Normal key (HID usage code, within usage page 7) void usb_keyboard_press_keycode(uint16_t n) { uint8_t key, mod, msb, modrestore=0; KEYCODE_TYPE keycode; KEYCODE_TYPE deadkeycode; msb = n >> 8; if (msb >= 0xC2) { if (msb <= 0xDF) { n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6); } else if (msb == 0xF0) { usb_keyboard_press_key(n, 0); return; } else if (msb == 0xE0) { usb_keyboard_press_key(0, n); return; #ifdef KEYMEDIA_INTERFACE } else if (msb == 0xE2) { // TODO: system keys return; } else if (msb >= 0xE4 && msb <= 0xE7) { // TODO: media/consumer keys return; #endif } else { return; } } keycode = unicode_to_keycode(n); if (!keycode) return; if (DEADKEYS_MASK) { deadkeycode = deadkey_to_keycode(keycode); if (deadkeycode) { modrestore = keyboard_modifier_keys; if (modrestore) { keyboard_modifier_keys = 0; usb_keyboard_send(); } // TODO: test if operating systems recognize // deadkey sequences when other keys are held mod = keycode_to_modifier(deadkeycode); key = keycode_to_key(deadkeycode); usb_keyboard_press_key(key, mod); usb_keyboard_release_key(key, mod); } } mod = keycode_to_modifier(keycode); key = keycode_to_key(keycode); usb_keyboard_press_key(key, mod | modrestore); } void usb_keyboard_release_keycode(uint16_t n) { uint8_t key, mod, msb; msb = n >> 8; if (msb >= 0xC2) { if (msb <= 0xDF) { n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6); } else if (msb == 0xF0) { usb_keyboard_release_key(n, 0); return; } else if (msb == 0xE0) { usb_keyboard_release_key(0, n); return; #ifdef KEYMEDIA_INTERFACE } else if (msb == 0xE2) { // TODO: system keys return; } else if (msb >= 0xE4 && msb <= 0xE7) { // TODO: media/consumer keys return; #endif } else { return; } } KEYCODE_TYPE keycode = unicode_to_keycode(n); if (!keycode) return; mod = keycode_to_modifier(keycode); key = keycode_to_key(keycode); usb_keyboard_release_key(key, mod); } static void usb_keyboard_press_key(uint8_t key, uint8_t modifier) { int i, send_required = 0; if (modifier) { if ((keyboard_modifier_keys & modifier) != modifier) { keyboard_modifier_keys |= modifier; send_required = 1; usb_keyboard_send(); // SEND MODKEY MULTIPLE TIMES, FIXES RDP ISSUE usb_keyboard_send(); usb_keyboard_send(); usb_keyboard_send(); usb_keyboard_send(); } } if (key) { for (i=0; i < 6; i++) { if (keyboard_keys[i] == key) goto end; } for (i=0; i < 6; i++) { if (keyboard_keys[i] == 0) { keyboard_keys[i] = key; send_required = 1; goto end; } } } end: if (send_required) usb_keyboard_send(); } static void usb_keyboard_release_key(uint8_t key, uint8_t modifier) { int i, send_required = 0; if (modifier) { if ((keyboard_modifier_keys & modifier) != 0) { keyboard_modifier_keys &= ~modifier; send_required = 1; usb_keyboard_send(); // SEND MODKEY MULTIPLE TIMES usb_keyboard_send(); usb_keyboard_send(); usb_keyboard_send(); usb_keyboard_send(); } } if (key) { for (i=0; i < 6; i++) { if (keyboard_keys[i] == key) { keyboard_keys[i] = 0; send_required = 1; } } } if (send_required) usb_keyboard_send(); } void usb_keyboard_release_all(void) { uint8_t i, anybits; anybits = keyboard_modifier_keys; keyboard_modifier_keys = 0; anybits |= keyboard_media_keys; keyboard_media_keys = 0; for (i=0; i < 6; i++) { anybits |= keyboard_keys[i]; keyboard_keys[i] = 0; } if (anybits) usb_keyboard_send(); } int usb_keyboard_press(uint8_t key, uint8_t modifier) { int r; keyboard_modifier_keys = modifier; keyboard_keys[0] = key; keyboard_keys[1] = 0; keyboard_keys[2] = 0; keyboard_keys[3] = 0; keyboard_keys[4] = 0; keyboard_keys[5] = 0; r = usb_keyboard_send(); if (r) return r; keyboard_modifier_keys = 0; keyboard_keys[0] = 0; return usb_keyboard_send(); } // Maximum number of transmit packets to queue so we don't starve other endpoints for memory #define TX_PACKET_LIMIT 4 static uint8_t transmit_previous_timeout=0; // When the PC isn't listening, how long do we wait before discarding data? #define TX_TIMEOUT_MSEC 50 #if F_CPU == 168000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100) #elif F_CPU == 144000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932) #elif F_CPU == 120000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764) #elif F_CPU == 96000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) #elif F_CPU == 72000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) #elif F_CPU == 48000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) #elif F_CPU == 24000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) #endif // send the contents of keyboard_keys and keyboard_modifier_keys int usb_keyboard_send(void) { #if 0 serial_print("Send:"); serial_phex(keyboard_modifier_keys); serial_phex(keyboard_keys[0]); serial_phex(keyboard_keys[1]); serial_phex(keyboard_keys[2]); serial_phex(keyboard_keys[3]); serial_phex(keyboard_keys[4]); serial_phex(keyboard_keys[5]); serial_print("\n"); #endif #if 1 uint32_t wait_count=0; usb_packet_t *tx_packet; while (1) { if (!usb_configuration) { return -1; } if (usb_tx_packet_count(KEYBOARD_ENDPOINT) < TX_PACKET_LIMIT) { tx_packet = usb_malloc(); if (tx_packet) break; } if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { transmit_previous_timeout = 1; return -1; } yield(); } *(tx_packet->buf) = keyboard_modifier_keys; *(tx_packet->buf + 1) = keyboard_media_keys; memcpy(tx_packet->buf + 2, keyboard_keys, 6); tx_packet->len = 8; usb_tx(KEYBOARD_ENDPOINT, tx_packet); #endif return 0; } #endif // F_CPU #endif // KEYBOARD_INTERFACE ================================================ FILE: usb_rawhid.c ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "usb_dev.h" #include "usb_rawhid.h" #include "core_pins.h" // for yield(), millis() #include // for memcpy() //#include "HardwareSerial.h" #ifdef RAWHID_INTERFACE // defined by usb_dev.h -> usb_desc.h #if F_CPU >= 20000000 int usb_rawhid_recv(void *buffer, uint32_t timeout) { usb_packet_t *rx_packet; uint32_t begin = millis(); uint8_t useinterface = 0; while (1) { if (!usb_configuration) return -1; rx_packet = usb_rx(RAWHID_RX_ENDPOINT); if (rx_packet) { useinterface=1; break; } rx_packet = usb_rx(RAWHID_RX_ENDPOINT2); if (rx_packet) { useinterface=2; break; } if (millis() - begin > timeout || !timeout) return 0; yield(); } memcpy(buffer, rx_packet->buf, RAWHID_RX_SIZE); usb_free(rx_packet); return useinterface; } int usb_rawhid_available(void) { uint32_t count; if (!usb_configuration) return 0; count = usb_rx_byte_count(RAWHID_RX_ENDPOINT); return count; } // Maximum number of transmit packets to queue so we don't starve other endpoints for memory #define TX_PACKET_LIMIT 4 int usb_rawhid_send(const void *buffer, uint32_t timeout) { usb_packet_t *tx_packet; uint32_t begin = millis(); while (1) { if (!usb_configuration) return -1; if (usb_tx_packet_count(RAWHID_TX_ENDPOINT) < TX_PACKET_LIMIT) { tx_packet = usb_malloc(); if (tx_packet) break; } if (millis() - begin > timeout) return 0; yield(); } memcpy(tx_packet->buf, buffer, RAWHID_TX_SIZE); tx_packet->len = RAWHID_TX_SIZE; usb_tx(RAWHID_TX_ENDPOINT, tx_packet); return RAWHID_TX_SIZE; } int usb_rawhid_send2(const void *buffer, uint32_t timeout) { usb_packet_t *tx_packet; uint32_t begin = millis(); while (1) { if (!usb_configuration) return -1; if (usb_tx_packet_count(RAWHID_TX_ENDPOINT2) < TX_PACKET_LIMIT) { tx_packet = usb_malloc(); if (tx_packet) break; } if (millis() - begin > timeout) return 0; yield(); } memcpy(tx_packet->buf, buffer, RAWHID_TX_SIZE); tx_packet->len = RAWHID_TX_SIZE; usb_tx(RAWHID_TX_ENDPOINT2, tx_packet); return RAWHID_TX_SIZE; } #endif // F_CPU #endif // RAWHID_INTERFACE ================================================ FILE: usb_rawhid.h ================================================ /* Modifications * Copyright (c) 2015-2020, CryptoTrust LLC. * All rights reserved. * * Author : Tim Steiner * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 4. The names "OnlyKey" and "CryptoTrust" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * admin@crp.to. * * 5. Products derived from this software may not be called "OnlyKey" * nor may "OnlyKey" or "CryptoTrust" appear in their names without * specific prior written permission. For written permission, please * contact admin@crp.to. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by CryptoTrust LLC. for * the OnlyKey Project (https://www.crp.to/ok)" * * 7. Redistributions in any form must be accompanied by information on * how to obtain complete source code for this software and any * accompanying software that uses this software. The source code * must either be included in the distribution or be available for * no more than the cost of distribution plus a nominal fee, and must * be freely redistributable under reasonable conditions. For a * binary file, complete source code means the source code for all * modules it contains. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS * ARE GRANTED BY THIS LICENSE. IF SOFTWARE RECIPIENT INSTITUTES PATENT * LITIGATION AGAINST ANY ENTITY (INCLUDING A CROSS-CLAIM OR COUNTERCLAIM * IN A LAWSUIT) ALLEGING THAT THIS SOFTWARE (INCLUDING COMBINATIONS OF THE * SOFTWARE WITH OTHER SOFTWARE OR HARDWARE) INFRINGES SUCH SOFTWARE * RECIPIENT'S PATENT(S), THEN SUCH SOFTWARE RECIPIENT'S RIGHTS GRANTED BY * THIS LICENSE SHALL TERMINATE AS OF THE DATE SUCH LITIGATION IS FILED. IF * ANY PROVISION OF THIS AGREEMENT IS INVALID OR UNENFORCEABLE UNDER * APPLICABLE LAW, IT SHALL NOT AFFECT THE VALIDITY OR ENFORCEABILITY OF THE * REMAINDER OF THE TERMS OF THIS AGREEMENT, AND WITHOUT FURTHER ACTION * BY THE PARTIES HERETO, SUCH PROVISION SHALL BE REFORMED TO THE MINIMUM * EXTENT NECESSARY TO MAKE SUCH PROVISION VALID AND ENFORCEABLE. ALL * SOFTWARE RECIPIENT'S RIGHTS UNDER THIS AGREEMENT SHALL TERMINATE IF IT * FAILS TO COMPLY WITH ANY OF THE MATERIAL TERMS OR CONDITIONS OF THIS * AGREEMENT AND DOES NOT CURE SUCH FAILURE IN A REASONABLE PERIOD OF * TIME AFTER BECOMING AWARE OF SUCH NONCOMPLIANCE. THIS SOFTWARE IS * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef USBrawhid_h_ #define USBrawhid_h_ #include "usb_desc.h" #if defined(RAWHID_INTERFACE) #include // C language implementation #ifdef __cplusplus extern "C" { #endif int usb_rawhid_recv(void *buffer, uint32_t timeout); int usb_rawhid_available(void); int usb_rawhid_send(const void *buffer, uint32_t timeout); int usb_rawhid_send2(const void *buffer, uint32_t timeout); #ifdef __cplusplus } #endif // C++ interface #ifdef __cplusplus class usb_rawhid_class { public: int available(void) {return usb_rawhid_available(); } int recv(void *buffer, uint16_t timeout) { return usb_rawhid_recv(buffer, timeout); } int send(const void *buffer, uint16_t timeout) { return usb_rawhid_send(buffer, timeout); } int send2(const void *buffer, uint16_t timeout) { return usb_rawhid_send2(buffer, timeout); } }; extern usb_rawhid_class RawHID; #endif // __cplusplus #endif // RAWHID_INTERFACE #endif // USBrawhid_h_