home *** CD-ROM | disk | FTP | other *** search
- Aug 13, 1988
- Note:
-
- The version of Structure Browser in this archive is 1.3, which differs
- from the earlier release in supporting more structures (nearly all of
- Intuition, plus some structures from the Layers and Graphics libraries),
- and in supporting the TWM tiny window standard. The process for adding new
- structures to those known by SB is as described below.
-
- Nick Sullivan
- Chris Zamara
-
- Transactor for the Amiga
-
- -----------------------------------------------------------------------------
-
-
- (This article introducing Structure Browser appeared in The Transactor,
- Volume 7 Issue 6. It has been edited slightly to reflect Version 1.2 of SB.)
-
- The Transactor Structure Browser
- By Chris Zamara and Nick Sullivan
-
- - Your guided tour through the system
-
-
- With this program and the information given in this article, you will
- gain knowledge about your Amiga that you yearned for, but
- couldn't find. This knowledge will make you a better programmer, almost
- certainly making you more prosperous than you would have been otherwise.
- With all of your extra money, you can buy more expensive computer
- hardware and advance yourself even further.
-
- You will be successful, and
- that success will give you greater self-confidence. People will turn to
- you for advice and you will help out many others who would like to be as
- clever and successful as yourself. By helping these people, not only will
- you gain deep personal fulfillment, but you will become quite popular and
- well-liked, which certainly can't hurt your sex life.
-
- Since so many
- people will be looking up to you and following your advice, you will
- wield quite a bit of power in the computer community and in your business
- dealings in general. By feeling good about yourself, you will certainly
- get into better physical shape and will definitely live longer - maybe up
- to three hundred years!
-
- In short, reading this article and typing in the
- program at the end will give you knowledge, power, success and
- prosperity. It will improve your sex life and give you greater self
- esteem and a feeling of usefulness. You will be able to buy lots of
- expensive computer hardware, and fast cars as well if you wish. You will
- live longer.
-
- But the choice is yours - read this article and make those
- changes in your life, or skip past it and possibly never realize the
- enormous potential that you know is inside of you.
-
-
- * * * * * * * * * * * * * * * * * * * * * * * *
-
- If you want to learn more about the Amiga's system structures, or you'd
- like an easy way to look at vital data about programs while they execute,
- you'll make good use of the Transactor Structure Browser.
-
- If you read our Amiga programming article in the last issue, you learned
- how important the various system structures are, since they are the key
- to finding out about all entities known to the system, like tasks,
- screens, windows, gadgets and the like. Structures in the Amiga are the
- equivalent of a memory map on a single-tasking machine, since there are
- no fixed memory locations on the Amiga.
-
- The structure has a direct C-language implementation, but we can speak of
- a structure template (the definition of the structure) independently of
- a language. A structure is just the particular way that some data is
- grouped. For example, a structure called 'X' might be defined as a word,
- followed by a pointer to another structure 'X', followed by a pointer to
- a structure 'Y', followed by a long word. By knowing a structure's
- template and where in memory such a structure is stored, it is a simple
- matter for the system or an application program to extract the data in
- that structure.
-
- What kind of information can we find in various structures throughout the
- system's memory? Well, some interesting things are to be found, for
- example, in the Intuition-managed structures. With the program presented
- here, you'll be able to look at Screen, Window, and Gadget structures,
- among others. Information about any program in the system can be gained by
- looking at these structures, since everybody's windows, screens and gadgets
- are maintained in a kind of network where they can be accessed via pointers
- from other Screen, Window and Gadget structures. A pointer to the first
- Screen is all that is needed to find everything else, and that is found in
- the "IntuitionBase" structure, which, in turn, is found when the Intuition
- library is opened by a call to the OpenLibrary() function. (OpenLibrary()
- is in the Exec library, a pointer to which is found in memory location
- 000004, the only fixed location in the entire Amiga memory map. C-language
- startup code opens the Exec library.) All programs that use Intuition have
- their information in these structures, so through them you can learn
- things about any task currently running in the system.
-
- A screen structure contains everything Intuition needs to know about a
- screen, like its size, title, number of bit-planes, a pointer to its
- gadgets, flags describing what kind of screen it is, the colours it's
- rendered in, etc. The screen structure points to a window structure for
- the first window on the screen. A window structure has a pointer that can
- point to another window structure, so that all windows in a screen are
- linked together. If there is more than one screen in the system (unless
- you have an application running that opens its own screen, the only
- screen will be the Workbench screen), there will be a pointer in the first
- screen structure to the next screen; any number of screens can be linked
- together in this way. In a window structure you'll find the usual size
- and colour information, along with an IDCMPFlags variable which describes
- what messages Intuition is getting from that window.
-
- A pointer to the first gadget in a linked list of gadgets can also be found
- in the window structure. A gadget structure totally describes a gadget (a
- simple way to get input from the user through the mouse) - its position,
- size, type, imagery, etc. The gadget structure is set up by an application
- before the structure is submitted to Intuition, so the values within
- represent those that the programmer actually put into his code - in other
- words, a peek into a program's gadget structure can give some insight into
- how a program was written.
-
- Other structures of interest that are not implemented in Version 1.2 of
- Structure Browser: Image, Requester, Layer, Interrupt, MemChunk, MsgPort,
- Message, Task, VSprite, AnimOb. (Many of these structures, like Task and
- Interrupt, are difficult to monitor since the data within are constantly
- changing.)
-
- The key to finding the memory location of any structure is the Library Base
- structures. Every shared library ("graphics.library", "intuition.library",
- "layers.library", to name a few) has a library base structure that contains
- pointers to structures of interest to routines in that library. The
- structures form a kind of network, since you can reach structures through
- pointers in other structures. In this network can be found every bit of
- data that the system cares anything about; a direct link to the the
- system's state of mind at any given moment. If we know the definitions for
- the system structures (there are over a hundred of them altogether), we can
- snoop around and discover anything we wish to know about what the system
- knows. And in the Amiga, the system knows a lot, because application
- software has to go through the system for just about anything it wants to
- do.
-
- The Structure Browser Program
-
- The Structure Browser (SB from now on) makes it easy to snoop through many
- of the structures in the system. You start with a list of the library base
- structures; in the current version of the program, only IntuitionBase is
- available. To display the contents of the library base structure, just move
- the pointer to the library base name on the screen and press the left mouse
- button. The library base structure will immediately be displayed, showing
- each structure member's name (as defined in the standard Amiga header
- files) and its data type. In the case of the IntuitionBase structure, all
- members are pointers to other structures of importance; to display any of
- these, just click on its name as usual. This process can be repeated again
- in the new structure, to bring you to other structures of interest. You can
- always get to the structure you came from by clicking on the "Previous
- Level" gadget at the bottom left of the window. You can trace your steps as
- far back as you want, since the program works recursively (the number of
- levels deep you are is displayed in the heading at the top of the window).
- Structures that contain more members than will fit on the window show the
- first 16 members and display a gadget that says "(MORE)". You can go to the
- next page of structure members by clicking on (MORE), and go to the
- previous page by clicking on the "Previous Page" gadget. By going from
- structure to structure in this manner, it is easy to view information
- about programs that would be impossible to find out otherwise. For example
- - what kind of gadgets are being used in that neat commercial program? Are
- they gadgets at all? Did the programmer use a requester or a window for
- that prompt? Just by mousing around with SB, you can find it all out!
-
- The data type for each structure member is shown in the same way that the
- members are declared in the C header files (the appropriate header file
- must be compiled - using the #include statement - with any C program that
- wants to refer to a system structure). These data types are standard in
- Amiga code, because they are `typedefs' that are set up in the header file
- "exec/types.h". The basic types are:
-
- BYTE - signed 8-bit value (char)
- UBYTE - unsigned 8-bit value (unsigned char)
- SHORT - signed 16-bit value (short)
- USHORT - unsigned 16-bit value (unsigned short)
- LONG - signed 32-bit value (long)
- ULONG - unsigned 32-bit value (unsigned long)
-
- Pointers to any of the above are denoted as in standard C syntax, with an
- asterisk (*). For example, a pointer to a SHORT would be denoted by SHORT *
- in the type field. Structure members that are pointers to other structures
- also use the C syntax; a pointer to a `Window' structure, for instance, is
- denoted by `struct Window *'. A structure member that is an actual
- structure, not a pointer to a structure, has no asterisk, and no value is
- given (it is contained within the structure being viewed, whose address is
- already shown).
-
- Structure members that represent not pointers to other structures, but
- actual data that may be of interest, are displayed in various ways depending
- on their nature. These data can be simple numbers, like those giving a
- window's LeftEdge, TopEdge, Width and Height. The item of interest might be
- a byte, word or longword containing flags of some sort, like the flags
- indicating a window or gadget type. Or the data you're concerned with might
- just be an area of memory that contains a table of some sort or describes a
- graphic image. Simple data values, like LefEdge, etc. are shown in black on
- the SB window. Such structure members cannot be used to bring up any further
- information by pointing on them and clicking - nothing will happen if you do
- so. They are just what they appear; a number for you to see. The values in
- black are often just what you want to find out after getting to a structure
- of interest. When one of these values is used for containing flags of some
- sort, it is treated differently: you can click on it to get a list of what
- flags are set. An example might be a "smart refresh" window with sizing,
- close and drag system gadgets. The "Flags" member of such a window's
- structure, when selected, would show:
-
- WINDOWDRAG WINDOWSIZING WINDOWCLOSE SMART_REFRESH
-
- (Like the member names, the flag names are those defined in the standard
- header files used for C or assembler program development.)
-
- Another form of specialized output in SB is the hex dump. When a
- structure member is an array of values or a pointer to an area of memory
- like a bit-plane or image data, clicking on the member name causes a hex
- dump of the data to be displayed. If the data type is specified in the
- structure template, the data size is taken into account in the hex dump -
- the hex values are shown as either bytes, words, or long words.
-
- A Sample Tour
-
- On paper, the process may sound rather involved, but using SB is a breeze.
- Here's an example of how you could find out the type of gadget used by a
- program that is currently running in the system. Let's use as an example
- the editor on which this article is being written - we'll take a look at
- the structure for this program's `page up' gadget to see how it is set up.
-
- First, we have to run SB. That's not hard: type `sb' from the CLI. (or `run
- sb' if you want to keep the CLI available for launching other tasks while
- SB is running). SB will bring up a window that is the full width of the
- screen, but isn't full height, leaving a bit of the WorkBench screen
- visible at the top. On the window you will be prompted to select a library
- structure. Since only one choice is available in this version of the
- program, the decision isn't difficult: select "Intuition" by pointing with
- the mouse and clicking the left button. After clicking, a list of the
- "IntuitionBase" structure members will be displayed, with their types and
- values shown on the right. All members are pointers to the indicated
- structures, and the top two are parenthesized, meaning that those structure
- types are not available in this version of the program. To keep the
- magazine listing reasonably short, we only implemented a few key structure
- types; pointers to unimplemented structures are parenthesized, and clicking
- on them has no effect.
-
- Now, on with our travels to the gadget structure of interest. Since the
- program we're interested in has a window on the WorkBench screen, we must
- get to that screen's structure first. We can get there by clicking on the
- "ActiveScreen" member in the IntuitionBase structure, since the active
- screen - the one we're currently working on - is the WorkBench screen. One
- click, and up comes the first page of the structure members in the WorkBench
- screen structure. You can tell you've got the right screen by looking at the
- member called "Title"; to the right it should say "Workbench Screen". To see
- more screen members, you can click on the "(MORE)" gadget that has appeared
- at the bottom of the window, and then click on "Previous Page" to get back.
- The second member of the screen structure is called "FirstWindow", and it
- points to the first window structure in a linked list containing all windows
- on the screen.
-
- Click on "FirstWindow" and a window structure will be displayed. It may not
- be the window we're looking for, in fact it might be the window belonging
- to SB itself. The "Title" member will tell you what window you're looking
- at, since it will say exactly what is on the title bar of the corresponding
- window. You'll also notice other items of interest in this structure, like
- the window's dimensions and the flags set for the window. Try clicking on
- the "Flags" member to show the window flags. Even if you're not familiar
- with Intuition programming, the names of the flags should suggest their
- purpose. Now, to get to the next window structure in the list, just click
- on the first member of the window structure, the one called "NextWindow".
- You'll now have the structure for the next window displayed - continue
- chaining through windows like this until you get to the one you want. For
- our sample structure tour, we would stop when we got to the window
- belonging the text editor.
-
- Now that we've found the window structure we want, let's look for a pointer
- to the gadget list attached to the window. There's nothing like that on the
- first page, so click the "(MORE)" gadget to see more window members. About
- half way down is the member "FirstGadget", which points to a gadget
- structure (its type is `struct Gadget *', meaning a pointer to a Gadget
- structure). Click there, and up comes the first in a linked list of gadget
- structures for that window. By looking at the LeftEdge and Top variables,
- you can see the position of the gadget on the screen. To go to the next
- gadget structure in the list, just click on the first member, "NextGadget".
- You can chain through the program's entire gadget list this way, stopping
- when you wish to examine the flag variables "Flags, "Activation", or
- "GadgetType". GadgetType will tell you if the gadget is a BOOLGADGET
- (boolean), PROPGADGET (proportional), or STRGADGET (string). Eventually, we
- get to a gadget with its TopEdge at 20, and its LeftEdge at -16. Since the
- GRELRIGHT flag is set in the Flags variable, we know the LeftEdge value
- indicates that the left edge of the gadget is 16 pixels to the left of the
- window's right border. That's the `page up' gadget that we're looking for.
- We can examine the Gadget structure to see exactly how we could create a
- similar gadget in our own programs. (Using the same imagery as someone
- else's gadget in your programs might be considered a violation of
- copyright, but the current version of SB doesn't support Image structures
- anyway so there'll be no "Don't try this at home, kids!" warning here.)
-
- Structure Browser doesn't support all the system structures as it stands
- now - there are just too many and the program would fill the entire
- magazine. Rather, we have put in some of the more interesting Intuition
- structures and we plan on adding more for version 2.0 of SB, which will be
- found on The Transactor's first Amiga disk, and will be uploaded to
- Compuserve's AmigaForum. The program is designed so that it is easy to add
- new structures as you wish - if you have access to the "include" files for
- development (or the listings of them in the ROM Kernal manual), it should
- be easy for you to add whatever structures you're interested in to the
- program. Information about doing this is given later in the article. SB is
- public domain, so you're free to use and modify it as you wish; if you do
- add new structures, though, please use the standard Amiga member names and
- types exactly as they appear in the include files. We plan to see how far
- the SB concept of system structure browsing can be taken - a few ideas for
- enhancements are given later in this article.
-
- Applications for SB
-
- By now you've probably seen that SB is a great tool for learning about
- the Amiga's internal data structures. But there are actually quite a few
- good reasons to have SB around on your most-used disk - maybe even in the
- C directory of your usual Workbench or development disk.
-
- For one thing, SB makes a very handy reference to the structure templates
- themselves. It's easier to bring up SB and click to a structure than to
- look up that structure definition in the ROM Kernal manual. And if you
- don't have the manual, it's easier than looking through lots of include
- files. If you don't have the include files, it's the only way!
-
- SB can also be used as a debugging tool: if your program is acting
- strange, you can peek at Intuition's view of your windows, gadgets, etc.,
- to make sure they are properly set up and linked together the way you
- intended. You can look at these things at any time during your program's
- execution to see what happens when certain actions are taken; kind of
- like a trace, but only pertaining to the program's interaction with the
- operating system.
-
- Another benefit of SB is that you can use it to learn programming
- techniques by looking at how other applications have set up their
- structures to achieve certain effects. By investigating the structures of
- known system entities, you can see what effect certain flags and variables
- have on their behaviour. If you're curious about the tricks that some
- program is using, just take a browse through its gadgets and windows. For
- instance, did you know that Workbench uses a borderless, backdrop window
- that lies on the Workbench screen just below the screen title? We didn't
- either, until we used SB to look at the Workbench window structure. You
- can get some good ideas from other people's use of Intuition's resources.
-
- Future Versions of SB
-
- Our main goal for SB is to eventually have it encompass all system
- structures and flags. The program can be expected to grow in size
- considerably, but it will be worth it for a total map of the system's
- inner thoughts. But besides expanding in scope, there could also be more
- flexibility in the ways that lowest-level data types are displayed. For
- example, graphic data could be displayed not as a hex-dump, but as the
- actual image that it defines. Some values, like the mouse's X and Y
- coordinates that are found in a window structure, could be updated
- frequently to give readings that are always up-to-date. The hex dump
- should also display ASCII equivalents of the bytes. Perhaps a less
- immediately-implemented feature will be the saving of image and BitMap
- data to disk as IFF-format files. There should be a way to save any
- structure and its current values to a file as well, perhaps as C or
- assembler code for easy inclusion in your own programs. If anyone has any
- good ideas, let us know. Or better yet, implement them - we don't want
- all the glory for ourselves! (read: we don't want to do all the work
- ourselves!)
-
- Program Listing Notes
-
- The C source for SB is broken into several files, each with its own purpose.
- The mainline and general functions are in the file "sb.c". The intuition
- calls and all functions dealing with the program's user interface is in the
- file "sbio.c". The other files contain the individual routines to handle
- different structure types. "sbwindow.c", "sbscreen.c", and "sbgadget.c"
- contain the functions that handle the structures their names suggest.
- "sbgfx.c" handles the graphics library-related structures, RastPort and
- BitMap. In addition, a header file, "sb.h", contains various #define
- statements and a structure definition - it should be stored in a
- subdirectory called "header". All of these separate files can be compiled
- with Manx Aztec C using "make" and the makefile provided. The makefile takes
- advantage of Manx's pre-compiled header file capability to speed up
- compilation by not having to re-compile "intuition.h" in each of the six
- source files. If you are using this method, you can delete the #include at
- the top of each source file as indicated in the comment. For users of
- Lattice C, just compile all six files and link them normally - don't worry
- about the makefile.
-
- When entering the program, take extra care in entering the the `structdata'
- arrays in each structure print function. The first character of each member
- name is either a space, minus, or left parenthesis; it is important to use
- the correct one. Also, if you use the wrong data size constant (like putting
- in INTSIZE where it should be PTRSIZE), you will get bad results when you
- try to display that structure, or worse yet, a software error.
-
- NOTE: in version 1.2 (and later) of SB, a trap-handler is installed to
- catch CPU exceptions and eliminate most software errors.
-
- Program Notes
-
- SB is quite useful as it stands, but you may want to modify it to
- incorporate some other structures that you're interested in. If you do,
- here is some explanation of the program to help you out. The specifics are
- up to you; have a ball, hackers!
-
- The principle behind SB is very simple. A specialized function exists for
- each kind of structure. If a structure contains more members than will fit
- on one page, there is a function for each subsequent page. The function is
- passed a pointer to the structure (and an offset, in the case of
- multiple-page structures), and it prints the structure's members, types and
- values, then waits for input. (The actual output and input is handled by
- functions in "sbio.c", but more on those later.) Depending on the member
- selected by the user, an appropriate routine is called to print that
- structure's members and again wait for input. It may be that a routine
- calls itself, as when chaining through a linked list of like structures. In
- any case, each selection brings the program one level of nesting deeper,
- and the only way to go up a level is by the user clicking the "Previous
- Level" or "Previous Page" gadget, causing the return from a function.
- Besides functions that handle specific structures, there are the more
- general output functions that display hex dumps or flags - these are in the
- file "sb.c". The function used to tell the output function in "sbio.c" what
- to display is called put(), and is also in "sb.c" - it is called by all the
- structure output functions and is passed a pointer to the structure and a
- pointer to an array of special "StructData" structures. Setting up this
- array is the key to adding more structures to SB's repetoire.
-
- A "StructData" structure is defined in the file "sb.h" seen in the listing.
- It contains information that SB needs to know about a structure member: its
- name, type, print option, and size. The name and type are just pointers to
- strings for display. The print type is needed so that put() knows how to
- print the member's value - as a byte, short, or long, signed or unsigned, or
- as a string or pointer. See the put() function to see how the print codes
- are interpreted. The other member of a struct StructData, the data size,
- indicates the number of bytes used by the structure member. The constants
- BYTESIZE, INTSIZE, and PTRSIZE are defined in "sb.h" to specify the common
- sizes 1, 2, and 4. When the member is a structure (not a pointer to a
- structure, but an instance of the structure itself), use the SZ macro
- defined in "sb.h" to calculate the size of the structure, e.g. SZ(View)
- instead of sizeof(struct View).
-
- By looking at the functions PrWindow(), PrScreen(), and PrGadget() as
- examples, you should have no difficulty adding the functions to display
- system structures of your interest. If you add a new structure, you'll have
- to allow the user to select it from another structure by removing the
- parenthesis from around the member name and type. An opening parenthesis at
- the start of a member name instead of a space prevents that member from
- being selected by the user (doesn't make it a gadget). Just remove these
- parenthesis from all functions whose structure contains a pointer to your
- newly-implemented structure, and add a call to your new function in the
- SWITCH statement. Again, refer to the functions mentioned above for
- clarification.
-
- In the print function for any new structure you've added to the program,
- set up a static 'structdata' array of StructData structures (try saying
- that three times quickly!) as in the other functions. Members names should
- begin with a space for flags, arrays, or pointers to structures that
- SB can handle (i.e. anything for which a print function exists), a minus
- (-) for simple data elements that will be rendered in black and will not be
- selectable by the user, or a parenthesis for pointers to structures that
- are not supported by the program.
-
- The output of members to the window and the input of a response from the
- user is handled by the same function, GetChoice(). Selectable structure
- members are implemented as Intuition gadgets that have no rendering other
- than the associated IntuiText. An array of 16 IntuiText structures is set up
- to contain the text for each line printed to the window. An array of 16
- boolean gadgets, each pointing to a different IntuiText structure, is also
- declared. Gadget structures also exist for the "Previous Level" and
- "(MORE)" gadgets that appear on the window.
-
- When GetChoice() is called, it calls Redisplay() to put up the structure
- member names and build the required list of gadgets. Redisplay() first
- removes all existing gadgets except the first in the gadget list, the
- "Previous Level" gadget (BackGadg). Depending on the number of structure
- members to be displayed, up to 16 passes through a loop are made to either
- print an IntuiText or add the associated gadget to the gadget list. After
- the loop, the "(MORE)" gadget (MoreGadg) is added if there are more than 16
- structure members to display. Finally, a call to the Intuition function
- RefreshGadgets() displays the gadget text on the window. After Redisplay()
- has done it job, GetChoice() waits for an IDCMP (Intuition Direct
- Communication Message Port) event, which will signify that the user has
- selected a gadget. If the window close gadget was selected, CloseOut() is
- called to close up libraries and the open window, then call exit() to fix
- up the stack and return to CLI. if another gadget was selected, the
- gadget's ID is returned to the caller of GetChoice(). The IDs of the
- structure member gadgets are their ordinal values - 1 for the first and so
- on. The "Previous Level" gadget has an ID of 0, and the "(MORE)" gadget's
- ID is the constant MOREGADG, defined as 25 in "sb.h".
-
- To SB 2.0 ... And Beyond!
-
- As you've read, SB can be expected to expand well beyond its current
- capabilities. If anyone adds new structures, flags, or features to SB, we
- would be happy to incorporate the changes in the latest version for wide
- public-domain distribution. We will play `keeper of the source' and attempt
- to coordinate all improvements to maintain the latest, greatest SB which
- will be uploaded to Compuserve and other services, and included on our
- public-domain Amiga disks (probably available next issue).
-
- Meanwhile, have fun picking Intuition's brains with SB 1.2, and we'll see
- you next issue!
-