File:  [OS/2 SDKs] / os2sdk / demos / examples / monitors / monitors.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:26:24 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1988, HEAD
Microsoft OS/2 SDK 03-01-1988

/*
 * Example of DosMonOpen, DosGetInfoSeg, DosMonReg,
 *	      DosMonRead, DosMonWrite, DosMonClose usage.
 *
 * Shows how to:
 *
 *	Obtain a keyboard monitor handle, get the handle of the
 *	current foreground screen group, register a pair of i/o
 *	buffers for the current screen group, move data through
 *	the i/o buffers, and finally close connection with the keyboard.
 *
 * Notes:
 *
 *	This program will issue a popup every time the F10 key is pressed.
 *	Pressing escape will terminate the program.
 *	While it is not particularly useful, it does demonstrate a use of
 *	monitors, and proper use of associated monitor calls and structures.
 *
 *	The first 16 bytes of a monitor buffer are devoted to the
 *	header, as described by the MonBuff structure below.  Prior to
 *	registering, the first word (bufflen) must be set to the size
 *	of the entire buffer itself.  The entire buffer includes the
 *	header (16 bytes) and room for at least one data record (16 bytes
 *	in the case of the keyboard device driver), so the minimum size
 *	for this example would be 32 bytes (see MINBUFFSIZE above);
 *	however, some drivers may have slightly different requirements,
 *	in which case you should use the method described next, rather than
 *	assuming some fixed length.
 *
 *	If you wish to monitor a device driver whose data record size
 *	is unknown, pick a convenient size and attempt a call to DosMonReg.
 *	If it fails due to ERROR_NOT_ENOUGH_MEMORY, examine the 2nd word
 *	of your buffer, since it will now contain the size of the driver's
 *	buffer (ddbufflen in the example).  Allocate buffer(s) which can
 *	hold a data record of that size (in addition to the 16-byte header)
 *	and re-register your buffer(s).  If the same error occurs, then
 *	there is simply insufficient resources to support another monitor.
 *
 *	Note the MonBuff header structure does not define the monitor buffer
 *	beyond the header, because data records (KeyPackets in this example)
 *	are transferred to and from the buffers by DosMonRead and DosMonWrite.
 *	You should not attempt to read or write that area directly, nor should
 *	you modify any part of the header after a successful DosMonReg.
 *
 *	To maintain a rapid flow of data through any chain of monitors,
 *	DosMonRead and DosMonWrite operations should be done without any
 *	intervening slow operations or system calls. If necessary, dedicate
 *	a thread to the monitor stream, and raise its priority.
 *
 * Makefile:
 *
 *     LIB=\lib
 *     INC=\include
 *     OPT=-AL -G2 -Zi -Lp -Ox -Zp -I$(INC)
 *
 *     monitors.exe:   monitors.c monitors
 *		     cl $(OPT) monitors.c
 *
 *
 * To Run:
 *	     detach monitors
 *
 *
 * Created by Microsoft Corp. 1988
 */

#define INCL_DOSPROCESS
#define INCL_SUB
#define INCL_DOSMONITORS
#define INCL_DOSINFOSEG

#include <malloc.h>		/* for malloc() declaration */
#include <os2def.h>
#include <bse.h>


#define CON		0		/* Handle for the console device */

#define NOPREFERENCE	0		/* DosMonReg constants - */
#define FRONT		1		 /* where in the monitor chain */
#define BACK		2		 /* do we want to be installed? */


#define NOERROR 	0		/* DOSEXIT constants - */
#define ERROR		1		 /* what to return for error code? */

#define ESCAPE		27		/* ASCII constant */
#define F10		68		/* SCAN code constant */

#define RELEASE 	0x40		/* bit mask to distinguish */
					/* key press from key release */

#define MINBUFFSIZE	64		/* size for monitor buffers */
					/* 64 is minimum, 128 recommended */


struct KeyPacket {			/* KBD monitor data record */
	unsigned       mnflags;
	KBDKEYINFO     cp;
	unsigned       ddflags;
};

struct MonBuff {			/* generic monitor buffer header */
	unsigned	bufflen;
	unsigned	ddbufflen;
	unsigned char	dispatch[12];
};


HKBD	KBDHandle;	     /* keyboard handle from monitor open */

struct MonBuff	*InBuff, *OutBuff;     /* buffers for monitor read/writes */


					/* message strings */
char *startMsg[] = {
	    "�������������������������������������������������������Ŀ",
	    "�                                                       �",
	    "�             Example Monitor installed                 �",
	    "�                                                       �",
	    "�               press Esc to terminate                  �",
	    "�                                                       �",
	    "���������������������������������������������������������",
	    0};

char *intMsg[] = {
	    "�������������������������������������������������������Ŀ",
	    "�                                                       �",
	    "�       <<<  The F10 key has been struck  >>>           �",
	    "�                                                       �",
	    "�             press any key to continue                 �",
	    "�                                                       �",
	    "���������������������������������������������������������",
	    0};


main()
{
	struct KeyPacket  keybuff;
	PGINFOSEG gdt;
	KBDKEYINFO dummy;

	USHORT	count;	    /* chars in monitor read/write buffer */
	SEL gdt_descriptor, ldt_descriptor;   /* infoseg descriptors */
	unsigned waitflag = 1;			       /* flag for popups */
	USHORT row, col = 3;	      /* where to draw popup box */
	USHORT length;			/* length of lines in popup box */
	char **msg;				   /* to display messages */
	char *pc;				    /* to test characters */


	/* initialize this value */
	for ( length = 0, pc = *intMsg; *pc; pc++, length++)
	    ;

	/* allocate space for monitor read/write buffers */
	InBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
	OutBuff = (struct MonBuff *)malloc(MINBUFFSIZE);

	/* prepare buffer headers for registration process */
	InBuff->bufflen = MINBUFFSIZE;
	OutBuff->bufflen = MINBUFFSIZE;

	/* obtain a handle for registering buffers */
	DosMonOpen ( "KBD$", &KBDHandle );

	/* get the descriptor of global infoseg */
	/* and convert to far pointer so we can */
	/* get ID of current foreground screen group */
	DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor);
	gdt = MAKEPGINFOSEG(gdt_descriptor);

	/* register the buffers to be used for monitoring */
	DosMonReg ( KBDHandle, (PBYTE)InBuff, (PBYTE)OutBuff, FRONT,
		     gdt->sgCurrent);

	/* Print a banner to show we've started */
	VioPopUp(&waitflag, CON);
	for (row = 2, msg = startMsg; *msg;)
	    VioWrtCharStr(*msg++, length, row++, col, CON);
	DosSleep(3000L);
	VioEndPopUp(CON);


	/* main loop - read into monitor buffer, examine and take */
	/* action if "interesting" key, pass on to device driver */
	for (keybuff.cp.chChar = 0; keybuff.cp.chChar != ESCAPE;) {
		count = sizeof(keybuff);
		DosMonRead ((PBYTE)InBuff, IO_WAIT,
			     (PBYTE)&keybuff, (PUSHORT)&count );
		if ( ( keybuff.cp.chChar == 0 ) &&
		     ( keybuff.cp.chScan == F10 ) &&
		     ( ! ( keybuff.ddflags & RELEASE ) ) )  {
			VioPopUp(&waitflag, CON);
			for (row = 2, msg = intMsg; *msg;)
			    VioWrtCharStr(*msg++, length, row++, col, CON);
			KbdCharIn( &dummy, IO_WAIT, CON);
			VioEndPopUp(CON);
		}

		DosMonWrite ( (PBYTE)OutBuff,
			      (PBYTE)&keybuff, count );
	}

	/* close connection with keyboard */
	DosMonClose ( KBDHandle );

	DosExit ( EXIT_PROCESS, NOERROR );


}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.