HP OpenVMS Systemsask the wizard |
The Question is: how do I setup the terminator-set argument for smg$read_string in C. I am trying to define up/down arrow keys as terminators for a string input. The Answer is :
/*
// SMG$READ_STRING.C
//
// Demonstration of using SMG$READ_STRING.C, dynamic string
// descriptors, various other SMG and OpenVMS calls.
//
// Stephen Hoffman, Compaq Computer Corporation
// Based on various other examples of SMG$READ_STRING found
// around, updated to DEC C, various updates and changes made.
//
// To build:
// $ cc/decc/prefix=all SMG$READ_STRING
// $ link SMG$READ_STRING
//
*/
#include <descrip.h>
#include <lib$routines.h>
#include <smgdef.h>
#include <smg$routines.h>
#include <ssdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <stsdef.h>
#include <unistd.h>
struct TerminatorSetLongForm
{
unsigned short int MaskSize;
unsigned short int NotUsed;
void *MaskAddr;
} TrmByRef;
struct TerminatorSetShortForm
{
unsigned short int MaskSize;
unsigned short int NotUsed;
long BitMask;
} TrmByVal;
main()
{
int RetStat;
int DispRows = 22, DispCols = 78, PasteRow = 2, PasteCol = 2;
unsigned int NewPBId, DispId, KeybId;
unsigned short int Message1Len, Message2Len, DDLen = 80;
unsigned long int BitMask;
struct dsc$descriptor_d Message1Dsc =
{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
struct dsc$descriptor_d Message2Dsc =
{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
$DESCRIPTOR(Prompt1Dsc, "Enter string terminated by ^A: ");
$DESCRIPTOR(Prompt2Dsc, "Enter string terminated by ^B: ");
printf("\n");
printf("SMG$READ_STRING demonstration program\n");
printf("\n");
printf("You must issue SET TERMINAL/NOLINE_EDITING before\n");
printf("attempting to use this program, otherwise the program\n");
printf("will not be able to receive and process the required\n");
printf("control characters.\n");
printf("\n");
printf("SMG$READ_STRING is now pausing briefly...\n");
sleep( 5 );
printf("Now continuing execution...\n");
RetStat = lib$sget1_dd( &DDLen, &Message1Dsc );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
RetStat = lib$sget1_dd( &DDLen, &Message2Dsc );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
/*
// Set up long form terminator
// ^A (bit 1) is the terminator
*/
TrmByRef.MaskSize = 4;
TrmByRef.NotUsed = 0;
TrmByRef.MaskAddr = &BitMask;
BitMask = 1L<<1;
/*
// Set up short form terminator.
// ^B (bit 2) is the terminator.
*/
TrmByVal.MaskSize = 0;
TrmByVal.NotUsed = 0;
TrmByVal.BitMask = 1L<<2;
/*
// establish terminal screen as pasteboard
*/
RetStat = SMG$CREATE_PASTEBOARD(&NewPBId, 0,0,0,0);
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
/*
// establish a virtual keyboard
*/
RetStat = SMG$CREATE_VIRTUAL_KEYBOARD(&KeybId);
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
/*
// establish a virtual display region
*/
RetStat = SMG$CREATE_VIRTUAL_DISPLAY(&DispRows, &DispCols, &DispId, 0,0,0);
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
/*
// paste virtual display to pasteboard at row 1, col 1
*/
RetStat = SMG$PASTE_VIRTUAL_DISPLAY(&DispId, &NewPBId, &PasteRow, &PasteCol);
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
/*
// Do what we came here to do...
*/
RetStat = SMG$READ_STRING(&KeybId, &Message1Dsc,
&Prompt1Dsc,0,0,0,&TrmByRef,&Message1Len,0,0,0,0,0,0);
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
PasteRow += 2;
RetStat = SMG$SET_CURSOR_ABS( &DispId, &PasteRow, &PasteCol );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
RetStat = SMG$PUT_LINE( &DispId, &Message1Dsc, 0,0,0,0,0,0 );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
PasteRow += 2;
RetStat = SMG$SET_CURSOR_ABS( &DispId, &PasteRow, &PasteCol );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
RetStat = SMG$READ_STRING(&KeybId, &Message2Dsc,
&Prompt2Dsc,0,0,0,&TrmByVal,&Message2Len,0,0, 0,0,0,0);
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
PasteRow += 2;
RetStat = SMG$SET_CURSOR_ABS( &DispId, &PasteRow, &PasteCol );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
RetStat = SMG$PUT_LINE( &DispId, &Message2Dsc, 0,0,0,0,0,0 );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
sleep( 1 );
/*
// Free up the dynamic string descriptors before exiting.
*/
RetStat = lib$sfree1_dd( &Message1Dsc );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
RetStat = lib$sfree1_dd( &Message2Dsc );
if (!$VMS_STATUS_SUCCESS( RetStat ))
return RetStat;
return SS$_NORMAL;
}
|