123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #include "vnc.h"
- #include <keyboard.h>
- #include "utf2ksym.h"
- enum {
- Xshift = 0xFFE1,
- Xctl = 0xFFE3,
- Xmeta = 0xFFE7,
- Xalt = 0xFFE9
- };
- static struct {
- Rune kbdc;
- ulong keysym;
- } ktab[] = {
- {'\b', 0xff08},
- {'\t', 0xff09},
- {'\n', 0xff0d},
- /* {0x0b, 0xff0b}, */
- {'\r', 0xff0d},
- {0x1b, 0xff1b}, /* escape */
- {Kins, 0xff63},
- {0x7F, 0xffff},
- {Khome, 0xff50},
- {Kend, 0xff57},
- {Kpgup, 0xff55},
- {Kpgdown, 0xff56},
- {Kleft, 0xff51},
- {Kup, 0xff52},
- {Kright, 0xff53},
- {Kdown, 0xff54},
- {KF|1, 0xffbe},
- {KF|2, 0xffbf},
- {KF|3, 0xffc0},
- {KF|4, 0xffc1},
- {KF|5, 0xffc2},
- {KF|6, 0xffc3},
- {KF|7, 0xffc4},
- {KF|8, 0xffc5},
- {KF|9, 0xffc6},
- {KF|10, 0xffc7},
- {KF|11, 0xffc8},
- {KF|12, 0xffc9},
- };
- static char shiftkey[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, /* nul soh stx etx eot enq ack bel */
- 0, 0, 0, 0, 0, 0, 0, 0, /* bs ht nl vt np cr so si */
- 0, 0, 0, 0, 0, 0, 0, 0, /* dle dc1 dc2 dc3 dc4 nak syn etb */
- 0, 0, 0, 0, 0, 0, 0, 0, /* can em sub esc fs gs rs us */
- 0, 1, 1, 1, 1, 1, 1, 0, /* sp ! " # $ % & ' */
- 1, 1, 1, 1, 0, 0, 0, 0, /* ( ) * + , - . / */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */
- 0, 0, 1, 0, 1, 0, 1, 1, /* 8 9 : ; < = > ? */
- 1, 1, 1, 1, 1, 1, 1, 1, /* @ A B C D E F G */
- 1, 1, 1, 1, 1, 1, 1, 1, /* H I J K L M N O */
- 1, 1, 1, 1, 1, 1, 1, 1, /* P Q R S T U V W */
- 1, 1, 1, 0, 0, 0, 1, 1, /* X Y Z [ \ ] ^ _ */
- 0, 0, 0, 0, 0, 0, 0, 0, /* ` a b c d e f g */
- 0, 0, 0, 0, 0, 0, 0, 0, /* h i j k l m n o */
- 0, 0, 0, 0, 0, 0, 0, 0, /* p q r s t u v w */
- 0, 0, 0, 1, 1, 1, 1, 0, /* x y z { | } ~ del */
- };
- ulong
- runetoksym(Rune r)
- {
- int i;
- for(i=0; i<nelem(ktab); i++)
- if(ktab[i].kbdc == r)
- return ktab[i].keysym;
- return r;
- }
- static void
- keyevent(Vnc *v, ulong ksym, int down)
- {
- vnclock(v);
- vncwrchar(v, MKey);
- vncwrchar(v, down);
- vncwrshort(v, 0);
- vncwrlong(v, ksym);
- vncflush(v);
- vncunlock(v);
- }
- void
- readkbd(Vnc *v)
- {
- char buf[256], k[10];
- ulong ks;
- int ctlfd, fd, kr, kn, w, shift, ctl, alt;
- Rune r;
- snprint(buf, sizeof buf, "%s/cons", display->devdir);
- if((fd = open(buf, OREAD)) < 0)
- sysfatal("open %s: %r", buf);
- snprint(buf, sizeof buf, "%s/consctl", display->devdir);
- if((ctlfd = open(buf, OWRITE)) < 0)
- sysfatal("open %s: %r", buf);
- write(ctlfd, "rawon", 5);
- kn = 0;
- shift = alt = ctl = 0;
- for(;;){
- while(!fullrune(k, kn)){
- kr = read(fd, k+kn, sizeof k - kn);
- if(kr <= 0)
- sysfatal("bad read from kbd\n");
- kn += kr;
- }
- w = chartorune(&r, k);
- kn -= w;
- memmove(k, &k[w], kn);
- ks = runetoksym(r);
- switch(r){
- case Kalt:
- alt = !alt;
- keyevent(v, Xalt, alt);
- break;
- case Kctl:
- ctl = !ctl;
- keyevent(v, Xctl, ctl);
- break;
- case Kshift:
- shift = !shift;
- keyevent(v, Xshift, shift);
- break;
- default:
- if(r == ks && r < 0x1A){ /* control key */
- keyevent(v, Xctl, 1);
- keyevent(v, r+0x60, 1); /* 0x60: make capital letter */
- keyevent(v, r+0x60, 0);
- keyevent(v, Xctl, 0);
- }else{
- /*
- * to send an upper case letter or shifted
- * punctuation, mac os x vnc server,
- * at least, needs a `shift' sent first.
- */
- if(!shift && r == ks && r < sizeof shiftkey && shiftkey[r]){
- shift = 1;
- keyevent(v, Xshift, 1);
- }
- /*
- * map an xkeysym onto a utf-8 char.
- * allows Xvnc to read us, see utf2ksym.h
- */
- if((ks & 0xff00) && ks < nelem(utf2ksym) && utf2ksym[ks] != 0)
- ks = utf2ksym[ks];
- keyevent(v, ks, 1);
- /*
- * up event needed by vmware inside linux vnc server,
- * perhaps others.
- */
- keyevent(v, ks, 0);
- }
- if(alt){
- keyevent(v, Xalt, 0);
- alt = 0;
- }
- if(ctl){
- keyevent(v, Xctl, 0);
- ctl = 0;
- }
- if(shift){
- keyevent(v, Xshift, 0);
- shift = 0;
- }
- break;
- }
- }
- }
|