Remove custom composition handling in favor of XIM. - sam - An updated version of the sam text editor.
 (HTM) git clone git://vernunftzentrum.de/sam.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit d9b184f7d9f20ba133be3853c96a2c609bf6da60
 (DIR) parent 5b680483799488bdcf83883a5caebe30cba28810
 (HTM) Author: Rob King <jking@deadpixi.com>
       Date:   Fri, 23 Jun 2017 10:20:11 -0500
       
       Remove custom composition handling in favor of XIM.
       
       Diffstat:
         README.rst                          |      11 ++++++++---
         doc/Makefile                        |       2 --
         doc/keyboard                        |      15 ---------------
         doc/keyboard.5                      |     169 -------------------------------
         doc/sam.1                           |      35 -------------------------------
         doc/samrc.5                         |       9 +--------
         libXg/GwinP.h                       |       3 ---
         libXg/Makefile                      |       2 +-
         libXg/gwin.c                        |      86 ++-----------------------------
         libXg/latin1.c                      |     310 -------------------------------
         libXg/xtbinit.c                     |       3 ---
       
       11 files changed, 14 insertions(+), 631 deletions(-)
       ---
 (DIR) diff --git a/README.rst b/README.rst
       @@ -115,6 +115,14 @@ Scalable Font Support
            This version of sam is not limited to classic X fonts, but can use modern scalable fonts.
            Inconsolata_ is this author's favorite, though `Courier Prime Code`_ and `Go Mono`_ are giving Inconsolata a run for its money.
        
       +X Input Method and Composition Support
       +    This version of sam supports the X Input Method extension for input processing.
       +    This allows users to input text via the methods with which they are most comfortable.
       +    Additionally, the XCompose(5) file can be used to bind arbitrary sequences of keystrokes
       +    to different input character sequences.
       +    This mechanism is both more portable and more extensible than the old composed text
       +    input mechanism.
       +
        Multicolor Support
            This version of sam supports configurable text, selection, border, and background colors.
            It also allows different files to have different background colors,
       @@ -126,8 +134,6 @@ Multicolor Support
        
        Simplified and Dynamic Configuration
            The graphical elements (colors and fonts) of this version of sam are controlled via environment variables, not X Resources.
       -    The table of composable characters is now dynamically configurable (via the `~/.keyboard` file),
       -    where it was once hard-coded.
            Keybindings and mouse chords are configurable at runtime via a configuration file.
        
        Far Better Keyboard Support
       @@ -196,7 +202,6 @@ Primary Goals
        - Scalable font support (DONE)
        - Support big- and little-endian 64-bit systems (DONE)
        - Support compilation and use on modern \*nix systems (DONE)
       -- Runtime configuration of composition sequences (DONE)
        - Support two-button mice (DONE)
        - Support tab expansion (DONE)
        - Support runtime configuration of tab sizes (DONE)
 (DIR) diff --git a/doc/Makefile b/doc/Makefile
       @@ -12,7 +12,6 @@ install: sam.1
                ln -sf "$(MANDIR)/man1/sam.1" "$(MANDIR)/man1/rsam.1"
                ln -sf "$(MANDIR)/man1/sam.1" "$(MANDIR)/man1/sam.save.1"
                mkdir -p "$(MANDIR)/man5"
       -        cp keyboard.5 "$(MANDIR)/man5"
                cp samrc.5 "$(MANDIR)/man5"
        
        uninstall:
       @@ -21,5 +20,4 @@ uninstall:
                rm -f "$(MANDIR)/man1/samterm.1"
                rm -f "$(MANDIR)/man1/rsam.1"
                rm -f "$(MANDIR)/man1/sam.save.1"
       -        rm -f "$(MANDIR)/man5/keyboard.5"
                rm -f "$(MANDIR)/man5/samrc.5"
 (DIR) diff --git a/doc/keyboard b/doc/keyboard
       @@ -1,15 +0,0 @@
       -"U 0xdc Ü
       -*l 0x3bb λ
       -~= 0x2243 ≃
       --: 0xf7 ÷
       -no 0xac ¬
       -'o 0xf3 ó
       -?? 0xbf ¿
       -`e 0xe8 è
       -bn 0x265e ♞
       -cg 0x2245 ≅
       -*M 0x39c Μ
       -*K 0x39a Κ
       -mu 0xd7 ×
       -"A 0xc4 Ä
       -*Y 0x397 Η
 (DIR) diff --git a/doc/keyboard.5 b/doc/keyboard.5
       @@ -1,169 +0,0 @@
       -.Dd $Mdocdate$
       -.Dt KEYBOARD 5
       -.Os
       -.Sh NAME
       -.Nm keyboard
       -.Nd map key sequences to Unicode codepoints
       -.Sh SYNOPSIS
       -.Pa ~/.keyboard
       -.Sh DESCRIPTION
       -A
       -.Nm
       -file in the user's home directory can be used to describe key sequences that are composed
       -into Unicode code points by the
       -.Xr sam 1
       -editor.
       -.Pp
       -Each line in the file is of the form
       -.Bd -literal -offset indent
       -cc hex comment
       -.Ed
       -.Pp
       -where
       -.Em "cc"
       -is two characters naming two characters to be typed,
       -.Em hex
       -is a single hexidecimal integer prefixed with
       -.Dq "0x"
       -naming a Unicode code point in the Basic Multilingual Plane, and
       -.Em comment
       -is the remainder of the line.
       -.Pp
       -.Xr sam 1
       -will read in this file at startup.
       -While running, any time the system's
       -.Em Compose
       -key
       -.Po
       -if configured
       -.Pc
       -is pressed, or the
       -.Em Mod1
       -key
       -.Po
       -usually
       -.Dq "Alt"
       -.Pc
       -is held down, and the two keys described by
       -.Em cc
       -are typed,
       -the Unicode code point named by
       -.Em hex
       -will be inserted into the file.
       -.Pp
       -If the two typed characters do not match a configured composition sequence,
       -they will be inserted verbatim.
       -.Pp
       -Note that the first character of a composition sequence may not be
       -.Dq "X"
       -.Po
       -upper case letter X
       -.Pc ","
       -because this would conflict with the editor's mechanism for inserting raw codepoints
       -.Po
       -see
       -.Xr sam 1
       -.Pc "."
       -.Sh EXAMPLE
       -Given the
       -.Pa ".keyboard"
       -line:
       -.Bd -literal -offset indent
       -12 0x00BD \[u00BD]
       -.Ed
       -.Pp
       -then typing the characters 1 and 2 while holding down the
       -.Em Mod1
       -key in
       -.Xr sam 1
       -will insert Unicode code point 0x00BD
       -.Pq \[u00BD]
       -into the current file.
       -.Pp
       -Note that after the hexadecimal codepoint specification,
       -the rest of the line is ignored and is therefore usable as a comment field.
       -.Sh DEFAULTS
       -The following key sequences are defined by default,
       -and can be selectively overridden in the
       -.Pa .keyboard
       -file:
       -.Pp
       -.TS
       -box;
       -c | c | c | c | c | c | c | c
       -- | - | - | - | - | - | - | -
       -c | c | c | c | c | c | c | c.
       -Keys        Codepoint        Keys        Codepoint        Keys        Codepoint        Keys        Codepoint
       -!!        \[u00A1]        c$        \[u00A2]        l$        \[u00A3]        g$        \[u00A4]        
       -y$        \[u00A5]        ||        \[u00A6]        SS        \[u00A7]        ""        \[u00A8]
       -cO        \[u00A9]        sa        \[u00AA]        <<        \[u00AB]        no        \[u00AC]        
       ---        (SOFT HYPHEN)        rO        \[u00AE]        __        \[u00AF]        de        \[u00B0]
       -+-        \[u00B1]        s2        \[u00B2]        s3        \[u00B3]        ''        \[u00B4]        
       -mi        \[u00B5]        pg        \[u00B6]        ..        \[u00B7]        ,,        \[u00B8]
       -s1        \[u00B9]        so        \[u00BA]        >>        \[u00BB]        14        \[u00BC]        
       -12        \[u00BD]        34        \[u00BE]        ??        \[u00BF]        `A        \[u00C0]
       -'A        \[u00C1]        ^A        \[u00C2]        ~A        \[u00C3]        "A        \[u00C4]        
       -oA        \[u00C5]        AE        \[u00C6]        ,C        \[u00C7]        `E        \[u00C8]
       -'E        \[u00C9]        ^E        \[u00CA]        "E        \[u00CB]        `I        \[u00CC]        
       -'I        \[u00CD]        ^I        \[u00CE]        "I        \[u00CF]        D-        \[u00D0]
       -~N        \[u00D1]        `O        \[u00D2]        'O        \[u00D3]        ^O        \[u00D4]        
       -~O        \[u00D5]        "O        \[u00D6]        mu        \[u00D7]        /O        \[u00D8]
       -`U        \[u00D9]        'U        \[u00DA]        ^U        \[u00DB]        "U        \[u00DC]        
       -'Y        \[u00DD]        |P        \[u00DE]        ss        \[u00DF]        `a        \[u00E0]
       -'a        \[u00E1]        ^a        \[u00E2]        ~a        \[u00E3]        "a        \[u00E4]        
       -oa        \[u00E5]        ae        \[u00E6]        ,c        \[u00E7]        `e        \[u00E8]
       -'e        \[u00E9]        ^e        \[u00EA]        "e        \[u00EB]        `i        \[u00EC]        
       -'i        \[u00ED]        ^i        \[u00EE]        "i        \[u00EF]        d-        \[u00F0]
       -~n        \[u00F1]        `o        \[u00F2]        'o        \[u00F3]        ^o        \[u00F4]        
       -~o        \[u00F5]        "o        \[u00F6]        -:        \[u00F7]        /o        \[u00F8]
       -`u        \[u00F9]        'u        \[u00FA]        ^u        \[u00FB]        "u        \[u00FC]        
       -'y        \[u00FD]        |p        \[u00FE]        "y        \[u00FF]        wk        \[u2654]
       -.TE
       -.TS
       -box;
       -c | c | c | c | c | c | c | c
       -- | - | - | - | - | - | - | -
       -c | c | c | c | c | c | c | c.
       -Keys        Codepoint        Keys        Codepoint        Keys        Codepoint        Keys        Codepoint
       -wq        \[u2655]        wr        \[u2656]        wb        \[u2657]        wn        \[u2658]        
       -wp        \[u2659]        bk        \[u265A]        bq        \[u265B]        br        \[u265C]
       -bb        \[u265D]        bn        \[u265E]        bp        \[u265F]        *a        \[u03B1]        
       -*b        \[u03B2]        *g        \[u03B3]        *d        \[u03B4]        *e        \[u03B5]
       -*z        \[u03B6]        *y        \[u03B7]        *h        \[u03B8]        *i        \[u03B9]        
       -*k        \[u03BA]        *l        \[u03BB]        *m        \[u03BC]        *n        \[u03BD]
       -*c        \[u03BE]        *o        \[u03BF]        *p        \[u03C0]        *r        \[u03C1]        
       -ts        \[u03C2]        *s        \[u03C3]        *t        \[u03C4]        *u        \[u03C5]
       -*f        \[u03C6]        *x        \[u03C7]        *q        \[u03C8]        *w        \[u03C9]        
       -*A        \[u0391]        *B        \[u0392]        *G        \[u0393]        *D        \[u0394]
       -*E        \[u0395]        *Z        \[u0396]        *Y        \[u0397]        *H        \[u0398]        
       -*I        \[u0399]        *K        \[u039A]        *L        \[u039B]        *M        \[u039C]
       -*N        \[u039D]        *C        \[u039E]        *O        \[u039F]        *P        \[u03A0]        
       -*R        \[u03A1]        *S        \[u03A3]        *T        \[u03A4]        *U        \[u03A5]
       -*F        \[u03A6]        *X        \[u03A7]        *Q        \[u03A8]        *W        \[u03A9]        
       -<-        \[u2190]        ua        \[u2191]        ->        \[u2192]        da        \[u2193]
       -ab        \[u2194]        V=        \[u21D0]        =V        \[u21D2]        fa        \[u2200]        
       -te        \[u2203]        pd        \[u2202]        es        \[u2205]        De        \[u2206]
       -gr        \[u2207]        mo        \[u2208]        !m        \[u2209]        st        \[u220D]        
       -**        \[u2217]        bu        \[u2219]        sr        \[u221A]        pt        \[u221D]
       -if        \[u221E]        an        \[u2220]        l&        \[u2227]        l|        \[u2228]        
       -ca        \[u2229]        cu        \[u222A]        is        \[u222B]        tf        \[u2234]
       -~=        \[u2243]        cg        \[u2245]        ~~        \[u2248]        !=        \[u2260]        
       -==        \[u2261]        <=        \[u2266]        >=        \[u2267]        sb        \[u2282]
       -sp        \[u2283]        !b        \[u2284]        ib        \[u2286]        ip        \[u2287]        
       -O+        \[u2295]        O-        \[u2296]        Ox        \[u2297]        tu        \[u22A2]
       -Tu        \[u22A8]        lz        \[u22C4]        el        \[u22EF]        :(        \[u2639]        
       -:)        \[u263A]        ;)        \[u263B]        ta        (TAB)
       -.TE
       -.Sh ENVIRONMENT
       -The following environment variables affect the operation of
       -.Nm sam ":"
       -.Bl -tag -width Ds
       -.It Ev HOME
       -Names the directory to be searched for the user's
       -.Pa ".keyboard"
       -file.
       -.El
       -.Sh SEE ALSO
       -.Xr sam 1
       -.Sh BUGS
       -Only codepoints in the Basic Multilingual Plane may be specified.
 (DIR) diff --git a/doc/sam.1 b/doc/sam.1
       @@ -927,31 +927,6 @@ to load the named files; the default is the most-recently started local instance
        .Pp
        .Nm B
        may also be called on a remote machine, causing the downloaded instance of sam connected to that machine to load the named files.
       -.Ss Composed Text Input
       -.Nm sam
       -allows the input of arbitrary Unicode characters from the Basic Multilingual Plane
       -.Pq BMP
       -via five-character and two-character sequences.
       -These sequences are entered while holding down the system Mod1 key
       -.Po
       -on most keyboards, this key is labeled
       -.Sy Alt
       -.Pc "."
       -If your system has a Compose key, it may be pressed once and then the composed character sequence entered, rather than needing to hold down a key continuously.
       -.Pp
       -The first method allows the entry of any code point in the BMP.
       -An uppercase
       -.Li X
       -character is typed, followed by exactly four lowercase hexadecimal digits naming the codepoint.
       -.Pp
       -Commonly used codepoints can be entered with an abbreviated two-character sequence.
       -These sequence definitions are read from a file called
       -.Pa ".keyboard"
       -in the user's home directory.
       -See
       -.Xr keyboard 5
       -for more information on that file and its format,
       -as well as a default list of composition sequences.
        .Sh ENVIRONMENT
        The following environment variables affect the operation of
        .Nm sam ":"
       @@ -1100,9 +1075,6 @@ mouse chords,
        colors,
        fonts,
        and tabs.
       -.It Pa "${HOME}/.keyboard"
       -Provides a mapping of two-character sequences to Unicode code points.
       -Note that the code points must be in the Basic Multilingual Plane.
        .It Pa "${HOME}/sam.save"
        Created if
        .Nm
       @@ -1114,16 +1086,9 @@ Stores output of shell commands executed by
        .El
        .Sh SEE ALSO
        .Xr ed 1
       -.Xr keyboard 5
        .Xr samrc 5
        .Sh BUGS
        .Pp
       -The character composition as described in
       -.Xs "Composed Text Input"
       -may be overridden or limited by the user's specified input method.
       -This is not necessarily a bug,
       -but rather a concession to the user's implied preferences.
       -.Pp
        The only human language in which colors may be specified is English.
        .Pp
        The only human language in which output is generated is English.
 (DIR) diff --git a/doc/samrc.5 b/doc/samrc.5
       @@ -52,13 +52,7 @@ see
        .Sx "Command Names"
        below
        .Pc
       -or a literal
       -.Po
       -or hexadecimal
       -as in
       -.Xr keyboard 5
       -.Pc
       -specification of a character,
       +or a literal or hexadecimal specification of a character,
        and
        .Em A
        is an arbitrary string to use as an argument to a bound command.
       @@ -380,4 +374,3 @@ file is provided in the sam source distribution as
        .Pa doc/samrc "."
        .Sh SEE ALSO
        .Xr sam 1
       -.Xr keyboard 5
 (DIR) diff --git a/libXg/GwinP.h b/libXg/GwinP.h
       @@ -42,7 +42,4 @@ typedef struct _GwinClassRec {
        /* External definition for class record */
        extern GwinClassRec gwinClassRec;
        
       -int unicode(unsigned char *k);
       -int latin1(unsigned char *k);
       -
        #endif /* GWINP_H */
 (DIR) diff --git a/libXg/Makefile b/libXg/Makefile
       @@ -25,7 +25,7 @@ CC?=c99
        
        OBJS=          arith.o balloc.o bitblt.o   border.o bscreenrect.o\
                  clipr.o   cursorset.o cursorswitch.o\
       -            gcs.o getrect.o gwin.o ldconvert.o latin1.o\
       +            gcs.o getrect.o gwin.o ldconvert.o\
                menuhit.o    \
                rectclip.o rune.o  string.o texture.o\
                wrbitmap.o   xtbinit.o
 (DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
       @@ -39,8 +39,6 @@ static XtResource resources[] = {
                Offset(gotmouse), XtRFunction, (XtPointer) NULL},
            {XtNselection, XtCSelection, XtRString, sizeof(String),
                Offset(selection), XtRString, (XtPointer) NULL},
       -    {XtNcomposeMod, XtCComposeMod, XtRInt, sizeof(int),
       -        Offset(compose), XtRImmediate, (XtPointer) 0}
        };
        #undef Offset
        
       @@ -158,12 +156,6 @@ Mappingaction(Widget w, XEvent *e, String *p, Cardinal *np)
                keypermod = modmap->max_keypermod;
        }
        
       -#define STUFFCOMPOSE() \
       -                f = ((GwinWidget)w)->gwin.gotchar; \
       -                if (f) \
       -                    for (int c = 0; c < composing; c++) \
       -                        (*f)(compose[c], 0, Tcurrent, 0, 0, NULL)
       -
        typedef struct Unikeysym Unikeysym;
        struct Unikeysym{
            KeySym keysym;
       @@ -249,8 +241,6 @@ static void
        Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
        {
            extern XIC xic;
       -    static unsigned char compose[5];
       -    static int composing = -2;
            int kind = Kraw;
        
            int c, len, minmod;
       @@ -268,6 +258,8 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
                return;
        
            len = XwcLookupString(xic, &e->xkey, buf, 32, &k, &s);
       +    if (IsModifierKey(k))
       +        return;
        
            /* Check to see if it's a specially-handled key first. */
            for (Keymapping *m = keymappings; m; m = m->next){
       @@ -299,79 +291,9 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
                }
            }
        
       -    /* The following song and dance is so we can have our chosen
       -     * modifier key behave like a compose key, i.e, press and release
       -     * and then type the compose sequence, like Plan 9.  We have
       -     * to find out which key is the compose key first though.
       -     */
       -    if (IsModifierKey(k) && ((GwinWidget)w)->gwin.compose && composing == -2 && modmap) {
       -        minmod = (((GwinWidget)w)->gwin.compose+2)*keypermod;
       -        for (c = minmod; c < minmod+keypermod; c++) {
       -            XtTranslateKeycode(e->xany.display,
       -                    modmap->modifiermap[c],
       -                        e->xkey.state, &md, &mk);
       -            if (k == mk) {
       -                composing = -1;
       -                break;
       -            }
       -        }
       -        return;
       -    }
       -
       -    /* Handle Multi_key and shifts separately, since it isn't a modifier */
       -    if(k == XK_Multi_key){
       -        composing = -1;
       -        return;
       -    }
       -
       -    /* If we got a lone modifier key, no key, or a key outside of the
       -     * representable range, ignore it.
       -     */
       -    if (IsModifierKey(k) || k == NoSymbol || k > 0xff00 || len <= 0)
       -        return;
       -
       -    /* Check to see if we are in a composition sequence */
       -    if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask)
       -            && composing == -2)
       -        composing = -1;
       -    if (composing > -2) {
       -        compose[++composing] = k;
       -        if ((*compose == 'X') && (composing > 0)) {
       -            if ((k < '0') || (k > 'f') ||
       -                    ((k > '9') && (k < 'a'))) {
       -                STUFFCOMPOSE();
       -                c = (uint16_t)k;
       -                composing = -2;
       -            } else if (composing == 4) {
       -                c = unicode(compose);
       -                if (c == -1) {
       -                    STUFFCOMPOSE();
       -                    c = (uint16_t)compose[4];
       -                }
       -                composing = -2;
       -            }
       -        } else if (composing == 1) {
       -            c = (int)latin1(compose);
       -            if (c == -1) {
       -                STUFFCOMPOSE();
       -                c = (uint16_t)compose[1];
       -            }
       -            composing = -2;
       -        }
       -    } else {
       -        if (composing >= 0) {
       -            composing++;
       -            STUFFCOMPOSE();
       -        }
       -        c = keysymtoshort(k);
       -        composing = -2;
       -    }
       -
       -    if (composing >= -1)
       -        return;
       -
       +    c = keysymtoshort(k);
            f = ((GwinWidget)w)->gwin.gotchar;
       -    if(f)
       +    if(f && c)
                (*f)(c? c : buf[0], kind, Tcurrent, 0, 0, NULL);
        }
        
 (DIR) diff --git a/libXg/latin1.c b/libXg/latin1.c
       @@ -1,310 +0,0 @@
       -/* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
       -/* Changes copyright 2014-2016 Rob King. */
       -
       -#include <inttypes.h>
       -#include <stdint.h>
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -
       -#define MAPPING_MAX 65535
       -
       -struct latin
       -{
       -    uint16_t  l;
       -    unsigned char   c[2];
       -};
       -
       -struct latin latintab[] = {
       -    {0x00a1, {'!','!'}}, /* spanish initial ! */
       -    {0x00a2, {'c','$'}}, /* cent */
       -    {0x00a3, {'l','$'}}, /* pound sterling */
       -    {0x00a4, {'g','$'}}, /* general currency */
       -    {0x00a5, {'y','$'}}, /* yen */
       -    {0x00a6, {'|','|'}}, /* broken vertical bar */
       -    {0x00a7, {'S','S'}}, /* section symbol */
       -    {0x00a8, {'\"','\"'}}, /* dieresis */
       -    {0x00a9, {'c','O'}}, /* copyright */
       -    {0x00aa, {'s','a'}}, /* super a, feminine ordinal */
       -    {0x00ab, {'<','<'}}, /* left angle quotation */
       -    {0x00ac, {'n','o'}}, /* not sign, hooked overbar */
       -    {0x00ad, {'-','-'}}, /* soft hyphen */
       -    {0x00ae, {'r','O'}}, /* registered trademark */
       -    {0x00af, {'_','_'}}, /* macron */
       -    {0x00b0, {'d','e'}}, /* degree */
       -    {0x00b1, {'+','-'}}, /* plus-minus */
       -    {0x00b2, {'s','2'}}, /* sup 2 */
       -    {0x00b3, {'s','3'}}, /* sup 3 */
       -    {0x00b4, {'\'','\''}}, /* acute accent */
       -    {0x00b5, {'m','i'}}, /* micron */
       -    {0x00b6, {'p','g'}}, /* paragraph (pilcrow) */
       -    {0x00b7, {'.','.'}}, /* centered . */
       -    {0x00b8, {',',','}}, /* cedilla */
       -    {0x00b9, {'s','1'}}, /* sup 1 */
       -    {0x00ba, {'s','o'}}, /* super o, masculine ordinal */
       -    {0x00bb, {'>','>'}}, /* right angle quotation */
       -    {0x00bc, {'1','4'}}, /* 1/4 */
       -    {0x00bd, {'1','2'}}, /* 1/2 */
       -    {0x00be, {'3','4'}}, /* 3/4 */
       -    {0x00bf, {'?','?'}}, /* spanish initial ? */
       -    {0x00c0, {'`','A'}}, /* A grave */
       -    {0x00c1, {'\'','A'}}, /* A acute */
       -    {0x00c2, {'^','A'}}, /* A circumflex */
       -    {0x00c3, {'~','A'}}, /* A tilde */
       -    {0x00c4, {'\"','A'}}, /* A dieresis */
       -    {0x00c5, {'o','A'}}, /* A circle */
       -    {0x00c6, {'A','E'}}, /* AE ligature */
       -    {0x00c7, {',','C'}}, /* C cedilla */
       -    {0x00c8, {'`','E'}}, /* E grave */
       -    {0x00c9, {'\'','E'}}, /* E acute */
       -    {0x00ca, {'^','E'}}, /* E circumflex */
       -    {0x00cb, {'\"','E'}}, /* E dieresis */
       -    {0x00cc, {'`','I'}}, /* I grave */
       -    {0x00cd, {'\'','I'}}, /* I acute */
       -    {0x00ce, {'^','I'}}, /* I circumflex */
       -    {0x00cf, {'\"','I'}}, /* I dieresis */
       -    {0x00d0, {'D','-'}}, /* Eth */
       -    {0x00d1, {'~','N'}}, /* N tilde */
       -    {0x00d2, {'`','O'}}, /* O grave */
       -    {0x00d3, {'\'','O'}}, /* O acute */
       -    {0x00d4, {'^','O'}}, /* O circumflex */
       -    {0x00d5, {'~','O'}}, /* O tilde */
       -    {0x00d6, {'\"','O'}}, /* O dieresis */
       -    {0x00d7, {'m','u'}}, /* times sign */
       -    {0x00d8, {'/','O'}}, /* O slash */
       -    {0x00d9, {'`','U'}}, /* U grave */
       -    {0x00da, {'\'','U'}}, /* U acute */
       -    {0x00db, {'^','U'}}, /* U circumflex */
       -    {0x00dc, {'\"','U'}}, /* U dieresis */
       -    {0x00dd, {'\'','Y'}}, /* Y acute */
       -    {0x00de, {'|','P'}}, /* Thorn */
       -    {0x00df, {'s','s'}}, /* sharp s */
       -    {0x00e0, {'`','a'}}, /* a grave */
       -    {0x00e1, {'\'','a'}}, /* a acute */
       -    {0x00e2, {'^','a'}}, /* a circumflex */
       -    {0x00e3, {'~','a'}}, /* a tilde */
       -    {0x00e4, {'\"','a'}}, /* a dieresis */
       -    {0x00e5, {'o','a'}}, /* a circle */
       -    {0x00e6, {'a','e'}}, /* ae ligature */
       -    {0x00e7, {',','c'}}, /* c cedilla */
       -    {0x00e8, {'`','e'}}, /* e grave */
       -    {0x00e9, {'\'','e'}}, /* e acute */
       -    {0x00ea, {'^','e'}}, /* e circumflex */
       -    {0x00eb, {'\"','e'}}, /* e dieresis */
       -    {0x00ec, {'`','i'}}, /* i grave */
       -    {0x00ed, {'\'','i'}}, /* i acute */
       -    {0x00ee, {'^','i'}}, /* i circumflex */
       -    {0x00ef, {'\"','i'}}, /* i dieresis */
       -    {0x00f0, {'d','-'}}, /* eth */
       -    {0x00f1, {'~','n'}}, /* n tilde */
       -    {0x00f2, {'`','o'}}, /* o grave */
       -    {0x00f3, {'\'','o'}}, /* o acute */
       -    {0x00f4, {'^','o'}}, /* o circumflex */
       -    {0x00f5, {'~','o'}}, /* o tilde */
       -    {0x00f6, {'\"','o'}}, /* o dieresis */
       -    {0x00f7, {'-',':'}}, /* divide sign */
       -    {0x00f8, {'/','o'}}, /* o slash */
       -    {0x00f9, {'`','u'}}, /* u grave */
       -    {0x00fa, {'\'','u'}}, /* u acute */
       -    {0x00fb, {'^','u'}}, /* u circumflex */
       -    {0x00fc, {'\"','u'}}, /* u dieresis */
       -    {0x00fd, {'\'','y'}}, /* y acute */
       -    {0x00fe, {'|','p'}}, /* thorn */
       -    {0x00ff, {'\"','y'}}, /* y dieresis */
       -    {0x2654, {'w','k'}}, /* chess white king */
       -    {0x2655, {'w','q'}}, /* chess white queen */
       -    {0x2656, {'w','r'}}, /* chess white rook */
       -    {0x2657, {'w','b'}}, /* chess white bishop */
       -    {0x2658, {'w','n'}}, /* chess white knight */
       -    {0x2659, {'w','p'}}, /* chess white pawn */
       -    {0x265a, {'b','k'}}, /* chess black king */
       -    {0x265b, {'b','q'}}, /* chess black queen */
       -    {0x265c, {'b','r'}}, /* chess black rook */
       -    {0x265d, {'b','b'}}, /* chess black bishop */
       -    {0x265e, {'b','n'}}, /* chess black knight */
       -    {0x265f, {'b','p'}}, /* chess black pawn */
       -    {0x03b1, {'*','a'}}, /* alpha */
       -    {0x03b2, {'*','b'}}, /* beta */
       -    {0x03b3, {'*','g'}}, /* gamma */
       -    {0x03b4, {'*','d'}}, /* delta */
       -    {0x03b5, {'*','e'}}, /* epsilon */
       -    {0x03b6, {'*','z'}}, /* zeta */
       -    {0x03b7, {'*','y'}}, /* eta */
       -    {0x03b8, {'*','h'}}, /* theta */
       -    {0x03b9, {'*','i'}}, /* iota */
       -    {0x03ba, {'*','k'}}, /* kappa */
       -    {0x03bb, {'*','l'}}, /* lambda */
       -    {0x03bc, {'*','m'}}, /* mu */
       -    {0x03bd, {'*','n'}}, /* nu */
       -    {0x03be, {'*','c'}}, /* xsi */
       -    {0x03bf, {'*','o'}}, /* omicron */
       -    {0x03c0, {'*','p'}}, /* pi */
       -    {0x03c1, {'*','r'}}, /* rho */
       -    {0x03c2, {'t','s'}}, /* terminal sigma */
       -    {0x03c3, {'*','s'}}, /* sigma */
       -    {0x03c4, {'*','t'}}, /* tau */
       -    {0x03c5, {'*','u'}}, /* upsilon */
       -    {0x03c6, {'*','f'}}, /* phi */
       -    {0x03c7, {'*','x'}}, /* chi */
       -    {0x03c8, {'*','q'}}, /* psi */
       -    {0x03c9, {'*','w'}}, /* omega */    
       -    {0x0391, {'*','A'}}, /* Alpha */
       -    {0x0392, {'*','B'}}, /* Beta */
       -    {0x0393, {'*','G'}}, /* Gamma */
       -    {0x0394, {'*','D'}}, /* Delta */
       -    {0x0395, {'*','E'}}, /* Epsilon */
       -    {0x0396, {'*','Z'}}, /* Zeta */
       -    {0x0397, {'*','Y'}}, /* Eta */
       -    {0x0398, {'*','H'}}, /* Theta */
       -    {0x0399, {'*','I'}}, /* Iota */
       -    {0x039a, {'*','K'}}, /* Kappa */
       -    {0x039b, {'*','L'}}, /* Lambda */
       -    {0x039c, {'*','M'}}, /* Mu */
       -    {0x039d, {'*','N'}}, /* Nu */
       -    {0x039e, {'*','C'}}, /* Xsi */
       -    {0x039f, {'*','O'}}, /* Omicron */
       -    {0x03a0, {'*','P'}}, /* Pi */
       -    {0x03a1, {'*','R'}}, /* Rho */
       -    {0x03a3, {'*','S'}}, /* Sigma */
       -    {0x03a4, {'*','T'}}, /* Tau */
       -    {0x03a5, {'*','U'}}, /* Upsilon */
       -    {0x03a6, {'*','F'}}, /* Phi */
       -    {0x03a7, {'*','X'}}, /* Chi */
       -    {0x03a8, {'*','Q'}}, /* Psi */
       -    {0x03a9, {'*','W'}}, /* Omega */
       -    {0x2190, {'<','-'}}, /* left arrow */
       -    {0x2191, {'u','a'}}, /* up arrow */
       -    {0x2192, {'-','>'}}, /* right arrow */
       -    {0x2193, {'d','a'}}, /* down arrow */
       -    {0x2194, {'a','b'}}, /* arrow both */
       -    {0x21d0, {'V','='}}, /* left double-line arrow */
       -    {0x21d2, {'=','V'}}, /* right double-line arrow */
       -    {0x2200, {'f','a'}}, /* forall */
       -    {0x2203, {'t','e'}}, /* there exists */
       -    {0x2202, {'p','d'}}, /* partial differential */
       -    {0x2205, {'e','s'}}, /* empty set */
       -    {0x2206, {'D','e'}}, /* delta */
       -    {0x2207, {'g','r'}}, /* gradient */
       -    {0x2208, {'m','o'}}, /* element of */
       -    {0x2209, {'!','m'}}, /* not element of */
       -    {0x220d, {'s','t'}}, /* such that */
       -    {0x2217, {'*','*'}}, /* math asterisk */
       -    {0x2219, {'b','u'}}, /* bullet */
       -    {0x221a, {'s','r'}}, /* radical */
       -    {0x221d, {'p','t'}}, /* proportional */
       -    {0x221e, {'i','f'}}, /* infinity */
       -    {0x2220, {'a','n'}}, /* angle */
       -    {0x2227, {'l','&'}}, /* logical and */
       -    {0x2228, {'l','|'}}, /* logical or */
       -    {0x2229, {'c','a'}}, /* intersection */
       -    {0x222a, {'c','u'}}, /* union */
       -    {0x222b, {'i','s'}}, /* integral */
       -    {0x2234, {'t','f'}}, /* therefore */
       -    {0x2243, {'~','='}}, /* asymptotically equal */
       -    {0x2245, {'c','g'}}, /* congruent */
       -    {0x2248, {'~','~'}}, /* almost equal */
       -    {0x2260, {'!','='}}, /* not equal */
       -    {0x2261, {'=','='}}, /* equivalent */
       -    {0x2266, {'<','='}}, /* less than or equal */
       -    {0x2267, {'>','='}}, /* greater than or equal */
       -    {0x2282, {'s','b'}}, /* proper subset */
       -    {0x2283, {'s','p'}}, /* proper superset */
       -    {0x2284, {'!','b'}}, /* not subset */
       -    {0x2286, {'i','b'}}, /* reflexive subset */
       -    {0x2287, {'i','p'}}, /* reflexive superset */
       -    {0x2295, {'O','+'}}, /* circle plus */
       -    {0x2296, {'O','-'}}, /* circle minus */
       -    {0x2297, {'O','x'}}, /* circle multiply */
       -    {0x22a2, {'t','u'}}, /* turnstile */
       -    {0x22a8, {'T','u'}}, /* valid */
       -    {0x22c4, {'l','z'}}, /* lozenge */
       -    {0x22ef, {'e','l'}}, /* ellipses */
       -    {0x2639, {':','('}}, /* saddy */
       -    {0x263a, {':',')'}}, /* white-face smiley */
       -    {0x263b, {';',')'}}, /* dark-face smiley */
       -    {0, {0, 0}}
       -};
       -
       -
       -struct latin *mappings = NULL;
       -
       -void
       -freelatin(void)
       -{
       -    free(mappings);
       -}
       -
       -void
       -addlatin(char c0, char c1, int16_t l)
       -{
       -    static int i = 0;
       -
       -    if (mappings && i < MAPPING_MAX){
       -        mappings[i].c[0] = c0;
       -        mappings[i].c[1] = c1;
       -        mappings[i].l = l;
       -        i++;
       -    }
       -}
       -
       -void
       -initlatin(void)
       -{
       -    mappings = calloc(MAPPING_MAX + 1, sizeof(struct latin));
       -    if (mappings)
       -        atexit(freelatin);
       -
       -    FILE *keyboard = NULL;
       -    if (getenv("HOME")){
       -        char path[1024] = {0};
       -        snprintf(path, sizeof(path) - 1, "%s/.keyboard", getenv("HOME"));
       -        keyboard = fopen(path, "r");
       -    }
       -
       -    if (!keyboard)
       -        return;
       -
       -    unsigned char c0, c1;
       -    uint16_t l;
       -    while (fscanf(keyboard, " %c%c %" SCNx16 "%*[^\n]\n", &c0, &c1, &l) == 3)
       -        addlatin(c0, c1, l);
       -
       -    fclose(keyboard);
       -}
       -
       -long
       -latin1(unsigned char *k)
       -{
       -    struct latin *l;
       -
       -    for (l = mappings; l->l; l++)
       -        if (k[0] == l->c[0] && k[1] == l->c[1])
       -            return l->l;
       -
       -    for (l = latintab; l->l; l++)
       -        if (k[0] == l->c[0] && k[1] == l->c[1])
       -            return l->l;
       -
       -    return -1;
       -}
       -
       -int
       -unicode(unsigned char *k)
       -{
       -    int i, c;
       -
       -    k++;    /* skip 'X' */
       -    c = 0;
       -    for(i=0; i<4; i++,k++){
       -        c <<= 4;
       -        if('0'<=*k && *k<='9')
       -            c += *k-'0';
       -        else if('a'<=*k && *k<='f')
       -            c += 10 + *k-'a';
       -        else if('A'<=*k && *k<='F')
       -            c += 10 + *k-'A';
       -        else
       -            return -1;
       -    }
       -    return c;
       -}
 (DIR) diff --git a/libXg/xtbinit.c b/libXg/xtbinit.c
       @@ -107,7 +107,6 @@ static Ebuf *ebadd(Esrc *, bool);
        static void focinit(Widget);
        static void wmproto(Widget, XEvent *, String *, Cardinal *);
        static void waitevent(void);
       -void initlatin();
        
        static Errfunc  onerr;
        
       @@ -146,8 +145,6 @@ xtbinit(Errfunc f, char *class, int *pargc, char **argv, char **fallbacks)
            char *p;
            int compose;
        
       -    initlatin();
       -
            if(!class && argv[0]){
                p = strrchr(argv[0], '/');
                if(p)