Example #1
0
void SelectMetaFile( PluginInstance *This, HMF hmf ) {
  if ( This->hmf ) GpiDeleteMetaFile( This->hmf );
  This->hmf=hmf;
  HAB hab=WinQueryAnchorBlock( This->hWnd );
  HPS hps=This->hps;
  if ( !hps ) {
    pprintf( szPPR, "No hps ???\n\r" );
    return;
  }
  //calculate bounds
  HDC hdc = WinQueryWindowDC( This->hWnd );
  if ( !hdc ) hdc = WinOpenWindowDC( This->hWnd );
  GpiResetBoundaryData( hps );
  if ( GpiAssociate( hps, NULL ) ) {
    GpiSetDrawControl( hps, DCTL_BOUNDARY, DCTL_ON );
    Draw( This, hps, FALSE, FALSE );
    if ( GpiQueryBoundaryData( hps, &This->rclMeta ) && (This->rclMeta.xLeft<This->rclMeta.xRight) ) {
      if ( !GpiAssociate( hps, hdc ) ) pprintf( szPPR, "GpfAssociate( hps, hdc ) failed\n\r" );
      GpiSetDrawControl( hps, DCTL_BOUNDARY, DCTL_OFF );
      GpiResetPS( hps, GRES_ALL);
      SetTransform( This, hps, &This->rclWnd );
    } else {
      pprintf( szPPR, "GpiQueryBoundaryData failed, Err=%x\n\r",
        WinGetLastError( hab ) );
    }
  } else pprintf( szPPR, "GpfAssociate( hps, NULL ) failed\n\r" );
  // invalidate window to ensure a redraw
  WinInvalidateRect( This->hWnd, 0, TRUE );
}
Example #2
0
VOID Finalize(VOID)
{
    APIRET rc;

    // Save Options to INI file
    SaveScoresToIni();
    SaveOptionsToIni();
    WinStoreWindowPos(szAppName, szKeyPosition, hwndFrame);


    // close the game engine and the associated async thread, if any
    Eng_Close();
    dprint("gameEng close\n");

    GfxEng->close();
    dprint("GfxEng close\n");


    // close the sound engine
    // this also takes care of any sound threads
    SndEng->close();
    dprint("SoundEng close");

    if( hrgnInvalid)
	GpiDestroyRegion( hpsClient, hrgnInvalid);
    if( hpsClient)
    {
        GpiAssociate( hpsClient, NULLHANDLE);
        GpiDestroyPS( hpsClient);
    }

    if( hpsPaint)
        GpiDestroyPS( hpsPaint);

    dprint("Destroyed hPS\n");

    DestroyHelpInstance();

    if (hwndFrame)
        WinDestroyWindow( hwndFrame);
    if (hmqMain)
        WinDestroyMsgQueue( hmqMain);
    if (habMain)
        WinTerminate( habMain);
    if (hGame)
        DosClose(hGame);

    dprint("Destroyed handles\n");


    if (debOut)
    {
        fprintf(debOut, "Exiting MakMan/2\n");
        fflush(debOut);
        fclose(debOut);
    }

    DosExit( EXIT_PROCESS, 0);

}   /* end Finalize() */
Example #3
0
void qt_free_mem_ps(HPS hps)
{
    HDC hdc = GpiQueryDevice(hps);
    GpiAssociate(hps, NULLHANDLE);
    GpiDestroyPS(hps);
    DevCloseDC(hdc);
}
void XPrinterDevice::CleanupPrinter()
{
   if (pSetup->hpsPrinterInfo)
   {
      GpiAssociate(pSetup->hpsPrinterInfo, (HDC) 0);
      GpiDestroyPS(pSetup->hpsPrinterInfo);
      pSetup->hpsPrinterInfo = (HPS) 0;
   }

   if (pSetup->hdcPrinterInfo)
   {
      DevCloseDC(pSetup->hdcPrinterInfo);
      pSetup->hdcPrinterInfo = (HDC) 0;
   }

   if (pSetup->pQueueInfo)
   {
      free(pSetup->pQueueInfo);
      pSetup->pQueueInfo = NULL;
   }

   if (pSetup->pDriverData)
   {
      free(pSetup->pDriverData);
      pSetup->pDriverData = NULL;
   }

   if (pSetup->devopenstruc.pszDriverName)
   {
      free(pSetup->devopenstruc.pszDriverName);
      pSetup->devopenstruc.pszDriverName = NULL;
   }
}
/*@ XPrinterDevice::KillPrinterJob()
@remarks Remove the printer job from the printer queue.
*/
void XPrinterDevice::KillPrinterJob()
{
   DevEscape(hdc, DEVESC_ABORTDOC, 0, NULL, NULL, NULL);

   if (hps)
   {
      GpiSetCharSet(hps, 0);
      GpiAssociate(hps, (HDC) 0);
      GpiDestroyPS(hps);
      hps = (HPS) 0;
   }

   if (hdc)
   {
      DevCloseDC(hdc);
      hdc = (HDC) 0;
   }
}
Example #6
0
//----------------------------------------------------------------------------
// NPP_DestroyStream:
//----------------------------------------------------------------------------
NPError NP_LOADDS
NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) {
  if ( instance == 0 ) return NPERR_INVALID_INSTANCE_ERROR;
  PluginInstance* This = (PluginInstance*) instance->pdata;

  if ( reason == NPRES_DONE && This->bufMeta ) {
    // create metafile from buffer

    // 1-st, create empty metafile
    HAB hab=WinQueryAnchorBlock( This->hWnd );
    DEVOPENSTRUC dop;
    dop.pszLogAddress = (PSZ) NULL;
    dop.pszDriverName = "DISPLAY";
    HDC hdcMeta = DevOpenDC( hab,
        OD_METAFILE,                 /* Metafile device context             */
        "*",                         /* Ignores OS2.INI                     */
        2L,                          /* Uses first two fields               */
        (PDEVOPENDATA) &dop,         /* Device information                  */
        (HDC) NULLHANDLE );          /* Compatible device context           */
    SIZEL sizlPage={ 0, 0 };
    HPS hpsMeta = GpiCreatePS( hab, hdcMeta, &sizlPage, PU_PELS | GPIA_ASSOC );
    GpiAssociate( hpsMeta, (HDC)NULLHANDLE );
    HMF hmf = DevCloseDC( hdcMeta );
    GpiDestroyPS( hpsMeta );

    // 2-nd, add real data
    GpiSetMetaFileBits( hmf, 0, This->offMeta, This->bufMeta );
    SelectMetaFile( This, hmf );
  }
  // delete buffer
  if ( This->bufMeta ) {
    free( This->bufMeta );
    This->bufMeta=NULL;
    This->cbMeta=0;
    This->offMeta=0;
  }
  return NPERR_NO_ERROR;
}
Example #7
0
/* Close the os2prn driver */
static int
os2prn_close(gx_device * dev)
{
    int code;
    LONG lOut;
    USHORT usJobID;

    /* tell printer that all is finished */
    DevEscape(opdev->hdc, DEVESC_ENDDOC, 0L, NULL, &lOut, (PBYTE) & usJobID);
    /* Free resources */
    GpiAssociate(opdev->hps, (HDC) NULL);
    GpiDestroyPS(opdev->hps);
    DevCloseDC(opdev->hdc);

    if (opdev->hpsMem != GPI_ERROR)
	GpiDestroyPS(opdev->hpsMem);
    if (opdev->hdcMem != DEV_ERROR)
	DevCloseDC(opdev->hdcMem);

    code = gdev_prn_close(dev);
    /* delete unwanted temporary file */
    unlink(opdev->fname);
    return code;
}
/*************************************************************************
 *
 * Name       : WinProc(hwnd, msg, mp1, mp2)
 *
 * Description: Processes the messages sent to the main client
 *              window.  This routine processes the basic
 *              messages all client windows should process.
 *
 * Concepts   : This procedure provides service routines for the general
 *              PM events (messages) that PM sends to the window, as well
 *              as the user initiated events (messages) that are generated
 *              when the user selects the action bar and pulldown menu
 *              controls or the corresponding keyboard accelerators.
 *
 *              The switch statement shown below distributes the window
 *              messages to the respective message service routines, which
 *              are set apart by the case statements.  The window
 *              procedures must provide an appropriate service routine for
 *              its end user initiated messages, as well as the general PM
 *              messages (like the WM_CLOSE message). If a message is sent
 *              to this procedure for which there is no programmed case
 *              clause (i.e., no service routine), the message is defaulted
 *              function WinDefWindowProc, where it is disposed of by PM.
 *
 *              Time-consuming tasks are posted to the object window where
 *              they can be performed without the 1/10 second turnaround
 *              time imposed on the client window. When the object window
 *              is busy, the client window is usually disabled. The object
 *              window then posts an acknowledgement
 *              back to the client when the lengthy task is completed.
 *
 *              Cases under the big switch appear in alphabetical order.
 *
 *  API's     :   WinLoadString
 *                WinMessageBox
 *                WinQueryWindowULong
 *                WinSendMsg
 *                WinPostMsg
 *                WinIsWindowEnabled
 *                WinSetPointer
 *                WinQuerySysPointer
 *                WinBeginPaint
 *                WinQueryWindowRect
 *                WinFillRect
 *                WinEndPaint
 *                WinInvalidateRect
 *                WinSetWindowText
 *                GpiDrawChain
 *                GpiConvert
 *                GpiSetDefaultViewMatrix
 *                GpiAssociate
 *                GpiDestroyPS
 *                GpiDeleteBitmap
 *                GpiDeleteMetafile
 *
 * Parameters : HWND         window handle
 *              ULONG        message
 *              MPARAM       message parameter 1
 *              MPARAM       message parameter 2
 *
 * Result     : MRESULT      message result
 *
 *************************************************************************/
MRESULT EXPENTRY WinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   BOOL                bOK;
   PMAIN_PARM       pmp;
   HPS                 hps;
   RECTL              rectl;
   PSZ                 psz;
   CHAR               szWork[ LEN_WORKSTRING ];
   SHORT              sStep;
   ULONG              ulWork;
   SHORT              sNewPos;
   ULONG              rc;

   switch(msg)
   {
   case WM_CLOSE:
      /* obtain the main parameter pointer from window words */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
#ifdef OSA_AWARE
      /* Do OSA termination */
      TerminateOSA(hwnd);
#endif
      if( pmp->fBusy )
      {
         /* OK to close when object window is busy?  */
         WinLoadString( pmp->hab, (HMODULE)NULLHANDLE,
                   ERRMSG_CLOSE_QUESTION, LEN_WORKSTRING, szWork );
         ulWork = WinMessageBox( HWND_DESKTOP,
                                 pmp->hwndFrame,
                                 szWork,
                                 pmp->pszTitle,
                                 (USHORT)0,
                                 MB_YESNOCANCEL | MB_MOVEABLE |
                                 MB_CUANOTIFICATION | MB_APPLMODAL);

         if( ulWork == MBID_YES )
         {
            /* close down the application in spite of being busy */
            pmp->fCancel = TRUE;
            /* disable client during exit */
            WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0 , (MPARAM)0  );
            /* start a watchdog timer to ensure a timely death */
            WinStartTimer( pmp->hab, hwnd, ID_DEATH_TIMER, LEN_DEATH_TIMER );
            /* Tell object window to close, quit, and post me a WM_QUIT */
            WinPostMsg( pmp->hwndObject, WM_USER_CLOSE, (MPARAM)hwnd, (MPARAM)0 );
         }
      }
      else
      {
         /* not busy, so initiate closure by telling object window to close */
         WinPostMsg( pmp->hwndObject, WM_USER_CLOSE, (MPARAM)hwnd, (MPARAM)0 );
      }
      return (MRESULT)NULL;


   case WM_COMMAND:
      /* do menu activities; see menu.c */
      return Menu( hwnd, msg, mp1, mp2 );


   case WM_CREATE:

      /*
       * Do one-time, startup processing in PRTCREAT.C.
       * This function allocates the pmp, a pointer to the program's
       * main parameters. See the declaration of this block of
       * parameters in PRTSAMP.H, the MAIN_PARM structure.
       *
       * The Create() function allocates this structure and
       * begins to initialize it. Throughout all the code, the pmp->
       * pointer is usually obtainable with a call to WinQueryWindowULong.
       * Window word space for this pointer was reserved on the call
       * to WinRegisterClass.
       *
       * Create() allocates, initializes, and stores the pmp pointer
       * in the client window words. It then starts thread 2 of the
       * application on which the object window operates. The pmp
       * pointer is passed to thread 2 with _beginthread in PRTCREAT.C.
       * The pmp is passed to the object window on the call to
       * WinCreateWindow in PRTOBJ.C. Finally, the object window stores
       * the pmp in its window words under the WM_CREATE case of the
       * ObjectWinProc in PRTOBJ.C.
       *
       */

      Create( hwnd );
#ifdef OSA_AWARE
      /* Do OSA Initialization */
      InitOSA(hwnd);
#endif

#ifdef OSA_AWARE
        /* Generate a Apple Event - Open Application to myself  (Workaround) */
        rc =  GenerateOSAEvent(hwnd, msg, MPFROMSHORT(IDM_AEOPENAPP), mp2);
#endif
      return (MRESULT)NULL;


   case WM_HSCROLL:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* Compute some fraction of scroll bar range for a unit of scrolling. */
      sStep  = pmp->sHScrollRange / 50;

      switch( SHORT2FROMMP( mp2 ))
      {
      case SB_LINELEFT:
         pmp->sHScrollPos -= sStep;
         break;
      case SB_PAGELEFT:
         pmp->sHScrollPos -= pmp->sizelClient.cx;
         break;
      case SB_LINERIGHT:
         pmp->sHScrollPos += sStep;
         break;
      case SB_PAGERIGHT:
         pmp->sHScrollPos += pmp->sizelClient.cx;
         break;
      case SB_SLIDERPOSITION:
      case SB_SLIDERTRACK:
         pmp->sHScrollPos = SHORT1FROMMP( mp2 );
         break;
      }

      /* Don't allow step assignments to exceed limits of zero to range. */
      pmp->sHScrollPos = max( (SHORT)0,
                              min( pmp->sHScrollPos, pmp->sHScrollRange ));

      if( pmp->sHScrollPos != SHORT1FROMMR(WinSendMsg( pmp->hwndHScroll,
          SBM_QUERYPOS, (MPARAM)0, (MPARAM)0 )))
      {
         /*
          * New scroll bar thumbbutton position is different than current.
          * Set a new X translation value to effect the scroll.
          * Current scale setting affects the X element of the matrix.
          */
         pmp->matlfDefView.lM31 = OFFSET_XY_TWIPS - (LONG)(pmp->floatScale *
                                                 (float)( pmp->sHScrollPos));
         bOK = GpiSetDefaultViewMatrix( pmp->hpsClient,
                                        9,
                                        &pmp->matlfDefView,
                                        TRANSFORM_REPLACE );
         pmassert( pmp->hab, bOK );
         CalibrateHorizontalScrollBar( pmp );
         WinInvalidateRect( hwnd, NULL, FALSE );
      }
      return (MRESULT) 0;


   case WM_MOUSEMOVE:
      /* display which pointer? -- could query pmp->fBusy or... */
      if( WinIsWindowEnabled( hwnd ))
      {
         /* not disabled; display regular pointer */
         WinSetPointer( HWND_DESKTOP,
                        WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE ));
      }
      else
      {
         /* disabled; display hourglass because I'm busy */
         WinSetPointer( HWND_DESKTOP,
                        WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE ));
      }
     return (MRESULT) 1;



   case WM_NACK_BITMAP_NOT_SUPPORTED:
      /*
       * Object window does not support this format of bitmap -
       * show a message box.
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
      bOK = WinLoadString( pmp->hab, (HMODULE)0,
                   ERRMSG_BITMAP_NOT_SUPPORTED, LEN_WORKSTRING, szWork );
      pmassert( pmp->hab, bOK );
      WinMessageBox( HWND_DESKTOP,
                     pmp->hwndFrame,
                     szWork,
                     pmp->pszTitle,
                     (USHORT)0,
                     MB_OK | MB_MOVEABLE | MB_CUACRITICAL | MB_APPLMODAL);

      pmp->ulNextMode        = MODE_UNKNOWN;
      pmp->szNextFilename[0] = 0;
      WinPostMsg( hwnd, WM_USER_NEW_MODE, (MPARAM)0, (MPARAM)0 );
      return (MRESULT) 0;


   case WM_NACK_BITMAP_ERROR:
      /*
       * Object window had error loading the bitmap file -
       * show a message box
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
      bOK = WinLoadString( pmp->hab,
                           (HMODULE)NULLHANDLE,
                           ERRMSG_BAD_BITMAP,
                           LEN_WORKSTRING,
                           szWork );
      pmassert( pmp->hab, bOK );
      WinMessageBox( HWND_DESKTOP,
                     pmp->hwndFrame,
                     szWork,
                     pmp->pszTitle,
                     (USHORT)0,
                     MB_OK | MB_MOVEABLE | MB_CUAWARNING | MB_APPLMODAL);

      pmp->ulNextMode        = MODE_UNKNOWN;
      pmp->szNextFilename[0] = 0;
      WinPostMsg( hwnd, WM_USER_NEW_MODE, (MPARAM)0, (MPARAM)0 );
      return (MRESULT) 0;


   case WM_NACK_FILE_READING_ERROR:
      /*
       * Object window had a problem with reading the disk -
       * show a message box.
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
      bOK = WinLoadString( pmp->hab, (HMODULE)NULLHANDLE,
                           ERRMSG_READ_ERROR, LEN_WORKSTRING, szWork );
      pmassert( pmp->hab, bOK );
      WinMessageBox( HWND_DESKTOP,
                     pmp->hwndFrame,
                     szWork,
                     pmp->pszTitle,
                     (USHORT)0,
                     MB_OK | MB_MOVEABLE | MB_CUACRITICAL | MB_APPLMODAL);
      pmp->ulNextMode        = MODE_UNKNOWN;
      pmp->szNextFilename[0] = 0;
      WinPostMsg( hwnd, WM_USER_NEW_MODE, (MPARAM)0, (MPARAM)0 );
      return (MRESULT) 0;


   case WM_PAINT:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* do not rely on client window rectangle being correct */
      WinQueryUpdateRect( hwnd, &rectl );
      WinQueryWindowRect( hwnd, &rectl );

      /* current mode of the program affects window painting */
      switch( pmp->ulMode )
      {
      case MODE_UNKNOWN:
         WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
         WinPostMsg( pmp->hwndObject, WM_USER_PAINT_DEFAULT_SCREEN,
                        (MPARAM)hwnd, (MPARAM)0 );
         /* must call default window proc for window validation */
         break;

      case MODE_TEXT:
         if( pmp->fBusy )
         {
            /*
             * Object window is busy with the client PS drawing into
             * retained segments. Use a cached micro PS to merely
             * fill the client window with a background wash.
             *
             * Proper painting of the text will occur in due time
             * because the WM_USER_ACK case below will
             * invalidate the client window and force a paint.
             * The object window won't be busy then.
             */
            hps = WinBeginPaint( hwnd, (HPS) 0, &rectl );
            pmassert( pmp->hab, hps );
            bOK = WinFillRect( hps, &rectl, SYSCLR_WINDOW );
            pmassert( pmp->hab, bOK );
            WinEndPaint( hps );
         }
         else
         {
            /* PS not busy. Use GpiDrawChain to repaint the text */
            hps = WinBeginPaint( hwnd, (HPS)pmp->hpsClient, &rectl );
            pmassert( pmp->hab, hps );
            bOK = WinFillRect( pmp->hpsClient, &rectl, SYSCLR_WINDOW );
            pmassert( pmp->hab, bOK );
            /*
             * GpiDrawChain re-plays the GpiCharString orders that were
             * retain in the WM_USER_PAGINATE case in prtobj.c
             */
            bOK = GpiDrawChain( pmp->hpsClient );
            pmassert( pmp->hab, bOK );
            bOK = WinEndPaint( pmp->hpsClient );
            pmassert( pmp->hab, bOK );
         }
         return (MRESULT) 0;

      case MODE_BITMAP:
         if( pmp->hbm )
         {
            WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
            WinPostMsg( pmp->hwndObject, WM_USER_PAINT_BITMAP,
                        (MPARAM)hwnd, (MPARAM)0 );
         }
         /* must call default window proc for window validation */
         break;

      case MODE_METAFILE:
         hps = WinBeginPaint( hwnd, (HPS) 0, &rectl );
         pmassert( pmp->hab, hps );
         WinFillRect( hps, &rectl, SYSCLR_WINDOW );
         if( pmp->hmf )
         {
            WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
            WinPostMsg( pmp->hwndObject, WM_USER_PAINT_METAFILE,
                        (MPARAM)hwnd, (MPARAM)0 );
         }
         WinEndPaint( hps );
         return (MRESULT) 0;

      default:
         pmassert( pmp->hab, NULL == "bad case in WM_PAINT" );
      }
      break;


#ifdef OSA_AWARE
   case WM_SEMANTICEVENT:
      /* Handle Apple Event Manager Semantic Event */
      WinMessageBox( HWND_DESKTOP,
                     HWND_DESKTOP,
                     "WM_SEMANTIC_EVENT was received",
                     "WinProc",
                     (USHORT)0,
                     MB_OK | MB_NOICON);
      /* Call ProcessSemanticEvent to process the Apple Event */
      ProcessSemanticEvent( hwnd, msg, mp1, mp2 );
      return (MRESULT) 0;
#endif


   case WM_SIZE:
      /* Do size process if frame is not minimized  */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /*
       * If the object window is busy drawing, the GPI calls here can fail
       * because the PS is busy. Check for this situation and delay
       * the sizing operation by a few milliseconds.
       */
      if( pmp->fBusy )
      {
          WinStartTimer( pmp->hab, hwnd, ID_SIZE_TIMER, LEN_SIZE_TIMER );
          return (MRESULT) 0;
      }

      ulWork = WinQueryWindowULong( pmp->hwndFrame, QWL_STYLE );

      if( !( ulWork & WS_MINIMIZED ))
      {
         /* Frame is not minimized. Get window size in pels. */
         WinQueryWindowRect( hwnd, &rectl );

         /* how many twips will fit into the client window now? */
         bOK = GpiConvert( pmp->hpsClient, CVTC_DEVICE,
                           CVTC_WORLD, 2L, (PPOINTL)&rectl );
         pmassert( pmp->hab, bOK );

         /* compute client size in twips, store in pmp */
         pmp->sizelClient.cx = rectl.xRight - rectl.xLeft;
         pmp->sizelClient.cy = rectl.yTop   - rectl.yBottom;

         /* Try to keep the current position still in view by calculating */
         /* the difference between size required and client window. */
         /* The scroll position is then either 0 or the minimum of the */
         /* difference and the old scroll position */
         sNewPos = (LONG)FixedInchesToTwips(pmp->form.fxxWidth) +
                    (((float)(2 * OFFSET_XY_TWIPS)) / pmp->floatScale) -
                   pmp->sizelClient.cx;
         pmp->sHScrollPos = min( max( 0, sNewPos), pmp->sHScrollPos);
         sNewPos = (LONG)FixedInchesToTwips(pmp->form.fxyHeight) +
                    (((float)(2 * OFFSET_XY_TWIPS)) / pmp->floatScale) -
                   pmp->sizelClient.cy;
         pmp->sVScrollPos = min( max( 0, sNewPos), pmp->sVScrollPos);

         /* recalibrate the scroll bars */
         CalibrateHorizontalScrollBar( pmp );
         CalibrateVerticalScrollBar( pmp );

         /*
          * Modify def-view matrix translation to home the displayed page.
          * This depends on the current scaling value.
          */
         pmp->matlfDefView.lM31 = OFFSET_XY_TWIPS - (LONG)(pmp->floatScale *
                                                 (float)( pmp->sHScrollPos));
         pmp->matlfDefView.lM32 = OFFSET_XY_TWIPS + (LONG)(pmp->floatScale *
                          (float)( pmp->sVScrollPos - pmp->sVScrollRange ));
         bOK = GpiSetDefaultViewMatrix( pmp->hpsClient, 9,
                          &pmp->matlfDefView, TRANSFORM_REPLACE );
         pmassert( pmp->hab, bOK );

         /* force a paint */
         WinInvalidateRect( hwnd, NULL, FALSE );
      }
      return (MRESULT) 0;




   case WM_TIMER:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      switch( (ULONG) mp1 )
      {
      case ID_DEATH_TIMER:
         /* object window never posted a quit in allotted time.
         WinPostMsg( hwnd, WM_QUIT, 0, 0 );
         break;
      case ID_SIZE_TIMER:
         /* object window was busy with the PS before; try sizing now */
         bOK = WinStopTimer( pmp->hab, hwnd, ID_SIZE_TIMER );
         pmassert( pmp->hab, bOK );
         WinSendMsg( hwnd, WM_SIZE, 0, 0 );
         break;
      }
      return (MRESULT) 0;





   case WM_USER_ACK:
      /*
       * Object window is done processing lengthy task.
       * mp1 contains the WM_USER msg originally posted to the object window
       * mp2 may contain a result code, depending on mp1
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* reenable the client window */
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );

      switch( (ULONG)mp1 )
      {
      case WM_USER_LOAD_BITMAP:
      case WM_USER_LOAD_METAFILE:
      case WM_USER_LOAD_TEXT:
         /*
          * Do size processing so that document will
          * "home" in the client window.
          */
         WinSendMsg( hwnd, WM_SIZE, (MPARAM)0, (MPARAM)0 );
         break;
      case WM_USER_PAGINATE:
         switch( (ULONG)mp2  )
         {
         case PAGINATE_EOF:
         case PAGINATE_EOF_PART_PAGE:
            /* seek top of file */
            fseek( pmp->f, 0, SEEK_SET );
         }
         WinInvalidateRect( hwnd, NULL, FALSE );
         break;
      }

      return (MRESULT) 0;


   case WM_USER_DISABLE_CLIENT:
      /*
       * usually disable before posting a task to the object window
       * this message may be sent; disable menu action bar as well
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      pmp->fBusy = TRUE;
      WinEnableWindow( pmp->hwndClient,  FALSE );
      WinEnableWindow( pmp->hwndMenubar, FALSE );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  FALSE );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, FALSE );
      return (MRESULT)0;


   case WM_USER_ENABLE_CLIENT:
      /*
       * usually enable upon receipt of object window ack/nack
       * this message may be sent; enable menu actions if text mode
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      pmp->fBusy = FALSE;
      WinEnableWindow( pmp->hwndClient,  TRUE );
      WinEnableWindow( pmp->hwndMenubar, TRUE );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  TRUE );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  TRUE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, TRUE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, TRUE );
      if( pmp->ulMode == MODE_TEXT )
      {
         WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, TRUE );
      }
      return (MRESULT) 0;



   case WM_USER_NEW_MODE:
      /*
       * The program now has a new file, file type, or printer, or
       * printer form, orientation, resolution, etc. The receipt
       * and processing of this message works to reset the program:
       * Old file, bitmap, or metafile handles are closed, and
       * new ones get opened. The titlebar shows the new filename.
       * This case works very much like a program reset.
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* close processing on current file */

      switch( pmp->ulMode )
      {
      case MODE_BITMAP:
        /* destroy previous memory dc, ps, and hbm */
        if( pmp->hpsMemory )
        {
          GpiAssociate( pmp->hpsMemory, (HDC)0 );
          GpiDestroyPS( pmp->hpsMemory );
          pmp->hpsMemory = (HPS) 0;
        }
        if( pmp->hdcMemory )
        {
          DevCloseDC( pmp->hdcMemory );
          pmp->hdcMemory = (HDC) 0;
        }
        if( pmp->hbm )
        {
          GpiDeleteBitmap( pmp->hbm );
          pmp->hbm = (HBITMAP) 0;
        }
        break;

      case MODE_METAFILE:
        /* destroy old metafile handle */
        if( pmp->hmf )
        {
          GpiDeleteMetaFile( pmp->hmf );
          pmp->hmf = (HMF) 0;
        }
        break;

      case MODE_TEXT:
        fclose( pmp->f );
        pmp->f = (FILE *) 0;
        /* turn off options for text mode */
        WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, FALSE );
        WinEnableMenuItem( pmp->hwndMenubar, IDM_SETFONT,  FALSE );
        break;
      }

      /* turn off options for all modes */
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, FALSE );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  FALSE );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  FALSE );

      /* copy over current values with the next values */
      pmp->ulMode = pmp->ulNextMode;
      strcpy( pmp->szFilename, pmp->szNextFilename );

      /* enable the print menu option if mode is known and there
         is a printer set up. */
      WinEnableMenuItem( pmp->hwndMenubar, IDM_PRINT,
       (pmp->ulMode != MODE_UNKNOWN && pmp->hpsPrinterInfo ) );


      /* update title bar text and show filename in use */
      if( *pmp->szFilename )
      {
         /* parse full-qualified filename to just get filename and extension */
         psz = strrchr( pmp->szFilename, '\\' );
         if (psz && *psz)
         {
             ++psz;
         }
         else
         {
             psz = pmp->szFilename;
         }
         sprintf( szWork, "%s - %s", pmp->pszTitle, psz );
      }
      else
      {
         strcpy( szWork, pmp->pszTitle );
      }
      WinSetWindowText( pmp->hwndTitlebar, szWork );

      /* enable options for all modes */
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, TRUE  );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, TRUE  );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  TRUE  );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  TRUE  );

      /* process this new mode */
      switch( pmp->ulMode )
      {
      case MODE_BITMAP:
        /* load the bitmap into memory so it is compatible with the screen */
        WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
        WinPostMsg( pmp->hwndObject, WM_USER_LOAD_BITMAP,
                    (MPARAM)hwnd, (MPARAM)FLAGS_SCREEN );
        break;

      case MODE_METAFILE:
        /* make object window read metafile */
        WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
        WinPostMsg( pmp->hwndObject, WM_USER_LOAD_METAFILE, (MPARAM)hwnd, 0 );
        break;

      case MODE_TEXT:
        /* turn on options for text mode */
        WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, TRUE  );
        WinEnableMenuItem( pmp->hwndMenubar, IDM_SETFONT,  TRUE  );
        /* reset view matrix that was last in effect for viewing text pages; */
        /* this gets lost after viewing a metafile */
        bOK = GpiSetDefaultViewMatrix( pmp->hpsClient, 9,
                                       &pmp->matlfDefView, TRANSFORM_REPLACE );
        pmassert( pmp->hab, bOK );
        /* disable until text loaded */
        WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
        /* tell object window to load the text file */
        bOK = WinPostMsg( pmp->hwndObject, WM_USER_LOAD_TEXT, (MPARAM)hwnd, 0 );
        pmassert( pmp->hab, bOK );
        break;


      case MODE_UNKNOWN:
        /* size screen to get correct scrollbars */
        WinPostMsg( pmp->hwndClient, WM_SIZE, 0, 0 );
        break;

      }
      return (MRESULT) 0;

   case WM_VSCROLL:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* Compute some fraction of scroll bar range for a unit of scrolling. */
      sStep  = pmp->sVScrollRange / 50;

      switch( SHORT2FROMMP( mp2 ))
      {
      case SB_LINEUP:
         pmp->sVScrollPos -= sStep;
         break;
      case SB_PAGEUP:
         pmp->sVScrollPos -= pmp->sizelClient.cy;
         break;
      case SB_LINEDOWN:
         pmp->sVScrollPos += sStep;
         break;
      case SB_PAGEDOWN:
         pmp->sVScrollPos += pmp->sizelClient.cy;
         break;
      case SB_SLIDERPOSITION:
      case SB_SLIDERTRACK:
         sNewPos          = SHORT1FROMMP( mp2 );
         pmp->sVScrollPos = sNewPos;
         break;
      }

      /* Don't allow step assignments to exceed limits of zero to range. */
      pmp->sVScrollPos = max( (SHORT)0,
                              min( pmp->sVScrollPos, pmp->sVScrollRange ));

      if( pmp->sVScrollPos != SHORT1FROMMR(WinSendMsg( pmp->hwndVScroll,
          SBM_QUERYPOS, (MPARAM)0, (MPARAM)0 )))
      {
         /*
          * New scroll bar thumbbutton position is different than current.
          * Set a new Y translation value to effect the scroll.
          * Current scale setting affects the Y element of the matrix.
          */
         pmp->matlfDefView.lM32 = OFFSET_XY_TWIPS + (LONG)(pmp->floatScale *
                          (float)( pmp->sVScrollPos - pmp->sVScrollRange ));

         pmp->matlfDefView.lM32 =  (LONG)(pmp->floatScale *
             (float)( OFFSET_XY_TWIPS +
                      pmp->sVScrollPos -
                      pmp->sVScrollRange ));

         bOK = GpiSetDefaultViewMatrix( pmp->hpsClient,
                                        9,
                                        &pmp->matlfDefView,
                                        TRANSFORM_REPLACE );
         pmassert( pmp->hab, bOK );
         CalibrateVerticalScrollBar( pmp );
         WinInvalidateRect( hwnd, NULL, FALSE );
      }
      return (MRESULT) 0;
   }
   return WinDefWindowProc( hwnd, msg, mp1, mp2 );
}  /* End of WinProc */
nsresult nsIconChannel::MakeInputStream(nsIInputStream **_retval,
                                        bool nonBlocking)
{

  // get some details about this icon
  nsCOMPtr<nsIFile> localFile;
  uint32_t desiredImageSize;
  nsXPIDLCString contentType;
  nsAutoCString filePath;
  nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(localFile),
                                       &desiredImageSize, contentType,
                                       filePath);
  NS_ENSURE_SUCCESS(rv, rv);

  // if the file exists, get its path
  bool fileExists = false;
  if (localFile) {
    localFile->GetNativePath(filePath);
    localFile->Exists(&fileExists);
  }

  // get the file's icon from either the WPS or PM
  bool fWpsIcon = false;
  HPOINTER hIcon = GetIcon(filePath, fileExists,
                           desiredImageSize <= 16, &fWpsIcon);
  if (hIcon == NULLHANDLE)
    return NS_ERROR_FAILURE;

  // get the color & mask bitmaps used by the icon
  POINTERINFO IconInfo;
  if (!WinQueryPointerInfo(hIcon, &IconInfo)) {
    DestroyIcon(hIcon, fWpsIcon);
    return NS_ERROR_FAILURE;
  }

  // if we need a mini-icon, use those bitmaps if present;
  // otherwise, signal that the icon needs to be shrunk
  bool fShrink = FALSE;
  if (desiredImageSize <= 16) {
    if (IconInfo.hbmMiniPointer) {
      IconInfo.hbmColor = IconInfo.hbmMiniColor;
      IconInfo.hbmPointer = IconInfo.hbmMiniPointer;
    } else {
      fShrink = TRUE;
    }
  }

  // various resources to be allocated
  PBITMAPINFO2  pBMInfo = 0;
  uint8_t*      pInBuf  = 0;
  uint8_t*      pOutBuf = 0;
  HDC           hdc     = 0;
  HPS           hps     = 0;

  // using this dummy do{...}while(0) "loop" guarantees that resources will
  // be deallocated, but eliminates the need for nesting, and generally makes
  // testing for & dealing with errors pretty painless (just 'break')
  do {
    rv = NS_ERROR_FAILURE;

    // get the details for the color bitmap;  if there isn't one
    // or this is 1-bit color, exit
    BITMAPINFOHEADER2  BMHeader;
    BMHeader.cbFix = sizeof(BMHeader);
    if (!IconInfo.hbmColor ||
        !GpiQueryBitmapInfoHeader(IconInfo.hbmColor, &BMHeader) ||
        BMHeader.cBitCount == 1)
      break;

    // alloc space for the color bitmap's info, including its color table
    uint32_t cbBMInfo = sizeof(BITMAPINFO2) + (sizeof(RGB2) * 255);
    pBMInfo = (PBITMAPINFO2)nsMemory::Alloc(cbBMInfo);
    if (!pBMInfo)
      break;

    // alloc space for the color bitmap data
    uint32_t cbInRow = ALIGNEDBPR(BMHeader.cx, BMHeader.cBitCount);
    uint32_t cbInBuf = cbInRow * BMHeader.cy;
    pInBuf = (uint8_t*)nsMemory::Alloc(cbInBuf);
    if (!pInBuf)
      break;
    memset(pInBuf, 0, cbInBuf);

    // alloc space for the BGRA32 bitmap we're creating
    uint32_t cxOut    = fShrink ? BMHeader.cx / 2 : BMHeader.cx;
    uint32_t cyOut    = fShrink ? BMHeader.cy / 2 : BMHeader.cy;
    uint32_t cbOutBuf = 2 + ALIGNEDBPR(cxOut, 32) * cyOut;
    pOutBuf = (uint8_t*)nsMemory::Alloc(cbOutBuf);
    if (!pOutBuf)
      break;
    memset(pOutBuf, 0, cbOutBuf);

    // create a DC and PS
    DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL};
    hdc = DevOpenDC((HAB)0, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
    if (!hdc)
      break;

    SIZEL sizel = {0,0};
    hps = GpiCreatePS((HAB)0, hdc, &sizel, GPIA_ASSOC | PU_PELS | GPIT_MICRO);
    if (!hps)
      break;

    // get the color bits
    memset(pBMInfo, 0, cbBMInfo);
    *((PBITMAPINFOHEADER2)pBMInfo) = BMHeader;
    GpiSetBitmap(hps, IconInfo.hbmColor);
    if (GpiQueryBitmapBits(hps, 0L, (LONG)BMHeader.cy,
                           (BYTE*)pInBuf, pBMInfo) <= 0)
      break;

    // The first 2 bytes are the width & height of the icon in pixels,
    // the remaining bytes are BGRA32 (B in first byte, A in last)
    uint8_t* outPtr = pOutBuf;
    *outPtr++ = (uint8_t)cxOut;
    *outPtr++ = (uint8_t)cyOut;

    // convert the color bitmap
    pBMInfo->cbImage = cbInBuf;
    ConvertColorBitMap(pInBuf, pBMInfo, outPtr, fShrink);

    // now we need to tack on the alpha data, so jump back to the first
    // pixel in the output buffer
    outPtr = pOutBuf+2;

    // Get the mask info
    BMHeader.cbFix = sizeof(BMHeader);
    if (!GpiQueryBitmapInfoHeader(IconInfo.hbmPointer, &BMHeader))
      break;

    // if the existing input buffer isn't large enough, reallocate it
    cbInRow = ALIGNEDBPR(BMHeader.cx, BMHeader.cBitCount);
    if ((cbInRow * BMHeader.cy) > cbInBuf)  // Need more for mask
    {
      cbInBuf = cbInRow * BMHeader.cy;
      nsMemory::Free(pInBuf);
      pInBuf = (uint8_t*)nsMemory::Alloc(cbInBuf);
      memset(pInBuf, 0, cbInBuf);
    }

    // get the mask/alpha bits
    memset(pBMInfo, 0, cbBMInfo);
    *((PBITMAPINFOHEADER2)pBMInfo) = BMHeader;
    GpiSetBitmap(hps, IconInfo.hbmPointer);
    if (GpiQueryBitmapBits(hps, 0L, (LONG)BMHeader.cy,
                           (BYTE*)pInBuf, pBMInfo) <= 0)
      break;

    // convert the mask/alpha bitmap
    pBMInfo->cbImage = cbInBuf;
    ConvertMaskBitMap(pInBuf, pBMInfo, outPtr, fShrink);

    // create a pipe
    nsCOMPtr<nsIInputStream> inStream;
    nsCOMPtr<nsIOutputStream> outStream;
    rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream),
                    cbOutBuf, cbOutBuf, nonBlocking);
    if (NS_FAILED(rv))
      break;

    // put our data into the pipe
    uint32_t written;
    rv = outStream->Write(reinterpret_cast<const char*>(pOutBuf),
                          cbOutBuf, &written);
    if (NS_FAILED(rv))
      break;

    // success! so addref the pipe
    NS_ADDREF(*_retval = inStream);
  } while (0);

  // free all the resources we allocated
  if (pOutBuf)
    nsMemory::Free(pOutBuf);
  if (pInBuf)
    nsMemory::Free(pInBuf);
  if (pBMInfo)
    nsMemory::Free(pBMInfo);
  if (hps) {
    GpiAssociate(hps, NULLHANDLE);
    GpiDestroyPS(hps);
  }
  if (hdc)
    DevCloseDC(hdc);
  if (hIcon)
    DestroyIcon(hIcon, fWpsIcon);

  return rv;
}
Example #10
0
static VOID CreateROPBitmap(HWND hWnd)

{
BITMAPINFOHEADER  bmp;		   /* Bitmap Information Header		*/
BITMAPINFOHEADER2 bminfo2;	   /* Bitmap Information Header		*/
HBITMAP		  hbmConstruct;	   /* Bitmap Handle			*/
HDC		  hDC;		   /* Device Context Handle		*/
HPS		  hpsBitmap;	   /* Bitmap Presentation Space	Handle	*/
LONG		  cFormats;	   /* Formats Count			*/
LONG		  lROP = 0L;	   /* ROP Value				*/
PLONG		  plFormats;	   /* Formats Array			*/
POINTL		  aptl[4];	   /* Conversion Point			*/
RECTL		  rcl;		   /* Window Rectangle			*/
SIZEL		  sizl;		   /* Sizing Structure			*/
register INT i,	n;		   /* Loop Counters			*/

if ( hbmROP )
   GpiDeleteBitmap(hbmROP);

GpiQueryBitmapParameters(hbmView, &bmp);

		       /* Get bitmap device context handle for the main	*/
		       /* Client Window					*/

if ( !(hDC = DevOpenDC(hAB, OD_MEMORY, "*", 0L,	0L, 0L)) )
   return((HBITMAP)NULL);
		       /* Create bitmap	presentation space specifying	*/
		       /* entire map Client Window for size required	*/

WinQueryWindowRect(hWnd, &rcl);
lHorzRange = (cxROP = sizl.cx =	bmp.cx * 16L + 150L) - (cxWindow = rcl.xRight -	rcl.xLeft);
lVertRange = (cyROP = sizl.cy =	bmp.cy * 16L + 150L) - (cyWindow = rcl.yTop - rcl.yBottom);

WinSendMsg(hwndVScroll,	SBM_SETSCROLLBAR, MPFROMSHORT(lVertPos),
	   MPFROM2SHORT(0, lVertRange));
WinSendMsg(hwndVScroll,	SBM_SETTHUMBSIZE, MPFROM2SHORT(cyWindow, cyROP), 0L);

WinSendMsg(hwndHScroll,	SBM_SETSCROLLBAR, MPFROMSHORT(lHorzPos),
	   MPFROM2SHORT(0, lHorzRange));
WinSendMsg(hwndHScroll,	SBM_SETTHUMBSIZE, MPFROM2SHORT(cxWindow, cxROP), 0L);

rclROP.xLeft   = 0L;
rclROP.yBottom = cyROP - cyWindow;
rclROP.xRight  = cxWindow;
rclROP.yTop    = cyROP;

cxImage	= bmp.cx + 10L;
cyImage	= bmp.cy + 10L;

if ( !(hpsBitmap = GpiCreatePS(hAB, hDC, &sizl,	PU_PELS	| GPIT_NORMAL |	GPIA_ASSOC)) )
   {
		       /* Error	occurred during	creation of		*/
		       /* presentation space, close device context	*/
   DevCloseDC(hDC);
   return((HBITMAP)NULL);
   }
		       /* Get the number of bitmap formats that	the	*/
		       /* display driver supports			*/

DevQueryCaps(hDC, CAPS_BITMAP_FORMATS, 1L, &cFormats);

		       /* Get the bitmap display formats.  The first	*/
		       /* set within the array will be the one that	*/
		       /* most closely matches the display device.	*/

GpiQueryDeviceBitmapFormats(hpsBitmap, cFormats	* 2L,
			    plFormats =	(PLONG)malloc(2UL * cFormats * sizeof(LONG)));

		       /* Create actual	bitmap storage for colour wheel	*/
		       /* having the default plane and bit count	*/

memset(&bminfo2, 0, sizeof(BITMAPINFOHEADER2));
bminfo2.cbFix	  = sizeof(BITMAPINFOHEADER2);
bminfo2.cx	  = (ULONG)sizl.cx;
bminfo2.cy	  = (ULONG)sizl.cy;
bminfo2.cPlanes	  = (USHORT)plFormats[0];
bminfo2.cBitCount = (USHORT)plFormats[1];

free(plFormats);

if ( !(hbmConstruct = GpiCreateBitmap(hpsBitmap, &bminfo2, 0L, 0L, 0L))	)
   {
		       /* Error	occurred during	creation of bitmap	*/
		       /* storage, destroy presentation	space created	*/
		       /* and close device context opened		*/

   GpiDestroyPS(hpsBitmap);
   DevCloseDC(hDC);
   return((HBITMAP)NULL);
   }
		       /* Set bitmap as	current	bitmap to use		*/

GpiSetBitmap(hpsBitmap,	hbmConstruct);

		       /* Draw the page					*/
GpiErase(hpsBitmap);

aptl[0].x = 0L;
aptl[0].y = sizl.cy - bmp.cy;
aptl[1].x = bmp.cx;
aptl[1].y = sizl.cy;

aptl[2].x = aptl[2].y =	0L;
aptl[3].x = bmp.cx;
aptl[3].y = bmp.cy;

GpiSetPattern(hpsBitmap, lPattern);

for ( i	= 0; i < 16; i++ )
   {
   for ( n = 0;	n < 16;	n++ )
       {
       rcl.xLeft   = aptl[0].x;
       rcl.xRight  = aptl[1].x + 1L;
       rcl.yBottom = aptl[0].y;
       rcl.yTop	   = aptl[1].y + 1L;
       WinFillRect(hpsBitmap, &rcl, lFillColour);
       GpiWCBitBlt(hpsBitmap, hbmView, 4L, aptl, lROP++, BBO_IGNORE);
       aptl[0].x += (bmp.cx + 10L);
       aptl[1].x += (bmp.cx + 10L);
       }
   aptl[0].y -=	(bmp.cy	+ 10L);
   aptl[1].y -=	(bmp.cy	+ 10L);
   aptl[0].x = 0L;
   aptl[1].x = bmp.cx;
   }
		       /* Set the bitmap to allow completion of	bitmap	*/
		       /* in memory					*/

GpiSetBitmap(hpsBitmap,	(HDC)NULL);

		       /* Destroy the memory device context		*/

GpiAssociate(hpsBitmap,	(HDC)NULL);

		       /* Destroy the presentation spaces used		*/
GpiDestroyPS(hpsBitmap);
DevCloseDC(hDC);
		       /* Return the bitmap handle that	will be	used in	*/
		       /* painting the image on	the window		*/
hbmROP = hbmConstruct;
}
/*@ XPrinterDevice::SetupPrinter(char *title, XFrameWindow * owner, XString * queueName, XString * fileName)
@remarks Let the user select the printer-queue in a dialog. The dialog is loaded from OOLRES.DLL which must be installed.
@parameters
<t 'ø' c=2>
øchar *title            øthe title of the dialog
øXFrameWindow * owner   øowner window. If NULL, the dialog for the printer-setup is not opened
                         and the  queue given in parameter 3 is initialized directly
øXString * queueName      ødefault queue-name (can be null)
øXString * fileName      øbuffer for a fileName if the user wants to print to a file (if NULL no fiflename is stored)
</t>
@returns BOOL success
*/
BOOL XPrinterDevice::SetupPrinter(const char *title, const XFrameWindow * owner, XString * queueName, XString * fileName)
{
   BOOL fOK;
   CHAR szDefaultQueue[196];
   CHAR szSavedQueue[196];
   CHAR szWork[196];
   PCHAR pch;
   PPRQINFO3 pqi;
   SIZEL sizel;
   ULONG cReturned;
   ULONG cTotal;
   ULONG cbNeeded;
   ULONG ul;
   ULONG ulrc;

   // Caller must set these items before calling.
   if (!pSetup->hab || !pSetup->lWorldCoordinates)
      return FALSE;

   // no good unless I can open a PS
   pSetup->pDevOpenData = NULL;

   // Close the info DC's and PS's from any previous call.
   if (pSetup->hpsPrinterInfo)
   {
      GpiAssociate(pSetup->hpsPrinterInfo, (HDC) 0);
      GpiDestroyPS(pSetup->hpsPrinterInfo);
      pSetup->hpsPrinterInfo = (HPS) 0;
   }

   if (pSetup->hdcPrinterInfo)
   {
      DevCloseDC(pSetup->hdcPrinterInfo);
      pSetup->hdcPrinterInfo = (HDC) 0;
   }

   if (pSetup->pQueueInfo)
   {
      // Free the array of PRQINFO3 from previous call.
      free(pSetup->pQueueInfo);
      pSetup->pQueueInfo = NULL;
   }

   // Query how many queues exist on this computer and the
   // number of bytes needed to hold the array.
   ul = SplEnumQueue(NULL, 3, NULL, 0, &cReturned, &cTotal, &cbNeeded, NULL);
   if (cTotal == 0)
   {
      // There are no queues on this computer!
      pSetup->cQueues = 0;
      return FALSE;
   }

   // Allocate memory to store the newly enumerated queue information.
   pSetup->pQueueInfo = (PRQINFO3 *) malloc(cbNeeded);
   if (!pSetup->pQueueInfo)
      return FALSE;

   // Call system again to get the array of PRQINFO3 structures.
   ul = SplEnumQueue(NULL, 3, pSetup->pQueueInfo, cbNeeded, &cReturned, &cTotal, &cbNeeded, NULL);
   if (ul != 0 ||
      cReturned != cTotal)
      return FALSE;
   pSetup->cQueues = cReturned;

   // Establish a default queue -- might need it.
   // Profiled queue name ends with a semicolon.
   ul = PrfQueryProfileString(HINI_PROFILE, (PSZ) "PM_SPOOLER", (PSZ) "QUEUE", NULL, szDefaultQueue, 196);
   if (ul > 1)
   {
      // Trim off semicolon.
      pch = strchr(szDefaultQueue, ';');
      *pch = 0;
   }
   else
   {
      // Hmmmm. Use the first one queue from the enumeration.
      strcpy(szDefaultQueue, (char*) pSetup->pQueueInfo->pszName);
   }
   if (!strlen(szDefaultQueue))
      return FALSE;

   if (0 == strlen(pSetup->szPreferredQueue))
   {
      // No queue preference; use default.
      strcpy(pSetup->szPreferredQueue, szDefaultQueue);

      // Don't expect to see DRIVDATA without queue name.
      // if(! pSetup->pDriverData ) return FALSE;
   }

   if (queueName)
   {
      if (!queueName->IsEmpty())
      {
         pSetup->fToFile = FALSE;
         strcpy(pSetup->szPreferredQueue, (char *) *queueName);
      }
      if (fileName)
      {
         if (!fileName->IsEmpty())
         {
            pSetup->fToFile = TRUE;
            strcpy(pSetup->szFileName, (char *) *fileName);
         }
      }
   }

   pqi = FindQueue(pSetup);
   if (!pqi)
   {
      strcpy(pSetup->szPreferredQueue, szDefaultQueue);
      if (pSetup->pDriverData)
      {
         free(pSetup->pDriverData);
         pSetup->pDriverData = NULL;
      }
   }
   else
   {
      fOK = TRUE;

      if (pSetup->pDriverData)
      {
         fOK = fOK && (pqi->pDriverData->cb == pSetup->pDriverData->cb);
         fOK = fOK && (0 == strcmp(pqi->pDriverData->szDeviceName, pSetup->pDriverData->szDeviceName));
      }

      if (!fOK)
      {
         free(pSetup->pDriverData);
         pSetup->pDriverData = NULL;
      }
   }

   pqi = FindQueue(pSetup);

   if (!pSetup->pDriverData)
   {
      pSetup->pDriverData = (DRIVDATA *) malloc(pqi->pDriverData->cb);
      if (!pSetup->pDriverData)
      {
         ulrc = FALSE;
         return ulrc;
      }
      memcpy(pSetup->pDriverData, pqi->pDriverData, pqi->pDriverData->cb);
   }

   if (!pSetup->pDriverData || pSetup->pDriverData->cb <= 0 || pSetup->pDriverData->cb != pqi->pDriverData->cb || strcmp(pqi->pDriverData->szDeviceName, pSetup->pDriverData->szDeviceName))
      return FALSE;

   memcpy(pqi->pDriverData, pSetup->pDriverData, pSetup->pDriverData->cb);

   strcpy(szSavedQueue, pSetup->szPreferredQueue);

   if (owner)
   {
      XCountryInfo info;
      XResourceLibrary lib( "oolres");
      LONG dlgID;

      switch (info.GetCountry())
      {
      case 39:            // italy
         dlgID = IDD_SELPRINT_ITA;
         break;
      case 2:             // can francais
      case 33:            // france
      case 32:            // belgien
         dlgID = IDD_SELPRINT_FRA;
         break;
      case 49:            // german
         dlgID = IDD_SELPRINT_GER;
         break;
      default:            // english
         dlgID = IDD_SELPRINT_ENG;
      }
      XResource res(dlgID, &lib);

      PrinterDialog *printerDialog = new PrinterDialog(owner, pSetup, &res);
//      printerDialog->SetText((char*) title);
      LONG result = printerDialog->Start();
      if (result == DID_CANCEL)
         return FALSE;
   }
   else
   {
      if (queueName)
      {
         pSetup->fToFile = FALSE;
         strcpy(pSetup->szPreferredQueue, (char *) *queueName);

         if (fileName)
         {
            pSetup->fToFile = TRUE;
            strcpy(pSetup->szFileName, (char *) *fileName);
         }
      }
   }

   *queueName = "";
   *fileName = "";

   pqi = FindQueue(pSetup);
   if (!pqi)
      return FALSE;

   if (0 != strcmp(szSavedQueue, pSetup->szPreferredQueue))
   {
      if (!pSetup->pDriverData)
         return FALSE;
      free(pSetup->pDriverData);

      pSetup->pDriverData = (DRIVDATA *) malloc(pqi->pDriverData->cb);
      if (!pSetup->pDriverData)
      {
         ulrc = FALSE;
         return ulrc;
      }
      pSetup->pDriverData->cb = pqi->pDriverData->cb;
   }

   if (!pSetup->pDriverData || !pSetup->pDriverData->cb == pqi->pDriverData->cb)
      return FALSE;
   memcpy(pSetup->pDriverData, pqi->pDriverData, pqi->pDriverData->cb);

   if (pSetup->fToFile)
   {
      pSetup->lDCType = OD_DIRECT;
      pSetup->devopenstruc.pszLogAddress = (PSZ) pSetup->szFileName;
   }
   else
   {
      pSetup->lDCType = OD_QUEUED;
      pSetup->devopenstruc.pszLogAddress = (PSZ) pSetup->szPreferredQueue;
   }

   strcpy(szWork, (char*) pqi->pszDriverName);
   pch = strchr(szWork, '.');
   if (pch)
      *pch = 0;

   if (pSetup->devopenstruc.pszDriverName)
      free(pSetup->devopenstruc.pszDriverName);

   pSetup->devopenstruc.pszDriverName = (PSZ) malloc(1 + strlen(szWork));
   if (!pSetup->devopenstruc.pszDriverName)
      return FALSE;

   strcpy( (char*) pSetup->devopenstruc.pszDriverName, szWork);

   pSetup->devopenstruc.pdriv = pSetup->pDriverData;
   pSetup->devopenstruc.pszDataType = (PSZ) "PM_Q_STD";

   pSetup->hdcPrinterInfo = DevOpenDC(pSetup->hab, OD_INFO, (PSZ) "*", 4, (PDEVOPENDATA) & pSetup->devopenstruc, (HDC) 0);
   if (!pSetup->hdcPrinterInfo)
      return FALSE;

   sizel.cx = 0;
   sizel.cy = 0;
   pSetup->hpsPrinterInfo = GpiCreatePS(pSetup->hab, pSetup->hdcPrinterInfo, &sizel, pSetup->lWorldCoordinates | GPIA_ASSOC);

   if (GPI_ERROR == pSetup->hpsPrinterInfo)
   {
      DevCloseDC(pSetup->hdcPrinterInfo);
      pSetup->hdcPrinterInfo = (HDC) 0;
      pSetup->hpsPrinterInfo = (HPS) 0;
      return FALSE;
   }

   pSetup->pDevOpenData = (PDEVOPENDATA) & pSetup->devopenstruc;

   *queueName = pSetup->szPreferredQueue;
   if (pSetup->fToFile)
      *fileName = pSetup->szFileName;
   return TRUE;
}