/***************************************************************************
 *                                                                         *
 *   WGSLANG.C                                                             *
 *                                                                         *
 *   Copyright (c) 1993-1997 Galacticomm, Inc.      All Rights Reserved.   *
 *                                                                         *
 *   This is the offline utility to create, delete, or export languages.   *
 *                                                                         *
 *                                  - C. Robert and R. Stein  12/17/92     *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "excphand.h"

#define FILREV "$Revision: 9 $"

#define   NMSCNS    4              /* number of screen files linked in     */

extern CHAR scntbl[][GVIDSCNSIZ]; /* array of screens (c/o MAKESCNS)*/

static CHAR dosscn[GVIDSCNSIZ],    /* saved DOS screen image               */
            savscn[GVIDSCNSIZ],    /* generic saved screen image           */
            hlpsav[GVIDSCNSIZ];    /* saved screen image while being helped*/

#define   LNGLEN    (LNGSIZ+LNGDSC+10)  /* length of our lingo names/descs */

static CHAR **lingos;              /* array of lingos (w/ descriptions)    */

#define   YNOSIZ    4              /* stg size for storing yes/no answers  */
#define   OURPSZ    30             /* our path size (for export)           */
#define   MDFSIZ    13             /* .MDF file name size                  */

                                   /* non-standard returns from our choose */
#define   ADDONE    -10            /* add a new language now               */
#define   ALLDUN    -11            /* all done (exit utility now)          */

INT done=0;                        /* all done (exit utility now?) 1 or 0  */

static VOID bldlst(VOID);
static INT lngnum(CHAR *name);
static INT ourcho(INT n,CHAR **chcs,INT upx,INT upy,INT lox,INT loy,INT mainm);
static VOID addlng(VOID);
static VOID dellng(INT num);
static VOID explng(INT num);
static INT samspk(CHAR *spok);
static INT samprt(CHAR *prot);
static GBOOL valfil(INT c,CHAR *stg);
static GBOOL valpth(INT c,CHAR *stg);
static GBOOL valnam(INT c,CHAR *stg);
static GBOOL valdsc(INT c,CHAR *stg);
static GBOOL valext(INT c,CHAR *stg);
static GBOOL valedt(INT c,CHAR *stg);
static GBOOL valyno(INT c,CHAR *stg);
static GBOOL valmdf(INT c,CHAR *stg);
static VOID gethlp(INT add);
static VOID lowadd(struct lingo *lngptr,CHAR *filnam);
static VOID lowdel(INT num,CHAR *files);
static VOID setsal(INT lnum);
static VOID lowexp(INT num,CHAR *files,CHAR *path);
static VOID wrapup(VOID);

INT
main(                              /* main program loop                    */
INT argc,
CHAR *argv[])
{
TRY
     INT i,sel;
     static CHAR *chclst[2]={" Remove .MSG file text for this language ",
                             " Export .MSG file text for this language "};

     (VOID)argc;
#ifdef GCWINNT
     if (!canRunUtil()) {
          MessageBox(NULL,NOPROCEED,
                    argv[0],MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
          return(1);
     }
#else
     (VOID)argv;
#endif // GCWINNT
     initvid();
     scn2mem(dosscn,0,GVIDSCNSIZ);
     monorcol();
     for (i=0 ; i < NMSCNS ; i++) {
          cvtscn(scntbl[i]);
     }
     inilingo();
     inimsgrdr(16384);
     bldlst();
     explode(scntbl[0],4,7,75,21);
     proff(0,0);
     scn2mem(savscn,0,GVIDSCNSIZ);
     do {
          selatr=0x70;
          nslatr=0x1E;
          switch (sel=ourcho(nlingo,lingos,5,14,74,20,1)) {
          case ADDONE:
               addlng();
               break;
          case ALLDUN:
               done=1;
               break;
          default:
               scn2mem(hlpsav,0,GVIDSCNSIZ);
               explodeto(scntbl[3],37,0,79,3,19,11);
               proff(0,0);
               selatr=0x70;
               nslatr=0x2E;
               switch (ourcho(2,chclst,20,12,60,13,0)) {
               case 0:
                    mem2scn(hlpsav,0,GVIDSCNSIZ);
                    dellng(sel);
                    break;
               case 1:
                    mem2scn(hlpsav,0,GVIDSCNSIZ);
                    explng(sel);
                    break;
               }
               break;
          }
          mem2scn(savscn,0,GVIDSCNSIZ);
     } while (!done);
     wrapup();
     return(0);
EXCEPT
#ifdef GCWINNT
     return(1);
#endif // GCWINNT
}

static VOID
bldlst(VOID)                       /* build the in-memory lingos list      */
{
     INT i;

     lingos=(CHAR **)alczer(nlingo*sizeof(CHAR *));
     for (i=0 ; i < nlingo ; i++) {
          lingos[i]=alcmem(LNGLEN);
          sprintf(lingos[i]," %-15s  %s",languages[i]->name,languages[i]->desc);
     }
}

static INT
lngnum(name)                       /* get lingo number based on a name     */
CHAR *name;                             /* language name to get number for */
{
     INT i;

     for (i=0 ; i < nlingo ; i++) {
          if (sameas(languages[i]->name,name)) {
               return(i);
          }
     }
     return(-1);
}

static INT
ourcho(n,chcs,upx,upy,lox,loy,mainm) /* our form of the choose() routine   */
INT n;                                  /* number of choices offered user  */
CHAR *chcs[];                           /* text of choices offered to user */
INT upx,upy;                            /* upper-left x and y coordinates  */
INT lox,loy;                            /* lower-right x and y coordinates */
INT mainm;                              /* are we at the main menu? (0-2)  */
{
     INT c,retval;

     supchc(n,chcs,upx,upy,lox,loy,TRUE);
     dspchc();
     cursiz(GVIDNOCURS);
     do {
          if (((c=getchc()) == ALT_H || c == F1) && mainm) {
               gethlp(0);
               retval=n;
          }
          else if (c == ESC || (mainm && c == ALT_X)) {
               retval=ALLDUN;
          }
          else if (mainm && c == ALT_N) {
               retval=ADDONE;
          }
          else {
               retval=hdlchc(c);
          }
     } while (retval == n);
     rstcur();
     return(retval);
}

static VOID
addlng(VOID)                       /* add a language                       */
{
     INT tmp;
     static struct lingo newlng;
     CHAR spok[LNGSIZ],prot[LNGSIZ],mdfnam[MDFSIZ],*ptr,yno[YNOSIZ];

     setmem(&newlng,sizeof(struct lingo),0);
     explode(scntbl[1],4,7,75,21);
     proff(0,0);
     while (1) {
          if (!edtval(23,14,LNGSIZ,newlng.name,valnam,0) ||
              strlen(newlng.name) < 1) {
               return;
          }
          if (lngnum(newlng.name) == -1) {
               break;
          }
          scn2mem(hlpsav,0,GVIDSCNSIZ);
          explodeto(scntbl[1],0,22,46,24,27,11);
          proff(0,0);
          getchc();
          mem2scn(hlpsav,0,GVIDSCNSIZ);
     }
     strcpy(spok,newlng.name);
     if ((ptr=strchr(spok,'/')) != NULL) {
          *ptr='\0';
          strcpy(prot,&ptr[1]);
     }
     else {
          prot[0]='\0';
     }
     if ((tmp=samspk(spok)) != -1) {
          strcpy(newlng.yes,languages[tmp]->yes);
          strcpy(newlng.no,languages[tmp]->no);
     }
     if ((tmp=samprt(prot)) != -1) {
          strcpy(newlng.extans,languages[tmp]->extans);
          strcpy(newlng.extasc,languages[tmp]->extasc);
          strcpy(newlng.extibm,languages[tmp]->extibm);
          strcpy(newlng.editor,languages[tmp]->editor);
     }
     else {
          strcpy(newlng.extans,".");
          strcpy(newlng.extasc,".");
          strcpy(newlng.extibm,".");
          strcpy(newlng.editor,languages[0]->editor);
     }
     if (!edtval(23,15,LNGDSC,newlng.desc,valdsc,0) ||
         strlen(newlng.desc) < 1) {
          return;
     }
     if (sameas(prot,DFTPRT)) {
          locate(25,16);
          setatr(0x1E);
          printf("IBM with ANSI: ");
          setatr(0x1F);
          printf(".");
          locate(48,16);
          setatr(0x1E);
          printf("ANSI: ");
          setatr(0x1F);
          printf(".");
          locate(62,16);
          setatr(0x1E);
          printf("ASCII: ");
          setatr(0x1F);
          printf(".");
          if (!edtval(41,16,LNGEXT-1,&newlng.extibm[1],valext,
                needupc() ? ALLCAPS : 0)) {
               return;
          }
          if (!edtval(55,16,LNGEXT-1,&newlng.extans[1],valext,
                needupc() ? ALLCAPS : 0)) {
               return;
          }
          if (!edtval(70,16,LNGEXT-1,&newlng.extasc[1],valext,
                needupc() ? ALLCAPS : 0)) {
               return;
          }
     }
     else {
          locate(23,16);
          setatr(0x1F);
          printf(".");
          if (!edtval(24,16,LNGEXT-1,&newlng.extans[1],valext,
                needupc() ? ALLCAPS : 0)) {
               return;
          }
          strcpy(newlng.extasc,newlng.extans);
          strcpy(newlng.extibm,newlng.extans);
     }
     if (!edtval(23,17,LNGEDT,newlng.editor,valedt,0)) {
          return;
     }
     if (newlng.editor[0] == '\0') {
          strcpy(newlng.editor,languages[0]->editor);
     }
     do {
          if (!edtval(30,18,LNGYN,newlng.yes,valyno,0)) {
               return;
          }
     } while (newlng.yes[0] == '\0');
     do {
          if (!edtval(48,18,LNGYN,newlng.no,valyno,0)) {
               return;
          }
     } while (newlng.no[0] == '\0');
     while (1) {
          setmem(mdfnam,MDFSIZ,0);
          do {
               if (!edtval(23,20,MDFSIZ-4,mdfnam,valmdf,
                  needupc() ? ALLCAPS : 0)) {
                    return;
               }
          } while (mdfnam[0] == '\0');
          strcat(mdfnam,".mdf");
          cntdir(mdfnam);
          if (numfils == 0L) {
               break;
          }
          scn2mem(hlpsav,0,GVIDSCNSIZ);
          explodeto(scntbl[2],0,0,42,2,17,13);
          proff(0,0);
          strcpy(yno,"No");
          if (edtval(55,14,YNOSIZ,yno,validyn,MCHOICE) &&
              toupper(yno[0]) == 'Y') {
               mem2scn(hlpsav,0,GVIDSCNSIZ);
               break;
          }
          mem2scn(hlpsav,0,GVIDSCNSIZ);
     }
     explodeto(scntbl[0],0,22,31,24,25,9);
     proff(0,0);
     strcpy(yno,"Yes");
     if (edtval(52,10,YNOSIZ,yno,validyn,MCHOICE) && toupper(yno[0]) == 'Y') {
          lowadd(&newlng,mdfnam);
          done=1;
     }
}

static VOID
dellng(num)                        /* delete a language                    */
INT num;                                /* language number to delete       */
{
     CHAR filnam[OURPSZ];

     if (num == 0) {
          cursiz(GVIDNOCURS);
          explodeto(scntbl[0],0,0,40,2,21,9);
          proff(0,0);
          getchc();
          return;
     }
     explodeto(scntbl[2],46,0,79,8,23,8);
     proff(0,0);
     setmem(filnam,OURPSZ,0);
     if (!edtval(39,15,13,filnam,valfil,needupc() ? ALLCAPS : 0)
      || strlen(filnam) < 1) {
          return;
     }
     if (strchr(filnam,'.') == NULL) {
          strcat(filnam,".msg");
     }
     explodeto(scntbl[0],10,3,39,5,25,11);
     proff(0,0);
     cursiz(GVIDNOCURS);
     lowdel(num,filnam);
     done=1;
}

static VOID
explng(num)                        /* export a language                    */
INT num;                           /* language number to export            */
{
     CHAR c,expfil[OURPSZ],expath[OURPSZ];

     scn2mem(hlpsav,0,GVIDSCNSIZ);
     explodeto(scntbl[3],0,0,36,7,21,9);
     proff(0,0);
     setmem(expfil,OURPSZ,0);
     if (!edtval(42,15,13,expfil,valfil,needupc() ? ALLCAPS : 0)
      || strlen(expfil) < 1) {
          return;
     }
     if (strchr(expfil,'.') == NULL) {
          strcat(expfil,".msg");
     }
     mem2scn(hlpsav,0,GVIDSCNSIZ);
     setmem(expath,OURPSZ,0);
     explodeto(scntbl[1],0,3,67,5,6,10);
     proff(0,0);
     if (edtval(43,11,OURPSZ,expath,valpth,needupc() ? ALLCAPS : 0)
      && strlen(expath) > 0) {
          if ((c=expath[strlen(expath)-1]) != SL && c != ':') {
               strncat(expath,SLS,OURPSZ-1);
          }
          mem2scn(hlpsav,0,GVIDSCNSIZ);
          explodeto(scntbl[0],42,0,72,2,25,9);
          proff(0,0);
          cursiz(GVIDNOCURS);
          lowexp(num,expfil,expath);
          done=1;
     }
     mem2scn(hlpsav,0,GVIDSCNSIZ);
}

static INT
samspk(spok)                       /* return a language with the same spok */
CHAR *spok;                        /* spoken language to find match 4      */
{
     INT i;
     CHAR spoken[LNGSIZ],*ptr;

     for (i=0 ; i < nlingo ; i++) {
          strcpy(spoken,languages[i]->name);
          if ((ptr=strchr(spoken,'/')) != NULL) {
               *ptr='\0';
               if (sameas(spoken,spok)) {
                    return(i);
               }
          }
     }
     return(-1);
}

static INT
samprt(prot)                       /* return a language with the same prot */
CHAR *prot;                        /* protocol to find a match for         */
{
     INT i;
     CHAR protocol[LNGSIZ],*ptr;

     for (i=0 ; i < nlingo ; i++) {
          strcpy(protocol,languages[i]->name);
          if ((ptr=strchr(protocol,'/')) != NULL) {
               strcpy(protocol,&ptr[1]);
               if (sameas(protocol,prot)) {
                    return(i);
               }
          }
     }
     return(-1);
}

static GBOOL
valfil(                            /* edtval() validation routine for paths*/
INT c,                             /*   character entered                  */
CHAR *stg)                         /*   string entered so far              */
{
     return(c == '*' || c == '?' || isfiln(c,stg));
}

static GBOOL
valpth(                            /* edtval() validation routine for paths*/
INT c,                             /*   character entered                  */
CHAR *stg)                         /*   string entered so far              */
{
     CHAR *cp,tmpstr[OURPSZ];

     unpad(strcpy(tmpstr,stg));
     if (*tmpstr == '\0') {
          return(isalpha(c));
     }
     *(cp=tmpstr+strlen(tmpstr))=c;
     *++cp='\0';
     return(isvaldn(tmpstr));
}

static GBOOL
valnam(                            /* edtval() validation routine for names*/
INT c,                             /*   character entered                  */
CHAR *stg)                         /*   string entered so far              */
{
     (VOID)stg;
     if (c == ALT_H || c == F1) {
          gethlp(1);
          return(FALSE);
     }
     return((' ' <= c && c <= 255) ? TRUE : FALSE);
}

static GBOOL
valdsc(                            /* edtval() validation routine for descs*/
INT c,                             /* character entered                    */
CHAR *stg)                         /* string entered so far                */
{
     (VOID)stg;                    /* get rid of blasted compiler warning  */
     if (c == ALT_H || c == F1) {
          gethlp(1);
          return(FALSE);
     }
     return((' ' <= c && c <= 255) ? TRUE : FALSE);
}

static GBOOL
valext(                            /* edtval() validation routine for exts */
INT c,                             /* character entered                    */
CHAR *stg)                         /* string entered so far                */
{
     if (c == ALT_H || c == F1) {
          gethlp(1);
          return(FALSE);
     }
     return((c != '.' && c != SL && isfiln(c,stg)) ? TRUE : FALSE);
}

static GBOOL
valedt(                            /* edtval() validation routine for edts */
INT c,                             /* character entered                    */
CHAR *stg)                         /* string entered so far                */
{
     (VOID)stg;                    /* get rid of blasted compiler warning  */
     if (c == ALT_H || c == F1) {
          gethlp(1);
          return(FALSE);
     }
     return((c < 255 && isprint(c)) ? TRUE : FALSE);
}

static GBOOL
valyno(                            /* edtval() validation routine for yesno*/
INT c,                             /* character entered                    */
CHAR *stg)                         /* string entered so far                */
{
     (VOID)stg;                    /* get rid of blasted compiler warning  */
     if (c == ALT_H || c == F1) {
          gethlp(1);
          return(FALSE);
     }
     return((' ' <= c && c <= 255) ? TRUE : FALSE);
}

static GBOOL
valmdf(                            /* edtval() validation routine for MDFs */
INT c,                             /* character entered                    */
CHAR *stg)                         /* string entered so far                */
{
     if (c == ALT_H || c == F1) {
          gethlp(1);
          return(FALSE);
     }
     return((c != '.' && c != SL && isfiln(c,stg)) ? TRUE : FALSE);
}

static VOID
gethlp(add)                        /* get help screen                      */
INT add;                           /* help with adding lang? (1 or 0)      */
{
     scn2mem(hlpsav,0,GVIDSCNSIZ);
     proff(0,0);
     cursiz(GVIDNOCURS);
     if (add) {
          explodeto(scntbl[2],8,10,79,24,4,7);
     }
     else {
          explodeto(scntbl[3],8,10,79,24,4,7);
     }
     proff(0,0);
     getchc();
     rstcur();
     mem2scn(hlpsav,0,GVIDSCNSIZ);
}

static VOID
lowadd(lngptr,filnam)              /* add a new language (low level)       */
struct lingo *lngptr;              /* language structure to add            */
CHAR *filnam;                      /* .MDF file name to save to            */
{
     FILE *fp;

     cursiz(GVIDNOCURS);
     if ((fp=fopen(filnam,FOPWA)) != NULL) {
          fprintf(fp,"; %s (language file created by WGSLANG.EXE)\n\n",filnam);
          fprintf(fp,"Module Name: %s language\n\n",lngptr->name);
          fprintf(fp,"Developer: Sysop\n\n");
          fprintf(fp,"Internal\n\n");
          fprintf(fp,"Language: %s\n",lngptr->name);
          fprintf(fp,"Language Description: %s\n",lngptr->desc);
          fprintf(fp,"Language File Extension: %s,%s,%s\n",lngptr->extans,
                  lngptr->extasc,lngptr->extibm);
          fprintf(fp,"Language Editor: %s\n",lngptr->editor);
          fprintf(fp,"Language Yes/No: %s/%s\n",lngptr->yes,lngptr->no);
          fclose(fp);
          explodeto(scntbl[2],0,3,45,9,17,9);
          proff(0,0);
          setatr(0x2E);
          locate(19,13);
          printf("%s file directly with an ASCII",filnam);
          getchc();
     }
     else {
          catastro("CAN'T OPEN \"%s\" FOR WRITING!",filnam);
     }
}

static VOID
lowdel(num,files)                  /* delete a language (low-level)        */
INT num;                           /* language number to delete            */
CHAR *files;                       /* file(s) to delete from               */
{
     LONG fpos;
     INT i,lnum;
     FILE *outfp;
     struct ffblk fb;

     if (!fnd1st(&fb,files,0)) {
          return;
     }
     do {
          if ((rdfp=fopen(fb.ff_name,FOPRB)) == NULL) {
               catastro("CAN'T OPEN \"%s\" FOR READING!",fb.ff_name);
          }
          if ((outfp=fopen("BBSTMP.$$$",FOPWB)) == NULL) {
               catastro("CAN'T OPEN \"BBSTMP.$$$\" FOR WRITING!");
          }
          if (setvbuf(outfp,NULL,_IOFBF,16384) != 0) {
               catastro("Cannot set output buffer for BBSTMP.$$$");
          }
          lnum=-1;
          while (rdmsg()) {
               scanalt();
               litopts();
               fprintf(outfp,"%s"STR_EOL"%s {",hlpbuf,msgnam);
               putval(outfp);
               fprintf(outfp,"}");
               fpos=ftell(rdfp);
               setsal(lnum);
               for (i=1 ; i < salingo ; i++) {
                    if (altlnm[i].value.ptr != NULL) {
                         loadtv(rdfp,&altlnm[i]);
                         if (lnum == -1 && sameas(msgnam,"LANGUAGE") &&
                              sameas(txtbuf,languages[num]->name)) {
                              setsal(lnum=i);
                         }
                         else if (i != lnum) {
                              fprintf(outfp,",{");
                              putval(outfp);
                              fprintf(outfp,"}");
                         }
                    }
                    else if (i != lnum) {
                         fprintf(outfp,",");
                    }
               }
               fseek(rdfp,fpos,0);
               fprintf(outfp,"%s"STR_EOL STR_EOL,lobuf);
          }
          fclose(rdfp);
          fclose(outfp);
          unlink(fb.ff_name);
          rename("BBSTMP.$$$",fb.ff_name);
     } while (fndnxt(&fb));
}

static VOID
setsal(lnum)                       /* set salingo based upon deleted lang  */
INT lnum;                          /* language number being deleted        */
{
     INT i;

     if (lnum == salingo-1) {
          for (i=salingo-2 ; i >= 0 ; i--) {
               if (altlnm[i].value.ptr != NULL) {
                    break;
               }
          }
          salingo=i+1;
     }
}

static VOID
lowexp(num,files,path)             /* export a language (low level)        */
INT num;                           /* language number to export            */
CHAR *files;                       /* file(s) to export                    */
CHAR *path;                        /* path to export to                    */
{
     LONG fpos;
     FILE *outfp;
     INT i,lfnd,lnum;
     struct ffblk fb;
     CHAR *ptr,outfil[OURPSZ+20];

     if (!fnd1st(&fb,files,0)) {
          return;
     }
     do {
          if ((rdfp=fopen(fb.ff_name,FOPRB)) == NULL) {
               catastro("CAN'T OPEN \"%s\" FOR READING!",fb.ff_name);
          }
          strcpy(outfil,path);
          strncat(outfil,fb.ff_name,OURPSZ+19);
          if ((ptr=strchr(outfil,'.')) != NULL) {
               *ptr='\0';
          }
          strncat(outfil,".mlx",OURPSZ+19);
          if ((outfp=fopen(outfil,FOPWB)) == NULL) {
               fclose(rdfp);
               cursiz(GVIDNOCURS);
               explodeto(scntbl[0],41,22,75,24,23,9);
               getchc();
               return;
          }
          if (setvbuf(outfp,NULL,_IOFBF,16384) != 0) {
               catastro("Cannot set output buffer for BBSTMP.$$$");
          }
          lfnd=0;
          lnum=-1;
          while (rdmsg()) {
               scanalt();
               litopts();
               if (!lfnd) {
                    if (sameas(msgnam,"LANGUAGE")) {
                         for (i=salingo-1 ; i >= 0 ; i--) {
                              if (altlnm[i].value.ptr != NULL) {
                                   loadtv(rdfp,&altlnm[i]);
                                   if (sameas(txtbuf,languages[num]->name)) {
                                        fprintf(outfp,STR_EOL"LANGUAGE {");
                                        fprintf(outfp,"%s}"STR_EOL STR_EOL,
                              txtbuf);
                                        break;
                                   }
                              }
                         }
                         lnum=i;
                    }
                    else {
                         if (sameas(DFTLNG,languages[num]->name)) {
                              fprintf(outfp,STR_EOL"LANGUAGE {");
                              fprintf(outfp,"%s}"STR_EOL STR_EOL,DFTLNG);
                              lnum=0;
                         }
                    }
                    lfnd=1;
               }
               if (lotype() == 'T') {
                    fpos=ftell(rdfp);
                    for (i=0 ; i < salingo ; i++) {
                         if (altlnm[i].value.ptr != NULL) {
                              if (i == lnum) {
                                   if (i != 0) {
                                        loadtv(rdfp,&altlnm[i]);
                                   }
                                   fprintf(outfp,STR_EOL"%s {",msgnam);
                                   putval(outfp);
                                   fprintf(outfp,"}%s"STR_EOL STR_EOL,lobuf);
                                   break;
                              }
                         }
                    }
                    fseek(rdfp,fpos,0);
               }
          }
          fclose(rdfp);
          fclose(outfp);
          if (lnum == -1) {
               unlink(outfil);
          }
     } while (fndnxt(&fb));
}

static VOID
wrapup(VOID)                       /* wrap things up before exiting        */
{
     setatr(0x07);
     printf(" ");
     locate(0,24);
     mem2scn(dosscn,0,GVIDSCNSIZ);
     cursiz(GVIDLILCURS);
     clsvid();
}
