Aros/Developer/Docs/Examples/GraphicScaling

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>

#include <graphics/scale.h>

#include <stdio.h>

static const char version[] = "$VER: Spy 41.1.2 (29.08.2008) by Olivier Tigréat";

void redraw(struct Window *spy_window, struct BitMap *wbm, struct Screen *observed_screen);

void redraw(struct Window *spy_window, struct BitMap *wbm, struct Screen *observed_screen)
{
    
    struct RastPort temprp;
    InitRastPort(&temprp);
    temprp.BitMap = wbm;

    struct BitScaleArgs bms_args;
    bms_args.bsa_SrcBitMap = observed_screen->RastPort.BitMap;
    bms_args.bsa_DestBitMap = temprp.BitMap;
    
    bms_args.bsa_Flags = 0;

    bms_args.bsa_SrcWidth = observed_screen->Width;
    bms_args.bsa_SrcHeight = observed_screen->Height;

    bms_args.bsa_SrcX = 0;
    bms_args.bsa_SrcY = 0;
    bms_args.bsa_DestX = 0;
    bms_args.bsa_DestY = 0;
    bms_args.bsa_XSrcFactor = observed_screen->Width;
    bms_args.bsa_XDestFactor = spy_window->GZZWidth;
    bms_args.bsa_YSrcFactor = observed_screen->Height;
    bms_args.bsa_YDestFactor = spy_window->GZZHeight;

    BitMapScale(&bms_args);

    ClipBlit(             &temprp,                      0,                     0,
                spy_window->RPort, spy_window->BorderLeft, spy_window->BorderTop,
             spy_window->GZZWidth,  spy_window->GZZHeight,                0x00C0);

    DeinitRastPort(&temprp);

}

int main()
{
    int retval   = 0;                           /* Return code for main() (Shell error code) */
    int closewin = FALSE;                       /* Flag used to end program */
    struct IntuiMessage *imsg;                  /* Structure to store Intuition message data */
    ULONG signals;                              /* User interaction reported by signals */
    struct Screen *screen = NULL, *observed_screen = NULL;
    struct Window *spy_window = NULL;           /* Our Spy window  */
    struct BitMap *scaledBitMap = NULL;         /* BitMap structure for scaled representation */
    IPTR depth = 0 ;

        
    if (NULL == (screen = LockPubScreen(NULL)))
    {
        retval = RETURN_ERROR;
        puts("LockPubScreen() failed to lock current screen");
    }
    
    else
        depth = GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH);
        
    if (depth == 0)
    {
        retval = RETURN_ERROR;
        puts("GetBitMapAttr() failed to get depth of screen");
    }
    
    else
        observed_screen = screen->NextScreen;
        
    if (!(scaledBitMap = AllocBitMap(                   screen->Width,
                                                       screen->Height,
                                                                depth,
                                                      BMF_DISPLAYABLE,
                                     observed_screen->RastPort.BitMap) ) )
    {
        UnlockPubScreen(NULL,screen);
        retval = RETURN_ERROR;
        puts("AllocBitMap() failed to allocate/initialise BitMap");
    }
    
    else
    {
        struct TagItem initial_tags[] = 
        {
            {          WA_Width , 160                                  },
            {         WA_Height , 120                                  },
            {           WA_Left , 400                                  },
            {            WA_Top , screen->BarHeight + 1                },
            {       WA_BackFill , (IPTR)LAYERS_NOBACKFILL              },
            {  WA_GimmeZeroZero , FALSE                                },
            {    WA_SizeBBottom , TRUE                                 },
            {        WA_DragBar , TRUE                                 },
            {        WA_RMBTrap , TRUE                                 },
            {    WA_DepthGadget , TRUE                                 },
            {    WA_CloseGadget , TRUE                                 },
            {     WA_SizeGadget , TRUE                                 },
            {  WA_NoCareRefresh , TRUE                                 },
            {          WA_IDCMP , IDCMP_CLOSEWINDOW|IDCMP_CHANGEWINDOW },
            {       WA_MinWidth , 80                                   },
            {      WA_MinHeight , 80                                   },
            {       WA_MaxWidth , -1                                   },
            {      WA_MaxHeight , -1                                   },
            {          WA_Title , (IPTR)"Spy"                          },
            {       WA_BackFill , (IPTR)LAYERS_NOBACKFILL              },
            {                     TAG_DONE                             }
        };
        
        
        if ( !(spy_window = OpenWindowTagList(NULL,initial_tags)))
        {
            UnlockPubScreen(NULL,screen);
            closewin = TRUE;
            retval = RETURN_ERROR;
            puts("OpenWindowTags() failed to open spy window");
        }
        
        else
        {
            UnlockPubScreen(NULL,screen);
            redraw(spy_window,scaledBitMap,observed_screen);
    
            while((closewin == FALSE))
            {
                signals = Wait(1L << spy_window->UserPort->mp_SigBit | SIGBREAKF_CTRL_C); /* Wait for an event! */
                if (signals & (1L << spy_window->UserPort->mp_SigBit))
                {
                    while ((imsg = (struct IntuiMessage *)GetMsg(spy_window->UserPort)))
                    {
                        switch (imsg->Class)
                        {
                            case IDCMP_CLOSEWINDOW:                     /* Check here if Close Window selected */
                                closewin = TRUE;                        /* so while loop will end there */
                                break;
                            case IDCMP_CHANGEWINDOW:
                                redraw(spy_window,scaledBitMap,observed_screen);
                                break;
                            case IDCMP_REFRESHWINDOW:
                                redraw(spy_window,scaledBitMap,observed_screen);
                                break;
                            default:
                                puts("Unknown IDCMP message");
                        } /* switch (imsg->Class) */
                           ReplyMsg((struct Message *)imsg);
                       } /* while ((imsg = (struct IntuiMessage *)GetMsg(spy_window->UserPort))) */
                } /* if(signals & (1L << spy_window->UserPort->mp_SigBit)) */
                if (signals & SIGBREAKF_CTRL_C)
                {
                    puts("Spy execution aborted with CTRL_C signal");
                    closewin = TRUE;
                } /* if (signals & SIGBREAKF_CTRL_C) */
            } /* while((closewin == FALSE)) */
        } /* else after if( !(spy_window... */
    } /* else after else if (!(scaledBitMap... */
    
    if (closewin == TRUE)
    {
        if (scaledBitMap) FreeBitMap(scaledBitMap);
        if (spy_window) CloseWindow(spy_window);             /* Close window */
        spy_window = NULL;
    }

    if(retval)
    {
        PrintFault(IoErr(), "spy");
    }
    return retval;
}