1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: usreditpac.c
6 * Point-and-click editor
7 * Written by: Steven M. Rubin, Static Free Software
8 *
9 * Copyright (c) 2000 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "global.h"
33 #include "egraphics.h"
34 #include "usr.h"
35 #include "usreditpac.h"
36 #include "usrtrack.h"
37 #include "edialogs.h"
38
39 #define THUMBSIZE 16 /* width of the thumb area in scroll slider */
40 #define HEADERLINES 2 /* number of lines of text at top of editor */
41 #define LEFTINDENT 4 /* space between left edge and text */
42 #define DEFAULTWID 1 /* default number of characters on a line */
43
44 static INTBIG us_editpactwid, us_editpacthei; /* size of a single letter */
45 static INTBIG us_editpacfont; /* font size for editor */
46 static CHAR *us_editpacbuffer = 0; /* the cut/copy/paste buffer */
47
48 /* variables for cursor tracking */
49 static WINDOWPART *us_editpaccurrentwin;
50 static INTBIG us_editpacdeltasofar;
51 static INTBIG us_editpacinitialthumb;
52 static INTBIG us_editpacorigcurline, us_editpacorigcurchar;
53 static INTBIG us_editpacorigendline, us_editpacorigendchar;
54 static INTBIG us_editpaclastc, us_editpaclastl;
55
56 /* variables for undo */
57 static INTBIG us_editpacundooldcurline, us_editpacundooldcurchar;
58 static INTBIG us_editpacundonewcurline, us_editpacundonewcurchar;
59 static INTBIG us_editpacundonewendline, us_editpacundonewendchar;
60 static CHAR *us_editpacundobuffer;
61 static INTBIG us_editpacundobuffersize = 0;
62
63 extern GRAPHICS us_ebox, us_menutext, us_menufigs;
64
65 /* prototypes for local routines */
66 static void us_editpacredraweditor(WINDOWPART*);
67 static void us_editpacgotbutton(WINDOWPART*, INTBIG, INTBIG, INTBIG);
68 static BOOLEAN us_editpacclickdown(INTBIG, INTBIG);
69 static BOOLEAN us_editpacdclickdown(INTBIG, INTBIG);
70 static BOOLEAN us_editpacdoclickdown(INTBIG, INTBIG, BOOLEAN);
71 static BOOLEAN us_editpacdownarrow(INTBIG, INTBIG);
72 static BOOLEAN us_editpacuparrow(INTBIG, INTBIG);
73 static BOOLEAN us_editpacdownpage(INTBIG, INTBIG);
74 static BOOLEAN us_editpacuppage(INTBIG, INTBIG);
75 static BOOLEAN us_editpacrightarrow(INTBIG, INTBIG);
76 static BOOLEAN us_editpacleftarrow(INTBIG, INTBIG);
77 static BOOLEAN us_editpacrightpage(INTBIG, INTBIG);
78 static BOOLEAN us_editpacleftpage(INTBIG, INTBIG);
79 static BOOLEAN us_editpacimplementchar(WINDOWPART*, INTSML, INTBIG, BOOLEAN);
80 static void us_editpacremoveselection(WINDOWPART*);
81 static void us_editpacredrawscreen(WINDOWPART*);
82 static void us_editpacdrawsliders(WINDOWPART*);
83 static void us_editpacdrawhscroll(WINDOWPART*);
84 static void us_editpacdrawvscroll(WINDOWPART*);
85 static void us_editpaccleanupline(WINDOWPART*, INTBIG);
86 static void us_editpacredrawlines(WINDOWPART*);
87 static void us_editpacsetheader(WINDOWPART*, CHAR*);
88 static void us_editpacinvertselection(WINDOWPART*);
89 static void us_editpacdonetyping(EDITOR*);
90 static void us_editpacamtyping(EDITOR*);
91 static void us_editpactypeddelete(EDITOR*);
92 static INTBIG us_editpaccharstocurrent(EDITOR*, INTBIG, INTBIG);
93 static void us_editpacloadselection(EDITOR*, CHAR*);
94 static void us_editpaccomputebounds(WINDOWPART*, EDITOR*);
95 static void us_editpacbeginwork(WINDOWPART*);
96 static void us_editpacaddmorelines(EDITOR*);
97 static void us_editpacaddmorechars(EDITOR*, INTBIG, INTBIG);
98 static void us_editpacmovebox(WINDOWPART*, INTBIG, INTBIG, INTBIG, INTBIG, INTBIG, INTBIG);
99 static void us_editpacclearbox(WINDOWPART*, INTBIG, INTBIG, INTBIG, INTBIG);
100 static void us_editpactext(WINDOWPART*, CHAR*, INTBIG, INTBIG);
101 static void us_editpacbackupposition(EDITOR *e, INTBIG *chr, INTBIG *lne);
102 static void us_editpacadvanceposition(EDITOR *e, INTBIG *chr, INTBIG *lne);
103 static BOOLEAN us_editpacsinglesearch(WINDOWPART *win, CHAR *str, CHAR *replace, INTBIG bits);
104 static void us_editpacpanwindow(WINDOWPART *w, INTBIG dx, INTBIG dy);
105 static void us_editpachthumbtrackingtextcallback(INTBIG delta);
106 static void us_editpacvthumbtrackingtextcallback(INTBIG delta);
107 static void us_editpacensurelinevisible(WINDOWPART *win, INTBIG lindex, BOOLEAN showcursor);
108
109 /******************** ROUTINES IN THE EDITOR TABLE ********************/
110
111 /*
112 * routine to convert window "oriwin" to a point-and-click text editor.
113 * If "oriwin" is NOWINDOWPART, create a popup window with one line. The window
114 * header is in "header". The number of characters and lines are placed in
115 * "chars" and "lines". Returns the window (NOWINDOWPART if the editor cannot be started).
116 */
us_editpacmakeeditor(WINDOWPART * oriwin,CHAR * header,INTBIG * chars,INTBIG * lines)117 WINDOWPART *us_editpacmakeeditor(WINDOWPART *oriwin, CHAR *header, INTBIG *chars, INTBIG *lines)
118 {
119 INTBIG x, y, i, xs, ys, swid, shei, pwid;
120 UINTBIG descript[TEXTDESCRIPTSIZE];
121 REGISTER EDITOR *e;
122 REGISTER VARIABLE *var;
123 REGISTER WINDOWPART *win;
124
125 /*
126 * the font that is used by the editor is the fixed-width font, TXTEDITOR.
127 * This can be changed by setting the variable "USER_textedit_font" on the user tool
128 * object. The value is the point size minus 4 divided by 2 (the value 0 is the
129 * default font TXTEDITOR). For example, to set the font to be 14 points, type:
130 * -var set tool:user.USER_textedit_font 5
131 */
132 us_editpacfont = TXTEDITOR;
133 var = getval((INTBIG)us_tool, VTOOL, VINTEGER, x_("USER_textedit_font"));
134 if (var != NOVARIABLE && var->addr >= 4)
135 us_editpacfont = var->addr;
136
137 /* if no window exists, create one as a popup */
138 win = oriwin;
139 if (win == NOWINDOWPART)
140 {
141 getpaletteparameters(&swid, &shei, &pwid);
142 if (el_curwindowpart == NOWINDOWPART)
143 {
144 x = swid / 2;
145 y = shei / 2;
146 } else
147 {
148 (void)getxy(&x, &y);
149 x = applyxscale(el_curwindowpart, x-el_curwindowpart->screenlx) + el_curwindowpart->uselx;
150 y = applyyscale(el_curwindowpart, y-el_curwindowpart->screenly) + el_curwindowpart->usely;
151 }
152
153 /* create a window that covers the popup */
154 startobjectchange((INTBIG)us_tool, VTOOL);
155 win = newwindowpart(x_("popup"), el_curwindowpart);
156 TDCLEAR(descript);
157 TDSETSIZE(descript, us_editpacfont);
158 screensettextinfo(win, NOTECHNOLOGY, descript);
159 screengettextsize(win, x_("X"), &us_editpactwid, &us_editpacthei);
160 xs = 400; ys = us_editpacthei*(HEADERLINES+1)+DISPLAYSLIDERSIZE+4;
161 win->uselx = maxi(x-xs/2, 0);
162 win->usehx = mini(win->uselx+xs, swid-1);
163 win->usely = maxi(y-ys, 0);
164 win->usehy = mini(win->usely+ys, shei-1);
165 win->state = (win->state & ~WINDOWTYPE) | POPTEXTWINDOW;
166 } else
167 {
168 /* make sure there is room for at least one line */
169 if (win->usehy - win->usely - us_editpacthei*HEADERLINES - 1 - DISPLAYSLIDERSIZE < us_editpacthei)
170 return(NOWINDOWPART);
171
172 if ((win->state&WINDOWTYPE) == DISPWINDOW)
173 {
174 win->usehx += DISPLAYSLIDERSIZE;
175 win->usely -= DISPLAYSLIDERSIZE;
176 }
177 if ((win->state&WINDOWTYPE) == WAVEFORMWINDOW)
178 {
179 win->uselx -= DISPLAYSLIDERSIZE;
180 win->usely -= DISPLAYSLIDERSIZE;
181 }
182 win->state = (win->state & ~(WINDOWTYPE|WINDOWMODE)) | TEXTWINDOW;
183 TDCLEAR(descript);
184 TDSETSIZE(descript, us_editpacfont);
185 screensettextinfo(win, NOTECHNOLOGY, descript);
186 screengettextsize(win, x_("X"), &us_editpactwid, &us_editpacthei);
187 }
188
189 win->curnodeproto = NONODEPROTO;
190 win->buttonhandler = us_editpacgotbutton;
191 win->charhandler = us_editpacgotchar;
192 win->termhandler = us_editpaceditorterm;
193 win->redisphandler = us_editpacredraweditor;
194 win->changehandler = 0;
195 win->screenlx = win->uselx; win->screenhx = win->usehx;
196 win->screenly = win->usely; win->screenhy = win->usehy;
197 computewindowscale(win);
198
199 /* create a new editor object */
200 e = us_alloceditor();
201 if (e == NOEDITOR) return(NOWINDOWPART);
202 e->state = (e->state & ~(EDITORTYPE|EGRAPHICSOFF|LINESFIXED|TEXTTYPING|TEXTTYPED)) | PACEDITOR;
203 (void)allocstring(&e->header, header, us_tool->cluster);
204 e->curline = e->curchar = 0;
205 e->endline = e->endchar = 0;
206 e->firstline = 0;
207 e->horizfactor = 0;
208 e->linecount = 1;
209 e->charposition = 0;
210 us_editpaccomputebounds(win, e);
211 *chars = e->screenchars;
212 *lines = e->screenlines;
213
214 /* initialize the EDITOR structure */
215 if ((e->state&EDITORINITED) == 0)
216 {
217 /* first time: allocate buffers */
218 e->state |= EDITORINITED;
219 e->maxlines = e->screenlines;
220 if (e->maxlines <= 0) e->maxlines = 1;
221 e->mostchars = e->screenchars;
222 e->formerline = (CHAR *)emalloc((e->mostchars+1) * SIZEOFCHAR, us_tool->cluster);
223 if (e->formerline == 0) ttyputnomemory();
224 e->textarray = (CHAR **)emalloc((e->maxlines * (sizeof (CHAR *))), us_tool->cluster);
225 if (e->textarray == 0) ttyputnomemory();
226 e->maxchars = (INTBIG *)emalloc((e->maxlines * SIZEOFINTBIG), us_tool->cluster);
227 if (e->maxchars == 0) ttyputnomemory();
228 for(i=0; i<e->maxlines; i++)
229 {
230 e->textarray[i] = (CHAR *)emalloc(DEFAULTWID * SIZEOFCHAR, us_tool->cluster);
231 if (e->textarray[i] == 0) ttyputnomemory();
232 e->maxchars[i] = DEFAULTWID;
233 }
234 } else
235 {
236 /* make sure buffers cover the screen */
237 while (e->screenlines > e->maxlines) us_editpacaddmorelines(e);
238 }
239 for(i=0; i<e->maxlines; i++)
240 e->textarray[i][0] = 0;
241 e->formerline[0] = 0;
242 e->working = 0;
243 e->dirty = FALSE;
244
245 /* now finish initializing window */
246 win->editor = e;
247 if (oriwin != NOWINDOWPART)
248 {
249 /* clear window and write header */
250 us_editpacredrawscreen(win);
251 } else
252 {
253 /* finish initializing popup text window */
254 e->savedbox = screensavebox(win, win->uselx, win->usehx, win->usely, win->usehy);
255 endobjectchange((INTBIG)us_tool, VTOOL);
256 }
257 return(win);
258 }
259
260 /*
261 * routine to free all memory associated with this module (at exit time)
262 */
us_freeedpacmemory(void)263 void us_freeedpacmemory(void)
264 {
265 if (us_editpacbuffer != 0) efree(us_editpacbuffer);
266 }
267
268 /*
269 * routine to free all memory associated with this editor
270 * Called prior to destruction of the window.
271 */
us_editpacterminate(EDITOR * e)272 void us_editpacterminate(EDITOR *e)
273 {
274 REGISTER INTBIG i;
275
276 efree((CHAR *)e->formerline);
277 for(i=0; i<e->maxlines; i++)
278 efree((CHAR *)e->textarray[i]);
279 efree((CHAR *)e->textarray);
280 efree((CHAR *)e->maxchars);
281 if (us_editpacundobuffersize > 0)
282 {
283 efree(us_editpacundobuffer);
284 us_editpacundobuffersize = 0;
285 }
286 }
287
288 /*
289 * routine to return the total number of valid lines in the edit buffer
290 */
us_editpactotallines(WINDOWPART * win)291 INTBIG us_editpactotallines(WINDOWPART *win)
292 {
293 REGISTER EDITOR *e;
294
295 e = win->editor;
296 if (e == NOEDITOR) return(0);
297 return(e->linecount);
298 }
299
300 /*
301 * routine to get the string on line "lindex" (0 based). A negative line
302 * returns the current line. Returns -1 if the index is beyond the file limit
303 */
us_editpacgetline(WINDOWPART * win,INTBIG lindex)304 CHAR *us_editpacgetline(WINDOWPART *win, INTBIG lindex)
305 {
306 REGISTER EDITOR *e;
307
308 e = win->editor;
309 if (e == NOEDITOR) return(x_(""));
310 if (lindex < 0) lindex = e->curline;
311 if (lindex >= e->linecount) return(NOSTRING);
312 return(e->textarray[lindex]);
313 }
314
315 /*
316 * routine to add line "str" to the text cell to become line "lindex"
317 */
us_editpacaddline(WINDOWPART * win,INTBIG lindex,CHAR * str)318 void us_editpacaddline(WINDOWPART *win, INTBIG lindex, CHAR *str)
319 {
320 REGISTER CHAR *pt;
321 REGISTER INTBIG savedsline, savedschar, savedeline, savedechar;
322 REGISTER EDITOR *e;
323 UINTBIG descript[TEXTDESCRIPTSIZE];
324
325 e = win->editor;
326 if (e == NOEDITOR) return;
327 if ((e->state&EGRAPHICSOFF) == 0)
328 {
329 TDCLEAR(descript);
330 TDSETSIZE(descript, us_editpacfont);
331 screensettextinfo(win, NOTECHNOLOGY, descript);
332 }
333
334 /* send out any pending changes */
335 us_editpacshipchanges(win);
336
337 /* change selection to the current line */
338 us_editpacinvertselection(win);
339 savedschar = e->curchar; savedsline = e->curline;
340 savedechar = e->endchar; savedeline = e->endline;
341 e->curline = e->endline = lindex; e->curchar = e->endchar = 0;
342 us_editpacbeginwork(win);
343
344 /* fake the characters */
345 for(pt = str; *pt != 0; pt++) (void)us_editpacimplementchar(win, *pt, 0, FALSE);
346 (void)us_editpacimplementchar(win, '\n', 0, FALSE);
347 e->state &= ~TEXTTYPED;
348
349 /* send out pending changes */
350 us_editpacshipchanges(win);
351
352 /* restore selection */
353 e->curchar = savedschar; e->curline = savedsline;
354 e->endchar = savedechar; e->endline = savedeline;
355 us_editpacinvertselection(win);
356 us_editpacbeginwork(win);
357 }
358
359 /*
360 * routine to replace the line number "lindex" with the string "str".
361 */
us_editpacreplaceline(WINDOWPART * win,INTBIG lindex,CHAR * str)362 void us_editpacreplaceline(WINDOWPART *win, INTBIG lindex, CHAR *str)
363 {
364 REGISTER CHAR *pt;
365 REGISTER INTBIG savedsline, savedschar, savedeline, savedechar;
366 REGISTER EDITOR *e;
367 UINTBIG descript[TEXTDESCRIPTSIZE];
368
369 e = win->editor;
370 if (e == NOEDITOR) return;
371 if ((e->state&EGRAPHICSOFF) == 0)
372 {
373 TDCLEAR(descript);
374 TDSETSIZE(descript, us_editpacfont);
375 screensettextinfo(win, NOTECHNOLOGY, descript);
376 }
377
378 /* send out any pending changes */
379 us_editpacshipchanges(win);
380
381 /* change selection to the current line */
382 us_editpacinvertselection(win);
383 savedschar = e->curchar; savedsline = e->curline;
384 savedechar = e->endchar; savedeline = e->endline;
385 e->curline = e->endline = lindex;
386 e->curchar = 0; e->endchar = estrlen(e->textarray[lindex]);
387 us_editpacbeginwork(win);
388
389 /* fake the characters */
390 for(pt = str; *pt != 0; pt++) (void)us_editpacimplementchar(win, *pt, 0, FALSE);
391 e->state &= ~TEXTTYPED;
392
393 /* send out pending changes */
394 us_editpacshipchanges(win);
395
396 /* restore selection */
397 e->curchar = savedschar; e->curline = savedsline;
398 e->endchar = savedechar; e->endline = savedeline;
399 us_editpacinvertselection(win);
400 us_editpacbeginwork(win);
401 }
402
403 /*
404 * routine to delete line number "lindex"
405 */
us_editpacdeleteline(WINDOWPART * win,INTBIG lindex)406 void us_editpacdeleteline(WINDOWPART *win, INTBIG lindex)
407 {
408 REGISTER INTBIG savedsline, savedschar, savedeline, savedechar;
409 REGISTER EDITOR *e;
410 UINTBIG descript[TEXTDESCRIPTSIZE];
411
412 e = win->editor;
413 if (e == NOEDITOR) return;
414 if ((e->state&EGRAPHICSOFF) == 0)
415 {
416 TDCLEAR(descript);
417 TDSETSIZE(descript, us_editpacfont);
418 screensettextinfo(win, NOTECHNOLOGY, descript);
419 }
420
421 /* send out any pending changes */
422 us_editpacshipchanges(win);
423
424 /* change selection to the current line */
425 us_editpacinvertselection(win);
426 savedschar = e->curchar; savedsline = e->curline;
427 savedechar = e->endchar; savedeline = e->endline;
428 e->curline = lindex; e->endline = lindex+1;
429 e->curchar = e->endchar = 0;
430 us_editpacbeginwork(win);
431
432 /* fake the deletion character */
433 (void)us_editpacimplementchar(win, BACKSPACEKEY, 0, FALSE);
434 e->state &= ~TEXTTYPED;
435
436 /* send out pending changes */
437 us_editpacshipchanges(win);
438
439 /* restore selection */
440 e->curchar = savedschar; e->curline = savedsline;
441 e->endchar = savedechar; e->endline = savedeline;
442 us_editpacinvertselection(win);
443 us_editpacbeginwork(win);
444 }
445
446 /*
447 * routine to highlight lines "lindex" to "hindex" in the text window
448 */
us_editpachighlightline(WINDOWPART * win,INTBIG lindex,INTBIG hindex)449 void us_editpachighlightline(WINDOWPART *win, INTBIG lindex, INTBIG hindex)
450 {
451 REGISTER EDITOR *e;
452 UINTBIG descript[TEXTDESCRIPTSIZE];
453
454 e = win->editor;
455 if (e == NOEDITOR) return;
456 TDCLEAR(descript);
457 TDSETSIZE(descript, us_editpacfont);
458 screensettextinfo(win, NOTECHNOLOGY, descript);
459 us_editpacinvertselection(win);
460 e->curline = lindex;
461 e->curchar = 0;
462 e->endline = hindex;
463 e->endchar = estrlen(e->textarray[hindex]);
464 us_editpacinvertselection(win);
465 us_editpacbeginwork(win);
466
467 /* ensure that line "lindex" is shown in the display */
468 us_editpacensurelinevisible(win, lindex, TRUE);
469 }
470
471 /*
472 * Routine to ensure that line "lindex" is visible in the edit window.
473 * If not, the text is shifted.
474 */
us_editpacensurelinevisible(WINDOWPART * win,INTBIG lindex,BOOLEAN showcursor)475 void us_editpacensurelinevisible(WINDOWPART *win, INTBIG lindex, BOOLEAN showcursor)
476 {
477 REGISTER EDITOR *e;
478
479 e = win->editor;
480 if (e == NOEDITOR) return;
481 if (lindex-e->firstline >= e->screenlines || lindex < e->firstline)
482 {
483 e->firstline = maxi(0, lindex - e->screenlines/2);
484 us_editpacredrawlines(win);
485 if (!showcursor) us_editpacinvertselection(win);
486 if ((win->state&WINDOWTYPE) != POPTEXTWINDOW)
487 us_editpacdrawvscroll(win);
488 }
489 }
490
491 /*
492 * routine to stop the graphic display of changes (for batching)
493 */
us_editpacsuspendgraphics(WINDOWPART * win)494 void us_editpacsuspendgraphics(WINDOWPART *win)
495 {
496 REGISTER EDITOR *e;
497
498 e = win->editor;
499 if (e == NOEDITOR) return;
500 e->state |= EGRAPHICSOFF;
501 }
502
503 /*
504 * routine to restart the graphic display of changes and redisplay (for batching)
505 */
us_editpacresumegraphics(WINDOWPART * win)506 void us_editpacresumegraphics(WINDOWPART *win)
507 {
508 REGISTER EDITOR *e;
509 UINTBIG descript[TEXTDESCRIPTSIZE];
510
511 e = win->editor;
512 if (e == NOEDITOR) return;
513 e->state &= ~EGRAPHICSOFF;
514 TDCLEAR(descript);
515 TDSETSIZE(descript, us_editpacfont);
516 screensettextinfo(win, NOTECHNOLOGY, descript);
517 us_editpacredrawscreen(win);
518 }
519
520 /*
521 * routine to write the text file to "file"
522 */
us_editpacwritetextfile(WINDOWPART * win,CHAR * file)523 void us_editpacwritetextfile(WINDOWPART *win, CHAR *file)
524 {
525 REGISTER EDITOR *e;
526 REGISTER INTBIG i;
527 REGISTER FILE *f;
528 CHAR *truename;
529
530 e = win->editor;
531 if (e == NOEDITOR) return;
532
533 /* find the last line */
534 if (e->linecount <= 0)
535 {
536 ttyputerr(_("File is empty"));
537 return;
538 }
539
540 f = xcreate(file, el_filetypetext, _("Text File"), &truename);
541 if (f == NULL)
542 {
543 if (truename != 0) ttyputerr(_("Cannot write %s"), truename);
544 return;
545 }
546
547 for(i = 0; i < e->linecount; i++) xprintf(f, x_("%s\n"), e->textarray[i]);
548 xclose(f);
549 ttyputmsg(_("%s written"), truename);
550 }
551
552 /*
553 * routine to read the text file "file"
554 */
us_editpacreadtextfile(WINDOWPART * win,CHAR * file)555 void us_editpacreadtextfile(WINDOWPART *win, CHAR *file)
556 {
557 REGISTER EDITOR *e;
558 REGISTER INTBIG i, filelength, charsread;
559 REGISTER INTBIG c;
560 REGISTER FILE *f;
561 UINTBIG descript[TEXTDESCRIPTSIZE];
562 CHAR *filename;
563 REGISTER void *infstr, *dia;
564
565 e = win->editor;
566 if (e == NOEDITOR) return;
567
568 /* get the file */
569 f = xopen(file, el_filetypetext, x_(""), &filename);
570 if (f == NULL)
571 {
572 ttyputerr(_("Cannot read %s"), file);
573 return;
574 }
575 filelength = filesize(f);
576 if (filelength > 0)
577 {
578 infstr = initinfstr();
579 formatinfstr(infstr, _("Reading %s..."), file);
580 dia = DiaInitProgress(returninfstr(infstr), 0);
581 if (dia == 0)
582 {
583 xclose(f);
584 return;
585 }
586 DiaSetProgress(dia, 1, filelength);
587 } else
588 ttyputmsg(_("Reading %s"), file);
589
590 e->state |= EGRAPHICSOFF;
591 for(i=0; i<e->maxlines; i++) e->textarray[i][0] = 0;
592 e->curline = e->curchar = e->firstline = 0;
593 e->endline = e->endchar = 0;
594 e->dirty = FALSE;
595 e->linecount = 0;
596
597 /* read the file */
598 charsread = 0;
599 for(;;)
600 {
601 c = xgetc(f);
602 if (c == EOF) break;
603 charsread++;
604 if (c == '\t') c = ' ';
605 if (c == '\n' || c == '\r')
606 {
607 if (e->curline >= e->maxlines-1) us_editpacaddmorelines(e);
608 e->linecount++;
609 e->curline++;
610 e->curchar = 0;
611 } else
612 {
613 /* see if line needs to be extended */
614 i = estrlen(e->textarray[e->curline]) + 2;
615 if (i > e->maxchars[e->curline])
616 us_editpacaddmorechars(e, e->curline, i+10);
617
618 e->textarray[e->curline][e->curchar] = (CHAR)c;
619 e->textarray[e->curline][e->curchar+1] = 0;
620 e->curchar++;
621 }
622 if (filelength > 0 && (charsread%100) == 0)
623 {
624 DiaSetProgress(dia, charsread, filelength);
625 }
626 }
627 xclose(f);
628
629 /* announce the changes (go backwards so the array expands only once) */
630 if (filelength > 0)
631 {
632 DiaSetProgress(dia, 999, 1000);
633 DiaSetTextProgress(dia, _("Cleaning up..."));
634 }
635 (*win->changehandler)(win, REPLACEALLTEXT, x_(""), (CHAR *)e->textarray, e->linecount);
636 if (filelength > 0) DiaDoneProgress(dia);
637
638 /* restore the display */
639 e->state &= ~EGRAPHICSOFF;
640 TDCLEAR(descript);
641 TDSETSIZE(descript, us_editpacfont);
642 screensettextinfo(win, NOTECHNOLOGY, descript);
643 e->curline = e->curchar = 0;
644 e->endline = e->endchar = 0;
645 us_editpacbeginwork(win);
646 us_editpacredrawlines(win);
647 if ((win->state&WINDOWTYPE) != POPTEXTWINDOW) us_editpacdrawvscroll(win);
648 us_editpacdrawhscroll(win);
649 }
650
us_editpaceditorterm(WINDOWPART * win)651 void us_editpaceditorterm(WINDOWPART *win)
652 {
653 REGISTER EDITOR *e;
654
655 e = win->editor;
656 if (e == NOEDITOR) return;
657
658 /* first flush any pending edit changes */
659 us_editpacshipchanges(win);
660
661 /* restore window state */
662 if ((win->state&WINDOWTYPE) == POPTEXTWINDOW)
663 {
664 screenrestorebox(e->savedbox, 0);
665 }
666 }
667
us_editpacshipchanges(WINDOWPART * win)668 void us_editpacshipchanges(WINDOWPART *win)
669 {
670 REGISTER EDITOR *e;
671
672 e = win->editor;
673 if (e == NOEDITOR) return;
674
675 if (e->working >= 0 && e->dirty)
676 {
677 if (win->changehandler != 0)
678 (*win->changehandler)(win, REPLACETEXTLINE, e->formerline, e->textarray[e->working],
679 e->working);
680 e->dirty = FALSE;
681 e->working = -1;
682 }
683 }
684
685 /*
686 * keyboard interrupt routine for the text window
687 */
us_editpacgotchar(WINDOWPART * win,INTSML i,INTBIG special)688 BOOLEAN us_editpacgotchar(WINDOWPART *win, INTSML i, INTBIG special)
689 {
690 REGISTER EDITOR *e;
691 UINTBIG descript[TEXTDESCRIPTSIZE];
692
693 /* pass accelerated keys to the main system */
694 if ((special&ACCELERATORDOWN) != 0)
695 {
696 return((*DEFAULTCHARHANDLER)(win, i, special));
697 }
698
699 e = win->editor;
700 if (e == NOEDITOR) return(TRUE);
701 TDCLEAR(descript);
702 TDSETSIZE(descript, us_editpacfont);
703 screensettextinfo(win, NOTECHNOLOGY, descript);
704 us_editpacinvertselection(win);
705 if (us_editpacimplementchar(win, i, special, TRUE)) return(TRUE);
706 us_editpacinvertselection(win);
707 setactivity(_("Text Editing"));
708 return(FALSE);
709 }
710
us_editpaccut(WINDOWPART * win)711 void us_editpaccut(WINDOWPART *win)
712 {
713 REGISTER EDITOR *e;
714 UINTBIG descript[TEXTDESCRIPTSIZE];
715
716 e = win->editor;
717 if (e == NOEDITOR) return;
718
719 /* copy the selection to the cut/copy buffer */
720 us_editpaccopy(win);
721
722 /* remove the selection from the edit buffer */
723 TDCLEAR(descript);
724 TDSETSIZE(descript, us_editpacfont);
725 screensettextinfo(win, NOTECHNOLOGY, descript);
726 us_editpacinvertselection(win);
727 (void)us_editpacimplementchar(win, BACKSPACEKEY, 0, TRUE);
728 us_editpacinvertselection(win);
729 }
730
us_editpaccopy(WINDOWPART * win)731 void us_editpaccopy(WINDOWPART *win)
732 {
733 REGISTER EDITOR *e;
734 REGISTER INTBIG len;
735
736 e = win->editor;
737 if (e == NOEDITOR) return;
738
739 /* free the former cut/copy buffer */
740 if (us_editpacbuffer != 0)
741 {
742 efree(us_editpacbuffer);
743 us_editpacbuffer = 0;
744 }
745
746 /* determine number of characters that are selected */
747 len = us_editpaccharstocurrent(e, e->endchar, e->endline);
748 if (len <= 0) return;
749
750 /* allocate a new cut/copy buffer */
751 us_editpacbuffer = (CHAR *)emalloc((len+1) * SIZEOFCHAR, us_tool->cluster);
752 if (us_editpacbuffer == 0) return;
753
754 /* fill the buffer */
755 us_editpacloadselection(e, us_editpacbuffer);
756
757 /* store it in the system-wide cut buffer */
758 setcutbuffer(us_editpacbuffer);
759 }
760
us_editpacpaste(WINDOWPART * win)761 void us_editpacpaste(WINDOWPART *win)
762 {
763 REGISTER EDITOR *e;
764 REGISTER INTBIG i;
765 UINTBIG descript[TEXTDESCRIPTSIZE];
766 INTBIG len;
767 CHAR *str;
768
769 /* flush the internal buffer and get the system-wide cut buffer */
770 if (us_editpacbuffer != 0) efree(us_editpacbuffer);
771 us_editpacbuffer = 0;
772 str = getcutbuffer();
773 len = estrlen(str);
774 if (len > 0)
775 {
776 us_editpacbuffer = (CHAR *)emalloc((len+1) * SIZEOFCHAR, us_tool->cluster);
777 if (us_editpacbuffer == 0) return;
778 estrcpy(us_editpacbuffer, str);
779 }
780 if (us_editpacbuffer == 0) return;
781
782 e = win->editor;
783 if (e == NOEDITOR) return;
784 TDCLEAR(descript);
785 TDSETSIZE(descript, us_editpacfont);
786 screensettextinfo(win, NOTECHNOLOGY, descript);
787
788 us_editpacsuspendgraphics(win);
789 us_editpacinvertselection(win);
790 for(i=0; us_editpacbuffer[i] != 0; i++)
791 {
792 if (i > 0)
793 {
794 if (us_editpacbuffer[i] == '\n' && us_editpacbuffer[i-1] == '\r') continue;
795 }
796 (void)us_editpacimplementchar(win, us_editpacbuffer[i], 0, TRUE);
797 }
798 us_editpacinvertselection(win);
799 us_editpacresumegraphics(win);
800 }
801
us_editpacundo(WINDOWPART * win)802 void us_editpacundo(WINDOWPART *win)
803 {
804 CHAR *savebuffer;
805 REGISTER EDITOR *e;
806 REGISTER INTBIG i;
807 UINTBIG descript[TEXTDESCRIPTSIZE];
808
809 e = win->editor;
810 if (e == NOEDITOR) return;
811
812 /* if no change made, stop */
813 if ((e->state&TEXTTYPED) == 0) return;
814
815 /* finish a set of changes */
816 us_editpacdonetyping(e);
817
818 /* save the replacement buffer */
819 (void)allocstring(&savebuffer, us_editpacundobuffer, el_tempcluster);
820
821 /* replace what was typed */
822 TDCLEAR(descript);
823 TDSETSIZE(descript, us_editpacfont);
824 screensettextinfo(win, NOTECHNOLOGY, descript);
825 us_editpacinvertselection(win);
826 e->curline = us_editpacundonewcurline; e->curchar = us_editpacundonewcurchar;
827 e->endline = us_editpacundonewendline; e->endchar = us_editpacundonewendchar;
828 us_editpacbeginwork(win);
829 if (savebuffer[0] == 0) (void)us_editpacimplementchar(win, BACKSPACEKEY, 0, TRUE); else
830 for(i=0; savebuffer[i] != 0; i++)
831 (void)us_editpacimplementchar(win, savebuffer[i], 0, TRUE);
832 us_editpacinvertselection(win);
833
834 efree(savebuffer);
835 }
836
837 /*
838 * routine to search and/or replace text. If "replace" is nonzero, this is
839 * a replace. The meaning of "bits" is as follows:
840 * 1 search from top
841 * 2 replace all
842 * 4 case sensitive
843 * 8 search upwards
844 */
us_editpacsearch(WINDOWPART * win,CHAR * str,CHAR * replace,INTBIG bits)845 void us_editpacsearch(WINDOWPART *win, CHAR *str, CHAR *replace, INTBIG bits)
846 {
847 if ((bits&2) != 0 && replace != 0)
848 {
849 for(;;)
850 {
851 if (!us_editpacsinglesearch(win, str, replace, bits)) break;
852 }
853 } else
854 {
855 (void)us_editpacsinglesearch(win, str, replace, bits);
856 }
857 }
858
us_editpacpan(WINDOWPART * win,INTBIG dx,INTBIG dy)859 void us_editpacpan(WINDOWPART *win, INTBIG dx, INTBIG dy)
860 {
861 us_editpacpanwindow(win, dx, dy);
862 }
863
864 /*
865 * Helper routine to do a search and replace. Returns true if a replacement
866 * was done.
867 */
us_editpacsinglesearch(WINDOWPART * win,CHAR * str,CHAR * replace,INTBIG bits)868 BOOLEAN us_editpacsinglesearch(WINDOWPART *win, CHAR *str, CHAR *replace, INTBIG bits)
869 {
870 REGISTER INTBIG i, want, mchr, mlne;
871 INTBIG startchr, startlne, chr, lne;
872 UINTBIG descript[TEXTDESCRIPTSIZE];
873 REGISTER EDITOR *e;
874
875 e = win->editor;
876 if (e == NOEDITOR) return(FALSE);
877
878 if ((bits&1) != 0)
879 {
880 /* search from the top of the buffer */
881 startchr = 0; startlne = 0;
882 } else
883 {
884 /* search from current location */
885 if ((bits&8) != 0)
886 {
887 /* search from before the start of the current selection */
888 startchr = e->curchar; startlne = e->curline;
889 us_editpacbackupposition(e, &startchr, &startlne);
890 } else
891 {
892 /* search from the end of the current selection */
893 startchr = e->endchar; startlne = e->endline;
894 }
895 }
896 chr = startchr; lne = startlne;
897 for(;;)
898 {
899 /* see if the string matches at this point */
900 mchr = chr; mlne = lne;
901 for(i=0; str[i] != 0; i++)
902 {
903 want = str[i];
904 if (want == '\n') want = 0;
905 if ((bits&4) != 0)
906 {
907 if (e->textarray[mlne][mchr] != str[i]) break;
908 } else
909 {
910 if (tolower(e->textarray[mlne][mchr]) != tolower(str[i])) break;
911 }
912
913 /* advance match pointer to the next character in the file */
914 if (e->textarray[mlne][mchr] != 0) mchr++; else
915 {
916 mchr = 0;
917 mlne++;
918 if (mlne >= e->linecount) break;
919 }
920 }
921 if (str[i] == 0) break;
922
923 /* advance to the next character in the file */
924 if ((bits&8) != 0)
925 {
926 us_editpacbackupposition(e, &chr, &lne);
927 } else
928 {
929 us_editpacadvanceposition(e, &chr, &lne);
930 }
931
932 /* if it came all the way around, stop */
933 if (chr == startchr && lne == startlne)
934 {
935 ttybeep(SOUNDBEEP, TRUE);
936 return(FALSE);
937 }
938 }
939
940 /* string found */
941 TDCLEAR(descript);
942 TDSETSIZE(descript, us_editpacfont);
943 screensettextinfo(win, NOTECHNOLOGY, descript);
944 us_editpacdonetyping(e);
945 us_editpacinvertselection(win);
946 e->curline = lne; e->curchar = chr;
947 for(i=0; str[i] != 0; i++)
948 us_editpacadvanceposition(e, &chr, &lne);
949 e->endline = lne; e->endchar = chr;
950 us_editpacinvertselection(win);
951 us_editpacbeginwork(win);
952
953 if (replace != 0)
954 {
955 us_editpacinvertselection(win);
956 if (replace[0] == 0)
957 {
958 (void)us_editpacimplementchar(win, BACKSPACEKEY, 0, TRUE);
959 } else
960 {
961 for(i=0; replace[i] != 0; i++)
962 (void)us_editpacimplementchar(win, replace[i], 0, TRUE);
963 }
964 us_editpacinvertselection(win);
965 }
966
967 /* ensure that line "e->curline" is shown in the display */
968 us_editpacensurelinevisible(win, e->curline, TRUE);
969 return(TRUE);
970 }
971
972 /******************** ROUTINES IN THE WINDOW STRUCTURE ********************/
973
us_editpacredraweditor(WINDOWPART * win)974 void us_editpacredraweditor(WINDOWPART *win)
975 {
976 REGISTER EDITOR *e;
977 UINTBIG descript[TEXTDESCRIPTSIZE];
978
979 e = win->editor;
980 if (e == NOEDITOR) return;
981 TDCLEAR(descript);
982 TDSETSIZE(descript, us_editpacfont);
983 screensettextinfo(win, NOTECHNOLOGY, descript);
984
985 /* compute window extents */
986 us_editpaccomputebounds(win, e);
987
988 while (e->screenlines > e->maxlines) us_editpacaddmorelines(e);
989
990 us_editpacredrawscreen(win);
991 }
992
us_editpacgotbutton(WINDOWPART * win,INTBIG but,INTBIG x,INTBIG y)993 void us_editpacgotbutton(WINDOWPART *win, INTBIG but, INTBIG x, INTBIG y)
994 {
995 REGISTER EDITOR *e;
996 REGISTER INTBIG xc, yc, len;
997 BOOLEAN (*clickroutine)(INTBIG, INTBIG);
998 UINTBIG descript[TEXTDESCRIPTSIZE];
999
1000 /* changes to the mouse-wheel are handled by the user interface */
1001 if (wheelbutton(but))
1002 {
1003 us_buttonhandler(win, but, x, y);
1004 return;
1005 }
1006 ttynewcommand();
1007
1008 e = win->editor;
1009 if (e == NOEDITOR) return;
1010 TDCLEAR(descript);
1011 TDSETSIZE(descript, us_editpacfont);
1012 screensettextinfo(win, NOTECHNOLOGY, descript);
1013 us_editpaccurrentwin = win;
1014
1015 if ((win->state&WINDOWTYPE) != POPTEXTWINDOW && x > e->offx + e->swid)
1016 {
1017 /* cursor in vertical slider */
1018 if (e->linecount <= e->screenlines) return;
1019 if (y < e->revy - e->shei + DISPLAYSLIDERSIZE)
1020 {
1021 /* the down arrow */
1022 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacdownarrow,
1023 us_nullchar, us_nullvoid, TRACKNORMAL);
1024 return;
1025 }
1026 if (y > e->revy - DISPLAYSLIDERSIZE)
1027 {
1028 /* the up arrow */
1029 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacuparrow,
1030 us_nullchar, us_nullvoid, TRACKNORMAL);
1031 return;
1032 }
1033 if (y < e->vthumbpos-THUMBSIZE/2 && y >= e->revy - e->shei + DISPLAYSLIDERSIZE)
1034 {
1035 /* scroll down one page */
1036 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacdownpage,
1037 us_nullchar, us_nullvoid, TRACKNORMAL);
1038 return;
1039 }
1040 if (y > e->vthumbpos+THUMBSIZE/2 && y <= e->revy - DISPLAYSLIDERSIZE)
1041 {
1042 /* scroll up one page */
1043 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacuppage,
1044 us_nullchar, us_nullvoid, TRACKNORMAL);
1045 return;
1046 }
1047 if (y >= e->vthumbpos-THUMBSIZE/2 && y <= e->vthumbpos+THUMBSIZE/2)
1048 {
1049 /* drag slider appropriately */
1050 us_editpacdeltasofar = 0;
1051 us_editpacinitialthumb = e->vthumbpos;
1052 us_vthumbbegin(y, win, win->usehx-DISPLAYSLIDERSIZE, win->usely+DISPLAYSLIDERSIZE,
1053 win->usehy-us_editpacthei*HEADERLINES, FALSE, us_editpacvthumbtrackingtextcallback);
1054 trackcursor(FALSE, us_nullup, us_nullvoid, us_vthumbdown, us_nullchar,
1055 us_vthumbdone, TRACKNORMAL);
1056 return;
1057 }
1058 }
1059 if (y <= e->revy - e->shei)
1060 {
1061 /* cursor in horizontal slider */
1062 if (x > e->offx + e->swid - DISPLAYSLIDERSIZE)
1063 {
1064 /* the right arrow */
1065 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacrightarrow,
1066 us_nullchar, us_nullvoid, TRACKNORMAL);
1067 return;
1068 }
1069 if (x < e->offx + DISPLAYSLIDERSIZE - LEFTINDENT)
1070 {
1071 /* the left arrow */
1072 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacleftarrow,
1073 us_nullchar, us_nullvoid, TRACKNORMAL);
1074 return;
1075 }
1076 if (x > e->hthumbpos+THUMBSIZE/2 && x <= e->offx + e->swid - DISPLAYSLIDERSIZE)
1077 {
1078 /* scroll right one page */
1079 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacrightpage,
1080 us_nullchar, us_nullvoid, TRACKNORMAL);
1081 return;
1082 }
1083 if (x < e->hthumbpos-THUMBSIZE/2 && x >= e->offx + DISPLAYSLIDERSIZE - LEFTINDENT)
1084 {
1085 /* scroll left one page */
1086 trackcursor(FALSE, us_nullup, us_nullvoid, us_editpacleftpage,
1087 us_nullchar, us_nullvoid, TRACKNORMAL);
1088 return;
1089 }
1090 if (x >= e->hthumbpos-THUMBSIZE/2 && x <= e->hthumbpos+THUMBSIZE/2)
1091 {
1092 /* drag slider appropriately */
1093 us_editpacdeltasofar = 0;
1094 us_editpacinitialthumb = (win->thumblx + win->thumbhx) / 2;
1095 us_hthumbbegin(x, win, win->usely+DISPLAYSLIDERSIZE, win->uselx,
1096 win->usehx-DISPLAYSLIDERSIZE, us_editpachthumbtrackingtextcallback);
1097 trackcursor(FALSE, us_nullup, us_nullvoid, us_hthumbdown, us_nullchar,
1098 us_hthumbdone, TRACKNORMAL);
1099 return;
1100 }
1101 }
1102
1103 /* find the character position in the edit buffer */
1104 if (y > e->revy) return;
1105 yc = (e->revy-y) / us_editpacthei + e->firstline;
1106 if (yc >= e->screenlines + e->firstline) yc = e->screenlines - 1 + e->firstline;
1107 if (yc >= e->linecount)
1108 {
1109 yc = e->linecount-1;
1110 xc = estrlen(e->textarray[yc]);
1111 } else
1112 {
1113 xc = (x-e->offx+us_editpactwid/2) / us_editpactwid + e->horizfactor;
1114 if (xc < 0) xc = 0;
1115 len = estrlen(e->textarray[yc]);
1116 if (xc > len) xc = len;
1117 }
1118
1119 /* turn off the former selection */
1120 us_editpacinvertselection(win);
1121 us_editpacdonetyping(e);
1122
1123 /* determine the selection from this click */
1124 if (shiftbutton(but))
1125 {
1126 if (yc < e->curline || (yc == e->curline && xc < e->curchar))
1127 {
1128 e->curline = yc; e->curchar = xc;
1129 } else
1130 {
1131 e->endline = yc; e->endchar = xc;
1132 }
1133 } else
1134 {
1135 e->curline = e->endline = yc;
1136 e->curchar = e->endchar = xc;
1137 }
1138 if (doublebutton(but))
1139 {
1140 /* double click: select word about cursor */
1141 for(e->curchar = xc-1; e->curchar >= 0; e->curchar--)
1142 if (!isalnum(e->textarray[yc][e->curchar])) break;
1143 e->curchar++;
1144 for(e->endchar = e->curchar; e->textarray[yc][e->endchar] != 0; e->endchar++)
1145 if (!isalnum(e->textarray[yc][e->endchar])) break;
1146 clickroutine = us_editpacdclickdown;
1147 } else clickroutine = us_editpacclickdown;
1148
1149 /* show the new selection */
1150 us_editpacinvertselection(win);
1151
1152 /* extend the selection while the cursor remains down */
1153 us_editpacorigcurline = e->curline; us_editpacorigcurchar = e->curchar;
1154 us_editpacorigendline = e->endline; us_editpacorigendchar = e->endchar;
1155 us_editpaclastc = us_editpaclastl = -1;
1156 trackcursor(FALSE, us_nullup, us_nullvoid, clickroutine,
1157 us_nullchar, us_nullvoid, TRACKNORMAL);
1158 us_editpacbeginwork(win);
1159 e->charposition = e->endchar;
1160 }
1161
1162 /******************** TRACKING ROUTINES ********************/
1163
us_editpachthumbtrackingtextcallback(INTBIG delta)1164 void us_editpachthumbtrackingtextcallback(INTBIG delta)
1165 {
1166 REGISTER INTBIG point, i;
1167 REGISTER EDITOR *e;
1168
1169 us_editpacdeltasofar += delta;
1170 e = us_editpaccurrentwin->editor;
1171 point = us_editpacinitialthumb + us_editpacdeltasofar;
1172 i = e->swid - DISPLAYSLIDERSIZE*2 + LEFTINDENT - THUMBSIZE;
1173 i = ((point - (e->offx+DISPLAYSLIDERSIZE-LEFTINDENT+THUMBSIZE/2)) *
1174 e->screenchars*10 + i/2) / i;
1175 if (i < 0) i = 0;
1176 if (i == e->horizfactor) return;
1177 e->horizfactor = i;
1178 us_editpacredrawlines(us_editpaccurrentwin);
1179 us_editpacdrawhscroll(us_editpaccurrentwin);
1180 }
1181
us_editpacvthumbtrackingtextcallback(INTBIG delta)1182 void us_editpacvthumbtrackingtextcallback(INTBIG delta)
1183 {
1184 REGISTER INTBIG point, thumbarea, thumbpos;
1185 REGISTER EDITOR *e;
1186
1187 us_editpacdeltasofar += delta;
1188 e = us_editpaccurrentwin->editor;
1189 thumbarea = e->linecount - e->screenlines;
1190 thumbpos = us_editpacinitialthumb + us_editpacdeltasofar;
1191 point = ((e->revy - DISPLAYSLIDERSIZE - THUMBSIZE/2 - thumbpos) * thumbarea - thumbarea/2) /
1192 (e->shei-DISPLAYSLIDERSIZE*2-THUMBSIZE);
1193 if (point < 0) point = 0;
1194 e->firstline = point;
1195 us_editpacredrawlines(us_editpaccurrentwin);
1196 us_editpacdrawvscroll(us_editpaccurrentwin);
1197 }
1198
us_editpacclickdown(INTBIG x,INTBIG y)1199 BOOLEAN us_editpacclickdown(INTBIG x, INTBIG y)
1200 {
1201 return(us_editpacdoclickdown(x, y, FALSE));
1202 }
1203
us_editpacdclickdown(INTBIG x,INTBIG y)1204 BOOLEAN us_editpacdclickdown(INTBIG x, INTBIG y)
1205 {
1206 return(us_editpacdoclickdown(x, y, TRUE));
1207 }
1208
us_editpacdoclickdown(INTBIG x,INTBIG y,BOOLEAN bywords)1209 BOOLEAN us_editpacdoclickdown(INTBIG x, INTBIG y, BOOLEAN bywords)
1210 {
1211 REGISTER INTBIG c, l, len, low, high;
1212 REGISTER EDITOR *e;
1213
1214 e = us_editpaccurrentwin->editor;
1215
1216 if (y > e->revy && (us_editpaccurrentwin->state&WINDOWTYPE) != POPTEXTWINDOW)
1217 {
1218 /* if cursor is above the window, may shift lines */
1219 if (e->firstline == 0) return(FALSE);
1220 e->firstline--;
1221 us_editpacredrawlines(us_editpaccurrentwin);
1222 us_editpacdrawvscroll(us_editpaccurrentwin);
1223 }
1224 if (y < e->revy-e->shei && (us_editpaccurrentwin->state&WINDOWTYPE) != POPTEXTWINDOW)
1225 {
1226 /* if cursor is below the window, may shift lines */
1227 if (e->linecount-e->firstline <= e->screenlines) return(FALSE);
1228 e->firstline++;
1229 us_editpacredrawlines(us_editpaccurrentwin);
1230 us_editpacdrawvscroll(us_editpaccurrentwin);
1231 }
1232 if (x < e->offx)
1233 {
1234 /* if cursor is to the left of the window, may shift screen */
1235 if (e->horizfactor > 0)
1236 {
1237 e->horizfactor--;
1238 us_editpacredrawlines(us_editpaccurrentwin);
1239 us_editpacdrawhscroll(us_editpaccurrentwin);
1240 }
1241 }
1242 if (x > e->offx+e->swid)
1243 {
1244 /* if cursor is to the right of the window, may shift screen */
1245 if (e->horizfactor < e->screenchars*10)
1246 {
1247 e->horizfactor++;
1248 us_editpacredrawlines(us_editpaccurrentwin);
1249 us_editpacdrawhscroll(us_editpaccurrentwin);
1250 }
1251 }
1252 l = (e->revy-y) / us_editpacthei + e->firstline;
1253 if (l >= e->screenlines + e->firstline) l = e->screenlines - 1 + e->firstline;
1254 if (l >= e->linecount)
1255 {
1256 l = e->linecount-1;
1257 c = estrlen(e->textarray[l]);
1258 } else
1259 {
1260 if (l < 0) l = 0;
1261 c = (x-e->offx+us_editpactwid/2) / us_editpactwid + e->horizfactor;
1262 if (c < 0) c = 0;
1263 len = estrlen(e->textarray[l]);
1264 if (c > len) c = len;
1265 }
1266
1267 /* only interested if the character position changed */
1268 if (us_editpaclastc != -1 && us_editpaclastl != -1 &&
1269 us_editpaclastc == c && us_editpaclastl == l) return(FALSE);
1270 us_editpaclastc = c; us_editpaclastl = l;
1271
1272 /* if going by words, advance that much at a time */
1273 if (bywords && isalnum(e->textarray[l][c]) && c > 0 && isalnum(e->textarray[l][c-1]))
1274 {
1275 for(low = c-1; low >= 0; low--)
1276 if (!isalnum(e->textarray[l][low])) break;
1277 low++;
1278 for(high = low; e->textarray[l][high] != 0; high++)
1279 if (!isalnum(e->textarray[l][high])) break;
1280 if (l > us_editpacorigendline || (l == us_editpacorigendline && high > us_editpacorigendchar))
1281 c = high;
1282 if (l < us_editpacorigcurline || (l == us_editpacorigcurline && low < us_editpacorigcurchar))
1283 c = low;
1284 }
1285
1286 us_editpacinvertselection(us_editpaccurrentwin);
1287 if (l > us_editpacorigendline || (l == us_editpacorigendline && c >= us_editpacorigendchar))
1288 {
1289 e->curline = us_editpacorigcurline; e->curchar = us_editpacorigcurchar;
1290 e->endline = l; e->endchar = c;
1291 }
1292 if (l < us_editpacorigcurline || (l == us_editpacorigcurline && c <= us_editpacorigcurchar))
1293 {
1294 e->curline = l; e->curchar = c;
1295 e->endline = us_editpacorigendline; e->endchar = us_editpacorigendchar;
1296 }
1297 us_editpacinvertselection(us_editpaccurrentwin);
1298 return(FALSE);
1299 }
1300
us_editpacdownarrow(INTBIG x,INTBIG y)1301 BOOLEAN us_editpacdownarrow(INTBIG x, INTBIG y)
1302 {
1303 REGISTER EDITOR *e;
1304
1305 e = us_editpaccurrentwin->editor;
1306 if (x <= e->offx + e->swid || x > e->offx + e->swid + DISPLAYSLIDERSIZE) return(FALSE);
1307 if (y >= e->revy - e->shei + DISPLAYSLIDERSIZE || y < e->revy - e->shei) return(FALSE);
1308 if (e->linecount-e->firstline <= e->screenlines) return(TRUE);
1309
1310 us_editpacpanwindow(us_editpaccurrentwin, 0, 1);
1311 return(FALSE);
1312 }
1313
us_editpacuparrow(INTBIG x,INTBIG y)1314 BOOLEAN us_editpacuparrow(INTBIG x, INTBIG y)
1315 {
1316 REGISTER EDITOR *e;
1317
1318 e = us_editpaccurrentwin->editor;
1319 if (x <= e->offx + e->swid || x > e->offx + e->swid + DISPLAYSLIDERSIZE) return(FALSE);
1320 if (y <= e->revy - DISPLAYSLIDERSIZE || y > e->revy) return(FALSE);
1321 if (e->firstline <= 0) return(TRUE);
1322
1323 us_editpacpanwindow(us_editpaccurrentwin, 0, -1);
1324 return(FALSE);
1325 }
1326
us_editpacdownpage(INTBIG x,INTBIG y)1327 BOOLEAN us_editpacdownpage(INTBIG x, INTBIG y)
1328 {
1329 REGISTER EDITOR *e;
1330
1331 e = us_editpaccurrentwin->editor;
1332 if (x <= e->offx + e->swid || x > e->offx + e->swid + DISPLAYSLIDERSIZE) return(FALSE);
1333 if (y >= e->vthumbpos-THUMBSIZE/2 || y < e->revy - e->shei + DISPLAYSLIDERSIZE) return(FALSE);
1334 if (e->linecount-e->firstline <= e->screenlines) return(TRUE);
1335 e->firstline += e->screenlines-1;
1336 if (e->linecount-e->firstline <= e->screenlines)
1337 e->firstline = e->linecount-e->screenlines;
1338 us_editpacredrawlines(us_editpaccurrentwin);
1339 us_editpacdrawvscroll(us_editpaccurrentwin);
1340 return(FALSE);
1341 }
1342
us_editpacuppage(INTBIG x,INTBIG y)1343 BOOLEAN us_editpacuppage(INTBIG x, INTBIG y)
1344 {
1345 REGISTER EDITOR *e;
1346
1347 e = us_editpaccurrentwin->editor;
1348 if (x <= e->offx + e->swid || x > e->offx + e->swid + DISPLAYSLIDERSIZE) return(FALSE);
1349 if (y <= e->vthumbpos+THUMBSIZE/2 || y > e->revy - DISPLAYSLIDERSIZE) return(FALSE);
1350 if (e->firstline <= 0) return(TRUE);
1351 e->firstline -= e->screenlines-1;
1352 if (e->firstline < 0) e->firstline = 0;
1353 us_editpacredrawlines(us_editpaccurrentwin);
1354 us_editpacdrawvscroll(us_editpaccurrentwin);
1355 return(FALSE);
1356 }
1357
us_editpacrightarrow(INTBIG x,INTBIG y)1358 BOOLEAN us_editpacrightarrow(INTBIG x, INTBIG y)
1359 {
1360 REGISTER EDITOR *e;
1361
1362 e = us_editpaccurrentwin->editor;
1363 if (y > e->revy - e->shei || y < e->revy - e->shei - DISPLAYSLIDERSIZE) return(FALSE);
1364 if (x <= e->offx + e->swid - DISPLAYSLIDERSIZE || x > e->offx + e->swid) return(FALSE);
1365 us_editpacpanwindow(us_editpaccurrentwin, 1, 0);
1366 return(FALSE);
1367 }
1368
us_editpacleftarrow(INTBIG x,INTBIG y)1369 BOOLEAN us_editpacleftarrow(INTBIG x, INTBIG y)
1370 {
1371 REGISTER EDITOR *e;
1372
1373 e = us_editpaccurrentwin->editor;
1374 if (y > e->revy - e->shei || y < e->revy - e->shei - DISPLAYSLIDERSIZE) return(FALSE);
1375 if (x >= e->offx + DISPLAYSLIDERSIZE - LEFTINDENT || x < e->offx - LEFTINDENT) return(FALSE);
1376 us_editpacpanwindow(us_editpaccurrentwin, -1, 0);
1377 return(FALSE);
1378 }
1379
us_editpacrightpage(INTBIG x,INTBIG y)1380 BOOLEAN us_editpacrightpage(INTBIG x, INTBIG y)
1381 {
1382 REGISTER EDITOR *e;
1383
1384 e = us_editpaccurrentwin->editor;
1385 if (y > e->revy - e->shei || y < e->revy - e->shei - DISPLAYSLIDERSIZE) return(FALSE);
1386 if (x <= e->hthumbpos+THUMBSIZE/2 || x > e->offx + e->swid - DISPLAYSLIDERSIZE) return(FALSE);
1387 if (e->horizfactor >= e->screenchars*10) return(TRUE);
1388 e->horizfactor += 10;
1389 if (e->horizfactor >= e->screenchars*10) e->horizfactor = e->screenchars*10;
1390 us_editpacredrawlines(us_editpaccurrentwin);
1391 us_editpacdrawhscroll(us_editpaccurrentwin);
1392 return(FALSE);
1393 }
1394
us_editpacleftpage(INTBIG x,INTBIG y)1395 BOOLEAN us_editpacleftpage(INTBIG x, INTBIG y)
1396 {
1397 REGISTER EDITOR *e;
1398
1399 e = us_editpaccurrentwin->editor;
1400 if (y > e->revy - e->shei || y < e->revy - e->shei - DISPLAYSLIDERSIZE) return(FALSE);
1401 if (x >= e->hthumbpos-THUMBSIZE/2 || x < e->offx + DISPLAYSLIDERSIZE - LEFTINDENT) return(FALSE);
1402 if (e->horizfactor <= 0) return(TRUE);
1403 e->horizfactor -= 10;
1404 if (e->horizfactor <= 0) e->horizfactor = 0;
1405 us_editpacredrawlines(us_editpaccurrentwin);
1406 us_editpacdrawhscroll(us_editpaccurrentwin);
1407 return(FALSE);
1408 }
1409
1410 /******************** CHANGES TO EDIT BUFFER ********************/
1411
1412 /*
1413 * routine to implement character "i". The key is issued internally if "fromuser"
1414 * is false. Routine returns true if the editor window has been terminated.
1415 */
us_editpacimplementchar(WINDOWPART * win,INTSML i,INTBIG special,BOOLEAN fromuser)1416 BOOLEAN us_editpacimplementchar(WINDOWPART *win, INTSML i, INTBIG special, BOOLEAN fromuser)
1417 {
1418 REGISTER EDITOR *e;
1419 INTBIG j, len;
1420 CHAR save;
1421 CHAR *nextline;
1422
1423 e = win->editor;
1424 if (e == NOEDITOR) return(TRUE);
1425
1426 /* ESCAPE quits the editor */
1427 if (i == ESCKEY) return(TRUE);
1428
1429 if ((special&SPECIALKEYDOWN) != 0)
1430 {
1431 switch ((special&SPECIALKEY) >> SPECIALKEYSH)
1432 {
1433 case SPECIALKEYARROWL:
1434 us_editpacdonetyping(e);
1435 if (e->curline == e->endline && e->curchar == e->endchar)
1436 {
1437 if (e->curchar != 0) e->curchar--; else
1438 {
1439 if (e->curline > 0)
1440 {
1441 e->curline--;
1442 e->curchar = estrlen(e->textarray[e->curline]);
1443 us_editpacbeginwork(win);
1444 }
1445 }
1446 }
1447 e->endline = e->curline;
1448 e->endchar = e->curchar;
1449 e->charposition = e->endchar;
1450 us_editpacensurelinevisible(win, e->curline, FALSE);
1451 return(FALSE);
1452 case SPECIALKEYARROWR:
1453 us_editpacdonetyping(e);
1454 if (e->curline == e->endline && e->curchar == e->endchar)
1455 {
1456 if (e->textarray[e->endline][e->endchar] != 0) e->endchar++; else
1457 {
1458 if (e->endline < e->linecount-1)
1459 {
1460 e->endline++;
1461 e->endchar = 0;
1462 us_editpacbeginwork(win);
1463 }
1464 }
1465 }
1466 e->curline = e->endline;
1467 e->curchar = e->endchar;
1468 e->charposition = e->endchar;
1469 us_editpacensurelinevisible(win, e->curline, FALSE);
1470 return(FALSE);
1471 case SPECIALKEYARROWU:
1472 us_editpacdonetyping(e);
1473 if (e->curline > 0)
1474 {
1475 e->curline--;
1476 len = estrlen(e->textarray[e->curline]);
1477 if (e->charposition > e->curchar) e->curchar = e->charposition;
1478 if (e->curchar > len) e->curchar = len;
1479 e->endline = e->curline;
1480 e->endchar = e->curchar;
1481 us_editpacbeginwork(win);
1482 us_editpacensurelinevisible(win, e->curline, FALSE);
1483 }
1484 return(FALSE);
1485 case SPECIALKEYARROWD:
1486 us_editpacdonetyping(e);
1487 if (e->endline < e->linecount-1)
1488 {
1489 e->endline++;
1490 len = estrlen(e->textarray[e->endline]);
1491 if (e->charposition > e->endchar) e->endchar = e->charposition;
1492 if (e->endchar > len) e->endchar = len;
1493 e->curline = e->endline;
1494 e->curchar = e->endchar;
1495 us_editpacbeginwork(win);
1496 us_editpacensurelinevisible(win, e->curline, FALSE);
1497 }
1498 return(FALSE);
1499 }
1500 }
1501
1502 /* if delete key hit and nothing selected, set to erase previous character */
1503 if (i == BACKSPACEKEY || i == DELETEKEY)
1504 {
1505 if (e->curline == e->endline && e->curchar == e->endchar)
1506 {
1507 #ifdef WIN32
1508 if (i == DELETEKEY)
1509 {
1510 /* advance the end character */
1511 len = estrlen(e->textarray[e->endline]);
1512 if (e->endchar < len) e->endchar++; else
1513 {
1514 if (e->endline < e->linecount)
1515 {
1516 e->endchar = 0;
1517 e->endline++;
1518 }
1519 }
1520 } else
1521 #endif
1522 {
1523 /* backup the start character */
1524 if (e->curchar > 0) e->curchar--; else
1525 {
1526 if (e->curline > 0)
1527 {
1528 e->curline--;
1529 e->curchar = estrlen(e->textarray[e->curline]);
1530 us_editpacbeginwork(win);
1531 }
1532 }
1533 }
1534 }
1535 }
1536
1537 /* see if lines are fixed */
1538 if ((e->state&LINESFIXED) != 0)
1539 {
1540 /* disallow line insertion, deletion or any action on the last line */
1541 if (e->curline != e->endline || i == '\n' || i == '\r' || e->curline == e->linecount-1)
1542 {
1543 ttybeep(SOUNDBEEP, TRUE);
1544 return(FALSE);
1545 }
1546 }
1547
1548 us_editpacamtyping(e);
1549 if (i == BACKSPACEKEY || i == DELETEKEY) us_editpactypeddelete(e);
1550
1551 /* remove the selected characters */
1552 us_editpacremoveselection(win);
1553 e->endline = e->curline;
1554 e->endchar = e->curchar;
1555 e->charposition = e->endchar;
1556
1557 /* mark a dirty edit buffer */
1558 e->dirty = TRUE;
1559
1560 /* ignore delete or backspace characters */
1561 if (i == BACKSPACEKEY || i == DELETEKEY) return(FALSE);
1562
1563 /* handle end-of-line characters */
1564 if (i == '\n' || i == '\r')
1565 {
1566 /* exit editor if only editing one line */
1567 if ((win->state&WINDOWTYPE) == POPTEXTWINDOW) return(TRUE);
1568
1569 /* see if there is room in the file */
1570 if (e->linecount >= e->maxlines) us_editpacaddmorelines(e);
1571
1572 if (fromuser)
1573 {
1574 if (e->curline == e->firstline+e->screenlines-1)
1575 {
1576 e->firstline++;
1577 if ((e->state&EGRAPHICSOFF) == 0)
1578 {
1579 us_editpacmovebox(win, 0, 0, e->swid, us_editpacthei*(e->screenlines-1), 0, 1);
1580 us_editpacclearbox(win, 0, e->screenlines-1, e->swid, us_editpacthei);
1581 if (e->screenlines+e->firstline <= e->linecount)
1582 us_editpactext(win, e->textarray[e->screenlines-1+e->firstline], 0,
1583 e->screenlines-1);
1584 }
1585 }
1586 }
1587
1588 /* shift lines down */
1589 for(j = e->linecount; j > e->curline; j--)
1590 {
1591 if (j == e->curline+1) nextline = &e->textarray[e->curline][e->curchar]; else
1592 nextline = e->textarray[j-1];
1593 len = estrlen(nextline) + 1;
1594 if (len > e->maxchars[j])
1595 us_editpacaddmorechars(e, j, len);
1596 (void)estrcpy(e->textarray[j], nextline);
1597 }
1598 e->textarray[e->curline][e->curchar] = 0;
1599 if ((e->state&EGRAPHICSOFF) == 0 && e->curline-e->firstline < e->screenlines &&
1600 e->curline >= e->firstline) us_editpaccleanupline(win, e->curline);
1601 e->curline = e->endline = e->curline+1;
1602 e->linecount++;
1603 e->curchar = 0; e->endchar = 0;
1604
1605 /* ship changes on the current line */
1606 us_editpacshipchanges(win);
1607 if (win->changehandler != 0)
1608 (*win->changehandler)(win, INSERTTEXTLINE, x_(""), e->textarray[e->curline], e->curline);
1609 us_editpacbeginwork(win);
1610
1611 /* shift lines down */
1612 if (e->curline+1-e->firstline < e->screenlines &&
1613 e->curline+1 >= e->firstline && (e->state&EGRAPHICSOFF) == 0)
1614 us_editpacmovebox(win, 0, e->curline+1-e->firstline,
1615 e->swid, e->shei-(e->curline+1-e->firstline)*us_editpacthei, 0,
1616 e->curline-e->firstline);
1617
1618 /* draw current line */
1619 if (e->curline-e->firstline < e->screenlines &&
1620 e->curline >= e->firstline && (e->state&EGRAPHICSOFF) == 0)
1621 {
1622 save = e->textarray[e->curline][0];
1623 e->textarray[e->curline][0] = 0;
1624 us_editpaccleanupline(win, e->curline);
1625 e->textarray[e->curline][0] = save;
1626 us_editpactext(win, e->textarray[e->curline], 0, e->curline-e->firstline);
1627 }
1628 if ((e->state&EGRAPHICSOFF) == 0) us_editpacdrawvscroll(win);
1629 e->charposition = e->endchar;
1630 return(FALSE);
1631 }
1632
1633 /* self-insert of normal characters */
1634 if (i == '\t') i = ' ';
1635
1636 /* see if line needs to be extended */
1637 j = estrlen(e->textarray[e->curline]) + 2;
1638 if (j > e->maxchars[e->curline])
1639 us_editpacaddmorechars(e, e->curline, j+10);
1640
1641 /* see if new character is at end of line */
1642 if (e->textarray[e->curline][e->curchar] != 0)
1643 {
1644 /* it is not: shift letters on the line */
1645 len = estrlen(e->textarray[e->curline]);
1646 for(j = len+1; j > e->curchar; j--)
1647 e->textarray[e->curline][j] = e->textarray[e->curline][j-1];
1648 } else e->textarray[e->curline][e->curchar+1] = 0;
1649
1650 /* clear from here to the end of the line */
1651 if (e->curline-e->firstline < e->screenlines && e->curline >= e->firstline &&
1652 (e->state&EGRAPHICSOFF) == 0)
1653 {
1654 e->textarray[e->curline][e->curchar] = 0;
1655 us_editpaccleanupline(win, e->curline);
1656 }
1657
1658 /* insert the character */
1659 e->textarray[e->curline][e->curchar] = (CHAR)i;
1660
1661 /* put the rest of the line on the display */
1662 if (e->curline-e->firstline < e->screenlines && e->curline >= e->firstline &&
1663 e->curchar-e->horizfactor < e->screenchars && (e->state&EGRAPHICSOFF) == 0)
1664 {
1665 us_editpactext(win, &e->textarray[e->curline][e->curchar], e->curchar,
1666 e->curline-e->firstline);
1667 }
1668
1669 /* advance the character pointer */
1670 e->curchar++; e->endchar++;
1671 e->charposition = e->endchar;
1672 return(FALSE);
1673 }
1674
us_editpacremoveselection(WINDOWPART * win)1675 void us_editpacremoveselection(WINDOWPART *win)
1676 {
1677 REGISTER EDITOR *e;
1678 REGISTER INTBIG j, k, diff;
1679 REGISTER CHAR save;
1680
1681 e = win->editor;
1682 if (e == NOEDITOR) return;
1683
1684 /* nothing to do if there is a null selection */
1685 diff = e->endline - e->curline;
1686 if (e->curline == e->endline && e->curchar == e->endchar) return;
1687
1688 /* report the deletion */
1689 if (win->changehandler != 0)
1690 {
1691 /* send out changes made so far if this is a multiline delete */
1692 if (diff > 0) us_editpacshipchanges(win);
1693 for(j=diff-1; j>=0; j--)
1694 (*win->changehandler)(win, DELETETEXTLINE, e->textarray[e->curline+j], x_(""),
1695 e->curline+j);
1696 }
1697 if (diff > 0)
1698 us_editpacbeginwork(win);
1699
1700 /* append text beyond end of selection to the start of the selection */
1701 j = estrlen(&e->textarray[e->endline][e->endchar]) + e->curchar + 1;
1702 if (j > e->maxchars[e->curline])
1703 us_editpacaddmorechars(e, e->curline, j);
1704 (void)estrcpy(&e->textarray[e->curline][e->curchar],
1705 &e->textarray[e->endline][e->endchar]);
1706
1707 /* redraw this line */
1708 if (e->curline-e->firstline < e->screenlines && e->curline >= e->firstline &&
1709 e->curchar-e->horizfactor < e->screenchars-1 && (e->state&EGRAPHICSOFF) == 0)
1710 {
1711 save = e->textarray[e->curline][e->curchar];
1712 e->textarray[e->curline][e->curchar] = 0;
1713 us_editpaccleanupline(win, e->curline);
1714 e->textarray[e->curline][e->curchar] = save;
1715 us_editpactext(win, &e->textarray[e->curline][e->curchar], e->curchar,
1716 e->curline-e->firstline);
1717 }
1718
1719 /* now shift up text (if a multiline delete) */
1720 if (diff > 0)
1721 {
1722 for(j=e->curline+1; j<e->linecount-diff; j++)
1723 {
1724 /* make sure there is room for the shifted line */
1725 k = estrlen(e->textarray[j+diff]) + 1;
1726 if (k > e->maxchars[j]) us_editpacaddmorechars(e, j, k);
1727
1728 /* copy new line */
1729 if (j-e->firstline < e->screenlines && j >= e->firstline &&
1730 (e->state&EGRAPHICSOFF) == 0)
1731 {
1732 /* erase this line */
1733 e->textarray[j][0] = 0;
1734 us_editpaccleanupline(win, j);
1735
1736 (void)estrcpy(e->textarray[j], e->textarray[j+diff]);
1737 us_editpactext(win, e->textarray[j], 0, j-e->firstline);
1738 } else (void)estrcpy(e->textarray[j], e->textarray[j+diff]);
1739 }
1740 for(j=e->linecount-diff; j<e->linecount; j++)
1741 {
1742 e->textarray[j][0] = 0;
1743 if (j-e->firstline < e->screenlines && j >= e->firstline && (e->state&EGRAPHICSOFF) == 0)
1744 us_editpaccleanupline(win, j);
1745 }
1746 e->linecount -= diff;
1747 }
1748 }
1749
1750 /******************** DISPLAY OF EDIT WINDOW ********************/
1751
1752 /*
1753 * routine to redisplay the text screen
1754 */
us_editpacredrawscreen(WINDOWPART * win)1755 void us_editpacredrawscreen(WINDOWPART *win)
1756 {
1757 REGISTER EDITOR *e;
1758
1759 e = win->editor;
1760 if (e == NOEDITOR) return;
1761 if ((e->state&EGRAPHICSOFF) != 0) return;
1762
1763 /* put header on display */
1764 us_editpacsetheader(win, e->header);
1765 us_editpacdrawsliders(win);
1766
1767 us_editpacredrawlines(win);
1768 }
1769
us_editpacdrawsliders(WINDOWPART * win)1770 void us_editpacdrawsliders(WINDOWPART *win)
1771 {
1772 REGISTER EDITOR *e;
1773
1774 e = win->editor;
1775 if (e == NOEDITOR) return;
1776
1777 /* draw horizontal slider */
1778 us_drawhorizontalslider(win, win->usely+DISPLAYSLIDERSIZE, win->uselx,
1779 win->usehx-DISPLAYSLIDERSIZE, 0);
1780 us_editpacdrawhscroll(win);
1781
1782 /* draw vertical slider if appropriate */
1783 if ((win->state&WINDOWTYPE) != POPTEXTWINDOW)
1784 {
1785 us_drawverticalslider(win, win->usehx-DISPLAYSLIDERSIZE,
1786 win->usely+DISPLAYSLIDERSIZE, win->usehy-us_editpacthei*HEADERLINES, FALSE);
1787
1788 /* the corner */
1789 us_drawslidercorner(win, win->usehx-DISPLAYSLIDERSIZE+1, win->usehx, win->usely,
1790 win->usely+DISPLAYSLIDERSIZE-1, FALSE);
1791 us_editpacdrawvscroll(win);
1792 }
1793 }
1794
1795 /*
1796 * Routine to set the horizontal scroll bar
1797 */
us_editpacdrawhscroll(WINDOWPART * win)1798 void us_editpacdrawhscroll(WINDOWPART *win)
1799 {
1800 INTBIG left, right;
1801 INTBIG f;
1802 REGISTER EDITOR *e;
1803
1804 e = win->editor;
1805 if (e == NOEDITOR) return;
1806
1807 /* get the area of the slider without arrows */
1808 left = e->offx+DISPLAYSLIDERSIZE-LEFTINDENT;
1809 right = e->offx + e->swid - DISPLAYSLIDERSIZE;
1810
1811 /* compute position of vertical thumb area */
1812 f = e->horizfactor; f *= right-left-THUMBSIZE; f /= e->screenchars*10;
1813 e->hthumbpos = left + THUMBSIZE/2 + f;
1814 if (e->hthumbpos > right-THUMBSIZE/2) e->hthumbpos = right-THUMBSIZE/2;
1815
1816 /* draw the thumb */
1817 win->thumblx = e->hthumbpos - THUMBSIZE/2; win->thumbhx = e->hthumbpos + THUMBSIZE/2;
1818 us_drawhorizontalsliderthumb(win, win->usely+DISPLAYSLIDERSIZE, win->uselx,
1819 win->usehx-DISPLAYSLIDERSIZE, win->thumblx, win->thumbhx, 0);
1820 }
1821
1822 /*
1823 * Routine to set the vertical scroll bar
1824 */
us_editpacdrawvscroll(WINDOWPART * win)1825 void us_editpacdrawvscroll(WINDOWPART *win)
1826 {
1827 INTBIG top, bottom;
1828 INTBIG den;
1829 REGISTER EDITOR *e;
1830
1831 e = win->editor;
1832 if (e == NOEDITOR) return;
1833
1834 /* get the area of the slider without arrows */
1835 top = e->revy - DISPLAYSLIDERSIZE;
1836 bottom = e->revy - e->shei + DISPLAYSLIDERSIZE;
1837
1838 /* if there is nothing to scroll, clear this area */
1839 if (e->linecount <= e->screenlines)
1840 {
1841 us_drawverticalsliderthumb(win, win->usehx-DISPLAYSLIDERSIZE, win->usely+DISPLAYSLIDERSIZE,
1842 win->usehy-us_editpacthei*HEADERLINES, 1, 0);
1843 return;
1844 }
1845
1846 /* compute position of vertical thumb area */
1847 den = e->linecount - e->screenlines;
1848 e->vthumbpos = e->revy - DISPLAYSLIDERSIZE - THUMBSIZE/2 -
1849 (e->firstline * (e->shei-DISPLAYSLIDERSIZE*2-THUMBSIZE) + den/2) / den;
1850 if (e->vthumbpos >= top-THUMBSIZE/2) e->vthumbpos = top-THUMBSIZE/2-1;
1851 if (e->vthumbpos <= bottom+THUMBSIZE/2) e->vthumbpos = bottom+THUMBSIZE/2+1;
1852
1853 win->thumbly = e->vthumbpos - THUMBSIZE/2;
1854 win->thumbhy = e->vthumbpos + THUMBSIZE/2;
1855 us_drawverticalsliderthumb(win, win->usehx-DISPLAYSLIDERSIZE, win->usely+DISPLAYSLIDERSIZE,
1856 win->usehy-us_editpacthei*HEADERLINES, win->thumbly, win->thumbhy);
1857 }
1858
1859 /*
1860 * routine to clear the bits from the last character to the end of the line
1861 */
us_editpaccleanupline(WINDOWPART * win,INTBIG line)1862 void us_editpaccleanupline(WINDOWPART *win, INTBIG line)
1863 {
1864 REGISTER INTBIG residue, linelen;
1865 REGISTER EDITOR *e;
1866
1867 e = win->editor;
1868 if (e == NOEDITOR) return;
1869 linelen = estrlen(e->textarray[line]);
1870 residue = e->swid-(linelen - e->horizfactor)*us_editpactwid;
1871 if (residue <= 0) return;
1872 us_editpacclearbox(win, linelen - e->horizfactor, line-e->firstline,
1873 residue, us_editpacthei);
1874 }
1875
1876 /*
1877 * routine to redisplay the text screen
1878 */
us_editpacredrawlines(WINDOWPART * win)1879 void us_editpacredrawlines(WINDOWPART *win)
1880 {
1881 REGISTER INTBIG j;
1882 REGISTER INTBIG bottom;
1883 REGISTER EDITOR *e;
1884
1885 e = win->editor;
1886 if (e == NOEDITOR) return;
1887 if ((e->state&EGRAPHICSOFF) != 0) return;
1888
1889 /* clear the screen */
1890 bottom = e->revy - e->shei;
1891 screendrawbox(win, e->offx-LEFTINDENT, e->offx+e->swid+1, bottom-1, e->revy,
1892 &us_ebox);
1893
1894 /* rewrite each line */
1895 for(j=0; j<e->screenlines; j++) if (j+e->firstline < e->linecount)
1896 us_editpactext(win, e->textarray[j+e->firstline], 0, j);
1897 us_editpacinvertselection(win);
1898 }
1899
1900 /*
1901 * routine to write the header string
1902 */
us_editpacsetheader(WINDOWPART * win,CHAR * header)1903 void us_editpacsetheader(WINDOWPART *win, CHAR *header)
1904 {
1905 REGISTER INTBIG save, formerhf, bottom;
1906 REGISTER EDITOR *e;
1907
1908 e = win->editor;
1909 if (e == NOEDITOR) return;
1910 screendrawbox(win, win->uselx, win->usehx, e->revy+1,
1911 e->revy+us_editpacthei*HEADERLINES, &us_ebox);
1912 if ((INTBIG)estrlen(header) > e->screenchars)
1913 {
1914 save = header[e->screenchars];
1915 header[e->screenchars] = 0;
1916 } else save = 0;
1917 formerhf = e->horizfactor;
1918 e->horizfactor = 0;
1919 us_editpactext(win, header, 0, -2);
1920 if ((win->state&WINDOWTYPE) == POPTEXTWINDOW)
1921 us_editpactext(win, _("Point-and-Click editor: type RETURN when done"), 0, -1); else
1922 {
1923 if (estrcmp(win->location, x_("entire")) != 0)
1924 us_editpactext(win, _("Point-and-Click editor: type ESC when done"), 0, -1); else
1925 {
1926 if (graphicshas(CANUSEFRAMES))
1927 us_editpactext(win, _("Point-and-Click editor: close the window when done"), 0, -1); else
1928 us_editpactext(win, _("Point-and-Click editor: text-only cell"), 0, -1);
1929 }
1930 }
1931 e->horizfactor = formerhf;
1932
1933 if (save != 0) header[e->screenchars] = (CHAR)save;
1934 bottom = e->revy - e->shei - 1;
1935 screeninvertbox(win, win->uselx, win->usehx, e->revy+1,
1936 e->revy+us_editpacthei*HEADERLINES);
1937 us_menufigs.col = el_colmengly;
1938 screendrawline(win, win->uselx, e->revy, win->uselx, bottom, &us_menufigs, 0);
1939 if ((win->state&WINDOWTYPE) == POPTEXTWINDOW)
1940 {
1941 screendrawline(win, win->uselx, win->usely, win->uselx, win->usehy, &us_menufigs, 0);
1942 screendrawline(win, win->uselx, win->usely, win->usehx, win->usely, &us_menufigs, 0);
1943 screendrawline(win, win->usehx, win->usely, win->usehx, win->usehy, &us_menufigs, 0);
1944 }
1945 }
1946
1947 /*
1948 * Routine to shift the edit window by the direction in the coordinates (dx, dy)
1949 */
us_editpacpanwindow(WINDOWPART * w,INTBIG dx,INTBIG dy)1950 void us_editpacpanwindow(WINDOWPART *w, INTBIG dx, INTBIG dy)
1951 {
1952 REGISTER EDITOR *e;
1953 REGISTER INTBIG i;
1954
1955 e = w->editor;
1956 us_editpacinvertselection(w);
1957 if (dx == 0)
1958 {
1959 /* vertical panning */
1960 if (dy > 0)
1961 {
1962 /* pan down by 1 line */
1963 if (e->firstline >= e->linecount) return;
1964 e->firstline++;
1965
1966 /* shift the window contents up by 1 line (us_editpacthei) */
1967 screenmovebox(w, e->offx-LEFTINDENT, e->revy-e->shei,
1968 e->swid+LEFTINDENT, e->shei-us_editpacthei, e->offx-LEFTINDENT,
1969 e->revy-e->shei+us_editpacthei);
1970
1971 /* fill in a new last line */
1972 screendrawbox(w, e->offx-LEFTINDENT, e->offx+e->swid,
1973 e->revy-e->shei, e->revy-e->shei+us_editpacthei, &us_ebox);
1974 i = e->firstline + e->screenlines - 1;
1975 if (i < e->linecount)
1976 us_editpactext(w, e->textarray[i], 0, i-e->firstline);
1977 } else
1978 {
1979 /* pan up by 1 line */
1980 if (e->firstline <= 0) return;
1981 e->firstline--;
1982
1983 /* shift the window contents down by 1 line (us_editpacthei) */
1984 screenmovebox(w, e->offx-LEFTINDENT, e->revy-e->shei+us_editpacthei, e->swid+LEFTINDENT,
1985 e->shei-us_editpacthei, e->offx-LEFTINDENT, e->revy-e->shei);
1986
1987 /* fill in a new first line */
1988 screendrawbox(w, e->offx-LEFTINDENT, e->offx+e->swid,
1989 e->revy-us_editpacthei, e->revy, &us_ebox);
1990 us_editpactext(w, e->textarray[e->firstline], 0, 0);
1991 }
1992 us_editpacinvertselection(w);
1993 us_editpacdrawvscroll(w);
1994 } else
1995 {
1996 /* horizontal panning */
1997 if (dx > 0)
1998 {
1999 /* pan to the right */
2000 if (e->horizfactor >= e->screenchars*10) return;
2001 e->horizfactor++;
2002 us_editpacredrawlines(w);
2003 us_editpacdrawhscroll(w);
2004 } else
2005 {
2006 /* pan to the left */
2007 if (e->horizfactor <= 0) return;
2008 e->horizfactor--;
2009 us_editpacredrawlines(w);
2010 us_editpacdrawhscroll(w);
2011 }
2012 }
2013 }
2014
2015 /*
2016 * routine to invert the selected text, turning it on or off
2017 */
us_editpacinvertselection(WINDOWPART * win)2018 void us_editpacinvertselection(WINDOWPART *win)
2019 {
2020 INTBIG i, startchar, endchar, ll, lc, hl, hc, lx, hx, ly, hy;
2021 REGISTER EDITOR *e;
2022
2023 e = win->editor;
2024 if (e == NOEDITOR) return;
2025
2026 if ((e->state&EGRAPHICSOFF) != 0) return;
2027 ll = e->curline; lc = e->curchar;
2028 hl = e->endline; hc = e->endchar;
2029 if (ll > hl || (ll == hl && lc > hc))
2030 {
2031 i = hl; hl = ll; ll = i;
2032 i = hc; hc = lc; lc = i;
2033 }
2034 for(i = ll; i <= hl; i++)
2035 {
2036 if (i < e->firstline) continue;
2037 if (i-e->firstline >= e->screenlines) continue;
2038 if (i == ll) startchar = lc; else startchar = 0;
2039 if (i == hl) endchar = hc; else endchar = e->mostchars+e->horizfactor;
2040 if (endchar == 0 && ll != hl) continue;
2041
2042 /* compute bounds of box to invert */
2043 lx = e->offx + (startchar-e->horizfactor) * us_editpactwid - 1;
2044 hx = e->offx + (endchar-e->horizfactor) * us_editpactwid - 1;
2045 ly = e->revy - (i-e->firstline) * us_editpacthei - us_editpacthei;
2046 hy = e->revy - (i-e->firstline) * us_editpacthei - 1;
2047
2048 /* limit to display */
2049 if (lx > e->offx + e->swid || hx < e->offx-1) continue;
2050 if (lx < e->offx-1) lx = e->offx-1;
2051 if (hx > e->offx + e->swid) hx = e->offx + e->swid;
2052 if (ly > e->revy || hy < e->revy - e->shei) continue;
2053 if (ly < e->revy - e->shei) ly = e->revy - e->shei;
2054 if (hy > e->revy) hy = e->revy;
2055
2056 screeninvertbox(win, lx, hx, ly, hy);
2057 }
2058 }
2059
2060 /******************** UNDO CONTROL ********************/
2061
us_editpacdonetyping(EDITOR * e)2062 void us_editpacdonetyping(EDITOR *e)
2063 {
2064 if ((e->state&TEXTTYPING) == 0) return;
2065
2066 if (e->curline < us_editpacundonewcurline ||
2067 (e->curline == us_editpacundonewcurline && e->curchar < us_editpacundonewcurchar))
2068 {
2069 us_editpacundonewcurline = e->curline; us_editpacundonewcurchar = e->curchar;
2070 }
2071 if (e->endline > us_editpacundonewendline ||
2072 (e->endline == us_editpacundonewendline && e->endchar > us_editpacundonewendchar))
2073 {
2074 us_editpacundonewendline = e->endline; us_editpacundonewendchar = e->endchar;
2075 }
2076
2077 e->state &= ~TEXTTYPING;
2078 }
2079
us_editpacamtyping(EDITOR * e)2080 void us_editpacamtyping(EDITOR *e)
2081 {
2082 REGISTER INTBIG len;
2083
2084 if ((e->state&TEXTTYPING) != 0)
2085 {
2086 if (e->curline < us_editpacundonewcurline ||
2087 (e->curline == us_editpacundonewcurline && e->curchar < us_editpacundonewcurchar))
2088 {
2089 us_editpacundonewcurline = e->curline;
2090 us_editpacundonewcurchar = e->curchar;
2091 }
2092 if (e->endline > us_editpacundonewendline ||
2093 (e->endline == us_editpacundonewendline && e->endchar > us_editpacundonewendchar))
2094 {
2095 us_editpacundonewendline = e->endline;
2096 us_editpacundonewendchar = e->endchar;
2097 }
2098 return;
2099 }
2100 e->state |= TEXTTYPING | TEXTTYPED;
2101
2102 /* start of typing: save current position for what is typed */
2103 us_editpacundonewcurline = us_editpacundonewendline = e->curline;
2104 us_editpacundonewcurchar = us_editpacundonewendchar = e->curchar;
2105
2106 /* remember former selection */
2107 us_editpacundooldcurline = e->curline; us_editpacundooldcurchar = e->curchar;
2108
2109 /* save what is selected */
2110 len = us_editpaccharstocurrent(e, e->endchar, e->endline) + 1;
2111 if (len > us_editpacundobuffersize)
2112 {
2113 if (us_editpacundobuffersize != 0) efree(us_editpacundobuffer);
2114 us_editpacundobuffersize = 0;
2115 us_editpacundobuffer = (CHAR *)emalloc(len * SIZEOFCHAR, us_tool->cluster);
2116 if (us_editpacundobuffer == 0) return;
2117 us_editpacundobuffersize = len;
2118 }
2119 us_editpacloadselection(e, us_editpacundobuffer);
2120 }
2121
us_editpactypeddelete(EDITOR * e)2122 void us_editpactypeddelete(EDITOR *e)
2123 {
2124 REGISTER INTBIG len, i;
2125 REGISTER CHAR *newbuffer;
2126
2127 if ((e->state&TEXTTYPING) == 0) return;
2128
2129 /* if still beyond start of typing, quit */
2130 if (e->curline > us_editpacundooldcurline ||
2131 (e->curline == us_editpacundooldcurline && e->curchar >= us_editpacundooldcurchar))
2132 return;
2133
2134 /* make sure there is room for one more character */
2135 len = estrlen(us_editpacundobuffer) +
2136 us_editpaccharstocurrent(e, us_editpacundooldcurchar, us_editpacundooldcurline) + 1;
2137 if (len > us_editpacundobuffersize)
2138 {
2139 newbuffer = (CHAR *)emalloc(len * SIZEOFCHAR, us_tool->cluster);
2140 if (newbuffer == 0) return;
2141 (void)estrcpy(newbuffer, us_editpacundobuffer);
2142 if (us_editpacundobuffersize > 0) efree(us_editpacundobuffer);
2143 us_editpacundobuffer = newbuffer;
2144 us_editpacundobuffersize = len;
2145 }
2146
2147 /* shift the buffer up */
2148 for(i=len-1; i>0; i--) us_editpacundobuffer[i] = us_editpacundobuffer[i-1];
2149 us_editpacundobuffer[0] = e->textarray[e->curline][e->curchar];
2150 if (us_editpacundobuffer[0] == 0) us_editpacundobuffer[0] = '\n';
2151
2152 us_editpacundooldcurline = e->curline; us_editpacundooldcurchar = e->curchar;
2153
2154 us_editpacundonewcurline = us_editpacundonewendline = e->curline;
2155 us_editpacundonewcurchar = us_editpacundonewendchar = e->curchar;
2156 }
2157
us_editpaccharstocurrent(EDITOR * e,INTBIG endchar,INTBIG endline)2158 INTBIG us_editpaccharstocurrent(EDITOR *e, INTBIG endchar, INTBIG endline)
2159 {
2160 REGISTER INTBIG len, line, startchar, startline, fromchar, tochar;
2161
2162 if (e->curline > endline || (e->curline == endline && e->curchar > endchar))
2163 {
2164 startchar = endchar; endchar = e->curchar;
2165 startline = endline; endline = e->curline;
2166 } else
2167 {
2168 startchar = e->curchar;
2169 startline = e->curline;
2170 }
2171 len = 0;
2172 for(line = startline; line <= endline; line++)
2173 {
2174 if (line == startline) fromchar = startchar; else fromchar = 0;
2175 if (line == endline) tochar = endchar; else
2176 tochar = estrlen(e->textarray[line])+1;
2177 len += tochar - fromchar;
2178 }
2179 return(len);
2180 }
2181
us_editpacloadselection(EDITOR * e,CHAR * buf)2182 void us_editpacloadselection(EDITOR *e, CHAR *buf)
2183 {
2184 REGISTER INTBIG len, line, startch, endch, i, ch;
2185
2186 len = 0;
2187 for(line = e->curline; line <= e->endline; line++)
2188 {
2189 if (line == e->curline) startch = e->curchar; else startch = 0;
2190 if (line == e->endline) endch = e->endchar; else endch = estrlen(e->textarray[line])+1;
2191 for(i=startch; i<endch; i++)
2192 {
2193 ch = e->textarray[line][i];
2194 if (ch == 0) ch = '\n';
2195 buf[len++] = (CHAR)ch;
2196 }
2197 }
2198 buf[len] = 0;
2199 }
2200
us_editpacadvanceposition(EDITOR * e,INTBIG * chr,INTBIG * lne)2201 void us_editpacadvanceposition(EDITOR *e, INTBIG *chr, INTBIG *lne)
2202 {
2203 if (e->textarray[*lne][*chr] != 0) (*chr)++; else
2204 {
2205 *chr = 0;
2206 (*lne)++;
2207 if (*lne >= e->linecount) *lne = 0;
2208 }
2209 }
2210
us_editpacbackupposition(EDITOR * e,INTBIG * chr,INTBIG * lne)2211 void us_editpacbackupposition(EDITOR *e, INTBIG *chr, INTBIG *lne)
2212 {
2213 (*chr)--;
2214 if (*chr < 0)
2215 {
2216 (*lne)--;
2217 if (*lne < 0) *lne = e->linecount - 1;
2218 *chr = estrlen(e->textarray[*lne]) - 1;
2219 }
2220 }
2221
2222 /******************** SUPPORT ********************/
2223
2224 /*
2225 * routine to determine the extents of the editing window
2226 */
us_editpaccomputebounds(WINDOWPART * win,EDITOR * e)2227 void us_editpaccomputebounds(WINDOWPART *win, EDITOR *e)
2228 {
2229 REGISTER INTBIG offset;
2230
2231 e->offx = win->uselx + 1 + LEFTINDENT;
2232 e->swid = win->usehx - e->offx - 1;
2233 offset = 1;
2234 if ((win->state&WINDOWTYPE) != POPTEXTWINDOW) e->swid -= DISPLAYSLIDERSIZE;
2235 else offset++;
2236 e->shei = win->usehy - win->usely - us_editpacthei*HEADERLINES - offset - DISPLAYSLIDERSIZE;
2237 e->revy = e->shei + win->usely + offset + DISPLAYSLIDERSIZE;
2238 e->screenlines = e->shei / us_editpacthei;
2239 e->screenchars = e->swid / us_editpactwid;
2240 }
2241
us_editpacbeginwork(WINDOWPART * win)2242 void us_editpacbeginwork(WINDOWPART *win)
2243 {
2244 EDITOR *e;
2245 REGISTER CHAR *newline;
2246 REGISTER INTBIG len;
2247
2248 e = win->editor;
2249 if (e == NOEDITOR) return;
2250 if (e->working == e->curline) return;
2251 us_editpacshipchanges(win);
2252 e->working = e->curline;
2253
2254 /* make sure there is room in the line-change buffer */
2255 len = estrlen(e->textarray[e->working]);
2256 if (len >= e->mostchars)
2257 {
2258 newline = (CHAR *)emalloc((len+1) * SIZEOFCHAR, us_tool->cluster);
2259 if (newline == 0) return;
2260 efree(e->formerline);
2261 e->formerline = newline;
2262 e->mostchars = len;
2263 }
2264
2265 /* save the current line */
2266 (void)estrcpy(e->formerline, e->textarray[e->working]);
2267 }
2268
2269 /*
2270 * routine to double the number of lines in the text buffer
2271 */
us_editpacaddmorelines(EDITOR * e)2272 void us_editpacaddmorelines(EDITOR *e)
2273 {
2274 REGISTER INTBIG oldlines, i;
2275 REGISTER INTBIG *maxchars;
2276 REGISTER CHAR **textarray;
2277
2278 /* save former buffer size, double it */
2279 oldlines = e->maxlines;
2280 e->maxlines *= 2;
2281 if (e->maxlines <= 0) e->maxlines = 1;
2282
2283 /* allocate new arrays */
2284 maxchars = (INTBIG *)emalloc((e->maxlines * SIZEOFINTBIG), us_tool->cluster);
2285 if (maxchars == 0) ttyputnomemory();
2286 textarray = (CHAR **)emalloc((e->maxlines * (sizeof (CHAR *))), us_tool->cluster);
2287 if (textarray == 0) ttyputnomemory();
2288
2289 /* copy old information */
2290 for(i=0; i<e->maxlines; i++)
2291 {
2292 if (i >= oldlines)
2293 {
2294 textarray[i] = (CHAR *)emalloc(DEFAULTWID * SIZEOFCHAR, us_tool->cluster);
2295 if (textarray[i] == 0) ttyputnomemory();
2296 textarray[i][0] = 0;
2297 maxchars[i] = DEFAULTWID;
2298 } else
2299 {
2300 textarray[i] = e->textarray[i];
2301 maxchars[i] = e->maxchars[i];
2302 }
2303 }
2304
2305 /* free old arrays */
2306 efree((CHAR *)e->textarray);
2307 efree((CHAR *)e->maxchars);
2308
2309 /* setup pointers correctly */
2310 e->textarray = textarray;
2311 e->maxchars = maxchars;
2312 }
2313
2314 /*
2315 * routine to increase the number of characters in line "line" to "need" (+1 for the null)
2316 */
us_editpacaddmorechars(EDITOR * e,INTBIG line,INTBIG need)2317 void us_editpacaddmorechars(EDITOR *e, INTBIG line, INTBIG need)
2318 {
2319 REGISTER CHAR *oldline;
2320
2321 /* extend the current line */
2322 if (line >= e->maxlines) return;
2323 oldline = e->textarray[line];
2324 e->maxchars[line] = need+1;
2325 e->textarray[line] = (CHAR *)emalloc((need+1) * SIZEOFCHAR, us_tool->cluster);
2326 (void)estrcpy(e->textarray[line], oldline);
2327 efree(oldline);
2328 }
2329
2330 /******************** LOW LEVEL GRAPHICS ********************/
2331
2332 /*
2333 * move text starting at character position (sx,sy) to character position
2334 * (dx, dy).
2335 */
us_editpacmovebox(WINDOWPART * win,INTBIG dx,INTBIG dy,INTBIG wid,INTBIG hei,INTBIG sx,INTBIG sy)2336 void us_editpacmovebox(WINDOWPART *win, INTBIG dx, INTBIG dy, INTBIG wid, INTBIG hei, INTBIG sx,
2337 INTBIG sy)
2338 {
2339 REGISTER EDITOR *e;
2340
2341 e = win->editor;
2342 if (e == NOEDITOR) return;
2343 screenmovebox(win, sx*us_editpactwid+e->offx, e->revy-(sy*us_editpacthei+hei-1), wid, hei,
2344 dx*us_editpactwid+e->offx, e->revy-(dy*us_editpacthei+hei-1));
2345 }
2346
2347 /*
2348 * erase text starting at character position (dx,dy) for (wid, hei)
2349 */
us_editpacclearbox(WINDOWPART * win,INTBIG dx,INTBIG dy,INTBIG wid,INTBIG hei)2350 void us_editpacclearbox(WINDOWPART *win, INTBIG dx, INTBIG dy, INTBIG wid, INTBIG hei)
2351 {
2352 REGISTER EDITOR *e;
2353
2354 e = win->editor;
2355 if (e == NOEDITOR) return;
2356
2357 dx = (dx * us_editpactwid) + e->offx;
2358 dy *= us_editpacthei;
2359 screendrawbox(win, dx, dx+wid-1, e->revy-(dy+hei-1), e->revy-dy, &us_ebox);
2360 }
2361
2362 /*
2363 * write text "str" starting at character position (x,y)
2364 */
us_editpactext(WINDOWPART * win,CHAR * str,INTBIG x,INTBIG y)2365 void us_editpactext(WINDOWPART *win, CHAR *str, INTBIG x, INTBIG y)
2366 {
2367 INTBIG xpos, len, diff, i, clip;
2368 REGISTER EDITOR *e;
2369 REGISTER void *infstr;
2370
2371 e = win->editor;
2372 if (e == NOEDITOR) return;
2373
2374 len = estrlen(str);
2375 diff = e->horizfactor - x;
2376
2377 /* make sure string doesn't start to left of edit window */
2378 if (diff > 0)
2379 {
2380 if (diff > len) return;
2381 str = &str[diff];
2382 x = e->horizfactor;
2383 len -= diff;
2384 }
2385
2386 /* make sure string doesn't start to the right of the edit window */
2387 if (x-e->horizfactor >= e->screenchars) return;
2388
2389 xpos = (x - e->horizfactor) * us_editpactwid;
2390 us_menutext.col = el_colmentxt;
2391
2392 if (len + x - e->horizfactor > e->screenchars)
2393 {
2394 infstr = initinfstr();
2395 clip = e->screenchars + e->horizfactor - x;
2396 for(i=0; i<clip; i++) addtoinfstr(infstr, str[i]);
2397 str = returninfstr(infstr);
2398 }
2399 screendrawtext(win, xpos + e->offx, e->revy-(y+1)*us_editpacthei, str, &us_menutext);
2400 }
2401