Contents > Porting PocketC Applications

Porting PocketC Applications

| General Approach | The basics of to porting to PocketC Architect.
| Breaking Changes | Breaking changes and common porting errors.
| API Conversion Notes | Additional notes on converting from old APIs to new.
| Legacy API | Reference for legacy PocketC APIs.

Contents > Porting PocketC Applications > General Approach

General Approach

Porting an application from PocketC to PocketC Architect is generally simple, and can be done in several phases. You can get your application running by only performing the first porting phase. To take full advantage of the new features and improved performance of the OrbC runtime, you may need to do a full conversion, as described below.

### Phase 1: Compiling a Legacy PocketC Application

The first and easiest step is simply getting your application to compile. The PocketC Architect requires you to specify a few properties of the application in an @app block. The only required @app properties are creator, name, and dbname. For example:

    @app {
      creator = "MyAp"; // same as PocketC's @cid
      name = "App Name"; // display name, same as PocketC's @name
      dbname = "AppName-MyAp"; // name of .prc database, same as PocketC's @dbname
    }

Second, you must include the PocketC compatibility headers. The OrbC runtime has a richer, object-oriented API, and doesn't support the PocketC APIs by default. In order to use the PocketC APIs, you must include the appropriate header files which implement the APIs you intend to use. The easiest way to start is to just include "pc_most.oc", which contains all of the PocketC APIs except those that require native add-ins. This is sufficient for most applications.

    #include "pc_most.oc"

The following table lists all the compatibility headers:

pc_most.oc | Includes all headers except those that would require a native add-in to be installed. Most applications should just use this header.
pc_all.oc | Includes all headers.
pc_io.oc | Implements the Basic I/O functions (e.g. puts, gets, clear).
pc_events.oc | Implements the event functions (e.g. pcevent, key, wait).
pc_string.oc | Implements the string functions (e.g. strlwr, strtok).
pc_math.oc | Implements the mathlib function.
pc_graphics.oc | Implements the graphics functionns (e.g. graph_on, rect, bucreate).
pc_sound.oc | Implements getvol.
pc_date.oc | Implements the time and date functions (e.g. time, date).
pc_database.oc | Implements the database functions (e.g. dbopen, dbcreate).
pc_memo.oc | Implements the memo functions (e.g. mmnew).
pc_serial.oc | Implements the serial port functions (e.g. seropenx). OrbSerial native add-in is required if this header is included. This header is not included by pc_most.oc.
pc_system.oc | Implements the system functions (e.g. clipget, getsysval).
pc_memory.oc | Implements the memory functions.
pc_network.oc | Implements the network functions (e.g. netopen, sockopen). OrbNetwork native add-in is required if this header is included. This header is not included by pc_most.oc.
pc_vfs.oc | Implements the VFS functions (e.g. fileread, filewrite). OrbVFS native add-in is required if this header is included. This header is not included by pc_most.oc.

Once the correct headers are included, there are three primary changes that must be made because of conflicts between the OrbC runtime and PocketC.

- All calls to event() must be replaced with calls to pcevent(). The OrbC runtime uses a global event struct named "event" which conflicts with the old function name.
- All calls to malloct() must have their parameters reversed. The type must be the first parameter, and the count must be the second.
- Any use of CControls must be replaced by the version of CControls which ships with PocketC Architect. This version contains the two changes mentioned above as well as several fixes for bugs that just happened to work on PocketC even though the code was incorrect.

### Phase 2: Convert to the New UI, Eventing, and Drawing Model

Using the new UI and eventing model makes programming new application much easier, and provides many benefits for existing applications. The most important benefit is that the new UI model uses native forms and controls, making applications much faster and more responsive to users. Another notable benefit is that forms and controls using the new UI model can automatically resize on devices with wide/tall screens without writing any code.

The new UI model, eventing model, and drawing model are not compatible with the old models. If you convert one of your forms from e.g. CControls, you must convert all of your forms, use only the new eventing model (no more pcevent(), key(), or similar calls), and use only the Draw methods (Draw.rect() instead of the rect() function). The reverse is also true, you cannot use the new eventing model if you are using the old graphics APIs (such as graph_on).

This phase is optional and straightforward, but may take considerable time. There are three basic steps involved:

- Recreate the forms using the OrbC resource syntax, removing the old code that would generate the forms.
- Create an onopen handler for your form's initialization code.
- Remove the old event loop, and replace it with form and control event handlers.

### Phase 3: Convert to the Object-Oriented APIs

Finally, you can convert from the old PocketC APIs to the new object-oriented APIs. In many cases, the old APIs implemented in the PocketC compatibility headers are just thin wrappers around the new APIs. There are two primary advantages to using the new APIs:

- Improved performance - by not calling through wrappers (some of which are more complicated than others, like the database APIs), you can gain significant performance improvements. Some of the new APIs are much faster than the original PocketC counterparts. For example, PocketC database APIs always closed and re-opened databases between calls for safety, where the OrbC runtime does not need to.
- Advanced functionality - many of the new APIs are richer than the old APIs. For example, the new database APIs allow multiple records and databases to be accessed simultaneously. See API Conversion Notes for more information.

Contents > Porting PocketC Applications > Breaking Changes

Breaking Changes

Legacy PocketC applications can be compiled with PocketC Architect with very few changes. This page lists the changes in the compiler and runtime that are incompatible with legacy PocketC applications. At the bottom of the page is a short list of the most common compiler errors during the porting process, and how to fix them.

### Deprecated Functions

The following functions are no longer supported:

- malloc - use `malloct` or the `new` operator.
- settype - types can no longer be changed at runtime, use `malloct` instead.
- typeof - types can no longer be changed at runtime. `typeof` is a keyword in OrbC.
- seropen - use PocketC's `seropenx`, or convert to using the Serial object.
- unpack - instead of reading into a byte array and unpacking it, use `Serial.recv` or `SerialStream.read` to read the bytes in the intended format.
- deepsleep - no equivalent.
- dbmovecat - no equivalent.

### Changed Functions

The following functions have changed either their signatures or behaviors:

- event - this function has been renamed to `pcevent`.
- malloct - the parameters have been reversed.
- mathlib - this function always returns 1. All math functions that require MathLib will cause a runtime error rather than returning an invalid result as they did in PocketC.
- memcpy - this function now requires that the source and destination have the same memory types. In PocketC, this function would change the memory type at the destination to match the source.
- tone - a volume parameter has been added
- seropenx and other serial functions - return true for success and false for failure, rather than 0 for success and an error code on error.

### All or Nothing Conversions

- Old graphics APIs (such as `graph_on`, `rect`) cannot be used in the same application as the Draw object.
- Event handlers (and therefore the new UI) cannot be used in the same application as the PocketC eventing functions (such as `pcevent`, `wait`).
- `atexit` cannot be used in an application with event handlers. Use the app onstop event instead.

### Native Libraries

Any new native code should be written as an OrbC native add-in. However, native libraries are supported with a few limitations:

- The native library interface function `callBI` only supports the following functions - `graph_on`, `hookmenu`, `hooksilk`, `event`, `malloc`, and `textattr`.
- Native libraries can take pointer parameters, but cannot call `deref` on non-parameters unless they are global values.
- To pass a function address to `Fctl` when using PToolboxLib, first cast it to a `pointer`.
- Several PToolboxLib functions are not yet compatible with the OrbC runtime, and will cause unexpected behavior or crashes.

For native library developers, do the following things to ensure that your library runs correctly:

- Use the extended APIs to deal will strings. DO NOT use the old lockString/unlockString. DO NOT use your own code for directly manipulating strings. See the original PocketC native library document for details. Strings that are pushed and popped to be handled as they always have.
- In you library's open function (where you allocate the global memory block), set the reserved field to 0x12345678 to inform the OrbC runtime that your library will not try to access strings manually.
- When calling deref(), never increment/decrement the pointer that is returned. In PocketC, this usually worked. In OrbC, this is not valid. Call deref() for each value you need to access.

### Other Issues/Differences

- Older versions of CControls had bugs which made them incompatible with the OrbC runtime. Only the version of CControls which is included with PocketC Architect can be used.
- In an application that uses the output form or graphics form (rather than the new UI), when the `main` function exits, the application remains on the final form it was on. In order to go back to the application launcher, call `exit`.
- Macros which contain other macros are now implemented properly
- Function pointers in OrbC do not require a dereference. PocketC-style function pointer still require a dereference for compatibility.
- `&array` is no longer valid. Instead, used `array` or `&array[0]`.
- `@bmp`, `@res`, and the PRC properties are no longer supported. Instead, use the new OrbC resource syntax.

### Common Compiler Errors

In porting your legacy PocketC application to OrbC, there are several common errors you may encounter:

- expected resource type - this is most commonly caused by the presence of one of the unsupported PRC properties, such as `@bmp` or `@licon1`.
- cannot call a non-funcptr type - this is most commonly caused by an attempt to call the PocketC `event()` function. In OrbC, call `pcevent()` instead.

Contents > Porting PocketC Applications > API Conversion Notes

API Conversion Notes

Much of the legacy PocketC APIs maps easily to the new object-oriented APIs. However, it may be helpful to cover a few specific categories.

### Graphics

In legacy PocketC, graphics were created by drawing directly to the screen, generally after opening the graphics form by calling `graph_on()`. Although easy to use, this mechanism results in global graphics state that doesn't fit nicely in a structured application, and doesn't work well with gadgets. The approach taken in OrbC is to draw using a Draw object. A Draw object is used to draw to either a form, a gadget, or an offscreen buffer. Drawing to a Draw object must be done between calls to begin and end.

- The drawing primitives and color functions map almost exactly to Draw methods. The meanings of some of the color values have changed.
- `bitmap` is not directly supported - embed your bitmaps using the bitmap resource syntax instead.
- Offscreen buffers are now just Draw objects. Use the `draw` method to copy between them.
- Resource bitmaps are not directly supported - embed your bitmaps using the bitmap resource syntax instead.
- `graph_on` and `graph_off` are no longer required, just attach the Draw object to the current form.
- `pushdraw` and `popdraw` are equivalent to calling `begin` and `end`.
- `saveg` and `restoreg` can be done by copying a form using `copyForm`.
- Screen attributes and color depth are available on the application object.

### Events

The eventing model in OrbC is substantially different that legacy PocketC. The most important difference is that your application doesn't have an event loop at all. Instead, you implement handlers for form and control events.

- Pen events are available on forms and gadgets
- Event data returned by functions such as `key` or `penx` is now available within event handlers in the global Event structure.
- The functions that wait for events such as `waitp` or `getc` no longer apply.

### Database

The legacy PocketC functions always operated on the current database and record. In OrbC, multiple databases and records can be opened at once.

- The legacy functions map to methods on either Database, DBRecord, or DatabaseMgr.
- The format used by OrbC read/write methods is slightly different than those used by `dbreadx` and `dbwritex`. See type strings for details.

Contents > Porting PocketC Applications > Legacy API

Legacy API

Library Routines

# Built-in Functions

- Basic I/O
- Event System
- String
- Math
- Graphics
- Color Tables
- Sound
- Time/Date
- Database I/O
- Memo Pad I/O
- Serial I/O
- System
- Memory Management
- Networking
- VFS

### Basic I/O

- puts(string text) - append a string to the output form. Does not add a newline. (To add a newline, add a "\n" to the end of your string).
- gets(string prompt) - presents an input dialog with the given string as a prompt. Returns a string if the user pressed OK, or an empty string if the user presses Cancel. The dialog can contain 2 lines of text, use the '\r' character to wrap to the second line.
- getsd(string prompt, string defaultValue) - presents an input dialog with the given string as a prompt and a default value in the input field. Returns a string if the user pressed OK, or an empty string if the user presses Cancel. The dialog can contain 2 lines of text, use the '\r' character to wrap to the second line.
- getsi(int x, int y, int w, string defaultValue) - presents an input dialog at the x, y coordinates specified, with the given string as a default value. The input dialog will have an edit field of width w (though the dialog will be larger). A string is returned when the user presses OK (there is no cancel option).
- getsm(int x, int y, int w, int lines, string defaultValue) - exactly like getsi(), but the edit field created is lines lines tall.
- alert(string msg) - displays an alert dialog with the given text.
- alertc(string title, string message, string buttons, int type) - displays an alert dialog with the specified title, message, and buttons. buttons is the name of a button, or a string containing several buttons names separated by a colon (e.g. "OK:Cancel"). Returns the 0-based index of the button pressed. type is one of the following: [0] info, [1] question, [2] warning, [3] error.
- promptc(string title, string message, string buttons, int type, pointer pentry) - displays a prompt dialog with the specified title, message, and buttons. buttons is the name of a button, or a string containing several buttons names separated by a colon (e.g. "OK:Cancel"). The entered string is placed in the string pointed to by pentry. Returns the 0-based index of the button pressed. type is one of the following: [0] info, [1] question, [2] warning, [3] error.
- confirm(string msg) - pops up an alert dialog with the given text and Yes/No buttons. Returns 1 for Yes, 0 for No.
- clear() - clears the output form.

### Event System

- pcevent(int time) - check for events in the event queue. If time is zero, event returns immediately. If time is one, the function waits indefinitely for an event to occur. If time is >1, time represents the timeout period in 1/100s of a second, e.g. event(50) waits for up to one half second. Events are as follows: [0] none, [1] key (character), [2] pen down, [3] pen up, [4] pen move, [5] page up key (or 5-way up), [6] page down key (or 5-way down), [7-10] hard key1-4, [11] menu button, [12] launch/home button, [13] find button, [14] calc button, [15] HotSync button, [16] 5-way left, [17] 5-way right, [18] 5-way select, [23] redraw, [24] resize. In order to receive messages from the hard keys or silkscreen buttons (7-15), you must call the corresponding hook function (see below). In order to receive the resize event, you must call enableresize() before opening the graphics form.
- key() - retrieve the character written during the last pcevent()
- penx() - retrieve the x value of the pen event processed by the last call to wait, waitp, or pcevent. Also retrieves the new form width for resize event.
- peny() - retrieve the y value of the previous pen event. Also retrieves the new form height for resize event.
- npenx() - retrieve the x value of the previous pen event in native coordinates.
- npeny() - retrieve the y value of the previous pen event in native coordinates.
- pstate() - returns 1 if the pen in down, 0 otherwise.
- bstate() - returns the state of the hard buttons. Returns [0] neither, [1] page up, [-1] page down.
- wait() - wait for a pen or character event. Returns the character written to the graffiti area or -1 for pen event. Use penx() and peny() to retrieve the location of a pen event, or key() to retrieve the character.
- waitp() - wait for a pen event. Use penx() and peny() to retrieve the location of a pen event.
- getc() - wait for and return a character written to the graffiti area.
- hookhard(int bHook) - if bHook is nonzero, hard keys (address button, etc.) are not processed by the OS. Instead, they are intercepted by the pcevent() function. If bHook is zero, hard key presses are no longer intercepted.
- hookmenu(int bHook) - if bHook is nonzero, the menu silkscreen button is not processed by the OS. Instead, it is intercepted by the pcevent() function. If bHook is zero, menu button presses are no longer intercepted.
- hooksilk(int bHook) - if bHook is nonzero, all silkscreen buttons are not processed by the OS. Instead, it is intercepted by the pcevent() function. If bHook is zero, silkscreen button presses are no longer intercepted.
- hooksync(int bHook) - if bHook is nonzero, the HotSync cradle button is not processed by the OS. Instead, it is intercepted by the pcevent() function. If bHook is zero, the button events are no longer intercepted.

### String

- strlen(string) - returns the length of a string.
- substr(string, int first, int len) - returns a string which consists of len characters from the original string starting at first character. (e.g. `substr(“Hello”, 1, 3)` returns “ell”)
- strleft(string, int len) - returns the len leftmost characters from the string.
- strright(string, int len) - returns the len rightmost characters from the string.
- strupr(string) - returns the original string in all uppercase.
- strlwr(string) - returns the original string in all lowercase.
- strstr(string str, string sub, int first) - searches str for a substring sub starting at the character first. Returns the starting position of sub within str or -1 on failure.
- hex(int n) - returns the hexadecimal representation of n
- format(float f, int prec) - returns the string representation of f with prec decimal places.
- strtoc(string str, pointer ptr) - fill the array of chars pointed to by ptr with the characters from the string str. ptr must either point to an array of characters long enough to hold the string plus the terminating 0, or it must be a pointer alloced with malloct().
- ctostr(pointer ptr) - takes the char array pointed to by ptr, and returns a string composed of its characters. The memory pointed to by ptr must be of type char and must end with a 0.
- strtok(string source, pointer result, string delims, int first) - breaks a string into tokens which are delimited by a character from the delims string. The resulting string is stored in the location referenced by the pointer res. Returns the location to use for first for the next call, or -1 if the end was already reached. If result is 0 or null, returns the number of tokens in the string. Example: string result; int first; first = strtok("1:2#3", &result, "#:", 0); while (first != -1) { puts(result); first = strtok("1:2#3", &result, "#:", first); } This would print "1" "2" and "3"

### Math

- cos, sin, tan, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh (float) - returns the expected trigonometric value, using radians. These functions require MathLib to be present.
- pow(float x, float y) - returns x^y. This function requires MathLib to be present.
- atan2(float y, float x) - returns the arctangent of y/x. This function requires MathLib to be present.
- sqrt(float x) - returns square root of x. This function requires MathLib to be present.
- log(float x) - returns natural log of x. This function requires MathLib to be present.
- log10(float x) - returns log base 10 of x. This function requires MathLib to be present.
- exp(float x) - returns e^x. This function requires MathLib to be present.
- rand() - returns a random float between 0 and 1.
- random(int n) - returns a random int between 0 and n-1.
- mathlib() - always returns 1.

Note: Functions that require MathLib will display an error if the library is not present.

### Graphics

- General APIs
  - graph_on() - switches to the graphics form.
  - graph_off() - switches from the graphics form to the output form. The appearance of the graphics form is not preserved.
  - enableresize() - enables resizing and resize events. This function must be called before the first call to graph_on().
  - title(string title) - set the graphic form title to title.
  - clearg() - clear the graphics form.
  - saveg() - save the graphics form internally. Returns 0 on failure, 1 otherwise.
  - restoreg() - restore the graphics form previously saved by a call to saveg(). This can only be called once for each time saveg() is called.
  - pushdraw() - push the current drawing state (pen colors, native/standard drawing mode, etc.). This function should be called before calling any other drawing function. This does nothing on OS < 3.5.
  - popdraw() - pop the previous drawing state. This function should be called after completing a set of drawing operations (matching the previous call to pushdraw()). This does nothing on OS < 3.5
  - drawnative(int bNative) - sets the current drawing mode to native coordinates if bNative is true, standard (160x160) otherwise, which determines how coordinates are interpreted. You must return to standard drawing mode before allowing any UI to be drawn (e.g. calling alert() or confirm()). When drawing natively, first call pushdraw(), then this function, complete your drawing, then popdraw() to reset the drawing state. Because this mode affect OS UI (such as the find dialog box), you should only enable native drawing mode when drawing, and disable as soon as possible.
  - getscreenattrib(int attrib) - get a screen attribute. Available attributes are width[0], height[1], density[5].
- Text Operations
  - text(int x, int y, string str) - display a string str at locations (x,y).
  - textattr(int font, int color, int underline) - set the current text drawing attributes. font is a number 0-6. Available fonts are normal[0], bold[1], large[2], symbol[3], symbol11[4], symbol7[5], LED[6], Large Bold[7] (OS 3.0 only). color is a number 0-2. Available colors are background[0], foreground[1], inverted[2]. underline is a number 0-2. Underline modes are none[0], solid[1], dotted[2].
  - textalign(char alignmentYX) - sets the alignment that text() uses. The parameter is a number between 0 and 22, where the first decimal digit describes the vertical alignment, and the second describes the horizontal. left[0], center[1], right[2].
  - textwidth(string str) - returns the width in pixels of str with the current font settings.
- Drawing Primitives
  - pixel(int col, int x, int y) - draws a pixel at (x, y) in color col. background[0], foreground[1], XOR[3].
  - line(int col, int x1, int y1, int x2, int y2) - draws a line from (x1, y1) to (x2, y2) in color col. background[0], foreground[1], dotted[2], XOR[3].
  - rect(int col, int x1, int y1, int x2, int y2, int radius) - draws a rectangle from (x1, y1) to (x2, y2) in color col with corners of radius radius. A radius of 0 has square edges. background[0], foreground[1], XOR[3]. (This function doesn't support dotted)
  - frame(int col, int x1, int y1, int x2, int y2, int radius) - same as rect() but not filled. background[0], foreground[1], dotted[2], XOR[3].
  - frame2(int col, int x1, int y1, int x2, int y2, int radius, int width) - same as frame() but allows specification of width (1-3 only).
  - bitmap(int x, int y, string bits) - draw a bitmap at (x,y). The bits string is a list of hexadecimal digits in the following form: "wwxxxxxxxx..." where 'ww' is the width of the bitmap (i.e. '0a' is a 10-pixel wide bitmap), and 'xxx...' are the bits of the bitmap, each character representing 4 pixels. So, "0affc804804ffc" is a 10x4 bitmap of a rectangle ('ffc' is a solid line, '804' represents a left and right edge.) Note: there are several PocketC utilities available that will generate these strings for you.

        Example:
        A 10x4 rectangle "0affc804804ffc"
        8 4 2 1  8 4 2 1  8 4 2 1
        X X X X  X X X X  X X 0 0 = ffc
        X 0 0 0  0 0 0 0  0 X 0 0 = 804
        X 0 0 0  0 0 0 0  0 X 0 0 = 804
        X X X X  X X X X  X X 0 0 = ffc

- Color - only available on OS 3.5+
  - getcolordepth() - get the current color depth in bits per pixel.
  - setcolordepth() - set the current color depth. Returns 1 if successful, 0 otherwise. This function will only succeed on OS 3.5+.
  - setfgi(int index) - set the current foreground color to the given index (see color table below). Returns the previous index. This function does nothing on OS < 3.5.
  - setfg(int r, int g, int b) - set the current foreground color to (r,g,b). The nearest color available at the current color depth is used. This function does nothing on OS < 3.5.
  - setbgi(int index) - set the current background color to the given index (see color table below). Returns the previous index. This function does nothing on OS < 3.5.
  - setbg(int r, int g, int b) - set the current background color to (r,g,b). The nearest color available at the current color depth is used. This function does nothing on OS < 3.5.
  - settextcolori(int index) - set the current text color to the given index (see color table below). Returns the previous index. This function does nothing on OS < 3.5.
  - settextcolor(int r, int g, int b) - set the current text color to (r,g,b). The nearest color available at the current color depth is used. This function does nothing on OS < 3.5.
  - rgbtoi(int r, int g, int b) - return the index of the color nearest (r,g,b) at the current color depth. Returns 0 on OS < 3.5.
  - getuicolor(int item) - return the system color for a given UI item. Returns 0 on OS < 3.5. Available items are ObjectFrame[0], ObjectFill[1], ObjectFG[2], ObjectSelFill[3], ObjectSelFG[4], MenuFrame[5], MenuFill[6], MenuFG[7], MenuSelFill[8], MenuSelFG[9], FieldBG[10], FieldText[11], FieldTextLines[12], FieldCaret[13], FieldTextHighlightBG[14], FieldTextHighlightFG[15], FieldFepRawText[16], FieldFepRawBG[17], FieldFepConvText[18], FieldFepConvBG[19], FieldFepUnderline[20], FormFrame[21], FormFill[22], DialogFrame[23], DialogFill[24], AlertFrame[25], AlertFill[26], OK[27], Caution[28], Warning[29]
  - choosecolori(string title, pointer pIndex) - displays a color selection dialog where pIndex is a pointer to an int that contains the initially selected color index and is set to the selected color index. Returns 0 if the user selects cancel, 1 otherwise. Returns 0 on OS < 3.5.
- Offscreen Buffers
  - bucreate(int width, int height) - create an offscreen buffer of the specified width and height (in standard coordinates). Returns the buffer id on success, 0 on failure.
  - budelete(int id) - delete the given buffer.
  - buset(int id) - set the current drawing buffer where id is a previously created buffer or 0 to specify the screen. All the text, primitive, and bitmap operations will be drawn into the selected buffer.
  - bucopy(int sid, int did, int x, int y, int mode) - copy all of buffer sid to buffer did (or 0 for screen) at (x,y), using the specified drawing mode. Available drawing modes are paint[0], erase[1], mask[2], invert[3], overlay[4], paintInverse[5], swap[6].
  - bucopyrect(int sid, int xs, int ys, int w, int h, int did, int xd, int yd, int mode) - copy the rectangle at (xs,ys) with the given width and height from buffer sid to buffer did (or 0 for screen) at (xd,yd), using the specified drawing mode. Available drawing modes are paint[0], erase[1], mask[2], invert[3], overlay[4], paintInverse[5], swap[6].
- Resource Bitmaps
  - resopen(string dbname) - open the given resource database. Returns the database id on success or 0 on failure.
  - resclose(int id) - close the given resource database.
  - bitmapr(int bmpid, int x, int y) - draw the bitmap with resource id bmpid at (x,y). The current app .prc database (if compiled as a .prc file with PocketC Dekstop Edition) is searched, along with any resource databases currently opened with resopen().
  - bitmaprm(int bmpid, int x, int y, int mode) - draw the bitmap with resource id bmpid at (x,y), using the specified mode. The current app .prc database (if compiled as a .prc file with PocketC Dekstop Edition) is searched, along with any resource databases currently opened with resopen(). Available drawing modes are paint[0], erase[1], mask[2], invert[3], overlay[4], paintInverse[5], swap[6].

### Color Tables

- 8-bit Color Table:

  0 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  16 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  32 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  48 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  64 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  80 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  96 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  112 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  128 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  144 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  160 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  176 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  192 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  208 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  224 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  240 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

- 4-bit Color Table:

  0 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

- 2-bit Color Table:

  0 |  |  |  |

- 1-bit Color Table:

  0 |  |

### Sound

- beep(int type) - generates a system sound, where type is between 1 and 7. Available sounds are info[1], warning[2], error[3], startup[4], alarm[5], confirmation[6], and click[7]. Note: not all sounds are unique in current versions of PalmOS.
- tone(int freq, int dur, int vol) - generates a tone of frequency freq (in Hz), and duration dur (in milliseconds), at volume vol.
- tonea(int freq, int dur, int vol) - asynchronously generates a tone of frequency freq (in Hz), duration dur (in milliseconds), at volume vol. Calling this function with a 0 for any parameter will silence any currently playing sound. This function does nothing on OS < 3.0.
- getvol(int type) - gets the current system volume setting for the given sound type. Available types are system[0], game[1], alarm[2]. This function returns maximum volume on OS < 3.0.

### Time/Date

- ticks() - the number of clock ticks since last reset. On all current devices there are 100 ticks per second. You can call getsysval to determine this value.
- seconds() - the number of seconds since Jan 1, 1904 minus 2^31.
- secondsx(int date, int time) - the number of seconds since Jan 1, 1904 minus 2^31 for the specified date and time. The date and time are integer values like those returned by time() and date() (e.g. yyyymmdd).
- time(int mode) - returns the current time in the given mode. [mode 0] integer value (hour*100+minute) [mode 1] string value (as determined by system preferences) [mode 2] integer value (hour*10000+minute*100+sec).
- timex(int secs, int mode) - same as time(), but uses the time specified by secs which is the number of seconds since Jan 1, 1904 minus 2^31.
- date(int mode) - returns the current date in the given mode. [mode 0] integer value (year*10000+month*100+day) [mode 1] short string value [mode 2] long string value (as determined by system preferences).
- datex(int secs, int mode) - same as date(), but uses the time specified by secs which is the number of seconds since Jan 1, 1904 minus 2^31.
- selecttime(int secs, string title) - displays the time selection dialog with the given title and initial time specified by secs which is the number of seconds since Jan 1, 1904 minus 2^31. Returns the selected time, or 0 if cancelled.
- selectdate(int secs, int selectBy, string title) - displays the date selection dialog with the given title and initial date specified by secs which is the number of seconds since Jan 1, 1904 minus 2^31. Returns the selected date, or 0 if cancelled. selectBy may be day[0], week[1], month[2].

### Database I/O

All the database functions work on databases with any creator id/type, but use of resource databases may cause unexpected results. When creating a new database, the database will have creator id 'PktC' and type 'user'. An attempt to overwrite a database with a given name but different creator/type will fail. Only one database can be open at a time.

- dbopen(string name) - opens the database named name, returns 0 on failure. The current record is set to 0.
- dbcreate(string name) - creates and opens a database named name, returns 0 on failure. If another database of the same name and creator ID/type 'PktC' / 'user' exists, it will first be erased. The current record is set to 0.
- dbcreatex(string name, string creator, string type) - creates and and opens a database named name with creator ID creator and type type, returns 0 on failure. If another database of the same name and creator ID/type exists, it will first be erased. The current record is set to 0.
- dbrename(string name) - rename the currently open database. name must be 31 characters or less.
- dbrec(int recnum) - sets the current record to rec and the current position to 0. If the record is greater than the current number of records, future reads will fail. However, the next write will create a new record at the end of the database and set the current record to it.
- dbnrecs() - returns the number of records in the current database.
- dbsize() - returns the size of the current record in bytes.
- dbwrite(data) - write the value data at the end of the current record. data can be of any type, use casting to ensure that data is the correct type. Use caution when writing in the middle of a database with null-terminated strings, as they are of unknown length.
- dbread(char type) - read a value from the current position in the database. A value must be read as the same type that it was written. Available types are 'c' char, 'i' int, 'f' float, 's' string.
- dbreadx(pointer ptr, string format) - Using the current database, read data of the the given format into the data pointed to by ptr. format is the same as dbwritex(). Returns the number of values read.
- dbreadxc(pointer ptr, string format, int count) - Same as dbreadx, but repeats the specified format count times. Returns the number of values written.
- dbwritex(pointer ptr, string format) - Using the current database, write data pointed to by ptr and described by format at the current position in the current record. format contains a list of data types, one per value following ptr. Data types are 'c' - a single byte, 'i2' - a 2-byte word, 'i4' - 4-byte double word, 'f' - a 4-byte float, 'sz' - a null-terminated string, 's#' - a string of length #. To specify more than 1 of a type, prefix it with a count number - '12i2' means 12 2-byte words. When a count number would be is next to a size number, separate them with a '.' - '12i2.8f' means 12 2-byte words followed by 8 floats. Returns the number of values written.
- dbwritexc(pointer ptr, string format, int count) - Same as dbwritex, but repeats the specified format count times. Returns the number of values written.
- dbpos() - get the current location in the database. -1 indicates the end has been reached.
- dbseek(int loc) - set the current location. If this value is greater than the length of the database, the next call to dbread() will set the position to -1.
- dbbackup(int flag) - flag [0] clear backup bit, [1] set backup bit, [2] query backup bit.
- dbclose() - close the current database.
- dbdelete() - delete and close the current database.
- dberase() - erases the content of the current record (but does not remove the record).
- dbdelrec(int recnum) - deletes the specified record from the current database. This removes the contents of the record and sets its 'delete' bit, which will cause the record to be removed on the next HotSync. Returns 0 on error.
- dbarcrec(int recnum) - archives the specified record from the current database. This maintains the contents of the record and sets its 'delete' bit, which will cause the record to be removed and archived on the next HotSync. Returns 0 on error.
- dbremrec(int recnum) - removes the specified record from the current database. This removes all traces of the record. Returns 0 on error.
- dbmoverec(int from, int to) - remove the record at index from and insert it at index to.
- dbenum(int first, string type, string creator) - enumerates the databases installed on the device, by type and/or creator. Returns 0 if no more databases are available. The type and creator are each 4 character strings, or the empty string for a wildcard. To get the first database, you must set first=1. To get the subsequent matching databases you must set first=0.
- dbgetcat() - returns the category ID for the current record.
- dbsetcat(int catID) - sets the category ID for the current record (must be a number between 0 and 15).
- dbcatname(int catID) - returns the name of the category given its category ID.
- dbsetcatname(int catID, string name) - sets the name of the category given its category ID.
- dbinfo(string name, pointer pstrType, pointer pstrCreator) - retrieve the type and creator ID of the database named name. pstrType and pstrCreator must be pointers to strings. Returns 1 on success, 0 on failure.
- dbtotalsize(string name) - retrieves the total size of all records in the database named name. Returns 0 on failure.
- dbgetappinfo() - converts the current database's app info block to a record, and sets the current record to this temporary record. If successful, returns the temporary record id. On failure, sets the current record to -1. Before closing the database, you must remove this temporary record or convert it back to an app info block.
- dbsetappinfo() - removes the current record and sets the app info block to its contents. Sets the current record to -1. Returns 1 on success.

### Memo Pad I/O

- mmnew() - create a new, empty memo, returns 0 on failure.
- mmfind(string name) - opens the memo with name as its first line, returns 0 on failure.
- mmfindx(string name) - opens the memo with name as its first line, and returns the record id of the memo, or -1 for failure.
- mmopen(int id) - opens the memo with the given id, returns 0 on failure. This function is not recommended, but is included for completeness.
- mmputs(string) - appends the given string to the end of the memo.
- mmgetl() - retrieves a string from the current position in the memo. Does not include the newline.
- mmeof() - returns 1 if at the end of the memo, 0 otherwise.
- mmrewind() - rewind the current memo to the beginning.
- mmclose() - close the current memo.
- mmdelete() - delete and close the current memo.
- mmcount() - returns the number of records in the memo pad database.

### Serial I/O

- seropenx(int port, int baud) - open the serial/IR port using the new serial manager. Returns 1 for success. Requires OS 3.3 or higher. Available port numbers are 0x8000 - cradle port, 0x8001 - raw IR port (works on devices not based on OMAP processor), 0x6972636D - IrComm (works on most newer devices), 0x7266636D - RfComm (bluetooth).
- sersettings(string flags, int timeout) - flags is a 4-char string in the form "8N1C" [bits/char (6,7,8) parity (N,E,O) stop bits (1,2) flow control (X-software, C-CTS, R-RTS, H-CTS/RTS, N-None)]. timeout is the number of clock ticks (1/100 sec) to wait between bytes for data. Returns 0 for success.
- serclose() - close serial port.
- sersend(char byte) - send a byte, returns 1 on success.
- serrecv() - receive a byte, returns an integer 0-255 on success, > 255 on failure.
- serdata() - return the number of bytes waiting in the receive buffer.
- serwait(int nBytes, int timeout) - wait until nBytes bytes are available in the receive buffer. timeout is the number of ticks (1 tick typically equals 1/100 second) allowed between consecutive bytes. Returns 0 for timeout/error, 1 for success.
- serbuffsize(int size) - allocates a serial buffer of the given size (+32 bytes for PalmOS overhead). This function should only be called if you seem to be having serial overrun problems. Returns 1 on success, 0 on failure.
- sersenda(pointer pData, int size) - send size bytes of data from an array. The memory pointed to by pData must be ints or chars, and each element my be one byte.
- serrecva(pointer pData, int size) - receive size bytes of data into an array. The memory pointed to by pData must be ints or chars, and each element will be filled with one byte.

### System

- sleep(int ms) - sleeps for ms milliseconds.
- resetaot() - resets the auto off timer.
- getsysval(int index) - gets a system value. Currently supported values: [0] Username, [1] OS Version, [2] OS Version string, [3] Serial number, [4] ticks per second.
- launch(string creatorID) - closes PocketC and launches the application with the given creator ID. Returns 0 on failure, does not return on success. Ex: launch("memo"); // Opens memo pad. Ex: launch("lnch"); // Opens the application launcher if running OS 3.0
- clipget() - returns the current clipboard contents (if text).
- clipset(string text) - sets the text clipboard contents.
- exit() - exits immediately. On OS 3.0+, exits to application launcher. On OS 2.x, exits to PocketC.
- atexit(pointer func) - The function whose address is passed to this function is called immediately when the user attempts to switch apps (but not when the user presses the Done button or the Applet|Stop menu item). Such a function must run very quickly and may not affect the display or use the event system (through pcevent(), puts(), alert(), graphics functions, etc.). Warning: it is not generally safe to make assumptions about where your applet was suspended when func began to execute.
- version() - always returns 710, since PocketC Architect implements compatibility with PocketC 7.1.0.

### Memory Management

A few notes that will help understand the following section: In a normal computer, memory is divided into bytes and words. PocketC divides its memory into elements called "values". Each value stores a basic PocketC type (int, char, float, string, pointer). Also, each element of memory knows its own type (thus the need for the settype() function).

- malloct(string blockTypes, int nBlocks) - allocates nBlocks blocks of memory whose types are described by blockTypes. blockTypes is a string of characters representing data types ( 'i'-int, 'p'-pointer, 'c'-char, 'f'-float, 's'-string). The memory block is initialized to 0 for numeric types and "" for strings. e.g. malloct(3, "piis") will allocate 12 values -- the first will be a pointer, the second/third an int, the fourth a string, the fifth another pointer, the sixth/seventh ints... A type can be preceded by a count number to repeat the type - 'p2is' is the same as 'piis', '8f' is the same as 'ffffffff'.
- free(pointer ptr) - releases the memory of the block pointed to by ptr which was previously allocated by malloct(). When an applet exits, all blocks that are still allocated will automatically be freed to prevent memory leaks.
- memcpy(pointer dest, pointer src, int size) - copies the data from the block of size size pointed to by src to the block pointed to by dest. The types of the destination values must match the types of the source values.

### Networking

PocketC's networking support is based on BSD-style sockets. This documentation assumes you understand the functionality and is not intended to teach you to use BSD-style sockets. Currently only TCP sockets are supported. Almost all of the networking functions returns 0 on success and an error code on failure. To interpret the error code, you can call the neterror() function provided in neterror.h (in PocketC's UtilCode directory) which will convert the error code to a string.

All the functions that take and return addresses use a string representation. An address string is a dotted IP address with optional port, such as: `"129.22.104.22:80"` An empty string is interpreted as the local address. Thus, when calling sockbind(), only a port needs to be specified: `":1234"`. All socket methods (and the DNS methods) have a timeout associated with them. This timeout value is globally set using netsettimeout().

- General APIs
  - netopen() - opens the networking stack and connects it to the network according to system settings. This function must be called before any other networking function. Return 0 on success.
  - netclose() - closes the networking stack.
  - netlocaladdr() - gets the local address string of the device when connected, otherwise an empty string. This function always returns the empty string when run on the emulator.
  - nethostbyname(string name, pointer paddr) - Looks up the given name using DNS, putting the resulting address in the string pointed to by paddr. Returns 0 on success.
  - nethostbyaddr(string addr, pointer pname) - Looks up the given addr using DNS, putting the resulting name in the string pointed to by pname. Returns 0 on success.
  - netgettimeout() - gets the maximum wait time for network operations, defined in ticks. -1 implies infinite.
  - netsettimeout(int timeout) - sets the maximum wait time for network operations, defined in ticks. -1 implies infinite.
- Sockets
  - sockopen(pointer pid) - opens a TCP socket, returning the new socket id in the int pointed to by pid. Returns 0 on success.
  - sockclose(int id) - closes the given socket. You must call this function when you are finished using a socket. Returns 0 on success.
  - sockaccept(int id, pointer pnewid) - accepts a new socket, and returns the new socket id in the int pointed to by pnewid. Returns 0 on success.
  - sockbind(int id, string localAddr) - binds the given socket to a local address. Generally only a port needs to be specified, such as `":1234"`. Returns 0 on success.
  - sockconnect(int id, string addr) - connects a socket to the the remote address addr. Returns 0 on success.
  - socklisten(int id, int backlog) - starts listening on the given socket, with the specified backlog. Currently the Palm OS only supports 1 for the backlog parameter. Returns 0 on success.
  - socksend(int id, pointer data, string format, int count) - sends the data pointed to by data and described by format (with the format repeated count times). format is the same as described by dbwritex(). Returns 0 on success.
  - sockrecv(int id, pointer data, string format, int count) - receives data into the memory pointed to by data and described by format (with the format repeated count times). format is the same as described by dbwritex(). Returns 0 on success.
  - sockshutdown(int id, int dir) - shuts down the socket for the given direction dir. Available directions are input[0], output[1], and both[2].
  - socklocaladdr(int id) - returns the local address of a connected socket.
  - sockremoteaddr(int id) - returns the remote address of a connected socket.

### VFS

The Palm OS support for Virtual File Systems (VFS) allows an application to read and write files to removable storage, such as a compact flash card or memory stick. Almost all of the VFS functions returns 0 on success and an error code on failure. To interpret the error code, you can call the vfserror() function provided in vfserror.h (in PocketC's UtilCode directory) which will convert the error code to a string. This file also contains #defines for many useful VFS constants. Some methods do not work as documented on the emulator (attributes and dates will be incorrect).

To access a file, you must first retrieve the volume on which it resides using enumvols(). This function will enumerate all volumes on the device - if the device does not support VFS, no volumes will be returned. Once you have retrieved the volume id, you can use it to create and open files and directories. To get a list of all the files in a directory, first open the directory with volopendir(), then enumerate through the files and directories using direnum(). The get the files in the root directory, call direnm(dirid, "/"). Unlike traditional operating systems, the Palm OS VFS support does not support a concept of "current directory". Instead, all paths are fully specified for a given volume.

- Volumes
  - enumvols(int first, pointer pvolid) - enumerates all the volumes on the device, returning the volume id in the int pointed to by pvolid. Set first to true to enumerate the first volume, set it to false for all subsequent calls. Returns 0 if there are no more volumes. You must close a volume when you have finished using it by calling volclose().
  - volclose(int volid) - closes the given volume.
  - volopenfile(int volid, string path, int mode, pointer fileid) - opens a file at the given path, using the specified mode, returning the new id of the file in the int pointed to by pfileid. Returns 0 on success. mode is a combination of the following flags: vfsModeRead[2], vfsModeWrite[5], vfsModeReadWrite[7], vfsModeCreate[8], vfsModeTruncate[16]. You must close the file when you have finished using it by calling fileclose().
  - volopendir(int volid, string path, pointer pdirid) - opens a directory at the given path, returning the new id of the directory in the int pointed to by pfileid. Returns 0 on success. You must close the directory when you have finished using it by calling dirclose().
  - volcreatefile(int volid, string path) - creates a new empty file at the given path. Returns 0 on success.
  - volcreatedir(int volid, string path) - creates a new empty directory at the given path. Returns 0 on success.
  - voldelete(int volid, string path) - deletes a file or empty directory at the given path. Returns 0 on success.
  - volrename(int volid, string path, string newname) - renames a file or directory specified by path. newname is the new name of the file or directory without the path. Returns 0 on success.
  - volexport(int volid, string name, string path) - exports the database name from internal storage to a file at path. Returns 0 on success.
  - volimport(int volid, string path, pointer pname) - imports the .pdb/.prc file at path. The name of the database is returned in the string pointed to by pname. Returns 0 on success.
  - volgetdefaultdir(int volid, string type) - retrieves the default directory for a file with the given mime type.
  - vollabel(int volid) - retrieves the label of the given volume.
- Directories
  - dirclose(int id) - closes the given directory.
  - dirsetdate(int id, int which, int date) - sets the date (number of seconds since Jan 1, 1904 minus 2^31) for the given directory. Returns 0 on success. which must be one of vfsDateCreated[1], vfsDateModified[2], vfsDateAccessed[3].
  - dirgetdate(int id, int which) - gets the date (number of seconds since Jan 1, 1904 minus 2^31) for the given directory. Returns 0 on success. which must be one of vfsDateCreated[1], vfsDateModified[2], vfsDateAccessed[3].
  - dirgetattribs(int id) - gets the attributes for the directory. Returns a set of flags which may include: vfsAttrReadOnly[1], vfsAttrHidden[2], vfsAttrSystem[4], vfsAttrVolumeLabel[8], vfsAttrDirectory[16], vfsAttrArchive[32], vfsAttrLink[64].
  - dirsetattribs(int id, int attribs) - sets the attributes for the directory. attributes is a set of flags (see dirgetattribs()).
  - direnum(int id, int first, pointer pname, pointer pattribs) - enumerates the directories and files in the given directory. Pass true in first when calling for the first time, false to continue the enumeration. Returns the name of the file/directory in the string pointed to by pname, and the attributes (see dirgetattributes()) in the int pointed to by pattribs. Returns 0 if no more files/directories can be found, 1 otherwise.
- Files
  - fileclose(int id) - closes the given file.
  - fileread(int id, pointer data, string format, int count) - reads data from the file into the memory pointed to by data and described by format (with the format repeated count times). format is the same as described by dbwritex(). Returns 0 on success.
  - filewrite(int id, pointer data, string format, int count) - writes the data pointed to by data and described by format (with the format repeated count times). format is the same as described by dbwritex(). Returns 0 on success.
  - filesetdate(int id, int which, int date) - sets the date (number of seconds since Jan 1, 1904 minus 2^31) for the given file. Returns 0 on success. which must be one of vfsDateCreated[1], vfsDateModified[2], vfsDateAccessed[3].
  - filegetdate(int id, int which) - gets the date (number of seconds since Jan 1, 1904 minus 2^31) for the given file. Returns 0 on success. which must be one of vfsDateCreated[1], vfsDateModified[2], vfsDateAccessed[3].
  - fileseek(int id, int offset) - sets the current file offset.
  - filetell(int id) - retrieves the current file offset.
  - fileeof(int id) - returns true if the end of the file has been reached.
  - filesize(int id) - gets the current size of the file.
  - fileresize(int id, int size) - resizes the file to the given size.
  - filegetattribs(int id) - gets the attributes for the file. Returns a set of flags which may include: vfsAttrReadOnly[1], vfsAttrHidden[2], vfsAttrSystem[4], vfsAttrVolumeLabel[8], vfsAttrDirectory[16], vfsAttrArchive[32], vfsAttrLink[64].
  - filesetattribs(int id, int attribs) - sets the attributes for the directory. attributes is a set of flags (see filegetattribs()).