[Previous] [Contents] [Index] [Next]

Printing

This chapter includes:

Printing and drawing are the same in Photon -- the difference depends on the draw context, a data structure that defines where the draw stream (i.e. the draw events) flows:

To print in Photon:

  1. Create a print context by calling PpCreatePC().
  2. Set up the print context automatically via the PtPrintSel widget, or programmatically via PpSetPC().
  3. Initialize the print job by calling PpStartJob().
  4. Any time after PpStartJob() is called, make the print context "active" by calling PpContinueJob(). When a print context is active, anything that's drawn via PpPrintWidget() or Pg* calls, including widgets, is directed to the file opened by the print context during the PpStartJob() call.
  5. Insert page breaks, as required, by calling PpPrintNewPage().
  6. The print context can be made inactive without terminating the current print job by calling PpSuspendJob(), or by calling PpContinueJob() with a different print context. To resume the print job from where you left off, call PpContinueJob().
  7. Complete the print job by calling PpEndJob().
  8. When your application doesn't need to print anything else, call PpReleasePC() to free the print context.

What's in a print context?

A print context includes a number of members that control how printing is to be done.


Note: The print context is an opaque datatype. Use PpGetPC() to extract members, and PpSetPC() to change them.

The possible values and meanings for the members of a print context are defined in /usr/photon/print/printers.

A print context includes the data described in the sections that follow.

Pp_PC_COLLATING_MODE

Dictates the order of pages that are printed in print jobs that are printing more than one copy, and may include:

Pp_PC_COLOR_MODE

The color mode to use -- you might want to print in black and white on a color printer. Possible meanings:

Pp_PC_CONTROL (read-only)

This member is the control structure, of type PpPCControl_t, for the print context.


Note: You can't use PpSetPC() to set Pp_PC_CONTROL.

The control structure has at least the following members:

char changed_prop[Pp_PC_FLAGSIZE]
This array is treated as a large bit field that indicates which portions of the context have been modified. There's a bit for each of the modifiable attributes of a print context.

This bit field can be manipulated with the following macros, which are defined in <photon/PpT.h>:

For example:

if( Pp_testbit( control-gt;changed_prop, Pp_PC_NAME) )
    printf( "Print name has been changed\n");
            
char emitted_prop[Pp_PC_FLAGSIZE]
Another large bit field. This one indicates which of the changed print context attributes have already been written to the destination or temporary file. For example:
if( Pp_testbit( control-gt;emitted_prop, Pp_PC_NAME) )
    printf( "source offset has been emitted\n");
            
ulong_t locked_prop[Pp_PC_FLAGSIZE]
Another large bitfield. This one indicates which context attributes are locked. Locked attributes are displayed as ghosted controls by the printer properties application, and PpSetPC() won't let you change them.
int fd
This is the file descriptor for the current print job's working file. The working file isn't opened until the print job is opened by PpStartJob(). This is -1 if no files are currently open.
char *tmp_target
The temporary working file that's used if do_preview is set.
char do_preview
If this is nonzero, the application specified in the print context's Pp_PC_PREVIEW_APP member is launched when the print job is finished (that is, when PpEndJob() is called).

Pp_PC_COPIES

The number of copies to produce.

Pp_PC_DATE

The date the print job was started. It's filled in when the print job is initialized. See PpStartJob() and PpContinueJob().

Pp_PC_DEVICE

Usually the spooler to use (e.g. /dev/spool/Ph.main_deskjet).

If you're sending the print job directly to a printer (such as /dev/par1), set Pp_PC_FILENAME to be the name of the printer (e.g. /dev/par1) and Pp_PC_DRIVER to be the name of the Photon print driver that produces output that the printer recognizes.


Note: If both the device and filename members are set, the output goes to the destination identified by the filename.

Pp_PC_DITHERING

Specifies the dithering. Possible meanings are defined in the printer configuration file, and include:

Pp_PC_DO_PREVIEW

If nonzero, the preview application is launched rather submitting the job to a spooler.

Pp_PC_DRIVER

The print filter, such as phs-to-pcl, to launch if printing to a file (if a filename is specified). For information about the available print drivers, see "Photon print drivers (phs-to-*)" in the summary of the QNX 6 Utilities Reference.

Pp_PC_DUPLEX

Specifies whether (1) or not (0) double-sided printing is to be done.

Pp_PC_FILENAME

If this member is specified, the final output of the print job is placed in this file instead of being sent to a device.

For raw phs output, you need to pass the file through a spooler device. There's a simple phs-to-phs filter (similar to cat) for this purpose.

Pp_PC_INKTYPE

Possible meanings:

Pp_PC_INTENSITY

A value between 0% and 100%. A printer's default intensity is 50%.

Pp_PC_JOB_NAME

The name of the print job, for identification purposes.

Pp_PC_MARGINS

A rectangle that specifies the margins to apply to the pages, specified in 1/1000ths of an inch:

The orientation of the page doesn't affect the margins.

Pp_PC_MAX_DEST_SIZE

The maximum size of the temporary phs file, in bytes.

Pp_PC_NAME

The name of the printer (e.g. R&D main printer).

Pp_PC_NONPRINT_MARGINS

A rectangle that specifies (in 1/1000ths of an inch) the nonprintable margins of the printer.

Pp_PC_ORIENTATION

Possible meanings include portrait and landscape, as defined in the printer-configuration file.

Pp_PC_PAGE_NUM

The current page being printed.

Pp_PC_PAGE_RANGE

The range of pages to be printed. This information should be used by the application when producing the printed output. Only those pages requested need to be printed.

The page range is a PpPageRange_t structure with two int members, from and to. Special meanings for the range are:

from to Print:
0 0 All
-1 -1 Selected region
n 0 From page n to the end of the document

The library assumes that the first page printed is the first requested page. If this isn't the case, use Pp_PC_PAGE_NUM to set the page number manually.

Pp_PC_PAPER_SIZE

The dimensions of the paper, including margins and the nonprintable area, in 1/1000ths of an inch. This size is used for clipping and for any scaling that may be applied.

Pp_PC_PAPER_SOURCE

The paper source, for printers that support more than one paper tray. The possible meanings are:

Pp_PC_PAPER_TYPE

This is in the range 0 through 100. Possible meanings include:

Pp_PC_PREVIEW_APP

The application to launch to preview the print job, usually /usr/photon/bin/preview.

Pp_PC_PRINTER_RESOLUTION

The printing mode, specified in x and y dots per inch. The printer tries to print at this resolution.

Pp_PC_PROP_APP

The application to launch to adjust the printer properties portion of the print context.

Pp_PC_REVERSED

If this is nonzero, the pages are printed in reverse order. The default is forward.

Pp_PC_SCALE

The scale to use in x and y:


Note: If x and y scales are both 0, the source is scaled to be as large as possible to fit on the page and still maintain its x and y aspect ratio.

Pp_PC_SOURCE_COLORS

The number of bitplanes per source pixel. If this is n, you'll have 2**n colors. For example, a value of 8 means 256 colors. This is a hint that helps the print drivers improve the dithering model. The default is 24bpp (True Color).

Pp_PC_SOURCE_OFFSET

The origin for the print job. For example, if a widget you want to print is at (50,50) but you want it to appear in the upper left corner of the page, set the source offset to (50,50).

This offset affects the entire page; to affect an individual widget, use the trans argument to PpPrintWidget().

Pp_PC_SOURCE_RESOLUTION

The resolution, in pixels per inch, of the original source image. This is a hint that helps the print drivers do the best scaling possible. The default is 100 pixels per inch.

Pp_PC_SOURCE_SIZE

The dimension of the source image, in pixels. This size is used for clipping and for any scaling that may be applied. printed.

Pp_PC_USER_ID (read-only)

The user creating the print job. It's filled in when the print job is initialized. See PpStartJob() and PpContinueJob().

Creating a print context

The first step to printing in Photon is to create a print context by calling PpCreatePC():

PpPrintContext_t *pc;

pc = PpCreatePC();

Caution: Never access the fields in a print context directly; use PpGetPC() and PpSetPC().

Modifying a print context

Once the print context is created, you must set it up properly for your printer and the options (orientation, paper size, etc.) you want to use. This can be done by calling:

These functions are described in the Photon Library Reference.

You can also use PtPrintSel (see the Photon Widget Reference).

You can get a list of available printers by calling PpLoadPrinterList(). When you're finished with the list, call PpFreePrinterList().

Starting a print job

If you're using an application that needs to know anything about the print context, you can use PpGetPC() to get the appropriate information. For example, you might need to know the selected orientation (in order to orient your widgets properly). If you need to know the size of the margins, you can call PpGetCanvas(). For an example, see the printing application prdemo.

Before printing, you must set the source size or resolution. For example:

When setting the source size, take the nonprintable area of the printer into account. All printers have a margin around the page that they won't print on, even if the page margins are set to 0. Therefore, the size set above is actually a bit larger than the size of a page, and the font will be scaled down to fit on the printable part of the page.

In the following example, the page size and nonprintable area are taken into account to give the proper source size and text height. Try this, and measure the output to prove the font is 1" high from ascender to descender:

#include <stdio.h>
#include <stdlib.h>
#include <Pt.h>

PtWidget_t *label, *window;
PpPrintContext_t *pc;

int quit_cb (PtWidget_t *widget, void *data, 
             PtCallbackInfo_t *cbinfo )
{
    exit (EXIT_SUCCESS);
    return (Pt_CONTINUE);
}

int print_cb (PtWidget_t *widget, void *data, 
              PtCallbackInfo_t *cbinfo )
{
    int action;
    PhDim_t size;
    PhRect_t const *rect;
    PhDim_t const *dim;

    action = PtPrintSelection(window, NULL, 
                              "Demo Print Selector", 
                              pc, Pt_PRINTSEL_DFLT_LOOK);
    if (action != Pt_PRINTSEL_CANCEL)
    {
        /* Get the nonprintable area and page size. Both are in 
           1/1000ths of an inch. */

        PpGetPC(pc, Pp_PC_NONPRINT_MARGINS, &rect);
        PpGetPC(pc, Pp_PC_PAPER_SIZE, &dim);
        size.w = ((dim->w  - 
                  (rect->ul.x + rect->lr.x)) * 72) / 1000;
        size.h = ((dim->h  - 
                  (rect->ul.y + rect->lr.y)) * 72) / 1000;

        /* Set the source size. */
        PpSetPC( pc, Pp_PC_SOURCE_SIZE, &size, 0);

        /* Start printing the label. */
        PpStartJob(pc);
        PpContinueJob(pc);

        /* Damage the widget. */
        PtDamageWidget(label);
        PtFlush();

        /* Close the PC. */
        PpSuspendJob(pc);
        PpEndJob(pc);
    }
    return (Pt_CONTINUE);
}

int main(int argc, char *argv[])
{
    PtArg_t args[10];
    PtWidget_t *print, *quit;
    PhDim_t   win_dim = { 400, 200 };
    PhPoint_t lbl_pos = {0, 0};
    PhArea_t print_area = { {130, 170}, {60, 20} };
    PhArea_t quit_area = { {210, 170}, {60, 20} };
    PtCallback_t callbacks[2] = { {print_cb, NULL}, 
                                  {quit_cb, NULL} };

    if (PtInit(NULL) == -1)
        PtExit(EXIT_FAILURE);

    /* Create the main window. */
    PtSetArg (&args[0], Pt_ARG_DIM, &win_dim, 0);
    PtSetArg (&args[1], Pt_ARG_WINDOW_TITLE, 
              "Print Example", 0);

    if ((window = PtCreateWidget(PtWindow, Pt_NO_PARENT,
                                 1, args)) == NULL)
        PtExit (EXIT_FAILURE);

    /* Create a print context. */
    pc = PpCreatePC();

    /* Create a label to be printed. */
    PtSetArg (&args[0], Pt_ARG_POS, &lbl_pos, 0);
    PtSetArg (&args[1], Pt_ARG_TEXT_STRING, 
              "I am 1 inch high", 0);
    PtSetArg (&args[2], Pt_ARG_TEXT_FONT, "swiss72", 0);
    PtSetArg (&args[3], Pt_ARG_MARGIN_HEIGHT, 0, 0);
    PtSetArg (&args[4], Pt_ARG_MARGIN_WIDTH, 0, 0);
    PtSetArg (&args[5], Pt_ARG_BEVEL_WIDTH, 0, 0);
    label = PtCreateWidget (PtLabel, window, 6, args);

    /* Create the print button. */
    PtSetArg(&args[0], Pt_ARG_AREA, &print_area, 0);
    PtSetArg(&args[1], Pt_ARG_TEXT_STRING, "Print", 0);
    PtSetArg(&args[2], Pt_CB_ACTIVATE, &callbacks[0], 0);
    print = PtCreateWidget (PtButton, window, 3, args);

    /* Create the quit button. */
    PtSetArg(&args[0], Pt_ARG_AREA, &quit_area, 0);
    PtSetArg(&args[1], Pt_ARG_TEXT_STRING, "Quit", 0);
    PtSetArg(&args[2], Pt_CB_ACTIVATE, &callbacks[1], 0);
    quit = PtCreateWidget (PtButton, window, 3, args);

    PtRealizeWidget(window);
    PtMainLoop();
    return (EXIT_SUCCESS);
}

You should also set the source offset, the upper left corner of what's to be printed. For example, if you have a button drawn at (20, 20) from the top left of a pane and you want it to be drawn at (0, 0) on the page, set the source offset to (20, 20). Any other widgets are drawn relative to their position from this widget's origin. A widget at (40, 40) will be drawn at (20, 20) on the page. The code is as follows:

PhPoint_t offset = {20, 20};
...
PpSetPC( pc, Pp_PC_SOURCE_OFFSET, &offset, 0 );

Once the source size and offset have been set, you can start printing:

PpStartJob(pc);
PpContinueJob(pc);

PpStartJob() sets up the print context for printing and PpContinueJob() makes the print context active, causing all Photon draw commands to be redirected to the destination specified in the print context.

Printing the desired widgets

After you've made the print context active, you can start printing widgets and so on. This can be done by calling any combination of the following:


Note: If you want to print all the contents of a widget that scrolls, you'll need to do some special preparations. See "Printing scrolling widgets" below.

Printing a new page

You can force a page break at any point by calling PpPrintNewPage():

PpPrintNewPage(pc);

Note that once you call PpStartJob(), any changes to the print context take effect after the next call to PpPrintNewPage().

Photon assumes that the page numbers increase by one. If this isn't the case, manually set the Pp_PC_PAGE_NUM member of the print context to the correct page number. Don't make the page number decrease because the print drivers might not work properly.

Printing widgets that scroll

If you want to print all the contents of a widget that scrolls, you need some special processing:

PtList

The only way to make a PtList print (or draw) all the items is by resizing it to be the total height of all the items. The easiest way is probably by using the resize policy:


Note: This will work only if the total height is smaller than 65K pixels.

  1. Open and start the print context.
  2. Get the current resize flags (Pt_ARG_RESIZE_FLAGS) for the PtList widget.
  3. Change the resize flags to Pt_RESIZE_XY_ALWAYS, to make the list resize to fit all of its text.
  4. Call PpPrintWidget() for the widget or parent widget.
  5. Call PtFlush().
  6. Reset the resize flags for the PtList widget.
  7. Stop and close the print context.

PtMultiText

Due to a bug in the resize flags of the multitext widget, the method used for PtList doesn't currently work on PtMultiText.

To print a PtMultiText widget's entire text:

  1. Open and start the print context.
  2. Get the current values of the widget's Pt_ARG_MULTITEXT_NUM_LINES and Pt_ARG_MULTITEXT_NUM_LINES_VISIBLE resources.
  3. Save the value of Pt_ARG_MULTITEXT_NUM_LINES_VISIBLE in a local variable (remember that PtGetResources() gives you a pointer into the widget's internal memory -- don't rely on it to save the number of visible lines).
  4. Set Pt_ARG_MULTITEXT_ROWS to the value of Pt_ARG_MULTITEXT_NUM_LINES.
  5. Call PpPrintWidget() for the widget or parent widget.
  6. Call PtFlush().
  7. Reset the value of Pt_ARG_MULTITEXT_ROWS to be the saved number of visible lines.
  8. Stop and close the print context.

Here's a callback that prints a PtMultiText widget:

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

{
    int action; 
    PhDim_t size = { 850, 1100 
	}; 
    long *num_lines;
    short *num_lines_visible;
    long  vis_lines;
    PtArg_t args[2];
 
    /* eliminate 'unreferenced' warnings */
    widget = widget, apinfo = apinfo, cbinfo = cbinfo;

    /* You could make these calls to PpSetPC() right 
       after creating the print context. Having it here
       lets you reuse the print context. */
 
    /* Set the source resolution to be proportional to 
       the size of a page. */
    PpSetPC( pc, Pp_PC_SOURCE_SIZE, &size, 0 ); 
 
    action = PtPrintSelection(ABW_base, NULL, 
                 "Demo Print Selector", pc, 
                 Pt_PRINTSEL_DFLT_LOOK); 

    if (action != Pt_PRINTSEL_CANCEL) 
    { 
        /* Start printing the pane. Note that we're using 
           the same print context for all print jobs. */
        PpStartJob(pc); 
        PpContinueJob(pc);
 
        /* Get the number of lines and the number of visible
           lines. */

        PtSetArg (&args[0], Pt_ARG_MULTITEXT_NUM_LINES, 
                  &num_lines, 0);
        PtSetArg (&args[1], Pt_ARG_MULTITEXT_NUM_LINES_VISIBLE, 
                  &num_lines_visible, 0);
        PtGetResources (ABW_multi, 2, args);

        /* Save the number of visible lines in a local variable;
           remember that num_lines_visible points into the
           widget's internal memory. */

        vis_lines = *num_lines_visible;

        /* Set the number of rows to be the number of lines. */

        PtSetResource( ABW_multi, Pt_ARG_MULTITEXT_ROWS,
                       *num_lines, 0);
     
        /* Print the widget. */

        PpPrintWidget(pc, ABW_multi, NULL, NULL, 0); 
        PtFlush(); 
 
        /* Close the print context. */
        PpSuspendJob(pc); 
        PpEndJob(pc); 

        /* Reset the number of rows to be the saved number 
           of visible lines. */

        PtSetResource (ABW_multi, Pt_ARG_MULTITEXT_ROWS,
                       vis_lines, 0);
    } 
 
    return( Pt_CONTINUE );
}

PtScrollArea

For a PtScrollArea, you need to print its virtual canvas, which is where all widgets created within or moved to a scroll area are placed:

  1. Get a pointer to the virtual canvas by calling:
    PtValidParent( ABW_Scroll_area, PtWidget );
              
  2. Get the area (Pt_ARG_AREA) of the virtual canvas, and use its size member as the source size in the print context.
  3. Set the print context's source offset to:
    PtWidgetOffset( PtValidParent( ABW_Scroll_area, 
                                   PtWidget ));
              
  4. Print the scroll area's virtual canvas by calling:
    PpPrintWidget( pc, PtValidParent( ABW_Scroll_area, 
                                      PtWidget ), 
                   NULL, NULL, 0);
              

Suspending and resuming a print job

To suspend a print job and direct all draw events back to the graphics driver at any point after calling PpStartJob(), call:

PpSuspendJob( pc );

To resume a print job, reactivating the print context, causing draw events to be directed towards the destination specified in the print context, call:

PpContinueJob( pc );

Ending a print job

When you're finished printing your widgets, the print context must be deactivated and closed. This is done by calling:

PpSuspendJob(pc);
PpEndJob(pc);

All draw events will be directed to the graphics driver.


Note: You can reuse the print context for new print jobs, eliminating the need to create and initialize it again.

Freeing the print context

When printing is complete and you no longer need the print context, you can free it, which in turn frees any resources used by it.

If you want to remember any information from the print context for future use, save it by calling PpGetPC() before freeing the print context. For example:

short const *orientation;
...
PpGetPC( pc, Pp_PC_ORIENTATION, &orientation );

To free a print context, call:

PpReleasePC( pc );

Example

This example creates an application with a main window, and a pane with a few widgets on it. When you press the Print button, a Print Selection Dialog appears. When you select this dialog's Print or Preview button, the pane is "drawn" on the printer.

#include <stdio.h>
#include <stdlib.h>
#include <Pt.h>

PtWidget_t *pane, *window;
PpPrintContext_t *pc;

int quit_cb ( PtWidget_t *widget, void *data, 
              PtCallbackInfo_t *cbinfo)
{
    PpReleasePC (pc);
    exit (EXIT_SUCCESS);
    return (Pt_CONTINUE);
}

int print_cb ( PtWidget_t *widget, void *data, 
               PtCallbackInfo_t *cbinfo)
{
    int action;

    /* You could make these calls to PpSetPC() right
       after creating the print context. Having it here
       lets you reuse the print context. */
    PhDim_t size = { 850, 1100 };
    PhDim_t size2 = { 200, 150 };

    /* Set the source resolution to be proportional to 
       the size of a page. */
    PpSetPC(pc, Pp_PC_SOURCE_SIZE, &size, 0);

    /* Uncomment this to set the source size to be the size
       of the widget. The widget will be scaled when printed. */
    /* PpSetPC(pc, Pp_PC_SOURCE_SIZE, &size2, 0); */

    action = PtPrintSelection(window, NULL, 
                 "Demo Print Selector", pc, 
                 Pt_PRINTSEL_DFLT_LOOK);
    if (action != Pt_PRINTSEL_CANCEL)
    {
        /* Start printing the pane. Note that we're using
           the same print context for all print jobs. */
        PpStartJob(pc);
        PpContinueJob(pc);

        /* Print the widget. */
        PpPrintWidget(pc, pane, NULL, NULL, 0);

        /* Close the print context. */
        PpSuspendJob(pc);
        PpEndJob(pc);
    }

    return (Pt_CONTINUE);
}

int main(int argc, char *argv[])
{
    PtArg_t args[4];
    PtWidget_t *print, *quit;
    PhDim_t  win_dim = { 200, 200 };
    PhArea_t pane_area = { {0, 0}, {200, 150} };
    PhArea_t print_area = { {30, 170}, {60, 20} };
    PhArea_t quit_area = { {110, 170}, {60, 20} };
    PhArea_t cir_area = { {35, 20}, {130, 110} };
    PhArea_t cir2_area = { {67, 40}, {20, 20} };
    PhArea_t cir3_area = { {110, 40}, {20, 20} };
    PhArea_t cir4_area = { {85, 80}, {30, 30} };
    PtCallback_t callbacks[2] = { {print_cb, NULL}, 
                                  {quit_cb, NULL} };

    if (PtInit(NULL) == -1)
        PtExit(EXIT_FAILURE);

    /* Create the main window. */
    PtSetArg (&args[0], Pt_ARG_DIM, &win_dim, 0);
    PtSetArg (&args[1], Pt_ARG_WINDOW_TITLE, 
              "Print Example", 0);
    if ((window = PtCreateWidget(PtWindow, Pt_NO_PARENT,
                                 2, args)) == NULL)
        PtExit(EXIT_FAILURE);

    /* Create a print context. */
    pc = PpCreatePC();

    /* Create the pane to be printed. */
    PtSetArg (&args[0], Pt_ARG_AREA, &pane_area, 0);
    pane = PtCreateWidget (PtPane, window, 1, args);

    /* put some stuff in the pane to be printed. */
    PtSetArg (&args[0], Pt_ARG_AREA, &cir_area, 0);
    PtCreateWidget (PtEllipse, pane, 1, args);

    PtSetArg (&args[0], Pt_ARG_AREA, &cir2_area, 0);
    PtSetArg (&args[1], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
    PtCreateWidget (PtEllipse, pane, 2, args);

    PtSetArg (&args[0], Pt_ARG_AREA, &cir3_area, 0);
    PtSetArg (&args[1], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
    PtCreateWidget (PtEllipse, pane, 2, args);

    PtSetArg (&args[0], Pt_ARG_AREA, &cir4_area, 0);
    PtCreateWidget (PtEllipse, pane, 1, args);

    /* Create the print button. */
    PtSetArg(&args[0], Pt_ARG_AREA, &print_area, 0);
    PtSetArg(&args[1], Pt_ARG_TEXT_STRING, "Print", 0);
    PtSetArg(&args[2], Pt_CB_ACTIVATE, &callbacks[0], 0);
    print = PtCreateWidget (PtButton, window, 3, args);

    /* Create the quit button. */
    PtSetArg(&args[0], Pt_ARG_AREA, &quit_area, 0);
    PtSetArg(&args[1], Pt_ARG_TEXT_STRING, "Quit", 0);
    PtSetArg(&args[2], Pt_CB_ACTIVATE, &callbacks[1], 0);
    quit = PtCreateWidget (PtButton, window, 3, args);

    PtRealizeWidget(window);
    PtMainLoop();
    return (EXIT_SUCCESS);
}

[Previous] [Contents] [Index] [Next]