decompose.c (6905B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include "keyboard.h" 21 22/** 23 * The X11 keysym for the dead key which types a grave (`). 24 */ 25#define DEAD_GRAVE 0xFE50 26 27/** 28 * The X11 keysym for the dead key which types an acute (´). Note that this is 29 * NOT equivalent to an apostrophe or single quote. 30 */ 31#define DEAD_ACUTE 0xFE51 32 33/** 34 * The X11 keysym for the dead key which types a circumflex/caret (^). 35 */ 36#define DEAD_CIRCUMFLEX 0xFE52 37 38/** 39 * The X11 keysym for the dead key which types a tilde (~). 40 */ 41#define DEAD_TILDE 0xFE53 42 43/** 44 * The X11 keysym for the dead key which types a dieresis/umlaut (¨). 45 */ 46#define DEAD_DIERESIS 0xFE57 47 48/** 49 * The X11 keysym for the dead key which types an abovering (˚). Note that this 50 * is NOT equivalent to the degree symbol. 51 */ 52#define DEAD_ABOVERING 0xFE58 53 54/** 55 * The decomposed form of a key that can be typed using two keypresses: a dead 56 * key followed by a base key. For example, on a keyboard which lacks a single 57 * dedicated key for doing the same, "ó" would be typed using the dead acute 58 * key followed by the "o" key. The dead key and base key are pressed and 59 * released in sequence; they are not held down. 60 */ 61typedef struct guac_rdp_decomposed_key { 62 63 /** 64 * The keysym of the dead key which must first be pressed and released to 65 * begin typing the desired character. The dead key defines the diacritic 66 * which will be applied to the character typed by the base key. 67 */ 68 int dead_keysym; 69 70 /** 71 * The keysym of the base key which must be pressed and released to finish 72 * typing the desired character. The base key defines the normal form of 73 * the character (the form which lacks any diacritic) to which the 74 * diacritic defined by the previously-pressed dead key will be applied. 75 */ 76 int base_keysym; 77 78} guac_rdp_decomposed_key; 79 80/** 81 * A lookup table of all known decomposed forms of various keysyms. Keysyms map 82 * directly to entries within this table. A keysym which has no entry within 83 * this table does not have a defined decomposed form (or at least does not 84 * have a decomposed form relevant to RDP). 85 */ 86guac_rdp_decomposed_key guac_rdp_decomposed_keys[256] = { 87 88 /* ^ */ [0x005E] = { DEAD_CIRCUMFLEX, ' ' }, 89 /* ` */ [0x0060] = { DEAD_GRAVE, ' ' }, 90 /* ~ */ [0x007E] = { DEAD_TILDE, ' ' }, 91 /* ¨ */ [0x00A8] = { DEAD_DIERESIS, ' ' }, 92 /* ´ */ [0x00B4] = { DEAD_ACUTE, ' ' }, 93 /* À */ [0x00C0] = { DEAD_GRAVE, 'A' }, 94 /* Á */ [0x00C1] = { DEAD_ACUTE, 'A' }, 95 /* Â */ [0x00C2] = { DEAD_CIRCUMFLEX, 'A' }, 96 /* Ã */ [0x00C3] = { DEAD_TILDE, 'A' }, 97 /* Ä */ [0x00C4] = { DEAD_DIERESIS, 'A' }, 98 /* Å */ [0x00C5] = { DEAD_ABOVERING, 'A' }, 99 /* È */ [0x00C8] = { DEAD_GRAVE, 'E' }, 100 /* É */ [0x00C9] = { DEAD_ACUTE, 'E' }, 101 /* Ê */ [0x00CA] = { DEAD_CIRCUMFLEX, 'E' }, 102 /* Ë */ [0x00CB] = { DEAD_DIERESIS, 'E' }, 103 /* Ì */ [0x00CC] = { DEAD_GRAVE, 'I' }, 104 /* Í */ [0x00CD] = { DEAD_ACUTE, 'I' }, 105 /* Î */ [0x00CE] = { DEAD_CIRCUMFLEX, 'I' }, 106 /* Ï */ [0x00CF] = { DEAD_DIERESIS, 'I' }, 107 /* Ñ */ [0x00D1] = { DEAD_TILDE, 'N' }, 108 /* Ò */ [0x00D2] = { DEAD_GRAVE, 'O' }, 109 /* Ó */ [0x00D3] = { DEAD_ACUTE, 'O' }, 110 /* Ô */ [0x00D4] = { DEAD_CIRCUMFLEX, 'O' }, 111 /* Õ */ [0x00D5] = { DEAD_TILDE, 'O' }, 112 /* Ö */ [0x00D6] = { DEAD_DIERESIS, 'O' }, 113 /* Ù */ [0x00D9] = { DEAD_GRAVE, 'U' }, 114 /* Ú */ [0x00DA] = { DEAD_ACUTE, 'U' }, 115 /* Û */ [0x00DB] = { DEAD_CIRCUMFLEX, 'U' }, 116 /* Ü */ [0x00DC] = { DEAD_DIERESIS, 'U' }, 117 /* Ý */ [0x00DD] = { DEAD_ACUTE, 'Y' }, 118 /* à */ [0x00E0] = { DEAD_GRAVE, 'a' }, 119 /* á */ [0x00E1] = { DEAD_ACUTE, 'a' }, 120 /* â */ [0x00E2] = { DEAD_CIRCUMFLEX, 'a' }, 121 /* ã */ [0x00E3] = { DEAD_TILDE, 'a' }, 122 /* ä */ [0x00E4] = { DEAD_DIERESIS, 'a' }, 123 /* å */ [0x00E5] = { DEAD_ABOVERING, 'a' }, 124 /* è */ [0x00E8] = { DEAD_GRAVE, 'e' }, 125 /* é */ [0x00E9] = { DEAD_ACUTE, 'e' }, 126 /* ê */ [0x00EA] = { DEAD_CIRCUMFLEX, 'e' }, 127 /* ë */ [0x00EB] = { DEAD_DIERESIS, 'e' }, 128 /* ì */ [0x00EC] = { DEAD_GRAVE, 'i' }, 129 /* í */ [0x00ED] = { DEAD_ACUTE, 'i' }, 130 /* î */ [0x00EE] = { DEAD_CIRCUMFLEX, 'i' }, 131 /* ï */ [0x00EF] = { DEAD_DIERESIS, 'i' }, 132 /* ñ */ [0x00F1] = { DEAD_TILDE, 'n' }, 133 /* ò */ [0x00F2] = { DEAD_GRAVE, 'o' }, 134 /* ó */ [0x00F3] = { DEAD_ACUTE, 'o' }, 135 /* ô */ [0x00F4] = { DEAD_CIRCUMFLEX, 'o' }, 136 /* õ */ [0x00F5] = { DEAD_TILDE, 'o' }, 137 /* ö */ [0x00F6] = { DEAD_DIERESIS, 'o' }, 138 /* ù */ [0x00F9] = { DEAD_GRAVE, 'u' }, 139 /* ú */ [0x00FA] = { DEAD_ACUTE, 'u' }, 140 /* û */ [0x00FB] = { DEAD_CIRCUMFLEX, 'u' }, 141 /* ü */ [0x00FC] = { DEAD_DIERESIS, 'u' }, 142 /* ý */ [0x00FD] = { DEAD_ACUTE, 'y' }, 143 /* ÿ */ [0x00FF] = { DEAD_DIERESIS, 'y' } 144 145}; 146 147int guac_rdp_decompose_keysym(guac_rdp_keyboard* keyboard, int keysym) { 148 149 /* Verify keysym is within range of lookup table */ 150 if (keysym < 0x00 || keysym > 0xFF) 151 return 1; 152 153 /* Verify keysym is actually defined within lookup table */ 154 guac_rdp_decomposed_key* key = &guac_rdp_decomposed_keys[keysym]; 155 if (!key->dead_keysym) 156 return 1; 157 158 /* Cannot type using decomposed keys if those keys are not defined within 159 * the current layout */ 160 if (!guac_rdp_keyboard_is_defined(keyboard, key->dead_keysym) 161 || !guac_rdp_keyboard_is_defined(keyboard, key->base_keysym)) 162 return 1; 163 164 /* Press dead key */ 165 guac_rdp_keyboard_update_keysym(keyboard, key->dead_keysym, 1, GUAC_RDP_KEY_SOURCE_SYNTHETIC); 166 guac_rdp_keyboard_update_keysym(keyboard, key->dead_keysym, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC); 167 168 /* Press base key */ 169 guac_rdp_keyboard_update_keysym(keyboard, key->base_keysym, 1, GUAC_RDP_KEY_SOURCE_SYNTHETIC); 170 guac_rdp_keyboard_update_keysym(keyboard, key->base_keysym, 0, GUAC_RDP_KEY_SOURCE_SYNTHETIC); 171 172 /* Decomposed key successfully typed */ 173 return 0; 174 175} 176