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