plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

io.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 }