123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- #include <u.h>
- #include <libc.h>
- #include <thread.h>
- #include <draw.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <control.h>
- #include <scribble.h>
- int debug = 0;
- typedef struct Win Win;
- struct Win {
- int n;
- int dirty;
- char *label;
- Control *button;
- };
- Win *win;
- int nwin;
- int mwin;
- int onwin;
- int rows, cols;
- int kbdonly;
- int scribbleleft;
- int winshow;
- Channel *kc;
- Channel *ec;
- Channel *tc;
- Rectangle r, rk, rs, rw;
- Font *keyfont, *keyctlfont;
- enum{
- Back,
- Shade,
- Light,
- Mask,
- Ncol
- };
- enum {
- kbdheight = 2 + 5*13,
- };
- enum {
- Keyback = 0xeeee9eff,
- Keyshade = 0xaaaa55ff,
- Keylight = DWhite,
- Keymask = 0x0C0C0C0C,
- };
- Image *colors[Ncol];
- Control *kbd;
- Control *scrib;
- Control *boxbox;
- Controlset *cs;
- int ctldeletequits = 1;
- int wctl;
- int
- hidden(void)
- {
- char buf[128];
- int n;
- close(wctl);
- if ((wctl = open("/dev/wctl", ORDWR)) < 0)
- return 0;
- n = read(wctl, buf, sizeof buf-1);
- if (n <= 0)
- sysfatal("wctl read: %r");
- buf[n] = 0;
- return strstr(buf, "visible") == nil;
- }
- void
- mousemux(void *v)
- {
- Mouse m;
- Channel *c;
- int ob;
- c = v;
- for(ob = 0;;ob = m.buttons){
- if(recv(c, &m) < 0)
- break;
- if ((m.buttons & 0x20) == 0) {
- if (ob & 0x20) {
- /* hide button just came up */
- if (hidden()) {
- if (debug) fprint(2, "unhide");
- if (fprint(wctl, "unhide") <= 0)
- fprint(2, "unhide failed: %r\n");
- } else {
- if (debug) fprint(2, "hide");
- if (fprint(wctl, "hide") <= 0)
- fprint(2, "hide failed: %r\n");
- }
- } else
- send(cs->mousec, &m);
- }
- }
- }
- void
- refreshwin(void)
- {
- char label[128];
- int i, fd, lfd, n, nr, nw, m;
- Dir *pd;
- if((fd = open("/dev/wsys", OREAD)) < 0)
- return;
- nw = 0;
- /* i'd rather read one at a time but rio won't let me */
- while((nr=dirread(fd, &pd)) > 0){
- for(i=0; i<nr; i++){
- n = atoi(pd[i].name);
- sprint(label, "/dev/wsys/%d/label", n);
- if((lfd = open(label, OREAD)) < 0)
- continue;
- m = read(lfd, label, sizeof(label)-1);
- close(lfd);
- if(m < 0)
- continue;
- label[m] = '\0';
- if(nw < nwin && win[nw].n == n && strcmp(win[nw].label, label)==0){
- nw++;
- continue;
- }
- if(nw < nwin){
- free(win[nw].label);
- win[nw].label = nil;
- }
- if(nw >= mwin){
- mwin += 8;
- win = ctlrealloc(win, mwin*sizeof(win[0]));
- memset(&win[mwin-8], 0, 8*sizeof(win[0]));
- }
- win[nw].n = n;
- win[nw].label = ctlstrdup(label);
- win[nw].dirty = 1;
- sprint(label, "%d", nw);
- if (win[nw].button == nil){
- win[nw].button = createtextbutton(cs, label);
- chanprint(cs->ctl, "%q font keyfont", label);
- chanprint(cs->ctl, "%q image keyback", label);
- chanprint(cs->ctl, "%q pressedtextcolor red", label);
- chanprint(cs->ctl, "%q mask transparent", label);
- chanprint(cs->ctl, "%q border 1", label);
- chanprint(cs->ctl, "%q bordercolor black", label);
- chanprint(cs->ctl, "%q align centerleft", label);
- chanprint(cs->ctl, "%q size 16 %d 512 %d", label, keyfont->height+2, keyfont->height+2);
- controlwire(win[nw].button, "event", ec);
- }
- if (nw >= nwin){
- activate(win[nw].button);
- chanprint(cs->ctl, "cols add %q", label);
- }
- chanprint(cs->ctl, "%q text %q", win[nw].button->name, win[nw].label);
- nw++;
- }
- }
- for(i = nw; i < nwin; i++){
- free(win[i].label);
- win[i].label = nil;
- deactivate(win[i].button);
- chanprint(cs->ctl, "cols remove %q", win[i].button->name);
- }
- nwin = nw;
- close(fd);
- if (rw.max.x)
- chanprint(cs->ctl, "cols rect %R\ncols show", rw);
- }
- void
- resizecontrolset(Controlset*)
- {
- int fd;
- char buf[61];
- if(getwindow(display, Refnone) < 0)
- ctlerror("resize failed: %r");
- if (hidden()) {
- if (debug) fprint(2, "resizecontrolset: hidden\n");
- return;
- }
- fd = open("/dev/screen", OREAD);
- if (fd < 0) {
- r = display->image->r;
- if (debug) fprint(2, "display->imgae->r: %R\n", r);
- } else {
- if (read(fd, buf, 60) != 60)
- sysfatal("resizecontrolset: read: /dev/screen: %r");
- close(fd);
- buf[60] = '\0';
- r.min.x = atoi(buf+1+1*12);
- r.min.y = atoi(buf+1+2*12);
- r.max.x = atoi(buf+1+3*12);
- r.max.y = atoi(buf+1+4*12);
- if (debug) fprint(2, "/dev/screen: %R\n", r);
- }
- r = insetrect(r, 4);
- r.min.y = r.max.y - kbdheight - 2*Borderwidth;
- if (debug) fprint(2, "before eqrect: %R\n", r);
- if (eqrect(r, screen->r) == 0) {
- if (debug) fprint(2, "resizecontrolset: resize %R\n", r);
- if (fprint(wctl, "resize -r %R", insetrect(r, -4)) <= 0) {
- fprint(2, "resizecontrolset: resize failed\n");
- }
- return;
- }
- if (debug) fprint(2, "after eqrect: %R\n", r);
- rk = r;
- if (winshow){
- rw = rk;
- rw.min.x = (3*rk.max.x + rk.min.x)/4;
- rk.max.x = rw.min.x;
- if (debug) fprint(2, "rw: rect %R\n", rw);
- chanprint(cs->ctl, "cols rect %R\ncols show", rw);
- }
- if (kbdonly) {
- chanprint(cs->ctl, "keyboard rect %R\nkeyboard show", rk);
- } else {
- rs = rk;
- if (scribbleleft){
- rk.min.x = (rk.max.x + 3*rk.min.x)/4;
- rs.max.x = rk.min.x;
- }else{
- rk.max.x = (3*rk.max.x + rk.min.x)/4;
- rs.min.x = rk.max.x;
- }
- chanprint(cs->ctl, "keyboard rect %R\nkeyboard show", rk);
- if (debug) fprint(2, "rk: rect %R\nkeyboard show\n", rk);
- chanprint(cs->ctl, "scribble rect %R\nscribble show", rs);
- if (debug) fprint(2, "rs: rect %R\nscribble show\n", rs);
- }
- }
- void
- usage(void)
- {
- fprint(2, "usage: keyboard\n");
- threadexitsall("usage");
- }
- void
- timerproc(void*v)
- {
- Channel *c;
- c = v;
- for(;;){
- sleep(5000);
- sendul(c, 1);
- }
- }
- void
- watchproc(void*)
- {
- for(;;){}
- }
- void
- threadmain(int argc, char *argv[])
- {
- int i, n, kbdfd;
- char str[UTFmax+1];
- Rune r;
- Mousectl *mousectl;
- Channel *mtok;
- char *e, buf[128], *args[8];
- int fd;
- ARGBEGIN{
- case 'w':
- winshow++;
- break;
- case 'l':
- scribbleleft++;
- break;
- case 'n':
- kbdonly++;
- break;
- case 'd':
- ScribbleDebug++;
- debug++;
- break;
- default:
- usage();
- }ARGEND
- if(argc != 0)
- usage();
- kbdfd = open("/dev/kbdin", OWRITE);
- if (kbdfd < 0 && (kbdfd = open("#r/kbdin", OWRITE)) < 0) {
- if (debug) fprint(2, "open %s: %r\n", "#r/kbdin");
- kbdfd = 1;
- }
- initdraw(0, 0, "keyboard");
- mousectl = initmouse(nil, screen);
- wctl = open("/dev/wctl", ORDWR);
- if (wctl < 0) {
- fprint(2, "open %s: %r\n", "/dev/wctl");
- wctl = 2; /* for debugging */
- }
- mtok = chancreate(sizeof(Mouse), 0);
- initcontrols();
- cs = newcontrolset(screen, nil, mtok, mousectl->resizec);
- threadcreate(mousemux, mousectl->c, 4096);
- kc = chancreate(sizeof(char*), 0);
- tc = chancreate(sizeof(int), 1);
- ec = chancreate(sizeof(char*), 1);
- colors[Back] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, Keyback);
- namectlimage(colors[Back], "keyback");
- colors[Light] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, Keylight);
- namectlimage(colors[Light], "keylight");
- colors[Shade] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, Keyshade);
- namectlimage(colors[Shade], "keyshade");
- colors[Mask] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, Keymask);
- namectlimage(colors[Shade], "keymask");
- keyfont = openfont(display, "/lib/font/bit/lucidasans/boldlatin1.6.font");
- namectlfont(keyfont, "keyfont");
- keyctlfont = openfont(display, "/lib/font/bit/lucidasans/unicode.6.font");
- namectlfont(keyctlfont, "keyctlfont");
- kbd = createkeyboard(cs, "keyboard");
- chanprint(cs->ctl, "keyboard font keyfont keyctlfont");
- chanprint(cs->ctl, "keyboard image keyback");
- chanprint(cs->ctl, "keyboard light keylight");
- chanprint(cs->ctl, "keyboard mask keymask");
- chanprint(cs->ctl, "keyboard border 1");
- chanprint(cs->ctl, "keyboard size %d %d %d %d", 246, 2 + 5 * (keyfont->height + 1), 512, 256);
- controlwire(kbd, "event", kc);
- if (kbdonly == 0){
- scrib = createscribble(cs, "scribble");
- if (scrib == nil)
- sysfatal("createscribble");
- chanprint(cs->ctl, "scribble font keyfont");
- chanprint(cs->ctl, "scribble image keyback");
- chanprint(cs->ctl, "scribble border 1");
- controlwire(scrib, "event", kc);
- }
- if (winshow){
- boxbox = createboxbox(cs, "cols");
-
- chanprint(cs->ctl, "cols border 2");
- chanprint(cs->ctl, "cols bordercolor keyback");
- }
- resizecontrolset(nil);
- activate(kbd);
- if (kbdonly == 0)
- activate(scrib);
- if (winshow){
- refreshwin();
- proccreate(timerproc, tc, 2048);
- }
- for(;;){
- Alt a[] = {
- { kc, &e, CHANRCV },
- { ec, &e, CHANRCV },
- { tc, &n, CHANRCV },
- { nil, nil, CHANEND }
- };
- switch(alt(a)){
- case 0: /* Keyboard */
- n = tokenize(e, args, nelem(args));
- if(n == 3)
- if(strcmp(args[0], "keyboard:")==0 || strcmp(args[0], "scribble:")==0)
- if(strcmp(args[1], "value") == 0){
- n = atoi(args[2]);
- if(n <= 0xFFFF){
- r = n;
- i = runetochar(str, &r);
- write(kbdfd, str, i);
- }
- }
- break;
- case 1: /* Button event */
- n = tokenize(e, args, nelem(args));
- if (n != 3 || strcmp(args[1], "value"))
- sysfatal("event string");
- i = atoi(args[0]);
- if (i < 0 || i >= nwin)
- sysfatal("win out of range: %d of %d", i, nwin);
- n = atoi(args[2]);
- if (n){
- sprint(buf, "/dev/wsys/%d/wctl", win[i].n);
- if((fd = open(buf, OWRITE)) >= 0){
- while (write(fd, "top\n", 4) < 0) {
- /* wait until mouse comes up */
- rerrstr(buf, sizeof buf);
- if (strncmp(buf, "action disallowed when mouse active", sizeof buf)){
- fprint(2, "write top: %s\n", buf);
- break;
- }
- sleep(100);
- }
- if (write(fd, "current\n", 8) < 0)
- fprint(2, "write current: %r\n");
- close(fd);
- }
- chanprint(cs->ctl, "%q value 0", win[i].button->name);
- }
- break;
- case 2:
- refreshwin();
- break;
- }
- }
- threadexitsall(nil);
- }
|