/************** START OF SOURCE FILE HEADER ****************************/
/*                                                                     */
/*  SOURCE FILE NAME: NLPOPUP.C                                        */
/*                                                                     */
/*  COPYRIGHT: (c) IBM Corp. 1989                                      */
/*                                                                     */
/*  FUNCTION: The NLPOPUP.C program is the source file of the BiDi     */
/*            PopUp. The BiDi PopUp is invoked by the user when        */
/*            pressing the Alt+Scroll Lock key combination to view     */
/*            and update the screen, keyboard and printers attributes  */
/*                                                                     */
/*  NOTE:                                                              */
/*                                                                     */
/*  ENTRY POINT:                                                       */
/*               NLPOPUP          - this is the main control loop      */
/*                                  which gives control to the         */
/*                                  appropriate functions.             */
/*               GetKbdAndLptAtts - gets the attributes of the current */
/*                                  session and the printers.          */
/*               StartPopUp       - saves the attributes of the popup  */
/*                                  session and puts its own default   */
/*                                  attributes.                        */
/*               GetMainChoice    - gets which choice the user wants,  */
/*                                  keyboard, printers or hot keys.    */
/*               ProcessExitPanel - gets the input from the user and   */
/*                                  calls the SaveChanges if the user  */
/*                                  wants to save.                     */
/*               KbdPg1           - processes the input from user in   */
/*                                  the first Keyboard Video page.     */
/*               KbdPg2           - processes the input from user in   */
/*                                  the second Keyboard Video page.    */
/*               GetLptChoice     - gets which printer the user wants  */
/*                                  to update or gets the orientation  */
/*                                  of the three printers in case of   */
/*                                  the 862 code page.                 */
/*               LptPg1           - processes the input in the first   */
/*                                  printer page                       */
/*               LptPg2           - processes the input in the second  */
/*                                  printer page                       */
/*               WrtLptNo         - Writes the printer number on the   */
/*                                  printer panel.                     */
/*               HotKeysPg1       - processes the input from the user  */
/*                                  in the first hot keys panel.       */
/*               HotKeysPg2       - processes the input from the user  */
/*                                  in the second hot keys panel.      */
/*               SaveChanges      - checks if any changes were done    */
/*                                  and saves any changes.             */
/*               DrawBiDiPanel    - decides which panel to display.    */
/*               DrawPanel        - displays the panels.               */
/*               ProcessHelpPanel - decides which help panel to display*/
/*               ProcessErrorMsg  - displays a message if the message  */
/*               PanelMenu        - handles the movement in the panel. */
/*               ChangeAttr       - changes the colors of a string.    */
/*               FixArrow         - displays solid squares and arrows. */
/*               SetBit           - sets the value of a bit in a word. */
/*               GetBit           - gets the value of a bit from a word*/
/*                                  file is either incomplete or not   */
/*                                  found.                             */
/*                                                                     */
/*  EXTERNAL ROUTINES USED:                                            */
/*                                                                     */
/*               NlsIntQueryBidiAtt()                                  */
/*               NlsIntSetBidiAtt()                                    */
/*               DosGetMessage()                                       */
/*               DosGetInfoSeg()                                       */
/*               DosBeep()                                             */
/*               DosGetCp()                                            */
/*               VioPopUp()                                            */
/*               VioEndPopUp()                                         */
/*               VioGetConfig()                                        */
/*               VioWrtCharStrAtt()                                    */
/*               VioWrtNAttr()                                         */
/*               VioWrtCharStrAtt()                                    */
/*               VioScrollUp()                                         */
/*                                                                     */
/************************ END OF SOURCE FILE HEADER ********************/

#define INCL_BASE
#include <os2.h>
#include "bidiapi.h"
#include "sq.h"

#define CURS_UP       72            /* Scan Code Definitions used for key */
#define CURS_DOWN     80            /* detection                          */
#define CURS_LEFT     75
#define CURS_RIGHT    77
#define ENTER        224
#define RETURN        28
#define ESC            1
#define SPACE_BAR     57
#define PG_UP         73
#define PG_DOWN       81
#define F1            59            /* F1 key for Help          */
#define F2            60            /* F2 key for ChgLang       */
#define F3            61            /* F3 key for Save and Exit */
#define F7            65            /* F7 key for backward      */
#define F8            66            /* F8 key for forward       */

#define ARABIC_CP       864
#define HEBREW_CP1      862
#define HEBREW_CP2      856

#define KBV_CB_LEN      16          /* the actual length of the KBVCB  */
#define LPT_CB_LEN      6           /* the actual length of the PRCB   */
#define BD_VER_ID       16          /* the BiDi version ID             */
                                    /* Non Bidi session attributes     */
#define PASSTHRU        1           /* No shapping is done             */
#define NUMERIC_PASSTHRU   16       /* Numeral shapes, Arabic numerics */
                                    /* changed from 17 to 16 due to    */
                                    /* symetric swap value change      */
                                    /* 20/11/90                        */
#define ORIENT_LTR      0           /* Screen orientation is LtR       */
#define RESERVED_BD_ATT 48
#define HOT_KEYS_DISABLE 0xFFFF     /* All Bidi hot keys are disabled      */
#define WINDOW_COLOR    0x31        /* The color of the window is blue     */
                                    /* over Cyan                           */
#define HILIGHT_COLOR        0x3E   /* The color of the hilighted option   */
                                    /* is yellow over Cyan                 */
#define SCROLL_BAR           0x1B   /* The color of the scroll bar is Cyan */
                                    /* over blue                           */
#define FUNCTION_AREA        0X30   /* The function keys area is black over*/
                                    /* Cyan                                */
#define HELP_WINDOW          0x1B   /* The color of the help panel is Cyan */
                                    /* over blue                           */
#define HELP_FUNCTION        0x1F   /* The color of the function keys area */
                                    /* is white over blue                  */
#define MONO_WINDOW_COLOR    0x07   /* The color of the window is white    */
                                    /* over black                          */
#define MONO_HILIGHT_COLOR   0x0F   /* The color of the hilighted option   */
                                    /* is intinsified white over black     */
#define MONO_SCROLL_BAR      0x7F   /* The color of the scroll bar is white*/
                                    /* over gray                           */
#define MONO_FUNCTION_AREA   0X07   /* The function keys area is white over*/
                                    /* black                               */
#define MONO_HELP_WINDOW     0x07   /* The color of the help panel is white*/
                                    /* over black                          */
#define MONO_HELP_FUNCTION   0x07   /* The color of the function keys area */
                                    /* is white over black                 */
#define NORMAL          0           /* Normal panels */
#define HELP            1           /* Help Panels */
#define PANEL_WIDTH     45
#define ENGLISH_PANEL  0            /* The panel language */
#define NATIONAL_PANEL 1


/*******************************************************************/
/*              Global Declarations                                */
/*******************************************************************/
/* Note on terminology :                                           */
/*                                                                 */
/*  "Choice" is used to refer to a BiDi attribute displayed on any */
/* panel. "Value" is used to refer to the actual setting of the    */
/* attribute.                                                      */
/*                                                                 */
/* Example :                                                       */
/*      Choice --> AutoPush            ON  <-- Value               */
/*                                     OFF <-- Value               */
/*                                                                 */
/*******************************************************************/

                                      /* Structure for specifying information*/
                                      /* about the layout of one choice on a */
                                      /* panel                               */

struct PanelInfoType {ULONG MaxValue; /* The last valid value this choice  */
                                      /* can take : e.g. MaxValue = 1 if  */
                                      /* the choice can take values in the*/
                                      /* range 0..1.                      */

                      ULONG Value;    /* The current value of this choice */

                      ULONG Row;      /* The row on which this choice is  */
                                      /* displayed, counting from the top */
                                      /* of the panel.                    */
                     };

struct BiDiAttTyp      {              /* Bidirectional Attributes Structure */
                          BYTE CSD;
                          BYTE NumShapes;
                          BYTE Orientation;
                          BYTE Reserved;
                        };

struct KbdVioCtrlBlkTyp {          /* Keyboard Video Control Block Structure */
                          int  Length;
                          int  BDVerID;
            struct BiDiAttTyp  BiDiAtt;
                          BYTE Res[4];
                        USHORT HotKeys;
                          int  ScrInfo;
                        };

struct LptInfoTyp       {             /* Printer Control Block Structure */
                          int  Length;
            struct BiDiAttTyp  BiDiAtt;
                        };

                                      /* Array to store info about all the */
                                      /* choices on a panel. The maximum   */
                                      /* number of choices on any panel is 8 */
typedef struct PanelInfoType PanelArray[8];

                                      /* Array to store the arrows for */
                                      /* English and Arabic panels     */
static  char *ArrowArray[2] = {"",""};

static  int  IncArray[2] = {-2,2};    /* Array to store the distance between */
                                      /* the start of the highlighted area   */
                                      /* and the arrows for the English and  */
                                      /* Arabic panels                       */

PanelArray PanelInfo;                 /* Declaration of array of structures */
                                      /* used to define the layout of each  */
                                      /* panel.                             */

void ProcessExitPanel(void);          /* Proto Types  Declaration */
void GetLptChoice(void);
void HotKeysPg1(void);
void HotKeysPg2(void);
void LptPg1(ULONG);
void LptPg2(ULONG);
void GetMainChoice(void);
void KbdPg1(void);
void KbdPg2(void);
void PanelMenu(PanelArray,ULONG,ULONG,ULONG,ULONG,USHORT *);
void ChangeAttr(BYTE,ULONG,ULONG,ULONG);
void DrawPanel(ULONG,ULONG);
ULONG  StartPopup(void);
void FixArrow(ULONG,ULONG,ULONG,ULONG);
void SetBit(ULONG,ULONG,ULONG *);
ULONG GetBit(ULONG,ULONG);
void GetKbdAndLptAtts(void);
void ProcessHelpPanel(ULONG,ULONG,ULONG,ULONG);
void DrawBiDiPanel(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
void SaveChanges(void);
void ProcessErrorMsg(void);
void WrtLptNo(ULONG);

                                      /* End of Proto Types  Declaration */

int F7Enable,F8Enable;                /* Flags used by PanelMenu() to     */
                                      /* enable/disable the use of the F7 */
                                      /* and F8 keys. These must be set   */
                                      /* for each panel depending on the  */
                                      /* required active keys.            */

ULONG  RowInc,       /* Number of rows between each value and the next    */
       ColInc,       /* Number of columns between each value and the next.*/
                     /* does have a value in case of the hot keys panels  */
       StartCol,     /* Starting column of the highlighted area           */
       NoOfChoices;  /* Number of choices, starting from 0. (i.e. 0..N)   */

USHORT ActionKey;    /* Character returned by PanelMenu */

                     /* Language of the panel            */
ULONG  Lang;         /* 0 = English, 1 = National        */
ULONG  ValLen;       /* The length which will be high-   */
                     /* lighted in English and national  */
                     /* languages                        */

                     /* variables used by DosGetCp()     */
USHORT  length = 6;
USHORT  CodePage;    /* A flag to indicate which panels  */
                     /* are to be displayed to the user  */
USHORT  PreparedCP[3];
USHORT  ListLength;

                     /* The position of the scroll bar  */
ULONG BarPos,        /* The choice which the bar is on  */
      BarVal;        /* The specific value of the above */
                     /* choice which is highlighted.    */
/********************************************************************/
/*  Example of how BarPos and BarVal are calculated.                */
/*                                                                  */
/*                                            BarPos       BarVal   */
/*     Numeral Shapes     þ Passthru            0            0      */
/*                        þ Hindu                            1      */
/*     Character Shape                                              */
/*       Determination    þ Automatic           1            0      */
/*                        þ Base Shapes                      1      */
/*                        þ Initial Shapes                   2      */
/*                        þ Middle Shapes                    3      */
/*                        þ Final Shapes                     4      */
/*                        þ Isolated Shapes                  5      */
/*                        þ Passthru                         6      */
/*                                                                  */
/*   BIDI PopUp           þ Enable  þ Disable   0            0 1    */
/*   Arabic Layer         þ Enable  þ Disable   1            0 1    */
/*   English Layer        þ Enable  þ Disable   2            0 1    */
/*   Screen Reverse       þ Enable  þ Disable   3            0 1    */
/*   Field Reverse        þ Enable  þ Disable   4            0 1    */
/*   Push                 þ Enable  þ Disable   5            0 1    */
/*   End Push             þ Enable  þ Disable   6            0 1    */
/*   Auto Push            þ Enable  þ Disable   7            0 1    */
/*                                                                  */
/********************************************************************/

int OldColumn,               /* Used to save the scroll bar was on which    */
    OldBarPos,               /* column when F1 or F2 were pressed           */

    ColumnFlag,              /* Used to say that the hot keys panels were   */
                             /* exited by F1 or F2                          */
    F3Flag,                  /* Flag to tell that F3 was pressed            */
    difference,              /* Flag to indicate if any changes where made  */
                             /* before ending the PopUp                     */
    ChangeLang;              /* This flag is set if the default language has*/
                             /* changed                                     */
ULONG  ReturnCode = NULL;    /* A global return code for the functions      */
                             /* called, initialized to NULL                 */

static char *ptrarray[] = {"\0"}; /* Arrays for use in DosGetMsg usage */
char   msg[50];

                                  /* Flag for the VioPopUp */
USHORT  len,WaitFlag = VP_WAIT | VP_TRANSPARENT;

ULONG AttributeChoice;       /* Indicates which attributes are to be set  */
                             /* i.e. kbd, printer or hotkeys              */
ULONG PrinterChoice;         /* Indicates which printer attributes are to */
                             /* be set                                    */

                             /* Declaration of internal indicators of     */
                             /* current settings                          */

                             /* Screen and Keyboard                 */
ULONG  ScrOrientation,       /* Screen orientation, LtR or RtL      */
       Language,             /* Language layer, English or National */
       AutoPush,             /* Auto push , on or off               */
       NumShape,             /* Numeric shapes, Arabic or Hindu     */
       CharShape;            /* Character shape, (On, isolated,.... */

                             /* The following array is used to translate  */
                             /* from CSD values to position on the screen */
                             /* and vice verca.                           */
static ULONG  ScrToCsd[] = {0,16,17,18,19,20,1};
static ULONG  CsdToScr[] = {0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5};

                             /* The following array is used to             */
                             /* translate from Hot keys values to position */
                             /* on the screen and vice verca.              */
static ULONG  HotToScr[] = {9,6,5,2,3,4};

                             /* The non Bidi contents of the Keyboard Video */
                             /* Control Block to set the PopUp session      */
                             /* attributes                                  */
struct  KbdVioCtrlBlkTyp DefaultPopUp;
                             /* Structure to hold the actual PopUp session  */
                             /* attributes                                  */
struct  KbdVioCtrlBlkTyp OriginalPopUp;

                             /* Arrays to hold the attributes of the printers */
ULONG  LptOrientation[3],LptNumShapes[3];
ULONG  LptCharShape[3];

                             /* Arrays to hold the values of the hot Keys */
ULONG HotKeys1[8];           /* an array containing all the hot keys */
                             /* on the first hot key panel           */

ULONG HotKeys2[5];           /* an array containing all the hot keys */
                             /* on the second hot key panel          */

int  Page;                   /* Which is the current displayed page */

KBDKEYINFO  kb;              /* Buffer for storing input characters */

PGINFOSEG  gdt;           /* Variables to get the current session ID */
SEL        sel,gdt_descriptor,ldt_descriptor;   /* infoseg descriptors   */
ULONG      Scope,         /* Hold the session ID */
           PopUpId;       /* Session ID of the PopUp session */

ULONG row,    /* The row at which the panel starts to be drawn    */
      col;    /* The column at which the panel starts to be drawn */
int EscFlag,  /* Flag to indicate if the escape key was pressed   */
    counter;  /* A dummy counter used by some of the functions    */

VIOCONFIGINFO VioConfig;      /* structure containing information */
                              /* on the display type              */
                              /* PopUp colors */
BYTE WindowColor;
BYTE HiLightColor;
BYTE ScrollBarColor;
BYTE FunctionAreaCo;
BYTE HelpWindowCo;
BYTE HelpFunctionCo;

                              /* Keyboard Video and Printer structure */
                              /* declaration                          */
struct  KbdVioCtrlBlkTyp  KbdVioCtrlBlk;
struct  LptInfoTyp        LptArray[3];

                              /* Keyboard Video and Printer structure        */
                              /* declaration to store the contents of the    */
                              /* control blocks before any changes and to    */
                              /* compare them later to the above two         */
                              /* structure to conclude if there were any     */
                              /* changes happened                            */
struct  KbdVioCtrlBlkTyp  OldKbdVioCtrlBlk;
struct  LptInfoTyp        OldLptArray[3];

int  quit;                   /* A global variable used to exit the     */
                             /* program if F3 pressed from any panel   */
                             /* or error occured from the message file */

                             /* End Global Declarations  */
/* ahmedt 27/1/91 */
BOOL Kbdpg1Flag = FALSE;
BYTE TempNum, TempCSD;       /* Temporary variables to store the CSD   */
                             /* and Num values while end of popup      */

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: NLPOPUP                                           */
/*                                                                     */
/*  DESCRIPTIVE NAME: Main control loop.                               */
/*                                                                     */
/*  FUNCTION: NLPOPUP manages navigation through the available panels  */
/*            It calls the appropriate panel handling functions        */
/*            and allows movement from one panel to another.           */
/*                                                                     */
/*  ENTRY POINT: NLPOPUP                                               */
/*      LINKAGE: CALL FAR (from BiDi Keyboard monitor).                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*                                                                     */
/*        WORD row             - Start row for the PopUp.              */
/*        WORD col             - Start column for the PopUp.           */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD quit            - Exit flag to leave the program        */
/*        WORD CodePage        - The code page (864/862).              */
/*        WORD Page            - The page number.                      */
/*        WORD ChangeLang      - Flag to indicate that panel language  */
/*                               has changed.                          */
/*        WORD ColumnFlag      - A flag to indicate if one of the hot  */
/*                               keys panels were exited by an F1 or   */
/*                               F2 key.                               */
/*       DWORD Scope           - The current session number.           */
/*       DWORD PopUpId         - The PopUp session number.             */
/*        WORD difference      - Indicates if any changes happened to  */
/*                               any of the control blocks.            */
/*        WORD ReturnCode      - Used by the called functions.         */
/*      STRUCT gdt             - structure of type PGINFOSEG.          */
/*        WORD gdt_descriptor  - Holds the segment selector.           */
/*        WORD ldt_descriptor  - Holds the segment selector.           */
/*        WORD AttributeChoice - Choose which device to view.          */
/*        WORD PrinterChoice   - Choose which printer to view.         */
/*      STRUCT KbdVioCtrlBlk - structure of the keyboard video control */
/*                             block.                                  */
/*      The structure of the control block is:                         */
/*             WORD Length  - Lenght of the control block.             */
/*             WORD BDVerID - BiDi version ID.                         */
/*           STRUCT BiDiAtt - BiDi attributes.                         */
/*             BYTE Res[4]  - Four bytes reserved.                     */
/*             WORD HotKeys - BiDi hot keys.                           */
/*             WORD ScrInfo - BiDi flags.                              */
/*                                                                     */
/*      The structure of the BiDi attributes:                          */
/*             BYTE  CSD         - Character Shape Determination values*/
/*             BYTE  NumShapes   - Numeral shapes.                     */
/*             BYTE  Orientation - Orientation of the screen.          */
/*             BYTE  Reserved    - A reserved byte containing 48.      */
/*      STRUCT OriginalPopUp  - A structure identical to the Keyboard  */
/*                              video control block.                   */
/*                                                                     */
/*     ROUTINES: GetKbdAndLptAtts  ()                                  */
/*               StartPopup()                                          */
/*               GetMainChoice()                                       */
/*               SaveChanges()                                         */
/*               ProcessExitPanel()                                    */
/*               KbdPg1()                                              */
/*               KbdPg2()                                              */
/*               GetLptChoice()                                        */
/*               LptPg1()                                              */
/*               LptPg2()                                              */
/*               HotKeysPg1()                                          */
/*               HotKeysPg2()                                          */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: DosGetInfoSeg()                                       */
/*               DosGetCp()                                            */
/*               VioGetConfig()                                        */
/*               VioEndPopUp()                                         */
/*               NlsIntSetBidiAtt()                                    */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
extern void far pascal _loadds NLPOPUP(void)
{
                             /* Initialize variables   */
   quit = 0;                 /* No error detected      */
   AttributeChoice=1;        /* Initialize the choices */
   PrinterChoice=1L;
   Page = 1;
   row = 0;                  /* row positon of the popup             */
   col = 34;                 /* column position of the popup         */
   ColumnFlag = 0;           /* initialize the bar position to zero  */
   F3Flag = 0;               /* initialize flag that detects if F3 pressed*/
   EscFlag= 0;               /* initialize flag that detects if Esc pressed*/
   ChangeLang = 0;           /* No change in the default language    */

                             /* Initialize the Default attributes structure */
   DefaultPopUp.Length = KBV_CB_LEN;
   DefaultPopUp.BDVerID = BD_VER_ID;
   DefaultPopUp.BiDiAtt.CSD = PASSTHRU;
   DefaultPopUp.BiDiAtt.NumShapes = NUMERIC_PASSTHRU;
   DefaultPopUp.BiDiAtt.Orientation = ORIENT_LTR;
   DefaultPopUp.BiDiAtt.Reserved = RESERVED_BD_ATT;
   for (counter = 0; counter < 4; counter++)
      DefaultPopUp.Res[counter] = NULL;
   DefaultPopUp.HotKeys = HOT_KEYS_DISABLE;
   DefaultPopUp.ScrInfo = NULL;

                            /* Get The current session number */
   DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor);
   gdt = MAKEPGINFOSEG(gdt_descriptor);   /* forground session ID */
   Scope = gdt->sgCurrent;

   GetKbdAndLptAtts();       /* Get the contents of the control blocks */
                             /* and put them in the variables used     */
                             /* within the program                     */

   ReturnCode=StartPopup();  /* Call VioPopUp, save the PopUp session  */
                             /* attributes and replace it by default   */
                             /* attributes                             */

   if (ReturnCode != 0) {      /* The VioPopup was unsuccessful  */
      DosExit(1,0);          /* exit the program.                     */
   }

/* Query the current code page, if it is not Hebrew code page then it */
/* is Arabic code page                                                */
   ReturnCode = DosGetCp (length,PreparedCP,&ListLength);

   if (PreparedCP[1] == ARABIC_CP || PreparedCP[2] == ARABIC_CP)
      CodePage = ARABIC_CP;
   else
      CodePage = PreparedCP[0];

/* Decide the colors of the panels according to the type of display */

   VioConfig.cb = sizeof(VioConfig);
   ReturnCode = VioGetConfig(0,&VioConfig,0);

   switch (VioConfig.display) {
   case 0: case 3:              /* monochrome display */
       WindowColor = MONO_WINDOW_COLOR;
       HiLightColor = MONO_HILIGHT_COLOR;
       ScrollBarColor = MONO_SCROLL_BAR;
       FunctionAreaCo = MONO_FUNCTION_AREA;
       HelpWindowCo = MONO_HELP_WINDOW;
       HelpFunctionCo = MONO_HELP_FUNCTION;
      break;
   default:
       WindowColor = WINDOW_COLOR;
       HiLightColor = HILIGHT_COLOR;
       ScrollBarColor = SCROLL_BAR;
       FunctionAreaCo = FUNCTION_AREA;
       HelpWindowCo = HELP_WINDOW;
       HelpFunctionCo = HELP_FUNCTION;
   } /* endswitch */

   /******************* Main Loop *******************/
 do{
                             /* Allow the user to choose which attributes */
                             /* to set.                                   */
   GetMainChoice();          /* Get user choice, keyboard, LPT, hot keys  */

                             /* Check for the escape flag and quit flag   */
   if (EscFlag == 1 && quit == 0) {
       F3Flag = 0;            /* Check only if something was modified   */
       SaveChanges();         /* if any changes where done then process */
                              /* the exit panel                         */
       if (difference != 0) { /* if changes were done */
          EscFlag = 0;        /* Clear the Esc flag   */
          ProcessExitPanel();
          }
      }
   else
     if (quit == 0)           /* no need to quit the program */
      {
                              /* Invoke the appropriate panel */
       switch((int)AttributeChoice)
       {
        case 1:
        /* Invoke the appropriate kbdpg() depending on the value of page  */
        /* and break if the Esc key is pressed                            */
            do{
               switch(Page)
                 {
                 case 1:
                   /* ahmedt 27/1/91 */
                   Kbdpg1Flag = TRUE;
                   KbdPg1();
                   Kbdpg1Flag = FALSE;
                   break;
                 case 2:
                   KbdPg2();              /* the second panel is specific    */
                                          /* for the Arabic code page        */
                   break;                 /* Go forward and backward between */
                 }                        /* pages until Esc is pressed      */
               } while(EscFlag!=1 && quit == 0);
               /* Reinitialize Page */
               Page = 1;
        break;

        case 2:
            /* Allow the user to specify which printer's attributes */
            /* will be set */
            do{
               GetLptChoice();        /* Which printer he wants to see */

               if(EscFlag!=1 && quit == 0) {
               /* Invoke the appropriate LptPg() depending on the value of */
               /* page and break if Esc key is pressed                     */
               /* Each LptPg() accepts the PrinterChoice as an arguement   */
               /* to tell it whether LPT1, LPT2 or LPT3 were chosen.       */

                   if (CodePage == ARABIC_CP) {
                      /* Hebrew code page has only one printer panel */
                   do {
                      switch (Page)
                      {
                      case 1:
                         LptPg1(PrinterChoice);
                      break;
                      case 2:
                         LptPg2(PrinterChoice);
                      break;
                      }
                     } while(EscFlag!=1 && quit == 0);
                   /* Reinitialize Page */
                   Page = 1;
                   } /* endif */
               EscFlag = 0;
              } /* endif */
            } while(EscFlag!=1 && quit == 0);
        break;

        case 3:
        /* Display the appropriate HotKeys panel depending on the */
        /* value of page and break if the ESC key is pressed      */
            do{
               if(Page==1)
                 HotKeysPg1();
               else
                 /* the second panel is specific for the Arabic code page */
                 HotKeysPg2();
               } while(EscFlag!=1 && quit == 0);
               /* Reinitialize Page */
               Page = 1;
         break;
       } /* End Switch */

   /* Reset EscFlag to loop again in the main loop */
       EscFlag=0;
   } /* endif */
 } while(EscFlag!=1 && quit == 0);

  if (F3Flag == 0 ){                     /* if end through the Exit panel    */
     VioEndPopUp(0);                /* End the PopUp to return to the     */
  } /* endif */

 /* Although no changes where done however if the panel language had   */
 /* changed then it must be saved                                      */
  if (ChangeLang == 1)
     ReturnCode = NlsIntSetBidiAtt(Scope,0L,(PSETINFO)&KbdVioCtrlBlk);

 } /** End of main control loop **/

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: GETKBDANDLPTATTS                                  */
/*                                                                     */
/*  DESCRIPTIVE NAME: Gets the contents on the control blocks.         */
/*                                                                     */
/*  FUNCTION: GetKbdAndLptAtts queries the screen and keyboard         */
/*            attributes and stores the information in the             */
/*            KbdVioCtrlBlk buffer. In the same manner, it initializes */
/*            the three Lpt buffers and the appropriate global         */
/*            variables to the current settings.                       */
/*            It also gives the appropriate global variables values to */
/*            indicate the current settings. It also saves the         */
/*            contents of the control blocks in temporary structures   */
/*            to be used at end of PopUp to decide if any changes were */
/*            done.                                                    */
/*                                                                     */
/*  ENTRY POINT: GetKbdAndLptAtts                                      */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC <-- 0                                              */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD LptCount    - Dummy counter for printers.               */
/*        WORD HotKeyCount - Dummy counter for the hot keys.           */
/*        WORD MemCount    - Dummy counter to copy the contents of     */
/*                           the control blocks.                       */
/*      @OTHER Source      - Pointer to a source string.               */
/*      @OTHER Target      - Pointer to a target string.               */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT KbdVioCtrlBlk - structure of the keyboard video control */
/*                             block.                                  */
/*      The structure of the control block is:                         */
/*             WORD Length  - Lenght of the control block.             */
/*             WORD BDVerID - BiDi version ID.                         */
/*           STRUCT BiDiAtt - BiDi attributes.                         */
/*             BYTE Res[4]  - Four bytes reserved.                     */
/*             WORD HotKeys - BiDi hot keys.                           */
/*             WORD ScrInfo - BiDi flags.                              */
/*                            (For more details, refer to appendix.)   */
/*                                                                     */
/*      The structure of the BiDi attributes:                          */
/*             BYTE  CSD         - Character Shape Determination values*/
/*             BYTE  NumShapes   - Numeral shapes.                     */
/*             BYTE  Orientation - Orientation of the screen.          */
/*             BYTE  Reserved    - A reserved byte containing 48.      */
/*                                                                     */
/*   STRUCT OldKbdVioCtrlBlk - structure like KbdVioCtrlBlk containing */
/*                             the original attributes of the current  */
/*                             session.                                */
/*      STRUCT OriginalPopUp - structure like KbdVioCtrlBlk containing */
/*                             the original attributes of the PopUp    */
/*                             session.                                */
/*      STRUCT LptArray[]    - Array of structures like the structure  */
/*                             of the printer control block.           */
/*      The contents of the printer structure:                         */
/*        WORD Length  - Length of the control block.                  */
/*      STRUCT BiDiAtt - The BiDi attributes.                          */
/*                                                                     */
/*      STRUCT OldLptArray[] - Array of structures like the structure  */
/*                             of the printer control block to save    */
/*                             the original printer control blocks.    */
/*        WORD Lang          - The current language panel.             */
/*        WORD Language      - The current language layer.             */
/*        WORD ScrOrientation- The screen orientation (LtR,RtL).       */
/*        WORD AutoPush      - The auto push (ON/OFF).                 */
/*        WORD NumShape      - The numeric shapes (Arabic,Hindu).      */
/*        WORD CharShape     - The character shapes (Auto, initial,..).*/
/* STATIC WORD CsdToScr[]    - A translation array to translate the    */
/*                             CSD value to a position on the screen.  */
/* STATIC WORD HotToScr[]    - A translation array to translate the hot*/
/*                             key values to a position on the screen  */
/*        WORD HotKeys1[]    - Array to contain the hot keys values.   */
/*        WORD HotKeys2[]    - Array to contain the hot keys values.   */
/*        WORD Lptorientation[]- Array containing the printers         */
/*                             orientation.                            */
/*        WORD LptNumShapes[]- Array containing the numeric shapes for */
/*                             the printers                            */
/*        WORD LptCharShape[]- Array containing the character shapes   */
/*                             of the printers.                        */
/*       DWORD Scope         - The ID of the current session.          */
/*       DWORD PopUpId       - The ID of the PopUp session.            */
/*        WORD ReturnCode    - Return code for the used functions.     */
/*                                                                     */
/*     ROUTINES: GetBit()                                              */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NlsIntQueryBidiAtt()                                  */
/*               VioPopUp()                                            */
/*               VioEndPopUp()                                         */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void GetKbdAndLptAtts()
{
ULONG LptCount;
  int HotKeyCount;
  int MemCount;
  int *Source, *Target;

/*  Get the content of the current keyboard video control block   */
KbdVioCtrlBlk.Length = KBV_CB_LEN;
ReturnCode = NlsIntQueryBidiAtt(Scope,0L,(PRETINFO)&KbdVioCtrlBlk);

 /* save the contents of the control block to be compared later before exit */

    Source = (int *)&KbdVioCtrlBlk;
    Target = (int *)&OldKbdVioCtrlBlk;
    for (MemCount = 0; MemCount < 8; MemCount++,Source++,Target++) {
        *Target = *Source;
    } /* endfor */

/*  Get the contents of the three printers control blocks      */
for( LptCount = 0; LptCount < 3; LptCount++)
   {
     LptArray[LptCount].Length = LPT_CB_LEN;
     ReturnCode = NlsIntQueryBidiAtt(0L,LptCount+1,
                                  (PRETINFO)&LptArray[LptCount]);
     LptArray[LptCount].BiDiAtt.Reserved = RESERVED_BD_ATT;
 /* save the contents of the control blocks to be compared later before exit */

    Source = (int *)&LptArray[LptCount];
    Target = (int *)&OldLptArray[LptCount];
    for (MemCount = 0; MemCount < 3; MemCount++,Source++,Target++) {
        *Target = *Source;
    } /* endfor */
   }

/* Set global variables according to information in KbdVioCtrlBlk   */

ScrOrientation  = KbdVioCtrlBlk.BiDiAtt.Orientation;
Language        = GetBit(4L,(ULONG)KbdVioCtrlBlk.ScrInfo);

Lang = GetBit(9L,(ULONG)KbdVioCtrlBlk.ScrInfo); /* Default panel language */

/* Position of AutoPush bit depend on screen orientation     */

AutoPush        = GetBit((ULONG)(!ScrOrientation),(ULONG)KbdVioCtrlBlk.ScrInfo);

NumShape        = GetBit(5L,(ULONG)KbdVioCtrlBlk.BiDiAtt.NumShapes);
/*       to make CharShape range between 0..6       */
CharShape        = CsdToScr[KbdVioCtrlBlk.BiDiAtt.CSD];

/*                    Set HotKeys            */

for (HotKeyCount = 0; HotKeyCount < 6; HotKeyCount++) {
    HotKeys1[HotKeyCount] = GetBit(HotToScr[HotKeyCount],
                                   (ULONG)KbdVioCtrlBlk.HotKeys);
} /* endfor */

for (HotKeyCount = 0; HotKeyCount < 5; HotKeyCount++) {
    HotKeys2[HotKeyCount] = GetBit((ULONG)(HotKeyCount+10),(ULONG)KbdVioCtrlBlk.HotKeys);
} /* endfor */

/*         Set global printer settings       */
for( LptCount = 0; LptCount < 3; LptCount++)
   {
   LptOrientation[LptCount]= LptArray[LptCount].BiDiAtt.Orientation;
   LptNumShapes[LptCount]  = GetBit(5L,(ULONG)LptArray[LptCount].BiDiAtt.NumShapes);
   /* to make LptCharShape range bet. 0..6  */
   LptCharShape[LptCount]  = CsdToScr[LptArray[LptCount].BiDiAtt.CSD];
   }
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: STARTPOPUP                                        */
/*                                                                     */
/*  DESCRIPTIVE NAME: Initialization for the PopUp.                    */
/*                                                                     */
/*  FUNCTION: Starts the Popup and gets the PopUp session ID. It saves */
/*            the BiDi attributes for this ID and replaces it by       */
/*            another default attributes.                              */
/*                                                                     */
/*  ENTRY POINT: StartPopup                                            */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC <-- 0                                              */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: The attributes of the PopUp session are changed.     */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        WORD gdt_descriptor - Holds the segment selector.            */
/*        WORD ldt_descriptor - Holds the segment selector.            */
/*      STRUCT gdt            - structure of type PGINFOSEG.           */
/*       DWORD PopUpId        - A double word to save the PopUp        */
/*                              session ID                             */
/*      @OTHER WaitFlag       - Used by the VioPopUp() call.           */
/*        WORD ReturnCode     - Return code for the used functions.    */
/*      STRUCT OriginalPopUp  - A structure identical to the Keyboard  */
/*                              video control block.                   */
/* STATIC STRUCT DefaultPopUp - A structure identical to the Keyboard  */
/*                              video control block containing a non   */
/*                              BiDi attributes.                       */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*               VioEndPopUp                                           */
/*               KbdCharIn()                                           */
/*               NlsIntQueryBidiAtt()                                  */
/*               NlsIntSetBidiAtt()                                    */
/*               DosGetInfoSeg()                                       */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
ULONG StartPopup(void)
{
  /* Start the popup */
   ReturnCode = VioPopUp( &WaitFlag, 0 );
   if (ReturnCode!=0) {          /* VioPopup unsuccessful, return */
      DosBeep(1200,100);         /* error and beep */
      return(ReturnCode);
   }
   VioSetCurPos(0,0,0);         /* position the cursor at the left corner */
   DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor);
   gdt = MAKEPGINFOSEG(gdt_descriptor);   /* foreground session ID */
   PopUpId = gdt->sgCurrent;
   OriginalPopUp.Length = KBV_CB_LEN;
   ReturnCode = NlsIntQueryBidiAtt(PopUpId,0L,(PRETINFO)&OriginalPopUp);
   ReturnCode = NlsIntSetBidiAtt(PopUpId,0L,(PSETINFO)&DefaultPopUp);
   return ReturnCode;
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: GETMAINCHOICE                                     */
/*                                                                     */
/*  DESCRIPTIVE NAME: Saves the new settings into the control blocks.  */
/*                                                                     */
/*  FUNCTION: Allows the user to choose between:                       */
/*            1. Setting screen and kbd attributes.                    */
/*            2. Setting printer attributes.                           */
/*            3. Enabling/Disabling BiDi hot keys.                     */
/*                                                                     */
/*  ENTRY POINT: GetMainChoice                                         */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC <-- 0                                              */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD F7Enable        - F7 enabled or disabled.               */
/*        WORD F8Enable        - F8 enabled or disabled.               */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD BarPos          - The position of the scroll bar.       */
/*        WORD BarVal          - The position of the highlighting.     */
/*        WORD RowInc          - Number of rows between each value.    */
/*        WORD ColInc          - Number of columns between each value. */
/*        WORD NoOfChoices     - Number of choices.                    */
/*        WORD CodePage        - The code page (864/862).              */
/*        WORD StartCol        - The start column of the text.         */
/*        CHAR ActionKey       - The pressed key which causes changing */
/*                               the panel.                            */
/*        WORD AttributeChoice - The choice that the user took.        */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void GetMainChoice()
{
 /*****    Initialize the array and variables for the panel menu *****/
  PanelInfo[0].Value = AttributeChoice-1;
  BarVal      = 0;
  RowInc      = 2;
  ColInc      = 0;
  NoOfChoices = 0; /* one choice */
  PanelInfo[0].MaxValue = 2; /*0..2*/
  PanelInfo[0].Row = 5;

   /* Disable F7 and F8 */
  F7Enable = 0;
  F8Enable = 0;
  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   if (CodePage == ARABIC_CP) {
      DrawBiDiPanel(6L,38L,38L,36L,0L,12L);
   } else {
      DrawBiDiPanel(6L,38L,38L,33L,52L,39L);
   } /* endif */

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
       PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(21L,49L,31L,44L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

     if (ActionKey==F3)
        SaveChanges();
  /* Set the value of AttributeChoice to the chosen option */
     AttributeChoice = PanelInfo[0].Value+1;
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: PROCESSEXITPANEL                                  */
/*                                                                     */
/*  DESCRIPTIVE NAME: Exit the PopUp.                                  */
/*                                                                     */
/*  FUNCTION: Allows the user to choose between saving and             */
/*            exiting, exiting without saving and resuming             */
/*            work through the panels.                                 */
/*                                                                     */
/*  ENTRY POINT: ProcessExitPanel                                      */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag       - Indicates if F3 was pressed.             */
/*        WORD F7Enable     - F7 enabled or disabled.                  */
/*        WORD F8Enable     - F8 enabled or disabled.                  */
/*        WORD EscFlag      - Esc Key pressed.                         */
/*        WORD BarPos       - The position of the scroll bar.          */
/*        WORD BarVal       - The position of the highlighting.        */
/*        WORD RowInc       - Number of rows between each value.       */
/*        WORD ColInc       - Number of columns between each value.    */
/*        WORD NoOfChoices  - Number of choices.                       */
/*        WORD CodePage     - The code page (864/862).                 */
/*        WORD StartCol     - The start column of the text.            */
/*        CHAR ActionKey    - The pressed key which causes changing    */
/*                            the panel.                               */
/*        WORD Page         - The page number.                         */
/*        WORD Lang         - The panel language.                      */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void ProcessExitPanel()
{
 /*****    Initialize the array and variables for the panel menu *****/
   BarVal = 0;
   RowInc      =  2;
   ColInc      =  0;
   StartCol    = 11;
   NoOfChoices =  0;  /*ie. one choice*/

   /*Initialize the array of structures*/

   PanelInfo[0].MaxValue =  2;   /* values = 0..2 */
   PanelInfo[0].Value     =  0;  /* default value = first value */
   PanelInfo[0].Row       =  5;  /* Starting row */

 /* Neither F7 or F8 are enabled */
   F7Enable  = 0;
   F8Enable  = 0;

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   if (CodePage == ARABIC_CP) {
      DrawBiDiPanel(11L,32L,23L,21L,8L,20L);
   } else {
      DrawBiDiPanel(11L,32L,27L,15L,53L,43L);
   } /* endif */

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
   PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(28L,51L,38L,48L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2)
          Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

   /* Check the key used to exit the panel */
   switch(ActionKey)
    {
     case F3:
     case ENTER:
     case RETURN:
          if (PanelInfo[0].Value==0) {   /* Save and exit option chosen */
             F3Flag = 1;
             SaveChanges();              /* Save all changes and return */
             }                           /* to keyboard monitor         */
          else
          if (PanelInfo[0].Value==1)     /* Exit without saving option  */
              EscFlag=1;                 /* Set Esc flag to exit        */
     break;
     case ESC:
        /* if Esc pressed, then PanelMenu sets the EscFlag. Reset it for */
        /* not to quit the popup                                         */
        EscFlag = 0;
        break;
    }/*End switch*/
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: KBDPG1                                            */
/*                                                                     */
/*  DESCRIPTIVE NAME: View and update the the contents of the panel.   */
/*                                                                     */
/*  FUNCTION: Allows the user to view and set the screen orientation,  */
/*            language and the auto push mode.                         */
/*                                                                     */
/*  ENTRY POINT: KbdPg1                                                */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD ChoiceCount - Dummy counter                             */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD F7Enable        - F7 enabled or disabled.               */
/*        WORD F8Enable        - F8 enabled or disabled.               */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD BarPos          - The position of the scroll bar.       */
/*        WORD BarVal          - The position of the highlighting.     */
/*        WORD RowInc          - Number of rows between each value.    */
/*        WORD ColInc          - Number of columns between each value. */
/*        WORD NoOfChoices     - Number of choices.                    */
/*        WORD CodePage        - The code page (864/862).              */
/*        WORD StartCol        - The start column of the text.         */
/*        CHAR ActionKey       - The pressed key which causes changing */
/*                               the panel.                            */
/*        WORD Page            - The page number.                      */
/*        WORD ValLen          - The longest highlighted value.        */
/*        WORD ScrOrientation  - The screen orientation.               */
/*        WORD Language        - The language layer.                   */
/*        WORD AutoPush        - The auto push mode.                   */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void KbdPg1()
{
 /*****    Initialize the array and variables for the panel menu *****/
   BarVal      = 0;
   RowInc=1;
   ColInc=0;
   StartCol = 33;
   NoOfChoices = 2;  /* ie. choices 0..2 */

   for (counter = 0; counter < 3; counter++) {
      PanelInfo[counter].MaxValue = 1;
      PanelInfo[counter].Row = 5 + 3*counter;
   } /* endfor */
   PanelInfo[0].Value = ScrOrientation;
   PanelInfo[1].Value = Language;
   PanelInfo[2].Value = !AutoPush;  /* Position of ON and OFF on the panel */

   if (CodePage == ARABIC_CP) {
      F7Enable = 0;  /* Disable F7 */
      F8Enable = 1;  /* Enable  F8 */
   } else {
   /* For Hebrew code page, there is only one panel */
      F7Enable = 0;  /* Disable F7 */
      F8Enable = 0;  /* Disable F8 */
   } /* endif */

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   if (CodePage == ARABIC_CP) {
      DrawBiDiPanel(33L,15L,7L,13L,1L,13L);
   } else {
      DrawBiDiPanel(33L,15L,7L,9L,9L,40L);
   } /* endif */

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
  PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(22L,29L,32L,45L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

  /* Check the character returned by the PanelMenu */
   if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey==F3))
    { /* Save the settings */
      ScrOrientation   = PanelInfo[0].Value;
      Language         = PanelInfo[1].Value;
      AutoPush         = !PanelInfo[2].Value;
   if (CodePage == ARABIC_CP)
      Page = 2;
   else
      EscFlag= 1;
   if (F3Flag == 1)
      SaveChanges();
    }/*if*/
 }

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: KBDPG2                                            */
/*                                                                     */
/*  DESCRIPTIVE NAME: View and updates the contents of the panel.      */
/*                                                                     */
/*  FUNCTION: Allows the user to view and set the numeral shapes and   */
/*            the character shapes.                                    */
/*                                                                     */
/*  ENTRY POINT: KbdPg2                                                */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD F7Enable        - F7 enabled or disabled.               */
/*        WORD F8Enable        - F8 enabled or disabled.               */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD BarPos          - The position of the scroll bar.       */
/*        WORD BarVal          - The position of the highlighting.     */
/*        WORD RowInc          - Number of rows between each value.    */
/*        WORD ColInc          - Number of columns between each value. */
/*        WORD NoOfChoices     - Number of choices.                    */
/*        WORD StartCol        - The start column of the text.         */
/*        CHAR ActionKey       - The pressed key which causes changing */
/*                               the panel.                            */
/*        WORD Page            - The page number.                      */
/*        WORD NumShape        - The numeral shape.                    */
/*        WORD CharShape       - The character shape.                  */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void KbdPg2()
{
 /*****    Initialize the array and variables for the panel menu *****/
  BarVal      = 0;
  RowInc=1;
  ColInc=0;
  NoOfChoices = 1;  /* ie. choices 0..1 */

  /* changed by ahmedt on 27/1/91 due to change in popup panels */
  if (Lang==ENGLISH_PANEL) {
    StartCol    = 27;
  } else {
    StartCol    = 31;
  } /* endif */

  PanelInfo[0].MaxValue = 1;
  PanelInfo[0].Value = NumShape;
  PanelInfo[0].Row = 5;

  PanelInfo[1].MaxValue = 6; /*0..7*/
  PanelInfo[1].Value = CharShape;
  PanelInfo[1].Row = 8;

  /* Enable the F7 and disable F8 keys */
  F7Enable = 1;
  F8Enable = 0;

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   /* changed by ahmedt on 27/1/91 due to change in popup panels */
   if (Lang==ENGLISH_PANEL) {
     StartCol    = 27;
   } else {
     StartCol    = 31;
   } /* endif */

   DrawBiDiPanel(27L,19L,15L,15L,2L,14L);

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
  PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
        ProcessHelpPanel(23L,33L,33L,33L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

  /* Check the character returned by the PanelMenu */
   if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey==F3))
   { /* Save the settings*/
     NumShape   = PanelInfo[0].Value;
     CharShape  = PanelInfo[1].Value;
     EscFlag= 1;
     if (F3Flag == 1) SaveChanges();
    }/*if*/
  }

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: GETLPTCHOICE                                      */
/*                                                                     */
/*  DESCRIPTIVE NAME: Gets the printer number or orientation.          */
/*                                                                     */
/*  FUNCTION: If the code page is Arabic, then it allows the user to   */
/*            choose which printer he wants to view or update its      */
/*            attributes. Otherwise the user can view and update the   */
/*            orientation of the printers.                             */
/*                                                                     */
/*  ENTRY POINT: GetLptChoice                                          */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD LptCount - Dumy counter.                                */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD F7Enable        - F7 enabled or disabled.               */
/*        WORD F8Enable        - F8 enabled or disabled.               */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD BarPos          - The position of the scroll bar.       */
/*        WORD BarVal          - The position of the highlighting.     */
/*        WORD RowInc          - Number of rows between each value.    */
/*        WORD ColInc          - Number of columns between each value. */
/*        WORD NoOfChoices     - Number of choices.                    */
/*        WORD CodePage        - The code page (864/862).              */
/*        WORD StartCol        - The start column of the text.         */
/*        CHAR ActionKey       - The pressed key which causes changing */
/*                               the panel.                            */
/*        WORD PrinterChoice   - The choice that the user took.        */
/*        WORD LptOrientation[]- Array containing the three printers   */
/*                               orientation.                          */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void GetLptChoice()
{
 /*****    Initialize the array and variables for the panel menu *****/
   BarVal      = 0;
   ColInc      = 0;

   if (CodePage == ARABIC_CP) {
      RowInc      = 2;
      StartCol    = 11;
      NoOfChoices = 0;

      PanelInfo[0].MaxValue = 2;
      PanelInfo[0].Value = PrinterChoice-1;
      PanelInfo[0].Row = 5;
   } else {
   /* Get the printers orientation */
      RowInc      = 1;
      StartCol    = 35;
      NoOfChoices = 2;

      for (counter = 0; counter < 3; counter++) {
         PanelInfo[counter].MaxValue = 1;
         PanelInfo[counter].Value = LptOrientation[counter];
         PanelInfo[counter].Row = 5 + 3*counter;
      } /* endfor */
   } /* endif */

   F7Enable = 0;   /* Neither F7 or F8 are enabled */
   F8Enable = 0;

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/
   if (CodePage == ARABIC_CP) {
      DrawBiDiPanel(11L,34L,5L,22L,3L,15L);
   } else {
      DrawBiDiPanel(35L,15L,3L,9L,10L,41L);
   } /* endif */

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
   PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(24L,30L,34L,46L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

  /* If code page is not Arabic then save orientation of the printers and */
  /* set the escape flag                                                  */
     if (CodePage != ARABIC_CP) {
        if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey == F3)) {
           for (counter = 0; counter < 3; counter++) {
              LptOrientation[counter] = (BYTE)PanelInfo[counter].Value;
           } /* endfor */
           EscFlag= 1;
         } /* endif */
      } /* endif */
     else
     if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey == F3))
        /* Set the new value of PrinterChoice */
        PrinterChoice = PanelInfo[0].Value+1;

     if (ActionKey==F3)
        SaveChanges();
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: LPTPG1                                            */
/*                                                                     */
/*  DESCRIPTIVE NAME: View and update the contents of the panel.       */
/*                                                                     */
/*  FUNCTION: Allows the user to view and set the printer orientation  */
/*            and the numeric shapes.                                  */
/*                                                                     */
/*  ENTRY POINT: LptPg1                                                */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: DWORD LptNo - The printer number.                           */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD F7Enable        - F7 enabled or disabled.               */
/*        WORD F8Enable        - F8 enabled or disabled.               */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD BarPos          - The position of the scroll bar.       */
/*        WORD BarVal          - The position of the highlighting.     */
/*        WORD RowInc          - Number of rows between each value.    */
/*        WORD ColInc          - Number of columns between each value. */
/*        WORD NoOfChoices     - Number of choices.                    */
/*        WORD StartCol        - The start column of the text.         */
/*        CHAR ActionKey       - The pressed key which causes changing */
/*                               the panel.                            */
/*        WORD Page            - The page number.                      */
/*        WORD LptOrientation[]- Array containing the three printers   */
/*                               orientation.                          */
/*        WORD LptNumShapes[]  - Array containing the three printers   */
/*                               numeral shapes.                       */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*               WrtLptNo()                                            */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void LptPg1(ULONG LptNo)
 {
 /*****    Initialize the array and variables for the panel menu *****/
   BarVal      = 0;
   RowInc      = 1;
   ColInc      = 0;
   StartCol    = 33;
   NoOfChoices = 1; /*0..1*/
   F7Enable    = 0; /*Disable F7*/
   F8Enable    = 1; /* Enable F8*/

   PanelInfo[0].MaxValue = 1;
   PanelInfo[0].Value = LptOrientation[LptNo-1];
   PanelInfo[0].Row = 5;

   PanelInfo[1].MaxValue = 1;
   PanelInfo[1].Value = LptNumShapes[LptNo-1];
   PanelInfo[1].Row = 8;


  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   DrawBiDiPanel(33L,16L,8L,13L,4L,16L);

   /* Write the number of the printer device on the panel */
   WrtLptNo(LptNo);

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
  PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(25L,25L,35L,35L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

  /* Check the character returned by the PanelMenu */
   if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey==F3))
   {

     /* Save the settings */
             LptOrientation[LptNo-1] = (BYTE)PanelInfo[0].Value;
             LptNumShapes[LptNo-1] = PanelInfo[1].Value;
             Page = 2; /* Adjust the page number */
             if (F3Flag == 1) SaveChanges();
    }/*if*/

 }

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: LPTPG2                                            */
/*                                                                     */
/*  DESCRIPTIVE NAME: View and update the contents of the panel.       */
/*                                                                     */
/*  FUNCTION: Allows the user to view and set the printer character    */
/*            shapes.                                                  */
/*                                                                     */
/*  ENTRY POINT: LptPg2                                                */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: DWORD LptNo - The printer number.                           */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag          - Indicates if F3 was pressed.          */
/*        WORD F7Enable        - F7 enabled or disabled.               */
/*        WORD F8Enable        - F8 enabled or disabled.               */
/*        WORD EscFlag         - Esc Key pressed.                      */
/*        WORD BarPos          - The position of the scroll bar.       */
/*        WORD BarVal          - The position of the highlighting.     */
/*        WORD RowInc          - Number of rows between each value.    */
/*        WORD ColInc          - Number of columns between each value. */
/*        WORD NoOfChoices     - Number of choices.                    */
/*        WORD StartCol        - The start column of the text.         */
/*        CHAR ActionKey       - The pressed key which causes changing */
/*                               the panel.                            */
/*        WORD Page            - The page number.                      */
/*        WORD LptCharShape[]  - Array containing the three printers   */
/*                               character shape.                      */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*               WrtLptNo()                                            */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void LptPg2(ULONG LptNo)
{
 /*****    Initialize the array and variables for the panel menu *****/
  BarVal      =  0;
  RowInc      =  1;
  ColInc      =  0;
  StartCol    = 27;
  NoOfChoices =  0;  /* ie. one choice */


  PanelInfo[0].MaxValue = 6; /* 0..7 */
  PanelInfo[0].Value = LptCharShape[LptNo-1];
  PanelInfo[0].Row = 6;

  F7Enable = 1;
  F8Enable = 0;

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   DrawBiDiPanel(27L,19L,15L,15L,5L,17L);

   /* Write the number of the printer device on the panel */
   WrtLptNo(LptNo);

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */
  PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(26L,26L,36L,36L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) Lang = !Lang;
  } while ( (ActionKey==F1) || (ActionKey==F2) );

  /* Check the character returned by the PanelMenu */
   if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey==F3))
      { /* Save the settings */
       LptCharShape[LptNo-1] = (BYTE)PanelInfo[0].Value;
       EscFlag= 1;
       Page = 1;
       if (F3Flag == 1) SaveChanges();
    }/*if*/
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: WRTLPTNO                                          */
/*                                                                     */
/*  DESCRIPTIVE NAME: Writes the printer number on the printer panel.  */
/*                                                                     */
/*  FUNCTION: Writes the printer number on the printer panel in the    */
/*            right language.                                          */
/*                                                                     */
/*  ENTRY POINT: WrtLptNo                                              */
/*      LINKAGE: CALL NEAR (from LptPg1, LptPg2).                      */
/*                                                                     */
/*  INPUT: DWORD LptNo - The printer number.                           */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        WORD CodePage    - The code page (864/862).                  */
/*        WORD Lang        - The panel language.                       */
/*        WORD row         - The row at which the PopUp is displayed.  */
/*        WORD col         - The column at which the PopUp is displayed*/
/*        BYTE WindowColor - The normal panel color.                   */
/*                                                                     */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void WrtLptNo(ULONG LptNo)
{
   switch ( (int)Lang ) {
   case ENGLISH_PANEL:

           switch((int)LptNo) {
             case 1:
                 VioWrtCharStrAtt("1",1, (USHORT)row + 1, (USHORT)col + 24, &WindowColor,0);
             break;
             case 2:
                  VioWrtCharStrAtt("2",1, (USHORT)row + 1, (USHORT)col + 24, &WindowColor,0);
             break;
             case 3:
                  VioWrtCharStrAtt("3",1, (USHORT)row + 1, (USHORT)col + 24, &WindowColor,0);
             break;
           }
   break;

   case NATIONAL_PANEL:
           switch((int)LptNo) {
             case 1:
                VioWrtCharStrAtt("õààäè™Ç",7, (USHORT)row+1, (USHORT)col+17, &WindowColor,0);
             break;
             case 2:
                VioWrtCharStrAtt("Éêæ¨ËäÇ",7, (USHORT)row+1, (USHORT)col+17, &WindowColor,0);
             break;
             case 3:
                VioWrtCharStrAtt("ÉËä¨ËäÇ",7, (USHORT)row+1, (USHORT)col+17, &WindowColor,0);
             break;
           }
   break;
  }
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: HOTKEYS1                                          */
/*                                                                     */
/*  DESCRIPTIVE NAME: View and update the panel contents.              */
/*                                                                     */
/*  FUNCTION: Allows the user to view and set the BiDi hot keys.       */
/*                                                                     */
/*  ENTRY POINT: HotKeys1                                              */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD count - Dummy counter.                                  */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag       - Indicates if F3 was pressed.             */
/*        WORD F7Enable     - F7 enabled or disabled.                  */
/*        WORD F8Enable     - F8 enabled or disabled.                  */
/*        WORD EscFlag      - Esc Key pressed.                         */
/*        WORD BarPos       - The position of the scroll bar.          */
/*        WORD BarVal       - The position of the highlighting.        */
/*        WORD RowInc       - Number of rows between each value.       */
/*        WORD ColInc       - Number of columns between each value.    */
/*        WORD NoOfChoices  - Number of choices.                       */
/*        WORD CodePage     - The code page (864/862).                 */
/*        WORD StartCol     - The start column of the text.            */
/*        CHAR ActionKey    - The pressed key which causes changing    */
/*                            the panel.                               */
/*        WORD Page         - The page number.                         */
/*        WORD Lang         - The panel language.                      */
/*        WORD HotKeys1[]   - Array containing the BiDi hot keys values*/
/*                               character shape.                      */
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void HotKeysPg1()
{
   int count;
 /*****    Initialize the array and variables for the panel menu *****/
   BarVal      = Lang; /* Left column for English, right for Arabic*/
   RowInc      = 0;
   NoOfChoices = 5;    /* 0..5 */
   if (CodePage == ARABIC_CP) {
      F7Enable    = 0; /* The F7 key is disabled */
      F8Enable    = 1; /* The F8 key is enabled */
//    /* added by ahmedt on 26/11/90 due to change in popup panels */
//    if (Lang==ENGLISH_PANEL) {
//      ColInc      = 10;
//      StartCol    = 27;
//    } else {
//      ColInc      = 9;
//      StartCol    = 30;
//    } /* endif */

   } else {
   /* Only one hot keys panel for Hebrew code page */
      F7Enable    = 0; /* The F7 key is disabled */
      F8Enable    = 0; /* The F8 key is disabled */
   } /* endif */

   for (count=0;count<6;count++) {
     PanelInfo[count].MaxValue = 1;
     if (Lang==ENGLISH_PANEL) {
         PanelInfo[count].Value = HotKeys1[count];
     } else {
     /* The columns have opposite meanings for the Arabic Panels */
         PanelInfo[count].Value = !HotKeys1[count];
         }
     PanelInfo[count].Row = count+5;
   }

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   if (CodePage == ARABIC_CP) {
    /* changed by ahmedt on 26/11/90 due to change in popup panels */
      if (Lang==ENGLISH_PANEL) {
        ColInc      = 10;
        StartCol    = 27;
      } else {
        ColInc      = 9;
        StartCol    = 30;
      } /* endif */
      DrawBiDiPanel(27L,6L,7L,5L,6L,18L);
   } else {
  /* added by ahmedezz and ranya on 28/7 */
      if (Lang==ENGLISH_PANEL) {
        ColInc      = 10;
        StartCol    = 27;
      } else {
        ColInc      = 10;
        StartCol    = 30;
      } /* endif */
      DrawBiDiPanel(27L,6L,7L,4L,11L,42L);
   } /* endif */

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */

   PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
        ProcessHelpPanel(27L,50L,37L,47L);

  /* If the ChLang Key was pressed, toggle the language */
  /* also toggle the values to fit with the opposite column order */
       if (ActionKey==F2) {
   /* Initialize the Bar value according to the language */
         BarVal = !BarVal; /* Left column for English, right for Arabic */
           Lang = !Lang;
           for (count=0;count<6;count++)
                PanelInfo[count].Value = !PanelInfo[count].Value;
       }
  } while ( (ActionKey==F1) || (ActionKey==F2) );

   /* Check the key used to exit the panel */
   if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey==F3))
   {
     /* If <Enter> is pressed save the settings */
            for (count=0;count<6;count++) {
               if (Lang==ENGLISH_PANEL) {
                   HotKeys1[count] = PanelInfo[count].Value;
               } else {
               /* The columns have opposite meanings for the Arabic Panels */
                   HotKeys1[count] = !PanelInfo[count].Value;
               } /* endif */
            }

     /* If the next panel exits, set the page to 2 */
            if (CodePage == ARABIC_CP)
               Page = 2;
            else  /* otherwise, set the escape flag */
            EscFlag= 1;

            if (F3Flag == 1) SaveChanges();
    }/*if*/
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: HOTKEYS2                                          */
/*                                                                     */
/*  DESCRIPTIVE NAME: View and updates the panel contents.             */
/*                                                                     */
/*  FUNCTION: Allows the user to view and set the BiDi hot keys.       */
/*                                                                     */
/*  ENTRY POINT: HotKeys2                                              */
/*      LINKAGE: CALL NEAR (from main).                                */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD count - Dummy counter.                                  */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT PanelInfo[] - Structure describing each choice in the   */
/*                           panel.                                    */
/*                           The structure consists of the following:  */
/*        WORD MaxValue    - The last valid value this choice          */
/*                           can take : e.g. MaxValue = 1 if           */
/*                           the choice can take values in the         */
/*                           range 0..1.                               */
/*        WORD Value       - The current value of this choice          */
/*        WORD Row         - The row on which this choice is           */
/*                           displayed, counting from the top          */
/*                           of the panel.                             */
/*                                                                     */
/*        WORD F3Flag       - Indicates if F3 was pressed.             */
/*        WORD F7Enable     - F7 enabled or disabled.                  */
/*        WORD F8Enable     - F8 enabled or disabled.                  */
/*        WORD EscFlag      - Esc Key pressed.                         */
/*        WORD BarPos       - The position of the scroll bar.          */
/*        WORD BarVal       - The position of the highlighting.        */
/*        WORD RowInc       - Number of rows between each value.       */
/*        WORD ColInc       - Number of columns between each value.    */
/*        WORD NoOfChoices  - Number of choices.                       */
/*        WORD StartCol     - The start column of the text.            */
/*        CHAR ActionKey    - The pressed key which causes changing    */
/*                            the panel.                               */
/*        WORD Page         - The page number.                         */
/*        WORD Lang         - The panel language.                      */
/*        WORD HotKeys2[]   - Array containing the BiDi hot keys values*/
/*                                                                     */
/*     ROUTINES: DrawBiDiPanel()                                       */
/*               PanelMenu()                                           */
/*               ProcessHelpPanel()                                    */
/*               SaveChanges()                                         */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void HotKeysPg2()
{
  int count;
 /*****    Initialize the array and variables for the panel menu *****/
  BarVal       = Lang;
  RowInc       = 0;
  ColInc       = 10;
  StartCol     = 27;
  NoOfChoices  = 4; /*0..5*/
  F7Enable     = 1; /* Enable F7 */
  F8Enable     = 0; /* Disable F8 */

  for (count=0;count<5;count++) {
   PanelInfo[count].MaxValue = 1;
   if (Lang==ENGLISH_PANEL) {
         PanelInfo[count].Value = HotKeys2[count];
     } else {
     /* The columns have opposite meanings for the Arabic Panels */
         PanelInfo[count].Value = !HotKeys2[count];
         }
   PanelInfo[count].Row = count+5;
  }

  do {
  /* Continue to display the panel in the current language */
  /* and to accept user input until no further language changes */
  /* are requested .*/

   if (Lang==ENGLISH_PANEL) {
     ColInc      = 10;
     StartCol    = 27;
   } else {
     ColInc      = 9;
     StartCol    = 30;
   } /* endif */

   DrawBiDiPanel(27L,6L,7L,5L,7L,19L);

  /* Invoke the PanelMenu which allows movement of the scrollbar */
  /* around the panel using the arrow keys, choosing of options  */
  /* using the spacebar and exiting the panel. The key used to   */
  /* exit the panel is returned.                                 */

   PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,&ActionKey);

  /* If the Help key was pressed, then draw the corresponding    */
  /* help panel in the appropriate language.                     */
  /* Return only if the ESC key is pressed                       */
     if (ActionKey==F1)
     ProcessHelpPanel(27L,27L,37L,47L);

  /* If the ChLang Key was pressed, toggle the language */
       if (ActionKey==F2) {
   /* Initialize the Bar value according to the language */
           BarVal = !BarVal; /* Left column for English, right for Arabic */
           Lang   = !Lang;
           for (count=0;count<5;count++)
                PanelInfo[count].Value = !PanelInfo[count].Value;
       }
  } while ( (ActionKey==F1) || (ActionKey==F2) );

  /* Check the character returned by panel menu */
    if ((ActionKey==RETURN)||(ActionKey==ENTER)||(ActionKey==F3))
    { /* Save the settings */
             for (count=0;count<5 ; count++) {
               if (Lang==ENGLISH_PANEL) {
                   HotKeys2[count] = PanelInfo[count].Value;
               } else {
               /* The columns have opposite meanings for the Arabic Panels */
                   HotKeys2[count] = !PanelInfo[count].Value;
                   }
             }
             /* Set the escape flag */
             EscFlag= 1;
             if (F3Flag == 1) SaveChanges();
    }
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: SAVECHANGES                                       */
/*                                                                     */
/*  DESCRIPTIVE NAME: Saves the new settings into the control blocks.  */
/*                                                                     */
/*  FUNCTION: SaveChanges checks if the F3 key was pressed. If pressed,*/
/*            the current blocks contents are compared to the original */
/*            contents. If any difference is detected in one of the    */
/*            control blocks, this control block is saved. The original*/
/*            contents of the PopUp session are restored and a global  */
/*            flag is set to end the program. However if the F3 key was*/
/*            not pressed, the same comparison is done with no savings */
/*            but if any difference is detected, a global variable     */
/*            "difference" is set and the control is returned to the   */
/*            caller.                                                  */
/*                                                                     */
/*  ENTRY POINT: SaveChanges                                           */
/*      LINKAGE: CALL NEAR (from GetMainChoice,GetLptChoice,KbdPg1,    */
/*                               KbdPg2,LptPg1,LptPg2,HotKeysPg1,      */
/*                               HotKeysPg2)                           */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: RC <-- 0                                              */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: The content of the BiDi data segment may be changed. */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD LptCount    - Dummy counter for printers.               */
/*        WORD HotKeyCount - Dummy counter for the hot keys.           */
/*        WORD MemCount    - Dummy counter to copy the contents of     */
/*                           the control blocks.                       */
/*      @OTHER Source      - Pointer to a source string.               */
/*      @OTHER Target      - Pointer to a target string.               */
/*                                                                     */
/*        WORD change      - Indicates that a change was detected in   */
/*                           the control block.                        */
/*        WORD OldLang     - Contains the old panel language.          */
/*        WORD NewLang     - Contains the new panel language.          */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*      STRUCT KbdVioCtrlBlk - structure of the keyboard video control */
/*                             block.                                  */
/*      The structure of the control block is:                         */
/*             WORD Length  - Lenght of the control block.             */
/*             WORD BDVerID - BiDi version ID.                         */
/*           STRUCT BiDiAtt - BiDi attributes.                         */
/*             BYTE Res[4]  - Four bytes reserved.                     */
/*             WORD HotKeys - BiDi hot keys.                           */
/*             WORD ScrInfo - BiDi flags.                              */
/*                                                                     */
/*      The structure of the BiDi attributes:                          */
/*             BYTE  CSD         - Character Shape Determination values*/
/*             BYTE  NumShapes   - Numeral shapes.                     */
/*             BYTE  Orientation - Orientation of the screen.          */
/*             BYTE  Reserved    - A reserved byte containing 48.      */
/*                                                                     */
/*   STRUCT OldKbdVioCtrlBlk - structure like KbdVioCtrlBlk containing */
/*                             the original attributes of the current  */
/*                             session.                                */
/*      STRUCT OriginalPopUp - structure like KbdVioCtrlBlk containing */
/*                             the original attributes of the PopUp    */
/*                             session.                                */
/*      STRUCT LptArray[]    - Array of structures like the structure  */
/*                             of the printer control block.           */
/*      The contents of the printer structure:                         */
/*        WORD Length  - Length of the control block.                  */
/*      STRUCT BiDiAtt - The BiDi attributes.                          */
/*                                                                     */
/*      STRUCT OldLptArray[] - Array of structures like the structure  */
/*                             of the printer control block to save    */
/*                             the original printer control blocks.    */
/*        WORD Lang          - The current language panel.             */
/*        WORD Language      - The current language layer.             */
/*        WORD ScrOrientation- The screen orientation (LtR,RtL).       */
/*        WORD AutoPush      - The auto push (ON/OFF).                 */
/*        WORD NumShape      - The numeric shapes (Arabic,Hindu).      */
/*        WORD CharShape     - The character shapes (Auto, initial,..).*/
/* STATIC WORD ScrToCsd[]    - A translation array to translate the    */
/*                             position on the screen to a CSD value.  */
/* STATIC WORD HotToScr[]    - A translation array to translate the hot*/
/*                             key values to a position on the screen  */
/*        WORD HotKeys1[]    - Array to contain the hot keys values.   */
/*        WORD HotKeys2[]    - Array to contain the hot keys values.   */
/*        WORD Lptorientation[]- Array containing the printers         */
/*                             orientation.                            */
/*        WORD LptNumShapes[]- Array containing the numeric shapes for */
/*                             the printers                            */
/*        WORD LptCharShape[]- Array containing the character shapes   */
/*                             of the printers.                        */
/*       DWORD Scope         - The ID of the current session.          */
/*       DWORD PopUpId       - The ID of the PopUp session.            */
/*        WORD ReturnCode    - Return code for the used functions.     */
/*        WORD ChangeLang    - Indicates that the language had changed.*/
/*        WORD difference    - Indicates if any changes were done to   */
/*                             any of the control blocks.              */
/*        WORD quit          - A global flag to exit the program       */
/*                                                                     */
/*     ROUTINES: GetBit()                                              */
/*               SetBit()                                              */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NlsIntSetBidiAtt()                                    */
/*               VioEndPopUp()                                         */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void SaveChanges(void)
{
  int HotKeyCount,change;
  ULONG LptCount,OldLang,NewLang;
  int MemCount;
  int *Source, *Target;

/* Remap the variables used within the program to valid values to be  */
/* stored in the control block                                         */

/*              Remap the printers attributes                          */
  for (LptCount = 0; LptCount < 3; LptCount++) {
      LptArray[LptCount].BiDiAtt.Orientation = (BYTE)LptOrientation[LptCount];
      LptArray[LptCount].BiDiAtt.NumShapes = (BYTE)
                                             (16*(LptNumShapes[LptCount]+1));
/*                                  (16*(LptNumShapes[LptCount]+1)+1); */
      LptArray[LptCount].BiDiAtt.CSD = (BYTE)ScrToCsd[LptCharShape[LptCount]];
  } /* endfor */

/*              Remap the keyboard video attributes                   */
  KbdVioCtrlBlk.BiDiAtt.Orientation = (BYTE)ScrOrientation;
/*     KbdVioCtrlBlk.BiDiAtt.NumShapes = (BYTE)(16*(NumShape+1)+1);    */
  KbdVioCtrlBlk.BiDiAtt.NumShapes = (BYTE)(16*(NumShape+1));
  KbdVioCtrlBlk.BiDiAtt.CSD = (BYTE)ScrToCsd[CharShape];
  SetBit(4L,Language,(ULONG *)&KbdVioCtrlBlk.ScrInfo);
  SetBit((ULONG)(!ScrOrientation),AutoPush,(ULONG *)&KbdVioCtrlBlk.ScrInfo);

/* save the default language for later PopUp invocation */
  SetBit(9L,Lang,(ULONG *)&KbdVioCtrlBlk.ScrInfo);

/* save the default language also in the old structure to not feel  */
/* a difference during comparasion. This bit is transparent.        */
/* Howver if the language is different a global variable is set so  */
/* that if there is no other changes  other than the language, in   */
/* this case, the language is saved before leaving the PopUp        */
  OldLang = GetBit(9L,((ULONG)OldKbdVioCtrlBlk.ScrInfo));
  NewLang = GetBit(9L,(ULONG)(KbdVioCtrlBlk.ScrInfo));
  if (NewLang != OldLang)
     ChangeLang = 1;

  SetBit(9L,Lang,(ULONG *)(&OldKbdVioCtrlBlk.ScrInfo));

/* Set the Hot keys of the first panel into the control block */
  for (HotKeyCount = 0; HotKeyCount < 6; HotKeyCount++) {
      SetBit(HotToScr[HotKeyCount],HotKeys1[HotKeyCount],
             (ULONG *)&KbdVioCtrlBlk.HotKeys);
  } /* endfor */

/* Set the Hot keys of the second panel into the control block */
  for (HotKeyCount = 0; HotKeyCount < 5; HotKeyCount++) {
      SetBit((ULONG)(HotKeyCount+10),HotKeys2[HotKeyCount], (ULONG *)&KbdVioCtrlBlk.HotKeys);
  } /* endfor */

  if (F3Flag == 1) {                     /* if we are going to save the updates */

   if ((KbdVioCtrlBlk.ScrInfo & 0x0004)  /* if we are in push or FR          */
                      ||
       (KbdVioCtrlBlk.ScrInfo & 0x0020) ){  /* Save the current CSD and numeric */
                                            /* value in temporary variables.    */
     TempCSD = KbdVioCtrlBlk.BiDiAtt.CSD;
     TempNum = KbdVioCtrlBlk.BiDiAtt.NumShapes;
                                     /* Set CSD and Numerics to Passthru */
                                     /* so that there will be no refresh */
                                     /* at end of popup.                 */
     KbdVioCtrlBlk.BiDiAtt.CSD = 0x01;
     KbdVioCtrlBlk.BiDiAtt.NumShapes = 0x10;
     ReturnCode = NlsIntSetBidiAtt(Scope,0L,(PSETINFO)&KbdVioCtrlBlk);
     VioEndPopUp(0);                 /* End the PopUp to return to the      */
                                     /* original session ID */
                                     /* Set attibutes back again         */
     KbdVioCtrlBlk.BiDiAtt.CSD = TempCSD;
     KbdVioCtrlBlk.BiDiAtt.NumShapes = TempNum;
     ReturnCode = NlsIntSetBidiAtt(Scope,0L,(PSETINFO)&KbdVioCtrlBlk);
                                     /* here is the actual setting       */

   } else {                          /* if we are in normal mode         */
     VioEndPopUp(0);                 /* End the PopUp to return to the      */
                                     /* original session ID */
     ReturnCode = NlsIntSetBidiAtt(Scope,0L,(PSETINFO)&KbdVioCtrlBlk);
   }/* endif */
     quit = 1;
  }

/* check if any changes where done to the control block      */

    Source = (int *)&KbdVioCtrlBlk;
    Target = (int *)&OldKbdVioCtrlBlk;

    change = 0;
    for (MemCount = 0; MemCount < 8; MemCount++) {
       if (*Target == *Source) {
          Source++;
          Target++;
       } else {
          change = 1;
          MemCount = 8;
       } /* endif */
    } /* endfor */

/* Set the global flag to be seen by the exit panel if it is invoked */
  difference = change;

  if ( (change != 0 && F3Flag == 1) || (ChangeLang == 1 && F3Flag == 1) ){
  /* there are changes in the keyboard video control block then save them */
     ReturnCode = NlsIntSetBidiAtt(Scope,0L,(PSETINFO)&KbdVioCtrlBlk);
    } /* end if */

  for (LptCount = 0; LptCount<3; LptCount++) {
/* check if any changes where done to the control block      */

    Source = (int *)&LptArray[LptCount];
    Target = (int *)&OldLptArray[LptCount];
    change = 0;
    for (MemCount = 0; MemCount < 3; MemCount++) {
       if (*Target == *Source) {
          Source++;
          Target++;
       } else {
          change = 1;
          MemCount = 3;
       } /* endif */
    } /* endfor */

/* if there were changes in the keyboard video control block then don't */
/* change the contents of difference as change may zero because there   */
/* were no changes in the printer control block                         */
     if (change != 0)
        difference = change;

  if (change != 0 && F3Flag == 1) {
     /* there are changes then save them  */
        ReturnCode = NlsIntSetBidiAtt(0L,LptCount+1,
                                   (PSETINFO)&LptArray[LptCount]);
     } /* end if */
  } /* endfor */
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: DRAWBIDIPANEL                                     */
/*                                                                     */
/*  DESCRIPTIVE NAME: Displays the appropriate BiDi panel.             */
/*                                                                     */
/*  FUNCTION: Initialize the parameters of the panel depending on the  */
/*            panel language and displays it.                          */
/*                                                                     */
/*  ENTRY POINT: DrawBiDiPanel                                         */
/*      LINKAGE: CALL NEAR (from GetMainChoice,GetLptChoice,KbdPg1,    */
/*                               KbdPg2,LptPg1,LptPg2,HotKeysPg1,      */
/*                               HotKeysPg2)                           */
/*                                                                     */
/*  INPUT: (EngStartCol,NlsStartCol,EngMaxLength,NlsMaxLength,EngNo,   */
/*                                                            NlsNo)   */
/*      EngStartCol  DWORD - The start column of the English panel.    */
/*      NlsStartCol  DWORD - The start column of the National panel.   */
/*      EngMaxLength DWORD - The maximum length of a message in the    */
/*                          English panel.                             */
/*      NlsMaxLength DWORD - The maximum length of a message in the    */
/*                          National panel.                            */
/*      EngNo        DWORD - The English panel number.                 */
/*      NlsNo        DWORD - The National panel number.                */
/*                                                                     */
/*  EXIT-NORMAL: The required panel is drawn.                          */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        WORD Lang      - The current language panel.                 */
/*        WORD StartCol  - The column at which the highlighting start  */
/*        WORD ValLen    - The longest highlighted value.              */
/*                                                                     */
/*     ROUTINES: DrawPanel                                             */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void DrawBiDiPanel(ULONG EngStartCol,ULONG NlsStartCol,ULONG EngMaxLength,
                   ULONG NlsMaxLength,ULONG EngNo,ULONG NlsNo)
{
      switch ( (int)Lang ) {
      /* Initialize the variables and draw the panel */
      /* according to the current panel language */
        case ENGLISH_PANEL :
                  StartCol = EngStartCol;
                  ValLen   = EngMaxLength;
                  DrawPanel(EngNo,(ULONG)NORMAL);
             break;
        case NATIONAL_PANEL:
                  StartCol = NlsStartCol;
                  ValLen   = NlsMaxLength;
                  DrawPanel(NlsNo,(ULONG)NORMAL);
             break;
       }/* endswitch */
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: DRAWPANEL                                         */
/*                                                                     */
/*  DESCRIPTIVE NAME: Displays the panel.                              */
/*                                                                     */
/*  FUNCTION: Displays the required panel by its number and type.      */
/*                                                                     */
/*  ENTRY POINT: DrawPanel                                             */
/*      LINKAGE: CALL NEAR (from ProcessHelpPanel, DrawBiDiPanel).     */
/*                                                                     */
/*  INPUT: (PanelNo, PanelType)                                        */
/*         PanelNo   DWORD - The number of the panel in the message    */
/*                           file.                                     */
/*         PanelType DWORD - The panel can be a normal or a help panel.*/
/*                                                                     */
/*  EXIT-NORMAL: The required panel is drawn.                          */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*        WORD FrameCount - Counter used to retrieve the messages.     */
/*        WORD PanelLen   - Number of messages to be displayed.        */
/*        BYTE PanelCo    - Color of the panel.                        */
/*        BYTE FunctionCo - Color of the function key area.            */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        BYTE WindowColor    - Color to use in display.               */
/*        BYTE FunctionAreaCo - The color of the function key area.    */
/*        BYTE HelpWindowCo   - Color of the help panel.               */
/*        BYTE HelpFunctionCo - Color of the function key area in the  */
/*                              help panel.                            */
/*        CHAR *ptrarray[]    - Array of pointers to characters {"\0"} */
/*        CHAR msg[50]        - Array of chars to get the message in.  */
/*        WORD ReturnCode     - Check retrieving the message.          */
/*                                                                     */
/*     ROUTINES: ProcessErrorMsg                                       */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*               VioWrtNAttr()                                         */
/*               DosGetMessage()                                       */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void DrawPanel(ULONG PanelNo,ULONG PanelType)
{
   int FrameCount, /* Counter used to retrieve messages          */
       PanelLen;   /* The length of each panel, not counting the */
                   /* top and bottom lines which are constant    */
                   /* and are only displayed once by StartPopup  */
   BYTE PanelCo,FunctionCo;

   if (PanelType == 0) { /* normal panel */
      PanelCo = WindowColor;
      FunctionCo = FunctionAreaCo;
   } else {  /* help panel */
      PanelCo = HelpWindowCo;
      FunctionCo = HelpFunctionCo;
   } /* endif */

   PanelLen = 19;
   /* Get and display the first line in the panels */
   if (CodePage == ARABIC_CP) {
   /* The borders of the panel differes from Arabic to Hebrew code page */
       ReturnCode = DosGetMessage(ptrarray,0, msg, sizeof(msg),
                                  0,"popmsg.msg",&len);
   } else {
       ReturnCode = DosGetMessage(ptrarray,0, msg, sizeof(msg),
                                  920,"popmsg.msg",&len);
   } /* endif */

   if (ReturnCode != 0) {
      ProcessErrorMsg();
      return;
      }

   VioWrtCharStrAtt(msg,len-2,(int) row,(int) col, &PanelCo,0);

   /* Get and display the last line in the panels */
   if (CodePage == ARABIC_CP) {
   /* The borders of the panel differes from Arabic to Hebrew code page */
       ReturnCode = DosGetMessage(ptrarray,0, msg, sizeof(msg),
                                  1,"popmsg.msg",&len);
   } else {
       ReturnCode = DosGetMessage(ptrarray,0, msg, sizeof(msg),
                                  921,"popmsg.msg",&len);
   } /* endif */

   if (ReturnCode != 0) {
      ProcessErrorMsg();
      return;
      }
   VioWrtCharStrAtt(msg,len-2,(USHORT)row+PanelLen-1,(USHORT)col, &PanelCo,0);

   PanelLen = 17;
   for(FrameCount=(USHORT)(PanelLen*PanelNo+2);
       FrameCount<(USHORT)(PanelLen*PanelNo+PanelLen+PanelType);
       FrameCount++) {

      /* Retrieve one panel line from the message file */
          ReturnCode = DosGetMessage(ptrarray,0, msg, sizeof(msg),
                                     FrameCount,"popmsg.msg",&len);
          if (ReturnCode != 0) {
             ProcessErrorMsg();
             return;
             }

      /* Display the line */
         VioWrtCharStrAtt(msg,len-2,(USHORT)(row+FrameCount-PanelLen*PanelNo-1),
                           (USHORT)col, &PanelCo,0);
                   }
/* Draw the function keys area with different attributes                */
   for(FrameCount=(USHORT)(PanelLen*PanelNo+PanelLen+PanelType);
       FrameCount<(USHORT)(PanelLen*PanelNo+PanelLen+2);
       FrameCount++) {

      /* Retrieve one panel line from the message file */
          ReturnCode = DosGetMessage(ptrarray,0, msg, sizeof(msg),
                                     FrameCount,"popmsg.msg",&len);
          if (ReturnCode != 0) {
             ProcessErrorMsg();
             return;
             }

      /* Display the line */
          VioWrtCharStrAtt(msg,len-2,(USHORT)row+FrameCount-PanelLen*(USHORT)PanelNo-1,
                          (USHORT)col, &FunctionCo,0);
      /*  Repaint the borders by the original border line            */
          VioWrtNAttr(&PanelCo,1,(USHORT)(row+FrameCount-PanelLen*PanelNo-1),(USHORT)col,0);
          VioWrtNAttr(&PanelCo,1,(USHORT)(row+FrameCount-PanelLen*PanelNo-1),
                      (USHORT)(col+PANEL_WIDTH),0);
                      }

}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: PROCESSHELPPANEL                                  */
/*                                                                     */
/*  DESCRIPTIVE NAME: Displays the appropriate help panel.             */
/*                                                                     */
/*  FUNCTION: Displays the appropriate help panel depending on the     */
/*            code page and returns to the caller if the Esc key is    */
/*            pressed                                                  */
/*                                                                     */
/*  ENTRY POINT: ProcessHelpPanel                                      */
/*      LINKAGE: CALL NEAR (from GetMainChoice,GetLptChoice,KbdPg1,    */
/*                               KbdPg2,LptPg1,LptPg2,HotKeysPg1,      */
/*                               HotKeysPg2)                           */
/*                                                                     */
/*  INPUT: (ArEngNo, HeEngNo, ArNo, HeNo)                              */
/*                                                                     */
/*      ArEngNo  DWORD - The English help panel of the Arabic panels   */
/*      HeEngNo  DWORD - The English help panel of the Hebrew panels   */
/*      ArNo     DWORD - The Arabic help panel of the Arabic panels    */
/*      HeNo     DWORD - The Hebrew help panel of the Hebrew panels    */
/*                                                                     */
/*  EXIT-NORMAL: Return to the caller when Esc is pressed.             */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        WORD Lang      - The current language panel.                 */
/*        WORD CodePage  - The current code page of this session.      */
/*      STRUCT kb        - structure of type KBDKEYINFO.               */
/*        WORD quit      - A global flag to exit the program           */
/*                                                                     */
/*     ROUTINES: DrawPanel                                             */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: DosBeep()                                             */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void ProcessHelpPanel(ULONG ArEngNo,ULONG HeEngNo,ULONG ArNo,ULONG HeNo)
{
      switch ( (int)Lang ) {
        case ENGLISH_PANEL :
                  if (CodePage == ARABIC_CP)
                     DrawPanel(ArEngNo,(ULONG)HELP);
                  else
                     DrawPanel(HeEngNo,(ULONG)HELP);
             break;
        case NATIONAL_PANEL:
                  if (CodePage == ARABIC_CP)
                     DrawPanel(ArNo,(ULONG)HELP);
                  else
                     DrawPanel(HeNo,(ULONG)HELP);
             break;
       }/* endswitch */

       kb.chScan = 0;           /* Check for Esc pressed only if the panel */
                                /* was drawn correctly                     */
       while (kb.chScan!=1 && quit == 0) {
          KbdCharIn(&kb,IO_WAIT,0);
          if (kb.chScan != 1)         /* beep if invalid key pressed */
              DosBeep(1200,100);
       } /* endwhile */
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: PROCESSERRORMSG                                   */
/*                                                                     */
/*  DESCRIPTIVE NAME: Process the error in messages.                   */
/*                                                                     */
/*  FUNCTION: Displays an error message if the message file in either  */
/*            incomplete or not found. It also ends the program.       */
/*                                                                     */
/*  ENTRY POINT: ProcessErrorMsg                                       */
/*      LINKAGE: CALL NEAR (from DrawPanel).                           */
/*                                                                     */
/*  INPUT: NONE.                                                       */
/*                                                                     */
/*  EXIT-NORMAL: The program is ended.                                 */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION: NONE.                                    */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        BYTE WindowColor    - Color of the error message.            */
/*        WORD row            - Row at which the PopUp is displayed.   */
/*        WORD col            - Column at which the PopUp is displayed.*/
/*        WORD quit           - A global variable to exit the program  */
/*      DWORD  PopUpId        - A double word to save the PopUp        */
/*                              session ID                             */
/*      STRUCT OriginalPopUp  - A structure identical to the Keyboard  */
/*                              video control block.                   */
/*      STRUCT kb             - structure of type KBDKEYINFO.          */
/*                                                                     */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*               VioEndPopUp                                           */
/*               KbdCharIn()                                           */
/*               VioScrollUp()                                         */
/*               DosBeep()                                             */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void ProcessErrorMsg(void)
{
 char cell[2];
 cell[0] = 0x20;
 cell[1] = WindowColor;
 VioScrollUp((USHORT)row,(USHORT)col,(USHORT)(row+18),(USHORT)(col+45),-1,cell,0);
 VioWrtCharStrAtt("The message file POPMSG.MSG is either",37,(USHORT)(row+5),
                                               (USHORT)(col+5),&WindowColor,0);
 VioWrtCharStrAtt("damaged or not found",20,(USHORT)(row+6),(USHORT) (col+5),&WindowColor,0);
 VioWrtCharStrAtt("Any changes will not be saved",29,(USHORT)(row+7),(USHORT)(col+9),&WindowColor,0);
 VioWrtCharStrAtt("Press ESCAPE to end the PopUp",29,(USHORT)(row+8),(USHORT)(col+9),&WindowColor,0);
 do {   /* ended if Esc pressed */
    KbdCharIn(&kb,IO_WAIT,0);
    if (kb.chScan != 1)    /* Beep if invalid key pressed */
        DosBeep(1200,100);
 } while (kb.chScan != 1); /* enddo */
 quit = 1;
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: PANELMENU                                         */
/*                                                                     */
/*  DESCRIPTIVE NAME: Handles the interactions with the user.          */
/*                                                                     */
/*  FUNCTION: Accepts user input and performs the correct              */
/*            highlighting, movement of the scrollbar according to     */
/*            the key detected.                                        */
/*                                                                     */
/*  ENTRY POINT: PanelMenu                                             */
/*      LINKAGE: CALL NEAR (from GetMainChoice,GetLptChoice,KbdPg1,    */
/*                               KbdPg2,LptPg1,LptPg2,HotKeysPg1,      */
/*                               HotKeysPg2)                           */
/*                                                                     */
/*  INPUT: (PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,KeyPressed)   */
/*      WORD  PanelInfo   - An array of structures containing          */
/*                          information about the layout of the panel  */
/*                          and the currently highlighted value of     */
/*                          each choice.                               */
/*                          Each structure is composed as follows:     */
/*                          WORD MaxValue - The last valid value this  */
/*                                          choice can take.           */
/*                          WORD Value    - The current value of this  */
/*                                          choice.                    */
/*                          WORD Row      - The row on which this      */
/*                                          choice is displayed.       */
/*                                                                     */
/*      DWORD  RowInc      - The number of lines between each value and*/
/*                          the next.                                  */
/*      DWORD  ColInc      - The number of columns between the start of*/
/*                          each value and the next.                   */
/*      DWORD  NoOfChoices - Number of choices in the panel.           */
/*                                                                     */
/*      DWORD  StartCol    - The column at which the highlighting start*/
/*     @OTHER KeyPressed  - The action key pressed to exit the panel.  */
/*                                                                     */
/*  NOTE: The term Choice is used to refer to a BiDi attribute         */
/*        displayed on any panel. The term Value is used to refer to   */
/*        the actual setting of the attribute.                         */
/*        Example:                                                     */
/*          choice --> Auto Push           ON   <-- value              */
/*                                         OFF  <-- value              */
/*                                                                     */
/*  EXIT-NORMAL: The action key pressed is returned.                   */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*      WORD count - Dummy counter.                                    */
/*      WORD Column - The column number in the hot keys panels.        */
/*                     (0 = Left column, 1 = Right column)             */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        BYTE WindowColor    - Color to use in display.               */
/*        BYTE ScrollBarColor - Color of the scroll bar.               */
/*        BYTE HiLightColor   - Color of the highlighted option.       */
/* STATIC WORD IncArray[Lang] - Distance between the arrow and the     */
/*                              text for English and National          */
/*                              panels {-2,2}.                         */
/* STATIC CHAR ArrowArray[Lang]                                        */
/*                            - Type of the arrow depending on the     */
/*                              language, {"",""}                    */
/*        WORD ColumnFlag     - if set indicates that F1 or F2 were    */
/*                              pressed.                               */
/*        WORD OldColumn      - saves the last column value if the     */
/*                              panel was exited by F1 or F2.          */
/*        WORD OldBarPos      - saves the last bar position if the     */
/*                              panel was exited by F1 or F2           */
/*        WORD ValLen         - The length of the longest value.       */
/*        WORD row            - Row at which the PopUp is displayed.   */
/*        WORD col            - Column at which the PopUp is displayed.*/
/*        WORD BarPos         - The choice on which the bar is found.  */
/*        WORD BarVal         - The value of the choice on which the   */
/*                              bar is on.                             */
/*      STRUCT kb             - structure of type KBDKEYINFO.          */
/*        WORD EscFlag        - Flag set if the Esc key is pressed.    */
/*        WORD F3Flag         - Flag set if the F3 key is pressed.     */
/*        WORD F8Enable       - Flag set if F8 is permitted.           */
/*        WORD F7Enable       - Flag set if F7 is permitted.           */
/*        WORD Page           - Contains the page number.              */
/*        WORD Lang           - Indicates what is the panel language.  */
/*        WORD quit           - A global flag to exit the program      */
/*                                                                     */
/*     ROUTINES: FixArrow()                                            */
/*               ChangeAttr()                                          */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*               KbdCharIn()                                           */
/*               DosBeep()                                             */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void PanelMenu(PanelInfo,RowInc,ColInc,NoOfChoices,StartCol,KeyPressed)
  PanelArray PanelInfo;
  ULONG  RowInc,ColInc,NoOfChoices,StartCol;
  USHORT *KeyPressed;
{
ULONG count, Column;

if (quit == 1)   /* Error happened during the drawing of the panel */
   return;

/********** Initialize panel : Draw arrows and highlight *********/
BarPos = 0;
*KeyPressed = 0;

for (count=0;count<=NoOfChoices ;count++ ) {
/* If the value is 0 & ColInc<>0, it is the left column */
/* Column = 0 for the left column and 1 for the right column */
     Column = PanelInfo[count].Value;

     /* Draw the arrow */
     VioWrtCharStrAtt(ArrowArray[Lang],1,
         (USHORT) (row + PanelInfo[count].Row + PanelInfo[count].Value*RowInc),
             (USHORT) (col + StartCol + Column*ColInc + IncArray[Lang]),
                      &WindowColor,0);

     /* Highlight the option in yellow */
     ChangeAttr(HiLightColor,ValLen,
                 row + PanelInfo[count].Row + PanelInfo[count].Value*RowInc,
                 col + StartCol + Column*ColInc);

}/*end for*/
/********** Initialize panel : Draw bar *********/

     if (ColumnFlag == 1) { /* the hot keys panel was exited by F1 or F2 */
        Column = OldColumn; /* preserve the old scroll bar position      */
        BarPos = OldBarPos; /* preserve the old scroll bar position      */
        }
     else
        Column = Lang;      /* Start on the left column for English */
                            /* and the right column for Arabic      */
     ColumnFlag = 0;
                            /* Draw the scroll bar */
     ChangeAttr(ScrollBarColor,ValLen,
                row + PanelInfo[BarPos].Row + BarVal*RowInc,
                col + StartCol + Column*ColInc);
/****************  End of initialization   **************************/

/****************  Handle KeyStrokes   **************************/

/* Process the hit keys */
   do {
       KbdCharIn(&kb,IO_WAIT,0);
       switch(kb.chScan)
        {
          case ESC:    EscFlag = 1;   /* Set the escape flag */
                      *KeyPressed = kb.chScan;
                       kb.chScan = 1; /* Exit the loop */
                       break;

          case F1:      /* Return the key pressed */
                       ColumnFlag = 1;
                       OldColumn = (USHORT)BarVal;
                       OldBarPos = (USHORT)BarPos;
                      *KeyPressed = kb.chScan;
                       kb.chScan = 1; /* Exit the loop */
                       break;
          case F2:
                       ColumnFlag = 1;
                       OldColumn = !BarVal;
                       OldBarPos = (USHORT)BarPos;
                      *KeyPressed = kb.chScan;
                       kb.chScan = 1; /* Exit the loop */
                       break;
          case F3:
                       F3Flag = 1;
          case ENTER:
          case RETURN:*KeyPressed = kb.chScan;
                       kb.chScan = 1; /* Exit the loop */
                       break;

          case F8:
          case PG_DOWN: if (F8Enable) {
                                   Page++;        /* Increment Page */
                                   kb.chScan = 1; /* Exit the loop  */
                                    }
                          else
                           DosBeep(1200,100);
                        break;
          case F7:
          case PG_UP:  if (F7Enable) {
                                   Page--;        /* Decrement Page */
                                   kb.chScan = 1; /* Exit the loop  */
                                   }
                          else
                           DosBeep(1200,100);
                         break;

          case CURS_DOWN:
          case CURS_RIGHT:
          case CURS_LEFT:
          case CURS_UP:
  /****** If bar was on the chosen option, redraw the old one in yellow ******/
            if (PanelInfo[BarPos].Value==BarVal)
             ChangeAttr(HiLightColor, ValLen,
                row + PanelInfo[BarPos].Row + BarVal*RowInc,
                col + StartCol + Column*ColInc);
             else   /* Redraw in blue */
             ChangeAttr(WindowColor, ValLen,
                row + PanelInfo[BarPos].Row + BarVal*RowInc,
                col + StartCol + Column*ColInc);

/* For all panels except the hot keys panels, the left and down arrows,*/
/* right and up arrows do the same thing in the national panel.        */
/* The left and up arrow, right and down arrows do the same thing in   */
/* an English panel.                                                   */
             if (ColInc==0) {  /* All panels except hot keys panels */
                if (Lang== NATIONAL_PANEL)
                     switch (kb.chScan) {
                        case CURS_LEFT:
                              kb.chScan = CURS_DOWN;
                        break;
                        case CURS_RIGHT:
                              kb.chScan = CURS_UP;
                        break;
                     }
                else
                     switch (kb.chScan) {
                        case CURS_LEFT:
                              kb.chScan = CURS_UP;
                        break;
                        case CURS_RIGHT:
                              kb.chScan = CURS_DOWN;
                        break;
                     }
             }

  /******** Adjust the bar position according to the key pressed *****/
                switch (kb.chScan) {
                   case CURS_UP:
             /********* Adjust bar position   *******************/
                   if (ColInc!=0)  { /* There are options on the same line */
                      if (BarPos>0)
                         BarPos-- ;            /* Move up one choice */
                      else
                         BarPos = NoOfChoices; /* Go to last choice  */
                   } else            /* Options under each other */
                     if (BarVal>0)
                        BarVal--;              /* Move up one value  */
                     else                      /* Move to last value */
                                               /* of previous choice */
                     if (BarPos>0)
                     {
                       BarPos--;               /* Move up one choice */
                       BarVal = PanelInfo[BarPos].MaxValue;
                      } else         /* Move to last value of last choice */
                        {
                        BarPos = NoOfChoices;
                        BarVal = PanelInfo[BarPos].MaxValue;
                        }
              break;

                   case CURS_LEFT:
             /********  Toggle to the other column **************/
                     Column = !Column;

             /********* Adjust bar position according to language ***********/
              switch ( (int)Lang ) {
                  case ENGLISH_PANEL:
                     if (BarVal>0)
                        BarVal--;      /* Move to previous value */
                     else    /* Move to maximum value of previous choice */
                     if (BarPos>0)
                     {
                       BarPos--;
                       BarVal = PanelInfo[BarPos].MaxValue;
                      } /*if*/
                      else { /* Move to last value of last choice */
                        BarPos = NoOfChoices;
                        BarVal = PanelInfo[BarPos].MaxValue;
                        }
                   break;
                   case NATIONAL_PANEL:
                     if (BarVal>0)
                        BarVal--;          /* Move to previous value */
                     else  /* Move to maximum value of next choice */
                     if (BarPos<NoOfChoices)
                     {
                       BarPos++;
                       BarVal = PanelInfo[BarPos].MaxValue;
                      } /*if*/
                      else { /* Move to maximum value of first choice */
                        BarPos = 0;
                        BarVal = PanelInfo[BarPos].MaxValue;
                        }

                   break;
                     } /* endswitch */
                   break;

                   case CURS_DOWN:
             /********* Adjust bar position   *******************/
                   if (ColInc!=0) { /* There are options on the same line */
                      if (BarPos<NoOfChoices)
                         BarPos++;   /* Move to next choice */
                      else
                         BarPos = 0; /* Move up to top choice */
                   } else /* Options under each other */
                   {
                     if (BarVal<PanelInfo[BarPos].MaxValue)
                         BarVal++;  /* Move to next value */
                     else /* Move to first value of next choice */
                     if (BarPos<NoOfChoices)
                     {
                        BarPos++;
                        BarVal = 0;
                      } /*if*/
                     else       /* Move to first value of first choice */
                        BarPos = BarVal = 0;
                   }
                    break;

                   case CURS_RIGHT :
             /********  Toggle to the other column **************/
                      Column = !Column;

             /********* Adjust bar position  according to language ****/
                     switch ( (int) Lang) {
                     case ENGLISH_PANEL:
                         if (BarVal<PanelInfo[BarPos].MaxValue)
                             BarVal++; /* Move to next value */
                         else  /* Move to first value of next choice */
                         if (BarPos<NoOfChoices)
                         {
                            BarPos++;
                            BarVal = 0;
                          } /*if*/
                         else   /* Move to first value of first choice */
                            BarPos = BarVal = 0;
                      break;
                      case NATIONAL_PANEL:
                         if (BarVal<PanelInfo[BarPos].MaxValue)
                             BarVal++; /* Move to next value */
                         else
                         if (BarPos>0) { /*Move to value 0 of prev choice*/
                             BarPos--;
                             BarVal = 0;
                         } else {/* Move to value 0 of last choice */
                             BarPos = NoOfChoices;
                             BarVal = 0;
                         } /* endif */
                      break;
                     } /* endswitch */
                   break;
                } /* endswitch */

            /********* Draw the bar in its new position *********/
            ChangeAttr(ScrollBarColor, ValLen,
               row + PanelInfo[BarPos].Row + BarVal*RowInc,
               col + StartCol + Column*ColInc);
          break;


          case SPACE_BAR :
         /* ahmedt 27/1/91 */
        if ( (Kbdpg1Flag) && ((KbdVioCtrlBlk.ScrInfo & 0x0004) ||
                              (KbdVioCtrlBlk.ScrInfo & 0x0020))
                    && (BarPos == NULL) ) {
          DosBeep(2000,1);
         } else {
                        /* not called from KbdPg1 and not in push mode */
/**** Only do something if the choice is not already highlighted ****/
          if (PanelInfo[BarPos].Value!=BarVal) {
       /*** Adjust the arrow and square **/
            FixArrow(StartCol + (!Column)*ColInc ,/*Draw square on other col*/
               PanelInfo[BarPos].Row+PanelInfo[BarPos].Value*RowInc,
               StartCol + Column*ColInc,
               PanelInfo[BarPos].Row+BarVal*RowInc);

       /*** Redraw the old choice in blue ***/
           ChangeAttr(WindowColor, ValLen,
             row + PanelInfo[BarPos].Row + PanelInfo[BarPos].Value*RowInc,
             col + StartCol + !Column*ColInc);

       /*** Assign the new value ***/
           PanelInfo[BarPos].Value = BarVal;

          }/*If*/
        } /* endif */
          break;
          default:  /* Invalid key pressed */
                DosBeep(1200,100);
       } /* end switch */
      } while(kb.chScan!=1);
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: CHANGEATTR                                        */
/*                                                                     */
/*  DESCRIPTIVE NAME: Changes the attributes of a string.              */
/*                                                                     */
/*  FUNCTION: Changes the attribute of the area starting at the        */
/*            given row and column, for the given Length to the given  */
/*            color. The direction in which this is done depends on    */
/*            the current panel language:                              */
/*               if English panel, the given column is the starting    */
/*               column.                                               */
/*               if National panel, the starting column is <Length>    */
/*               columns to the left of the given column.              */
/*                                                                     */
/*  ENTRY POINT: ChangeAttr                                            */
/*      LINKAGE: CALL NEAR (from PanelMenu).                           */
/*                                                                     */
/*  INPUT: (Color, Length, Row, Col)                                   */
/*         Color   DWORD - The required attribute color.               */
/*         Length  DWORD - The length of the required field.           */
/*         Row     DWORD - The row of the required field.              */
/*         Col     DWORD - The starting column of the required field.  */
/*                                                                     */
/*  EXIT-NORMAL: The required area is highlighted.                     */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:  NONE.                                   */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*         Lang    WORD - Panel language.                              */
/*                                                                     */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtNAttr()                                         */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void ChangeAttr(BYTE Colour,ULONG Length,ULONG Row,ULONG Col)
{
/* Col is start column (logical) of the english and national sentence */
   if (Lang==ENGLISH_PANEL)  /* Start displaying from Col -> Col+Length */
      VioWrtNAttr(&Colour,(USHORT)Length,(USHORT)Row,(USHORT)Col,0);
   else  /* Start displaying from Col-Length -> Col */
      VioWrtNAttr(&Colour,(USHORT)Length,(USHORT)Row,(USHORT)(Col-Length+1),0);
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: FIXARROW                                          */
/*                                                                     */
/*  DESCRIPTIVE NAME: Displays an arrow and a solid square.            */
/*                                                                     */
/*  FUNCTION: Displays a square in the position specified by           */
/*            OldCol and OldRow and an arrow in the position specified */
/*            by NewCol and NewRow.                                    */
/*                                                                     */
/*  ENTRY POINT: FixArrow                                              */
/*      LINKAGE: CALL NEAR (from PanelMenu).                           */
/*                                                                     */
/*  INPUT: (OldCol, OldRow, NewCol, NewRow)                            */
/*         OldCol  DWORD - Column where þ is to be displayed.          */
/*         OldRow  DWORD - Row    where þ is to be displayed.          */
/*         NewCol  DWORD - Column where  is to be displayed.          */
/*         NewRow  DWORD - Row    where  is to be displayed.          */
/*                                                                     */
/*  EXIT-NORMAL: The required arrow and square are displayed.          */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:  NONE.                                   */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*        BYTE WindowColor    - Color to use in display.               */
/*        WORD row            - Row at which the PopUp is displayed.   */
/*        WORD col            - Column at which the PopUp is displayed.*/
/*        WORD Lang           - Panel language (English, National)     */
/* STATIC WORD IncArray[Lang] - Distance between the arrow and the     */
/*                              text for English and National          */
/*                              languages {-2,2}.                      */
/* STATIC CHAR ArrowArray[Lang]                                        */
/*                            - Type of the arrow depending on the     */
/*                              language, {"",""}                    */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: VioWrtCharStrAtt()                                    */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void FixArrow(ULONG OldCol,ULONG OldRow,ULONG NewCol,ULONG NewRow)
{
  VioWrtCharStrAtt("þ",1,(USHORT)(row+OldRow),
                   (USHORT)(col+OldCol+IncArray[Lang]),&WindowColor,0);
  VioWrtCharStrAtt(ArrowArray[Lang],1,(USHORT)(row+NewRow),
                   (USHORT)(col+NewCol+IncArray[Lang]),&WindowColor,0);
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: SETBIT                                            */
/*                                                                     */
/*  DESCRIPTIVE NAME: Sets a bit in a word.                            */
/*                                                                     */
/*  FUNCTION: Sets a bit at a given position in a word to either 0 or  */
/*            1.                                                       */
/*                                                                     */
/*  ENTRY POINT: SetBit                                                */
/*      LINKAGE: CALL NEAR (from SaveChanges).                         */
/*                                                                     */
/*  INPUT: (Position, value, *ReqWord)                                 */
/*         Position  DWORD - Position of the bit in the word.          */
/*                          The position counting starts from zero.    */
/*         value     DWORD - The value to set the bit with.            */
/*         ReqWord  @OTHER - Address of the required word.             */
/*                                                                     */
/*  EXIT-NORMAL: The bit value is changed.                             */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:  NONE.                                   */
/*                                                                     */
/*     GLOBAL DATA DEFINITION: NONE.                                   */
/*                                                                     */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
void SetBit(ULONG Position, ULONG value, ULONG *ReqWord)
{
   if (value == 0) {
      *ReqWord = *ReqWord & (~(1 << Position));
   } else {
      *ReqWord = *ReqWord | (1 << Position);
   } /* endif */
}

/******************** START OF SPECIFICATIONS **************************/
/*                                                                     */
/*  SUBROUTINE NAME: GETBIT                                            */
/*                                                                     */
/*  DESCRIPTIVE NAME: Gets a bit value.                                */
/*                                                                     */
/*  FUNCTION: Returns the value of a bit in a word at a certain        */
/*            position.                                                */
/*                                                                     */
/*  ENTRY POINT: GetBit                                                */
/*      LINKAGE: CALL NEAR (from GetKbdAndLptAtts).                    */
/*                                                                     */
/*  INPUT: (Position, ReqWord)                                         */
/*         Position  DWORD - Position of the bit in the word.          */
/*                          The position counting starts from zero.    */
/*         ReqWord   DWORD - The word which contains that bit.         */
/*                                                                     */
/*  EXIT-NORMAL: The bit value is returned.                            */
/*                                                                     */
/*  EXIT-ERROR:  NONE.                                                 */
/*                                                                     */
/*  SIDE EFFECTS: NONE.                                                */
/*                                                                     */
/*  INTERNAL REFRENCES:                                                */
/*     LOCAL DATA DEFINITION:  NONE.                                   */
/*                                                                     */
/*     GLOBAL DATA DEFINITION: NONE.                                   */
/*                                                                     */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/********************* END OF SPECIFICATIONS ***************************/
/* Get the required bit in the target byte then return with it */

ULONG GetBit(ULONG Position,ULONG ReqWord)
{
   if (ReqWord & (1 << Position))
      return(1L);
   else
      return(0L);
}
