xref: /plan9-contrib/sys/src/cmd/samterm/io.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <libg.h>
4 #include <frame.h>
5 #include "flayer.h"
6 #include "samterm.h"
7 
8 int	cursorfd;
9 int	input;
10 int	got;
11 int	block;
12 int	kbdc;
13 int	reshaped;
14 uchar	*hostp;
15 uchar	*hoststop;
16 uchar	*externbase;
17 uchar	*externp;
18 uchar	*externstop;
19 void	panic(char*);
20 
21 void
22 initio(void){
23 	einit(Emouse|Ekeyboard);
24 	estart(Ehost, 0, 0);
25 	extstart();
26 }
27 
28 void
29 frgetmouse(void)
30 {
31 	mouse = emouse();
32 }
33 
34 void
35 mouseunblock(void)
36 {
37 	got &= ~Emouse;
38 }
39 
40 void
41 kbdblock(void)
42 {		/* ca suffit */
43 	block = Ekeyboard|Eextern;
44 }
45 
46 int
47 button(int but)
48 {
49 	frgetmouse();
50 	return mouse.buttons&(1<<(but-1));
51 }
52 
53 void
54 externload(Event *e)
55 {
56 	externbase = malloc(e->n);
57 	if(externbase == 0)
58 		return;
59 	memmove(externbase, e->data, e->n);
60 	externp = externbase;
61 	externstop = externbase + e->n;
62 	got |= Eextern;
63 }
64 
65 int
66 waitforio(void)
67 {
68 	ulong type;
69 	static Event e;
70 
71 	if(got & ~block)
72 		return got & ~block;
73 	type = eread(~(got|block), &e);
74 	switch(type){
75 	case Ehost:
76 		hostp = e.data;
77 		hoststop = hostp + e.n;
78 		block = 0;
79 		break;
80 	case Eextern:
81 		externload(&e);
82 		break;
83 	case Ekeyboard:
84 		kbdc = e.kbdc;
85 		break;
86 	case Emouse:
87 		mouse = e.mouse;
88 		break;
89 	}
90 	got |= type;
91 	return got;
92 }
93 
94 int
95 rcvchar(void)
96 {
97 	int c;
98 
99 	if(!(got & Ehost))
100 		return -1;
101 	c = *hostp++;
102 	if(hostp == hoststop)
103 		got &= ~Ehost;
104 	return c;
105 }
106 
107 char*
108 rcvstring(void)
109 {
110 	*hoststop = 0;
111 	got &= ~Ehost;
112 	return (char*)hostp;
113 }
114 
115 int
116 getch(void)
117 {
118 	int c;
119 
120 	while((c = rcvchar()) == -1){
121 		block = ~Ehost;
122 		waitforio();
123 		block = 0;
124 	}
125 	return c;
126 }
127 
128 int
129 externchar(void)
130 {
131 	Rune r;
132 
133     loop:
134 	if(got & (Eextern & ~block)){
135 		externp += chartorune(&r, (char*)externp);
136 		if(externp >= externstop){
137 			got &= ~Eextern;
138 			free(externbase);
139 		}
140 		if(r == 0)
141 			goto loop;
142 		return r;
143 	}
144 	return -1;
145 }
146 
147 int
148 kbdchar(void)
149 {
150 	int c;
151 	static Event e;
152 
153 	c = externchar();
154 	if(c > 0)
155 		return c;
156 	if(got & Ekeyboard){
157 		c = kbdc;
158 		kbdc = -1;
159 		got &= ~Ekeyboard;
160 		return c;
161 	}
162 	while(ecanread(Eextern)){
163 		eread(Eextern, &e);
164 		externload(&e);
165 		c = externchar();
166 		if(c > 0)
167 			return c;
168 	}
169 	if(!ecankbd())
170 		return -1;
171 	return ekbd();
172 }
173 
174 int
175 qpeekc(void)
176 {
177 	return kbdc;
178 }
179 
180 void
181 ereshaped(Rectangle r)
182 {
183 	USED(r);
184 
185 	reshaped = 1;
186 }
187 
188 int
189 RESHAPED(void)
190 {
191 	if(reshaped){
192 		screen.r = bscreenrect(&screen.clipr);
193 		reshaped = 0;
194 		return 1;
195 	}
196 	return 0;
197 }
198 
199 void
200 mouseexit(void)
201 {
202 	exits(0);
203 }
204