ref: 8b56be517e51869c58e5eba7bdb5a22bd1361d40
parent: bfdf9e3c44c822a456db6664ea7eff8ce9e15854
author: qwx <qwx@sciops.net>
date: Sat Aug 26 02:45:41 EDT 2023
remove vnc: patch no longer necessary after last update
--- a/sys/src/cmd/vnc/auth.c
+++ /dev/null
@@ -1,171 +1,0 @@
-#include "vnc.h"
-#include <libsec.h>
-#include <auth.h>
-
-int
-vncsrvhandshake(Vnc *v)
-{
- char msg[VerLen+1];
-
- vncwrbytes(v, "RFB 003.003\n", VerLen);
- vncflush(v);
-
- vncrdbytes(v, msg, VerLen);
- if(verbose)
- fprint(2, "client version: %s\n", msg);
- return 0;
-}
-
-int
-vnchandshake(Vnc *v)
-{
- char msg[VerLen + 1];
-
- msg[VerLen] = 0;
- vncrdbytes(v, msg, VerLen);
-
- if(verbose)
- fprint(2, "server version: %s\n", msg);
-
- if(strncmp(msg, "RFB 003.003\n", VerLen) == 0)
- v->vers = 33;
- else if(strncmp(msg, "RFB 003.007\n", VerLen) == 0)
- v->vers = 37;
- else if(strncmp(msg, "RFB 003.008\n", VerLen) == 0)
- v->vers = 38;
- else if(strncmp(msg, "RFB 003.889\n", VerLen) == 0)
- v->vers = 38; /* Darwin */
- else if(strncmp(msg, "RFB 004.000\n", VerLen) == 0)
- v->vers = 38;
- else /* RFC6143: Any other should be treated as 3.3. */
- v->vers = 33;
-
- strcpy(msg, "RFB 003.008\n");
- vncwrbytes(v, msg, VerLen);
- vncflush(v);
- return 0;
-}
-
-int
-vncauth(Vnc *v, char *keypattern)
-{
- uchar chal[VncChalLen];
- ulong auth, type;
- int i, ntypes;
- char *err;
-
- if(keypattern == nil)
- keypattern = "";
-
- auth = AFailed;
- if(v->vers == 33)
- auth = vncrdlong(v);
- else{
- ntypes = vncrdchar(v);
- for(i = 0; i < ntypes; i++){
- type = vncrdchar(v);
- if(verbose)
- fprint(2, "auth type %uld\n", type);
- if(type > auth && type <= AVncAuth)
- auth = type;
- }
- if(auth == AFailed){
- werrstr("no supported auth types");
- return -1;
- }
- }
-
- switch(auth){
- default:
- werrstr("unknown auth type 0x%lux", auth);
- if(verbose)
- fprint(2, "unknown auth type 0x%lux\n", auth);
- return -1;
-
- case AFailed:
- err = vncrdstring(v);
- werrstr("%s", err);
- if(verbose)
- fprint(2, "auth failed: %s\n", err);
- return -1;
-
- case ANoAuth:
- if(v->vers == 38){
- vncwrchar(v, auth);
- vncflush(v);
- }
- if(verbose)
- fprint(2, "no auth needed\n");
- break;
-
- case AVncAuth:
- if(v->vers == 38){
- vncwrchar(v, auth);
- vncflush(v);
- }
-
- vncrdbytes(v, chal, VncChalLen);
- if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey,
- "proto=vnc role=client server=%s %s", v->srvaddr, keypattern) != VncChalLen){
- return -1;
- }
- vncwrbytes(v, chal, VncChalLen);
- vncflush(v);
- break;
- }
-
- /* in version 3.8 the auth status is always sent, in 3.3 and 3.7, only in AVncAuth */
- if(v->vers == 38 || auth == AVncAuth){
- auth = vncrdlong(v); /* auth status */
- switch(auth){
- default:
- werrstr("unknown server response 0x%lux", auth);
- return -1;
- case VncAuthFailed:
- err = (v->vers == 38) ? vncrdstring(v) : "rejected";
- werrstr("%s", err);
- if(verbose)
- fprint(2, "auth failed: %s\n", err);
- return -1;
- case VncAuthTooMany:
- werrstr("server says too many tries");
- return -1;
- case VncAuthOK:
- break;
- }
- }
- return 0;
-}
-
-int
-vncsrvauth(Vnc *v)
-{
- Chalstate *c;
- AuthInfo *ai;
-
- if((c = auth_challenge("proto=vnc role=server user=%q", getuser()))==nil)
- sysfatal("vncchal: %r");
- if(c->nchal != VncChalLen)
- sysfatal("vncchal got %d bytes wanted %d", c->nchal, VncChalLen);
- vncwrlong(v, AVncAuth);
- vncwrbytes(v, c->chal, VncChalLen);
- vncflush(v);
-
- vncrdbytes(v, c->chal, VncChalLen);
- c->resp = c->chal;
- c->nresp = VncChalLen;
- ai = auth_response(c);
- auth_freechal(c);
- if(ai == nil){
- fprint(2, "vnc auth failed: server factotum: %r\n");
- vncwrlong(v, VncAuthFailed);
- vncflush(v);
- return -1;
- }
- auth_freeAI(ai);
- vncwrlong(v, VncAuthOK);
- vncflush(v);
-
- return 0;
-}
-
--- a/sys/src/cmd/vnc/chan.c
+++ /dev/null
@@ -1,203 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-#include "error.h"
-
-Chan*
-newchan(void)
-{
- Chan *c;
-
- c = smalloc(sizeof(Chan));
-
- /* if you get an error before associating with a dev,
- close calls rootclose, a nop */
- c->type = 0;
- c->flag = 0;
- c->ref = 1;
- c->dev = 0;
- c->offset = 0;
- c->iounit = 0;
- c->aux = 0;
- c->name = 0;
- return c;
-}
-
-void
-chanfree(Chan *c)
-{
- c->flag = CFREE;
-
- cnameclose(c->name);
- free(c);
-}
-
-void
-cclose(Chan *c)
-{
- if(c->flag&CFREE)
- panic("cclose %#p", getcallerpc(&c));
- if(decref(c))
- return;
-
- if(!waserror()){
- devtab[c->type]->close(c);
- poperror();
- }
-
- chanfree(c);
-}
-
-Chan*
-cclone(Chan *c)
-{
- Chan *nc;
- Walkqid *wq;
-
- wq = devtab[c->type]->walk(c, nil, nil, 0);
- if(wq == nil)
- error("clone failed");
- nc = wq->clone;
- free(wq);
- nc->name = c->name;
- if(c->name)
- incref(c->name);
- return nc;
-}
-
-enum
-{
- CNAMESLOP = 20
-};
-
-static Ref ncname;
-
-void cleancname(Cname*);
-
-int
-isdotdot(char *p)
-{
- return p[0]=='.' && p[1]=='.' && p[2]=='\0';
-}
-
-int
-incref(Ref *r)
-{
- int x;
-
- lock(r);
- x = ++r->ref;
- unlock(r);
- return x;
-}
-
-int
-decref(Ref *r)
-{
- int x;
-
- lock(r);
- x = --r->ref;
- unlock(r);
- if(x < 0)
- panic("decref");
-
- return x;
-}
-
-Cname*
-newcname(char *s)
-{
- Cname *n;
- int i;
-
- n = smalloc(sizeof(Cname));
- i = strlen(s);
- n->len = i;
- n->alen = i+CNAMESLOP;
- n->s = smalloc(n->alen);
- memmove(n->s, s, i+1);
- n->ref = 1;
- incref(&ncname);
- return n;
-}
-
-void
-cnameclose(Cname *n)
-{
- if(n == nil)
- return;
- if(decref(n))
- return;
- decref(&ncname);
- free(n->s);
- free(n);
-}
-
-Cname*
-addelem(Cname *n, char *s)
-{
- int i, a;
- char *t;
- Cname *new;
-
- if(s[0]=='.' && s[1]=='\0')
- return n;
-
- if(n->ref > 1){
- /* copy on write */
- new = newcname(n->s);
- cnameclose(n);
- n = new;
- }
-
- i = strlen(s);
- if(n->len+1+i+1 > n->alen){
- a = n->len+1+i+1 + CNAMESLOP;
- t = smalloc(a);
- memmove(t, n->s, n->len+1);
- free(n->s);
- n->s = t;
- n->alen = a;
- }
- if(n->len>0 && n->s[n->len-1]!='/' && s[0]!='/') /* don't insert extra slash if one is present */
- n->s[n->len++] = '/';
- memmove(n->s+n->len, s, i+1);
- n->len += i;
- if(isdotdot(s))
- cleancname(n);
- return n;
-}
-
-/*
- * In place, rewrite name to compress multiple /, eliminate ., and process ..
- */
-void
-cleancname(Cname *n)
-{
- char *p;
-
- if(n->s[0] == '#'){
- p = strchr(n->s, '/');
- if(p == nil)
- return;
- cleanname(p);
-
- /*
- * The correct name is #i rather than #i/,
- * but the correct name of #/ is #/.
- */
- if(strcmp(p, "/")==0 && n->s[1] != '/')
- *p = '\0';
- }else
- cleanname(n->s);
- n->len = strlen(n->s);
-}
-
-void
-isdir(Chan *c)
-{
- if(c->qid.type & QTDIR)
- return;
- error(Enotdir);
-}
--- a/sys/src/cmd/vnc/color.c
+++ /dev/null
@@ -1,194 +1,0 @@
-#include "vnc.h"
-#include "vncv.h"
-
-enum {
- RGB12 = CHAN4(CIgnore, 4, CRed, 4, CGreen, 4, CBlue, 4),
- BGR12 = CHAN4(CIgnore, 4, CBlue, 4, CGreen, 4, CRed, 4),
- BGR8 = CHAN3(CBlue, 2, CGreen, 3, CRed, 3),
-};
-
-void (*cvtpixels)(uchar*, uchar*, int);
-
-static void
-chan2fmt(Pixfmt *fmt, ulong chan)
-{
- ulong c, rc, shift;
-
- shift = 0;
- for(rc = chan; rc; rc >>=8){
- c = rc & 0xFF;
- switch(TYPE(c)){
- case CRed:
- fmt->red = (Colorfmt){(1<<NBITS(c))-1, shift};
- break;
- case CBlue:
- fmt->blue = (Colorfmt){(1<<NBITS(c))-1, shift};
- break;
- case CGreen:
- fmt->green = (Colorfmt){(1<<NBITS(c))-1, shift};
- break;
- }
- shift += NBITS(c);
- }
-}
-
-/*
- * convert 32-bit data to 24-bit data by skipping
- * the last of every four bytes. we skip the last
- * because we keep the server in little endian mode.
- */
-static void
-cvt32to24(uchar *dst, uchar *src, int npixel)
-{
- int i;
-
- for(i=0; i<npixel; i++){
- *dst++ = *src++;
- *dst++ = *src++;
- *dst++ = *src++;
- src++;
- }
-}
-
-/*
- * convert RGB12 (x4r4g4b4) into CMAP8
- */
-static uchar rgb12[16*16*16];
-static void
-mkrgbtab(void)
-{
- int r, g, b;
-
- for(r=0; r<16; r++)
- for(g=0; g<16; g++)
- for(b=0; b<16; b++)
- rgb12[r*256+g*16+b] = rgb2cmap(r*0x11, g*0x11, b*0x11);
-}
-
-static void
-cvtrgb12tocmap8(uchar *dst, uchar *src, int npixel)
-{
- int i, s;
-
- for(i=0; i<npixel; i++){
- s = (src[0] | (src[1]<<8)) & 0xFFF;
- *dst++ = rgb12[s];
- src += 2;
- }
-}
-
-/*
- * convert BGR8 (b2g3r3, default VNC format) to CMAP8
- * some bits are lost.
- */
-static uchar bgr8[256];
-static void
-mkbgrtab(void)
-{
- int i, r, g, b;
-
- for(i=0; i<256; i++){
- b = i>>6;
- b = (b<<6)|(b<<4)|(b<<2)|b;
- g = (i>>3) & 7;
- g = (g<<5)|(g<<2)|(g>>1);
- r = i & 7;
- r = (r<<5)|(r<<2)|(r>>1);
- bgr8[i] = rgb2cmap(r, g, b);
- }
-}
-
-static void
-cvtbgr332tocmap8(uchar *dst, uchar *src, int npixel)
-{
- uchar *ed;
-
- ed = dst+npixel;
- while(dst < ed)
- *dst++ = bgr8[*src++];
-}
-
-static void
-cvt16to32(uchar *dst, uchar *src, int npixel)
-{
- uchar *ed;
- int w, r, g, b;
-
- ed = dst+npixel*4;
- while(dst < ed){
- w = src[1]<<8 | src[0];
- b = (w >> 11) & 0x1F;
- g = (w >> 5) & 0x3F;
- r = (w >> 0) & 0x1F;
- dst[0] = b<<(8-5);
- dst[1] = g<<(8-6);
- dst[2] = r<<(8-5);
- dst += 4;
- src += 2;
- }
-}
-
-void
-choosecolor(Vnc *v)
-{
- int bpp, depth;
- ulong chan;
-
- chan = screen->chan;
- depth = screen->depth;
- bpp = depth;
- if((bpp / 8) * 8 != bpp)
- sysfatal("screen not supported");
-/*
- if(bpp == 32 && v->Pixfmt.bpp == 16){
- cvtpixels = cvt16to32;
- goto Done;
- }
-*/
- if(bpp == 24){
- if(verbose)
- fprint(2, "24bit emulation using 32bpp\n");
- bpp = 32;
- cvtpixels = cvt32to24;
- }
-
- if(chan == CMAP8){
- if(bpp12){
- if(verbose)
- fprint(2, "8bit emulation using 12bpp\n");
- bpp = 16;
- depth = 12;
- chan = RGB12;
- cvtpixels = cvtrgb12tocmap8;
- mkrgbtab();
- }else{
- if(verbose)
- fprint(2, "8bit emulation using 6bpp\n"); /* 6: we throw away 1 r, g bit */
- bpp = 8;
- depth = 8;
- chan = BGR8;
- cvtpixels = cvtbgr332tocmap8;
- mkbgrtab();
- }
- }
-
- v->bpp = bpp;
- v->depth = depth;
- v->truecolor = 1;
- v->bigendian = 0;
- chan2fmt(v, chan);
- if(v->red.max == 0 || v->green.max == 0 || v->blue.max == 0)
- sysfatal("screen not supported");
-
-Done:
- if(verbose)
- fprint(2, "%d bpp, %d depth, 0x%lx chan, %d truecolor, %d bigendian\n",
- v->bpp, v->depth, screen->chan, v->truecolor, v->bigendian);
-
- /* send information to server */
- vncwrchar(v, MPixFmt);
- vncwrchar(v, 0); /* padding */
- vncwrshort(v, 0);
- vncwrpixfmt(v, &v->Pixfmt);
- vncflush(v);
-}
--- a/sys/src/cmd/vnc/compat.c
+++ /dev/null
@@ -1,250 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-#include "error.h"
-
-#include "errstr.h"
-
-ulong kerndate;
-Proc **privup;
-char *eve;
-extern void *mainmem;
-
-void
-_assert(char *fmt)
-{
- panic("assert failed: %s", fmt);
-}
-
-int
-errdepth(int ed)
-{
- if(ed >= 0 && up->nerrlab != ed)
- panic("unbalanced error depth: expected %d got %d\n", ed, up->nerrlab);
- return up->nerrlab;
-}
-
-void
-newup(char *name)
-{
- up = smalloc(sizeof(Proc));
- up->user = eve;
- strncpy(up->name, name, KNAMELEN-1);
- up->name[KNAMELEN-1] = '\0';
-}
-
-void
-kproc(char *name, void (*f)(void *), void *a)
-{
- int pid;
-
- pid = rfork(RFPROC|RFMEM|RFNOWAIT);
- switch(pid){
- case -1:
- panic("can't make new thread: %r");
- case 0:
- break;
- default:
- return;
- }
-
- newup(name);
- if(!waserror())
- (*f)(a);
- _exits(nil);
-}
-
-void
-kexit(void)
-{
- _exits(nil);
-}
-
-void
-initcompat(void)
-{
- rfork(RFREND);
- privup = privalloc();
- kerndate = seconds();
- eve = getuser();
- newup("main");
-}
-
-int
-openmode(ulong o)
-{
- o &= ~(OTRUNC|OCEXEC|ORCLOSE);
- if(o > OEXEC)
- error(Ebadarg);
- if(o == OEXEC)
- return OREAD;
- return o;
-}
-
-void
-panic(char *fmt, ...)
-{
- char buf[512];
- char buf2[512];
- va_list va;
-
- va_start(va, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, va);
- va_end(va);
- sprint(buf2, "panic: %s\n", buf);
- write(2, buf2, strlen(buf2));
-
- exits("error");
-}
-
-void*
-smalloc(ulong n)
-{
- void *p;
-
- p = mallocz(n, 1);
- if(p == nil)
- panic("out of memory");
- setmalloctag(p, getcallerpc(&n));
- return p;
-}
-
-long
-seconds(void)
-{
- return time(nil);
-}
-
-void
-error(char *err)
-{
- strncpy(up->error, err, ERRMAX);
- nexterror();
-}
-
-void
-nexterror(void)
-{
- longjmp(up->errlab[--up->nerrlab], 1);
-}
-
-int
-readstr(ulong off, char *buf, ulong n, char *str)
-{
- int size;
-
- size = strlen(str);
- if(off >= size)
- return 0;
- if(off+n > size)
- n = size-off;
- memmove(buf, str+off, n);
- return n;
-}
-
-void
-_rendsleep(void* tag)
-{
- void *value;
-
- for(;;){
- value = rendezvous(tag, (void*)0x22a891b8);
- if(value == (void*)0x7f7713f9)
- break;
- if(tag != (void*)~0)
- panic("_rendsleep: rendezvous mismatch");
- }
-}
-
-void
-_rendwakeup(void* tag)
-{
- void *value;
-
- for(;;){
- value = rendezvous(tag, (void*)0x7f7713f9);
- if(value == (void*)0x22a891b8)
- break;
- if(tag != (void*)~0)
- panic("_rendwakeup: rendezvous mismatch");
- }
-}
-
-void
-rendsleep(Rendez *r, int (*f)(void*), void *arg)
-{
- lock(&up->rlock);
- up->r = r;
- unlock(&up->rlock);
-
- lock(r);
-
- /*
- * if condition happened, never mind
- */
- if(up->intr || f(arg)){
- unlock(r);
- goto Done;
- }
-
- /*
- * now we are committed to
- * change state and call scheduler
- */
- if(r->p)
- panic("double sleep");
- r->p = up;
- unlock(r);
-
- _rendsleep(r);
-
-Done:
- lock(&up->rlock);
- up->r = 0;
- if(up->intr){
- up->intr = 0;
- unlock(&up->rlock);
- error(Eintr);
- }
- unlock(&up->rlock);
-}
-
-int
-rendwakeup(Rendez *r)
-{
- Proc *p;
- int rv;
-
- lock(r);
- p = r->p;
- rv = 0;
- if(p){
- r->p = nil;
- _rendwakeup(r);
- rv = 1;
- }
- unlock(r);
- return rv;
-}
-
-void
-rendintr(void *v)
-{
- Proc *p;
-
- p = v;
- lock(&p->rlock);
- p->intr = 1;
- if(p->r)
- rendwakeup(p->r);
- unlock(&p->rlock);
-}
-
-void
-rendclearintr(void)
-{
- lock(&up->rlock);
- up->intr = 0;
- unlock(&up->rlock);
-}
-
--- a/sys/src/cmd/vnc/compat.h
+++ /dev/null
@@ -1,168 +1,0 @@
-#define Rendez KRendez
-
-typedef struct Block Block;
-typedef struct Chan Chan;
-typedef struct Cname Cname;
-typedef struct Dev Dev;
-typedef struct Dirtab Dirtab;
-typedef struct Proc Proc;
-typedef struct Ref Ref;
-typedef struct Rendez Rendez;
-typedef struct Walkqid Walkqid;
-typedef int Devgen(Chan*, Dirtab*, int, int, Dir*);
-
-enum
-{
- KNAMELEN = 28,
- NERR = 15,
-
- COPEN = 0x0001, /* for i/o */
- CFREE = 0x0010, /* not in use */
-};
-
-struct Ref
-{
- Lock;
- int ref;
-};
-
-struct Rendez
-{
- Lock;
- Proc *p;
-};
-
-struct Chan
-{
- Ref;
- Chan* next; /* allocation */
- Chan* link;
- vlong offset; /* in file */
- ushort type;
- ulong dev;
- ushort mode; /* read/write */
- ushort flag;
- Qid qid;
- int fid; /* for devmnt */
- ulong iounit; /* chunk size for i/o; 0==default */
- void* aux;
- Cname *name;
-};
-
-struct Cname
-{
- Ref;
- int alen; /* allocated length */
- int len; /* strlen(s) */
- char *s;
-};
-
-struct Dev
-{
- int dc;
- char* name;
-
- void (*reset)(void);
- void (*init)(void);
- Chan* (*attach)(char*);
- Walkqid* (*walk)(Chan*, Chan*, char**, int);
- int (*stat)(Chan*, uchar*, int);
- Chan* (*open)(Chan*, int);
- void (*create)(Chan*, char*, int, ulong);
- void (*close)(Chan*);
- long (*read)(Chan*, void*, long, vlong);
- Block* (*bread)(Chan*, long, ulong);
- long (*write)(Chan*, void*, long, vlong);
- long (*bwrite)(Chan*, Block*, ulong);
- void (*remove)(Chan*);
- int (*wstat)(Chan*, uchar*, int);
-};
-
-struct Dirtab
-{
- char name[KNAMELEN];
- Qid qid;
- vlong length;
- long perm;
-};
-
-struct Walkqid
-{
- Chan *clone;
- int nqid;
- Qid qid[1];
-};
-
-struct Proc
-{
- Lock rlock; /* for rendsleep, rendwakeup, intr */
- Rendez *r;
- int intr;
-
- char name[KNAMELEN];
- char *user;
- char error[ERRMAX];
- int nerrlab;
- jmp_buf errlab[NERR];
- char genbuf[128]; /* buffer used e.g. for last name element from namec */
-};
-
-#define DEVDOTDOT -1
-
-extern Proc **privup;
-#define up (*privup)
-extern char *eve;
-extern Dev* devtab[];
-
-Chan* cclone(Chan*);
-void cclose(Chan*);
-void cnameclose(Cname*);
-int decref(Ref*);
-Chan* devattach(int, char*);
-Block* devbread(Chan*, long, ulong);
-long devbwrite(Chan*, Block*, ulong);
-void devcreate(Chan*, char*, int, ulong);
-void devdir(Chan*, Qid, char*, vlong, char*, long, Dir*);
-long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*);
-Devgen devgen;
-void devinit(void);
-Chan* devopen(Chan*, int, Dirtab*, int, Devgen*);
-void devremove(Chan*);
-void devreset(void);
-int devstat(Chan*, uchar*, int, Dirtab*, int, Devgen*);
-Walkqid* devwalk(Chan*, Chan*, char**, int, Dirtab*, int, Devgen*);
-int devwstat(Chan*, uchar*, int);
-void error(char*);
-int incref(Ref*);
-void isdir(Chan*);
-void kproc(char*, void(*)(void*), void*);
-void mkqid(Qid*, vlong, ulong, int);
-void nexterror(void);
-Chan* newchan(void);
-Cname* newcname(char*);
-int openmode(ulong);
-void panic(char*, ...);
-int readstr(ulong, char*, ulong, char*);
-long seconds(void);
-void* smalloc(ulong);
-
-#define poperror() up->nerrlab--
-#define waserror() (up->nerrlab++, setjmp(up->errlab[up->nerrlab-1]))
-
-void initcompat(void);
-void rendintr(void *v);
-void rendclearintr(void);
-void rendsleep(Rendez*, int(*)(void*), void*);
-int rendwakeup(Rendez*);
-void kexit(void);
-int sysexport(int fd, Chan **roots, int nroots);
-int errdepth(int ed);
-void newup(char *name);
-
-int exporter(Dev**, int*, int*);
-int mounter(char *mntpt, int how, int fds, int n);
-void shutdown(void);
-
-void screeninit(int, int, char*);
-
-#pragma varargck argpos panic 1
--- a/sys/src/cmd/vnc/dev.c
+++ /dev/null
@@ -1,339 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include "compat.h"
-#include "error.h"
-
-extern ulong kerndate;
-
-void
-mkqid(Qid *q, vlong path, ulong vers, int type)
-{
- q->type = type;
- q->vers = vers;
- q->path = path;
-}
-
-int
-devno(int c, int user)
-{
- int i;
-
- for(i = 0; devtab[i] != nil; i++){
- if(devtab[i]->dc == c)
- return i;
- }
- if(user == 0)
- panic("devno %C 0x%ux", c, c);
-
- return -1;
-}
-
-void
-devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db)
-{
- db->name = n;
- db->qid = qid;
- db->type = devtab[c->type]->dc;
- db->dev = c->dev;
- db->mode = (qid.type << 24) | perm;
- db->atime = seconds();
- db->mtime = kerndate;
- db->length = length;
- db->uid = user;
- db->gid = eve;
- db->muid = user;
-}
-
-/*
- * the zeroth element of the table MUST be the directory itself for ..
-*/
-int
-devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
-{
- if(tab == 0)
- return -1;
- if(i != DEVDOTDOT){
- i++; /* skip first element for . itself */
- if(i >= ntab)
- return -1;
- tab += i;
- }
- devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
- return 1;
-}
-
-void
-devreset(void)
-{
-}
-
-void
-devinit(void)
-{
-}
-
-Chan*
-devattach(int tc, char *spec)
-{
- Chan *c;
- char *buf;
-
- c = newchan();
- mkqid(&c->qid, 0, 0, QTDIR);
- c->type = devno(tc, 0);
- if(spec == nil)
- spec = "";
- buf = smalloc(4+strlen(spec)+1);
- sprint(buf, "#%C%s", tc, spec);
- c->name = newcname(buf);
- free(buf);
- return c;
-}
-
-
-Chan*
-devclone(Chan *c)
-{
- Chan *nc;
-
- if(c->flag & COPEN)
- panic("clone of open file type %C\n", devtab[c->type]->dc);
-
- nc = newchan();
-
- nc->type = c->type;
- nc->dev = c->dev;
- nc->mode = c->mode;
- nc->qid = c->qid;
- nc->offset = c->offset;
- nc->aux = c->aux;
- return nc;
-}
-
-Walkqid*
-devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen *gen)
-{
- int i, j, alloc;
- Walkqid *wq;
- char *n;
- Dir dir;
-
- isdir(c);
-
- alloc = 0;
- wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
- if(waserror()){
- if(alloc && wq->clone!=nil)
- cclose(wq->clone);
- free(wq);
- return nil;
- }
- if(nc == nil){
- nc = devclone(c);
- nc->type = 0; /* device doesn't know about this channel yet */
- alloc = 1;
- }
- wq->clone = nc;
-
- for(j=0; j<nname; j++){
- isdir(nc);
- n = name[j];
- if(strcmp(n, ".") == 0){
- Accept:
- wq->qid[wq->nqid++] = nc->qid;
- continue;
- }
- if(strcmp(n, "..") == 0){
- (*gen)(nc, tab, ntab, DEVDOTDOT, &dir);
- nc->qid = dir.qid;
- goto Accept;
- }
- for(i=0;; i++){
- switch((*gen)(nc, tab, ntab, i, &dir)){
- case -1:
- if(j == 0)
- error(Enonexist);
- strncpy(up->error, Enonexist, ERRMAX);
- goto Done;
- case 0:
- continue;
- case 1:
- if(strcmp(n, dir.name) == 0){
- nc->qid = dir.qid;
- goto Accept;
- }
- continue;
- }
- }
- }
- /*
- * We processed at least one name, so will return some data.
- * If we didn't process all nname entries succesfully, we drop
- * the cloned channel and return just the Qids of the walks.
- */
-Done:
- poperror();
- if(wq->nqid < nname){
- if(alloc)
- cclose(wq->clone);
- wq->clone = nil;
- }else if(wq->clone){
- /* attach cloned channel to same device */
- wq->clone->type = c->type;
- }
- return wq;
-}
-
-int
-devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen)
-{
- int i;
- Dir dir;
- char *p, *elem;
-
- for(i=0;; i++)
- switch((*gen)(c, tab, ntab, i, &dir)){
- case -1:
- if(c->qid.type & QTDIR){
- if(c->name == nil)
- elem = "???";
- else if(strcmp(c->name->s, "/") == 0)
- elem = "/";
- else
- for(elem=p=c->name->s; *p; p++)
- if(*p == '/')
- elem = p+1;
- devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir);
- return convD2M(&dir, db, n);
- }
-
- error(Enonexist);
- case 0:
- break;
- case 1:
- if(c->qid.path == dir.qid.path){
- return convD2M(&dir, db, n);
- }
- break;
- }
-}
-
-long
-devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen)
-{
- long k, m, dsz;
- struct{
- Dir;
- char slop[100];
- }dir;
-
- k = c->offset;
- for(m=0; m<n; k++){
- switch((*gen)(c, tab, ntab, k, &dir)){
- case -1:
- return m;
-
- case 0:
- c->offset++; /* BUG??? (was DIRLEN: skip entry) */
- break;
-
- case 1:
- dsz = convD2M(&dir, (uchar*)d, n-m);
- if(dsz <= BIT16SZ){ /* <= not < because this isn't stat; read is stuck */
- if(m == 0)
- return -1;
- return m;
- }
- m += dsz;
- d += dsz;
- break;
- }
- }
-
- return m;
-}
-
-/*
- * error(Eperm) if open permission not granted for up->user.
- */
-void
-devpermcheck(char *fileuid, ulong perm, int omode)
-{
- ulong t;
- static int access[] = { 0400, 0200, 0600, 0100 };
-
- if(strcmp(up->user, fileuid) == 0)
- perm <<= 0;
- else
- if(strcmp(up->user, eve) == 0)
- perm <<= 3;
- else
- perm <<= 6;
-
- t = access[omode&3];
- if((t&perm) != t)
- error(Eperm);
-}
-
-Chan*
-devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
-{
- int i;
- Dir dir;
-
- for(i=0;; i++){
- switch((*gen)(c, tab, ntab, i, &dir)){
- case -1:
- goto Return;
- case 0:
- break;
- case 1:
- if(c->qid.path == dir.qid.path){
- devpermcheck(dir.uid, dir.mode, omode);
- goto Return;
- }
- break;
- }
- }
-Return:
- c->offset = 0;
- if((c->qid.type&QTDIR) && omode!=OREAD)
- error(Eperm);
- c->mode = openmode(omode);
- c->flag |= COPEN;
- return c;
-}
-
-void
-devcreate(Chan*, char*, int, ulong)
-{
- error(Eperm);
-}
-
-Block*
-devbread(Chan *, long, ulong)
-{
- panic("no block read");
- return nil;
-}
-
-long
-devbwrite(Chan *, Block *, ulong)
-{
- panic("no block write");
- return 0;
-}
-
-void
-devremove(Chan*)
-{
- error(Eperm);
-}
-
-int
-devwstat(Chan*, uchar*, int)
-{
- error(Eperm);
- return 0;
-}
--- a/sys/src/cmd/vnc/devcons.c
+++ /dev/null
@@ -1,186 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-#include "kbd.h"
-#include "error.h"
-
-Snarf snarf = {
- .vers = 1
-};
-
-enum{
- Qdir,
- Qcons,
- Qconsctl,
- Qsnarf,
-};
-
-static Dirtab consdir[]={
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
- "cons", {Qcons}, 0, 0660,
- "consctl", {Qconsctl}, 0, 0220,
- "snarf", {Qsnarf}, 0, 0600,
-};
-
-static Chan*
-consattach(char *spec)
-{
- return devattach('c', spec);
-}
-
-static Walkqid*
-conswalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name,nname, consdir, nelem(consdir), devgen);
-}
-
-static int
-consstat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, consdir, nelem(consdir), devgen);
-}
-
-static Chan*
-consopen(Chan *c, int omode)
-{
- c->aux = nil;
- c = devopen(c, omode, consdir, nelem(consdir), devgen);
- switch((ulong)c->qid.path){
- case Qconsctl:
- break;
- case Qsnarf:
- if((c->mode&3) == OWRITE || (c->mode&3) == ORDWR)
- c->aux = smalloc(sizeof(Snarf));
- break;
- }
- return c;
-}
-
-void
-setsnarf(char *buf, int n, int *vers)
-{
- int i;
-
- qlock(&snarf);
- snarf.vers++;
- if(vers)
- *vers = snarf.vers;
- for(i = 0; i < nelem(consdir); i++){
- if(consdir[i].qid.type == Qsnarf){
- consdir[i].qid.vers = snarf.vers;
- break;
- }
- }
- free(snarf.buf);
- snarf.n = n;
- snarf.buf = buf;
- qunlock(&snarf);
-}
-
-static void
-consclose(Chan *c)
-{
- Snarf *t;
-
- switch((ulong)c->qid.path){
- /* last close of control file turns off raw */
- case Qconsctl:
- break;
- /* odd behavior but really ok: replace snarf buffer when /dev/snarf is closed */
- case Qsnarf:
- t = c->aux;
- if(t == nil)
- break;
- setsnarf(t->buf, t->n, 0);
- t->buf = nil; /* setsnarf took it */
- free(t);
- c->aux = nil;
- break;
- }
-}
-
-static long
-consread(Chan *c, void *buf, long n, vlong off)
-{
- if(n <= 0)
- return n;
- switch((ulong)c->qid.path){
- case Qsnarf:
- qlock(&snarf);
- if(off < snarf.n){
- if(off + n > snarf.n)
- n = snarf.n - off;
- memmove(buf, snarf.buf+off, n);
- }else
- n = 0;
- qunlock(&snarf);
- return n;
-
- case Qdir:
- return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
-
- case Qcons:
- error(Egreg);
- return -1;
-
- default:
- print("consread 0x%llux\n", c->qid.path);
- error(Egreg);
- }
- return -1; /* never reached */
-}
-
-static long
-conswrite(Chan *c, void *va, long n, vlong)
-{
- Snarf *t;
- char *a;
-
- switch((ulong)c->qid.path){
- case Qcons:
- screenputs(va, n);
- break;
-
- case Qconsctl:
- error(Egreg);
- break;
-
- case Qsnarf:
- t = c->aux;
- /* always append only */
- if(t->n > MAXSNARF) /* avoid thrashing when people cut huge text */
- error("snarf buffer too big");
- a = realloc(t->buf, t->n + n + 1);
- if(a == nil)
- error("snarf buffer too big");
- t->buf = a;
- memmove(t->buf+t->n, va, n);
- t->n += n;
- t->buf[t->n] = '\0';
- break;
- default:
- print("conswrite: 0x%llux\n", c->qid.path);
- error(Egreg);
- }
- return n;
-}
-
-Dev consdevtab = {
- 'c',
- "cons",
-
- devreset,
- devinit,
- consattach,
- conswalk,
- consstat,
- consopen,
- devcreate,
- consclose,
- consread,
- devbread,
- conswrite,
- devbwrite,
- devremove,
- devwstat,
-};
--- a/sys/src/cmd/vnc/devdraw.c
+++ /dev/null
@@ -1,2134 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-#include "error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <memlayer.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum
-{
- Qtopdir = 0,
- Qnew,
- Qwinname,
- Q3rd,
- Q2nd,
- Qcolormap,
- Qctl,
- Qdata,
- Qrefresh,
-};
-
-/*
- * Qid path is:
- * 4 bits of file type (qids above)
- * 24 bits of mux slot number +1; 0 means not attached to client
- */
-#define QSHIFT 4 /* location in qid of client # */
-
-#define QID(q) ((((ulong)(q).path)&0x0000000F)>>0)
-#define CLIENTPATH(q) ((((ulong)q)&0x7FFFFFF0)>>QSHIFT)
-#define CLIENT(q) CLIENTPATH((q).path)
-
-#define NHASH (1<<5)
-#define HASHMASK (NHASH-1)
-
-typedef struct Client Client;
-typedef struct Draw Draw;
-typedef struct DImage DImage;
-typedef struct DScreen DScreen;
-typedef struct CScreen CScreen;
-typedef struct FChar FChar;
-typedef struct Refresh Refresh;
-typedef struct Refx Refx;
-typedef struct DName DName;
-
-struct Draw
-{
- int clientid;
- int nclient;
- Client** client;
- int nname;
- DName* name;
- int vers;
- int softscreen;
-};
-
-struct Client
-{
- Ref r;
- DImage* dimage[NHASH];
- CScreen* cscreen;
- Refresh* refresh;
- Rendez refrend;
- QLock refq;
- uchar* readdata;
- int nreaddata;
- int busy;
- int clientid;
- int slot;
- int refreshme;
- int infoid;
- int op;
-};
-
-struct Refresh
-{
- DImage* dimage;
- Rectangle r;
- Refresh* next;
-};
-
-struct Refx
-{
- Client* client;
- DImage* dimage;
-};
-
-struct DName
-{
- char *name;
- Client *client;
- DImage* dimage;
- int vers;
-};
-
-struct FChar
-{
- int minx; /* left edge of bits */
- int maxx; /* right edge of bits */
- uchar miny; /* first non-zero scan-line */
- uchar maxy; /* last non-zero scan-line + 1 */
- schar left; /* offset of baseline */
- uchar width; /* width of baseline */
-};
-
-/*
- * Reference counts in DImages:
- * one per open by original client
- * one per screen image or fill
- * one per image derived from this one by name
- */
-struct DImage
-{
- int id;
- int ref;
- char *name;
- int vers;
- Memimage* image;
- int ascent;
- int nfchar;
- FChar* fchar;
- DScreen* dscreen; /* 0 if not a window */
- DImage* fromname; /* image this one is derived from, by name */
- DImage* next;
-};
-
-struct CScreen
-{
- DScreen* dscreen;
- CScreen* next;
-};
-
-struct DScreen
-{
- int id;
- int public;
- int ref;
- DImage *dimage;
- DImage *dfill;
- Memscreen* screen;
- Client* owner;
- DScreen* next;
-};
-
-static Draw sdraw;
- QLock drawlock;
-
-static Memimage *screenimage;
-static DImage* screendimage;
-static char screenname[40];
-static int screennameid;
-
-static Rectangle flushrect;
-static int waste;
-static DScreen* dscreen;
-extern void flushmemscreen(Rectangle);
- void drawmesg(Client*, void*, int);
- void drawuninstall(Client*, int);
- void drawfreedimage(DImage*);
- Client* drawclientofpath(ulong);
- DImage* allocdimage(Memimage*);
-
-static char Enodrawimage[] = "unknown id for draw image";
-static char Enodrawscreen[] = "unknown id for draw screen";
-static char Eshortdraw[] = "short draw message";
-static char Eshortread[] = "draw read too short";
-static char Eimageexists[] = "image id in use";
-static char Escreenexists[] = "screen id in use";
-static char Edrawmem[] = "image memory allocation failed";
-static char Ereadoutside[] = "readimage outside image";
-static char Ewriteoutside[] = "writeimage outside image";
-static char Enotfont[] = "image not a font";
-static char Eindex[] = "character index out of range";
-static char Enoclient[] = "no such draw client";
-static char Enameused[] = "image name in use";
-static char Enoname[] = "no image with that name";
-static char Eoldname[] = "named image no longer valid";
-static char Enamed[] = "image already has name";
-static char Ewrongname[] = "wrong name for image";
-
-static void
-dlock(void)
-{
- qlock(&drawlock);
-}
-
-static int
-candlock(void)
-{
- return canqlock(&drawlock);
-}
-
-static void
-dunlock(void)
-{
- qunlock(&drawlock);
-}
-
-static int
-drawgen(Chan *c, Dirtab*, int, int s, Dir *dp)
-{
- int t;
- Qid q;
- ulong path;
- Client *cl;
-
- q.vers = 0;
-
- if(s == DEVDOTDOT){
- switch(QID(c->qid)){
- case Qtopdir:
- case Q2nd:
- mkqid(&q, Qtopdir, 0, QTDIR);
- devdir(c, q, "#i", 0, eve, 0500, dp);
- break;
- case Q3rd:
- cl = drawclientofpath(c->qid.path);
- if(cl == nil)
- strcpy(up->genbuf, "??");
- else
- sprint(up->genbuf, "%d", cl->clientid);
- mkqid(&q, Q2nd, 0, QTDIR);
- devdir(c, q, up->genbuf, 0, eve, 0500, dp);
- break;
- default:
- panic("drawwalk %llux", c->qid.path);
- }
- return 1;
- }
-
- /*
- * Top level directory contains the name of the device.
- */
- t = QID(c->qid);
- switch(t){
- case Qtopdir:
- if(s == 0){
- mkqid(&q, Q2nd, 0, QTDIR);
- devdir(c, q, "draw", 0, eve, 0555, dp);
- return 1;
- }
- if(s == 1){
- case Qwinname:
- mkqid(&q, Qwinname, 0, QTFILE);
- devdir(c, q, "winname", 0, eve, 0444, dp);
- return 1;
- }
- return -1;
- }
-
- /*
- * Second level contains "new" plus all the clients.
- */
- switch(t){
- case Q2nd:
- if(s == 0){
- case Qnew:
- mkqid(&q, Qnew, 0, QTFILE);
- devdir(c, q, "new", 0, eve, 0666, dp);
- return 1;
- }
- if(s <= sdraw.nclient){
- cl = sdraw.client[s-1];
- if(cl == nil)
- return 0;
- sprint(up->genbuf, "%d", cl->clientid);
- mkqid(&q, (s<<QSHIFT)|Q3rd, 0, QTDIR);
- devdir(c, q, up->genbuf, 0, eve, 0555, dp);
- return 1;
- }
- return -1;
- }
-
- /*
- * Third level.
- */
- path = c->qid.path&~((1<<QSHIFT)-1); /* slot component */
- q.vers = c->qid.vers;
- q.type = QTFILE;
- switch(s){
- case 0:
- q.path = path|Qcolormap;
- devdir(c, q, "colormap", 0, eve, 0600, dp);
- break;
- case 1:
- q.path = path|Qctl;
- devdir(c, q, "ctl", 0, eve, 0600, dp);
- break;
- case 2:
- q.path = path|Qdata;
- devdir(c, q, "data", 0, eve, 0600, dp);
- break;
- case 3:
- q.path = path|Qrefresh;
- devdir(c, q, "refresh", 0, eve, 0400, dp);
- break;
- default:
- return -1;
- }
- return 1;
-}
-
-static
-int
-drawrefactive(void *a)
-{
- Client *c;
-
- c = a;
- return c->refreshme || c->refresh!=0;
-}
-
-static
-void
-drawrefreshscreen(DImage *l, Client *client)
-{
- while(l != nil && l->dscreen == nil)
- l = l->fromname;
- if(l != nil && l->dscreen->owner != client)
- l->dscreen->owner->refreshme = 1;
-}
-
-static
-void
-drawrefresh(Memimage*, Rectangle r, void *v)
-{
- Refx *x;
- DImage *d;
- Client *c;
- Refresh *ref;
-
- if(v == 0)
- return;
- x = v;
- c = x->client;
- d = x->dimage;
- for(ref=c->refresh; ref; ref=ref->next)
- if(ref->dimage == d){
- combinerect(&ref->r, r);
- return;
- }
- ref = malloc(sizeof(Refresh));
- if(ref){
- ref->dimage = d;
- ref->r = r;
- ref->next = c->refresh;
- c->refresh = ref;
- }
-}
-
-static void
-addflush(Rectangle r)
-{
- int abb, ar, anbb;
- Rectangle nbb;
-
- if(sdraw.softscreen==0 || screenimage == nil || !rectclip(&r, screenimage->r))
- return;
- if(flushrect.min.x >= flushrect.max.x){
- flushrect = r;
- waste = 0;
- return;
- }
- /* VNC uses a region to compute the minimum bounding area.
- * The waste is far less than that of a bounding box. see region.c
- */
- if(1){
- flushmemscreen(flushrect);
- flushrect = r;
- return;
- }
- nbb = flushrect;
- combinerect(&nbb, r);
- ar = Dx(r)*Dy(r);
- abb = Dx(flushrect)*Dy(flushrect);
- anbb = Dx(nbb)*Dy(nbb);
- /*
- * Area of new waste is area of new bb minus area of old bb,
- * less the area of the new segment, which we assume is not waste.
- * This could be negative, but that's OK.
- */
- waste += anbb-abb - ar;
- if(waste < 0)
- waste = 0;
- /*
- * absorb if:
- * total area is small
- * waste is less than half total area
- * rectangles touch
- */
- if(anbb<=1024 || waste*2<anbb || rectXrect(flushrect, r)){
- flushrect = nbb;
- return;
- }
- /* emit current state */
- if(flushrect.min.x < flushrect.max.x)
- flushmemscreen(flushrect);
- flushrect = r;
- waste = 0;
-}
-
-static
-void
-dstflush(int dstid, Memimage *dst, Rectangle r)
-{
- Memlayer *l;
-
- if(dstid == 0){
- //combinerect(&flushrect, r);
- addflush(r); // for VNC, see comments in addflush
- return;
- }
- if(screenimage == nil || dst == nil || (l = dst->layer) == nil)
- return;
- do{
- if(l->screen->image->data != screenimage->data)
- return;
- r = rectaddpt(r, l->delta);
- l = l->screen->image->layer;
- }while(l);
- addflush(r);
-}
-
-void
-drawflush(void)
-{
- if(screenimage && flushrect.min.x < flushrect.max.x)
- flushmemscreen(flushrect);
- flushrect = Rect(10000, 10000, -10000, -10000);
-}
-
-static
-int
-drawcmp(char *a, char *b, int n)
-{
- if(strlen(a) != n)
- return 1;
- return memcmp(a, b, n);
-}
-
-DName*
-drawlookupname(int n, char *str)
-{
- DName *name, *ename;
-
- name = sdraw.name;
- ename = &name[sdraw.nname];
- for(; name<ename; name++)
- if(drawcmp(name->name, str, n) == 0)
- return name;
- return 0;
-}
-
-int
-drawgoodname(DImage *d)
-{
- DName *n;
-
- /* if window, validate the screen's own images */
- if(d->dscreen)
- if(drawgoodname(d->dscreen->dimage) == 0
- || drawgoodname(d->dscreen->dfill) == 0)
- return 0;
- if(d->name == nil)
- return 1;
- n = drawlookupname(strlen(d->name), d->name);
- if(n==nil || n->vers!=d->vers)
- return 0;
- return 1;
-}
-
-DImage*
-drawlookup(Client *client, int id, int checkname)
-{
- DImage *d;
-
- d = client->dimage[id&HASHMASK];
- while(d){
- if(d->id == id){
- if(checkname && !drawgoodname(d))
- error(Eoldname);
- return d;
- }
- d = d->next;
- }
- return 0;
-}
-
-DScreen*
-drawlookupdscreen(int id)
-{
- DScreen *s;
-
- s = dscreen;
- while(s){
- if(s->id == id)
- return s;
- s = s->next;
- }
- return 0;
-}
-
-DScreen*
-drawlookupscreen(Client *client, int id, CScreen **cs)
-{
- CScreen *s;
-
- s = client->cscreen;
- while(s){
- if(s->dscreen->id == id){
- *cs = s;
- return s->dscreen;
- }
- s = s->next;
- }
- error(Enodrawscreen);
- return 0;
-}
-
-DImage*
-allocdimage(Memimage *i)
-{
- DImage *d;
-
- d = malloc(sizeof(DImage));
- if(d == 0)
- return 0;
- d->ref = 1;
- d->name = 0;
- d->vers = 0;
- d->image = i;
- d->dscreen = 0;
- d->nfchar = 0;
- d->fchar = 0;
- d->fromname = 0;
- return d;
-}
-
-Memimage*
-drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
-{
- DImage *d;
-
- d = allocdimage(i);
- if(d == 0)
- return 0;
- d->id = id;
- d->dscreen = dscreen;
- d->next = client->dimage[id&HASHMASK];
- client->dimage[id&HASHMASK] = d;
- return i;
-}
-
-Memscreen*
-drawinstallscreen(Client *client, DScreen *d, int id, DImage *dimage, DImage *dfill, int public)
-{
- Memscreen *s;
- CScreen *c;
-
- c = malloc(sizeof(CScreen));
- if(dimage && dimage->image && dimage->image->chan == 0)
- panic("bad image %p in drawinstallscreen", dimage->image);
-
- if(c == 0)
- return 0;
- if(d == 0){
- d = malloc(sizeof(DScreen));
- if(d == 0){
- free(c);
- return 0;
- }
- s = malloc(sizeof(Memscreen));
- if(s == 0){
- free(c);
- free(d);
- return 0;
- }
- s->frontmost = 0;
- s->rearmost = 0;
- d->dimage = dimage;
- if(dimage){
- s->image = dimage->image;
- dimage->ref++;
- }
- d->dfill = dfill;
- if(dfill){
- s->fill = dfill->image;
- dfill->ref++;
- }
- d->ref = 0;
- d->id = id;
- d->screen = s;
- d->public = public;
- d->next = dscreen;
- d->owner = client;
- dscreen = d;
- }
- c->dscreen = d;
- d->ref++;
- c->next = client->cscreen;
- client->cscreen = c;
- return d->screen;
-}
-
-void
-drawdelname(DName *name)
-{
- int i;
-
- free(name->name);
- i = name-sdraw.name;
- memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName));
- sdraw.nname--;
-}
-
-void
-drawfreedscreen(DScreen *this)
-{
- DScreen *ds, *next;
-
- this->ref--;
- if(this->ref < 0)
- print("negative ref in drawfreedscreen\n");
- if(this->ref > 0)
- return;
- ds = dscreen;
- if(ds == this){
- dscreen = this->next;
- goto Found;
- }
- while(next = ds->next){ /* assign = */
- if(next == this){
- ds->next = this->next;
- goto Found;
- }
- ds = next;
- }
- error(Enodrawimage);
-
- Found:
- if(this->dimage)
- drawfreedimage(this->dimage);
- if(this->dfill)
- drawfreedimage(this->dfill);
- free(this->screen);
- free(this);
-}
-
-void
-drawfreedimage(DImage *dimage)
-{
- int i;
- Memimage *l;
- DScreen *ds;
-
- dimage->ref--;
- if(dimage->ref < 0)
- print("negative ref in drawfreedimage\n");
- if(dimage->ref > 0)
- return;
-
- /* any names? */
- for(i=0; i<sdraw.nname; )
- if(sdraw.name[i].dimage == dimage)
- drawdelname(sdraw.name+i);
- else
- i++;
- if(dimage->fromname){ /* acquired by name; owned by someone else*/
- drawfreedimage(dimage->fromname);
- goto Return;
- }
- ds = dimage->dscreen;
- if(ds){
- l = dimage->image;
- if(screenimage && l->data == screenimage->data)
- addflush(l->layer->screenr);
- if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
- free(l->layer->refreshptr);
- l->layer->refreshptr = nil;
- if(drawgoodname(dimage))
- memldelete(l);
- else
- memlfree(l);
- drawfreedscreen(ds);
- }else
- freememimage(dimage->image);
- Return:
- free(dimage->fchar);
- free(dimage);
-}
-
-void
-drawuninstallscreen(Client *client, CScreen *this)
-{
- CScreen *cs, *next;
-
- cs = client->cscreen;
- if(cs == this){
- client->cscreen = this->next;
- drawfreedscreen(this->dscreen);
- free(this);
- return;
- }
- while(next = cs->next){ /* assign = */
- if(next == this){
- cs->next = this->next;
- drawfreedscreen(this->dscreen);
- free(this);
- return;
- }
- cs = next;
- }
-}
-
-void
-drawuninstall(Client *client, int id)
-{
- DImage *d, *next;
-
- d = client->dimage[id&HASHMASK];
- if(d == 0)
- error(Enodrawimage);
- if(d->id == id){
- client->dimage[id&HASHMASK] = d->next;
- drawfreedimage(d);
- return;
- }
- while(next = d->next){ /* assign = */
- if(next->id == id){
- d->next = next->next;
- drawfreedimage(next);
- return;
- }
- d = next;
- }
- error(Enodrawimage);
-}
-
-void
-drawaddname(Client *client, DImage *di, int n, char *str)
-{
- DName *name, *ename, *new, *t;
-
- name = sdraw.name;
- ename = &name[sdraw.nname];
- for(; name<ename; name++)
- if(drawcmp(name->name, str, n) == 0)
- error(Enameused);
- t = smalloc((sdraw.nname+1)*sizeof(DName));
- memmove(t, sdraw.name, sdraw.nname*sizeof(DName));
- free(sdraw.name);
- sdraw.name = t;
- new = &sdraw.name[sdraw.nname++];
- new->name = smalloc(n+1);
- memmove(new->name, str, n);
- new->name[n] = 0;
- new->dimage = di;
- new->client = client;
- new->vers = ++sdraw.vers;
-}
-
-Client*
-drawnewclient(void)
-{
- Client *cl, **cp;
- int i;
-
- for(i=0; i<sdraw.nclient; i++){
- cl = sdraw.client[i];
- if(cl == 0)
- break;
- }
- if(i == sdraw.nclient){
- cp = malloc((sdraw.nclient+1)*sizeof(Client*));
- if(cp == 0)
- return 0;
- memmove(cp, sdraw.client, sdraw.nclient*sizeof(Client*));
- free(sdraw.client);
- sdraw.client = cp;
- sdraw.nclient++;
- cp[i] = 0;
- }
- cl = malloc(sizeof(Client));
- if(cl == 0)
- return 0;
- memset(cl, 0, sizeof(Client));
- cl->slot = i;
- cl->clientid = ++sdraw.clientid;
- cl->op = SoverD;
- sdraw.client[i] = cl;
- return cl;
-}
-
-static int
-drawclientop(Client *cl)
-{
- int op;
-
- op = cl->op;
- cl->op = SoverD;
- return op;
-}
-
-int
-drawhasclients(void)
-{
- /*
- * if draw has ever been used, we can't resize the frame buffer,
- * even if all clients have exited (nclients is cumulative); it's too
- * hard to make work.
- */
- return sdraw.nclient != 0;
-}
-
-Client*
-drawclientofpath(ulong path)
-{
- Client *cl;
- int slot;
-
- slot = CLIENTPATH(path);
- if(slot == 0)
- return nil;
- cl = sdraw.client[slot-1];
- if(cl==0 || cl->clientid==0)
- return nil;
- return cl;
-}
-
-
-Client*
-drawclient(Chan *c)
-{
- Client *client;
-
- client = drawclientofpath(c->qid.path);
- if(client == nil)
- error(Enoclient);
- return client;
-}
-
-Memimage*
-drawimage(Client *client, uchar *a)
-{
- DImage *d;
-
- d = drawlookup(client, BGLONG(a), 1);
- if(d == nil)
- error(Enodrawimage);
- return d->image;
-}
-
-void
-drawrectangle(Rectangle *r, uchar *a)
-{
- r->min.x = BGLONG(a+0*4);
- r->min.y = BGLONG(a+1*4);
- r->max.x = BGLONG(a+2*4);
- r->max.y = BGLONG(a+3*4);
-}
-
-void
-drawpoint(Point *p, uchar *a)
-{
- p->x = BGLONG(a+0*4);
- p->y = BGLONG(a+1*4);
-}
-
-Point
-drawchar(Memimage *dst, Memimage *rdst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
-{
- FChar *fc;
- Rectangle r;
- Point sp1;
- static Memimage *tmp;
-
- fc = &font->fchar[index];
- r.min.x = p.x+fc->left;
- r.min.y = p.y-(font->ascent-fc->miny);
- r.max.x = r.min.x+(fc->maxx-fc->minx);
- r.max.y = r.min.y+(fc->maxy-fc->miny);
- sp1.x = sp->x+fc->left;
- sp1.y = sp->y+fc->miny;
-
- /*
- * If we're drawing greyscale fonts onto a VGA screen,
- * it's very costly to read the screen memory to do the
- * alpha blending inside memdraw. If this is really a stringbg,
- * then rdst is the bg image (in main memory) which we can
- * refer to for the underlying dst pixels instead of reading dst
- * directly.
- */
- if(ishwimage(dst) && !ishwimage(rdst) && font->image->depth > 1){
- if(tmp == nil || tmp->chan != dst->chan || Dx(tmp->r) < Dx(r) || Dy(tmp->r) < Dy(r)){
- if(tmp)
- freememimage(tmp);
- tmp = allocmemimage(Rect(0,0,Dx(r),Dy(r)), dst->chan);
- if(tmp == nil)
- goto fallback;
- }
- memdraw(tmp, Rect(0,0,Dx(r),Dy(r)), rdst, r.min, memopaque, ZP, S);
- memdraw(tmp, Rect(0,0,Dx(r),Dy(r)), src, sp1, font->image, Pt(fc->minx, fc->miny), op);
- memdraw(dst, r, tmp, ZP, memopaque, ZP, S);
- }else{
- fallback:
- memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
- }
-
- p.x += fc->width;
- sp->x += fc->width;
- return p;
-}
-
-static DImage*
-makescreenimage(void)
-{
- int width, depth;
- ulong chan;
- DImage *di;
- Memdata *md;
- Memimage *i;
- Rectangle r;
-
- if((md = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen)) == nil)
- return nil;
- assert(md->ref > 0);
- if((i = allocmemimaged(r, chan, md)) == nil){
- if(--md->ref == 0 && md->allocd)
- free(md);
- return nil;
- }
- i->width = width;
- i->clipr = r;
- di = allocdimage(i);
- if(di == nil){
- freememimage(i); /* frees md */
- return nil;
- }
- if(!waserror()){
- snprint(screenname, sizeof screenname, "noborder.screen.%d", ++screennameid);
- drawaddname(nil, di, strlen(screenname), screenname);
- poperror();
- }
- return di;
-}
-
-static int
-initscreenimage(void)
-{
- if(screenimage != nil)
- return 1;
-
- screendimage = makescreenimage();
- if(screendimage == nil)
- return 0;
- screenimage = screendimage->image;
-// iprint("initscreenimage %p %p\n", screendimage, screenimage);
- mouseresize();
- return 1;
-}
-
-void
-deletescreenimage(void)
-{
- dlock();
- if(screenimage){
- /* will be freed via screendimage; disable */
- screenimage->clipr = ZR;
- screenimage = nil;
- }
- if(screendimage){
- drawfreedimage(screendimage);
- screendimage = nil;
- }
- dunlock();
-}
-
-void
-resetscreenimage(void)
-{
- dlock();
- initscreenimage();
- dunlock();
-}
-
-static Chan*
-drawattach(char *spec)
-{
- dlock();
- if(!initscreenimage()){
- dunlock();
- error("no frame buffer");
- }
- dunlock();
- return devattach('i', spec);
-}
-
-static Walkqid*
-drawwalk(Chan *c, Chan *nc, char **name, int nname)
-{
- if(screenimage == nil)
- error("no frame buffer");
- return devwalk(c, nc, name, nname, 0, 0, drawgen);
-}
-
-static int
-drawstat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, 0, 0, drawgen);
-}
-
-static Chan*
-drawopen(Chan *c, int omode)
-{
- Client *cl;
- DName *dn;
- DImage *di;
-
- if(c->qid.type & QTDIR){
- c = devopen(c, omode, 0, 0, drawgen);
- c->iounit = IOUNIT;
- }
-
- dlock();
- if(waserror()){
- dunlock();
- nexterror();
- }
-
- if(QID(c->qid) == Qnew){
- cl = drawnewclient();
- if(cl == 0)
- error(Enodev);
- c->qid.path = Qctl|((cl->slot+1)<<QSHIFT);
- }
-
- switch(QID(c->qid)){
- case Qwinname:
- break;
-
- case Qnew:
- break;
-
- case Qctl:
- cl = drawclient(c);
- if(cl->busy)
- error(Einuse);
- cl->busy = 1;
- flushrect = Rect(10000, 10000, -10000, -10000);
- dn = drawlookupname(strlen(screenname), screenname);
- if(dn == 0)
- error("draw: cannot happen 2");
- if(drawinstall(cl, 0, dn->dimage->image, 0) == 0)
- error(Edrawmem);
- di = drawlookup(cl, 0, 0);
- if(di == 0)
- error("draw: cannot happen 1");
- di->vers = dn->vers;
- di->name = smalloc(strlen(screenname)+1);
- strcpy(di->name, screenname);
- di->fromname = dn->dimage;
- di->fromname->ref++;
- incref(&cl->r);
- break;
-
- case Qcolormap:
- case Qdata:
- case Qrefresh:
- cl = drawclient(c);
- incref(&cl->r);
- break;
- }
- dunlock();
- poperror();
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- c->iounit = IOUNIT;
- return c;
-}
-
-static void
-drawclose(Chan *c)
-{
- int i;
- DImage *d, **dp;
- Client *cl;
- Refresh *r;
-
- if(QID(c->qid) < Qcolormap) /* Qtopdir, Qnew, Q3rd, Q2nd have no client */
- return;
- dlock();
- if(waserror()){
- dunlock();
- nexterror();
- }
-
- cl = drawclient(c);
- if(QID(c->qid) == Qctl)
- cl->busy = 0;
- if((c->flag&COPEN) && (decref(&cl->r)==0)){
- while(r = cl->refresh){ /* assign = */
- cl->refresh = r->next;
- free(r);
- }
- /* free names */
- for(i=0; i<sdraw.nname; )
- if(sdraw.name[i].client == cl)
- drawdelname(sdraw.name+i);
- else
- i++;
- while(cl->cscreen)
- drawuninstallscreen(cl, cl->cscreen);
- /* all screens are freed, so now we can free images */
- dp = cl->dimage;
- for(i=0; i<NHASH; i++){
- while((d = *dp) != nil){
- *dp = d->next;
- drawfreedimage(d);
- }
- dp++;
- }
- sdraw.client[cl->slot] = 0;
- drawflush(); /* to erase visible, now dead windows */
- free(cl);
- }
- dunlock();
- poperror();
-}
-
-long
-drawread(Chan *c, void *a, long n, vlong off)
-{
- int index, m;
- ulong red, green, blue;
- Client *cl;
- uchar *p;
- Refresh *r;
- DImage *di;
- Memimage *i;
- ulong offset = off;
- char buf[16];
-
- if(c->qid.type & QTDIR)
- return devdirread(c, a, n, 0, 0, drawgen);
- if(QID(c->qid) == Qwinname)
- return readstr(off, a, n, screenname);
-
- cl = drawclient(c);
- dlock();
- if(waserror()){
- dunlock();
- nexterror();
- }
- switch(QID(c->qid)){
- case Qctl:
- if(n < 12*12)
- error(Eshortread);
- if(cl->infoid < 0)
- error(Enodrawimage);
- if(cl->infoid == 0){
- i = screenimage;
- if(i == nil)
- error(Enodrawimage);
- }else{
- di = drawlookup(cl, cl->infoid, 1);
- if(di == nil)
- error(Enodrawimage);
- i = di->image;
- }
- n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d",
- cl->clientid, cl->infoid, chantostr(buf, i->chan), (i->flags&Frepl)==Frepl,
- i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y,
- i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y);
- ((char*)a)[n++] = ' ';
- cl->infoid = -1;
- break;
-
- case Qcolormap:
- p = malloc(4*12*256+1);
- if(p == 0)
- error(Enomem);
- m = 0;
- for(index = 0; index < 256; index++){
- getcolor(index, &red, &green, &blue);
- m += sprint((char*)p+m, "%11d %11lud %11lud %11lud\n", index, red>>24, green>>24, blue>>24);
- }
- n = readstr(offset, a, n, (char*)p);
- free(p);
- break;
-
- case Qdata:
- if(cl->readdata == nil)
- error("no draw data");
- if(n < cl->nreaddata)
- error(Eshortread);
- n = cl->nreaddata;
- memmove(a, cl->readdata, cl->nreaddata);
- free(cl->readdata);
- cl->readdata = nil;
- break;
-
- case Qrefresh:
- if(n < 5*4)
- error(Ebadarg);
- for(;;){
- if(cl->refreshme || cl->refresh)
- break;
- dunlock();
- if(waserror()){
- dlock();
- nexterror();
- }
- qlock(&cl->refq);
- if(waserror()){
- qunlock(&cl->refq);
- nexterror();
- }
- rendsleep(&cl->refrend, drawrefactive, cl);
- poperror();
- qunlock(&cl->refq);
- poperror();
- dlock();
- }
- p = a;
- while(cl->refresh && n>=5*4){
- r = cl->refresh;
- BPLONG(p+0*4, r->dimage->id);
- BPLONG(p+1*4, r->r.min.x);
- BPLONG(p+2*4, r->r.min.y);
- BPLONG(p+3*4, r->r.max.x);
- BPLONG(p+4*4, r->r.max.y);
- cl->refresh = r->next;
- free(r);
- p += 5*4;
- n -= 5*4;
- }
- cl->refreshme = 0;
- n = p-(uchar*)a;
- break;
- }
- dunlock();
- poperror();
- return n;
-}
-
-void
-drawwakeall(void)
-{
- Client *cl;
- int i;
-
- for(i=0; i<sdraw.nclient; i++){
- cl = sdraw.client[i];
- if(cl && (cl->refreshme || cl->refresh))
- rendwakeup(&cl->refrend);
- }
-}
-
-static long
-drawwrite(Chan *c, void *a, long n, vlong)
-{
- char buf[128], *fields[4], *q;
- Client *cl;
- int i, m, red, green, blue, x;
-
- if(c->qid.type & QTDIR)
- error(Eisdir);
- cl = drawclient(c);
- dlock();
- if(waserror()){
- drawwakeall();
- dunlock();
- nexterror();
- }
- switch(QID(c->qid)){
- case Qctl:
- if(n != 4)
- error("unknown draw control request");
- cl->infoid = BGLONG((uchar*)a);
- break;
-
- case Qcolormap:
- m = n;
- n = 0;
- while(m > 0){
- x = m;
- if(x > sizeof(buf)-1)
- x = sizeof(buf)-1;
- q = memccpy(buf, a, '\n', x);
- if(q == 0)
- break;
- i = q-buf;
- n += i;
- a = (char*)a + i;
- m -= i;
- *q = 0;
- if(tokenize(buf, fields, nelem(fields)) != 4)
- error(Ebadarg);
- i = strtoul(fields[0], 0, 0);
- red = strtoul(fields[1], 0, 0);
- green = strtoul(fields[2], 0, 0);
- blue = strtoul(fields[3], &q, 0);
- if(fields[3] == q)
- error(Ebadarg);
- if(red>255 || green>255 || blue>255 || i<0 || i>255)
- error(Ebadarg);
- red |= red<<8;
- red |= red<<16;
- green |= green<<8;
- green |= green<<16;
- blue |= blue<<8;
- blue |= blue<<16;
- setcolor(i, red, green, blue);
- }
- break;
-
- case Qdata:
- drawmesg(cl, a, n);
- drawwakeall();
- break;
-
- default:
- error(Ebadusefd);
- }
- dunlock();
- poperror();
- return n;
-}
-
-uchar*
-drawcoord(uchar *p, uchar *maxp, int oldx, int *newx)
-{
- int b, x;
-
- if(p >= maxp)
- error(Eshortdraw);
- b = *p++;
- x = b & 0x7F;
- if(b & 0x80){
- if(p+1 >= maxp)
- error(Eshortdraw);
- x |= *p++ << 7;
- x |= *p++ << 15;
- if(x & (1<<22))
- x |= ~0<<23;
- }else{
- if(b & 0x40)
- x |= ~0<<7;
- x += oldx;
- }
- *newx = x;
- return p;
-}
-
-static void
-printmesg(char *fmt, uchar *a, int plsprnt)
-{
- char buf[256];
- char *p, *q;
- int s;
-
- if(1|| plsprnt==0){
- SET(s,q,p);
- USED(fmt, a, buf, p, q, s);
- return;
- }
- q = buf;
- *q++ = *a++;
- for(p=fmt; *p; p++){
- switch(*p){
- case 'l':
- q += sprint(q, " %ld", (long)BGLONG(a));
- a += 4;
- break;
- case 'L':
- q += sprint(q, " %.8lux", (ulong)BGLONG(a));
- a += 4;
- break;
- case 'R':
- q += sprint(q, " [%d %d %d %d]", BGLONG(a), BGLONG(a+4), BGLONG(a+8), BGLONG(a+12));
- a += 16;
- break;
- case 'P':
- q += sprint(q, " [%d %d]", BGLONG(a), BGLONG(a+4));
- a += 8;
- break;
- case 'b':
- q += sprint(q, " %d", *a++);
- break;
- case 's':
- q += sprint(q, " %d", BGSHORT(a));
- a += 2;
- break;
- case 'S':
- q += sprint(q, " %.4ux", BGSHORT(a));
- a += 2;
- break;
- }
- }
- *q++ = '\n';
- *q = 0;
- // iprint("%.*s", (int)(q-buf), buf);
-}
-
-void
-drawmesg(Client *client, void *av, int n)
-{
- int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
- uchar *u, *a, refresh;
- char *fmt;
- ulong value, chan;
- Rectangle r, clipr;
- Point p, q, *pp, sp;
- Memimage *i, *bg, *dst, *src, *mask;
- Memimage *l, **lp;
- Memscreen *scrn;
- DImage *font, *ll, *di, *ddst, *dsrc;
- DName *dn;
- DScreen *dscrn;
- FChar *fc;
- Refx *refx;
- CScreen *cs;
- Refreshfn reffn;
-
- a = av;
- m = 0;
- fmt = nil;
- if(waserror()){
- if(fmt) printmesg(fmt, a, 1);
- /* iprint("error: %s\n", up->errstr); */
- nexterror();
- }
- while((n-=m) > 0){
- USED(fmt);
- a += m;
- switch(*a){
- default:
- error("bad draw command");
- /* new allocate: 'b' id[4] screenid[4] refresh[1] chan[4] repl[1] R[4*4] clipR[4*4] rrggbbaa[4] */
- case 'b':
- printmesg(fmt="LLbLbRRL", a, 0);
- m = 1+4+4+1+4+1+4*4+4*4+4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- scrnid = BGLONG(a+5);
- refresh = a[9];
- chan = BGLONG(a+10);
- repl = a[14];
- drawrectangle(&r, a+15);
- drawrectangle(&clipr, a+31);
- value = BGLONG(a+47);
- if(drawlookup(client, dstid, 0))
- error(Eimageexists);
- if(scrnid){
- dscrn = drawlookupscreen(client, scrnid, &cs);
- scrn = dscrn->screen;
- if(repl || chan!=scrn->image->chan)
- error("image parameters incompatible with screen");
- reffn = nil;
- switch(refresh){
- case Refbackup:
- break;
- case Refnone:
- reffn = memlnorefresh;
- break;
- case Refmesg:
- reffn = drawrefresh;
- break;
- default:
- error("unknown refresh method");
- }
- l = memlalloc(scrn, r, reffn, 0, value);
- if(l == 0)
- error(Edrawmem);
- addflush(l->layer->screenr);
- l->clipr = clipr;
- rectclip(&l->clipr, r);
- if(drawinstall(client, dstid, l, dscrn) == 0){
- memldelete(l);
- error(Edrawmem);
- }
- dscrn->ref++;
- if(reffn){
- refx = nil;
- if(reffn == drawrefresh){
- refx = malloc(sizeof(Refx));
- if(refx == 0){
- drawuninstall(client, dstid);
- error(Edrawmem);
- }
- refx->client = client;
- refx->dimage = drawlookup(client, dstid, 1);
- }
- memlsetrefresh(l, reffn, refx);
- }
- continue;
- }
- i = allocmemimage(r, chan);
- if(i == 0)
- error(Edrawmem);
- if(repl)
- i->flags |= Frepl;
- i->clipr = clipr;
- if(!repl)
- rectclip(&i->clipr, r);
- if(drawinstall(client, dstid, i, 0) == 0){
- freememimage(i);
- error(Edrawmem);
- }
- memfillcolor(i, value);
- continue;
-
- /* allocate screen: 'A' id[4] imageid[4] fillid[4] public[1] */
- case 'A':
- printmesg(fmt="LLLb", a, 1);
- m = 1+4+4+4+1;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(dstid == 0)
- error(Ebadarg);
- if(drawlookupdscreen(dstid))
- error(Escreenexists);
- ddst = drawlookup(client, BGLONG(a+5), 1);
- dsrc = drawlookup(client, BGLONG(a+9), 1);
- if(ddst==0 || dsrc==0)
- error(Enodrawimage);
- if(drawinstallscreen(client, 0, dstid, ddst, dsrc, a[13]) == 0)
- error(Edrawmem);
- continue;
-
- /* set repl and clip: 'c' dstid[4] repl[1] clipR[4*4] */
- case 'c':
- printmesg(fmt="LbR", a, 0);
- m = 1+4+1+4*4;
- if(n < m)
- error(Eshortdraw);
- ddst = drawlookup(client, BGLONG(a+1), 1);
- if(ddst == nil)
- error(Enodrawimage);
- if(ddst->name)
- error("cannot change repl/clipr of shared image");
- dst = ddst->image;
- if(a[5])
- dst->flags |= Frepl;
- drawrectangle(&dst->clipr, a+6);
- continue;
-
- /* draw: 'd' dstid[4] srcid[4] maskid[4] R[4*4] P[2*4] P[2*4] */
- case 'd':
- printmesg(fmt="LLLRPP", a, 0);
- m = 1+4+4+4+4*4+2*4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- src = drawimage(client, a+5);
- mask = drawimage(client, a+9);
- drawrectangle(&r, a+13);
- drawpoint(&p, a+29);
- drawpoint(&q, a+37);
- op = drawclientop(client);
- memdraw(dst, r, src, p, mask, q, op);
- dstflush(dstid, dst, r);
- continue;
-
- /* toggle debugging: 'D' val[1] */
- case 'D':
- printmesg(fmt="b", a, 0);
- m = 1+1;
- if(n < m)
- error(Eshortdraw);
- continue;
-
- /* ellipse: 'e' dstid[4] srcid[4] center[2*4] a[4] b[4] thick[4] sp[2*4] alpha[4] phi[4]*/
- case 'e':
- case 'E':
- printmesg(fmt="LLPlllPll", a, 0);
- m = 1+4+4+2*4+4+4+4+2*4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- src = drawimage(client, a+5);
- drawpoint(&p, a+9);
- e0 = BGLONG(a+17);
- e1 = BGLONG(a+21);
- if(e0<0 || e1<0)
- error("invalid ellipse semidiameter");
- j = BGLONG(a+25);
- if(j < 0)
- error("negative ellipse thickness");
- drawpoint(&sp, a+29);
- c = j;
- if(*a == 'E')
- c = -1;
- ox = BGLONG(a+37);
- oy = BGLONG(a+41);
- op = drawclientop(client);
- /* high bit indicates arc angles are present */
- if(ox & (1<<31)){
- if((ox & (1<<30)) == 0)
- ox &= ~(1<<31);
- memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
- }else
- memellipse(dst, p, e0, e1, c, src, sp, op);
- dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
- continue;
-
- /* free: 'f' id[4] */
- case 'f':
- printmesg(fmt="L", a, 1);
- m = 1+4;
- if(n < m)
- error(Eshortdraw);
- ll = drawlookup(client, BGLONG(a+1), 0);
- if(ll && ll->dscreen && ll->dscreen->owner != client)
- ll->dscreen->owner->refreshme = 1;
- drawuninstall(client, BGLONG(a+1));
- continue;
-
- /* free screen: 'F' id[4] */
- case 'F':
- printmesg(fmt="L", a, 1);
- m = 1+4;
- if(n < m)
- error(Eshortdraw);
- drawlookupscreen(client, BGLONG(a+1), &cs);
- drawuninstallscreen(client, cs);
- continue;
-
- /* initialize font: 'i' fontid[4] nchars[4] ascent[1] */
- case 'i':
- printmesg(fmt="Llb", a, 1);
- m = 1+4+4+1;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(dstid == 0)
- error("cannot use display as font");
- font = drawlookup(client, dstid, 1);
- if(font == 0)
- error(Enodrawimage);
- if(font->image->layer)
- error("cannot use window as font");
- ni = BGLONG(a+5);
- if(ni<=0 || ni>4096)
- error("bad font size (4096 chars max)");
- free(font->fchar); /* should we complain if non-zero? */
- font->fchar = malloc(ni*sizeof(FChar));
- if(font->fchar == 0)
- error("no memory for font");
- memset(font->fchar, 0, ni*sizeof(FChar));
- font->nfchar = ni;
- font->ascent = a[9];
- continue;
-
- /* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */
- case 'l':
- printmesg(fmt="LLSRPbb", a, 0);
- m = 1+4+4+2+4*4+2*4+1+1;
- if(n < m)
- error(Eshortdraw);
- font = drawlookup(client, BGLONG(a+1), 1);
- if(font == 0)
- error(Enodrawimage);
- if(font->nfchar == 0)
- error(Enotfont);
- src = drawimage(client, a+5);
- ci = BGSHORT(a+9);
- if(ci >= font->nfchar)
- error(Eindex);
- drawrectangle(&r, a+11);
- drawpoint(&p, a+27);
- memdraw(font->image, r, src, p, memopaque, p, S);
- fc = &font->fchar[ci];
- fc->minx = r.min.x;
- fc->maxx = r.max.x;
- fc->miny = r.min.y;
- fc->maxy = r.max.y;
- fc->left = a[35];
- fc->width = a[36];
- continue;
-
- /* draw line: 'L' dstid[4] p0[2*4] p1[2*4] end0[4] end1[4] radius[4] srcid[4] sp[2*4] */
- case 'L':
- printmesg(fmt="LPPlllLP", a, 0);
- m = 1+4+2*4+2*4+4+4+4+4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- drawpoint(&p, a+5);
- drawpoint(&q, a+13);
- e0 = BGLONG(a+21);
- e1 = BGLONG(a+25);
- j = BGLONG(a+29);
- if(j < 0)
- error("negative line width");
- src = drawimage(client, a+33);
- drawpoint(&sp, a+37);
- op = drawclientop(client);
- memline(dst, p, q, e0, e1, j, src, sp, op);
- /* avoid memlinebbox if possible */
- if(dstid==0 || dst->layer!=nil){
- /* BUG: this is terribly inefficient: update maximal containing rect*/
- r = memlinebbox(p, q, e0, e1, j);
- dstflush(dstid, dst, insetrect(r, -(1+1+j)));
- }
- continue;
-
- /* create image mask: 'm' newid[4] id[4] */
-/*
- *
- case 'm':
- printmesg("LL", a, 0);
- m = 4+4;
- if(n < m)
- error(Eshortdraw);
- break;
- *
- */
-
- /* attach to a named image: 'n' dstid[4] j[1] name[j] */
- case 'n':
- printmesg(fmt="Lz", a, 0);
- m = 1+4+1;
- if(n < m)
- error(Eshortdraw);
- j = a[5];
- if(j == 0) /* give me a non-empty name please */
- error(Eshortdraw);
- m += j;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(drawlookup(client, dstid, 0))
- error(Eimageexists);
- dn = drawlookupname(j, (char*)a+6);
- if(dn == nil)
- error(Enoname);
- if(drawinstall(client, dstid, dn->dimage->image, 0) == 0)
- error(Edrawmem);
- di = drawlookup(client, dstid, 0);
- if(di == 0)
- error("draw: cannot happen");
- di->vers = dn->vers;
- di->name = smalloc(j+1);
- di->fromname = dn->dimage;
- di->fromname->ref++;
- memmove(di->name, a+6, j);
- di->name[j] = 0;
- client->infoid = dstid;
- continue;
-
- /* name an image: 'N' dstid[4] in[1] j[1] name[j] */
- case 'N':
- printmesg(fmt="Lbz", a, 0);
- m = 1+4+1+1;
- if(n < m)
- error(Eshortdraw);
- c = a[5];
- j = a[6];
- if(j == 0) /* give me a non-empty name please */
- error(Eshortdraw);
- m += j;
- if(n < m)
- error(Eshortdraw);
- di = drawlookup(client, BGLONG(a+1), 0);
- if(di == 0)
- error(Enodrawimage);
- if(di->name)
- error(Enamed);
- if(c)
- drawaddname(client, di, j, (char*)a+7);
- else{
- dn = drawlookupname(j, (char*)a+7);
- if(dn == nil)
- error(Enoname);
- if(dn->dimage != di)
- error(Ewrongname);
- drawdelname(dn);
- }
- continue;
-
- /* position window: 'o' id[4] r.min [2*4] screenr.min [2*4] */
- case 'o':
- printmesg(fmt="LPP", a, 0);
- m = 1+4+2*4+2*4;
- if(n < m)
- error(Eshortdraw);
- dst = drawimage(client, a+1);
- if(dst->layer){
- drawpoint(&p, a+5);
- drawpoint(&q, a+13);
- r = dst->layer->screenr;
- ni = memlorigin(dst, p, q);
- if(ni < 0)
- error("image origin failed");
- if(ni > 0){
- addflush(r);
- addflush(dst->layer->screenr);
- ll = drawlookup(client, BGLONG(a+1), 1);
- drawrefreshscreen(ll, client);
- }
- }
- continue;
-
- /* set compositing operator for next draw operation: 'O' op */
- case 'O':
- printmesg(fmt="b", a, 0);
- m = 1+1;
- if(n < m)
- error(Eshortdraw);
- client->op = a[1];
- continue;
-
- /* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
- /* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
- case 'p':
- case 'P':
- printmesg(fmt="LslllLPP", a, 0);
- m = 1+4+2+4+4+4+4+2*4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- dst = drawimage(client, a+1);
- ni = BGSHORT(a+5);
- if(ni < 0)
- error("negative count in polygon");
- e0 = BGLONG(a+7);
- e1 = BGLONG(a+11);
- j = 0;
- if(*a == 'p'){
- j = BGLONG(a+15);
- if(j < 0)
- error("negative polygon line width");
- }
- src = drawimage(client, a+19);
- drawpoint(&sp, a+23);
- drawpoint(&p, a+31);
- ni++;
- pp = malloc(ni*sizeof(Point));
- if(pp == nil)
- error(Enomem);
- doflush = 0;
- if(dstid==0 || (screenimage && dst->layer && dst->layer->screen->image->data == screenimage->data))
- doflush = 1; /* simplify test in loop */
- ox = oy = 0;
- esize = 0;
- u = a+m;
- for(y=0; y<ni; y++){
- q = p;
- oesize = esize;
- u = drawcoord(u, a+n, ox, &p.x);
- u = drawcoord(u, a+n, oy, &p.y);
- ox = p.x;
- oy = p.y;
- if(doflush){
- esize = j;
- if(*a == 'p'){
- if(y == 0){
- c = memlineendsize(e0);
- if(c > esize)
- esize = c;
- }
- if(y == ni-1){
- c = memlineendsize(e1);
- if(c > esize)
- esize = c;
- }
- }
- if(*a=='P' && e0!=1 && e0 !=~0)
- r = dst->clipr;
- else if(y > 0){
- r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
- combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
- }
- if(rectclip(&r, dst->clipr)) /* should perhaps be an arg to dstflush */
- dstflush(dstid, dst, r);
- }
- pp[y] = p;
- }
- if(y == 1)
- dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
- op = drawclientop(client);
- if(*a == 'p')
- mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
- else
- memfillpoly(dst, pp, ni, e0, src, sp, op);
- free(pp);
- m = u-a;
- continue;
-
- /* read: 'r' id[4] R[4*4] */
- case 'r':
- printmesg(fmt="LR", a, 0);
- m = 1+4+4*4;
- if(n < m)
- error(Eshortdraw);
- i = drawimage(client, a+1);
- drawrectangle(&r, a+5);
- if(!rectinrect(r, i->r))
- error(Ereadoutside);
- c = bytesperline(r, i->depth);
- c *= Dy(r);
- free(client->readdata);
- client->readdata = mallocz(c, 0);
- if(client->readdata == nil)
- error("readimage malloc failed");
- client->nreaddata = memunload(i, r, client->readdata, c);
- if(client->nreaddata < 0){
- free(client->readdata);
- client->readdata = nil;
- error("bad readimage call");
- }
- continue;
-
- /* string: 's' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] ni*(index[2]) */
- /* stringbg: 'x' dstid[4] srcid[4] fontid[4] P[2*4] clipr[4*4] sp[2*4] ni[2] bgid[4] bgpt[2*4] ni*(index[2]) */
- case 's':
- case 'x':
- printmesg(fmt="LLLPRPs", a, 0);
- m = 1+4+4+4+2*4+4*4+2*4+2;
- if(*a == 'x')
- m += 4+2*4;
- if(n < m)
- error(Eshortdraw);
-
- dst = drawimage(client, a+1);
- dstid = BGLONG(a+1);
- src = drawimage(client, a+5);
- font = drawlookup(client, BGLONG(a+9), 1);
- if(font == 0)
- error(Enodrawimage);
- if(font->nfchar == 0)
- error(Enotfont);
- drawpoint(&p, a+13);
- drawrectangle(&r, a+21);
- drawpoint(&sp, a+37);
- ni = BGSHORT(a+45);
- u = a+m;
- m += ni*2;
- if(n < m)
- error(Eshortdraw);
- clipr = dst->clipr;
- dst->clipr = r;
- op = drawclientop(client);
- bg = dst;
- if(*a == 'x'){
- /* paint background */
- bg = drawimage(client, a+47);
- drawpoint(&q, a+51);
- r.min.x = p.x;
- r.min.y = p.y-font->ascent;
- r.max.x = p.x;
- r.max.y = r.min.y+Dy(font->image->r);
- j = ni;
- while(--j >= 0){
- ci = BGSHORT(u);
- if(ci<0 || ci>=font->nfchar){
- dst->clipr = clipr;
- error(Eindex);
- }
- r.max.x += font->fchar[ci].width;
- u += 2;
- }
- memdraw(dst, r, bg, q, memopaque, ZP, op);
- u -= 2*ni;
- }
- q = p;
- while(--ni >= 0){
- ci = BGSHORT(u);
- if(ci<0 || ci>=font->nfchar){
- dst->clipr = clipr;
- error(Eindex);
- }
- q = drawchar(dst, bg, q, src, &sp, font, ci, op);
- u += 2;
- }
- dst->clipr = clipr;
- p.y -= font->ascent;
- dstflush(dstid, dst, Rect(p.x, p.y, q.x, p.y+Dy(font->image->r)));
- continue;
-
- /* use public screen: 'S' id[4] chan[4] */
- case 'S':
- printmesg(fmt="Ll", a, 0);
- m = 1+4+4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- if(dstid == 0)
- error(Ebadarg);
- dscrn = drawlookupdscreen(dstid);
- if(dscrn==0 || (dscrn->public==0 && dscrn->owner!=client))
- error(Enodrawscreen);
- if(dscrn->screen->image->chan != BGLONG(a+5))
- error("inconsistent chan");
- if(drawinstallscreen(client, dscrn, 0, 0, 0, 0) == 0)
- error(Edrawmem);
- continue;
-
- /* top or bottom windows: 't' top[1] nw[2] n*id[4] */
- case 't':
- printmesg(fmt="bsL", a, 0);
- m = 1+1+2;
- if(n < m)
- error(Eshortdraw);
- nw = BGSHORT(a+2);
- if(nw < 0)
- error(Ebadarg);
- if(nw == 0)
- continue;
- m += nw*4;
- if(n < m)
- error(Eshortdraw);
- lp = malloc(nw*sizeof(Memimage*));
- if(lp == 0)
- error(Enomem);
- if(waserror()){
- free(lp);
- nexterror();
- }
- for(j=0; j<nw; j++){
- lp[j] = drawimage(client, a+1+1+2+j*4);
- if(lp[j]->layer == 0)
- error("images are not windows");
- if(lp[j]->layer->screen != lp[0]->layer->screen)
- error("images not on same screen");
- }
- if(a[1])
- memltofrontn(lp, nw);
- else
- memltorearn(lp, nw);
- if(screenimage && lp[0]->layer->screen->image->data == screenimage->data)
- for(j=0; j<nw; j++)
- addflush(lp[j]->layer->screenr);
- ll = drawlookup(client, BGLONG(a+1+1+2), 1);
- drawrefreshscreen(ll, client);
- poperror();
- free(lp);
- continue;
-
- /* visible: 'v' */
- case 'v':
- printmesg(fmt="", a, 0);
- m = 1;
- drawflush();
- continue;
-
- /* write: 'y' id[4] R[4*4] data[x*1] */
- /* write from compressed data: 'Y' id[4] R[4*4] data[x*1] */
- case 'y':
- case 'Y':
- printmesg(fmt="LR", a, 0);
- // iprint("load %c\n", *a);
- m = 1+4+4*4;
- if(n < m)
- error(Eshortdraw);
- dstid = BGLONG(a+1);
- dst = drawimage(client, a+1);
- drawrectangle(&r, a+5);
- if(!rectinrect(r, dst->r))
- error(Ewriteoutside);
- y = memload(dst, r, a+m, n-m, *a=='Y');
- if(y < 0)
- error("bad writeimage call");
- dstflush(dstid, dst, r);
- m += y;
- continue;
- }
- }
- poperror();
-}
-
-Dev drawdevtab = {
- 'i',
- "draw",
-
- devreset,
- devinit,
- drawattach,
- drawwalk,
- drawstat,
- drawopen,
- devcreate,
- drawclose,
- drawread,
- devbread,
- drawwrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-/*
- * On 8 bit displays, load the default color map
- */
-void
-drawcmap(void)
-{
- int r, g, b, cr, cg, cb, v;
- int num, den;
- int i, j;
-
- for(r=0,i=0; r!=4; r++)
- for(v=0; v!=4; v++,i+=16){
- for(g=0,j=v-r; g!=4; g++)
- for(b=0;b!=4;b++,j++){
- den = r;
- if(g > den)
- den = g;
- if(b > den)
- den = b;
- if(den == 0) /* divide check -- pick grey shades */
- cr = cg = cb = v*17;
- else{
- num = 17*(4*den+v);
- cr = r*num/den;
- cg = g*num/den;
- cb = b*num/den;
- }
- setcolor(i+(j&15),
- cr*0x01010101, cg*0x01010101, cb*0x01010101);
- }
- }
-}
--- a/sys/src/cmd/vnc/devmouse.c
+++ /dev/null
@@ -1,346 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-#include "error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-typedef struct Mouseinfo Mouseinfo;
-typedef struct Mousestate Mousestate;
-
-struct Mousestate
-{
- Point xy; /* mouse.xy */
- int buttons; /* mouse.buttons */
- ulong counter; /* increments every update */
- ulong msec; /* time of last event */
-};
-
-struct Mouseinfo
-{
- Lock;
- Mousestate;
- ulong lastcounter; /* value when /dev/mouse read */
- Rendez r;
- Ref;
- int resize;
- int open;
- Mousestate queue[16]; /* circular buffer of click events */
- ulong ri; /* read index into queue */
- ulong wi; /* write index into queue */
-};
-
-Mouseinfo mouse;
-Cursorinfo cursor;
-Cursor curs;
-
-void Cursortocursor(Cursor*);
-int mousechanged(void*);
-
-enum{
- Qdir,
- Qcursor,
- Qmouse,
- Qmousein,
- Qmousectl,
-};
-
-static Dirtab mousedir[]={
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
- "cursor", {Qcursor}, 0, 0666,
- "mouse", {Qmouse}, 0, 0666,
- "mousein", {Qmousein}, 0, 0222,
- "mousectl", {Qmousectl}, 0, 0222,
-};
-
-Cursor arrow = {
- { -1, -1 },
- { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
- 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
- 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
- 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
- },
- { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
- 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
- 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
- 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
- },
-};
-
-extern Memimage* gscreen;
-extern void mousewarpnote(Point);
-
-static void
-mousereset(void)
-{
- curs = arrow;
- Cursortocursor(&arrow);
-}
-
-static void
-mouseinit(void)
-{
- curs = arrow;
- Cursortocursor(&arrow);
- cursoron();
-}
-
-static Chan*
-mouseattach(char *spec)
-{
- return devattach('m', spec);
-}
-
-static Walkqid*
-mousewalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
-}
-
-static int
-mousestat(Chan *c, uchar *db, int n)
-{
- return devstat(c, db, n, mousedir, nelem(mousedir), devgen);
-}
-
-static Chan*
-mouseopen(Chan *c, int omode)
-{
- int mode;
-
- mode = openmode(omode);
- switch((ulong)c->qid.path){
- case Qdir:
- if(omode != OREAD)
- error(Eperm);
- break;
- case Qmousein:
- case Qmousectl:
- error(Egreg);
- break;
- case Qmouse:
- if(_tas(&mouse.open) != 0)
- error(Einuse);
- mouse.lastcounter = mouse.counter;
- /* wet floor */
- case Qcursor:
- incref(&mouse);
- }
- c->mode = mode;
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-static void
-mouseclose(Chan *c)
-{
- if((c->qid.type&QTDIR)!=0 || (c->flag&COPEN)==0)
- return;
- switch((ulong)c->qid.path){
- case Qmouse:
- mouse.open = 0;
- /* wet floor */
- case Qcursor:
- if(decref(&mouse) != 0)
- return;
- cursoroff();
- curs = arrow;
- Cursortocursor(&arrow);
- cursoron();
- }
-}
-
-
-static long
-mouseread(Chan *c, void *va, long n, vlong off)
-{
- char buf[1+4*12+1];
- uchar *p;
- ulong offset = off;
- Mousestate m;
-
- p = va;
- switch((ulong)c->qid.path){
- case Qdir:
- return devdirread(c, va, n, mousedir, nelem(mousedir), devgen);
-
- case Qcursor:
- if(offset != 0)
- return 0;
- if(n < 2*4+2*2*16)
- error(Eshort);
- n = 2*4+2*2*16;
- BPLONG(p+0, curs.offset.x);
- BPLONG(p+4, curs.offset.y);
- memmove(p+8, curs.clr, 2*16);
- memmove(p+40, curs.set, 2*16);
- return n;
-
- case Qmouse:
- while(mousechanged(0) == 0)
- rendsleep(&mouse.r, mousechanged, 0);
-
- lock(&mouse);
- if(mouse.ri != mouse.wi)
- m = mouse.queue[mouse.ri++ % nelem(mouse.queue)];
- else
- m = mouse.Mousestate;
- unlock(&mouse);
-
- sprint(buf, "m%11d %11d %11d %11ld ",
- m.xy.x, m.xy.y, m.buttons, m.msec);
-
- mouse.lastcounter = m.counter;
- if(mouse.resize){
- mouse.resize = 0;
- buf[0] = 'r';
- }
-
- if(n > 1+4*12)
- n = 1+4*12;
- memmove(va, buf, n);
- return n;
- }
- return 0;
-}
-
-static long
-mousewrite(Chan *c, void *va, long n, vlong)
-{
- char *p;
- Point pt;
- char buf[64];
-
- p = va;
- switch((ulong)c->qid.path){
- case Qdir:
- error(Eisdir);
-
- case Qcursor:
- cursoroff();
- if(n < 2*4+2*2*16){
- curs = arrow;
- Cursortocursor(&arrow);
- }else{
- n = 2*4+2*2*16;
- curs.offset.x = BGLONG(p+0);
- curs.offset.y = BGLONG(p+4);
- memmove(curs.clr, p+8, 2*16);
- memmove(curs.set, p+40, 2*16);
- Cursortocursor(&curs);
- }
- cursoron();
- return n;
-
- case Qmouse:
- if(n > sizeof buf-1)
- n = sizeof buf -1;
- memmove(buf, va, n);
- buf[n] = 0;
-
- pt.x = strtol(buf+1, &p, 0);
- if(*p == 0)
- error(Eshort);
- pt.y = strtol(p, 0, 0);
- absmousetrack(pt.x, pt.y, mouse.buttons, nsec()/(1000*1000LL));
- mousewarpnote(pt);
- return n;
- }
-
- error(Egreg);
- return -1;
-}
-
-Dev mousedevtab = {
- 'm',
- "mouse",
-
- mousereset,
- mouseinit,
- mouseattach,
- mousewalk,
- mousestat,
- mouseopen,
- devcreate,
- mouseclose,
- mouseread,
- devbread,
- mousewrite,
- devbwrite,
- devremove,
- devwstat,
-};
-
-void
-Cursortocursor(Cursor *c)
-{
- lock(&cursor);
- memmove(&cursor.Cursor, c, sizeof(Cursor));
- setcursor(c);
- unlock(&cursor);
-}
-
-void
-absmousetrack(int x, int y, int b, ulong msec)
-{
- int lastb;
-
- if(gscreen==nil)
- return;
-
- if(x < gscreen->clipr.min.x)
- x = gscreen->clipr.min.x;
- if(x >= gscreen->clipr.max.x)
- x = gscreen->clipr.max.x-1;
- if(y < gscreen->clipr.min.y)
- y = gscreen->clipr.min.y;
- if(y >= gscreen->clipr.max.y)
- y = gscreen->clipr.max.y-1;
-
-
- lock(&mouse);
- mouse.xy = Pt(x, y);
- lastb = mouse.buttons;
- mouse.buttons = b;
- mouse.msec = msec;
- mouse.counter++;
-
- /*
- * if the queue fills, don't queue any more events until a
- * reader polls the mouse.
- */
- if(b != lastb && (mouse.wi-mouse.ri) < nelem(mouse.queue))
- mouse.queue[mouse.wi++ % nelem(mouse.queue)] = mouse.Mousestate;
- unlock(&mouse);
-
- rendwakeup(&mouse.r);
-
- cursoron();
-}
-
-int
-mousechanged(void*)
-{
- return mouse.lastcounter != mouse.counter || mouse.resize != 0;
-}
-
-Point
-mousexy(void)
-{
- return mouse.xy;
-}
-
-/*
- * notify reader that screen has been resized
- */
-void
-mouseresize(void)
-{
- mouse.resize = 1;
- rendwakeup(&mouse.r);
-}
--- a/sys/src/cmd/vnc/draw.c
+++ /dev/null
@@ -1,428 +1,0 @@
-#include "vnc.h"
-#include "vncv.h"
-
-static struct {
- char *name;
- int num;
-} enctab[] = {
- "copyrect", EncCopyRect,
- "corre", EncCorre,
- "hextile", EncHextile,
- "raw", EncRaw,
- "rre", EncRre,
- "mousewarp", EncMouseWarp,
- "desktopsize", EncDesktopSize,
- "xdesktopsize", EncXDesktopSize,
-};
-
-static uchar *pixbuf;
-static uchar *linebuf;
-static int vpixb;
-static int pixb;
-static void (*pixcp)(uchar*, uchar*);
-
-static void
-vncsetdim(Vnc *v, Rectangle dim)
-{
- v->dim = rectsubpt(dim, dim.min);
- linebuf = realloc(linebuf, v->dim.max.x * vpixb);
- pixbuf = realloc(pixbuf, v->dim.max.x * pixb * v->dim.max.y);
- if(linebuf == nil || pixbuf == nil)
- sysfatal("can't allocate pix decompression storage");
- lockdisplay(display);
- adjustwin(v, 0);
- unlockdisplay(display);
-}
-
-static void
-vncrdcolor(Vnc *v, uchar *color)
-{
- vncrdbytes(v, color, vpixb);
-
- if(cvtpixels)
- (*cvtpixels)(color, color, 1);
-}
-
-void
-sendencodings(Vnc *v)
-{
- char *f[16];
- int enc[16], nenc, i, j, nf;
-
- nf = tokenize(encodings, f, nelem(f));
- nenc = 0;
- for(i=0; i<nf; i++){
- for(j=0; j<nelem(enctab); j++)
- if(strcmp(f[i], enctab[j].name) == 0)
- break;
- if(j == nelem(enctab)){
- print("warning: unknown encoding %s\n", f[i]);
- continue;
- }
- enc[nenc++] = enctab[j].num;
- }
-
- vnclock(v);
- vncwrchar(v, MSetEnc);
- vncwrchar(v, 0);
- vncwrshort(v, nenc);
- for(i=0; i<nenc; i++)
- vncwrlong(v, enc[i]);
- vncflush(v);
- vncunlock(v);
-}
-
-void
-requestupdate(Vnc *v, int incremental)
-{
- Rectangle r;
-
- lockdisplay(display);
- flushimage(display, 1);
- r = rectsubpt(screen->r, screen->r.min);
- unlockdisplay(display);
- vnclock(v);
- if(incremental == 0 && (v->canresize&2)!=0 && !eqrect(r, v->dim)){
- vncwrchar(v, MSetDesktopSize);
- vncwrchar(v, 0);
- vncwrpoint(v, r.max);
- vncwrchar(v, 1);
- vncwrchar(v, 0);
- vncwrlong(v, v->screen[0].id);
- vncwrrect(v, r);
- vncwrlong(v, v->screen[0].flags);
- } else
- rectclip(&r, v->dim);
- vncwrchar(v, MFrameReq);
- vncwrchar(v, incremental);
- vncwrrect(v, r);
- vncflush(v);
- vncunlock(v);
-}
-
-static Rectangle
-clippixbuf(Rectangle r, int maxx, int maxy)
-{
- int y, h, stride1, stride2;
-
- if(r.min.x > maxx || r.min.y > maxy){
- r.max.x = 0;
- return r;
- }
- if(r.max.y > maxy)
- r.max.y = maxy;
- if(r.max.x <= maxx)
- return r;
-
- stride2 = Dx(r) * pixb;
- r.max.x = maxx;
- stride1 = Dx(r) * pixb;
- h = Dy(r);
- for(y = 0; y < h; y++)
- memmove(&pixbuf[y * stride1], &pixbuf[y * stride2], stride1);
-
- return r;
-}
-
-/* must be called with display locked */
-static void
-updatescreen(Rectangle r)
-{
- int b, bb;
-
- lockdisplay(display);
- if(r.max.x > Dx(screen->r) || r.max.y > Dy(screen->r)){
- r = clippixbuf(r, Dx(screen->r), Dy(screen->r));
- if(r.max.x == 0){
- unlockdisplay(display);
- return;
- }
- }
-
- /*
- * assume load image fails only because of resize
- */
- b = Dx(r) * pixb * Dy(r);
- bb = loadimage(screen, rectaddpt(r, screen->r.min), pixbuf, b);
- if(bb != b && verbose)
- fprint(2, "loadimage %d on %R for %R returned %d: %r\n", b, rectaddpt(r, screen->r.min), screen->r, bb);
- unlockdisplay(display);
-}
-
-static void
-fillrect(Rectangle r, int stride, uchar *color)
-{
- int x, xe, y, off;
-
- y = r.min.y;
- off = y * stride;
- for(; y < r.max.y; y++){
- xe = off + r.max.x * pixb;
- for(x = off + r.min.x * pixb; x < xe; x += pixb)
- (*pixcp)(&pixbuf[x], color);
- off += stride;
- }
-}
-
-static void
-loadbuf(Vnc *v, Rectangle r, int stride)
-{
- int off, y;
-
- if(cvtpixels){
- y = r.min.y;
- off = y * stride + r.min.x * pixb;
- for(; y < r.max.y; y++){
- vncrdbytes(v, linebuf, Dx(r) * vpixb);
- (*cvtpixels)(&pixbuf[off], linebuf, Dx(r));
- off += stride;
- }
- }else{
- y = r.min.y;
- off = y * stride + r.min.x * pixb;
- for(; y < r.max.y; y++){
- vncrdbytes(v, &pixbuf[off], Dx(r) * pixb);
- off += stride;
- }
- }
-}
-
-static Rectangle
-hexrect(ushort u)
-{
- int x, y, w, h;
-
- x = u>>12;
- y = (u>>8)&15;
- w = ((u>>4)&15)+1;
- h = (u&15)+1;
-
- return Rect(x, y, x+w, y+h);
-}
-
-
-static void
-dohextile(Vnc *v, Rectangle r, int stride)
-{
- ulong bg, fg, c;
- int enc, nsub, sx, sy, w, h, th, tw;
- Rectangle sr, ssr;
-
- fg = bg = 0;
- h = Dy(r);
- w = Dx(r);
- for(sy = 0; sy < h; sy += HextileDim){
- th = h - sy;
- if(th > HextileDim)
- th = HextileDim;
- for(sx = 0; sx < w; sx += HextileDim){
- tw = w - sx;
- if(tw > HextileDim)
- tw = HextileDim;
-
- sr = Rect(sx, sy, sx + tw, sy + th);
- enc = vncrdchar(v);
- if(enc & HextileRaw){
- loadbuf(v, sr, stride);
- continue;
- }
-
- if(enc & HextileBack)
- vncrdcolor(v, (uchar*)&bg);
- fillrect(sr, stride, (uchar*)&bg);
-
- if(enc & HextileFore)
- vncrdcolor(v, (uchar*)&fg);
-
- if(enc & HextileRects){
- nsub = vncrdchar(v);
- (*pixcp)((uchar*)&c, (uchar*)&fg);
- while(nsub-- > 0){
- if(enc & HextileCols)
- vncrdcolor(v, (uchar*)&c);
- ssr = rectaddpt(hexrect(vncrdshort(v)), sr.min);
- fillrect(ssr, stride, (uchar*)&c);
- }
- }
- }
- }
-}
-
-static void
-dorectangle(Vnc *v)
-{
- ulong type;
- long n, stride;
- ulong color;
- Point p;
- Rectangle r, subr, maxr;
-
- r = vncrdrect(v);
- type = vncrdlong(v);
- switch(type){
- case EncMouseWarp:
- mousewarp(r.min);
- return;
- case EncDesktopSize:
- v->canresize |= 1;
- vncsetdim(v, r);
- return;
- case EncXDesktopSize:
- v->canresize |= 2;
- n = vncrdlong(v)>>24;
- if(n <= 0)
- break;
- v->screen[0].id = vncrdlong(v);
- v->screen[0].rect = vncrdrect(v);
- v->screen[0].flags = vncrdlong(v);
- while(--n > 0){
- vncrdlong(v);
- vncrdrect(v);
- vncrdlong(v);
- }
- vncsetdim(v, v->screen[0].rect);
- return;
- }
-
- if(!rectinrect(r, v->dim))
- sysfatal("bad rectangle from server: %R not in %R", r, v->dim);
- maxr = rectsubpt(r, r.min);
- stride = maxr.max.x * pixb;
-
- switch(type){
- default:
- sysfatal("bad rectangle encoding from server");
- break;
- case EncRaw:
- loadbuf(v, maxr, stride);
- updatescreen(r);
- break;
-
- case EncCopyRect:
- p = vncrdpoint(v);
- lockdisplay(display);
- p = addpt(p, screen->r.min);
- r = rectaddpt(r, screen->r.min);
- draw(screen, r, screen, nil, p);
- unlockdisplay(display);
- break;
-
- case EncRre:
- case EncCorre:
- n = vncrdlong(v);
- vncrdcolor(v, (uchar*)&color);
- fillrect(maxr, stride, (uchar*)&color);
- while(n-- > 0){
- vncrdcolor(v, (uchar*)&color);
- if(type == EncRre)
- subr = vncrdrect(v);
- else
- subr = vncrdcorect(v);
- if(!rectinrect(subr, maxr))
- sysfatal("bad encoding from server");
- fillrect(subr, stride, (uchar*)&color);
- }
- updatescreen(r);
- break;
-
- case EncHextile:
- dohextile(v, r, stride);
- updatescreen(r);
- break;
- }
-}
-
-static void
-pixcp8(uchar *dst, uchar *src)
-{
- *dst = *src;
-}
-
-static void
-pixcp16(uchar *dst, uchar *src)
-{
- *(ushort*)dst = *(ushort*)src;
-}
-
-static void
-pixcp32(uchar *dst, uchar *src)
-{
- *(ulong*)dst = *(ulong*)src;
-}
-
-static void
-pixcp24(uchar *dst, uchar *src)
-{
- dst[0] = src[0];
- dst[1] = src[1];
- dst[2] = src[2];
-}
-
-static int
-calcpixb(int bpp)
-{
- if(bpp / 8 * 8 != bpp)
- sysfatal("can't handle your screen");
- return bpp / 8;
-}
-
-void
-readfromserver(Vnc *v)
-{
- uchar type;
- uchar junk[100];
- long n;
-
- vpixb = calcpixb(v->bpp);
- pixb = calcpixb(screen->depth);
- switch(pixb){
- case 1:
- pixcp = pixcp8;
- break;
- case 2:
- pixcp = pixcp16;
- break;
- case 3:
- pixcp = pixcp24;
- break;
- case 4:
- pixcp = pixcp32;
- break;
- default:
- sysfatal("can't handle your screen: bad depth %d", pixb);
- }
- vncsetdim(v, v->dim);
- for(;;){
- type = vncrdchar(v);
- switch(type){
- default:
- sysfatal("bad message from server: %x", type);
- break;
- case MFrameUpdate:
- vncrdchar(v);
- n = vncrdshort(v);
- while(n-- > 0)
- dorectangle(v);
- requestupdate(v, 1);
- break;
-
- case MSetCmap:
- vncrdbytes(v, junk, 3);
- n = vncrdshort(v);
- vncgobble(v, n*3*2);
- break;
-
- case MBell:
- break;
-
- case MSAck:
- break;
-
- case MSCut:
- vncrdbytes(v, junk, 3);
- n = vncrdlong(v);
- writesnarf(v, n);
- break;
- }
- }
-}
--- a/sys/src/cmd/vnc/error.h
+++ /dev/null
@@ -1,48 +1,0 @@
-extern char Enoerror[]; /* no error */
-extern char Emount[]; /* inconsistent mount */
-extern char Eunmount[]; /* not mounted */
-extern char Eunion[]; /* not in union */
-extern char Emountrpc[]; /* mount rpc error */
-extern char Eshutdown[]; /* mounted device shut down */
-extern char Enocreate[]; /* mounted directory forbids creation */
-extern char Enonexist[]; /* file does not exist */
-extern char Eexist[]; /* file already exists */
-extern char Ebadsharp[]; /* unknown device in # filename */
-extern char Enotdir[]; /* not a directory */
-extern char Eisdir[]; /* file is a directory */
-extern char Ebadchar[]; /* bad character in file name */
-extern char Efilename[]; /* file name syntax */
-extern char Eperm[]; /* permission denied */
-extern char Ebadusefd[]; /* inappropriate use of fd */
-extern char Ebadarg[]; /* bad arg in system call */
-extern char Einuse[]; /* device or object already in use */
-extern char Eio[]; /* i/o error */
-extern char Etoobig[]; /* read or write too large */
-extern char Etoosmall[]; /* read or write too small */
-extern char Enoport[]; /* network port not available */
-extern char Ehungup[]; /* write to hungup channel */
-extern char Ebadctl[]; /* bad process or channel control request */
-extern char Enodev[]; /* no free devices */
-extern char Eprocdied[]; /* process exited */
-extern char Enochild[]; /* no living children */
-extern char Eioload[]; /* i/o error in demand load */
-extern char Enovmem[]; /* virtual memory allocation failed */
-extern char Ebadfd[]; /* fd out of range or not open */
-extern char Enofd[]; /* no free file descriptors */
-extern char Eisstream[]; /* seek on a stream */
-extern char Ebadexec[]; /* exec header invalid */
-extern char Etimedout[]; /* connection timed out */
-extern char Econrefused[]; /* connection refused */
-extern char Econinuse[]; /* connection in use */
-extern char Eintr[]; /* interrupted */
-extern char Enomem[]; /* kernel allocate failed */
-extern char Enoswap[]; /* swap space full */
-extern char Esoverlap[]; /* segments overlap */
-extern char Emouseset[]; /* mouse type already set */
-extern char Eshort[]; /* i/o count too small */
-extern char Egreg[]; /* ken has left the building */
-extern char Ebadspec[]; /* bad attach specifier */
-extern char Enoreg[]; /* process has no saved registers */
-extern char Enoattach[]; /* mount/attach disallowed */
-extern char Eshortstat[]; /* stat buffer too small */
-extern char Ebadstat[]; /* malformed stat buffer */
--- a/sys/src/cmd/vnc/errstr.h
+++ /dev/null
@@ -1,48 +1,0 @@
-char Enoerror[] = "no error";
-char Emount[] = "inconsistent mount";
-char Eunmount[] = "not mounted";
-char Eunion[] = "not in union";
-char Emountrpc[] = "mount rpc error";
-char Eshutdown[] = "mounted device shut down";
-char Enocreate[] = "mounted directory forbids creation";
-char Enonexist[] = "file does not exist";
-char Eexist[] = "file already exists";
-char Ebadsharp[] = "unknown device in # filename";
-char Enotdir[] = "not a directory";
-char Eisdir[] = "file is a directory";
-char Ebadchar[] = "bad character in file name";
-char Efilename[] = "file name syntax";
-char Eperm[] = "permission denied";
-char Ebadusefd[] = "inappropriate use of fd";
-char Ebadarg[] = "bad arg in system call";
-char Einuse[] = "device or object already in use";
-char Eio[] = "i/o error";
-char Etoobig[] = "read or write too large";
-char Etoosmall[] = "read or write too small";
-char Enoport[] = "network port not available";
-char Ehungup[] = "write to hungup channel";
-char Ebadctl[] = "bad process or channel control request";
-char Enodev[] = "no free devices";
-char Eprocdied[] = "process exited";
-char Enochild[] = "no living children";
-char Eioload[] = "i/o error in demand load";
-char Enovmem[] = "virtual memory allocation failed";
-char Ebadfd[] = "fd out of range or not open";
-char Enofd[] = "no free file descriptors";
-char Eisstream[] = "seek on a stream";
-char Ebadexec[] = "exec header invalid";
-char Etimedout[] = "connection timed out";
-char Econrefused[] = "connection refused";
-char Econinuse[] = "connection in use";
-char Eintr[] = "interrupted";
-char Enomem[] = "kernel allocate failed";
-char Enoswap[] = "swap space full";
-char Esoverlap[] = "segments overlap";
-char Emouseset[] = "mouse type already set";
-char Eshort[] = "i/o count too small";
-char Egreg[] = "ken has left the building";
-char Ebadspec[] = "bad attach specifier";
-char Enoreg[] = "process has no saved registers";
-char Enoattach[] = "mount/attach disallowed";
-char Eshortstat[] = "stat buffer too small";
-char Ebadstat[] = "malformed stat buffer";
--- a/sys/src/cmd/vnc/exporter.c
+++ /dev/null
@@ -1,94 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-
-typedef struct Exporter Exporter;
-struct Exporter
-{
- int fd;
- Chan **roots;
- int nroots;
-};
-
-int
-mounter(char *mntpt, int how, int fd, int n)
-{
- char buf[32];
- int i, ok, mfd;
-
- ok = 1;
- for(i = 0; i < n; i++){
- snprint(buf, sizeof buf, "%d", i);
- mfd = dup(fd, -1);
- if(mount(mfd, -1, mntpt, how, buf) == -1){
- close(mfd);
- fprint(2, "can't mount on %s: %r\n", mntpt);
- ok = 0;
- break;
- }
- close(mfd);
- if(how == MREPL)
- how = MAFTER;
- }
-
- close(fd);
-
- return ok;
-}
-
-static void
-extramp(void *v)
-{
- Exporter *ex;
-
- rfork(RFNAMEG);
- ex = v;
- sysexport(ex->fd, ex->roots, ex->nroots);
- shutdown();
- exits(nil);
-}
-
-int
-exporter(Dev **dt, int *fd, int *sfd)
-{
- Chan **roots;
- Exporter ex;
- int p[2], i, n, ed;
-
- for(n = 0; dt[n] != nil; n++)
- ;
- if(!n){
- werrstr("no devices specified");
- return 0;
- }
-
- ed = errdepth(-1);
- if(waserror()){
- werrstr(up->error);
- return 0;
- }
-
- roots = smalloc(n * sizeof *roots);
- for(i = 0; i < n; i++){
- (*dt[i]->reset)();
- (*dt[i]->init)();
- roots[i] = (*dt[i]->attach)("");
- }
- poperror();
- errdepth(ed);
-
- if(pipe(p) < 0){
- werrstr("can't make pipe: %r");
- return 0;
- }
-
- *sfd = p[0];
- *fd = p[1];
-
- ex.fd = *sfd;
- ex.roots = roots;
- ex.nroots = n;
- kproc("exporter", extramp, &ex);
-
- return n;
-}
--- a/sys/src/cmd/vnc/exportfs.c
+++ /dev/null
@@ -1,804 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include "compat.h"
-#include "error.h"
-
-typedef struct Fid Fid;
-typedef struct Export Export;
-typedef struct Exq Exq;
-typedef struct Exwork Exwork;
-
-enum
-{
- Nfidhash = 32,
- Maxfdata = 8192,
- Maxrpc = IOHDRSZ + Maxfdata,
-};
-
-struct Export
-{
- Ref r;
- Exq* work;
- Lock fidlock;
- Fid* fid[Nfidhash];
- int io; /* fd to read/write */
- int iounit;
- int nroots;
- Chan **roots;
-};
-
-struct Fid
-{
- Fid* next;
- Fid** last;
- Chan* chan;
- long offset;
- int fid;
- int ref; /* fcalls using the fid; locked by Export.Lock */
- int attached; /* fid attached or cloned but not clunked */
-};
-
-struct Exq
-{
- Lock lk;
- int responding; /* writing out reply message */
- int noresponse; /* don't respond to this one */
- Exq* next;
- int shut; /* has been noted for shutdown */
- Export* export;
- void* slave;
- Fcall rpc;
- uchar buf[Maxrpc];
-};
-
-struct Exwork
-{
- Lock l;
-
- int ref;
-
- int nwaiters; /* queue of slaves waiting for work */
- QLock qwait;
- Rendez rwait;
-
- Exq *head; /* work waiting for a slave */
- Exq *tail;
-};
-
-Exwork exq;
-
-static void exshutdown(Export*);
-static void exflush(Export*, int, int);
-static void exslave(void*);
-static void exfree(Export*);
-static void exportproc(Export*);
-
-static char* Exattach(Export*, Fcall*, uchar*);
-static char* Exauth(Export*, Fcall*, uchar*);
-static char* Exclunk(Export*, Fcall*, uchar*);
-static char* Excreate(Export*, Fcall*, uchar*);
-static char* Exversion(Export*, Fcall*, uchar*);
-static char* Exopen(Export*, Fcall*, uchar*);
-static char* Exread(Export*, Fcall*, uchar*);
-static char* Exremove(Export*, Fcall*, uchar*);
-static char* Exsession(Export*, Fcall*, uchar*);
-static char* Exstat(Export*, Fcall*, uchar*);
-static char* Exwalk(Export*, Fcall*, uchar*);
-static char* Exwrite(Export*, Fcall*, uchar*);
-static char* Exwstat(Export*, Fcall*, uchar*);
-
-static char *(*fcalls[Tmax])(Export*, Fcall*, uchar*);
-
-static char Enofid[] = "no such fid";
-static char Eseekdir[] = "can't seek on a directory";
-static char Ereaddir[] = "unaligned read of a directory";
-static int exdebug = 0;
-
-int
-sysexport(int fd, Chan **roots, int nroots)
-{
- Export *fs;
-
- fs = smalloc(sizeof(Export));
- fs->r.ref = 1;
- fs->io = fd;
- fs->roots = roots;
- fs->nroots = nroots;
-
- exportproc(fs);
-
- return 0;
-}
-
-static void
-exportinit(void)
-{
- lock(&exq.l);
- exq.ref++;
- if(fcalls[Tversion] != nil){
- unlock(&exq.l);
- return;
- }
-
- fmtinstall('F', fcallfmt);
- fcalls[Tversion] = Exversion;
- fcalls[Tauth] = Exauth;
- fcalls[Tattach] = Exattach;
- fcalls[Twalk] = Exwalk;
- fcalls[Topen] = Exopen;
- fcalls[Tcreate] = Excreate;
- fcalls[Tread] = Exread;
- fcalls[Twrite] = Exwrite;
- fcalls[Tclunk] = Exclunk;
- fcalls[Tremove] = Exremove;
- fcalls[Tstat] = Exstat;
- fcalls[Twstat] = Exwstat;
- unlock(&exq.l);
-}
-
-static void
-exportproc(Export *fs)
-{
- Exq *q;
- int n, ed;
-
- exportinit();
- ed = errdepth(-1);
- for(;;){
- errdepth(ed);
- q = smalloc(sizeof(Exq));
-
- n = read9pmsg(fs->io, q->buf, Maxrpc);
- if(n <= 0 || convM2S(q->buf, n, &q->rpc) != n)
- break;
-
- if(exdebug)
- print("export %d <- %F\n", getpid(), &q->rpc);
-
- if(q->rpc.type == Tflush){
- exflush(fs, q->rpc.tag, q->rpc.oldtag);
- free(q);
- continue;
- }
-
- q->export = fs;
- incref(&fs->r);
-
- lock(&exq.l);
- if(exq.head == nil)
- exq.head = q;
- else
- exq.tail->next = q;
- q->next = nil;
- exq.tail = q;
- n = exq.nwaiters;
- if(n)
- exq.nwaiters = n - 1;
- unlock(&exq.l);
- if(!n)
- kproc("exportfs", exslave, nil);
- rendwakeup(&exq.rwait);
- }
- free(q);
- if(exdebug)
- fprint(2, "export proc shutting down: %r\n");
- exshutdown(fs);
- exfree(fs);
-}
-
-static void
-exflush(Export *fs, int flushtag, int tag)
-{
- Exq *q, **last;
- Fcall fc;
- uchar buf[Maxrpc];
- int n;
-
- /* hasn't been started? */
- lock(&exq.l);
- last = &exq.head;
- for(q = exq.head; q != nil; q = q->next){
- if(q->export == fs && q->rpc.tag == tag){
- *last = q->next;
- unlock(&exq.l);
- exfree(fs);
- free(q);
- goto Respond;
- }
- last = &q->next;
- }
- unlock(&exq.l);
-
- /* in progress? */
- lock(&fs->r);
- for(q = fs->work; q != nil; q = q->next){
- if(q->rpc.tag == tag){
- lock(&q->lk);
- q->noresponse = 1;
- if(!q->responding)
- rendintr(q->slave);
- unlock(&q->lk);
- break;
- }
- }
- unlock(&fs->r);
-
-Respond:
- fc.type = Rflush;
- fc.tag = flushtag;
-
- n = convS2M(&fc, buf, Maxrpc);
- if(n == 0)
- panic("convS2M error on write");
- if(write(fs->io, buf, n) != n)
- panic("mount write");
-}
-
-static void
-exshutdown(Export *fs)
-{
- Exq *q, **last;
-
- lock(&exq.l);
- last = &exq.head;
- for(q = exq.head; q != nil; q = *last){
- if(q->export == fs){
- *last = q->next;
- exfree(fs);
- free(q);
- continue;
- }
- last = &q->next;
- }
-
- /*
- * cleanly shut down the slaves if this is the last fs around
- */
- exq.ref--;
- if(!exq.ref)
- rendwakeup(&exq.rwait);
- unlock(&exq.l);
-
- /*
- * kick any sleepers
- */
- lock(&fs->r);
- for(q = fs->work; q != nil; q = q->next){
- lock(&q->lk);
- q->noresponse = 1;
- if(!q->responding)
- rendintr(q->slave);
- unlock(&q->lk);
- }
- unlock(&fs->r);
-}
-
-static void
-exfree(Export *fs)
-{
- Fid *f, *n;
- int i;
-
- if(decref(&fs->r) != 0)
- return;
- for(i = 0; i < Nfidhash; i++){
- for(f = fs->fid[i]; f != nil; f = n){
- if(f->chan != nil)
- cclose(f->chan);
- n = f->next;
- free(f);
- }
- }
- free(fs);
-}
-
-static int
-exwork(void *)
-{
- int work;
-
- lock(&exq.l);
- work = exq.head != nil || !exq.ref;
- unlock(&exq.l);
- return work;
-}
-
-static void
-exslave(void *)
-{
- Export *fs;
- Exq *q, *t, **last;
- char *volatile err;
- int n, ed;
-
- while(waserror())
- fprint(2, "exslave %d errored out of loop -- heading back in!\n", getpid());
- ed = errdepth(-1);
- for(;;){
- errdepth(ed);
- qlock(&exq.qwait);
- if(waserror()){
- qunlock(&exq.qwait);
- nexterror();
- }
- rendsleep(&exq.rwait, exwork, nil);
-
- lock(&exq.l);
- if(!exq.ref){
- unlock(&exq.l);
- poperror();
- qunlock(&exq.qwait);
- break;
- }
- q = exq.head;
- if(q == nil){
- unlock(&exq.l);
- poperror();
- qunlock(&exq.qwait);
- continue;
- }
- exq.head = q->next;
- if(exq.head == nil)
- exq.tail = nil;
- poperror();
- qunlock(&exq.qwait);
-
- /*
- * put the job on the work queue before it's
- * visible as off of the head queue, so it's always
- * findable for flushes and shutdown
- */
- q->slave = up;
- q->noresponse = 0;
- q->responding = 0;
- rendclearintr();
- fs = q->export;
- lock(&fs->r);
- q->next = fs->work;
- fs->work = q;
- unlock(&fs->r);
-
- unlock(&exq.l);
-
- if(exdebug > 1)
- print("exslave dispatch %d %F\n", getpid(), &q->rpc);
-
- if(waserror()){
- print("exslave err %r\n");
- err = up->error;
- }else{
- if(q->rpc.type >= Tmax || !fcalls[q->rpc.type])
- err = "bad fcall type";
- else
- err = (*fcalls[q->rpc.type])(fs, &q->rpc, &q->buf[IOHDRSZ]);
- poperror();
- }
-
- q->rpc.type++;
- if(err){
- q->rpc.type = Rerror;
- q->rpc.ename = err;
- }
- n = convS2M(&q->rpc, q->buf, Maxrpc);
-
- if(exdebug)
- print("exslave %d -> %F\n", getpid(), &q->rpc);
-
- lock(&q->lk);
- if(!q->noresponse){
- q->responding = 1;
- unlock(&q->lk);
- write(fs->io, q->buf, n);
- }else
- unlock(&q->lk);
-
- /*
- * exflush might set noresponse at this point, but
- * setting noresponse means don't send a response now;
- * it's okay that we sent a response already.
- */
- if(exdebug > 1)
- print("exslave %d written %d\n", getpid(), q->rpc.tag);
-
- lock(&fs->r);
- last = &fs->work;
- for(t = fs->work; t != nil; t = t->next){
- if(t == q){
- *last = q->next;
- break;
- }
- last = &t->next;
- }
- unlock(&fs->r);
-
- exfree(q->export);
- free(q);
-
- rendclearintr();
- lock(&exq.l);
- exq.nwaiters++;
- unlock(&exq.l);
- }
- if(exdebug)
- fprint(2, "export slaveshutting down\n");
- kexit();
-}
-
-Fid*
-Exmkfid(Export *fs, int fid)
-{
- ulong h;
- Fid *f, *nf;
-
- nf = mallocz(sizeof(Fid), 1);
- if(nf == nil)
- return nil;
- lock(&fs->fidlock);
- h = fid % Nfidhash;
- for(f = fs->fid[h]; f != nil; f = f->next){
- if(f->fid == fid){
- unlock(&fs->fidlock);
- free(nf);
- return nil;
- }
- }
-
- nf->next = fs->fid[h];
- if(nf->next != nil)
- nf->next->last = &nf->next;
- nf->last = &fs->fid[h];
- fs->fid[h] = nf;
-
- nf->fid = fid;
- nf->ref = 1;
- nf->attached = 1;
- nf->offset = 0;
- nf->chan = nil;
- unlock(&fs->fidlock);
- return nf;
-}
-
-Fid*
-Exgetfid(Export *fs, int fid)
-{
- Fid *f;
- ulong h;
-
- lock(&fs->fidlock);
- h = fid % Nfidhash;
- for(f = fs->fid[h]; f; f = f->next){
- if(f->fid == fid){
- if(f->attached == 0)
- break;
- f->ref++;
- unlock(&fs->fidlock);
- return f;
- }
- }
- unlock(&fs->fidlock);
- return nil;
-}
-
-void
-Exputfid(Export *fs, Fid *f)
-{
- lock(&fs->fidlock);
- f->ref--;
- if(f->ref == 0 && f->attached == 0){
- if(f->chan != nil)
- cclose(f->chan);
- f->chan = nil;
- *f->last = f->next;
- if(f->next != nil)
- f->next->last = f->last;
- unlock(&fs->fidlock);
- free(f);
- return;
- }
- unlock(&fs->fidlock);
-}
-
-static char*
-Exversion(Export *fs, Fcall *rpc, uchar *)
-{
- if(rpc->msize < 256)
- return "version: message size too small";
- if(rpc->msize > Maxrpc)
- rpc->msize = Maxrpc;
- if(strncmp(rpc->version, "9P", 2) != 0){
- rpc->version = "unknown";
- return nil;
- }
-
- fs->iounit = rpc->msize - IOHDRSZ;
- rpc->version = "9P2000";
- return nil;
-}
-
-static char*
-Exauth(Export *, Fcall *, uchar *)
-{
- return "vnc: authentication not required";
-}
-
-static char*
-Exattach(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *f;
- int w;
-
- w = 0;
- if(rpc->aname != nil)
- w = strtol(rpc->aname, nil, 10);
- if(w < 0 || w > fs->nroots)
- error(Ebadspec);
- f = Exmkfid(fs, rpc->fid);
- if(f == nil)
- return Einuse;
- if(waserror()){
- f->attached = 0;
- Exputfid(fs, f);
- return up->error;
- }
- f->chan = cclone(fs->roots[w]);
- poperror();
- rpc->qid = f->chan->qid;
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Exclunk(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *f;
-
- f = Exgetfid(fs, rpc->fid);
- if(f != nil){
- f->attached = 0;
- Exputfid(fs, f);
- }
- return nil;
-}
-
-static char*
-Exwalk(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *volatile f, *volatile nf;
- Walkqid *wq;
- Chan *c;
- int i, nwname;
- int volatile isnew;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- nf = nil;
- if(waserror()){
- Exputfid(fs, f);
- if(nf != nil)
- Exputfid(fs, nf);
- return up->error;
- }
-
- /*
- * optional clone, but don't attach it until the walk succeeds.
- */
- if(rpc->fid != rpc->newfid){
- nf = Exmkfid(fs, rpc->newfid);
- if(nf == nil)
- error(Einuse);
- nf->attached = 0;
- isnew = 1;
- }else{
- nf = Exgetfid(fs, rpc->fid);
- isnew = 0;
- }
-
- /*
- * let the device do the work
- */
- c = f->chan;
- nwname = rpc->nwname;
- wq = (*devtab[c->type]->walk)(c, nf->chan, rpc->wname, nwname);
- if(wq == nil)
- error(Enonexist);
-
- poperror();
-
- /*
- * copy qid array
- */
- for(i = 0; i < wq->nqid; i++)
- rpc->wqid[i] = wq->qid[i];
- rpc->nwqid = wq->nqid;
-
- /*
- * update the channel if everything walked correctly.
- */
- if(isnew && wq->nqid == nwname){
- nf->chan = wq->clone;
- nf->attached = 1;
- }
-
- free(wq);
- Exputfid(fs, f);
- Exputfid(fs, nf);
- return nil;
-}
-
-static char*
-Exopen(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *volatile f;
- Chan *c;
- int iou;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
- c = f->chan;
- c = (*devtab[c->type]->open)(c, rpc->mode);
- poperror();
-
- f->chan = c;
- f->offset = 0;
- rpc->qid = f->chan->qid;
- iou = f->chan->iounit;
- if(iou > fs->iounit)
- iou = fs->iounit;
- rpc->iounit = iou;
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Excreate(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *f;
- Chan *c;
- int iou;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
- c = f->chan;
- (*devtab[c->type]->create)(c, rpc->name, rpc->mode, rpc->perm);
- poperror();
-
- f->chan = c;
- rpc->qid = f->chan->qid;
- iou = f->chan->iounit;
- if(iou > fs->iounit)
- iou = fs->iounit;
- rpc->iounit = iou;
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Exread(Export *fs, Fcall *rpc, uchar *buf)
-{
- Fid *f;
- Chan *c;
- long off;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
-
- c = f->chan;
-
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
-
- rpc->data = (char*)buf;
- off = rpc->offset;
- c->offset = off;
- rpc->count = (*devtab[c->type]->read)(c, rpc->data, rpc->count, off);
- poperror();
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Exwrite(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *f;
- Chan *c;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
- c = f->chan;
- if(c->qid.type & QTDIR)
- error(Eisdir);
- rpc->count = (*devtab[c->type]->write)(c, rpc->data, rpc->count, rpc->offset);
- poperror();
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Exstat(Export *fs, Fcall *rpc, uchar *buf)
-{
- Fid *f;
- Chan *c;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
- c = f->chan;
- rpc->stat = buf;
- rpc->nstat = (*devtab[c->type]->stat)(c, rpc->stat, Maxrpc);
- poperror();
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Exwstat(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *f;
- Chan *c;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
- c = f->chan;
- (*devtab[c->type]->wstat)(c, rpc->stat, rpc->nstat);
- poperror();
- Exputfid(fs, f);
- return nil;
-}
-
-static char*
-Exremove(Export *fs, Fcall *rpc, uchar *)
-{
- Fid *f;
- Chan *c;
-
- f = Exgetfid(fs, rpc->fid);
- if(f == nil)
- return Enofid;
- if(waserror()){
- Exputfid(fs, f);
- return up->error;
- }
- c = f->chan;
- (*devtab[c->type]->remove)(c);
- poperror();
-
- /*
- * chan is already clunked by remove.
- * however, we need to recover the chan,
- * and follow sysremove's lead in making to point to root.
- */
- c->type = 0;
-
- f->attached = 0;
- Exputfid(fs, f);
- return nil;
-}
--- a/sys/src/cmd/vnc/kbd.h
+++ /dev/null
@@ -1,21 +1,0 @@
-typedef struct Snarf Snarf;
-
-struct Snarf
-{
- QLock;
- int vers;
- int n;
- char *buf;
-};
-
-enum
-{
- MAXSNARF = 100*1024
-};
-
-extern Snarf snarf;
-extern int kbdin;
-
-void screenputs(char*, int);
-void vncputc(int, int);
-void setsnarf(char *buf, int n, int *vers);
--- a/sys/src/cmd/vnc/kbds.c
+++ /dev/null
@@ -1,74 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <keyboard.h>
-#include "compat.h"
-#include "kbd.h"
-#include "ksym2utf.h"
-
-enum {
- VKSpecial = 0xff00,
-};
-
-static Rune vnckeys[] =
-{
-[0x00] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x08] '\b', '\t', '\r', 0, 0, '\n', 0, 0,
-[0x10] 0, 0, 0, 0, Kscroll,0, 0, 0,
-[0x18] 0, 0, 0, Kesc, 0, 0, 0, 0,
-[0x20] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x28] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x30] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x38] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x40] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x48] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x50] Khome, Kleft, Kup, Kright, Kdown, Kpgup, Kpgdown,Kend,
-[0x58] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x60] 0, Kprint, 0, Kins, 0, 0, 0, 0,
-[0x68] 0, 0, 0, Kbreak, 0, 0, 0, 0,
-[0x70] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x78] 0, 0, 0, 0, 0, 0, 0, Knum,
-[0x80] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x88] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x90] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x98] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xa0] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xa8] 0, 0, '*', '+', 0, '-', '.', '/',
-[0xb0] '0', '1', '2', '3', '4', '5', '6', '7',
-[0xb8] '8', '9', 0, 0, 0, '=', 0, 0,
-[0xc0] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xc8] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xd0] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xd8] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xe0] 0, Kshift, Kshift, Kctl, Kctl, Kcaps, Kcaps, 0,
-[0xe8] 0, Kalt, Kalt, 0, 0, 0, 0, 0,
-[0xf0] 0, 0, 0, 0, 0, 0, 0, 0,
-[0xf8] 0, 0, 0, 0, 0, 0, 0, Kdel,
-};
-
-/*
- * keyboard interrupt
- */
-void
-vncputc(int keyup, int c)
-{
- char buf[16];
-
- /*
- * character mapping
- */
- if((c & VKSpecial) == VKSpecial){
- c = vnckeys[c & 0xff];
- if(c == 0)
- return;
- }
- /*
- * map an xkeysym onto a utf-8 char
- */
- if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0)
- c = ksym2utf[c];
- snprint(buf, sizeof(buf), "r%C", c);
- if(keyup)
- buf[0] = 'R';
- if(kbdin >= 0)
- write(kbdin, buf, strlen(buf)+1);
-}
--- a/sys/src/cmd/vnc/kbdv.c
+++ /dev/null
@@ -1,270 +1,0 @@
-#include "vnc.h"
-#include <keyboard.h>
-#include "utf2ksym.h"
-
-enum {
- Xshift = 0xFFE1,
- Xctl = 0xFFE3,
- Xmeta = 0xFFE7,
- Xalt = 0xFFE9,
- Xsuper = 0xFFEB,
-};
-
-static struct {
- Rune kbdc;
- ulong keysym;
-} ktab[] = {
- {'\b', 0xff08},
- {'\t', 0xff09},
- {'\n', 0xff0d},
- /* {0x0b, 0xff0b}, */
- {'\r', 0xff0d},
- {Kesc, 0xff1b},
- {Kins, 0xff63},
- {Kdel, 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},
-
- {Kshift, Xshift},
- {Kalt, Xalt},
- {Kaltgr, Xmeta},
- {Kmod4, Xsuper},
- {Kctl, Xctl},
-};
-
-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);
-}
-
-static void
-readcons(Vnc *v)
-{
- char buf[256], k[10];
- ulong ks;
- int ctlfd, fd, kr, kn, w, shift, ctl, alt, super;
- 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 = super = 0;
- for(;;){
- while(!fullrune(k, kn)){
- kr = read(fd, k+kn, sizeof k - kn);
- if(kr <= 0)
- sysfatal("bad read from kbd");
- 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;
- case Kmod4:
- super = !super;
- keyevent(v, Xsuper, super);
- 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;
- }
- if(super){
- keyevent(v, Xsuper, 0);
- super = 0;
- }
- break;
- }
- }
-}
-
-ulong
-runetovnc(Rune r)
-{
- ulong k;
-
- k = runetoksym(r);
- if((k & 0xff00) && k < nelem(utf2ksym) && utf2ksym[k] != 0)
- k = utf2ksym[k];
- return k;
-}
-
-void
-readkbd(Vnc *v)
-{
- char buf[128], buf2[128], *s;
- int fd, n;
- Rune r;
-
- if((fd = open("/dev/kbd", OREAD)) < 0){
- readcons(v);
- return;
- }
-
- buf2[0] = 0;
- buf2[1] = 0;
- buf[0] = 0;
- for(;;){
- if(buf[0] != 0){
- n = strlen(buf)+1;
- memmove(buf, buf+n, sizeof(buf)-n);
- }
- if(buf[0] == 0){
- n = read(fd, buf, sizeof(buf)-1);
- if(n <= 0)
- break;
- buf[n-1] = 0;
- buf[n] = 0;
- }
- switch(buf[0]){
- case 'k':
- s = buf+1;
- while(*s){
- s += chartorune(&r, s);
- if(utfrune(buf2+1, r) == nil)
- if((r == Kshift) ||
- utfrune(buf+1, Kctl) ||
- utfrune(buf+1, Kalt) ||
- utfrune(buf+1, Kmod4) ||
- utfrune(buf+1, Kaltgr))
- keyevent(v, runetovnc(r), 1);
- }
- break;
- case 'K':
- s = buf2+1;
- while(*s){
- s += chartorune(&r, s);
- if(utfrune(buf+1, r) == nil)
- keyevent(v, runetovnc(r), 0);
- }
- break;
- case 'c':
- if(utfrune(buf2+1, Kctl) ||
- utfrune(buf2+1, Kalt) ||
- utfrune(buf2+1, Kmod4) ||
- utfrune(buf2+1, Kaltgr))
- continue;
- chartorune(&r, buf+1);
- keyevent(v, runetovnc(r), 1);
- if(utfrune(buf2+1, r) == nil)
- keyevent(v, runetovnc(r), 0);
- default:
- continue;
- }
- strcpy(buf2, buf);
- }
-}
-
--- a/sys/src/cmd/vnc/ksym2utf.h
+++ /dev/null
@@ -1,1097 +1,0 @@
-/*
- * VNC uses X11's keysyms defined in X11/keysym.h, this is a converter
- * to unicode characters
- */
-static ulong
-ksym2utf [] = {
- [0x1a1] L'Ą',
- [0x1a2] L'˘',
- [0x1a3] L'Ł',
- [0x1a5] L'Ľ',
- [0x1a6] L'Ś',
- [0x1a9] L'Š',
- [0x1aa] L'Ş',
- [0x1ab] L'Ť',
- [0x1ac] L'Ź',
- [0x1ae] L'Ž',
- [0x1af] L'Ż',
- [0x1b1] L'ą',
- [0x1b2] L'˛',
- [0x1b3] L'ł',
- [0x1b5] L'ľ',
- [0x1b6] L'ś',
- [0x1b7] L'ˇ',
- [0x1b9] L'š',
- [0x1ba] L'ş',
- [0x1bb] L'ť',
- [0x1bc] L'ź',
- [0x1bd] L'˝',
- [0x1be] L'ž',
- [0x1bf] L'ż',
- [0x1c0] L'Ŕ',
- [0x1c3] L'Ă',
- [0x1c5] L'Ĺ',
- [0x1c6] L'Ć',
- [0x1c8] L'Č',
- [0x1ca] L'Ę',
- [0x1cc] L'Ě',
- [0x1cf] L'Ď',
- [0x1d0] L'Đ',
- [0x1d1] L'Ń',
- [0x1d2] L'Ň',
- [0x1d5] L'Ő',
- [0x1d8] L'Ř',
- [0x1d9] L'Ů',
- [0x1db] L'Ű',
- [0x1de] L'Ţ',
- [0x1e0] L'ŕ',
- [0x1e3] L'ă',
- [0x1e5] L'ĺ',
- [0x1e6] L'ć',
- [0x1e8] L'č',
- [0x1ea] L'ę',
- [0x1ec] L'ě',
- [0x1ef] L'ď',
- [0x1f0] L'đ',
- [0x1f1] L'ń',
- [0x1f2] L'ň',
- [0x1f5] L'ő',
- [0x1f8] L'ř',
- [0x1f9] L'ů',
- [0x1fb] L'ű',
- [0x1fe] L'ţ',
- [0x1ff] L'˙',
- [0x2a1] L'Ħ',
- [0x2a6] L'Ĥ',
- [0x2a9] L'İ',
- [0x2ab] L'Ğ',
- [0x2ac] L'Ĵ',
- [0x2b1] L'ħ',
- [0x2b6] L'ĥ',
- [0x2b9] L'ı',
- [0x2bb] L'ğ',
- [0x2bc] L'ĵ',
- [0x2c5] L'Ċ',
- [0x2c6] L'Ĉ',
- [0x2d5] L'Ġ',
- [0x2d8] L'Ĝ',
- [0x2dd] L'Ŭ',
- [0x2de] L'Ŝ',
- [0x2e5] L'ċ',
- [0x2e6] L'ĉ',
- [0x2f5] L'ġ',
- [0x2f8] L'ĝ',
- [0x2fd] L'ŭ',
- [0x2fe] L'ŝ',
- [0x3a2] L'ĸ',
- [0x3a3] L'Ŗ',
- [0x3a5] L'Ĩ',
- [0x3a6] L'Ļ',
- [0x3aa] L'Ē',
- [0x3ab] L'Ģ',
- [0x3ac] L'Ŧ',
- [0x3b3] L'ŗ',
- [0x3b5] L'ĩ',
- [0x3b6] L'ļ',
- [0x3ba] L'ē',
- [0x3bb] L'ģ',
- [0x3bc] L'ŧ',
- [0x3bd] L'Ŋ',
- [0x3bf] L'ŋ',
- [0x3c0] L'Ā',
- [0x3c7] L'Į',
- [0x3cc] L'Ė',
- [0x3cf] L'Ī',
- [0x3d1] L'Ņ',
- [0x3d2] L'Ō',
- [0x3d3] L'Ķ',
- [0x3d9] L'Ų',
- [0x3dd] L'Ũ',
- [0x3de] L'Ū',
- [0x3e0] L'ā',
- [0x3e7] L'į',
- [0x3ec] L'ė',
- [0x3ef] L'ī',
- [0x3f1] L'ņ',
- [0x3f2] L'ō',
- [0x3f3] L'ķ',
- [0x3f9] L'ų',
- [0x3fd] L'ũ',
- [0x3fe] L'ū',
- [0x4a1] L'。',
- [0x4a2] L'〈',
- [0x4a3] L'〉',
- [0x4a4] L'、',
- [0x4a5] L'・',
- [0x4a6] L'ヲ',
- [0x4a7] L'ァ',
- [0x4a8] L'ィ',
- [0x4a9] L'ゥ',
- [0x4aa] L'ェ',
- [0x4ab] L'ォ',
- [0x4ac] L'ャ',
- [0x4ad] L'ュ',
- [0x4ae] L'ョ',
- [0x4af] L'ッ',
- [0x4b0] L'ー',
- [0x4b1] L'ア',
- [0x4b2] L'イ',
- [0x4b3] L'ウ',
- [0x4b4] L'エ',
- [0x4b5] L'オ',
- [0x4b6] L'カ',
- [0x4b7] L'キ',
- [0x4b8] L'ク',
- [0x4b9] L'ケ',
- [0x4ba] L'コ',
- [0x4bb] L'サ',
- [0x4bc] L'シ',
- [0x4bd] L'ス',
- [0x4be] L'セ',
- [0x4bf] L'ソ',
- [0x4c0] L'タ',
- [0x4c1] L'チ',
- [0x4c2] L'ツ',
- [0x4c3] L'テ',
- [0x4c4] L'ト',
- [0x4c5] L'ナ',
- [0x4c6] L'ニ',
- [0x4c7] L'ヌ',
- [0x4c8] L'ネ',
- [0x4c9] L'ノ',
- [0x4ca] L'ハ',
- [0x4cb] L'ヒ',
- [0x4cc] L'フ',
- [0x4cd] L'ヘ',
- [0x4ce] L'ホ',
- [0x4cf] L'マ',
- [0x4d0] L'ミ',
- [0x4d1] L'ム',
- [0x4d2] L'メ',
- [0x4d3] L'モ',
- [0x4d4] L'ヤ',
- [0x4d5] L'ユ',
- [0x4d6] L'ヨ',
- [0x4d7] L'ラ',
- [0x4d8] L'リ',
- [0x4d9] L'ル',
- [0x4da] L'レ',
- [0x4db] L'ロ',
- [0x4dc] L'ワ',
- [0x4dd] L'ン',
- [0x4de] L'゛',
- [0x4df] L'゜',
- [0x58a] L'ロ',
- [0x58b] L'ワ',
- [0x58c] L'ン',
- [0x58d] L'゛',
- [0x58e] L'゜',
- [0x590] L'۰',
- [0x591] L'۱',
- [0x592] L'۲',
- [0x593] L'۳',
- [0x594] L'۴',
- [0x595] L'۵',
- [0x596] L'۶',
- [0x597] L'۷',
- [0x598] L'۸',
- [0x599] L'۹',
- [0x5a5] L'٪',
- [0x5a6] L'ٰ',
- [0x5a7] L'ٹ',
- [0x5a8] L'پ',
- [0x5a9] L'چ',
- [0x5aa] L'ڈ',
- [0x5ab] L'ڑ',
- [0x5ac] L'،',
- [0x5ae] L'۔',
- [0x5b0] L'٠',
- [0x5b1] L'١',
- [0x5b2] L'٢',
- [0x5b3] L'٣',
- [0x5b4] L'٤',
- [0x5b5] L'٥',
- [0x5b6] L'٦',
- [0x5b7] L'٧',
- [0x5b8] L'٨',
- [0x5b9] L'٩',
- [0x5bb] L'؛',
- [0x5bf] L'؟',
- [0x5c1] L'ء',
- [0x5c2] L'آ',
- [0x5c3] L'أ',
- [0x5c4] L'ؤ',
- [0x5c5] L'إ',
- [0x5c6] L'ئ',
- [0x5c7] L'ا',
- [0x5c8] L'ب',
- [0x5c9] L'ة',
- [0x5ca] L'ت',
- [0x5cb] L'ث',
- [0x5cc] L'ج',
- [0x5cd] L'ح',
- [0x5ce] L'خ',
- [0x5cf] L'د',
- [0x5d0] L'ذ',
- [0x5d1] L'ر',
- [0x5d2] L'ز',
- [0x5d3] L'س',
- [0x5d4] L'ش',
- [0x5d5] L'ص',
- [0x5d6] L'ض',
- [0x5d7] L'ط',
- [0x5d8] L'ظ',
- [0x5d9] L'ع',
- [0x5da] L'غ',
- [0x5e0] L'ـ',
- [0x5e1] L'ف',
- [0x5e2] L'ق',
- [0x5e3] L'ك',
- [0x5e4] L'ل',
- [0x5e5] L'م',
- [0x5e6] L'ن',
- [0x5e7] L'ه',
- [0x5e8] L'و',
- [0x5e9] L'ى',
- [0x5ea] L'ي',
- [0x5eb] L'ً',
- [0x5ec] L'ٌ',
- [0x5ed] L'ٍ',
- [0x5ee] L'َ',
- [0x5ef] L'ُ',
- [0x5f0] L'ِ',
- [0x5f1] L'ّ',
- [0x5f2] L'ْ',
- [0x5f3] L'ٓ',
- [0x5f4] L'ٔ',
- [0x5f5] L'ٕ',
- [0x5f6] L'ژ',
- [0x5f7] L'ڤ',
- [0x5f8] L'ک',
- [0x5f9] L'گ',
- [0x5fa] L'ں',
- [0x5fb] L'ھ',
- [0x5fc] L'ی',
- [0x5fd] L'ے',
- [0x5fe] L'ہ',
- [0x680] L'Ғ',
- [0x681] L'Җ',
- [0x682] L'Қ',
- [0x683] L'Ҝ',
- [0x684] L'Ң',
- [0x685] L'Ү',
- [0x686] L'Ұ',
- [0x687] L'Ҳ',
- [0x688] L'Ҷ',
- [0x689] L'Ҹ',
- [0x68a] L'Һ',
- [0x68c] L'Ә',
- [0x68d] L'Ӣ',
- [0x68e] L'Ө',
- [0x68f] L'Ӯ',
- [0x690] L'ғ',
- [0x691] L'җ',
- [0x692] L'қ',
- [0x693] L'ҝ',
- [0x694] L'ң',
- [0x695] L'ү',
- [0x696] L'ұ',
- [0x697] L'ҳ',
- [0x698] L'ҷ',
- [0x699] L'ҹ',
- [0x69a] L'һ',
- [0x69c] L'ә',
- [0x69d] L'ӣ',
- [0x69e] L'ө',
- [0x69f] L'ӯ',
- [0x6a1] L'ђ',
- [0x6a2] L'ѓ',
- [0x6a3] L'ё',
- [0x6a4] L'є',
- [0x6a5] L'ѕ',
- [0x6a6] L'і',
- [0x6a7] L'ї',
- [0x6a8] L'ј',
- [0x6a9] L'љ',
- [0x6aa] L'њ',
- [0x6ab] L'ћ',
- [0x6ac] L'ќ',
- [0x6ad] L'ґ',
- [0x6ae] L'ў',
- [0x6af] L'џ',
- [0x6b0] L'№',
- [0x6b1] L'Ђ',
- [0x6b2] L'Ѓ',
- [0x6b3] L'Ё',
- [0x6b4] L'Є',
- [0x6b5] L'Ѕ',
- [0x6b6] L'І',
- [0x6b7] L'Ї',
- [0x6b8] L'Ј',
- [0x6b9] L'Љ',
- [0x6ba] L'Њ',
- [0x6bb] L'Ћ',
- [0x6bc] L'Ќ',
- [0x6bd] L'Ґ',
- [0x6be] L'Ў',
- [0x6bf] L'Џ',
- [0x6c0] L'ю',
- [0x6c1] L'а',
- [0x6c2] L'б',
- [0x6c3] L'ц',
- [0x6c4] L'д',
- [0x6c5] L'е',
- [0x6c6] L'ф',
- [0x6c7] L'г',
- [0x6c8] L'х',
- [0x6c9] L'и',
- [0x6ca] L'й',
- [0x6cb] L'к',
- [0x6cc] L'л',
- [0x6cd] L'м',
- [0x6ce] L'н',
- [0x6cf] L'о',
- [0x6d0] L'п',
- [0x6d1] L'я',
- [0x6d2] L'р',
- [0x6d3] L'с',
- [0x6d4] L'т',
- [0x6d5] L'у',
- [0x6d6] L'ж',
- [0x6d7] L'в',
- [0x6d8] L'ь',
- [0x6d9] L'ы',
- [0x6da] L'з',
- [0x6db] L'ш',
- [0x6dc] L'э',
- [0x6dd] L'щ',
- [0x6de] L'ч',
- [0x6df] L'ъ',
- [0x6e0] L'Ю',
- [0x6e1] L'А',
- [0x6e2] L'Б',
- [0x6e3] L'Ц',
- [0x6e4] L'Д',
- [0x6e5] L'Е',
- [0x6e6] L'Ф',
- [0x6e7] L'Г',
- [0x6e8] L'Х',
- [0x6e9] L'И',
- [0x6ea] L'Й',
- [0x6eb] L'К',
- [0x6ec] L'Л',
- [0x6ed] L'М',
- [0x6ee] L'Н',
- [0x6ef] L'О',
- [0x6f0] L'П',
- [0x6f1] L'Я',
- [0x6f2] L'Р',
- [0x6f3] L'С',
- [0x6f4] L'Т',
- [0x6f5] L'У',
- [0x6f6] L'Ж',
- [0x6f7] L'В',
- [0x6f8] L'Ь',
- [0x6f9] L'Ы',
- [0x6fa] L'З',
- [0x6fb] L'Ш',
- [0x6fc] L'Э',
- [0x6fd] L'Щ',
- [0x6fe] L'Ч',
- [0x6ff] L'Ъ',
- [0x7a1] L'Ά',
- [0x7a2] L'Έ',
- [0x7a3] L'Ή',
- [0x7a4] L'Ί',
- [0x7a5] L'Ϊ',
- [0x7a7] L'Ό',
- [0x7a8] L'Ύ',
- [0x7a9] L'Ϋ',
- [0x7ab] L'Ώ',
- [0x7ae] L'΅',
- [0x7af] L'―',
- [0x7b1] L'ά',
- [0x7b2] L'έ',
- [0x7b3] L'ή',
- [0x7b4] L'ί',
- [0x7b5] L'ϊ',
- [0x7b6] L'ΐ',
- [0x7b7] L'ό',
- [0x7b8] L'ύ',
- [0x7b9] L'ϋ',
- [0x7ba] L'ΰ',
- [0x7bb] L'ώ',
- [0x7c1] L'Α',
- [0x7c2] L'Β',
- [0x7c3] L'Γ',
- [0x7c4] L'Δ',
- [0x7c5] L'Ε',
- [0x7c6] L'Ζ',
- [0x7c7] L'Η',
- [0x7c8] L'Θ',
- [0x7c9] L'Ι',
- [0x7ca] L'Κ',
- [0x7cb] L'Λ',
- [0x7cc] L'Μ',
- [0x7cd] L'Ν',
- [0x7ce] L'Ξ',
- [0x7cf] L'Ο',
- [0x7d0] L'Π',
- [0x7d1] L'Ρ',
- [0x7d2] L'Σ',
- [0x7d4] L'Τ',
- [0x7d5] L'Υ',
- [0x7d6] L'Φ',
- [0x7d7] L'Χ',
- [0x7d8] L'Ψ',
- [0x7d9] L'Ω',
- [0x7e1] L'α',
- [0x7e2] L'β',
- [0x7e3] L'γ',
- [0x7e4] L'δ',
- [0x7e5] L'ε',
- [0x7e6] L'ζ',
- [0x7e7] L'η',
- [0x7e8] L'θ',
- [0x7e9] L'ι',
- [0x7ea] L'κ',
- [0x7eb] L'λ',
- [0x7ec] L'μ',
- [0x7ed] L'ν',
- [0x7ee] L'ξ',
- [0x7ef] L'ο',
- [0x7f0] L'π',
- [0x7f1] L'ρ',
- [0x7f2] L'σ',
- [0x7f3] L'ς',
- [0x7f4] L'τ',
- [0x7f5] L'υ',
- [0x7f6] L'φ',
- [0x7f7] L'χ',
- [0x7f8] L'ψ',
- [0x7f9] L'ω',
- [0x8a4] L'⌠',
- [0x8a5] L'⌡',
- [0x8a7] L'⌜',
- [0x8a8] L'⌝',
- [0x8a9] L'⌞',
- [0x8aa] L'⌟',
- [0x8bc] L'≤',
- [0x8bd] L'≠',
- [0x8be] L'≥',
- [0x8bf] L'∫',
- [0x8c0] L'∴',
- [0x8c2] L'∞',
- [0x8c5] L'∇',
- [0x8c8] L'≅',
- [0x8c9] L'≆',
- [0x8ce] L'⊢',
- [0x8d6] L'√',
- [0x8da] L'⊂',
- [0x8db] L'⊃',
- [0x8dc] L'∩',
- [0x8dd] L'∪',
- [0x8de] L'∧',
- [0x8df] L'∨',
- [0x8f6] L'ƒ',
- [0x8fb] L'←',
- [0x8fc] L'↑',
- [0x8fd] L'→',
- [0x8fe] L'↓',
- [0x9df] L'␢',
- [0x9e0] L'♦',
- [0x9e1] L'▦',
- [0x9e2] L'␉',
- [0x9e3] L'␌',
- [0x9e4] L'␍',
- [0x9e5] L'␊',
- [0x9e8] L'␊',
- [0x9e9] L'␋',
- [0x9ea] L'┘',
- [0x9eb] L'┐',
- [0x9ec] L'┌',
- [0x9ed] L'└',
- [0x9ee] L'┼',
- [0x9ef] L'─',
- [0x9f4] L'├',
- [0x9f5] L'┤',
- [0x9f6] L'┴',
- [0x9f7] L'┬',
- [0x9f8] L'│',
- [0xaa1] L' ',
- [0xaa2] L' ',
- [0xaa3] L' ',
- [0xaa4] L' ',
- [0xaa5] L' ',
- [0xaa6] L' ',
- [0xaa7] L' ',
- [0xaa8] L' ',
- [0xaa9] L'—',
- [0xaaa] L'–',
- [0xaae] L'…',
- [0xaaf] L'‥',
- [0xab0] L'⅓',
- [0xab1] L'⅔',
- [0xab2] L'⅕',
- [0xab3] L'⅖',
- [0xab4] L'⅗',
- [0xab5] L'⅘',
- [0xab6] L'⅙',
- [0xab7] L'⅚',
- [0xab8] L'℅',
- [0xabb] L'‒',
- [0xabc] L'‹',
- [0xabd] L'․',
- [0xabe] L'›',
- [0xac3] L'⅛',
- [0xac4] L'⅜',
- [0xac5] L'⅝',
- [0xac6] L'⅞',
- [0xac9] L'™',
- [0xaca] L'℠',
- [0xacc] L'◁',
- [0xacd] L'▷',
- [0xace] L'○',
- [0xacf] L'▭',
- [0xad0] L'‘',
- [0xad1] L'’',
- [0xad2] L'“',
- [0xad3] L'”',
- [0xad4] L'℞',
- [0xad6] L'′',
- [0xad7] L'″',
- [0xad9] L'✝',
- [0xadb] L'∎',
- [0xadc] L'◂',
- [0xadd] L'‣',
- [0xade] L'●',
- [0xadf] L'▬',
- [0xae0] L'◦',
- [0xae1] L'▫',
- [0xae2] L'▮',
- [0xae3] L'▵',
- [0xae4] L'▿',
- [0xae5] L'☆',
- [0xae6] L'•',
- [0xae7] L'▪',
- [0xae8] L'▴',
- [0xae9] L'▾',
- [0xaea] L'☚',
- [0xaeb] L'☛',
- [0xaec] L'♣',
- [0xaed] L'♦',
- [0xaee] L'♥',
- [0xaf0] L'✠',
- [0xaf1] L'†',
- [0xaf2] L'‡',
- [0xaf3] L'✓',
- [0xaf4] L'☒',
- [0xaf5] L'♯',
- [0xaf6] L'♭',
- [0xaf7] L'♂',
- [0xaf8] L'♀',
- [0xaf9] L'℡',
- [0xafa] L'⌕',
- [0xafb] L'℗',
- [0xafc] L'‸',
- [0xafd] L'‚',
- [0xafe] L'„',
- [0xcdf] L'‗',
- [0xce0] L'א',
- [0xce1] L'ב',
- [0xce2] L'ג',
- [0xce3] L'ד',
- [0xce4] L'ה',
- [0xce5] L'ו',
- [0xce6] L'ז',
- [0xce7] L'ח',
- [0xce8] L'ט',
- [0xce9] L'י',
- [0xcea] L'ך',
- [0xceb] L'כ',
- [0xcec] L'ל',
- [0xced] L'ם',
- [0xcee] L'מ',
- [0xcef] L'ן',
- [0xcf0] L'נ',
- [0xcf1] L'ס',
- [0xcf2] L'ע',
- [0xcf3] L'ף',
- [0xcf4] L'פ',
- [0xcf5] L'ץ',
- [0xcf6] L'צ',
- [0xcf7] L'ק',
- [0xcf8] L'ר',
- [0xcf9] L'ש',
- [0xcfa] L'ת',
- [0xda1] L'ก',
- [0xda2] L'ข',
- [0xda3] L'ฃ',
- [0xda4] L'ค',
- [0xda5] L'ฅ',
- [0xda6] L'ฆ',
- [0xda7] L'ง',
- [0xda8] L'จ',
- [0xda9] L'ฉ',
- [0xdaa] L'ช',
- [0xdab] L'ซ',
- [0xdac] L'ฌ',
- [0xdad] L'ญ',
- [0xdae] L'ฎ',
- [0xdaf] L'ฏ',
- [0xdb0] L'ฐ',
- [0xdb1] L'ฑ',
- [0xdb2] L'ฒ',
- [0xdb3] L'ณ',
- [0xdb4] L'ด',
- [0xdb5] L'ต',
- [0xdb6] L'ถ',
- [0xdb7] L'ท',
- [0xdb8] L'ธ',
- [0xdb9] L'น',
- [0xdba] L'บ',
- [0xdbb] L'ป',
- [0xdbc] L'ผ',
- [0xdbd] L'ฝ',
- [0xdbe] L'พ',
- [0xdbf] L'ฟ',
- [0xdc0] L'ภ',
- [0xdc1] L'ม',
- [0xdc2] L'ย',
- [0xdc3] L'ร',
- [0xdc4] L'ฤ',
- [0xdc5] L'ล',
- [0xdc6] L'ฦ',
- [0xdc7] L'ว',
- [0xdc8] L'ศ',
- [0xdc9] L'ษ',
- [0xdca] L'ส',
- [0xdcb] L'ห',
- [0xdcc] L'ฬ',
- [0xdcd] L'อ',
- [0xdce] L'ฮ',
- [0xdcf] L'ฯ',
- [0xdd0] L'ะ',
- [0xdd1] L'ั',
- [0xdd2] L'า',
- [0xdd3] L'ำ',
- [0xdd4] L'ิ',
- [0xdd5] L'ี',
- [0xdd6] L'ึ',
- [0xdd7] L'ื',
- [0xdd8] L'ุ',
- [0xdd9] L'ู',
- [0xdda] L'ฺ',
- [0xdde] L'',
- [0xddf] L'฿',
- [0xde0] L'เ',
- [0xde1] L'แ',
- [0xde2] L'โ',
- [0xde3] L'ใ',
- [0xde4] L'ไ',
- [0xde5] L'ๅ',
- [0xde6] L'ๆ',
- [0xde7] L'็',
- [0xde8] L'่',
- [0xde9] L'้',
- [0xdea] L'๊',
- [0xdeb] L'๋',
- [0xdec] L'์',
- [0xded] L'ํ',
- [0xdf0] L'๐',
- [0xdf1] L'๑',
- [0xdf2] L'๒',
- [0xdf3] L'๓',
- [0xdf4] L'๔',
- [0xdf5] L'๕',
- [0xdf6] L'๖',
- [0xdf7] L'๗',
- [0xdf8] L'๘',
- [0xdf9] L'๙',
- [0xea1] L'ᄁ',
- [0xea2] L'ᄁ',
- [0xea3] L'ᆪ',
- [0xea4] L'ᄂ',
- [0xea5] L'ᆬ',
- [0xea6] L'ᆭ',
- [0xea7] L'ᄃ',
- [0xea8] L'ᄄ',
- [0xea9] L'ᄅ',
- [0xeaa] L'ᆰ',
- [0xeab] L'ᆱ',
- [0xeac] L'ᆲ',
- [0xead] L'ᆳ',
- [0xeae] L'ᆴ',
- [0xeaf] L'ᆵ',
- [0xeb0] L'ᆶ',
- [0xeb1] L'ᄆ',
- [0xeb2] L'ᄇ',
- [0xeb3] L'ᄈ',
- [0xeb4] L'ᆹ',
- [0xeb5] L'ᄉ',
- [0xeb6] L'ᄊ',
- [0xeb7] L'ᄋ',
- [0xeb8] L'ᄌ',
- [0xeb9] L'ᄍ',
- [0xeba] L'ᄎ',
- [0xebb] L'ᄏ',
- [0xebc] L'ᄐ',
- [0xebd] L'ᄑ',
- [0xebe] L'ᄒ',
- [0xebf] L'ᅡ',
- [0xec0] L'ᅢ',
- [0xec1] L'ᅣ',
- [0xec2] L'ᅤ',
- [0xec3] L'ᅥ',
- [0xec4] L'ᅦ',
- [0xec5] L'ᅧ',
- [0xec6] L'ᅨ',
- [0xec7] L'ᅩ',
- [0xec8] L'ᅪ',
- [0xec9] L'ᅫ',
- [0xeca] L'ᅬ',
- [0xecb] L'ᅭ',
- [0xecc] L'ᅮ',
- [0xecd] L'ᅯ',
- [0xece] L'ᅰ',
- [0xecf] L'ᅱ',
- [0xed0] L'ᅲ',
- [0xed1] L'ᅳ',
- [0xed2] L'ᅴ',
- [0xed3] L'ᅵ',
- [0xed4] L'ᆨ',
- [0xed5] L'ᆩ',
- [0xed6] L'ᆪ',
- [0xed7] L'ᆫ',
- [0xed8] L'ᆬ',
- [0xed9] L'ᆭ',
- [0xeda] L'ᆮ',
- [0xedb] L'ᆯ',
- [0xedc] L'ᆰ',
- [0xedd] L'ᆱ',
- [0xede] L'ᆲ',
- [0xedf] L'ᆳ',
- [0xee0] L'ᆴ',
- [0xee1] L'ᆵ',
- [0xee2] L'ᆶ',
- [0xee3] L'ᆷ',
- [0xee4] L'ᆸ',
- [0xee5] L'ᆹ',
- [0xee6] L'ᆺ',
- [0xee7] L'ᆻ',
- [0xee8] L'ᆼ',
- [0xee9] L'ᆽ',
- [0xeea] L'ᆾ',
- [0xeeb] L'ᆿ',
- [0xeec] L'ᇀ',
- [0xeed] L'ᇁ',
- [0xeee] L'ᇂ',
- [0xef2] L'ᅀ',
- [0xef5] L'ᅙ',
- [0xef6] L'ᆞ',
- [0xef8] L'ᇫ',
- [0xefa] L'ᇹ',
- [0xeff] L'₩',
- [0x12a1] L'Ḃ',
- [0x12a2] L'ḃ',
- [0x12a6] L'Ḋ',
- [0x12a8] L'Ẁ',
- [0x12aa] L'Ẃ',
- [0x12ab] L'ḋ',
- [0x12ac] L'Ỳ',
- [0x12b0] L'Ḟ',
- [0x12b1] L'ḟ',
- [0x12b4] L'Ṁ',
- [0x12b5] L'ṁ',
- [0x12b7] L'Ṗ',
- [0x12b8] L'ẁ',
- [0x12b9] L'ṗ',
- [0x12ba] L'ẃ',
- [0x12bb] L'Ṡ',
- [0x12bc] L'ỳ',
- [0x12bd] L'Ẅ',
- [0x12be] L'ẅ',
- [0x12bf] L'ṡ',
- [0x12d0] L'Ŵ',
- [0x12d7] L'Ṫ',
- [0x12de] L'Ŷ',
- [0x12f0] L'ŵ',
- [0x12f7] L'ṫ',
- [0x12fe] L'ŷ',
- [0x13bc] L'Œ',
- [0x13bd] L'œ',
- [0x13be] L'Ÿ',
- [0x14a1] L'❁',
- [0x14a2] L'§',
- [0x14a3] L'։',
- [0x14a4] L')',
- [0x14a5] L'(',
- [0x14a6] L'»',
- [0x14a7] L'«',
- [0x14a8] L'—',
- [0x14a9] L'.',
- [0x14aa] L'՝',
- [0x14ab] L',',
- [0x14ac] L'–',
- [0x14ad] L'֊',
- [0x14ae] L'…',
- [0x14af] L'՜',
- [0x14b0] L'՛',
- [0x14b1] L'՞',
- [0x14b2] L'Ա',
- [0x14b3] L'ա',
- [0x14b4] L'Բ',
- [0x14b5] L'բ',
- [0x14b6] L'Գ',
- [0x14b7] L'գ',
- [0x14b8] L'Դ',
- [0x14b9] L'դ',
- [0x14ba] L'Ե',
- [0x14bb] L'ե',
- [0x14bc] L'Զ',
- [0x14bd] L'զ',
- [0x14be] L'Է',
- [0x14bf] L'է',
- [0x14c0] L'Ը',
- [0x14c1] L'ը',
- [0x14c2] L'Թ',
- [0x14c3] L'թ',
- [0x14c4] L'Ժ',
- [0x14c5] L'ժ',
- [0x14c6] L'Ի',
- [0x14c7] L'ի',
- [0x14c8] L'Լ',
- [0x14c9] L'լ',
- [0x14ca] L'Խ',
- [0x14cb] L'խ',
- [0x14cc] L'Ծ',
- [0x14cd] L'ծ',
- [0x14ce] L'Կ',
- [0x14cf] L'կ',
- [0x14d0] L'Հ',
- [0x14d1] L'հ',
- [0x14d2] L'Ձ',
- [0x14d3] L'ձ',
- [0x14d4] L'Ղ',
- [0x14d5] L'ղ',
- [0x14d6] L'Ճ',
- [0x14d7] L'ճ',
- [0x14d8] L'Մ',
- [0x14d9] L'մ',
- [0x14da] L'Յ',
- [0x14db] L'յ',
- [0x14dc] L'Ն',
- [0x14dd] L'ն',
- [0x14de] L'Շ',
- [0x14df] L'շ',
- [0x14e0] L'Ո',
- [0x14e1] L'ո',
- [0x14e2] L'Չ',
- [0x14e3] L'չ',
- [0x14e4] L'Պ',
- [0x14e5] L'պ',
- [0x14e6] L'Ջ',
- [0x14e7] L'ջ',
- [0x14e8] L'Ռ',
- [0x14e9] L'ռ',
- [0x14ea] L'Ս',
- [0x14eb] L'ս',
- [0x14ec] L'Վ',
- [0x14ed] L'վ',
- [0x14ee] L'Տ',
- [0x14ef] L'տ',
- [0x14f0] L'Ր',
- [0x14f1] L'ր',
- [0x14f2] L'Ց',
- [0x14f3] L'ց',
- [0x14f4] L'Ւ',
- [0x14f5] L'ւ',
- [0x14f6] L'Փ',
- [0x14f7] L'փ',
- [0x14f8] L'Ք',
- [0x14f9] L'ք',
- [0x14fa] L'Օ',
- [0x14fb] L'օ',
- [0x14fc] L'Ֆ',
- [0x14fd] L'ֆ',
- [0x14fe] L'’',
- [0x14ff] L''',
- [0x15d0] L'ა',
- [0x15d1] L'ბ',
- [0x15d2] L'გ',
- [0x15d3] L'დ',
- [0x15d4] L'ე',
- [0x15d5] L'ვ',
- [0x15d6] L'ზ',
- [0x15d7] L'თ',
- [0x15d8] L'ი',
- [0x15d9] L'კ',
- [0x15da] L'ლ',
- [0x15db] L'მ',
- [0x15dc] L'ნ',
- [0x15dd] L'ო',
- [0x15de] L'პ',
- [0x15df] L'ჟ',
- [0x15e0] L'რ',
- [0x15e1] L'ს',
- [0x15e2] L'ტ',
- [0x15e3] L'უ',
- [0x15e4] L'ფ',
- [0x15e5] L'ქ',
- [0x15e6] L'ღ',
- [0x15e7] L'ყ',
- [0x15e8] L'შ',
- [0x15e9] L'ჩ',
- [0x15ea] L'ც',
- [0x15eb] L'ძ',
- [0x15ec] L'წ',
- [0x15ed] L'ჭ',
- [0x15ee] L'ხ',
- [0x15ef] L'ჯ',
- [0x15f0] L'ჰ',
- [0x15f1] L'ჱ',
- [0x15f2] L'ჲ',
- [0x15f3] L'ჳ',
- [0x15f4] L'ჴ',
- [0x15f5] L'ჵ',
- [0x15f6] L'ჶ',
- [0x16a2] L'',
- [0x16a3] L'Ẋ',
- [0x16a5] L'',
- [0x16a6] L'Ĭ',
- [0x16a7] L'',
- [0x16a8] L'',
- [0x16a9] L'Ƶ',
- [0x16aa] L'Ǧ',
- [0x16af] L'Ɵ',
- [0x16b2] L'',
- [0x16b3] L'ẋ',
- [0x16b4] L'Ǒ',
- [0x16b5] L'',
- [0x16b6] L'ĭ',
- [0x16b7] L'',
- [0x16b8] L'',
- [0x16b9] L'ƶ',
- [0x16ba] L'ǧ',
- [0x16bd] L'ǒ',
- [0x16bf] L'ɵ',
- [0x16c6] L'Ə',
- [0x16d1] L'Ḷ',
- [0x16d2] L'',
- [0x16d3] L'',
- [0x16e1] L'ḷ',
- [0x16e2] L'',
- [0x16e3] L'',
- [0x16f6] L'ə',
- [0x1e9f] L'̃',
- [0x1ea0] L'Ạ',
- [0x1ea1] L'ạ',
- [0x1ea2] L'Ả',
- [0x1ea3] L'ả',
- [0x1ea4] L'Ấ',
- [0x1ea5] L'ấ',
- [0x1ea6] L'Ầ',
- [0x1ea7] L'ầ',
- [0x1ea8] L'Ẩ',
- [0x1ea9] L'ẩ',
- [0x1eaa] L'Ẫ',
- [0x1eab] L'ẫ',
- [0x1eac] L'Ậ',
- [0x1ead] L'ậ',
- [0x1eae] L'Ắ',
- [0x1eaf] L'ắ',
- [0x1eb0] L'Ằ',
- [0x1eb1] L'ằ',
- [0x1eb2] L'Ẳ',
- [0x1eb3] L'ẳ',
- [0x1eb4] L'Ẵ',
- [0x1eb5] L'ẵ',
- [0x1eb6] L'Ặ',
- [0x1eb7] L'ặ',
- [0x1eb8] L'Ẹ',
- [0x1eb9] L'ẹ',
- [0x1eba] L'Ẻ',
- [0x1ebb] L'ẻ',
- [0x1ebc] L'Ẽ',
- [0x1ebd] L'ẽ',
- [0x1ebe] L'Ế',
- [0x1ebf] L'ế',
- [0x1ec0] L'Ề',
- [0x1ec1] L'ề',
- [0x1ec2] L'Ể',
- [0x1ec3] L'ể',
- [0x1ec4] L'Ễ',
- [0x1ec5] L'ễ',
- [0x1ec6] L'Ệ',
- [0x1ec7] L'ệ',
- [0x1ec8] L'Ỉ',
- [0x1ec9] L'ỉ',
- [0x1eca] L'Ị',
- [0x1ecb] L'ị',
- [0x1ecc] L'Ọ',
- [0x1ecd] L'ọ',
- [0x1ece] L'Ỏ',
- [0x1ecf] L'ỏ',
- [0x1ed0] L'Ố',
- [0x1ed1] L'ố',
- [0x1ed2] L'Ồ',
- [0x1ed3] L'ồ',
- [0x1ed4] L'Ổ',
- [0x1ed5] L'ổ',
- [0x1ed6] L'Ỗ',
- [0x1ed7] L'ỗ',
- [0x1ed8] L'Ộ',
- [0x1ed9] L'ộ',
- [0x1eda] L'Ớ',
- [0x1edb] L'ớ',
- [0x1edc] L'Ờ',
- [0x1edd] L'ờ',
- [0x1ede] L'Ở',
- [0x1edf] L'ở',
- [0x1ee0] L'Ỡ',
- [0x1ee1] L'ỡ',
- [0x1ee2] L'Ợ',
- [0x1ee3] L'ợ',
- [0x1ee4] L'Ụ',
- [0x1ee5] L'ụ',
- [0x1ee6] L'Ủ',
- [0x1ee7] L'ủ',
- [0x1ee8] L'Ứ',
- [0x1ee9] L'ứ',
- [0x1eea] L'Ừ',
- [0x1eeb] L'ừ',
- [0x1eec] L'Ử',
- [0x1eed] L'ử',
- [0x1eee] L'Ữ',
- [0x1eef] L'ữ',
- [0x1ef0] L'Ự',
- [0x1ef1] L'ự',
- [0x1ef2] L'̀',
- [0x1ef3] L'́',
- [0x1ef4] L'Ỵ',
- [0x1ef5] L'ỵ',
- [0x1ef6] L'Ỷ',
- [0x1ef7] L'ỷ',
- [0x1ef8] L'Ỹ',
- [0x1ef9] L'ỹ',
- [0x1efa] L'Ơ',
- [0x1efb] L'ơ',
- [0x1efc] L'Ư',
- [0x1efd] L'ư',
- [0x1efe] L'̉',
- [0x1eff] L'̣',
- [0x20a0] L'₠',
- [0x20a1] L'₡',
- [0x20a2] L'₢',
- [0x20a3] L'₣',
- [0x20a4] L'₤',
- [0x20a5] L'₥',
- [0x20a6] L'₦',
- [0x20a7] L'₧',
- [0x20a8] L'₨',
- [0x20a9] L'₩',
- [0x20aa] L'₪',
- [0x20ab] L'₫',
- [0x20ac] L'€',
-
-};
\ No newline at end of file
--- a/sys/src/cmd/vnc/mkfile
+++ /dev/null
@@ -1,60 +1,0 @@
-</$objtype/mkfile
-
-TARG=vncs vncv
-BIN=/$objtype/bin
-
-OFILES=\
- proto.$O\
- auth.$O\
-
-SOFILES=\
- devdraw.$O\
- devmouse.$O\
- devcons.$O\
- screen.$O\
- exporter.$O\
- dev.$O\
- chan.$O\
- compat.$O\
- exportfs.$O\
- kbds.$O\
- rre.$O\
- rlist.$O\
-
-COFILES=\
- draw.$O\
- kbdv.$O\
- color.$O\
- wsys.$O\
-
-HFILES=\
- vnc.h\
- screen.h\
- compat.h\
- errstr.h\
- kbd.h\
- vncv.h\
- vncs.h\
-
-UPDATE=\
- mkfile\
- $HFILES\
- ${OFILES:%.$O=%.c}\
- ${SOFILES:%.$O=%.c}\
- ${COFILES:%.$O=%.c}\
- ${TARG:%=%.c}\
-
-
-default:V: all
-
-</sys/src/cmd/mkmany
-
-$O.vncs: $SOFILES
-
-$O.vncv: $COFILES
-
-errstr.h: error.h
- sed 's/extern //;s,;.*/\* (.*) \*/, = "\1";,' < error.h > errstr.h
-
-kbds.$O: ksym2utf.h
-kbdv.$O: utf2ksym.h
--- a/sys/src/cmd/vnc/proto.c
+++ /dev/null
@@ -1,294 +1,0 @@
-#include "vnc.h"
-
-#define SHORT(p) (((p)[0]<<8)|((p)[1]))
-#define LONG(p) ((SHORT(p)<<16)|SHORT(p+2))
-
-uchar zero[64];
-
-Vnc*
-vncinit(int fd, int cfd, Vnc *v)
-{
- if(v == nil)
- v = mallocz(sizeof(*v), 1);
- Binit(&v->in, fd, OREAD);
- Binit(&v->out, fd, OWRITE);
- v->datafd = fd;
- v->ctlfd = cfd;
- return v;
-}
-
-void
-vncterm(Vnc *v)
-{
- Bterm(&v->out);
- Bterm(&v->in);
-}
-
-void
-vncflush(Vnc *v)
-{
- if(Bflush(&v->out) < 0){
- if(verbose > 1)
- fprint(2, "hungup while sending flush: %r\n");
- vnchungup(v);
- }
-}
-
-uchar
-vncrdchar(Vnc *v)
-{
- uchar buf[1];
-
- vncrdbytes(v, buf, 1);
- return buf[0];
-}
-
-ushort
-vncrdshort(Vnc *v)
-{
- uchar buf[2];
-
- vncrdbytes(v, buf, 2);
- return SHORT(buf);
-}
-
-ulong
-vncrdlong(Vnc *v)
-{
- uchar buf[4];
-
- vncrdbytes(v, buf, 4);
- return LONG(buf);
-}
-
-Point
-vncrdpoint(Vnc *v)
-{
- Point p;
-
- p.x = vncrdshort(v);
- p.y = vncrdshort(v);
- return p;
-}
-
-Rectangle
-vncrdrect(Vnc *v)
-{
- Rectangle r;
-
- r.min.x = vncrdshort(v);
- r.min.y = vncrdshort(v);
- r.max.x = r.min.x + vncrdshort(v);
- r.max.y = r.min.y + vncrdshort(v);
- return r;
-}
-
-Rectangle
-vncrdcorect(Vnc *v)
-{
- Rectangle r;
-
- r.min.x = vncrdchar(v);
- r.min.y = vncrdchar(v);
- r.max.x = r.min.x + vncrdchar(v);
- r.max.y = r.min.y + vncrdchar(v);
- return r;
-}
-
-void
-vncrdbytes(Vnc *v, void *a, int n)
-{
- if(Bread(&v->in, a, n) != n){
- if(verbose > 1)
- fprint(2, "hungup while reading\n");
- vnchungup(v);
- }
-}
-
-Pixfmt
-vncrdpixfmt(Vnc *v)
-{
- Pixfmt fmt;
- uchar pad[3];
-
- fmt.bpp = vncrdchar(v);
- fmt.depth = vncrdchar(v);
- fmt.bigendian = vncrdchar(v);
- fmt.truecolor = vncrdchar(v);
- fmt.red.max = vncrdshort(v);
- fmt.green.max = vncrdshort(v);
- fmt.blue.max = vncrdshort(v);
- fmt.red.shift = vncrdchar(v);
- fmt.green.shift = vncrdchar(v);
- fmt.blue.shift = vncrdchar(v);
- vncrdbytes(v, pad, 3);
- return fmt;
-}
-
-char*
-vncrdstring(Vnc *v)
-{
- ulong len;
- char *s;
-
- len = vncrdlong(v);
- s = malloc(len+1);
- assert(s != nil);
-
- vncrdbytes(v, s, len);
- s[len] = '\0';
- return s;
-}
-
-/*
- * on the server side of the negotiation protocol, we read
- * the client response and then run the negotiated function.
- * in some cases (e.g., TLS) the negotiated function needs to
- * use v->datafd directly and be sure that no data has been
- * buffered away in the Bio. since we know the client is waiting
- * for our response, it won't have sent any until we respond.
- * thus we read the response with vncrdstringx, which goes
- * behind bio's back.
- */
-char*
-vncrdstringx(Vnc *v)
-{
- char tmp[4];
- char *s;
- ulong len;
-
- assert(Bbuffered(&v->in) == 0);
- if(readn(v->datafd, tmp, 4) != 4){
- fprint(2, "cannot rdstringx: %r");
- vnchungup(v);
- }
- len = LONG(tmp);
- s = malloc(len+1);
- assert(s != nil);
- if(readn(v->datafd, s, len) != len){
- fprint(2, "cannot rdstringx len %lud: %r", len);
- vnchungup(v);
- }
- s[len] = '\0';
- return s;
-}
-
-void
-vncwrstring(Vnc *v, char *s)
-{
- ulong len;
-
- len = strlen(s);
- vncwrlong(v, len);
- vncwrbytes(v, s, len);
-}
-
-void
-vncwrbytes(Vnc *v, void *a, int n)
-{
- if(Bwrite(&v->out, a, n) < 0){
- if(verbose > 1)
- fprint(2, "hungup while writing bytes\n");
- vnchungup(v);
- }
-}
-
-void
-vncwrlong(Vnc *v, ulong u)
-{
- uchar buf[4];
-
- buf[0] = u>>24;
- buf[1] = u>>16;
- buf[2] = u>>8;
- buf[3] = u;
- vncwrbytes(v, buf, 4);
-}
-
-void
-vncwrshort(Vnc *v, ushort u)
-{
- uchar buf[2];
-
- buf[0] = u>>8;
- buf[1] = u;
- vncwrbytes(v, buf, 2);
-}
-
-void
-vncwrchar(Vnc *v, uchar c)
-{
- vncwrbytes(v, &c, 1);
-}
-
-void
-vncwrpixfmt(Vnc *v, Pixfmt *fmt)
-{
- vncwrchar(v, fmt->bpp);
- vncwrchar(v, fmt->depth);
- vncwrchar(v, fmt->bigendian);
- vncwrchar(v, fmt->truecolor);
- vncwrshort(v, fmt->red.max);
- vncwrshort(v, fmt->green.max);
- vncwrshort(v, fmt->blue.max);
- vncwrchar(v, fmt->red.shift);
- vncwrchar(v, fmt->green.shift);
- vncwrchar(v, fmt->blue.shift);
- vncwrbytes(v, zero, 3);
-}
-
-void
-vncwrrect(Vnc *v, Rectangle r)
-{
- vncwrshort(v, r.min.x);
- vncwrshort(v, r.min.y);
- vncwrshort(v, r.max.x-r.min.x);
- vncwrshort(v, r.max.y-r.min.y);
-}
-
-void
-vncwrpoint(Vnc *v, Point p)
-{
- vncwrshort(v, p.x);
- vncwrshort(v, p.y);
-}
-
-void
-vnclock(Vnc *v)
-{
- qlock(v);
-}
-
-void
-vncunlock(Vnc *v)
-{
- qunlock(v);
-}
-
-void
-hexdump(void *a, int n)
-{
- uchar *p, *ep;
-
- p = a;
- ep = p+n;
-
- for(; p<ep; p++)
- print("%.2ux ", *p);
- print("\n");
-}
-
-void
-vncgobble(Vnc *v, long n)
-{
- uchar buf[8192];
- long m;
-
- while(n > 0){
- m = n;
- if(m > sizeof(buf))
- m = sizeof(buf);
- vncrdbytes(v, buf, m);
- n -= m;
- }
-}
--- a/sys/src/cmd/vnc/rlist.c
+++ /dev/null
@@ -1,286 +1,0 @@
-#include "vnc.h"
-#include "vncs.h"
-
-static int tot;
-static void rprint(Rlist*);
-
-static void
-growrlist(Rlist *rlist, int n)
-{
- int old;
-
- if(rlist->nrect+n <= rlist->maxrect)
- return;
-
- old = rlist->maxrect;
- while(rlist->nrect+n > rlist->maxrect){
- if(rlist->maxrect == 0)
- rlist->maxrect = 16;
- else
- rlist->maxrect *= 2;
- }
-
- tot += rlist->maxrect - old;
- if(tot > 10000)
- sysfatal("too many rectangles");
-
- rlist->rect = realloc(rlist->rect, rlist->maxrect*sizeof(rlist->rect[0]));
- if(rlist->rect == nil)
- sysfatal("realloc failed in growrlist");
-}
-
-static void
-rappend(Rlist *rl, Rectangle r)
-{
- growrlist(rl, 1);
- rl->rect[rl->nrect++] = r;
-}
-
-/* remove rectangle i from the list */
-static int
-rtrim(Rlist *r, int i)
-{
- if(i < 0 || i >= r->nrect)
- return 0;
- if(i == r->nrect-1){
- r->nrect--;
- return 1;
- }
- r->rect[i] = r->rect[--r->nrect];
- return 1;
-}
-
-static int
-rectadjacent(Rectangle r, Rectangle s)
-{
- return r.min.x<=s.max.x && s.min.x<=r.max.x &&
- r.min.y<=s.max.y && s.min.y<=r.max.y;
-}
-
-/*
- * If s shares three edges with r, compute the
- * rectangle r - s and return 1.
- * Else return 0.
- */
-static int
-rectubr(Rectangle *r, Rectangle s)
-{
- if(r->min.y==s.min.y && r->max.y==s.max.y){
- if(r->min.x == s.min.x){
- r->min.x = s.max.x;
- assert(r->max.x > r->min.x);
- return 1;
- }
- if(r->max.x == s.max.x){
- r->max.x = s.min.x;
- assert(r->max.x > r->min.x);
- return 1;
- }
- }
- if(r->min.x==s.min.x && r->max.x==s.max.x){
- if(r->min.y == s.min.y){
- r->min.y = s.max.y;
- assert(r->max.y > r->min.y);
- return 1;
- }
- if(r->max.y == s.max.y){
- r->max.y = s.min.y;
- assert(r->max.y > r->min.y);
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * If s is a corner of r, remove s from r, yielding
- * two rectangles r and rr. R holds the part with
- * smaller coordinates.
- */
-static int
-rectcornersubr(Rectangle *r, Rectangle s, Rectangle *rr)
-{
-# define UPRIGHT(r) Pt((r).max.x, (r).min.y)
-# define LOWLEFT(r) Pt((r).min.x, (r).max.y)
-
- *rr = *r;
-
- if(s.min.x == r->min.x){
- if(s.min.y == r->min.y){ // upper left
- *rr = Rpt(UPRIGHT(s), r->max);
- *r = Rpt(LOWLEFT(s), LOWLEFT(*rr));
- return 1;
- }
- if(s.max.y == r->max.y){ // lower left
- *rr = Rpt(Pt(s.max.x, r->min.y), r->max);
- *r = Rpt(r->min, UPRIGHT(s));
- return 1;
- }
- }
- if(s.max.x == r->max.x){
- if(s.max.y == r->max.y){ // lower right
- *rr = Rpt(Pt(s.min.x, r->min.y), UPRIGHT(s));
- *r = Rpt(r->min, LOWLEFT(s));
- return 1;
- }
- if(s.min.y == r->min.y){ // upper right
- *rr = Rpt(LOWLEFT(s), r->max);
- *r = Rpt(r->min, LOWLEFT(*rr));
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * If s is a band cutting r into two pieces, set r to one piece
- * and rr to the other.
- */
-static int
-recttridesubr(Rectangle *nr, Rectangle s, Rectangle *rr)
-{
- *rr = *nr;
- if((nr->min.x == s.min.x && nr->max.x == s.max.x) &&
- (nr->min.y < s.min.y && s.max.y < nr->max.y)){
- nr->max.y = s.min.y;
- rr->min.y = s.max.y;
- return 1;
- }
-
- if((nr->min.y == s.min.y && nr->max.y == s.max.y) &&
- (nr->min.x < s.min.x && s.max.x < nr->max.x)){
- nr->max.x = s.min.x;
- rr->min.x = s.max.x;
- return 1;
- }
- return 0;
-}
-
-void
-addtorlist(Rlist *rlist, Rectangle r)
-{
- int i, j;
- Rectangle ir, cr, rr;
- Rlist tmp;
-
- if(r.min.x >= r.max.x || r.min.y >= r.max.y)
- return;
-
- memset(&tmp, 0, sizeof tmp);
- rappend(&tmp, r);
-
- if(verbose > 5)
- fprint(2, "region union add %R:\n", r);
-
- combinerect(&rlist->bbox, r); // must do this first
- for(j = 0; j < tmp.nrect; j++){
- r = tmp.rect[j];
-
- for(i=0; i < rlist->nrect; i++){
- ir = rlist->rect[i];
-
- if(verbose > 5)
- fprint(2, "checking %R against %R\n", r, ir);
- if(!rectadjacent(ir, r))
- continue;
-
- /* r is covered by ir? */
- if(rectinrect(r, ir))
- break;
-
- /* r covers ir? */
- if(rectinrect(ir, r)){
- rtrim(rlist, i);
- i--;
- continue;
- }
-
- /* aligned and overlapping? */
- if((ir.min.y == r.min.y && ir.max.y == r.max.y) ||
- (ir.min.x == r.min.x && ir.max.x == r.max.x)){
- combinerect(&r, ir);
- rtrim(rlist, i);
- i--;
- continue;
- }
-
- /* not aligned */
- if(verbose > 5)
- fprint(2, "break up rect %R and %R\n", ir, r);
- /* 2->2 breakup */
- cr = ir;
- if (!rectclip(&cr, r)) /* share only one point */
- continue;
-
- if(rectubr(&r, cr))
- continue;
-
- if(rectubr(&rlist->rect[i], cr))
- continue;
-
- /* 2 -> 3 breakup */
- /* stride across */
- if(recttridesubr(&r, cr, &rr)){
- rappend(&tmp, rr);
- continue;
- }
-
- /* corner overlap */
- if(rectcornersubr(&r, cr, &rr)){
- rappend(&tmp, rr);
- continue;
- }
- abort();
- }
- if(i == rlist->nrect)
- rappend(rlist, r);
- }
- freerlist(&tmp);
- if(verbose > 5)
- rprint(rlist);
-}
-
-void
-freerlist(Rlist *r)
-{
- free(r->rect);
- tot -= r->maxrect;
- r->nrect = 0;
- r->maxrect = 0;
- r->rect = nil;
-}
-
-static void
-rprint(Rlist *r)
-{
- int i;
-
- fprint(2, "rlist %p:", r);
- for(i=0; i<r->nrect; i++)
- fprint(2, " %R", r->rect[i]);
- fprint(2, "\n");
-}
-
-
-#ifdef REGION_DEBUG
-
-int verbose = 10;
-
-void main(int argc, char * argv[])
-{
- Rectangle r1 = Rect(0, 0, 300, 200);
- Rectangle r2 = Rect(100, 100, 400, 300);
- Rectangle r3 = Rect(200, 100, 500, 300);
- Region reg;
-
- if(initdraw(0, 0, "vncviewer") < 0){
- fprint(2, "%s: initdraw failed: %r\n", argv[0]);
- exits("initdraw");
- }
- region_init(®);
- region_union(®, r1, r1);
- region_union(®, r2, r2);
- region_union(®, r3, r3);
-}
-
-#endif
--- a/sys/src/cmd/vnc/rre.c
+++ /dev/null
@@ -1,549 +1,0 @@
-#include "vnc.h"
-#include "vncs.h"
-
-/*
- * rise and run length encoding, aka rre.
- *
- * the pixel contained in r are subdivided into
- * rectangles of uniform color, each of which
- * is encoded by <color, x, y, w, h>.
- *
- * use raw encoding if it's shorter.
- *
- * for compact rre, use limited size rectangles,
- * which are shorter to encode and therefor give better compression.
- *
- * hextile encoding uses rre encoding on at most 16x16 rectangles tiled
- * across and then down the screen.
- */
-static int encrre(uchar *raw, int stride, int w, int h, int back, int pixb, uchar *buf, int maxr, uchar *done, int (*eqpix)(uchar*, int, int), uchar *(putr)(uchar*, uchar*, int, int, int, int, int, int));
-static int eqpix16(uchar *raw, int p1, int p2);
-static int eqpix32(uchar *raw, int p1, int p2);
-static int eqpix8(uchar *raw, int p1, int p2);
-static int findback(uchar *raw, int stride, int w, int h, int (*eqpix)(uchar*, int, int));
-static uchar* putcorre(uchar *buf, uchar *raw, int p, int pixb, int x, int y, int w, int h);
-static uchar* putrre(uchar *buf, uchar *raw, int p, int pixb, int x, int y, int w, int h);
-static void putpix(Vnc *v, uchar *raw, int p, int pixb);
-static int hexcolors(uchar *raw, int stride, int w, int h, int (*eqpix)(uchar*, int, int), int back, int *fore);
-static uchar *puthexfore(uchar *buf, uchar*, int, int, int x, int y, int w, int h);
-static uchar *puthexcol(uchar *buf, uchar*, int, int, int x, int y, int w, int h);
-static void sendtraw(Vnc *v, uchar *raw, int pixb, int stride, int w, int h);
-
-/*
- * default routine, no compression, just the pixels
- */
-int
-sendraw(Vncs *v, Rectangle r)
-{
- int pixb, stride;
- uchar *raw;
-
- if(!rectinrect(r, v->image->r))
- sysfatal("sending bad rectangle");
-
- pixb = v->bpp >> 3;
- if((pixb << 3) != v->bpp)
- sysfatal("bad pixel math in sendraw");
- stride = v->image->width*sizeof(ulong);
- if(((stride / pixb) * pixb) != stride)
- sysfatal("bad pixel math in sendraw");
- stride /= pixb;
-
- raw = byteaddr(v->image, r.min);
-
- vncwrrect(v, r);
- vncwrlong(v, EncRaw);
- sendtraw(v, raw, pixb, stride, Dx(r), Dy(r));
- return 1;
-}
-
-int
-countraw(Vncs*, Rectangle)
-{
- return 1;
-}
-
-/*
- * grab the image for the entire rectangle,
- * then encode each tile
- */
-int
-sendhextile(Vncs *v, Rectangle r)
-{
- uchar *(*putr)(uchar*, uchar*, int, int, int, int, int, int);
- int (*eq)(uchar*, int, int);
- uchar *raw, *buf, *done, *traw;
- int w, h, stride, pixb, pixlg, nr, bpr, back, fore;
- int sy, sx, th, tw, oback, ofore, k, nc;
-
- h = Dy(r);
- w = Dx(r);
- if(h == 0 || w == 0 || !rectinrect(r, v->image->r))
- sysfatal("bad rectangle %R in sendhextile %R", r, v->image->r);
-
- switch(v->bpp){
- case 8: pixlg = 0; eq = eqpix8; break;
- case 16: pixlg = 1; eq = eqpix16; break;
- case 32: pixlg = 2; eq = eqpix32; break;
- default:
- sendraw(v, r);
- return 1;
- }
- pixb = 1 << pixlg;
- stride = v->image->width*sizeof(ulong);
- if(((stride >> pixlg) << pixlg) != stride){
- sendraw(v, r);
- return 1;
- }
- stride >>= pixlg;
-
- buf = malloc(HextileDim * HextileDim * pixb);
- done = malloc(HextileDim * HextileDim);
- if(buf == nil || done == nil){
- free(buf);
- free(done);
- sendraw(v, r);
- return 1;
- }
- raw = byteaddr(v->image, r.min);
-
- vncwrrect(v, r);
- vncwrlong(v, EncHextile);
- oback = -1;
- ofore = -1;
- for(sy = 0; sy < h; sy += HextileDim){
- th = h - sy;
- if(th > HextileDim)
- th = HextileDim;
- for(sx = 0; sx < w; sx += HextileDim){
- tw = w - sx;
- if(tw > HextileDim)
- tw = HextileDim;
-
- traw = raw + ((sy * stride + sx) << pixlg);
-
- back = findback(traw, stride, tw, th, eq);
- nc = hexcolors(traw, stride, tw, th, eq, back, &fore);
- k = 0;
- if(oback < 0 || !(*eq)(raw, back + ((traw - raw) >> pixlg), oback))
- k |= HextileBack;
- if(nc == 1){
- vncwrchar(v, k);
- if(k & HextileBack){
- oback = back + ((traw - raw) >> pixlg);
- putpix(v, raw, oback, pixb);
- }
- continue;
- }
- k |= HextileRects;
- if(nc == 2){
- putr = puthexfore;
- bpr = 2;
- if(ofore < 0 || !(*eq)(raw, fore + ((traw - raw) >> pixlg), ofore))
- k |= HextileFore;
- }else{
- putr = puthexcol;
- bpr = 2 + pixb;
- k |= HextileCols;
- /* stupid vnc clients smash foreground in this case */
- ofore = -1;
- }
-
- nr = th * tw << pixlg;
- if(k & HextileBack)
- nr -= pixb;
- if(k & HextileFore)
- nr -= pixb;
- nr /= bpr;
- memset(done, 0, HextileDim * HextileDim);
- nr = encrre(traw, stride, tw, th, back, pixb, buf, nr, done, eq, putr);
- if(nr < 0){
- vncwrchar(v, HextileRaw);
- sendtraw(v, traw, pixb, stride, tw, th);
- /* stupid vnc clients smash colors in this case */
- ofore = -1;
- oback = -1;
- }else{
- vncwrchar(v, k);
- if(k & HextileBack){
- oback = back + ((traw - raw) >> pixlg);
- putpix(v, raw, oback, pixb);
- }
- if(k & HextileFore){
- ofore = fore + ((traw - raw) >> pixlg);
- putpix(v, raw, ofore, pixb);
- }
- vncwrchar(v, nr);
- vncwrbytes(v, buf, nr * bpr);
- }
- }
- }
- free(buf);
- free(done);
- return 1;
-}
-
-int
-counthextile(Vncs*, Rectangle)
-{
- return 1;
-}
-
-static int
-hexcolors(uchar *raw, int stride, int w, int h, int (*eqpix)(uchar*, int, int), int back, int *rfore)
-{
- int s, es, sx, esx, fore;
-
- *rfore = -1;
- fore = -1;
- es = stride * h;
- for(s = 0; s < es; s += stride){
- esx = s + w;
- for(sx = s; sx < esx; sx++){
- if((*eqpix)(raw, back, sx))
- continue;
- if(fore < 0){
- fore = sx;
- *rfore = fore;
- }else if(!(*eqpix)(raw, fore, sx))
- return 3;
- }
- }
-
- if(fore < 0)
- return 1;
- return 2;
-}
-
-static uchar*
-puthexcol(uchar *buf, uchar *raw, int p, int pixb, int x, int y, int w, int h)
-{
- raw += p * pixb;
- while(pixb--)
- *buf++ = *raw++;
- *buf++ = (x << 4) | y;
- *buf++ = (w - 1) << 4 | (h - 1);
- return buf;
-}
-
-static uchar*
-puthexfore(uchar *buf, uchar*, int, int, int x, int y, int w, int h)
-{
- *buf++ = (x << 4) | y;
- *buf++ = (w - 1) << 4 | (h - 1);
- return buf;
-}
-
-static void
-sendtraw(Vnc *v, uchar *raw, int pixb, int stride, int w, int h)
-{
- int y;
-
- for(y = 0; y < h; y++)
- vncwrbytes(v, &raw[y * stride * pixb], w * pixb);
-}
-
-static int
-rrerects(Rectangle r, int split)
-{
- return ((Dy(r) + split - 1) / split) * ((Dx(r) + split - 1) / split);
-}
-
-enum
-{
- MaxCorreDim = 48,
- MaxRreDim = 64,
-};
-
-int
-countrre(Vncs*, Rectangle r)
-{
- return rrerects(r, MaxRreDim);
-}
-
-int
-countcorre(Vncs*, Rectangle r)
-{
- return rrerects(r, MaxCorreDim);
-}
-
-static int
-_sendrre(Vncs *v, Rectangle r, int split, int compact)
-{
- uchar *raw, *buf, *done;
- int w, h, stride, pixb, pixlg, nraw, nr, bpr, back, totr;
- int (*eq)(uchar*, int, int);
-
- totr = 0;
- h = Dy(r);
- while(h > split){
- h = r.max.y;
- r.max.y = r.min.y + split;
- totr += _sendrre(v, r, split, compact);
- r.min.y = r.max.y;
- r.max.y = h;
- h = Dy(r);
- }
- w = Dx(r);
- while(w > split){
- w = r.max.x;
- r.max.x = r.min.x + split;
- totr += _sendrre(v, r, split, compact);
- r.min.x = r.max.x;
- r.max.x = w;
- w = Dx(r);
- }
- if(h == 0 || w == 0 || !rectinrect(r, v->image->r))
- sysfatal("bad rectangle in sendrre");
-
- switch(v->bpp){
- case 8: pixlg = 0; eq = eqpix8; break;
- case 16: pixlg = 1; eq = eqpix16; break;
- case 32: pixlg = 2; eq = eqpix32; break;
- default:
- sendraw(v, r);
- return totr + 1;
- }
- pixb = 1 << pixlg;
- stride = v->image->width*sizeof(ulong);
- if(((stride >> pixlg) << pixlg) != stride){
- sendraw(v, r);
- return totr + 1;
- }
- stride >>= pixlg;
-
- nraw = w * pixb * h;
- buf = malloc(nraw);
- done = malloc(w * h);
- if(buf == nil || done == nil){
- free(buf);
- free(done);
- sendraw(v, r);
- return totr + 1;
- }
- memset(done, 0, w * h);
-
- raw = byteaddr(v->image, r.min);
-
- if(compact)
- bpr = 4 * 1 + pixb;
- else
- bpr = 4 * 2 + pixb;
- nr = (nraw - 4 - pixb) / bpr;
- back = findback(raw, stride, w, h, eq);
- if(compact)
- nr = encrre(raw, stride, w, h, back, pixb, buf, nr, done, eq, putcorre);
- else
- nr = encrre(raw, stride, w, h, back, pixb, buf, nr, done, eq, putrre);
- if(nr < 0){
- vncwrrect(v, r);
- vncwrlong(v, EncRaw);
- sendtraw(v, raw, pixb, stride, w, h);
- }else{
- vncwrrect(v, r);
- if(compact)
- vncwrlong(v, EncCorre);
- else
- vncwrlong(v, EncRre);
- vncwrlong(v, nr);
- putpix(v, raw, back, pixb);
- vncwrbytes(v, buf, nr * bpr);
- }
- free(buf);
- free(done);
-
- return totr + 1;
-}
-
-int
-sendrre(Vncs *v, Rectangle r)
-{
- return _sendrre(v, r, MaxRreDim, 0);
-}
-
-int
-sendcorre(Vncs *v, Rectangle r)
-{
- return _sendrre(v, r, MaxCorreDim, 1);
-}
-
-static int
-encrre(uchar *raw, int stride, int w, int h, int back, int pixb, uchar *buf,
- int maxr, uchar *done, int (*eqpix)(uchar*, int, int),
- uchar *(*putr)(uchar*, uchar*, int, int, int, int, int, int))
-{
- int s, es, sx, esx, sy, syx, esyx, rh, rw, y, nr, dsy, dp;
-
- es = stride * h;
- y = 0;
- nr = 0;
- dp = 0;
- for(s = 0; s < es; s += stride){
- esx = s + w;
- for(sx = s; sx < esx; ){
- rw = done[dp];
- if(rw){
- sx += rw;
- dp += rw;
- continue;
- }
- if((*eqpix)(raw, back, sx)){
- sx++;
- dp++;
- continue;
- }
-
- if(nr >= maxr)
- return -1;
-
- /*
- * find the tallest maximally wide uniform colored rectangle
- * with p at the upper left.
- * this isn't an optimal parse, but it's pretty good for text
- */
- rw = esx - sx;
- rh = 0;
- for(sy = sx; sy < es; sy += stride){
- if(!(*eqpix)(raw, sx, sy))
- break;
- esyx = sy + rw;
- for(syx = sy + 1; syx < esyx; syx++){
- if(!(*eqpix)(raw, sx, syx)){
- if(sy == sx)
- break;
- goto breakout;
- }
- }
- if(sy == sx)
- rw = syx - sy;
- rh++;
- }
- breakout:;
-
- nr++;
- buf = (*putr)(buf, raw, sx, pixb, sx - s, y, rw, rh);
-
- /*
- * mark all pixels done
- */
- dsy = dp;
- while(rh--){
- esyx = dsy + rw;
- for(syx = dsy; syx < esyx; syx++)
- done[syx] = esyx - syx;
- dsy += w;
- }
-
- sx += rw;
- dp += rw;
- }
- y++;
- }
- return nr;
-}
-
-/*
- * estimate the background color
- * by finding the most frequent character in a small sample
- */
-static int
-findback(uchar *raw, int stride, int w, int h, int (*eqpix)(uchar*, int, int))
-{
- enum{
- NCol = 6,
- NExamine = 4
- };
- int ccount[NCol], col[NCol], i, wstep, hstep, x, y, pix, c, max, maxc;
-
- wstep = w / NExamine;
- if(wstep < 1)
- wstep = 1;
- hstep = h / NExamine;
- if(hstep < 1)
- hstep = 1;
-
- for(i = 0; i< NCol; i++)
- ccount[i] = 0;
- for(y = 0; y < h; y += hstep){
- for(x = 0; x < w; x += wstep){
- pix = y * stride + x;
- for(i = 0; i < NCol; i++){
- if(ccount[i] == 0){
- ccount[i] = 1;
- col[i] = pix;
- break;
- }
- if((*eqpix)(raw, pix, col[i])){
- ccount[i]++;
- break;
- }
- }
- }
- }
- maxc = ccount[0];
- max = 0;
- for(i = 1; i < NCol; i++){
- c = ccount[i];
- if(!c)
- break;
- if(c > maxc){
- max = i;
- maxc = c;
- }
- }
- return col[max];
-}
-
-static uchar*
-putrre(uchar *buf, uchar *raw, int p, int pixb, int x, int y, int w, int h)
-{
- raw += p * pixb;
- while(pixb--)
- *buf++ = *raw++;
- *buf++ = x >> 8;
- *buf++ = x;
- *buf++ = y >> 8;
- *buf++ = y;
- *buf++ = w >> 8;
- *buf++ = w;
- *buf++ = h >> 8;
- *buf++ = h;
- return buf;
-}
-
-static uchar*
-putcorre(uchar *buf, uchar *raw, int p, int pixb, int x, int y, int w, int h)
-{
- raw += p * pixb;
- while(pixb--)
- *buf++ = *raw++;
- *buf++ = x;
- *buf++ = y;
- *buf++ = w;
- *buf++ = h;
- return buf;
-}
-
-static int
-eqpix8(uchar *raw, int p1, int p2)
-{
- return raw[p1] == raw[p2];
-}
-
-static int
-eqpix16(uchar *raw, int p1, int p2)
-{
- return ((ushort*)raw)[p1] == ((ushort*)raw)[p2];
-}
-
-static int
-eqpix32(uchar *raw, int p1, int p2)
-{
- return ((ulong*)raw)[p1] == ((ulong*)raw)[p2];
-}
-
-static void
-putpix(Vnc *v, uchar *raw, int p, int pixb)
-{
- vncwrbytes(v, raw + p * pixb, pixb);
-}
--- a/sys/src/cmd/vnc/screen.c
+++ /dev/null
@@ -1,347 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "compat.h"
-#include "kbd.h"
-#include "error.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-enum
-{
- CURSORDIM = 16
-};
-
-Memimage *gscreen;
-Point ZP;
-int cursorver;
-Point cursorpos;
-
-static Memimage *back;
-static Memimage *conscol;
-static Memimage *curscol;
-static Point curpos;
-static Memsubfont *memdefont;
-static Rectangle flushr;
-static Rectangle window;
-static int h;
-static int w;
-
-static Rectangle cursorr;
-static Point offscreen;
-static uchar cursset[CURSORDIM*CURSORDIM/8];
-static uchar cursclr[CURSORDIM*CURSORDIM/8];
-static int cursdrawvers = -1;
-static Memimage *cursorset;
-static Memimage *cursorclear;
-static Cursor screencursor;
-
-void
-screeninit(int x, int y, char *chanstr)
-{
- char buf[128];
- Rectangle r;
- int chan;
-
- cursorver = 0;
-
- memimageinit();
- chan = strtochan(chanstr);
- if(chan == 0)
- error("bad screen channel string");
-
- r = Rect(0, 0, x, y);
- gscreen = allocmemimage(r, chan);
- if(gscreen == nil){
- snprint(buf, sizeof buf, "can't allocate screen image: %r");
- error(buf);
- }
-
- offscreen = Pt(x + 100, y + 100);
- cursorr = Rect(0, 0, CURSORDIM, CURSORDIM);
- cursorset = allocmemimage(cursorr, GREY8);
- cursorclear = allocmemimage(cursorr, GREY1);
- if(cursorset == nil || cursorclear == nil){
- freememimage(gscreen);
- freememimage(cursorset);
- freememimage(cursorclear);
- gscreen = nil;
- cursorset = nil;
- cursorclear = nil;
- snprint(buf, sizeof buf, "can't allocate cursor images: %r");
- error(buf);
- }
-
- /* a lot of work to get a grey color */
- curscol = allocmemimage(Rect(0,0,1,1), RGBA32);
- curscol->flags |= Frepl;
- curscol->clipr = gscreen->r;
- memfillcolor(curscol, 0xff0000ff);
-
- screenwin();
-
- setcursor(&arrow);
-}
-
-void
-screenwin(void)
-{
- Point p;
- char *greet;
- Memimage *grey;
-
- qlock(&drawlock);
- back = memwhite;
- conscol = memblack;
- memfillcolor(gscreen, 0x888844FF);
-
- memdefont = getmemdefont();
- h = memdefont->height;
-
- window = insetrect(gscreen->clipr, 20);
- memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
- window = insetrect(window, 4);
- memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
-
- /* a lot of work to get a grey color */
- grey = allocmemimage(Rect(0,0,1,1), CMAP8);
- grey->flags |= Frepl;
- grey->clipr = gscreen->r;
- memfillcolor(grey, 0xAAAAAAFF);
- memimagedraw(gscreen, Rect(window.min.x, window.min.y,
- window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
- freememimage(grey);
- window = insetrect(window, 5);
-
- greet = " Plan 9 Console ";
- p = addpt(window.min, Pt(10, 0));
- memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
- window.min.y += h+6;
- curpos = window.min;
- window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
- flushmemscreen(gscreen->r);
- qunlock(&drawlock);
-}
-
-Memdata*
-attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
-{
- *r = gscreen->clipr;
- *d = gscreen->depth;
- *chan = gscreen->chan;
- *width = gscreen->width;
- *softscreen = 1;
-
- gscreen->data->ref++;
- return gscreen->data;
-}
-
-void
-getcolor(ulong , ulong* pr, ulong* pg, ulong* pb)
-{
- *pr = 0;
- *pg = 0;
- *pb = 0;
-}
-
-int
-setcolor(ulong , ulong , ulong , ulong )
-{
- return 0;
-}
-
-/*
- * called with cursor unlocked, drawlock locked
- */
-void
-cursordraw(Memimage *dst, Rectangle r)
-{
- static uchar set[CURSORDIM*CURSORDIM], clr[CURSORDIM*CURSORDIM/8];
- static int ver = -1;
- int i, j, n;
-
- lock(&cursor);
- if(ver != cursorver){
- n = 0;
- for(i = 0; i < CURSORDIM*CURSORDIM/8; i += CURSORDIM/8){
- for(j = 0; j < CURSORDIM; j++){
- if(cursset[i + (j >> 3)] & (1 << (7 - (j & 7))))
- set[n] = 0xaa;
- else
- set[n] = 0;
- n++;
- }
- }
- memmove(clr, cursclr, CURSORDIM*CURSORDIM/8);
- ver = cursorver;
- unlock(&cursor);
- loadmemimage(cursorset, cursorr, set, CURSORDIM*CURSORDIM);
- loadmemimage(cursorclear, cursorr, clr, CURSORDIM*CURSORDIM/8);
- }else
- unlock(&cursor);
- memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP, SoverD);
- memimagedraw(dst, r, curscol, ZP, cursorset, ZP, SoverD);
-}
-
-/*
- * called with cursor locked, drawlock possibly unlocked
- */
-Rectangle
-cursorrect(void)
-{
- Rectangle r;
-
- r.min.x = cursorpos.x + cursor.offset.x;
- r.min.y = cursorpos.y + cursor.offset.y;
- r.max.x = r.min.x + CURSORDIM;
- r.max.y = r.min.y + CURSORDIM;
- return r;
-}
-
-/*
- * called with cursor locked, drawlock possibly unlocked
- */
-void
-setcursor(Cursor* curs)
-{
- cursorver++;
- memmove(cursset, curs->set, CURSORDIM*CURSORDIM/8);
- memmove(cursclr, curs->clr, CURSORDIM*CURSORDIM/8);
-}
-
-void
-cursoron(void)
-{
- cursorpos = mousexy();
-}
-
-void
-cursoroff(void)
-{
- cursorpos = offscreen;
-}
-
-void
-blankscreen(int blank)
-{
- USED(blank);
-}
-
-static void
-screenflush(void)
-{
- flushmemscreen(flushr);
- flushr = Rect(10000, 10000, -10000, -10000);
-}
-
-static void
-addflush(Rectangle r)
-{
- if(flushr.min.x >= flushr.max.x)
- flushr = r;
- else
- combinerect(&flushr, r);
-}
-
-static void
-scroll(void)
-{
- int o;
- Point p;
- Rectangle r;
-
- o = 8*h;
- r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
- p = Pt(window.min.x, window.min.y+o);
- memimagedraw(gscreen, r, gscreen, p, nil, p, S);
- r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
- memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
- flushmemscreen(gscreen->clipr);
-
- curpos.y -= o;
-}
-
-static void
-screenputc(char *buf)
-{
- Point p;
- int w, pos;
- Rectangle r;
- static int *xp;
- static int xbuf[256];
-
- if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
- xp = xbuf;
-
- switch(buf[0]){
- case '\n':
- if(curpos.y+h >= window.max.y)
- scroll();
- curpos.y += h;
- screenputc("\r");
- break;
- case '\r':
- xp = xbuf;
- curpos.x = window.min.x;
- break;
- case '\t':
- p = memsubfontwidth(memdefont, " ");
- w = p.x;
- *xp++ = curpos.x;
- pos = (curpos.x-window.min.x)/w;
- pos = 8-(pos%8);
- r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
- addflush(r);
- curpos.x += pos*w;
- break;
- case '\b':
- if(xp <= xbuf)
- break;
- xp--;
- r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
- addflush(r);
- curpos.x = *xp;
- break;
- case '\0':
- break;
- default:
- p = memsubfontwidth(memdefont, buf);
- w = p.x;
-
- if(curpos.x >= window.max.x-w)
- screenputc("\n");
-
- *xp++ = curpos.x;
- r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
- memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
- memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
- addflush(r);
- curpos.x += w;
- }
-}
-
-void
-screenputs(char *s, int n)
-{
- static char rb[UTFmax+1];
- static int nrb;
- char *e;
-
- qlock(&drawlock);
- e = s + n;
- while(s < e){
- rb[nrb++] = *s++;
- if(nrb >= UTFmax || fullrune(rb, nrb)){
- rb[nrb] = 0;
- screenputc(rb);
- nrb = 0;
- }
- }
- screenflush();
- qunlock(&drawlock);
-}
--- a/sys/src/cmd/vnc/screen.h
+++ /dev/null
@@ -1,37 +1,0 @@
-typedef struct Cursor Cursor;
-typedef struct Cursorinfo Cursorinfo;
-struct Cursorinfo {
- Cursor;
- Lock;
-};
-
-extern Cursorinfo cursor;
-extern Cursor arrow;
-extern Memimage *gscreen;
-extern int cursorver;
-extern Point cursorpos;
-
-void mouseresize(void);
-Point mousexy(void);
-void cursoron(void);
-void cursoroff(void);
-void setcursor(Cursor*);
-void flushmemscreen(Rectangle r);
-Rectangle cursorrect(void);
-void cursordraw(Memimage *dst, Rectangle r);
-
-extern QLock drawlock;
-void drawactive(int);
-void getcolor(ulong, ulong*, ulong*, ulong*);
-int setcolor(ulong, ulong, ulong, ulong);
-#define TK2SEC(x) 0
-extern void blankscreen(int);
-void screeninit(int x, int y, char *chanstr);
-void screenwin(void);
-void absmousetrack(int x, int y, int b, ulong msec);
-Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*);
-void deletescreenimage(void);
-void resetscreenimage(void);
-
-void fsinit(char *mntpt, int x, int y, char *chanstr);
-#define ishwimage(i) 0
--- a/sys/src/cmd/vnc/utf2ksym.h
+++ /dev/null
@@ -1,1073 +1,0 @@
-/*
- * VNC uses X11's keysyms defined in X11/keysym.h, this is a converter
- * from unicode characters to ksyms that other servers use.
- */
-static ulong
-utf2ksym [] = {
- [L'Ą'] 0x1a1,
- [L'˘'] 0x1a2,
- [L'Ł'] 0x1a3,
- [L'Ľ'] 0x1a5,
- [L'Ś'] 0x1a6,
- [L'Š'] 0x1a9,
- [L'Ş'] 0x1aa,
- [L'Ť'] 0x1ab,
- [L'Ź'] 0x1ac,
- [L'Ž'] 0x1ae,
- [L'Ż'] 0x1af,
- [L'ą'] 0x1b1,
- [L'˛'] 0x1b2,
- [L'ł'] 0x1b3,
- [L'ľ'] 0x1b5,
- [L'ś'] 0x1b6,
- [L'ˇ'] 0x1b7,
- [L'š'] 0x1b9,
- [L'ş'] 0x1ba,
- [L'ť'] 0x1bb,
- [L'ź'] 0x1bc,
- [L'˝'] 0x1bd,
- [L'ž'] 0x1be,
- [L'ż'] 0x1bf,
- [L'Ŕ'] 0x1c0,
- [L'Ă'] 0x1c3,
- [L'Ĺ'] 0x1c5,
- [L'Ć'] 0x1c6,
- [L'Č'] 0x1c8,
- [L'Ę'] 0x1ca,
- [L'Ě'] 0x1cc,
- [L'Ď'] 0x1cf,
- [L'Đ'] 0x1d0,
- [L'Ń'] 0x1d1,
- [L'Ň'] 0x1d2,
- [L'Ő'] 0x1d5,
- [L'Ř'] 0x1d8,
- [L'Ů'] 0x1d9,
- [L'Ű'] 0x1db,
- [L'Ţ'] 0x1de,
- [L'ŕ'] 0x1e0,
- [L'ă'] 0x1e3,
- [L'ĺ'] 0x1e5,
- [L'ć'] 0x1e6,
- [L'č'] 0x1e8,
- [L'ę'] 0x1ea,
- [L'ě'] 0x1ec,
- [L'ď'] 0x1ef,
- [L'đ'] 0x1f0,
- [L'ń'] 0x1f1,
- [L'ň'] 0x1f2,
- [L'ő'] 0x1f5,
- [L'ř'] 0x1f8,
- [L'ů'] 0x1f9,
- [L'ű'] 0x1fb,
- [L'ţ'] 0x1fe,
- [L'˙'] 0x1ff,
- [L'Ħ'] 0x2a1,
- [L'Ĥ'] 0x2a6,
- [L'İ'] 0x2a9,
- [L'Ğ'] 0x2ab,
- [L'Ĵ'] 0x2ac,
- [L'ħ'] 0x2b1,
- [L'ĥ'] 0x2b6,
- [L'ı'] 0x2b9,
- [L'ğ'] 0x2bb,
- [L'ĵ'] 0x2bc,
- [L'Ċ'] 0x2c5,
- [L'Ĉ'] 0x2c6,
- [L'Ġ'] 0x2d5,
- [L'Ĝ'] 0x2d8,
- [L'Ŭ'] 0x2dd,
- [L'Ŝ'] 0x2de,
- [L'ċ'] 0x2e5,
- [L'ĉ'] 0x2e6,
- [L'ġ'] 0x2f5,
- [L'ĝ'] 0x2f8,
- [L'ŭ'] 0x2fd,
- [L'ŝ'] 0x2fe,
- [L'ĸ'] 0x3a2,
- [L'Ŗ'] 0x3a3,
- [L'Ĩ'] 0x3a5,
- [L'Ļ'] 0x3a6,
- [L'Ē'] 0x3aa,
- [L'Ģ'] 0x3ab,
- [L'Ŧ'] 0x3ac,
- [L'ŗ'] 0x3b3,
- [L'ĩ'] 0x3b5,
- [L'ļ'] 0x3b6,
- [L'ē'] 0x3ba,
- [L'ģ'] 0x3bb,
- [L'ŧ'] 0x3bc,
- [L'Ŋ'] 0x3bd,
- [L'ŋ'] 0x3bf,
- [L'Ā'] 0x3c0,
- [L'Į'] 0x3c7,
- [L'Ė'] 0x3cc,
- [L'Ī'] 0x3cf,
- [L'Ņ'] 0x3d1,
- [L'Ō'] 0x3d2,
- [L'Ķ'] 0x3d3,
- [L'Ų'] 0x3d9,
- [L'Ũ'] 0x3dd,
- [L'Ū'] 0x3de,
- [L'ā'] 0x3e0,
- [L'į'] 0x3e7,
- [L'ė'] 0x3ec,
- [L'ī'] 0x3ef,
- [L'ņ'] 0x3f1,
- [L'ō'] 0x3f2,
- [L'ķ'] 0x3f3,
- [L'ų'] 0x3f9,
- [L'ũ'] 0x3fd,
- [L'ū'] 0x3fe,
- [L'。'] 0x4a1,
- [L'〈'] 0x4a2,
- [L'〉'] 0x4a3,
- [L'、'] 0x4a4,
- [L'・'] 0x4a5,
- [L'ヲ'] 0x4a6,
- [L'ァ'] 0x4a7,
- [L'ィ'] 0x4a8,
- [L'ゥ'] 0x4a9,
- [L'ェ'] 0x4aa,
- [L'ォ'] 0x4ab,
- [L'ャ'] 0x4ac,
- [L'ュ'] 0x4ad,
- [L'ョ'] 0x4ae,
- [L'ッ'] 0x4af,
- [L'ー'] 0x4b0,
- [L'ア'] 0x4b1,
- [L'イ'] 0x4b2,
- [L'ウ'] 0x4b3,
- [L'エ'] 0x4b4,
- [L'オ'] 0x4b5,
- [L'カ'] 0x4b6,
- [L'キ'] 0x4b7,
- [L'ク'] 0x4b8,
- [L'ケ'] 0x4b9,
- [L'コ'] 0x4ba,
- [L'サ'] 0x4bb,
- [L'シ'] 0x4bc,
- [L'ス'] 0x4bd,
- [L'セ'] 0x4be,
- [L'ソ'] 0x4bf,
- [L'タ'] 0x4c0,
- [L'チ'] 0x4c1,
- [L'ツ'] 0x4c2,
- [L'テ'] 0x4c3,
- [L'ト'] 0x4c4,
- [L'ナ'] 0x4c5,
- [L'ニ'] 0x4c6,
- [L'ヌ'] 0x4c7,
- [L'ネ'] 0x4c8,
- [L'ノ'] 0x4c9,
- [L'ハ'] 0x4ca,
- [L'ヒ'] 0x4cb,
- [L'フ'] 0x4cc,
- [L'ヘ'] 0x4cd,
- [L'ホ'] 0x4ce,
- [L'マ'] 0x4cf,
- [L'ミ'] 0x4d0,
- [L'ム'] 0x4d1,
- [L'メ'] 0x4d2,
- [L'モ'] 0x4d3,
- [L'ヤ'] 0x4d4,
- [L'ユ'] 0x4d5,
- [L'ヨ'] 0x4d6,
- [L'ラ'] 0x4d7,
- [L'リ'] 0x4d8,
- [L'ル'] 0x4d9,
- [L'レ'] 0x4da,
- [L'ロ'] 0x4db,
- [L'ワ'] 0x4dc,
- [L'ン'] 0x4dd,
- [L'゛'] 0x4de,
- [L'゜'] 0x4df,
- [L'۰'] 0x10006f0,
- [L'۱'] 0x10006f1,
- [L'۲'] 0x10006f2,
- [L'۳'] 0x10006f3,
- [L'۴'] 0x10006f4,
- [L'۵'] 0x10006f5,
- [L'۶'] 0x10006f6,
- [L'۷'] 0x10006f7,
- [L'۸'] 0x10006f8,
- [L'۹'] 0x10006f9,
- [L'٪'] 0x5a5,
- [L'ٰ'] 0x5a6,
- [L'ٹ'] 0x5a7,
- [L'پ'] 0x100067e,
- [L'چ'] 0x1000686,
- [L'ڈ'] 0x5aa,
- [L'ڑ'] 0x5ab,
- [L'،'] 0x5ac,
- [L'۔'] 0x5ae,
- [L'٠'] 0x5b0,
- [L'١'] 0x5b1,
- [L'٢'] 0x5b2,
- [L'٣'] 0x5b3,
- [L'٤'] 0x5b4,
- [L'٥'] 0x5b5,
- [L'٦'] 0x5b6,
- [L'٧'] 0x5b7,
- [L'٨'] 0x5b8,
- [L'٩'] 0x5b9,
- [L'؛'] 0x5bb,
- [L'؟'] 0x5bf,
- [L'ء'] 0x5c1,
- [L'آ'] 0x5c2,
- [L'أ'] 0x5c3,
- [L'ؤ'] 0x5c4,
- [L'إ'] 0x5c5,
- [L'ئ'] 0x5c6,
- [L'ا'] 0x5c7,
- [L'ب'] 0x5c8,
- [L'ة'] 0x5c9,
- [L'ت'] 0x5ca,
- [L'ث'] 0x5cb,
- [L'ج'] 0x5cc,
- [L'ح'] 0x5cd,
- [L'خ'] 0x5ce,
- [L'د'] 0x5cf,
- [L'ذ'] 0x5d0,
- [L'ر'] 0x5d1,
- [L'ز'] 0x5d2,
- [L'س'] 0x5d3,
- [L'ش'] 0x5d4,
- [L'ص'] 0x5d5,
- [L'ض'] 0x5d6,
- [L'ط'] 0x5d7,
- [L'ظ'] 0x5d8,
- [L'ع'] 0x5d9,
- [L'غ'] 0x5da,
- [L'ـ'] 0x5e0,
- [L'ف'] 0x5e1,
- [L'ق'] 0x5e2,
- [L'ك'] 0x5e3,
- [L'ل'] 0x5e4,
- [L'م'] 0x5e5,
- [L'ن'] 0x5e6,
- [L'ه'] 0x5e7,
- [L'و'] 0x5e8,
- [L'ى'] 0x5e9,
- [L'ي'] 0x5ea,
- [L'ً'] 0x5eb,
- [L'ٌ'] 0x5ec,
- [L'ٍ'] 0x5ed,
- [L'َ'] 0x5ee,
- [L'ُ'] 0x5ef,
- [L'ِ'] 0x5f0,
- [L'ّ'] 0x5f1,
- [L'ْ'] 0x5f2,
- [L'ٓ'] 0x5f3,
- [L'ٔ'] 0x5f4,
- [L'ٕ'] 0x5f5,
- [L'ژ'] 0x1000698,
- [L'ڤ'] 0x5f7,
- [L'ک'] 0x10006a9,
- [L'گ'] 0x10006af,
- [L'ں'] 0x5fa,
- [L'ھ'] 0x5fb,
- [L'ی'] 0x10006cc,
- [L'ے'] 0x5fd,
- [L'ہ'] 0x5fe,
- [L'Ғ'] 0x680,
- [L'Җ'] 0x681,
- [L'Қ'] 0x682,
- [L'Ҝ'] 0x683,
- [L'Ң'] 0x684,
- [L'Ү'] 0x685,
- [L'Ұ'] 0x686,
- [L'Ҳ'] 0x687,
- [L'Ҷ'] 0x688,
- [L'Ҹ'] 0x689,
- [L'Һ'] 0x68a,
- [L'Ә'] 0x68c,
- [L'Ӣ'] 0x68d,
- [L'Ө'] 0x68e,
- [L'Ӯ'] 0x68f,
- [L'ғ'] 0x690,
- [L'җ'] 0x691,
- [L'қ'] 0x692,
- [L'ҝ'] 0x693,
- [L'ң'] 0x694,
- [L'ү'] 0x695,
- [L'ұ'] 0x696,
- [L'ҳ'] 0x697,
- [L'ҷ'] 0x698,
- [L'ҹ'] 0x699,
- [L'һ'] 0x69a,
- [L'ә'] 0x69c,
- [L'ӣ'] 0x69d,
- [L'ө'] 0x69e,
- [L'ӯ'] 0x69f,
- [L'ђ'] 0x6a1,
- [L'ѓ'] 0x6a2,
- [L'ё'] 0x6a3,
- [L'є'] 0x6a4,
- [L'ѕ'] 0x6a5,
- [L'і'] 0x6a6,
- [L'ї'] 0x6a7,
- [L'ј'] 0x6a8,
- [L'љ'] 0x6a9,
- [L'њ'] 0x6aa,
- [L'ћ'] 0x6ab,
- [L'ќ'] 0x6ac,
- [L'ґ'] 0x6ad,
- [L'ў'] 0x6ae,
- [L'џ'] 0x6af,
- [L'№'] 0x6b0,
- [L'Ђ'] 0x6b1,
- [L'Ѓ'] 0x6b2,
- [L'Ё'] 0x6b3,
- [L'Є'] 0x6b4,
- [L'Ѕ'] 0x6b5,
- [L'І'] 0x6b6,
- [L'Ї'] 0x6b7,
- [L'Ј'] 0x6b8,
- [L'Љ'] 0x6b9,
- [L'Њ'] 0x6ba,
- [L'Ћ'] 0x6bb,
- [L'Ќ'] 0x6bc,
- [L'Ґ'] 0x6bd,
- [L'Ў'] 0x6be,
- [L'Џ'] 0x6bf,
- [L'ю'] 0x6c0,
- [L'а'] 0x6c1,
- [L'б'] 0x6c2,
- [L'ц'] 0x6c3,
- [L'д'] 0x6c4,
- [L'е'] 0x6c5,
- [L'ф'] 0x6c6,
- [L'г'] 0x6c7,
- [L'х'] 0x6c8,
- [L'и'] 0x6c9,
- [L'й'] 0x6ca,
- [L'к'] 0x6cb,
- [L'л'] 0x6cc,
- [L'м'] 0x6cd,
- [L'н'] 0x6ce,
- [L'о'] 0x6cf,
- [L'п'] 0x6d0,
- [L'я'] 0x6d1,
- [L'р'] 0x6d2,
- [L'с'] 0x6d3,
- [L'т'] 0x6d4,
- [L'у'] 0x6d5,
- [L'ж'] 0x6d6,
- [L'в'] 0x6d7,
- [L'ь'] 0x6d8,
- [L'ы'] 0x6d9,
- [L'з'] 0x6da,
- [L'ш'] 0x6db,
- [L'э'] 0x6dc,
- [L'щ'] 0x6dd,
- [L'ч'] 0x6de,
- [L'ъ'] 0x6df,
- [L'Ю'] 0x6e0,
- [L'А'] 0x6e1,
- [L'Б'] 0x6e2,
- [L'Ц'] 0x6e3,
- [L'Д'] 0x6e4,
- [L'Е'] 0x6e5,
- [L'Ф'] 0x6e6,
- [L'Г'] 0x6e7,
- [L'Х'] 0x6e8,
- [L'И'] 0x6e9,
- [L'Й'] 0x6ea,
- [L'К'] 0x6eb,
- [L'Л'] 0x6ec,
- [L'М'] 0x6ed,
- [L'Н'] 0x6ee,
- [L'О'] 0x6ef,
- [L'П'] 0x6f0,
- [L'Я'] 0x6f1,
- [L'Р'] 0x6f2,
- [L'С'] 0x6f3,
- [L'Т'] 0x6f4,
- [L'У'] 0x6f5,
- [L'Ж'] 0x6f6,
- [L'В'] 0x6f7,
- [L'Ь'] 0x6f8,
- [L'Ы'] 0x6f9,
- [L'З'] 0x6fa,
- [L'Ш'] 0x6fb,
- [L'Э'] 0x6fc,
- [L'Щ'] 0x6fd,
- [L'Ч'] 0x6fe,
- [L'Ъ'] 0x6ff,
- [L'Ά'] 0x7a1,
- [L'Έ'] 0x7a2,
- [L'Ή'] 0x7a3,
- [L'Ί'] 0x7a4,
- [L'Ϊ'] 0x7a5,
- [L'Ό'] 0x7a7,
- [L'Ύ'] 0x7a8,
- [L'Ϋ'] 0x7a9,
- [L'Ώ'] 0x7ab,
- [L'΅'] 0x7ae,
- [L'―'] 0x7af,
- [L'ά'] 0x7b1,
- [L'έ'] 0x7b2,
- [L'ή'] 0x7b3,
- [L'ί'] 0x7b4,
- [L'ϊ'] 0x7b5,
- [L'ΐ'] 0x7b6,
- [L'ό'] 0x7b7,
- [L'ύ'] 0x7b8,
- [L'ϋ'] 0x7b9,
- [L'ΰ'] 0x7ba,
- [L'ώ'] 0x7bb,
- [L'Α'] 0x7c1,
- [L'Β'] 0x7c2,
- [L'Γ'] 0x7c3,
- [L'Δ'] 0x7c4,
- [L'Ε'] 0x7c5,
- [L'Ζ'] 0x7c6,
- [L'Η'] 0x7c7,
- [L'Θ'] 0x7c8,
- [L'Ι'] 0x7c9,
- [L'Κ'] 0x7ca,
- [L'Λ'] 0x7cb,
- [L'Μ'] 0x7cc,
- [L'Ν'] 0x7cd,
- [L'Ξ'] 0x7ce,
- [L'Ο'] 0x7cf,
- [L'Π'] 0x7d0,
- [L'Ρ'] 0x7d1,
- [L'Σ'] 0x7d2,
- [L'Τ'] 0x7d4,
- [L'Υ'] 0x7d5,
- [L'Φ'] 0x7d6,
- [L'Χ'] 0x7d7,
- [L'Ψ'] 0x7d8,
- [L'Ω'] 0x7d9,
- [L'α'] 0x7e1,
- [L'β'] 0x7e2,
- [L'γ'] 0x7e3,
- [L'δ'] 0x7e4,
- [L'ε'] 0x7e5,
- [L'ζ'] 0x7e6,
- [L'η'] 0x7e7,
- [L'θ'] 0x7e8,
- [L'ι'] 0x7e9,
- [L'κ'] 0x7ea,
- [L'λ'] 0x7eb,
- [L'μ'] 0x7ec,
- [L'ν'] 0x7ed,
- [L'ξ'] 0x7ee,
- [L'ο'] 0x7ef,
- [L'π'] 0x7f0,
- [L'ρ'] 0x7f1,
- [L'σ'] 0x7f2,
- [L'ς'] 0x7f3,
- [L'τ'] 0x7f4,
- [L'υ'] 0x7f5,
- [L'φ'] 0x7f6,
- [L'χ'] 0x7f7,
- [L'ψ'] 0x7f8,
- [L'ω'] 0x7f9,
- [L'⌠'] 0x8a4,
- [L'⌡'] 0x8a5,
- [L'⌜'] 0x8a7,
- [L'⌝'] 0x8a8,
- [L'⌞'] 0x8a9,
- [L'⌟'] 0x8aa,
- [L'≤'] 0x8bc,
- [L'≠'] 0x8bd,
- [L'≥'] 0x8be,
- [L'∫'] 0x8bf,
- [L'∴'] 0x8c0,
- [L'∞'] 0x8c2,
- [L'∇'] 0x8c5,
- [L'≅'] 0x8c8,
- [L'≆'] 0x8c9,
- [L'⊢'] 0x8ce,
- [L'√'] 0x8d6,
- [L'⊂'] 0x8da,
- [L'⊃'] 0x8db,
- [L'∩'] 0x8dc,
- [L'∪'] 0x8dd,
- [L'∧'] 0x8de,
- [L'∨'] 0x8df,
- [L'ƒ'] 0x8f6,
- [L'←'] 0x8fb,
- [L'↑'] 0x8fc,
- [L'→'] 0x8fd,
- [L'↓'] 0x8fe,
- [L'␢'] 0x9df,
- [L'♦'] 0x9e0,
- [L'▦'] 0x9e1,
- [L'␉'] 0x9e2,
- [L'␌'] 0x9e3,
- [L'␍'] 0x9e4,
- [L'␊'] 0x9e5,
- [L'␋'] 0x9e9,
- [L'┘'] 0x9ea,
- [L'┐'] 0x9eb,
- [L'┌'] 0x9ec,
- [L'└'] 0x9ed,
- [L'┼'] 0x9ee,
- [L'─'] 0x9ef,
- [L'├'] 0x9f4,
- [L'┤'] 0x9f5,
- [L'┴'] 0x9f6,
- [L'┬'] 0x9f7,
- [L'│'] 0x9f8,
- [L' '] 0xaa1,
- [L' '] 0xaa2,
- [L' '] 0xaa3,
- [L' '] 0xaa4,
- [L' '] 0xaa5,
- [L' '] 0xaa6,
- [L' '] 0xaa7,
- [L' '] 0xaa8,
- [L'—'] 0xaa9,
- [L'–'] 0xaaa,
- [L'…'] 0xaae,
- [L'‥'] 0xaaf,
- [L'⅓'] 0xab0,
- [L'⅔'] 0xab1,
- [L'⅕'] 0xab2,
- [L'⅖'] 0xab3,
- [L'⅗'] 0xab4,
- [L'⅘'] 0xab5,
- [L'⅙'] 0xab6,
- [L'⅚'] 0xab7,
- [L'℅'] 0xab8,
- [L'‒'] 0xabb,
- [L'‹'] 0xabc,
- [L'․'] 0xabd,
- [L'›'] 0xabe,
- [L'⅛'] 0xac3,
- [L'⅜'] 0xac4,
- [L'⅝'] 0xac5,
- [L'⅞'] 0xac6,
- [L'™'] 0xac9,
- [L'℠'] 0xaca,
- [L'◁'] 0xacc,
- [L'▷'] 0xacd,
- [L'○'] 0xace,
- [L'▭'] 0xacf,
- [L'‘'] 0xad0,
- [L'’'] 0xad1,
- [L'“'] 0xad2,
- [L'”'] 0xad3,
- [L'℞'] 0xad4,
- [L'′'] 0xad6,
- [L'″'] 0xad7,
- [L'✝'] 0xad9,
- [L'∎'] 0xadb,
- [L'◂'] 0xadc,
- [L'‣'] 0xadd,
- [L'●'] 0xade,
- [L'▬'] 0xadf,
- [L'◦'] 0xae0,
- [L'▫'] 0xae1,
- [L'▮'] 0xae2,
- [L'▵'] 0xae3,
- [L'▿'] 0xae4,
- [L'☆'] 0xae5,
- [L'•'] 0xae6,
- [L'▪'] 0xae7,
- [L'▴'] 0xae8,
- [L'▾'] 0xae9,
- [L'☚'] 0xaea,
- [L'☛'] 0xaeb,
- [L'♣'] 0xaec,
- [L'♥'] 0xaee,
- [L'✠'] 0xaf0,
- [L'†'] 0xaf1,
- [L'‡'] 0xaf2,
- [L'✓'] 0xaf3,
- [L'☒'] 0xaf4,
- [L'♯'] 0xaf5,
- [L'♭'] 0xaf6,
- [L'♂'] 0xaf7,
- [L'♀'] 0xaf8,
- [L'℡'] 0xaf9,
- [L'⌕'] 0xafa,
- [L'℗'] 0xafb,
- [L'‸'] 0xafc,
- [L'‚'] 0xafd,
- [L'„'] 0xafe,
- [L'‗'] 0xcdf,
- [L'א'] 0xce0,
- [L'ב'] 0xce1,
- [L'ג'] 0xce2,
- [L'ד'] 0xce3,
- [L'ה'] 0xce4,
- [L'ו'] 0xce5,
- [L'ז'] 0xce6,
- [L'ח'] 0xce7,
- [L'ט'] 0xce8,
- [L'י'] 0xce9,
- [L'ך'] 0xcea,
- [L'כ'] 0xceb,
- [L'ל'] 0xcec,
- [L'ם'] 0xced,
- [L'מ'] 0xcee,
- [L'ן'] 0xcef,
- [L'נ'] 0xcf0,
- [L'ס'] 0xcf1,
- [L'ע'] 0xcf2,
- [L'ף'] 0xcf3,
- [L'פ'] 0xcf4,
- [L'ץ'] 0xcf5,
- [L'צ'] 0xcf6,
- [L'ק'] 0xcf7,
- [L'ר'] 0xcf8,
- [L'ש'] 0xcf9,
- [L'ת'] 0xcfa,
- [L'ก'] 0xda1,
- [L'ข'] 0xda2,
- [L'ฃ'] 0xda3,
- [L'ค'] 0xda4,
- [L'ฅ'] 0xda5,
- [L'ฆ'] 0xda6,
- [L'ง'] 0xda7,
- [L'จ'] 0xda8,
- [L'ฉ'] 0xda9,
- [L'ช'] 0xdaa,
- [L'ซ'] 0xdab,
- [L'ฌ'] 0xdac,
- [L'ญ'] 0xdad,
- [L'ฎ'] 0xdae,
- [L'ฏ'] 0xdaf,
- [L'ฐ'] 0xdb0,
- [L'ฑ'] 0xdb1,
- [L'ฒ'] 0xdb2,
- [L'ณ'] 0xdb3,
- [L'ด'] 0xdb4,
- [L'ต'] 0xdb5,
- [L'ถ'] 0xdb6,
- [L'ท'] 0xdb7,
- [L'ธ'] 0xdb8,
- [L'น'] 0xdb9,
- [L'บ'] 0xdba,
- [L'ป'] 0xdbb,
- [L'ผ'] 0xdbc,
- [L'ฝ'] 0xdbd,
- [L'พ'] 0xdbe,
- [L'ฟ'] 0xdbf,
- [L'ภ'] 0xdc0,
- [L'ม'] 0xdc1,
- [L'ย'] 0xdc2,
- [L'ร'] 0xdc3,
- [L'ฤ'] 0xdc4,
- [L'ล'] 0xdc5,
- [L'ฦ'] 0xdc6,
- [L'ว'] 0xdc7,
- [L'ศ'] 0xdc8,
- [L'ษ'] 0xdc9,
- [L'ส'] 0xdca,
- [L'ห'] 0xdcb,
- [L'ฬ'] 0xdcc,
- [L'อ'] 0xdcd,
- [L'ฮ'] 0xdce,
- [L'ฯ'] 0xdcf,
- [L'ะ'] 0xdd0,
- [L'ั'] 0xdd1,
- [L'า'] 0xdd2,
- [L'ำ'] 0xdd3,
- [L'ิ'] 0xdd4,
- [L'ี'] 0xdd5,
- [L'ึ'] 0xdd6,
- [L'ื'] 0xdd7,
- [L'ุ'] 0xdd8,
- [L'ู'] 0xdd9,
- [L'ฺ'] 0xdda,
- [L''] 0xdde,
- [L'฿'] 0xddf,
- [L'เ'] 0xde0,
- [L'แ'] 0xde1,
- [L'โ'] 0xde2,
- [L'ใ'] 0xde3,
- [L'ไ'] 0xde4,
- [L'ๅ'] 0xde5,
- [L'ๆ'] 0xde6,
- [L'็'] 0xde7,
- [L'่'] 0xde8,
- [L'้'] 0xde9,
- [L'๊'] 0xdea,
- [L'๋'] 0xdeb,
- [L'์'] 0xdec,
- [L'ํ'] 0xded,
- [L'๐'] 0xdf0,
- [L'๑'] 0xdf1,
- [L'๒'] 0xdf2,
- [L'๓'] 0xdf3,
- [L'๔'] 0xdf4,
- [L'๕'] 0xdf5,
- [L'๖'] 0xdf6,
- [L'๗'] 0xdf7,
- [L'๘'] 0xdf8,
- [L'๙'] 0xdf9,
- [L'ᄁ'] 0xea2,
- [L'ᄂ'] 0xea4,
- [L'ᄃ'] 0xea7,
- [L'ᄄ'] 0xea8,
- [L'ᄅ'] 0xea9,
- [L'ᄆ'] 0xeb1,
- [L'ᄇ'] 0xeb2,
- [L'ᄈ'] 0xeb3,
- [L'ᄉ'] 0xeb5,
- [L'ᄊ'] 0xeb6,
- [L'ᄋ'] 0xeb7,
- [L'ᄌ'] 0xeb8,
- [L'ᄍ'] 0xeb9,
- [L'ᄎ'] 0xeba,
- [L'ᄏ'] 0xebb,
- [L'ᄐ'] 0xebc,
- [L'ᄑ'] 0xebd,
- [L'ᄒ'] 0xebe,
- [L'ᅡ'] 0xebf,
- [L'ᅢ'] 0xec0,
- [L'ᅣ'] 0xec1,
- [L'ᅤ'] 0xec2,
- [L'ᅥ'] 0xec3,
- [L'ᅦ'] 0xec4,
- [L'ᅧ'] 0xec5,
- [L'ᅨ'] 0xec6,
- [L'ᅩ'] 0xec7,
- [L'ᅪ'] 0xec8,
- [L'ᅫ'] 0xec9,
- [L'ᅬ'] 0xeca,
- [L'ᅭ'] 0xecb,
- [L'ᅮ'] 0xecc,
- [L'ᅯ'] 0xecd,
- [L'ᅰ'] 0xece,
- [L'ᅱ'] 0xecf,
- [L'ᅲ'] 0xed0,
- [L'ᅳ'] 0xed1,
- [L'ᅴ'] 0xed2,
- [L'ᅵ'] 0xed3,
- [L'ᆨ'] 0xed4,
- [L'ᆩ'] 0xed5,
- [L'ᆪ'] 0xed6,
- [L'ᆫ'] 0xed7,
- [L'ᆬ'] 0xed8,
- [L'ᆭ'] 0xed9,
- [L'ᆮ'] 0xeda,
- [L'ᆯ'] 0xedb,
- [L'ᆰ'] 0xedc,
- [L'ᆱ'] 0xedd,
- [L'ᆲ'] 0xede,
- [L'ᆳ'] 0xedf,
- [L'ᆴ'] 0xee0,
- [L'ᆵ'] 0xee1,
- [L'ᆶ'] 0xee2,
- [L'ᆷ'] 0xee3,
- [L'ᆸ'] 0xee4,
- [L'ᆹ'] 0xee5,
- [L'ᆺ'] 0xee6,
- [L'ᆻ'] 0xee7,
- [L'ᆼ'] 0xee8,
- [L'ᆽ'] 0xee9,
- [L'ᆾ'] 0xeea,
- [L'ᆿ'] 0xeeb,
- [L'ᇀ'] 0xeec,
- [L'ᇁ'] 0xeed,
- [L'ᇂ'] 0xeee,
- [L'ᅀ'] 0xef2,
- [L'ᅙ'] 0xef5,
- [L'ᆞ'] 0xef6,
- [L'ᇫ'] 0xef8,
- [L'ᇹ'] 0xefa,
- [L'₩'] 0xeff,
- [L'Ḃ'] 0x12a1,
- [L'ḃ'] 0x12a2,
- [L'Ḋ'] 0x12a6,
- [L'Ẁ'] 0x12a8,
- [L'Ẃ'] 0x12aa,
- [L'ḋ'] 0x12ab,
- [L'Ỳ'] 0x12ac,
- [L'Ḟ'] 0x12b0,
- [L'ḟ'] 0x12b1,
- [L'Ṁ'] 0x12b4,
- [L'ṁ'] 0x12b5,
- [L'Ṗ'] 0x12b7,
- [L'ẁ'] 0x12b8,
- [L'ṗ'] 0x12b9,
- [L'ẃ'] 0x12ba,
- [L'Ṡ'] 0x12bb,
- [L'ỳ'] 0x12bc,
- [L'Ẅ'] 0x12bd,
- [L'ẅ'] 0x12be,
- [L'ṡ'] 0x12bf,
- [L'Ŵ'] 0x12d0,
- [L'Ṫ'] 0x12d7,
- [L'Ŷ'] 0x12de,
- [L'ŵ'] 0x12f0,
- [L'ṫ'] 0x12f7,
- [L'ŷ'] 0x12fe,
- [L'Œ'] 0x13bc,
- [L'œ'] 0x13bd,
- [L'Ÿ'] 0x13be,
- [L'❁'] 0x14a1,
- [L'§'] 0x14a2,
- [L'։'] 0x14a3,
- [L')'] 0x14a4,
- [L'('] 0x14a5,
- [L'»'] 0x14a6,
- [L'«'] 0x14a7,
- [L'.'] 0x14a9,
- [L'՝'] 0x14aa,
- [L','] 0x14ab,
- [L'֊'] 0x14ad,
- [L'՜'] 0x14af,
- [L'՛'] 0x14b0,
- [L'՞'] 0x14b1,
- [L'Ա'] 0x14b2,
- [L'ա'] 0x14b3,
- [L'Բ'] 0x14b4,
- [L'բ'] 0x14b5,
- [L'Գ'] 0x14b6,
- [L'գ'] 0x14b7,
- [L'Դ'] 0x14b8,
- [L'դ'] 0x14b9,
- [L'Ե'] 0x14ba,
- [L'ե'] 0x14bb,
- [L'Զ'] 0x14bc,
- [L'զ'] 0x14bd,
- [L'Է'] 0x14be,
- [L'է'] 0x14bf,
- [L'Ը'] 0x14c0,
- [L'ը'] 0x14c1,
- [L'Թ'] 0x14c2,
- [L'թ'] 0x14c3,
- [L'Ժ'] 0x14c4,
- [L'ժ'] 0x14c5,
- [L'Ի'] 0x14c6,
- [L'ի'] 0x14c7,
- [L'Լ'] 0x14c8,
- [L'լ'] 0x14c9,
- [L'Խ'] 0x14ca,
- [L'խ'] 0x14cb,
- [L'Ծ'] 0x14cc,
- [L'ծ'] 0x14cd,
- [L'Կ'] 0x14ce,
- [L'կ'] 0x14cf,
- [L'Հ'] 0x14d0,
- [L'հ'] 0x14d1,
- [L'Ձ'] 0x14d2,
- [L'ձ'] 0x14d3,
- [L'Ղ'] 0x14d4,
- [L'ղ'] 0x14d5,
- [L'Ճ'] 0x14d6,
- [L'ճ'] 0x14d7,
- [L'Մ'] 0x14d8,
- [L'մ'] 0x14d9,
- [L'Յ'] 0x14da,
- [L'յ'] 0x14db,
- [L'Ն'] 0x14dc,
- [L'ն'] 0x14dd,
- [L'Շ'] 0x14de,
- [L'շ'] 0x14df,
- [L'Ո'] 0x14e0,
- [L'ո'] 0x14e1,
- [L'Չ'] 0x14e2,
- [L'չ'] 0x14e3,
- [L'Պ'] 0x14e4,
- [L'պ'] 0x14e5,
- [L'Ջ'] 0x14e6,
- [L'ջ'] 0x14e7,
- [L'Ռ'] 0x14e8,
- [L'ռ'] 0x14e9,
- [L'Ս'] 0x14ea,
- [L'ս'] 0x14eb,
- [L'Վ'] 0x14ec,
- [L'վ'] 0x14ed,
- [L'Տ'] 0x14ee,
- [L'տ'] 0x14ef,
- [L'Ր'] 0x14f0,
- [L'ր'] 0x14f1,
- [L'Ց'] 0x14f2,
- [L'ց'] 0x14f3,
- [L'Ւ'] 0x14f4,
- [L'ւ'] 0x14f5,
- [L'Փ'] 0x14f6,
- [L'փ'] 0x14f7,
- [L'Ք'] 0x14f8,
- [L'ք'] 0x14f9,
- [L'Օ'] 0x14fa,
- [L'օ'] 0x14fb,
- [L'Ֆ'] 0x14fc,
- [L'ֆ'] 0x14fd,
- [L'''] 0x14ff,
- [L'ა'] 0x15d0,
- [L'ბ'] 0x15d1,
- [L'გ'] 0x15d2,
- [L'დ'] 0x15d3,
- [L'ე'] 0x15d4,
- [L'ვ'] 0x15d5,
- [L'ზ'] 0x15d6,
- [L'თ'] 0x15d7,
- [L'ი'] 0x15d8,
- [L'კ'] 0x15d9,
- [L'ლ'] 0x15da,
- [L'მ'] 0x15db,
- [L'ნ'] 0x15dc,
- [L'ო'] 0x15dd,
- [L'პ'] 0x15de,
- [L'ჟ'] 0x15df,
- [L'რ'] 0x15e0,
- [L'ს'] 0x15e1,
- [L'ტ'] 0x15e2,
- [L'უ'] 0x15e3,
- [L'ფ'] 0x15e4,
- [L'ქ'] 0x15e5,
- [L'ღ'] 0x15e6,
- [L'ყ'] 0x15e7,
- [L'შ'] 0x15e8,
- [L'ჩ'] 0x15e9,
- [L'ც'] 0x15ea,
- [L'ძ'] 0x15eb,
- [L'წ'] 0x15ec,
- [L'ჭ'] 0x15ed,
- [L'ხ'] 0x15ee,
- [L'ჯ'] 0x15ef,
- [L'ჰ'] 0x15f0,
- [L'ჱ'] 0x15f1,
- [L'ჲ'] 0x15f2,
- [L'ჳ'] 0x15f3,
- [L'ჴ'] 0x15f4,
- [L'ჵ'] 0x15f5,
- [L'ჶ'] 0x15f6,
- [L''] 0x16a2,
- [L'Ẋ'] 0x16a3,
- [L''] 0x16a5,
- [L'Ĭ'] 0x16a6,
- [L''] 0x16a7,
- [L''] 0x16a8,
- [L'Ƶ'] 0x16a9,
- [L'Ǧ'] 0x16aa,
- [L'Ɵ'] 0x16af,
- [L''] 0x16b2,
- [L'ẋ'] 0x16b3,
- [L'Ǒ'] 0x16b4,
- [L''] 0x16b5,
- [L'ĭ'] 0x16b6,
- [L''] 0x16b7,
- [L''] 0x16b8,
- [L'ƶ'] 0x16b9,
- [L'ǧ'] 0x16ba,
- [L'ǒ'] 0x16bd,
- [L'ɵ'] 0x16bf,
- [L'Ə'] 0x16c6,
- [L'Ḷ'] 0x16d1,
- [L''] 0x16d2,
- [L''] 0x16d3,
- [L'ḷ'] 0x16e1,
- [L''] 0x16e2,
- [L''] 0x16e3,
- [L'ə'] 0x16f6,
- [L'̃'] 0x1e9f,
- [L'Ạ'] 0x1ea0,
- [L'ạ'] 0x1ea1,
- [L'Ả'] 0x1ea2,
- [L'ả'] 0x1ea3,
- [L'Ấ'] 0x1ea4,
- [L'ấ'] 0x1ea5,
- [L'Ầ'] 0x1ea6,
- [L'ầ'] 0x1ea7,
- [L'Ẩ'] 0x1ea8,
- [L'ẩ'] 0x1ea9,
- [L'Ẫ'] 0x1eaa,
- [L'ẫ'] 0x1eab,
- [L'Ậ'] 0x1eac,
- [L'ậ'] 0x1ead,
- [L'Ắ'] 0x1eae,
- [L'ắ'] 0x1eaf,
- [L'Ằ'] 0x1eb0,
- [L'ằ'] 0x1eb1,
- [L'Ẳ'] 0x1eb2,
- [L'ẳ'] 0x1eb3,
- [L'Ẵ'] 0x1eb4,
- [L'ẵ'] 0x1eb5,
- [L'Ặ'] 0x1eb6,
- [L'ặ'] 0x1eb7,
- [L'Ẹ'] 0x1eb8,
- [L'ẹ'] 0x1eb9,
- [L'Ẻ'] 0x1eba,
- [L'ẻ'] 0x1ebb,
- [L'Ẽ'] 0x1ebc,
- [L'ẽ'] 0x1ebd,
- [L'Ế'] 0x1ebe,
- [L'ế'] 0x1ebf,
- [L'Ề'] 0x1ec0,
- [L'ề'] 0x1ec1,
- [L'Ể'] 0x1ec2,
- [L'ể'] 0x1ec3,
- [L'Ễ'] 0x1ec4,
- [L'ễ'] 0x1ec5,
- [L'Ệ'] 0x1ec6,
- [L'ệ'] 0x1ec7,
- [L'Ỉ'] 0x1ec8,
- [L'ỉ'] 0x1ec9,
- [L'Ị'] 0x1eca,
- [L'ị'] 0x1ecb,
- [L'Ọ'] 0x1ecc,
- [L'ọ'] 0x1ecd,
- [L'Ỏ'] 0x1ece,
- [L'ỏ'] 0x1ecf,
- [L'Ố'] 0x1ed0,
- [L'ố'] 0x1ed1,
- [L'Ồ'] 0x1ed2,
- [L'ồ'] 0x1ed3,
- [L'Ổ'] 0x1ed4,
- [L'ổ'] 0x1ed5,
- [L'Ỗ'] 0x1ed6,
- [L'ỗ'] 0x1ed7,
- [L'Ộ'] 0x1ed8,
- [L'ộ'] 0x1ed9,
- [L'Ớ'] 0x1eda,
- [L'ớ'] 0x1edb,
- [L'Ờ'] 0x1edc,
- [L'ờ'] 0x1edd,
- [L'Ở'] 0x1ede,
- [L'ở'] 0x1edf,
- [L'Ỡ'] 0x1ee0,
- [L'ỡ'] 0x1ee1,
- [L'Ợ'] 0x1ee2,
- [L'ợ'] 0x1ee3,
- [L'Ụ'] 0x1ee4,
- [L'ụ'] 0x1ee5,
- [L'Ủ'] 0x1ee6,
- [L'ủ'] 0x1ee7,
- [L'Ứ'] 0x1ee8,
- [L'ứ'] 0x1ee9,
- [L'Ừ'] 0x1eea,
- [L'ừ'] 0x1eeb,
- [L'Ử'] 0x1eec,
- [L'ử'] 0x1eed,
- [L'Ữ'] 0x1eee,
- [L'ữ'] 0x1eef,
- [L'Ự'] 0x1ef0,
- [L'ự'] 0x1ef1,
- [L'̀'] 0x1ef2,
- [L'́'] 0x1ef3,
- [L'Ỵ'] 0x1ef4,
- [L'ỵ'] 0x1ef5,
- [L'Ỷ'] 0x1ef6,
- [L'ỷ'] 0x1ef7,
- [L'Ỹ'] 0x1ef8,
- [L'ỹ'] 0x1ef9,
- [L'Ơ'] 0x1efa,
- [L'ơ'] 0x1efb,
- [L'Ư'] 0x1efc,
- [L'ư'] 0x1efd,
- [L'̉'] 0x1efe,
- [L'̣'] 0x1eff,
- [L'₠'] 0x20a0,
- [L'₡'] 0x20a1,
- [L'₢'] 0x20a2,
- [L'₣'] 0x20a3,
- [L'₤'] 0x20a4,
- [L'₥'] 0x20a5,
- [L'₦'] 0x20a6,
- [L'₧'] 0x20a7,
- [L'₨'] 0x20a8,
- [L'₪'] 0x20aa,
- [L'₫'] 0x20ab,
- [L'€'] 0x20ac,
-
-};
\ No newline at end of file
--- a/sys/src/cmd/vnc/vnc.h
+++ /dev/null
@@ -1,149 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <draw.h>
-#include <memdraw.h>
-
-typedef struct Pixfmt Pixfmt;
-typedef struct Colorfmt Colorfmt;
-typedef struct Vnc Vnc;
-
-struct Colorfmt {
- int max;
- int shift;
-};
-
-struct Pixfmt {
- int bpp;
- int depth;
- int bigendian;
- int truecolor;
- Colorfmt red;
- Colorfmt green;
- Colorfmt blue;
-};
-
-struct Vnc {
- QLock;
- int datafd; /* for network connection */
- int ctlfd; /* control for network connection */
-
- Biobuf in;
- Biobuf out;
-
- Rectangle dim;
- Pixfmt;
-
- /* client only */
- char *name;
- char *srvaddr;
- int vers;
-
- int canresize;
- struct {
- ulong id;
- Rectangle rect;
- ulong flags;
- } screen[1];
-};
-
-enum {
- VerLen = 12,
- /* authentication negotiation */
- AFailed = 0,
- ANoAuth,
- AVncAuth,
-
- /* vnc auth negotiation */
- VncAuthOK = 0,
- VncAuthFailed,
- VncAuthTooMany,
- VncChalLen = 16,
-
- /* server to client */
- MFrameUpdate = 0,
- MSetCmap,
- MBell,
- MSCut,
- MSAck,
-
- /* client to server */
- MPixFmt = 0,
- MFixCmap,
- MSetEnc,
- MFrameReq,
- MKey,
- MMouse,
- MCCut,
- MSetDesktopSize = 251,
-
- /* image encoding methods */
- EncRaw = 0,
- EncCopyRect = 1,
- EncRre = 2,
- EncCorre = 4,
- EncHextile = 5,
- EncZlib = 6, /* 6,7,8 have been used by others */
- EncTight = 7,
- EncZHextile = 8,
- EncMouseWarp = 9,
-
- EncDesktopSize = -223,
- EncXDesktopSize = -308,
-
- /* paramaters for hextile encoding */
- HextileDim = 16,
- HextileRaw = 1,
- HextileBack = 2,
- HextileFore = 4,
- HextileRects = 8,
- HextileCols = 16
-};
-
-/*
- * we're only using the ulong as a place to store bytes,
- * and as something to compare against.
- * the bytes are stored in little-endian format.
- */
-typedef ulong Color;
-
-/* auth.c */
-extern int vncauth(Vnc*, char*);
-extern int vnchandshake(Vnc*);
-extern int vncsrvauth(Vnc*);
-extern int vncsrvhandshake(Vnc*);
-
-/* proto.c */
-extern Vnc* vncinit(int, int, Vnc*);
-extern uchar vncrdchar(Vnc*);
-extern ushort vncrdshort(Vnc*);
-extern ulong vncrdlong(Vnc*);
-extern Point vncrdpoint(Vnc*);
-extern Rectangle vncrdrect(Vnc*);
-extern Rectangle vncrdcorect(Vnc*);
-extern Pixfmt vncrdpixfmt(Vnc*);
-extern void vncrdbytes(Vnc*, void*, int);
-extern char* vncrdstring(Vnc*);
-extern char* vncrdstringx(Vnc*);
-extern void vncwrstring(Vnc*, char*);
-extern void vncgobble(Vnc*, long);
-
-extern void vncflush(Vnc*);
-extern void vncterm(Vnc*);
-extern void vncwrbytes(Vnc*, void*, int);
-extern void vncwrlong(Vnc*, ulong);
-extern void vncwrshort(Vnc*, ushort);
-extern void vncwrchar(Vnc*, uchar);
-extern void vncwrpixfmt(Vnc*, Pixfmt*);
-extern void vncwrrect(Vnc*, Rectangle);
-extern void vncwrpoint(Vnc*, Point);
-
-extern void vnclock(Vnc*); /* for writing */
-extern void vncunlock(Vnc*);
-
-extern void hexdump(void*, int);
-
-/* implemented by clients of the io library */
-extern void vnchungup(Vnc*);
-
-extern int verbose;
--- a/sys/src/cmd/vnc/vncs.c
+++ /dev/null
@@ -1,1143 +1,0 @@
-#define Image IMAGE
-#include "vnc.h"
-#include "vncs.h"
-#include "compat.h"
-#include <cursor.h>
-#include "screen.h"
-#include "kbd.h"
-
-#include <mp.h>
-#include <libsec.h>
-
-extern Dev drawdevtab;
-extern Dev mousedevtab;
-extern Dev consdevtab;
-
-Dev *devtab[] =
-{
- &drawdevtab,
- &mousedevtab,
- &consdevtab,
- nil
-};
-
-/*
- * list head. used to hold the list, the lock, dim, and pixelfmt
- */
-struct {
- QLock;
- Vncs *head;
-} clients;
-
-int shared;
-int sleeptime = 5;
-int verbose = 0;
-int noauth = 0;
-int kbdin = -1;
-
-char *cert;
-char *pixchan = "r5g6b5";
-static int cmdpid;
-static int srvfd;
-static int exportfd;
-static Vncs **vncpriv;
-
-static int parsedisplay(char*);
-static void vnckill(char*, int, int);
-static int vncannounce(char *net, int display, char *adir, int base);
-static void noteshutdown(void*, char*);
-static void vncaccept(Vncs*);
-static int vncsfmt(Fmt*);
-static void getremote(char*, char*);
-#pragma varargck type "V" Vncs*
-
-void
-usage(void)
-{
- fprint(2, "usage: vncs [-v] [-c cert] [-d :display] [-g widthXheight] [-p pixelfmt] [-A] [cmd [args]...]\n");
- fprint(2, "\tto kill a server: vncs [-v] -k :display\n");
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- int baseport, cfd, display, exnum, fd, pid, h, killing, w;
- char adir[NETPATHLEN], ldir[NETPATHLEN];
- char net[NETPATHLEN], *p;
- char *kbdfs[] = { "/bin/aux/kbdfs", "-dq", nil };
- char *rc[] = { "/bin/rc", "-i", nil };
- Vncs *v;
-
- fmtinstall('V', vncsfmt);
- display = -1;
- killing = 0;
- w = 1024;
- h = 768;
- baseport = 5900;
- setnetmtpt(net, sizeof net, nil);
- ARGBEGIN{
- default:
- usage();
- case 'c':
- cert = EARGF(usage());
- baseport = 35729;
- break;
- case 'd':
- if(display != -1)
- usage();
- display = parsedisplay(EARGF(usage()));
- break;
- case 'g':
- p = EARGF(usage());
- w = strtol(p, &p, 10);
- if(*p != 'x' && *p != 'X' && *p != ' ' && *p != ' ')
- usage();
- h = strtol(p+1, &p, 10);
- if(*p != 0)
- usage();
- break;
- case 'k':
- if(display != -1)
- usage();
- display = parsedisplay(EARGF(usage()));
- killing = 1;
- break;
- case 'p':
- pixchan = EARGF(usage());
- break;
-/* DEBUGGING
- case 's':
- sleeptime = atoi(EARGF(usage()));
- break;
-*/
- case 'v':
- verbose++;
- break;
- case 'x':
- p = EARGF(usage());
- setnetmtpt(net, sizeof net, p);
- break;
- case 'A':
- noauth = 1;
- break;
- }ARGEND
-
- if(killing){
- vnckill(net, display, baseport);
- exits(nil);
- }
-
- if(argc == 0)
- argv = rc;
-
- /* easy exit */
- if(access(argv[0], AEXEC) < 0)
- sysfatal("access %s for exec: %r", argv[0]);
-
- /* background ourselves */
- switch(rfork(RFPROC|RFNAMEG|RFFDG|RFNOTEG)){
- case -1:
- sysfatal("rfork: %r");
- default:
- exits(nil);
- case 0:
- break;
- }
-
- vncpriv = privalloc();
- if(vncpriv == nil)
- sysfatal("privalloc: %r");
-
- /* start screen */
- initcompat();
- if(waserror())
- sysfatal("screeninit %dx%d %s: %s", w, h, pixchan, up->error);
- if(verbose)
- fprint(2, "geometry is %dx%d\n", w, h);
- screeninit(w, h, pixchan);
- poperror();
-
- /* start file system device slaves */
- exnum = exporter(devtab, &fd, &exportfd);
-
- /* rebuild /dev because the underlying connection might go away (ick) */
- unmount(nil, "/dev");
- bind("#c", "/dev", MREPL);
-
- /* mount exporter */
- if(mounter("/dev", MBEFORE, fd, exnum) < 0)
- sysfatal("mounter: %r");
- close(fd);
-
- pid = rfork(RFPROC|RFMEM|RFFDG|RFNOTEG);
- switch(pid){
- case -1:
- sysfatal("rfork: %r");
- break;
- case 0:
- close(exportfd);
-
- close(1);
- open("/dev/cons", OWRITE);
- close(2);
- open("/dev/cons", OWRITE);
-
- /* start and mount kbdfs */
- pid = rfork(RFPROC|RFMEM|RFFDG|RFREND);
- switch(pid){
- case -1:
- sysfatal("rfork: %r");
- break;
- case 0:
- exec(kbdfs[0], kbdfs);
- fprint(2, "exec %s: %r\n", kbdfs[0]);
- _exits("kbdfs");
- }
- if(waitpid() != pid){
- rendezvous(&kbdin, nil);
- sysfatal("waitpid: %s: %r", kbdfs[0]);
- }
- rendezvous(&kbdin, nil);
-
- rfork(RFNAMEG|RFREND);
-
- close(0);
- open("/dev/cons", OREAD);
- close(1);
- open("/dev/cons", OWRITE);
- close(2);
- open("/dev/cons", OWRITE);
-
- exec(argv[0], argv);
- fprint(2, "exec %s: %r\n", argv[0]);
- _exits(nil);
- }
- cmdpid = pid;
-
- /* wait for kbdfs to get mounted */
- rendezvous(&kbdin, nil);
- if((kbdin = open("/dev/kbdin", OWRITE)) < 0)
- sysfatal("open /dev/kbdin: %r");
-
- /* run the service */
- srvfd = vncannounce(net, display, adir, baseport);
- if(srvfd < 0)
- sysfatal("announce failed");
- if(verbose)
- fprint(2, "announced in %s\n", adir);
-
- atexit(shutdown);
- notify(noteshutdown);
- for(;;){
- procsetname("listener");
- cfd = listen(adir, ldir);
- if(cfd < 0)
- break;
- if(verbose)
- fprint(2, "call in %s\n", ldir);
- fd = accept(cfd, ldir);
- if(fd < 0){
- close(cfd);
- continue;
- }
- v = mallocz(sizeof(Vncs), 1);
- if(v == nil){
- close(cfd);
- close(fd);
- continue;
- }
- v->ctlfd = cfd;
- v->datafd = fd;
- v->nproc = 1;
- v->ndead = 0;
- getremote(ldir, v->remote);
- strcpy(v->netpath, ldir);
- qlock(&clients);
- v->next = clients.head;
- clients.head = v;
- qunlock(&clients);
- vncaccept(v);
- }
- exits(0);
-}
-
-static int
-parsedisplay(char *p)
-{
- int n;
-
- if(*p != ':')
- usage();
- if(*p == 0)
- usage();
- n = strtol(p+1, &p, 10);
- if(*p != 0)
- usage();
- return n;
-}
-
-static void
-getremote(char *ldir, char *remote)
-{
- char buf[NETPATHLEN];
- int fd, n;
-
- snprint(buf, sizeof buf, "%s/remote", ldir);
- strcpy(remote, "<none>");
- if((fd = open(buf, OREAD)) < 0)
- return;
- n = readn(fd, remote, NETPATHLEN-1);
- close(fd);
- if(n < 0)
- return;
- remote[n] = 0;
- if(n>0 && remote[n-1] == '\n')
- remote[n-1] = 0;
-}
-
-static int
-vncsfmt(Fmt *fmt)
-{
- Vncs *v;
-
- v = va_arg(fmt->args, Vncs*);
- return fmtprint(fmt, "[%d] %s %s", getpid(), v->remote, v->netpath);
-}
-
-/*
- * We register exiting as an atexit handler in each proc, so that
- * client procs need merely exit when something goes wrong.
- */
-static void
-vncclose(Vncs *v)
-{
- Vncs **l;
-
- /* remove self from client list if there */
- qlock(&clients);
- for(l=&clients.head; *l; l=&(*l)->next)
- if(*l == v){
- *l = v->next;
- break;
- }
- qunlock(&clients);
-
- /* if last proc, free v */
- vnclock(v);
- if(++v->ndead < v->nproc){
- vncunlock(v);
- return;
- }
-
- freerlist(&v->rlist);
- vncterm(v);
- if(v->ctlfd >= 0)
- close(v->ctlfd);
- if(v->datafd >= 0)
- close(v->datafd);
- if(v->image)
- freememimage(v->image);
- free(v);
-}
-
-static void
-exiting(void)
-{
- vncclose(*vncpriv);
-}
-
-void
-vnchungup(Vnc *v)
-{
- if(verbose)
- fprint(2, "%V: hangup\n", (Vncs*)v);
- exits(0); /* atexit and exiting() will take care of everything */
-}
-
-/*
- * Kill all clients except safe.
- * Used to start a non-shared client and at shutdown.
- */
-static void
-killclients(Vncs *safe)
-{
- Vncs *v;
-
- qlock(&clients);
- for(v=clients.head; v; v=v->next){
- if(v == safe)
- continue;
- if(v->ctlfd >= 0){
- hangup(v->ctlfd);
- close(v->ctlfd);
- v->ctlfd = -1;
- close(v->datafd);
- v->datafd = -1;
- }
- }
- qunlock(&clients);
-}
-
-/*
- * Kill the executing command and then kill everyone else.
- * Called to close up shop at the end of the day
- * and also if we get an unexpected note.
- */
-static char killkin[] = "die vnc kin";
-static void
-killall(void)
-{
- postnote(PNGROUP, cmdpid, "hangup");
- close(srvfd);
- srvfd = -1;
- close(exportfd);
- exportfd = -1;
- close(kbdin);
- kbdin = -1;
- postnote(PNGROUP, getpid(), killkin);
-}
-
-void
-shutdown(void)
-{
- if(verbose)
- fprint(2, "vnc server shutdown\n");
- killall();
-}
-
-static void
-noteshutdown(void*, char *msg)
-{
- if(strcmp(msg, killkin) == 0) /* already shutting down */
- noted(NDFLT);
- killall();
- noted(NDFLT);
-}
-
-/*
- * Kill a specific instance of a server.
- */
-static void
-vnckill(char *net, int display, int baseport)
-{
- int fd, i, n, port;
- char buf[NETPATHLEN], *p;
-
- for(i=0;; i++){
- snprint(buf, sizeof buf, "%s/tcp/%d/local", net, i);
- if((fd = open(buf, OREAD)) < 0)
- sysfatal("did not find display");
- n = read(fd, buf, sizeof buf-1);
- close(fd);
- if(n <= 0)
- continue;
- buf[n] = 0;
- p = strchr(buf, '!');
- if(p == 0)
- continue;
- port = atoi(p+1);
- if(port != display+baseport)
- continue;
- snprint(buf, sizeof buf, "%s/tcp/%d/ctl", net, i);
- fd = open(buf, OWRITE);
- if(fd < 0)
- sysfatal("cannot open %s: %r", buf);
- if(write(fd, "hangup", 6) != 6)
- sysfatal("cannot hangup %s: %r", buf);
- close(fd);
- break;
- }
-}
-
-/*
- * Look for a port on which to announce.
- * If display != -1, we only try that one.
- * Otherwise we hunt.
- *
- * Returns the announce fd.
- */
-static int
-vncannounce(char *net, int display, char *adir, int base)
-{
- int port, eport, fd;
- char addr[NETPATHLEN];
-
- if(display == -1){
- port = base;
- eport = base+50;
- }else{
- port = base+display;
- eport = port;
- }
-
- for(; port<=eport; port++){
- snprint(addr, sizeof addr, "%s/tcp!*!%d", net, port);
- if((fd = announce(addr, adir)) >= 0){
- fprint(2, "server started on display :%d\n", port-base);
- return fd;
- }
- }
- if(display == -1)
- fprint(2, "could not find any ports to announce\n");
- else
- fprint(2, "announce: %r\n");
- return -1;
-}
-
-/*
- * Handle a new connection.
- */
-static void clientreadproc(Vncs*);
-static void clientwriteproc(Vncs*);
-static void chan2fmt(Pixfmt*, ulong);
-static ulong fmt2chan(Pixfmt*);
-
-static void
-vncaccept(Vncs *v)
-{
- char buf[32];
- int fd;
-
- /* caller returns to listen */
- switch(rfork(RFPROC|RFMEM|RFNAMEG)){
- case -1:
- fprint(2, "%V: fork failed: %r\n", v);
- vncclose(v);
- return;
- default:
- return;
- case 0:
- break;
- }
- *vncpriv = v;
-
- if(!atexit(exiting)){
- fprint(2, "%V: could not register atexit handler: %r; hanging up\n", v);
- exiting();
- exits(nil);
- }
-
- if(cert != nil){
- TLSconn conn;
-
- memset(&conn, 0, sizeof conn);
- conn.cert = readcert(cert, &conn.certlen);
- if(conn.cert == nil){
- fprint(2, "%V: could not read cert %s: %r; hanging up\n", v, cert);
- exits(nil);
- }
- fd = tlsServer(v->datafd, &conn);
- if(fd < 0){
- fprint(2, "%V: tlsServer: %r; hanging up\n", v);
- free(conn.cert);
- free(conn.sessionID);
- exits(nil);
- }
- v->datafd = fd;
- free(conn.cert);
- free(conn.sessionID);
- }
- vncinit(v->datafd, v->ctlfd, v);
-
- if(verbose)
- fprint(2, "%V: handshake\n", v);
- if(vncsrvhandshake(v) < 0){
- fprint(2, "%V: handshake failed; hanging up\n", v);
- exits(0);
- }
-
- if(noauth){
- if(verbose)
- fprint(2, "%V: noauth\n", v);
- vncwrlong(v, ANoAuth);
- vncflush(v);
- } else {
- if(verbose)
- fprint(2, "%V: auth\n", v);
- if(vncsrvauth(v) < 0){
- fprint(2, "%V: auth failed; hanging up\n", v);
- exits(0);
- }
- }
-
- shared = vncrdchar(v);
-
- if(verbose)
- fprint(2, "%V: %sshared\n", v, shared ? "" : "not ");
- if(!shared)
- killclients(v);
-
- v->dim = rectsubpt(gscreen->clipr, gscreen->clipr.min);
- vncwrpoint(v, v->dim.max);
- if(verbose)
- fprint(2, "%V: send screen size %R\n", v, v->dim);
-
- v->bpp = gscreen->depth;
- v->depth = gscreen->depth;
- v->truecolor = 1;
- v->bigendian = 0;
- chan2fmt(v, gscreen->chan);
- if(verbose)
- fprint(2, "%V: bpp=%d, depth=%d, chan=%s\n", v,
- v->bpp, v->depth, chantostr(buf, gscreen->chan));
- vncwrpixfmt(v, v);
- vncwrlong(v, 14);
- vncwrbytes(v, "Plan9 Desktop", 14);
- vncflush(v);
-
- if(verbose)
- fprint(2, "%V: handshaking done\n", v);
-
- v->updatereq = 0;
-
- switch(rfork(RFPROC|RFMEM)){
- case -1:
- fprint(2, "%V: cannot fork: %r; hanging up\n", v);
- vnchungup(v);
- default:
- clientreadproc(v);
- exits(nil);
- case 0:
- *vncpriv = v;
- v->nproc++;
- if(atexit(exiting) == 0){
- exiting();
- fprint(2, "%V: could not register atexit handler: %r; hanging up\n", v);
- exits(nil);
- }
- clientwriteproc(v);
- exits(nil);
- }
-}
-
-
-/*
- * Set the pixel format being sent. Can only happen once.
- * (Maybe a client would send this again if the screen changed
- * underneath it? If we want to support this we need a way to
- * make sure the current image is no longer in use, so we can free it.
- */
-static void
-setpixelfmt(Vncs *v)
-{
- ulong chan;
-
- vncgobble(v, 3);
- v->Pixfmt = vncrdpixfmt(v);
- chan = fmt2chan(v);
- if(chan == 0){
- fprint(2, "%V: bad pixel format; hanging up\n", v);
- vnchungup(v);
- }
- v->imagechan = chan;
-}
-
-/*
- * Set the preferred encoding list. Can only happen once.
- * If we want to support changing this more than once then
- * we need to put a lock around the encoding functions
- * so as not to conflict with updateimage.
- */
-static void
-setencoding(Vncs *v)
-{
- int n, x;
-
- vncrdchar(v);
- n = vncrdshort(v);
- while(n-- > 0){
- x = vncrdlong(v);
- switch(x){
- case EncCopyRect:
- v->copyrect = 1;
- continue;
- case EncMouseWarp:
- v->canwarp = 1;
- continue;
- case EncDesktopSize:
- v->canresize |= 1;
- continue;
- case EncXDesktopSize:
- v->canresize |= 2;
- continue;
- }
- if(v->countrect != nil)
- continue;
- switch(x){
- case EncRaw:
- v->encname = "raw";
- v->countrect = countraw;
- v->sendrect = sendraw;
- break;
- case EncRre:
- v->encname = "rre";
- v->countrect = countrre;
- v->sendrect = sendrre;
- break;
- case EncCorre:
- v->encname = "corre";
- v->countrect = countcorre;
- v->sendrect = sendcorre;
- break;
- case EncHextile:
- v->encname = "hextile";
- v->countrect = counthextile;
- v->sendrect = sendhextile;
- break;
- }
- }
-
- if(v->countrect == nil){
- v->encname = "raw";
- v->countrect = countraw;
- v->sendrect = sendraw;
- }
-
- if(verbose)
- fprint(2, "Encoding with %s%s%s%s\n", v->encname,
- v->copyrect ? ", copyrect" : "",
- v->canwarp ? ", canwarp" : "",
- v->canresize ? ", resize" : "");
-}
-
-/*
- * Continually read updates from one client.
- */
-static void
-clientreadproc(Vncs *v)
-{
- int incremental, key, keydown, buttons, type, x, y, n;
- char *buf;
- Rectangle r;
-
- procsetname("read %V", v);
-
- for(;;){
- type = vncrdchar(v);
- switch(type){
- default:
- fprint(2, "%V: unknown vnc message type %d; hanging up\n", v, type);
- vnchungup(v);
-
- /* set pixel format */
- case MPixFmt:
- setpixelfmt(v);
- break;
-
- /* ignore color map changes */
- case MFixCmap:
- vncgobble(v, 3);
- n = vncrdshort(v);
- vncgobble(v, n*6);
- break;
-
- /* set encoding list */
- case MSetEnc:
- setencoding(v);
- break;
-
- /* request image update in rectangle */
- case MFrameReq:
- incremental = vncrdchar(v);
- r = vncrdrect(v);
- if(!incremental){
- qlock(&drawlock); /* protects rlist */
- addtorlist(&v->rlist, r);
- qunlock(&drawlock);
- }
- v->updatereq++;
- break;
-
- case MSetDesktopSize:
- vncrdchar(v);
- vncrdpoint(v); // desktop size
- n = vncrdchar(v);
- vncrdchar(v);
- if(n == 0)
- break;
- vncrdlong(v); // id
- r = vncrdrect(v);
- vncrdlong(v); // flags
- while(--n > 0){
- vncrdlong(v);
- vncrdrect(v);
- vncrdlong(v);
- }
- qlock(&drawlock);
- if(!rectclip(&r, gscreen->r)){
- qunlock(&drawlock);
- break;
- }
- gscreen->clipr = r;
- qunlock(&drawlock);
-
- screenwin();
- deletescreenimage();
- resetscreenimage();
- break;
-
- /* send keystroke */
- case MKey:
- keydown = vncrdchar(v);
- vncgobble(v, 2);
- key = vncrdlong(v);
- vncputc(!keydown, key);
- break;
-
- /* send mouse event */
- case MMouse:
- buttons = vncrdchar(v);
- x = vncrdshort(v);
- y = vncrdshort(v);
- absmousetrack(x, y, buttons, nsec()/(1000*1000LL));
- break;
-
- /* send cut text */
- case MCCut:
- vncgobble(v, 3);
- n = vncrdlong(v);
- buf = malloc(n+1);
- if(buf){
- vncrdbytes(v, buf, n);
- buf[n] = 0;
- vnclock(v); /* for snarfvers */
- setsnarf(buf, n, &v->snarfvers);
- vncunlock(v);
- }else
- vncgobble(v, n);
- break;
- }
- }
-}
-
-static int
-nbits(ulong mask)
-{
- int n;
-
- n = 0;
- for(; mask; mask>>=1)
- n += mask&1;
- return n;
-}
-
-typedef struct Col Col;
-struct Col {
- int type;
- int nbits;
- int shift;
-};
-
-static ulong
-fmt2chan(Pixfmt *fmt)
-{
- Col c[4], t;
- int i, j, depth, n, nc;
- ulong mask, u;
-
- /* unpack the Pixfmt channels */
- c[0] = (Col){CRed, nbits(fmt->red.max), fmt->red.shift};
- c[1] = (Col){CGreen, nbits(fmt->green.max), fmt->green.shift};
- c[2] = (Col){CBlue, nbits(fmt->blue.max), fmt->blue.shift};
- nc = 3;
-
- /* add an ignore channel if necessary */
- depth = c[0].nbits+c[1].nbits+c[2].nbits;
- if(fmt->bpp != depth){
- /* BUG: assumes only one run of ignored bits */
- if(fmt->bpp == 32)
- mask = ~0;
- else
- mask = (1<<fmt->bpp)-1;
- mask ^= fmt->red.max << fmt->red.shift;
- mask ^= fmt->green.max << fmt->green.shift;
- mask ^= fmt->blue.max << fmt->blue.shift;
- if(mask == 0)
- abort();
- n = 0;
- for(; !(mask&1); mask>>=1)
- n++;
- c[3] = (Col){CIgnore, nbits(mask), n};
- nc++;
- }
-
- /* sort the channels, largest shift (leftmost bits) first */
- for(i=1; i<nc; i++)
- for(j=i; j>0; j--)
- if(c[j].shift > c[j-1].shift){
- t = c[j];
- c[j] = c[j-1];
- c[j-1] = t;
- }
-
- /* build the channel descriptor */
- u = 0;
- for(i=0; i<nc; i++){
- u <<= 8;
- u |= CHAN1(c[i].type, c[i].nbits);
- }
-
- return u;
-}
-
-static void
-chan2fmt(Pixfmt *fmt, ulong chan)
-{
- ulong c, rc, shift;
-
- shift = 0;
- for(rc = chan; rc; rc >>=8){
- c = rc & 0xFF;
- switch(TYPE(c)){
- case CRed:
- fmt->red = (Colorfmt){(1<<NBITS(c))-1, shift};
- break;
- case CBlue:
- fmt->blue = (Colorfmt){(1<<NBITS(c))-1, shift};
- break;
- case CGreen:
- fmt->green = (Colorfmt){(1<<NBITS(c))-1, shift};
- break;
- }
- shift += NBITS(c);
- }
-}
-
-/*
- * Note that r has changed on the screen.
- * Updating the rlists is okay because they are protected by drawlock.
- */
-void
-flushmemscreen(Rectangle r)
-{
- Vncs *v;
-
- if(!rectclip(&r, gscreen->clipr))
- return;
- qlock(&clients);
- for(v=clients.head; v; v=v->next)
- addtorlist(&v->rlist, r);
- qunlock(&clients);
-}
-
-/*
- * Queue a mouse warp note for the next update to each client.
- */
-void
-mousewarpnote(Point p)
-{
- Vncs *v;
-
- qlock(&clients);
- for(v=clients.head; v; v=v->next){
- if(v->canwarp){
- vnclock(v);
- v->dowarp = 1;
- v->warppt = p;
- vncunlock(v);
- }
- }
- qunlock(&clients);
-}
-
-/*
- * Send a client his changed screen image.
- * v is locked on entrance, locked on exit, but released during.
- */
-static int
-updateimage(Vncs *v)
-{
- int i, j, ncount, nsend, docursor, dowarp, doresize;
- vlong ooffset = 0, t1 = 0;
- Point warppt;
- Rectangle cr;
- Rlist rlist;
- int (*count)(Vncs*, Rectangle);
- int (*send)(Vncs*, Rectangle);
-
- vnclock(v);
- dowarp = v->canwarp && v->dowarp;
- warppt = v->warppt;
- v->dowarp = 0;
- vncunlock(v);
-
- /* copy the screen bits and then unlock the screen so updates can proceed */
- qlock(&drawlock);
- rlist = v->rlist;
- memset(&v->rlist, 0, sizeof v->rlist);
-
- if(v->canresize && !eqrect(v->screen[0].rect, gscreen->clipr)){
- v->screen[0].rect = gscreen->clipr;
- v->dim = rectsubpt(gscreen->clipr, gscreen->clipr.min);
- doresize = 1;
- } else
- doresize = 0;
-
- if(doresize
- || (v->image == nil && v->imagechan != 0)
- || (v->image != nil && v->image->chan != v->imagechan)){
- if(v->image)
- freememimage(v->image);
- v->image = allocmemimage(v->dim, v->imagechan);
- if(v->image == nil){
- fprint(2, "%V: allocmemimage: %r; hanging up\n", v);
- qlock(&drawlock);
- vnchungup(v);
- }
- }
-
- /* if the cursor has moved or changed shape, we need to redraw its square */
- lock(&cursor);
- if(v->cursorver != cursorver || !eqpt(v->cursorpos, cursorpos)){
- docursor = 1;
- v->cursorver = cursorver;
- v->cursorpos = cursorpos;
- cr = cursorrect();
- }else{
- docursor = 0;
- cr = v->cursorr;
- }
- unlock(&cursor);
-
- if(docursor){
- addtorlist(&rlist, v->cursorr);
- if(!rectclip(&cr, gscreen->clipr))
- cr.max = cr.min;
- addtorlist(&rlist, cr);
- }
-
- /* copy changed screen parts, also check for parts overlapping cursor location */
- for(i=0; i<rlist.nrect; i++){
- if(!docursor)
- docursor = rectXrect(v->cursorr, rlist.rect[i]);
- memimagedraw(v->image, rlist.rect[i], gscreen, rlist.rect[i].min, memopaque, ZP, S);
- }
-
- if(docursor){
- cursordraw(v->image, cr);
- addtorlist(&rlist, v->cursorr);
- v->cursorr = cr;
- }
-
- qunlock(&drawlock);
-
- count = v->countrect;
- send = v->sendrect;
- if(count == nil || send == nil){
- count = countraw;
- send = sendraw;
- }
-
- ncount = 0;
- for(i=j=0; i<rlist.nrect; i++){
- if(j < i)
- rlist.rect[j] = rlist.rect[i];
- if(rectclip(&rlist.rect[j], v->dim))
- ncount += (*count)(v, rlist.rect[j++]);
- }
- rlist.nrect = j;
-
- if(doresize == 0 && ncount == 0 && dowarp == 0)
- return 0;
-
- if(verbose > 1){
- fprint(2, "sendupdate: rlist.nrect=%d, ncount=%d\n", rlist.nrect, ncount);
- t1 = nsec();
- ooffset = Boffset(&v->out);
- }
-
- if(doresize && v->canresize == 1){
- doresize = 0;
-
- vncwrchar(v, MFrameUpdate);
- vncwrchar(v, 0);
- vncwrshort(v, 1);
- vncwrrect(v, v->dim);
- vncwrlong(v, EncDesktopSize);
- }
-
- vncwrchar(v, MFrameUpdate);
- vncwrchar(v, 0);
- vncwrshort(v, doresize+ncount+dowarp);
-
- if(doresize){
- vncwrrect(v, gscreen->r);
- vncwrlong(v, EncXDesktopSize);
- vncwrlong(v, 1<<24);
- vncwrlong(v, v->screen[0].id);
- vncwrrect(v, v->screen[0].rect);
- vncwrlong(v, v->screen[0].flags);
- }
-
- nsend = 0;
- for(i=0; i<rlist.nrect; i++)
- nsend += (*send)(v, rlist.rect[i]);
-
- if(ncount != nsend){
- fprint(2, "%V: ncount=%d, nsend=%d; hanging up\n", v, ncount, nsend);
- vnchungup(v);
- }
-
- if(dowarp){
- vncwrrect(v, Rect(warppt.x, warppt.y, warppt.x+1, warppt.y+1));
- vncwrlong(v, EncMouseWarp);
- }
-
- if(verbose > 1){
- t1 = nsec() - t1;
- fprint(2, " in %lldms, %lld bytes\n", t1/1000000, Boffset(&v->out) - ooffset);
- }
-
- freerlist(&rlist);
- return 1;
-}
-
-/*
- * Update the snarf buffer if it has changed.
- */
-static void
-updatesnarf(Vncs *v)
-{
- char *buf;
- int len;
-
- if(v->snarfvers == snarf.vers)
- return;
- qlock(&snarf);
- len = snarf.n;
- buf = malloc(len);
- if(buf == nil){
- qunlock(&snarf);
- return;
- }
- memmove(buf, snarf.buf, len);
- v->snarfvers = snarf.vers;
- qunlock(&snarf);
-
- vncwrchar(v, MSCut);
- vncwrbytes(v, "pad", 3);
- vncwrlong(v, len);
- vncwrbytes(v, buf, len);
- free(buf);
-}
-
-/*
- * Continually update one client.
- */
-static void
-clientwriteproc(Vncs *v)
-{
- ulong last = 0;
-
- procsetname("write %V", v);
- while(!v->ndead){
- sleep(sleeptime);
- updatesnarf(v);
- if(v->updatereq != last && updateimage(v))
- last++;
- vncflush(v);
- }
- vnchungup(v);
-}
-
--- a/sys/src/cmd/vnc/vncs.h
+++ /dev/null
@@ -1,54 +1,0 @@
-typedef struct Rlist Rlist;
-typedef struct Vncs Vncs;
-
-struct Rlist
-{
- Rectangle bbox;
- int maxrect;
- int nrect;
- Rectangle *rect;
-};
-
-struct Vncs
-{
- Vnc;
-
- Vncs *next;
- char remote[NETPATHLEN];
- char netpath[NETPATHLEN];
-
- char *encname;
- int (*countrect)(Vncs*, Rectangle);
- int (*sendrect)(Vncs*, Rectangle);
- int copyrect;
- int canwarp;
- int dowarp;
- Point warppt;
-
- ulong updatereq;
-
- Rlist rlist;
- int ndead;
- int nproc;
- int cursorver;
- Point cursorpos;
- Rectangle cursorr;
- int snarfvers;
-
- Memimage *image;
- ulong imagechan;
-};
-
-/* rre.c */
-int countcorre(Vncs*, Rectangle);
-int counthextile(Vncs*, Rectangle);
-int countraw(Vncs*, Rectangle);
-int countrre(Vncs*, Rectangle);
-int sendcorre(Vncs*, Rectangle);
-int sendhextile(Vncs*, Rectangle);
-int sendraw(Vncs*, Rectangle);
-int sendrre(Vncs*, Rectangle);
-
-/* rlist.c */
-void addtorlist(Rlist*, Rectangle);
-void freerlist(Rlist*);
--- a/sys/src/cmd/vnc/vncv.c
+++ /dev/null
@@ -1,205 +1,0 @@
-#include "vnc.h"
-#include "vncv.h"
-#include <libsec.h>
-
-char* charset = "utf-8";
-char* encodings = "copyrect hextile corre rre raw mousewarp desktopsize xdesktopsize";
-int bpp12;
-int shared;
-int verbose;
-Vnc* vnc;
-int mousefd;
-int tls;
-
-
-static int vncstart(Vnc*, int);
-
-enum
-{
- NProcs = 4
-};
-
-static int pids[NProcs];
-static char killkin[] = "die vnc kin";
-
-/*
- * called by any proc when exiting to tear everything down.
- */
-static void
-shutdown(void)
-{
- int i, pid;
-
- hangup(vnc->ctlfd);
- close(vnc->ctlfd);
- vnc->ctlfd = -1;
- close(vnc->datafd);
- vnc->datafd = -1;
-
- pid = getpid();
- for(i = 0; i < NProcs; i++)
- if(pids[i] != 0 && pids[i] != pid)
- postnote(PNPROC, pids[i], killkin);
-}
-
-char*
-netmkvncaddr(char *server)
-{
- char *p, portstr[NETPATHLEN];
- int port;
-
- /* leave execnet dial strings alone */
- if(strncmp(server, "exec!", 5) == 0)
- return server;
-
- port = 5900;
- if(tls)
- port = 35729;
- if((p = strchr(server, ']')) == nil)
- p = server;
- if((p = strchr(p, ':')) != nil) {
- *p++ = '\0';
- port += atoi(p);
- }
- snprint(portstr, sizeof portstr, "%d", port);
- return netmkaddr(server, "tcp", portstr);
-}
-
-void
-vnchungup(Vnc*)
-{
- sysfatal("connection closed");
-}
-
-void
-usage(void)
-{
- fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-l charset] [-csv] host[:n]\n");
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- int p, dfd, cfd, shared;
- char *keypattern, *label;
-
- keypattern = nil;
- shared = 0;
- ARGBEGIN{
- case 'c':
- bpp12 = 1;
- break;
- case 'e':
- encodings = EARGF(usage());
- break;
- case 's':
- shared = 1;
- break;
- case 't':
- tls = 1;
- break;
- case 'v':
- verbose++;
- break;
- case 'k':
- keypattern = EARGF(usage());
- break;
- case 'l':
- charset = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND;
-
- if(argc != 1)
- usage();
-
- dfd = dial(netmkvncaddr(argv[0]), nil, nil, &cfd);
- if(dfd < 0)
- sysfatal("cannot dial %s: %r", argv[0]);
- if(tls){
- TLSconn conn;
-
- memset(&conn, 0, sizeof(conn));
- if((dfd = tlsClient(dfd, &conn)) < 0)
- sysfatal("tlsClient: %r");
- /* XXX check thumbprint */
- free(conn.cert);
- free(conn.sessionID);
- }
- vnc = vncinit(dfd, cfd, nil);
- vnc->srvaddr = strdup(argv[0]);
-
- if(vnchandshake(vnc) < 0)
- sysfatal("handshake failure: %r");
- if(vncauth(vnc, keypattern) < 0)
- sysfatal("authentication failure: %r");
- if(vncstart(vnc, shared) < 0)
- sysfatal("init failure: %r");
-
- label = smprint("vnc %s", argv[0]);
- if(initdraw(0, 0, label) < 0)
- sysfatal("initdraw: %r");
- free(label);
- display->locking = 1;
- unlockdisplay(display);
-
- choosecolor(vnc);
- sendencodings(vnc);
- initmouse();
-
- rfork(RFREND);
- atexit(shutdown);
- pids[0] = getpid();
-
- switch(p = rfork(RFPROC|RFMEM)){
- case -1:
- sysfatal("rfork: %r");
- default:
- break;
- case 0:
- atexit(shutdown);
- readfromserver(vnc);
- exits(nil);
- }
- pids[1] = p;
-
- switch(p = rfork(RFPROC|RFMEM)){
- case -1:
- sysfatal("rfork: %r");
- default:
- break;
- case 0:
- atexit(shutdown);
- checksnarf(vnc);
- exits(nil);
- }
- pids[2] = p;
-
- switch(p = rfork(RFPROC|RFMEM)){
- case -1:
- sysfatal("rfork: %r");
- default:
- break;
- case 0:
- atexit(shutdown);
- readkbd(vnc);
- exits(nil);
- }
- pids[3] = p;
-
- readmouse(vnc);
- exits(nil);
-}
-
-static int
-vncstart(Vnc *v, int shared)
-{
- vncwrchar(v, shared);
- vncflush(v);
- v->dim = Rpt(ZP, vncrdpoint(v));
- v->Pixfmt = vncrdpixfmt(v);
- v->name = vncrdstring(v);
- return 0;
-}
--- a/sys/src/cmd/vnc/vncv.h
+++ /dev/null
@@ -1,28 +1,0 @@
-/* color.c */
-extern void choosecolor(Vnc*);
-extern void (*cvtpixels)(uchar*, uchar*, int);
-extern void settranslation(Vnc*);
-
-/* draw.c */
-extern void sendencodings(Vnc*);
-extern void requestupdate(Vnc*, int);
-extern void readfromserver(Vnc*);
-
-extern uchar zero[];
-
-/* vncv.c */
-extern char *charset;
-extern char *encodings;
-extern int bpp12;
-extern Vnc* vnc;
-extern int mousefd;
-
-/* wsys.c */
-extern void adjustwin(Vnc*, int);
-extern void readkbd(Vnc*);
-extern void initmouse(void);
-extern void mousewarp(Point);
-extern void readmouse(Vnc*);
-extern void senddim(Vnc*);
-extern void writesnarf(Vnc*, long);
-extern void checksnarf(Vnc*);
--- a/sys/src/cmd/vnc/wsys.c
+++ /dev/null
@@ -1,323 +1,0 @@
-#include "vnc.h"
-#include "vncv.h"
-#include <cursor.h>
-
-typedef struct Cursor Cursor;
-
-typedef struct Mouse Mouse;
-struct Mouse {
- int buttons;
- Point xy;
-};
-
-void
-adjustwin(Vnc *v, int force)
-{
- int fd;
- Point d;
-
- if(force)
- d = v->dim.max;
- else {
- /*
- * limit the window to at most the vnc server's size
- */
- d = subpt(screen->r.max, screen->r.min);
- if(d.x > v->dim.max.x){
- d.x = v->dim.max.x;
- force = 1;
- }
- if(d.y > v->dim.max.y){
- d.y = v->dim.max.y;
- force = 1;
- }
- }
- if(force) {
- fd = open("/dev/wctl", OWRITE);
- if(fd >= 0){
- fprint(fd, "resize -dx %d -dy %d", d.x+2*Borderwidth, d.y+2*Borderwidth);
- close(fd);
- }
- }
-}
-
-static void
-resized(int first)
-{
- lockdisplay(display);
- if(getwindow(display, Refnone) < 0)
- sysfatal("internal error: can't get the window image");
- if((vnc->canresize&2) == 0)
- adjustwin(vnc, first);
- unlockdisplay(display);
- requestupdate(vnc, 0);
-}
-
-static Cursor dotcursor = {
- {-7, -7},
- {0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x03, 0xc0,
- 0x07, 0xe0,
- 0x0f, 0xf0,
- 0x0f, 0xf0,
- 0x0f, 0xf0,
- 0x07, 0xe0,
- 0x03, 0xc0,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, },
- {0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x03, 0xc0,
- 0x07, 0xe0,
- 0x07, 0xe0,
- 0x07, 0xe0,
- 0x03, 0xc0,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00, }
-};
-
-static void
-mouseevent(Vnc *v, Mouse m)
-{
- vnclock(v);
- vncwrchar(v, MMouse);
- vncwrchar(v, m.buttons);
- vncwrpoint(v, m.xy);
- vncflush(v);
- vncunlock(v);
-}
-
-void
-mousewarp(Point pt)
-{
- pt = addpt(pt, screen->r.min);
- if(fprint(mousefd, "m%d %d", pt.x, pt.y) < 0)
- fprint(2, "mousefd write: %r\n");
-}
-
-void
-initmouse(void)
-{
- char buf[1024];
-
- snprint(buf, sizeof buf, "%s/mouse", display->devdir);
- if((mousefd = open(buf, ORDWR)) < 0)
- sysfatal("open %s: %r", buf);
-}
-
-enum {
- EventSize = 1+4*12
-};
-void
-readmouse(Vnc *v)
-{
- int cursorfd, len, n;
- char buf[10*EventSize], *start, *end;
- uchar curs[2*4+2*2*16];
- Cursor *cs;
- Mouse m;
-
- cs = &dotcursor;
-
- snprint(buf, sizeof buf, "%s/cursor", display->devdir);
- if((cursorfd = open(buf, OWRITE)) < 0)
- sysfatal("open %s: %r", buf);
-
- BPLONG(curs+0*4, cs->offset.x);
- BPLONG(curs+1*4, cs->offset.y);
- memmove(curs+2*4, cs->clr, 2*2*16);
- write(cursorfd, curs, sizeof curs);
-
- resized(1);
- start = end = buf;
- len = 0;
- for(;;){
- if((n = read(mousefd, end, sizeof(buf) - (end - buf))) < 0)
- sysfatal("read mouse failed");
-
- len += n;
- end += n;
- while(len >= EventSize){
- if(*start == 'm'){
- m.xy.x = atoi(start+1);
- m.xy.y = atoi(start+1+12);
- m.buttons = atoi(start+1+2*12) & 0x1F;
- m.xy = subpt(m.xy, screen->r.min);
- if(ptinrect(m.xy, v->dim)){
- mouseevent(v, m);
- /* send wheel button *release* */
- if ((m.buttons & 0x7) != m.buttons) {
- m.buttons &= 0x7;
- mouseevent(v, m);
- }
- }
- } else
- resized(0);
- start += EventSize;
- len -= EventSize;
- }
- if(start - buf > sizeof(buf) - EventSize){
- memmove(buf, start, len);
- start = buf;
- end = start+len;
- }
- }
-}
-
-static int
-tcs(int fd0, int fd1)
-{
- int pfd[2];
-
- if(strcmp(charset, "utf-8") == 0)
- goto Dup;
- if(pipe(pfd) < 0)
- goto Dup;
- switch(rfork(RFPROC|RFFDG|RFMEM)){
- case -1:
- close(pfd[0]);
- close(pfd[1]);
- goto Dup;
- case 0:
- if(fd0 < 0){
- dup(pfd[0], 0);
- dup(fd1, 1);
- close(fd1);
- } else {
- dup(pfd[0], 1);
- dup(fd0, 0);
- close(fd0);
- }
- close(pfd[0]);
- close(pfd[1]);
- execl("/bin/tcs", "tcs", fd0 < 0 ? "-f" : "-t", charset, nil);
- execl("/bin/cat", "cat", nil);
- _exits(0);
- }
- close(pfd[0]);
- return pfd[1];
-Dup:
- return dup(fd0 < 0 ? fd1 : fd0, -1);
-}
-
-static int snarffd = -1;
-static ulong snarfvers;
-
-static int
-gotsnarf(void)
-{
- Dir *dir;
- int ret;
-
- if(snarffd < 0 || (dir = dirfstat(snarffd)) == nil)
- return 0;
-
- ret = dir->qid.vers != snarfvers;
- snarfvers = dir->qid.vers;
- free(dir);
-
- return ret;
-}
-
-void
-writesnarf(Vnc *v, long n)
-{
- uchar buf[8192];
- int fd, sfd;
- long m;
-
- vnclock(v);
- fd = -1;
- if((sfd = create("/dev/snarf", OWRITE, 0666)) >= 0){
- fd = tcs(-1, sfd);
- close(sfd);
- }
- if(fd < 0)
- vncgobble(v, n);
- else {
- while(n > 0){
- m = n;
- if(m > sizeof(buf))
- m = sizeof(buf);
- vncrdbytes(v, buf, m);
- n -= m;
- write(fd, buf, m);
- }
- close(fd);
- waitpid();
- }
- gotsnarf();
- vncunlock(v);
-}
-
-char *
-getsnarf(int *sz)
-{
- char *snarf, *p;
- int fd, n, c;
-
- *sz =0;
- n = 8192;
- p = snarf = malloc(n);
-
- seek(snarffd, 0, 0);
- if((fd = tcs(snarffd, -1)) >= 0){
- while((c = read(fd, p, n)) > 0){
- p += c;
- n -= c;
- *sz += c;
- if (n == 0){
- snarf = realloc(snarf, *sz + 8192);
- p = snarf + *sz;
- n = 8192;
- }
- }
- close(fd);
- waitpid();
- }
- return snarf;
-}
-
-void
-checksnarf(Vnc *v)
-{
- char *snarf;
- int len;
-
- if(snarffd < 0){
- snarffd = open("/dev/snarf", OREAD);
- if(snarffd < 0)
- sysfatal("can't open /dev/snarf: %r");
- }
-
- for(;;){
- sleep(1000);
-
- vnclock(v);
- if(gotsnarf()){
- snarf = getsnarf(&len);
-
- vncwrchar(v, MCCut);
- vncwrbytes(v, "pad", 3);
- vncwrlong(v, len);
- vncwrbytes(v, snarf, len);
- vncflush(v);
-
- free(snarf);
- }
- vncunlock(v);
- }
-}