Przemyslaw,

> To be precise the problem is with any console input and it's inside pure
> OS2 API functions. It means that we probably using them in wrong way.

I attach here kbCharIn docs

---------8<--------------
Reads a character data record from the keyboard.


#define INCL_KBD
#include <os2.h>

PKBDKEYINFO    CharData;  /*  Pointer to character data. */
ULONG          Wait;      /*  Wait Flag. */
HKBD           hkbd;      /*  Reserved.  Must be 0. */
APIRET         rc;        /*  Return code. */

rc = KbdCharIn(CharData, Wait, hkbd);


CharData (PKBDKEYINFO) - output
Pointer to character data.

A pointer to a KBDKEYINFO structure in which the character data is returned.

Wait (ULONG) - input
Wait Flag.


0 IO_WAIT
Wait for a keystroke if one is not available. The keystroke returned is
removed from the queue.
1 IO_NOWAIT
Return immediately, with or without a keystroke. If a keystroke is returned,
remove it from the queue.
2 IO_PEEK
Return immediately, with or without a keystroke. Do not remove the keystroke
from the queue.
3 IO_PEEKWAIT
Wait for a keystroke if one is not available. Return the keystroke but do not
remove it from the queue.

hkbd (HKBD) - input
Reserved. Must be 0.

rc (APIRET) - returns
Return code.

KbdCharIn returns one of the following values:

0 NO_ERROR
375 ERROR_KBD_INVALID_IOWAIT
445 ERROR_KBD_FOCUS_REQUIRED
447 ERROR_KBD_KEYBOARD_BUSY
504 ERROR_KBD_EXTENDED_SG

Note: KbdCharIn returns a complete keystroke. This behavior is unlike the OS/2
1.3 version, which returned only a single byte. This affects only double-byte
character set (DBCS) characters.


If bit 0 of fbStatus is set, the character returned is either 0 or 0xe0. The
Unicode character contains the virtual key.

For valid characters, the character in the current code page is returned, and
the Unicode character contains the Unicode encoding of the character.

On an enhanced keyboard, the secondary enter key returns the normal character
0DH and a scan code of E0H.

Extended ASCII codes are identified by bit 1 of the status byte being set to
on, and the ASCII character code being either 00H or E0H. Both conditions must
be satisfied for the character to be an extended keystroke. For extended ASCII
codes, the scan-code byte returned is the second code (extended code).
Usually, the extended ASCII code is the scan code of the primary key that was
pressed.

A thread in the foreground session that repeatedly polls the keyboard with
KbdCharIn (with no wait), can prevent all regular priority-class threads from
executing. If polling must be used, and a minimal amount of other processing
is being performed, the thread should periodically yield to the CPU by issuing
a DosSleep call for an interval of at least 5 milliseconds.

---------8<--------------

> It may works for GCC because it may use some wrappers which resolve the
> problem or hide it. I would be good to find what exactly it does because
> it's a risk that the problem will be exploited also in some GCC builds.
> First we should check keyboard input and disable mouse code. It should
> give some answers which probably will also help to resolve problem with
> mouse. We can easy disable mouse code for tests by removing:
>    if( ch == 0 )
>       ch = HB_GTSELF_MOUSEREADKEY( pGT, iEventMask );
> from hb_gt_os2_ReadKey().
> Now when 2-nd thread calls:
> 
>    KbdCharIn( s_key, IO_NOWAIT, ( HKBD ) * s_hk );
> 
> it fails with internal error. In OW this call is directly translated by:
> 
>    #define KbdCharIn          KBD16CHARIN
> 
> inside bsesub.h.

I don't think GCC does this, it has kbdCharIn in two .h files:

1)  os2tk.h (i read it as os2toolkit) which has a

#define KBD16CHARIN             KbdCharIn

2) os2emx.h which has

USHORT APIENTRY KbdCharIn (PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd);

No other references are to be found.

> Why does it fail?

I don't know, but I remember that I started working on harbour for OS/2
exactly for the same problem, sometimes it was GPFing without reason and I
traced that reason to two things:

1) KBD code not using tiled memory
2) gtos2.c code calling video functions (VioXXX) and not using tiled memory.

You need to use tiled memory because OS/2 drivers are 16 bit protected memory
code and I think that, maybe, OW code does not respect this requirement.

BTW, when I started hacking harbour code, back in year 2000, harbour was being
built using ICC (IBM C Set compiler) which is long gone. You can see those
first changes inside current changelog and that comment of mine was about this
fact (OS/2 ToolKit was ICC OS/2 specific bindings).

20000330-23:04 GMT+1 Maurilio Longo <[EMAIL PROTECTED]>

        * include/hbvmpub.h
          ! with OS/2 GCC pragma pack(8) is not valid
        * source/rtl/gtos2/gtos2.c
          * with OS/2 GCC kbhit() is not available (it's a ToolKit function)

2001-02-26 22:59 GMT+1 Maurilio Longo <[EMAIL PROTECTED]>
   * source/rtl/gtos2/gtos2.c
     ! hb_gt_ReadKey() uses KBD subsystem of OS/2 instead of any compiler
runtime function to fetch characters from keyboard this way I can be sure that
used memory is tileable.


> Why we have s_hk which is only low memory block initialized to NULL?
> This code efectively works like:
>    KbdCharIn( s_key, IO_NOWAIT, NULL );

Uhm, I'm not sure, but I think that since it has to receive a pointer to a
tiled memory area, this was to be sure that the memory was really tiled.

> so why we have s_hk variable if it does nothing?
> OS2 API contains KbdGetFocus() and KbdFreeFocus(). If we begin to use
> them to protect  can it help us?
> 

I think they're old, deprecated functions from the 1.x times, my docs don't
have them listed.

> You left this comment in gtos2.c:
>    #if defined(HB_OS_OS2_GCC)
>       /* 25/03/2000 - [EMAIL PROTECTED]
>       OS/2 GCC hasn't got ToolKit headers available */
>       #include <stdlib.h>
>    #else
>       #include <bsedos.h>
>       #ifndef KBDTRF_EXTENDED_CODE
>          #define KBDTRF_EXTENDED_CODE 0x02
>       #endif
>    #endif
> 
> It suggests me that in GCC builds KbdCharIn() is not directly translated
> to KBD16CHARIN() but it's a wrapper function. Can you check its body and
> what it exactly does? If the problem is not solved by some external setting
> then the answer should be here.
> 

I'll have a look at gcc code and let you know.

Anyway, this code works ok when built using GCC:

function main()
   hb_threadStart( @t() )
   inkey(100)
return

function t()
    local n := 10
    while n-- > 0
      inkey( 1 )
    enddo
return

Just an ugly test, anyway no GPF.

Best regards.

Maurilio.

-- 
 __________
|  |  | |__| Maurilio Longo
|_|_|_|____| farmaconsult s.r.l.



_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to