3.5 Routines M-P


MakeWWFixed()

WWFixed MakeWWFixed(number); This macro casts a floating-point or integer number to a WWFixed value.

Include: geos.h


malloc()

void	* malloc(
		size_t		blockSize);			/* # of bytes to allocate*/ The **malloc()** family of routines is provided for Standard C compatibility. If  a geode needs a small amount of fixed memory, it can call one of the routines.  The kernel will allocate a fixed block to satisfy the geode's **malloc()** requests;  it will allocate memory from this block. When the block is filled, it will  allocate another fixed malloc-block. When all the memory in the block is  freed, the memory manager will automatically free the block.

When a geode calls malloc(), a section of memory of the size specified will be allocated out of its malloc-block, and the address of the start of the memory will be returned. The memory will not be zero-initialized. If the request cannot be satisfied, malloc will return a null pointer. The memory is guaranteed not to be moved until it is freed (with free()) or resized (with realloc()). When GEOS shuts down, all fixed blocks are freed, and any memory allocated with malloc() is lost.

Using too many fixed blocks degrades the memory manager’s performance, slowing the whole system. For this reason, applications should not use malloc-family routines if they can possibly be avoided. They are provided only to simplify porting of existing programs; however, applications should make every effort to use the GEOS memory management and LMem routines instead. If you must use the malloc-family routines, use them sparingly, and free the memory as quickly as possible.

Tips and Tricks: You can allocate memory in another geode’s malloc-block by calling GeoMalloc(). However, that block will be freed when the other geode exits.

Warnings: All memory allocated with malloc() is freed when GEOS shuts down.

Include: stdlib.h

See Also: calloc(), free(), GeoMalloc(), realloc()


ManufacturerFromFormatID

word	ManufacturerFromFormatID(id);
		ClipboardItemFormatID id; This macro extracts the word-sized manufacturer ID (of type  **ManufacturerIDs**) from a **ClipboardInfoFormatID** argument.

MemAlloc()

MemHandle MemAlloc(
		word			byteSize,		/* Size of block in bytes */
		HeapFlags		hfFlags,		/* Type of block */
		HeapAllocFlags	haFlags);		/* How to allocate block */ This routine allocates a global memory block and creates an entry for it in the  global handle table. The properties of the block are determined by the  **HeapFlags** record passed; the way the block should be allocated is  determined by the **HeapAllocFlags** record. Both sets of flags are described  below. The routine returns the block's handle. If it could not allocate the  block, it returns a null handle. The block allocated may be larger than the  size requested, as the block size is rounded up to the next even paragraph  (one paragraph equals sixteen bytes).

HeapFlags are stored in the block’s handle table entry. They can be retrieved with the routine MemGetInfo(); some of them can be changed with the routine MemModifyFlags(). The following flags are available:

HF_FIXED
The block will not move from its place in the global heap until it is freed. If this flag is off, the memory manager may move the block while it is unlocked. If the flag is on, the block may not be locked, and HF_DISCARDABLE and HF_SWAPABLE must be off.

HF_SHARABLE
The block may be locked by threads belonging to geodes other than the block’s owner.

HF_DISCARDABLE
The block may be discarded when unlocked.

HF_SWAPABLE
The block may be swapped to extended/expanded memory or to the disk swap space when it is unlocked.

HF_LMEM
The block contains a local memory heap. This flag is set automatically by LMemInitHeap() and VMAllocLMem(); applications should not need to set this flag.

HF_DISCARDED
The memory manager turns this bit on when it discards a block. The bit is turned off when the block is reallocated.

HF_SWAPPED
The memory manager turns this bit on when it swaps a block to extended/expanded memory or to the disk swap space. It turns the bit off when it swaps the block back into the global heap.

HeapAllocFlags indicate how the block should be allocated and initialized. They are not stored and can not be retrieved. Some of the flags can be passed with MemReAlloc(). The following flags are available:

HAF_ZERO_INIT
The memory manager should initialize the block to null bytes. This flag may be passed to MemReAlloc() to cause new memory to be zero-initialized.

HAF_LOCK
The memory manager should lock the block after allocating it. To get the block’s address, call MemDeref(). This flag may be passed to MemReAlloc().

HAF_NO_ERR
The memory manager should not return errors. If it cannot allocate block, GEOS will crash. Use of this flag is strongly discouraged. This flag may be passed to MemReAlloc().

HAF_UI
If both HAF_OBJECT_RESOURCE and HAF_UI are set, this block will be run by the application’s UI thread.

HAF_READ_ONLY
The block’s data will not be modified. Useful for the debugger.

HAF_OBJECT_RESOURCE
This block will be an object block.

HAF_CODE
This block contains executable code.

HAF_CONFORMING
If the block contains code, the code may be run by a less privileged entity. If the block contains data, the data may be accessed or altered by a less privileged entity.

Include: heap.h

See Also: MemAllocSetOwner(), MemReAlloc(), MemDeref()


MemAllocLMem()

	MemHandle MemAllocLMem(
		LMemType	type,				/* type of LMem block */
		word		headerSize);		/* size of header structure */ This routine allocates and initializes a local memory block; it can be used to  simplify this procedure from the two-step process of **MemAlloc()** followed by  **LMemInitHeap()**. Pass an LMem type indicating what will be stored in the  block, along with the size of the header structure to use. If the block is to have  the standard header, pass zero in *headerSize*.

This routine returns the handle of the unlocked, newly allocated block. The block will contain two LMem handles and 64 bytes allocated for the LMem heap.

Include: lmem.h

See Also: LMemInitHeap()


MemAllocSetOwner()

MemHandle MemAllocSetOwner(
		GeodeHandle		owner,				/* Handle of block's owner */
		word			byteSize,			/* Size of block in bytes */
		HeapFlags		hfFlags,			/* Type of block */
		HeapAllocFlags	haFlags);			/* How to allocate block */ This routine is the same as **MemAlloc()** except that you can specify the  owner of the global memory block created.

Include: heap.h

See Also: MemAlloc()


MemDecRefCount()

void	MemDecRefCount(
		MemHandle		mh);			/* handle of affected block */ This routine decrements the reference count of a global memory block (the  reference count is stored in *HM_otherInfo*). If the reference count reaches  zero, **MemDecRefCount()** will free the block.

Warnings: This routine assumes that a reference count is stored in HM_otherInfo. You may only use this routine if the block has had a reference count set up with MemInitRefCount().

Include: heap.h


MemDeref()

void	* MemDeref(
		MemHandle	mh);	/* Handle of locked block to dereference */ This routine takes one argument, the handle of a global memory block; it  returns the address of the block on the global heap. If the block has been  discarded, or if the handle is not a memory handle, it returns a null pointer.  It gets this information by reading the block's handle table entry; it does not  need to actually access the block.

Note that if the handle is of an unlocked, moveable block, MemDeref() will return the block’s address with out any warning; however, the address will be unreliable, since the memory manager can move the block at any time.

Include: heap.h

Tips and Tricks: This is very useful when you allocate a fixed or locked block, and need to get the block’s address without calling MemLock().

Warnings: This routine, if given an unlocked, moveable block, will return the pointer without a warning, even though that block may move at any time.

See Also: MemGetInfo(), MemModifyFlags()


MemDowngradeExclLock()

void	MemDowngradeExclLock(
		MemHandle		mh);		/* handle of affected block */ An application that has an exclusive lock on a block may downgrade it to a  shared lock with this routine. It does not otherwise affect the block.

Include: heap.h


MemFree()

void	MemFree(
		MemHandle		mh);		/* handle of block to be freed */ This routine frees a global memory block. The block can be locked or  unlocked. 

Include: heap.h

Warnings: The routine does not care whether other threads have locked the block. If you try to free a bad handle, routine may fatal-error.


MemGetInfo()

word	MemGetInfo( /* return value depends on flag passed */
		MemHandle		mh, 	/* Handle of block to get info about */
		MemGetInfoType	info);	/* Type of information to get */ **MemGetInfo()** is a general-purpose routine for getting information about a  global memory block. It gets the information by looking in the block's handle  table entry; it does not need to access the actual block. It returns a single  word of data; the meaning of that word depends on the value of the  **MemGetInfoType** variable passed. The following types are available:

MGIT_SIZE
Return value is size of the block in bytes. This may be larger than the size originally requested, as blocks are allocated along paragraph boundaries.

MGIT_FLAGS_AND_LOCK_COUNT
The upper byte of the return value is the current HeapFlags record for the block. The lower byte is the number of locks currently on the block.

MGIT_OWNER_OR_VM_FILE_HANDLE
If the block is part of a VM file, return value is the VM file handle. Otherwise, return value is the GeodeHandle of the owning thread.

MGIT_ADDRESS
Return value is block’s segment address on the global heap, or zero if block has been discarded. If block is unlocked and moveable, address may change without warning. Ordinarily, MemDeref() is preferable.

MGIT_OTHER_INFO
Returns the value of the HM_otherInfo word. This word is used in different ways for different types of handles.

MGIT_EXEC_THREAD
Returns the ThreadHandle of the thread executing this block, if any.

Include: heap.h

Warnings: If the handle is not a global memory block handle, results are unpredictable (the routine will read inappropriate data from the handle table entry).

See Also: MemDeref(), MemModifyFlags(), MemModifyOtherInfo(), HandleModifyOwner()


MemIncRefCount()

void	MemIncRefCount(
		MemHandle		mh);		/* handle of affected block */ This routine increments the reference count of a global memory block (the  reference count is stored in *HM_otherInfo*).

Warnings: This routine assumes that a reference count is stored in HM_otherInfo. You may only use this routine if the block has had a reference count set up with MemInitRefCount().

Include: heap.h


MemInitRefCount()

void	MemInitRefCount(
		MemHandle	mh,				/* handle of affected block */
		word		count);			/* initial reference count */ This routine sets up a reference count for the specified global memory block.  The passed count is stored in the *HM_otherInfo* field of the block's  handle-table entry.

Warnings: This routine overwrites the HM_otherInfo field. Since the semaphore routines (HandleP() and HandleV() and the routines which use them) use this field, you cannot use both the semaphore routines and the reference count routines on the same block.

Include: heap.h


MemLock()

void	* MemLock(
		MemHandle		mh);		/* Handle of block to lock */ This routine locks a global memory block on the global heap. If the block is  swapped, the memory manager swaps it back into the global heap; it then  increments the lock count (up to a maximum of 255). The block will not be  moved, swapped, or discarded until the lock count reaches zero. This routine  returns a pointer to the start of the block, or a null pointer if block has been  discarded. To get the address of a block without locking it, use **MemDeref()**.

Include: heap.h

Warnings: If you try to lock a bad handle, the routine may fatal-error. This routine does not check for synchronization problems; if the block is used by several threads, you should use the synchronization routines.

Never Use Situations: Never lock a fixed block.

See Also: MemDeref()


MemLockExcl()

void	* MemLockExcl(
		MemHandle		mh);		/* Handle of block to grab */ If several different threads will be accessing the same global memory block,  they should use data-access synchronization routines. **MemLockExcl()**  belongs to one such set of routines. Often, several threads will need access to  the same block; however, most of the time, they will not need to change the  block. There is no synchronization problem if several threads read the same  block at once, as long as none of them alters the block (by resizing it, writing  to it, etc.) However, if a thread needs to change a block, no other thread  should have access at that time.

The routines MemLockExcl(), MemLockShared(), MemUnlockShared(), and MemUnlockExcl() take advantage of this situation. They maintain a queue of threads requesting access to a block. When the block is not being used, they awaken the highest priority thread on the queue. If that thread requested exclusive access, the other threads sleep until it relinquishes access (via MemUnlockExcl()). If it requested shared access, the routines awaken every other thread which requested shared access; the other threads on the queue will sleep until every active thread relinquishes access (via MemUnlockShared()).

MemLockExcl() requests exclusive access to the block. If the block is not being accessed, the routine will grab exclusive access for the block, lock the block, and return the block’s address. If the block is being accessed, the routine will sleep on the queue until it can get access; it will then awaken, lock the block, and return its address.

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all routines accessing the block get access with MemLockExcl() or MemLockShared(). The routines use the block’s HM_otherInfo word; you must not alter it. When you are done accessing the block, make sure to relinquish access by calling MemUnlockExcl().

Warnings: If a thread calls MemLockExcl() when it already has shared or exclusive access, it will deadlock; it will sleep until access is relinquished, but it cannot relinquish access while it is sleeping. If you try to grab a block which is owned by a different geode and is non-sharable, the routine will fatal-error.

Never Use Situations: Never use MemLockExcl() or MemLockShared() on a fixed block. It will attempt to lock the block, and fixed blocks cannot be locked. Instead, use the HandleP() and HandleV() routines.

See Also: MemLockShared(), MemUnlockExcl(), MemUnlockShared()


MemLockFixedOrMovable()

void	* MemLockFixedOrMovable(
		void	* ptr);		/* virtual segment */ Given a virtual segment, this routine locks it (if it was movable). A virtual  segment is an opaque pointer to a block that an application views as locked  or fixed - the memory manager can actually swap locked or fixed blocks and  will designate them as virtual segments.

Include: heap.h


MemLockShared()

void	* MemLockShared(
		MemHandle		mh);			/* Handle of block to grab */ **MemLockShared()** requests shared access to the passed block. If the block  is not being accessed, or if it is held for shared access and the queue is empty,  the routine gets access, locks the block, and returns the block's address.  Otherwise it sleeps on the queue until the shared requests are awakened; it  then locks the block and returns the block's address.

Include: heap.h

Be Sure To: Make sure that all routines accessing the block get access with MemLockExcl() or MemLockShared(). The routines use the block’s HM_otherInfo word; you must not alter it. When you are done accessing the block, make sure to relinquish access by calling MemUnlockExcl().

Warnings: If a thread calls MemLockShared() when it already has exclusive access, it will deadlock; it will sleep until access is relinquished, but it cannot relinquish access while it is sleeping. The thread must be careful not to take actions which could change the block, such as resizing it or writing to it. The routine will not enforce this. If you try to grab a block which is owned by a different geode and is non-sharable, the routine will fatal-error.

Never Use Situations: Never use MemLockExcl() or MemLockShared() on a fixed block. It will attempt to lock the block, and fixed blocks cannot be locked. Instead, use the HandleP() and HandleV() routines.

See Also: MemLockExcl(), MemUnlockExcl(), MemUnlockShared()


MemModifyFlags()

void	MemModifyFlags(
		MemHandle		mh,				/* Handle of block to modify */
		HeapFlags		bitsToSet,		/* HeapFlags to turn on */
		HeapFlags		bitsToClear);	/* HeapFlags to turn off */ **MemModifyFlags()** changes the **HeapFlags** record of the global memory  block specified. Not all flags can be changed after the block is created; only  the flags HF_SHARABLE, HF_DISCARDABLE, HF_SWAPABLE, and HF_LMEM  can be changed.

The routine uses the handle table entry of the block specified; it does not need to look at the actual block. The routine performs normally whether or not the block is locked, fixed, or discarded.

Include: heap.h

Warnings: If the handle is not a global memory handle, results are unpredictable; the routine will change inappropriate bits of the handle table entry.

See Also: MemGetInfo(), HandleModifyOwner(), MemModifyOtherInfo()


MemModifyOtherInfo()

void	MemModifyOtherInfo(
		MemHandle	mh,				/* Handle of block to modify */
		word		otherInfo);		/* New value of HM_otherInfo word */ Use this routine to change the value of the global memory block's  *HM_otherInfo* word. Some blocks need this word left alone; for example,  data-access synchronization routines use this word.

Include: heap.h

See Also: MemGetInfo(), MemModifyFlags(), HandleModifyOwner()


MemOwner()

GeodeHandle MemOwner(

MemHandle		mh);			/* handle of block queried */ This routine returns the owning geode of the passed block. If the block  belongs to a VM file, the owner of the VM file will be returned (unlike  **MemInfo()**, which returns the VM file handle).

Include: heap.h


MemPLock()

void	* MemPLock(
		MemHandle		mh);		/* Handle of block to lock */ If several different threads will be accessing the same global memory block,  they need to make sure their activities will not conflict. The way they do that  is to use synchronization routines to get control of a block. **MemPLock()** is  part of one set of synchronization routines.

If the threads are using the MemPLock() family, then whenever a thread needs access to the block in question, it can call MemPLock(). This routine calls HandleP() to get control of the block; it then locks the block and returns its address. If the block has been discarded, it grabs the block and returns a null pointer; you can then reallocate the block. When the thread is done with the block, it should release it with MemUnlockV().

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all threads accessing the block use MemPLock() and/or HandleP() to grab the block. These routines use the HM_otherInfo field of the block’s handle table entry; do not alter this field. Release the block with HandleV() or MemUnlockV() when you are done with it.

Warnings: If a thread calls MemPLock() when it already has control of the block, it will deadlock. MemThreadGrab() avoids this conflict. If you try to grab a non-sharable block owned by another thread, MemPLock() will fatal-error.

Never Use Situations: Never use MemPLock() with a fixed block. It will try to lock the block, and fixed blocks cannot be locked. Instead, use HandleP().

See Also: HandleP(), MemUnlockV(), HandleV()


MemPtrToHandle()

MemHandle MemPtrToHandle(
		void	* ptr);		/* pointer to locked block */ This routine returns the global handle of the locked block.

Include: heap.h


MemReAlloc()

MemHandle 	MemReAlloc(
		MemHandle		mh,					/* Handle of block */
		word			byteSize,			/* New size of the block */
		HeapAllocFlags	heapAllocFlags);	/* How to reallocate block */ This routine reallocates a global memory block. It can be used to resize a  block; it can also be used to reallocate memory for a discarded block. Locked  and fixed blocks can be reallocated; however, they may move on the global  heap, so all pointers within the block must be adjusted. Note, however, that  if the new size is smaller than the old size, the block is guaranteed not to  move. The reallocated block may be larger than the size requested, as the  block size is rounded up to the next even paragraph (one paragraph equals  sixteen bytes).

The routine is passed a record of HeapAllocFlags. Only the flags HAF_ZERO_INIT, HAF_LOCK, and HAF_NO_ERR may be passed.

Include: heap.h

Warnings: If HAF_LOCK is passed, the lock count will be incremented even if the block is already locked by this thread. The routine does not care whether the block has been locked by another thread (possibly belonging to another geode); thus, if the block is being used by more than one thread, it is important to use the synchronization routines.

See Also: MemAlloc(), MemDeref()


MemThreadGrab()

void	* MemThreadGrab(
		MemHandle		mh);		/* Handle of block to grab */ **MemThreadGrab()** is used in conjunction with **MemThreadGrabNB()**  and **MemThreadRelease()** to maintain data-access synchronization. If  several threads will all have access to the same global memory block, they  should use data-acess synchronization routines to make sure that their  activities do not conflict. If a thread uses **MemThreadGrab()** and no other  thread has grabbed the block in question, the routine will increment the  "grab count," lock the block, and return its address. It can do this even if the  calling thread has already grabbed the block. If another thread has grabbed  the block, **MemThreadGrab()** will put the calling thread in a queue to get  the block; the thread will sleep until it gets the block, then  **MemThreadGrab()** will grab the block, lock it, and return its address.

If the block has been discarded, MemThreadGrab() grabs the block and returns a null pointer; you can then reallocate memory for the block.

Include: heap.h

Be Sure To: Make sure that all threads using the block use the MemThread…() routines to access it (not other data-acess synchronization routines). Do not change the HM_otherInfo word of the block’s handle table entry (the routines use that word as a semaphore).

Warnings: If you try to grab a block which is owned by a different geode and is non-sharable, the routine will fatal-error.

Never Use Situations: Never use MemThreadGrab() with a fixed block. It will try to lock the block, and fixed blocks cannot be locked. If you need data-access synchronization for a fixed block, use the HandleP() and HandleV() routines.

See Also: MemThreadGrabNB(), MemThreadRelease()


MemThreadGrabNB()

void	* MemThreadGrabNB(
		MemHandle		mh);	/* handle of block to grab */ This is a data-synchronization routine to be used in conjunction with  **MemThreadGrab()** and **MemThreadRelease()**. It is exactly the same as  **MemThreadGrab()**, except that if it cannot grab the global memory block  because another thread has it, the routine returns an error instead of  blocking.

If successful, MemThreadGrabNB() returns a pointer to the block. If the block has been discarded, it grabs the block and returns a null pointer; you can then reallocate memory for the block. If the block has been grabbed by another thread, MemThreadGrab() returns the constant BLOCK_GRABBED.

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all threads using the block use the MemThread…() routines to access the block (not other data-access synchronization routines). Do not change the HM_otherInfo word of the block’s handle table entry (the routines use that word as a semaphore).

Warnings: If you try to grab a block that is owned by a different geode and is non-sharable, the routine will fatal-error.

Never Use Situations: Never use MemThreadGrabNB() with a fixed block. It will try to lock the block, and fixed blocks cannot be locked. If you need synchronization for a fixed block, use the HandleP() and HandleV() routines.

See Also: MemThreadGrab(), MemThreadRelease()


MemThreadRelease()

void	MemThreadRelease(
		MemHandle		mh);	/* handle of locked block to release */ Use this routine to release a global memory block which you have grabbed  with **MemThreadGrab()** or **MemThreadGrabNB()**. The routine  decrements the grab count; if the grab count reaches zero, the routine  unlocks the block.

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all threads using the block use the MemThread…() routines to access the block (not other data-access synchronization routines). Do not change the HM_otherInfo word of the block’s handle table entry (the routines use that word as a semaphore). Make sure to release the block once for every time you grab it; the block is not unlocked until each of your grabs is released.

Warnings: If you try to release a block that you have not successfully grabbed, the routine will fatal-error.

See Also: MemThreadGrab(), MemThreadGrabNB()


MemUnlock()

void	MemUnlock(
		MemHandle		mh);		/* Handle of block to unlock */ This routine decrements the lock count of the indicated block. If the lock  count reaches zero, the block becomes unlocked (it can be moved, swapped,  or discarded). Do not try to unlock a block that has not been locked.

Include: heap.h


MemUnlockExcl()

void	MemUnlockExcl(
		memHandle		mh);		/* Handle of block to release */ If a thread has gained access to a block with **MemLockExcl()**, it should  release the block as soon as it can. Until it does, no other thread can access  the block for either shared or exclusive access. It can release the block by  calling **MemUnlockExcl()**. This routine unlocks the block and releases the  thread's access to it. If there is a queue for this block, the highest-priority  thread waiting will be awakened, as described in **MemLockExcl()**.

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all routines accessing the block get access with MemLockExcl() or MemLockShared(). The routines use the block’s HM_otherInfo word; you must not alter it. Call this routine while the block is still locked; it will call MemUnlock() to unlock the block.

Warnings: If you call this routine on a block which you have not gained access to, it may fatal-error.

See Also: MemLockExcl(), MemLockShared(), MemUnlockShared()


MemUnlockFixedOrMovable()

void	MemUnlockFixedOrMovable(
		void	* ptr);		/* virtual segment */ This routine unlocks a previously locked, movable virtual segment. Do not  call this routine with normal locked or fixed blocks; only call it for those  blocks locked with **MemLockFixedOrMovable()**.

Include: heap.h


MemUnlockShared()

void	MemUnlockShared(
		MemHandle		mh);		/* Handle of block to release */ If a thread has gained access to a block with **MemLockShared()**, it should  release the block as soon as it can. Until it does, no thread can be awakened  from the queue. It can release the block by calling **MemUnlockShared()**.  This routine calls **MemUnlock()**, decrementing the block's lock count; it  then releases the thread's access to it. If no other thread is accessing the  block and there is a queue for this block, the highest-priority thread waiting  will be awakened, as described in **MemLockExcl()**.

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all routines accessing the block get access with MemLockExcl() or MemLockShared(). These routines use the block’s HM_otherInfo word; you must not alter it. Call this routine while the block is still locked; it will call MemUnlock() to unlock the block.

Warnings: If you call this routine on a block which you have not gained access to, it may fatal-error.

See Also: MemLockExcl(), MemLockShared(), MemUnlockExcl()


MemUnlockV()

void	MemUnlockV(
		MemHandle		mh);		/* Handle of block to release */ This routine unlocks a block with **MemUnlock()**, then releases its  semaphore with **HandleV()**. Do not use this routine unless the block's  semaphore was grabbed and the block locked (typically with the  **MemPLock()** routine).

Include: heap.h

Tips and Tricks: You can find out if the block is being accessed by looking at the HM_otherInfo word (with MemGetInfo()). If HM_otherInfo equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.

Be Sure To: Make sure that all threads accessing the block use HandleP() or MemPLock() to access the thread. These routines use the HM_otherInfo field of the handle table entry; do not alter this field.

Warnings: Do not use this on a block unless you have grabbed it. The routine does not check to see that you have grabbed the thread; it just clears the semaphore and returns.

Never Use Situations: Never use this routine to release a fixed block. It will try to unlock the block; fixed blocks cannot be locked or unlocked. Instead, call HandleV() directly.

See Also: MemPLock(), HandleP(), HandleV()


MemUpgradeSharedLock()

void	* MemUpgradeSharedLock(
		MemHandle		mh);		/* handle of locked block */ This routine upgrades a shared lock on the block to an exclusive lock, as if  the caller had used **MemLockExcl()**. If other threads have access to the block,  the caller will sleep in the access queue until it can gain exclusive access.

This routine returns the pointer of the locked block because, if the caller sleeps in the queue, the memory block could move between the call and the granting of access.

Include: heap.h

See Also: MemLockExcl(), MemLockShared(), MemDowngradeExclLock()


MessageSetDestination()

void	MessageSetDestination(
		EventHandle		event,		/* handle of the event to be modified */
		optr			dest);		/* new destination for the event */ This routine sets the destination of an event to the optr passed.

Include: object.h


NameArrayAdd()

word	NameArrayAdd(
		optr 				arr,		/* optr of name array */
		const char			* nameToAdd,/* Name of new element */
		word				nameLength,	/* Length of name; pass zero if
										 * name string is null-terminated */
		NameArrayAddFlags	flags,		/* Described below */
		const void			* data);	/* Copy this data to new element */ This routine creates a new element in a name array, copying the passed name  and data into the new element. If no element with the passed name exists,  **NameArrayAdd()** will create the element and return its token. If an  element with the same name already exists, the existing element's reference  count will be incremented and its token will be returned. The routine takes  the following arguments:

array - The optr of the name array.

nameToAdd - The name of the new element. This string may contain nulls.

nameLength - The length of the name string, in bytes. If you pass zero, NameArrayAdd() will assume the string is null-terminated.

flags - A record of NameArrayAddFlags, described below.

data - The data to copy into the new element.

Structures: The argument is passed a set of NameArrayAddFlags. Only one flag is currently defined:

NAAF_SET_DATA_ON_REPLACE
If an element with the specified name exists and this flag is set, the data passed will be copied into the data area of the existing element. If this flag is not set, the existing element will not be changed.

Warnings: This routine may resize the name array; therefore, all pointers to the LMem heap are invalidated.

Include: chunkarr.h


NameArrayAddHandles()

dword	NameArrayAddHandles(
		MemHandle 			mh,			/* Handle of LMem heap */
		ChunkHandle 		arr,		/* Chunk handle of name array */
		const char * 		nameToAdd,	/* Name of new element */
		word				nameLength,	/* Length of name; pass zero if
										 * name string is null-terminated */
		NameArrayAddFlags	flags,		/* Described below */
		const void *		data);		/* Copy this data to new element */ This routine is exactly like **NameArrayAdd()** above, except that the name  array is specified by its global and chunk handles (instead of with an optr).

Warnings: This routine may resize the name array; therefore, all pointers to within the LMem heap are invalidated.

Include: chunkarr.h


NameArrayChangeName()

void	NameArrayChangeName(
		optr 		array,			/* optr of name array */
		word		token,			/* Token of element to be changed */
		const char * newName,		/* New name for element */
		word		nameLength);	/* Length of name in bytes; pass
									 * zero if name string is
									 * null-terminated */ This routine changes the name of an element in a name array.

Warnings: If the new name is longer than the old, the chunk will be resized, invalidating all pointers to within the LMem heap.

Include: chunkarr.h


NameArrayChangeNameHandles()

dword	NameArrayChangeNameHandles(
		MemHandle 		mh,				/* Handle of LMem heap */
		ChunkHandle 	array,			/* Chunk handle of name array */
		word			token,			/* Token of element to be changed */
		const char * 	newName,		/* New name for element */
		word			nameLength);	/* Length of name in bytes; pass
										 * zero if name string is
										 * null-terminated */ This routine is exactly like **NameArrayChangeName()** above, except that  the name array is specified by its global and chunk handles (instead of with  an optr).

Warnings: If the new name is longer than the old, the chunk will be resized, invalidating all pointers to within the LMem heap.

Include: chunkarr.h


NameArrayCreate()

ChunkHandle 	NameArrayCreate(
		MemHandle 	mh,				/* Global handle of LMem heap */
		word		dataSize,		/* Size of data section for
									 * each element */
		word		headerSize);	/* Size of header; pass
									 * zero for default header */ This routine creates a name array in the indicated LMem heap. It creates a  **NameArrayHeader** structure at the head of a new chunk. If you want to  leave extra space before the start of the array, you can pass a larger header  size; if you want to use the standard header, pass a header size of zero.

You must specify the size of the data portion of each element when you create the array. The name portion will be variable sized.

Include: chunkarr.h

Tips and Tricks: If you want extra space after the NameArrayHeader, you may want to create your own header structure, the first element of which is a NameArrayHeader. You can pass the size of this header to NameArrayCreate() and access the data in your header via the structure fields.

Be Sure To: Lock the block on the global heap before calling this routine (unless it is fixed). If you pass a header size, make sure it is larger than sizeof(NameArrayHeader).

Include: chunkarr.h


NameArrayCreateAt()

ChunkHandle 	NameArrayCreateAt(
		optr	array,		/* Turn this chunk into a name array */
		word	dataSize,	/* Size of data section of each element */
		word	headerSize);/* Size of header; pass zero for default header */ This routine is just like **NameArrayCreate()** above, except that the element  array is created in a pre-existing chunk. The contents of that chunk will be  destroyed.

Include: chunkarr.h

Warnings: If the chunk isn’t large enough, it will be resized. This will invalidate all pointers to chunks in that block.

Include: chunkarr.h


NameArrayCreateAtHandles()

ChunkHandle 	NameArrayCreateAtHandles(
		MemHandle 		mh,			/* Global handle of LMem heap */
		ChunkHandle 	chunk,		/* the chunk for the array */
		word			dataSize,	/* Size of data for each element */
		word			headerSize);/* Size of header; pass
									 * zero for default header */ This routine is exactly like **NameArrayCreateAt()** above, except that the  name array is specified by its global and chunk handles (instead of with an  optr).

Include: chunkarr.h

Warnings: If the chunk isn’t large enough, it will be resized. This will invalidate all pointers to chunks in that block.

Include: chunkarr.h


NameArrayFind()

word	NameArrayFind(
		optr 		array,			/* optr to name array */
		const char	* nameToFind,	/* Find element with this name */
		word		nameLength,		/* Pass zero if name string is
									 * null-terminated */
		void *		returnData);	/* Copy data section into this
									 * buffer */ This routine locates the element with the specified name. It returns the token  of the element and copies its data section into the passed buffer. If there is no  element with the specified name, the routine will return  CA_NULL_ELEMENT. The routine takes the following arguments:

array - The optr of the name array.

nameToAdd - The name of the element to find. This string may contain nulls.

nameLength - The length of the name string, in bytes. If you pass zero, NameArrayFind() will assume the string is null-terminated.

returnData - The data section of the element is written to this buffer.

Include: chunkarr.h

Warnings: You must make sure the returnData buffer is large enough to hold an element’s data portion; otherwise, data after the buffer will be overwritten.


NameArrayFindHandles()

word	NameArrayFindHandles(
		MemHandle		mh,				/* Handle of LMem heap */
		ChunkHandle 	array,			/* Handle of name array */
		const char *	nameToFind,		/* Find element with this name */
		word			nameLength,		/* Pass zero if name string is
										 * null-terminated */
		void *			returnData);	/* Copy data section into this
										 * buffer */ This routine is exactly like **NameArrayFind()** above, except that the name  array is specified by its global and chunk handles (instead of with an optr).

Include: chunkarr.h


NEC()

NEC(line) This macro defines a line of code that will only be compiled into the  *non*-error-checking version of the geode. The *line* parameter of the macro is  the actual line of code. When the non-EC version of the program is compiled,  the line will be treated as a normal line of code; when the EC version is  compiled, the line will be ignored.

Include: ec.h


ObjBlockGetOutput()

optr	ObjBlockGetOutput(
		MemHandle	mh);		/* handle of the subject object block */ This routine returns the optr of the output destination object set for the  specified object block. The output object is stored in the object block's header  in the *OLMBH_output* field. If the block has no output set, NullOptr will be  returned.

Include: object.h

See Also: ObjLMemBlockHeader


ObjBlockSetOutput()

void	ObjBlockSetOutput(
		MemHandle	mh,			/* handle of the subject object block */
		optr		o);			/* optr of the new output object */ This routine sets the *OLMBH_output* field in the specified object block's  header. The optr passed in *o* will be set as the block's output.

Include: object.h

See Also: ObjLMemBlockHeader


ObjCompAddChild()

void	ObjCompAddChild(
		optr	obj,			/* optr of parent composite */
		optr	objToAdd,		/* optr of new child */
		word	flags,			/* CompChildFlags */
		word	masterOffset,	/* offset to master part */
		word	compOffset,		/* offset to comp field in master part */
		word	linkOffset);	/* offset to link field in master part */ This routine adds the given object to an object tree as the child of another  specified object. It returns nothing. You will not likely want to use this  routine; instead, you will probably use the messages listed below under "See  Also." The parameters of this routine are

obj - The optr of the parent composite object. The parent must be a composite; if it is not, an error will result.

objToAdd - The optr of the child object. The child must have a link instance field (defined with @link).

flags - A record of CompChildFlags. These flags indicate whether the object should initially be marked dirty as well as where in the parent’s child list the new child should be placed (first, second, last, etc.).

masterOffset - The offset within the parent’s instance chunk to the master group’s offset. (The value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure.)

compOffset - The offset within the parent’s instance chunk to the composite field.

linkOffset - The offset within the parent’s instance chunk to the link field.

Warnings: This routine may resize and move LMem and Object blocks on the heap, thereby invalidating all segment addresses and pointers.

Include: metaC.goh

See Also: MSG_VIS_ADD_CHILD, MSG_GEN_ADD_CHILD


ObjCompFindChildByNumber()

optr	ObjCompFindChildByNumber(
		optr	obj,			/* parent's optr */
		word	childToFind,	/* zero-based child number */
		word	masterOffset,	/* offset to master part */
		word	compOffset,		/* offset to comp field in master part */
		word	linkOffset);	/* offset to link field in master part */ This routine returns the optr of the passed object's child; the child is specified  based on its position in the object's child list. You will not often use this  routine, but you will probably use the messages listed under "See Also"  instead. The routine's parameters are listed below:

obj - The optr of the parent object.

childToFind - The zero-based number of the child to be found. For example, to return the first child’s optr, pass zero or CCO_FIRST; to return the last child’s optr, pass CCO_LAST.

masterOffset - The offset within the parent’s instance chunk to the master group’s offset. (The value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure.)

compOffset - The offset within the parent’s instance chunk to the composite field.

linkOffset - The offset within the parent’s instance chunk to the link field.

Include: metaC.goh

See Also: MSG_GEN_FIND_CHILD, MSG_VIS_FIND_CHILD


ObjCompFindChildByOptr()

word	ObjCompFindChildByOptr(
		optr	obj,			/* parent's optr */
		optr	childToFind,	/* optr of child to find */
		word	masterOffset,	/* offset to master part */
		word	compOffset,		/* offset to comp field in master part */
		word	linkOffset);	/* offset to link field in master part */ This routine returns the zero-based child number of an object given its optr  and its parent's optr. The returned number represents the child's position in  its parent's child list. For example, a return value of zero indicates the object  is the parent's first child. You will not likely use this routine; instead, you will  probably use the messages shown below under "See Also."

The parameters for this routine are listed below:

obj - The optr of the parent object.

childToFind - The optr of the child whose number is to be returned. If the child is not found, the routine will return -1.

masterOffset - The offset within the parent’s instance chunk to the master group’s offset. (The value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure.)

compOffset - The offset within the parent’s instance chunk to the composite field.

linkOffset - The offset within the parent’s instance chunk to the link field.

Include: - metaC.goh

See Also: MSG_GEN_FIND_CHILD, MSG_VIS_FIND_CHILD


ObjCompMoveChild()

void	ObjCompMoveChild(
		optr	obj,			/* parent's optr */
		optr	objToMove,		/* optr of child to move */
		word	flags,			/* CompChildFlags */
		word	masterOffset,	/* offset to master part */
		word	compOffset,		/* offset to comp field in master part */
		word	linkOffset);	/* offset to link field in master part */ This routine moves the specified child within its parent's child list. This  routine will not move a child from one parent to another, but it can reorganize  a parent's children. You will not likely use this routine, but you may often use  the messages listed under "See Also" below.

The parameters of this routine are shown below:

obj - The optr of the parent object.

objToMove - The optr of the child to be moved. If the optr does not point to a valid child, behavior is undefined and an error is likely.

flags - A record of CompChildFlags indicating the new position of the child and whether the link should be marked dirty.

masterOffset - The offset within the parent’s instance chunk to the master group’s offset. (The value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure.)

compOffset - The offset within the parent’s instance chunk to the composite field.

linkOffset - The offset within the parent’s instance chunk to the link field.

Warnings: This routine may cause LMem and/or Object Blocks to move or to shuffle their chunks, thereby invalidating any segment addresses or pointers.

Include: metaC.goh

See Also: MSG_GEN_MOVE_CHILD, MSG_VIS_MOVE_CHILD


ObjCompProcessChildren()

Boolean	ObjCompProcessChildren(
		optr			obj,			/* parent's optr */
		optr			firstChild,		/* optr of first child to process */
		ObjCompCallType	stdCallback,	/* standard callback type */
		void 			* cbData,		/* data passed to callback */
		word			masterOffset,	/* offset to master part */
		word			compOffset,		* offset to comp field */
		word			linkOffset);	/* offset to link field */
		Boolean _pascal (*callback) (optr parent, optr child, void *cbData)); This routine performs a specific set of actions on all or some of an object's  children. It is very rare that you will use this routine; typically, you should  send a message to all of the parent's children. If, however, you use this  routine, you must also write a callback routine that will be executed once for  each affected child.

ObjCompProcessChildren() returns true (nonzero) only if it was stopped before all children had been processed. The only two ways this could be returned is if an error occurs or if your callback returns true when called.

The parameters for this routine are

obj - The optr of the composite whose children are to be processed.

firstChild - The optr of the first child to be processed. This routine will begin with the passed child and continue with all subsequent children. Pass the optr of the composite’s first child - retrieved with the routine ObjCompFindChildByNumber() - to process all children.

stdCallback - A value of ObjCompCallType indicating how the data in the buffer pointed to by cbData will be passed to your callback routine. These values are detailed below.

cbData - A pointer to a buffer in which data can be passed to your callback routine. This buffer can be altered by your callback.

masterOffset - The offset within the parent’s instance chunk to the master group’s offset. (The value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure.)

compOffset - The offset within the parent’s instance chunk to the composite field.

linkOffset - The offset within the parent’s instance chunk to the link field.

callback - A pointer to the actual callback routine that will be executed once for each child. The callback should be in your geode’s fixed memory. The parameters and return values for the callback routine are given below.

The callback routine takes three parameters and returns a boolean value. It must be declared _pascal. The three parameters to the callback are listed below:

parent - The optr of the parent composite.

child - The optr of the current child being processed.

cbData - A pointer to the buffer passed by the original caller of ObjCompProcessChildren(). What is actually in this buffer may depend on the value in the original sdtCallback parameter; if the buffer is not saved and restored by ObjCompProcessChildren() between children, each child may receive data altered by the previous child.

The callback routine can access and alter the buffer pointed to by cbData, or it can query the child or do anything else with the exception of destroying the child. It should return a Boolean value: true if ObjCompProcessChildren() should be aborted, false if it should not.

The values you can pass to ObjCompProcessChildren() in stdCallback are of type ObjCompCallType. You can use one of the following values to specify how the buffer in cbData will be passed on to the next child’s callback routine:

OCCT_SAVE_PARAMS_TEST_ABORT
Save the buffer passed in cbData before calling each child; abort the routine if the callback returns true.

OCCT_SAVE_PARAMS_DONT_TEST_ABORT
Save the buffer passed in cbData before calling each child; do not check the return value of the callback before proceeding to the next child.

OCCT_DONT_SAVE_PARAMS_TEST_ABORT
Do not save the buffer in cbData, and abort if the callback routine returns true.

OCCT_DONT_SAVE_PARAMS_DONT_TEST_ABORT
Do not save the buffer in cbData, and do not check the callback routine’s return value.

OCCT_ABORT_AFTER_FIRST
Abort the processing after only one child (typically used to call the nth child).

OCCT_COUNT_CHILDREN
Counts the number of children rather than calling each.

Include: metaC.goh

See Also: @send, @call, MSG_META_SEND_CLASSED_EVENT


ObjCompRemoveChild()

void	ObjCompRemoveChild(
		optr	obj,			/* parent's optr */
		optr	objToRemove		/* optr of child to be removed */
		word	flags,			/* CompChildFlags */
		word	masterOffset,	/* offset to master part */
		word	compOffset,		/* offset to comp field in master part */
		word	linkOffset);	/* offset to link field in master part */ This routine removes the given child from the specified parent composite.  The child will be removed entirely from the object tree, but it will not be  detached or freed. The parameters of this routine are listed below:

obj - The optr of the parent composite.

objToRemove - The optr of the child to be removed.

flags - A record of CompChildFlags indicating whether the parent and child should be marked dirty after the operation.

masterOffset - The offset within the parent’s instance chunk to the master group’s offset. (The value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure.)

compOffset - The offset within the parent’s instance chunk to the composite field.

linkOffset - The offset within the parent’s instance chunk to the link field.

Include: metaC.goh


ObjDecInteractibleCount()

void	ObjDecInteractibleCount(
		MemHandle mh);			/* subject object block */ This routine decrements the given object block's interactable count. Do not  decrement the interactable count without first incrementing it with  **ObjIncInteractibleCount()**. Visible objects automatically decrement the  interactable count in their MSG_VIS_CLOSE handlers.

Include: object.h

See Also: ObjIncInteractibleCount(), MSG_VIS_CLOSE, ObjLMemBlockHeader


ObjDecInUseCount()

void	ObjDecInUseCount(
		MemHandle mh);		/* subject object block */ This routine decrements the given object block's in-use count. When the  in-use count reaches zero, the block may safely be freed. You should not  decrement the in-use count of a block without first incrementing it at some  point with **ObjIncInUseCount()**.

Warnings: Do not decrement the in-use count without incrementing it first. An error will result.

Include: object.h

See Also: ObjIncInUseCount(), ObjDecInteractibleCount(), ObjLMemBlockHeader


ObjDeref()

void	* ObjDeref(
		optr	obj				/* optr to dereference */
		word	masterLevel);	/* specific master level to dereference */ This routine dereferences the given optr and master level to reset the  message parameter *pself*. Because many routines and messages may cause  the calling object's instance chunk to move, the *pself* parameter may become  invalid. The two parameters to **ObjDeref()** are

obj - The optr of the object to be dereferenced; nearly always you will want to pass oself.

masterLevel - The master level of the part to be dereferenced. This is the offset into the instance chunk where the offset to the master part is stored. Since pself points to the first byte of a master part, you must specify which master part you are dereferencing.

For example, a visible object dereferencing its VisClass instance data would call this routine as follows:

pself = ObjDeref(oself, 4);

Note, however, the ObjDeref1() and ObjDerefVis() exist to dereference the Vis master part, and ObjDeref2() and ObjDerefGen() exist to dereference the Gen master part.

Include: object.h

See Also: ObjDeref1(), ObjDeref2()


ObjDerefHandles()

void	* ObjDerefHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		word			masterLevel);	/* master level to dereference */ This routine is exactly the same as **ObjDeref()**, above, except that the optr  is specified as its separate handles.

Include: object.h


ObjDeref1()

void	* ObjDeref1(
		optr obj);			/* optr of object to be dereferenced */ This routine is a special version of **ObjDeref()** which dereferences the first  master part of an object. Visible objects should use this routine or  **ObjDerefVis()** instead of **ObjDeref()**.

Include: object.h

See Also: ObjDeref(), ObjDeref2()


ObjDeref1Handles()

void	*ObjDeref1Handles(
		MemHandle		mh,			/* handle portion of optr */
		ChunkHandle		ch,);		/* chunk handle portion of optr */ This routine is exactly like **ObjDeref1()**, above, except that the optr is  specified as its separate handles.

Include: object.h


ObjDeref2()

void	* ObjDeref2(
		optr	obj);		/* optr of object to be dereferenced */ This routine is a specialized version of **ObjDeref()** which dereferences the  second master part of an object. Generic objects should use this routine or  **ObjDerefGen()** instead of **ObjDeref()**.

Include: object.h

See Also: ObjDeref(), ObjDeref1()


ObjDeref2Handles()

void	* ObjDeref2Handles(
		MemHandle		mh,/			/* handle portion of optr */
		ChunkHandle		ch);			/* chunk portion of optr */ This routine is exactly like **ObjDeref2()**, above, except that the optr is  specified as its separate handles.

Include: object.h


ObjDerefGen()

void	* ObjDerefGen(
		optr	obj);			/* generic object to be dereferenced */ This routine is exactly the same as **ObjDeref2()** and dereferences the Gen  master part of a generic object.

Include: object.h

See Also: ObjDeref(), ObjDeref2()


ObjDerefVis()

void	* ObjDerefVis(
		optr	obj);			/* visible object to be dereferenced */ This routine is exactly the same as **ObjDeref1()** and dereferences the Vis  master part of a visible object or a visibly-realized generic object.

Include: object.h

See Also: ObjDeref(), ObjDeref1()


ObjDoRelocation()

Boolean	ObjDoRelocation( /* returns true if error */
		ObjRelocationType	type,			/* type of relocation */
		MemHandle			block,			/* handle of info block */
		void				* sourceData,	/* source of relocation */
		void				* destData);	/* relocated value */ This routine relocates a given word or dword argument and is used for  resolving handles and pointers to movable objects. Most often, relocation and  unrelocation occur when resources are loaded, swapped, or saved, and this is  in most cases taken care of by the kernel.

ObjDoRelocation() takes four parameters:

type - The type of relocation to be performed (RelocationType). This can be one of the three values shown below.

block - The handle of the block containing the relocation.

sourceData - A pointer to the source of the relocation; this pointer should be cast to the proper type (word or dword) when calling the routine.

destData - A pointer to the value to be returned; this pointer should be cast appropriately when the routine is called. The exact type of return value depends on sourceData and type, above.

The type of relocation to be done affects the type of data passed in sourceData and destData. The relocation type is passed in the type parameter and must be one of the following enumerations of RelocationType:

RELOC_RELOC_HANDLE
The relocation will be from a resource ID to a handle. The sourceData pointer should be cast to type word, and the destData pointer should be cast to type Handle.

RELOC_RELOC_SEGMENT
The relocation will be from a resource ID to a segment address. The sourceData pointer should be cast to type word, and the destData pointer should be cast to type Segment.

RELOC_RELOC_ENTRY_POINT
The relocation will be from either a resource ID or an entry number to an entry point. Both the sourceData pointer and the destData pointer should be cast to type dword.

ObjDoRelocation() returns an error flag that will be true if an error occurs, false otherwise.

The relocation done by this routine can be undone with ObjDoUnRelocation().

Include: object.h


ObjDoUnRelocation()

Boolean	ObjDoUnRelocation( /* returns true if error */
		ObjRelocationType	type,			/* type of relocation */
		MemHandle			block,			/* handle of info block */
		void				* sourceData,	/* source of relocation */
		void				* destData);	/* relocated value */ This routine unrelocates a given word or dword. It translates a handle, a  segment address, or an entry point back into a resource ID. The translation  done is the exact reverse of that done by **ObjDoRelocation()**. See that  routine (above) for more information.

ObjDoUnRelocation() returns an error flag that will be true if an error occurs and false if the unrelocation is successful. The unrelocated resource ID will be returned pointed to by the destData pointer.

Include: object.h

See Also: ObjDoRelocation()


ObjDuplicateMessage()

EventHandle ObjDuplicateMessage(
		EventHandle msg);				/* event to duplicate */ This routine duplicates a prerecorded event, returning the event handle of  the new event. Pass the handle of the event to be duplicated. You can then  change information about the event with **ObjSetMessageDestination()**.

Include: object.h

See Also: ObjSetEventInfo()


ObjDuplicateResource()

MemHandle ObjDuplicateResource(
		MemHandle		blockToDup,		/* handle of resource; must
										 * not be loaded */
		GeodeHandle		owner,			/* owner of duplicate */
		ThreadHandle	burdenThread);	/* burden thread of duplicate */ This routine duplicates an entire object resource block. The new block will be  put on the "saved blocks" list so it gets saved to the geode's state file. Usually  this is used by the UI to make editable copies of an application's UI resources  to ensure the proper state information gets saved. This routine takes three  parameters:

blockToDup - The handle of the block to be duplicated. The block must not be resident in memory when ObjDuplicateResource() is called. Also, it can only be a “template” resource - a resource that does not get used by the UI or the application directly, but only gets copied via this routine.

owner - The owner geode of the new block. This should be the geode handle of the owning geode or zero to have the calling geode own it. If you pass an owner of -1, the new block will be owned by the same geode that owns the original.

burdenThread - The thread that will run the block and handle its messages. This should be a thread handle or zero to have the calling thread run the block. Passing a burdenThread of -1 makes the new resource have the same burden thread as the original.

ObjDuplicateResource() returns the handle of the newly created block, which will be unlocked and may or may not be resident in memory.

Include: object.h

See Also: ObjFreeDuplicate(), MSG_META_BLOCK_FREE, ObjLockObjBlock()


ObjEnableDetach()

void	ObjEnableDetach(
		optr	obj);		/* object calling this routine */ This routine acts as an object's handler for MSG_META_ACK. This handler  decrements the acknowledgment count (incremented with **ObjIncDetach()**)  and, if the count is zero, enables the detach mechanism so the object can be  fully detached. Because the detach mechanism is implemented in  **MetaClass**, it is highly unlikely you will ever call this routine.

The lone parameter of this routine is the optr of the calling object (or, in the case of MSG_META_ACK, the object sending acknowledgment).

Warnings: This routine may resize and/or move chunks and object blocks, thereby invalidating all pointers and segment addresses.

Include: metaC.goh

See Also: MSG_META_DETACH, ObjInitDetach(), ObjIncDetach(), MSG_META_ACK


ObjFreeChunk()

void	ObjFreeChunk(
		optr	o);		/* optr of chunk to be freed */ This routine frees the passed object's instance chunk. If the object came from  a loaded resource, however, the object is resized to zero and marked dirty  rather than actually freed.

Warnings: The object must be fully detached, and its message queues must be empty before it can safely be freed. All this is handled by MSG_META_DETACH and MSG_META_OBJ_FREE.

Include: object.h

See Also: MSG_META_DETACH, MSG_META_OBJ_FREE, ObjInstantiate()


ObjFreeChunkHandles()

void	ObjFreeChunkHandles(
		MemHandle		mh,			/* handle portion of optr */
		ChunkHandle		ch);		/* chunk portion of optr */ This routine is the same as **ObjFreeChunk()**; the chunk is specified by its  handles rather than by an optr.

Include: object.h


ObjFreeDuplicate()

void	ObjFreeDuplicate(
		MemHandle mh);		/* handle of duplicate block to be freed */ This routine frees a block that had been saved with **ObjSaveBlock()** or  created with **ObjDuplicateResource()**. It must be passed the memory  handle of the duplicated resource.

Warnings: All objects in the duplicated resource must be properly detached to ensure that nothing tries to send messages to the objects in the block. Additionally, the block’s in-use count and interactable count should be zero.

Include: object.h

See Also: ObjDuplicateResource(), ObjSaveBlock(), ObjLMemBlockHeader


ObjFreeMessage()

void	ObjFreeMessage(
		EventHandle event);			/* event to be freed */ This routine frees an event handle and its associated event. This is rarely, if  ever, used by anything other than the kernel. The kernel uses this routine to  free events after they have been handled.

Include: object.h


ObjFreeObjBlock()

void	ObjFreeObjBlock(
		MemHandle block);	/* handle of the object block to be freed */ This routine frees the specified object block. It first checks the block's in-use  count to see if any external references to the block are being kept. If the  in-use count is nonzero, **ObjFreeObjBlock()** simply sets the block's  auto-free bit and returns; the block will be freed the first time the in-use  count reaches zero. If the in-use count is zero (no external references), the  block will be freed immediately.

If the object block passed is not run by the calling thread, the operation will be handled by a remote call in the object block’s thread.

Include: object.h

See Also: ObjFreeDuplicate(), MSG_META_BLOCK_FREE


ObjGetFlags()

ObjChunkFlags ObjGetFlags(
		optr	o);		/* optr of subject object */ This routine returns the object flags associated with a given object. The object  is specified by the passed optr, and the flags are stored in the object's  **ObjChunkFlags** record.

Include: object.h

See Also: ObjSetFlags(), ObjChunkFlags


ObjGetFlagsHandles()

ObjChunkFlags ObjGetFlagsHandles(
		Memhandle		mh,			/* handle portion of optr */
		ChunkHandle		ch);		/* chunk portion of optr */ This routine is the same as **ObjGetFlags()**, but the object is specified with  its handles rather than with its optr.

Include: object.h


ObjGetMessageInfo()

Message	ObjGetMessageInfo(
		EventHandle		event,		/* event to be queried */
		optr	 		* dest);	/* buffer for destination optr */ This routine gets information about the specified *event*. The return value is  the message number of the event. The *dest* parameter is a pointer to an optr.  This routine will return with the optr represinting the event's destination  object.

Include: object.h


ObjIncDetach()

void	ObjIncDetach(
		optr	obj);		/* optr of calling object */ This routine increments the number of detach acknowledgments an object  must receive before it can safely be detached. Each time the detaching object  sends notification of its detachment, it must call **ObjIncDetach()** to indicate  that it must receive a corresponding detach acknowledgment  (MSG_META_ACK).

The calling object must have previously called ObjInitDetach(). Since the detach mechanism is implemented in MetaClass, it is highly unlikely you will ever need to call this routine. ObjIncDetach() takes a single parameter: the optr of the calling object.

Include: metaC.goh

See Also: MSG_META_DETACH, ObjInitDetach(), ObjEnableDetach(), MSG_META_ACK


ObjIncInteractibleCount()

void	ObjIncInteractibleCount(
		MemHandle mh);			/* handle of object block */ This routine increments the interactable count of the given object block. The  interactable count maintains the number of objects currently visible to the  user or about to be acted on by the user (e.g. via keyboard accelerator). The  interactable count is maintained by the UI; only in extremely special cases  may you need to increment or decrement the count. To decrement the count,  use **ObjDecInteractibleCount()**.

Visible objects increment the interactable count in their MSG_VIS_OPEN handlers and decrement it in their MSG_VIS_CLOSE handlers. This is built into VisClass.

Include: object.h

See Also: ObjDecInteractibleCount(), MSG_VIS_OPEN, MSG_VIS_CLOSE, ObjLMemBlockHeader


ObjIncInUseCount()

void	ObjIncInUseCount(
		MemHandle mh);			/* handle of object block */ This routine increments the given object block's in-use count. The in-use  count maintains the number of outside references to this object block which  are stored elsewhere and which need to be removed before the block can  safely be freed. If you store an optr to an object block, you should increment  the in-use count of the block.

When the reference to the block is removed, the in-use count should be decremented with ObjDecInUseCount().

Include: object.h

See Also: ObjDecInUseCount(), ObjIncInteractibleCount(), ObjLMemBlockHeader


ObjInitDetach()

void	ObjInitDetach(
		MetaMessages 	msg,
		optr			obj			/* object being detached */
		word			callerID,	/* an identifier token for the caller */
		optr			ackOD);		/* object to which ack is ent */

Initialize the detach sequence for the specified object. The detach sequence severs all ties between the system and the object, allowing it to be destroyed without other objects or geodes trying to contact it. It is highly unlikely you will ever call this routine; typically, you will instead use MSG_META_DETACH or one of the generic or visible object messages, which will call this routine. The parameters for this routine are

msg - The detach message.

obj - The optr of the object to be detached.

callerID - The caller object’s ID.

ackOD - The optr of the caller object or another object which is to receive acknowledgment notification of the detach.

Include: metaC.goh

See Also: MSG_META_DETACH, MSG_GEN_DESTROY, MSG_VIS_REMOVE, ObjIncDetach(), ObjEnableDetach(), MSG_META_ACK


ObjInitializeMaster()

void	ObjInitializeMaster(
		optr 			obj,		/* object to be initialized */
		ClassStruct		* class);	/* class in master group */ This routine initializes the appropriate master part of the passed object,  resizing the instance chunk if necessary. It takes two parameters:

obj - The optr of the object whose master part is to be initialized.

class - A pointer to the class definition of a class in the appropriate master group. This does not have to be the master class; it must only be a class in the master group.

Warnings: This routine may resize and/or move chunks or object blocks, thereby invalidating pointers and segment addresses.

Include: object.h

See Also: ObjResizeMaster(), ObjInitializePart(), ClassStruct


ObjInitializeMasterHandles()

void	ObjInitializeMasterHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		ClassStruct		* class);		/* class in master group */ This routine is the same as **ObjInitializeMaster()** except it specifies the  object via its handles rather than its optr.

Include: object.h


ObjInitializePart()

void	ObjInitializePart(
		optr 	obj,			/* object to have a part initialized */
		word	masterOffset);	/* offset to master offset in chunk */ This routine initializes all master parts of the given object down to and  including the master part specified in *masterOffset*. It will resize the chunk  if necessary and even resolve variant classes above the master group  specified, if necessary. This routine takes two parameters:

obj - The optr of the object to be initialized.

masterOffset - The offset within the parent’s instance chunk to the master group’s offset (the value that would appear in the parent class’ Class_masterOffset field in its ClassStruct structure).

Warnings: This routine may move and/or resize chunks or object blocks, thereby invalidating pointers and segment addresses.

Include: object.h

See Also: ObjResizeMaster(), ObjInitializeMaster(), MSG_META_RESOLVE_VARIANT_SUPERCLASS


ObjInitializePartHandles()

void	ObjInitializePartHandles(
		Memhandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		word			masterOffset);	/* master group offset */ This routine is the same as **ObjInitializePart()** except that it specifies the  object via its handles rather than an optr.

Include: object.h


ObjInstantiate()

optr	ObjInstantiate(
		MemHandle		block,		/* block in which new object
									 * will be instantiated */
		ClassStruct		* class);	/* class of new object */ This routine instantiates a new object, allocating the proper size instance  chunk. It returns the optr of the new object; this optr can then be used to send  setup messages or other messages (such as adding the object to an object tree,  setting it usable, etc.).

The new object’s instance data will be initialized to all zeroes if it has no master parts (is a direct descendant of MetaClass). If it is a member of some master group, only enough space for the base structure (the master offsets and the class pointer) will be allocated. In either case, initialization of the instance data will occur at a later time.

ObjInstantiate() takes two parameters:

block - The memory handle of an object block in which the object’s instance chunk will be allocated. This block must be an object block, though it need not be run by the caller’s thread. If the block is run by another thread, the routine will be executed as a remote call.

class - A pointer to the ClassStruct structure of the class of the new object. This pointer will be set in the object’s class pointer (the first four bytes of the instance chunk).

Warnings: This routine, because it allocates a new chunk, may cause LMem and Object blocks to move or resize, thereby invalidating any pointers and segment addresses. Be sure to dereference pointers after calls to this routine.

Include: metaC.goh


ObjIsClassADescendant()

Boolean	ObjIsClassADescendant(
		ClassStruct		* class1,			/* proposed ancestor */
		ClassStruct		* class2);			/* proposed descendant */ This routine checks if *class2* is a descendant of *class1* and returns *true* if it is.

Include: object.h


ObjIsObjectInClass()

Boolean	ObjIsObjectInClass(
		optr			obj,			/* object to check */
		ClassStruct		* class);		/* proposed class */ This routine checks to see if the passed object is a member of the specified  class. It checks superclasses as well, but if an unresolved variant class is  encountered, the variant will *not* be resolved. If you want to search past  variant class links, you should sent MSG_META_DUMMY to the object first.  The two parameters for this routine are

obj - The optr of the object to be checked.

class - A pointer to the subject class’ ClassStruct definition.

ObjIsObjectInClass() returns true if the object is in the class, false (zero) if it is not.

Include: object.h


ObjIsObjectInClassHandles()

Boolean	ObjIsObjectInClassHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		ClassStruct		* class);		/* proposed class */ This routine is just like **ObjIsObjectInClass()** except the object is specified  via its handles rather than its optr.

Include: object.h


ObjLinkFindParent()

optr	ObjLinkFindParent(
		optr	obj,			/* child's optr */
		word	masterOffset,	/* offset to master part with link field */
		word	linkOffset);	/* offset in master part to link field */ This routine returns the optr of the specified object's parent. It must be  passed the following:

obj The optr of the object whose parent is to be found.

masterOffset - The offset within the object’s instance chunk to its master group’s offset (the value that would appear in the Class_masterOffset field in its ClassStruct structure).

linkOffset - The offset within the object’s instance chunk to the link field.

Include: metaC.goh

See Also: MSG_VIS_FIND_PARENT, MSG_GEN_FIND_PARENT


ObjLockObjBlock()

void	* ObjLockObjBlock(
		MemHandle mh);			/* handle of object block */ This routine locks an object block, loading in the block if necessary. It must  be passed the handle of the block, and it returns the locked block's segment  address. When the caller is done using the block, it should unlock it with  **MemUnlock()**.

Be Sure To: Always unlock the block when you are done with it, with MemUnlock().

Include: object.h

See Also: MemLock(), MemUnlock()


ObjMapSavedToState()

VMBlockHandle ObjMapSavedToState(
	MemHandle mh);			/* handle of object block */ This routine returns the VM block handle of the state file block corresponding  to the passed object block. If the specified object block has no state file  equivalent, a null handle is returned.

Include: object.h


ObjMapStateToSaved()

MemHandle ObjMapStateToSaved(
		VMBlockHandle	vmbh,	/* VM block handle of state block */
		GeodeHandle		gh);	/* handle of geode owning block */ This routine takes a VM block handle and a geode handle and returns the  memory block corresponding to the VM block, if any. The two parameters are

vmbh - The VM block handle of the VM block to be mapped.

gh - The geode handle of the owner of the block, or zero to use the calling geode’s handle.

If the block is found, ObjMapStateToSaved() returns its handle. If the block is not found, it returns a null handle.

Include: object.h


ObjMarkDirty()

void	ObjMarkDirty(
		optr 	o);			/* object to be marked dirty */ This routine marks an object dirty, indicating that changes to it should be  saved when its object block is saved. If you want changes to objects saved, you  should mark the object dirty.

Tips and Tricks: Often you do not need this routine because parameters or flags to other routines will set the object dirty automatically. If there is any doubt, however, you should use this routine.

Include: object.h

See Also: ObjChunkFlags, ObjSetFlags()


ObjMarkDirtyHandles()

void	ObjMarkDirtyHandles(
		MemHandle		mh,			/* handle portion of optr */
		ChunkHandle		ch);		/* chunk portion of optr */ This routine is the same as **ObjMarkDirty()** except that it specifies the  object via handles rather than an optr.

ObjProcBroadcastMessage()

void	ObjProcBroadcastMessage(
		EventHandle event);			/* the event to be broadcast */ This routine broadcasts the given event to all threads which have message  queues. It must be passed as an encapsulated event (usually recorded with  **@record**) and returns nothing. This is typically used for notification  purposes.

Include: metaC.goh


ObjRelocateEntryPoint()

void *	ObjRelocateEntryPoint(
		EntryPointRelocation *			relocData);

ObjRelocOrUnRelocSuper()

void	ObjRelocOrUnRelocSuper(
		optr 			oself,
		ClassStruct		*class,
		word			frame); Call this routine to relocate an object's superclass.

Include: object.h


ObjResizeMaster()

void	ObjResizeMaster(
		optr	obj,			/* object to have its master part resized */
		word	masterOffset,	/* master offset of proper master part */
		word	newSize);		/* new size for the master part */ This routine resizes a master part of an object's instance chunk. It is typically  used to allocate space for a master part or to resize the master part to zero  (as when the Vis part of a visible object is removed in MSG_VIS_CLOSE). This  routine must be passed the following three parameters:

obj - The optr of the object whose master part is to be resized.

masterOffset - The offset into the object’s instance chunk where the offset to the master part is kept (this is the same offset held in the master class’ Class_masterOffset field).

newSize - The new size of the master part. This can be found in the master class’ Class_instanceSize field.

Warnings: This routine may resize and/or move chunks or object blocks, thereby invalidating stored segment addresses and pointers.

Include: object.h

See Also: ClassStruct, ObjInitializeMaster(), ObjInitializePart()


ObjResizeMasterHandles()

void	ObjResizeMasterHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		word			masterOffset,	/* offset to master part */
		word			newSize);		/* new size of master part */ This routine is the same as **ObjResizeMaster()** except that the object is  specified with its handles rather than its optr.

Include: object.h


ObjSaveBlock()

void	ObjSaveBlock(
		MemHandle	mh);	/*handle of block to be marked for saving */ This routine sets up an object or LMem block to be saved to its owner's state  file. The block's handle must be passed in *mh*. The block must be an object  block.

Include: object.h

See Also: ObjMapSavedToState(), ObjMapStateToSaved()


ObjSetEventInfo()

void	ObjSetEventInfo(
		EventHandle		event,		/* handle of the event to be modified */
		Message			msg,		/* the new message for the event */
		optr			dest);		/* the new destination of the event */ This routine modifies an event, setting its information to the passed values.  The three parameters are

event - The event handle of the event to be modified.

msg - The message to be sent in place of the current message. To use the same message, you must first retrieve it with ObjGetMessageInfo().

dest - The optr of the new destination object for the event. To use the same destination object, you must first retrieve it with ObjGetMessageInfo().

Include: object.h

See Also: ObjGetEventInfo()


ObjSetFlags()

void	ObjSetFlags(
		optr			o,				/* object whose flags will be set */
		ObjChunkFlags 	bitsToSet,		/* flags to set */
		ObjChunkFlags	bitsToClear);	/* flags to clear */ This routine sets the chunk flags for the specified object. Flags that should be  set are passed in *bitsToSet*, and flags that should be cleared are passed in  *bitsToClear*. Typically, applications will not use this routine but will rather  let the kernel maintain the object's flags.

Include: object.h

See Also: ObjGetFlags(), ObjChunkFlags


ObjSetFlagsHandles()

void	ObjSetFlagsHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		ObjChunkFlags	bitsToSet,		/* flags to set */
		ObjChunkFlags	bitsToClear);	/* flags to clear */ This routine is the same as **ObjSetFlags()** except that the object is specified  via its handles rather than its optr.

Include: object.h


ObjTestIfObjBlockRunByCurThread()

Boolean	ObjTestIfObjBlockRunByCurThread(
		MemHandle	mh);		/* handle of object block */ This routine checks if the calling thread is running the specified object block.  This routine can be used to determine if calls to objects in the block are across  threads or internal to the calling thread. Pass this routine the handle of the  object block to be checked - if the object block is a VM block, the thread for the  VM file is checked rather than that for the block.

If the block is run by the calling thread, the return value is true. If a different thread runs the block, the return is false (zero).

Include: object.h


ObjUnrelocateEntryPoint()

void	ObjUnrelocateEntryPoint(
		EntryPointRelocation *		relocData,
		void *						entryPoint);

ObjVarAddData()

void	* ObjVarAddData(
		optr		obj,			/* object to add vardata to */
		VardataKey	dataType,		/* vardata type */
		word		dataSize);		/* vardata data size, if any */ This routine adds or alters a variable data entry for the specified object. If the  data type does not currently exist in the instance chunk, it will be allocated  and added to the chunk. If it does exist, the extra data of the entry will be  re-initialized to all zeroes.

This routine returns a pointer to the extra data of the new or modified entry; if the entry has no extra data, an opaque pointer to the entry is passed, and you can use this pointer with ObjVarDeleteDataAt(). In either case, the object will be marked dirty.

The parameters of this routine are

obj - The optr of the object affected. This should be the caller’s optr.

dataType - The VardataKey word declaring the data type and its flags. The VDF_SAVE_TO_STATE flag must be properly set; the VDF_EXTRA_DATA flag is ignored, however, as the routine will set it properly.

dataSize - The size of the extra data for this type. If the type has no extra data, pass zero.

Include: object.h

Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects’ vardata remotely, use messages provided by MetaClass (see below under “See Also”).

See Also: MSG_META_ADD_VAR_DATA, ObjVarDeleteDataAt()


ObjVarAddDataHandles()

void	* ObjVarAddDataHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		VardataKey		dataType,		/* vardata type */
		word			dataSize);		/* vardata data size, if any */ This routine is the same as **ObjVarAddData()** except that the object is  specified via its handles rather than its optr.

Include: object.h


ObjVarCopyDataRange()

void	ObjVarCopyDataRange(
		optr	source,		/* the optr of the source object */
		optr	dest,		/* the optr of the destination (calling) object */
		word	rangeStart,	/* the smallest data type value to be copied */
		word	rangeEnd);	/* the largest data type value to be copied */ This routine copies all the vardata entries within the specified range from the  *source* object to the *dest* object. The range to be copied is specified by data  types and is between *rangeStart* and *rangeEnd*, inclusive. If any data entries  are copied, the destination object will be marked dirty.

Warnings: This routine should be called only by the destination object; it is against OOP doctrine for one object to alter another’s instance data.

Include: object.h


ObjVarDeleteData()

Boolean	ObjVarDeleteData(
		optr		obj,			/* object to delete from */
		VardataKey	dataType);		/* data type to delete */ This routine deletes a vardata entry from the specified object's instance  chunk, if the entry exists. The entry is specified by its data type; to delete an  entry specified by a pointer to it, use **ObjVarDeleteDataAt()**, below. It  returns an error flag: *true* if the entry was not found, *false* if the entry was  successfully deleted. The object will also be marked dirty by the routine.

The parameters for this routine are

obj - The optr of the object affected. This should be the caller’s optr.

dataType - The VardataKey word declaring the data type and its flags. Both the VDF_SAVE_TO_STATE flag and the VDF_EXTRA_DATA flag are ignored.

Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects’ vardata remotely, use messages provided by MetaClass (see below under “See Also”).

Include: object.h

See Also: MSG_META_DELETE_VAR_DATA, ObjVarDeleteDataAt()


ObjVarDeleteDataHandles()

Boolean	ObjVarDeleteDataHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		VardataKey		dataType);		/* data type to delete */ This routine is the same as **ObjVarDeleteData()** except that the object is  specified via its handles rather than its optr.

Include: object.h


ObjVarDeleteDataAt()

void	ObjVarDeleteDataAt(
		optr	obj,				/* object to delete from */
		word	extraDataOffset);	/* offset to extra data to delete */ This routine deletes the specified vardata entry from the given object's  instance chunk. The vardata entry is specified by its pointer as returned by  **ObjVarAddData()**, **ObjVarFindData()**, and **ObjVarDerefData()**. To  delete an entry specified by its data type, use **ObjVarDeleteData()**, above.

Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects’ vardata remotely, use messages provided by MetaClass (see below under “See Also”).

Include: object.h

See Also: MSG_META_DELETE_VAR_DATA, ObjVarDeleteData()


ObjVarDeleteDataAtHandles()

void	ObjVarDeleteDataAtHandles(
		MemHandle		mh,			/* handle portion of optr */
		ChunkHandle		ch,			/* chunk portion of optr */
		word	extraDataOffset);	/* offset to extra data to delete */ This routine is the same as **ObjVarDeleteDataAt()** except that the object is  specified via its handles rather than its optr.

Include: object.h


ObjVarDeleteDataRange()

void	ObjVarDeleteDataRange(
		optr 		obj,				/* object to delete from */
		word		rangeStart,			/* start of range */
		word		rangeEnd,			/* end of range */
		Boolean		useStateFlag);		/* save to state flag */ This routine deletes all data entries within a given range for the passed  object. The range is specified by beginning and ending data types and is  inclusive. The four parameters to this routine are

obj - The optr of the object whose data entries are to be deleted.

rangeStart - The lowest number data type to be deleted. Both the VDF_SAVE_TO_STATE flag and the VDF_EXTRA_DATA flag are ignored.

rangeEnd - The highest number data type to be deleted. Both the VDF_SAVE_TO_STATE flag and the VDF_EXTRA_DATA flag are ignored.

useStateFlag - A flag indicating whether entries with their VDF_SAVE_TO_STATE flags should be deleted. Pass true (nonzero) to take the state flag into account; pass false (zero) to delete all entries in the range.

Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects’ vardata remotely, use messages provided by MetaClass (see below under “See Also”).

Include: object.h

See Also: MSG_META_DELETE_VAR_DATA


ObjVarDeleteDataRangeHandles()

void	ObjVarDeleteDataRangeHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		word			rangeStart,		/* start of range */
		word			rangeEnd,		/* end of range */
		Boolean			useStateFlag);	/* save to state flag */ This routine is the same as **ObjVarDeleteDataRange()** except that the  object is specified via its handles rather than its optr.

Include: object.h


ObjVarDerefData()

void	* ObjVarDerefData(
		optr			obj,			/* object having data type */
		VardataKey		dataType);		/* data type to dereference */ This routine is exactly like **ObjVarFindData()**, below, except that it does not  return a null pointer if the data type is not found. Do not use this routine  unless you are absolutely sure the data type is in the object; otherwise,  results are unpredictable.

Include: object.h

See Also: ObjVarFindData()


ObjVarDerefDataHandles()

void	* ObjVarDerefDataHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		VardataKey		dataType);		/* data type to dereference */ This routine is the same as **ObjVarDerefData()** except that the object is  specified via its handles rather than its optr.

Include: object.h


ObjVarFindData()

void	* ObjVarFindData(
		optr			obj,			/* object to be checked */
		VardataKey		dataType);		/* data type to find */ This routine searches an object's variable data for a given data type. If the  type is found, **ObjVarFindData()** returns a pointer to the entry's extra data;  if the entry has no extra data, an opaque pointer is returned which may be  used with **ObjVarDeleteDataAt()**. If the entry is not found, a null pointer  is returned. The pointer returned by this routine must be used before any  subsequent operations on the object's block; the pointer may be invalidated  by other LMem or object operations.

The two parameters of this routine are

obj - The optr of the object affected. This should be the caller’s optr.

dataType - The VardataKey word declaring the data type and its flags. Both the VDF_SAVE_TO_STATE flag and the VDF_EXTRA_DATA flag are ignored.

Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects’ vardata remotely, use messages provided by MetaClass (see below under “See Also”).

Include: object.h

See Also: MSG_META_FIND_VAR_DATA


ObjVarFindDataHandles()

void	* ObjVarFindDataHandles(
		MemHandle		mh,				/* handle portion of optr */
		ChunkHandle		ch,				/* chunk portion of optr */
		VardataKey		dataType);		/* data type to find */ This routine is the same as **ObjVarFindData()** except that the object is  specified via its handles rather than its optr.

Include: object.h


ObjVarScanData()

void	ObjVarScanData(
		optr				obj,			/* object to be scanned */
		word				numHandlers,	/* number of handlers in table */
		VarDataCHandler		* handlerTable,	/* pointer to handler table */
		void				* handlerData);	/* pointer to handler data */ This routine scans an object's vardata and calls all the vardata handlers  specified in the passed handler table. Pass it the following parameters:

obj - The optr of the object whose variable data table is to be scanned.

numHandlers - The number of handlers specified in the passed handler table.

handlerTable A pointer to a list of VarDataCHandler structures. Each of these structures contains a vardata data type and a pointer to the routine that is to handle it. All the handler routines must be in the same segment as the handler table.

handlerData - A pointer to a buffer that is passed on to the handlers. This can contain any information of specific interest to the application or handlers.

Vardata Handler Format: A vardata handler routine must have the following format:

void _pascal (MemHandle mh, ChunkHandle chnk,
	VarDataEntry *extraData, word dataType,
	void *handlerData) The handler should not free the object chunk or destroy the object; it can do  anything else it pleases. The handler returns nothing and takes the following  parameters:

mh:chnk - The memory handle and chunk handle of the object being referenced. Together, these comprise the optr of the object.

extraData - A pointer to the data type’s extra data, if it has any. This pointer may be parsed with the macros VarDataTypePtr(), VarDataFlagsPtr(), and VarDataSizePtr().

dataType - The data type of the data entry being handled. This is a record of type VardataKey.

handlerData - A pointer to a buffer passed through by ObjVarScanData(). This buffer may be used for passing additional data to the handlers.

Structures: The VarDataCHandler structure contains two elements:

typedef struct {
	word			VDCH_dataType;
	void_pascal 	(*VDCH_handler) (
			MemHandle		mh,
			ChunkHandle		chnk,
			VarDataEntry	* extraData,
			word			dataType
			void			* handlerData);
} VarDataCHandler; The first element is the data type, a record containing the data type and the  vardata flags. The second element is a far pointer to the handler routine for  the type.

Include: object.h


ObjVarScanDataHandles()

void	ObjVarScanDataHandles(
		MemHandle			mh,				/* handle portion of optr */
		ChunkHandle			ch,				/* chunk portion of optr */
		word				numHandlers,	/* number of handlers in table */
		VarDataCHandler		* handlerTable,	/* pointer to handler table */
		void				* handlerData);	/* pointer to handler data */ This routine is the same as **ObjVarScanData()** except that the object is  specified via its handles rather than its optr.

Include: object.h


offsetof()

word	offsetof(struc, field); This macro returns the offset of the specified field within the specified  structure.

OptrToChunk()

ChunkHandle OptrToChunk(op);
		optr	op; This macro extracts the chunk handle portion of the given optr.

See Also: ConstructOptr(), OptrToHandle()


OptrToHandle()

MemHandle OptrToHandle(op);
		optr	op; This macro extracts the MemHandle portion of the given optr.

See Also: ConstructOptr(), OptrToChunk()


ParallelClose()

StreamError ParallelClose(
		GeodeHandle 		driver,
		ParallelUnit 		unit,
		Boolean 			linger); Close the stream to a parallel port.

Include: streamC.h


ParallelOpen()

StreamError ParallelOpen(
		GeodeHandle 		driver,
		ParallelUnit 		unit,
		StreamOpenFlags 	flags,
		word				outBuffSize,
		word 				timeout); This routine opens a stream to the specified parallel port. It is passed the  following arguments:

driver - The GeodeToken of the parallel driver.

unit - The parallel port to open.

flags - This specifies whether the call should fail if the port is busy, or wait for a time to see if it will become free.

outBuffSize - The size of the stream buffer used for output to the parallel port.

timeout - The number of clock ticks to wait for the port to become free. (This argument is ignored if flags is not STREAM_OPEN_TIMEOUT.)

If the routine is successful, it returns zero. If it is unsuccessful, it returns a member of the StreamError enumerated type.

Include: streamC.h


ParallelWrite()

StreamError ParallelWrite(
		GeodeHandle 		driver,
		ParallelUnit 		unit,
		StreamBlocker 		blocker,
		word 				buffSize,
		const byte *		buffer,
		word *				numBytesWritten); Write data to a parallel port.

Include: streamC.h


ParallelWriteByte()

StreamError ParallelWrite(
		GeodeHandle 		driver,
		ParallelUnit 		unit,
		StreamBlocker 		blocker,
		word 				buffSize,
		byte				dataByte); Write one byte of data to a parallel port.

Include: streamC.h


PCB()

#define PCB(return_type, pointer_name, args) \
		return_type _pascal (*pointer_name) args This macro is useful for declaring pointers to functions that use the pascal  calling conventions. For example, to declare a pointer to a function which is  passed two strings and returns an integer, one could write

PCB(int, func_ptr, (const char *, const char *));

which would be expanded to

int _pascal (*func_ptr) (const char *, const char *);

See Also: CCB()


PCCOMABORT()

void PCCOMABORT(void); This routine aborts the current file transfer operation being carried out by  the PCCom library. It is the third entry point in the PCCom library.

Include: pccom.goh


PCCOMEXIT()

PCComReturnType PCCOMEXIT(); This routine kills a pccom thread such as those started by PCCOMINIT(). It is  the second entry point in the PCCom library.

Structures:

typedef ByteEnum PCComReturnType;
#define PCCRT_NO_ERROR 0
#define PCCRT_CANNOT_LOAD_SERIAL_DRIVER 1
#define PCCRT_CANNOT_CREATE_THREAD 2
#define PCCRT_CANNOT_ALLOC_STREAM 3
#define PCCRT_ALREADY_INITIALIZED 4 **Include:** pccom.goh 

PCCOMINIT()

PCComReturnType PCCOMINIT(
		SerialPortNum 		port,
		SerialBaud 			baud,
		word 				timeout,
		optr 				callbackOptr,
		PCComInitFlags 		flags); This entry point of the PCCom library spawns a new thread which monitors  a serial port and acts as a passive pccom terminal. This routine is the first  entry point in the PCCom library.

This routine takes the following arguments:

port - A SerialPortNum value specifying which serial port to use for the pccom connection. Pass -1 for the system default value: com1 for the Zoomer, com2 for the desktop product.

baud - A SerialBaud value specifying what speed to use. Pass -1 for the system default value: 19200 baud for the Zoomer, 38400 baud for the desktop product.

timeout - Number of clock ticks (one tick is 1/60 second) to allow for connection.

callbackOptr - An object which will receive notification messages of certain events. A value of zero means no notification will be sent.

flags - If an object will be receiving notification messages, these flags determine what sort of notifications will be sent.

Structures:

typedef ByteEnum PCComReturnType;
#define PCCRT_NO_ERROR 0
#define PCCRT_CANNOT_LOAD_SERIAL_DRIVER 1
#define PCCRT_CANNOT_CREATE_THREAD 2
#define PCCRT_CANNOT_ALLOC_STREAM 3
#define PCCRT_ALREADY_INITIALIZED 4

typedef WordFlags PCComInitFlags;
	/* send notifications when text is available for display */
#define PCCIF_NOTIFY_OUTPUT 0x8000
	/* send notification when the remote machine shuts down the
	 * serial line */
#define PCCIF_NOTIFY_EXIT 0x4000 **Include:** pccom.goh 

ProcCallFixedOrMovable_cdecl()

dword	ProcCallFixedOrMovable_cdecl(
		void 	(*routine),
		...) This routine calls the routine pointed to, passing the other arguments  through to the called routine. The called routine must use C calling  conventions.

Include: resource.h


ProcCallFixedOrMovable_pascal()

dword	ProcCallFixedOrMovable_pascal(
		...,
		void 	(*routine))

This routine calls the routine pointed to, passing the other arguments through to the called routine. The called routine must use Pascal calling conventions.

Include: resource.h


ProcGetLibraryEntry()

void *	ProcGetLibraryEntry(
		GeodeHandle		library,
		word			entryNumber) This routine returns the pointer to a library's entry-point.

Include: resource.h


ProcInfo()

ThreadHandle ProcInfo(
		GeodeHandle gh);		/* handle of geode to check */ This routine returns the first thread of the process geode specified. If the  geode is not a process, the routine will return a null handle.

Include: geode.h


PtrToOffset()

word	PtrToOffset(ptr);
		dword	ptr; This macro returns just the lower 16 bits of the given dword. It is most useful  for extracting the offset portion of a far pointer.

PtrToSegment()

word	PtrToSegment(ptr);
		dword	ptr; This macro returns just the upper 16 bits of the given dword. It is most useful  for extracting the segment address of a far pointer.

Routines H-L <– Table of Contents    –> Routines Q-T