home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cenvi23.zip
/
FSSLAVE.CMM
< prev
next >
Wrap
Text File
|
1994-12-04
|
10KB
|
320 lines
//********************************************************************
//*** FSSlave.cmm - Full-screen OS/2 keystroke slave. Receive ***
//*** ver.2 keystrokes for program running in full-screen. ***
//********************************************************************
#define DEFAULT_KEYDELAY 2000
Instructions()
{
puts(`FSSlave.cmm - Keystroke slave for full-screen OS/2 sessions`)
puts(``)
puts(`SYNTAX: CEnvi2 FSSlave.cmm [Options] <SlaveName> [Commands...]`)
puts(``)
puts(`WHERE: SlaveName - Unique slave name (conform to 8.3 file spec)`)
puts(``)
puts(`OPTIONS: /KEYDELAY=MilliTime - Approximate time between checks for`)
printf(" keystrokes if the keyboard buffer has been empty: default=%d\n",DEFAULT_KEYDELAY);
puts(``)
puts(`EXAMPLES: START /FS /F /N CEnvi2.exe FSSlave NOTES`)
puts(``)
ErrorPrintf("");
}
ErrorPrintf(pString/*...*/)
{
printf("\a");
va_start(va_list,pString);
vprintf(pString,va_list);
printf("\n\aPress any key to exit...");
while( kbhit() ) getch();
getch();
printf("\n");
exit(EXIT_FAILURE);
}
#include <OptParms.lib>
main(argc,argv)
{
Delay = OptionalParameter(argc,argv,"KEYDELAY",lTemp)
? atoi(lTemp) : DEFAULT_KEYDELAY ;
if ( argc < 2 )
Instructions();
// first paramter is the SlaveName
strcpy(SlaveName,argv[1]);
// if any more parameters then they are program to run, else default to
// OS2_SHELL or COMSPEC
if ( 2 < argc ) {
argv += 2;
argc -= 2;
} else {
if ( !(argv[0] = getenv("OS2_SHELL"))
&& !(argv[0] = getenv("COMSPEC")) )
ErrorPrintf("Could not get shell via %s or %s.","OS2_SHELL","COMSPEC");
argc = 1;
}
// we must be running full-screen, or this won't work
MustBeFullScreen();
// start their program running
CmdChild = ( argc == 1 )
? spawn(P_NOWAIT,argv[0])
: spawn(P_NOWAIT,argv[0],argv+1);
if ( -1 == CmdChild )
ErrorPrintf("Error executing %s",argv[0]);
// characters for keyboard will be received in a queue
if ( !StartReceiveQueue(Queue,SlaveName) )
ErrorPrintf("Unable to create message queue for \"%s\".",SlaveName);
// Setup a keyboard monitor to read and pass on keystrokes
if ( !StartKeyboardMonitor(Kbd) )
ErrorPrintf("Unable to start keyboard monitor.");
// stay in this loop as long as the child is running
DelayTime = 0;
while ( IsProcessRunning(CmdChild) ) {
// while keys are available, keep stuffing them
DelayTime += 100;
while ( PassKeycodes(Kbd,GetStuffKeycode(Queue)) )
DelayTime = 0; // key, so do next check quickly
suspend(DelayTime = min(DelayTime,Delay));
}
// close keyboard monitor and msg queue, then all done
EndKeyboardMonitor(Kbd);
EndReceiveQueue(Queue);
return(EXIT_SUCCESS);
}
MustBeFullScreen()
{
#define SESSION_WINDOWABLEVIO 2
#define ORD_DOS32GETINFOBLOCKS 312
DynamicLink("doscalls",ORD_DOS32GETINFOBLOCKS,BIT32,CDECL,
ThreadInfoBlock,ProcessInfoBlock)
SessionType = peek(ProcessInfoBlock + (6 * 4),UWORD32);
if ( SessionType == SESSION_WINDOWABLEVIO )
ErrorPrintf("FSSlave.cmm must run in a full-screen session.");
}
IsProcessRunning(pProcessID)
{
if ( lList = ProcessList(False) ) {
for ( li = GetArraySpan(lList); 0 <= li; li-- ) {
if ( pProcessID == lList[li].id )
return(True);
}
}
return False;
}
DosSetPriority(pScope,pPriorityClass,pPriorityDelta,pID)
{
#define PRTYS_THREAD 2
#define PRTYC_REGULAR 2
#define PRTYC_TIMECRITICAL 3
#define ORD_DOS32SETPRIORITY 236
return DynamicLink("doscalls",ORD_DOS32SETPRIORITY,BIT32,CDECL,
pScope,pPriorityClass,pPriorityDelta,pID);
}
//***********************************************************
//********************** MESSAGE QUEUE **********************
//***********************************************************
StartKeyboardMonitor(pKbd)
{
#define ORD_DOSMONOPEN 4
lRC = DynamicLink("MONCALLS",ORD_DOSMONOPEN,BIT16,PASCAL,"KBD$",lHandle);
if ( (lRC & 0xFFFF) )
return False;
pKbd.Handle = lHandle & 0xFFFF;
// need an input monitor buffer, and output monitor buffer
#define MONITOR_BUFFER_SIZE 2 + 18 + 108
BLObSize(pKbd.MonInBuf,MONITOR_BUFFER_SIZE+1000);
memset(pKbd.MonInBuf,0,MONITOR_BUFFER_SIZE);
BLObPut(pKbd.MonInBuf,0,MONITOR_BUFFER_SIZE,UWORD16);
BLObSize(pKbd.MonOutBuf,MONITOR_BUFFER_SIZE+1000);
memset(pKbd.MonOutBuf,0,MONITOR_BUFFER_SIZE);
BLObPut(pKbd.MonOutBuf,0,MONITOR_BUFFER_SIZE,UWORD16);
// initialize monitor I/O buffers
assert( !DosSetPriority(PRTYS_THREAD,PRTYC_TIMECRITICAL,0,0) );
#define MONITOR_BEGIN 0x0001
#define ORD_DOSMONREG 5
if ( 0xFFFF & DynamicLink("MONCALLS",ORD_DOSMONREG,BIT16,PASCAL,
pKbd.Handle,pKbd.MonInBuf,pKbd.MonOutBuf,
MONITOR_BEGIN,Info().Session) )
return False;
assert( !DosSetPriority(PRTYS_THREAD,PRTYC_REGULAR,0,0) );
return True;
}
EndKeyboardMonitor(pKbd)
{
#define ORD_DOSMONCLOSE 3
DynamicLink("MONCALLS",ORD_DOSMONCLOSE,BIT16,PASCAL,pKbd.Handle);
}
DosMonRead(pMonitorBuffer,pWaitFlag,pDataBuffer,pByteCount)
{
#define ORD_DOSMONREAD 2
BLObPut(lByteCount,pByteCount,UWORD16);
lRC = 0xFFFF & DynamicLink("MONCALLS",ORD_DOSMONREAD,BIT16,PASCAL,
pMonitorBuffer,pWaitFlag,pDataBuffer,lByteCount);
pByteCount = BLObGet(lByteCount,0,UWORD16);
return lRC;
}
PassKeycodes(pKbd,pStuffKey) // return True if key pressed or faked
{ // else False for no keys
// use a key packet to monitor buffer
#define KEYPACKET_SIZE 2 + 10 + 2
BLObSize(lKeyPacket,KEYPACKET_SIZE);
lCount = KEYPACKET_SIZE;
if ( pStuffKey ) {
memset(lKeyPacket,0,KEYPACKET_SIZE);
BLObPut(lKeyPacket,2,pStuffKey,UWORD16);
} else {
// read next from keyboard
#define IO_WAIT 0
#define IO_NOWAIT 1
if ( DosMonRead(pKbd.MonInBuf,IO_NOWAIT,lKeyPacket,lCount) )
return False;
//printf("mnflags = %04X\n",BLObGet(lKeyPacket,0,UWORD16));
//printf("Keycode = %04X\n",BLObGet(lKeyPacket,2,UWORD16));
//printf("fbStatus = %02X\n",BLObGet(lKeyPacket,4,UWORD8));
//printf("bNlsShift = %02X\n",BLObGet(lKeyPacket,5,UWORD8));
//printf("fsState = %04X\n",BLObGet(lKeyPacket,6,UWORD16));
//printf("time = %08X\n",BLObGet(lKeyPacket,8,UWORD32));
//printf("ddflags = %04X\n\n",BLObGet(lKeyPacket,12,UWORD16));
}
#define ORD_DOSMONWRITE 1
DynamicLink("MONCALLS",ORD_DOSMONWRITE,BIT16,PASCAL,
pKbd.MonOutBuf,lKeyPacket,lCount);
return True;
}
// typedef struct _KBDKEYINFO /* kbci */
// {
// UCHAR chChar;
// UCHAR chScan;
// UCHAR fbStatus;
// UCHAR bNlsShift;
// USHORT fsState;
// ULONG time;
// }KBDKEYINFO;
//
// typedef struct _keypacket
// {
// USHORT mnflags;
// KBDKEYINFO cp;
// USHORT ddflags;
// } KEYPACKET;
//************************************************************
//***************** CONSOLE KEYBOARD MONITOR *****************
//************************************************************
StartReceiveQueue(pQueue,pQueueName)
{
sprintf(lQueueName,"\\QUEUES\\%s",pQueueName);
#define QUEUE_FIFO 0
#define QUEUE_LIFO 1
#define ORD_DOS32CREATEQUEUE 16
if ( DynamicLink("QUECALLS",ORD_DOS32CREATEQUEUE,BIT32,CDECL,
lQueueHandle,QUEUE_FIFO,lQueueName) )
return False;
pQueue.Handle = lQueueHandle;
pQueue.KeyCount = 0; // no keys in buffer
return True;
}
EndReceiveQueue(pQueue)
{
#define ORD_DOS32CLOSEQUEUE 11
DynamicLink("QUECALLS",ORD_DOS32CLOSEQUEUE,BIT32,CDECL,pQueue.Handle);
}
GetStuffKeycode(pQueue)
{
lKeyCode = 0; // assume no key
// if there is nothing in the queue then return 0
#define ORD_DOS32QUERYQUEUE 12
if ( !DynamicLink("QUECALLS",ORD_DOS32QUERYQUEUE,BIT32,CDECL,
pQueue.Handle,lQueueCount)
&& lQueueCount ) {
// read the next key character from the queue
#define ORD_DOS32READQUEUE 9
#define DCWW_WAIT 0
#define DCWW_NOWAIT 1
BLObPut(lRequest,0,Info().Process,UWORD32);
if ( !DynamicLink("QUECALLS",ORD_DOS32READQUEUE,BIT32,CDECL,
pQueue.Handle,lRequest,lDataLength,lDataPtr,
0,DCWW_WAIT,lPriority,0) ) {
if ( 0xFACE == peek(lDataPtr,UWORD16) ) {
ReadScreenIntoMemory(lDataPtr+2);
} else {
// the keys will be copied to our keybuffer
BLObPut(pQueue.KeyBuffer,2*pQueue.KeyCount,
peek(lDataPtr+2,lDataLength-2),lDataLength-2);
pQueue.KeyCount += (lDataLength-2) / 2;
}
// put 0 at memory to show it's done
poke(lDataPtr,0,UWORD16);
// that memory was given to use, and so free it
#define ORD_DOS32FREEMEM 304
DynamicLink("DOSCALLS",ORD_DOS32FREEMEM,BIT32,CDECL,lDataPtr);
}
}
if ( pQueue.KeyCount ) {
lKeyCode = BLObGet(pQueue.KeyBuffer,0,UWORD16);
pQueue.KeyBuffer += 2;
if ( !(--pQueue.KeyCount) )
undefine(pQueue.KeyBuffer);
}
return lKeyCode;
}
ReadScreenIntoMemory(pMem)
{
#define MAX_ROW_COUNT 50
#define MAX_COL_COUNT 80
#define ORD_VIOGETMODE 21
// get size of screen
BLObSize(lVioMode,8);
BLObPut(lVioMode,0,8,UWORD16);
DynamicLink("VIOCALLS",ORD_VIOGETMODE,BIT16,PASCAL,lVioMode,0);
lColCount = min(MAX_COL_COUNT,BLObGet(lVioMode,4,UWORD16));
lRowCount = min(MAX_ROW_COUNT,BLObGet(lVioMode,6,UWORD16));
poke(pMem,lColCount,UWORD16);
poke(pMem+2,lRowCount,UWORD16);
#define ORD_VIOREADCHARSTR 30
BLObSize(lBuf,lRowCount*lColCount);
BLObPut(lSize,0,lRowCount*lColCount,UWORD16);
lRc = DynamicLink("VIOCALLS",ORD_VIOREADCHARSTR,BIT16,PASCAL,
lBuf,lSize,0,0,0);
poke(pMem+4,lBuf,lRowCount*lColCount);
}