cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

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