Simplify Pen Application Development

by Bryan Dobbs

The graphics subsystem in OS/2 Warp Version 4 provides a new type of presentation space (PS), called an ink PS (InkPS). This new presentation space helps applications display the output from a pen-style pointing device. In the past, applications had to provide the function and resources needed to display ink on the screen. Now, the graphics subsystem provides some of the basic functions and most of the resources (memory).

This new InkPS can be either a windowed or desktop InkPS. The windowed version only displays ink output inside of a window, while the desktop InkPS lets your applications display ink output over the entire OS/2 desktop, including any windows that are open on the desktop. The graphics subsystem also allows your application to remove the ink output from the screen if certain mix modes are used.

Creating an InkPS
An InkPS is created in nearly the same way any presentation space is created. First, you need to open a device context (DC), and then you create a PS and associate it with the DC. New function was added to the DevOpenDC and GpiCreatePS APIs to allow an InkPS to be created.

The type of DC that is opened determines the type of PS windowed or desktop. A windowed DC is created by calling WinOpenWindowDC. A desktop DC is created by calling DevOpenDC and specifying the type as OD_SCREEN.

The PS is created and associated with the DC through the GpiCreatePS call. An InkPS is a micro PS, so the options for the GpiCreatePS call must include GPIT_MICRO, GPIT_INK, and GPIA_ASSOC. Now you have a handle to your InkPS so you can start using it.

Displaying Ink in the InkPS
Three new APIs are used to display ink in the InkPS GpiBeginInkPath, GpiEndInkPath, and GpiStrokeInkPath. These APIs are used in almost the same way as the regular path APIs except for one major difference. A call to GpiStrokeInkPath does not destroy the path and can be made from within the InkPath bracket. In other words, you don't have to call GpiEndInkPath before you call GpiStrokeInkPath. This setup allows the:
 * InkPath to be updated without reprocessing the whole path, making it faster and more efficient
 * Graphics subsystem to maintain the path instead of the application

This section briefly describes the new APIs and their parameters

GpiBeginInkPath

GpiBeginInkPath, as the name implies, specifies the start of an inking path. This function requires three parameters:
 * The handle to the InkPS
 * The path identifier (which must be one)


 * The options (currently, no options are available for this function and flOptions should be set to zero)

GpiEndInkPath

GpiEndInkPath ends the ink path and deletes it. This function requires two parameters:
 * The handle to the InkPS
 * The options

The options specify whether to erase the ink path from the screen or to keep it there The PPE_KEEPPATH option is the default and is the only option available for most foreground mix attributes Both options, PPE_KEEPPATH and PPE_ERASEPATH, are available if the foreground mix attribute is set to either FM_XOR or FM_INVERT.

GpiStrokeInkPath

GpiStrokeInkPath is the API that does most of the work. This function requires five parameters: When called, GpiStrokeInkPath takes the points in the array, adds them to the current ink path and displays them on the screen. The way the path is displayed depends on the geometric line width, but will be explained in a moment.
 * The handle to the InkPS
 * The path identifier (which must be one)
 * The number of points in the array
 * A pointer to an array of points
 * The stroke options

The stroke options allow the path to be comprised of several disjoint strokes, like someone s signature. The options are: Now, back to how the path is displayed The geometric line width, which is a field in the line bundle, determines how the ink path is drawn. If the geometric width is equal to 1, the ink path is drawn as a single pel cosmetic line with line attributes. Otherwise it is drawn as a geometric line and the width is stroked with the area attributes. Therefore, you must remember to use either the line attributes or the area attributes depending on the type of line you want to draw. The attributes behave exactly the same in an ink path as they do in a regular path.
 * PPS_INKDOWN signals the start of a new stroke
 * PPS_INKMOVE is the default option and is used in the middle of a stroke
 * PPS_INKUP signals the end of a stroke

If you are using a desktop InkPS, you'll want to call WinLockWindowUpdate(HWND_DESKTOP,HWND_DESKTOP) to prohibit output to the desktop while you are drawing the ink path. You will also need to remember to call WinLockWindowUpdate( HWND_DESKTOP,NULLHANDLE) to unlock it when you are finished.

Summary
A sample program, INKPS, is included on the DevCon for OS/2 CDs in the "Source Code from The Developer Connection News" category.

This program allows you to change all the line and area attributes and see how the ink output looks on the screen. Be sure to use the FM_XOR or FM_INVERT foreground mix attributes so you can choose to erase or keep the ink on the screen. The program also allows you to experiment with a desktop InkPS and locking the desktop. Press the left mouse button to draw, and double-click the right mouse button to end the path. Remember, you can draw multiple line segments in the same path.

This new Ink Presentation Space should enable you to more easily include ink support in your OS/2 applications. Please direct your feedback, input, and perspectives to my Internet ID: bryan_dobbs@austin.ibm.com.