
/****************************************************************************/

/*  Module PNLKVALC.C 

    Copyright 1986 Roundhill Computer Systems Limited
    All rights reserved

    Use and disclosure of this code are prohibited unless in accordance
    with the terms of the PANEL software licence.

    ************************************************************************
    *** THE OBJECT CODE VERSION OF THIS MODULE IS INCLUDED IN THE PANEL  ***
    *** LIBRARY.  IF YOU AMEND AND COMPILE THIS MODULE AND LINK IT WITH  ***
    *** YOUR APPLICATION IT WILL SUPERSEDE THE LIBRARY VERSION.          ***
    ************************************************************************

    PANEL:  Type 4          : Key Validation
            Source Language : C

    Modification History (Push-Down List):  

            11.02.86        : Use null to repeat last message
            25.01.86        : Use PASCAN instead of sscanf
            27.12.85        : Convert to table-driven operation

******************************************************************************/

#define VALKARG 1
#include <pnl4.h>

uint  PVKARG;               /* converted arg for key validation */

extern int PASCRO;
extern int PAMLN;
extern panfcb PAMFCB;
static panfcb HFCB =    /* FCB for help messages */
  {'\0','\0','\120','\1',' ','\0',0,0,'\0','\0','\204','\1',
   PANULL,'\0','\0',PANULL,'\0','\0','\0','\0',
   'H','E','L','P','M','S','G','E'}; 

static panfcb BFCB =    /* FCB for help boxes */
  {'\0','\0','\1','\1',' ','\177',bord,0,'\0','\0','\1','\1',
   PANULL,'\0','\0',PANULL,'\0','\0','\0','\0',
   'H','E','L','P','B','O','X',' '}; 

static panxa BFCBXA;

extern int (*PAKVTB[])();   /* key validation function table */
extern int PAKVPM;          /* max index into function table */
int PASCAN();               /* PASCAN(n, &i). gets numeric arg from PAXASP[n],
                               places result in i, returns 1 if success */

/*****************************************************************************/

int PAKVAL(kp)

/*    Calling conventions:
    
      On entry, 
            - PACRF is the FCB of the field being input
            - *kp is the value returned from PAGETF, with least significant
              byte indicating the key function as follows:
    
              0: char inp    7: down        14: query    21-29: PF6-14
              1: cr          8: erase eol   15: home
              2: esc         9: ins char    16: PF1
              3: bs         10: del char    17: PF2
              4: left       11: ins line    18: PF3
              5: right      12: del line    19: PF4
              6: up         13: tab         20: PF5
                            
      On exit, 
            - no change should be made to PACRF
            - the field's data area may be altered with care
            - the keyboard code *kp may be altered 
            - the PAKVAL return code will be interpreted as follows:
    
               0:  Function is valid
               1:  Function is invalid for the field, beep it            
               2:  Function is to be ignored

******************************************************************************/

uint *kp;

{
int i,tmp, tmpl;
static int help = 0;
uchar *malloc();
int cv;

PVKARG = *kp & 0xff;

/*****************************************************************************/

/*  Process Help Message extended attribute.  This routine assumes that xa 
    number NXAHM, when present, will contain a message of first-level help 
    for the field.  If not, the NXAHB xa if present is used to provide a
    'help box'.  Any key removes the help message.

******************************************************************************/

if (help)           /* already a help message displayed */
    {                   /* so restore it as soon as another key depressed */
    switch (help) {
    case 1: PAMSGE(PANULL);         /* repeat last message */
            break;
    case 2: PANELF(funsh,&BFCB);    /* lift off help box */
            break; }
    help = 0;
    PARSTC();           /* restore cursor */
    }

if (PVKARG == 14)       /* help/query key depressed */
    {                   /* so do we have any help ? */
#ifdef AMIGA
    if ( (PACRF.xa != PANULL) && (PACRF.xa->xbits & (1 << NXAHS)) )
        {
        PANARR(PACRF.xa->xattr[NXAHS]); /* Say it using Narrator device */
        }
#endif
    if ( (PACRF.xa != PANULL) && (PACRF.xa->xbits & (1 << NXAHM)) )
        {
        HFCB.hightype = PAMFCB.hightype;        /* use same hl as messages */
        HFCB.datablock = PACRF.xa->xattr[NXAHM];/* use string for display */
        HFCB.sl = HFCB.datawidth = strlen(PACRF.xa->xattr[0]);  /* & length */
        HFCB.sy = PAMLN;    /* use standard message line */
        PASBAD(0,PAMLN);    /* go to it */
        PAHIOF();           /* in case EEOL writes spaces on this system */
        PAHTYP(0);          /* set off highlighting */
        PAFUNC(4);          /* erase to end of line */
        PANELF(2,&HFCB);    /* display message */
        help = 1;           /* indicate help message displayed and level */
        PARSTC();           /* restore cursor */
        return(1);          /* beep user to draw attention to message */
        }
    else if ( (PACRF.xa != PANULL) && (PACRF.xa->xbits & (1 << NXAHB)) )
        {
        PAXASC(PACRF.xa->xattr[NXAHB]);
        if (PAXASN < 3) return(0);      /* need x, y, min one string */
        if (1 != PASCAN(0,&tmp)) return 0;
        BFCB.sx = tmp;
        if (1 != PASCAN(1,&tmp)) return 0;
        BFCB.sy = tmp;
        BFCB.hightype = PAMFCB.hightype;        /* use same hl as messages */
        BFCB.sh = PAXASN - 2;
        tmp = 0;
        for (i = 2; i < PAXASN; i++)    /* find longest line */
            if ( (tmpl = strlen(PAXASP[i])) > tmp) tmp = tmpl;
        BFCB.sl = tmp;
        BFCB.datawidth = BFCB.sl;
        BFCB.dataheight = BFCB.sh;
        tmpl = UCI(BFCB.dataheight);        /* simplify to avoid MWC error */
        tmpl *= UCI(BFCB.datawidth);
        BFCB.datablock = malloc(tmpl);      /* make data area */
        if (BFCB.datablock == PANULL) return(0);
        PABF(BFCB.datablock,tmpl,' ');  /* clear to blank */
        for (i = 2; i < PAXASN; i++)
            {
            tmp = UCI(BFCB.datawidth) * (i - 2);
            PABM(PAXASP[i],BFCB.datablock+tmp,strlen(PAXASP[i]));
            }
        BFCB.xa = &BFCBXA;
        BFCBXA.xbits = 1 << NXABD;
        BFCBXA.xattr[NXABD] = "//// Help ///";
        PANELF(2,&BFCB);    /* display box */
        help = 2;           /* indicate help message displayed and level */
        PARSTC();           /* restore cursor */
        return(1);          /* beep user to draw attention to message */
        }
    }

/*****************************************************************************/

/*  Remaining processing is based on the char val number  

    If the validation number is higher than the table maximum, use the default

******************************************************************************/

cv = UCI(PACRF.charvaln);
return (*PAKVTB[(cv>PAKVPM)?0:cv])();  
}           /* end pakval */
