1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <config.h>
25: #include <stdio.h>
26: #include "cm.h"
27: #include "termhooks.h"
28:
29:
30:
31:
32:
33: #if defined HAVE_TERMCAP_H && 0
34: #include <termcap.h>
35: #else
36: extern void tputs P_ ((const char *, int, int (*)(int)));
37: extern char *tgoto P_ ((const char *, int, int));
38: #endif
39:
40: #define BIG 9999
41:
42:
43: extern char *BC, *UP;
44:
45: int cost;
46:
47:
48: int
49: evalcost (c)
50: char c;
51: {
52: cost++;
53: return c;
54: }
55:
56: int
57: cmputc (c)
58: char c;
59: {
60: if (termscript)
61: fputc (c & 0177, termscript);
62: putchar (c & 0177);
63: return c;
64: }
65:
66:
67: #if 0
68:
69:
70:
71:
72:
73:
74: static
75: at (row, col) {
76: curY = row;
77: curX = col;
78: }
79:
80:
81:
82:
83:
84: static
85: addcol (n) {
86: curX += n;
87:
88:
89:
90:
91:
92:
93:
94:
95:
96: if (curX == Wcm.cm_cols) {
97:
98:
99:
100:
101:
102:
103: if (Wcm.cm_magicwrap)
104: ;
105: else if (Wcm.cm_autowrap) {
106: curX = 0;
107: curY++;
108: }
109: else
110: curX--;
111: }
112: }
113: #endif
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125: void
126: cmcheckmagic ()
127: {
128: if (curX == FrameCols)
129: {
130: if (!MagicWrap || curY >= FrameRows - 1)
131: abort ();
132: if (termscript)
133: putc ('\r', termscript);
134: putchar ('\r');
135: if (termscript)
136: putc ('\n', termscript);
137: putchar ('\n');
138: curX = 0;
139: curY++;
140: }
141: }
142:
143:
144:
145:
146:
147:
148:
149:
150: void
151: cmcostinit ()
152: {
153: char *p;
154:
155: #define COST(x,e) (x ? (cost = 0, tputs (x, 1, e), cost) : BIG)
156: #define CMCOST(x,e) ((x == 0) ? BIG : (p = tgoto(x, 0, 0), COST(p ,e)))
157:
158: Wcm.cc_up = COST (Wcm.cm_up, evalcost);
159: Wcm.cc_down = COST (Wcm.cm_down, evalcost);
160: Wcm.cc_left = COST (Wcm.cm_left, evalcost);
161: Wcm.cc_right = COST (Wcm.cm_right, evalcost);
162: Wcm.cc_home = COST (Wcm.cm_home, evalcost);
163: Wcm.cc_cr = COST (Wcm.cm_cr, evalcost);
164: Wcm.cc_ll = COST (Wcm.cm_ll, evalcost);
165: Wcm.cc_tab = Wcm.cm_tabwidth ? COST (Wcm.cm_tab, evalcost) : BIG;
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176: Wcm.cc_abs = CMCOST (Wcm.cm_abs, evalcost);
177: Wcm.cc_habs = CMCOST (Wcm.cm_habs, evalcost);
178: Wcm.cc_vabs = CMCOST (Wcm.cm_vabs, evalcost);
179:
180: #undef CMCOST
181: #undef COST
182: }
183:
184:
185:
186:
187:
188:
189:
190: static int
191: calccost (srcy, srcx, dsty, dstx, doit)
192: int srcy, srcx, dsty, dstx, doit;
193: {
194: register int deltay,
195: deltax,
196: c,
197: totalcost;
198: int ntabs,
199: n2tabs,
200: tabx,
201: tab2x,
202: tabcost;
203: register char *p;
204:
205:
206:
207:
208:
209: if (curX == Wcm.cm_cols)
210: goto fail;
211:
212: totalcost = 0;
213: if ((deltay = dsty - srcy) == 0)
214: goto x;
215: if (deltay < 0)
216: p = Wcm.cm_up, c = Wcm.cc_up, deltay = -deltay;
217: else
218: p = Wcm.cm_down, c = Wcm.cc_down;
219: if (c == BIG) {
220: if (doit)
221: printf ("OOPS");
222: return c;
223: }
224: totalcost = c * deltay;
225: if (doit)
226: while (--deltay >= 0)
227: tputs (p, 1, cmputc);
228: x:
229: if ((deltax = dstx - srcx) == 0)
230: goto done;
231: if (deltax < 0) {
232: p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
233: goto dodelta;
234: }
235:
236: if (Wcm.cc_tab >= BIG || !Wcm.cm_usetabs)
237: goto olddelta;
238:
239:
240:
241:
242:
243:
244:
245:
246:
247: ntabs = (deltax + srcx % Wcm.cm_tabwidth) / Wcm.cm_tabwidth;
248: n2tabs = ntabs + 1;
249: tabx = (srcx / Wcm.cm_tabwidth + ntabs) * Wcm.cm_tabwidth;
250: tab2x = tabx + Wcm.cm_tabwidth;
251:
252: if (tab2x >= Wcm.cm_cols)
253: n2tabs = 0;
254:
255:
256:
257:
258:
259:
260:
261: tabcost = ntabs ? ntabs * Wcm.cc_tab + (dstx - tabx) * Wcm.cc_right
262: : BIG;
263:
264:
265: c = n2tabs ? n2tabs * Wcm.cc_tab + (tab2x - dstx) * Wcm.cc_left
266: : BIG;
267:
268: if (c < tabcost)
269: ntabs = n2tabs, tabcost = c, tabx = tab2x;
270:
271: if (tabcost >= BIG)
272: goto newdelta;
273:
274:
275:
276:
277:
278: if (tabcost < (deltax * Wcm.cc_right)) {
279: totalcost += tabcost;
280: if (doit)
281: while (--ntabs >= 0)
282: tputs (Wcm.cm_tab, 1, cmputc);
283: srcx = tabx;
284: }
285:
286:
287:
288:
289:
290: newdelta:
291: if ((deltax = dstx - srcx) == 0)
292: goto done;
293: olddelta:
294: if (deltax > 0)
295: p = Wcm.cm_right, c = Wcm.cc_right;
296: else
297: p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
298:
299: dodelta:
300: if (c == BIG) {
301: fail:
302: if (doit)
303: printf ("OOPS");
304: return BIG;
305: }
306: totalcost += c * deltax;
307: if (doit)
308: while (--deltax >= 0)
309: tputs (p, 1, cmputc);
310: done:
311: return totalcost;
312: }
313:
314: #if 0
315: losecursor ()
316: {
317: curY = -1;
318: }
319: #endif
320:
321: #define USEREL 0
322: #define USEHOME 1
323: #define USELL 2
324: #define USECR 3
325:
326: void
327: cmgoto (row, col)
328: int row, col;
329: {
330: int homecost,
331: crcost,
332: llcost,
333: relcost,
334: directcost;
335: int use;
336: char *p,
337: *dcm;
338:
339:
340: if (row == curY && col == curX)
341: return;
342:
343: if (curY >= 0 && curX >= 0)
344: {
345:
346:
347:
348:
349:
350: relcost = calccost (curY, curX, row, col, 0);
351: use = USEREL;
352: if ((homecost = Wcm.cc_home) < BIG)
353: homecost += calccost (0, 0, row, col, 0);
354: if (homecost < relcost)
355: relcost = homecost, use = USEHOME;
356: if ((llcost = Wcm.cc_ll) < BIG)
357: llcost += calccost (Wcm.cm_rows - 1, 0, row, col, 0);
358: if (llcost < relcost)
359: relcost = llcost, use = USELL;
360: if ((crcost = Wcm.cc_cr) < BIG) {
361: if (Wcm.cm_autolf)
362: if (curY + 1 >= Wcm.cm_rows)
363: crcost = BIG;
364: else
365: crcost += calccost (curY + 1, 0, row, col, 0);
366: else
367: crcost += calccost (curY, 0, row, col, 0);
368: }
369: if (crcost < relcost)
370: relcost = crcost, use = USECR;
371: directcost = Wcm.cc_abs, dcm = Wcm.cm_abs;
372: if (row == curY && Wcm.cc_habs < BIG)
373: directcost = Wcm.cc_habs, dcm = Wcm.cm_habs;
374: else if (col == curX && Wcm.cc_vabs < BIG)
375: directcost = Wcm.cc_vabs, dcm = Wcm.cm_vabs;
376: }
377: else
378: {
379: directcost = 0, relcost = 100000;
380: dcm = Wcm.cm_abs;
381: }
382:
383:
384:
385:
386:
387: if (directcost <= relcost)
388: {
389:
390: cost = 0;
391: p = dcm == Wcm.cm_habs ? tgoto (dcm, row, col) :
392: tgoto (dcm, col, row);
393: tputs (p, 1, evalcost);
394: if (cost <= relcost)
395: {
396: tputs (p, 1, cmputc);
397: curY = row, curX = col;
398: return;
399: }
400: }
401:
402: switch (use)
403: {
404: case USEHOME:
405: tputs (Wcm.cm_home, 1, cmputc);
406: curY = 0, curX = 0;
407: break;
408:
409: case USELL:
410: tputs (Wcm.cm_ll, 1, cmputc);
411: curY = Wcm.cm_rows - 1, curX = 0;
412: break;
413:
414: case USECR:
415: tputs (Wcm.cm_cr, 1, cmputc);
416: if (Wcm.cm_autolf)
417: curY++;
418: curX = 0;
419: break;
420: }
421:
422: (void) calccost (curY, curX, row, col, 1);
423: curY = row, curX = col;
424: }
425:
426:
427:
428:
429:
430: void
431: Wcm_clear ()
432: {
433: bzero (&Wcm, sizeof Wcm);
434: UP = 0;
435: BC = 0;
436: }
437:
438:
439:
440:
441:
442:
443:
444:
445: int
446: Wcm_init ()
447: {
448: #if 0
449: if (Wcm.cm_abs && !Wcm.cm_ds)
450: return 0;
451: #endif
452: if (Wcm.cm_abs)
453: return 0;
454:
455: if (!Wcm.cm_up || !Wcm.cm_left)
456: return - 1;
457: if (!Wcm.cm_abs && (!Wcm.cm_down || !Wcm.cm_right))
458: return - 1;
459:
460: if (Wcm.cm_rows <= 0 || Wcm.cm_cols <= 0)
461: return - 2;
462: return 0;
463: }
464:
465:
466: