Here's a mini app (all error handling, comments, etc. removed.)
(also all this stuff to avoid compile warnings !!!!!). compile with: icc
-Sm -Kabgioprx+ -Ss+ -W3 -Gs+ -Gf+ -O+ KEY.C
start with: detach key
stop with: F11 or CTRL-F10
test envir: OS/2 2.0GA+SP, C-Set++ CSD 22.
no other functionality.
orginal src part of my glorious DOS/OS2 1.x/OS2 2.0 keyboard roboter which inserts keys into the keyboard monitor queue controlled by an source file (mini language).
(C) Mario Semo 1777,1832,1967-92.
========= TOP OF FILE KEY.C ================
#define INCL_DOS
#define INCL_KBD
#define INCL_NOPM
#include<os2.h>
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<stdlib.h>
#include<string.h>
#define DosMonOpen DOS16MONOPEN
#define DosMonClose DOS16MONCLOSE
#define DosMonReg DOS16MONREG
#define DosMonRead DOS16MONREAD
#define DosMonWrite DOS16MONWRITE
#define MONITOR_DEFAULT 0x0000
#define MONITOR_BEGIN 0x0001
#define MONITOR_END 0x0002
typedef SHANDLE HMONITOR; /* hmon */
typedef HMONITOR *PHMONITOR;
#pragma pack(2)
typedef struct _MONIN { /* mnin */
USHORT cb;
BYTE abReserved[18];
BYTE abBuffer[108];
} MONIN;
typedef MONIN *PMONIN;
#pragma pack(2)
typedef struct _MONOUT { /* mnout */
USHORT cb;
UCHAR buffer[18];
BYTE abBuf[108];
} MONOUT;
typedef MONOUT *PMONOUT;
APIRET16 APIENTRY16 DosMonOpen(PSZ pszDevName, PHMONITOR phmon);
APIRET16 APIENTRY16 DosMonClose(HMONITOR hmon);
APIRET16 APIENTRY16 DosMonReg(HMONITOR hmon, PBYTE pbInBuf,
PBYTE pbOutBuf, USHORT fPosition, USHORT usIndex);
APIRET16 APIENTRY16 DosMonRead(PBYTE pbInBuf, USHORT fWait,
PBYTE pbDataBuf,
PUSHORT pcbData);
APIRET16 APIENTRY16 DosMonWrite(PBYTE pbOutBuf, PBYTE pbDataBuf,
USHORT cbData);
#define DosGetInfoSeg DOS16GETINFOSEG
APIRET16 APIENTRY16 DosGetInfoSeg(PSEL pselGlobal, PSEL pselLocal);
#pragma pack(2)
typedef struct _GINFOSEG { /* gis */
ULONG time; ULONG msecs; UCHAR hour;
UCHAR minutes; UCHAR seconds; UCHAR hundredths;
USHORT timezone; USHORT cusecTimerInterval; UCHAR day;
UCHAR month; USHORT year; UCHAR weekday;
UCHAR uchMajorVersion; UCHAR uchMinorVersion;
UCHAR chRevisionLetter; UCHAR sgCurrent;
UCHAR sgMax; UCHAR cHugeShift;
UCHAR fProtectModeOnly; USHORT pidForeground;
UCHAR fDynamicSched; UCHAR csecMaxWait;
USHORT cmsecMinSlice; USHORT cmsecMaxSlice;
USHORT bootdrive; UCHAR amecRAS[32];
UCHAR csgWindowableVioMax; UCHAR csgPMMax;
} GINFOSEG;
typedef GINFOSEG *PGINFOSEG;
static PGINFOSEG gdt;
#define MAKEPGINFOSEG(sel) ((PGINFOSEG)MAKEP(sel, 0))
#define MAKEPLINFOSEG(sel) ((PLINFOSEG)MAKEP(sel, 0))
#pragma pack(2)
typedef struct _keypacket
{
USHORT mnflags;
KBDKEYINFO cp;
USHORT ddflags;
} KEYPACKET;
#define RELEASE 0x40
#define CTL_F10_KEY 103
#define F11_KEY 133
#pragma stack16(8192)
#pragma seg16(HKBD)
#pragma seg16(MONIN)
#pragma seg16(MONOUT)
#pragma seg16(KEYPACKET)
static HKBD KBDHandle = (HKBD)0;
static PGINFOSEG _Seg16 gdt;
static MONIN monInbuf = {0};
static MONOUT monOutbuf = {0};
static HEV hevThreadDone = (HEV)0;
static void _System keyboard_monitor(ULONG Dummy);
int main(int argc, char *argv[], char *envp[])
{
SEL gdt_descriptor, ldt_descriptor;
PID pidKeybrd;
monInbuf.cb = sizeof(MONIN);
monOutbuf.cb = sizeof(MONOUT);
DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor);
gdt = MAKEPGINFOSEG(gdt_descriptor);
DosMonOpen ( "KBD$", &KBDHandle );
DosCreateEventSem(NULL, &hevThreadDone,0,FALSE);
if (DosCreateThread(&pidKeybrd, &keyboard_monitor, 0L, 2L, 12000L))
DosExit(EXIT_PROCESS,0);
DosWaitEventSem(hevThreadDone, (ULONG)SEM_INDEFINITE_WAIT);
DosMonClose(KBDHandle);
DosBeep(100,100);
DosExit(EXIT_PROCESS,0);
return(0);
}
static void _System keyboard_monitor(ULONG Dummy)
{
KEYPACKET keybuff;
USHORT count;
DosSetPrty(PRTYS_THREAD, PRTYC_TIMECRITICAL,0, 0);
DosMonReg( KBDHandle, (PBYTE)&monInbuf, (PBYTE)&monOutbuf,
MONITOR_BEGIN, gdt->sgCurrent);
DosSetPrty(PRTYS_THREAD, PRTYC_REGULAR,0, 0);
for(keybuff.cp.chChar = 0; ; )
{
count = sizeof(keybuff);
DosMonRead( (PBYTE)&monInbuf, IO_WAIT, (PBYTE)&keybuff, &count);
if (!(keybuff.ddflags & RELEASE))
{
if(keybuff.cp.chChar == 0)
{
switch (keybuff.cp.chScan)
{
case CTL_F10_KEY :
case F11_KEY :
DosPostEventSem(hevThreadDone);
DosExit(EXIT_THREAD,0);
break;
}
}
}
DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&keybuff,count);
}
}
Credit: Mario Semo