123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- #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
- initio(void)
- {
- threadsetname("main");
- mousectl = initmouse(nil, display->image);
- if(mousectl == nil){
- fprint(2, "samterm: mouse init failed: %r\n");
- threadexitsall("mouse");
- }
- mousep = mousectl;
- keyboardctl = initkeyboard(nil);
- if(keyboardctl == nil){
- fprint(2, "samterm: keyboard init failed: %r\n");
- threadexitsall("kbd");
- }
- 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 = &mousectl->Mouse;
- 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);
- 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;
- }
|