Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include        <u.h>
#include        <libc.h>
#include        "compat.h"
#include        "kbd.h"
#include   "ksym2utf.h"

enum
{
        VKSpecial = 0xff00,

        /*
         * plan 9 key mappings
         */
        Spec=           0xF800,

        PF=             Spec|0x20,      /* num pad function key */
        View=           Spec|0x00,      /* view (shift window up) */
        KF=             0xF000, /* function key (begin Unicode private space) */
        Shift=          Spec|0x60,
        Break=          Spec|0x61,
        Ctrl=           Spec|0x62,
        Latin=          Spec|0x63,
        Caps=           Spec|0x64,
        Num=            Spec|0x65,
        Middle=         Spec|0x66,
        No=             0x00,           /* peter */

        Home=           KF|13,
        Up=             KF|14,
        Pgup=           KF|15,
        Print=          KF|16,
        Left=           KF|17,
        Right=          KF|18,
        End=            '\r',
        Down=           View,
        Pgdown=         KF|19,
        Ins=            KF|20,
        Del=            0x7F,
        Scroll=         KF|21,

        Esc = 0x1b,
        Delete = 0x7f,
};

static Rune vnckeys[] =
{
[0x00]  No,     No,     No,     No,     No,     No,     No,     No,
[0x08]  '\b',   '\t',   '\r',   No,     No,     '\n',   No,     No,
[0x10]  No,     No,     No,     No,     Scroll, No,     No,     No,
[0x18]  No,     No,     No,     Esc,    No,     No,     No,     No,
[0x20]  No,     No,     No,     No,     No,     No,     No,     No,
[0x28]  No,     No,     No,     No,     No,     No,     No,     No,
[0x30]  No,     No,     No,     No,     No,     No,     No,     No,
[0x38]  No,     No,     No,     No,     No,     No,     No,     No,
[0x40]  No,     No,     No,     No,     No,     No,     No,     No,
[0x48]  No,     No,     No,     No,     No,     No,     No,     No,
[0x50]  Home,   Left,   Up,     Right,  Down,   Pgup,   Pgdown, No,
[0x58]  No,     No,     No,     No,     No,     No,     No,     No,
[0x60]  No,     Print,  No,     Ins,    No,     No,     No,     No,
[0x68]  No,     No,     No,     Break,  No,     No,     No,     No,
[0x70]  No,     No,     No,     No,     No,     No,     No,     No,
[0x78]  No,     No,     No,     No,     No,     No,     No,     Num,
[0x80]  No,     No,     No,     No,     No,     No,     No,     No,
[0x88]  No,     No,     No,     No,     No,     No,     No,     No,
[0x90]  No,     No,     No,     No,     No,     No,     No,     No,
[0x98]  No,     No,     No,     No,     No,     No,     No,     No,
[0xa0]  No,     No,     No,     No,     No,     No,     No,     No,
[0xa8]  No,     No,     '*',    '+',    No,     '-',    '.',    '/',
[0xb0]  '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',
[0xb8]  '8',    '9',    No,     No,     No,     '=',    No,     No,
[0xc0]  No,     No,     No,     No,     No,     No,     No,     No,
[0xc8]  No,     No,     No,     No,     No,     No,     No,     No,
[0xd0]  No,     No,     No,     No,     No,     No,     No,     No,
[0xd8]  No,     No,     No,     No,     No,     No,     No,     No,
[0xe0]  No,     Shift,  Shift,  Ctrl,   Ctrl,   Caps,   Caps,   No,
[0xe8]  No,     Latin,  Latin,  No,     No,     No,     No,     No,
[0xf0]  No,     No,     No,     No,     No,     No,     No,     No,
[0xf8]  No,     No,     No,     No,     No,     No,     No,     Delete,
};

/*
 *  keyboard interrupt
 */
void
vncputc(int keyup, int c)
{
        int i;
        static int esc1, esc2;
        static int alt, caps, ctl, num, shift;
        static int collecting, nk;
        static Rune kc[5];

        if(caps && c<='z' && c>='a')
                c += 'A' - 'a';

        /*
         *  character mapping
         */
        if((c & VKSpecial) == VKSpecial){
                c = vnckeys[c & 0xff];
                if(c == No)
                        return;
        }
        /*
         * map an xkeysym onto a utf-8 char
         */
        if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0)
                        c = ksym2utf[c];

        /*
         *  keyup only important for shifts
         */
        if(keyup){
                switch(c){
                case Latin:
                        alt = 0;
                        break;
                case Shift:
                        shift = 0;
                        break;
                case Ctrl:
                        ctl = 0;
                        break;
                }
                return;
        }

        /*
         *  normal character
         */
        if(!(c & (Spec|KF))){
                if(ctl){
                        c &= 0x1f;
                }
                if(!collecting){
                        kbdputc(c);
                        return;
                }
                kc[nk++] = c;
                c = latin1(kc, nk);
                if(c < -1)      /* need more keystrokes */
                        return;
                if(c != -1)     /* valid sequence */
                        kbdputc(c);
                else    /* dump characters */
                        for(i=0; i<nk; i++)
                                kbdputc(kc[i]);
                nk = 0;
                collecting = 0;
                return;
        }else{
                switch(c){
                case Caps:
                        caps ^= 1;
                        return;
                case Num:
                        num ^= 1;
                        return;
                case Shift:
                        shift = 1;
                        return;
                case Latin:
                        alt = 1;
                        collecting = 1;
                        nk = 0;
                        return;
                case Ctrl:
                        ctl = 1;
                        return;
                }
        }
        kbdputc(c);
}