v_event.c revision 1.3 1 1.3 christos /* $NetBSD: v_event.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
2 1.1 christos /*-
3 1.1 christos * Copyright (c) 1996
4 1.1 christos * Keith Bostic. All rights reserved.
5 1.1 christos *
6 1.1 christos * See the LICENSE file for redistribution information.
7 1.1 christos */
8 1.1 christos
9 1.1 christos #include "config.h"
10 1.1 christos
11 1.3 christos #include <sys/cdefs.h>
12 1.3 christos #if 0
13 1.1 christos #ifndef lint
14 1.1 christos static const char sccsid[] = "Id: v_event.c,v 8.21 2001/06/25 15:19:31 skimo Exp (Berkeley) Date: 2001/06/25 15:19:31 ";
15 1.1 christos #endif /* not lint */
16 1.3 christos #else
17 1.3 christos __RCSID("$NetBSD: v_event.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
18 1.3 christos #endif
19 1.1 christos
20 1.1 christos #include <sys/types.h>
21 1.1 christos #include <sys/queue.h>
22 1.1 christos #include <sys/time.h>
23 1.1 christos
24 1.1 christos #include <bitstring.h>
25 1.1 christos #include <ctype.h>
26 1.1 christos #include <errno.h>
27 1.1 christos #include <limits.h>
28 1.1 christos #include <stdio.h>
29 1.1 christos #include <stdlib.h>
30 1.1 christos #include <string.h>
31 1.1 christos #include <unistd.h>
32 1.1 christos
33 1.1 christos #include "../common/common.h"
34 1.1 christos #include "../ipc/ip.h"
35 1.1 christos #include "vi.h"
36 1.1 christos
37 1.1 christos /*
38 1.1 christos * v_c_settop --
39 1.1 christos * Scrollbar position.
40 1.1 christos */
41 1.1 christos static int
42 1.1 christos v_c_settop(SCR *sp, VICMD *vp)
43 1.1 christos {
44 1.1 christos SMAP *smp;
45 1.1 christos size_t x = 0, y = LASTLINE(sp); /* Future: change to -1 to not
46 1.1 christos * display the cursor
47 1.1 christos */
48 1.1 christos size_t tx, ty = -1;
49 1.1 christos
50 1.1 christos /*
51 1.1 christos * We want to scroll the screen, without changing the cursor position.
52 1.1 christos * So, we fill the screen map and then flush it to the screen. Then,
53 1.1 christos * set the VIP_S_REFRESH flag so the main vi loop doesn't update the
54 1.1 christos * screen. When the next real command happens, the refresh code will
55 1.1 christos * notice that the screen map is way wrong and fix it.
56 1.1 christos *
57 1.1 christos * XXX
58 1.1 christos * There may be a serious performance problem here -- we're doing no
59 1.1 christos * optimization whatsoever, which means that we're copying the entire
60 1.1 christos * screen out to the X11 screen code on each change.
61 1.1 christos */
62 1.1 christos if (vs_sm_fill(sp, vp->ev.e_lno, P_TOP))
63 1.1 christos return (1);
64 1.1 christos for (smp = HMAP; smp <= TMAP; ++smp) {
65 1.1 christos SMAP_FLUSH(smp);
66 1.1 christos if (vs_line(sp, smp, &ty, &tx))
67 1.1 christos return (1);
68 1.2 christos if (ty != (size_t)-1) {
69 1.1 christos y = ty;
70 1.1 christos x = tx;
71 1.1 christos }
72 1.1 christos }
73 1.1 christos (void)sp->gp->scr_move(sp, y, x);
74 1.1 christos
75 1.1 christos F_SET(VIP(sp), VIP_S_REFRESH);
76 1.1 christos
77 1.1 christos return (sp->gp->scr_refresh(sp, 0));
78 1.1 christos }
79 1.1 christos
80 1.1 christos /*
81 1.1 christos * v_edit --
82 1.1 christos * Edit command.
83 1.1 christos */
84 1.1 christos static int
85 1.1 christos v_edit(SCR *sp, VICMD *vp)
86 1.1 christos {
87 1.1 christos EXCMD cmd;
88 1.1 christos
89 1.1 christos ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
90 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
91 1.1 christos return (v_exec_ex(sp, vp, &cmd));
92 1.1 christos }
93 1.1 christos
94 1.1 christos /*
95 1.1 christos * v_editopt --
96 1.1 christos * Set an option value.
97 1.1 christos */
98 1.1 christos static int
99 1.1 christos v_editopt(SCR *sp, VICMD *vp)
100 1.1 christos {
101 1.1 christos int rval;
102 1.2 christos const char *np;
103 1.1 christos size_t nlen;
104 1.1 christos char *p2;
105 1.1 christos
106 1.1 christos INT2CHAR(sp, vp->ev.e_str2, STRLEN(vp->ev.e_str2)+1, np, nlen);
107 1.1 christos p2 = strdup(np);
108 1.1 christos rval = api_opts_set(sp, vp->ev.e_str1, p2,
109 1.1 christos vp->ev.e_val1, vp->ev.e_val1);
110 1.1 christos if (sp->gp->scr_reply != NULL)
111 1.1 christos (void)sp->gp->scr_reply(sp, rval, NULL);
112 1.1 christos free(p2);
113 1.1 christos return (rval);
114 1.1 christos }
115 1.1 christos
116 1.1 christos /*
117 1.1 christos * v_editsplit --
118 1.1 christos * Edit in a split screen.
119 1.1 christos */
120 1.1 christos static int
121 1.1 christos v_editsplit(SCR *sp, VICMD *vp)
122 1.1 christos {
123 1.1 christos EXCMD cmd;
124 1.1 christos
125 1.1 christos ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
126 1.1 christos F_SET(&cmd, E_NEWSCREEN);
127 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
128 1.1 christos return (v_exec_ex(sp, vp, &cmd));
129 1.1 christos }
130 1.1 christos
131 1.1 christos /*
132 1.1 christos * v_tag --
133 1.1 christos * Tag command.
134 1.1 christos */
135 1.1 christos static int
136 1.1 christos v_tag(SCR *sp, VICMD *vp)
137 1.1 christos {
138 1.1 christos EXCMD cmd;
139 1.1 christos
140 1.1 christos if (v_curword(sp))
141 1.1 christos return (1);
142 1.1 christos
143 1.1 christos ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
144 1.1 christos argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
145 1.1 christos return (v_exec_ex(sp, vp, &cmd));
146 1.1 christos }
147 1.1 christos
148 1.1 christos /*
149 1.1 christos * v_tagas --
150 1.1 christos * Tag on the supplied string.
151 1.1 christos */
152 1.1 christos static int
153 1.1 christos v_tagas(SCR *sp, VICMD *vp)
154 1.1 christos {
155 1.1 christos EXCMD cmd;
156 1.1 christos
157 1.1 christos ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
158 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
159 1.1 christos return (v_exec_ex(sp, vp, &cmd));
160 1.1 christos }
161 1.1 christos
162 1.1 christos /*
163 1.1 christos * v_tagsplit --
164 1.1 christos * Tag in a split screen.
165 1.1 christos */
166 1.1 christos static int
167 1.1 christos v_tagsplit(SCR *sp, VICMD *vp)
168 1.1 christos {
169 1.1 christos EXCMD cmd;
170 1.1 christos
171 1.1 christos if (v_curword(sp))
172 1.1 christos return (1);
173 1.1 christos
174 1.1 christos ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
175 1.1 christos F_SET(&cmd, E_NEWSCREEN);
176 1.1 christos argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
177 1.1 christos return (v_exec_ex(sp, vp, &cmd));
178 1.1 christos }
179 1.1 christos
180 1.1 christos /*
181 1.1 christos * v_quit --
182 1.1 christos * Quit command.
183 1.1 christos */
184 1.1 christos static int
185 1.1 christos v_quit(SCR *sp, VICMD *vp)
186 1.1 christos {
187 1.1 christos EXCMD cmd;
188 1.1 christos
189 1.1 christos ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
190 1.1 christos return (v_exec_ex(sp, vp, &cmd));
191 1.1 christos }
192 1.1 christos
193 1.1 christos /*
194 1.1 christos * v_erepaint --
195 1.1 christos * Repaint selected lines from the screen.
196 1.1 christos *
197 1.1 christos * PUBLIC: int v_erepaint __P((SCR *, EVENT *));
198 1.1 christos */
199 1.1 christos int
200 1.1 christos v_erepaint(SCR *sp, EVENT *evp)
201 1.1 christos {
202 1.1 christos SMAP *smp;
203 1.1 christos
204 1.1 christos for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) {
205 1.1 christos smp = HMAP + evp->e_flno - 1;
206 1.1 christos SMAP_FLUSH(smp);
207 1.1 christos if (vs_line(sp, smp, NULL, NULL))
208 1.1 christos return (1);
209 1.1 christos }
210 1.1 christos return (0);
211 1.1 christos }
212 1.1 christos
213 1.1 christos /*
214 1.1 christos * v_sel_end --
215 1.1 christos * End selection.
216 1.1 christos */
217 1.2 christos static int
218 1.1 christos v_sel_end(SCR *sp, EVENT *evp)
219 1.1 christos {
220 1.1 christos SMAP *smp;
221 1.1 christos VI_PRIVATE *vip;
222 1.1 christos
223 1.1 christos smp = HMAP + evp->e_lno;
224 1.1 christos if (smp > TMAP) {
225 1.1 christos /* XXX */
226 1.1 christos return (1);
227 1.1 christos }
228 1.1 christos
229 1.1 christos vip = VIP(sp);
230 1.1 christos vip->sel.lno = smp->lno;
231 1.1 christos vip->sel.cno =
232 1.1 christos vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
233 1.1 christos return (0);
234 1.1 christos }
235 1.1 christos
236 1.1 christos /*
237 1.1 christos * v_sel_start --
238 1.1 christos * Start selection.
239 1.1 christos */
240 1.2 christos static int
241 1.1 christos v_sel_start(SCR *sp, EVENT *evp)
242 1.1 christos {
243 1.1 christos SMAP *smp;
244 1.1 christos VI_PRIVATE *vip;
245 1.1 christos
246 1.1 christos smp = HMAP + evp->e_lno;
247 1.1 christos if (smp > TMAP) {
248 1.1 christos /* XXX */
249 1.1 christos return (1);
250 1.1 christos }
251 1.1 christos
252 1.1 christos vip = VIP(sp);
253 1.1 christos vip->sel.lno = smp->lno;
254 1.1 christos vip->sel.cno =
255 1.1 christos vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
256 1.1 christos return (0);
257 1.1 christos }
258 1.1 christos
259 1.1 christos /*
260 1.1 christos * v_wq --
261 1.1 christos * Write and quit command.
262 1.1 christos */
263 1.1 christos static int
264 1.1 christos v_wq(SCR *sp, VICMD *vp)
265 1.1 christos {
266 1.1 christos EXCMD cmd;
267 1.1 christos
268 1.1 christos ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0);
269 1.1 christos
270 1.1 christos cmd.addr1.lno = 1;
271 1.1 christos if (db_last(sp, &cmd.addr2.lno))
272 1.1 christos return (1);
273 1.1 christos return (v_exec_ex(sp, vp, &cmd));
274 1.1 christos }
275 1.1 christos
276 1.1 christos /*
277 1.1 christos * v_write --
278 1.1 christos * Write command.
279 1.1 christos */
280 1.1 christos static int
281 1.1 christos v_write(SCR *sp, VICMD *vp)
282 1.1 christos {
283 1.1 christos EXCMD cmd;
284 1.1 christos
285 1.1 christos ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
286 1.1 christos
287 1.1 christos cmd.addr1.lno = 1;
288 1.1 christos if (db_last(sp, &cmd.addr2.lno))
289 1.1 christos return (1);
290 1.1 christos return (v_exec_ex(sp, vp, &cmd));
291 1.1 christos }
292 1.1 christos
293 1.1 christos /*
294 1.1 christos * v_writeas --
295 1.1 christos * Write command.
296 1.1 christos */
297 1.1 christos static int
298 1.1 christos v_writeas(SCR *sp, VICMD *vp)
299 1.1 christos {
300 1.1 christos EXCMD cmd;
301 1.1 christos
302 1.1 christos ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
303 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
304 1.1 christos
305 1.1 christos cmd.addr1.lno = 1;
306 1.1 christos if (db_last(sp, &cmd.addr2.lno))
307 1.1 christos return (1);
308 1.1 christos return (v_exec_ex(sp, vp, &cmd));
309 1.1 christos }
310 1.1 christos
311 1.1 christos /*
312 1.1 christos * v_event --
313 1.1 christos * Find the event associated with a function.
314 1.1 christos *
315 1.1 christos * PUBLIC: int v_event __P((SCR *, VICMD *));
316 1.1 christos */
317 1.1 christos int
318 1.1 christos v_event(SCR *sp, VICMD *vp)
319 1.1 christos {
320 1.1 christos /* This array maps events to vi command functions. */
321 1.2 christos #define VIKEYDEF(a, b) { a, b, NULL, NULL }
322 1.1 christos static VIKEYS const vievents[] = {
323 1.1 christos #define V_C_SETTOP 0 /* VI_C_SETTOP */
324 1.2 christos VIKEYDEF(v_c_settop, 0),
325 1.1 christos #define V_EDIT 1 /* VI_EDIT */
326 1.2 christos VIKEYDEF(v_edit, 0),
327 1.1 christos #define V_EDITOPT 2 /* VI_EDITOPT */
328 1.2 christos VIKEYDEF(v_editopt, 0),
329 1.1 christos #define V_EDITSPLIT 3 /* VI_EDITSPLIT */
330 1.2 christos VIKEYDEF(v_editsplit, 0),
331 1.1 christos #define V_EMARK 4 /* VI_MOUSE_MOVE */
332 1.2 christos VIKEYDEF(v_emark, V_ABS_L|V_MOVE),
333 1.1 christos #define V_QUIT 5 /* VI_QUIT */
334 1.2 christos VIKEYDEF(v_quit, 0),
335 1.1 christos #define V_SEARCH 6 /* VI_SEARCH */
336 1.2 christos VIKEYDEF(v_esearch, V_ABS_L|V_MOVE),
337 1.1 christos #define V_TAG 7 /* VI_TAG */
338 1.2 christos VIKEYDEF(v_tag, 0),
339 1.1 christos #define V_TAGAS 8 /* VI_TAGAS */
340 1.2 christos VIKEYDEF(v_tagas, 0),
341 1.1 christos #define V_TAGSPLIT 9 /* VI_TAGSPLIT */
342 1.2 christos VIKEYDEF(v_tagsplit, 0),
343 1.1 christos #define V_WQ 10 /* VI_WQ */
344 1.2 christos VIKEYDEF(v_wq, 0),
345 1.1 christos #define V_WRITE 11 /* VI_WRITE */
346 1.2 christos VIKEYDEF(v_write, 0),
347 1.1 christos #define V_WRITEAS 12 /* VI_WRITEAS */
348 1.2 christos VIKEYDEF(v_writeas, 0),
349 1.1 christos };
350 1.1 christos
351 1.1 christos switch (vp->ev.e_ipcom) {
352 1.1 christos case VI_C_BOL:
353 1.1 christos vp->kp = &vikeys['0'];
354 1.1 christos break;
355 1.1 christos case VI_C_BOTTOM:
356 1.1 christos vp->kp = &vikeys['G'];
357 1.1 christos break;
358 1.1 christos case VI_C_DEL:
359 1.1 christos vp->kp = &vikeys['x'];
360 1.1 christos break;
361 1.1 christos case VI_C_DOWN:
362 1.1 christos F_SET(vp, VC_C1SET);
363 1.1 christos vp->count = vp->ev.e_lno;
364 1.1 christos vp->kp = &vikeys['\012'];
365 1.1 christos break;
366 1.1 christos case VI_C_EOL:
367 1.1 christos vp->kp = &vikeys['$'];
368 1.1 christos break;
369 1.1 christos case VI_C_INSERT:
370 1.1 christos vp->kp = &vikeys['i'];
371 1.1 christos break;
372 1.1 christos case VI_C_LEFT:
373 1.1 christos vp->kp = &vikeys['\010'];
374 1.1 christos break;
375 1.1 christos case VI_C_PGDOWN:
376 1.1 christos F_SET(vp, VC_C1SET);
377 1.1 christos vp->count = vp->ev.e_lno;
378 1.1 christos vp->kp = &vikeys['\006'];
379 1.1 christos break;
380 1.1 christos case VI_C_PGUP:
381 1.1 christos F_SET(vp, VC_C1SET);
382 1.1 christos vp->count = vp->ev.e_lno;
383 1.1 christos vp->kp = &vikeys['\002'];
384 1.1 christos break;
385 1.1 christos case VI_C_RIGHT:
386 1.1 christos vp->kp = &vikeys['\040'];
387 1.1 christos break;
388 1.1 christos case VI_C_SEARCH:
389 1.1 christos vp->kp = &vievents[V_SEARCH];
390 1.1 christos break;
391 1.1 christos case VI_C_SETTOP:
392 1.1 christos vp->kp = &vievents[V_C_SETTOP];
393 1.1 christos break;
394 1.1 christos case VI_C_TOP:
395 1.1 christos F_SET(vp, VC_C1SET);
396 1.1 christos vp->count = 1;
397 1.1 christos vp->kp = &vikeys['G'];
398 1.1 christos break;
399 1.1 christos case VI_C_UP:
400 1.1 christos F_SET(vp, VC_C1SET);
401 1.1 christos vp->count = vp->ev.e_lno;
402 1.1 christos vp->kp = &vikeys['\020'];
403 1.1 christos break;
404 1.1 christos case VI_EDIT:
405 1.1 christos vp->kp = &vievents[V_EDIT];
406 1.1 christos break;
407 1.1 christos case VI_EDITOPT:
408 1.1 christos vp->kp = &vievents[V_EDITOPT];
409 1.1 christos break;
410 1.1 christos case VI_EDITSPLIT:
411 1.1 christos vp->kp = &vievents[V_EDITSPLIT];
412 1.1 christos break;
413 1.1 christos case VI_MOUSE_MOVE:
414 1.1 christos vp->kp = &vievents[V_EMARK];
415 1.1 christos break;
416 1.1 christos case VI_SEL_END:
417 1.1 christos v_sel_end(sp, &vp->ev);
418 1.1 christos /* XXX RETURN IGNORE */
419 1.1 christos break;
420 1.1 christos case VI_SEL_START:
421 1.1 christos v_sel_start(sp, &vp->ev);
422 1.1 christos /* XXX RETURN IGNORE */
423 1.1 christos break;
424 1.1 christos case VI_QUIT:
425 1.1 christos vp->kp = &vievents[V_QUIT];
426 1.1 christos break;
427 1.1 christos case VI_TAG:
428 1.1 christos vp->kp = &vievents[V_TAG];
429 1.1 christos break;
430 1.1 christos case VI_TAGAS:
431 1.1 christos vp->kp = &vievents[V_TAGAS];
432 1.1 christos break;
433 1.1 christos case VI_TAGSPLIT:
434 1.1 christos vp->kp = &vievents[V_TAGSPLIT];
435 1.1 christos break;
436 1.1 christos case VI_UNDO:
437 1.1 christos vp->kp = &vikeys['u'];
438 1.1 christos break;
439 1.1 christos case VI_WQ:
440 1.1 christos vp->kp = &vievents[V_WQ];
441 1.1 christos break;
442 1.1 christos case VI_WRITE:
443 1.1 christos vp->kp = &vievents[V_WRITE];
444 1.1 christos break;
445 1.1 christos case VI_WRITEAS:
446 1.1 christos vp->kp = &vievents[V_WRITEAS];
447 1.1 christos break;
448 1.1 christos default:
449 1.1 christos return (1);
450 1.1 christos }
451 1.1 christos return (0);
452 1.1 christos }
453