Documentation  |   Table of Contents   |  < Previous   |  Next >   |  Index

16    Standard IO Applications

Palm OS® Programmer's Companion

Volume I

     

The Palm OS® supports command line (UNIX style) applications for debugging and special purposes such as communications utilities. This capability is not intended for general users, but for developers. This feature is not implemented in the Palm OS, but rather by additional C modules that you must link with your application.


NOTE: Don't confuse this standard IO functionality with the file streaming API. They are unrelated.

There are two parts necessary for a standard IO application:

  • The standard IO application itself.

    A standard IO application is not like a normal Palm application. It is executed by a command line and has minimal user interface. It can take character input from the stdin device (the keyboard) and write character output to the stdout window.

  • The standard IO provider application.

    A standard IO provider application is necessary to execute and see output from a standard IO application. The standard IO provider application is a normal Palm application that provides a field in which you can enter commands to execute standard IO applications. The field also serves as a stdout window where output from the executing application is written.

The details of creating these two different applications are described in the following sections.

Creating a Standard IO Application ^TOP^

To create a standard IO application, you must include the header file StdIOPalm.h. In addition to including this header, you must link the application with the module StdIOPalm.c. This module provides a PilotMain routine that extracts the command line arguments from the cmd and cmdPBP parameters and the glue code necessary for executing the appropriate callbacks supplied by the standard IO provider application.

You build the application normally, but give it a database type of sioDBType ('sdio') instead of 'appl'. In addition, it must be named "Cmd-cmdname" where cmdname is the name of the command used to execute the application. For example, the ping command would be placed in a database named "Cmd-ping".

In the Palm VII handheld, the Network panel, whose log window is a standard IO provider application, has two standard IO commands built-in: info and finger. The ROM has two additional ones: ping and nettrace.

When compiling for the Palm Powered handheld, the entry point must be named SioMain and must accept two parameters: argc and argv. Here's the simplest possible example of a standard IO application.


#include <StdIOPalm.h> 
Int16 SioMain(UInt16 argc, Char* argv[ ]) 
{  
    printf("Hello World\n"); 
} 

Standard IO applications can use several input and output functions that mimic their similarly named UNIX counterparts. These are listed in the summary table at the end of this chapter.

Your standard IO application can accept input from stdin and write output to stdout. The stdin device corresponds to the text field in the standard IO provider application that is used for input and output. The stdout device corresponds to that same text field.

Creating a Standard IO Provider Application ^TOP^

In order for a standard IO application to be invoked and able to provide results, you need a standard IO provider application. This application provides the user interface support; that is, the stdin device support and the stdout window that the standard IO application reads from and writes to.

The standard IO provider launches the standard IO application when the user types in a command line and Return (using Graffiti® or Graffiti® 2 writing). The provider application passes a structure pointer that contains the callbacks necessary for performing IO to the standard IO application through the cmdPBP parameter of PilotMain.

To create a standard IO provider application, you must link the application with the module StdIOProvider.c.

To handle input and output, the standard IO provider application must provide a form with a text field and a scroll bar. The standard IO provider application must do the following:

  1. Call SioInit during application initialization. SioInit saves the object ID of the form that contains the input/output field, the field itself, and the scroll bar.
  2. Call SioHandleEvent from the form's event handler before doing application specific processing of the event. In other words, the form event handler that the application installs with FrmSetEventHandler should call SioHandleEvent before it does anything else with the event.
  3. Call SioFree during application shutdown.

The application is free to call any of the standard IO macros and functions between the SioInit and SioFree calls. If the current form is not the standard IO form when these calls are made, they will record changes to the active text and display it the next time the form becomes active.

A typical standard IO provider application will have a routine called ApplicationHandleEvent, which gets called from its main event loop after SysHandleEvent and MenuHandleEvent. An example is shown in Listing 16.1.

Listing 16.1  Standard IO Provider ApplicationHandleEvent Routine


   static Boolean ApplicationHandleEvent (EventPtr event) 
   { 
      FormType* frm; 
      UInt16 formId; 
  
      if (event->eType == frmLoadEvent) { 
        formId = event->data.frmLoad.formID; 
        frm = FrmInitForm (formId); 
        FrmSetActiveForm (frm);		 
         
        switch (formId) { 
           ..... 
           case myViewWithStdIO: 
              FrmSetEventHandler (frm, MyViewHandleEvent); 
              break; 
           } 
        return (true); 
        } 
  
      return (false); 
      } 

A typical application form event handler is shown in Listing 16.2.

Listing 16.2  Standard IO Provider Form Event Handler


   static Boolean MyViewHandleEvent (EventPtr event) 
   { 
      FormType* frm; 
      Boolean handled = false; 
  
      // Let StdIO handler do its thing first. 
      if (SioHandleEvent(event)) return true; 
  
      // If StdIO did not completely handle the event... 
      if (event->eType == ctlSelectEvent) { 
         switch (event->data.ctlSelect.controlID) { 
            case myViewDoneButtonID: 
              FrmGotoForm (networkFormID); 
              handled = true; 
              break; 
           } 
         } 
  
      else if (event->eType == menuEvent)  
        return MyMenuDoCommand( event->data.menu.itemID ); 
         
      else if (event->eType == frmUpdateEvent) { 
        MyViewDraw( FrmGetActiveForm() ); 
        handled = true; 
        } 
  
      else if (event->eType == frmOpenEvent) { 
        frm = FrmGetActiveForm(); 
        MyViewInit( frm ); 
        MyViewDraw( frm ); 
        handled = true; 
        } 
  
      else if (event->eType == frmCloseEvent) { 
        frm = FrmGetActiveForm(); 
        MyViewClose(frm); 
        } 
  
      return (handled); 
   } 

Summary of Standard IO ^TOP^

Application-Defined Functions

SioMain