VCB

Section: User Commands (1)
Updated: AM*GA Programmer's Manual
Index Return to Main Contents
 

NAME

VCB  

DESCRIPTION

stands for Virtual Co-ordinate Box. There is an every-day example for its use right at hand: the Workbench windows.

The user peeps through their rectangular inner box onto a (i.e. seemingly real, but not there) plane that infinitely extents into all directions and on which icons of files and drawers lie at certain By means of the scrollers within the window borders, the user can shift the box around on the virtual plane, causing new things to appear in the window.

Another example would be a text editor. Once you have entered more text that the window can hold, the text extents beyond the window's bounds on its arbitrarily long fanfold paper. Then you will use the scroll bar that normally is attached to the right border of the window to look at different parts of your text.

Almost every application program that operates on an arbitrarily extensible project data base and that employs a graphical user interface will use the virtual co-ordinate plane to display its data.

Now VCB allows programs not only to share the concept, but also the code!

VCB is a BOOPSI class implementation in shape of a scanned library (for Manx/Aztec C).

At present this class is still `private� in the sense that I do not provide code that adds it to the system's public pool of named classes and therefore is not accessible by a symbolic name.

After some experiences in its use have been collected and possible bugs habe been fixed, it will be submitted to Commodore Amiga for becoming a public BOOPSI class with a registered name. This name will probably be "vcbgclass" (it is a descendant of "gadgetclass"). Maybe some day it will even be part of the OS itself (Intuition provide such a service).

You should link the library to your client code in order to create VCB gadgets and attach them to your windows. Such a gadget consists of horizontal and/or vertical scrollers (that look almost identical to those within Workbench windows) and the box in which your data will be visible. You have to supply a hook to a function of your own that will do the actual rendering within the box according to the `instructions� the gadget gives it. The internals of that function are completely It just makes no difference to that gadget whether you are going to display text, graphics, a musical score etc. or all of them at once!

 

USAGE

Using VCB starts with creating the BOOPSI class. You do this by calling the library function initVCBClass(). freeVCBClass() will free that class again. Once you have the class, you can create as many instances (gadgets) of that class as you want by calling NewObject().

As each of Intuition's own classes defines certain specific tags for setting up the instance as the client needs it, so does VCB. Here are the  

TAGS

 

VCBGA_ExposureHook (struct Hook *)

       the hook to your rendering function (see the CALLBACK section below).

 

VCBGA_Interim (BOOL)

       TRUE (1) indicates that the display should update while a scroller
        is moved or a button repeats, not only when the scroller or button
        is released. Think twice before setting this flag! Although the
        exposure hook only gets called when the display actually changes
        (and not on
       mouse move), there may be quite a lot of invokations to your rendering
        function.
        If your rendering
        function takes too long to complete, the system may choke with pending
        mouse move events.

 

VCBGA_HScroller (BOOL)

       TRUE (1) indicates that you want a horizontal scroller.

 

VCBGA_VScroller (BOOL)

       TRUE (1) indicates that you want a vertical scroller.

        Without the scroller, you cannot move the display box over the virtual
        plane in that direction
       but besides that there is no difference
        (you can still move it via SetGadgetAttrs()).

 

VCBGA_HBorder (BOOL)

       TRUE (1) put horizontal scroller (if any) into bottom border of the host window.

 

VCBGA_VBorder (BOOL)

       TRUE (1) put vertical scroller (if any) into right border of the host window

        Note: Setting the VCBGA_H/VBorder flag will adjust the window borders to accommodate
        the scroller, it will not resize your gadget in any way.
        (see also example).

 

VCBGA_HUnit (ULONG)

       the number of pixels that make one virtual horizontal co-ordinate unit.

 

VCBGA_VUnit (ULONG)

       the number of pixels that make one virtual vertical co-ordinate unit.

 

VCBGA_HTotal (ULONG)

       the horizontal extension of the virtual plane measured in virtual units.

 

VCBGA_VTotal (ULONG)

       the vertical extension of the virtual plane measured in virtual units.

        In this version, VCB cannot emulate Workbench windows which feature an
        infinitely large virtual plane. I personally don't need this (now), but
        I will add it if someone misses it.

 

VCBGA_HOffset (ULONG)

       the current horizontal co-ordinate of the left border of the display box,
        measured in virtual units.

 

VCBGA_VOffset (ULONG)

       the current vertical co-ordinate of the left border of the display box,
        measured in virtual units.

In addition to these, all tags that apply to the general remain active as well, of course.

To create the imagery for the scrollers, two additional tags should be provided. The tag values are defined in <intuition/imageclass.h>.

These are SYSIA_DrawInfo (struct DrawInfo *) (you get/free the DrawInfo structure using GetScreenDrawInfo()/FreeScreenDrawInfo, see AutoDocs) and SYSIA_Size (SYSISIZE_...). While a missing SYSIA_Size tag is defaulted to SYSISIZE_MEDRES (Workbench default resolution), a missing SYSIA_DrawInfo tag will cause NewObject() to fail.

There are five further tags that refer to read-only attributes (ignored by SetGadgetAttrs(), but retrievable by GetAttr()):

 

VCBGA_HSize (ULONG), VCBGA_VSize (ULONG)

       the number of units (as defined by VCBGA_H/VUnit) that currently fit into
        the display box horizontally/vertically. For VCBs with
        GFLG_RELWIDTH / GFLG_RELHEIGHT set these values change each time the window
        is resized.

 

VCBGA_XOrigin (ULONG), VCBGA_YOrigin (ULONG)

       the current co-ordinates of the left top corner of the display box
        (where data is displayed)
        within the rastport. Note that this values change for VCBs with
        GFLG_RELRIGHT / GFLG_RELBOTTOM set each time the window is resized.
        The rendering function
        must get this values every time it is invoked and use them in every rendering
        operation as offsets to the rastport's origin.

 

VCBGA_Semaphore (struct SignalSemaphore *)

       This returns the address of a SignalSemaphore structure that the client code
        must obtain if it is going to modify data structures that the rendering
        function relies on (see ARBITRATION section below).

 

CALLBACK

The callback function will receive arguments in the usual form: the hook pointer, an `object� and a command message.

The `object� is the usual public handle to the VCB instance. You will need this to retrieve geometric data via GetAttr() (the VCB structure is I'm doing this the clean way, despite the overhead). See the example.

The message pointer refers to an ExposureMsg structure (defined in vcb.h). It contains a command ID (the only defined command ID is VCBCMD_RENDER, but better test for this ID explicitly), a pointer to the rastport into which the renderings go and left, top, width and height values for the rectangle that has to be (re-)drawn. An `exposure� has occured if the bitmap contents do no longer reflect the data that is located at the respective position on the virtual plane. Possible reasons are that the window wasn't previously open or was exposed by some other window going away or that the display box moved to another position on the virtual plane (either by manipulation of the scrollers or by a client request via SetGadgetAttrs()).

The left, top, width and height values are in virtual units and have to be multiplied with the respective unit values to yield pixel dimensions.

Be aware that callback code is hazardous area! There are some things that be avoided.

The execution time of this function is critical. The functionality of the whole user interface depends on that your function completes as quickly as possible. Prepare all information needed for rendering in advance and store it where the function can get it (please read the ARBITRATION section below, too). Better to consume some more memory than to freeze the user interface.

Do not call dos.library functions directly or indirectly from the rendering function! This function executes in the context of the input device's task!

Likewise, do not directly or indirectly call Wait() (deadlock imminent). This implies that you cannot employ the console.device to do text rendering!

If you have to debug this part of your code, never use printf() or fprintf()! Try to kprintf() to a terminal or record to an internal data structure and evaluate it later.

Nonetheless, do the things that are necessary: Please do not make any assumptions on the state that the rastport is in when your function is called. Setup the rastport explicitly before you start rendering. In particular, set the pens and the draw mode where appropriate (text, vector drawings, area drawings), set the line pattern for vector drawings, set the area pattern for area drawings. Certainly I forgot something, so please read through the docs of the graphics.library functions that you use to find out what they depend on. Even if the OS does not make use of some rastport features now, it may do so in the future. We are all suffering the system font dependency of pre-OS 2.0 software now. Let this be a lesson to us!

 

ARBITRATION

The callback function executes on another task's context and time slice. If it relies on data that is going to be changed by the client task (which is most probably the case if it is a project data base that is being edited by the user), the client task has to arbitrate for the write access to that data (read access is free for the client since the callback code is not supposed to modify any static data).

To that purpose, a SignalSemaphore structure is part of the VCB instance data. The semaphore is automatically initialized during the processing of NewObject(). The gadget only performs a callback if an AttemptSemaphore() succeeds. It calls ReleaseSemaphore() after the callback completes.

Thus to prevent the gadget from rendering data that is being modified, the client must wait for ObtainSemaphore() to return (which should happen as soon as the user stops fiddling with the VCB's scrollers or moving/resizing the window). As long as the client posseses the access right, the gadget's display will not be updated, even not due to client calls to SetGadgetAttrs().

The pointer to the semaphore must be retrieved by GetAttr( VCBGA_Semaphore, ... ) (see TAGS and example program).

 

EXAMPLE PROGRAM

There is a simple test program included in this distribution, named test.c. It does not do anything useful, but it shows how to write a VCB client. The rendering function exposure() simply draws a cross into the rectangle that it should refresh, just to visualize the idea. test opens a window with scrollers in its borders that look almost identical to Workbench scrollers (the only difference is that the horizontal scroller starts at a slightly different offset from the window's left edge, respecting the window's left border which Workbench does not). The parameters necessary for this Workbench-look can all be found in the NewObject() taglist. By clicking on the close gadget repeatedly you can run through a number of test operations: Prior to that, resize the window to be smaller than the cross that is initially visible. Note that the scrollers indicate now that there is more `data� than what is displayed.

Click the close gadget. This changes the horizontal offset, causing the box contents to `scroll�. If the offset change conserves some old imagery, then VCB will ScrollRaster() it to its new place within the display box and only refresh those areas blanked out by the scroll. If the jump is too far, it simply runs a complete redraw.

Click again and again and again and again. The horizontal and vertical totals (the number units that the virtual plane extends horizontally and vertically) have changed to 3, 10, 20 and finally 30.

Click again. The program fetches the VCB semaphore and obtains it. Now moving the scroll bars or pressing the buttons has no visual effect. Note however that pressing a button will still move the associated scroll bar - the gadget is still alive! If you do something with the window, the display box contents will decay.

Click again. The program releases the VCB semaphore again and calls RefreshGList(). Now the gadget updates itself according to the new scroller positions. Releasing the semaphore does not trigger any display refresh. To get an immediate update, you need to call RefreshGList().

Click again and the program terminates.

 

MORE EXAMPLES

A real, complex VCB application is about to be publicly released: The View-Handler which is a AmigaDOS device that displays text written to it in a window, using a VCB. Look for it on anonymous ftp sites (probably first in Germany).

 

ADDITIONAL DOCUMENTATION

I'm sorry that at present I don't have the time to document the internal operations of VCB sufficiently. When looking at the sources, you will notice that VCB is build on another BOOPSI class named VCX for virtual co-ordinate axis. The scrollers of a VCB are VCX instances. Of course, this class could be useful for application programmers in its own right without the VCB framework. If you want to use it or have any other questions regarding VCB, please e-mail to me! I should be able answer within a week.

 

SEE ALSO

RKM Libraries, BOOPSI documentation.

 

BUGS

I'm presently integrating VCB into several applications of my own and will try to fix VCB bugs/problems as they occur, but since I'm focused on certain fields of applications, I may miss some important flaw. Therefore, I would appreciate reports of bugs, in particular (but not only) if they showed up in a more uncommon application of this stuff. I find this a very basic piece of GUI-technology and I want this to run as stable as possible!

 

CONTACT

Stefan Reisner, Aachener Stra�e 399, 5000 K�ln 41, Germany, internet sr@ph-cip.uni-koeln.de


 

Index

NAME
DESCRIPTION
USAGE
TAGS
VCBGA_ExposureHook (struct Hook *)
VCBGA_Interim (BOOL)
VCBGA_HScroller (BOOL)
VCBGA_VScroller (BOOL)
VCBGA_HBorder (BOOL)
VCBGA_VBorder (BOOL)
VCBGA_HUnit (ULONG)
VCBGA_VUnit (ULONG)
VCBGA_HTotal (ULONG)
VCBGA_VTotal (ULONG)
VCBGA_HOffset (ULONG)
VCBGA_VOffset (ULONG)
VCBGA_HSize (ULONG), VCBGA_VSize (ULONG)
VCBGA_XOrigin (ULONG), VCBGA_YOrigin (ULONG)
VCBGA_Semaphore (struct SignalSemaphore *)
CALLBACK
ARBITRATION
EXAMPLE PROGRAM
MORE EXAMPLES
ADDITIONAL DOCUMENTATION
SEE ALSO
BUGS
CONTACT

This document was created by man2html, using the manual pages.
Time: 18:58:37 GMT, November 11, 2024