URI: 
       tio.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tio.c (4793B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <thread.h>
            5 #include <mouse.h>
            6 #include <cursor.h>
            7 #include <keyboard.h>
            8 #include <frame.h>
            9 #include "flayer.h"
           10 #include "samterm.h"
           11 
           12 int        protodebug;
           13 int        cursorfd;
           14 int        plumbfd = -1;
           15 int        input;
           16 int        got;
           17 int        block;
           18 int        kbdc;
           19 int        resized;
           20 uchar        *hostp;
           21 uchar        *hoststop;
           22 uchar        *plumbbase;
           23 uchar        *plumbp;
           24 uchar        *plumbstop;
           25 Channel        *plumbc;
           26 Channel        *hostc;
           27 Mousectl        *mousectl;
           28 Mouse        *mousep;
           29 Keyboardctl *keyboardctl;
           30 void        panic(char*);
           31 
           32 void
           33 initio(void)
           34 {
           35         threadsetname("main");
           36         if(protodebug) print("mouse\n");
           37         mousectl = initmouse(nil, display->image);
           38         if(mousectl == nil){
           39                 fprint(2, "samterm: mouse init failed: %r\n");
           40                 threadexitsall("mouse");
           41         }
           42         mousep = &mousectl->m;
           43         if(protodebug) print("kbd\n");
           44         keyboardctl = initkeyboard(nil);
           45         if(keyboardctl == nil){
           46                 fprint(2, "samterm: keyboard init failed: %r\n");
           47                 threadexitsall("kbd");
           48         }
           49         if(protodebug) print("hoststart\n");
           50         hoststart();
           51         if(protodebug) print("plumbstart\n");
           52         if(plumbstart() < 0){
           53                 if(protodebug) print("extstart\n");
           54                 extstart();
           55         }
           56         if(protodebug) print("initio done\n");
           57 }
           58 
           59 void
           60 getmouse(void)
           61 {
           62         if(readmouse(mousectl) < 0)
           63                 panic("mouse");
           64 }
           65 
           66 void
           67 mouseunblock(void)
           68 {
           69         got &= ~(1<<RMouse);
           70 }
           71 
           72 void
           73 kbdblock(void)
           74 {                /* ca suffit */
           75         block = (1<<RKeyboard)|(1<<RPlumb);
           76 }
           77 
           78 int
           79 button(int but)
           80 {
           81         getmouse();
           82         return mousep->buttons&(1<<(but-1));
           83 }
           84 
           85 void
           86 externload(int i)
           87 {
           88         drawtopwindow();
           89         plumbbase = malloc(plumbbuf[i].n);
           90         if(plumbbase == 0)
           91                 return;
           92         memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);
           93         plumbp = plumbbase;
           94         plumbstop = plumbbase + plumbbuf[i].n;
           95         got |= 1<<RPlumb;
           96 }
           97 
           98 int
           99 waitforio(void)
          100 {
          101         Alt alts[NRes+1];
          102         Rune r;
          103         int i;
          104         ulong type;
          105 
          106 again:
          107         alts[RPlumb].c = plumbc;
          108         alts[RPlumb].v = &i;
          109         alts[RPlumb].op = CHANRCV;
          110         if((block & (1<<RPlumb)) || plumbc == nil)
          111                 alts[RPlumb].op = CHANNOP;
          112 
          113         alts[RHost].c = hostc;
          114         alts[RHost].v = &i;
          115         alts[RHost].op = CHANRCV;
          116         if(block & (1<<RHost))
          117                 alts[RHost].op = CHANNOP;
          118 
          119         alts[RKeyboard].c = keyboardctl->c;
          120         alts[RKeyboard].v = &r;
          121         alts[RKeyboard].op = CHANRCV;
          122         if(block & (1<<RKeyboard))
          123                 alts[RKeyboard].op = CHANNOP;
          124 
          125         alts[RMouse].c = mousectl->c;
          126         alts[RMouse].v = &mousectl->m;
          127         alts[RMouse].op = CHANRCV;
          128         if(block & (1<<RMouse))
          129                 alts[RMouse].op = CHANNOP;
          130 
          131         alts[RResize].c = mousectl->resizec;
          132         alts[RResize].v = nil;
          133         alts[RResize].op = CHANRCV;
          134         if(block & (1<<RResize))
          135                 alts[RResize].op = CHANNOP;
          136 
          137         if(protodebug) print("waitforio %c%c%c%c%c\n",
          138                 "h-"[alts[RHost].op == CHANNOP],
          139                 "k-"[alts[RKeyboard].op == CHANNOP],
          140                 "m-"[alts[RMouse].op == CHANNOP],
          141                 "p-"[alts[RPlumb].op == CHANNOP],
          142                 "R-"[alts[RResize].op == CHANNOP]);
          143 
          144         alts[NRes].op = CHANEND;
          145 
          146         if(got & ~block)
          147                 return got & ~block;
          148         flushimage(display, 1);
          149         type = alt(alts);
          150         switch(type){
          151         case RHost:
          152                 if(0) print("hostalt recv %d %d\n", i, hostbuf[i].n);
          153                 hostp = hostbuf[i].data;
          154                 hoststop = hostbuf[i].data + hostbuf[i].n;
          155                 block = 0;
          156                 break;
          157         case RPlumb:
          158                 externload(i);
          159                 break;
          160         case RKeyboard:
          161                 kbdc = r;
          162                 break;
          163         case RMouse:
          164                 break;
          165         case RResize:
          166                 resized = 1;
          167                 /* do the resize in line if we've finished initializing and we're not in a blocking state */
          168                 if(hasunlocked && block==0 && RESIZED())
          169                         resize();
          170                 goto again;
          171         }
          172         got |= 1<<type;
          173         return got;
          174 }
          175 
          176 int
          177 rcvchar(void)
          178 {
          179         int c;
          180 
          181         if(!(got & (1<<RHost)))
          182                 return -1;
          183         c = *hostp++;
          184         if(hostp == hoststop)
          185                 got &= ~(1<<RHost);
          186         return c;
          187 }
          188 
          189 char*
          190 rcvstring(void)
          191 {
          192         *hoststop = 0;
          193         got &= ~(1<<RHost);
          194         return (char*)hostp;
          195 }
          196 
          197 int
          198 getch(void)
          199 {
          200         int c;
          201 
          202         while((c = rcvchar()) == -1){
          203                 block = ~(1<<RHost);
          204                 waitforio();
          205                 block = 0;
          206         }
          207         return c;
          208 }
          209 
          210 int
          211 externchar(void)
          212 {
          213         Rune r;
          214 
          215     loop:
          216         if(got & ((1<<RPlumb) & ~block)){
          217                 plumbp += chartorune(&r, (char*)plumbp);
          218                 if(plumbp >= plumbstop){
          219                         got &= ~(1<<RPlumb);
          220                         free(plumbbase);
          221                 }
          222                 if(r == 0)
          223                         goto loop;
          224                 return r;
          225         }
          226         return -1;
          227 }
          228 
          229 int kpeekc = -1;
          230 int
          231 ecankbd(void)
          232 {
          233         Rune r;
          234 
          235         if(kpeekc >= 0)
          236                 return 1;
          237         if(nbrecv(keyboardctl->c, &r) > 0){
          238                 kpeekc = r;
          239                 return 1;
          240         }
          241         return 0;
          242 }
          243 
          244 int
          245 ekbd(void)
          246 {
          247         int c;
          248         Rune r;
          249 
          250         if(kpeekc >= 0){
          251                 c = kpeekc;
          252                 kpeekc = -1;
          253                 return c;
          254         }
          255         if(recv(keyboardctl->c, &r) < 0){
          256                 fprint(2, "samterm: keybard recv error: %r\n");
          257                 panic("kbd");
          258         }
          259         return r;
          260 }
          261 
          262 int
          263 kbdchar(void)
          264 {
          265         int c, i;
          266 
          267         c = externchar();
          268         if(c > 0)
          269                 return c;
          270         if(got & (1<<RKeyboard)){
          271                 c = kbdc;
          272                 kbdc = -1;
          273                 got &= ~(1<<RKeyboard);
          274                 return c;
          275         }
          276         while(plumbc!=nil && nbrecv(plumbc, &i)>0){
          277                 externload(i);
          278                 c = externchar();
          279                 if(c > 0)
          280                         return c;
          281         }
          282         if(!ecankbd())
          283                 return -1;
          284         return ekbd();
          285 }
          286 
          287 int
          288 qpeekc(void)
          289 {
          290         return kbdc;
          291 }
          292 
          293 int
          294 RESIZED(void)
          295 {
          296         if(resized){
          297                 if(getwindow(display, Refnone) < 0)
          298                         panic("can't reattach to window");
          299                 resized = 0;
          300                 return 1;
          301         }
          302         return 0;
          303 }