TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: David Noon
from: Murray Lesser
date: 1995-12-23 07:28:20
subject: Pl/i Query

Excerpted from message dated 12-19-95, David Noon to Murray Lesser:

DN>I think your "knowledgeable friend" was right. If the KBDKEYINFO
  >structure is to be passed BYADDR, then the pointer has to be passed
  >BYVALUE. This is also in conformance with IBM's include file, which
  >passes a HANDLE #KBDKEYINFO BYVALUE as the first argument to
  >KbdCharIn().

DN>However, this approach of IBM's would seem to pass a 0:32 pointer to
  >KbdCharIn(), which would seem to be at variance from the API's
  >definition. I suspect it could be yet another buglet in their
  >%include files.

Hi David--

    I'm not using BSESUB.CPY or BSESUB.CV2.  I lifted the structure and
function descriptions from BSESUB.CPY (Personal Edition CSD#4), with
some modification, albeit it seems apparent that I did not do it right
before.  Would have tried the .CV2 version except I am even less sure
about PL/I HANDLEs than I am about PL/I pointers, at this stage in the
learning process.  (Incidentally, my version in PLITK\NEWCPY (CSD#1)
doesn't have the BYVALUE that is on your quoted statement.)

    My friend may have been right, but I would remind you that
PKBDKEYINFO is an "output" parameter, and is passed back to the program
by the KBD16CHARIN API.  Following my previous approach as modified by
my friend's advice, this would have been a pointer declared BYADDR
SEGMENTED, somehow related to the KBDKEYINFO structure.

    If I had been calling a KBD API in C, I would have passed
&KBDKEYINFO as the first parameter and would have used the
almost-undocumented (PVOID)DosSelToFlat() to thunk the output back to a
32-bit pointer.  But PL/I doesn't seem to need that API thunking call,
as it says somewhere in the "Language Reference" that pointers declared
SEGMENTED are automatically thunked when the the pointer variable is
used in 32-bit code.  I now think my problem was that I wasn't able to
properly relate the pointer to the structure, ending up with some sort
of addressing problem that may or may not have been connected to
thunking.  My present version seems to be more closely related to the
way I would have done it in C, except for letting the PL/I compiler take
care of all of the thunking rather than only part of it.

DN>Can you please post the snippet of code that does the getch()? Any
  >pointer passed to a 16-bit function or subroutine should be
  >SEGMENTED, whether passed BYVALUE or BYADDR. The SEGMENTED option
  >applies to the pointer itself, not its address, which should be
  >"thunked" automatically by the LINKAGE(PASCAL16) option.

    I changed the approach completely.  This one works as advertised! No
pointers explicitly declared, segmented or otherwise!  Cribbed the idea
from the stuff in the "Language Reference" manual on typed structures
(pp 144ff).  The example was for Dos32GetDateTime(), which plays a
similar game to pass a pointer to an API structure back to the program.

I worried about whether the approach would work with a call to a 16-bit
API function, but it seems to (minimal testing so far).  PL/I appears to
handle all the thunking required without my interfering.  As written,
compiled and linked, keytest.exe displays the  "Press an alpha key"
message, waits for the keypress, and then displays that keypress value.

Haven't bothered yet to add the SELECT required to report function
keys, etc., but will (when I am sure it works) for another program I'm
writing.  Any comments would be appreciated.

----------
 keytest: proc options (main);
   define alias UCHAR char;
   define alias USHORT fixed bin(16) unsigned;
   define alias ULONG fixed bin(31) signed;
   define structure
       1 KBDKEYINFO unaligned,
          2 chChar type UCHAR,
          2 chScan type UCHAR,
          2 fbStatus type UCHAR,
          2 bNlsShift type UCHAR,
          2 time type ULONG;
   dcl KbdChar entry (
            byaddr type KBDKEYINFO,
            type USHORT,          /* fwait */
            type USHORT)          /* keyboard handle */
            returns(optional byvalue fixed bin(16) unsigned)
            ext ( 'KBD16CHARIN' )
            options(byvalue nodescriptor linkage(pascal16)) external;
   dcl keybdinfo type kbdkeyinfo;
   dcl rc type Ushort;
   display ( 'Press an alpha key' );
   rc = KbdChar(KeybdInfo, 0, 0);
   display ( rc );
   display ( "'"||keybdinfo.chChar||"'" );
 end keytest;
----------

    Next task is to rework this to be a function and insert it into my
threaded beeper test case.  But I think I will wait until later, as I am
somewhat worn out from clearing the snow from my driveway.  (Those folks
"Dreaming of a White Christmas" are nuts, in my book.)

    In the meantime, thanks for the help (it got me thinking again), and
have a happy holiday season.

          --Murray

___
 * MR/2 2.25 #120 * If you are not confused, you don't understand the situation
               
---
* Origin: 2" x 4" bbs - a basic board - (914) 271-9407 (1:2625/108)
SEEN-BY: 270/101 620/243 711/401 409 410 413 430 808 809 934 955 712/407 515
SEEN-BY: 712/517 628 713/888 800/1 7877/2809
@PATH: 2625/108 1 2619/211 3615/50 396/1 270/101 712/515 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.