In this tutorial, you will create a simple GEOS application that draws text and demonstrates the basic components of a GEOS application. You'll learn how to compile and link the application and explore its source code using the Swat debugger.
1 Creating "Tutorial"
1.1 Setting Up Your Working Directory
1.2 Compiling Your Source Code
1.3 Starting the Emulator and Swat
2 Learning GOC
2.1 TUTORIAL.GP: Geode Parameters File
2.2 TUTORIAL.GOC: Source Code
3 Exploring With Swat
4 Source Code
The application that you'll be working on throughout this tutorial is called, appropriately enough, "Tutorial." In this section you'll create two files: TUTORIAL.GP and TUTORIAL.GOC. The .GP (or "geode parameters") file tells the linker how the application is organized; the .GOC file contains the actual source code. All GEOS applications require these two files.
The first step in creating your application is to set up your Working Directory where you will do all your private development. Because your application is called "Tutorial," you need to create a \TUTORIAL\ subdirectory in your Working Directory to hold the source files (see "Developing In Your Working Branch" for more information).
Now that you've created some source code, it's time to compile your application. First, you will need to create a Makefile and then run the "make" or compilation utility.
When you have completed these steps, your directory should contain some new files, including TUTORIALEC.GEO and your newly created GEOS executable or "geode." The "EC" in the name indicates that you've compiled the error-checking version of your application. The GEOS SDK tools have been set up with some optional compilation features to allow for error-checking code which is useful during development.
Once you've successfully compiled your code, it's time to start up the GEOS emulator and attach Swat, the debugger.
Swat version 2.1 (May 28 1997 11:43:32). Using the N9000v20 version of GEOS. SDK version: ntsdk30 Looking for "loader"...c:/pcgeos/N9000v20/Installed/Loader/Text/loaderec.sym Sourcing swat.tcl...Warning: Couldn't find the init file: c:\pcgeos\.swat done GEOS Attached Stopped in LoadGeos, address 0a50h:0007h LoadGeos: CLD ;DF=0 (loader:0) 1 =>
At this point, Swat is telling you that it has successfully established communications with the target emulator, has started the process of loading the GEOS kernel, and is now waiting for you to type in a command. Type
c
and press the <Enter> key to continue loading the GEOS emulator. The following will appear:
(loader:0) 2 => c Looking for "geos Eker"...c:/pcgeos/N9000v20/Installed/Library/Kernel/N9000DE MO_WIN32/geosec.sym Looking for "os2 Eifs"...c:/pcgeos/N9000v20/Installed/Driver/IFS/DOS/OS2/N90 00/os2ec.sym WARNING(os2::OS2Init): NOT_MONITORING_JFT Looking for "netware Eifs"...c:/pcgeos/N9000v20/Installed/Driver/IFS/DOS/NetWare /netwareec.sym Looking for "respondrElib"...c:/pcgeos/N9000v20/Installed/Library/Respondr/N9000 DEMO/respondrec.sym Looking for "rspwr Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Power/Rspwr/N90 00DEMO/rspwrec.sym Thread 1 created for patient geos Thread 2 created for patient geos Looking for "vidmem Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Video/Dumb/VidM em/vidmemec.sym Looking for "swap Elib"...c:/pcgeos/N9000v20/Installed/Library/Swap/swapec.sy m Looking for "disk Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Swap/Disk/diske c.sym Looking for "xms Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Swap/XMS/xmsec. sym Looking for "gdi Elib"...c:/pcgeos/N9000v20/Installed/Library/GDI/GenPC/N900 0DEMO_WIN32/gdiec.sym Looking for "gdiKbd Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Keyboard/GDI/gd iKbdec.sym Looking for "nimbus Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Font/Nimbus/nim busec.sym Looking for "stream Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Stream/streamec .sym Looking for "sound Elib"...c:/pcgeos/N9000v20/Installed/Library/Sound/N9000/so undec.sym Looking for "standarddrvr"...c:/pcgeos/N9000v20/Installed/Driver/Sound/Standard/ N9000DEMO/standard.sym Looking for "ui Elib"...c:/pcgeos/N9000v20/Installed/Library/User/N9000/uie c.sym Thread 0 created for patient ui Looking for "styles Elib"...c:/pcgeos/N9000v20/Installed/Library/Styles/N9000/s tylesec.sym Looking for "color Elib"...c:/pcgeos/N9000v20/Installed/Library/Color/N9000/co lorec.sym Looking for "ruler Elib"...c:/pcgeos/N9000v20/Installed/Library/Ruler/N9000/ru lerec.sym Looking for "text Elib"...c:/pcgeos/N9000v20/Installed/Library/Text/N9000/tex tec.sym Looking for "rtcm Elib"...c:/pcgeos/N9000v20/Installed/Library/RTCM/rtcmec.sy m Looking for "ansic Elib"...c:/pcgeos/N9000v20/Installed/Library/AnsiC/ansicec. sym Looking for "vp Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/OEM/vp_st b/vpec.sym Looking for "foam Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/Foam/foam ec.sym Looking for "foamdb Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/DB/foamdb ec.sym Looking for "contdb Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/Contdb/co ntdbec.sym Looking for "securitylib "...c:/pcgeos/N9000v20/Installed/Library/Foam/Security/ security.sym Looking for "rudy Espu"...c:/pcgeos/N9000v20/Installed/Library/SpecUI/Rudy/ru dyec.sym Looking for "simp4bitEdrv"...c:/pcgeos/N9000v20/Installed/Driver/Video/Dumb/Simp 4Bit/WIN32/simp4bitec.sym WARNING(rudy::OLAppEnsureIndicatorCorrect): RUDY_INDICATOR_NOT_FOUND_IS_GEOS_BOO TING_OR_SHUTTING_DOWN Looking for "spool Elib"...c:/pcgeos/N9000v20/Installed/Library/Spool/N9000/sp oolec.sym Thread 0 created for patient spool Looking for "mailbox Elib"...c:/pcgeos/N9000v20/Installed/Library/Mailbox/N9000/ mailboxec.sym Thread 0 created for patient mailbox Looking for "nonts Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Task/NonTS/nont sec.sym Looking for "contlog Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/ContLog/c ontlogec.sym Looking for "indicatoEapp"...c:/pcgeos/N9000v20/Installed/Appl/FApps/OEM/indicat o/indicate.sym Thread 0 created for patient indicato Looking for "faxfile Elib"...c:/pcgeos/N9000v20/Installed/Library/Fax/File/N9000 /faxfileec.sym Looking for "viewer Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/Viewer/vi ewerec.sym Looking for "clrfax Egeo"...(cached)...c:/pcgeos/N9000v20/Installed/Appl/FApps/ ClrFax/clrfaxec.sym Thread 0 created for patient clrfax Looking for "math Elib"...c:/pcgeos/N9000v20/Installed/Library/Math/mathec.sy m Looking for "ssset Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/OEM/ssset /sssetec.sym Looking for "scm Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/OEM/scm/s cmec.sym Thread 0 created for patient scm Looking for "ota Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/OEM/ota/o taec.sym Looking for "compose Elib"...c:/pcgeos/N9000v20/Installed/Library/Foam/OEM/compo se/composee.sym Looking for "accpnt Elib"...c:/pcgeos/N9000v20/Installed/Library/AccPnt/N9000/a ccpntec.sym Looking for "borlandcElib"...c:/pcgeos/N9000v20/Installed/Library/Math/Compiler/ BorlandC/borlandcec.sym Looking for "phone Eapp"...c:/pcgeos/N9000v20/Installed/Appl/FApps/OEM/phone/p honeec.sym Thread 0 created for patient phone Thread 1 created for patient indicato viewer exited. faxfile exited. clrfax exited. Thread 0 of clrfax exited 0 Thread 1 of indicato exited 0 Looking for "serial Edrv"...c:/pcgeos/N9000v20/Installed/Driver/Stream/Serial/s erialec.sym serial exited.
Each line that begins "Looking for..." indicates that the system is loading a geode (a GEOS executable) and that Swat is looking for its symbol information. Swat also tells you whenever it creates (or exits) a thread for any geode.
Now that the emulator is running with Swat attached, you need to send your source code to the emulator to run it.
Ctrl-C
in the Swat window. At this point, the Swat prompt should appear:GEOS Halted Stopped in TimerInterrupt, address 15a1h:c618h TimerInterrupt+274: STI (geos:0) 2 =>
send tutorial
to copy the application to the emulator:(geos:0) 2 => send tutorial Looking for EC version of tutorial... (cached)...Sending file c:\pcgeos\janice\Appl\tutorial\TUTORIALEC.GEO to WORLD \EXTRAPPS\TUTORIALEC.GEO Bytes transfered: 1788/1788 (100%) Send complete. (geos:0) 3 =>
run tutorial
to run the application:(geos:0) 3 => run tutorial Looking for application... Allocating AppLaunchBlock Force-queueing MSG_USER_LAUNCH_APPLICATION Waiting for message... Loading EXTRAPPS\TUTORIAL.GEO... Looking for "tutorialEapp"...c:/pcgeos/janice/Appl/Tutorial/tutorialec.SYM Thread 0 created for patient tutorial Spawning tutorial... (tutorial:0) 4 =>
c
to allow execution to continue on the emulator.
After you've followed these steps, your emulator should look like
the screen pictured below.
Figure 1: The "Tutorial" application screen. This is how your application will look after you type in the first pieces of code. Notice that it consists only of a blank viewing window and a "Close" button; later you will add code that displays text in this window. |
As you can see, your application consists of an empty window. In the next chapter, you will add procedural code that draws a text string in this window.
By typing in the contents of the source files (both the .GOC and .GP files), you've probably become a little familiar with GOC syntax. GOC is a proprietary superset of standard ANSI C. It supports C routines and functionality and adds its own set of keywords and special syntax. This section will cover basic GOC syntax, including the usage and meaning of various GOC keywords, by giving a line-by-line explanation of the code you entered.
The .GP file tells the Glue linker about an application's general organization. (You can get complete information about all of the possible fields in a .GP file by reading the GP File Keywords reference.) Let's take a look at the code in TUTORIAL.GP to find out what each line means.
name tutorial.app
The
name
field specifies the "patient" name by which Swat will identify the application. Swat thinks of each geode as a patient, so you'll see phrases in Swat like "patient died".
longname "Tutorial Sample Application"
The
longname
field is the name the system displays for this application. For example, if you press
Ctrl-F12
on the emulator (to list the applications in the "Extras" folder), you will see the
longname
for this application displayed. GEOS supports names up to 32 characters in length.
tokenchars "TUTO" tokenid 8
Each application has its own unique identifier to the system. This identifier is a special GEOS data type called a
GeodeToken
. A
GeodeToken
is a data structure comprised of two fields:
tokenchars
tokenid
GeodeTokens
do not conflict with those of other manufacturers. All sample applications, including this tutorial application, use a
tokenid
of 8; for your "real" applications, you should use your company's assigned Manufacturer ID. (Send email to
orders@geoworks.com to receive a Manufacturer ID.)type appl, process, single
The type
line tells Glue whether your geode is an application, a driver or a library.
Tutorial, like most GEOS applications, uses the following keywords:
appl
which tells Glue that this geode is an application;
process
which specifies that the geode should be run in its own thread;
single
which specifies that only one copy of the program may run at a time.Because GEOS is a multi-tasking or multi-threaded operating system, it allows more than one thread of execution to run at a time. This enables programs to run in the background. By specifying that your application has a process, you are requesting that it have its own thread of execution. If you were writing a library, you probably wouldn't want to give it a process, figuring that other geodes would be executing the library's code.
class TutorialProcessClass
The
class
line specifies which class will run the process thread. In this case, the
TutorialProcessClass
will be in charge of the process thread. (You will declare
TutorialProcessClass
in the
TUTORIAL.GOC file.)
appobj TutorialApp
The
appobj
line specifies the "application object" for this application. The application object is the interface between your geode and the rest of the system. (You will declare this object in your source file as well.)
platform n9000v20
Glue will use the
platform
line to make sure that your application doesn't rely on any geodes that aren't present on the GEOS device.
heapspace 3K
The
heapspace
line specifies the maximum amount of memory the application requires on the global memory heap. Note that the value 3K is a wild guess. Once your application is closer to completion, you can use Swat's
heapspace
command to find out how much heap space the application really needs.
library geos library ui
The
library
lines tell Glue which libraries to load for your application. All GEOS libraries are dynamically linked and loaded.
resource APPRESOURCE ui-object resource INTERFACE ui-object
The
resource
lines specify the blocks of memory that your application uses for objects. Breaking up an application into resources allows it to run more efficiently because the system will only load those resources it needs.
The ui-object
keyword signals that the UI thread should run the specified resource. Specifying a UI thread ensures that your application will
have
a UI thread and thus be dual-threaded: the process will run in one thread and UI objects will run in the UI thread. If you don't want the application to have two threads, use the keyword
object
instead of
ui-object
.
Now let's take a look at the source code in TUTORIAL.GOC. (For more information about GOC syntax, see the GEOS Programming chapter.)
@include <stdapp.goh> @include <foam.goh>
The first lines of code contain the
@include
directive. Note the '@' symbol. This symbol is used to denote GOC keywords and distinguish them from regular C syntax.
@include
behaves the same way as
#include
, except that the inclusion will take place when the GOC preprocessor is processing the source code. Generally, you
@include
.GOH files and
#include
regular .H files.
@class TutorialProcessClass, GenProcessClass; @endc;
The
@class
and
@endc
keywords mark the beginning and end of a new class definition. Here, you're defining
TutorialProcessClass
as a subclass of
GenProcessClass
, which means that
TutorialProcessClass
will inherit all the behavior of its parent,
GenProcessClass
.
@classdecl TutorialProcessClass, neverSaved;
Once you define the class, you need to declare it so that the system will know how to build objects of that class. To declare the class, you use the
@classdecl
keyword and because this is the process object, (a special object with no instance data), you also use the
neverSaved
flag. This flag tells the system that no instance data need be saved when the system shuts down.
@start AppResource;
The
@start
keyword defines a resource or block of memory. In this case, you're defining the APPRESOURCE resource. In the
.
GP file, you may recall that this resource holds objects, and that those objects will be run by the UI thread.
@object FoamSubApplicationClass TutorialApp = {
The first object to be declared in the APPRESOURCE resource is the application object,
TutorialApp
. In the .GP file, you specified
TutorialApp
as the application object in the
appobj
line. The application object is responsible for receiving and handling all sorts of system messages and notifications. This is a nontrivial task so the object will be of a class specifically set up to handle this task:
FoamSubApplicationClass
. (Note, on GEOS systems other than the Nokia 9000i Communicator, you would use a
GenApplicationClass
;
FoamSubApplicationClass
is a specialized subclass of
GenApplicationClass
.)
Because the application object provides important information to the system, it needs to live in its own resource; that way, the system can query the application object by loading only that resource which contains it.
The next set of fields contains the application object's instance data. Instance data are characteristics of an object, as defined by the object's class. (This should make more sense as you read on.)
GI_visMoniker = list{ @TutorialTextMoniker };
The GI_visMoniker
field specifies the object's label or name that appears to the user (not to be confused with
TutorialApp
, the name of the object).
The "visMoniker" part of the field name is short for "visual moniker." In GEOS parlance, a "visual moniker" is a text string or graphic used to identify an object to the user. This field is commonly set to a "list" of monikers; the system uses the moniker list to determine which text or graphic to display for your application.
GI_comp = @TutorialPrimary;
The
GI_comp
field specifies the children of a generic UI object. In this case, the only child of the
TutorialApp
object is the
TutorialPrimary
object (which you declare later). (For a detailed description of how objects keep track of their children, see the GEOS Programming chapter.)
Notice that both instance data field names begin with "GI_." The "GI_" stands for "Gen Instance." Because
GenApplicationClass
is a subclass of
GenClass
, it inherits the
GI_visMoniker
field from its parent. By Geoworks' naming conventions, instance data field names begin with the initials of their associated class followed by an "I" for "instance." Thus, any
GenApplicationClass
instance field names would begin "GAI_."
You may be wondering about the syntax for @TutorialPrimary
.
@TutorialPrimary
is actually a reference to the
TutorialPrimary
object. Object references have their own GEOS-specified type called an
optr
.
gcnList( MANUFACTURER_ID_GEOWORKS, GAGCNLT_WINDOWS ) =@TutorialPrimary; }
This line puts the
TutorialPrimary
object,which is the primary window of your application, on a General Change Notification (GCN) list so that it will receive notification when a system-level change has occurred. (For more information about GCN lists, see the gcnList entry in the GEOS Programming chapter.)
This completes the declaration of the
TutorialApp
object.
@visMoniker TutorialTextMoniker = "My Tutorial";
This line contains the string to which the
TutorialApp
's
GI_visMoniker
field refers. The
@visMoniker
keyword stores the string in a GEOS data structure set up strictly for monikers.
@localize "Program Title";
This
@localize
statement doesn't actually affect the program; it simply acts as a hint for someone translating the program to a foreign language. The ResEdit program displays the information in
@localize
statements when it prompts the translator to translate a moniker or string chunk. In this case, for example, when ResEdit prompts the translator to translate the string, "My Tutorial," it will display the string "Program Title" to assist with the translation.
@end AppResource
This line signals the end of the APPRESOURCE declaration.
@start Interface;
Here begins the next resource definition. This resource is called INTERFACE and will hold the basic UI gadgetry for your application.
@object GenPrimaryClass TutorialPrimary = {
The first object to be declared in this resource is
TutorialPrimary
, your application's primary window and an object of
GenPrimaryClass
.
GI_comp = @TutorialView, @TutorialCloseTrigger; }
The first instance data field is
GI_comp
, which specifies the children of
TutorialPrimary
.
@object GenViewClass TutorialView = {
The next object is a
GenViewClass
object called
TutorialView
; this object provides space on the screen for objects to draw themselves.
GVI_horizAttrs = @default | GVDA_NO_LARGER_THAN_CONTENT; GVI_vertAttrs = @default | GVDA_NO_LARGER_THAN_CONTENT; GVI_content = process; }
The
GVI_content
field specifies the top-level object which will appear in the view's drawing space. The
GVI_horizAttrs
and
GVI_vertAttrs
fields specify how the view should size itself in relation to the
content
object's size. Setting the flag GVDA_NO_LARGER_THAN_CONTENT
ensures that the view will be the same size as its content object.
Notice that the
GVI_...Attrs
fields also use the
@default
keyword.
@default
tells the system to expand to the default values for this field (as defined by
GenViewClass
); additional flags are ORed in with the single pipe ("|").
@object ComplexMonikerClass TutorialCloseTrigger = { ComplexMoniker = GenTriggerClass; CMI_topText = CMT_CLOSE;
The last object declared in the INTERFACE resource is
TutorialCloseTrigger
, an object of
ComplexMonikerClass
.
TutorialCloseTrigger
provides the "Close" button for your application.
The ComplexMoniker
instance data field allows
a sort of "multiple inheritance" in GEOS.
ComplexMonikerClass
defines behavior useful for
many Communicator UI object types. GenTriggerClass
defines behavior useful for buttons. GEOS multiple inheritance
is complicated (you can learn more about it in the
Goc syntax chapter); fortunately, it's easy to use it to set
up this button--we just set the ComplexMoniker
field
as shown. The CMI_topText
field supplies the text
by which the button will identify itself to the user: "Close".
GTI_destination = @TutorialApp; GTI_actionMsg = MSG_FSA_RETURN_TO_LAUNCHER;
The GTI_destination
and GTI_actionMsg
fields are GenTrigger instance data fields. GTI_actionMsg
specifies the message that gets sent when the user presses the "Close" button; GTI_destination
specifies the object who will handle the message. (We will discuss messages in more detail in the next chapter; suffice it to say that a message is a signal which may be handled by a set of procedural code defined for a class.)
HINT_SEEK_MENU_BAR; HINT_SEEK_REPLY_BAR; HINT_SEEK_SLOT = 3; }
These hints ensure that the button is placed on the right side of the screen so that it aligns with the buttons on the Nokia 9000i Communicator.
@end Interface;
This line signals the end of the INTERFACE resource definition.
Now that you've successfully compiled your application, you can use Swat to "debug" it. In the Swat window, press
Ctrl-C
to halt the emulator and gain control back in the Swat window. Something similar to the following should appear in your Swat window:
GEOS Halted Stopped in DOSIdleHook, address 277eh:1136h DosIdleHook+17 MOVE AX, 5760 (1680h) (geos:0) 5 =>
"GEOS Halted" indicates that Swat has frozen the emulator. The next two lines of Swat output indicate the address of the current internal routine that is executing. If Swat stopped in a public routine, the address would have been given in relation to the routine name and would have been more readable.
The last line indicates the thread that was executing (on the emulator) when you hit
Ctrl-C
. In this example, the zeroth thread associated with the GEOS geode (the kernel) was executing. To examine the thread associated with your application, type "tutorial." (Recall that this is the value you set in the
name
field of your
TUTORIAL.GP
file [without the suffix].) This tells Swat which thread to switch to.
(geos:0) 5 => tutorial [tutorial:0] 6 =>
The prompt indicates that you are now in the process thread of the
tutorial
geode. If you were in the UI thread, your prompt would read "[tutorial:1]." To change threads within a geode, simply type
:0
or
:1
.
Now try the
where
command to find out what this thread was doing when you stopped the system.
[tutorial:0] 6 => where * 1: near BlockOnLongQueue(), 153dh:c22ah 2: far QueueGetMessage(), 153dh:133ch ------------------------------------------------------------------------------ The event queue for "tutorial:0" is empty ============================================================================== [tutorial:0] 7 =>
These lines tells you that the tutorial thread is idling; it's waiting for a message or something to happen.
Next, use the
gentree
command to examine your application's generic UI object tree.
[tutorial:0] 7 => gentree *TutorialPrimary *TutorialPrimary::GenPrimary (@1, ^l5230h:001eh) "My Tutorial" *TutorialView::GenViewClass (@2, ^l5230h:0020h) ^143b0h:002ah(GenValueClass) (@3, ^15230h:002ah) *TutorialCloseTrigger(CM/GenTriggerClass) (@4, ^15230h:0024h) "Close"
[tutorial:0] 8=>
The
gentree
command prints out a list of all the objects in the tree, along with their class, object references, and monikers. For an example, let's look at the information for the
TutorialView
object:
You can refer to an object by a shortcut that Swat provides, namely, the "@number." To look at an object's instance data, use the Swat command
pobj
followed by the "@number" designation for the particular object. Try the
pobj
command with the
TutorialView
object.
[tutorial:0] 8 => pobj @2 *TutorialView{TutorialViewClass} (@5, ^l53e0h:0020h) master part: Gen_offset(131) -- TutorialViewInstance @6: {TutorialViewInstance (^h21472:426)+131} = { MetaBase Gen = { ClassStruct _far *MB_class = 3a57h:183ah (rudy::CommonUIClassStructures: :OLPaneClass) } LinkPart GI_link = { dword LP_next = 53e0h:0022h } CompPart GI_comp = { dword CP_firstChild = 53e0h:0028h } word GI_visMoniker = 0h word GI_kbdAccelerator = 0h byte GI_attrs = 2h byte GI_states = c0h PointDWFixed GVI_origin = { DWFixed PDF_x = {0.000000} DWFixed PDF_y = {0.000000} } RectDWord GVI_docBounds = { long RD_left = 0 long RD_top = 0 long RD_right = +1000 long RD_bottom = +1000 } PointDWord GVI_increment = { long PD_x = +20 long PD_y = +15 } PointWWFixed GVI_scaleFactor = { WWFixed PF_x = {1.000000} WWFixed PF_y = {1.000000} } ColorQuad GVI_color = { CQ_redOrIndex = fh, CQ_info = 0h, CQ_green = 0h, CQ_blue = 0h } word GVI_attrs = 810h byte GVI_horizAttrs = 98h byte GVI_vertAttrs = 88h byte GVI_inkType = 0h dword GVI_content = 4e60h:0000h dword GVI_horizLink = 0000h:0000h dword GVI_vertLink = 0000h:0000h } Variable Data: *** No Variable Data *** [tutorial:0] 9 =>
We certainly got a lot of data from that command!
*TutorialView{TutorialViewClass} (@5, ^l5230h:0020h)
The first line gives the object's class, shortcut and pointer information, similar to the output from gentree
.
The rest of the output consists of the object's instance data. For example:
GenViewDimensionAttrs GVI_horizAttrs = 810h
This line show which flags (of type GenViewDimensionAttrs
)
are set for the object's GVI_horizAttrs
instance data field.
You may recognize some of the instance data fields from your source code. Other fields you may not recognize because you didn't specify values for these fields, allowing the system to use default values instead.
With pobj
, you took advantage of another Swat
feature: command completion.
There is no "pobj
"
Swat command; the command's name is really
"pobject
." Because
"pobject
" was the only
Swat command that begins with p-o-b-j, Swat realized what you meant when you used
"pobj
."
Next let's try another exploratory Swat command:
[tutorial:0] 9 => classes TutorialProcessClass (@10, 42b8h:0040h), off ui::UserClassStructures::GenProcessClass [tutorial:0] 10 =>
The
classes
command lists all classes created by the application. To view the class hierarchy for a particular class, use the
cup
("class up") command.
[tutorial:0] 10 => cup @10 dgroup::TutorialProcessClass (@11, 42b8h:0040h) ui::UserClassStructures::GenProcessClass (@12, 30c4h:11e6h) geos::kcode::ProcessClass (@13, 153dh:a9d5h) geos::kcode::MetaClass (@14, 153dh:a8edh) [tutorial:0] 11 =>
As shown above, you can use the shortcut reference (the "@number") with the
cup
command or you can use the class name or reference address,
e.g.,
cup TutorialProcessClass
or
cup 42b8h:0040h
.
Some other Swat commands you might want to try out:
help
command provides documentation on Swat commands. Try
help stop
.
apropos
command allows you to search the Swat documentation by keyword. Try
apropos instance
.
heapspace
command tells you the amount of memory your application requires; you may recall that this value goes in your
.
GP file on the
heapspace
line. Because this value should reflect a worse-case scenario, it's important to run this command several times towards the end of development so that the figure is accurate.
handles
command scans the entire memory heap and returns information about all handles used by the application.In the next chapter, you'll begin by editing the source code, so prepare to switch over to your editor window.