/********************* START OF SPECIFICATIONS *************************/
/*                                                                     */
/*  SUBROUTINE NAME: NLSINTQUERYBIDIATT                                */
/*                                                                     */
/*  DESCRIPTIVE NAME: Queries the contents of the control block.       */
/*                                                                     */
/*  COPYRIGHT: (c) IBM Corp. 1989                                      */
/*                                                                     */
/*  FUNCTION: The NlsIntQueryBidiAtt retrieves the BiDi Attributes for */
/*            any of the sessions or for any of the three printers     */
/*            connected to the system.                                 */
/*                                                                     */
/*  ENTRY POINT: NlsIntQueryBidiAtt                                    */
/*      LINKAGE: CALL FAR (from any internal component).               */
/*                                                                     */
/*  INPUT:       (Scope,Effect,RetInfo)                                */
/*               Scope (DWORD)    - Session identifier                 */
/*               Effect (DWORD)   - Select Keyboard/Video or printer   */
/*               RetInfo (@Other) - Address of an area for the API to  */
/*                                  return the BiDi data in it.        */
/*                                                                     */
/*  EXIT-NORMAL: RC = 0                                                */
/*                                                                     */
/*  EXIT-ERROR:  RC = ERROR_BIDI_INVALID_SCOPE                         */
/*               RC = ERROR_BIDI_INVALID_EFFECT                        */
/*               RC = ERROR_BIDI_INVALID_COMBINATION                   */
/*               RC = ERROR_BIDI_INVALID_LENGTH                        */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*     LOCAL DATA DEFINITION:                                          */
/*            WORD ActualLength - Contains the first word of the       */
/*                                control block.                       */
/*            DWORD CBcount     - Dummy counter.                       */
/*            DWORD ReturnCode  - Used by the called functions.        */
/*            @OTHER ShrPtr     - Pointer to a structure of type       */
/*                                bididseg.                            */
/*            @OTHER RetInfo    - Pointer to a structure of type       */
/*                                retinfo.                             */
/*                                                                     */
/*     GLOBAL DATA DEFINITION:                                         */
/*                                                                     */
/*          STRUCT RETINFO  - Structure of the area in which the API   */
/*                            returns the BiDi attributes.             */
/*                            It consists of the following:            */
/*                             DWORD length        - Length of the     */
/*                                                   structure.        */
/*                             BYTE ReturnArea[78] - Rest of the       */
/*                                                   structure.        */
/*                                                                     */
/*          STRUCT lptblock - Structure of the printer control block   */
/*                            It consists of the following:            */
/*                             DWORD  LptLength  - Length of the       */
/*                                                 control block.      */
/*                             BYTE  LptArea[18] - Rest of the control */
/*                                                 block               */
/*                                                                     */
/*          STRUCT KBVBLOCK - Structure of the keyboard video          */
/*                            control block.                           */
/*                            It consists of the following:            */
/*                             WORD  KbvLength   - Length of the       */
/*                                                 control block.      */
/*                             BYTE  KbvArea[78] - Rest of the control */
/*                                                 block               */
/*                                                                     */
/*          STRUCT bididseg - Structure of the BiDi data segment       */
/*                            It consists of the following:            */
/*                             BYTE  reserved[320] - Reserved area     */
/*                             lptblock  lpt[3]    - Printers area     */
/*                             kbvblock  kbvcb[17] - Keyboard video    */
/*                                                   area.             */
/*                                                                     */
/*     ROUTINES: NONE.                                                 */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*     ROUTINES: NlsQueryBidisegAddress()                              */
/*                                                                     */
/********************** END OF SPECIFICATIONS **************************/
#define  INCL_BASE
#include <os2.h>
#include "bdcalls.h"        /* include the Bidi Data Segment structure, */
#include "sq.h"             /* the RetInfo Structure.                   */

USHORT EXPENTRY NlsQueryBidisegAddress (ULONG);

USHORT far pascal _loadds NlsIntQueryBidiAtt (LONG Scope,
                                              LONG Effect,
                                              PRETINFO retinfo)

{
/*-----------------------------------------------------------------------*/
/*                         Variables Definition                          */
/*-----------------------------------------------------------------------*/
   int      ActualLength;
   USHORT   CBcount;
   RETINFO  *RetInfo;
   USHORT   RC=0;
   struct   bididseg  *ShrPtr;
/*-----------------------------------------------------------------------*/
/* Insure that the I/P parms are valid                                   */
/*-----------------------------------------------------------------------*/
   RetInfo = (RETINFO*) retinfo;

   RC = NlsQueryBidisegAddress ((ULONG)&ShrPtr);
                                               /* Get the address of the */
                                               /* BiDi data segment      */
   if(RC !=0) return (RC);         /* e.g ERROR_BIDI_NO_SUPPORT */

   if (!(Scope >= MIN_SCOPE && Scope <= SCOPE_LIMIT))
      return(ERROR_BIDI_INVALID_SCOPE);            /* Scope out of range */
                                                   /* -1 <= Scope <= 15  */

   if (!(Effect >= NULL && Effect <= EFFECT_LIMIT))
                                                 /* Effect out of range */
      return(ERROR_BIDI_INVALID_EFFECT);
                                     /* The inputs parameters are valid */
                                     /* Is it required to query for the */
                                     /* BiDi Keyboard Video Control     */
                                     /* Block or for the BiDi Printer   */
                                     /* Control Block                   */

   if (Scope != NULL && Effect != NULL)
      return(ERROR_BIDI_INVALID_COMBINATION);

   if (Effect == NULL) {
                                         /* Query for the Bidi keyboard */
                                         /* video control block         */
      Scope++;                           /*  0 <= Scope <= 16           */
      ActualLength = ShrPtr -> kbvcb[Scope].KbvLength;

      if ( RetInfo -> length < 2 )
          return(ERROR_BIDI_INVALID_LENGTH);

      if ( RetInfo -> length == 2 ) {   /* return the actual length of  */
                                        /* the control block            */
         RetInfo -> length = ActualLength;
         return (NO_ERROR);
      }

      if ( RetInfo -> length > 2 && RetInfo -> length <= ActualLength ) {
                                      /* Copy the specified length from */
                                      /* BDKBVCB[Scope] to RetInfo      */
         for ( CBcount = 0; CBcount < RetInfo -> length - 2; CBcount++ )
            RetInfo -> ReturnArea[CBcount] =
            ShrPtr -> kbvcb[Scope].KbvArea[CBcount];
         return (NO_ERROR);
      }
      else {               /* if ( RetInfo -> length > ActualLength )   */
                           /* Copy all the BDKBVCB[Scope] to RetInfo    */
                           /* and update RetInfo.length to ActualLength */
         for ( CBcount = 0; CBcount < ActualLength -2; CBcount++ )
            RetInfo -> ReturnArea[CBcount] =
            ShrPtr -> kbvcb[Scope].KbvArea[CBcount];
         RetInfo -> length = ActualLength;
         return (NO_ERROR);
      }
   }
   else  {                   /* Query for the Bidi printer cotrol block */
          ActualLength = ShrPtr -> lpt[Effect - 1].LptLength;
          if ( RetInfo -> length < 2 ) {
             return(ERROR_BIDI_INVALID_LENGTH);
          }

      if ( RetInfo -> length == 2 ) {
                        /* Query the actual length of the control block */
         RetInfo -> length = ActualLength;
         return (NO_ERROR);
      }

      if ( RetInfo -> length > 2 && RetInfo -> length <= ActualLength ) {
                                      /* Copy the specified length from */
                                      /* BDPRCB[Effect - 1] to RetInfo  */
         for ( CBcount = 0; CBcount < RetInfo -> length - 2; CBcount++ )
            RetInfo -> ReturnArea[CBcount] =
            ShrPtr -> lpt[Effect - 1].LptArea[CBcount];
         return (NO_ERROR);
      }
      else {                 /* if ( RetInfo -> length > ActualLength ) */
                             /* Copy all the BDPRCB[Effect - 1] to      */
                             /* RetInfo and update RetInfo.length to    */
                             /* ActualLength                            */
         for ( CBcount = 0; CBcount < ActualLength - 2; CBcount++ )
            RetInfo -> ReturnArea[CBcount] =
            ShrPtr -> lpt[Effect - 1].LptArea[CBcount];
         RetInfo -> length = ActualLength;
         return (NO_ERROR);
      }
   }
 }                                                        /*end program */
