/* vio.c - demonstrate the use of some VIO and KBD 16-bit APIs
 */

#define INCL_NOPMAPI
#define INCL_KBD
#define INCL_VIO
#include <os2.h>

#include <stdio.h>

/* This external routine is used to convert a segmented 16:16 pointer
 * to a flat 0:32 pointer.  The function to convert the other way
 * is called _mw_FlatToSel.
 */
#ifdef _PPC
    #define _mw_SelToFlat(ptr) ptr
#else
    void *_mw_SelToFlat(void *ptr);
#endif

void main() {
    ULONG ptr16;
#ifdef _PPC
    ULONG count;
#else
    USHORT count;
#endif
    char *ptr;
    int i;
    KBDKEYINFO keyinfo;
    KBDINFO kinfo;

    /* Write to the screen as a TTY.
     */
    char msg[] = "Hello, World!\r\n";
    for (i = 0; i < 10; i++)
                VioWrtTTY((PCH)msg, sizeof(msg)-1, 0);

    /* Get the keyboard status, then get a key.
     */
    kinfo.cb = sizeof(kinfo);
    if (KbdGetStatus(&kinfo, 0) != 0)
        printf("Unable to get kbd status\n");
    else
        printf("Kbd mask 0x%x\n", kinfo.fsMask);

    printf("Hit a key...\n");
    KbdCharIn(&keyinfo, 0, 0);
    printf("\nAscii 0x%x, scancode 0x%x\n", keyinfo.chChar, keyinfo.chScan);

    /* Write directly to the logical video buffer.  Note the use
     * of _mw_SelToFlat to convert the pointer returned by VioGetBuf
     * into a flat 0:32 pointer that we can use.
     */
    VioGetBuf(&ptr16, &count, 0);
    printf("lvb (16 bit) = %p, length = %d\n", ptr16, count);
    ptr = _mw_SelToFlat((void *)ptr16);
    printf("32-bit pointer = %p\n", ptr);
    for (i = 0; i < 1024; i++)
        ptr[i*2] = '*';
    VioShowBuf(0, 2048, 0);	/* display first 2048 bytes of screen */
    }
