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