Blame


1 a309537f 2018-11-16 rsc /*
2 a309537f 2018-11-16 rsc This code was taken from 9front repository (https://code.9front.org/hg/plan9front).
3 a309537f 2018-11-16 rsc It is subject to license from 9front, below is a reproduction of the license.
4 a309537f 2018-11-16 rsc
5 a309537f 2018-11-16 rsc Copyright (c) 20XX 9front
6 a309537f 2018-11-16 rsc
7 a309537f 2018-11-16 rsc Permission is hereby granted, free of charge, to any person obtaining a copy
8 a309537f 2018-11-16 rsc of this software and associated documentation files (the "Software"), to deal
9 a309537f 2018-11-16 rsc in the Software without restriction, including without limitation the rights
10 a309537f 2018-11-16 rsc to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 a309537f 2018-11-16 rsc copies of the Software, and to permit persons to whom the Software is
12 a309537f 2018-11-16 rsc furnished to do so, subject to the following conditions:
13 a309537f 2018-11-16 rsc
14 a309537f 2018-11-16 rsc The above copyright notice and this permission notice shall be included in all
15 a309537f 2018-11-16 rsc copies or substantial portions of the Software.
16 a309537f 2018-11-16 rsc
17 a309537f 2018-11-16 rsc THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 a309537f 2018-11-16 rsc IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 a309537f 2018-11-16 rsc FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 a309537f 2018-11-16 rsc AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 a309537f 2018-11-16 rsc LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 a309537f 2018-11-16 rsc OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 a309537f 2018-11-16 rsc SOFTWARE.
24 a309537f 2018-11-16 rsc */
25 a309537f 2018-11-16 rsc #include <u.h>
26 a309537f 2018-11-16 rsc #include <libc.h>
27 a309537f 2018-11-16 rsc #include <draw.h>
28 a309537f 2018-11-16 rsc #include <event.h>
29 a309537f 2018-11-16 rsc #include <keyboard.h>
30 a309537f 2018-11-16 rsc
31 a309537f 2018-11-16 rsc /* additional keyboard codes needed - defined here to avoid API change */
32 a309537f 2018-11-16 rsc enum {
33 a309537f 2018-11-16 rsc Spec= 0xF800,
34 a309537f 2018-11-16 rsc Knack= 0x15,
35 a309537f 2018-11-16 rsc Ksoh= 0x01,
36 a309537f 2018-11-16 rsc Kenq= 0x05,
37 a309537f 2018-11-16 rsc Ketb= 0x17
38 a309537f 2018-11-16 rsc };
39 a309537f 2018-11-16 rsc
40 a309537f 2018-11-16 rsc int
41 a309537f 2018-11-16 rsc eenter(char *ask, char *buf, int len, Mouse *m)
42 a309537f 2018-11-16 rsc {
43 a309537f 2018-11-16 rsc int done, down, tick, n, h, w, l, i;
44 a309537f 2018-11-16 rsc Image *b, *save, *backcol, *bordcol;
45 a309537f 2018-11-16 rsc Point p, o, t;
46 a309537f 2018-11-16 rsc Rectangle r, sc;
47 a309537f 2018-11-16 rsc Event ev;
48 a309537f 2018-11-16 rsc Rune k;
49 a309537f 2018-11-16 rsc
50 a309537f 2018-11-16 rsc o = screen->r.min;
51 a309537f 2018-11-16 rsc backcol = allocimagemix(display, DPurpleblue, DWhite);
52 a309537f 2018-11-16 rsc bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
53 a309537f 2018-11-16 rsc if(backcol == nil || bordcol == nil)
54 a309537f 2018-11-16 rsc return -1;
55 a309537f 2018-11-16 rsc
56 a309537f 2018-11-16 rsc while(ecankbd())
57 a309537f 2018-11-16 rsc ekbd();
58 a309537f 2018-11-16 rsc
59 a309537f 2018-11-16 rsc if(m) o = m->xy;
60 a309537f 2018-11-16 rsc
61 a309537f 2018-11-16 rsc if(buf && len > 0)
62 a309537f 2018-11-16 rsc n = strlen(buf);
63 a309537f 2018-11-16 rsc else {
64 a309537f 2018-11-16 rsc buf = nil;
65 a309537f 2018-11-16 rsc len = 0;
66 a309537f 2018-11-16 rsc n = 0;
67 a309537f 2018-11-16 rsc }
68 a309537f 2018-11-16 rsc
69 a309537f 2018-11-16 rsc k = -1;
70 a309537f 2018-11-16 rsc tick = n;
71 a309537f 2018-11-16 rsc save = nil;
72 a309537f 2018-11-16 rsc done = down = 0;
73 a309537f 2018-11-16 rsc
74 a309537f 2018-11-16 rsc p = stringsize(font, " ");
75 a309537f 2018-11-16 rsc h = p.y;
76 a309537f 2018-11-16 rsc w = p.x;
77 a309537f 2018-11-16 rsc
78 a309537f 2018-11-16 rsc b = screen;
79 a309537f 2018-11-16 rsc sc = b->clipr;
80 a309537f 2018-11-16 rsc replclipr(b, 0, b->r);
81 fafa622a 2020-01-12 rsc t = ZP;
82 a309537f 2018-11-16 rsc
83 a309537f 2018-11-16 rsc while(!done){
84 a309537f 2018-11-16 rsc p = stringsize(font, buf ? buf : "");
85 a309537f 2018-11-16 rsc if(ask && ask[0]){
86 a309537f 2018-11-16 rsc if(buf) p.x += w;
87 a309537f 2018-11-16 rsc p.x += stringwidth(font, ask);
88 a309537f 2018-11-16 rsc }
89 a309537f 2018-11-16 rsc r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
90 a309537f 2018-11-16 rsc p.x = 0;
91 a309537f 2018-11-16 rsc r = rectsubpt(r, p);
92 a309537f 2018-11-16 rsc
93 a309537f 2018-11-16 rsc p = ZP;
94 a309537f 2018-11-16 rsc if(r.min.x < screen->r.min.x)
95 a309537f 2018-11-16 rsc p.x = screen->r.min.x - r.min.x;
96 a309537f 2018-11-16 rsc if(r.min.y < screen->r.min.y)
97 a309537f 2018-11-16 rsc p.y = screen->r.min.y - r.min.y;
98 a309537f 2018-11-16 rsc r = rectaddpt(r, p);
99 a309537f 2018-11-16 rsc p = ZP;
100 a309537f 2018-11-16 rsc if(r.max.x > screen->r.max.x)
101 a309537f 2018-11-16 rsc p.x = r.max.x - screen->r.max.x;
102 a309537f 2018-11-16 rsc if(r.max.y > screen->r.max.y)
103 a309537f 2018-11-16 rsc p.y = r.max.y - screen->r.max.y;
104 a309537f 2018-11-16 rsc r = rectsubpt(r, p);
105 a309537f 2018-11-16 rsc
106 a309537f 2018-11-16 rsc r = insetrect(r, -2);
107 a309537f 2018-11-16 rsc if(save == nil){
108 a309537f 2018-11-16 rsc save = allocimage(display, r, b->chan, 0, DNofill);
109 a309537f 2018-11-16 rsc if(save == nil){
110 a309537f 2018-11-16 rsc n = -1;
111 a309537f 2018-11-16 rsc break;
112 a309537f 2018-11-16 rsc }
113 a309537f 2018-11-16 rsc draw(save, r, b, nil, r.min);
114 a309537f 2018-11-16 rsc }
115 a309537f 2018-11-16 rsc draw(b, r, backcol, nil, ZP);
116 a309537f 2018-11-16 rsc border(b, r, 2, bordcol, ZP);
117 a309537f 2018-11-16 rsc p = addpt(r.min, Pt(6, 6));
118 a309537f 2018-11-16 rsc if(ask && ask[0]){
119 a309537f 2018-11-16 rsc p = string(b, p, bordcol, ZP, font, ask);
120 a309537f 2018-11-16 rsc if(buf) p.x += w;
121 a309537f 2018-11-16 rsc }
122 a309537f 2018-11-16 rsc if(buf){
123 a309537f 2018-11-16 rsc t = p;
124 a309537f 2018-11-16 rsc p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick));
125 a309537f 2018-11-16 rsc draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
126 a309537f 2018-11-16 rsc draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
127 a309537f 2018-11-16 rsc draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
128 a309537f 2018-11-16 rsc p = string(b, p, display->black, ZP, font, buf+tick);
129 a309537f 2018-11-16 rsc }
130 a309537f 2018-11-16 rsc flushimage(display, 1);
131 a309537f 2018-11-16 rsc
132 a309537f 2018-11-16 rsc nodraw:
133 a309537f 2018-11-16 rsc i = Ekeyboard;
134 a309537f 2018-11-16 rsc if(m != nil)
135 a309537f 2018-11-16 rsc i |= Emouse;
136 a309537f 2018-11-16 rsc
137 a309537f 2018-11-16 rsc replclipr(b, 0, sc);
138 a309537f 2018-11-16 rsc i = eread(i, &ev);
139 a309537f 2018-11-16 rsc
140 a309537f 2018-11-16 rsc /* screen might have been resized */
141 a309537f 2018-11-16 rsc if(b != screen || !eqrect(screen->clipr, sc)){
142 a309537f 2018-11-16 rsc freeimage(save);
143 a309537f 2018-11-16 rsc save = nil;
144 a309537f 2018-11-16 rsc }
145 a309537f 2018-11-16 rsc b = screen;
146 a309537f 2018-11-16 rsc sc = b->clipr;
147 a309537f 2018-11-16 rsc replclipr(b, 0, b->r);
148 a309537f 2018-11-16 rsc
149 a309537f 2018-11-16 rsc switch(i){
150 a309537f 2018-11-16 rsc default:
151 a309537f 2018-11-16 rsc done = 1;
152 a309537f 2018-11-16 rsc n = -1;
153 a309537f 2018-11-16 rsc break;
154 a309537f 2018-11-16 rsc case Ekeyboard:
155 a309537f 2018-11-16 rsc k = ev.kbdc;
156 a309537f 2018-11-16 rsc if(buf == nil || k == Keof || k == '\n'){
157 a309537f 2018-11-16 rsc done = 1;
158 a309537f 2018-11-16 rsc break;
159 a309537f 2018-11-16 rsc }
160 a309537f 2018-11-16 rsc if(k == Knack || k == Kesc){
161 a309537f 2018-11-16 rsc done = !n;
162 a309537f 2018-11-16 rsc buf[n = tick = 0] = 0;
163 a309537f 2018-11-16 rsc break;
164 a309537f 2018-11-16 rsc }
165 a309537f 2018-11-16 rsc if(k == Ksoh || k == Khome){
166 a309537f 2018-11-16 rsc tick = 0;
167 a309537f 2018-11-16 rsc continue;
168 a309537f 2018-11-16 rsc }
169 a309537f 2018-11-16 rsc if(k == Kenq || k == Kend){
170 a309537f 2018-11-16 rsc tick = n;
171 a309537f 2018-11-16 rsc continue;
172 a309537f 2018-11-16 rsc }
173 a309537f 2018-11-16 rsc if(k == Kright){
174 a309537f 2018-11-16 rsc if(tick < n)
175 a309537f 2018-11-16 rsc tick += chartorune(&k, buf+tick);
176 a309537f 2018-11-16 rsc continue;
177 a309537f 2018-11-16 rsc }
178 a309537f 2018-11-16 rsc if(k == Kleft){
179 a309537f 2018-11-16 rsc for(i = 0; i < n; i += l){
180 a309537f 2018-11-16 rsc l = chartorune(&k, buf+tick);
181 a309537f 2018-11-16 rsc if(i+l >= tick){
182 a309537f 2018-11-16 rsc tick = i;
183 a309537f 2018-11-16 rsc break;
184 a309537f 2018-11-16 rsc }
185 a309537f 2018-11-16 rsc }
186 a309537f 2018-11-16 rsc continue;
187 a309537f 2018-11-16 rsc }
188 a309537f 2018-11-16 rsc if(k == Ketb){
189 a309537f 2018-11-16 rsc while(tick > 0){
190 a309537f 2018-11-16 rsc tick--;
191 a309537f 2018-11-16 rsc if(tick == 0 ||
192 a309537f 2018-11-16 rsc strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1]))
193 a309537f 2018-11-16 rsc break;
194 a309537f 2018-11-16 rsc }
195 a309537f 2018-11-16 rsc buf[n = tick] = 0;
196 a309537f 2018-11-16 rsc break;
197 a309537f 2018-11-16 rsc }
198 a309537f 2018-11-16 rsc if(k == Kbs){
199 a309537f 2018-11-16 rsc if(tick <= 0)
200 a309537f 2018-11-16 rsc continue;
201 a309537f 2018-11-16 rsc for(i = 0; i < n; i += l){
202 a309537f 2018-11-16 rsc l = chartorune(&k, buf+i);
203 a309537f 2018-11-16 rsc if(i+l >= tick){
204 a309537f 2018-11-16 rsc memmove(buf+i, buf+i+l, n - (i+l));
205 a309537f 2018-11-16 rsc buf[n -= l] = 0;
206 a309537f 2018-11-16 rsc tick -= l;
207 a309537f 2018-11-16 rsc break;
208 a309537f 2018-11-16 rsc }
209 a309537f 2018-11-16 rsc }
210 a309537f 2018-11-16 rsc break;
211 a309537f 2018-11-16 rsc }
212 a309537f 2018-11-16 rsc if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
213 a309537f 2018-11-16 rsc continue;
214 a309537f 2018-11-16 rsc if((len-n) <= (l = runelen(k)))
215 a309537f 2018-11-16 rsc continue;
216 a309537f 2018-11-16 rsc memmove(buf+tick+l, buf+tick, n - tick);
217 a309537f 2018-11-16 rsc runetochar(buf+tick, &k);
218 a309537f 2018-11-16 rsc buf[n += l] = 0;
219 a309537f 2018-11-16 rsc tick += l;
220 a309537f 2018-11-16 rsc break;
221 a309537f 2018-11-16 rsc case Emouse:
222 a309537f 2018-11-16 rsc *m = ev.mouse;
223 a309537f 2018-11-16 rsc if(!ptinrect(m->xy, r)){
224 a309537f 2018-11-16 rsc down = 0;
225 a309537f 2018-11-16 rsc goto nodraw;
226 a309537f 2018-11-16 rsc }
227 a309537f 2018-11-16 rsc if(m->buttons & 7){
228 a309537f 2018-11-16 rsc down = 1;
229 a309537f 2018-11-16 rsc if(buf && m->xy.x >= (t.x - w)){
230 a309537f 2018-11-16 rsc down = 0;
231 a309537f 2018-11-16 rsc for(i = 0; i < n; i += l){
232 a309537f 2018-11-16 rsc l = chartorune(&k, buf+i);
233 a309537f 2018-11-16 rsc t.x += stringnwidth(font, buf+i, 1);
234 a309537f 2018-11-16 rsc if(t.x > m->xy.x)
235 a309537f 2018-11-16 rsc break;
236 a309537f 2018-11-16 rsc }
237 a309537f 2018-11-16 rsc tick = i;
238 a309537f 2018-11-16 rsc }
239 a309537f 2018-11-16 rsc continue;
240 a309537f 2018-11-16 rsc }
241 a309537f 2018-11-16 rsc done = down;
242 a309537f 2018-11-16 rsc break;
243 a309537f 2018-11-16 rsc }
244 a309537f 2018-11-16 rsc if(save){
245 a309537f 2018-11-16 rsc draw(b, save->r, save, nil, save->r.min);
246 a309537f 2018-11-16 rsc freeimage(save);
247 a309537f 2018-11-16 rsc save = nil;
248 a309537f 2018-11-16 rsc }
249 a309537f 2018-11-16 rsc }
250 a309537f 2018-11-16 rsc
251 a309537f 2018-11-16 rsc replclipr(b, 0, sc);
252 a309537f 2018-11-16 rsc
253 a309537f 2018-11-16 rsc freeimage(backcol);
254 a309537f 2018-11-16 rsc freeimage(bordcol);
255 a309537f 2018-11-16 rsc flushimage(display, 1);
256 a309537f 2018-11-16 rsc
257 a309537f 2018-11-16 rsc return n;
258 a309537f 2018-11-16 rsc }