|
|
1.1 root 1: /* uifc32.c */
2:
3: /* Curses implementation of UIFC (user interface) library based on uifc.c */
4:
1.1.1.2 ! root 5: /* $Id: uifc32.c,v 1.197 2011/04/23 17:42:19 deuce Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2010 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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: #ifdef __unix__
39: #include <stdio.h>
40: #include <unistd.h>
41: #ifdef __QNX__
42: #include <strings.h>
43: #endif
44: #define mswait(x) delay(x)
45: #elif defined(_WIN32)
46: #include <share.h>
47: #include <windows.h>
48: #include <malloc.h>
49: #define mswait(x) Sleep(x)
50: #endif
51:
52: #include "ciolib.h"
53: #include "keys.h"
54: #include "uifc.h"
55: #define MAX_GETSTR 5120
56:
57: #define BLINK 128
58:
59: static int cursor;
60: static char* helpfile=0;
61: static uint helpline=0;
62: static size_t blk_scrn_len;
63: static char* blk_scrn;
64: static uchar* tmp_buffer;
65: static uchar* tmp_buffer2;
66: static win_t sav[MAX_BUFS];
67: static uifcapi_t* api;
68:
69: /* Prototypes */
70: static int uprintf(int x, int y, unsigned attr, char *fmt,...);
71: static void bottomline(int line);
72: static char *utimestr(time_t *intime);
73: static void help(void);
74: static int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int *lastkey);
75: static void timedisplay(BOOL force);
76:
77: /* API routines */
78: static void uifcbail(void);
79: static int uscrn(char *str);
80: static int ulist(int mode, int left, int top, int width, int *dflt, int *bar
81: ,char *title, char **option);
82: static int uinput(int imode, int left, int top, char *prompt, char *str
83: ,int len ,int kmode);
84: static void umsg(char *str);
85: static void upop(char *str);
86: static void sethelp(int line, char* file);
87: static void showbuf(int mode, int left, int top, int width, int height, char *title
88: , char *hbuf, int *curp, int *barp);
89:
90: /* Dynamic menu support */
91: static int *last_menu_cur=NULL;
92: static int *last_menu_bar=NULL;
93: static int save_menu_cur=-1;
94: static int save_menu_bar=-1;
95: static int save_menu_opts=-1;
96:
1.1.1.2 ! root 97: char* uifcYesNoOpts[]={"Yes","No",NULL};
! 98:
1.1 root 99: static void reset_dynamic(void) {
100: last_menu_cur=NULL;
101: last_menu_bar=NULL;
102: save_menu_cur=-1;
103: save_menu_bar=-1;
104: save_menu_opts=-1;
105: }
106:
107: /****************************************************************************/
108: /* Initialization function, see uifc.h for details. */
109: /* Returns 0 on success. */
110: /****************************************************************************/
111:
112: void uifc_mouse_enable(void)
113: {
114: ciomouse_setevents(0);
115: ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_START);
116: ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_MOVE);
117: ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_END);
118: ciomouse_addevent(CIOLIB_BUTTON_1_CLICK);
119: ciomouse_addevent(CIOLIB_BUTTON_2_CLICK);
120: ciomouse_addevent(CIOLIB_BUTTON_3_CLICK);
121: showmouse();
122: }
123:
124: void uifc_mouse_disable(void)
125: {
126: ciomouse_setevents(0);
127: hidemouse();
128: }
129:
130: int kbwait(void) {
131: int timeout=0;
132: while(timeout++<50) {
133: if(kbhit())
134: return(TRUE);
135: mswait(1);
136: }
137: return(FALSE);
138: }
139:
140: int inkey(void)
141: {
142: int c;
143:
144: c=getch();
1.1.1.2 ! root 145: if(!c || c==0xe0)
1.1 root 146: c|=(getch()<<8);
147: return(c);
148: }
149:
150: int uifcini32(uifcapi_t* uifcapi)
151: {
152: unsigned i;
153: struct text_info txtinfo;
154:
155: if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t))
156: return(-1);
157:
158: api=uifcapi;
159:
160: /* install function handlers */
161: api->bail=uifcbail;
162: api->scrn=uscrn;
163: api->msg=umsg;
164: api->pop=upop;
165: api->list=ulist;
166: api->input=uinput;
167: api->sethelp=sethelp;
168: api->showhelp=help;
169: api->showbuf=showbuf;
170: api->timedisplay=timedisplay;
171: api->bottomline=bottomline;
172: api->getstrxy=ugetstr;
173: api->printf=uprintf;
174:
175: if(api->scrn_len!=0) {
176: switch(api->scrn_len) {
177: case 14:
178: textmode(C80X14);
179: break;
180: case 21:
181: textmode(C80X21);
182: break;
183: case 25:
184: textmode(C80);
185: break;
186: case 28:
187: textmode(C80X28);
188: break;
189: case 43:
190: textmode(C80X43);
191: break;
192: case 50:
193: textmode(C80X50);
194: break;
195: case 60:
196: textmode(C80X60);
197: break;
198: default:
199: textmode(C4350);
200: break;
201: }
202: }
203:
204: #if 0
205: clrscr();
206: #endif
207:
208: gettextinfo(&txtinfo);
209: /* unsupported mode? */
210: if(txtinfo.screenheight<MIN_LINES
211: /* || txtinfo.screenheight>MAX_LINES */
212: || txtinfo.screenwidth<40) {
213: textmode(C80); /* set mode to 80x25*/
214: gettextinfo(&txtinfo);
215: }
216: window(1,1,txtinfo.screenwidth,txtinfo.screenheight);
217:
218: api->scrn_len=txtinfo.screenheight;
219: if(api->scrn_len<MIN_LINES) {
220: cprintf("\7UIFC: Screen length (%u) must be %d lines or greater\r\n"
221: ,api->scrn_len,MIN_LINES);
222: return(-2);
223: }
224: api->scrn_len--; /* account for status line */
225:
226: if(txtinfo.screenwidth<40) {
227: cprintf("\7UIFC: Screen width (%u) must be at least 40 characters\r\n"
228: ,txtinfo.screenwidth);
229: return(-3);
230: }
231: api->scrn_width=txtinfo.screenwidth;
232:
233: if(!(api->mode&UIFC_COLOR)
234: && (api->mode&UIFC_MONO
235: || txtinfo.currmode==MONO || txtinfo.currmode==BW40 || txtinfo.currmode==BW80
236: || txtinfo.currmode==MONO14 || txtinfo.currmode==BW40X14 || txtinfo.currmode==BW80X14
237: || txtinfo.currmode==MONO21 || txtinfo.currmode==BW40X21 || txtinfo.currmode==BW80X21
238: || txtinfo.currmode==MONO28 || txtinfo.currmode==BW40X28 || txtinfo.currmode==BW80X28
239: || txtinfo.currmode==MONO43 || txtinfo.currmode==BW40X43 || txtinfo.currmode==BW80X43
240: || txtinfo.currmode==MONO50 || txtinfo.currmode==BW40X50 || txtinfo.currmode==BW80X50
1.1.1.2 ! root 241: || txtinfo.currmode==MONO60 || txtinfo.currmode==BW40X60 || txtinfo.currmode==BW80X60
! 242: || txtinfo.currmode==ATARI_40X24 || txtinfo.currmode==ATARI_80X25))
1.1 root 243: {
244: api->bclr=BLACK;
245: api->hclr=WHITE;
246: api->lclr=LIGHTGRAY;
247: api->cclr=LIGHTGRAY;
248: api->lbclr=BLACK|(LIGHTGRAY<<4); /* lightbar color */
249: } else {
250: api->bclr=BLUE;
251: api->hclr=YELLOW;
252: api->lclr=WHITE;
253: api->cclr=CYAN;
254: api->lbclr=BLUE|(LIGHTGRAY<<4); /* lightbar color */
255: }
256:
257: blk_scrn_len=api->scrn_width*api->scrn_len*2;
258: if((blk_scrn=(char *)malloc(blk_scrn_len))==NULL) {
259: cprintf("UIFC line %d: error allocating %u bytes."
260: ,__LINE__,blk_scrn_len);
261: return(-1);
262: }
263: if((tmp_buffer=(uchar *)malloc(blk_scrn_len))==NULL) {
264: cprintf("UIFC line %d: error allocating %u bytes."
265: ,__LINE__,blk_scrn_len);
266: return(-1);
267: }
268: if((tmp_buffer2=(uchar *)malloc(blk_scrn_len))==NULL) {
269: cprintf("UIFC line %d: error allocating %u bytes."
270: ,__LINE__,blk_scrn_len);
271: return(-1);
272: }
273: for(i=0;i<blk_scrn_len;i+=2) {
274: blk_scrn[i]='�';
275: blk_scrn[i+1]=api->cclr|(api->bclr<<4);
276: }
277:
278: cursor=_NOCURSOR;
279: _setcursortype(cursor);
280:
281: if(cio_api.mouse) {
282: api->mode|=UIFC_MOUSE;
283: uifc_mouse_enable();
284: }
285:
286: /* A esc_delay of less than 10 is stupid... silently override */
287: if(api->esc_delay < 10)
288: api->esc_delay=25;
289:
290: if(cio_api.ESCDELAY)
291: *(cio_api.ESCDELAY)=api->esc_delay;
292:
293: for(i=0; i<MAX_BUFS; i++)
294: sav[i].buf=NULL;
1.1.1.2 ! root 295: api->savnum=0;
! 296:
! 297: api->initialized=TRUE;
1.1 root 298:
299: return(0);
300: }
301:
302: void docopy(void)
303: {
304: int key;
305: struct mouse_event mevent;
306: unsigned char *screen;
307: unsigned char *sbuffer;
308: int sbufsize=0;
309: int x,y,startx,starty,endx,endy,lines;
310: int outpos;
311: char *copybuf;
312:
313: sbufsize=api->scrn_width*2*(api->scrn_len+1);
314: screen=(unsigned char*)alloca(sbufsize);
315: sbuffer=(unsigned char*)alloca(sbufsize);
316: gettext(1,1,api->scrn_width,api->scrn_len+1,screen);
317: while(1) {
318: key=getch();
1.1.1.2 ! root 319: if(key==0 || key==0xe0)
1.1 root 320: key|=getch()<<8;
321: switch(key) {
322: case CIO_KEY_MOUSE:
323: getmouse(&mevent);
324: if(mevent.startx<mevent.endx) {
325: startx=mevent.startx;
326: endx=mevent.endx;
327: }
328: else {
329: startx=mevent.endx;
330: endx=mevent.startx;
331: }
332: if(mevent.starty<mevent.endy) {
333: starty=mevent.starty;
334: endy=mevent.endy;
335: }
336: else {
337: starty=mevent.endy;
338: endy=mevent.starty;
339: }
340: switch(mevent.event) {
341: case CIOLIB_BUTTON_1_DRAG_MOVE:
342: memcpy(sbuffer,screen,sbufsize);
343: for(y=starty-1;y<endy;y++) {
344: for(x=startx-1;x<endx;x++) {
345: int pos=y*api->scrn_width+x;
346: if((sbuffer[pos*2+1]&0x70)!=0x10)
1.1.1.2 ! root 347: sbuffer[pos*2+1]=(sbuffer[pos*2+1]&0x8F)|0x10;
1.1 root 348: else
1.1.1.2 ! root 349: sbuffer[pos*2+1]=(sbuffer[pos*2+1]&0x8F)|0x60;
1.1 root 350: if(((sbuffer[pos*2+1]&0x70)>>4) == (sbuffer[pos*2+1]&0x0F)) {
351: sbuffer[pos*2+1]|=0x08;
352: }
353: }
354: }
355: puttext(1,1,api->scrn_width,api->scrn_len+1,sbuffer);
356: break;
357: case CIOLIB_BUTTON_1_DRAG_END:
358: lines=abs(mevent.endy-mevent.starty)+1;
359: copybuf=alloca((endy-starty+1)*(endx-startx+1)+1+lines*2);
360: outpos=0;
361: for(y=starty-1;y<endy;y++) {
362: for(x=startx-1;x<endx;x++) {
363: copybuf[outpos++]=screen[(y*api->scrn_width+x)*2];
364: }
1.1.1.2 ! root 365: #ifdef _WIN32
! 366: copybuf[outpos++]='\r';
! 367: #endif
1.1 root 368: copybuf[outpos++]='\n';
369: }
370: copybuf[outpos]=0;
371: copytext(copybuf, strlen(copybuf));
372: puttext(1,1,api->scrn_width,api->scrn_len+1,screen);
373: return;
374: }
375: break;
376: default:
377: puttext(1,1,api->scrn_width,api->scrn_len+1,screen);
378: ungetch(key);
379: return;
380: }
381: }
382: }
383:
384: static int uifc_getmouse(struct mouse_event *mevent)
385: {
386: mevent->startx=0;
387: mevent->starty=0;
388: mevent->event=0;
389: if(api->mode&UIFC_MOUSE) {
390: getmouse(mevent);
391: if(mevent->event==CIOLIB_BUTTON_3_CLICK)
392: return(ESC);
393: if(mevent->event==CIOLIB_BUTTON_1_DRAG_START) {
394: docopy();
395: return(0);
396: }
397: if(mevent->starty==api->buttony) {
398: if(mevent->startx>=api->exitstart
399: && mevent->startx<=api->exitend
400: && mevent->event==CIOLIB_BUTTON_1_CLICK) {
401: return(ESC);
402: }
403: if(mevent->startx>=api->helpstart
404: && mevent->startx<=api->helpend
405: && mevent->event==CIOLIB_BUTTON_1_CLICK) {
406: return(CIO_KEY_F(1));
407: }
408: }
409: return(0);
410: }
411: return(-1);
412: }
413:
414: void uifcbail(void)
415: {
1.1.1.2 ! root 416: int i;
! 417:
1.1 root 418: _setcursortype(_NORMALCURSOR);
419: textattr(LIGHTGRAY);
420: uifc_mouse_disable();
421: suspendciolib();
422: FREE_AND_NULL(blk_scrn);
423: FREE_AND_NULL(tmp_buffer);
424: FREE_AND_NULL(tmp_buffer2);
425: api->initialized=FALSE;
1.1.1.2 ! root 426: for(i=0; i< MAX_BUFS; i++)
! 427: FREE_AND_NULL(sav[i].buf);
1.1 root 428: }
429:
430: /****************************************************************************/
431: /* Clear screen, fill with background attribute, display application title. */
432: /* Returns 0 on success. */
433: /****************************************************************************/
434: int uscrn(char *str)
435: {
436: textattr(api->bclr|(api->cclr<<4));
437: gotoxy(1,1);
438: clreol();
439: gotoxy(3,1);
440: cputs(str);
441: if(!puttext(1,2,api->scrn_width,api->scrn_len,blk_scrn))
442: return(-1);
443: gotoxy(1,api->scrn_len+1);
444: clreol();
445: reset_dynamic();
446: setname(str);
447: return(0);
448: }
449:
450: /****************************************************************************/
451: /****************************************************************************/
452: static void scroll_text(int x1, int y1, int x2, int y2, int down)
453: {
454: gettext(x1,y1,x2,y2,tmp_buffer2);
455: if(down)
456: puttext(x1,y1+1,x2,y2,tmp_buffer2);
457: else
458: puttext(x1,y1,x2,y2-1,tmp_buffer2+(((x2-x1)+1)*2));
459: }
460:
461: /****************************************************************************/
462: /* Updates time in upper left corner of screen with current time in ASCII/ */
463: /* Unix format */
464: /****************************************************************************/
465: static void timedisplay(BOOL force)
466: {
467: static time_t savetime;
468: time_t now;
469:
470: now=time(NULL);
471: if(force || difftime(now,savetime)>=60) {
472: uprintf(api->scrn_width-25,1,api->bclr|(api->cclr<<4),utimestr(&now));
473: savetime=now;
474: }
475: }
476:
477: /****************************************************************************/
478: /* Truncates white-space chars off end of 'str' */
479: /****************************************************************************/
480: static void truncsp(char *str)
481: {
482: uint c;
483:
484: c=strlen(str);
485: while(c && (uchar)str[c-1]<=' ') c--;
486: if(str[c]!=0) /* don't write to string constants */
487: str[c]=0;
488: }
489:
490: /****************************************************************************/
491: /* General menu function, see uifc.h for details. */
492: /****************************************************************************/
493: int ulist(int mode, int left, int top, int width, int *cur, int *bar
494: , char *initial_title, char **option)
495: {
1.1.1.2 ! root 496: uchar line[MAX_COLS*2],shade[MAX_LINES*4],*ptr
1.1 root 497: ,search[MAX_OPLN],bline=0,*win;
498: int height,y;
499: int i,j,opts=0,s=0; /* s=search index into options */
500: int is_redraw=0;
501: int s_top=SCRN_TOP;
502: int s_left=SCRN_LEFT;
503: int s_right=SCRN_RIGHT;
504: int s_bottom=api->scrn_len-3;
505: int hbrdrsize=2;
506: int lbrdrwidth=1;
507: int rbrdrwidth=1;
508: int vbrdrsize=4;
509: int tbrdrwidth=3;
510: int bbrdrwidth=1;
511: int title_len;
512: struct mouse_event mevnt;
513: char *title=NULL;
514: int a,b,c,longopt;
515: int optheight=0;
1.1.1.2 ! root 516: int gotkey;
1.1 root 517: uchar hclr,lclr,bclr,cclr,lbclr;
518:
519: hclr=api->hclr;
520: lclr=api->lclr;
521: bclr=api->bclr;
522: cclr=api->cclr;
523: lbclr=api->lbclr;
524: if(mode & WIN_INACT) {
525: bclr=api->cclr;
526: hclr=api->lclr;
527: lclr=api->lclr;
528: cclr=api->cclr;
529: lbclr=(api->cclr<<4)|api->hclr;
530: }
531: title=strdup(initial_title==NULL?"":initial_title);
532:
1.1.1.2 ! root 533: if(!(api->mode&UIFC_NHM))
! 534: uifc_mouse_disable();
1.1 root 535:
536: title_len=strlen(title);
537:
538: if(mode&WIN_FAT) {
539: s_top=1;
540: s_left=2;
541: s_right=api->scrn_width-3; /* Leave space for the shadow */
542: s_bottom=api->scrn_len-1; /* Leave one for the shadow */
543: }
544: if(mode&WIN_NOBRDR) {
545: hbrdrsize=0;
546: vbrdrsize=0;
547: lbrdrwidth=0;
548: rbrdrwidth=0;
549: tbrdrwidth=0;
550: bbrdrwidth=0;
551: }
552:
553: if(mode&WIN_SAV && api->savnum>=MAX_BUFS-1)
554: putch(7);
555: if(api->helpbuf!=NULL || api->helpixbfile[0]!=0) bline|=BL_HELP;
556: if(mode&WIN_INS) bline|=BL_INS;
557: if(mode&WIN_DEL) bline|=BL_DEL;
558: if(mode&WIN_GET) bline|=BL_GET;
559: if(mode&WIN_PUT) bline|=BL_PUT;
560: if(mode&WIN_EDIT) bline|=BL_EDIT;
561: if(api->bottomline != NULL)
562: api->bottomline(bline);
563: while(option!=NULL && opts<MAX_OPTS)
564: if(option[opts]==NULL || option[opts][0]==0)
565: break;
566: else opts++;
567: if(mode&WIN_XTR && opts<MAX_OPTS)
568: opts++;
569: optheight=opts+vbrdrsize;
570: height=optheight;
571: if(mode&WIN_FIXEDHEIGHT) {
572: height=api->list_height;
573: }
574: if(top+height>s_bottom)
575: height=(s_bottom)-top;
576: if(optheight>height)
577: optheight=height;
578: if(!width || width<title_len+hbrdrsize+2) {
579: width=title_len+hbrdrsize+2;
580: for(i=0;i<opts;i++) {
581: if(option[i]!=NULL) {
582: truncsp(option[i]);
583: if((j=strlen(option[i])+hbrdrsize+2+1)>width)
584: width=j;
585: }
586: }
587: }
588: /* Determine minimum widths here to accomodate mouse "icons" in border */
589: if(!(mode&WIN_NOBRDR) && api->mode&UIFC_MOUSE) {
590: if(bline&BL_HELP && width<8)
591: width=8;
592: else if(width<5)
593: width=5;
594: }
595: if(width>(s_right+1)-s_left) {
596: width=(s_right+1)-s_left;
597: if(title_len>(width-hbrdrsize-2)) {
598: *(title+width-hbrdrsize-2-3)='.';
599: *(title+width-hbrdrsize-2-2)='.';
600: *(title+width-hbrdrsize-2-1)='.';
601: *(title+width-hbrdrsize-2)=0;
602: title_len=strlen(title);
603: }
604: }
605: if(mode&WIN_L2R)
606: left=(s_right-s_left-width+1)/2;
607: else if(mode&WIN_RHT)
608: left=s_right-(width+hbrdrsize+2+left);
609: if(mode&WIN_T2B)
610: top=(api->scrn_len-height+1)/2-2;
611: else if(mode&WIN_BOT)
612: top=s_bottom-height-top;
613: if(left<0)
614: left=0;
615: if(top<0)
616: top=0;
617:
618: /* Dynamic Menus */
619: if(mode&WIN_DYN
620: && cur != NULL
621: && bar != NULL
622: && last_menu_cur==cur
623: && last_menu_bar==bar
624: && save_menu_cur==*cur
625: && save_menu_bar==*bar
626: && save_menu_opts==opts) {
627: is_redraw=1;
628: }
629:
630: if(mode&WIN_DYN && mode&WIN_REDRAW)
631: is_redraw=1;
632: if(mode&WIN_DYN && mode&WIN_NODRAW)
633: is_redraw=0;
634:
635: if(mode&WIN_ORG) { /* Clear all save buffers on WIN_ORG */
636: for(i=0; i< MAX_BUFS; i++)
637: FREE_AND_NULL(sav[i].buf);
638: api->savnum=0;
639: }
640:
641: if(mode&WIN_SAV) {
642: /* Check if this screen (by cur/bar) is already saved */
643: for(i=0; i<MAX_BUFS; i++) {
644: if(sav[i].buf!=NULL) {
645: if(cur==sav[i].cur && bar==sav[i].bar) {
646: /* Yes, it is... */
647: for(j=api->savnum-1; j>i; j--) {
648: /* Retore old screens */
649: puttext(sav[j].left,sav[j].top,sav[j].right,sav[j].bot
650: ,sav[j].buf); /* put original window back */
651: FREE_AND_NULL(sav[j].buf);
652: }
653: api->savnum=i;
654: }
655: }
656: }
657: /* savnum not the next one - must be a dynamic window or we popped back up the stack */
658: if(sav[api->savnum].buf != NULL) {
659: /* Is this even the right window? */
660: if(sav[api->savnum].cur==cur
661: && sav[api->savnum].bar==bar) {
662: if((sav[api->savnum].left!=s_left+left
663: || sav[api->savnum].top!=s_top+top
664: || sav[api->savnum].right!=s_left+left+width+1
665: || sav[api->savnum].bot!=s_top+top+height)) { /* dimensions have changed */
666: puttext(sav[api->savnum].left,sav[api->savnum].top,sav[api->savnum].right,sav[api->savnum].bot
667: ,sav[api->savnum].buf); /* put original window back */
668: FREE_AND_NULL(sav[api->savnum].buf);
669: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) {
670: cprintf("UIFC line %d: error allocating %u bytes."
671: ,__LINE__,(width+3)*(height+2)*2);
672: free(title);
1.1.1.2 ! root 673: if(!(api->mode&UIFC_NHM))
! 674: uifc_mouse_enable();
1.1 root 675: return(-1);
676: }
677: gettext(s_left+left,s_top+top,s_left+left+width+1
678: ,s_top+top+height,sav[api->savnum].buf); /* save again */
679: sav[api->savnum].left=s_left+left;
680: sav[api->savnum].top=s_top+top;
681: sav[api->savnum].right=s_left+left+width+1;
682: sav[api->savnum].bot=s_top+top+height;
683: sav[api->savnum].cur=cur;
684: sav[api->savnum].bar=bar;
685: }
686: }
687: else {
688: /* Find something available... */
689: while(sav[api->savnum].buf!=NULL)
690: api->savnum++;
691: }
692: }
693: else {
694: if((sav[api->savnum].buf=(char *)malloc((width+3)*(height+2)*2))==NULL) {
695: cprintf("UIFC line %d: error allocating %u bytes."
696: ,__LINE__,(width+3)*(height+2)*2);
697: free(title);
1.1.1.2 ! root 698: if(!(api->mode&UIFC_NHM))
! 699: uifc_mouse_enable();
1.1 root 700: return(-1);
701: }
702: gettext(s_left+left,s_top+top,s_left+left+width+1
703: ,s_top+top+height,sav[api->savnum].buf);
704: sav[api->savnum].left=s_left+left;
705: sav[api->savnum].top=s_top+top;
706: sav[api->savnum].right=s_left+left+width+1;
707: sav[api->savnum].bot=s_top+top+height;
708: sav[api->savnum].cur=cur;
709: sav[api->savnum].bar=bar;
710: }
711: }
712:
713: if(!is_redraw) {
714: if(mode&WIN_ORG) { /* Clear around menu */
715: if(top)
716: puttext(1,2,api->scrn_width,s_top+top-1,blk_scrn);
717: if((unsigned)(s_top+height+top)<=api->scrn_len)
718: puttext(1,s_top+height+top,api->scrn_width,api->scrn_len,blk_scrn);
719: if(left)
720: puttext(1,s_top+top,s_left+left-1,s_top+height+top
721: ,blk_scrn);
722: if(s_left+left+width<=s_right)
723: puttext(s_left+left+width,s_top+top,/* s_right+2 */api->scrn_width
724: ,s_top+height+top,blk_scrn);
725: }
726: ptr=tmp_buffer;
727: if(!(mode&WIN_NOBRDR)) {
728: *(ptr++)='�';
729: *(ptr++)=hclr|(bclr<<4);
730:
731: if(api->mode&UIFC_MOUSE) {
732: *(ptr++)='[';
733: *(ptr++)=hclr|(bclr<<4);
734: /* *(ptr++)='�'; */
735: *(ptr++)=0xfe;
736: *(ptr++)=lclr|(bclr<<4);
737: *(ptr++)=']';
738: *(ptr++)=hclr|(bclr<<4);
739: i=3;
740: if(bline&BL_HELP) {
741: *(ptr++)='[';
742: *(ptr++)=hclr|(bclr<<4);
743: *(ptr++)='?';
744: *(ptr++)=lclr|(bclr<<4);
745: *(ptr++)=']';
746: *(ptr++)=hclr|(bclr<<4);
747: i+=3;
748: }
749: api->buttony=s_top+top;
750: api->exitstart=s_left+left+1;
751: api->exitend=s_left+left+3;
752: api->helpstart=s_left+left+4;
753: api->helpend=s_left+left+6;
754: }
755: else
756: i=0;
757:
758: for(;i<width-2;i++) {
759: *(ptr++)='�';
760: *(ptr++)=hclr|(bclr<<4);
761: }
762: *(ptr++)='�';
763: *(ptr++)=hclr|(bclr<<4);
764: *(ptr++)='�';
765: *(ptr++)=hclr|(bclr<<4);
766: a=title_len;
767: b=(width-a-1)/2;
768: for(i=0;i<b;i++) {
769: *(ptr++)=' ';
770: *(ptr++)=hclr|(bclr<<4);
771: }
772: for(i=0;i<a;i++) {
773: *(ptr++)=title[i];
774: *(ptr++)=hclr|(bclr<<4);
775: }
776: for(i=0;i<width-(a+b)-2;i++) {
777: *(ptr++)=' ';
778: *(ptr++)=hclr|(bclr<<4);
779: }
780: *(ptr++)='�';
781: *(ptr++)=hclr|(bclr<<4);
782: *(ptr++)='�';
783: *(ptr++)=hclr|(bclr<<4);
784: for(i=0;i<width-2;i++) {
785: *(ptr++)='�';
786: *(ptr++)=hclr|(bclr<<4);
787: }
788: *(ptr++)='�';
789: *(ptr++)=hclr|(bclr<<4);
790: }
791:
792: if((*cur)>=opts)
793: (*cur)=opts-1; /* returned after scrolled */
794:
795: if(!bar) {
796: if((*cur)>height-vbrdrsize-1)
797: (*cur)=height-vbrdrsize-1;
798: if((*cur)>opts-1)
799: (*cur)=opts-1;
800: i=0;
801: }
802: else {
803: if((*bar)>=opts)
804: (*bar)=opts-1;
805: if((*bar)>height-vbrdrsize-1)
806: (*bar)=height-vbrdrsize-1;
807: if((*cur)==opts-1)
808: (*bar)=height-vbrdrsize-1;
809: if((*bar)>opts-1)
810: (*bar)=opts-1;
811: if((*bar)<0)
812: (*bar)=0;
813: if((*cur)<(*bar))
814: (*cur)=(*bar);
815: i=(*cur)-(*bar);
816: if(i+(height-vbrdrsize-1)>=opts) {
817: i=opts-(height-vbrdrsize);
818: if(i<0)
819: i=0;
820: (*cur)=i+(*bar);
821: }
822: }
823: if((*cur)<0)
824: (*cur)=0;
825:
826: j=0;
827: if(i<0) i=0;
828: longopt=0;
829: while(j<height-vbrdrsize) {
830: if(!(mode&WIN_NOBRDR)) {
831: *(ptr++)='�';
832: *(ptr++)=hclr|(bclr<<4);
833: }
834: *(ptr++)=' ';
835: *(ptr++)=hclr|(bclr<<4);
836: *(ptr++)='�';
837: *(ptr++)=lclr|(bclr<<4);
838: if(i==(*cur))
839: a=lbclr;
840: else
841: a=lclr|(bclr<<4);
842: if(i<opts && option[i]!=NULL) {
843: b=strlen(option[i]);
844: if(b>longopt)
845: longopt=b;
846: if(b+hbrdrsize+2>width)
847: b=width-hbrdrsize-2;
848: for(c=0;c<b;c++) {
849: *(ptr++)=option[i][c];
850: *(ptr++)=a;
851: }
852: }
853: else
854: c=0;
855: while(c<width-hbrdrsize-2) {
856: *(ptr++)=' ';
857: *(ptr++)=a;
858: c++;
859: }
860: if(!(mode&WIN_NOBRDR)) {
861: *(ptr++)='�';
862: *(ptr++)=hclr|(bclr<<4);
863: }
864: i++;
865: j++;
866: }
867: if(!(mode&WIN_NOBRDR)) {
868: *(ptr++)='�';
869: *(ptr++)=hclr|(bclr<<4);
870: for(i=0;i<width-2;i++) {
871: *(ptr++)='�';
872: *(ptr++)=hclr|(bclr<<4);
873: }
874: *(ptr++)='�';
875: *(ptr)=hclr|(bclr<<4); /* Not incremented to shut ot BCC */
876: }
877: puttext(s_left+left,s_top+top,s_left+left+width-1
878: ,s_top+top+height-1,tmp_buffer);
879: if(bar)
880: y=top+tbrdrwidth+(*bar);
881: else
882: y=top+tbrdrwidth+(*cur);
883: if(opts+vbrdrsize>height && ((!bar && (*cur)!=opts-1)
884: || (bar && ((*cur)-(*bar))+(height-vbrdrsize)<opts))) {
885: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
886: textattr(lclr|(bclr<<4));
887: putch(31); /* put down arrow */
888: textattr(hclr|(bclr<<4));
889: }
890:
891: if(bar && (*bar)!=(*cur)) {
892: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
893: textattr(lclr|(bclr<<4));
894: putch(30); /* put the up arrow */
895: textattr(hclr|(bclr<<4));
896: }
897:
898: if(!(mode&WIN_NOBRDR)) {
899: /* Shadow */
900: if(bclr==BLUE) {
901: gettext(s_left+left+width,s_top+top+1,s_left+left+width+1
902: ,s_top+top+height-1,shade);
903: for(i=1;i<height*4;i+=2)
904: shade[i]=DARKGRAY;
905: puttext(s_left+left+width,s_top+top+1,s_left+left+width+1
906: ,s_top+top+height-1,shade);
907: gettext(s_left+left+2,s_top+top+height,s_left+left+width+1
908: ,s_top+top+height,shade);
909: for(i=1;i<width*2;i+=2)
910: shade[i]=DARKGRAY;
911: puttext(s_left+left+2,s_top+top+height,s_left+left+width+1
912: ,s_top+top+height,shade);
913: }
914: }
915: }
916: else { /* Is a redraw */
917: if(bar)
918: y=top+tbrdrwidth+(*bar);
919: else
920: y=top+tbrdrwidth+(*cur);
921: i=(*cur)+(top+tbrdrwidth-y);
922: j=2;
923:
924: longopt=0;
925: while(j<height-bbrdrwidth-1) {
926: ptr=tmp_buffer;
927: if(i==(*cur))
928: a=lbclr;
929: else
930: a=lclr|(bclr<<4);
931: if(i<opts && option[i]!=NULL) {
932: b=strlen(option[i]);
933: if(b>longopt)
934: longopt=b;
935: if(b+hbrdrsize+2>width)
936: b=width-hbrdrsize-2;
937: for(c=0;c<b;c++) {
938: *(ptr++)=option[i][c];
939: *(ptr++)=a;
940: }
941: }
942: else
943: c=0;
944: while(c<width-hbrdrsize-2) {
945: *(ptr++)=' ';
946: *(ptr++)=a;
947: c++;
948: }
949: i++;
950: j++;
951: puttext(s_left+left+lbrdrwidth+2,s_top+top+j,s_left+left+width-rbrdrwidth-1
952: ,s_top+top+j,tmp_buffer);
953: }
954: }
955: free(title);
956:
957: last_menu_cur=cur;
958: last_menu_bar=bar;
1.1.1.2 ! root 959: if(!(api->mode&UIFC_NHM))
! 960: uifc_mouse_enable();
1.1 root 961:
962: if(mode&WIN_IMM) {
963: return(-2);
964: }
965:
966: if(mode&WIN_ORG) {
967: if(api->timedisplay != NULL)
968: api->timedisplay(/* force? */TRUE);
969: }
970:
971: while(1) {
972: #if 0 /* debug */
973: gotoxy(30,1);
974: cprintf("y=%2d h=%2d c=%2d b=%2d s=%2d o=%2d"
975: ,y,height,*cur,bar ? *bar :0xff,api->savnum,opts);
976: #endif
977: if(api->timedisplay != NULL)
978: api->timedisplay(/* force? */FALSE);
1.1.1.2 ! root 979: gotkey=0;
! 980: if(kbwait() || (mode&(WIN_POP|WIN_SEL))) {
! 981: if(mode&WIN_POP)
! 982: gotkey=ESC;
! 983: else if(mode&WIN_SEL)
! 984: gotkey=CR;
! 985: else
! 986: gotkey=inkey();
! 987: if(gotkey==CIO_KEY_MOUSE) {
! 988: if((gotkey=uifc_getmouse(&mevnt))==0) {
1.1 root 989: /* Clicked in menu */
990: if(mevnt.startx>=s_left+left+lbrdrwidth+2
991: && mevnt.startx<=s_left+left+width-rbrdrwidth-1
992: && mevnt.starty>=s_top+top+tbrdrwidth
993: && mevnt.starty<=(s_top+top+optheight)-bbrdrwidth-1
994: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
995:
996: (*cur)=((mevnt.starty)-(s_top+top+tbrdrwidth))+(*cur+(top+tbrdrwidth-y));
997: if(bar)
998: (*bar)=(*cur);
999: y=top+tbrdrwidth+((mevnt.starty)-(s_top+top+tbrdrwidth));
1000:
1001: if(!opts)
1002: continue;
1003:
1004: if(mode&WIN_SAV)
1005: api->savnum++;
1006: if(mode&WIN_ACT) {
1.1.1.2 ! root 1007: if(!(api->mode&UIFC_NHM))
! 1008: uifc_mouse_disable();
1.1 root 1009: if((win=(char *)alloca((width+3)*(height+2)*2))==NULL) {
1010: cprintf("UIFC line %d: error allocating %u bytes."
1011: ,__LINE__,(width+3)*(height+2)*2);
1012: return(-1);
1013: }
1014: gettext(s_left+left,s_top+top,s_left
1015: +left+width-1,s_top+top+height-1,win);
1016: for(i=1;i<(width*height*2);i+=2)
1017: win[i]=lclr|(cclr<<4);
1018: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2);
1019: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
1020: win[i]=hclr|(cclr<<4);
1021:
1022: puttext(s_left+left,s_top+top,s_left
1023: +left+width-1,s_top+top+height-1,win);
1.1.1.2 ! root 1024: if(!(api->mode&UIFC_NHM))
! 1025: uifc_mouse_enable();
1.1 root 1026: }
1027: else if(mode&WIN_SAV) {
1028: api->savnum--;
1.1.1.2 ! root 1029: if(!(api->mode&UIFC_NHM))
! 1030: uifc_mouse_disable();
1.1 root 1031: puttext(sav[api->savnum].left,sav[api->savnum].top
1032: ,sav[api->savnum].right,sav[api->savnum].bot
1033: ,sav[api->savnum].buf);
1.1.1.2 ! root 1034: if(!(api->mode&UIFC_NHM))
! 1035: uifc_mouse_enable();
1.1 root 1036: FREE_AND_NULL(sav[api->savnum].buf);
1037: }
1038: if(mode&WIN_XTR && (*cur)==opts-1)
1039: return(MSK_INS|*cur);
1040: return(*cur);
1041: }
1042: /* Clicked Scroll Up */
1043: else if(mevnt.startx==s_left+left+lbrdrwidth
1044: && mevnt.starty==s_top+top+tbrdrwidth
1045: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
1.1.1.2 ! root 1046: gotkey=CIO_KEY_PPAGE;
1.1 root 1047: }
1048: /* Clicked Scroll Down */
1049: else if(mevnt.startx==s_left+left+lbrdrwidth
1050: && mevnt.starty==(s_top+top+height)-bbrdrwidth-1
1051: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
1.1.1.2 ! root 1052: gotkey=CIO_KEY_NPAGE;
1.1 root 1053: }
1054: /* Clicked Outside of Window */
1055: else if((mevnt.startx<s_left+left
1056: || mevnt.startx>s_left+left+width-1
1057: || mevnt.starty<s_top+top
1058: || mevnt.starty>s_top+top+height-1)
1059: && (mevnt.event==CIOLIB_BUTTON_1_CLICK
1060: || mevnt.event==CIOLIB_BUTTON_3_CLICK)) {
1061: if(mode&WIN_UNGETMOUSE) {
1062: ungetmouse(&mevnt);
1.1.1.2 ! root 1063: gotkey=CIO_KEY_MOUSE;
1.1 root 1064: }
1065: else {
1.1.1.2 ! root 1066: gotkey=ESC;
1.1 root 1067: }
1068: }
1069: }
1070: }
1071: /* For compatibility with terminals lacking special keys */
1.1.1.2 ! root 1072: switch(gotkey) {
1.1 root 1073: case '\b':
1.1.1.2 ! root 1074: gotkey=ESC;
1.1 root 1075: break;
1076: case '+':
1.1.1.2 ! root 1077: gotkey=CIO_KEY_IC; /* insert */
1.1 root 1078: break;
1079: case '-':
1080: case DEL:
1.1.1.2 ! root 1081: gotkey=CIO_KEY_DC; /* delete */
1.1 root 1082: break;
1083: case CTRL_B:
1084: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1085: gotkey=CIO_KEY_HOME;
1.1 root 1086: break;
1087: case CTRL_E:
1088: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1089: gotkey=CIO_KEY_END;
1.1 root 1090: break;
1091: case CTRL_U:
1092: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1093: gotkey=CIO_KEY_PPAGE;
1.1 root 1094: break;
1095: case CTRL_D:
1096: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1097: gotkey=CIO_KEY_NPAGE;
1.1 root 1098: break;
1099: case CTRL_Z:
1100: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1101: gotkey=CIO_KEY_F(1); /* help */
1.1 root 1102: break;
1103: case CTRL_C:
1104: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1105: gotkey=CIO_KEY_F(5); /* copy */
1.1 root 1106: break;
1107: case CTRL_V:
1108: if(!(api->mode&UIFC_NOCTRL))
1.1.1.2 ! root 1109: gotkey=CIO_KEY_F(6); /* paste */
! 1110: break;
! 1111: case CIO_KEY_ABORTED:
! 1112: gotkey=ESC;
1.1 root 1113: break;
1114: }
1.1.1.2 ! root 1115: if(gotkey>255) {
1.1 root 1116: s=0;
1.1.1.2 ! root 1117: switch(gotkey) {
1.1 root 1118: /* ToDo extended keys */
1119: case CIO_KEY_HOME: /* home */
1120: if(!opts)
1121: break;
1122: if(opts+vbrdrsize>optheight) {
1123: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1124: textattr(lclr|(bclr<<4));
1125: putch(' '); /* Delete the up arrow */
1126: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1127: putch(31); /* put the down arrow */
1128: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth
1129: ,lbclr
1130: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[0]);
1131: for(i=1;i<optheight-vbrdrsize;i++) /* re-display options */
1132: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+i
1133: ,lclr|(bclr<<4)
1134: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1135: (*cur)=0;
1136: if(bar)
1137: (*bar)=0;
1138: y=top+tbrdrwidth;
1139: break;
1140: }
1141: gettext(s_left+left+lbrdrwidth+2,s_top+y
1142: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1143: for(i=1;i<width*2;i+=2)
1144: line[i]=lclr|(bclr<<4);
1145: puttext(s_left+left+lbrdrwidth+2,s_top+y
1146: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1147: (*cur)=0;
1148: if(bar)
1149: (*bar)=0;
1150: y=top+tbrdrwidth;
1151: gettext(s_left+lbrdrwidth+2+left,s_top+y
1152: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1153: for(i=1;i<width*2;i+=2)
1154: line[i]=lbclr;
1155: puttext(s_left+lbrdrwidth+2+left,s_top+y
1156: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1157: break;
1158: case CIO_KEY_UP: /* up arrow */
1159: if(!opts)
1160: break;
1161: if(!(*cur) && opts+vbrdrsize>optheight) {
1162: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth); /* like end */
1163: textattr(lclr|(bclr<<4));
1164: putch(30); /* put the up arrow */
1165: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1166: putch(' '); /* delete the down arrow */
1167: for(i=(opts+vbrdrsize)-optheight,j=0;i<opts;i++,j++)
1168: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j
1169: ,i==opts-1 ? lbclr
1170: : lclr|(bclr<<4)
1171: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1172: (*cur)=opts-1;
1173: if(bar)
1174: (*bar)=optheight-vbrdrsize-1;
1175: y=top+optheight-bbrdrwidth-1;
1176: break;
1177: }
1178: gettext(s_left+lbrdrwidth+2+left,s_top+y
1179: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1180: for(i=1;i<width*2;i+=2)
1181: line[i]=lclr|(bclr<<4);
1182: puttext(s_left+lbrdrwidth+2+left,s_top+y
1183: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1184: if(!(*cur)) {
1185: y=top+optheight-bbrdrwidth-1;
1186: (*cur)=opts-1;
1187: if(bar)
1188: (*bar)=optheight-vbrdrsize-1;
1189: }
1190: else {
1191: (*cur)--;
1192: y--;
1193: if(bar && *bar)
1194: (*bar)--;
1195: }
1196: if(y<top+tbrdrwidth) { /* scroll */
1197: if(!(*cur)) {
1198: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1199: textattr(lclr|(bclr<<4));
1200: putch(' '); /* delete the up arrow */
1201: }
1202: if((*cur)+optheight-vbrdrsize==opts-1) {
1203: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1204: textattr(lclr|(bclr<<4));
1205: putch(31); /* put the dn arrow */
1206: }
1207: y++;
1208: scroll_text(s_left+left+lbrdrwidth+1,s_top+top+tbrdrwidth
1209: ,s_left+left+width-rbrdrwidth-1,s_top+top+height-bbrdrwidth-1,1);
1210: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth
1211: ,lbclr
1212: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[*cur]);
1213: }
1214: else {
1215: gettext(s_left+lbrdrwidth+2+left,s_top+y
1216: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1217: for(i=1;i<width*2;i+=2)
1218: line[i]=lbclr;
1219: puttext(s_left+lbrdrwidth+2+left,s_top+y
1220: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1221: }
1222: break;
1223: case CIO_KEY_PPAGE: /* PgUp */
1224: if(!opts)
1225: break;
1226: *cur -= (optheight-vbrdrsize-1);
1227: if(*cur<0)
1228: *cur = 0;
1229: if(bar)
1230: *bar=0;
1231: y=top+tbrdrwidth;
1232: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1233: textattr(lclr|(bclr<<4));
1.1.1.2 ! root 1234: if(*cur) /* Scroll mode */
1.1 root 1235: putch(30); /* put the up arrow */
1236: else
1237: putch(' '); /* delete the up arrow */
1238: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1.1.1.2 ! root 1239: if(opts >= height-tbrdrwidth && *cur + height - vbrdrsize < opts)
1.1 root 1240: putch(31); /* put the down arrow */
1241: else
1242: putch(' '); /* delete the down arrow */
1243: for(i=*cur,j=0;i<=*cur-vbrdrsize-1+optheight;i++,j++)
1244: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j
1245: ,i==*cur ? lbclr
1246: : lclr|(bclr<<4)
1247: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1248: break;
1249: case CIO_KEY_NPAGE: /* PgDn */
1250: if(!opts)
1251: break;
1252: *cur += (height-vbrdrsize-1);
1253: if(*cur>opts-1)
1254: *cur = opts-1;
1255: if(bar)
1256: *bar = optheight-vbrdrsize-1;
1257: y=top+optheight-bbrdrwidth-1;
1258: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1259: textattr(lclr|(bclr<<4));
1260: if(*cur>height-vbrdrsize-1) /* Scroll mode */
1261: putch(30); /* put the up arrow */
1262: else
1263: putch(' '); /* delete the up arrow */
1264: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1265: if(*cur < opts-1)
1266: putch(31); /* put the down arrow */
1267: else
1268: putch(' '); /* delete the down arrow */
1269: for(i=*cur+vbrdrsize+1-optheight,j=0;i<=*cur;i++,j++)
1270: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j
1271: ,i==*cur ? lbclr
1272: : lclr|(bclr<<4)
1273: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1274: break;
1275: case CIO_KEY_END: /* end */
1276: if(!opts)
1277: break;
1278: if(opts+vbrdrsize>height) { /* Scroll mode */
1279: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1280: textattr(lclr|(bclr<<4));
1281: putch(30); /* put the up arrow */
1282: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1283: putch(' '); /* delete the down arrow */
1284: for(i=(opts+vbrdrsize)-height,j=0;i<opts;i++,j++)
1285: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j
1286: ,i==opts-1 ? lbclr
1287: : lclr|(bclr<<4)
1288: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1289: (*cur)=opts-1;
1290: y=top+optheight-bbrdrwidth-1;
1291: if(bar)
1292: (*bar)=optheight-vbrdrsize-1;
1293: break;
1294: }
1295: gettext(s_left+lbrdrwidth+2+left,s_top+y
1296: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1297: for(i=1;i<width*2;i+=2)
1298: line[i]=lclr|(bclr<<4);
1299: puttext(s_left+lbrdrwidth+2+left,s_top+y
1300: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1301: (*cur)=opts-1;
1302: y=top+optheight-bbrdrwidth-1;
1303: if(bar)
1304: (*bar)=optheight-vbrdrsize-1;
1305: gettext(s_left+lbrdrwidth+2+left,s_top+y
1306: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1307: for(i=1;i<148;i+=2)
1308: line[i]=lbclr;
1309: puttext(s_left+lbrdrwidth+2+left,s_top+y
1310: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1311: break;
1312: case CIO_KEY_DOWN: /* dn arrow */
1313: if(!opts)
1314: break;
1315: if((*cur)==opts-1 && opts+vbrdrsize>height) { /* like home */
1316: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1317: textattr(lclr|(bclr<<4));
1318: putch(' '); /* Delete the up arrow */
1319: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1320: putch(31); /* put the down arrow */
1321: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth
1322: ,lbclr
1323: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[0]);
1324: for(i=1;i<height-vbrdrsize;i++) /* re-display options */
1325: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+i
1326: ,lclr|(bclr<<4)
1327: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1328: (*cur)=0;
1329: y=top+tbrdrwidth;
1330: if(bar)
1331: (*bar)=0;
1332: break;
1333: }
1334: gettext(s_left+lbrdrwidth+2+left,s_top+y
1335: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1336: for(i=1;i<width*2;i+=2)
1337: line[i]=lclr|(bclr<<4);
1338: puttext(s_left+lbrdrwidth+2+left,s_top+y
1339: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1340: if((*cur)==opts-1) {
1341: (*cur)=0;
1342: y=top+tbrdrwidth;
1343: if(bar) {
1344: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */
1345: (*bar)=0;
1346: }
1347: }
1348: else {
1349: (*cur)++;
1350: y++;
1351: if(bar && (*bar)<height-vbrdrsize-1) {
1352: /* gotoxy(1,1); cprintf("bar=%08lX ",bar); */
1353: (*bar)++;
1354: }
1355: }
1356: if(y==top+height-bbrdrwidth) { /* scroll */
1357: if(*cur==opts-1) {
1358: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1359: textattr(lclr|(bclr<<4));
1360: putch(' '); /* delete the down arrow */
1361: }
1362: if((*cur)+vbrdrsize==height) {
1363: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1364: textattr(lclr|(bclr<<4));
1365: putch(30); /* put the up arrow */
1366: }
1367: y--;
1368: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */
1369: scroll_text(s_left+left+lbrdrwidth+1,s_top+top+tbrdrwidth
1370: ,s_left+left+width-rbrdrwidth-1,s_top+top+height-bbrdrwidth-1,0);
1371: /* gotoxy(1,1); cprintf("\rdebug: %4d ",__LINE__); */
1372: uprintf(s_left+left+lbrdrwidth+2,s_top+top+height-bbrdrwidth-1
1373: ,lbclr
1374: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[*cur]);
1375: }
1376: else {
1377: gettext(s_left+lbrdrwidth+2+left,s_top+y
1378: ,s_left+left+width-rbrdrwidth-1,s_top+y
1379: ,line);
1380: for(i=1;i<width*2;i+=2)
1381: line[i]=lbclr;
1382: puttext(s_left+lbrdrwidth+2+left,s_top+y
1383: ,s_left+left+width-rbrdrwidth-1,s_top+y
1384: ,line);
1385: }
1386: break;
1387: case CIO_KEY_F(1): /* F1 - Help */
1388: api->showhelp();
1389: break;
1390: case CIO_KEY_F(2): /* F2 - Edit */
1391: if(mode&WIN_XTR && (*cur)==opts-1) /* can't edit */
1392: break; /* extra line */
1393: if(mode&WIN_EDIT) {
1.1.1.2 ! root 1394: if(mode&WIN_SAV)
! 1395: api->savnum++;
! 1396: if(mode&WIN_ACT) {
1.1 root 1397: gettext(s_left+left,s_top+top,s_left
1398: +left+width-1,s_top+top+height-1,tmp_buffer);
1399: for(i=1;i<(width*height*2);i+=2)
1400: tmp_buffer[i]=lclr|(cclr<<4);
1401: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2);
1402: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
1403: tmp_buffer[i]=hclr|(cclr<<4);
1.1.1.2 ! root 1404:
1.1 root 1405: puttext(s_left+left,s_top+top,s_left
1406: +left+width-1,s_top+top+height-1,tmp_buffer);
1407: }
1.1.1.2 ! root 1408: else if(mode&WIN_SAV) {
! 1409: api->savnum--;
! 1410: puttext(sav[api->savnum].left,sav[api->savnum].top
! 1411: ,sav[api->savnum].right,sav[api->savnum].bot
! 1412: ,sav[api->savnum].buf);
! 1413: FREE_AND_NULL(sav[api->savnum].buf);
! 1414: }
1.1 root 1415: return((*cur)|MSK_EDIT);
1416: }
1417: break;
1418: case CIO_KEY_F(5): /* F5 - Copy */
1419: if(mode&WIN_GET && !(mode&WIN_XTR && (*cur)==opts-1))
1420: return((*cur)|MSK_GET);
1421: break;
1422: case CIO_KEY_F(6): /* F6 - Paste */
1423: if(mode&WIN_PUT && !(mode&WIN_XTR && (*cur)==opts-1))
1424: return((*cur)|MSK_PUT);
1425: break;
1426: case CIO_KEY_IC: /* insert */
1427: if(mode&WIN_INS) {
1.1.1.2 ! root 1428: if(mode&WIN_SAV)
! 1429: api->savnum++;
1.1 root 1430: if(mode&WIN_INSACT) {
1431: gettext(s_left+left,s_top+top,s_left
1432: +left+width-1,s_top+top+height-1,tmp_buffer);
1433: for(i=1;i<(width*height*2);i+=2)
1434: tmp_buffer[i]=lclr|(cclr<<4);
1.1.1.2 ! root 1435: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2);
! 1436: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
! 1437: tmp_buffer[i]=hclr|(cclr<<4);
! 1438:
1.1 root 1439: puttext(s_left+left,s_top+top,s_left
1440: +left+width-1,s_top+top+height-1,tmp_buffer);
1441: }
1.1.1.2 ! root 1442: else if(mode&WIN_SAV) {
! 1443: api->savnum--;
! 1444: puttext(sav[api->savnum].left,sav[api->savnum].top
! 1445: ,sav[api->savnum].right,sav[api->savnum].bot
! 1446: ,sav[api->savnum].buf);
! 1447: FREE_AND_NULL(sav[api->savnum].buf);
! 1448: }
1.1 root 1449: if(!opts) {
1450: return(MSK_INS);
1451: }
1452: return((*cur)|MSK_INS);
1453: }
1454: break;
1455: case CIO_KEY_DC: /* delete */
1456: if(mode&WIN_XTR && (*cur)==opts-1) /* can't delete */
1457: break; /* extra line */
1458: if(mode&WIN_DEL) {
1.1.1.2 ! root 1459: if(mode&WIN_SAV)
! 1460: api->savnum++;
1.1 root 1461: if(mode&WIN_DELACT) {
1462: gettext(s_left+left,s_top+top,s_left
1463: +left+width-1,s_top+top+height-1,tmp_buffer);
1464: for(i=1;i<(width*height*2);i+=2)
1465: tmp_buffer[i]=lclr|(cclr<<4);
1466: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2);
1467: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
1468: tmp_buffer[i]=hclr|(cclr<<4);
1.1.1.2 ! root 1469:
1.1 root 1470: puttext(s_left+left,s_top+top,s_left
1471: +left+width-1,s_top+top+height-1,tmp_buffer);
1472: }
1.1.1.2 ! root 1473: else if(mode&WIN_SAV) {
! 1474: api->savnum--;
! 1475: puttext(sav[api->savnum].left,sav[api->savnum].top
! 1476: ,sav[api->savnum].right,sav[api->savnum].bot
! 1477: ,sav[api->savnum].buf);
! 1478: FREE_AND_NULL(sav[api->savnum].buf);
! 1479: }
1.1 root 1480: return((*cur)|MSK_DEL);
1481: }
1482: break;
1483: default:
1484: if(mode&WIN_EXTKEYS)
1.1.1.2 ! root 1485: return(-2-gotkey);
1.1 root 1486: break;
1487: }
1488: }
1489: else {
1.1.1.2 ! root 1490: gotkey&=0xff;
! 1491: if(isalnum(gotkey) && opts>1 && option[0][0]) {
! 1492: search[s]=gotkey;
1.1 root 1493: search[s+1]=0;
1494: for(j=(*cur)+1,a=b=0;a<2;j++) { /* a = search count */
1495: if(j==opts) { /* j = option count */
1496: j=-1; /* b = letter count */
1497: continue;
1498: }
1499: if(j==(*cur)) {
1500: b++;
1501: continue;
1502: }
1503: if(b>=longopt) {
1504: b=0;
1505: a++;
1506: }
1507: if(a==1 && !s)
1508: break;
1509: if(option[j]!=NULL
1510: && strlen(option[j])>(size_t)b
1511: && ((!a && s && !strnicmp(option[j]+b,search,s+1))
1.1.1.2 ! root 1512: || ((a || !s) && toupper(option[j][b])==toupper(gotkey)))) {
1.1 root 1513: if(a) s=0;
1514: else s++;
1515: if(y+(j-(*cur))+2>height+top) {
1516: (*cur)=j;
1517: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1518: textattr(lclr|(bclr<<4));
1519: putch(30); /* put the up arrow */
1520: if((*cur)==opts-1) {
1521: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1522: putch(' '); /* delete the down arrow */
1523: }
1524: for(i=((*cur)+vbrdrsize+1)-height,j=0;i<(*cur)+1;i++,j++)
1525: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+j
1526: ,i==(*cur) ? lbclr
1527: : lclr|(bclr<<4)
1528: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[i]);
1529: y=top+height-bbrdrwidth-1;
1530: if(bar)
1531: (*bar)=optheight-vbrdrsize-1;
1532: break;
1533: }
1534: if(y-((*cur)-j)<top+tbrdrwidth) {
1535: (*cur)=j;
1536: gotoxy(s_left+left+lbrdrwidth,s_top+top+tbrdrwidth);
1537: textattr(lclr|(bclr<<4));
1538: if(!(*cur))
1539: putch(' '); /* Delete the up arrow */
1540: gotoxy(s_left+left+lbrdrwidth,s_top+top+height-bbrdrwidth-1);
1541: putch(31); /* put the down arrow */
1542: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth
1543: ,lbclr
1544: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2,option[(*cur)]);
1545: for(i=1;i<height-vbrdrsize;i++) /* re-display options */
1546: uprintf(s_left+left+lbrdrwidth+2,s_top+top+tbrdrwidth+i
1547: ,lclr|(bclr<<4)
1548: ,"%-*.*s",width-hbrdrsize-2,width-hbrdrsize-2
1549: ,option[(*cur)+i]);
1550: y=top+tbrdrwidth;
1551: if(bar)
1552: (*bar)=0;
1553: break;
1554: }
1555: gettext(s_left+lbrdrwidth+2+left,s_top+y
1556: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1557: for(i=1;i<width*2;i+=2)
1558: line[i]=lclr|(bclr<<4);
1559: puttext(s_left+lbrdrwidth+2+left,s_top+y
1560: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1561: if((*cur)>j)
1562: y-=(*cur)-j;
1563: else
1564: y+=j-(*cur);
1565: if(bar) {
1566: if((*cur)>j)
1567: (*bar)-=(*cur)-j;
1568: else
1569: (*bar)+=j-(*cur);
1570: }
1571: (*cur)=j;
1572: gettext(s_left+lbrdrwidth+2+left,s_top+y
1573: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1574: for(i=1;i<width*2;i+=2)
1575: line[i]=lbclr;
1576: puttext(s_left+lbrdrwidth+2+left,s_top+y
1577: ,s_left+left+width-rbrdrwidth-1,s_top+y,line);
1578: break;
1579: }
1580: }
1581: if(a==2)
1582: s=0;
1583: }
1584: else
1.1.1.2 ! root 1585: switch(gotkey) {
1.1 root 1586: case CR:
1587: if(!opts)
1588: break;
1589: if(mode&WIN_SAV)
1590: api->savnum++;
1591: if(mode&WIN_ACT) {
1592: gettext(s_left+left,s_top+top,s_left
1593: +left+width-1,s_top+top+height-1,tmp_buffer);
1594: for(i=1;i<(width*height*2);i+=2)
1595: tmp_buffer[i]=lclr|(cclr<<4);
1596: j=(((y-top)*width)*2)+7+((width-hbrdrsize-2)*2);
1597: for(i=(((y-top)*width)*2)+7;i<j;i+=2)
1598: tmp_buffer[i]=hclr|(cclr<<4);
1599:
1600: puttext(s_left+left,s_top+top,s_left
1601: +left+width-1,s_top+top+height-1,tmp_buffer);
1602: }
1603: else if(mode&WIN_SAV) {
1604: api->savnum--;
1605: puttext(sav[api->savnum].left,sav[api->savnum].top
1606: ,sav[api->savnum].right,sav[api->savnum].bot
1607: ,sav[api->savnum].buf);
1608: FREE_AND_NULL(sav[api->savnum].buf);
1609: }
1610: if(mode&WIN_XTR && (*cur)==opts-1)
1611: return(MSK_INS|*cur);
1612: return(*cur);
1613: case 3:
1614: case ESC:
1615: if(mode&WIN_SAV)
1616: api->savnum++;
1617: if(mode&WIN_ESC || (mode&WIN_CHE && api->changes)) {
1618: gettext(s_left+left,s_top+top,s_left
1619: +left+width-1,s_top+top+height-1,tmp_buffer);
1620: for(i=1;i<(width*height*2);i+=2)
1621: tmp_buffer[i]=lclr|(cclr<<4);
1622: puttext(s_left+left,s_top+top,s_left
1623: +left+width-1,s_top+top+height-1,tmp_buffer);
1624: }
1625: else if(mode&WIN_SAV) {
1626: api->savnum--;
1627: puttext(sav[api->savnum].left,sav[api->savnum].top
1628: ,sav[api->savnum].right,sav[api->savnum].bot
1629: ,sav[api->savnum].buf);
1630: FREE_AND_NULL(sav[api->savnum].buf);
1631: }
1632: return(-1);
1633: default:
1634: if(mode&WIN_EXTKEYS)
1.1.1.2 ! root 1635: return(-2-gotkey);
1.1 root 1636: }
1637: }
1638: }
1639: else
1640: mswait(1);
1641: if(mode&WIN_DYN) {
1642: save_menu_cur=*cur;
1643: save_menu_bar=*bar;
1644: save_menu_opts=opts;
1.1.1.2 ! root 1645: return(-2-gotkey);
1.1 root 1646: }
1647: }
1648: }
1649:
1650:
1651: /*************************************************************************/
1652: /* This function is a windowed input string input routine. */
1653: /*************************************************************************/
1654: int uinput(int mode, int left, int top, char *inprompt, char *str,
1655: int max, int kmode)
1656: {
1.1.1.2 ! root 1657: unsigned char save_buf[MAX_COLS*8],in_win[MAX_COLS*6]
! 1658: ,shade[MAX_COLS*2];
1.1 root 1659: int width;
1660: int height=3;
1661: int i,plen,slen,j;
1662: int iwidth;
1663: int l;
1664: char *prompt;
1665: int s_top=SCRN_TOP;
1666: int s_left=SCRN_LEFT;
1667: int s_right=SCRN_RIGHT;
1668: int s_bottom=api->scrn_len-3;
1669: int hbrdrsize=2;
1670: int lbrdrwidth=1;
1671: int rbrdrwidth=1;
1672: int vbrdrsize=4;
1673: int tbrdrwidth=1;
1674: int bbrdrwidth=1;
1675:
1676: reset_dynamic();
1677:
1678: if(mode&WIN_FAT) {
1679: s_top=1;
1680: s_left=2;
1681: s_right=api->scrn_width-3; /* Leave space for the shadow */
1682: s_bottom=api->scrn_len-1; /* Leave one for the shadow */
1683: }
1684: if(mode&WIN_NOBRDR) {
1685: hbrdrsize=0;
1686: vbrdrsize=0;
1687: lbrdrwidth=0;
1688: rbrdrwidth=0;
1689: tbrdrwidth=0;
1690: bbrdrwidth=0;
1691: height=1;
1692: }
1693:
1694: prompt=strdup(inprompt==NULL ? "":inprompt);
1695: plen=strlen(prompt);
1696: if(!plen)
1697: slen=2+hbrdrsize;
1698: else
1699: slen=4+hbrdrsize;
1700:
1701: width=plen+slen+max;
1702: if(width>(s_right-s_left+1))
1703: width=(s_right-s_left+1);
1704: if(mode&WIN_T2B)
1705: top=(api->scrn_len-height+1)/2-2;
1706: if(mode&WIN_L2R)
1707: left=(s_right-s_left-width+1)/2;
1708: if(left<=-(s_left))
1709: left=-(s_left)+1;
1710: if(top<0)
1711: top=0;
1712: if(mode&WIN_SAV)
1713: gettext(s_left+left,s_top+top,s_left+left+width+1
1714: ,s_top+top+height,save_buf);
1715: iwidth=width-plen-slen;
1716: while(iwidth<1 && plen>4) {
1717: plen=strlen(prompt);
1718: prompt[plen-1]=0;
1719: prompt[plen-2]='.';
1720: prompt[plen-3]='.';
1721: prompt[plen-4]='.';
1722: plen--;
1723: iwidth=width-plen-slen;
1724: }
1725:
1726: i=0;
1727: if(!(mode&WIN_NOBRDR)) {
1728: in_win[i++]='�';
1729: in_win[i++]=api->hclr|(api->bclr<<4);
1730: for(j=1;j<width-1;j++) {
1731: in_win[i++]='�';
1732: in_win[i++]=api->hclr|(api->bclr<<4);
1733: }
1734: if(api->mode&UIFC_MOUSE && width>6) {
1735: j=2;
1736: in_win[j++]='[';
1737: in_win[j++]=api->hclr|(api->bclr<<4);
1738: /* in_win[4]='�'; */
1739: in_win[j++]=0xfe;
1740: in_win[j++]=api->lclr|(api->bclr<<4);
1741: in_win[j++]=']';
1742: in_win[j++]=api->hclr|(api->bclr<<4);
1743: l=3;
1744: if(api->helpbuf!=NULL || api->helpixbfile[0]!=0) {
1745: in_win[j++]='[';
1746: in_win[j++]=api->hclr|(api->bclr<<4);
1747: in_win[j++]='?';
1748: in_win[j++]=api->lclr|(api->bclr<<4);
1749: in_win[j++]=']';
1750: in_win[j++]=api->hclr|(api->bclr<<4);
1751: l+=3;
1752: }
1753: api->buttony=s_top+top;
1754: api->exitstart=s_left+left+1;
1755: api->exitend=s_left+left+3;
1756: api->helpstart=s_left+left+4;
1757: api->helpend=s_left+left+l;
1758: }
1759:
1760: in_win[i++]='�';
1761: in_win[i++]=api->hclr|(api->bclr<<4);
1762: in_win[i++]='�';
1763: in_win[i++]=api->hclr|(api->bclr<<4);
1764: }
1765:
1766: if(plen) {
1767: in_win[i++]=' ';
1768: in_win[i++]=api->lclr|(api->bclr<<4);
1769: }
1770:
1771: for(j=0;prompt[j];j++) {
1772: in_win[i++]=prompt[j];
1773: in_win[i++]=api->lclr|(api->bclr<<4);
1774: }
1775:
1776: if(plen) {
1777: in_win[i++]=':';
1778: in_win[i++]=api->lclr|(api->bclr<<4);
1779: }
1780:
1781: for(j=0;j<iwidth+2;j++) {
1782: in_win[i++]=' ';
1783: in_win[i++]=api->lclr|(api->bclr<<4);
1784: }
1785:
1786: if(!(mode&WIN_NOBRDR)) {
1787: in_win[i++]='�';
1788: in_win[i++]=api->hclr|(api->bclr<<4);
1789: in_win[i++]='�';
1790: in_win[i++]=api->hclr|(api->bclr<<4);
1791: for(j=1;j<width-1;j++) {
1792: in_win[i++]='�';
1793: in_win[i++]=api->hclr|(api->bclr<<4);
1794: }
1795: in_win[i++]='�';
1796: in_win[i]=api->hclr|(api->bclr<<4); /* I is not incremented to shut up BCC */
1797: }
1798: puttext(s_left+left,s_top+top,s_left+left+width-1
1799: ,s_top+top+height-1,in_win);
1800:
1801: if(!(mode&WIN_NOBRDR)) {
1802: /* Shadow */
1803: if(api->bclr==BLUE) {
1804: gettext(s_left+left+width,s_top+top+1,s_left+left+width+1
1805: ,s_top+top+(height-1),shade);
1806: for(j=1;j<12;j+=2)
1807: shade[j]=DARKGRAY;
1808: puttext(s_left+left+width,s_top+top+1,s_left+left+width+1
1809: ,s_top+top+(height-1),shade);
1810: gettext(s_left+left+2,s_top+top+3,s_left+left+width+1
1811: ,s_top+top+height,shade);
1812: for(j=1;j<width*2;j+=2)
1813: shade[j]=DARKGRAY;
1814: puttext(s_left+left+2,s_top+top+3,s_left+left+width+1
1815: ,s_top+top+height,shade);
1816: }
1817: }
1818:
1819: textattr(api->lclr|(api->bclr<<4));
1820: if(!plen)
1821: i=ugetstr(s_left+left+2,s_top+top+tbrdrwidth,iwidth,str,max,kmode,NULL);
1822: else
1823: i=ugetstr(s_left+left+plen+4,s_top+top+tbrdrwidth,iwidth,str,max,kmode,NULL);
1824: if(mode&WIN_SAV)
1825: puttext(s_left+left,s_top+top,s_left+left+width+1
1826: ,s_top+top+height,save_buf);
1827: free(prompt);
1828: return(i);
1829: }
1830:
1831: /****************************************************************************/
1832: /* Displays the message 'str' and waits for the user to select "OK" */
1833: /****************************************************************************/
1834: void umsg(char *str)
1835: {
1836: int i=0;
1837: char *ok[2]={"OK",""};
1838:
1839: if(api->mode&UIFC_INMSG) /* non-cursive */
1840: return;
1841: api->mode|=UIFC_INMSG;
1842: ulist(WIN_SAV|WIN_MID,0,0,0,&i,0,str,ok);
1843: api->mode&=~UIFC_INMSG;
1844: }
1845:
1846: /***************************************/
1847: /* Private sub - updates a ugetstr box */
1848: /***************************************/
1849: void getstrupd(int left, int top, int width, char *outstr, int cursoffset, int *scrnoffset, int mode)
1850: {
1851: _setcursortype(_NOCURSOR);
1852: if(cursoffset<*scrnoffset)
1853: *scrnoffset=cursoffset;
1854:
1855: if(*scrnoffset+width < cursoffset)
1856: *scrnoffset=cursoffset-width;
1857:
1858: gotoxy(left,top);
1859: if(mode&K_PASSWORD)
1860: cprintf("%-*.*s",width,width,"********************************************************************************"+(80-strlen(outstr+*scrnoffset)));
1861: else
1862: cprintf("%-*.*s",width,width,outstr+*scrnoffset);
1863: gotoxy(left+(cursoffset-*scrnoffset),top);
1864: _setcursortype(cursor);
1865: }
1866:
1867: /****************************************************************************/
1868: /* Gets a string of characters from the user. Turns cursor on. Allows */
1869: /* Different modes - K_* macros. ESC aborts input. */
1870: /****************************************************************************/
1871: int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int *lastkey)
1872: {
1873: uchar *str,ins=0;
1874: int ch;
1875: int i,j,k,f=0; /* i=offset, j=length */
1876: BOOL gotdecimal=FALSE;
1877: int soffset=0;
1878: struct mouse_event mevnt;
1879: unsigned char *pastebuf=NULL;
1880: unsigned char *pb=NULL;
1881:
1882: if((str=(uchar *)alloca(max+1))==NULL) {
1883: cprintf("UIFC line %d: error allocating %u bytes\r\n"
1884: ,__LINE__,(max+1));
1885: _setcursortype(cursor);
1886: return(-1);
1887: }
1888: gotoxy(left,top);
1889: cursor=_NORMALCURSOR;
1890: _setcursortype(cursor);
1891: str[0]=0;
1892: if(mode&K_EDIT && outstr[0]) {
1893: /***
1894: truncsp(outstr);
1895: ***/
1896: outstr[max]=0;
1897: i=j=strlen(outstr);
1898: textattr(api->lbclr);
1899: getstrupd(left, top, width, outstr, i, &soffset, mode);
1900: textattr(api->lclr|(api->bclr<<4));
1901: if(strlen(outstr)<(size_t)width) {
1902: k=wherex();
1903: f=wherey();
1904: cprintf("%*s",width-strlen(outstr),"");
1905: gotoxy(k,f);
1906: }
1907: strcpy(str,outstr);
1908: #if 0
1909: while(kbwait()==0) {
1910: mswait(1);
1911: }
1912: #endif
1913: f=inkey();
1914: if(f==CIO_KEY_MOUSE) {
1915: f=uifc_getmouse(&mevnt);
1916: if(f==0 || (f==ESC && mevnt.event==CIOLIB_BUTTON_3_CLICK)) {
1917: if(mode & K_MOUSEEXIT
1918: && (mevnt.starty != top
1919: || mevnt.startx > left+width
1920: || mevnt.startx < left)
1921: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
1922: if(lastkey)
1923: *lastkey=CIO_KEY_MOUSE;
1924: ungetmouse(&mevnt);
1925: return(j);
1926: }
1927: if(mevnt.startx>=left
1928: && mevnt.startx<=left+width
1929: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
1930: i=mevnt.startx-left+soffset;
1931: if(i>j)
1932: i=j;
1933: }
1934: if(mevnt.starty == top
1935: && mevnt.startx>=left
1936: && mevnt.startx<=left+width
1937: && (mevnt.event==CIOLIB_BUTTON_2_CLICK
1938: || mevnt.event==CIOLIB_BUTTON_3_CLICK)) {
1939: i=mevnt.startx-left+soffset;
1940: if(i>j)
1941: i=j;
1942: pastebuf=getcliptext();
1943: pb=pastebuf;
1944: f=0;
1945: }
1946: }
1947: }
1948:
1949: if(f == CR
1950: || (f >= 0xff && f != CIO_KEY_DC)
1951: || (f == '\t' && mode&K_TABEXIT)
1952: || (f == '%' && mode&K_SCANNING)
1953: || f==CTRL_B
1954: || f==CTRL_E
1955: || f==CTRL_V
1956: || f==CTRL_Z
1957: || f==0)
1958: {
1959: getstrupd(left, top, width, str, i, &soffset, mode);
1960: }
1961: else
1962: {
1963: getstrupd(left, top, width, str, i, &soffset, mode);
1964: i=j=0;
1965: }
1966: }
1967: else
1968: i=j=0;
1969:
1970: ch=0;
1971: while(ch!=CR)
1972: {
1973: if(i>j) j=i;
1974: str[j]=0;
1975: getstrupd(left, top, width, str, i, &soffset, mode);
1976: if(f || pb!=NULL || (ch=inkey())!=0)
1977: {
1978: if(f) {
1979: ch=f;
1980: f=0;
1981: }
1982: else if(pb!=NULL) {
1983: ch=*(pb++);
1984: if(!*pb) {
1985: free(pastebuf);
1986: pastebuf=NULL;
1987: pb=NULL;
1988: }
1989: }
1990: if(ch==CIO_KEY_MOUSE) {
1991: ch=uifc_getmouse(&mevnt);
1992: if(ch==0 || (ch==ESC && mevnt.event==CIOLIB_BUTTON_3_CLICK)) {
1993: if(mode & K_MOUSEEXIT
1994: && (mevnt.starty != top
1995: || mevnt.startx > left+width
1996: || mevnt.startx < left)
1997: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
1998: if(lastkey)
1999: *lastkey=CIO_KEY_MOUSE;
2000: ungetmouse(&mevnt);
2001: ch=CR;
2002: continue;
2003: }
2004: if(mevnt.starty == top
2005: && mevnt.startx>=left
2006: && mevnt.startx<=left+width
2007: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
2008: i=mevnt.startx-left+soffset;
2009: if(i>j)
2010: i=j;
2011: }
2012: if(mevnt.starty == top
2013: && mevnt.startx>=left
2014: && mevnt.startx<=left+width
2015: && (mevnt.event==CIOLIB_BUTTON_2_CLICK
2016: || mevnt.event==CIOLIB_BUTTON_3_CLICK)) {
2017: i=mevnt.startx-left+soffset;
2018: if(i>j)
2019: i=j;
2020: pastebuf=getcliptext();
2021: pb=pastebuf;
2022: ch=0;
2023: }
2024: }
2025: }
2026: if(lastkey != NULL)
2027: *lastkey=ch;
2028: switch(ch)
2029: {
2030: case CTRL_Z:
2031: case CIO_KEY_F(1): /* F1 Help */
2032: api->showhelp();
2033: continue;
2034: case CIO_KEY_LEFT: /* left arrow */
2035: if(i)
2036: {
2037: i--;
2038: }
2039: continue;
2040: case CIO_KEY_RIGHT: /* right arrow */
2041: if(i<j)
2042: {
2043: i++;
2044: }
2045: continue;
2046: case CTRL_B:
2047: case CIO_KEY_HOME: /* home */
2048: if(i)
2049: {
2050: i=0;
2051: }
2052: continue;
2053: case CTRL_E:
2054: case CIO_KEY_END: /* end */
2055: if(i<j)
2056: {
2057: i=j;
2058: }
2059: continue;
2060: case CTRL_V:
2061: case CIO_KEY_IC: /* insert */
2062: ins=!ins;
2063: if(ins)
2064: cursor=_SOLIDCURSOR;
2065: else
2066: cursor=_NORMALCURSOR;
2067: _setcursortype(cursor);
2068: continue;
2069: case BS:
2070: if(i)
2071: {
2072: if(i==j)
2073: {
2074: j--;
2075: i--;
2076: }
2077: else {
2078: i--;
2079: j--;
2080: if(str[i]=='.')
2081: gotdecimal=FALSE;
2082: for(k=i;k<=j;k++)
2083: str[k]=str[k+1];
2084: }
2085: continue;
2086: }
2087: case CIO_KEY_DC: /* delete */
1.1.1.2 ! root 2088: case DEL: /* sdl_getch() is returning 127 when keypad "Del" is hit */
1.1 root 2089: if(i<j)
2090: {
2091: if(str[i]=='.')
2092: gotdecimal=FALSE;
2093: for(k=i;k<j;k++)
2094: str[k]=str[k+1];
2095: j--;
2096: }
2097: continue;
1.1.1.2 ! root 2098: case CIO_KEY_ABORTED:
1.1 root 2099: case CTRL_C:
2100: case ESC:
2101: {
2102: cursor=_NOCURSOR;
2103: _setcursortype(cursor);
2104: if(pastebuf!=NULL)
2105: free(pastebuf);
2106: return(-1);
2107: }
2108: case CR:
2109: break;
2110: case 3840: /* Backtab */
2111: case '\t':
2112: if(mode&K_TABEXIT)
2113: ch=CR;
2114: break;
2115: case '%': /* '%' indicates that a UPC is coming next */
2116: if(mode&K_SCANNING)
2117: ch=CR;
2118: break;
2119: case CIO_KEY_F(2):
2120: case CIO_KEY_UP:
2121: case CIO_KEY_DOWN:
2122: if(mode&K_DEUCEEXIT) {
2123: ch=CR;
2124: break;
2125: }
2126: continue;
2127: case CTRL_X:
2128: if(j)
2129: {
2130: i=j=0;
2131: }
2132: continue;
2133: case CTRL_Y:
2134: if(i<j)
2135: {
2136: j=i;
2137: }
2138: continue;
2139: }
2140: if(mode&K_NUMBER && !isdigit(ch))
2141: continue;
2142: if(mode&K_DECIMAL && !isdigit(ch)) {
2143: if(ch!='.')
2144: continue;
2145: if(gotdecimal)
2146: continue;
2147: gotdecimal=TRUE;
2148: }
2149: if(mode&K_ALPHA && !isalpha(ch))
2150: continue;
2151: #if 0
2152: /* This broke swedish chars... */
2153: if((ch>=' ' || (ch==1 && mode&K_MSG)) && i<max && (!ins || j<max) && isprint(ch))
2154: #else
2155: if((ch>=' ' || (ch==1 && mode&K_MSG)) && i<max && (!ins || j<max) && ch < 256)
2156: #endif
2157: {
2158: if(mode&K_UPPER)
2159: ch=toupper(ch);
2160: if(ins)
2161: {
2162: for(k=++j;k>i;k--)
2163: str[k]=str[k-1];
2164: }
2165: str[i++]=ch;
2166: }
2167: }
2168: }
2169:
2170:
2171: str[j]=0;
2172: if(mode&K_EDIT)
2173: {
2174: truncsp(str);
2175: if(strcmp(outstr,str))
2176: api->changes=1;
2177: }
2178: else
2179: {
2180: if(j)
2181: api->changes=1;
2182: }
2183: strcpy(outstr,str);
2184: cursor=_NOCURSOR;
2185: _setcursortype(cursor);
2186: if(pastebuf!=NULL)
2187: free(pastebuf);
2188: return(j);
2189: }
2190:
2191: /****************************************************************************/
2192: /* Performs printf() through puttext() routine */
2193: /****************************************************************************/
2194: static int uprintf(int x, int y, unsigned attr, char *fmat, ...)
2195: {
2196: va_list argptr;
1.1.1.2 ! root 2197: char str[MAX_COLS+1],buf[MAX_COLS*2];
1.1 root 2198: int i,j;
2199:
2200: va_start(argptr,fmat);
2201: vsprintf(str,fmat,argptr);
2202: va_end(argptr);
2203: for(i=j=0;str[i];i++) {
2204: buf[j++]=str[i];
2205: buf[j++]=attr;
2206: }
2207: puttext(x,y,x+(i-1),y,buf);
2208: return(i);
2209: }
2210:
2211:
2212: /****************************************************************************/
2213: /* Display bottom line of screen in inverse */
2214: /****************************************************************************/
2215: void bottomline(int line)
2216: {
1.1.1.2 ! root 2217: int i=1;
1.1 root 2218:
2219: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4)," ");
2220: i+=4;
2221: if(line&BL_HELP) {
2222: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F1 ");
2223: i+=3;
2224: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Help ");
2225: i+=6;
2226: }
2227: if(line&BL_EDIT) {
2228: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F2 ");
2229: i+=3;
2230: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Edit Item ");
2231: i+=11;
2232: }
2233: if(line&BL_GET) {
2234: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F5 ");
2235: i+=3;
2236: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Copy Item ");
2237: i+=11;
2238: }
2239: if(line&BL_PUT) {
2240: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"F6 ");
2241: i+=3;
2242: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Paste ");
2243: i+=7;
2244: }
2245: if(line&BL_INS) {
2246: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"INS ");
2247: i+=4;
2248: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Add Item ");
2249: i+=10;
2250: }
2251: if(line&BL_DEL) {
2252: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"DEL ");
2253: i+=4;
2254: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Delete Item ");
2255: i+=13;
2256: }
2257: uprintf(i,api->scrn_len+1,api->bclr|(api->cclr<<4),"ESC "); /* Backspace is no good no way to abort editing */
2258: i+=4;
2259: uprintf(i,api->scrn_len+1,BLACK|(api->cclr<<4),"Exit");
2260: i+=4;
2261: gotoxy(i,api->scrn_len+1);
2262: textattr(BLACK|(api->cclr<<4));
2263: clreol();
2264: }
2265:
2266:
2267: /*****************************************************************************/
2268: /* Generates a 24 character ASCII string that represents the time_t pointer */
2269: /* Used as a replacement for ctime() */
2270: /*****************************************************************************/
2271: char *utimestr(time_t *intime)
2272: {
2273: static char str[25];
2274: char wday[4],mon[4],mer[3],hour;
2275: struct tm *gm;
2276:
2277: gm=localtime(intime);
2278: switch(gm->tm_wday) {
2279: case 0:
2280: strcpy(wday,"Sun");
2281: break;
2282: case 1:
2283: strcpy(wday,"Mon");
2284: break;
2285: case 2:
2286: strcpy(wday,"Tue");
2287: break;
2288: case 3:
2289: strcpy(wday,"Wed");
2290: break;
2291: case 4:
2292: strcpy(wday,"Thu");
2293: break;
2294: case 5:
2295: strcpy(wday,"Fri");
2296: break;
2297: case 6:
2298: strcpy(wday,"Sat");
2299: break;
2300: }
2301: switch(gm->tm_mon) {
2302: case 0:
2303: strcpy(mon,"Jan");
2304: break;
2305: case 1:
2306: strcpy(mon,"Feb");
2307: break;
2308: case 2:
2309: strcpy(mon,"Mar");
2310: break;
2311: case 3:
2312: strcpy(mon,"Apr");
2313: break;
2314: case 4:
2315: strcpy(mon,"May");
2316: break;
2317: case 5:
2318: strcpy(mon,"Jun");
2319: break;
2320: case 6:
2321: strcpy(mon,"Jul");
2322: break;
2323: case 7:
2324: strcpy(mon,"Aug");
2325: break;
2326: case 8:
2327: strcpy(mon,"Sep");
2328: break;
2329: case 9:
2330: strcpy(mon,"Oct");
2331: break;
2332: case 10:
2333: strcpy(mon,"Nov");
2334: break;
2335: case 11:
2336: strcpy(mon,"Dec");
2337: break;
2338: }
2339: if(gm->tm_hour>12) {
2340: strcpy(mer,"pm");
2341: hour=gm->tm_hour-12;
2342: }
2343: else {
2344: if(!gm->tm_hour)
2345: hour=12;
2346: else
2347: hour=gm->tm_hour;
2348: strcpy(mer,"am");
2349: }
2350: sprintf(str,"%s %s %02d %4d %02d:%02d %s",wday,mon,gm->tm_mday,1900+gm->tm_year
2351: ,hour,gm->tm_min,mer);
2352: return(str);
2353: }
2354:
2355: /****************************************************************************/
2356: /* Status popup/down function, see uifc.h for details. */
2357: /****************************************************************************/
2358: void upop(char *str)
2359: {
2360: static char sav[26*3*2];
2361: char buf[26*3*2];
2362: int i,j,k;
2363:
2364: if(!str) {
2365: /* puttext(28,12,53,14,sav); */
2366: puttext((api->scrn_width-26+1)/2+1,(api->scrn_len-3+1)/2+1
2367: ,(api->scrn_width+26-1)/2+1,(api->scrn_len+3-1)/2+1,sav);
2368: return;
2369: }
2370: /* gettext(28,12,53,14,sav); */
2371: gettext((api->scrn_width-26+1)/2+1,(api->scrn_len-3+1)/2+1
2372: ,(api->scrn_width+26-1)/2+1,(api->scrn_len+3-1)/2+1,sav);
2373: memset(buf,' ',25*3*2);
2374: for(i=1;i<26*3*2;i+=2)
2375: buf[i]=(api->hclr|(api->bclr<<4));
2376: buf[0]='�';
2377: for(i=2;i<25*2;i+=2)
2378: buf[i]='�';
2379: buf[i]='�'; i+=2;
2380: buf[i]='�'; i+=2;
2381: i+=2;
2382: k=strlen(str);
2383: i+=(((23-k)/2)*2);
2384: for(j=0;j<k;j++,i+=2) {
2385: buf[i]=str[j];
2386: buf[i+1]|=BLINK;
2387: }
2388: i=((25*2)+1)*2;
2389: buf[i]='�'; i+=2;
2390: buf[i]='�'; i+=2;
2391: for(;i<((26*3)-1)*2;i+=2)
2392: buf[i]='�';
2393: buf[i]='�';
2394:
2395: /* puttext(28,12,53,14,buf); */
2396: puttext((api->scrn_width-26+1)/2+1,(api->scrn_len-3+1)/2+1
2397: ,(api->scrn_width+26-1)/2+1,(api->scrn_len+3-1)/2+1,buf);
2398: }
2399:
2400: /****************************************************************************/
2401: /* Sets the current help index by source code file and line number. */
2402: /****************************************************************************/
2403: void sethelp(int line, char* file)
2404: {
2405: helpline=line;
2406: helpfile=file;
2407: }
2408:
2409: /****************************************************************************/
2410: /* Shows a scrollable text buffer - optionally parsing "help markup codes" */
2411: /****************************************************************************/
2412: void showbuf(int mode, int left, int top, int width, int height, char *title, char *hbuf, int *curp, int *barp)
2413: {
2414: char inverse=0,high=0;
2415: char *textbuf;
2416: char *p;
2417: char *oldp=NULL;
2418: int i,j,k,len;
2419: int lines;
2420: int pad=1;
2421: int is_redraw=0;
2422: uint title_len=0;
2423: struct mouse_event mevnt;
2424:
2425: _setcursortype(_NOCURSOR);
2426:
2427: title_len=strlen(title);
2428: if(api->mode&UIFC_MOUSE)
2429: title_len+=6;
2430:
2431: if((unsigned)(top+height)>api->scrn_len-3)
2432: height=(api->scrn_len-3)-top;
2433: if(!width || (unsigned)width<title_len+6)
2434: width=title_len+6;
2435: if((unsigned)width>api->scrn_width)
2436: width=api->scrn_width;
2437: if(mode&WIN_L2R)
2438: left=(api->scrn_width-width+2)/2;
2439: else if(mode&WIN_RHT)
2440: left=SCRN_RIGHT-(width+4+left);
2441: if(mode&WIN_T2B)
2442: top=(api->scrn_len-height+1)/2;
2443: else if(mode&WIN_BOT)
2444: top=api->scrn_len-height-3-top;
2445: if(left<0)
2446: left=0;
2447: if(top<0)
2448: top=0;
2449:
2450: if(mode&WIN_PACK)
2451: pad=0;
2452:
2453: /* Dynamic Menus */
2454: if(mode&WIN_DYN
2455: && curp != NULL
2456: && barp != NULL
2457: && last_menu_cur==curp
2458: && last_menu_bar==barp
2459: && save_menu_cur==*curp
2460: && save_menu_bar==*barp)
2461: is_redraw=1;
2462: if(mode&WIN_DYN && mode&WIN_REDRAW)
2463: is_redraw=1;
2464: if(mode&WIN_DYN && mode&WIN_NODRAW)
2465: is_redraw=0;
2466:
2467: gettext(1,1,api->scrn_width,api->scrn_len,tmp_buffer);
2468:
2469: if(!is_redraw) {
2470: memset(tmp_buffer2,' ',width*height*2);
2471: for(i=1;i<width*height*2;i+=2)
2472: tmp_buffer2[i]=(api->hclr|(api->bclr<<4));
2473: tmp_buffer2[0]='�';
2474: j=title_len;
2475: if(j>width-6) {
2476: *(title+width-6)=0;
2477: j=width-6;
2478: }
2479: for(i=2;i<(width-j);i+=2)
2480: tmp_buffer2[i]='�';
2481: if(api->mode&UIFC_MOUSE && !mode&WIN_DYN) {
2482: tmp_buffer2[2]='[';
2483: tmp_buffer2[3]=api->hclr|(api->bclr<<4);
2484: /* tmp_buffer2[4]='�'; */
2485: tmp_buffer2[4]=0xfe;
2486: tmp_buffer2[5]=api->lclr|(api->bclr<<4);
2487: tmp_buffer2[6]=']';
2488: tmp_buffer2[7]=api->hclr|(api->bclr<<4);
2489: /* Buttons are ignored - leave it this way to not confuse stuff from help() */
2490: }
2491: tmp_buffer2[i]='�'; i+=4;
2492: for(p=title;*p;p++) {
2493: tmp_buffer2[i]=*p;
2494: i+=2;
2495: }
2496: i+=2;
2497: tmp_buffer2[i]='�'; i+=2;
2498: for(j=i;j<((width-1)*2);j+=2)
2499: tmp_buffer2[j]='�';
2500: i=j;
2501: tmp_buffer2[i]='�'; i+=2;
2502: j=i; /* leave i alone */
2503: for(k=0;k<(height-2);k++) { /* the sides of the box */
2504: tmp_buffer2[j]='�'; j+=2;
2505: j+=((width-2)*2);
2506: tmp_buffer2[j]='�'; j+=2;
2507: }
2508: tmp_buffer2[j]='�'; j+=2;
2509: if(!(mode&WIN_DYN) && (width>31)) {
2510: for(k=j;k<j+(((width-4)/2-13)*2);k+=2)
2511: tmp_buffer2[k]='�';
2512: tmp_buffer2[k]='�'; k+=4;
2513: tmp_buffer2[k]='H'; k+=2;
2514: tmp_buffer2[k]='i'; k+=2;
2515: tmp_buffer2[k]='t'; k+=4;
2516: tmp_buffer2[k]='a'; k+=2;
2517: tmp_buffer2[k]='n'; k+=2;
2518: tmp_buffer2[k]='y'; k+=4;
2519: tmp_buffer2[k]='k'; k+=2;
2520: tmp_buffer2[k]='e'; k+=2;
2521: tmp_buffer2[k]='y'; k+=4;
2522: tmp_buffer2[k]='t'; k+=2;
2523: tmp_buffer2[k]='o'; k+=4;
2524: tmp_buffer2[k]='c'; k+=2;
2525: tmp_buffer2[k]='o'; k+=2;
2526: tmp_buffer2[k]='n'; k+=2;
2527: tmp_buffer2[k]='t'; k+=2;
2528: tmp_buffer2[k]='i'; k+=2;
2529: tmp_buffer2[k]='n'; k+=2;
2530: tmp_buffer2[k]='u'; k+=2;
2531: tmp_buffer2[k]='e'; k+=4;
2532: tmp_buffer2[k]='�'; k+=2;
2533: for(j=k;j<k+(((width-4)/2-12)*2);j+=2)
2534: tmp_buffer2[j]='�';
2535: }
2536: else {
2537: for(k=j;k<j+((width-2)*2);k+=2)
2538: tmp_buffer2[k]='�';
2539: j=k;
2540: }
2541: tmp_buffer2[j]='�';
2542: puttext(left,top+1,left+width-1,top+height,tmp_buffer2);
2543: }
2544: len=strlen(hbuf);
2545:
2546: lines=0;
2547: k=0;
2548: for(j=0;j<len;j++) {
2549: if(mode&WIN_HLP && (hbuf[j]==2 || hbuf[j]=='~' || hbuf[j]==1 || hbuf[j]=='`'))
2550: continue;
2551: if(hbuf[j]==CR)
2552: continue;
2553: k++;
2554: if((hbuf[j]==LF) || (k>=width-2-pad-pad && (hbuf[j+1]!='\n' && hbuf[j+1]!='\r'))) {
2555: k=0;
2556: lines++;
2557: }
2558: }
2559: if(k)
2560: lines++;
2561: if(lines < height-2-pad-pad)
2562: lines=height-2-pad-pad;
2563:
2564: if((textbuf=(char *)malloc((width-2-pad-pad)*lines*2))==NULL) {
2565: cprintf("UIFC line %d: error allocating %u bytes\r\n"
2566: ,__LINE__,(width-2-pad-pad)*lines*2);
2567: _setcursortype(cursor);
2568: return;
2569: }
2570: memset(textbuf,' ',(width-2-pad-pad)*lines*2);
2571: for(i=1;i<(width-2-pad-pad)*lines*2;i+=2)
2572: textbuf[i]=(api->hclr|(api->bclr<<4));
2573:
2574: i=0;
2575:
2576: for(j=i;j<len;j++,i+=2) {
2577: if(hbuf[j]==LF) {
2578: i+=2;
2579: while(i%((width-2-pad-pad)*2)) i++; i-=2;
2580: }
2581: else if(mode&WIN_HLP && (hbuf[j]==2 || hbuf[j]=='~')) { /* Ctrl-b toggles inverse */
2582: inverse=!inverse;
2583: i-=2;
2584: }
2585: else if(mode&WIN_HLP && (hbuf[j]==1 || hbuf[j]=='`')) { /* Ctrl-a toggles high intensity */
2586: high=!high;
2587: i-=2;
2588: }
2589: else if(hbuf[j]!=CR) {
2590: textbuf[i]=hbuf[j];
2591: textbuf[i+1]=inverse ? (api->bclr|(api->cclr<<4))
2592: : high ? (api->hclr|(api->bclr<<4)) : (api->lclr|(api->bclr<<4));
1.1.1.2 ! root 2593: if(((i+2)%((width-2-pad-pad)*2)==0 && (hbuf[j+1]==LF)) || (hbuf[j+1]==CR && hbuf[j+2]==LF))
1.1 root 2594: i-=2;
2595: }
2596: else
2597: i-=2;
2598: }
2599: i=0;
2600: p=textbuf;
2601: if(mode&WIN_DYN) {
2602: puttext(left+1+pad,top+2+pad,left+width-2-pad,top+height-1-pad,p);
2603: }
2604: else {
2605: while(i==0) {
2606: if(p!=oldp) {
2607: if(p > textbuf+(lines-(height-2-pad-pad))*(width-2-pad-pad)*2)
2608: p=textbuf+(lines-(height-2-pad-pad))*(width-2-pad-pad)*2;
2609: if(p<textbuf)
2610: p=textbuf;
2611: if(p!=oldp) {
2612: puttext(left+1+pad,top+2+pad,left+width-2-pad,top+height-1-pad,p);
2613: oldp=p;
2614: }
2615: }
2616: if(kbwait()) {
2617: j=inkey();
2618: if(j==CIO_KEY_MOUSE) {
2619: /* Ignores return value to avoid hitting help/exit hotspots */
2620: if(uifc_getmouse(&mevnt)>=0) {
2621: /* Clicked Scroll Up */
2622: if(mevnt.startx>=left+pad
2623: && mevnt.startx<=left+pad+width-3
2624: && mevnt.starty>=top+pad+1
2625: && mevnt.starty<=top+pad+(height/2)-2
2626: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
2627: p = p-((width-2-pad-pad)*2*(height-5));
2628: continue;
2629: }
2630: /* Clicked Scroll Down */
2631: else if(mevnt.startx>=left+pad
2632: && mevnt.startx<=left+pad+width
2633: && mevnt.starty<=top+pad+height-2
2634: && mevnt.starty>=top+pad+height-(height/2+1)-2
2635: && mevnt.event==CIOLIB_BUTTON_1_CLICK) {
2636: p=p+(width-2-pad-pad)*2*(height-5);
2637: continue;
2638: }
1.1.1.2 ! root 2639: /* Non-click events (drag, move, multiclick, etc) */
! 2640: else if(mevnt.event!=CIOLIB_BUTTON_CLICK(CIOLIB_BUTTON_NUMBER(mevnt.event)))
! 2641: continue;
1.1 root 2642: i=1;
2643: }
2644: continue;
2645: }
2646: switch(j) {
2647: case CIO_KEY_HOME: /* home */
2648: p=textbuf;
2649: break;
2650:
2651: case CIO_KEY_UP: /* up arrow */
2652: p = p-((width-2-pad-pad)*2);
2653: break;
2654:
2655: case CIO_KEY_PPAGE: /* PgUp */
2656: p = p-((width-2-pad-pad)*2*(height-5));
2657: break;
2658:
2659: case CIO_KEY_NPAGE: /* PgDn */
2660: p=p+(width-2-pad-pad)*2*(height-5);
2661: break;
2662:
2663: case CIO_KEY_END: /* end */
2664: p=textbuf+(lines-height+1)*(width-2-pad-pad)*2;
2665: break;
2666:
2667: case CIO_KEY_DOWN: /* dn arrow */
2668: p = p+((width-2-pad-pad)*2);
2669: break;
2670:
2671: default:
2672: i=1;
2673: }
2674: }
2675: mswait(1);
2676: }
2677:
2678: puttext(1,1,api->scrn_width,api->scrn_len,tmp_buffer);
2679: }
2680: free(textbuf);
2681: if(is_redraw) /* Force redraw of menu also. */
2682: reset_dynamic();
2683: _setcursortype(cursor);
2684: }
2685:
2686: /************************************************************/
2687: /* Help (F1) key function. Uses helpbuf as the help input. */
2688: /************************************************************/
2689: static void help(void)
2690: {
2691: char hbuf[HELPBUF_SIZE],str[256];
2692: char *p;
2693: unsigned short line; /* This must be 16-bits */
2694: long l;
2695: FILE *fp;
2696:
2697: if(api->helpbuf==NULL && api->helpixbfile[0]==0)
2698: return;
2699:
2700: _setcursortype(_NOCURSOR);
2701:
2702: if(api->helpbuf!=NULL)
2703: strcpy(hbuf,api->helpbuf);
2704: else {
2705: if((fp=fopen(api->helpixbfile,"rb"))==NULL) {
2706: sprintf(hbuf,"\2 ERROR \2 Cannot open help index:\r\n %s"
2707: ,api->helpixbfile);
2708: }
2709: else {
2710: p=strrchr(helpfile,'/');
2711: if(p==NULL)
2712: p=strrchr(helpfile,'\\');
2713: if(p==NULL)
2714: p=helpfile;
2715: else
2716: p++;
2717: l=-1L;
2718: while(!feof(fp)) {
2719: if(!fread(str,12,1,fp))
2720: break;
2721: str[12]=0;
2722: fread(&line,sizeof(line),1,fp);
2723: if(stricmp(str,p) || line!=helpline) {
2724: fseek(fp,sizeof(l),SEEK_CUR);
2725: continue;
2726: }
2727: fread(&l,sizeof(l),1,fp);
2728: break;
2729: }
2730: fclose(fp);
2731: if(l==-1L)
2732: sprintf(hbuf,"\2 ERROR \2 Cannot locate help key (%s:%u) in:\r\n"
2733: " %s",p,helpline,api->helpixbfile);
2734: else {
2735: if((fp=fopen(api->helpdatfile,"rb"))==NULL)
2736: sprintf(hbuf,"\2 ERROR \2 Cannot open help file:\r\n %s"
2737: ,api->helpdatfile);
2738: else {
2739: fseek(fp,l,SEEK_SET);
2740: fread(hbuf,HELPBUF_SIZE,1,fp);
2741: fclose(fp);
2742: }
2743: }
2744: }
2745: }
2746:
2747: showbuf(WIN_MID|WIN_HLP, 0, 0, 76, api->scrn_len, "Online Help", hbuf, NULL, NULL);
2748: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.