[comp.sys.amiga] UserClipRects

dale@amiga.UUCP (06/29/87)

This was a feature that was added in 1.2, so make sure you are asking
for library version 33.
To show this feature we modified the 'dotty' program, you should compare
the 1.1 and 1.2 SIDEBYSIDE to see the difference. It is subtle.
Anyway,
Here's the source, I thought I was having trouble with our news posting
so I'm sorry if this got out there twice.

This last compiler under Greenhills, It should compile under aztec
of lattice, make sure you use the 'long int' options.

------CUT HERE------

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/clip.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <intuition/intuition.h>

struct IntuitionBase *IntuitionBase;
struct LayersBase *LayersBase;
struct GfxBase *GfxBase;

#define DEPTH   2

#define WIDTH  100
#define HEIGHT 50

#define CLIPPING

#define IS_PAL (((struct GfxBase *)GfxBase)->DisplayFlags & PAL)

#define NTSC_MAX_HEIGHT 200
#define PAL_MAX_HEIGHT 256

int waiting_for_message = FALSE;

char dotty[] = "Dotty Window";

int usable_width(w)
struct Window *w;
{
#ifdef CLIPPING
        return (w->Width);
#else
   return (w->Width - w->BorderLeft - w->BorderRight);
#endif
}

int usable_height(w)
struct Window *w;
{
#ifdef CLIPPING
        return (w->Height);
#else
   return(w->Height - w->BorderTop - w->BorderBottom);
#endif
}

struct Region *NewRegion(),*InstallClipRegion();

clip_for_me(window)
struct Window *window;
{
#ifdef CLIPPING
        struct Rectangle Bounds;
        struct Region *clipregion = NewRegion();

	if(clipregion)
	{

		Bounds.MinX = window->BorderLeft;
		Bounds.MinY = window->BorderTop;
		Bounds.MaxX = window->Width - window->BorderRight;
		Bounds.MaxY = window->Height - window->BorderBottom;

		/* include only "positive" regions */
		if((Bounds.MinX < Bounds.MaxX)&&(Bounds.MinY < Bounds.MaxY))
		{
			OrRectRegion(clipregion,&Bounds);
		}

		/* calculate the rectangle that holds that little piece */
		/* above the size gadget */
		{
			USHORT target = SYSGADGET|SIZING;
			struct Gadget *g;
			for (g = window->FirstGadget; g ; g = g->NextGadget)
			{
				if ( (g->GadgetType & target) == target)
				{
					Bounds.MinX = Bounds.MaxX+1;
					Bounds.MaxX = 
					window->Width-window->BorderLeft;
					Bounds.MaxY = 
					window->Height - g->Height - 1;

					/* include only "positive" regions */
					if((Bounds.MinX < Bounds.MaxX)&&
					   (Bounds.MinY < Bounds.MaxY))
					{
					       OrRectRegion(clipregion,&Bounds);
					}
					break;
				}
			}
		}
		/* swap new one in */
		clipregion = InstallClipRegion(window->WLayer,clipregion);
		if (clipregion) DisposeRegion(clipregion);
	}
#endif
}

main()
{
   struct RastPort *rp;
   struct Window *window;
   struct NewWindow nw;
   int x,y,c;
   int xoffset,yoffset;
   int width,height;
   struct IntuiMessage *message;
   ULONG MessageClass;

   if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",33)))
   {
#ifdef DEBUG
      printf("no graphics library!!!\n");
#endif
      exit(1);
   }

   if (!(LayersBase = (struct LayersBase *)OpenLibrary("layers.library",33)))
   {
      CloseLibrary(GfxBase);
#ifdef DEBUG
      printf("no layers library!!!\n");
#endif
      exit(1);
   }

   if (!(IntuitionBase = (struct IntuitionBase *)
                           OpenLibrary("intuition.library",33)) )
   {
        CloseLibrary(GfxBase);
	CloseLibrary(LayersBase);
#ifdef DEBUG
      printf("no intuition here!!\n");
#endif
      exit(1);
   }

   nw.LeftEdge = 50;
   nw.TopEdge = 50;
   nw.Width = WIDTH;
   nw.Height = HEIGHT;
   nw.DetailPen = -1;
   nw.BlockPen = -1;
   nw.IDCMPFlags = CLOSEWINDOW
                 | REFRESHWINDOW
                 | SIZEVERIFY
                 | NEWSIZE;
   nw.Flags = WINDOWDEPTH
            | WINDOWSIZING
            | WINDOWDRAG
            | WINDOWCLOSE
            | SIMPLE_REFRESH;
   nw.FirstGadget = NULL;
   nw.CheckMark = NULL;
   nw.Title = dotty;
   nw.Screen = NULL;
   nw.BitMap = NULL;

   nw.MinHeight = 16;
   nw.MinWidth = 80;
   nw.MaxHeight = ~0; /* V32 and above */
   nw.MaxWidth = ~0;

   nw.Type = WBENCHSCREEN;

   if (!(window = (struct Window *)OpenWindow(&nw) ))
   {
#ifdef DEBUG
      printf("could not open the window\n");
#endif
      CloseLibrary(IntuitionBase);
      CloseLibrary(LayersBase);
      CloseLibrary(GfxBase);
      exit(2);
   }

   /* bart - 11.13.85 */
   SetWindowTitles(window,-1,dotty);

   width = usable_width(window);
   height = usable_height(window);
   rp = window->RPort;
#ifdef CLIPPING
   xoffset = 0;
   yoffset = 0;
   clip_for_me(window);
#else
   xoffset = window->BorderLeft;
   yoffset = window->BorderTop;
#endif
   while (TRUE)      /* do this forever, or until user gets bored */
   {
      while (!(message = (struct IntuiMessage *)GetMsg(window->UserPort)) )
      {
         if (waiting_for_message)   Wait(1<<window->UserPort->mp_SigBit);
         else
         {
            x = RangeRand(width);
            y = RangeRand(height);
            c = RangeRand(32);
            SetAPen(rp,c);
		    if ( WritePixel(rp,xoffset+x,yoffset+y) == -1 )
            {
                /* be nice - bart 11.18.85 */
                OwnBlitter();
                DisownBlitter();
            }
         }
      }
      MessageClass = message->Class;
      ReplyMsg(message);
      switch (MessageClass)
      {
         case CLOSEWINDOW  :
                           {
#ifdef CLIPPING
                              struct Region *r;
                              /* remove the ClipRegion before closewindow */
                              r = InstallClipRegion(window->WLayer,0);
                              if (r) DisposeRegion(r);
#endif
			      CloseWindow(window);
                              CloseLibrary(IntuitionBase);
                              CloseLibrary(LayersBase);
                              CloseLibrary(GfxBase);
                              exit(0);
			    }

        case SIZEVERIFY   :  waiting_for_message = TRUE;
                             break;

        case REFRESHWINDOW:  BeginRefresh(window);
                             SetAPen(rp,0);
                             /* should not have to recalculate these */
                             width = usable_width(window);
                             height = usable_height(window);
#ifdef CLIPPING
                             SetRast(rp,0);   /* let clipping do work */
#else
                             RectFill(rp,xoffset,yoffset,
                                         xoffset+width-1,yoffset+height-1);
#endif
                             EndRefresh(window,TRUE);
                             break;

        case NEWSIZE      :  waiting_for_message = FALSE;
                             width = usable_width(window);
                             height = usable_height(window);
#ifdef CLIPPING
                             clip_for_me(window);
#endif
                             break;
     }
  }
}

---- CUT HERE------