Aros/Developer/Docs/Libraries/Layers

Navbar for the Aros wikibook
Aros User
Aros User Docs
Aros User FAQs
Aros User Applications
Aros User DOS Shell
Aros/User/AmigaLegacy
Aros Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
Aros x86 Complete System HCL
Aros x86 Audio/Video Support
Aros x86 Network Support
Aros Intel AMD x86 Installing
Aros Storage Support IDE SATA etc
Aros Poseidon USB Support
x86-64 Support
Motorola 68k Amiga Support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Android Support
Arm Raspberry Pi Support
PPC Power Architecture
misc
Aros Public License

Introduction

edit

A layer is a rectangular drawing area. Every Intuition window has an associated Layer structure. Intuition windows are the only supported method of adding layers to Intuition screens. Using Intuition window calls

Layers

edit

The Layer Structure is Read-Only. Applications should never directly modify any of the elements of the Layer structure. In addition, applications should only read the front, back, rp, bounds, Flags, SuperBitMap and DamageList elements of the Layer structure.

When a layer is created, a RastPort is automatically to go along with it. The pointer to the RastPort is contained in the layer data structure. Using this RastPort, the application may draw anywhere into the layer’s bounds rectangle. If the application tries to draw outside of this rectangle, the graphics routines will clip the graphics.

Create rastport using layers.library calls and you get clipping. You just attach your bitmap to this rastport created by layers.lib. The normal graphics operations only perform clipping when there's a layer.


only one layer-type flag (LAYERSIMPLE, LAYERSMART and LAYERSUPER) should be specified.

created by using the primitives InitVPort(), InitView(), MakeVPort(), MrgCop(), and LoadView()


layers.library depends on graphics.library which depends on layers.library - this circular dependency expected? It occurs due to the autogenerated __LIBS_LIST__ for layers.library. graphics.library explicitly calls OpenLibrary() on layers.library

Graphics Primitives for creating a low-level graphics display on the common bit map by calling CreateUpfrontLayer() or CreateBehindLayer()

struct Layer_Info *NewLayerInfo( void );
void DisposeLayerInfo( struct Layer_Info *li );

How do you create a layer without a bitmap?

Usually call NewLayerInfo and CreateUpfrontLayer (which needs the bitmap pointer) and get a readily initialized RastPort from layer->rp.

RastPort width and height are 15 bits (struct Rectangle contains WORDs, not UWORDs). A bitmap with 32k pixel in a square would be more than 1000 megapixel.


Regions

edit

Use the routine InstallClipRegion() creates rectangle clipping (which allows graphic functions) within a layer

struct Region *NewRegion( void );
void DisposeRegion( struct Region *region );


Misc

edit

ABIv1

edit

Intuition and Layers, since they have their roots in MorphOS (because MorphOS has roots in AROS), but already have some extensions from OS4. The main question is window shaping implementation. Both MOS and AOS4 have this mechanism, with different API. Our own variant was close to AOS4 (perhaps they took it as base), so i fixed it up to be compatible (except ChangeLayerShape() function - not done yet).

1. If anyone can confirm that the implementation is OS4-compatible? I tried to google for some AOS4 code sample, but failed to find one.

2. Can anyone help me to complete ChangeLayerShape() ? It should use the same hook, according to OS4 autodocs. Unfortunately my understanding of Layers is very poor.

3. Our API better fits to follow MorphOS than OS4. This is mainly because we use library vectors for function calls, and not interfaces. This allows to have a binary compatibility with MorphOS in future. So, it's logical to implement MorphOS version of shaping. There's only one significant difference: MorphOS version is inverse of AOS one. I. e. in OS4 we provide a region describing visible area, in MorphOS we provide a region describing invisible one. So - would it be better to switch to MorphOS variant, or implement support for both? Both versions are not very redundant, i believe amount of code will be minimal.


BackFill Hooks

edit

With a slightly modified version of Thomas Rapp's backfill example. Try to change the backfill hook function to use:

  (msg->bounds.MinX - layer->bounds.MinX);
  (msg->bounds.MinY - layer->bounds.MinY);

in places where it used

  msg->offsetx
  msg->offsety

See workbench/demos/winbackfill.c.


Examples

edit
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/layers.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <aros/oldprograms.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <graphics/regions.h> 
#include <stdio.h>

struct NewWindow MyWin =
  {
    20,20,300,200,-1,-1,IDCMP_CLOSEWINDOW|/*IDCMP_DELTAMOVE|*/IDCMP_MOUSEMOVE,
    WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|WINDOWSIZING|WFLG_SMART_REFRESH|WFLG_REPORTMOUSE,
    NULL,NULL,(char *)"Testwindow",
    NULL,NULL,0,0,0,0,WBENCHSCREEN 
  };

struct GfxBase * GfxBase;
struct Library * LayersBase;

void installClipRegion(struct Window * w)
{
  int width, height;
  struct Rectangle Rect;
  ULONG x,y,line;
  struct Region * R = NewRegion();
  printf("Width of ClipRegion Rectangles: ");
  scanf("%i",&width);
  printf("Height of ClipRegion Rectangles: ");
  scanf("%i",&height);
  
  if (height == 0 || width == 0)
    return;
  y = 0;
  line = 0;
  while (y < w->Height)
  {
    x = (line & 1) * width;
    while (x < w->Width)
    {
      Rect.MinX = x;
      Rect.MinY = y;
      Rect.MaxX = x+width-1;
      Rect.MaxY = y+height-1;
      OrRectRegion(R,&Rect);
    
      x += (2*width);
    }
    y += height;
    line ++;
  }
  
  InstallClipRegion(w->WLayer, R);
  
}
  
void uninstallClipRegion(struct Window * w)
{
  struct Region * R = InstallClipRegion(w->WLayer, NULL);
  if (NULL != R)
    DisposeRegion(R);
}

int main(void)
{
  LayersBase = OpenLibrary("layers.library",0);
  GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
  if (NULL != GfxBase)
  {
    struct IntuitionBase * IntuitionBase =
       (struct IntuitionBase *)OpenLibrary("intuition.library",0);
    if (NULL != IntuitionBase)
    {
      struct Window * TheDude = OpenWindow(&MyWin);
      if (NULL != TheDude)
      {
        struct RastPort * rp = TheDude->RPort;
        struct TmpRas tmpras;
        struct IntuiMessage * Msg;
        UWORD areabuffer[250];
        char c;
        struct AreaInfo myAreaInfo;
        installClipRegion(TheDude);
        InitArea(&myAreaInfo, &areabuffer[0], 50);
        rp->AreaInfo = &myAreaInfo;
        InitTmpRas(&tmpras, AllocRaster(320,200),RASSIZE(320,200));
        rp->TmpRas = &tmpras;
        
        /* Let's draw something */
        SetAPen(rp,1);
        SetOutlinePen(rp,3);
        
/*
        AreaMove(rp,10,20);
        AreaDraw(rp,110,30);
        AreaDraw(rp,110,100);
        AreaDraw(rp,10,110);
        AreaEnd(rp);
*/

/**/
        AreaMove(rp,10,20);
        AreaDraw(rp,110,30);
        AreaDraw(rp,110,100);
        AreaDraw(rp,10,50);
        AreaEnd(rp);
/**/
/*
        AreaEllipse(rp, 110, 30, 50, 20);
        AreaEnd(rp);        
*/
/*
        Move(rp,0,0);
        Draw(rp,0,100);
        Draw(rp,100,110);
        Draw(rp,100,0);
        Draw(rp,0,0);
        SetAPen(rp, 1);
        Flood(rp,0,50,50);
*/
/*        
        ScrollRaster(&IntuitionBase->ActiveScreen->RastPort,
                     -1,
                     -1,
                     10,
                     10,
                     100,
                     100);
*/
        printf("press a key and hit return!");
        scanf("%c",&c);
        ScrollRaster(rp,
                     -10,
                     -10,
                     10,
                     10,
                     100,
                     100);

    
        while (TRUE)
        {               
          WaitPort(TheDude->UserPort);
          Msg = (struct IntuiMessage *)GetMsg(TheDude->UserPort);
          if (IDCMP_CLOSEWINDOW == Msg->Class)
            break;
          if (IDCMP_MOUSEMOVE == Msg->Class)
          {
            printf("Received a delta move message! (%i,%i)\n",Msg->MouseX,Msg->MouseY);
          }
          ReplyMsg((struct Message *)Msg);
        }
        uninstallClipRegion(TheDude);
        CloseWindow(TheDude);
      }
      CloseLibrary((struct Library *)IntuitionBase);
    }
    CloseLibrary((struct Library *)GfxBase);
  }
  
    return 0;
}


References

edit
void InitLayers(struct Layer_Info *li) 
struct Layer *CreateUpfrontLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, 
              LONG x1, LONG y1, LONG flags, struct BitMap *bm2) 
struct Layer *CreateBehindLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, 
              LONG x1, LONG y1, LONG flags, struct BitMap *bm2)

LONG UpfrontLayer(LONG dummy, struct Layer *l) 
LONG BehindLayer(LONG dummy, struct Layer *l) 
LONG MoveLayer(LONG dummy, struct Layer *l, LONG dx, LONG dy) 
LONG SizeLayer(LONG dummy, struct Layer *l, LONG dw, LONG dh) 
void ScrollLayer(LONG dummy, struct Layer *l, LONG dx, LONG dy)

LONG BeginUpdate(struct Layer *l) 
void EndUpdate(struct Layer *l, UWORD flag)

LONG DeleteLayer(LONG dummy, struct Layer *l) 
void LockLayer(LONG dummy, struct Layer *layer) 
void UnlockLayer(struct Layer *layer) 
void LockLayers(struct Layer_Info *li) 
void UnlockLayers(struct Layer_Info *li) 
void LockLayerInfo(struct Layer_Info *li) 
void SwapBitsRastPortClipRect(struct RastPort *rp, struct ClipRect *cr)

struct Layer *WhichLayer(struct Layer_Info *li, LONG x, LONG y) 
void UnlockLayerInfo(struct Layer_Info *li) 
struct Layer_Info *NewLayerInfo() 
void DisposeLayerInfo(struct Layer_Info *li) 
LONG FattenLayerInfo(struct Layer_Info *li) 
void ThinLayerInfo(struct Layer_Info *li) 
LONG MoveLayerInFrontOf(struct Layer *layer_to_move, struct Layer *other_layer)

struct Region *InstallClipRegion(struct Layer *l, struct Region *region) 
LONG MoveSizeLayer(struct Layer *l, LONG dx, LONG dy, LONG dw, LONG dh)

struct Layer *CreateUpfrontHookLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, 
             LONG x1, LONG y1, LONG flags, struct Hook *hook, struct BitMap *bm2) 
struct Layer *CreateBehindHookLayer(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, 
             LONG x1, LONG y1, LONG flags, struct Hook *hook, struct BitMap *bm2) 
struct Hook *InstallLayerHook(struct Layer *layer, struct Hook *hook) 
struct Hook *InstallLayerInfoHook(struct Layer_Info *li, struct Hook *hook)

void SortLayerCR(struct Layer *layer, LONG dx, LONG dy) 
void DoHookClipRects(struct Hook *hook, struct RastPort *rport, struct Rectangle *rect) 
struct Layer *CreateLayerTagList(struct Layer_Info *li, struct BitMap *bm, LONG x0, LONG y0, 
              LONG x1, LONG y1, LONG flags, struct TagItem *tagList) 
struct Layer *GetFirstFamilyMember(struct Layer *l) 
LONG ChangeLayerVisibility(struct Layer *l, int visible) 
LONG IsLayerVisible(struct Layer *l) 
struct Region *ChangeLayerShape(struct Layer *l, struct Region *newshape, struct Hook *callback) 
ULONG ScaleLayer(struct Layer *l, struct TagItem *taglist) 
BOOL IsFrontmostLayer(struct Layer *l, BOOL check_invisible) 
BOOL IsLayerHiddenBySibling(struct Layer *l, BOOL check_invisible) (A0,
void CollectPixelsLayer(struct Layer *l, struct Region *r, struct Hook *callback)