|
|
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 );
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.