123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <thread.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <frame.h>
- #include "flayer.h"
- #include "samterm.h"
- int cursorfd;
- int plumbfd = -1;
- int input;
- int got;
- int block;
- int kbdc;
- int resized;
- uchar* hostp;
- uchar* hoststop;
- uchar* plumbbase;
- uchar* plumbp;
- uchar* plumbstop;
- Channel* plumbc;
- Channel* hostc;
- Mousectl* mousectl;
- Mouse* mousep;
- Keyboardctl* keyboardctl;
- void panic(char*);
- void
- closeio(void)
- {
- closekeyboard(keyboardctl);
- closemouse(mousectl);
- }
- void
- initio(void)
- {
- threadsetname("main");
- mousectl = initmouse(nil, display->image);
- if(mousectl == nil) {
- fprint(2, "samterm: mouse init failed: %r\n");
- threadexitsall("mouse");
- }
- mousep = (Mouse*)mousectl;
- keyboardctl = initkeyboard(nil);
- if(keyboardctl == nil) {
- fprint(2, "samterm: keyboard init failed: %r\n");
- threadexitsall("kbd");
- }
- atexit(closeio);
- hoststart();
- if(plumbstart() < 0)
- extstart();
- }
- void
- getmouse(void)
- {
- if(readmouse(mousectl) < 0)
- panic("mouse");
- }
- void
- mouseunblock(void)
- {
- got &= ~(1 << RMouse);
- }
- void
- kbdblock(void)
- { /* ca suffit */
- block = (1 << RKeyboard) | (1 << RPlumb);
- }
- int
- button(int but)
- {
- getmouse();
- return mousep->buttons & (1 << (but - 1));
- }
- void
- externload(int i)
- {
- plumbbase = malloc(plumbbuf[i].n);
- if(plumbbase == 0)
- return;
- memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);
- plumbp = plumbbase;
- plumbstop = plumbbase + plumbbuf[i].n;
- got |= 1 << RPlumb;
- }
- int
- waitforio(void)
- {
- Alt alts[NRes + 1];
- Rune r;
- int i;
- ulong type;
- again:
- alts[RPlumb].c = plumbc;
- alts[RPlumb].v = &i;
- alts[RPlumb].op = CHANRCV;
- if((block & (1 << RPlumb)) || plumbc == nil)
- alts[RPlumb].op = CHANNOP;
- alts[RHost].c = hostc;
- alts[RHost].v = &i;
- alts[RHost].op = CHANRCV;
- if(block & (1 << RHost))
- alts[RHost].op = CHANNOP;
- alts[RKeyboard].c = keyboardctl->c;
- alts[RKeyboard].v = &r;
- alts[RKeyboard].op = CHANRCV;
- if(block & (1 << RKeyboard))
- alts[RKeyboard].op = CHANNOP;
- alts[RMouse].c = mousectl->c;
- alts[RMouse].v = (Mouse*)mousectl;
- alts[RMouse].op = CHANRCV;
- if(block & (1 << RMouse))
- alts[RMouse].op = CHANNOP;
- alts[RResize].c = mousectl->resizec;
- alts[RResize].v = nil;
- alts[RResize].op = CHANRCV;
- if(block & (1 << RResize))
- alts[RResize].op = CHANNOP;
- alts[NRes].op = CHANEND;
- if(got & ~block)
- return got & ~block;
- flushimage(display, 1);
- type = alt(alts);
- if(!(type < NRes)) {
- /* coverity wants to make sure type cant do an INT_MAX shift when we return */
- fprint(2, "samterm: waited wrong: %lx\n", type);
- panic("wait");
- }
- switch(type) {
- case RHost:
- hostp = hostbuf[i].data;
- hoststop = hostbuf[i].data + hostbuf[i].n;
- block = 0;
- break;
- case RPlumb:
- externload(i);
- break;
- case RKeyboard:
- kbdc = r;
- break;
- case RMouse:
- break;
- case RResize:
- resized = 1;
- /* do the resize in line if we've finished initializing and we're not in a blocking state */
- if(hasunlocked && block == 0 && RESIZED())
- resize();
- goto again;
- }
- got |= 1 << type;
- return got;
- }
- int
- rcvchar(void)
- {
- int c;
- if(!(got & (1 << RHost)))
- return -1;
- c = *hostp++;
- if(hostp == hoststop)
- got &= ~(1 << RHost);
- return c;
- }
- char*
- rcvstring(void)
- {
- *hoststop = 0;
- got &= ~(1 << RHost);
- return (char*)hostp;
- }
- int
- getch(void)
- {
- int c;
- while((c = rcvchar()) == -1) {
- block = ~(1 << RHost);
- waitforio();
- block = 0;
- }
- return c;
- }
- int
- externchar(void)
- {
- Rune r;
- loop:
- if(got & ((1 << RPlumb) & ~block)) {
- plumbp += chartorune(&r, (char*)plumbp);
- if(plumbp >= plumbstop) {
- got &= ~(1 << RPlumb);
- free(plumbbase);
- }
- if(r == 0)
- goto loop;
- return r;
- }
- return -1;
- }
- int kpeekc = -1;
- int
- ecankbd(void)
- {
- Rune r;
- if(kpeekc >= 0)
- return 1;
- if(nbrecv(keyboardctl->c, &r) > 0) {
- kpeekc = r;
- return 1;
- }
- return 0;
- }
- int
- ekbd(void)
- {
- int c;
- Rune r;
- if(kpeekc >= 0) {
- c = kpeekc;
- kpeekc = -1;
- return c;
- }
- if(recv(keyboardctl->c, &r) < 0) {
- fprint(2, "samterm: keybard recv error: %r\n");
- panic("kbd");
- }
- return r;
- }
- int
- kbdchar(void)
- {
- int c, i;
- c = externchar();
- if(c > 0)
- return c;
- if(got & (1 << RKeyboard)) {
- c = kbdc;
- kbdc = -1;
- got &= ~(1 << RKeyboard);
- return c;
- }
- while(plumbc != nil && nbrecv(plumbc, &i) > 0) {
- externload(i);
- c = externchar();
- if(c > 0)
- return c;
- }
- if(!ecankbd())
- return -1;
- return ekbd();
- }
- int
- qpeekc(void)
- {
- return kbdc;
- }
- int
- RESIZED(void)
- {
- if(resized) {
- if(getwindow(display, Refnone) < 0)
- panic("can't reattach to window");
- resized = 0;
- return 1;
- }
- return 0;
- }
|