[comp.os.os2] IBM OS/2 1.2 and 2nd display

rommel@lan.informatik.tu-muenchen.dbp.de (Kai-Uwe Rommel) (06/08/90)

I reported problems with IBM OS/2 1.2 and switching to a secondary
monochrome display using "MODE MONO" command in an earlier article.

These are the results:

As was noted in another article, the installation procedure is not very
safe at the point of configuration of displays. It requires to MARK all
installed display adaptors before pressing enter in the "Yes - but other
displays installed" menu. Then the VIDEO_DEVICES environment variables are
set correctly. But this did not solve my problems, I was still unable to
switch to the Hercules card.

Then I found a workaround: exchange the VIO_IBMVGA and VIO_IBMMPA
keywords in the VIDEO_DEVICES variable. That makes OS/2 think the mono
card is the primary display. All boot messages are printed on the mono
display but PM comes up on the VGA because the VGA driver is installed.
Now every time a fullscreen session is created it is started on the mono
screen. Then one can switch to the VGA with MODE CO80 or stay on the
Hercules card as desired.

But the real bug is in MODE.EXE itself. With OS/2 1.1 the swicthing was
done by VioSetMode() and specifying 0 colors and 80x25. Since 1.2 now
"officially" supports multiple displays (VIDEO_DEVICES env. var.) this
is no longer enough. A new subfunction of VioSetState() is available
now, called VIOSETTARGET. This call allows to select the adaptor to be
used for the next call to VioSetMode(). Probably MODE.EXE does not use
this call ...

I found this information in volume 4 of the OS/2 Programmers Reference.

The following small program can now be used to switch between primary
and secondary displays instead of MODE.EXE. It switches correctly from
VGA to Hercules (as MODE should do) even if the first workaround is not
used but is also required to switch back to the VGA because MODE
complains about "invalid parameter CO80" once you are on the mono card
:-)

Note that 1.2 headers are not required to compile the program but you
have to remove the definition of structure VIOTARGET when 1.2 headers
are used instead of 1.1 ones.

Hope this helps other people too.

Kai Uwe Rommel
Munich
rommel@lan.informatik.tu-muenchen.dbp.de


/* DISP.C
 *
 * (c) Kai Uwe Rommel, Thu 07-Jun-1990
 *
 * This program substitutes MODE for switching to the other display
 * because MODE appears to have a bug which does not allow to switch
 * between VGA and Hercules cards.
 *
 * Compile with small model.
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define INCL_NOPM
#define INCL_SUB
#include <os2.h>

typedef struct   /* not defined in OS/2 1.1 headers */
{
  USHORT cb;
  USHORT type;
  USHORT defalg;
}
VIOTARGET;

BYTE bCell[2] = {' ', 0x07};

int main(int argc, char **argv)
{
  VIOTARGET tg;
  VIOMODEINFO mi;
  USHORT res;
  USHORT display;

  if ( argc != 2 )
  {
    printf("\nUsage: %s P[RIMARY] | S[ECONDARY]\n", strupr(argv[0]));
    return 0;
  }
  else
    display = (toupper(argv[1][0]) == 'P') ? 1    /* primary */
            : (toupper(argv[1][0]) == 'S') ? 2    /* secondary */
            : 0;                                  /* default */

  tg.cb     = sizeof(tg);
  tg.type   = 6;
  tg.defalg = display;
  res = VioSetState(&tg, 0);                      /* set target display */

  if ( res )
    return res;

  mi.cb     = sizeof(mi);
  mi.fbType = (UCHAR) (display == 2 ? 0 : VGMT_OTHER);
  mi.color  = (UCHAR) (display == 2 ? 0 : COLORS_16);
  mi.col    = 80;
  mi.row    = 25;
  mi.hres   = 720;
  mi.vres   = (display == 2) ? 350 : 400;
  res = VioSetMode(&mi, 0);                       /* set screen mode */

  if ( res )
    return res;

  VioScrollUp(0, 0, 255, 255, 255, bCell, 0);     /* clear screen */
  VioSetCurPos(0, 0, 0);                          /* cursor home */

  return 0;                                       /* Yeah ! */
}

-----------------