Corrected Example: Graphics Regions

Report errors, omissions, etc. regarding the AmigaOS Documentation Wiki here.
Post Reply
dstastny
Posts: 48
Joined: Fri Dec 16, 2016 6:31 am
Location: Atlanta GA

Corrected Example: Graphics Regions

Post by dstastny »

http://wiki.amigaos.net/wiki/Graphics_Regions

Code: Select all

/* clipping.c */
 
/* Force use of new variable names to help prevent errors */
#define INTUI_V36_NAMES_ONLY
 
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/displayinfo.h>
 
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/layers.h>
 
#define MY_WIN_WIDTH  (300)
#define MY_WIN_HEIGHT (100)
 
struct IntuitionIFace *IIntuition;
struct GraphicsIFace *IGraphics;
struct LayersIFace *ILayers;
 
/*
** unclipWindow()
**
** Used to remove a clipping region installed by clipWindow() or
** clipWindowToBorders(), disposing of the installed region and
** reinstalling the region removed.
*/
void unclipWindow(struct Window *win)
{
struct Region     *old_region;
 
/* Remove any old region by installing a NULL region,
** then dispose of the old region if one was installed.
*/
if (NULL != (old_region = ILayers->InstallClipRegion(win->WLayer, NULL)))
    IGraphics->DisposeRegion(old_region);
}
 
/*
** clipWindow()
** Clip a window to a specified rectangle (given by upper left and
** lower right corner.)  the removed region is returned so that it
** may be re-installed later.
*/
struct Region *clipWindow(struct Window *win,
    LONG minX, LONG minY, LONG maxX, LONG maxY)
{
struct Region    *new_region;
struct Rectangle  my_rectangle;
 
/* set up the limits for the clip */
my_rectangle.MinX = minX;
my_rectangle.MinY = minY;
my_rectangle.MaxX = maxX;
my_rectangle.MaxY = maxY;
 
/* get a new region and OR in the limits. */
if (NULL != (new_region = IGraphics->NewRegion()))
    {
    if (FALSE == IGraphics->OrRectRegion(new_region, &my_rectangle))
        {
        IGraphics->DisposeRegion(new_region);
        new_region = NULL;
        }
    }
 
/* Install the new region, and return any existing region.
** If the above allocation and region processing failed, then
** new_region will be NULL and no clip region will be installed.
*/
return(ILayers->InstallClipRegion(win->WLayer, new_region));
}
 
/*
** clipWindowToBorders()
** clip a window to its borders.
** The removed region is returned so that it may be re-installed later.
*/
struct Region *clipWindowToBorders(struct Window *win)
{
return(clipWindow(win, win->BorderLeft, win->BorderTop,
    win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1));
}
 
/*
** Wait for the user to select the close gadget.
*/
VOID wait_for_close(struct Window *win)
{
struct IntuiMessage *msg;
SHORT done;
 
done = FALSE;
while (FALSE == done)
    {
    /* we only have one signal bit, so we do not have to check which
    ** bit broke the Wait().
    */
    IExec->Wait(1L << win->UserPort->mp_SigBit);
 
    while ( (FALSE == done) &&
            (NULL != (msg = (struct IntuiMessage *)IExec->GetMsg(win->UserPort))))
        {
        /* use a switch statement if looking for multiple event types */
        if (msg->Class == IDCMP_CLOSEWINDOW)
            done = TRUE;
 
        IExec->ReplyMsg((struct Message *)msg);
        }
    }
}
 
/*
** Simple routine to blast all bits in a window with color three to show
** where the window is clipped.  After a delay, flush back to color zero
** and refresh the window borders.
*/
VOID draw_in_window(struct Window *win, UBYTE *message)
{
IDOS->Printf("%s...", message); 
IGraphics->SetRast(win->RPort, 3);
IDOS->Delay(200);
IGraphics->SetRast(win->RPort, 0);
IIntuition->RefreshWindowFrame(win);
IDOS->Printf("done\n");
}
 
 
/*
** Show drawing into an unclipped window, a window clipped to the
** borders and a window clipped to a random rectangle.  It is possible
** to clip more complex shapes by AND'ing, OR'ing and exclusive-OR'ing
** regions and rectangles to build a user clip region.
**
** This example assumes that old regions are not going to be re-used,
** so it simply throws them away.
*/
VOID clip_test(struct Window *win)
{
struct Region    *old_region;
 
draw_in_window(win,"Window with no clipping");
 
/* if the application has never installed a user clip region,
** then old_region will be NULL here.  Otherwise, delete the
** old region (you could save it and re-install it later...)
*/
if (NULL != (old_region = clipWindowToBorders(win)))
    IGraphics->DisposeRegion(old_region);
draw_in_window(win,"Window clipped to window borders");
unclipWindow(win);
 
/* here we know old_region will be NULL, as that is what we
** installed with unclipWindow()...
*/
if (NULL != (old_region = clipWindow(win,20,20,100,50)))
    IGraphics->DisposeRegion(old_region);
draw_in_window(win,"Window clipped from (20,20) to (100,50)");
unclipWindow(win);
 
wait_for_close(win);
}
 
 
 
/*
** Open and close resources, call the test routine when ready.
*/
int main(int argc, char **argv)
{
  struct Window *win;
 
  struct Library *IntuitionBase = IExec->OpenLibrary("intuition.library", 50);
  IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase, "main", 1, NULL);
 
  struct Library *GfxBase = IExec->OpenLibrary("graphics.library", 50);
  IGraphics = (struct GraphicsIFace*)IExec->GetInterface(GfxBase, "main", 1, NULL);
 
  struct Library *LayersBase = IExec->OpenLibrary("layers.library", 50);
  ILayers = (struct LayersIFace*)IExec->GetInterface(LayersBase, "main", 1, NULL);
 
  if (IIntuition != NULL && IGraphics != NULL && ILayers != NULL)
  {
    if (NULL != (win =IIntuition->OpenWindowTags(NULL,
                             WA_Width,       MY_WIN_WIDTH,
                             WA_Height,      MY_WIN_HEIGHT,
                             WA_IDCMP,       IDCMP_CLOSEWINDOW,
                             WA_CloseGadget, TRUE,
                             WA_DragBar,     TRUE,
                             WA_Activate,    TRUE,
                             TAG_END)))
    {
      clip_test(win);
 
      IIntuition->CloseWindow(win);
    }
  }
 
  IExec->DropInterface((struct Interface*)ILayers);
  IExec->CloseLibrary(LayersBase);
 
  IExec->DropInterface((struct Interface*)IGraphics);
  IExec->CloseLibrary(GfxBase);
 
  IExec->DropInterface((struct Interface*)IIntuition);
  IExec->CloseLibrary(IntuitionBase);
 
  return 0;
}


User avatar
trixie
Posts: 409
Joined: Thu Jun 30, 2011 2:54 pm
Location: Czech Republic

Re: Corrected Example: Graphics Regions

Post by trixie »

@dstastny

Thank you - code updated in the wiki.
The Rear Window blog

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon RX 560 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
Post Reply