@DATABASE Libraries Manual
@NODE MAIN "Amiga RKM Libraries: 11 Intuition Special Functions"
@INDEX Lib_Index/MAIN
@TOC Libraries_Manual/User
There are several Intuition topics which, while not large enough to fill
chapters of their own, nontheless deserve to be discussed.  The subjects
covered here include locking @{"IntuitionBase" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuitionbase.h/MAIN 59}, the Intuition memory functions
@{"AllocRemember()" link 11-2-1} and @{"FreeRemember()" link 11-2-1 29}, using sprites with Intuition, and
Intuition's special internal functions.

@{" Locking IntuitionBase " link 11-1}
@{" Easy Memory Allocation and Deallocation " link 11-2}
@{" Current Time Values " link 11-3}
@{" Using Sprites in Intuition Windows and Screens " link 11-4}
@{" Intuition and Preferences " link 11-5}
@{" Function Reference " link 11-6}

@ENDNODE

@NODE 11-1 "11 Intuition Special Functions / Locking IntuitionBase"
It is sometimes necessary to examine the @{"IntuitionBase" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuitionbase.h/MAIN 59} structure.  Items
such as the address of the active screen and window, current mouse
coordinates and more can be found there.  It is never a good idea to
simply read these fields, as they are prone to sudden change.  The
IntuitionBase structure must always be locked before looking at its fields.

It is necessary to inform Intuition that an application is about to
examine @{"IntuitionBase" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuitionbase.h/MAIN 59} so that Intuition will not change any variables and
IntuitionBase will remain static during the access.  The call @{"LockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/LockIBase()}
will lock the state of IntuitionBase so that it may be examined.  During
the time that the application has IntuitionBase locked, all Intuition
input processing is frozen.  Make every effort to examine IntuitionBase
and release the lock as quickly as possible.  The values in IntuitionBase
are read-only.  Applications should never write values to IntuitionBase.

    ULONG LockIBase( unsigned long dontknow );

@{"LockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/LockIBase()} is passed a ULONG (dontknow in the prototype above) indicating
the Intuition lock desired.  For all foreseeable uses of the call this
value should be 0.  LockIBase() returns a ULONG, that must be passed to
@{"UnlockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/UnlockIBase()} later to allow @{"IntuitionBase" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuitionbase.h/MAIN 59} to change once again.

Every call to @{"LockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/LockIBase()} must be matched by a subsequent call to
@{"UnlockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/UnlockIBase()}:

    void UnlockIBase( unsigned long ibLock );

Set the ibLock argument to the value returned by the previous call to
@{"LockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/LockIBase()}.

    About LockIBase().
    ------------------
    This function should not be called while holding any other system
    locks such as @{"Layer" link ADCD_v1.2:Reference_Library/Libraries/Lib_30/30-1-1} and @{"Layer_Info" link ADCD_v1.2:Inc&AD2.1/includes/graphics/Layers.h/MAIN 33} locks.  Between calls to
    @{"LockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/LockIBase()} and @{"UnlockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/UnlockIBase()}, you may not call any Intuition
    or other high-level system functions so it is best to copy the
    information you need and release the lock as quickly as possible.

    About IntuitionBase.
    --------------------
    Never, ever, modify any of the fields in @{"IntuitionBase" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuitionbase.h/MAIN 59} directly.
    Also, there are fields in IntuitionBase that are considered system
    private that should not be accessed, even for reading.  (Refer to the
    <intuition/@{"intuitionbase" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuitionbase.h/MAIN}> include file.) Application programs
    cannot depend on (and should not use) the contents of these fields;
    their usage is subject to change in future revisions of Intuition.

@ENDNODE

@NODE 11-2 "11 Special Functions / Easy Memory Allocation and Deallocation"
Intuition has a pair of routines that enable applications to make multiple
memory allocations which are easily deallocated with a single call.  The
Intuition routines for memory management are @{"AllocRemember()" link 11-2-1} and
@{"FreeRemember()" link 11-2-1 29}.  These routines rely upon the @{"Remember" link 11-2-3} structure to track
allocations.

@{" Intuition Helps You Remember " link 11-2-1}  @{" The Remember Structure " link 11-2-3}
@{" How to Remember " link 11-2-2}               @{" An Example of Remembering " link ADCD_v1.2:Reference_Library/Libraries/lib_examples/remembertest.c/MAIN}

@ENDNODE

@NODE 11-2-1 "11 / Easy Memory Allocation and Deallocation / Helps You Remember"
The @{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()} routine calls the Exec @{"AllocMem()" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/20-1} function to perform
the memory allocation.  (Of course, the application may directly call Exec
memory functions, see the chapter "@{"Exec Memory Allocation" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/MAIN}" for details.)

@{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()} performs two allocations each time it is called.  The
first allocation is the actual memory requested by the application.  This
memory is of the size and type specified in the call and is independent of
the second block of memory.  The second allocation is memory for a
@{"Remember" link 11-2-3} structure which is used to save the specifics of the allocation
in a linked list.  When @{"FreeRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/FreeRemember()} is called it uses the information
in this linked list to free all previous memory allocations at once.  This
is convenient since normally you would have to free each memory block one
at a time which requires knowing the size and base address of each one.

The @{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()} call takes three arguments:

    APTR AllocRemember( struct Remember **rememberKey, unsigned long size,
                        unsigned long flags );

The rememberKey is the address of a pointer to a @{"Remember" link 11-2-3} structure.  Note
that this is a double indirection, not just a simple pointer.  The size is
the size, in bytes, of the requested allocation.  The flags argument is
the specification for the memory allocation.  These are the same as the
specifications for the Exec @{"AllocMem()" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/20-1} function described in the chapter
on "@{"Exec Memory Allocation" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/MAIN}".

If @{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()} succeeds, it returns the address of the allocated
memory block.  It returns a NULL if the allocation fails.

The @{"FreeRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/FreeRemember()} function gives the option of freeing memory in either
of two ways.  The first (and most useful) option is to free both the link
nodes that @{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()} created and the memory blocks to which they
correspond.  The second option is to free only the link nodes, leaving the
memory blocks for further use (and later deallocation via Exec's @{"FreeMem()" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/20-1 11}
function).  But, as a general rule, the application should never free only
the link nodes as this can greatly fragment memory.  If the link nodes are
not required, use the Exec memory allocation functions.

The @{"FreeRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/FreeRemember()} call is as follows:

    void FreeRemember( struct Remember **rememberKey, long reallyForget );

Set the rememberKey argument to the address of a pointer to a @{"Remember" link 11-2-3}
structure.  This is the same value that was passed to previous calls to
@{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()}.  The reallyForget argument is a boolean that should be
set to TRUE.  If TRUE, then both the link nodes and the memory blocks are
freed.  If FALSE, then only the link nodes are freed.  Again, applications
should avoid using the FALSE value since it can lead to highly fragmented
memory.

@ENDNODE

@NODE 11-2-2 "11 / Easy Memory Allocation and Deallocation / How to Remember"
To use Intuition's memory functions, first create an anchor for the memory
to be allocated by declaring a variable that is a pointer to a @{"Remember" link 11-2-3}
structure and initializing that pointer to NULL.  This variable is called
the remember key.

    struct Remember *rememberKey = NULL;

Call @{"AllocRemember()" link 11-2-1} with the address of the remember key, along with the
memory requirements for the specific allocation.  Multiple allocations may
be made before a call to @{"FreeRemember()" link 11-2-1 29}.

    memBlockA = AllocRemember(&rememberKey, SIZE_A,
                              MEMF_CLEAR | MEMF_PUBLIC);
    if (memBlockA == NULL)
        {
        /* error: allocation failed */
        printf("Memory allocation failed.\n");
        }
    else
        {
        /* use the memory here */
        printf("Memory allocation succeeded.\n");
        }

@{"AllocRemember()" link 11-2-1} actually performs two memory allocations per call, one for
the memory requested and the other for a @{"Remember" link 11-2-3} structure.  The Remember
structure is filled in with data describing the allocation, and is linked
into the list to which the remember key points.

To free memory that has been allocated, simply call @{"FreeRemember()" link 11-2-1 29} with
the correct remember key.

    void FreeRemember(&rememberKey, TRUE);

This will free all the memory blocks previously allocated with
@{"AllocRemember()" link 11-2-1} in a single call.

@ENDNODE

@NODE 11-2-3 "11 / Easy Memory Allocation and Deallocation / The Remember Structure"
The Remember structure is defined in <intuition/@{"intuition" link ADCD_v1.2:Inc&AD2.1/includes/intuition/intuition.h/MAIN 1229}> as follows:

    struct Remember
        {
        struct Remember *NextRemember;
        ULONG RememberSize;
        UBYTE *Memory;
        };

Generally, the Remember structure is handled only by the system.  Here are
its fields:

    NextRemember - The link to the next Remember structure.
    RememberSize - The size of the memory tracked by this node.
    Memory       - A pointer to the memory tracked by this node.

@ENDNODE

@NODE 11-3 "11 Intuition Special Functions / Current Time Values"
The function @{"CurrentTime()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/CurrentTime()} gets the current time values.  To use this
function, first declare the variables Seconds and Micros.  Then, when the
application call the function, the current time is copied into the
argument pointers.

    void CurrentTime( ULONG *seconds, ULONG *micros );

See the DOS library Autodocs in the AmigaDOS Manual (Bantam Books) for
more information on functions dealing with the date and time.  The DOS
library includes such functions as @{"DateToStr()" link ADCD_v1.2:Inc&AD2.1/autodocs/dos/DateToStr()}, @{"StrToDate()" link ADCD_v1.2:Inc&AD2.1/autodocs/dos/StrToDate()}, @{"SetFileDate()" link ADCD_v1.2:Inc&AD2.1/autodocs/dos/SetFileDate()}
and @{"CompareDates()" link ADCD_v1.2:Inc&AD2.1/autodocs/dos/CompareDates()}.

@ENDNODE

@NODE 11-4 "11 Special Functions / Using Sprites in Intuition Windows and Screens"
Sprite functionality has limitations under Intuition.  The hardware and
graphics library sprite systems manage sprites independently of the
Intuition display.  In particular:

  * Sprites cannot be attached to any particular screen.  Instead, they
    always appear in front of every screen.

  * When a screen is moved, the sprites do not automatically move with
    it. The sprites move to their correct locations only when the
    appropriate function is called (either @{"DrawGList()" link ADCD_v1.2:Reference_Library/Libraries/Lib_28/28-3-12-1} or @{"MoveSprite()" link ADCD_v1.2:Reference_Library/Libraries/Lib_28/28-2-1-3}).

Hardware sprites are of limited use under the Intuition paradigm.  They
travel out of windows and out of screens, unlike all other Intuition
mechanisms (except the Intuition pointer, which is meant to be global).

Remember that sprite data must be in Chip memory to be accessible to the
custom chips.  This may be done with a compiler specific feature, such as
the __chip keyword of SAS/C.  Otherwise, Chip memory can be allocated with
the Exec @{"AllocMem()" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/20-1} function or the Intuition @{"AllocRemember()" link 11-2-1} function,
setting the memory requirement flag to @{"MEMF_CHIP" link ADCD_v1.2:Reference_Library/Libraries/Lib_17/17-2 27}.  The sprite data may
then be copied to Chip memory using a function like @{"CopyMem()" link ADCD_v1.2:Reference_Library/Libraries/Lib_20/20-1-5-1} in the Exec
library.  See the chapter "@{"Graphics Sprites, Bobs and Animation" link ADCD_v1.2:Reference_Library/Libraries/Lib_28/28-2-1-2}" for more
information.

@ENDNODE

@NODE 11-5 "11 Intuition Special Functions / Intuition and Preferences"
The @{"SetPrefs()" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/13-1-3} function is used to configure Intuition's internal data
states according to a given @{"Preferences" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/13-1-2} structure.  This call relies on
the Preferences system used in V34 and earlier versions of the OS.  The
old system has been largely superceded in Release 2.  See the
"@{"Preferences" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/MAIN}" chapter for details.  This routine is called only by:

  * The Preferences program itself after the user changes Preferences
    settings (under V34 and earlier).

  * AmigaDOS when the system is being booted up.  AmigaDOS opens the
    devs:system-configuration file and passes the information found there
    to the @{"SetPrefs()" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/13-1-3} routine.  This way, the user can create an
    environment and have that environment restored every time the system
    is booted.

The function takes three arguments:

    struct Preferences *SetPrefs(struct Preferences *prefbuf,
                                 long size, long realThing)

The prefbuf argument is a pointer to a Preferences structure that will be
used for Intuition's internal settings.  The  size is the number of bytes
contained in your @{"Preferences" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/13-1-2} structure.  Typically, you will use
sizeof(struct Preferences) for this argument.  The realThing argument is a
boolean TRUE or FALSE designating whether or not this is an intermediate
or final version of the Preferences.  The difference is that final changes
to Intuition's internal Preferences settings cause a global broadcast of
NEWPREFS events to every application that is listening for this event.
Intermediate changes may be used, for instance, to update the screen
colors while the user is playing with the color gadgets.

    About SetPrefs().
    -----------------
    The intended use for the @{"SetPrefs()" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/13-1-3} call is entirely to serve
    the user.  You should never use this routine to make your programming
    or design job easier at the cost of yanking the rug out from beneath
    the user.

Refer to the chapter "@{"Preferences" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/MAIN}" for information about the @{"Preferences" link ADCD_v1.2:Reference_Library/Libraries/Lib_13/13-1-2}
structure and the new Preferences procedure calls used in Release 2.

@ENDNODE

@NODE 11-6 "11 Intuition Special Functions / Function Reference"
The following are brief descriptions of the Intuition functions discussed
in this chapter.  See the Amiga ROM Kernel Reference Manual: Includes and
Autodocs for details on each function call.


               Table 11-1: Other Functions for Intuition
  _____________________________________________________________________
 |                                                                     |
 |     Function                 Description                            |
 |=====================================================================|
 |  @{"AllocRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/AllocRemember()}  Allocate memory and track the allocation.         |
 |   @{"FreeRemember()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/FreeRemember()}  Free memory allocated with AllocRemember().       |
 |---------------------------------------------------------------------|
 |      @{"LockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/LockIBase()}  Lock IntuitionBase for reading.                   |
 |    @{"UnlockIBase()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/UnlockIBase()}  Unlock IntuitionBase when done reading.           |
 |---------------------------------------------------------------------|
 |    @{"CurrentTime()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/CurrentTime()}  Get the system time in seconds and micro-seconds. |
 |       @{"SetPrefs()" link ADCD_v1.2:Inc&AD2.1/autodocs/intuition/SetPrefs()}  An Intuition internal function you should try to  |
 |                   avoid.                                            |
 |_____________________________________________________________________|

@ENDNODE
