|
|
1.1 root 1: /* uifc.c */
2:
3: /* Original implementation of UIFC (user interface) library based on conio */
4:
5: /* $Id: uifc.c,v 1.30 2005/09/20 05:39:41 deuce Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This library is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU Lesser General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU Lesser General Public License for more details: lgpl.txt or *
18: * http://www.fsf.org/copyleft/lesser.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "uifc.h"
39: #include <share.h>
40: #include <conio.h>
41:
42: #if defined(__OS2__)
43:
44: #define INCL_BASE
45: #include <os2.h>
46:
47: void mswait(int msec)
48: {
49: DosSleep(msec ? msec : 1);
50: }
51:
52: #elif defined(_WIN32)
53: #include <windows.h>
54: #define mswait(x) Sleep(x)
55: #else
56: #define mswait(x) delay(x)
57: #endif
58:
59: static char hclr,lclr,bclr,cclr,show_free_mem=0;
60: static int cursor;
61: static char* helpfile=0;
62: static uint helpline=0;
63: static char blk_scrn[MAX_BFLN];
64: static win_t sav[MAX_BUFS];
65: static uint max_opts=MAX_OPTS;
66: static uifcapi_t* api;
67:
68: /* Prototypes */
69: static int uprintf(int x, int y, char attr, char *fmt,...);
70: static void bottomline(int line);
71: static char *utimestr(time_t *intime);
72: static void help(void);
73: static int getstr(char *outstr, int max, long mode);
74:
75: /* API routines */
76: static void uifcbail(void);
77: static int uscrn(char *str);
78: static int ulist(int mode, int left, int top, int width, int *dflt, int *bar
79: ,char *title, char **option);
80: static int uinput(int imode, int left, int top, char *prompt, char *str
81: ,int len ,int kmode);
82: static void umsg(char *str);
83: static void upop(char *str);
84: static void sethelp(int line, char* file);
85: static void timedisplay(void);
86:
87: int inkey(int mode)
88: {
89: int c;
90:
91: if(mode)
92: return(kbhit());
93: c=getch();
94: if(!c)
95: c=(getch()<<8);
96: return(c);
97: }
98:
99: static uint mousecursor=0x28;
100:
101: /****************************************************************************/
102: /* Initialization function, see uifc.h for details. */
103: /* Returns 0 on success. */
104: /****************************************************************************/
105: int uifcini(uifcapi_t* uifcapi)
106: {
107: int i;
108: struct text_info txtinfo;
109:
110: if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t))
111: return(-1);
112:
113: api=uifcapi;
114:
115: /* install function handlers */
116: api->bail=uifcbail;
117: api->scrn=uscrn;
118: api->msg=umsg;
119: api->pop=upop;
120: api->list=ulist;
121: api->input=uinput;
122: api->sethelp=sethelp;
123: api->showhelp=help;
124: api->showbuf=NULL;
125: api->timedisplay=timedisplay;
126: api->bottomline=bottomline;
127:
128: if(api->scrn_len!=0) {
129: switch(api->scrn_len) {
130: case 14:
131: textmode(C80X14);
132: break;
133: case 21:
134: textmode(C80X21);
135: break;
136: case 25:
137: textmode(C80);
138: break;
139: case 28:
140: textmode(C80X28);
141: break;
142: case 43:
143: textmode(C80X43);
144: break;
145: case 50:
146: textmode(C80X50);
147: break;
148: case 60:
149: textmode(C80X60);
150: break;
151: default:
152: textmode(C4350);
153: break;
154: }
155: }
156:
157: clrscr();
158: gettextinfo(&txtinfo);
159: /* unsupported mode? */
160: if(txtinfo.screenheight<MIN_LINES
161: || txtinfo.screenheight>MAX_LINES
162: || txtinfo.screenwidth<80) {
163: textmode(C80); /* set mode to 80x25*/
164: gettextinfo(&txtinfo);
165: }
166: window(1,1,txtinfo.screenwidth,txtinfo.screenheight);
167:
168: api->scrn_len=txtinfo.screenheight;
169: if(api->scrn_len<MIN_LINES || api->scrn_len>MAX_LINES) {
170: cprintf("\7UIFC: Screen length (%u) must be between %d and %d lines\r\n"
171: ,api->scrn_len,MIN_LINES,MAX_LINES);
172: return(-2);
173: }
174: api->scrn_len--; /* account for status line */
175:
176: if(txtinfo.screenwidth<80) {
177: cprintf("\7UIFC: Screen width (%u) must be at least 80 characters\r\n"
178: ,txtinfo.screenwidth);
179: return(-3);
180: }
181: api->scrn_width=txtinfo.screenwidth;
182:
183: if(!(api->mode&UIFC_COLOR)
184: && (api->mode&UIFC_MONO
185: || txtinfo.currmode==MONO || txtinfo.currmode==BW80)) {
186: bclr=BLACK;
187: hclr=WHITE;
188: lclr=LIGHTGRAY;
189: cclr=LIGHTGRAY;
190: } else {
191: bclr=BLUE;
192: hclr=YELLOW;
193: lclr=WHITE;
194: cclr=CYAN;
195: }
196: for(i=0;i<MAX_BFLN;i+=2) {
197: blk_scrn[i]='�';
198: blk_scrn[i+1]=cclr|(bclr<<4);
199: }
200:
201: cursor=_NOCURSOR;
202: _setcursortype(cursor);
203:
204: return(0);
205: }
206:
207: static void hidemouse(void)
208: {
209: }
210:
211: static void showmouse(void)
212: {
213: }
214:
215:
216: void uifcbail(void)
217: {
218:
219: hidemouse();
220: _setcursortype(_NORMALCURSOR);
221: textattr(LIGHTGRAY);
222: clrscr();
223: }
224:
225: /****************************************************************************/
226: /* Clear screen, fill with background attribute, display application title. */
227: /* Returns 0 on success. */
228: /****************************************************************************/
229: int uscrn(char *str)
230: {
231: textattr(bclr|(cclr<<4));
232: gotoxy(1,1);
233: clreol();
234: gotoxy(3,1);
235: cputs(str);
236: if(!puttext(1,2,80,api->scrn_len,blk_scrn))
237: return(-1);
238: gotoxy(1,api->scrn_len+1);
239: clreol();
240: return(0);
241: }
242:
243: /****************************************************************************/
244: /****************************************************************************/
245: static void scroll_text(int x1, int y1, int x2, int y2, int down)
246: {
247: uchar buf[MAX_BFLN];
248:
249: gettext(x1,y1,x2,y2,buf);
250: if(down)
251: puttext(x1,y1+1,x2,y2,buf);
252: else
253: puttext(x1,y1,x2,y2-1,buf+(((x2-x1)+1)*2));
254: }
255:
256: /****************************************************************************/
257: /* Updates time in upper left corner of screen with current time in ASCII/ */
258: /* Unix format */
259: /****************************************************************************/
260: static void timedisplay(BOOL force)
261: {
262: static time_t savetime;
263: time_t now;
264:
265: now=time(NULL);
266: if(force || difftime(now,savetime)>=60) {
267: uprintf(55,1,bclr|(cclr<<4),utimestr(&now));
268: savetime=now;
269: }
270: }
271:
272: /****************************************************************************/
273: /* Truncates white-space chars off end of 'str' */
274: /****************************************************************************/
275: static void truncsp(char *str)
276: {
277: uint c;
278:
279: c=strlen(str);
280: while(c && (uchar)str[c-1]<=' ') c--;
281: str[c]=0;
282: }
283:
284: /****************************************************************************/
285: /* General menu function, see uifc.h for details. */
286: /****************************************************************************/
287: int ulist(int mode, int left, int top, int width, int *cur, int *bar
288: , char *title, char **option)
289: {
290: uchar line[256],shade[256],win[MAX_BFLN],*ptr,a,b,c,longopt
291: ,search[MAX_OPLN],bline=0;
292: int height,y;
293: int i,j,opts=0,s=0; /* s=search index into options */
294:
295: if(mode&WIN_SAV && api->savnum>=MAX_BUFS-1)
296: putch(7);
297: i=0;
298: if(mode&WIN_INS) bline|=BL_INS;
299: if(mode&WIN_DEL) bline|=BL_DEL;
300: if(mode&WIN_GET) bline|=BL_GET;
301: if(mode&WIN_PUT) bline|=BL_PUT;
302: if(api->bottomline != NULL)
303: api->bottomline(bline);
304: while(opts<max_opts && opts<MAX_OPTS)
305: if(option[opts]==NULL || option[opts][0]==0)
306: break;
307: else opts++;
308: if(mode&WIN_XTR && opts<max_opts && opts<MAX_OPTS)
309: option[opts++][0]=0;
310: height=opts+4;
311: if(top+height>api->scrn_len-3)
312: height=(api->scrn_len-3)-top;
313: if(!width || width<strlen(title)+6) {
314: width=strlen(title)+6;
315: for(i=0;i<opts;i++) {
316: truncsp(option[i]);
317: if((j=strlen(option[i])+5)>width)
318: width=j; } }
319: if(width>(SCRN_RIGHT+1)-SCRN_LEFT)
320: width=(SCRN_RIGHT+1)-SCRN_LEFT;
321: if(mode&WIN_L2R)
322: left=36-(width/2);
323: else if(mode&WIN_RHT)
324: left=SCRN_RIGHT-(width+4+left);
325: if(mode&WIN_T2B)
326: top=(api->scrn_len/2)-(height/2)-2;
327: else if(mode&WIN_BOT)
328: top=api->scrn_len-height-3-top;
329: if(mode&WIN_SAV && api->savdepth==api->savnum) {
330: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) {
331: cprintf("UIFC line %d: error allocating %u bytes."
332: ,__LINE__,(width+3)*(height+2)*2);
333: return(-1); }
334: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1
335: ,SCRN_TOP+top+height,sav[api->savnum].buf);
336: sav[api->savnum].left=SCRN_LEFT+left;
337: sav[api->savnum].top=SCRN_TOP+top;
338: sav[api->savnum].right=SCRN_LEFT+left+width+1;
339: sav[api->savnum].bot=SCRN_TOP+top+height;
340: api->savdepth++; }
341: else if(mode&WIN_SAV
342: && (sav[api->savnum].left!=SCRN_LEFT+left
343: || sav[api->savnum].top!=SCRN_TOP+top
344: || sav[api->savnum].right!=SCRN_LEFT+left+width+1
345: || sav[api->savnum].bot!=SCRN_TOP+top+height)) { /* dimensions have changed */
346: puttext(sav[api->savnum].left,sav[api->savnum].top,sav[api->savnum].right,sav[api->savnum].bot
347: ,sav[api->savnum].buf); /* put original window back */
348: free(sav[api->savnum].buf);
349: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) {
350: cprintf("UIFC line %d: error allocating %u bytes."
351: ,__LINE__,(width+3)*(height+2)*2);
352: return(-1); }
353: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1
354: ,SCRN_TOP+top+height,sav[api->savnum].buf); /* save again */
355: sav[api->savnum].left=SCRN_LEFT+left;
356: sav[api->savnum].top=SCRN_TOP+top;
357: sav[api->savnum].right=SCRN_LEFT+left+width+1;
358: sav[api->savnum].bot=SCRN_TOP+top+height; }
359:
360:
361:
362: if(mode&WIN_ORG) { /* Clear around menu */
363: if(top)
364: puttext(SCRN_LEFT,SCRN_TOP,SCRN_RIGHT+2,SCRN_TOP+top-1,blk_scrn);
365: if(SCRN_TOP+height+top<=api->scrn_len)
366: puttext(SCRN_LEFT,SCRN_TOP+height+top,SCRN_RIGHT+2,api->scrn_len,blk_scrn);
367: if(left)
368: puttext(SCRN_LEFT,SCRN_TOP+top,SCRN_LEFT+left-1,SCRN_TOP+height+top
369: ,blk_scrn);
370: if(SCRN_LEFT+left+width<=SCRN_RIGHT)
371: puttext(SCRN_LEFT+left+width,SCRN_TOP+top,SCRN_RIGHT+2
372: ,SCRN_TOP+height+top,blk_scrn); }
373: ptr=win;
374: *(ptr++)='�';
375: *(ptr++)=hclr|(bclr<<4);
376:
377: if(api->mode&UIFC_MOUSE) {
378: *(ptr++)='[';
379: *(ptr++)=hclr|(bclr<<4);
380: *(ptr++)='�';
381: *(ptr++)=lclr|(bclr<<4);
382: *(ptr++)=']';
383: *(ptr++)=hclr|(bclr<<4);
384: *(ptr++)='[';
385: *(ptr++)=hclr|(bclr<<4);
386: *(ptr++)='?';
387: *(ptr++)=lclr|(bclr<<4);
388: *(ptr++)=']';
389: *(ptr++)=hclr|(bclr<<4);
390: i=6; }
391: else
392: i=0;
393: for(;i<width-2;i++) {
394: *(ptr++)='�';
395: *(ptr++)=hclr|(bclr<<4); }
396: *(ptr++)='�';
397: *(ptr++)=hclr|(bclr<<4);
398: *(ptr++)='�';
399: *(ptr++)=hclr|(bclr<<4);
400: a=strlen(title);
401: b=(width-a-1)/2;
402: for(i=0;i<b;i++) {
403: *(ptr++)=' ';
404: *(ptr++)=hclr|(bclr<<4); }
405: for(i=0;i<a;i++) {
406: *(ptr++)=title[i];
407: *(ptr++)=hclr|(bclr<<4); }
408: for(i=0;i<width-(a+b)-2;i++) {
409: *(ptr++)=' ';
410: *(ptr++)=hclr|(bclr<<4); }
411: *(ptr++)='�';
412: *(ptr++)=hclr|(bclr<<4);
413: *(ptr++)='�';
414: *(ptr++)=hclr|(bclr<<4);
415: for(i=0;i<width-2;i++) {
416: *(ptr++)='�';
417: *(ptr++)=hclr|(bclr<<4); }
418: *(ptr++)='�';
419: *(ptr++)=hclr|(bclr<<4);
420:
421: if((*cur)>=opts)
422: (*cur)=opts-1; /* returned after scrolled */
423:
424: if(!bar) {
425: if((*cur)>height-5)
426: (*cur)=height-5;
427: i=0; }
428: else {
429: if((*bar)>=opts)
430: (*bar)=opts-1;
431: if((*bar)>height-5)
432: (*bar)=height-5;
433: if((*cur)==opts-1)
434: (*bar)=height-5;
435: if((*bar)<0)
436: (*bar)=0;
437: if((*cur)<(*bar))
438: (*cur)=(*bar);
439: i=(*cur)-(*bar);
440:
441: if(i+(height-5)>=opts) {
442: i=opts-(height-4);
443: (*cur)=i+(*bar);
444: }
445: }
446: if((*cur)<0)
447: (*cur)=0;
448:
449: j=0;
450: if(i<0) i=0;
451: longopt=0;
452: while(j<height-4 && i<opts) {
453: *(ptr++)='�';
454: *(ptr++)=hclr|(bclr<<4);
455: *(ptr++)=' ';
456: *(ptr++)=hclr|(bclr<<4);
457: *(ptr++)='�';
458: *(ptr++)=lclr|(bclr<<4);
459: if(i==(*cur))
460: a=bclr|(LIGHTGRAY<<4);
461: else
462: a=lclr|(bclr<<4);
463: b=strlen(option[i]);
464: if(b>longopt)
465: longopt=b;
466: if(b+4>width)
467: b=width-4;
468: for(c=0;c<b;c++) {
469: *(ptr++)=option[i][c];
470: *(ptr++)=a; }
471: while(c<width-4) {
472: *(ptr++)=' ';
473: *(ptr++)=a;
474: c++; }
475: *(ptr++)='�';
476: *(ptr++)=hclr|(bclr<<4);
477: i++;
478: j++; }
479: *(ptr++)='�';
480: *(ptr++)=hclr|(bclr<<4);
481: for(i=0;i<width-2;i++) {
482: *(ptr++)='�';
483: *(ptr++)=hclr|(bclr<<4); }
484: *(ptr++)='�';
485: *(ptr++)=hclr|(bclr<<4);
486: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width-1
487: ,SCRN_TOP+top+height-1,win);
488: if(bar)
489: y=top+3+(*bar);
490: else
491: y=top+3+(*cur);
492: if(opts+4>height && ((!bar && (*cur)!=opts-1)
493: || (bar && ((*cur)-(*bar))+(height-4)<opts))) {
494: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
495: textattr(lclr|(bclr<<4));
496: putch(31); /* put down arrow */
497: textattr(hclr|(bclr<<4)); }
498:
499: if(bar && (*bar)!=(*cur)) {
500: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
501: textattr(lclr|(bclr<<4));
502: putch(30); /* put the up arrow */
503: textattr(hclr|(bclr<<4)); }
504:
505: if(bclr==BLUE) {
506: gettext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1
507: ,SCRN_TOP+top+height-1,shade);
508: for(i=1;i<height*4;i+=2)
509: shade[i]=DARKGRAY;
510: puttext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1
511: ,SCRN_TOP+top+height-1,shade);
512: gettext(SCRN_LEFT+left+2,SCRN_TOP+top+height,SCRN_LEFT+left+width+1
513: ,SCRN_TOP+top+height,shade);
514: for(i=1;i<width*2;i+=2)
515: shade[i]=DARKGRAY;
516: puttext(SCRN_LEFT+left+2,SCRN_TOP+top+height,SCRN_LEFT+left+width+1
517: ,SCRN_TOP+top+height,shade); }
518: showmouse();
519: while(1) {
520: #if 0 /* debug */
521: gotoxy(30,1);
522: cprintf("y=%2d h=%2d c=%2d b=%2d s=%2d o=%2d"
523: ,y,height,*cur,bar ? *bar :0xff,api->savdepth,opts);
524: #endif
525: if(!show_free_mem) {
526: if(api->timedisplay != NULL)
527: api->timedisplay(FALSE);
528: }
529:
530: if(inkey(1)) {
531: i=inkey(0);
532: if(!(i&0xff)) {
533: s=0;
534: switch(i>>8) {
535: case 71: /* home */
536: if(!opts)
537: break;
538: if(opts+4>height) {
539: hidemouse();
540: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
541: textattr(lclr|(bclr<<4));
542: putch(' '); /* Delete the up arrow */
543: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
544: putch(31); /* put the down arrow */
545: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3
546: ,bclr|(LIGHTGRAY<<4)
547: ,"%-*.*s",width-4,width-4,option[0]);
548: for(i=1;i<height-4;i++) /* re-display options */
549: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+i
550: ,lclr|(bclr<<4)
551: ,"%-*.*s",width-4,width-4,option[i]);
552: (*cur)=0;
553: if(bar)
554: (*bar)=0;
555: y=top+3;
556: showmouse();
557: break; }
558: hidemouse();
559: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
560: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
561: for(i=1;i<width*2;i+=2)
562: line[i]=lclr|(bclr<<4);
563: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
564: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
565: (*cur)=0;
566: if(bar)
567: (*bar)=0;
568: y=top+3;
569: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
570: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
571: for(i=1;i<width*2;i+=2)
572: line[i]=bclr|(LIGHTGRAY<<4);
573: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
574: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
575: showmouse();
576: break;
577: case 72: /* up arrow */
578: if(!opts)
579: break;
580: if(!(*cur) && opts+4>height) {
581: hidemouse();
582: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3); /* like end */
583: textattr(lclr|(bclr<<4));
584: putch(30); /* put the up arrow */
585: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
586: putch(' '); /* delete the down arrow */
587: for(i=(opts+4)-height,j=0;i<opts;i++,j++)
588: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j
589: ,i==opts-1 ? bclr|(LIGHTGRAY<<4)
590: : lclr|(bclr<<4)
591: ,"%-*.*s",width-4,width-4,option[i]);
592: (*cur)=opts-1;
593: if(bar)
594: (*bar)=height-5;
595: y=top+height-2;
596: showmouse();
597: break; }
598: hidemouse();
599: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
600: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
601: for(i=1;i<width*2;i+=2)
602: line[i]=lclr|(bclr<<4);
603: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
604: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
605: showmouse();
606: if(!(*cur)) {
607: y=top+height-2;
608: (*cur)=opts-1;
609: if(bar)
610: (*bar)=height-5; }
611: else {
612: (*cur)--;
613: y--;
614: if(bar && *bar)
615: (*bar)--; }
616: if(y<top+3) { /* scroll */
617: hidemouse();
618: if(!(*cur)) {
619: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
620: textattr(lclr|(bclr<<4));
621: putch(' '); } /* delete the up arrow */
622: if((*cur)+height-4==opts-1) {
623: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
624: textattr(lclr|(bclr<<4));
625: putch(31); } /* put the dn arrow */
626: y++;
627: scroll_text(SCRN_LEFT+left+2,SCRN_TOP+top+3
628: ,SCRN_LEFT+left+width-3,SCRN_TOP+top+height-2,1);
629: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3
630: ,bclr|(LIGHTGRAY<<4)
631: ,"%-*.*s",width-4,width-4,option[*cur]);
632: showmouse(); }
633: else {
634: hidemouse();
635: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
636: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
637: for(i=1;i<width*2;i+=2)
638: line[i]=bclr|(LIGHTGRAY<<4);
639: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
640: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
641: showmouse(); }
642: break;
643: #if 0
644: case 0x49; /* PgUp */
645: case 0x51; /* PgDn */
646: if(!opts || (*cur)==(opts-1))
647: break;
648: (*cur)+=(height-4);
649: if((*cur)>(opts-1))
650: (*cur)=(opts-1);
651:
652: hidemouse();
653: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
654: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
655: for(i=1;i<width*2;i+=2)
656: line[i]=lclr|(bclr<<4);
657: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
658: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
659:
660: for(i=(opts+4)-height,j=0;i<opts;i++,j++)
661: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j
662: ,i==(*cur) bclr|(LIGHTGRAY<<4) : lclr|(bclr<<4)
663: ,"%-*.*s",width-4,width-4,option[i]);
664: y=top+height-2;
665: if(bar)
666: (*bar)=height-5;
667: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
668: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
669: for(i=1;i<148;i+=2)
670: line[i]=bclr|(LIGHTGRAY<<4);
671: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
672: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
673: showmouse();
674: break;
675: #endif
676: case 79: /* end */
677: if(!opts)
678: break;
679: if(opts+4>height) { /* Scroll mode */
680: hidemouse();
681: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
682: textattr(lclr|(bclr<<4));
683: putch(30); /* put the up arrow */
684: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
685: putch(' '); /* delete the down arrow */
686: for(i=(opts+4)-height,j=0;i<opts;i++,j++)
687: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j
688: ,i==opts-1 ? bclr|(LIGHTGRAY<<4)
689: : lclr|(bclr<<4)
690: ,"%-*.*s",width-4,width-4,option[i]);
691: (*cur)=opts-1;
692: y=top+height-2;
693: if(bar)
694: (*bar)=height-5;
695: showmouse();
696: break; }
697: hidemouse();
698: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
699: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
700: for(i=1;i<width*2;i+=2)
701: line[i]=lclr|(bclr<<4);
702: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
703: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
704: (*cur)=opts-1;
705: y=top+height-2;
706: if(bar)
707: (*bar)=height-5;
708: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
709: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
710: for(i=1;i<148;i+=2)
711: line[i]=bclr|(LIGHTGRAY<<4);
712: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
713: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
714: showmouse();
715: break;
716: case 80: /* dn arrow */
717: if(!opts)
718: break;
719: if((*cur)==opts-1 && opts+4>height) { /* like home */
720: hidemouse();
721: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
722: textattr(lclr|(bclr<<4));
723: putch(' '); /* Delete the up arrow */
724: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
725: putch(31); /* put the down arrow */
726: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3
727: ,bclr|(LIGHTGRAY<<4)
728: ,"%-*.*s",width-4,width-4,option[0]);
729: for(i=1;i<height-4;i++) /* re-display options */
730: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+i
731: ,lclr|(bclr<<4)
732: ,"%-*.*s",width-4,width-4,option[i]);
733: (*cur)=0;
734: y=top+3;
735: if(bar)
736: (*bar)=0;
737: showmouse();
738: break; }
739: hidemouse();
740: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
741: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
742: for(i=1;i<width*2;i+=2)
743: line[i]=lclr|(bclr<<4);
744: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
745: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
746: showmouse();
747: if((*cur)==opts-1) {
748: (*cur)=0;
749: y=top+3;
750: if(bar) {
751: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */
752: (*bar)=0; } }
753: else {
754: (*cur)++;
755: y++;
756: if(bar && (*bar)<height-5) {
757: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */
758: (*bar)++; } }
759: if(y==top+height-1) { /* scroll */
760: hidemouse();
761: if(*cur==opts-1) {
762: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
763: textattr(lclr|(bclr<<4));
764: putch(' '); } /* delete the down arrow */
765: if((*cur)+4==height) {
766: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
767: textattr(lclr|(bclr<<4));
768: putch(30); } /* put the up arrow */
769: y--;
770: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */
771: scroll_text(SCRN_LEFT+left+2,SCRN_TOP+top+3
772: ,SCRN_LEFT+left+width-3,SCRN_TOP+top+height-2,0);
773: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */
774: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+height-2
775: ,bclr|(LIGHTGRAY<<4)
776: ,"%-*.*s",width-4,width-4,option[*cur]);
777: showmouse(); }
778: else {
779: hidemouse();
780: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
781: ,SCRN_LEFT+left+width-2,SCRN_TOP+y
782: ,line);
783: for(i=1;i<width*2;i+=2)
784: line[i]=bclr|(LIGHTGRAY<<4);
785: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
786: ,SCRN_LEFT+left+width-2,SCRN_TOP+y
787: ,line);
788: showmouse(); }
789: break;
790: case 0x3b: /* F1 */
791: help();
792: break;
793: case 0x3f: /* F5 */
794: if(mode&WIN_GET && !(mode&WIN_XTR && (*cur)==opts-1))
795: return((*cur)|MSK_GET);
796: break;
797: case 0x40: /* F6 */
798: if(mode&WIN_PUT && !(mode&WIN_XTR && (*cur)==opts-1))
799: return((*cur)|MSK_PUT);
800: break;
801: case 82: /* insert */
802: if(mode&WIN_INS) {
803: if(mode&WIN_INSACT) {
804: hidemouse();
805: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
806: +left+width-1,SCRN_TOP+top+height-1,win);
807: for(i=1;i<(width*height*2);i+=2)
808: win[i]=lclr|(cclr<<4);
809: if(opts) {
810: j=(((y-top)*width)*2)+7+((width-4)*2);
811: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
812: win[i]=hclr|(cclr<<4); }
813: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
814: +left+width-1,SCRN_TOP+top+height-1,win);
815: showmouse(); }
816: if(!opts)
817: return(MSK_INS);
818: return((*cur)|MSK_INS); }
819: break;
820: case 83: /* delete */
821: if(mode&WIN_XTR && (*cur)==opts-1) /* can't delete */
822: break; /* extra line */
823: if(mode&WIN_DEL) {
824: if(mode&WIN_DELACT) {
825: hidemouse();
826: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
827: +left+width-1,SCRN_TOP+top+height-1,win);
828: for(i=1;i<(width*height*2);i+=2)
829: win[i]=lclr|(cclr<<4);
830: j=(((y-top)*width)*2)+7+((width-4)*2);
831: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
832: win[i]=hclr|(cclr<<4);
833: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
834: +left+width-1,SCRN_TOP+top+height-1,win);
835: showmouse(); }
836: return((*cur)|MSK_DEL); }
837: break; } }
838: else {
839: i&=0xff;
840: if(isalnum(i) && opts && option[0][0]) {
841: search[s]=i;
842: search[s+1]=0;
843: for(j=(*cur)+1,a=b=0;a<2;j++) { /* a = search count */
844: if(j==opts) { /* j = option count */
845: j=-1; /* b = letter count */
846: continue; }
847: if(j==(*cur)) {
848: b++;
849: continue; }
850: if(b>=longopt) {
851: b=0;
852: a++; }
853: if(a==1 && !s)
854: break;
855: if(strlen(option[j])>b
856: && ((!a && s && !strncmpi(option[j]+b,search,s+1))
857: || ((a || !s) && toupper(option[j][b])==toupper(i)))) {
858: if(a) s=0;
859: else s++;
860: if(y+(j-(*cur))+2>height+top) {
861: (*cur)=j;
862: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
863: textattr(lclr|(bclr<<4));
864: putch(30); /* put the up arrow */
865: if((*cur)==opts-1) {
866: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
867: putch(' '); } /* delete the down arrow */
868: for(i=((*cur)+5)-height,j=0;i<(*cur)+1;i++,j++)
869: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+j
870: ,i==(*cur) ? bclr|(LIGHTGRAY<<4)
871: : lclr|(bclr<<4)
872: ,"%-*.*s",width-4,width-4,option[i]);
873: y=top+height-2;
874: if(bar)
875: (*bar)=height-5;
876: break; }
877: if(y-((*cur)-j)<top+3) {
878: (*cur)=j;
879: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+3);
880: textattr(lclr|(bclr<<4));
881: if(!(*cur))
882: putch(' '); /* Delete the up arrow */
883: gotoxy(SCRN_LEFT+left+1,SCRN_TOP+top+height-2);
884: putch(31); /* put the down arrow */
885: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3
886: ,bclr|(LIGHTGRAY<<4)
887: ,"%-*.*s",width-4,width-4,option[(*cur)]);
888: for(i=1;i<height-4;i++) /* re-display options */
889: uprintf(SCRN_LEFT+left+3,SCRN_TOP+top+3+i
890: ,lclr|(bclr<<4)
891: ,"%-*.*s",width-4,width-4
892: ,option[(*cur)+i]);
893: y=top+3;
894: if(bar)
895: (*bar)=0;
896: break; }
897: hidemouse();
898: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
899: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
900: for(i=1;i<width*2;i+=2)
901: line[i]=lclr|(bclr<<4);
902: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
903: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
904: if((*cur)>j)
905: y-=(*cur)-j;
906: else
907: y+=j-(*cur);
908: if(bar) {
909: if((*cur)>j)
910: (*bar)-=(*cur)-j;
911: else
912: (*bar)+=j-(*cur); }
913: (*cur)=j;
914: gettext(SCRN_LEFT+3+left,SCRN_TOP+y
915: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
916: for(i=1;i<width*2;i+=2)
917: line[i]=bclr|(LIGHTGRAY<<4);
918: puttext(SCRN_LEFT+3+left,SCRN_TOP+y
919: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line);
920: showmouse();
921: break; } }
922: if(a==2)
923: s=0; }
924: else
925: switch(i) {
926: case CR:
927: if(!opts || (mode&WIN_XTR && (*cur)==opts-1))
928: break;
929: if(mode&WIN_ACT) {
930: hidemouse();
931: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
932: +left+width-1,SCRN_TOP+top+height-1,win);
933: for(i=1;i<(width*height*2);i+=2)
934: win[i]=lclr|(cclr<<4);
935: j=(((y-top)*width)*2)+7+((width-4)*2);
936: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
937: win[i]=hclr|(cclr<<4);
938:
939: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
940: +left+width-1,SCRN_TOP+top+height-1,win);
941: showmouse(); }
942: else if(mode&WIN_SAV) {
943: hidemouse();
944: puttext(sav[api->savnum].left,sav[api->savnum].top
945: ,sav[api->savnum].right,sav[api->savnum].bot
946: ,sav[api->savnum].buf);
947: showmouse();
948: free(sav[api->savnum].buf);
949: api->savdepth--; }
950: return(*cur);
951: case ESC:
952: case '\b': /* backspace */
953: if(mode&WIN_ESC || (mode&WIN_CHE && api->changes)
954: && !(mode&WIN_SAV)) {
955: hidemouse();
956: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
957: +left+width-1,SCRN_TOP+top+height-1,win);
958: for(i=1;i<(width*height*2);i+=2)
959: win[i]=lclr|(cclr<<4);
960: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
961: +left+width-1,SCRN_TOP+top+height-1,win);
962: showmouse(); }
963: else if(mode&WIN_SAV) {
964: hidemouse();
965: puttext(sav[api->savnum].left,sav[api->savnum].top
966: ,sav[api->savnum].right,sav[api->savnum].bot
967: ,sav[api->savnum].buf);
968: showmouse();
969: free(sav[api->savnum].buf);
970: api->savdepth--; }
971: return(-1); } } }
972: else
973: mswait(1);
974: }
975: }
976:
977:
978: /*************************************************************************/
979: /* This function is a windowed input string input routine. */
980: /*************************************************************************/
981: int uinput(int mode, int left, int top, char *prompt, char *str,
982: int max, int kmode)
983: {
984: unsigned char c,tmp[81],save_buf[2048],in_win[2048]
985: ,shade[160],width,height=3;
986: int i,j,plen,slen;
987:
988: hidemouse();
989: plen=strlen(prompt);
990: if(!plen)
991: slen=4;
992: else
993: slen=6;
994: width=plen+slen+max;
995: if(mode&WIN_T2B)
996: top=(api->scrn_len/2)-(height/2)-2;
997: if(mode&WIN_L2R)
998: left=36-(width/2);
999: if(mode&WIN_SAV)
1000: gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1
1001: ,SCRN_TOP+top+height,save_buf);
1002: i=0;
1003: in_win[i++]='�';
1004: in_win[i++]=hclr|(bclr<<4);
1005: for(c=1;c<width-1;c++) {
1006: in_win[i++]='�';
1007: in_win[i++]=hclr|(bclr<<4); }
1008: in_win[i++]='�';
1009: in_win[i++]=hclr|(bclr<<4);
1010: in_win[i++]='�';
1011: in_win[i++]=hclr|(bclr<<4);
1012:
1013: if(plen) {
1014: in_win[i++]=' ';
1015: in_win[i++]=lclr|(bclr<<4); }
1016:
1017: for(c=0;prompt[c];c++) {
1018: in_win[i++]=prompt[c];
1019: in_win[i++]=lclr|(bclr<<4); }
1020:
1021: if(plen) {
1022: in_win[i++]=':';
1023: in_win[i++]=lclr|(bclr<<4);
1024: c++; }
1025:
1026: for(c=0;c<max+2;c++) {
1027: in_win[i++]=' ';
1028: in_win[i++]=lclr|(bclr<<4); }
1029:
1030: in_win[i++]='�';
1031: in_win[i++]=hclr|(bclr<<4);
1032: in_win[i++]='�';
1033: in_win[i++]=hclr|(bclr<<4);
1034: for(c=1;c<width-1;c++) {
1035: in_win[i++]='�';
1036: in_win[i++]=hclr|(bclr<<4); }
1037: in_win[i++]='�';
1038: in_win[i++]=hclr|(bclr<<4);
1039: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width-1
1040: ,SCRN_TOP+top+height-1,in_win);
1041:
1042: if(bclr==BLUE) {
1043: gettext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1
1044: ,SCRN_TOP+top+(height-1),shade);
1045: for(c=1;c<12;c+=2)
1046: shade[c]=DARKGRAY;
1047: puttext(SCRN_LEFT+left+width,SCRN_TOP+top+1,SCRN_LEFT+left+width+1
1048: ,SCRN_TOP+top+(height-1),shade);
1049: gettext(SCRN_LEFT+left+2,SCRN_TOP+top+3,SCRN_LEFT+left+width+1
1050: ,SCRN_TOP+top+height,shade);
1051: for(c=1;c<width*2;c+=2)
1052: shade[c]=DARKGRAY;
1053: puttext(SCRN_LEFT+left+2,SCRN_TOP+top+3,SCRN_LEFT+left+width+1
1054: ,SCRN_TOP+top+height,shade); }
1055:
1056: textattr(lclr|(bclr<<4));
1057: if(!plen)
1058: gotoxy(SCRN_LEFT+left+2,SCRN_TOP+top+1);
1059: else
1060: gotoxy(SCRN_LEFT+left+plen+4,SCRN_TOP+top+1);
1061: i=getstr(str,max,kmode);
1062: if(mode&WIN_SAV)
1063: puttext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1
1064: ,SCRN_TOP+top+height,save_buf);
1065: showmouse();
1066: return(i);
1067: }
1068:
1069: /****************************************************************************/
1070: /* Displays the message 'str' and waits for the user to select "OK" */
1071: /****************************************************************************/
1072: void umsg(char *str)
1073: {
1074: int i=0;
1075: char *ok[2]={"OK",""};
1076:
1077: if(api->mode&UIFC_INMSG) /* non-cursive */
1078: return;
1079: api->mode|=UIFC_INMSG;
1080: if(api->savdepth) api->savnum++;
1081: ulist(WIN_SAV|WIN_MID,0,0,0,&i,0,str,ok);
1082: if(api->savdepth) api->savnum--;
1083: api->mode&=~UIFC_INMSG;
1084: }
1085:
1086: /****************************************************************************/
1087: /* Gets a string of characters from the user. Turns cursor on. Allows */
1088: /* Different modes - K_* macros. ESC aborts input. */
1089: /* Cursor should be at END of where string prompt will be placed. */
1090: /****************************************************************************/
1091: static int getstr(char *outstr, int max, long mode)
1092: {
1093: uchar ch,str[256],ins=0,buf[256],y;
1094: int i,j,k,f=0; /* i=offset, j=length */
1095:
1096: cursor=_NORMALCURSOR;
1097: _setcursortype(cursor);
1098: y=wherey();
1099: if(mode&K_EDIT) {
1100: /***
1101: truncsp(outstr);
1102: ***/
1103: outstr[max]=0;
1104: textattr(bclr|(LIGHTGRAY<<4));
1105: cputs(outstr);
1106: textattr(lclr|(bclr<<4));
1107: strcpy(str,outstr);
1108: i=j=strlen(str);
1109: while(inkey(1)==0) {
1110: mswait(1);
1111: }
1112: f=inkey(0);
1113: gotoxy(wherex()-i,y);
1114: if(!isprint(f&0xff) && f!=0x5300)
1115: cputs(outstr);
1116: else {
1117: cprintf("%*s",i,"");
1118: gotoxy(wherex()-i,y);
1119: i=j=0; } }
1120: else
1121: i=j=0;
1122:
1123:
1124: while(1) {
1125:
1126:
1127: if(i>j) j=i;
1128: if(f || inkey(1)) {
1129: if(f) k=f; /* First key */
1130: else k=inkey(0);
1131: f=0;
1132: ch=k&0xff;
1133: if(!ch) {
1134: switch(k>>8) {
1135: case 0x3b: /* F1 Help */
1136: help();
1137: continue;
1138: case 0x4b: /* left arrow */
1139: if(i) {
1140: gotoxy(wherex()-1,y);
1141: i--; }
1142: continue;
1143: case 0x4d: /* right arrow */
1144: if(i<j) {
1145: gotoxy(wherex()+1,y);
1146: i++; }
1147: continue;
1148: case 0x47: /* home */
1149: if(i) {
1150: gotoxy(wherex()-i,y);
1151: i=0; }
1152: continue;
1153: case 0x4f: /* end */
1154: if(i<j) {
1155: gotoxy(wherex()+(j-i),y);
1156: i=j; }
1157: continue;
1158: case 0x52: /* insert */
1159: ins=!ins;
1160: if(ins)
1161: cursor=_SOLIDCURSOR;
1162: else
1163: cursor=_NORMALCURSOR;
1164: _setcursortype(cursor);
1165: continue;
1166: case 0x53: /* delete */
1167: if(i<j) {
1168: gettext(wherex()+1,y,wherex()+(j-i),y,buf);
1169: puttext(wherex(),y,wherex()+(j-i)-1,y,buf);
1170: gotoxy(wherex()+(j-i),y);
1171: putch(' ');
1172: gotoxy(wherex()-((j-i)+1),y);
1173: for(k=i;k<j;k++)
1174: str[k]=str[k+1];
1175: j--; }
1176: continue; }
1177: continue; }
1178: if(ch==03 || ch==ESC) {
1179: cursor=_NOCURSOR;
1180: _setcursortype(cursor);
1181: return(-1); }
1182: if(ch==BS && i) {
1183: if(i==j) {
1184: cputs("\b \b");
1185: j--;
1186: i--; }
1187: else {
1188: gettext(wherex(),y,wherex()+(j-i),y,buf);
1189: puttext(wherex()-1,y,wherex()+(j-i)-1,y,buf);
1190: gotoxy(wherex()+(j-i),y);
1191: putch(' ');
1192: gotoxy(wherex()-((j-i)+2),y);
1193: i--;
1194: j--;
1195: for(k=i;k<j;k++)
1196: str[k]=str[k+1]; }
1197: continue; }
1198: if(ch==CR)
1199: break;
1200: if(ch==24) { /* ctrl-x */
1201: if(j) {
1202: gotoxy(wherex()-i,y);
1203: cprintf("%*s",j,"");
1204: gotoxy(wherex()-j,y);
1205: i=j=0; }
1206: continue; }
1207: if(ch==25) { /* ctrl-y */
1208: if(i<j) {
1209: cprintf("%*s",(j-i),"");
1210: gotoxy(wherex()-(j-i),y);
1211: j=i; }
1212: continue; }
1213: if(mode&K_NUMBER && !isdigit(ch))
1214: continue;
1215: if(mode&K_ALPHA && !isalpha(ch))
1216: continue;
1217: if((ch>=' ' || (ch==1 && mode&K_MSG)) && i<max && (!ins || j<max)) {
1218: if(mode&K_UPPER)
1219: ch=toupper(ch);
1220: if(ins) {
1221: gettext(wherex(),y,wherex()+(j-i),y,buf);
1222: puttext(wherex()+1,y,wherex()+(j-i)+1,y,buf);
1223: for(k=++j;k>i;k--)
1224: str[k]=str[k-1]; }
1225: putch(ch);
1226: str[i++]=ch; } }
1227: else
1228: mswait(1);
1229: }
1230: str[j]=0;
1231: if(mode&K_EDIT) {
1232: truncsp(str);
1233: if(strcmp(outstr,str))
1234: api->changes=1; }
1235: else {
1236: if(j)
1237: api->changes=1; }
1238: strcpy(outstr,str);
1239: cursor=_NOCURSOR;
1240: _setcursortype(cursor);
1241: return(j);
1242: }
1243:
1244: /****************************************************************************/
1245: /* Performs printf() through puttext() routine */
1246: /****************************************************************************/
1247: static int uprintf(int x, int y, char attr, char *fmat, ...)
1248: {
1249: va_list argptr;
1250: char str[256],buf[512];
1251: int i,j;
1252:
1253: va_start(argptr,fmat);
1254: vsprintf(str,fmat,argptr);
1255: va_end(argptr);
1256: for(i=j=0;str[i];i++) {
1257: buf[j++]=str[i];
1258: buf[j++]=attr; }
1259: puttext(x,y,x+(i-1),y,buf);
1260: return(i);
1261: }
1262:
1263:
1264: /****************************************************************************/
1265: /* Display bottom line of screen in inverse */
1266: /****************************************************************************/
1267: void bottomline(int line)
1268: {
1269: int i=0;
1270: uprintf(i,api->scrn_len+1,bclr|(cclr<<4)," ");
1271: i+=4;
1272: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F1 ");
1273: i+=3;
1274: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Help ");
1275: i+=6;
1276: if(line&BL_GET) {
1277: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F5 ");
1278: i+=3;
1279: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Copy Item ");
1280: i+=11; }
1281: if(line&BL_PUT) {
1282: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F6 ");
1283: i+=3;
1284: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Paste ");
1285: i+=7; }
1286: if(line&BL_INS) {
1287: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"INS ");
1288: i+=4;
1289: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Add Item ");
1290: i+=10; }
1291: if(line&BL_DEL) {
1292: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"DEL ");
1293: i+=4;
1294: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Delete Item ");
1295: i+=13; }
1296: uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"ESC ");
1297: i+=4;
1298: uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Exit");
1299: i+=4;
1300: gotoxy(i,api->scrn_len+1);
1301: textattr(BLACK|(cclr<<4));
1302: clreol();
1303: }
1304:
1305:
1306: /*****************************************************************************/
1307: /* Generates a 24 character ASCII string that represents the time_t pointer */
1308: /* Used as a replacement for ctime() */
1309: /*****************************************************************************/
1310: char *utimestr(time_t *intime)
1311: {
1312: static char str[25];
1313: char wday[4],mon[4],mer[3],hour;
1314: struct tm *gm;
1315:
1316: gm=localtime(intime);
1317: switch(gm->tm_wday) {
1318: case 0:
1319: strcpy(wday,"Sun");
1320: break;
1321: case 1:
1322: strcpy(wday,"Mon");
1323: break;
1324: case 2:
1325: strcpy(wday,"Tue");
1326: break;
1327: case 3:
1328: strcpy(wday,"Wed");
1329: break;
1330: case 4:
1331: strcpy(wday,"Thu");
1332: break;
1333: case 5:
1334: strcpy(wday,"Fri");
1335: break;
1336: case 6:
1337: strcpy(wday,"Sat");
1338: break; }
1339: switch(gm->tm_mon) {
1340: case 0:
1341: strcpy(mon,"Jan");
1342: break;
1343: case 1:
1344: strcpy(mon,"Feb");
1345: break;
1346: case 2:
1347: strcpy(mon,"Mar");
1348: break;
1349: case 3:
1350: strcpy(mon,"Apr");
1351: break;
1352: case 4:
1353: strcpy(mon,"May");
1354: break;
1355: case 5:
1356: strcpy(mon,"Jun");
1357: break;
1358: case 6:
1359: strcpy(mon,"Jul");
1360: break;
1361: case 7:
1362: strcpy(mon,"Aug");
1363: break;
1364: case 8:
1365: strcpy(mon,"Sep");
1366: break;
1367: case 9:
1368: strcpy(mon,"Oct");
1369: break;
1370: case 10:
1371: strcpy(mon,"Nov");
1372: break;
1373: case 11:
1374: strcpy(mon,"Dec");
1375: break; }
1376: if(gm->tm_hour>12) {
1377: strcpy(mer,"pm");
1378: hour=gm->tm_hour-12; }
1379: else {
1380: if(!gm->tm_hour)
1381: hour=12;
1382: else
1383: hour=gm->tm_hour;
1384: strcpy(mer,"am"); }
1385: sprintf(str,"%s %s %02d %4d %02d:%02d %s",wday,mon,gm->tm_mday,1900+gm->tm_year
1386: ,hour,gm->tm_min,mer);
1387: return(str);
1388: }
1389:
1390: /****************************************************************************/
1391: /* Status popup/down function, see uifc.h for details. */
1392: /****************************************************************************/
1393: void upop(char *str)
1394: {
1395: static char sav[26*3*2];
1396: char buf[26*3*2];
1397: int i,j,k;
1398:
1399: hidemouse();
1400: if(!str) {
1401: puttext(28,12,53,14,sav);
1402: showmouse();
1403: return; }
1404: gettext(28,12,53,14,sav);
1405: memset(buf,' ',25*3*2);
1406: for(i=1;i<26*3*2;i+=2)
1407: buf[i]=(hclr|(bclr<<4));
1408: buf[0]='�';
1409: for(i=2;i<25*2;i+=2)
1410: buf[i]='�';
1411: buf[i]='�'; i+=2;
1412: buf[i]='�'; i+=2;
1413: i+=2;
1414: k=strlen(str);
1415: i+=(((23-k)/2)*2);
1416: for(j=0;j<k;j++,i+=2) {
1417: buf[i]=str[j];
1418: buf[i+1]|=BLINK; }
1419: i=((25*2)+1)*2;
1420: buf[i]='�'; i+=2;
1421: buf[i]='�'; i+=2;
1422: for(;i<((26*3)-1)*2;i+=2)
1423: buf[i]='�';
1424: buf[i]='�';
1425:
1426: puttext(28,12,53,14,buf);
1427: showmouse();
1428: }
1429:
1430: /****************************************************************************/
1431: /* Sets the current help index by source code file and line number. */
1432: /****************************************************************************/
1433: void sethelp(int line, char* file)
1434: {
1435: helpline=line;
1436: helpfile=file;
1437: }
1438:
1439: /************************************************************/
1440: /* Help (F1) key function. Uses helpbuf as the help input. */
1441: /************************************************************/
1442: void help()
1443: {
1444: char *savscrn,*buf,inverse=0,high=0
1445: ,hbuf[HELPBUF_SIZE],str[256];
1446: char *p;
1447: uint i,j,k,len;
1448: unsigned short line;
1449: long l;
1450: FILE *fp;
1451:
1452: _setcursortype(_NOCURSOR);
1453:
1454: if((savscrn=(char *)malloc(80*25*2))==NULL) {
1455: cprintf("UIFC line %d: error allocating %u bytes\r\n"
1456: ,__LINE__,80*25*2);
1457: _setcursortype(cursor);
1458: return; }
1459: if((buf=(char *)malloc(76*21*2))==NULL) {
1460: cprintf("UIFC line %d: error allocating %u bytes\r\n"
1461: ,__LINE__,76*21*2);
1462: free(savscrn);
1463: _setcursortype(cursor);
1464: return; }
1465: hidemouse();
1466: gettext(1,1,80,25,savscrn);
1467: memset(buf,' ',76*21*2);
1468: for(i=1;i<76*21*2;i+=2)
1469: buf[i]=(hclr|(bclr<<4));
1470: buf[0]='�';
1471: for(i=2;i<30*2;i+=2)
1472: buf[i]='�';
1473: buf[i]='�'; i+=4;
1474: buf[i]='O'; i+=2;
1475: buf[i]='n'; i+=2;
1476: buf[i]='l'; i+=2;
1477: buf[i]='i'; i+=2;
1478: buf[i]='n'; i+=2;
1479: buf[i]='e'; i+=4;
1480: buf[i]='H'; i+=2;
1481: buf[i]='e'; i+=2;
1482: buf[i]='l'; i+=2;
1483: buf[i]='p'; i+=4;
1484: buf[i]='�'; i+=2;
1485: for(j=i;j<i+(30*2);j+=2)
1486: buf[j]='�';
1487: i=j;
1488: buf[i]='�'; i+=2;
1489: j=i; /* leave i alone */
1490: for(k=0;k<19;k++) { /* the sides of the box */
1491: buf[j]='�'; j+=2;
1492: j+=(74*2);
1493: buf[j]='�'; j+=2; }
1494: buf[j]='�'; j+=2;
1495: for(k=j;k<j+(23*2);k+=2)
1496: buf[k]='�';
1497: buf[k]='�'; k+=4;
1498: buf[k]='H'; k+=2;
1499: buf[k]='i'; k+=2;
1500: buf[k]='t'; k+=4;
1501: buf[k]='a'; k+=2;
1502: buf[k]='n'; k+=2;
1503: buf[k]='y'; k+=4;
1504: buf[k]='k'; k+=2;
1505: buf[k]='e'; k+=2;
1506: buf[k]='y'; k+=4;
1507: buf[k]='t'; k+=2;
1508: buf[k]='o'; k+=4;
1509: buf[k]='c'; k+=2;
1510: buf[k]='o'; k+=2;
1511: buf[k]='n'; k+=2;
1512: buf[k]='t'; k+=2;
1513: buf[k]='i'; k+=2;
1514: buf[k]='n'; k+=2;
1515: buf[k]='u'; k+=2;
1516: buf[k]='e'; k+=4;
1517: buf[k]='�'; k+=2;
1518: for(j=k;j<k+(24*2);j+=2)
1519: buf[j]='�';
1520: buf[j]='�';
1521:
1522: if(!api->helpbuf) {
1523: if((fp=_fsopen(api->helpixbfile,"rb",SH_DENYWR))==NULL)
1524: sprintf(hbuf," ERROR Cannot open help index:\r\n %s"
1525: ,api->helpixbfile);
1526: else {
1527: p=strrchr(helpfile,'/');
1528: if(p==NULL)
1529: p=strrchr(helpfile,'\\');
1530: if(p==NULL)
1531: p=helpfile;
1532: else
1533: p++;
1534: l=-1L;
1535: while(!feof(fp)) {
1536: if(!fread(str,12,1,fp))
1537: break;
1538: str[12]=0;
1539: fread(&line,2,1,fp);
1540: if(stricmp(str,p) || line!=helpline) {
1541: fseek(fp,4,SEEK_CUR);
1542: continue; }
1543: fread(&l,4,1,fp);
1544: break; }
1545: fclose(fp);
1546: if(l==-1L)
1547: sprintf(hbuf," ERROR Cannot locate help key (%s:%u) in:\r\n"
1548: " %s",p,helpline,api->helpixbfile);
1549: else {
1550: if((fp=_fsopen(api->helpdatfile,"rb",SH_DENYWR))==NULL)
1551: sprintf(hbuf," ERROR Cannot open help file:\r\n %s"
1552: ,api->helpdatfile);
1553: else {
1554: fseek(fp,l,SEEK_SET);
1555: fread(hbuf,HELPBUF_SIZE,1,fp);
1556: fclose(fp); } } } }
1557: else
1558: strcpy(hbuf,api->helpbuf);
1559:
1560: len=strlen(hbuf);
1561:
1562: i+=78*2;
1563: for(j=0;j<len;j++,i+=2) {
1564: if(hbuf[j]==LF) {
1565: while(i%(76*2)) i++;
1566: i+=2; }
1567: else if(hbuf[j]==2 || hbuf[j]=='~') { /* Ctrl-b toggles inverse */
1568: inverse=!inverse;
1569: i-=2; }
1570: else if(hbuf[j]==1 || hbuf[j]=='`') { /* Ctrl-a toggles high intensity */
1571: high=!high;
1572: i-=2; }
1573: else if(hbuf[j]!=CR) {
1574: buf[i]=hbuf[j];
1575: buf[i+1]=inverse ? (bclr|(cclr<<4))
1576: : high ? (hclr|(bclr<<4)) : (lclr|(bclr<<4)); } }
1577: puttext(3,3,78,23,buf);
1578: showmouse();
1579: while(1) {
1580: if(inkey(1)) {
1581: inkey(0);
1582: break; }
1583: mswait(1);
1584: }
1585:
1586: hidemouse();
1587: puttext(1,1,80,25,savscrn);
1588: showmouse();
1589: free(savscrn);
1590: free(buf);
1591: _setcursortype(cursor);
1592: }
1593:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.