Dear Up The Wave:

The Voyager Software Development Kit (SDK) contains PhAB-based web widgets
along with internet-ready applications and source code you can edit. Since
you probably already have all the software needed to use the Voyager SDK
(QNX 4.23, Watcom 10.6, TCP/IP for QNX, and Photon 1.12), your first
prototype can be ready in a matter of days.

Your application can take advantage of the PtWebClient widget provided in the
kit. This widget interacts with the Voyager Browser engine in either of two
modes. The compact mode of the browser is designed for embedded applications 
(it provides basic functionality like HTML formatting on an extremely small
footprint). The full mode of the browser has extensive functionality
typically required for desktop applications.

Lets say you need a simple web browser with basic features. The browser could
include a text field for specifying a URL and four buttons for navigating
through web pages: Back, Forward, Reload, and Stop. Once the PtText and
PtButton widgets are placed on the base window along with a PtWebClient
viewing area, we will add the code that is needed for the PtWebClient widget
to display web pages.

The first thing we will need to do is create a header file that includes the
PtWebClient widget header file, then define it as a global header file in
PhAB's Application Startup Information dialog. The contents would look
something like this:

/* Header webbruce.h for Browser Application */
#include <Ph.h>
#include <Pt.h>
#include <Ap.h>
#include <photon/PtWebClient.h>

We also need to define which version of the browser engine (i.e. the server
portion of the browser) the PtWebClient widget will start. Either copy the
sample code provided in the kit, or using PhAB, click on the Web Server
resource in the Control Panel (Pt_ARG_WEB_SERVER resource of the PtWebClient
widget), then enter a value of voyager.server for the full mode version.

Now we can display a web page in the widget. In the example code below, the
activate callback of a PtText widget provides an input field for the user to
choose a URL. The code sets the Pt_ARG_WEB_GET_URL resource of the
PtWebClient widget to the user-provided value in the PtText field. The length
argument to PtSetArg() can be set to WWW_ACTION_DISPLAY or WWW_ACTION_SAVEAS.
To display the URL in the browser, we will use WWW_ACTION_DISPLAY.
Alternatively, a value of WWW_ACTION_SAVEAS can be used to download and
save a URL.

/* Standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* Toolkit headers */
#include <Ph.h>
#include <Pt.h>
#include <Ap.h>

/* Local headers */
#include "webbruce.h"
#include "abimport.h"
#include "proto.h"

int change_page( PtWidget_t *widget, ApInfo_t *apinfo, 					             PtCallbackInfo_t *cbinfo )
{
PtTextCallback_t *text_data = cbinfo->cbdata;
PtArg_t  args[1];
char  *url;

/* Eliminate unreferenced warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

if( cbinfo->reason == Pt_CB_ACTIVATE )
	if( ( cbinfo->reason_subtype == Pt_EDIT_ACTIVATE) && 
	     ( text_data->length>0 ) ){
		url = text_data->text;
		PtSetArg( &args[0], Pt_ARG_WEB_GET_URL, url, 
				 WWW_ACTION_DISPLAY );
		PtSetResources( ABW_WebClient, 1, args );
	}
return( Pt_CONTINUE );
}
...
The PtWebClient widget's Pt_CB_WEB_ERROR callback can 
be used as shown below to determine if there was a problem accessing the URL.
You can also use the Pt_CB_WEB_ERROR callback to detect if the voyager.server
process fails to start.

...
int handle_error( PtWidget_t *widget, ApInfo_t *apinfo, 					            PtCallbackInfo_t *cbinfo )
{
PtArg_t  args[1];
PtWebErrorCallback_t *web_error = cbinfo->cbdata;
char  buf[1024];

...
sprintf( buf,"error:%d?%s", web_error->reason, web_error->url );
PtSetArg( &args[0], Pt_ARG_WEB_GET_URL, buf, WWW_ACTION_DISPLAY);
PtSetResources( widget, 1, args);

return( Pt_CONTINUE );
}
...

Once web pages have been loaded, the user might want to move forwards or
backwards in the history, reload a page, or stop a page from loading. Let's
look at the activate callback code for Back button. First, the code checks if
a page exists in the history queue by doing a PtGetResources() on the
Pt_ARG_WEB_NAVIGATE_PAGE resource. Provided the user has already viewed a
page, we can set this resource to a new direction. The resource also
accommodates page scrolling up, down, left, or right. The code for the
Forward button would be similar.
...
int go_back( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )
{
int  *nav_dir;
PtArg_t  args[1];

PtSetArg( &args, Pt_ARG_WEB_NAVIGATE_PAGE, &nav_dir, 0 );
PtGetResources( ABW_WebClient, 1, args );
if( *nav_dir & ( 1 << WWW_DIRECTION_BACK ) ){
	PtSetArg( &args[0], Pt_ARG_WEB_NAVIGATE_PAGE, 
			         WWW_DIRECTION_BACK, 0 );
	PtSetResources( ABW_WebClient, 1, args );
           }

return( Pt_CONTINUE );
}
...

As the user moves back and forth through the page history, we can update the
PtText widget with the URL currently being displayed. The following code
would be attached to the Web URL callback (Pt_CB_WEB_URL) of the
PtWebClient widget.


int new_url( PtWidget_t *widget, ApInfo_t *apinfo, 
			    PtCallbackInfo_t *cbinfo )
{
PtWebUrlCallback_t *cb = cbinfo->cbdata;
PtArg_t  args[1];
PtSetArg( &args[0], Pt_ARG_TEXT_STRING, cb->url, 0 );
PtSetResources( ABW_url_field, 1, args );

return( Pt_CONTINUE );
}

The code for the Stop button's activate callback uses the PtWebClient widget's
Pt_ARG_WEB_STOP resource to stop a page from loading:

int stop_loading( PtWidget_t *widget, ApInfo_t *apinfo, 
	            PtCallbackInfo_t *cbinfo )
{
PtArg_t  args[1];

PtSetArg( &args[0], Pt_ARG_WEB_STOP, 0, 0 );
PtSetResources( ABW_WebClient, 1, args );

return( Pt_CONTINUE );
}

The code for the Reload button's activate callback uses the PtWebClient
widget's Pt_ARG_WEB_RELOAD resource to reload the current URL.

int reload_url( PtWidget_t *widget, ApInfo_t *apinfo, 
		        PtCallbackInfo_t *cbinfo )

{
PtArg_t  args[1];

PtSetArg( &args[0], Pt_ARG_WEB_RELOAD, 0, 0 );
PtSetResources( ABW_WebClient, 1, args );

return( Pt_CONTINUE );
}

Complete source code for this example browser application is available for
downloading from /usr/free/qnx4/photon/examples/ brucebrowser.tgz. However,
the PtWebClient widget is by no means limited to the features used in this
example. For a demonstration, visit www.qnx.com/iat and create your own
web-ready demo disk. The single, self-booting demo disk features the Voyager
Browser (built from the PtWebClient widget), an embedded web server, and all
the software you need to surf the web or serve web pages. 

bruce