Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

KbdGetStatus

2 views
Skip to first unread message

Peter Moylan

unread,
Apr 4, 1998, 3:00:00 AM4/4/98
to

Is there any special trick that's needed when calling
KbdGetStatus from a VIO application? When I try it my program
locks up solid, and I end up with an unkillable process.
The symptoms are the same whether I run full-screen or in
an OS/2 window.

Alternatively, is there any other way (in a VIO application) to
find out the current state of the Caps Lock, Num Lock, and
Scroll Lock keys?

--
Peter Moylan pe...@ee.newcastle.edu.au
OS/2 tuning tips at
http://www.ee.newcastle.edu.au/users/staff/peter/os2/tuning.html

Martin Lafaix

unread,
Apr 4, 1998, 3:00:00 AM4/4/98
to

In article <6g5ana$h8m$2...@seagoon.newcastle.edu.au>,

pe...@PJM2.newcastle.edu.au (Peter Moylan) wrote:
>Alternatively, is there any other way (in a VIO application) to
>find out the current state of the Caps Lock, Num Lock, and
>Scroll Lock keys?

The following allows to query/set keyboard state. It works on both
windowed and fullscreen sessions. (The WinXxx functions are needed
when in windowed sessions.) Quite dusty, but should compile as-is
(be sure to remove my sig :-)

Hope this helps.


/***************************************************************************\
* keybset.c - this is the VIO part of the ShiftLock project 950403
*
* Copyright (c) 1995 Martin Lafaix. All Rights Reserved.
\***************************************************************************/

#define INCL_DOSFILEMGR
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_WININPUT

#include <os2.h>
#include <stdio.h>

HFILE hf;
SHIFTSTATE ss;
BYTE KeyState[257];
BOOL bFlag;
APIRET rc;


static VOID _error(const char *pch)
/*
* This function prints an error message on stderr, and halts program
* execution.
*
* Input: pch - the offending command-line parameter.
* Returns: 1.
*/
{
fprintf(stderr, "KEYBSET: error - Invalid switch : %s\n", pch);
exit(1);
}

static VOID _verbose(VOID)
/*
* This function prints program information on stdout.
*
* Returns: nothing.
*/
{
puts("Operating System/2 Keyboard Flags Modifier");
puts("Version 0.0.003 Apr 3 1995");
puts("(C) Copyright Martin Lafaix 1995");
puts("All rights reserved.\n");

puts("Usage: keybset [option[:[ON|OFF]]] ...");
puts(" /Capslock");
puts(" /Numlock");
puts(" /Scrolllock");
puts(" /Query");
}

static VOID _setflag(BOOL bSet, USHORT usvk, USHORT usflag)
/*
* This function sets or resets specified flag.
*
* We use the KeyState and ss global structures.
*
* Input: bSet - new flag state.
* usvk - flag's corresponding virtual key code.
* usflag - flag's corresponding value.
* Returns: nothing.
*/
{
if(bSet)
{
KeyState[usvk] |= 0x01;
ss.fsState |= usflag;
}
else
{
KeyState[usvk] &= ~0x01;
ss.fsState &= ~usflag;
}
}

static VOID _readstate(VOID)
/*
* This function reads the current keyboard state, and stores the results
* in the KeyState and ss global structures.
*
* We use the hf global variable, as well as the KeyState and ss global
* structures.
*
* Returns: nothing.
*/
{
ULONG ulAction, ulLength;

rc = DosOpen("KBD$",
&hf,
&ulAction,
0L,
0,
FILE_OPEN,
OPEN_ACCESS_READONLY|OPEN_SHARE_DENYNONE,
0);

ulAction = 0;
ulLength = sizeof(ss);
rc = DosDevIOCtl(hf,
IOCTL_KEYBOARD,
KBD_GETSHIFTSTATE,
0,
0,
&ulAction,
&ss,
sizeof(ss),
&ulLength);

WinSetKeyboardStateTable(HWND_DESKTOP, KeyState, FALSE);
}

static VOID _querystate(VOID)
/*
* This function queries and displays keyboard information.
*
* We use the hf global variable as well as the ss global structure.
*
* Returns: nothing.
*/
{
ULONG ulAction, ulLength;
KBDTYPE kt;
CPID cpid;
PCHAR pch;
#pragma pack(2)
struct {USHORT usLength; USHORT usCp; CHAR ach[8];} kcp;
#pragma pack()

printf("Keyboard state : 0x%04x (Num:%s Caps:%s Scroll:%s), fNLS = %d\n",
ss.fsState,
ss.fsState & NUMLOCK_ON ? "ON" : "OFF",
ss.fsState & CAPSLOCK_ON ? "ON" : "OFF",
ss.fsState & SCROLLLOCK_ON ? "ON" : "OFF",
ss.fNLS);

ulAction = 0;
ulLength = sizeof(kt);
rc = DosDevIOCtl(hf, IOCTL_KEYBOARD, KBD_GETKEYBDTYPE,
0, 0, &ulAction,
&kt, sizeof(kt), &ulLength);

printf(" type : 0x%04x (", kt.usType);
switch(kt.usType)
{
case 0x00:
puts("PC AT Keyboard)");
break;
case 0x01:
puts("Enhanced Keyboard)");
break;
default:
puts("Unknown Keyboard Type)");
break;
}

ulAction = 0;
ulLength = cpid.idCodePage = sizeof(cpid);
rc = DosDevIOCtl(hf, IOCTL_KEYBOARD, 0x7A,
0, 0, &ulAction,
&cpid, sizeof(cpid), &ulLength);

printf(" ID : 0x%04x (", cpid.Reserved);
switch(cpid.Reserved)
{
case 0x0001:
puts("PC AT Standard Keyboard)");
break;
case 0xAB41:
puts("101/102 Key Enhanced Keyboard)");
break;
case 0xAB54:
puts("88/89 Key Enhanced Keyboard)");
break;
case 0xAB86:
puts("122 Key Mainframe Interactive (MFI) Keyboard)");
break;
default:
puts("Unknown Keyboard ID)");
break;
}

ulAction = 0;
ulLength = kcp.usLength = sizeof(kcp);
rc = DosDevIOCtl(hf, IOCTL_KEYBOARD, 0x7B, 0, 0, &ulAction,
&kcp, sizeof(kcp), &ulLength);

printf(" layout : CP = %d, Country = \"%s\"", kcp.usCp, kcp.ach);
for(pch = kcp.ach; *pch++; );
printf(", Subcountry = \"%s\"\n", pch);

printf("\nPM virtual state: Num:%s (%02x) Caps:%s (%02x) Scroll:%s (%02x)\n",
KeyState[VK_NUMLOCK] & 1 ? "ON" : "OFF", KeyState[VK_NUMLOCK],
KeyState[VK_CAPSLOCK] & 1 ? "ON" : "OFF", KeyState[VK_CAPSLOCK],
KeyState[VK_SCRLLOCK] & 1 ? "ON" : "OFF", KeyState[VK_SCRLLOCK]);

ulAction = sizeof(cpid);
ulLength = 0;
rc = DosDevIOCtl(hf, IOCTL_KEYBOARD, KBD_GETCODEPAGEID,
&cpid, sizeof(cpid), &ulAction,
0, 0, &ulLength);

printf("Current CodePage: %d\n", cpid.idCodePage);
}

static VOID _writestate(VOID)
/*
* This function sets the keyboard state as described by the KeyState
* and ss global structures.
*
* We use the hf global variable as well as the KeyState and ss global
* structures.
*
* Returns: nothing.
*/
{
ULONG ulAction, ulLength;

WinSetKeyboardStateTable(HWND_DESKTOP, KeyState, TRUE);

ulAction = sizeof(ss);
ulLength = 0;
rc = DosDevIOCtl(hf,
IOCTL_KEYBOARD,
KBD_SETSHIFTSTATE,
&ss,
sizeof(ss),
&ulAction,
0,
0,
&ulLength);

rc = DosClose(hf);
}

static BOOL _is(const char *pchOpt, const char *achName)
/*
* This function compares pchOpt with achName. If pchOpt is an abbreviation
* of achName, it returns TRUE.
*
* Side effect: bFlag is set if pchOpt ends with "", ":" or ":on". It is
* cleared otherwise.
*
* Input: pchOpt - the parameter to examine.
* achName - the reference value (in lowercase).
* Returns: TRUE if pchOpt is an abbreviation of achName, FALSE otherwise.
*/
{
BOOL bRet = TRUE;

bFlag = TRUE;

if((pchOpt[0] == '-' || pchOpt[0] == '/') && pchOpt[1])
{
while(*++pchOpt && *achName && (*pchOpt|32) == *achName++);

if(*pchOpt)
if(*pchOpt == ':')
bFlag = pchOpt[1] == 0 || ((pchOpt[1]|32) == 'o' && (pchOpt[2]|32) == 'n');
else
bRet = FALSE;
}
else
bRet = FALSE;

return bRet;
}

int main(int argc, char *argv[], char *envp[])
{
USHORT w;

if(argc == 1 || (argc == 2 && argv[1][0] == '/' && argv[1][1] == '?'))
{
_verbose();
return 0;
}

_readstate();

for(w = 1; w < argc; w++)
if(_is(argv[w], "numlock"))
_setflag(bFlag, VK_NUMLOCK, NUMLOCK_ON);
else
if(_is(argv[w], "capslock"))
_setflag(bFlag, VK_CAPSLOCK, CAPSLOCK_ON);
else
if(_is(argv[w], "scrolllock"))
_setflag(bFlag, VK_SCRLLOCK, SCROLLLOCK_ON);
else
if(_is(argv[w], "query"))
_querystate();
else
_error(argv[w]);

_writestate();

return 0;
}

--
Martin Lafaix <laf...@ibm.net>
Team OS/2
http://www.mygale.org/~lafaix

Peter Moylan

unread,
Apr 6, 1998, 3:00:00 AM4/6/98
to

Martin Lafaix <laf...@ibm.net> wrote:
>In article <6g5ana$h8m$2...@seagoon.newcastle.edu.au>,
>pe...@PJM2.newcastle.edu.au (Peter Moylan) wrote:
>>Alternatively, is there any other way (in a VIO application) to
>>find out the current state of the Caps Lock, Num Lock, and
>>Scroll Lock keys?
>
>The following allows to query/set keyboard state. It works on both
>windowed and fullscreen sessions. (The WinXxx functions are needed
>when in windowed sessions.) Quite dusty, but should compile as-is
>(be sure to remove my sig :-)

[Code snipped]

Thanks, Martin, this should help a lot. I was hoping to avoid having
to understand the rather sketchy DosDevIOCtl documentation, but
if that's what it takes ...

I would never have guessed that WinSetKeyboardStateTable
was needed for a VIO application. Chalk up one more thing I've
learnt today.

Cindy Ross

unread,
Apr 6, 1998, 3:00:00 AM4/6/98
to

In <6g5ana$h8m$2...@seagoon.newcastle.edu.au>, pe...@PJM2.newcastle.edu.au (Peter Moylan) writes:
>Is there any special trick that's needed when calling
>KbdGetStatus from a VIO application? When I try it my program
>locks up solid, and I end up with an unkillable process.
>The symptoms are the same whether I run full-screen or in
>an OS/2 window.
>
>Alternatively, is there any other way (in a VIO application) to
>find out the current state of the Caps Lock, Num Lock, and
>Scroll Lock keys?
<clip>

The Numlock "snippets" at edm (http://www.edm2.com)
might be of help to you.

-------------------------------------------------------------
Cindy Ross ro...@us.ibm.com
(These opinions are just mine, I only represent myself, etc.)
-------------------------------------------------------------


0 new messages