Introduction

Initially I developed this library to speed up and enhance the graphic capabilities of PocketC (www.orbworks.com) by providing functions for drawing resource bitmaps and for handling multiple screen buffers. Over time, the library has evolved to include an assortment of functions. Generally, these functions either expose more of the built-in Palm OS functionality, or they perform computationally complex tasks which would be much slower if written in PocketC.

I've come to see PocketC as a kind of "glue logic". It's not the fastest programming language for the Palm OS, but it's extremely easy to use. The beauty is that with native libraries, its possible to make very fast running functions for PocketC. In using such libraries, the role of PocketC shifts from doing all the heavy computation work, to just "gluing" the various fast native library functions together. PocketC's automatic type conversion facilities make it a particularly good glue language. Another, big plus in my mind is PocketC's support of pointers, this allows for the construction all kinds of useful data structures. The result is a rather speedy, easy to use, and powerful language. I also particularly like PocketC's ability to compile on a PC desktop or on a PDA itself (I find it quite handy being able to code on the road!).

Joseph Stadolnik

Download

Click here to download Version 7.6.1: PToolboxLib.zip

The Pocket Toolbox web page: http://www.geocities.com/retro_01775/PToolboxLib.htm

Feature List

Legal Statement

I am making the iconized version of the Pocket Toolbox Library freely available to the general public. You may use it in a commercial product, but you may not sell the library.   You may freely include the library with your applications.  If you do use it in any publicly available commercial or freeware product, please give me (Joseph Stadolnik) due credit and please include a link to this web page AND the library version number in your documentation (http://www.geocities.com/retro_01775/PToolboxLib.htm ). The Pocket Toolbox Library comes with absolutely NO WARRANTY of any kind. As such, I cannot be held liable for any data loss or damage to a system resulting from the use of this library.

As for payment for my efforts for using the iconized library, I only request that you send me a complementary copy of any software that you publicly release which uses the Pocket Toolbox Library. My palm user name is "Joe Stadolnik" and my email address is jstadolnik@hotmail.com . Thanks!

Note: For a fee the library can also be embedded inside an application's .prc file, thus creating a complete stand-alone application.  Also, when the library is embedded, a developer may choose what features they want to include which usually reduces the library's memory footprint (the library is partitioned into different functional modules).  See the PRC Embedding section of this document for more details.

Installation

  1. Install the PToolboxLib761.prc file on your PDA (just as you would any other PalmOS application).
  2. If you are using the PocketC Desktop Editition (PDE) compiler copy the PToolboxLib.lib to the same directory as the pde.exe file.
  3. If you are using the PocketC PDA-based compiler you may also want to copy the Fctl.h file to a memo and hotsync it.

History

v7.6.1 6/29/2003
Fixed version bug GetPTVersion() (It was returning 0x754 for version 7.6.0.)
v7.6.0 6/23/2003
Added Copy(), an array copying function (has many-to-many, one-to-many, and swap copy modes).  Added Replace(), Strip(), and Translate() string manipulation functions.  Added FgetList() for getting all elements of a list.  Added Run() for launching apps and PocketC applets by name.  Added Feature() function for PalmOS feature access.  FsetText() & FgetText() now works on labels and titlebars (use id=0).  List draw handler can now draw horizontal spacers (see Fctl LISTHAND command).  Fctl BENABLE & BDISABLE both now accept an id of -1 argument which enables/disables all buttons.  Fevent() now traps FrmUpdateEvent, 5-Way navigator, and Sony Jog dial events.  New Fctl LISTLEN command for getting number of elements in a list.  New Fctl JOGMASK for disabling Sony Jog assist.  New  Fctl FIVEWAY command to enabling the 8 compass directions on 5-way navigator.  New plot() offset mode.  DBinfo() field count mode now returns a count based on the last non-none field position.  CopyBuf() speed up (now a hair faster then PocketC's bucopy() function).  Fixed HanDBase access error occuring on DBgetfield() if field was of of type none.  Fixed thick line drawing for points far off screen. Fixed BmpInfo() pointer bug.  Fixed OS5 FrevList() bug.  Fixes Sony OS5 font anomolies.
v7.5.3 1/15/2003
Fixes bug on NR70 when Sony(1,1) used.  Fctl HIDE/SHOW now works on scrollbars on pre-OS3.5 systems.
v7.5.2 1/14/2003
New SetScale() function for high-resolution graphics control on OS5 devices.  New Trunc() function.  Improved form ID checking on Fctl LOAD, Form(), and Dialog().  Fixed a nasty memory leak bug effecting FsetMany() on <OS3.5 systems.  Fixed GetDate/AddDate PDA based compile bug.  Fixed small font problem on Sony OS5 devices.  Handbase3 support is now fully functional (DBcreate now works for it).  Fixed two embedding library bugs.
v7.5.1 12/19/2002
The library can now be embedded inside applications.  Plug-in scheme to reduce the memory footprint of embedded libraries.  New improved Arc() function. Added SETGSI Fctl command for setting the GSI object state.  Sped up tri() function. Fixed bug in SaveBmp. Support for PocketC v5.x.x (apps larger than 64k).
v7.5.0 11/22/2002
Added DateBook access functions: GetDate(), AddDate(), and DelDate(). EHAND and REPEAT Fctl commands now return previous handler functions. New Vibrate() command for controlling the vibration engine on some devices. FsetMany/FgetMany now works on standard form buttons. Fevent() can now trap "button exit" events. New Fctl commands: BENABLE (button enable), BDISABLE (button disable), and BEXITID (for button exit event capture). Renamed line() to Line(), rect() to Rect(), and frame2() to Frame(). New (x,y,width,hieght) mode for Rect() and Frame() functions. Fixed empty resource list bug. Many OS5.0 compatability updates. Removed: SetAppPref(), GetAppPref(), serIR(), arc(), and polygon(), and tbitmap() functions. Added PTLreg() function for embeded library activation.
v7.4.4 8/20/2002
Fixed bug in OpenFontDb() occuring on app exit when the database contained no fonts.
v7.4.3 8/8/2002
Added AppPrefBytes() function. Fixed bug in GetPref() call. Fixed Size() bug for PDA compiled code. Fixed Note() bug occuring in mode 1 when field emptied.
v7.4.2 7/20/2002
Added Size() function for getting array size (Array() created only). If Field() height param is zero, automatically resizes it the current font height. Enhanced Array(): i) no more limitations on data structure size, ii) numerical prefixes to types now signify repeat count for that type (e.g. "3i4f2s"), iii) optional default integer value now must immediately follow type strings (e.g for a default of 4 do "i4"), and iv) if type string is less than data structure size, the types automatically repeat (e.g. "si,4" will produce "sisi"). Fixed bug in arc() function.
v7.4.1 7/4/2002
Fixed BmpInfo() bug.
v7.4.0 7/1/2002
Resource scrollbar support with field binding capability (see new EHAND Fctl command). New FgetMany() & FsetMany() functions for quickly moving array contents to/from matrices (tables) of fields and buttons. Added FaddList(), FdelList(), and FrevList() functions for better control of list objects. New Compress() function for de/compressing database records. New CmdBarAdd() function for adding icons to the command bar. Sort() can sort data structures referenced by pointers. Three new Fctl commands: EHAND (new event handler, supercedes REPEAT), SCROLLMODE (for scrollbar & slider control), and POPMENU. Zoom out mode capability added to CopyRect(). If no bitmap database is opened and FastBmp() is called, the application .prc is searched for the bitmap (using load-on-demand mode). Faster form cleanup. Added duplicate Id and post DRAW installation checking for dynamic form objects. Fixed offset bug in Query() function. Fixed empty resource list bug. Fixed field draw for FsetText when form is not visible. Fixed graph_on issue effecting hi-res mode on Handera devices. Plugged memory leak occuring with DBgetrec() calls on a HanDBase databases with zero records. Fixed OpenRsrcDb() re-entrancy bug. Fixed CopyBuf() bug occuring when forms are deleted. Partially fixed graffiti hide issue on Handera devices. Removed natural sort capability from Note() function.
v7.3.6 4/28/2002
Fixed bug in FsetText() effecting fields.

v7.3.5 4/25/2002

Added TRIGTIME, OBJTYPE, STBLSIZE, STBLPFX, and STBLGET Fctl commands. Line() now draws in hi-res when Sony hi-res drawing is enabled (mode 2). SetDepth(-3) returns current color depth. Fixed string reference count bug effecting Split() & DBgetrec() functions. Fixed a memory leak associated with resource forms which don't have titlebars.

v7.3.3 4/2/2002

Fixed form drawing problem on Handera devices.

v7.3.2 4/2/2002

Fixed form drawing problem on Sony hi-res devices.

v7.3.1 3/30/2002

Fixed Dbopen() bug effecting HanDBase databases. Fixed HanDBase date formatting bug. Fixed string handle bug in Insert() function. Fctl SETACTIVE and SETFORM commands now return ID of the current form.

v7.3.0 3/24/2002

HanDBase® and Pilot-DB database interface functions: DBcreate(), DBopen(), DBinfo(), DBsetrec(), DBgetrec(), DBgetfield(), DBrm(), and DBmoverec(). The Query() function will now returns the closest match on search misses through the countPtr pointer. Fixed resource form display issues with no-save-behind resource forms on pre-OS3.5 systems. Plugged memory leak with pop-trigger buttons on OS3.1. Fixed a bug in how silk buttons worked via HOOKSILK and HOOKMENU when a list was popped. PToolboxLib should now work if installed on a handspring springboard rom.

v7.2.3 3/9/2002

Added Sony() function for Sony high-res screen control. Force initial screen size to 160 by 160 on Sony high-resolution devices. Corrected x & y coordinate swap on FormBmp() function. Now if Fctl SETFOCUS command Id is zero, the focus is released. Slider objects in resource forms will always be hidden in pre-OS3.5 systems. FsetList() updated: new selection=-2 and num_items=-1 options. PocketC background event checking is now disabled upon first the Fevent() call when using PocketC v4.3.0+, this fixes the event loss problem previous encountered with Fevent().

v7.2.2 2/28/2002

Added Swap() function. Added new delimiters option for the Split() function.

v7.2.1 2/22/2002

Fixed PDA based compile problem with some new v7.2.0 functions. FormBmp() objects will now SHOW/HIDE in pre-OS3.3 systems.

v7.2.0 2/21/2002

Resource Form support (everything but scrollbars and tables). An function called OpenRsrcDb() for managing temporary resource databases. Three new dynamic form object functions: FormBmp(), GButton(), and Slider(). Five new Fctl() commands: POPHELP, POPALERT, POPDIALOG, GETTSTR, and SETFORM. Added Sort(), a general purpose array sorting function. Added Query(), a general purpose array searching function. Added three new string manipulation functions: Split(), Join(), and Insert(). Added Handera() function for managing features on Handera devices: hi-resolution display, grafitti area, screen rotation, form expansion, bitmap expansion, and font translation. The PalmPrint() function from the IRPrintLib is now included. OpenFontDb() now handles both pFNT and NFNT resource types in .prc files. HeapSize() function no longer compacts the heap. String allocation in Array() function is now x20 faster. General speedup: native library overhead reduced for all functions, resulting in a 5% to 40% speedup, depending on the function. Note() edit-index and edit-name modes now return the cursor position on exit. Added new copy-to-clipboard command bit to Note(). Fixed Note() crash bug with OS3.1. Grafitti stroke for Copy item in Note() pull-down fixed. Fctl/Fevent BINDX, BINDY, and BINDKEY crash bugs fixed.

v7.1.6 1/16/2002

Fix to OpenBmpDb bug.

v7.1.5 1/15/2001

This is a v7.2.0 pre-release. There is a lot more coming! OpenBmpDb can now open .pdb files. OpenBmpDb can now open bitmap resources in two modes: "load&lock" and "load-on-demand". FastBmp can now alternatively use resource Ids rather than the bitmap index. Portable keyboard support with new Fctl commands: HOOKTAB, HOOKLF, HOOKARROWS. Other new Fctl commands: FRAME (form frame control) , HELPID (help icon), LISTHAND (set list font handler), LISTUP (scroll list up), LISTDOWN (scroll list down), LISTPGUP (page list up), LISTPGDOWN (page list down), INCSEARCH (list incremental search enable), NEXTFIELD (move focus to next field), PREVFIELD (move focus to previous field), DIRTY (field touched?), and AUTOSIZE (button auto-size control with FsetText). If set before form object installation, the BINDX and BINDY variables will now contain the right and bottom boundaries of the last object installed - useful for object placement. Fevent now supports non-1 time values. Handera jog dial support (see Fevent).

v7.1.0 10/6/2001

Added new preferences functions: GetAppPref(), SetAppPref(), GetSysPref(), and SetSysPref(). Added more time/date functions: PickTime(), PickTime2(), and DateConv(). Added SpriteRectColl() for managing collisions between sprites. Renamed sprite() to Sprite(). Overhauled Sprite() function: 1) each sprite can have its own handler function, 2) new movement vectors, and 3) a background buffer of -1 will skip the save-behind feature (useful for multi-buffered graphics). Added AutoOff() to control auto-off timer. Added more form object control functions: FmoveObj() and FresizeObj(). Added two new Fctl() commands: OVISIBLE and LOAD. All form button types now resize correctly when FsetText() used. Form() now calls graph_on() automatically if not already called. Renamed time2str() to TimeConv(). Added more display modes to TimeConv(). Simplified Battery() function format. OpenBmpDb(), OpenBufDb(), and Note() now create databases of type "data", also for stand-alone apps the creator ID of these databases will be the same as the app. Fixed textbox() OS3.1 bug. Fixed Note() index zero bug. FsetList() can now have zero num_items. Fixed Handera bugs with SaveBuf(), RestoreBuf(), and CopyBuf(). Eliminated pre-OS3.5 emulator warnings for CopyRect() and other drawing functions.

v7.0.0 8/5/2001

Added new compression mode to SaveBmp(). Added transparency & compression parameter to BmpInfo(). Update to TransBmp() in how transparent bitmaps are handled. GetURL() can now strip HTML tags. OpenFontDb() can now read fonts from .prc files (applets). Added sprite(), FontHeight(), Battery(), PickDate(), textbox(), and time2str() functions. Dynamic form support, added: Form(), Dialog, FgetState(), FsetState(), FgetText(), FsetText(), Button(), Field(), List(), FsetList(), GSI(), Label(), Fevent(), Fctl(), and UIColor() functions. A second maze generation algorithm was added to MakeMaze(). Fixed a Note() sorting bug.

v6.0.1 2/16/2001

Fixed TransBmp() bug. Fixed a SetPixel() bug which showed up after drawing with custom fills. Enhanced ScrollRect(), can now force erase of vacated space.

v6.0.0 2/7/2001

Added Note(), a full blown data entry/viewing function (similar to the note capability Memo Pad, but with a 32k field size limit!). Fast record sorting (apha-numeric, natural, case-insensitive, & reverse) through the Note() function. Record string searching through the Note() function. Added GetURL(), a function for downloading web content. Added two new color depths: 4 and 16. Line width control has been added to the following functions: line(), lines(), frame2(), ellipse(), and plot(). Added fill options to lines(). Enhanced frame2(): now supports shadows. SetPalette() now can be used to change the color palette settings on color devices. Strings created by Array() are now defaulted to "". PickColor() now returns -1 if "exit" button is pressed. Fixed OS3.5 CopyRect() bug which occurred for screen depths of 1.

v5.3.2 12/26/2000

Fixed a bug in SaveBmp().

v5.3.1 12/19/2000

Fix bad rev number (was 5.21 for 5.30 release). Added new default value specification capability to Array().

v5.3.0 12/17/2000

Added InPoly(), a point-in-polygon function. Added HeapSize() for determining available heap memory. Array() now defaults values (int,char,float) to zero. Added new destination buffer capability to CopyRect(). Enhanced lines() function with the ability to specify an (x,y) offset for all points.

v5.2.0 11/11/2000

Added wrand(), a weighted random number generation function. Fixed a bug with determining the default screen depth.

v5.1.1 10/28/2000

OS2.0 is now supported (see Limitations section). A couple of bug fixes with: SaveBmp(), peek(), rotate & zoom modes for CopyRect() in certain sized custom buffers. Improving TransBmp() handling of 1 bit deep mask bitmaps. Plot() now doesn't need MathLib if radius is zero. OpenBmpDb() will now create a resource database if the one specified does not exist, and will set the backup bit on it.

v5.1.0 10/15/2000

Added three bitmap collision functions: BmpBmpColl(), BmpBackColl(), and BmpRectColl().

v5.0.1 10/11/2000

Fixed version 5.00 PToolboxLib.lib file. It was causing fatal emulator errors on some of the new 5.00 functions for code compiled with the PocketC Desktop Edition. Also fixed a potential memory bug in SaveBmp.

v5.0.0 10/6/2000

Added serIR() for low level IR capabilities. Added OpenFontDb() for importing font databases. Added SaveBmp(), RmBmp(), and BmpInfo() for working with resource bitmaps. Added Array() for creating multi-dimensional arrays and data structures. Added peek and poke for writing process registers directly. Added Backlight() for controlling backlight. Replaced FillLine() with enhanced line() functionality (mode 4). Replaced FillRect() with enhanced rect() functionality (mode 4). Added 50% gray (mode 2) functionality to rect(). Added mode field to OpenBufDb(). Enabled SetPalette() to work with OS3.5.

v4.1.0 9/11/2000

Added GetPref() for getting volume preferences.

v4.0.0 9/10/2000

Added FloodFill(), ellipse(), arc(), polygon(), plot(), and lines() functions. Revised modes for tri() function. Changed OpenBmpDb(), SaveBuf(), RestoreBuf(), OpenBufDb() to return 0 on failure rather than force reset errors.

v3.2.0 8/24/2000

Added tri(), a rectangle drawing function. Moved TriArea() functionality into tri function as a sub-mode. Added ClearBuf() function: clears current draw buffer, including title.

v3.1.0 8/19/2000

CopyRect() function format changed: "rotatation" parameter added, "dest_buf" removed (the destination buffer is now the current draw buffer). The RotateRect() function was removed from library (superceded by new CopyRect()). The "database" parameter was removed from the SaveBuf() and RestoreBuf() functions. OpenBufDb() and CloseBufDb() functions were added as a replacement. This change improved the SaveBuf() and RestoreBuf() speeds by 250% (they are now only 10% slower than CopyBuf()). The () speed was also improved by 25%.

v3.0.0 8/13/2000

Added 4 bit grayscale graphics for OS3.0+ machines. Added color graphics for Palm IIIc (see SetDepth() & PickColor()). Added vtone() function with volume & blocking/non-blocking control. New zoom parameter added to CopyRect() function. Added NoKeyEvents() function to disable downkey events. Added CustomBuf() and FreeBuf() functions for better scratch buffer memory management. New "chip corner" parameter added to MakeMaze(), also negative island values are now allowed. Added GetNumBmps() function which returns number of bitmap records in a resource database. SetFore(), SetBack(), SetTextColor(), and SetDrawBuf() now return previous state when called. GetOS() return value changed from base-10 to hex format. Added GetPTVersion() for determining the PocketToolbox library version.

v2.1.1 8/1/2000

Fixed SetPalette() bug which caused fatal exceptions.

v2.1.0 7/26/2000

Added functions for drawing in custom display patterns (SetPattern(), FillRect(), FillLine()). Added function for scrolling graphics (ScrollRect()). Added function for rotating and flipping graphics (RotateRect()). Added GetTicksPerSec() function which yields the number of ticks per second. Can now draw resource bitmaps from any .prc file which contains them.

v2.0.0 7/18/2000

Added functions for masked and transparent bitmaps (TransBmp() & tbitmap()). Added 4 bit grayscale support. Renamed SetGrayscale() function to SetDepth(), also field definitions changed (1=1 bit B&W graphics, 2=2 bit gray, 4=4bit gray). Added an additional mode field to the CopyRect() function which allows for different effects.

v1.2.0 7/12/2000

Added CheckKey() function to test status of hardkeys. Fixed SetPalette() bug… input variables were mixed up. Removed color field from SetPixel()… now uses foreground color.

v1.1.0 7/11/2000

Expanded 2-bit grayscale capabilities (added SetFore(), SetBack(), & SetTextColor() functions - these provide grayscale support for built-in PocketC graphics functions.

v1.0.0 7/7/2000

Initial Release

Files

PtoolboxLib761.prc - the library (current version)

PtoolboxLib753.prc - previous version of the library

PToolboxLib.htm - this document

PToolboxLib.lib - PocketC desktop edition file (put in PocketC desktop directory)

map_demo.c - a "drag about" map demo

toolbox_demo.c - a demo of many features

vtone_demo.c - a demo of the vtone function

test_bitmap.prc - a test bitmap resource database

multiform_demo.c - a demo showing how to use multiple forms

field_demo.c - a demo showing how to use forms & a simple menu

button_demo.c - a demo showing buttons and lists

database_demo.c - a demo showing how use the PToolbox database functions

fevent_demo.c - a demo showing how to trap pen & key events with Fevent().

list_demo.c - a demo showing how to use the FaddList, FdelList, & FrevList calls.

sprite.c - an example using the sprite() function to manage bitmaps.

graphics.c - Shows 3 different graphics techniques.

menu.rcp - A PilRC file for creating a resource menu (includes instructions)

speedopt.c - A collection of non-PToolbox speed optimizations for PocketC

Functions

Grayscale/Color Functions

int SetDepth(int depth)

Grayscale and color graphics is enabled through this function. The allowable depth values are as follows:

SetDepth depth definitions

Depth

Effect

Palette Size

OS Support

-3
Return current color depth
-
All OS

-2

Return color availability (1=color enabled)

-

All OS

-1

Return available color depths

-

All OS

0

Restore depth to original state.

-

All OS

1

1 bit graphics (black & white)

2

All OS

2

2 bit grayscale graphics (4 shades)

4

OS3.0+

4

4 bit grayscale graphics (16 shades)

16

OS3.3+ (EZ or later cpu's only)

5

4 bit color (16 colors)

16

OS3.5+ (color devices only)

8

8 bit color

256

OS3.5+ (color devices only)

16

16 bit color

256

OS3.5+ (some color devices only)

Be sure to call this function before any buffer related functions are called. Normally returns 1 on success and 0 on failure. If a failure occurs it means that the OS and/or hardware do not support the selected depth.

The higher the depth, the slower the graphics rendering. Thus, it is highly recommend that graphics intensive color applications take advantage of the 4 bit color mode, which is as fast as 4 bit grayscale mode. The SetPalette() function can be used to change the available 16 colors in 4 bit color mode.

The return value of mode "-1" indicates what depth modes available for a given device. If a depth mode is available, the bit corresponding to 2^(N-1), where N is the screen depth, will be set (e.g. A return value of 0x808b hex has bits 15, 7, 3, 1, and 0 set which indicates that depths 16, 8, 4, 2, & 1 are available). Note: 4 bit color requires a 4 bit depth (not a 5 bit depth).

Always call SetDepth before graph_on(). Always call graph_off before changing the depth (don't bother if graph_on has not been called yet). The one exception is when changing between modes 4 and 5, since they are both 4 bits deep no change in screen memory occurs. It is also a good idea to call FreeBuf(0) before a change of depth since any scratch buffers will then be the wrong size (don't bother if no scratch buffers have been opened, or when changing between depths 4 and 5)

For 16 bit graphics mode, the color palette is kept to 256 colors to keep heap memory usage down (a full 16 bit palette would use 262Kbytes of heap memory!). The palette will appear to be the same colors as in 8-bit mode, however the SetPalette() function can be used to change any of the colors to the various 65 thousand available.

int SetFore(int color)

Sets foreground color. Returns previous foreground color. Must be called after graph_on(). The permissible color ranges are as follows:

Color Range

1 bit graphics

0 to 1 (0=white, 1=black)

2 bit graphics

0 to 3 (0=white, 3=black)

4 bit graphics

0 to 15 (0=white, 15=black)

8 bit graphics

0 to 255 (see PickColor function)

16 bit graphics

0 to 255 (palette has 256 colors)

There is a useful color palette application available called McColors. This application can be used to determine the index number for a given color.

int SetBack(int color)

Sets background color. The color range is the same as the SetFore function. Must be called after graph_on(). When text and built-in bitmaps are drawn, this is the background color used. Returns previous background color.

int SetTextColor(int color)

Sets text color. The color range is the same as the SetFore function. This function only works in OS3.5 and up. For OS's less than 3.5, the foreground color is the text color. Must be called after graph_on(). Returns previous text color.

int PickColor()

This OS3.5+ function pops up a graphical palette interface for selecting colors and or grays. The value returned is the palette index of the color selected. This index can be used in the SetFore, SetBack, and SetTextColor functions. If the "exit" button is pressed, the return value will be -1. The current foreground color is initial selected color.

This function will work in all screen depth modes.

SetPalette(int gray0, int gray1, int gray2, int gray3) //for non-color devices

SetPalette(int index, int rgb_red, int rgb_green, int rgb_blue) //for color devices

For non-color devices: Sets 2 bit grayscale color palette. Acceptable values range from 0 to 7, where 0 is white and 6 & 7 are black, in between is gray. Gray0 is normally white, and Gray3 is normally black. Strangely, some hardware devices seem to have colors swapped around (e.g. the following format seems to work better on EZ processors: SetPalette(int gray0, int gray3, int gray1, int gray2)).

For color devices: Changes the color of the for the specified color index. The red, green, and blue RGB components each range from 0 to 255.

WARNING: Using this function with non-color roms on the POSE emulator causes "bus errors". However, on the real hardware no such error occurs. It's because a memory register is being written directly.

This function only works for OS3.0 and up. It also may not work on all hardware models (it definitely works on EZ processors).

Thanks to Astraware for the 2 bit gray adjustment source code.


Form Functions

The PToolbox library supports both resource forms and dynamic forms. Resource forms must be created beforehand using special tools and are either embedded in an applications .prc file or in a separate resource database. Dynamic forms differ in that they are created and populated with various objects by calling certain functions.

The library also provides a set of functions to easily manipulate the objects in both resource and dynamic forms. The FgetState, FsetState, FgetText, FsetText, FsetList, FresizeObj, and FmoveObj functions work on both resource and dynamic form objects. Most Fctl commands also work on both types of forms and objects.

Multiple forms are supported, as well as pop-up dialogs.

Resource verses Dynamic Form Comparison


Resource Forms

Dynamic Forms

How Created:

With 3rd party tools and embedded either in an application or in a separate resource .prc file.

From within a program itself by calling functions such as: Form, Dialog, Button, Field, List, etc. Convenient: no need to bother with resources.

Creation Control:

More form/object creation options available: GSI objects in all OS versions, title-less forms, button frame control on all OS versions, forms can be created with built-in help options and menus.

Fewer form/object creation control options.

Flexibility:

Rigid. The objects in a resource form cannot be changed from a PocketC program. Though they can be hidden, moved, and/or resized. Also, dynamic objects can be added to resource forms.

Fluid. Since dynamic forms are created on-the-fly, they can be easily configured to contain whatever objects are needed.

Load Time:

Very Fast.

Tends to be slower, especially when a large number of objects are being installed in a form.

Code size:

Small. The form resources do not consume code space. Minimal code support required.

Moderate. Forms need to be created and populated with library function calls. This consumes program space.

OS Availability

All OS versions.

OS3.0 minimum. Some form objects require OS3.5 (GSI, sliders, and graphical buttons)

Re-usability

Resource forms can be recycled in applications written with gcc, Codewarrior, or the like. This is useful should you decide to upgrade a PocketC application to another development platform.

Form re-use limited to PocketC.

Event Handling Speed:

Very Fast. Speed equal for resource and dynamic forms.

Caveats

There are a number of general rules and caveats for using working with resource and dynamic forms. Failure to follow these guidelines can result in undesirable program behavior (such emulator errors and system crashes).

  1. Dynamic forms and objects are only available for OS3.0 and up. Resource forms work in all OS versions.
  2. Always test your code on the POSE emulator with multiple debug ROMs (minimally OS3.1, 3.3, 3.5, and 4.0) (both can be obtained from http://www.palmos.com) In order to avoid POSE emulator warnings when running with pre-OS3.5 roms, uncheck the "UIMgr Data Access" box in the emulator "Settings->Debug Options" panel. Also, when running a ROM downloaded from a real device, uncheck the "Low Memory Access" box, there is a harmless emulator bug which causes warnings.
  3. Each form and dialog must have its own UNIQUE identification (resource) number. Each object within a given form/dialog must also have its own UNIQUE identification number. It is possible for multiple forms to have objects with the same ID numbers, however the objects are not "shared" across forms and must still be installed in each form/dialog. ID numbers 0 through 255 are reserved by the PToolboxLib. ID numbers of 10000 and above are reserved by the palmOS. Forms and dialogs should have IDs of no less than 3000 so as not to interfere with reserved PocketC forms.
  4. When using dynamic objects, be careful not to install an object with the same ID more than once per form. The results of doing so are unpredictable.
  5. Be sure not to create (via the Form or Dialog functions) or load (via the Fctl LOAD command) more than one form/dialog with the same ID number, unless the first form is freed (Fctl(FREE,x)). Having more than one form/dialog with the same ID number active will cause serious instability problems.
  6. The Form() function and the Fctl LOAD command (#10) will both internally call graph_on() if it has not been done so already. Do not call graph_on() after Form() or the LOAD command.
  7. Be sure to set the color depth (via the SetDepth function) and any special screen resolution (via the Handera or Sony functions) before calling the first graph_on, Form(), or Fctl LOAD call. If these settings need to be changed first call graph_off before doing so (see also the next caveat about graph_off).
  8. Calling graph_off() will delete all forms and dialogs.
  9. Creating a dynamic form and installing objects does not draw them. Likewise loading a resource form does not draw it. Use the Fctl "DRAW" command (#0) to draw forms and dialogs. In the case of dynamic forms, only call the DRAW command once all the desired objects have been installed.
  10. The Fevent() function must be used to capture button, list, and resource menu events. The Fevent() function will return the ID number of the button, list, or menu item selected. The built-in PocketC event functions (event, wait, waitp, getc, etc) will not capture form events correctly.
  11. If you get a "Form.c, line XXX, object not in form" error, you are likely trying to use some PToolbox form function with an ID number which has no corresponding object installed for it. If this error is observed when tapping on a field, the most likely problem is that a repeat handler function has been setup (see the REPEAT Fctl command (#103) and that the handler function is calling on an object which is not in the current form. Either disable the repeat handler for that form or modify the handler function.
  12. In pre-OS4.0 systems, if two forms objects overlap, the one installed first will always take precedence. In OS4.0+ systems, the object installed last will take precedence. The only way around this is to change the object installation order based on the OS version.
  13. If the draw buffer is changed, always return it (see SetDrawBuf) to 0 (the display) before calling Fevent() when a form containing objects is active. Failure to do this will likely result in system errors.
  14. Some built-in PocketC commands, notably the Basic I/O functions (puts, gets, setsd, getsi, setsm, alert, confirm, and clear), can "eat" button, list, and resource menu events.
  15. There is no way to delete individual objects, it's a whole form/dialog or nothing. However you can "SHOW" or "HIDE" individual objects easily. See the respective Fctl() commands (#2 & #3).
  16. There is a bug in the POSE emulator which effects the background restoration of forms and dialogs. When a form or dialog is exited, the emulator does not restore the background behind the form/dialog correctly. However, the background is correctly restored when running on real hardware.
  17. It is possible to draw on forms/dialogs, however it is best to do this after the Fctl "DRAW" call to prevent the form objects from drawing over existing graphics. Anything drawn on a form will not be saved if the form is switched, except in the next forms save-behind memory. However, you can use scratch buffers to save and restore the screen in these cases (see the SetDrawBuf() and CopyBuf() functions for more details).
  18. When calling the Fctl() "DRAW" command (#0), the state of the previous form is saved before the new one is drawn. In calling the Fctl() "FREE" command (#1), the current form is destroyed, and the saved background is restored… a potentially useful trick. Similarly, when the Fctl() "DRAW" command is used to change forms, the saved background is restored before the new form is drawn. To minimize the flashing effect of the restored background, use ClearBuf() to clear the screen before using Fctl "DRAW" to draw (non-dialog) forms.
  19. The first form created cannot be a dialog. It should be at least 160 by 160 pixels in size.
  20. At most one dialog should be shown at a time… in other words, a dialog should not be popped on top of another dialog, otherwise system errors will result when the dialog is exited.
  21. Take care when using the FsetList() command. If the array of strings is shorter than the num_items parameter, the function will read off the end of the array and unpredictable behavior will result (usually fatal errors).
  22. Stand-alone lists do not update correctly using the Fctl() "UPDATE" command (#8) in pre-OS3.5 systems. Use extra Fctl "SHOW" command (#3) to restore lists cleanly (though this may just be an emulator artifact?)
  23. The Fctl "SHOW" command (#3) will not effect stand-alone lists when the Id = -1 ("show all") mode is invoked. Stand-alone list must be "shown" separately (i.e. first "show all", and then show each stand-alone list).
  24. Calling the Fctl() "POPLIST" command (#200), alert(), confirm(), or any other built-in PocketC dialog will flush the undo memory (as triggered by the Fctl() "UNDO" command (#308)). This is a PalmOS "feature".
  25. The Palm OS does not support dynamic menus, tables, or scrollbars, as such they are not supported by the PToolboxLib. Tables in resource forms are also not supported.
  26. The standard dropdown PocketC menu with the stop option is not available for PToolbox created forms.
  27. All Forms, dialogs, and form objects, whether they be resource or dynamic in origin, consume dynamic heap memory. If your application runs out of heap space the PDA may crash. The Form(), Dialog(), Button(), Field(), List(), and GSI() functions will all return 0 if they fail to allocate the necessary heap space. Similarly, the Fctl LOAD command (#10) will return 0 if the form failed to load. Destroy unneeded forms with the Fctl() "FREE" command (#1) to free memory in the heap. Also, the HeapSize() function can be used to determine the amount of available heap memory.
  28. The color settings, as set with SetFore(), SetBack(), and SetTextColor(), get reset when switching to a different form (via Fctl(DRAW,id);).
  29. Don't call the alert() function when a less then full screen size dialog is active.

Resource Forms & Objects

Resource forms must be created with 3rd party tools, notably PilRC (freeware) for the desktop creation of resources, and RsrcEdit ($15) for onboard PDA resource creation.

PilRC (desktop)

Here is an outline of how to use PilRC to generate resource forms.

  1. The developer creates a .rcp file (with a text editor) describing what forms to create and how they should be populated. Each form and object is assigned a resource ID in the .rcp file. See the PilRC manual for information about writing .rcp files. There are also a number of desktop GUI editors, which can generate and/or edit .rcp files: PiBuilder (free), PilrcEdit (free, requires java), and PilotMag($20).
  2. The developer runs PilRC on a dos/shell command line passing in the .rcp file as an argument (e.g. PilRC rcp_file_name.rcp)
  3. PilRC generates one or more .bin (binary) files. These are the resources. The first four characters of the .bin file name indicate what type of resource it is (form=tFRM, menu=MBAR, string=tSTR, alert=Talt, bitmap=Tbmp, see PilRC manual for others). The next four digits of a binary files is the resource ID in hexadecimal.
  4. The .bin resource files should be now embedded within either your application's .prc file or into a resource database (see the OpenRsrcDb function for more details). Use the par utility to do the embedding: "par a app_name.prc *.bin" OR "par a resource_db_name.prc *.bin". Instead of wild carding all binary files with *.bin you can also list out one or more binary files explicitly, for example "par a app_name.prc tFRM0BB8.bin MBAR0BB9.bin".
  5. In your PocketC code, use the Fctl LOAD command (#10) to load a form. If the form is not the application .prc file, you must first use the OpenRsrcDb() function to open the .prc containing the form before calling the LOAD command. Use the Fctl DRAW command (#0) to draw the form. See the code sample below.
Note: If you create an application .prc file with the BuildPRC tool from Orbworks, your application will need to do an OpenRsrcDb() on itself in order to access any resources you embed within it. For example, if your application name is myapp.prc, it will need to internally do a OpenRsrcDb("myapp").

RsrcEdit (PDA)

Here is an outline of how to use RsrcEdit to generate resource forms.

  1. Create an empty resource database. Open RsrcEdit. From the menu create a new database. The type should be "data". Make sure the resource database checkbox is selected.
  2. Open the database. Select the new database from the selection list and push the "open" button.
  3. From the menu selected "New" and then "Form". For a standard form use the following options: top=0, left=0, width=160, height=160, Frame type=no frame, modal=no (yes for dialogs), usable=yes, save behind=yes, Def Btn=0, Mbar ID=id of resource menu to use (0 if none), Help ID=id of string resource (tSTR) to use (0 if none). Add objects form the pulldown menu as needed. When done, hit ok and give the form a new ID number (of 3000 or more). This is the ID number used to load and draw the form from PocketC. See the RsrcEdit documentation for more details on creating forms and form objects with this tool.
  4. Use the "PREVIEW" button in RsrcEdit to see what a created form will look like and how it will behave. The preview button is available on the form and alert resource windows.
  5. Use the "ADJUST" button in RsrcEdit to move the form object around manually. Select an object with the pen and move it with the hardkeys.
  6. Create Menu resources, string resources (for Help icons), and bitmaps (for form bitmaps and graphical buttons) from the main resource menu.
  7. In your PocketC code, first use the OpenRsrcDb() function to open the .prc containing the form. Then use the Fctl LOAD command (#10) to load a form. Use the Fctl DRAW command (#0) to draw the form. See the code sample below.
  8. When the application is completed use the par utility to embed the resource database into the application's .prc file, example: "par a app_name.prc rsrc_db_name.prc".
Note: If you create an application .prc file with the BuildPRC tool from Orbworks, your application will need to do an OpenRsrcDb() on itself in order to access any resources you embed within it. For example, if your application name is myapp.prc, it will need to internally do a OpenRsrcDb("myapp").

Resource Types

The supported resource types are: forms, menus, alerts (see the Fctl POPALERT command), strings (for help icons, also see the Fctl GETTSTR command), bitmaps (for form bitmaps and graphical buttons), and string tables (see the Fctl STBLSIZE, STBLPFX, & STBLGET commands). Table objects are not supported.

Re-Use

Most palm development platforms support resource forms. This means that should you ever upgrade a PocketC application to another platform (for better speed and program size) such as gcc or Codewarrior, you can use the same resource forms.

Use Prc2Pilrc (free, requires java) to translate the resources in a .prc into a .rcp file.

Also, resources can be extracted from a .prc with the par utility, and then embedded in another application. Extraction example: "par x app_name.prc". Embedding example: : "par a app_name.prc tFRM0BB8.bin MBAR0BB9.bin".

Tips

Sample Code

//Sample .rcp file for PilRC

//Create a form

//Note1: This form is actually a dialog (the model flag is set). This was

// done so that the help icon shows.

//Note2: The HELPID refers to the STRING resource in this file.

//Note3: The POPUPLIST resource is need to bind the LIST to the POPTRIGGER.

FORM ID 3000 AT (0 0 160 160)
NOFRAME
SAVEBEHIND
USABLE
MODAL
MENUID 4000
HELPID 5000
BEGIN
TITLE "Demo Form"
FIELD ID 3001 AT (0 16 80 80) UNDERLINED MULTIPLELINES MAXCHARS 4095 AUTOSHIFT
GRAFFITISTATEINDICATOR AT (135 150)
BUTTON "Done" ID 3002 AT (1 147 AUTO AUTO)
BUTTON "Status" ID 3003 AT (80 147 AUTO AUTO)
POPUPTRIGGER "Trigger" ID 3004 AT (110 20 AUTO AUTO)
LIST "First" "Second" "Third" "Forth" "Dog" ID 3005 AT (110 20 40 AUTO) NONUSABLE VISIBLEITEMS 3
POPUPLIST 3004 3005
END

//Create the menu for the form

//Note: ID's 10000-10007 are special OS menu items, the

//OS will handle them automatically.

MENU ID 4000
BEGIN
PULLDOWN "Options"
BEGIN
MENUITEM "Undo" ID 10000 "U"
MENUITEM "Cut" ID 10001 "X"
MENUITEM "Copy" ID 10002 "C"
MENUITEM "Paste" ID 10003 "P"
MENUITEM "Select All" ID 10004 "S"
MENUITEM SEPARATOR
MENUITEM "Keyboard" ID 10006 "K"
MENUITEM "Grafitti Help" ID 10007 "G"
MENUITEM SEPARATOR
MENUITEM "Save" ID 4001
MENUITEM "Compile" ID 4002
MENUITEM "Run" ID 4003
END
END

STRING ID 5000 "Here's some bogus help information."

ALERT ID 6000
CONFIRMATION
BEGIN
TITLE "Rash Status"
MESSAGE "Has the rash cleared up?"
BUTTONS "Yes" "No" "Maybe"
END

//resource_form.c

//Uses resources generated in above .rcp file

library "PToolboxLib"

include "Fctl.h"

main() {
OpenRsrcDb("rsrc_db_name");
Fctl(LOAD,3000);
Fctl(DRAW,3000);

while(1) {
switch(Fevent(1)) {
case 3002: return;
case 3003:
puts("Alert="+Fctl(POPALERT,6000)+"\n");
break;
}
}
}

Dynamic Forms & Objects

The following dynamic objects can be installed in dynamic forms and dialogs: standard buttons, pushbuttons (radio and stand-alone), checkboxes (radio and stand-alone), select boxes, pop-triggers, repeat buttons, stand-alone lists, drop-down lists, in-place text edit fields, labels, graffiti shift indicators, bitmaps, graphical buttons, and slider controls.

A tool called Cconvert has been developed by Chris Cason which can translate CEditor (Ccontrols editor) databases into PToolbox dynamic forms. This tool makes it possible to graphically design PToolbox forms.

Menu Handling in Dynamic Forms

There are three methods of handling menus with the PToolboxLib form functions:

Menu Method 1: Create the menu with dynamic form objects. A simple menu can be emulated with dropdown list installed in the upper left corner. Pop the list using the Fctl() "POPLIST" command (#200) when a menu event is received with Fevent().

More complex menus can be constructed with pushbuttons and stand-alone lists. These objects should be hidden after installation before the Fctl() "DRAW" call is made. When a menu event is trapped with Fevent(), unhide the appropriate pushbutton and lists objects. Check for events from the objects to control further behavior. When done handling the menu, hide the buttons and lists again and use the Fctl() "UPDATE" command (#8) to re-draw all the form objects.

Menu Method 2: Resource Menus. First a resource menu must be created and embedded within a .prc file. This can be done on a desktop using PilRC (to create it) and par (to embed it)(see the menu.rcp example), or use the onboard PDA toolRsrcEdit ($15). If the later method is chosen, the menu resource must created either in the application's .prc file or in a separate resource database (see the OpenRsrcDb() function for more details). Be sure to use a menu resource ID of at least 2000 to prevent clashing with PocketC's own menu resources. After Form() is called use the Fctl() SETMENU command #104 to activate the menu. Each selectable menu item much have its own unique object ID. Upon selection, the Fevent() function will return the menu item ID number. Graffiti shortcuts assigned to these menu items will also trigger events returning the ID number of their respective menu item

Menu Method 3: Ccontrols Menus. The Ccontrols package by Mario Schlesinger can be used to handle menus. The process is outlined below. The trick is to disable the form while the Ccontrols menu handling is active, otherwise selecting menu events can trigger the dynamic form objects.

  1. First trap the menu event with Fevent().
  2. Save the screen with saveg().
  3. Use the Fctl() "HOOKFORM" command (#110) to disable the form objects.
  4. Handle the menu as you would normally with Ccontrols, except use Fevent() rather than event().
  5. When done, restore the screen with restoreg(), then use "HOOKFORM" to re-enable the form objects
  6. Execute the menu command.

EHAND (Event Handler) Functions

Event handlers are special user defined functions which are allow users to access a number of advanced form event capabilities. The Fctl EHAND (#123) command is used to enable event handler functions. Only one event handler function can be active at any given time, and that function effects all forms. The capabilies provided by event handlers are as follows:

Every event handler function must have two input arguments: first an integer id field, second an integer type field. The handler function should return an integer. Generally, the id refers to the resource ID of the object the event is associated with (repeat button, slider, field, or scrollbar) and the type refers to the kind of event trapped (repeat, field enter, field change, scrollbar exit, scrollbar move, or command bar open).

The following table shows all the table types.

Event Handler Type
Type
Event Type
ID
Return Value Meanings
0
Repeat event (repeat buttons & slider controls)
Id of button or slider control
0 = reshedule next repeat event, >0 = number of ticks to wait before rescheding next event, -1 = don't reschedule
1
Field Enter (fields only)
Id of field
0 = do nothing. >0 = id of scrollbar to update
2
Field Change
Id of field
0 = do nothing. >0 = id of scrollbar to update. Note: Calling FsetText() on a field will trigger this event.
3
Scrollbar Exit
Id of scrollbar
0 = do nothing. >0 = id of field to update (not required if trapping scrollbar move events)
4
Scrollbar Move
Id of scrollbar
0 = do nothing. >0 = id of field to update.
5
Command Bar Open
unused
1 = show command bar, but inhibit field edit icons, 0 = show command bar with edit icons, -1 = suppress command bar. Note: CmdBarAdd() functions must be called from within an event handler to work.

To map a scrollbar to a field, simply return the ID of the desired scrollbar in response to field change (type 2) event. Conversely, to map a field to a scrollbar, return the ID of a field in response to a scrollbar move (type 4) event. Field enter (type 1) and scrollbar exit (type 3) can also be used for field-scrollbar mapping, but with differing behavior (see the type table for details).

The EHAND command supercedes the REPEAT Fctl command. REPEAT handler functions differ in that they don't have a type field. An event handler function can do everything that a repeat handler can do.

Below are two event handler examples, one simple, the other complex. NOTE: If you use RsrcEdit to create the form, be sure to check the "ScrollBar" checkbox for the field. If using PilRC, be sure to use the HASSCROLLBAR atrribute for the field. Failure to do this will result in the field not issuing field change events and the scrollbar not updating correctly.

//scrollbar_field_binding
//Shows how to do field-scrollbar binding
library "PToolboxLib"
include "Fctl.h"

#define FORM1 3000
#define FIELD1 3001
#define SCROLLBAR1 3002

int simpleHandler(int id, int type) {
//note: ignoring type field here
if(id==SCROLLBAR1) return(FIELD1); //bind field to scrollbar (triggers on event types 3 & 4)
else if(id==FIELD1) return(SCROLLBAR1); //bind scrollbar to field (triggers on event types 1 & 2)
}

main() {
OpenRsrcDb("resourceDB"); //open database containing a form with a field & scrollbar (user must create this database)
Fctl(EHAND,simpleHandler); //setup event handler
Fctl(LOAD,FORM1); //load the form
Fctl(DRAW,FORM1); //draw the form
while(1) Fevent(1);
}

//complex_handler
#define REPEAT1 3001
#define FIELD1 3002
#define FIELD2 3003
#define SCROLLBAR1 3004
#define CMDBAR1 3005
#define CMDBAR2 3006
#define BITMAP1 4000
#define BITMAP2 4001

int count;

int compleHandler(int id, int type) {
int fieldId;
switch(type) {
case 0: //repeat events
if(REPEAT1) {
count++; //count how many repeat events occur for fun
return(10); //slow down repeat rate for repeat button
}
break;

case 1: case 2: //field enter & change events
if(id==FIELD1 || id==FIELD2) return(SCROLLBAR1); //two fields share a scrollbar
break;

case 4: //scrollbar move events
fieldId = Fctl(GETFOCUS);
if(fieldId==FIELD1 || fieldId==FIELD2) return(fieldId); //update scrollbar
break;

case 5: //Command bar open event
//add two custom command bar icons
CmdBarAdd(CMDBAR1,0,BITMAP1,"erase");
CmdBarAdd(CMDBAR2,0,BITMAP2,"draw");
return(0);
}
}


Portable Keyboard Support

The Ptoolbox library provides portable keyboard support through the following mechanisms: 1) inter-field navigation via tabs (see the Fctl HOOKTAB command (#111)) and the up/down arrows keys (see the Fctl HOOKARROWS command (#113), and 2) carriage return completion (see the Fctl HOOKLF command (#112)).

Functions

int Fevent(int time)

Fevent() is similiar the built-in PocketC event() function with some additional features. Notably, the calculator and find silk button events can be trapped, as well as title bar pen-down events. If a form button is pushed, the ID of that button gets returned by this function (thus it is imperative that each form object has its own unique ID). Selecting an item within a stand-alone listbox will cause Fevent() to return the ID of that listbox. If a drop-down menu item (from a menu resource - see Fctl command #104) is selected, the ID of that item will be returned. If the a menu item has a Graffiti shortcut associated with it, entering the shortcut will cause Fevent() to return the ID of that menu item.

With a time value of 1, Fevent() will wait indefinitely for a user input event, otherwise Fevent will wait the specified amount of time before returning control back to PocketC. If the time value is zero, no wait will occur.

WARNING: On the first Fevent() call, PocketC's normal background event checking mechanism is disabled. This causes PocketC to run about 5% faster, but also prevents the user from exiting or even turning off their PDA if the app should get into an infinite loop which does not call the Fevent() or event() functions. If such a lock-up state is encountered, the only recourse is to perform a soft reset (which always works). An example of such a lock-up loop is: "while(1);". To avoid a lock-up problem simply code as follows: "while(1) Fevent(0);".

Repeat button events are not handled through Fevent(), instead they are trapped through a special repeat handler function (see the Fctl() command #103 "REPEAT").

When running in pre-OS3.5 systems, tapping the title bar will trigger a menu event (just as in OS3.5+). Title bar events can also be trapped by Fevent() by enabling "HOOKTITLE" mode (see Fctl() command #107)

Fevent return codes

0

Nil event (rarely occurs)

1

Key (Grafitti character) (the key value is returned through the variable (of type "char") defined with Fctl() command #102 "BINDKEY")(Note: This event type will only occur if a variable is bound.)

2

Pen Down (X & Y positions are returned through variables defined with Fctl() commands #100 "BINDX" and #101 "BINDY")")(Note: This event type will occur only if both X & Y variables are bound.)

3

Pen Up (X & Y positions are returned through variables defined with Fctl() commands #100 "BINDX" and #101 "BINDY")")(Note: This event type will only occur if both X & Y variables are bound.)

4

Pen Move (X & Y positions are returned through variables defined with Fctl() commands #100 "BINDX" and #101 "BINDY")

5

Page Up hardkey (also 5-way navigator Up)

6

Page Down hardkey (also 5-way navigator Down)

7

Hardkey 1 (Calander) (requires Fctl() command #105 "HOOKHARD")

8

Hardkey 2 (Address) (Calander) (requires Fctl() command #105 "HOOKHARD")

9

Hardkey 3 (ToDo) (Calander) (requires Fctl() command #105 "HOOKHARD")

10

Hardkey 4 (Memo) (Calander) (requires Fctl() command #105 "HOOKHARD")

11

Menu Silk button (requires Fctl() command #106 "HOOKMENU")

12

Home Silk button. (requires Fctl() command #108 "HOOKSILK")

13

Find Silk button (requires Fctl() command #108 "HOOKSILK")

14

Calculator Silk button (requires Fctl() command #108 "HOOKSILK")

15

Hotsync (Cradle) button (requires Fctl() command #109 "HOOKSYNC")

16
5-Way Navigator West (Left)
17
5-Way Navigator East (Right)
18
5-Way Navigator Select
238
5-WayNavigator North-East (Up & Right).  Requires FIVEWAY Fctl command (#127) to set to 1.  May not be available to all 5-way hardware.
239
5-Way Navigator South-East (Up & Right).  Requires FIVEWAY Fctl command (#127) to set to 1.  May not be available to all 5-way hardware.
240
5-Way Navigator South-West (Down & Left). Requires FIVEWAY Fctl command (#127) to set to 1.  May not be available to all 5-way hardware.
241
5-Way Navigator North-West (Up & Left).  Requires FIVEWAY Fctl command (#127) to set to 1.  May not be available to all 5-way hardware.
242
Sony Jog Up.  Requires Jog Assist Mask bit 0 to be set, otherwise event #5 will be generated.  See Fctl JOGMASK command (#126).
243
Sony Jog Down.  Requires Jog Assist Mask bit 1 to be set, otherwise event #6 will be generated.  See Fctl JOGMASK command (#126).
244
Sony Jog Push Repeat
245
Sony Jog Pushed Up
246
Sony Jog Pushed Down
247
Sony Jog Dial Push
248
Sony Jog Dial Release
249
Sony Jog Back Button.  Requires Jog Assist Mask bit 7 to be set.  See Fctl JOGMASK command (#126).
250
Button Exit. Triggered when a pen-down event occurs within a form's button frame, but the pen dragged out of the frame before being lifted. Use the Fctl BEXITID command (#402) to retrieve the ID of the button.

251

Line Feed. Only trapped when in HOOKLF mode is enabled (see Fctl command #112). Useful with data entry on portable keyboards.

252

Prev Field. Grafitti strait up-down stroke or Handera Jog dial down.

253

Next Field. Grafitti strait down-up stroke or Handera Jog dial up.

254

Carriage Return. (Handera jog dial pushed)

255

Titlebar Event (requires Fctl() "hooktitle" command #107 "HOOKTITLE")

>255

Button ID, List ID, or a drop-down menu item ID (from menu resources)

int/string Fctl(int command, int Id)

"Form Control". This is a multi-use function used to control many aspects of forms and dialogs.

The available command are shown in the table below:

NOTE: The define macros can be found in the Fctl.h include file.

Fctl commands

Command

Define Macro

Description

0

DRAW

Draw Form. Draw the form/dialog with the ID specified by Id. Use this command to switch between existing forms. The graphics form has ID 1500.

1

FREE

Free Form. Deletes a form or dialog. If the Id field is -1, all forms/dialogs are deleted. If If the current active form is specified, it is deleted and the last created form is returned to. Otherwise, the form specified via Id is deleted.

2

HIDE

Hide Object. Id field = ID of object to hide. If Id is -1, all objects in form/dialog are hidden.

3

SHOW

Show Object. Id field = ID of hidden object to show. If Id is -1, all objects in form/dialog are shown. Caveat: Stand-alone lists will not show when -1 is used, though they can be shown individually.

4

FORMID

Get ID. Returns the ID of the current active form. Id parameter is unused.

5

FVISIBLE

Form Visible? Return 1 is the specified form is visible, 0 if not, and -1 if the form does not exist.

6

EXIST

Object Exists? Returns 1 if a form object exists with the specified Id in the current form/dialog, 0 if not. Warning: Does not work on forms, only form objects.

7

SETACTIVE

Set Active Form. This function sets the form/dialog specified by Id as the active form. When a new form or dialog is created, the new form/dialog will become the active form. This function is provided so that the previous form can be reactivated so that the background saved behind the previous form can be restored properly. Generally, this command shouldn't be used unless absolutely needed. The feature can also be used to disable the current form (.e.g. temporarily switch to the graphics form… Fctl(SETACTIVE,1500). Be sure to use SETACTIVE again to return to original form). This command returns the form ID of the previous form.

8

UPDATE

Update Form. Redraws all the visible objects in the current active form. Id unused. Note: Stand-alone list do not update correctly using this command in pre-OS3.5 systems. Use extra Fctl "SHOW" command (#3) to restore lists cleanly (though this may just be an emulator artifact?)

9

OVISIBLE

Object Visible? Returns 1 if the object specified by Id is visible and 0 if hidden.

10

LOAD

Load Resource Form. Use this command to load resource forms. The Id parameter should the resource ID of the form to load. The form should either be in the application .prc file or in a separate resource database opened with the OpenRsrcDb() function. Use the Fctl() DRAW command (#0) to make the form visible. See the "Resource Forms" section in the "Form Functions" header for more information about using resource forms.

11

SETFORM

Sets Current Form. This command sets the current form. The Id value should be the ID of the form to set. This does not draw the form or make it active. This feature is useful for getting and changing a form which is currently not the active one. If you call SETFORM on a form, be sure to call it again to set the current form to be the active form (e.g. Fctl(SETFORM,oldform); //tweak/query old form; Fctl(SETFORM, activeform);). Like SETACTIVE, this a power-user command and generally should not be used unless absolutely needed. This command returns the form ID of the previous form.

12
OBJTYPE
Get Object Type. Returns the object type of the object specified by Id. The possible return values are as follows: 0=Field, 1=Button/Slider, 2=List, 4=Form bitmap, 8=Label, 13=Scrollbar.

100

BINDX

Bind X Position Variable. Id is a pointer to a global variable to hold the pen event X positions. (e.g. Fctl(100,&xpos);) When Fevent() returns a 2, 3, or 4, the X-position variable gets updated. Set Id to zero to disable X-position capture. If a pen event occurs within a button, the X position variable will be updated, allowing the user to determine where in a button the pen tap occurred.

101

BINDY

Bind Y Position Variable. Id is a pointer to a global variable to hold the pen event Y positions. . (e.g. Fctl(101,&ypos);) );) When Fevent() returns a 2, 3, or 4, the Y-position variable gets updated. Set Id to zero to disable Y-position capture. If a pen event occurs within a button, the Y position variable will be updated, allowing the user to determine where in a button the pen tap occurred.

102

BINDKEY

Bind Key Variable. Id is a pointer to a global variable (of type "char") to hold the last graffiti key character (e.g. Fctl(102,&key);) When Fevent() returns a 1, the key variable will get updated. Set Id to zero to disable key capture.

103

REPEAT

Set Repeat Handler Function. Id is a pointer to a user defined function which is automatically called when either, 1) a repeat event occurs (see repeat buttons in Button() function), or 2) the cursor moves to a different text field. The repeat function should have one input argument, an integer, which will hold either the ID of the repeat button or the new field. The value the user returns from the repeat function determines the number of additional ticks to wait before the OS issues the next repeat event (thus the repeat rate can be controlled). If the handler function returns a -1, the repeat event chain is terminated (a new repeat event is not scheduled). Set the Id to zero to disable the repeat handler. Returns the previous REPEAT handler function.

104

SETMENU

Set Resource Menu. Binds a resource menu to the current form. The resource ID of the menu specified in the Id field. See "Menu Handling" section in "Form Functions" introduction for more information. If an Id of 10000 is specified, a built-in edit menu will be used. The default PocketC graphics menu is 1200. The SETMENU command should be called after all the necessary objects have been installed in a form, but before the first DRAW command.

105

HOOKHARD

Hook Hard. If set to 1, enables the 4 hardkeys to be trapped by Fevent(). Set to 0 to disable hookhard mode.

106

HOOKMENU

Hook Menu. If set to 1, enables the menu silk button to be trapped by Fevent(). Set to 0 to disable hookmenu mode.

107

HOOKTITLE

Hook Title. If set to 1, pen-down events occurring in the title bar will be trapped with Fevent() and no menu event will occur. Set to 0, to disable hooktitle mode.

108

HOOKSILK

Hook Silk. If set to 1, enables the home, find, and calculator silk buttons to be trapped by Fevent(). Set to 0 to disable hooksilk mode.

109

HOOKSYNC

Hook Sync. If set to 1, enables the hotsync (cradle) hardkey to be trapped by Fevent(). Set to 0 to disable hooksync mode.

110

HOOKFORM

Hook Form. If set to 1, all form objects are disabled (they will not respond to user input). Set to 0 to re-enable the form objects. Only use Fevent times of 1 when this mode is enabled, otherwise it will not work all the time. Use the SETACTIVE command to disable a form if non-1 Fevent times are desired.

111

HOOKTAB

Hook Tab. When enabled, causes tab characters to move the field focus to the next field in the form (e.g. like the NEXTFIELD Fctl command). This is useful for portable keyboard support. Id=1 enables, Id=0 disables.

112

HOOKLF

Hook Line Feed. When enabled, causes line feeds to be trapped by Fevent(). Useful for portable keyboard support (e.g. used as a form complete indicator). Id=1 enables, Id=0 disables.

113

HOOKARROWS

Hook Up/Down Keys. When enabled, the up/down keys on portable keyboards can be used to navigate to other fields (e.g. similar to the NEXTFIELD and PREVFIELD Fctl commands, but automatically). Id=1 enables, Id=0 disables.

114

FRAME

Form Frame. Sets the frame style for a current form or dialog. The format for Id is as follows: bits[15:8]=corner diameter, bit[4]=3D mode, bits[3:2]=shadow width in pixels, bits[1:0]=frame width in pixels. This feature is primarily useful for dynamic forms. The frames on resource forms can be specified internally and don't require this call.

115

HELPID

Setup Help String. Installs a help icon in the current dialog/form. The Id value must be the resource ID of a string resource (of type 'tSTR') included in the applications .prc file or in a resource database (see the OpenRsrcDb function). Use either RsrcEdit OR PilRC & par to create this string resource. The contents of the string resource will show up in the "Tips" form when the help icon is tapped. The graphics for this function only displays correctly if the used in a dialog (forms with the modal bit set), though it still works for normal forms, it just won't show the help icon in the upper right hand corner. Also, the dialog should be the full screen width and be bottom justified (resting on the screen bottom) (e.g. x=2, y=122, width=156, height=36. Note the dynamic dialog frame thickness (2 pixels) actually makes it 160 pixels wide, so this dialog is 160x40 in size and sits at the screen bottom). This is primarily useful for adding a help icon to dynamic forms. Resource forms can have a help ID string bound internally and don't require this call.

116

POPHELP

Pop Help Dialog. Pops a help information dialog. The Id value must be the ID of a string resource (tSTR type) located in either the application's .prc file or in a separate resource database (see the OpenRsrcDb function for more details).

117

POPALERT

Pop Alert. Displays an alert resource. The alert resource should be created with either RsrcEdit or PilRC and places in either the application's .prc file or in a separate resource database (see the OpenRsrcDb function for more details). This function gives the user access to the all four alert types: information (the one shown by the alert() call), warning, confirmation, and error. The dialog exits when a user presses a button (the dialog must have a button). The index of selected button is returned. The first button in the dialog has an index of 0, the next has index 1, and so on.

118

POPDIALOG

Pop Dialog. Displays a dialog (any form with the modal bit set). The Id refers to the ID of the dialog (can be resource or dynamic). The dialog exits when a user psonyresses a button (the dialog must have a button). The ID of the selected button is returned. This is a convenient way to handle dialogs (though you can also handle them with DRAW command). Before using this command, the dialog should have either of been created dynamically with the Dialog() function or loaded (if a resource form) with the Fctl LOAD command (#10).

119

GETTSTR

Get String Resource. Return the string contained in a string resource. The string resource should be created with either RsrcEdit or PilRC and places in either the application's .prc file or in a separate resource database (see the OpenRsrcDb function for more details).

120
STBLSIZE
String Table Size. Returns the number of element in the specified string table (not including the prefix). The Id refers to the resource ID of a string table resource contained within either the application's .prc file or in a separate resource database (see the OpenRsrcDb function for more details). Use PilRC to create the string table resource.
121
STBLPFX
String Table Prefix. Returns the prefix string of the specified string table. The Id refers to the resource ID of a string table resource located in either the application's .prc file or in a separate resource database (see the OpenRsrcDb function for more details). Use PilRC to create the string table resource.
122
STBLGET
Get String Table. Returns the pointer to a dynamically created array of strings containing the contents of a string table resource (not including the prefix string). The Id refers to the resource ID of a string table resource contained within either the application's .prc file or in a separate resource database (see the OpenRsrcDb function for more details). Use PilRC to create the string table resource. Use the free() function to free the string table array when done with it.
123
EHAND
Setup Event Handler Function. Binds an event handler function. The Id must be a pointer to the handler function. See the EHAND Functionssection. Returns the previous EHAND event handler function.
124
POPMENU
Menu Pop. Enqueues a menu trigger event. The next time Fevent() is called the dropdown menu of the current form will activate.
125
SCROLLMODE
Set Scroll Mode. This command controls how the FsetState() function works on scrollbar and slider objects. The Id specifies the mode: 0 (default)=position value, 1=minimum value, 2=maximum value, and 3=page size value. For example, if you want to set the maximum value of a scrollbar object with an id 4000 to 100, do: Fctl(SCROLLMODE,2); FsetState(4000,100);
126
JOGMASK Sony Jog Dial Assist Mask Control.  This command allows the jog dial assist on Sony devices to be disabled.  Notably, this allows for jog-up, jog-down, and back button events to be captured.  Note: The jog assist normally translates jog-up and jog-down events events into page-up and page-down events.  By masking the jog-up/down events these events can be captured separately from the page keys.  The bits are as follows: 0=JogUp, 1=JogDown, 2=JogPushedUp, 3=JogPushedDown, 4=JogPush, 5=JogRelease, 6=JogPushRepeat, 7=JogBack.  A "1" for the bit indicates that the the jog assist is disabled for that particular event type.  For example: Fctl(JOGMASK, 0xff);//will disable jog assist entirely
127
FIVEWAY
5-Way Navigator Control.  Sets how the Fevent() function handles 5-way navigator events.  The Id field specifies the mode.  There are two modes: 0=four direction mode (default)(N-S-E-W ), 1=eight direction mode (N-NE-E-SE-S-SW-W-NW).  Note: Some devices may not support 8 direction mode.  See the Fevent() event tables for 5-way navigator return values.

200

POPLIST

Pop List. Cause a dropdown list to pop. After the user makes a list selection, the list will disappear. Useful for making custom triggered pop-up list. The index of the selected list item is returned. If no item is selected a -1 is returned. This command should only be used on downdown lists. Do NOT use it on list bound to trigger buttons and stand-alone lists.

201

LISTHAND

Enable List Handler. Enables a special drawing handler for the specified list (Id = list number). When active the list handler allows the font in list items to be changed and for overline seperators via special escape codes. The font escape code consist of four characters "`fXX", where XX is the hex value of the new font.  Custom fonts can be used (see the OpenFontDb function for more details).  The overline escape codes are as follows: "`s1" = solid overline, "`s2" = dotted overline.  The list items themselves must contain the control codes.  An overline control code can occur anywhere in the text of list entry (putting them at the end is useful when sorting the list).  When an overline is enabled for a list item, a horizontal line is drawn above the text (Note: the list's scroll arrows will always appear on top of overlines, nor can the overline on the very top item be suppressed).   Use only on stand-alone lists.

202

LISTUP

Scroll List Up. Scroll the specified list (Id = list number) up one line.

203

LISTDOWN

Scroll List Down. Scroll the specified list (Id = list number) down one line.

204

LISTPGUP

Page List Up. Page the specified list (Id = list number) up.

205

LISTPGDOWN

Page List Down. Page the specified list (Id = list number) down.

206

INCSEARCH

Enable List Incremental Search. Id specifies the list to enable incremental searching on. Works only on sorted pop-up lists. Allow the user to enter up to 5 characters. The list automatically scrolls to the closest match. If a match is found, that item is automatically selected.

207
LISTLEN
List Length.  Returns the number of elements in a list.  Id specifies the the list to query.

300

SCROLL

Scroll Field. Scrolls the field with the focus (cursor) a number of lines. The Id parameter determines the number of lines to scroll. A positive Id value will scroll forwards, negetive value will scroll backwards. Returns 1 if the field cannot be scrolled further in that direction, or 0 is the scroll was successful.

301

SETFOCUS

Set Field Focus. Sets to focus (cursor) to the field specified by Id. If the Id is zero, the focus is released (no object will have the focus).

302

GETFOCUS

Get Field Focus. Returns the ID of the field with the focus (cursor). Id unused.

303

SETFONT

Set Field Font. Sets the font of the field with the focus (cursor) as specified in the Id parameter.

304

GETFONT

Get Field Font. Returns the font of the field with the focus (cursor). Id unused.

305

COPY

Field Copy. Copies selected text to the clipboard. Id unused.

306

CUT

Field Cut. Copies selected text to the clipboard and removed the selected text from the field. Id unused.

307

PASTE

Field Paste. Inserts the contents of the clipboard at the cursor (insertion point) position. Id unused.

308

UNDO

Field Undo. Undo the last text change. Id unused. WARNING: Calling the Fctl() "POPLIST" command (#200), alert(), confirm(), or any other built-in PocketC dialog will erase the undo memory.

309

INSERT

Insert Text. Insert text into at the cursor (insertion point) position. The Id field must be a pointer to a string. (e.g. Fctl(309,&text);)

310

GETSEL

Get Selected Text. Returns currently selected text. Id unused.

311

DELSEL

Delete Text. Deletes the currently selected text.

312

SETINS

Set Insertion Point. Sets the cursor position. The Id parameter specifies the byte position of the cursor.

313

GETINS

Get Insertion Point. Returns the byte position of the cursor (insertion point).

314

SELTEXT

Select Text. Selects text in the field with the focus. The text selection starts with the insertion point (cursor position). The Id parameter indicates the number of characters to select.

315

SELALL

Select All Text. Selects all text in the field with focus.

316

GETSELBEG

Get Select Beginning. Returns the starting byte position of selected text. Id unused.

317

GETSELLEN

Get Select Length. Returns the length in characters of the selected text. Id unused.

318

GRAFFITI

Graffiti Reference Pop. Pop the Graffiti help reference. Id unused.

319

KEYBOARD

Keyboard Pop. Pops a keyboard. The Id parameter determines the type of keyboard: 0=alpha, 1=numeric, 2= accent.

320

SEARCH

String Search. Searches for a string in the field with focus. Search starts as cursor (insertion point) position. Id must contain a pointer to a string. The byte position of the found text is returned. A -1 value is returned if no match was found.

321

BYTECOUNT

Byte Count. Returns the number of characters in the field with the focus (cursor).

322

PHONELOOKUP

Phone Lookup. Takes the currently selected name or name containing the insertion point, and performs a phone number search in the Address Book database with that name. The selected text is replaced with found name and phone number. If no match was found, the Address Book short list is popped.

323

PREVFIELD

Previous Field. Moves the focus to the previous field in the form.

324

NEXTFIELD

Next Field. Moves the focus to the next field in the form.

325

DIRTY

Field Dirty. Returns the dirty state (1=modified, 0=unmodied) of the current active field. Also, sets the dirty bit of the field to Id. If Id is "-1", the dirty bit is not changed.

326
SETGSI
Set GSI.  Sets the state of the graffiti shift indicator.  The valid Id values are: 0=no shift, 1=shift upper, 2=shift lock.  Currently does not work in EHAND or REPEAT handler functions.

400

AUTOSIZE

Button Auto-Resize. An Id value of 1 enables auto-resize mode, 0 disables it. 0 is the default mode. When enabled, auto-resize mode causes FsetText to horizontally resize buttons to fit the new text.

401

TRIGTIME

Button Trigger Time. Returns the "pen down" time in ticks for the last button event. The Id field is ignored. This command is useful for applications which need to capture the button enter time (as opposed to the button exit time), such as lap timers, etc..

402
BEXITID
Button Exit ID. Returns the ID of last button exit event observed. Use this command after Fevent() return code of 250 is received. The id field is unused.
403
BENABLE
Enable Button. Enables a button which has been deactivated with the BDISABLE Fctl command (#404). The id should be the ID of the button to enable.  An id of -1 will enable all buttons on the current form.
404
BDISABLE
Disable Button. Disables (makes usable, but still visible) a button. The id field should contain the ID of the button to disable. An id of -1 will disable all buttons on the current form.  Use the BENABLE Fctl command (#403) to re-enable a button.

int FgetState(int Id)

Returns either the current state of a button or the current selection for a list. If the Id value ranges from 1 to 255, the value will be treated as a button group number, and the ID of the selected button in the group will be returned. Otherwise, the Id should contain the ID number of the list or button to query.

FgetState return values

Object Type

Return Value

Button (pushbutton & checkbox)

Button state. 1=On, 0=Off.

Group (Id range 1 to 255)

ID of selected button in group. -1 if none.

List

Array index of selected item. -1 if none.

FsetState(int Id, int state)

This function can be used to change the state of a button or the selection item on a list. The Id parameter determines the button or list to modify.

For buttons, setting the state parameter to 1 will assert the button, 0 will de-assert the button. If a button is grouped with others, be sure to call FgetState first to determine if any button in the group is already selected. If a button is already selected, unselect it with FsetState(id,0). Failure to do this can result in more than one button in a group being selected.

For lists, the state parameter specifies what list item to select. A value of -1 will cause no items to be selected, a 0 will cause the first item to be selected, a 1 the second item, and so on.

string FgetText(int Id)

With this function, the contents of a field, the text of the current selected item of a list, the text of a button, the text of a label, or the title text of a form can be returned. The Id parameter should contain the ID of the object to query.  Use an Id of zero to obtain the current form's title string.

FsetText(int Id, string text)

With this function, the text in a field, button, or label can be changed. If the Id parameter specifies the ID of a field, the field contents are replaced by the text parameter.  Also, the title text of a form can be changed with this function.

If the Id parameter specifies the ID of a button, the button's texts is replaced by the text parameter. If the button is a select box, the frame of the button will be re-sized to accommodate the new text. By default, the other button types do not auto-resize when FsetText is called. Use the Fctl() AUTOSIZE command (#400) to enable or disable auto-resizing for the other button types.

If the Id parameter specifies the ID of a label, the label's text is replaced by the text parameter.  The length of the new text is truncated if it has more characters than the old label text.

To change the text of the current form's title, use an Id of zero.  For example: FsetText(0,"New Title");

FmoveObj(int Id, int x, int y)

Moves the form object specified by Id to location (x, y).

FresizeObj(int Id, int width, int height)

Resizes the form object specified by Id.

If a list object is resized to have a height which is not aligned with to a text row boundary, strange ghosting effects will occur in the misaligned gap. For example, suppose the font for a list has a height of 14 pixels and the list has 3 rows (for a hieght of 42 pixels). Resizing the list height to 49 will result in 7 pixels of height being unused. This 7 pixel gap will be subject to bizarre ghosting effects.

int Form(int Id, string title)

Creates a screen sized dynamic form with the specified title.

Each form, dialog, and form object MUST have its own unique ID number. Duplicates will result in system error and/or unpredictable behavior will result. The minimum form ID number is 3000.

Creating a form does not make it draw. After a form is created, form objects should be installed into it via the Button, List, Field, Label, and GSI commands. Once all the desired objects are installed, the Fctl() "DRAW" command (#0) should be used to draw the form and all its objects.

Multiple forms can be created simply by calling Form() multiple times (e.g. call Form(),install objects, call Form(), install objects, etc.). Use the Fctl() "DRAW" command (#0) to switch between forms.

Unneeded forms can be removed with the Fctl() "FREE" command (#1).

Form() will internally call graph_on() if it has not been done so already. As such, do not call graph_on() after Form() since it will have already been called.

This function will return 0 upon failure to create the form, and 1 if successful.

By default, forms do not have a menu associated with them. See the Fctl SETMENU (#104) command for more details.

int Dialog(int Id, int x, int y, int width, int height, string title)

Creates a dynamic dialog form with the specified title. The upper-left hand corner of the dialog will be at location (x,y).

All objects installed in the dialog are positioned relative to the upper left hand corner of the dialog, NOT the screen!

Each form, dialog, and form object MUST have its own unique ID number. Duplicate ID numbers will result in system error and/or unpredictable behavior will result. The minimum form ID number is 3000.

The PocketC graphics window must be activated with the graph_on() command before the first form/dialog is created.

Creating a dialog form does not make it draw. After a dialog is created, form objects should be installed into it via the Button, List, Field, Label, and GSI commands. Once all the desired objects are installed, the Fctl() "DRAW" command (#0) should be used to draw the dialog and all its objects.

Multiple forms and dialogs can be created simply by calling Form() and/or Dialog() multiple times (e.g. call Form(),install objects, call Dialog(), install objects, etc.). Use the Fctl() "DRAW" command to switch between forms/dialogs.

The background graphics behind dialogs is saved when the Fctl() "DRAW" command (#0) is issued. The background is restored when either the dialog is deleted with the Fctl() "FREE" command or when the active form is changed via the Fctl() "DRAW" command (#0). There is POSE emulator bug which can cause the background to not be restored properly, the problem does not appear on real hardware.

Dialogs are a type of form. Any Fctl() command which works on forms will also work on dialogs.

This function will return 0 upon failure to create the dialog, and 1 if successful.

int Button(int Id, int mode, int x, int y, int width, int height, string text)

This function will install a dynamic button in the current active form at position (x,y) with the label specified in the text parameter. If the width field is set to 0, the button width will be automatically resized to fit the text. If the height field is set to 0, the button height will be automatically resized to fit the text. WARNING: Button auto-sizing doesn't work the same for pre-OS3.5 systems, as it does for OS3.5+ systems.

Each form, dialog, and form object MUST have its own unique ID number. Duplicate ID numbers will result in system error and/or unpredictable behavior will result. The minimum button ID number is 256.

There are 6 button types as specified by the mode field.

Button Mode

Bits

Value

Effect

3:0

0

Standard button

Button Type

1

Push button

2

Check Box

3

Pop-Trigger

4

Select Box

5

Repeat Button

5:4

0

Standard Frame

Frame Style (for Standard and Repeat Buttons).

Note: Palm OS5.0 will only support the standard frame style for standard buttons and the no frame style for repeat buttons.

1

Bold Frame

2

Square Frame

3

No Frame

15:8

0 to 255

Group number. 0=Not grouped. Turns Push Buttons & Check Boxes into "radio" buttons. All buttons in a group should have the same group number.

16

0 to 1

Alignment. 0=left align, 1= right align. Useful for Select boxes.

Pop-trigger buttons need to be bound to a list (see the List() call). When selected, the list will pop-ip. If an item in the list is tapped, the label of the pop-trigger button will be updated.

Select box buttons are surrounded by a dotted frame. If the text of the button is changed with the SetButton() function, the frame will be resized. The alignment of the resize can be specified with bit 16 of the mode parameter.

Repeat button events are not handled through the Fevent() call. Instead, repeat button events are handled through a special user defined function. The function is bound with the Fctl() "REPEAT" command #103. See this Fctl() command for more details.

Push buttons and checkboxes can be made to behave in a "radio button" fashion. This is accomplished by giving a set of buttons the same group number (mode bits 15:8). If the group number is zero, the buttons will not be grouped.

The font of the button label can be set by calling textattr() with the desired font (including custom fonts. See OpenFontDb) before installation.

This function will return 0 upon failure to install the button, and the rightmost "x position" of the button if successful. This "x position" return value feature is useful for laying out adjacent pushbuttons. Simply use the return value as the X-position of the next pushbutton. Alternatively, if a BINDX variable is set (see Fctl command #100), the variable will be set to the rightmost button boundary value. If the BINDY variable is set (see Fctl command #101), the variable will be set to the bottom button boundary value.

Also, if the Fctl BINDX and/or BINDY commands have been used to setup position variables, these variables will be updated when a pen event occurs within a button boundary. This can be used to determine where in a button the pen tap occurred.

int Field(int Id, int mode, int x, int y, int width, int height, int max_chars, string text)

Installs a dynamic, in-place edit text field at position (x,y) with the specified width and height. The maximum number of characters in the field is specified by the max_chars parameter. The field will be preloaded with the contents of the text parameter.

Each form, dialog, and form object MUST have its own unique ID number. Duplicate ID numbers will result in system error and/or unpredictable behavior will result. The minimum button ID number is 256.

The initial font of the field can be set by calling textattr() with the desired font (including custom fonts. See OpenFontDb) before installation. The font can also be changed on the fly with the Fctl() "SETFONT" command #303.

If the height parameter is set to zero, the field height will be automatically set the current font height (the field will be a single text line high).

The last field installed will have the focus (cursor).

The mode definition is as follows:

Field mode definition

Bit

Effect

0

Single-line mode (ignores returns). 1=enable, 0=disable.

4

Underline mode. 1=no underline, 0=dotted underline.

8

Editable. 1=No, 0=Yes

12

Numbers only (ignores alpha characters). 1=enable, 0=disable.

16

Justification. 1=right, 0=left.

This function will return 0 upon failure to install the field, and 1 if successful.

If a BINDX variable is set (see Fctl command #100), the variable will be set to the rightmost field boundary value. If the BINDY variable is set (see Fctl command #101), the variable will be set to the bottom field boundary value.

Int GButton(int Id, int mode, int x, int y, int width, int height, int bmpId, int selectedBmpId)

Installs a dynamic graphical button in the current form with the specified Id. Graphical buttons are similar to regular buttons except that they have bitmaps instead of text. Two bitmaps need to be provided, one for the "normal" state and one for the "selected" state. The bitmaps must be specified by resource ID and must be located in the application's .prc file, in a bitmap resource database (see the OpenBmpDb() function), or in a separate resource database (see the OpenRsrcDb() function for more details on this).

Graphical buttons are only available in OS3.5 and beyond. They can be easily faked out in earlier OS versions by drawing a FormBmp() object on top of a Button() object which has no text.

The mode format is identical to that of the Button() function with the one exception being that checkbox graphical buttons are not supported.

The function returns a 1 upon successful installation and 0 upon failure.

int List(int Id, int x, int y, int width, int max_items, int trigger_Id)

Installs a dynamic list at position (x,y) with the specified width. The max_items field determines the maximum number of items to show. If a list has more items than the max_items parameter value, scroll arrows will appear in the list.

Set the trigger value to 0 to create a stand-alone list. Set the trigger value to a pop-trigger button Id to create a pop-triggered list. Set the trigger_Id to an used ID (such as 9999) to create a dropdown list (use the Fctl() "POPLIST" command #200 to pop the dropdown list).

The minimum Id value is 256.

The font of the button label can be set by calling textattr() with the desired font (including custom fonts. See OpenFontDb) before installation.

Use FsetList() to define item values for a list object.

If a BINDX variable is set (see Fctl command #100), the variable will be set to the rightmost list boundary value. If the BINDY variable is set (see Fctl command #101), the variable will be set to the bottom list boundary value.

int FormBmp(int Id, int x, int y)

Installs a dynamic bitmap object in the current form at position (x,y). The Id parameter specifies the resource ID of a bitmap located in the application's .prc, in a bitmap resource database (see the OpenBmpDb() function), or in a separate resource database (see the OpenRsrcDb() for more details on this). The resource Id is also the ID which should be used for hiding and showing the bitmap (see the Fctl SHOW and HIDE commands), and for moving it with the FmoveObj() function.

The function returns a 1 on success and a 0 upon failure.

FaddList(int Id, int num_items, pointer array)

This function appends the contents of an array to a list form object. The Id is the ID of the list object. The num_items parameter determines the number of items to add. The array parameter is the pointer to a list of strings.

Use the FdelList() command with index=-1 to clear out the list of all items. Use the FrevList() command to sort and/or draw a list when complete.

See the list_demo.c file for an example using this function.

To add a single element to a list use the following function: FaddItem(int Id, string item) { FaddList(Id,1,&item); }

FdelList(int Id, int index)

This function deletes either one or all items from a list form object. The Id is the ID of the list object. The index is the list element to delete (e.g. the first element is 0, the second 1, third 2, etc). If an index of -1 is specified, all items in the list are deleted.

Calling this function does not redraw the list. Call the FrevList() to redraw the list.

See the list_demo.c file for an example using this function.

FgetList(int Id, pointer stringArray);
Copies the contents of the list with the specified Id to an array of strings pointed to by stringArray.  The string array must be large enough to contain all the list elements.  Use the Fctl LISTLEN command (#207) to determine the number of elements in the list if uncertain of its size.

FrevList(int Id, int mode)

"Revise List". This function will redraw the a list object if the form it is within is visible. Optionally, the forwared and reverse sort options are available. The The Id is the ID of the list object.

FrevList Mode
Bit
Effect
0
0=draw only, 1=sort & draw
4
0=foward sort, 1=reverse sort

Note: The INCRSEARCH Fctl command (#206) is particularly useful on forward sorted pop-trigger lists.

See the list_demo.c file for an example using this function.

FsetList(int Id, int selection, int num_items, pointer string_array)

Assigns item data to the list specified by Id. The string_array should point to an array of strings. Each element in the array will be a item in the list. The num_items field determines the number of items in the array. The selection parameter specifies the initial selected item. If the selection is -1, no item will be initially selected.

Also, setting the selection field to -2 will prevent the current selection from being changed.

Note: The function is now somewhat depreciated. See the newer FaddList(), FdelList(), and FrevList() functions. The FsetState() function can also be used to set the selection.

int GSI(int x, int y)

Installs a dynamic Graffiti Shift Indicator at the (x,y) position. The function only works for OS3.5+. For earlier OS versions the function simply exits.

int Label(int Id, int x, int y, string text)

Installs a dynamic text label of the given Id at position (x,y).

The minimum Id value is 256.

The font of the label can be set by calling textattr() with the desired font (including custom fonts. See OpenFontDb) before installation.

Tip: Multi-line labels can be created by using "\r" characters in the text string (note: "\n" doesn't work).  Example: Label(3001, 80,80,"Line1\rLine2\rLine3");

int OpenRsrcDb(string dbName)

Opens a resource database so that various form functions can access the resources within. If no such database exists, it will be created and opened. If the database is created it will be of type "data" and will have a creator ID of "PktC". The database will also have its backup bit set.

This function is handy during the development phase when working with resource forms, menus, strings (for dialog help icons), bitmaps (for FormBmp() and Gbutton()), and alerts (see the Fctl POPALERT command (#117)). These resources can be created with a desktop tool such as PilRC (and placed within the .prc with par), or created on the PDA itself with RsrcEdit. See the "Resource Forms" sub-section in the "Form Function" section of this document for more details.

Once a project is complete, the resource database can be embedded in the final application .prc with par (e.g. "par a app.prc resource.prc"). After being embedded, the resource database is not needed by the application. Note: If you create an application .prc file with the BuildPRC tool from Orbworks, your application will need to do an OpenRsrcDb() on itself in order to access any resources you embed within it. For example, if your application name is myapp.prc, it will need to internally do a OpenRsrcDb("myapp").

The function returns 0 upon failure, 1 if the database was opened, and 2 if the database was created.

int Slider(int Id, int style, int x, int y, int width, int height, int min, int max, int page, int initial)

This function installs a dynamic horizontal slider object in the current form. This object type is only available for OS 3.5 and higher. There are two slider styles: 0=normal slider, 1=feedback slider. A feedback slider differs from a normal slider in that it will send repeat events if the pen is dragged across the slider. Use the Fctl REPEAT command (#103) to set up a repeat handler function when using feedback sliders.

The min and max parameters define the value boundaries of the slider. The page parameter determines how much to move the slider when the user clicks to the right or left of the thumb. The initial parameter set the initial value of the slider. Use the FgetState() and FsetState() functions to change the state of the slider programmatically.

Use the Fctl SCROLLMODE command in conjunction with the FsetState() function to change the position, minimum, maximum, and page size values.

int CmdBarAdd(int object_id, int position, int bitmap_id, string text)

When called from within an event handler function (see the EHAND Fctl command #123) in response to a command bar open event, this function can be used to add custom icons to the command bar. The object_id indicates the id that Fevent() will return if the icon is selected. (See also the Event Handler Functions section.) The position parameter determines where to place the new icon with respect to the other (0=left, 1=right). Note: The standard field icons will always appear on the right. The bitmap_id refers the resource id of the bitmap to use for the icon. The bitmap must have a width of 16 pixels and a hieght of 13 pixels. The bitmap can be placed in a a bitmap database (see OpenBmpDb), a resource database (see OpenRsrcDb), or in an application .prc file itself. The text field determines what text to display if the icon is selected. If text is left null (i.e. "") and the object_id matches an item in the pulldown menu, the text for the pulldown menu item is used.

This function returns a 0 upon failure and a 1 upon success.

If the event handler function should return -1, the command bar will not be displayed. If a 1 is returned, any field related icons will be supressed. Return a 0 to keep any field icons in the command bar.

This function is only works for OS3.5 and greater and will do nothing in earlier OS versions.

FsetMany(int starting_id, int step_size, int block_size, int offset, int num_blocks, pointer array)

This function rapidly loads the contents of an array of data structures into a set of fields and/or buttons. This is useful for loading tables (matrices) of fields and/or buttons quickly.

The starting_id parameter contains the id of field or button to start with. The step_size parameter determines the amount to increment the starting_id on consecutive object writes (e.g. if the starting_id is 4000 and the step_size is 10, the following objects will be updated: 4000, 4010, 4020, 4030, etc). The block_size determines the size of blocks (elements per data structure) in the data array (e.g. a simple array has a block_size of 1). The offset parameter determines where to look in each each block for the data (e.g. if offset is 1, the second element in the block is used). For simple arrays, an offset of 0 should be used. The num_blocks parameter determines the number of form objects to load (it's also the number of blocks in the array used). The array parameter points to an array of blocks. For fields, values of any type can be used (int, float, string, or char), for standard, pop trigger, and selectbox buttons a string must be used, and for all other types of buttons integer or string types can be used. Type conversion automatically occurs as neccessary.

In cases where no data structure emulation is occuring, the block_size should be 1, the offset should be set to 0, and num_block should be the size of the array.

See also the Sort() and Query() functions for examples using this block_size,offset, and num_blocks concept.

See also the FgetMany() function.

FgetMany(int starting_id, int step_size, int block_size, int offset, int num_blocks, pointer array)

This function rapidly stores the contents of a set of fields and/or buttons to an array of data structures. This is useful for reading tables (matrices) of fields and/or buttons quickly.

The parameter list is identical to the FsetMany() function.

UIColor(int style, int color)

This function controls the color settings for the various form objects. It only works for OS3.5. For earlier OS versions the function simply exits.

The style parameter determines the what type of color change.

UIColor Styles

Style Value

Effect

0

Object Frame

1

Object Fill

2

Object Foreground/Text

3

Object Selected Fill

4

Object Selected Foreground

5

Menu Frame

6

Menu Fill

7

Menu Foreground

8

Menu Selected Fill

9

Menu Selected Foreground

10

Field Background

11

Field Text

12

Field Text Lines

13

Field Caret

14

Field Text Highlight Background

15

Field Text Highlight Foreground

16

Field Fep Raw Text (Japanese OS)

17

Field Fep Raw Background (Japanese OS)

18

Field Fep Converted Text (Japanese OS)

19

Field Fep Converted Background (Japanese OS)

20

Field Fep Underline (Japanese OS)

21

Form Frame

22

Form Fill

23

Dialog Frame

24

Dialog Fill

25

Alert Frame (use #2 to set Alert text color)

26

Alert Fill


Database Functions

This family of functions allows the PocketC to interface directly with two 3rd party database formats: HanDBase® (commercial) and Pilot-DB (freeware). The advantage of using these database formats is that they both have desktop tools for accessing the contents of these databases. Both also have powerful PDA based support applications for sorting, filtering, searching, and beaming their respective databases.

The PToolboxLib provides unified data access to HanDBase® and Pilot-DB databases, in other words the same functions and data types are used for both database formats. This allows applications to seamless switch between the two types.

HanDBase® (a product of DDH Software) is a Palm® and PocketPC® database industry leader. It has a powerful desktop companion for data entry and viewing. The desktop tool also has a number of add-on features, notably a conduit (for PDA-desktop data synchronization), a MS-Access® interface, and a ODBC interface. Another advantage of the HanDBase® standard is that it supports Palm® and PocketPC® cross-compatibility. I highly recommend the HanDBase® Plus product, it includes the desktop companion and the conduit.

Pilot-DB is the freeware Palm® database standard. It supports a variety of fields (though not as many as HanDBase®). There are a set of tools for converting Pilot-DB databases to and from CSV (comma-separated-value) text files. See the DB-Tools area (see link off main Pilot-DB web page). There is also a free MS-Access conduit available (see the "links" section off the main Pilot-DB web page).

Database Comparison Table


HanDBase®

Pilot-DB

Software License

Commercial

Freeware (GPL)

Software Version Supported by PToolboxLib

v2.75e

v1.0.0

Onboard PDA software

Yes. Installation required for PocketC database access

Yes. Installation not required for PocketC database access.

Desktop Companion software

Yes. Has a powerful graphical desktop application for data entry and access.

Yes. DB-Editor.  Also, DB-Tools (see main Pilot-DB link), simple scripts for converting databases to and from CSV (comma-seperated-value) text files.  Additionally, there are some Java interface libraries:  JPilot-DB.

Desktop Conduit for automatic PDA-desktop synchronization.

Yes. With HanDBase® Plus desktop companion.

Yes. See "links" section on Pilot-DB web page for a MS-Access conduit.

MS-Access & ODBC interface

Yes. Requires additional software.

Conduit directly interfaces with MS-Access, but no ODBC support.

Access Speed from PocketC

7 times slower than Pilot-DB. L

Fast.

Maximum Fields per Record

30

No limit.

Field Types (supported)

String, integer, float, date, time, note, boolean, popup (list), calculated, plus others.

String, integer, float, date, time, note, boolean.

Global Find on PDA

Yes

Yes

Functions

int DBcreate(string dbname, int type, int numFields, pointer fieldArray)

Creates and opens a database of the given name. If the type parameter, 0=HanDBase® and 1=Pilot-DB. The numFields parameter specified the number of fields per record. HanDBase® databases have a maximum number of 30 fields per record, while there is not field limit on Pilot-DB databases. The fieldArray pointer should point to the first item of an array which has two elements per field (e.g. for a 30 field database, the array size must be 60)(e.g. the pointer will generally look like: &array[0][0]). Furthermore, each array element pair must consist of first an integer (for the field code) and second a string (for the field name). For example, to allocate memory for an array to handle 20 elements do a: ptr = malloct(20,"is"), or alternatively: ptr = Array("is,20,2");. See the database_demo.c file for a complete code example.

The available database field types are listed in the table below. Provided that one limits oneself to using the: string, integer, float, date, time, boolean, and note fields, the data records can be written seamlessly as either HanDBase® or Pilot-DB records (since they both have these field types).

Database Field Types

Code

Field Type

Format

HanDBase® Support

Pilot-DB Support

0

none

Not applicable

Yes. HanDBase® records always have 30 fields. Unused fields are automatically marked to type "none".

No

1

String

String

Yes

Yes

2

Integer

Integer

Yes

Yes

3

Float

Float

Yes

Yes

4

Popup List

Integer

Yes, untested

No

5

Boolean

Integer (1=true, 0=false)

Yes

Yes

6

Unique

?

Yes, untested

No

7

Image

?

No? untested

No

8

Date

Integer: YYYYMMDD (Y=year,M=month,D=day)

Yes

Yes

9

Time

Integer: HHMM (H=hour,M=minutes)

Yes

Yes

10

Link Field

?

Yes, untested

No

11

Linked Field

?

Yes, untested

No

12

Note

String: "header\nbody"

Yes

Yes, one note per record limit.

13

Heading

?

Yes, untested

No

14

Link List

?

Yes, untested

No

15

Calculated

?

Yes

No

For HanDBase® databases DBcreate() returns -1 if HanDBase® PDA application not available, 0 for success, and 1 or higher for failure. For Pilot-DB databases, DBcreate() returns 0 on success and 1 upon failure.

int/string DBinfo(int mode, int field)

Returns information about the currently opened database.

DBInfo Behavior

Mode

Functionality

0

Database Type. Returns the type of currently opened database. 0=HanDBase®, 1=Pilot-DB. Field parameter unused.

1

Field Count. Returns the number of fields per record. Field parameter unused.  For HanDBase databases returns a count based on the last non-none field position.

2

Record Count. Returns the number of records in the database. Field parameter unused.

3

Field Code. Returns the field type (code number) for the specified field.

4

Field Name. Returns the field name (a string) for the specified field.

Returns -1 if no database is currently open.

int DBopen(string dbname)

This function opens the specified Handbase® or Pilot-DB database. If another such database is already open, it is closed before the new one is opened.

Returns 0 upon success, and 1 upon failure.

int DBsetrec(int recordNum, pointer arrayPtr)

Loads the record specified by recordNum with the contents of arrayPtr. The array must consist entirely of strings. The length of the string should be at least equal to the number of fields per record in the database (the DBinfo() function can be used to get the number of fields). The first record is at postition 0.

If the recordNum parameter is set to -1, a new record is created and appended to the database.

For HanDBase® databases returns -1 if HanDBase® PDA application not available, 0 for success, and 1 or higher for failure. For Pilot-DB databases, returns 0 on success and 1 upon failure.

int DBgetrec(int recordNum, pointer arrayPtr)

Reads the record specified by recordNum and writes the contents to the array pointed to by arrayPtr. The array must consist entirely of strings and have at least as many elements as the there are fields in the database. The first record is at postition 0.

For HanDBase® databases returns -1 if HanDBase® PDA application not available, 0 for success, and 1 or higher for failure. For Pilot-DB databases, returns 0 on success and 1 upon failure.

string DBgetfield(int record, int field)

Returns the contents of the field of the specified record. Returns "" upon failure.

int DBrm(int recordNum)

Deletes the specified record. If the recordNum parameter is set to -1, the database is deleted.

Returns 0 on success and 1 on failure.

int DBmoverec(int fromRecord, int toRecord)

Inserts the "from" record at the "to" record position.

This "to" value may be one greater than the index of the last record in the database. In cases where "to" is greater than "from", the new index of the record becomes "to"-1 after the move is complete.

Returns 0 on success and 1 on failure.


Bitmap Functions

Bitmap resource databases can be created with various tools:

First, I highly recommend artBMP, a free, palm based bitmap editor created by Dian Suharto Iskandar. It can be found here: Artosoft.

Other notable products are : MADPaint (freeware) by MAD Ant Design and RsrcEdit ($15) from Quartus. MADPaint is similiar to artBMP, and offers some interesting features. RsrcEdit allows one to draw bitmaps on a PDA or emulator (though it's not quite as powerful as artBMP or MADPaint).

Advanced users can use PilRC (freeware) to compile bitmaps into raw binaries and a tool like par (freeware) to put these binaries into a .prc file. With these two tools users can put many bitmaps into a .prc file at once (e.g. par a applet.prc *.bin).

Empty resource database files can be created with the OpenBmpDb() function. The empty database can then be populated with bitmaps using the SaveBmp() function.

It is possible to merge a bitmap database into a program's .prc file, thus eliminating the separate bitmap database. Use par in append mode to do this (e.g. "par a applet.prc bitmap.prc"), and use your applet name (as specified with #dbname) in the OpenBmpDb call (though leave out the .prc extension).

//MakeBmpDb

//This program will create an empty resource database file for holding bitmaps

library "PToolboxLib"

main() { OpenBmpDb("database_name"); }

int OpenBmpDb(string database)

Opens a database by the given name. Only one such database can be open at a time. Calling this function again will close the current database before opening the new one. When the application exits the database is closed automatically. This function will return a 0 on failure to open/create the specified database, and 1 upon success.

The bitmap database can either be a .prc or a .pdb file.

If the database does not exist, a new one is created with the given name. The new database will be of type "data". If the application is a stand-alone type, the creator ID of the database will be the same as the application, otherwise the creator ID will be 'PktC'. The backup bit will also be automatically set for this new database. Thus, this function can be used to create empty resource database (.prc) files for inserting bitmaps into.

There are two modes in which a bitmap database can be opened: "load&lock" mode (the default), and "load-on-demand" mode. In "load&lock" mode, all the bitmaps in the database are immediately loaded into memory and locked down. This process can take some time, especially if there are many bitmaps in the database. The benefit is that the bitmaps draw very quickly. In "load-on-demand" mode, a bitmap is loaded and locked only when it is drawn. After being drawn the bitmap image is immediately unlocked and freed. Bitmaps in "load-on-demand" mode draw slower than those under "load&lock" mode, however there is no up-front database load delay. "Load-on-demand" mode is also more suitable in cases where there are many, very large bitmaps. To open a database in "load-on-demand" mode, simply prefix the database name with a "#" character. For example, if a database name is "bitmaps", use OpenBmpDb("#bitmap") to open the file in "load-on-demand" mode, and OpenBmpDb("bitmap") to open the file in "lock&load" mode.

Bitmap databases (.prc's only) can be merged into an applet's .prc file, thus eliminating the separate bitmap database. Use par in append mode to do this (e.g. "par a applet.prc bitmap.prc"), and use your applet name (as specified with @dbname) in the OpenBmpDb call (though leave out the .prc extension).

int GetNumBmps()

Returns the number of bitmaps in a database opened with OpenBmpDb.

int FastBmp(int x, int y, int index)

"Fast Bitmap". Displays the specified bitmap at the selected position.

Depending on how the bitmap database was opened, in either "lock&load" or "load-on-demand" mode, the bitmaps can either be addressed by bitmap index or by resource ID number. See the OpenBmpDb function description for more information on these modes.

If the database was opened in "lock&load" mode, the index field always refers to the bitmap index of the bitmap. The first bitmap in the database is at index 0, the second at 1, the third at 2, and so on. Returns 1 on success, 0 on failure (could not find record).

If the bitmap database was opened in "load-on-demand" mode AND the index field value is less than 1000 (decimal), the bitmap is also addressed by the bitmap index. If the index field value is 1000 or larger, the value is treated as a bitmap resource ID (thus only bitmaps with resource number of 1000 or higher can be accessed via this method).

Bitmaps draw faster in "lock&load" mode than in "load-on-demand" mode. However, the OpenBmpDb execution time is shorter in "load-on-demand" mode.

If no bitmap database is opened, then the application .prc is file itself is searched for bitmaps. In this case the mode is "load-on-demand".

Bitmaps with a depth of 1 will always draw in the current foreground and background colors regardless of the current screen depth (e.g. A 1 bit deep bitmap drawn on a 4 bit deep screen will appear in the current foreground and background colors).

Note: Drawing bitmaps at 8 bit boundaries seems to be faster than at other boundaries. Also the bitmap size is a multiple of 8 bits, that helps too. For example, drawing a 16x16 bitmap at location x=80,y=80 is faster than drawing a 17x17 bitmap at location x=161,y=160.

int TransBmp(int x, int y, int overlay_index, int mask_index)

"Transparent Bitmap". This function allows the user to mask out a "hole" in the screen and then overlay a bitmap into that "hole". The mask is simply another bitmap resource with all black which defines the "hole". The overlay_index refers to the index of the bitmap to fill in the "hole". The mask_index refers to the index of the bitmap which defines the "hole". See FastBmp() functional description for how indexing with bitmap resource databases works.

If the mask_index is set to -1, no mask will laid down and the overlay bitmap will be placed on top any existing pixels, possibly altering the bitmaps appearance.

If running OS3.5+ and the bitmap specified with the overlay_index has its transparency bit set (see the SaveBmp & BmpInfo functions for more details), the mask will not be used, and the bitmap will draw in transparent mode. Setting the transparency bit on the mask bitmap can result in system errors ('Blitter.c, Line:XXXX,Transparency only supported in scrCopy mode').

Returns 1 on success, 0 on failure. This functions fails if the specified bitmap cannot be found.

TransBmp() is approximately 3 times slower than FastBmp().

Note: TransBmp only works in "lock&load" bitmap mode (see OpenBmpDb for more details on this mode).

int SaveBmp(int id, int x, int y, int width, int height, int transparency, int compression)

This function saves part of the current draw buffer to a resource database (.prc file) opened with OpenBmpDb. Each bitmap resource should have it's own unique ID (typically they start at 1000). For OS3.5 and above, the transparency parameter defines what color will be made transparent. Set it to -1 for no transparency. Bitmaps made transparent will be drawn as non-transparent by OS3.3 and earlier. The function will return the index of the resource bitmap as needed by the FastBmp and TransBmp functions.

With compression, a bitmap can be made to take up less memory, however the bitmap will draw slower. There are three compression modes available: 0=none, 1=scan line, and 2=RLE. RLE compression can be much better than scan line, but it also may be much worse, even increasing the size the bitmap almost two-fold (it depends on the image). Also, RLE bitmaps will not draw correctly in pre OS3.5 systems. Scan line compressed bitmaps should draw correctly in all OS versions. Bitmaps can only be compressed in OS3.5+ systems (pre-OS3.5 systems default to mode 0).  Note: Compression does not work on OS5, all bitmaps created on an OS5 device will uncompressed.

A bitmap can either be transparent or compressed, but not both.

The Palm OS will not compress small bitmaps because compressing them offers little benefit.

Bitmaps larger than 160 by 160 may not save because Palm bitmap resources are limited to maximum size of 65k bytes. Compressing such large bitmaps often allows them to fit under this 65k byte ceiling.

This function can be used to save bitmaps to .prc application file.

Note: SaveBmp only works if the bitmap database is a .prc file. The function does nothing if the database is a .pdb file.

int BmpInfo(int index, pointer width_ptr, pointer height_ptr, pointer depth_ptr, pointer transparency_ptr, pointer compression_ptr)

Given the index to a bitmap, the width, height, depth, transparency color, compression type, and ID are returned. The bitmap resource ID as the return value of the function. A zero is returned if the bitmap does not exist. The width, height, depth, transparency, and compression values are passed back through pointers.

A transparency value of -1 indicates that the bitmap has no transparency color set. There are three possible compression values: 0=none, 1=scan-line, and 2=RLE (see SaveBmp for more details about transparency and compression).

Warning: Some bitmaps (e.g. those created with RsrsEdit) don't set the depth parameter correctly on bitmaps they generate. Thus you can't always trust the return depth value. The SaveBmp function will set the depth correctly.

A zero can be passed in for the width_ptr, height_ptr, depth_ptr, tranparency_ptr, and compression_ptr parameters if their return values are not needed.

Note: This function only works if the bitmap database is a .prc file. It does not work on .pdb files.

//BmpInfo.c

library "PToolboxLib"

main() {

int index, id, width, height, depth, trans, comp;

if(OpenBmpDb("test_bitmap")) {

for(index=0;index<GetNumBmps();index++) {

id = BmpInfo(index, &width, &height,&depth,&trans,&comp);

puts("Index="+index+", ID="+id+", Width="+width+", Height="+height+", Depth="+depth+", Transparency="+trans+", Compression="+comp+"\n");

}

}

}

int RmBmp(int index)

This function will delete a bitmap from a resource database. If an index of -1 is specified all the bitmaps in the database will be removed. Furthermore, if an index -2 is specified the resource database is closed and deleted. A return value of 1 indicates success, 0 indicates failure.

Note: This function only works if the bitmap database is a .prc file. It does not work on .pdb files.

Sprite(int num_sprites,pointer data_array)

Roughly, this function combines the capabilities of TransBmp() and CopyRect() to manage a number of bitmaps and respective backgrounds with one function. With each call of this function, the previous background of every "sprite" bitmap is restored, and each sprite is then redrawn in its new position.

Alternatively, the save-behind feature can be disabled for a sprite by setting its save buffer (array[5]) to -1. This is useful when using a full screen multi-buffered approach where it is not desirable to save and restore the background behind each sprite.

Each sprite can be assigned its own user defined handler function which is executed internally each time Sprite() is called (unless the sprite is "off"). The handler function must be of the following format: func(int sprite_number, pointer array). The sprite_number indicates what sprite is being called (0=first one, 1=second one, etc), while the array pointer points the array structure for the given sprite. A good use of a sprite handler function is to check a sprite's position to ensure that it has not crosses any boundaries (e.g. the edge of the screen, etc.). The use of these handler functions can significantly reduce code complexity. See the sprite.c code sample for an example of how to use sprite handler functions.

X and Y movement vectors can also be specified for each sprite. The vectors are automatically added to the sprites current

The function has two inputs: the num_sprites parameter indicates the number of bitmaps ("sprites") to manage, the data_array parameter points an array of integers containing information on each of the "sprites". The array needs to be 12 times the number of sprites in size (e.g. for 5 sprites: array = malloct(5*12,'i');).

The array format is as follows:

Sprite array definitions

Position in array

Definition

array[0]

X position of sprite

array[1]

Y position of sprite

array[2]

Command (see command table below)

array[3]

Bitmap index (same as in TransBmp)

array[4]

Mask index (same as in TransBmp)(set to -1 if none)

array[5]

Scratch buffer index for storing background (set to -1 to not save background).

array[6]

Handler function. (pointer to handler function of format: func(int sprite_number, pointer array))

array[7]

Collision mask (32 bits). See SpriteRectColl() function for more details.

array[8]

X-Move. Added to X position (array[0]) each time Sprite() is called.

array[9]

Y-Move. Added to Y position (array[1]) each time Sprite() is called.

array[10]

Previous X position (the sprite function will set this)

array[11]

Previous Y position (the sprite function will set this)

Note: The array values repeat for subsequent sprites. (e.g. The New X position for the second sprite is at array[12], the third starts at array[24], etc.).

Sprite command definition

Number

Effect

0

Off. Do not draw/update the sprite.

1

Initialize Mode (first use of sprite - save initial background). (Sprite automatically changes command 1 to 2)

2

Normal Mode. Sprite background is restored and sprite is redrawn in new position.

3

Turn sprite off, but keep it visible (position will not update with further sprite() calls unless command is changed back to 2). (sprite automatically changes command 3 to 0)

4

Turn sprite off and hide it (will not reappear unless command is set back to 2) (sprite automatically changes command 4 to 0)

5

Initialize Static Mode. Draws sprite only once. (Sprite automatically changes command 5 to 6)

6

Static Mode. Sprite is not re-drawn with each sprite call, but still considered active for SpriteRectColl() purposes. Useful for stationary sprites which do not need to be re-drawn with each Sprite() call.

When the Sprite() function is called the following sequence of events occurs:

  1. Restore the previous background behind all active sprites. *
  2. Save the new background behind all active sprites (for new the positions). *
  3. Re-draw all active sprites in their new positions
  4. Update the position of all sprites with their movement vectors.
  5. Call the handler function of each active sprite (usually to check if the new position is valid).

* Stage skipped for sprites with buffer (array[5]) set to -1.

Using the sprite save-behind feature can be faster than double or triple screen buffering, especially when using screen depths of 4, 8, or 16, however, the graphic rendering may not be as smooth.

The SpriteRecColl() function can be used for rapidly checking for collisions between sprites.

See the sprite.c program for an example using the sprite() function.

This function only works in "lock&load" mode. See the OpenBmpDb function for more information about this mode.


Screen Buffer Functions

WARNING: Full-screen scratch buffers can use up a considerable amount of heap space (3.2k for 1 bit screen depths, 6.4k for 2 bit depths, 12.8k for 4 bit depths, and 25.6k for 8 bit depths). So if you are using a number of buffers don't be too surprised if you run out of memory… then again you may not (e.g. OS3.0 to 3.3 gives the user ~36k of heap). The HeapSize() function can be used to determine the amount of available heap memory. The CustomBuf() function can be used create smaller (or larger) buffer sizes and the FreeBuf function can be used to free the memory used by a buffer. Another trick is to use the SaveBuf and RestoreBuf functions to cut down on the number of active buffers (buffers saved to a database do not use heap space!).

SetDrawBuf(int buffer)

Sets the draw buffer. All graphics from then on will be directed to the specified buffer. Buffer 0 is the display buffer. Buffers 1 to 32 are scratch buffers (there is a maximum limit of 32 scratch buffers). Thus the allowed buffer number are 0 through 32.

Memory for the scratch buffers is automatically allocated as needed, and is freed when the application closes. Buffer memory allocated through this function is sized for the full screen (160 by 160 pixels). If the memory for a buffer has already been allocated, calling SetDrawBuf does not allocate new memory for that buffer. Thus if you call SetDrawBuf(1), SetDrawBuf(4), SetDrawBuf(1), and SetDrawBuf(5), you've actually allocated memory for 3 full-screen scratch buffers.

Smaller or larger than full screen sized buffers can be created with the CustomBuf function. The memory for a buffer can also be freed using the FreeBuf function.

CopyBuf(int dest, int src)

Copies the entire contents of one buffer to another. (e.g. CopyBuf(0,1) copies the contents of scratch buffer 1 to the display buffer)

CopyRect(int src_buf, int dest_x, int dest_y, int src_x, int src_y, int width, int height, int mode, int zoom, int rotation)

Normally copies a rectangle from the source buffer to the current draw buffer. Alternatively, if the rotation field is -1, then the rectangle is copied to the destination buffer specified in the zoom field.

A number of copy modes are available:

CopyRect Modes

0

Copy

Destination replaced with source pixels.

1

Erase*

Destination cleared where source pixels are off (AND mode). OS3.5+ only.

2

Mask**

Destination cleared where source pixels are on (AND NOT mode).

3

Invert

Destination inverted where source pixels are on (XOR mode).

4

Overlay

Destination set only where source pixels are on (OR mode).

5

CopyInverse

Destination replaced with inverted source (copy NOT mode).

6

Swap*

Destination foreground and background colors are swapped, leaving any other colors unchanged (color invert operation). OS3.5+ only.

*Erase and Swap modes work only in OS3.5 and up.

**When using CopyRect() with a screen depth of 8 (color) and in Mask mode (=2), the foreground color should be set to 255 and the background to 0, otherwise the masking will modulate the colors in the image.

The value in the zoom field determines how large or small to draw the copied rectangle. Values of 0, 1, and -1 perform no enlargement; a value of 2 performs a X2 enlargment; 3 yields a X3 enlargement, etc. A value of -2 shrinks the image in half, a value of 3 to a third, and so on. When therotationfield is -1, the zoom field determines the destination buffer (otherwise the destination buffer is the current screen buffer).

The following rotation values are available:

Rotation Values

-1

zoom field = destination buffer

0

Rotate 0 degress (strait copy)

1

Rotate 90 degrees

2

Rotate 180 degrees

3

Rotate 270 degrees

4

Flip horizontally

5

Flip vertically

WARNING: This function tends to fail if the source buffer is also the draw buffer and the rectangles are in close proximity of each other. This is a problem with the operating system.

ClearBuf()

Clears the current draw buffer. Unlike the built-in clear_g function, ClearBuf removes the title bar

CustomBuf(int buffer, int x, int y)

Allocates memory for a custom sized scratch buffer. The x and y parameters defines the buffer size in pixels. The buffer can be made to be smaller or larger than the full screen (160 by 160 pixels). The buffer number corresponds to one of the 32 buffer slots as described in the SetDrawBuf() section. The buffers created with CustomBuf() use the same buffer slots as those created with SetDrawBuf(). The only difference being that those created with SetDrawBuf() are automatically the full screen size, while the size of the buffers created with CustomBuf() is user defined.

This function normally doesn't need to be used unless you find yourself running out of memory due to too many full-screen buffers. (You will get a "Failed to create draw buffer" system error if this is the case.)

FreeBuf(int buffer)

Frees the memory associated with the specified scratch buffer. Calling buffer 0, frees the memory for all scratch buffers.

This function does not normally need to be called because the all memory will be freed when the application exits. However, if you find yourself running out memory due to too many large buffers, this function may help.

int OpenBufDb(string database, int mode)

This function opens a "buffer database" for use with the SaveBuf and RestoreBuf functions. If not such database exists then one is created and opened. . The new database will be of type "data". If the application is a stand-alone type, the creator ID of the database will be the same as the application, otherwise the creator ID will be 'PktC'.

Only one "buffer database" can be open at any given time. If a "buffer database" is already open, it is closed, and the new one is opened. The library will automatically close an open "buffer database" when the application exits. The CloseBufDb function can also be used to close a database if the user wants to modify it with the standard Pocket database functions. This function will return a 0 upon failure to open/create the specified database, and 1 upon success.

The modes are as follows: 0 = open database, 1 = open database and set backup bit, 2 = open database and automatically delete it when closed. Note that with mode 2, the buffer database will be automatically closed and thus removed when the application exits. Mode 2 is useful for applications which use the buffer database a temporary screen buffer storage (this can be used to get around the screen buffer quantity limitation).

CloseBufDb()

Closes the "buffer database" if it is open. Once a buffer database is closed, it can then be edited with the built-in PocketC database functions. For example, if one wants to set the backup bit on a buffer database the following operations should be applied: CloseBufDb(); dbopen("database_name"); dbbackup(1); dbclose();

int SaveBuf(int record)

Saves the contents of the current draw buffer to the a database at the corresponding record number. The database must have been opened with the OpenBufDb function. If a the record number is higher than the number of existing records in the database, the buffer will be written into the next available record slot. (So the record number specified may not be the one which gets written.) This function returns a 0 if the record cannot be saved, and a 1 upon success.

The database created is accessible via the standard PocketC database routines (provided that the database has been closed first).

int RestoreBuf(int record)

Writes the contents of a database record to the draw buffer. The database must have been opened with the OpenBufDb function. If the buffer saved was of a custom size (see CustomBuf function), the screen size needs to be the same size and depth as to when the corresponding SaveBuf call was made, else you will get a garbled image. This function will return a 0 if the restore failed (usually means the record doesn't exists), and 1 upon success.


Miscellaneous Graphics Function

Arc(int x, int y, int x_radius, int y_radius, float start_phase, float end_phase, int sides)

Draw an arc with center at coordinates (x,y) with the horizontal extent x_radius, and vertical extent y_radius. The sides parameter determines the number of lines to construct the arc with, set it to -1 to draw a smooth curve. Use The phases are specified in radians. (e.g. arc(80,80,60,40,3*3.14159/2, 5*3.14159/2,-1); //draws an elliptical backwards C arc)

To draw a circular arc set x_radius and y_radius to the same value.

This function requires the Mathlib to run.

ellipse(int mode, int x, int y, int a, int b)

Draws an ellipse. The center of the ellipse is defined parameters "x" and "y". The width is specified by radius "a", while the height is specified by radius "b". If "a" and "b" are equal a circle is drawn. There are a number of modes available:

Ellipse Mode

Bits

Value

Effect

1:0

0

Frame - solid

1

Fill - solid

2

Frame - current fill pattern (see SetPattern)

3

Fill - current fill pattern (see SetPattern)

23:16

0-255

Brush (line) width (note: 0 & 1 are the same)

31:24

0-255

Brush corner radius (for when width > 2)

Example: ellipse(0x050a0002,80,80,30,40); //draws an ellipse of width 10 using a round brush (width=10, radius=5) using the custom fill pattern.

Lines(int mode, pointer array, int array_depth)

Given a array of (x,y) coordinates this function draws lines between the points specified. The pointer should point to an array of int's. The array_depth should be equal to the number of points times two (e.g. four coordinates require a depth of 8). A number of modes are available:

Lines Mode

Bits

Value

Effect

1:0

0

Plot points only

1

"paired mode". Pairs up coordinates and draw lines between the points in each pair.

2

"chain mode". Draw lines between all subsequent points.

3

"polygon mode". As mode 2 but also connects first and last points.

4

0-1

OFFSET mode (1=enable, 0=disable)

5

0-1

Draw Style (0=solid, 1=custom fill)

8

0-1

Scan fill a polygon (slower than convex fill)

9

0-1

Convex fill a polygon (fast - works on convex polygons only)

23-16

0-255

Brush (line) width (0 & 1 are the same)

31-24

0-255

Brush corner radius (for when brush width > 2)

When OFFSET mode is enabled, the first (X,Y) coordinate pair in the array serves as an offset for all other points in the array. In other words, the first X parameter will get added to all the other X coordinates in the array, and the first Y parameter will get added to all the other Y coordinates in the array. This offset feature allows for the arbitrary repositioning of a polygon. The array_depth parameter must include both the initial offsets and all the points to be drawn (e.g. Drawing a polygon with 3 points in OFFSET mode requires an 8 deep array). The contents of the array is not modified by this function.

Warning: Be careful not to specify a pointer and/or depth value which will exceed the length of the array. This will cause the program to crash.

//lines example

int array[8];

pointer ptr;

graph_on();

ptr = &array[2];

array[0]=40; array[1]=60; // point #1 (x,y)

array[2]=120; array[3]=100; // point #2 (x,y)

array[4]=10; array[5]=140; // point #3 (x,y)

array[6]=20; array[7]=80; //point #4 (x,y)

lines(3,ptr,6); //using "polygon mode" to draw a triangle with the last 3 points

lines(3,array,8); //draw a 4 sided figure with all 4 points

array[0] = 15; array[1] = 15; //set offset

lines(0x30013,array,8); //draw same 3 sided figure with different position and width=3

event(1);


Int SetScale(int mode)

This function controls the high resolution graphics facilities on OS5+ devices (also the Tungsten W) which have screen resolutions greater than 160 by 160 pixels.  This function does not actually change the screen resolution, but instead controls the drawing scale.  The mode definitions are in the table below.  This function will return 0 in all cases if the PalmOS high-resolution API is unavailable.

Call this function before drawing graphics or creating a scratch buffer.  Unlike, SetDepth(), this call should generally be made after graph_on() or a Fctl DRAW command.  The scaling can be changed any time, even between drawing routines.

On Sony OS5+ devices, use this function instead to enable high resolution drawing.  On these devices first call SetScale(-1) to  determine if SetScale() scaling will work.  If a 0 is returned, use the Sony(1,x) instead to set the desired screen density mode.

SetScale Mode
Mode Value
Feature
-3
Device Screen Resolution?  (returns: 72, 108, 144, 216, or 288... see mode values in this table for description)
-2
Current Scaling Mode.  (returns: 72, 108, 144, 216, or 288... see mode values in this table for description)
-1
High Resolution Available? (returns: 0=no, 1=yes)
0
Native Scaling Mode (1:1) pixel mapping.  Will enable the highest density mode available for the given screen hardware.  Returns previous scaling mode.
72
Standard Scaling Mode (emulates 160x160 pixel density display).  This is the default mode.  Returns previous scaling mode.
108*
One-And-A-Half Scaling Mode (for 240x240 or 240x320 pixel density displays).  Currently not suported by OS5.  Returns previous scaling mode.
144
Double Scaling Mode.  For 320x320 pixel density displays.  Returns previous scaling mode.
216*
Triple Scaling Mode.  Currently not supported by OS5.  Returns previous scaling mode.
288*
Quadruple Scaling Mode.  Currently not supported by OS5.  Returns previous scaling mode.
*Currently not supported by OS5.

//SetScale.pc
library "PToolboxLib"
main() {
  graph_on();

  if(!SetScale(-1)) {   
    alert("High resolution scaling is not supported on this device.");
    exit();
  }

  SetScale(72); //Set 160x160 scaling mode
  Line(1,0,0,159,159);
  Rect(0x11,100,40,30,30,15); //draw circle

  SetScale(0); //Set native scaling mode (likely 320x320)
  Line(1,159,0,0,159);
  Rect(0x11,80,240,30,30,15); //will be half the scale of the other circle

  event(1);
}

plot(int mode, int x, int y, float radius, float phase)

This function allows the plotting of points specified in either polar or Cartesian formats. Optionally lines can be drawn between the points. The (x,y) coordinate always specifies the origin. The radius and phase fields determine the position of the point to draw relative the origin position. If the radius is set to zero, the origin becomes the drawn point. Internally this function keeps track of the previous point drawn, this allows lines to be drawn connecting the current and the previous point. The following modes are available:

Plot Modes

Bits

Value

Description

1:0

0

Plot the point, also the current point becomes the previous point

1

Draws a solid line between the current point and the previous point. Needs previous point set. After point is plotted, the current point becomes the previous point.

2

Same as mode 0 but uses custom fill pattern (see SetPattern function)

3

Same as mode 1 but uses custom fill pattern (see SetPattern function)

4
0-1
Offset Mode (1=enable, 0=disable).  When offset mode is enabled, the x, y, radius, and phase parameters are treated as offset values from the previous end-point position.

23:16

0-255

Brush (line) width

31:24

0-255

Brush corner radius

If the radius parameter is non-zero, the Mathlib is required.

// plot example - draws a sharp triangle

#define PI 3.14159265

float phase_offset; // controls direction of the sharp point

phase_offset = PI/2; // make triangle point upwards

plot(0,80,80,70,phase_offset); //sets up previous point

plot(1,80,80,30,2*PI/3+phase_offset); // draw first line

plot(1,80,80,30,4*PI/3+phase_offset); // draw second line

plot(1,80,80,70,2*PI+phase_offset); // draw last connecting line

//sketch.c

//A simple drawing program

library "PToolboxLib"

main() {

int e, mode;

graph_on();

while((e=event(1)) != 1) {

if(e==2) mode=0x03050000; //round brush: width=5, radius=3

else mode=0x03050001;

plot(mode,penx(),peny(),0,0);

}

}

int tri(int mode, int x1, int y1, int x2, int y2, int x3, int y3)

Given the 3 point coordinates a triangle is drawn. The following modes are available:

Triangle Mode

0

Frame - solid

1

Fill - solid

2

Frame - current fill pattern (see SetPattern)

3

Fill - current fill pattern (see SetPattern)

4

Returns area of the triangle in pixels (The result may be off by one due to integer rounding errors).

int GetPixel(int x, int y)

Returns the pixel value at the specified position from the draw buffer. If in grayscale mode the value returned is 2 bits.

SetPixel(int x, int y)

Sets the pixel at the specified position in the draw buffer using the current foreground color.

ScrollRect(int x, int y, int width, int height, int direction, int distance)

This function scrolls the contents of a given rectangle in the draw buffer. The direction field format is described in the table below. The distance is specified in pixels.

When scrolling, the graphics in the "evacuated area" will remain untouched.

ScrollRect Direction Format

Bits

Value

Description

1:0

0

Scroll up

1

Scroll down

2

Scroll left

3

Scroll right

4

0-1

Enable erase mode (1=erase vacated space,0=do not erase vacated space)

SetPattern(string pattern)

This functions sets the custom fill pattern. The pattern is 8 by 8 bits and takes on the format of a traditional bitmap string with the two beginning size characters stripped off. Thus all pattern strings must have exactly 16 characters in them. The fill pattern can be drawn with the FillRect, FillLine, ellipse, plot, FloodFill, and tri functions.

The pattern is drawn with the current foreground and background colors (see SetFore & SetBack functions).

Example: SetPattern("fafafafafafafafa"); //sets a grid pattern

NOTE: Custom patterns do not draw correctly for OS3.3 when in 4 bit grayscale mode. This is an OS problem.

Line(int mode, int x1, int y1, int x2, int y2)

This function replaces the built-in "line" function. This function also allows for correct drawing in larger than 160 by 160 custom draw buffers.

Mode Format

Bits

Value

Description

2:0

0

Erase mode

1

Draw (solid) mode

2

Gray (checkerboard) mode

3

XOR mode

4

Custom fill mode (see SetPattern() function)

23:16

0-255

Brush (line) width

31:24

0-255

Brush corner radius

Rect(int mode, int x1, int y1, int x2, int y2, int radius)

This function is a replacement the built-in "rect" function. The modes are as follows: 0=erase, 1=draw, 2=gray(checkerboard), 3=XOR,4=custom fill (as set with SetPattern)).

If bit 4 of the mode field is set, the x2 and y2 parameters are treated as the width and height for the rectangle. Thus Rect(0x11,10,20,30,50,0) will draw a 30 by 50 pixel rectangle at location (10,20).

Frame(int mode, int x1, int y1, int x2, int y2, int radius, int width)

This function is a replacement for the built-in "frame2" function. It offers custom fill drawing (mode=4), shadow effects, a 3D effect (removes corner pixels), and variable brush width (1 to 255). When the brush width is greater than 3 or the mode is set to 4, the radius capability only effects the brush corner radius. Widths greater than 3 are only available to modes 1 (solid fill) and 4 (custom fill). This function will allow for frame drawing in any sized custom buffer (the built-in frame2 does not). The shadow effects are always strait even when the radius is larger than zero.

If bit 4 of the mode field is set, the x2 and y2 parameters are treated as the width and height for the frame. Thus Frame(0x11,10,20,30,50,0) will draw a 30 by 50 pixel frame at location (10,20).

There is also no equivalent frame() function in the toolbox library because the same functionality can be obtained from Frame().

Width Format

Bits

Value

Description

7:0

0-255

Brush (line) width

9:8

0-3

Shadow width (Brush width<4 only)

10

0-1

3D mode (removes corner pixels. Brush width < 4 only)

FloodFill(int mode, int x, int y)

Performs a floodfill at the specified point using the current foreground color. The fill is bounded by pixels having the foreground color. If the color of the point (x,y) is already the foreground color, no fill is performed. A number of fill modes are available:

FloodFill Mode

0

Solid fill - overwrites only pixels with color of point (x,y)

1

Solid fill - overwrites all pixels except foreground color

2

Custom fill (see SetPattern) - overwrites only pixels with color of point (x,y)

3

Custom fill (see SetPattern) - overwrites all pixels except foreground color

When filling extremely complex graphics, the FloodFill algorithm may run out of steam and the fill may be incomplete. This can happen because the algorithm used was given a fixed amount of memory to operate with. Currently the function allocates 8k of heap memory to perform the fill, thus if you are already tight on memory due to the use of scratch buffers, using this function may cause a memory fault.

int OpenFontDb(string database_name)

With this function a font database (.pdb or .prc) file can be opened. The function returns the number of fonts in the database. Once a font database is open, a font can be set using the textattr() built-in function. The font numbers for fonts in the database start at 129 and increment from there. So the first font is accessed with textattr(129,1,0), while the second with textattr(130,1,0), the third with textattr(131,1,0), etc..

If this function is called while a font database is already open, the first gets closed before the second is opened. When the application closed, the font database is automatically closed.

Fonts can placed inside an applet .prc file via the following method: First select a font database .pdb file containing the desired font. Use par to extract the fonts in the .pdb file into separate files (e.g. par x fontdb.pdb). Each font in the .pdb will now have its own unique .pdr file. The first number in the .pdr file name indicates its original index in the .pdb file. Rename the desired .pdr file(s) using the following format: pFNTxxxx.bin, where xxxx corresponds to a user defined 4 digit hex number (e.g. rename 001.0.0.pdr pFNT0001.bin). Each font .bin file should have its own unique hex number. Finally, append the new .bin file(s) to the applet .prc file using par (e.g. par a applet.prc pFNT0001.bin pFNT0002.bin). In the OpenFontDb() call, use the applet .prc name as the font database name (the one specified with @dbname).

Note: If using PilRC to generate a font resource, be sure to terminate the font with a "GLYPH -1" character.  See the PilRC manual for more details.

Here are some links to free fonts: Misc Fonts, Alphafonts,Cool Fonts, New Fonts.

There are also a number of font editing tools available, here are some: xFont (Freeware), NDM Pilot Font Tool ($12), Pilot Font Editor ($18), and Handy Pilot Font Editor ($22.95).

//font example

int a;

a = OpenFontDb("font_db");

if(a > 0) {

textattr(129, 1, 0); //use first font in font_db.pdb, use foreground color, no underline

text(40,80,"Alternative Font!");

}

int FontHeight()

Returns the height in pixels of the current font. See the textattr() PocketC built-in function and the OpenFontDb() PToolbox function for more information about using fonts.

int textbox(int x, int y, int width, int height, int starting_line, string text)

This function clears out a rectangular area and fills it with the specified text. The starting_line field indication what line in the string to start drawing. If starting_line is -1, the total number of lines in the string is returned and the box is not drawn. Otherwise, the number of lines drawn is returned.

The text alignment, color, font, and underline mode can be changed via special escape character sequences. All of the escape sequences begin with the backtick ("`") character. Below is a table showing all the escape codes:

textbox escape codes

``

Draw a backtick

`cXX

Set foreground text color (where XX is the color in hex)

`bXX

Set background text color (where XX is the color in hex)

`fXX

Set the font (where XX is the font number in hex… works with OpenFontDb)

`uX

Set the underline mode (where X can be: none[0], solid[1], or dotted[2])

`aX

Set text alignment. Where X can be: left[0], centered[1], or right [2]. This should be performed only at the start of new lines.

`I

Enable inverted text mode (colors are mangled on pre-OS3.5 systems with screen depth >1, use `c & `b escapes instead)

`i

Disable inverted text mode

//textbox.c

library "PToolboxLib"

main() {

SetDepth(8); //color

graph_on();

frame(1,19,19,130,140,0); //frame the box

textbox(20,20,110,120,0,"`a1`f07CENTERED\n`a0`f00`IInverted text.`i `f01Font change.`f00 `c5fPretty `c60Colored `c7dText.`cff\nNow here is a `u1very-very-long-underlined-word`u0, and a few more words to show the text wrapping.");

event(1);

graph_off();

SetDepth(0);

}


Collision and Intersection Functions

Int SpriteRectColl(int index, int num_sprites, pointer array)

This function allows for the rapid detection of sprite collisions. The index value determines what sprite to check against all the others in the sprite array. The num_spritesparameter determines the number of sprites to check in the sprite array. See the Sprite() function for more details on how the sprite array is structured.

The collision detection works by checking the rectangle boundaries of the sprites in question. If the rectangles overlap a collision is flagged and the index of the intercepted sprite is immediately returned. The collision detection process begins with the first sprite in the array. If no collision is detected with the indexed sprite, the next sprite in the array is then checked. This process continues until either a collision is detected or the last sprite in the array has been checked. If no collision is found, a -1 is returned.

If a sprite is in the "off" command mode, no collision check will occur between it and the indexed sprite.

Additionally, each sprite has a collision mask array element. This collision mask undergoes a bitwise AND with the collision mask of the indexed sprite, if the bitwise AND results in a zero no collision check will occur. For example, suppose the indexed sprite has a collision mask of 0x1002 (has bits 1 and 12 set), only other sprites which have either bits 1 or 12 set in their collision mask can collide with the indexed sprite (e.g.0x1000, 0x1001, and 0x0002 would all collide, but 0x2000 would not). The collision mask is an integer type and thus has 32 bits. Essentially, the collision mask provides a simple mechanism for determining what sprites can collide with each other.

See the sprite.c sample code for an example using SpriteCollRect().

int BmpBackColl(int x, int y, int mask_index)

Determines if the non-zero pixels in a resource bitmap will collide with non-zero pixels in the current draw buffer. Returns 1 for a collision and 0 otherwise. The mask_index refers to a mask bitmap (see TransBmp() function) in the current bitmap database (see OpenBmpDb()). Unlike TransBmp(), the mask bitmap must have the same depth of the draw buffer.

This function requires the bitmap database to be opened in load&lock mode with OpenBmpDb().

This function is approximately twice as slow as FastBmp().

int BmpBmpColl(int x1, int y1, int mask_index1, int x2, int y2, int mask_index2)

Determines if the non-zero pixels in two resource bitmaps will collide. Returns 1 for a collision and 0 otherwise. Returns 1 for a collision and 0 otherwise. The mask indexes refer to a mask bitmaps (see TransBmp() function) in the current bitmap database (see OpenBmpDb()). The mask bitmaps must have the same depth.

This function requires the bitmap database to be opened in load&lock mode with OpenBmpDb().

This function is approximately 2.5 times as slow as FastBmp(). Use BmpRectColl() whenever possible to improve a programs speed.

int BmpRectColl(int x1, int y1, int mask_index1, int x2, int y2, int mask_index2)

Determines if the rectangle spaces of two resource bitmaps will collide. This function does not check any pixels, and is thus quite fast. The mask indexes refer to a mask bitmaps (see TransBmp() function) in the current bitmap database (see OpenBmpDb()). The depths of the bitmaps does not matter.

This function requires the bitmap database to be opened in load&lock mode with OpenBmpDb().

Int InPoly(int mode, pointer array, int array_depth, int x, int y)

Given an array of (X,Y) cordinates (same as in lines() function - mode 3) defining a polygon, and an point (x,y), the function returns a 1 if the point is inside the polygon, and 0 otherwise0. Points on the polygon boarders will either be reported as being inside or outside. In these cases the actual value cannot be determined beforehand, but it will at least be consistent.

There are two modes available, 0 = normal mode, and 1= OFFSET mode. See the lines() function for more information on how OFFSET mode works.

//inpoly.c

//Check every point on the screen to see if it is in the polygon

library "PToolboxLib"

main() {

int x,y;

int p[6];

p[0]=10; p[1]=80; //point #1 (x,y)

p[2]=90; p[3]=40; //point #2 (x,y)

p[4]=140; p[5]=140; //point #3 (x,y)

graph_on();

ClearBuf();

for(x=0;x<160;x++) {

for(y=0;y<160;y++) {

if(InPoly(0,p,6,x,y)) line(1,x,y,x,y);

}

}

event(1);

}

int RectCross(int x1, int y1, int width1, int height1, int x2, int y2, int width2, int height2)

Given two rectangles, this function determines if they intersect, returning a 1 if true.

int LineCross(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)

Given two lines (x1,y1,x2,y2) and (x3,y3,x4,y4), this function determines if they intersect, returning 1 if true. Thanks to BigFoot for this algorithm.

int CircleCross(int x1, int y1, int radius1, int x2, int y2, int radius2)

Given two circles, this function determines if they intersect, returning a 1 if true.


Pseudo-Random Functions

With these functions a reproducible sequence of random numbers can be generated.

int pseed(int seed)

Sets pseudo-random seed. Additionally, the function returns first random value (16 bit number) for the given seed. If the seed is set to zero, the seed is not updated, but the next number in the pseudo-random sequence is returned. This calls the SysRandom Palm OS function.

int prand(int range)

Returns a pseudo random integer between 0 and range-1. Range should not be more than 0xffff. The pseed() function sets the random seed for prand().

int wrand(int weight_string)

This is a random weighted number generation function. Given a string containing a list of weight values, a weighted random number is returned. The weight string should contain a list of numbers of zero or greater, each separated by a comma. The weight base is the sum of all these numbers. The return value of the function is the index of the weight randomly selected. The first number in the weight string is at index 0, the next at index 1, the third at index 2, and so forth. The chance that a given index value will be returned is equal to the that weight value divided by the weight base.

For example, given the weight string "4,1,3,2", the weight base is 10. There is a 4-in-10 chance of that in index of 0 will be returned, a 1-in-10 chance that 1 will be returned, a 3-in-10 chance that a 2 will be returned, and finally a 2-in-10 chance that a 3 will be returned.

If the weight string is "1,1,1,2,1,1", the return value will range from 0 to 5, but a 3 will returned twice as often as the other numbers.

Whitespace in the weight string is ignored. The weight string can contain up to 32 weight values. The pseed() function sets the random seed for wrand().


Maze Generation Functions

MakeMaze(int cols, int rows, int walls, int wallmin, int wallmax, int islands, int clean, int symmetry, int chip_corners)

cols

Number of columns in maze. Must be an odd number.

rows

Number of rows in maze. Must be an odd number.

walls

Percentage of walls of draw. Range is 1 to 100. 100=no rooms. 99=small rooms. <99=larger rooms. If 0, a second (more chaotic) maze algorithm is enabled.

wallmin

Minimum length of a wall segment (unless another wall is reached first). A value of 0 defaults to infinite length. (Unused for maze alg #2).

wallmax

Maximum length of a wall segment (unless another wall is reached first). ). A value of 0 defaults to infinite length. (Unused for maze alg #2).

islands

Number of islands in maze. Use when wallmin=0 and wallmax=0. A negative island value will produce a different style of island. (e.g. try -5 instead of 5)

clean

Percentage of dead-end corridors in maze to remove. Range is 0 to 100. 0=don't clean maze, 100=clean maze completely.

symmetry

0=no symmetry, 1=horizontal symmetry, 2=vertical symmetry, 3=horizontal & vertical symmetry. When using horizontal symmetry, (cols+1)/2 should be an even number. When using vertical symmetry, (rows+1)/2 should be an even number.

chip_corners

Percentage of wall corners in maze to remove. Range 0 to 100. When used with clean>0 and walls<100, this can produce some interesting nooks, as well as a more cave-like appearance.

This function generates a random maze in memory. (It does not display the maze.) The contents of the maze can be accessed via the GetMaze and SetMaze functions. The memory for the maze is handled by the library. 8 bits of storage is allotted for each maze element (this allows for huge mazes). Only one maze is permitted at given time. Calling MakeMaze destroys any existed maze before it creates a new one. MakeMaze uses the pseudo-random number utilities in the library, allowing mazes to be reproduced by setting a random seed via "pseed" before calling MakeMaze.

A second maze algorithm can be enabled by setting the walls parameter to zero. This second algorithm is far more chaotic in that it corridors tend to be on average shorter and maze itself more intricate. The wallmin and wallmax parameters have not effect for alg #2.

This implementation is approximately 40 times faster than equivalent pocketC code.

Thanks to Rich Allen for the initial maze algorithm.

int GetMaze(int x, int y)

Returns an element from the maze. The value will have only 8 bits of information.

SetMaze(int x, int y, int value)

Sets an element in the maze. The value should be at most be 8 bits (between 0 and 255).


Date & Time Functions

int/string DateConv(int date, int format)

This function converts the specified date into another format. See the below table for all the various format modes.

DateConv Formats

Format Value

Return Type

Description

0

integer

Day from YYYYMMDD format

1

integer

Month from YYYYMMDD format

2

integer

Year from YYYYMMDD format

3

integer

YYYYMMDD format to days since January 1st 1904

4

integer

Days since January 1st 1904 to YYYYMMDD format

5

integer

Day of week

6

integer

Day of month (0=1st Sunday, 1=1st Monday, 7=2ndSunday, etc)

7

integer

Days in month

8

string

Short date format from preferences*

9

string

Long date format from preferences*

10

string

MDY With Slashes

12/31/95

11

string

DMY With Slashes

31/12/95

12

string

DMY With Dots

31.12.95

13

string

DMY With Dashes

31-12-95

14

string

YMD With Slashes

95/12/31

15

string

YMD With Dots

95.12.31

16

string

YMD With Dashes

95-12-31

17

string

MDY Long With Comma

Dec 31, 1995

18

string

DMY Long

31 Dec 1995

19

string

DMY Long With Dot

31. Dec 1995

20

string

MY Long No Day

Dec 1995

21

string

DMY Long With Comma

31 Dec, 1995

22

string

YMD Long With Dot

1995.12.31

23

string

YMD Long With Space

1995 Dec 31

24

string

MY Med

Dec '95

25

string

MY Med No Post

Dec 95

26

string

MDY With Dashes (OS4.0+)

12-31-95

* As set in the "Formats" preferences panel.

//DateConv.c

library "PToolboxLib"

int DateDiff(int date1, int date2) {

return(DateConv(date2,3)-DateConv(date1,3));

}

int DateAdj(int date1, int offset) {

return(DateConv(DateConv(date1,3)+offset,4));

}

main() {

int date1 = 20010904;

int date2 = 20010929;

puts("date1 = "+date1+", date2 = "+date2+"\n");

puts("DateDiff = "+DateDiff(date1,date2)+"\n");

puts("date1 + 25 = "+DateAdj(date1,25)+"\n");

}

int PickDate(int mode, int starting_date, string title)

This function pops a the palm date select form. There are three modes available: 0=select day, 1=select week, 2=select month. The initial date selected is specified by the starting_date field, which has a YYYYMMDD format. The title of the pop-up is specified with title.

If a day is selected the function returns that day in a YYYYMMDD format. If the cancel button is pressed, a -1 is returned instead.

//PickDate.c

library "PToolboxLib"

main() {

int day;

clear();

day = PickDate(0,date(0) /*current date*/,"Pick a date...");

if(day==-1) {

puts("No date selected\n");

}

else {

puts("Year="+(day/10000)+"\n");

puts("Month="+((day/100)%100)+"\n");

puts("Day="+(day%100)+"\n");

}

}

int PickTime(int start_time, string title)

This function pops a time input dialog where a single time is entered and returned. The initial start time and the dialog title must be specified. The format for the start_time parameter and the return value is HHMM (where HH=hours and MM=minutes). If the "cancel" button is selected the function returns a -1.

int PickTime2(pointer start_time, pointer end_time, int start_of_day, int end_of_day, int start_hour, string title)

This function pops a time input dialog where two times, a start and end time are entered. The selected start and end times are passed back through pointers. Initial start and end call also be passed to the function through the same pointers. If the values passed in through the start and end pointers are both -1, an no initial time will be shown. Otherwise the start and end times should be of the format HHMM (where HH=hours and MM=minutes).

The start_of_day and end_of_day are both time values of format HHMM, which indicate the start and end of the days schedule. The start_hour parameter is only available for OS3.5 and above.

If the "cancel" button is selected the function returns a 0, if "no time" is selected a 2 is returned, otherwise a 1 is returned indicating that the start_time and end_time variables hold valid data.

//picktime2.c

library "PToolboxLib"

main() {

int start=1030, end=1130;

graph_on();

//default time case

puts("status="+PickTime2(&start,&end,8,18,8,"Case1: default time")+"\n");

puts("Start="+start+"\n");

puts("Stop="+end+"\n");

//no default case

start=-1;

end=-1;

puts("status="+PickTime2(&start,&end,8,18,8,"Case2: no time")+"\n");

puts("Start="+start+"\n");

puts("Stop="+end+"\n");

}

int/string TimeConv(int time, int format)

Converts a time value in a HHMM format into a string. A number of formatting options are available.

TimeConv format

Value

Mode

Return Type

Example (1:00 pm)

0

Minutes

integer

0

1

Hours

integer

13

2

System preferences format*

string

varies

3

Colon

string

1:00

4

ColonAMPM

string

1:00 pm

5

Colon24h

string

13:00

6

Dot

string

1.00

7

DotAMPM

string

1.00 pm

8

Dot24h

string

13.00

9

HoursAMPM

string

1 pm

10

Hours24h

string

13

11

Comma24h

string

13,00

* As set in the "Formats" preferences panel.


DateBook Access Functions

With this family of functions it is possible get, add, and delete DateBook database entries. Repeating appointments and alarms are also supported.

Note that the datebook database format (and access method) will supposedly change completely with the upcoming Palm OS6.0. These functions will not work on that version of the OS and will need updating at that point.

WARNING: These datebook functions do not create a datebook database should none exist. In this case, a fatal (but harmless) error will result should one of these functions be called. Typically this error is encountered when running code on the emulator because by default a DateBook database does not exist. To create the database, an entry must be first added to the DateBook by hand.

DateBook entries are read and appending from a PocketC array of the following structure "3i2s8i". The array contents are defined in the following table.

DateBook Array Format
Index
Type
Description
0
Integer
Date in YYYYMMDD format.
1
Integer
Start Time in HHMM format.
2
Integer
End Time in HHMM format.
3
String
Description. Leave to "" for none.
4
String
Note info. Leave to "" for none.
5
Integer
Alarm Enable. 1=enable, 0=disable.
6
Integer
Alarm Advance Time (in units specified in index #7).
7
Integer Alarm Advance Unit (0=minutes, 1=hours, 2=days). 
8
Integer Repeat (0=no repeat, 1=daily, 2=weekly, 3=monthly-by-day, 4=monthly-by-date, 5=yearly).
9
Integer End Date in YYYYMMDD format. Set to -1 for no end date.
10
Integer Repeat Interval (in units: day, week, month, or year, defined at index #7).
11
Integer Repeat On X. For Weekly mode: bit 0=Sunday, bit 1=Monday, bit 6=Friday)(Can set multiple bits). For Monthly-by-Day mode: 0=first Sunday of month, 1=first Monday, 7=second Sunday, etc.
12
Integer Start of Week. (0=Sunday, 1=Monday, no others supported).
13
Integer Exceptions (GetDate only). 1=has exceptions, 0=none. Generally don't remove entries with exceptions.


int GetDate(int index, int date, pointer array)

Retrieves an appointment for the specified day. The index corresponds to what appointment for the day to access. Index 0 is the first appointment, index 1 is the second, and so on. This function returns a 1 if an appointment exists for the given index and date, and 0 if no more appointments are available. The date field is an integer of the following format YYYYMMDD. The array should be a pointer to an array of the following structure "3i2s9i" (see the DateBook Array format table above for details). Upon success, the array will contain the appointment information.

Repeating appointments will always appear after any non-repeating appointments. For example, if a day has 5 appointments, three of which are repeating, index 0 and 1 will return the non-repeating appointments while indexes 2 through 4 will return the repeating appointments.

//datebook.c
//Example of datebook access functions
library "PToolboxLib"

clearDay(int day) {
while(DelDate(0,day,0)>0);
}

showAppts(int day) {
pointer p;
int i=0;
p=malloct(1,"3i2s9i");
while(GetDate(i,day,p)) {
puts("Day "+day+", Appt #"+i+"\n");
puts("Start time: "+p[1]+"\n");
puts("End time: "+p[2]+"\n");
puts("Description: "+p[3]+"\n");
puts("Note: "+p[4]+"\n");
puts("Alarm Enable: "+p[5]+"\n");
puts("Alarm Advance Time: "+p[6]+"\n");
puts("Alarm Advance Unit: "+p[7]+"\n");
puts("Repeat mode: "+p[8]+"\n");
puts("Repeat end date: "+p[9]+"\n");
puts("Repeat interval: "+p[10]+"\n");
puts("Repeat On: "+hex(p[11])+"\n");
puts("Start of Week: "+p[12]+"\n");
puts("Exceptions: "+p[13]+"\n");
i++;
}
free(p);
}

main() {
pointer p;
int i, day;
day = date(0); //today
clear();
//clearDay(day);

p=malloct(1,"3i2s9i");
p[0]=day; //day
p[1]=900; //start time
p[2]=1000; //end time
p[3]="Morning Meeting"; //description
p[4]="Don't forget your coffee"; //note
p[5]=1; //alarm enable
p[6]=10; //10 minutes advance notice
p[7]=0; //advance unit = minutes
p[8]=2; //repeat weekly
p[9]=-1; //no end date
p[10]=1; //interval - once every week
p[11]=0x3e; //repeat on Monday through Friday (bits 1 to 5)
p[12]=0; //start-of-week = sunday
AddDate(p);

showAppts(day);
}


AddDate(pointer array)

This functions adds an appointment to the DateBook database. The array must have the following structure "3i2s9i" (see the DateBook Array format table above for details).

int DelDate(int index, int date, int archive)

This function removes an appointment from the DateBook database. The entry at the specified index on the specified data is deleted. The date field is an integer of the following format YYYYMMDD. If the archive field is 1, the appointment will be archive on the desktop at the next hotsync, if 0 no archiving will occur.

A value of 1 is returned if the function is successful and a 0 if a failure occurs (e.g. no date entry exists for the give index and date).



Preference Functions

int AppPrefBytes(int byteCount, string CreatorID, int index, pointer version, int saved, pointer charArray)
This function provides byte level read/write access application preferences. It is particularly useful for modifying the preference settings of other applications (e.g. games, etc).

The byteCount parameter determines the number of bytes to write to the preference. If the value is -1, a read operation will be performed instead.

The CreatorID should be a string of four characters. The index refers to what preference "record" to access with the specified CreatorID. The preference record version is passed through a pointer. Specify a pointer to an integer if you want the preference version number back, or just a 0 if no version desired. If the saved parameter is a 1, the "Saved Preferences" database is checked for the preference, if 0, the "Unsaved Preferences" database is checked.

The charArray should be the pointer to an array of char types. In write mode (byteCount >= 0), the contents of the array is written to the preference. In read mode, the contents of the preference is copied to the array. If in read mode and the charArray field is set to zero/null, no read occurs but instead the function will return the number of bytes in the preference.

The function returns -1 if the CreatorID was malformed, and -2 if the preference could not be found (read mode only).

//AppPrefBytes.c
library "PToolboxLib"

set2bytes(int value, int offset, pointer array) {
array[offset] = (value >> 8) & 0xff;
array[offset+1] = value & 0xff;
}

int get2bytes(int offset, pointer array) {
return(((int)array[offset]<<8) | (int)array[offset+1]);
}

set4bytes(int value, int offset, pointer array) {
array[offset] = (value >> 24) & 0xff;
array[offset+1] = (value >> 16) & 0xff;
array[offset+2] = (value >> 8) & 0xff;
array[offset+3] = value & 0xff;
}

int get4bytes(int offset, pointer array) {
return(((int)array[offset]<<24) | ((int)array[offset+1]<<16) | ((int)array[offset+2]<<8) | (int)array[offset+3]);
}

main() {
char array[20], data[20];
int Version = 0x1234;
int i;

clear();
array[0]=0;
array[1]='a';
array[2]='b';
array[3]='c';
array[4]=0;
array[5]='d';
array[6]='e';
array[7]=0;
array[8]='f';
array[9]=0;

set2bytes(0x1122,10,array);
set4bytes(0x33445566,12,array);

//write pref
AppPrefBytes(16,"ZZYZ",1,&Version, 0, array);

//Get pref size
puts("Size="+AppPrefBytes(-1,"ZZYZ",1,&Version,0,null)+"\n");

//Read pref
Version = 0;
AppPrefBytes(-1,"ZZYZ",1,&Version, 0, data);
puts("Version="+hex(Version)+"\n");
for(i=0;i<16;i++) puts((int)data[i]+"\n");

//change one byte
data[8]='x';
AppPrefBytes(16,"ZZYZ",1,&Version, 0, data);

//print out some byte slices
puts("2bytes="+hex(get2bytes(10,data))+"\n");
puts("4bytes="+hex(get4bytes(12,data))+"\n");
}

int GetPref(int pref_number

This function has been depreciated. Use the GetSysPref() function instead (modes 8,9,10, 31,32, & 33).

This function currently returns volume preferences. The following preference numbers are available:

GetPref Preference Numbers

0

System sound volume*

1

Game sound volume*

2

Alarm sound volume*

* The return values are: Off=0, Low=8, Medium=32, High=64. These values can be used in conjunction with the vtone function to respect the users volume preferences.

int GetSysPref(int type)

This function returns the specified system preference value. This function directly calls the PalmOS PrefGetPrefrence API. See the PalmOS reference manual for more detailed information about this API function and how the various types work.

Note: First use type 0 call to determine the preference level available on the device. The preference version varies on OS version (2=OS2.0, 3=OS3.0, 4=OS3.1, 5=OS3.2, 6=OS3.3, 8=OS3.5, 9=OS4.0). Not all preference types are available for all OS versions.

GetSysPref Types

Value

Version

Description

0

2

Preferences Version (returns the preference version)

1

2

Country

2

2

Short Date Format

3

2

Long Date Format

4

2

Week Start Day

5

2

Time Format

6

2

Number Format

7

2

Default Auto-Off Duration

8

2

System Sound Level V20

9

2

Game Sound Level V20

10

2

Alarm Sound Level V20

11

2

Hide Private Records V33

12

2

Device Locked

13

2

Local Sync Requires Password

14

2

Remote Sync Requires Password

15

2

Sys Battery Pref Kind

16

2

Allow Easter Eggs (????)

17

2

Minutes West of GMT

18

2

Daylight Savings

19

2

Ronamatic Char

20

2

Hardkey 1 App Creator ID

21

2

Hardkey 2 App Creator ID

22

2

Hardkey 3 App Creator ID

23

2

Hardkey 4 App Creator ID

24

2

Calc Silk Button App Creator ID

25

2

Cradle Button App Creator ID

26

2

Launcher Silk Button App Creator ID

27

2

Preference Flags (system use)

28

2

Cradle Button 2 App Creator ID

29

2

Animation Level

30

4

System Sound Volume

31

4

Game Sound Volume

32

4

Alarm Sound Volume

33

4

Beam Receive

34

4

Calibrate Digitizer At Reset

35

4

System Keyboard ID

36

4

Serial Default Plug-In Database ID

37

5

Stay On When Plugged-In

38

5

Stay Lit When Plugged-In

39

6

Antenna Raise App Creator ID

40

7

Measurement System

41

8

Show Private Records

42

8

Auto-Off Duration in Seconds

43

9

Time Zone

44

9

Daylight Savings Adjustment

45

9

Time Zone Country

46

9

Auto Lock Type

47

9

Auto Lock Time

48

9

Auto Lock Time Flag

49

9

Language

50

9

Attention Flags

51

9

Default App Creator ID

52

9

Local

SetSysPref(int type, int value)

With this function, any the system preference settings can be changes. Take care with this function because some of the settings cannot be easily changed back by the user (there is not panel access to some of them).

This function directly calls the PalmOS PrefSetPrefrence API. See the PalmOS reference manual for more detailed information about this API function and how the various types work.

See the table in the GetSysPref() for a complete list of preference types.


Array Functions

Copy(pointer src_array, int src_block_size, int src_starting_index,  pointer dest_array, int dest_block_size, int dest_starting_index, int num_blocks_to_copy, int copy_block_size, int mode)

A mass array/data structure copying function, supporting three different copy modes: many-to-many, one-to-many, and swap.  In many-to-many mode, many blocks of data are copied from one array to another.  In one-to-many mode, one block of data is copied from a source array to many blocks in a destination array.  In swap mode, blocks from two arrays are swapped.

The src_block_size and dest_block_size parameters should reflect the actual size of the data structures in the source and destination arrays respectively.  Arrays with no data structure formating have blocks sizes of 1.  The copy_block_size parameter refers to the number of elements from each source block to be copied to each destination block.  The src_starting_index refers to what element to begin copying in each source block (0=first element, 1=second, etc).  The dest_starting_index refers to what element to start copying data into for each destination block.  The num_blocks_to_copy parameter determines the number of blocks to copy.  The modes are as follows: 0=many-to-many, 1=one-to-many, and 2=swap.

pointe Array(string format)

This function allows for multi-dimensional array and data structure emulation. The format string must contain at least two arguments. All arguments should be separated by commas (e.g."i, 10,10" creates a 10 by 10 array of integers). The first argument defines the type of the data (i=int, c=char, f=float, s=string, p=pointer). The remaining arguments determine the sizes and number of dimensions. Each additional argument defines adds an extra dimension of the specified size (e.g. "s,3,4,5" creates a 3 by 4 by 5 multi-dimensional array of strings).

Data in an array is accessed in the same way as in ANSI C (e.g. data = Array("i,6,5,10"); data[4][6][3] = 9; element = data[4][6][3];).

The "type" field can also contain more than one type character. This allows for data structure emulation. For example: data=Array("iscf, 8, 4") creates an 8 deep array of structures. Each structure here is an integer-string-char-float. Thus data[1][0] is an integer, data[1][1] is a string, data[1][2] is a char, and data[1][3] is a float. The number of characters in the type format string must be equal to or less than the size of the last array dimension. For example, if your type string is "iiisc" than the last array dimension should be 5. If the number of type characters is less than the last array dimension size than the type characters will be repeated. For instance, "sif,4,9" will generate an array of 4 structures each with the following format "sifsifsif". Similarly, "i,5,20" will generate an array contains 5 stuctures of 20 integers each.

Numbers can prefix to type characters to signify a repeat count. For example: "5i2s3f" will produce a data structure of "iiiiissff".

The function returns a pointer to the created array/data structure. The memory of the array/data structure should be freed (with the "free" function) when it is no longer needed (e.g. free(data);).

Normally, integer, char, and float elements created by Array() are defaulted to zero. If however, a numerical (integer) value is placed as the LAST type format argument, that value is used as the default (this works for int types only). (e.g. Array("i34,7,8,9") - all data values are defaulted to 34!). Strings are always defaulted to "".

The maximum number of dimensions is 8.

The initial algorithm behind this function was derived from code provided by Wolfgang of BFSoft.

//Array example

pointer data;

data = Array("cis,2,3"); //creates a 2 by 3 array

data[0][0] = 'a'; //char

data[0][1] = 1; //integer

data[0][2] = "first"; //string

data[1][0] = 'b'; //char

data[1][1] = 2; //integer

data[1][2] = "second"; //string

puts(data[0][0]+", "+data[0][1]+", "+data[0][2]+"\n");

puts(data[1][0]+", "+data[1][1]+", "+data[1][2]+"\n");

free(data); //free data memory

//example routine for setting multi-dimensional values quickly

pointer a, b;

int count;

a = Array("i,3,4,5"); // A 2 x 4 x 5 multi-dimensional array of integers

b = &a[0][0][0]; // get pointer to first element in array

count = 3 * 4 * 5; // total number of elements in array

while(count--) *b++=1; //sets all element to 1

int Size(pointer array)

Warning: Only use this function on arrays created with the Array() function.

The Size() function returns the size of an array created with the Array() function. More precisely, the function returns the number of elements to the last array element. So if an array has 20 elements, Size(array) would return 20, while Size(&array[12]) would return 8.

Note that multidimensional arrays created with Array() will be larger than you may think. For example Array("i,3,4") will return an array of size 15 (12 for the data, plus 3 for internal pointers to the data).

To get the true total number of data elements in a multi-dimensional array, specify the pointer the first data element. In the 3 by 4 array case above, Size(&array[0][0]) would return 12.

The Size function can also be used to determine when you have reached the end of an array. If Size() returns 1, the current array index is the last element. (e.g. if(Size(array[x]==1) puts("Last index at "+x+"\n"); )

Sort(int mode, int blockSize, int offset, int numBlocks, pointer arrayPtr)

This function sorts an array of data. All four data types: integer, strings, floats, and chars are supported. Two different sort algorithms are available: quick sort, which is suitable for randomized arrays, and insertion sort, which is more efficient on arrays which are already mostly sorted. There are also a number of sorting options: strait ASCII or natural sorting, case-less or case sensitive sorting, forward or reverse sorting, and flat or pointer based sorting.

The array elements can be grouped into blocks (e.g. 3 elements per block), and these blocks can be sorted rather than the individual array elements. This is useful for sorting data structures emulated with an array. The size of the blocks is determined by the blockSize parameter. The minimum block size is 1 (i.e. one element per block). The offset parameter determines what element in a block to sort on. The first element in a block corresponds to offset 0, the next offset to 1, and so on. The numBlocks parameter defines the number of blocks in the array to sort. The arrayPtr parameter should point to the block where the sort is to begin (not necessarily the first block in the array, but usually). It should point to the first element of this block.

Up to three levels of sorting is supported. What this means is that if two blocks have a matching offset elements, then another offset value can be used to resolve how the blocks are ordered. If the values match again, then a third offset can be used to resolve the ordering. For example, suppose one is sorting a array containing the names of people. The names are to be ordered alphabetically according to last names. The block size is two. The first element in a block is a person's last name, the second element is a person's first name. Doing a two layer sort ensures that if any blocks have the same last name, the first name will be used to resolve the sort order.

If the "Pointer Sort" bit is enabled, the function will sort a set of data structures referenced by pointers. The arrayPtr field must be the pointer to an array of pointers. Each pointer in the array then points to a data structure. The pointers in the array are reordered such that the data structures they reference are sorted. If any of these pointers are zeroed, they will get moved to the end of the array (to the front if reverse sort is enabled for level 1)... useful for compacting an array which has had elements deleted.

Sort Mode

Bits

Feature

0

Sort Algorithm: 0=quick sort, 1=insertion sort

4

Sort Level 1 Reverse: 0=forward sort, 1=reverse sort

5

Sort Level 2 Reverse: 0=forward sort, 1=reverse sort

6

Sort Level 3 Reverse: 0=forward sort, 1=reverse sort

8

Case Sensitivity. 0=case-sensitive sort, 1=caseless sort (string/char type only)(effects all sort levels)

12

Natural Sort. 0=strait ASCII sort, 1=natural sort (string/char type only)(effects all sort levels)

18:16

Sort Level: 0=one level sort, 1=two level sort, 3=three level sort

20
Pointer Sort. 0=flat sort (normal), 1=pointer sort.


Sort Offset

Bits

Feature

7:0

Sort Level 1 offset. Range 0 to 255.

15:8

Sort Level 2 offset. Range 0 to 255.

23:16

Sort Level 3 offset. Range 0 to 254.

Examples:

Given the following array of strings: 12jim, car, 20bill,1.2jack, bag, 4.0greg, 2bob, ape.

A forward ASCII sort yields: 1.2jack,12jim, 20bill, 2bob, 4.0greg, ape, bag, car.

A forward natural sort yields: 1.2jack, 2bob, 4.0greg, 12jim, 20bill, ape, bag, car (Note: the number are ascending!)

//Simple Sort
//To sort a simple array...
//mode=0, blockSize=1, offset=0, array_size= # elements in the array.
Sort(0, 1, 0, array_size, array);

//Sort.c

//A 3 level sort example

library "PToolboxLib"

#define .priority [0]

#define .lastname [1]

#define .firstname [2]

main() {

pointer data;

int i;

clear();

data = Array("iss,7,3");

data[0].priority=3;

data[0].lastname="Jones";

data[0].firstname="Stan";

data[1].priority=2;

data[1].lastname="Smith";

data[1].firstname="Louis";

data[2].priority=3;

data[2].lastname="Jones";

data[2].firstname="Ed";

data[3].priority=2;

data[3].lastname="Smith";

data[3].firstname="Betty";

data[4].priority=1;

data[4].lastname="Wilikers";

data[4].firstname="Rebecca";

data[5].priority=3;

data[5].lastname="Jones";

data[5].firstname="Theresa";

data[6].priority=3;

data[6].lastname="Brown";

data[6].firstname="Bob";

for(i=0;i<7;i++) puts(data[i].priority+","+data[i].lastname+","+data[i].firstname+"\n");

puts("-\n");

Sort(0x20000,3,0x020100,7,data[0]); //3 layer sort: first by priority, then lastname, then firstname

for(i=0;i<7;i++) puts(data[i].priority+","+data[i].lastname+","+data[i].firstname+"\n");

}

Int Query(int mode, int blockSize, int offset, int numBlocks, pointer arrayPtr, pointer matchPtr, pointer countPtr)

Fast array search. Given a value specified through the matchPtr parameter, this function will search through an array for a matching element. It works in a manner similar to the Sort() function with regards to the blockSize, offset, numBlocks, and arrayPtr parameters. The command modes also are similar. Two search modes are available: a binary search and a linear search. Binary searches are in general faster, especially for large arrays, but they require the array to be sorted (use the Sort() function for this). Linear searching simply starts at the beginning of the array and searches upwards either until a match is found, or the end of the array is reached. Like the Sort() function, the contents of the array can be divided into segments of size blockSize. The minimumblockSize value is 1. The offset parameter specified what element in each block to try to match (0=first element, 1=second element, etc.).

The matchPtr parameter is a pointer to the value to match. The value can be of any type, but it must of the same type as the array elements searched. The countPtr parameter should be a pointer to a integer variable. If a match occurs the number of consecutive blocks with the matched will be returned though this pointer. If countPtr is zero, no value will be passed back. The countPtr feature is useful for determining if more than one block matched. In these cases, the Query() function can be called again to resolve the search by using a different offset value. The array should be sorted if the countPtr feature is used. Additionally, if a Query() call is doing a binary search and no match is found, the countPtr variable will return the closest match position (depending on the Return Mode settings, either a block index or a block pointer will be returned as the closest match position).

If a binary search is used, the array must first be sorted. Use the same reverse, case-sensitivity, and natural sort settings with the Query() function as were used with the Sort() function.

If a match is found, either the block number or a pointer to the block number is returned, depending on how the mode parameter was configured. See the Return Mode bit in the Query Mode table below.

Pre 4.0 OS roms suffer from a bug in the binary search API which limits the maximum array size to 5460 elements, beyond this number, the algorithm may yield unpredictable results.

Query Mode

Bit

Feature

0

Search Algorithm: 0=binary search, 1=linear search.

4

Reverse search: 0=forward, 1=reverse. Used only for binary searches.

8

Case Sensitivity: 0=case-sensitive, 1=case-insenstive. Used only for binary searches.

12

Natural Sort: 0=strait alpha-numeric, 1=natural sort. Used only for binary searches.

16

Return Mode: 0=index mode (-1 is a non-match, otherwise index of first matching block returned), 1=pointer mode (0 is a non-match, otherwise pointer to first matching block returned.

//Query.c

library "PToolboxLib"

main() {

string array[14] ={"maple","oak","ash","elm","birch","hickory","oak",

"walnut","cherry","poplar","willow","pine","oak","spruce"};

int i,count;

string value;

clear();

Sort(0,1,0,14,array); //sort the array first

for(i=0;i<14;i++) puts(i+", "+array[i]+"\n");

value="oak"; //value to search for

i=Query(0,1,0,14,array,&value,&count); //do a binary search

puts("Position of first "+value+"="+i+"\n");

puts("Count="+count+" matches\n");

}


String Functions

string Insert(pointer stringPtr, string insertStr, int position, int cutLength)

Given a pointer to a string, this function can cut out a selection of it and/or insert new text at that point. The stringPtr parameter is the pointer the string to operate upon. The insertStr parameter is the text to insert. The position parameter specified the byte offset in the operation string to insert and/or cut text. Zero is the position if the first byte. The cutLength parameter specifies the number of character to remove, starting at the point marked by position.

If insertStr is empty (i.e. ""), no text will be inserted. If cutLength is zero, no text will be cut. If cutLength is greater than zero, this function will return the cut text.

//insert.c

library "PToolboxLib"

main() {

string text = "abcdefghij";

string cut;

cut = Insert(&text,"vwxyz",4,3);

puts("CUT="+cut+"\n"); //will be "efg"

puts("TEXT="+text+"\n"); //will be "abcdvwxyzhij"

}

string Join(int arraySize, pointer array, string separator)

Given an array of values (of any type: string, int, float, or char), this function will convert all the values into strings and join them together with separator string. The resultant string is returned.

This function is particularly useful for turning an array into a CSV (comma separated value) string. Example: result=Join(10,array,",");. The Split() function can be used to reverse the process.

The speed of this function is about twice that of equivalent PocketC code.

Replace(pointer stringPtr, string searchString, string replaceString, int mode, int offset)
This function will perform a "search & replace" operation on the string specified via the stringPtr parameter (it's a pointer to a string).  The searchString field contains the string to search for.  The replaceString field contains the string to replace the found string with.  There are two modes: 0=replace first occurance then exit, and 1=replace all occurances.  The offset parameter specifies the character position in the string to start the search & replace operation.

//Replace.c
//A small example of using Replace
library "PToolboxLib"
main() {
  string str = "this is a test...test...test.";
  Replace(&str,"test","demo",1,0);
  puts(str+"\n");
}

int Split(pointer stringPtr, int count, pointer array, string delimiters)

This function will take a string and segments it into smaller pieces based on a set of delimiter characters. Each segment is then written to the specified array.

The stringPtr parameter is a pointer to the string to split. The count parameter determines the number of values to split and place in the array. The array pointer parameter refers to the array to fill. The delimiters strings contains one or more characters which define the segment boundaries. If for example the delimiters string is ",\n" either the a comma or line-feed encountered will serve as a segment boundary character. The delimiters characters are not included in the segments placed in the array. If the delimiters string is empty (e.g. ""), all white-space characters will be used for the split (equivalent to " \n\r\t").

If the first character in the delimiter string is a "@", the delimiters will be "grouped", meaning that if consecutive delimiter characters are found, they are treated as just one with regards to segmenting the input string. The "@" as the first character will not be treated as a delimiter character. For example, given a string "this,is,,a,,,test". A delimiter string of "," will return 7 segments (3 of them empty), while a delimiter string of "@," will return 4 (the four words). The "group" mode is useful for extracting the words in a string, while the "ungrouped" mode is better for handling CSV (comma separated value) data.

If the count value is zero, the splitting does not occur, but the function will return to total number of split segments found. This can be used to determine the size of the array needed to fill. It can also be used to rapidly count the number of words in a string. If the count is -1, then all the segments are written to the array.

WARNING: If the array is not large enough to hold the all the split segments, a system error will result. Either call Split initially with a count of zero to first determine the number of segments, or set a count value which is equal to or less than the array size.

If a non-zero count value is used, the number of segments split and placed in the array is returned.

The array can be of any type (string, int, float, or char), or even of mixed type. The Split function will automatically perform a type conversion on each segment so that it matches the corresponding array element type.

//split.c

library "PToolboxLib"

scan(pointer str, string delimiters) {

int i,count;

pointer p;

count=Split(str,0,0,delimiters);

puts("word count="+count+"\n");

p=malloct(count,"s");

Split(str,count,p,delimiters);

for(i=0;i<count;i++) puts(p[i]+"\n");

free(p);

puts("\n");

}

main() {

string data = "here is a simple sentence.";

string csv = "last name,first name,birth date,gender,foot size,neck size";

scan(&data,"@ ."); //pass in pointer to string - using "group delimiters" mode

scan(&csv,","); //comma separated values

}

Strip(pointer stringPtr, string stripChars, int mode)
This function removes a set of specficied characters from a string.  The stringPtr parameter must be pointer to a string.  The stripChars fields should contain a string of all characters to be removed.  There are a number of mode configurations, see the table below.  This function is especially useful for stripping extra whitespace characters from strings.

Strip Mode Format
Bits
Effect
0
Strip head.  1=remove all stripChars from the front of the string.  Example: 0x0001
4
Strip tail.  1=remove all stripChars from the end of the string.  Example: 0x0010
8
Skip middle. 1=skip middle of string. 0=remove all stripChars from middle of string. Example: 0x0100
12
Leave one.  1=leave one (the first) stripChars before and after every word.  Example: 0x1000

//Strip.c
//Example using Strip on spaces
library "PToolboxLib"
main() {
  string str = "     this   is  a     test       ";
  string tmp;
  tmp=str; //copy str into tmp;
  puts(tmp+":End\n");
  Strip(&tmp," ",0x0111); //strip out all whitespace from front & back, and skip middle of string.
  puts(tmp+":End\n");
  tmp=str;
  Strip(&tmp," ",0x1011); //strip out all whitespace from front & back, and make words separated only by 1 whitespace
  puts(tmp+":End\n");
}


Translate(pointer string_pointer, string source, string dest)
Given a string, this function maps characters of one type into another type.  The stringPtr parameter must be pointer to a string. The source and dest strings must be exactly the same length.

//Example
string str = "abcdefghij";
Translate(&str,"abcfgij","1234567");
puts(str+"\n");
//Result: "123de45hi67", some letters where remapped into numbers

string Trunc(int mode, int pixel_length, string text)

This function will truncate a string to fit within a specified pixel width.  The truncated string is returned.  If mode is set to 1, the return string will terminate with an ellipse character (...).  Set mode to 0 to avoid the ellipse.


Miscellaneous Functions

int AutoOff(int seconds)

Sets the auto-off timer value. A time of zero seconds turns off the timer. The previous setting is returned.

int Battery(int mode)

This function returns information about the current battery state.

Battery Modes

Mode

Return Value

0

Voltage

1

Critical voltage threshold

2

Warning voltage threshold

3

Battery type. Return values: 0=Alkaline, 1=Nickle Cadmium, 2=Lithium Ion, 3=Rechargeable Alkaline, 4=Nickle Metal Hydride, 5=Lithium Ion 1400.

4

Plugged-in (works on rechargables only). 0=no, 1=yes.

5

Battery percentage remaining (OS3.0+ only)


int Compress(int mode, string database_name, int record_index)

This function can compress and uncompress the data in contained in database records. The function uses a pdoc un/compression algorithm. The compression yield for standard text is typically around 40%. Mileage may vary. The algorithm is assymetrical in that uncompression time is much shorter then the compression time.

If mode bit 4 is set, the specified record will not be uncompressed in place, but rather the record's contents will be uncompressed and placed in a new record at the the end of the database. The function will return the index of this new record. This feature is handy when you only want to read compressed records. You can just decompress a record into a new record, and delete it when done, thus avoiding the need to do a recompression.

This function will return a -1 if the database cannot be found; -2 if the record cannot be found; a -3 upon un/compression failure due to lack of heap memory; and a -4 if an uncompression is attempted on an already uncompressed record. Otherwise the function will return the size of the un/compressed record (unless bit 4 is set, in which it returns the index of the new record).

The database_name string should be the name of the database containing the record to un/compress. Therecord_index field should contain the index of the record to un/compress. The mode bits are described in the table below:

Compression Mode
Bit
Effect
0
0=compress, 1=uncompress
4
0=uncompress in place, 1=uncompress into a new record (returns record index of new record)

Swap(pointer A, pointer B)

Given a pointer to two variables, this function simply swaps the data. This function is approximately 60% faster at swapping non-strings than equivalent PocketC code, and 6 times faster at swapping strings!

//A rather speedy array shuffle algorithm

fastShuffle(pointer array, int size) {

while(size) Swap(&array[random(size--)],&array[size]);

}

int/string Note(int command, string database, string str, int index, string title, int start_pos, int select_length, int max_length)

Note is multi-use text input/viewing function. It also has fast record sorting and searching capabilities.

The text to be edited can either be a string passed to the function or a record in a database. In either case, the maximum string or record size is 32k bytes (this breaks the 4k memo pad size limit!). PocketC is also capable of compiling memos larger than 4k.

When editing text, the screen takes on a form similar to that of the Memo Pad application. The edit form features include a scrollbar, a grafitti shift indicator, up/down hardkey paging, copy/cut/paste/undo/select all (via menu and shortcut keys), the pop-up keyboard, grafitti help, and a "byte count" menu option.

The title field specifies the text to be used as the title of the edit form. The start_pos field specifies the position in the field to place the cursor. The select_length fields specifies the length of text to initially highlight, starting at the start_pos location. The max_length field specifies the maximum allowable size of the edited text in bytes (the highest possible value is 32768 bytes).

The graph_on() command should be called before using Note(), otherwise a system error will result.

Be sure that any records read in by Note() are null terminated (they must end in a zero char), else system crashes will likely occur.

The font of the edit field can be changed by calling textattr() before Note() (custom fonts work too!).

Note Command Format

Bits

Value

Description

Return Value

2:0

0

String In-String-Out mode: Str field contains default string to edit. (no database involved) Similar to getsm().

Returns edited string.

1

Edit-Index mode: Open record in database and edit it. Record specified by index.

-2 if database could not be opened/created. -1 if record could not be opened/created.

2

Edit-Name mode: Find record which starts with string specified in Str. Open the record and edit it. Search starts at record index specified. Example: str = "//toolbox_demo.c"

-2 if database could not be opened/created. -1 if record could not be found.

3

Find-Name mode: Find record which starts with string specified. Does not pull up edit form.

-2 if database could not be opened/created. -1 if record could not be found. Returns index of record otherwise.

4

Search mode: Searches through record for string matching Str field. Start_pos field specifies starting point of search in record. Record is specified by index field.

Returns -2 if database could not be found. -1 if record could not be found or if no string match was made. Otherwise returns starting byte position of match in record.

5

Sort only mode: Does not pull up edit form.

-2 if database could not be opened. 1 otherwise.

4

0-1

1=Sort all records when function exits, 0=do not sort

5

0-1

1=enable caseless sort, 0=use case-sensitive sort

6

0-1

1=use natural string sort, 0=use alpha-numeric string sort

7

0-1

1=reverse sort, 0=forward sort

8

0-1

1=disable text edit, 0=enable text edit

9

0-1

1=no text underlines, 0=text underlined

10

0-1

1=copy selected text to clipboard upon note exit, 0=don't touch clipboard

The natural sort differs from the alpha-numeric sort in how it handles numbers. See below:

Alpha-numeric sort: 100a -> 10a -> 1a -> b

Natural sort: 1a -> 10a -> 100a -> b

For more details on the natural sort algorithm go here.

Note examples:

puts(Note(0,"","Edit this text.",0, "HELLO",0,256,256)); //String-in-string-out case (select all the text)

Note(2,"MemoDB","//toolbox_demo.c",0,"toolbox_demo.c",0,0,4096); //edit toolbox_demo.c file

Note(0x45,"MemoDB", "",0, "",0,0,0); //sort "Memo DB" with natural sort (mode=5 and bit 6 set)

int GetURL(string url, string database, int record_index, int mode, int max_bytes, int timeout)

This function allows users to download content from the internet and place it into a database record. Once a block of data has been downloaded to a record, the user can then do whatever they would like with it. This function requires the INet Library to work (the Net Library will not do). The INet Library comes pre-installed in all Palm VII devices, it also comes with the Palm Mobile Internet Kit and with some modems.

The max_byte field determines the maximum number of bytes to download. The timeout field determines the amount of time in ticks (usually 100 per second) to wait for data (a -1 means "wait forever").

You can test your programs with the POSE emulator using a Palm VII rom by: 1) setting the iMessenger proxy in the Preferences->Wireless window to 209.247.202.106, and 2) by checking the "redirect Net Lib calls to Host TCP/IP" box in the emulator Settings->Properties window.

Here is matrix of all the available modes:

GetURL() Modes

Bit

Description

0

Convert lines-to-strings. If set to 1, replace all carriage returns with null characters (breaks record into strings: 1 string per line)

1

Get HTML header. If set to 1, include HTML header in download.

2

Strip HTML tags. If set to 1, all HTML tags are stripped.

3

Bytes/Lines return value. If set to 1, GetURL() returns number of lines downloaded rather than number of bytes.

Here is a matrix of all the possible return codes:

GetURL Return Codes

-5

URL opened but download failed

-4

URL failed to open

-3

Failure to find, open, or initialize the INet Library

-2

Failed to open/create database

-1

Failed to open/create record

0

URL failed to open

1+

Number of bytes or lines downloaded. See mode bit 3.

//geturl.c

library "PToolboxLib"

main() {

int x;

clear();

x = GetURL("http://www.geocities.com/retro_01775/ptbody.htm","testurl",0,0x6,4000,-1);

if(x<0) {

puts("Failed with return code: "+x+"\n");

}

else {

if(!x) {

puts("No data downloaded.\n");

}

else {

Note(0x301,"testurl","",0,"URL",0,0,32000);

}

}

}

int Handera(int mode, int state)

This function provides access to a number of hi-resolution drawing and screen manipulation capabilities of Handera ™ devices. The grid below shows the available features.

Handera Function Modes

Mode

Feature

0

Device Handera? Returns 0 if not a Handera device. Returns1 if high-resolution QVGA graphics is available, 2 if silk-screen control is available, or 3 if both hi-res and silk-screen capabilities are present.

1

Enable Hi-Resolution Graphics. State: 0=scale-to-fit mode, 1=one-to-one-map mode, 2=return screen mode (0 or 1). In one-to-one-map mode the full 240 by 320 screen becomes usable by the standard drawing commands. Note: The resolution should be set before graph_on(), Form(), or Fctl(LOAD,id) is called.

2

Rotate Screen. State: 0=normal, 1=90º, 2=180º, 3=270º. Returns 1 on success, 0 on failure.

3

Silk Screen Control. State: 0=minimize silk screen, 1=maximize, 2=return state (0 or 1)

4

Pop Rotate Selector. Pops a rotation select dialog. Returns the value selected: 0=normal, 1=90º, 2=180º, 3=270º. State specifies the default rotation selection.

5

Translate Font. Given a lo-res font Id (0 through 7)(via state parameter), a hi-res equivalent font Id is returned. If not a Handera hi-res device, the input state value is returned. Use the return value as the font in textattr() calls.

6

Expand Form. Expands a 160 by 160 form to automatically fit the screen when hi-res graphics are enabled. Very Cool! When using the PToolbox forms, call this mode after the last form object is installed, but before the Fctl DRAW command is given. This also should only be done once per form.  Note: The standard PocketC graphics form cannot be expanded to 240x320 resolution.  Instead create a new form with the Form() function to achieve a blank 240x320 resolution screen.

Example:

main() {
Handera(1, 1); //enable hi-res mode
Form(3000,"Handera"); //create a new form
Handera(6,0); //stretch form
Fctl(DRAW,3000); //draw the form
//other functionality here
}

7

Stretch Bitmaps. State: 1=enable, 0=disable. When enabled, all bitmaps drawn with FastBmp will be scaled (stretched) to fit the 240x320 screen. This only effects the FastBmp function.

See also the Fevent() function for Handera jog dial support.

Int HeapSize(pointer freebytes)

This function returns the number of bytes of the largest contiguous block in the heap. Also, the total number of free bytes remaining in the heap is returned through the freebytes pointer. If freebytes is zero, no "bytes free" value will be returned (e.g. x=HeapSize(0);).

This function is particularly useful for debugging when working with many screen buffers and/or with large multi-dimensional arrays (see Array()). The sizes used the full screens (160 by 160 pixels) is as follows:

Screen Buffer Contiguous Memory Usage

1 bit depth (black & white)

3200 bytes

2 bit (grayscale 4 shades)

6400 bytes

4 bit (grayscale 16 shades)

12800 bytes

8 bit (color)

25600 bytes

16 bit (color)

51200 bytes

// HeapSize example

int freeBytes, largestBlock;

SetDepth(4); //enable 4 bit grayscale mode

graph_on();

largestBlock = HeapSize(&freeBytes);

if(largestBlock < 12800) {

alert("Not enough memory for scratch buffer");

exit();

}

else {

SetDrawBuf(1); //creates new screen buffer
}


Run(string application_name)
This function is similiar to PocketC's built-in launch function in that it will launch another application.  The difference being that app is specified by its name rather than creator ID.  Note: Use the application's "database" name, which may actually differ than name which shows up in the launcher.  Use application like RsrcEdit to determine an application's database name.  Example: Run("Memo Pad");

Also, the Run() function can be used to launch other PocketC applets which are in pdb format (having no icon).  The PocketC runtime or compiler application must be installed on the PDA in order to launch .pdb applets.

int Sony(int mode, int state)

This function provides control over the high-resolution display available on certain Sony devices. The grid below shows the available options.

Sony Function Modes

Mode

Feature

0

Device has Sony high-resolution screen? Returns 1=true, 0=false. State unused.

1

Enable High-Resolution Screen Mode. State 1=320x320 screen, 0=160x160 screen. Note: The resolution should be set before graph_on(), Form(), or Fctl(LOAD,id) is called.  On Sony OS5 devices, this feature has no effect.  Use the SetScale() function instead.

2

Enable Special Hi-Resolution PToolbox Drawing Features. FastBmp(), textbox(), and line() only. State 1=enable, 0=disable (default).  No effect on OS5 Sony devices.  Use SetScale() on OS5 devices instead.

Note: When mode 2 is enabled (special hi-res drawing), the FastBmp() function will draw in a 320x320 resolution, otherwise it will draw with a 160x160 mode (the pixels are doubled so at to appear as if the screen were 160x160). The textbox() function also has additional font capabilities in this "special" drawing mode, notably 8 additional fonts become available: the standard fonts (0-7)(which display small) and their equivalent Sony hi-res fonts (8-15)(these are larger). When the special hi-res mode is disabled, textbox will by default use the sharper Sony hi-res fonts. The line() function will also draw in high resolution (thin lines) when in high-res drawing mode, however line thickness control is not supported. Also, when the special hi-res drawing mode is enabled, both the FastBmp(), textbox(), and line() functions need to use coordinates in a 320x320 space rather than 160x160.

While in high-resolution mode (320x320), all text drawing functions and forms will use the Sony hi-resolution fonts (though textbox() has additional font options enabled through Mode 2).

WARNING: A number of PToolbox drawing features will behave strangely in pre-OS5 Sony high resolution mode (320x320), though many will draw as if in 160x160 mode. The functions which behave oddly or badly in high-resolution mode are:

vtone(int mode, int frequency, int duration, int volume)

This function is similar to the built-in tone PocketC function except is has two additional parameters. There are three modes: 0=blocking, 1=non-blocking; 2=stop sound. In blocking mode, the function exits after the tone finishes playing. In non-blocking mode, the function exits before the tone is finished playing. Calling this function while a non-blocking sound is already playing will interrupt the old sound and immediately play the new one with no silence gap! The "stop sound" mode will terminate a playing non-blocking sound.

The acceptable range of volumes is 0(no sound) to 64(max value). A volume value of 1 is much quieter than 64, however it is not exactly near-inaudible.

See the GetPref function for determining volume preferences.

int Backlight(int mode)

This function can be used to turn the backlight on and off, or get the backlight's current state. The modes are as follows: 0=off, 1=on, 2=return state (0=off, 1=on). If the backlight doesn't exist on the device (like IIIc machines) a -1 will be returned.

int Feature(int mode, string creatorID, int index, pointer value/valuePtr)

This function provides access to PalmOS feature resources.  Features are 32 bit storage elements which are tied to specific creator IDs.  They are useful for storing small amounts of data, and are simplier to use than databases.  There are three mode values: 0=read, 1=write/create, and 2=delete.  The creatorID is a 4 character string which specfies the creator ID to use (note: all creator IDs should be registered here).  The index refers to a slot to access (similiar to a database record number).   A given creatorID may have feature data stored at many indexes (32 bits storage per index).  The value/valuePtr functionality varies depending on the mode.  In read mode (=0), valuePtr should be pointer to an integer (e.g. &variable).  In write/create mode (=1), value refers to the integer which is written to the feature.  The value/valuePtr field is not used on delete operations (=2). 

All features are deleted upon a soft reset.  Also, if an application with the same creator ID is deleted, the feature will also be deleted.

This function returns 1 upon success and 0 if the operation fails.  If valuePtr is 0 on a read operation, no value will be passed back.  This is useful for testing if a feature exists without having to declare a variable to hold a return value.

//Feature.pc
library "PToolboxLib"
main() {
   int data;
   //Write/create features
   Feature(1,"ZZZZ",0,123); //write integer 123 into feature with creatorID="ZZZZ" and index=0
   Feature(1,"ZZZZ",1,456); //write integer 456 into feature with creatorID="ZZZZ" and index=1
   Feature(1,"ZZZZ",2,789); //write integer 789 into feature with creatorID="ZZZZ" and index=2
  
    //Read features
    Feature(0,"ZZZZ",0,&data); //read feature with creatorID="ZZZZ" and index=0
    puts("CID=ZZZZ, index=0, data="+data+"\n");
    Feature(0,"ZZZZ",1,&data); //read feature with creatorID="ZZZZ" and index=1
    puts("CID=ZZZZ, index=1, data="+data+"\n");
    Feature(0,"ZZZZ",2,&data); //read feature with creatorID="ZZZZ" and index=2
    puts("CID=ZZZZ, index=2, data="+data+"\n");

    //Delete a feature
    Feature(2,"ZZZZ",1,0); //delete feature with creatorID="ZZZZ" and index=1

    //Scan for features
    if(Feature(0,"ZZZZ",0,0)) puts("Feature CID=ZZZZ, index=0 exists\n"); //should print
    if(Feature(0,"ZZZZ",1,0)) puts("Feature CID=ZZZZ, index=1 exists\n"); //should not print
    if(Feature(0,"ZZZZ",2,0)) puts("Feature CID=ZZZZ, index=2 exists\n"); //should print
}

int CheckKey(int hardkey)

Given a hardkey number, the function returns 1 if the key is currently being pressed, 0 if not. The hardkey numbers are as follows: 1=calender key, 2=phone key, 3=todo key, 4=note key, 5=page up key, 6=page down key.

This function has no internal sleep delays, as such it is best to call sleep() after you do a round of these, otherwise the battery drain is much faster.

Thanks to Vilmos for this very handy function (he provided the source code).

NoKeyEvents(int mode)

A value of 1 disables all hardkey keydown events. A value of 0 re-enables hardkey downkey events. The CheckKey function can still be used to check the status of the hardkeys.

Since using this function disables downkey hardkey events, pressing the keys will not reset the auto-off timer. The application should periodically call the resetaot built-in PocketC function (when keys are found to be pressed) to prevent the PDA from nodding off.

As a side effect, this function disables the tick system sound normally produced when the page up and down keys are pressed.

int peek(int address)

This function returns the contents of the processor register at the specified address. See the appropriate processor manual for a description of available registers. WARNING: This function also cannot be used with the emulator, it will yield "bus errors".

int poke(int address, int data)

This function writes the contents of the processor register at the specified address. See the appropriate processor manual for a description of available registers. WARNING: The use of this function can be dangerous (possibly causing soft or hard resets), so make sure you know what you're doing before you use it. This function also cannot be used with the emulator, it will yield "bus errors".

int PalmPrint(int command, string data)

This function invokes either PalmPrint or SCS Server software (which must be installed on the Palm device) to perform IR printing. Both products are from Stevens Creek Software. Note: SCS Server is a streamlined version of PalmPrint. There are a number of commands available, see the SDK section at the PalmPrint Developers page for a full list of commands.

This function returns a 0 upon success and a 1 if the PalmPrint or SCS Server is not installed. Other values indicate a failure in the IR printing software.

For the expanded formating commands (#32800 and higher), the data value should be an integer when appropriate.

//palmprint.c

//Here is a sample program.

#define cmdPrintChars 32768

library "PToolboxLib"

main() {

PalmPrint(cmdPrintChars,"HELLO!");

}

int GetTicksPerSec()

Returns the number of ticks per second for the device. This function calls the SysTicksPerSecond OS system function and returns the result.

int GetOS()

Returns a 3 digit hex value corresponding to the OS version being used. (e.g. OS3.3 returns 0x330, OS3.5 returns 0x350).

Int GetPTVersion()

Returns a 3 digit hex value corresponding to the PocketToolbox version being used. (e.g. version 3.00 returns 0x300).

int Vibrate(int count, int rate, int pattern)

This function activates the vibration hardware available on some devices. The count value indicates the number of vibration intervals to perform. The rate indicates how long each interval should be (100 = ~1 sec). While the pattern determines the vibrate pattern. All 32 bits are used for the pattern. Bit 31 (i.e. 0x80000000 or 1<<31) is the starting bit while bit 0 (i.e. 0x00000001 or 1<<0) is the ending bit.

If the count value is a 0, the function will return a 1 if vibration hardware is available and a 0 if not. This function does nothing if no vibration hardware is present.

WARNING: This function uses undocumented PalmOS API (I actually had to do debugger crawl to figure out how it worked). Given that there is no Palm OS documentation supporting this API, there is the possibility that using this feature may do harm your device (e.g. using very small rates like 10 with choppy patterns like 0x55555555?). Then again maybe not, I'm just guessing. As such, use this function at your own risk.

To replicate the standard three vibration alarm do the following: Vibrate(3,78,0x000000FC);


PRC Embedding

It is possible to embed the PToolbox library inside an application's .prc file. With the library embedded, the host application does not require the external version of the library. Furthermore, the library has been divided into a set of plug-ins, where each plug-in contains a set of related functions (Forms, Database, DateBook, String, etc). A user need only include the plug-ins required for the application, it is thus possible to significantly reduce the memory footprint of an embedded library.

An unlock code is required for an embedded library work on a real device (the correct code is not required when using the emulator). Each application with a unique name and creator ID will require its own unlock code. There will be a fee of $30 USD for each unlock code. Payment options are given later in this document. Note: The standalone version of the library having the icon will always remain freeware.

It is possible for other applications to use the embedded library contained in an application. The caveats are that the host .prc must be a PocketC application created with the PocketC Desktop Edition (PDE), and the host application must be installed on the device. See the Satellite Applications section for more details.

The following table list each plug-in and what functions they contain.

Master Plug-in Table
Plug-in Name
Size (in bytes)
Functions
MainLib (color)(required by all apps)
6816
ClearBuf, FastBmp, FontHeight, GetPTLVersion, GetOS, PickColor, SetBack, SetDepth, SetFore, SetPalette, SetTextColor
ArrayPlug
3432
Array, Copy, Query, Size, Sort
BitmapPlug
5428
BmpInfo, CloseBmpDb, GetNumBmps, OpenBmpDb, RmBmp, SaveBmp, Sprite, TransBmp
BufferPlug
3928
CloseBufDb, CopyBuf, CopyRect, CustomBuf, FreeBuf, OpenBufDb, RestoreBuf, SaveBuf, ScrollRect, SetDrawBuf
CollisionPlug
2600
BmpBackColl, BmpBmpColl, BmpRectColl, CircleCross, InPoly, LineCross, RectCross, SpriteRectColl
CompressPlug
1612
Compress
DateBookPlug
3720
AddDate, DelDate, GetDate
DateTimePlug
2236
DateConv, PickDate, PickTime, PickTime2, TimeConv
DBPlug (database)
7620
DBcreate, DBgetfield, DBgetrec, DBinfo, DBmoverec, DBopen, DBrm, DBsetrec
DevicePlug
1192
Handera, SetScale, Sony.  NOTE: This plug will also force low resolution mode on pre-OS5 Sony devices (use the Sony() function to explicitly change to high resolution mode if desired)(This feature prevents the user from forcing your application into high resolution mode which may result in strange behavior because not all PToolbox graphics functions support pre-OS5 Sony high resolution graphics).
DynObjPlug (dynamic form objects)
4036
Button, CmdBarAdd, Dialog, Form, FormBmp, Field, GButton, GSI, Label, List, Slider
FormPlug
15148
FaddList, Fctl, FdelList, Fevent, FgetList, FgetMany, FgetState, FgetText, FmoveObj, FresizeObj, FrevList, FsetList, FsetMany, FsetState, FsetText, OpenRsrcDb, UIColor
FormLitePlug (streamlined version of FormPlug)
10004
FaddList, Fctl (only: DRAW, FREE, HIDE, SHOW, SETACTIVE, UPDATE, LOAD, SETFORM, BINDX, BINDY, BINDKEY, SETMENU, HOOKHARD, HOOKMENU, HOOKTITLE, HOOKSILK, HOOKSYNC, HOOKFORM, HOOKTAB, HOOKLF, HOOKARROWS, FRAME, HELPID, POPHELP, POPALERT, POPDIALOG, EHAND, POPLIST, LISTUP, LISTDOWN, LISTPGUP, LISTPGDOWN, SCROLL, SETFOCUS, GETFOCUS, AUTOSIZE, TRIGTIME, BEXITID), FdelList, Fevent, FgetState, FgetText, FrevList, FsetState, FsetText, OpenRsrcDb, UIColor
Graphics1Plug
7880
Arc, Ellipse, Line, Lines, FloodFill, GetPixel, Frame, plot, Rect, SetPattern, SetPixel, tri
Graphics2Plug
2420
OpenFontDb, textbox
MazePlug 2576
GetMaze, MakeMaze, SetMaze
NetPlug
1636
GetURL
NotePlug
Not Yet Available
Note
PrintPlug
332
PalmPrint
StringPlug
2168
Insert, Join, Replace, Split, Strip, Translate, Trunc
SystemPlug
3196
AppPrefBytes, AutoOff, Backlight, Battery, CheckKey, Feature, GetPref, GetSysPref, GetTicksPerSec, HeapSize, NoKeyEvents, peek, poke, prand, pseed, Run, SetSysPref, Swap, vibrate, vtone, wrand


Embedding Process

  1. Get PDE (PocketC Desktop Edition) & install it.
  2. Download par (http://www.djw.org/product/palm/par/) & put it in the directory where PDE is installed.
  3. Move the PToolbox Plugin directory to reside in the directory where PDE is installed.
  4. Make a copy of the PToolboxLib.lib file and rename it to <your_app_name>.lib (same name as  used for @dbname).  Place this new .lib file in the directory where PDE is installed.
  5. Setup the program header. See Program Header section below.
  6. Compile the program on PDE.
  7. Test app on PalmOS Emulator & Simulator (unlock code is not required to do this). Verify that that there are no missing plugins and that the application yields no unexpected errors/warnings (see Debug Information section for more details).
Program Header
The following is an example application header showing the plug-in embedding. Note, that the PTLreg() must be the first function called when embedding.

//app_file_name.pc
//The following is an example application header

@cid "????"; //creator id (register cid here: http://dev.palmos.com/creatorid)
@name "app_launcher_name"; //app name shown in launcher window
@dbname "app_info_name"; //app name shown in "info" window
@ver "??"; //version number
//@licon1 "icons/large1.bmp";
//@sicon1 "icons/small1.bmp";

//embed MainLib and other plug-ins as needed...
@cmd "par a app_file_name.prc Plugins/MainLib.prc"; //required core library plug-ins
//@cmd "par a app_file_name.prc Plugins/FormPlug.prc"; //list all other plug-ins here
//@cmd "par a app_file_name.prc Plugins/DynObjPlug.prc";

//embed any bitmap, resource, and font databases if desired
//@cmd "par a app_file_name.prc app_bitmaps.prc"; //embed bitmap databases(s)
//@cmd "par a app_file_name.prc app_forms.prc"; //embed resource databases(s)
//@cmd "par a app_file_name.prc app_fonts.prc"; //embed font databases(s)

library "app_info_name"; //need same name from @dbname

main() {
PTLreg("app_cid","app_unlock_code"); //first function call must be to PTLreg(), use same creator Id from @cid

//main program starts here...
}

Debug Information

The embedded application should be throughly tested on both the PalmOS Emulator and Simulator before putting in payment for the unlock code. Both can be obtained here at http://www.palmos.com/dev/tools/. Debug ROMs should be used with the emulator rather than non-debug roms (ones downloaded from devices). Debug roms catch and report bugs that non-debug roms do not. To get debugger roms you need to join the Palm OS Developer Program (http://www.palmos.com/dev/programs/pdp). Note, it is illegal to distribute these roms, so please don't ask me for them.

The correct unlock code is not required for an application with an embbed library to work. A "Bad PTLreg registration string" warning will appear, but this can be safely ignored. No warning will appear if the correct unlock code is entered.

If a function is called, but the corresponding plug-in has not been embedded, the following error will be reported: "Function #X called but plug missing", where X is an ID number. To decode the ID number, open the PToolboxLib.lib file with a text editor. In the comment area of each function the unique ID number and plug-in is listed..

Also if the embedding process is not done properly, "Embedded Error #X" fatal error messages will occur. The table shows all possible error codes.

Embedded Errors Codes (from "Embedded Error #X" messages)
Code (X)
Meaning
0
Program specified by unlock code/cid is not a resource database (.prc file).
1
Program specified by unlock code/cid is missing the embedded PocketC runtime engine.
2
Program specified by unlock code/cid was not created by PDE as a standalone application.
3
Program specified by unlock code/cid is missing the MainLib plug-in.
4
Program specified by unlock code/cid is not installed on device.
5
Bad unlock code. Occurs only on real devices.


Satellite Applications

Other applications can also call the embedded library contained in an another application.  This is useful for creating small support applications for a larger "parent" application.  The PTLreg call must still be the first function called and the cid and unlock code fields should be the same for the parent application.  The child application should also use the same .lib file as the parent.

Satellite applications should use the same library as the main application containing the embedded library, as well as the PTLreg() call with the same parameter values.  Satellite applications should not have any plug-ins embedded within.

Known Library Limitations
Legal Statement

The library is provided AS IS, with no guarantee of fitness for any particular task.   It is the purchaser's responsiblity to test thier applications thoroughly on target devices to ensure proper functionality.  The library comes with NO WARRANTY of any kind. As such, I cannot be held liable for any data loss or damage to a system resulting from the use of this library.

Payment

Every embedded library requires its own unique unlock code.  The unlock code is based upon the host application's creator ID and database name.  Each unlock code will cost $30 USD.

PayPal is the prefered payment method (PayPal is the owned and run by eBay).  Check and money offers are also accepted (email me if so interested at jstadolnik@hotmail.com).

Before making payment first ensure the following:
  1. That the application Creator ID has been registered with PalmSource (http://dev.palmos.com/creatorid)
  2. Choose an application name that you really want.  Changing the application's name (or creator ID) will require an new unlock code and an additional $30.
  3. Validate that the application (containing the embedded libarary) runs without warning messages or errors on both the PalmOS Emulator and Simulator (http://www.palmos.com/dev/tools/).
PayPal Order Form*
Creator ID
Application Name (as specified with @dbname)

*If more than one unlock code is being purchased email me all the creator ID and application name information at jstadolnik@hotmail.com.

Functions

PTLreg(string App_CID, string unlock_code)

This function allows the Pocket Toolbox library to unlocked and embedded in an application's .prc file, eliminating the applications dependency on the standalone version of the library (the one with the icon).  The function has two parameters, the first being the creator ID of the application containing the library, and the second is the unlock code required for the app to work on real devices (the correct unlock code is not requires for emulator/simulator testing).


Tips & Tricks


Limitations

Dynamic forms are supported only on OS3.0+. The GSI(), Slider(), and Gbutton() functions are only supported on OS3.5+.

The following features do not work for OS2.0: dynamic form objects, grayscale graphics, font importing, and non-blocking sound with vtone.

Custom patterns do not draw correctly for OS3.3 when in 4 bit grayscale mode. This is an OS problem.

CopyRect() function modes 1 (Erase) and 6 (Swap) work only for OS3.5 and up. This is an OS problem.

Under OS3.3 there is an intermittent emulator warning which appears when PocketC exists and the Math library is present.

When using CopyRect() with a screen depth of 8 (color) and in Mask mode (=2), the foreground color should be set to 255 and the background to 0, otherwise the masking will modulate the colors in the image.

Contact Information

Please direct any bugs, suggestions, or feedback to jstadolnik@hotmail.com. There is also a PToolboxLib forum, click here to go there. If you have a question, suggestion, or trick which you think others might find useful please post it to the PToolboxLib forum.

If you think you've found a bug, first make sure that you are using the latest versions of the Toolbox library and PocketC. Also, be sure that you are running with the most current Palm OS patch for your operating system. If the problem persist, please include the following information in an email: OS version, PocketC version, screen depth being used, a description of what is happening, and any relevant source code (small, complete test cases are a big help). Thanks.