Copyright (c) Hyperion Entertainment and contributors.

Programming AmigaOS 4: Intuition - The User Interface

From AmigaOS Documentation Wiki
Jump to navigation Jump to search

This article was adapted from Amiga Future magazine's series on developing for AmigaOS....

After having worked "under the hood" in the two last issues, we'll be working with the interface from now on. The first point to understand is Intuition as an interface to the user. We'll try to show you what kind of innovations there are especially in the interface.

This issue's topic is massive, as Intuition is practically in charge of the complete 'Look & Feel', so there is quite a lot to explain as well.

First of all, I have to remind you that there are no custom chips any longer on the new computers and everything runs over the graphic card. So lots of things must be done internally and there are some really new design options in co-operation with the layers- and graphics.library for the windows and gadgets. You'll notice these changes immediately on the Workbench. Seen from the programmer's perspective nothing much has changed.

Everything is variable

If you've already clicked yourselves through the GUI-adjuster, you'll know just how many options are at your fingertips to design all the possible GUI elements. For some, there are far too many, but remember all the settings are supposed to end up giving a harmonious big picture. For example, windows can nowadays have shading, the background can display as (half)transparent, the captions can have colour gradients, and the windows can be presented with rounded edges. The width for the window frame used to be practically fixed: now it can be displayed very differently. In theory the left and right margin can have a different width. If you intend to position gadgets in the window frame, you should make them relative. So, if you write a text in the caption, what can occur is that the background colour does not match the rest of the caption.

That's why we'll take a simple Intuition window with sliders in the frame as our first example. This project is also compilable under AmigaOS 3.9 showing you that you don't have to program differently, if you've already made it compatible by default. You must translate the program with "gcc -D__USE_INLINE__ WinSlider.c -o WinSlider -lauto" because of the old denotation. It is due to Define that you can omit the Interface name before the function calls. In the sample program a simple keyboard command with cursor keys is included.

/* Michael Christoph - Musterbeispiel */
/* WinSlider - Fenster mit Schiebern im Rahmen */
 
/*
** gcc -D__USE_INLINE__ -D__USE_BASETYPE__ WinSlider.c -o WinSlider -l auto
*/
 
/******************************************************************************/
 
#include <exec/types.h>
#include <utility/tagitem.h>
#include <intuition/intuition.h>
 
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <intuition/cghooks.h>
#include <intuition/icclass.h>
 
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/utility.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdlib.h>
 
#define RAWKEY_CURSORUP    0x4C   /* CURSORUP */
#define RAWKEY_CURSORDOWN  0x4D   /* CURSORDOWN */
#define RAWKEY_CURSORLEFT  0x4F   /* CURSORLEFT */
#define RAWKEY_CURSORRIGHT 0x4E   /* CURSORRIGHT */
 
/******************************************************************************/
 
void cleanup(UBYTE *str);
void goHandleWindow(struct Window *win);
void UpdateSlider(struct Window *win);
 
/******************************************************************************/
 
struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct UtilityBase   *UtilityBase;
 
/* Prop-Gadget + Richtungs-Pfeile */
struct Gadget *rightpropg;
struct Gadget *uparrowg;
struct Gadget *downarrowg;
 
struct Gadget *bottompropg;
struct Gadget *leftarrowg;
struct Gadget *rightarrowg;
 
/* Images f¸r die Pfeiltasten  */
struct Image  *upimage;
struct Image  *downimage;
struct Image  *leftimage;
struct Image  *rightimage;
 
enum gadgetids
{
  gSliderR =1,
  gUp      =2,
  gDown    =3,
 
  gSliderB =4,
  gLeft    =5,
  gRight   =6,
};
 
LONG currvalr=0,   currvalb=0;     /* Aktuelle Position */
LONG currvalrs=10, currvalbs=10;   /* Anzahl Schritte */
 
/******************************************************************************/
 
void createallandrunit()
{
  struct Gadget   *mygadgets = NULL;
  struct Gadget   *tmpgad;
  struct Window   *win;
  struct DrawInfo *drinfo;
 
  if(!(UtilityBase=(struct Library *) OpenLibrary("utility.library",36)))
    cleanup("no V36 utility library\n");
 
  if(!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36)))
    cleanup("no V36 intuition library\n");
 
  if(!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",36)))
    cleanup("no V36 graphics library\n");
 
  if(!(win = OpenWindowTags(NULL,
      WA_Left,          300,
      WA_Top,            50,
      WA_Width,         240,
      WA_Height,        180,
      WA_Title,         "WinSliders Example",
      WA_Flags,         WFLG_ACTIVATE,
      WA_IDCMP,         IDCMP_GADGETDOWN | IDCMP_GADGETUP |
                        IDCMP_MOUSEMOVE | IDCMP_CLOSEWINDOW |
                        IDCMP_NEWSIZE | IDCMP_VANILLAKEY | IDCMP_RAWKEY,
      WA_SimpleRefresh, TRUE,
      WA_NoCareRefresh, TRUE,
      WA_DepthGadget,   TRUE,
      WA_DragBar,       TRUE,
      WA_CloseGadget,   TRUE,
      WA_SizeGadget,    TRUE,
      WA_SizeBRight,    TRUE,
      WA_SizeBBottom,   TRUE,
      WA_MinWidth,      100,
      WA_MinHeight,     50,
      WA_MaxWidth,      ~0,
      WA_MaxHeight,     ~0,
      TAG_DONE)))
    cleanup( "couldn't open my window.\n");
 
  drinfo = GetScreenDrawInfo(win->WScreen);
 
  /* erzeugen der Pfeil-Symbole */
  upimage = (struct Image *) NewObject(NULL, "sysiclass",
             SYSIA_Size,     0,    /* normal "medium-res" grˆfle */
             SYSIA_Which,    UPIMAGE,
             SYSIA_DrawInfo, drinfo,
             TAG_DONE);
 
  downimage = (struct Image *) NewObject(NULL, "sysiclass",
             SYSIA_Size,     0,    /* normal "medium-res" grˆfle */
             SYSIA_Which,    DOWNIMAGE,
             SYSIA_DrawInfo, drinfo,
             TAG_DONE);
 
  leftimage = (struct Image *) NewObject(NULL, "sysiclass",
             SYSIA_Size,     0,    /* normal "medium-res" Grˆfle */
             SYSIA_Which,    LEFTIMAGE,
             SYSIA_DrawInfo, drinfo,
             TAG_DONE);
 
  rightimage = (struct Image *) NewObject(NULL, "sysiclass",
             SYSIA_Size,     0,    /* normal "medium-res" Grˆfle */
             SYSIA_Which,    RIGHTIMAGE,
             SYSIA_DrawInfo, drinfo,
             TAG_DONE);
 
  /* erzeugen der einzelnen Gadgets */
  tmpgad = (struct Gadget *) &mygadgets;
 
  rightpropg = (struct Gadget *) NewObject(NULL, "propgclass",
               GA_Previous,    tmpgad,
               GA_ID,          gSliderR,
               GA_RelRight,    -13,
               GA_Top,         win->BorderTop + 1,
               GA_Width,       10,
               GA_RelHeight,   -win->BorderTop - win->BorderBottom - upimage->Height - downimage->Height - 2,
               GA_Immediate,   TRUE,
               GA_RelVerify,   TRUE,
               GA_RightBorder, TRUE,
               GA_FollowMouse, TRUE,      /* erzegt IDCMP_MOUSEMOVE */
               PGA_NewLook,    TRUE,
               PGA_Borderless, TRUE,
               PGA_Freedom,    FREEVERT,
               PGA_Top,        0,         /* Nummer des ersten sihtbaren Elements  */
               PGA_Visible,    1,         /* Anzahl der sichtbaren Elemente */
               PGA_Total,      currvalrs, /* Anzahl Stellungen */
               TAG_DONE);
 
  uparrowg = (struct Gadget *) NewObject(NULL, "buttongclass",
               GA_Previous,    rightpropg,
               GA_ID,          gUp,
               GA_Image,       upimage,
               GA_RelRight,    -upimage->Width + 1,
               GA_RelBottom,   -win->BorderBottom - upimage->Height - downimage->Height + 1,
               GA_Width,       upimage->Width,
               GA_Height,      upimage->Height,
               GA_Immediate,   TRUE,
               GA_RelVerify,   TRUE,
               GA_RightBorder,TRUE,
               TAG_DONE);
 
  downarrowg = (struct Gadget *) NewObject(NULL, "buttongclass",
               GA_Previous,    uparrowg,
               GA_ID,          gDown,
               GA_Image,       downimage,
               GA_RelRight,    -downimage->Width + 1,
               GA_RelBottom,   -win->BorderBottom - upimage->Height + 1,
               GA_Width,       upimage->Width,
               GA_Height,      upimage->Height,
               GA_Immediate,   TRUE,
               GA_RelVerify,   TRUE,
               GA_RightBorder,TRUE,
               TAG_DONE);
 
  bottompropg = (struct Gadget *) NewObject(NULL, "propgclass",
               GA_Previous,    downarrowg,
               GA_ID,          gSliderB,
               GA_Left,        5,
               GA_RelBottom,   -7,
               GA_RelWidth,    -win->BorderRight - leftimage->Width - rightimage->Width - 6,
               GA_Height,      6,
               GA_Immediate,   TRUE,
               GA_RelVerify,   TRUE,
               GA_BottomBorder,TRUE,
               GA_FollowMouse, TRUE,      /* erzegt IDCMP_MOUSEMOVE */
               PGA_NewLook,    TRUE,
               PGA_Borderless, TRUE,
               PGA_Freedom,    FREEHORIZ,
               PGA_Top,        0,         /* Nummer des ersten sihtbaren Elements  */
               PGA_Visible,    1,         /* Anzahl der sichtbaren Elemente */
               PGA_Total,      currvalbs, /* Anzahl Stellungen */
               TAG_DONE);
 
  leftarrowg = (struct Gadget *) NewObject(NULL, "buttongclass",
               GA_Previous,    bottompropg,
               GA_ID,          gLeft,
               GA_Image,       leftimage,
               GA_RelRight,    -win->BorderRight - leftimage->Width - rightimage->Width + 1,
               GA_RelBottom,   -win->BorderBottom + 1,
               GA_Width,       leftimage->Width,
               GA_Height,      leftimage->Height,
               GA_Immediate,   TRUE,
               GA_RelVerify,   TRUE,
               GA_BottomBorder,TRUE,
               TAG_DONE);
 
  rightarrowg = (struct Gadget *) NewObject(NULL, "buttongclass",
               GA_Previous,    leftarrowg,
               GA_ID,          gRight,
               GA_Image,       rightimage,
               GA_RelRight,    -win->BorderRight - leftimage->Width + 1,
               GA_RelBottom,   -win->BorderBottom + 1,
               GA_Width,       downimage->Width,
               GA_Height,      downimage->Height,
               GA_Immediate,   TRUE,
               GA_RelVerify,   TRUE,
               GA_BottomBorder,TRUE,
               TAG_DONE);
 
  /* alle Gadgets ins Fenster einh‰ngen */
  AddGList(win, mygadgets, -1, -1, NULL);
  RefreshGList(mygadgets, win, NULL, -1);
 
  /* Nachrichtenschleife */
  goHandleWindow(win);
 
  /* alle Gadgets wieder aus dem Fenster entfernen */
  RemoveGList(win, mygadgets, -1);
  FreeScreenDrawInfo(win->WScreen, drinfo);
  CloseWindow(win);
 
  /* komplette Liste der erzeugten Gadgets freigeben */
  while(mygadgets)
  {
    tmpgad = mygadgets->NextGadget;
    DisposeObject(mygadgets);
    mygadgets = tmpgad;
  }
 
  /* die Images m¸ssen seperat freigegeben werden */
  DisposeObject(upimage);
  DisposeObject(downimage);
  DisposeObject(leftimage);
  DisposeObject(rightimage);
 
  cleanup("all done");
}
 
/******************************************************************************/
 
void cleanup(UBYTE *str)
{
  if(str) Printf("%s\n", str);
 
  if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  if(GfxBase)       CloseLibrary((struct Library *)GfxBase);
  if(UtilityBase)   CloseLibrary(UtilityBase);
 
  exit(0);
}
 
/******************************************************************************/
 
void goHandleWindow(struct Window *win)
{
  struct IntuiMessage *imsg;
  struct Gadget *gad;
 
  for(;;)
  {
    WaitPort(win->UserPort);
    while((imsg=(struct IntuiMessage *) GetMsg(win->UserPort)))
    {
      switch(imsg->Class)
      {
        case IDCMP_CLOSEWINDOW:
          ReplyMsg((struct Message *) imsg);
          return;
 
        case IDCMP_GADGETDOWN:
          /* gedr¸cktes Gadget vermerken wenn IDCMP_MOUSEMOVE benutzt werden soll */
          break;
 
        case IDCMP_GADGETUP:
          gad = (struct Gadget *) imsg->IAddress;
 
          /* Pfeil-Gadgets (und Slider) auswerten */
          switch(gad->GadgetID)
          {
            case gSliderR:
                GetAttr(PGA_Top, gad, (ULONG*)&currvalr);
Printf("RIGHT %ld\n",currvalr);
                break;
            case gUp:
                if(currvalr > 0) currvalr--;
Printf("RIGHT %ld --\n",currvalr);
                UpdateSlider(win);
                break;
            case gDown:
                if(currvalr < currvalrs-1) currvalr++;
Printf("RIGHT %ld ++\n",currvalr);
                UpdateSlider(win);
                break;
 
            case gSliderB:
                GetAttr(PGA_Top, gad, (ULONG*)&currvalb);
Printf("BOTTOM %ld\n",currvalb);
                break;
            case gLeft:
                if(currvalb > 0) currvalb--;
Printf("BOTTOM %ld --\n",currvalb);
                UpdateSlider(win);
                break;
            case gRight:
                if(currvalb < currvalbs-1) currvalb++;
Printf("BOTTOM %ld ++\n",currvalb);
                UpdateSlider(win);
                break;
          }
          break;
 
        /* Tastatureingaben auswerten */
        case IDCMP_RAWKEY:
          if(imsg->Code == RAWKEY_CURSORLEFT)
          {
            if(currvalb > 0) currvalb--;
Printf("BOTTOM %ld --\n",currvalb);
            UpdateSlider(win);
          }
          if(imsg->Code == RAWKEY_CURSORRIGHT)
          {
            if(currvalb < currvalbs-1) currvalb++;
Printf("BOTTOM %ld ++\n",currvalb);
            UpdateSlider(win);
          }
          if(imsg->Code == RAWKEY_CURSORUP)
          {
            if(currvalr > 0) currvalr--;
Printf("RIGHT %ld --\n",currvalr);
            UpdateSlider(win);
          }
          if(imsg->Code == RAWKEY_CURSORDOWN)
          {
            if(currvalr < currvalrs-1) currvalr++;
Printf("RIGHT %ld ++\n",currvalr);
            UpdateSlider(win);
          }
          break;
      }
 
      ReplyMsg((struct Message *) imsg);
    }
  }
}
 
/******************************************************************************/
 
void UpdateSlider(struct Window *win)
{
  SetGadgetAttrs(rightpropg, win, NULL, PGA_Top, currvalr, TAG_DONE);
  SetGadgetAttrs(bottompropg, win, NULL, PGA_Top, currvalb, TAG_DONE);
}
 
/******************************************************************************/
 
int main()
{
  createallandrunit();
 
  return( 0 );
}
AF106 WinSlider-grab.png

Screens and windows

If you want to, you can move windows now beyond the screen boundaries. You must set the tag SA_OffScreenDragging to TRUE when you open a window. As the tag is not set by default, there can be some undesired side-effects in old programs.

If you want to be able to determine whether you can set a window according to your ideas, you can do it through the list in the intuition.library. It is recommended to turn off the multi-tasking so no-one can change the list while browsing it. There is a new function for it under AmigaOS4 IIntuition->LockScreenList(). It gives the index to the first screen as a return value. Based on the NextScreen, that is, FirstWindow references you can navigate through the list like before. To unlock the list use - IIntuition->UnlockScreenList() . As you can't either open or close a screen/window during this time, you should use the unlock command as little as possible. We'll find a handy way to implement it in the example "WindowList.c".

You can automatically create a message port in windows, or create it dynamically too if you have several windows. In a drawing program or a text editor, for instance, you must manually create a message port and give it to every window. When you close a window you must make sure that there are no more entries for that window in the message bar. If you set the tag WA_UserPort with a messageport when you open a window, Intuition immediately takes care of it so that it is nicely left. But you still have to do the programming to create and de-allocate the actual message port.

A new tag for windows is WA_Hidden. You can use it to create windows that are not visible. As this option doesn't seem to make much sense there are two functions IIntuition->ShowWindow() and Iintuition->HideWindow() that enable you to show and hide a window. The whole thing works the other way around too; if you don't need a window at the moment, but you don't want to close it. Unlike the present Iconify options the window remains entirely in memory at this point and so all the pointers are valid too. We also created a mini program "HideWindow.c" for this purpose as well. You can start it from the console, show the window with CTRL-E, hide it with CTRL-F and close the program with CTRL-C. The previous program WindowList shows you that there is a window even though it is not visible.

  • EasyRequester

Programmers can use EasyRequesters to give a user feedback or to make queries with several options. The "EasyStruct" has been expanded so it now can be used even more flexibly. For example, previously the window was always opened top left and on the Workbench. You could change this if you passed a window pointer, which was only possible if you already had an open window on your own screen. For this case there is now the entry es_Screen that must be used in combination with es_Flag = ESF_SCREEN. Additionally, you can also pass a taglist with es_TagList. In order to be considered you must enable it with es_Flag = ESF_TAGGED. There is so far only one possible tag for the position of the window with ESA_Position:

 REQPOS_DEFAULT ? use Prefs settings
 REQPOS_CORNER ? top left on the screen
 REQPOS_BELOWBAR ? top left underneath the screen caption
 REQPOS_CENTERMOUSE ? in the centre underneath the mouse
 REQPOS_CENTERSCREEN ? in the centre of the screen
 REQPOS_CENTERWINDOW ? in the centre of the active window

You can find the practical use in the code example "EasyRequester.c".

  • The forgotten requester.class

The requester.class was already introduced with AmigaOS2 in-line with the Boopsi concept. But because of the EasyRequester it hardly gained any attention. With AmigaOS4 the class has been upgraded significantly offering new possibilities and tags.

Using REQ_Type you can select four predefined types:

 REQTYPE_INFO       (value 0) = Information/Query
 REQTYPE_INTEGER    (value 1) = number input
 REQTYPE_STRING     (value 2) = text input
 REQTYPE_PROGRESS   (value 3) = progress bar (still not available)

The Tag REQ_Image is particularly interesting. It allows the use of predefined symbols that are shown in the requester (on the left).

The following symbols are available:
 REQIMAGE_DEFAULT = empty
 REQIMAGE_INFO = show information
 REQIMAGE_WARNING = warning, hints 
 REQIMAGE_ERROR = error, program abort
 REQIMAGE_QUESTION = in a query
 REQIMAGE_INSERTDISK = demand disk

Alternatively, you can also use your own image (of type struct Image *). All the options are summarised in the example "Requester.c".

  • Mouse wheel

Nowadays a computer mouse can have one, or several wheels, that you can use in order to scroll through a document, for example, without having to press and move the scroller. So you can perform this action without having to physically move the mouse. The general support is already implemented in AmigaOS, in your own program there is an option for you to ensure that you have context-dependent support.

For this you need to set the IDCMP-Flag on IDCMP_EXTENDEDMOUSE when you create a window. This flag shows up when you move the mouse wheel and is also set in the code field IMSGCODE_INTUIWHEELDATA. Over the IAdress pointer you can get the IntuiWheelData structure where increments for up to two mouse wheels can be readout (X=mousewheel 1 and Y=mousewheel 2). However, there is a fly in the ointment, because if you create the window with window.class, as is usually the case in current applications, there is still no support for it, and you must attach a WINDOW_IDCMPHook additionally in order to be able to analyze the message.

As not all mice have two wheels, but the program provides two possibilities in some situations (e.g. scroll up/down or left/right browser window content), you can solve this problem with an additionally pressed key. For example, if you hold the CTRL-key pressed, then you can simulate the movement of the mousewheel 2 with a movement of the mousewheel 1. So far there is no general recommendation or setting in the operating system for this situation. A possible implementation is to be found in the example "MouseWheelTest.c".

  • Further changes

The Boopsi classes have now received the official type "struct ClassLibrary *" too and have now their own functions for opening and closing. Previously, you had to resort to Iexec->OpenLibrary()/IExec->CloseLibrary() for this purpose, and in some cases search in different directories as well. Besides, the function IIntuition->OpenClass() returns the class pointer in the third argument. You can rely on this in all system classes; in other developments you must definitely check the pointer. If you are not in the mood for it, you can simply enter "-l auto" and all required Boopsi gadgets, images and classes are automatically opened from the startup-code.

There are also new functions to set and determine window and screen attributes too. In future you won't have to read or change screen/window structures, but there will be a normalised interface that will take care of it. So far only a part of the SA_xxx and WA_xxx tags can be used for it. The function names are IIntuition->GetScreenAttr()/IIntuition->SetScreenAttr() for screens, i.e., IIntuition->GetWindowAttr()/IIntuition->SetWindowAttr() for windows.

  • Rainbow

So, before we finish this part, we'll use some colours. There is now a function in Intuition, with which you can draw a colour gradient. You must fill out a structure GradientSpec (from intuition/intuition.h) for this. Primarily, these are, the RGB start value, and RGB end value for the gradient, and an angle. The angle (in the 0-359 degree range) must be converted before with IIntuition->DirectionVector(). The actual drawing in the rastport stating the size is done by Iintuition->DrawGradient(). Under "GradientPrg.c" you'll find a practical example that draws the gradient of type COLOR and allows the colour value setting. You can take over the window in your own projects too if the option for the colour gradient selection is given.

  • Finished

So we've come to the end of this part. To complete it we've created a short list with lots of new functions. In the next issue we'll deal with the graphics- and layers.library that works closely with today's intuition.library. In one of the next issues we'll handle the subject of transparent windows and how you can program frameless windows yourselves.



[*** Kasten] New functions in the intuition.library V50-52

[*** zuerst steht die Erkl‰rung, darunter dann ein oder zwei dazugehˆrige Kommandos]

Open and close Boopsi (Reaction) classes:

 struct ClassLibrary *OpenClass( STRPTR name, ULONG version, Class **clasr );
 VOID CloseClass( struct ClassLibrary *cl );

internal help functions for Boopsi objects

 VOID DoRender( Object *o, struct GadgetInfo *gi, ULONG flags );

Conducting a Boopsi method (Boopsi-intern):

 ULONG ICoerceMethodA( Class *cl, Object *obj, Msg msg );

Conducting a Super method (Boopsi-intern):

 ULONG IDoSuperMethodA( Class *cl, Object *obj, Msg msg );

Conducting a Set method (Boopsi-intern):

 ULONG ISetSuperAttrsA( Class *cl, Object *obj, struct TagItem *taglist );

Locking a screen (Boopsi-intern):

 struct RastPort *LockScreenGI( struct GadgetInfo *gi, ULONG micros );
 VOID UnlockScreenGI( struct GadgetInfo *gi, struct RastPort *rastport );

Monitoring a screen for changes

 APTR StartScreenNotifyTagList( struct TagItem *taglist );
 BOOL EndScreenNotify( APTR screen );

determining the absolute position and size of a gadget:

 ULONG GadgetBox( struct Gadget *gad, APTR domain, ULONG type, ULONG flags, APTR box);

determining the attributes of a Boopsi gadget:

 ULONG GetAttrsA (Object *object, struct TagItem *taglist);

determining/setting the screen attributes:

 LONG GetScreenAttr( struct Screen *scr, ULONG attr, LONG data, LONG size );
 LONG SetScreenAttr( struct Screen *scr, ULONG attr, LONG data, LONG size );

determining/setting the window attributes:

 LONG GetWindowAttr( struct Window *win, ULONG attr, LONG data, LONG size );
 LONG SetWindowAttr( struct Window *win, ULONG attr, LONG data, LONG size );

Showing/hiding the window:

 BOOL ShowWindow( struct Window *win, struct Window *other );
 BOOL HideWindow( struct Window *win );

Conducting a Boopsi method:

 ULONG IDoMethodA( Object *obj, Msg msg );

Determining the required space for a text output Locking a screen (instead of LockLayers):

 BOOL LockScreen( struct Screen *scr, ULONG micros );
 VOID UnlockScreen( struct Screen * scr );

Locking the screen list for changes:

 struct Screen *LockScreenList( VOID );
 VOID UnlockScreenList( VOID );

determining the FillHock for the background:

 struct Hook *ObtainIBackFill( struct DrawInfo *di, ULONG element, ULONG state, ULONG flags );
 VOID ReleaseIBackFill( struct Hook *hook );

setting attributes for a Boopsi gadget and possibly refreshing the display:

 VOID RefreshSetGadgetAttrsA( struct Gadget *gad, struct Window *win, struct Requester *req, struct TagItem *taglist );

removing all messages from the messageport for a defined window:

 VOID StripIntuiMessages( struct MsgPort *msgport, struct Window *win );

Hook for filling free areas when scrolling

 VOID DoScrollHook(struct ScrollHook *scroll_hook, LONG scroll_mode);

requesting i.e. setting an area in the RastPort, in which you can draw:

 ULONG GetRenderDomain( struct RastPort *rp, struct Rectangle *rect );
 ULONG SetRenderDomain( struct RastPort *rp, struct Rectangle *rect );

Drawing a colour gradient:

 ULONG DrawGradient( struct RastPort * rp, LONG left, LONG top, LONG width, LONG height, struct IBox * domain, ULONG reserved, struct GradientSpec * gradientspec, struct DrawInfo * dri );
 ULONG DirectionVector( ULONG degrees );

Authors

Written by Michael Christoph and Bernd Schmidt
Copyright (c) 2013 Michael Christoph