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

Manipulating Resources in Application Code

Although you can set the initial values of a widget's resources in PhAB, you'll probably need to access them from your code. For example:

In addition, if you use PtCreateWidget() to instantiate a widget in your code, you can give an initial value to its resources.

The value for the resource is specified or retrieved using an argument list.


Note: There are two steps involved in specifying or retrieving resource values:
  • Setting up the argument list, using the PtSetArg() macro.
  • Setting the value, using PtSetResources(), or retrieving the value, using PtGetResources().

Argument lists

An argument list is an array of PtArg_t structures. Each of these elements identifies a widget resource and a new value for the resource (or the address of a variable that will be set to the resource's current value).

You can use the PtSetArg() macro to initialize each element of the argument list:

PtSetArg( PtArg_t *arg,
          long type,
          long value,
          long len );

Note: If the values don't need to be calculated at runtime, you might be able to use Pt_ARG() instead to initialize the argument list. For more information, see the Photon Library Reference.

The first two arguments to PtSetArg() are the address of the argument list element, and the name of the resource. The third and fourth arguments vary, depending on the type of the resource, and on whether a set or a get operation is being applied. When setting a resource, the third argument is always used to hold a resource value or a pointer to a resource's value.

The fourth argument is used as either a size indicator or a mask, depending on the type of the value being specified. The possible resource types are given in the table below:

Type: Description:
Alloc An arbitrarily sized memory object
Array An array
Boolean A bit that's either on or off
Complex A resource that's handled in a special way; see below.
Flag A value in which each bit has a different meaning
Link A linked list
Pointer A pointer to an address that you specify
Scalar A value that can be represented within a single long
String A null-terminated string
Struct A fixed-size data type, usually a structure, float, or double

For information about the resources defined for each widget, see the Photon Widget Reference.


Note: Complex resources are special; see their descriptions in the Widget Reference for instructions for setting and getting them. Widgets that have complex resources usually have convenience functions to make it easier to work with them.

Setting resources

Remember that there are two steps involved in setting resource values:

Argument lists for setting resources

The sections that follow demonstrate setting some resources for a PtComboBox widget. Note that you can set more than one resource at a time. To do so, define an argument list of the appropriate length:

PtArg_t  args[5];

After initializing the argument list, you'll actually set the resources.

Scalar resources

When setting a scalar value, you should specify the value as the third argument to PtSetArg(). The fourth argument isn't used and should be set to 0.

For example, to set the border width of the combo box, pass the new value as the third argument:

PtSetArg(&args[0], Pt_ARG_BORDER_WIDTH, 5, 0);

When you call PtSetResources(), the widget will copy the scalar value into its own internal data structure.

String resources

Setting a string value is similar to setting a scalar value; you specify the string as the third argument to the PtSetArg() macro. The fourth argument isn't used and should be set to 0.

For example, to set the default text for the combo box, you could specify a value for the Pt_ARG_TEXT_STRING resource in one element of the argument list:

PtSetArg(&args[1], Pt_ARG_TEXT_STRING,
         "Rectangle", 0);

When you call PtSetResources(), the widget will copy the string into its own internal data structure.

If you need to use international (non-ASCII) characters in a string, do one of the following:

For more information on Unicode and UTF-8, see the appendix on Unicode Multilingual Support.

Alloc resources

Some resources are designed to store an allocated block of memory. For example, every widget includes a Pt_ARG_USER_DATA resource that you can use to store any data you want in the widget's internal memory. To set this resource, pass a pointer to the data as the third argument to PtSetArg(). The fourth argument is the size of the block of memory, in bytes:

my_struct user_data;

/* Initialize the data */

PtSetArg(&args[2], Pt_ARG_USER_DATA, &user_data,
         sizeof (user_data));

The widget will copy the number of bytes given into its internal memory when you call PtSetResources().

Array resources

When setting an array value, the third argument to PtSetArg() is the address of the array. The fourth argument is the number of elements in the array.

For example, the following entry in the argument list can be used to set up Pt_ARG_ITEMS, the list of choices for the combo box:

char *cbox_items[3] = {"Circle", "Rectangle", "Polygon"};

PtSetArg(&args[3], Pt_ARG_ITEMS, cbox_items, 3);         

The widget will copy the contents of the array into its own internal data structure when you call PtSetResources().

Flag resources

When setting a flag, the third argument to PtSetArg() is a bit field specifying the value of the bits to be set. The fourth argument is a bit mask indicating which elements of the bit field should be used.


Note: For the value, use Pt_TRUE, Pt_FALSE, or a combination of specific bits and their complements. Don't use a value of 1, since it contains just one bit that's on; that bit might not correspond to the bit you're trying to set.

For example, the following argument list specification turns on the combo box widget's Pt_COMBOBOX_STATIC flag (so that the combo box always displays the list of items):

PtSetArg(&args[4], Pt_ARG_CBOX_FLAGS, 
         Pt_TRUE, Pt_COMBOBOX_STATIC);

When you call PtSetResources(), the widget will use the bit mask to determine which bits of its internal flag resource representation to alter. It will take the bit values from the value specified.

Pointer resources

When setting a pointer resource, the pointer must be given as the third argument to PtSetArg(). The fourth argument is ignored and should be set to 0.

When you call PtSetResources(), the widget will simply do a shallow copy of the pointer into the resource.


Note: The widget doesn't make a copy of the memory referenced by the pointer; don't free the memory while the widget is still referencing it.

Link resources

When setting a Link, pass the address of an array of data as the third argument to PtSetArg(). The fourth argument has some special meanings:

num
append num items (if num is 0, one item is appended)
Pt_LINK_INSERT
insert the first array element at the beginning of the linked list
Pt_LINK_DELETE
remove the first list element that matches the first array element

The widget will copy the data into its internal memory when you call PtSetResources().

Struct resources

When setting a struct resource, pass the address of the data as the third argument to PtSetArg(). The fourth argument isn't used and should be set to 0.

The widget will copy the data into its internal memory when you call PtSetResources().

Boolean resources

When setting a Boolean value, you should specify the value as the third argument to PtSetArg(), using 0 for false, and a nonzero value for true. The fourth argument isn't used, and should be set to 0.

For example, to set the protocol for a PtTerminal to ANSI, pass a nonzero value as the third argument:

PtSetArg(&args[1], Pt_ARG_TERM_PROTOCOL, 1, 0);

When you call PtSetResources(), the widget clears or sets one bit in its own internal data structure depending on whether or not the value is zero.

Calling PtSetResources()

Once you've set up the argument list, you're ready to set the resources. Remember that PtSetArg() doesn't set the resources; it just sets up the argument list.

You can use PtSetResources() to set the new values for resources:

int PtSetResources( PtWidget_t *widget,
                    int n_args,
                    PtArg_t *args );

The arguments to this function are a pointer to the widget, the number of entries in the argument list, and the argument list itself.

You can also set resources by passing an argument list to the PtCreateWidget() function. The rules for specifying values in argument list elements are the same for both functions. For more information, see the Creating Widgets in Application Code chapter.

For example, you could set the resources of a combo box, using the argument list created above. Call PtSetResources() as follows:

PtSetResources (ABW_shapes_cbox, 5, args);

In response to a change to its resources, a widget may have to redisplay itself. The PtSetResources() call triggers this change. Any changes to the appearance of the widget, however, don't take effect until control is restored to the Photon event-handling loop. Therefore, if PtSetResources() is called from within a callback function or an event-handling function, the change to the widget won't be visible until all the callbacks in the callback list and all event handlers have been executed.

Getting resources

There are two steps involved in retrieving resource values:

There are two methods of getting resources: one that involves pointers, and one that doesn't. The nonpointer method is usually easier and safer:

The pointer method may be less confusing if you're getting the values of several resources at once; you'll have named pointers to the values instead of having to remember which element in the argument list corresponds to which resource.

Not using pointers

If you set the value and len arguments to PtSetArg() to zero, PtGetResources() will return the resource's value (converted to long) as follows:

Resource type value len
Flags (any C type) Value of the resource N/A
Scalar (any C type) Value of the resource N/A
Pointer (any C type) Value of the resource N/A
String Address of the string N/A
Struct Address of the data N/A
Array Address of the first array item Number of items in the array
Alloc Address of where the resource is stored N/A
Boolean 0 (false) or 1 (true) N/A

Scalar and flag resources (nonpointer method)

To get a scalar or flag resource (of any C type) with the nonpointer method:

unsigned long getscalar( PtWidget_t *widget, long type ) {
    /* Get any kind of scalar */
    PtArg_t arg;
    PtSetArg( &arg, type, 0, 0 );
    PtGetResources( widget, 1, &arg );
    return arg.value;
    }

String resources (nonpointer method)

Here's how to use the nonpointer method to get the value of a string resource:

const char *getstr2( PtWidget_t *widget, long type ) {
    PtArg_t arg;

    PtSetArg( &arg, type, 0, 0 );
    PtGetResources( widget, 1, &arg );
    return (char*) arg.value;
    }

Boolean resources (nonpointer method)

In the nonpointer method to get a boolean, the value (0 or 1) is returned in value argument to PtSetArg():

int getbool( PtWidget_t *widget, long type ) {
    PtArg_t arg;

    PtSetArg( &arg, type, 0, 0 );
    PtGetResources( widget, 1, &arg );
    return arg.value;
    }

Using pointers

When using the pointer method to get a scalar, array, or flag resource, the widget will always give a pointer to an internal widget data structure. In the argument list element you set up using PtSetArg(), you must provide the address of a variable to which the internal data pointer can be assigned.

The fourth argument isn't used for most types of resources. For arrays, it's the address of a pointer that on return from PtGetResources() will point to the number of entries.

For example, to obtain the contents of the Pt_ARG_FLAGS resource (which is a long) for a widget, you must pass the address of a pointer to a long:

const long *flags;
PtArg_t arg[1];

PtSetArg(&arg[0], Pt_ARG_FLAGS, &flags, 0);
PtGetResources(ABW_label, 1, arg);

Caution: PtGetResources() returns pointers directly into the widget's internal memory. Don't attempt to modify the resources directly using these pointers. Such a modification won't have the desired effect and will likely corrupt the widget's behavior. Never free these pointers either - this will certainly result in a memory violation or some other fault.

Using const pointers will help avoid these problems.

Changes to the widget's state may invalidate these pointers; use them promptly.


If you wish to retrieve the value of a given resource and then modify that value:

  1. Get the resource.
  2. Copy the resource to a temporary variable.
  3. Modify the temporary variable.
  4. Using the modified copy, set the resource.

You can use the value obtained to set the value of another resource of this or any other widget, as long as you don't change the original value.

For example, you can use the following code to obtain Pt_ARG_TEXT_STRING, the text string displayed in the label widget named label:

char *str;
PtArg_t args[1];

PtSetArg(&args[0], Pt_ARG_TEXT_STRING, &str, 0);
PtGetResources(ABW_label, 1, args);

You can then assign this text string to another label named label2:

PtSetArg(&args[0], Pt_ARG_TEXT_STRING, str, 0);
PtSetResources(ABW_label2, 1, args);

Scalar and flag resources (pointer method)

If you're getting scalar or flag resources using the pointer method:

When PtGetResources() is called, the pointer will be set to point to the widget's internal storage for that resource.

Here are some functions that get a scalar or flag resource, using the pointer method:

unsigned long getlong( PtWidget_t *widget, long type ) {
    /* Get a long or long flags */
    PtArg_t arg; unsigned long const *result;

    PtSetArg( &arg, type, &result, 0 );
    PtGetResources( widget, 1, &arg );
    return *result;
    }

unsigned getshort( PtWidget_t *widget, long type ) {
    /* Get a short or short flags */
    PtArg_t arg; unsigned short const *result;

    PtSetArg( &arg, type, &result, 0 );
    PtGetResources( widget, 1, &arg );
    return *result;
    }

unsigned getbyte( PtWidget_t *widget, long type ) {
    /* Get a char or char flags */
    PtArg_t arg; unsigned char const *result;

    PtSetArg( &arg, type, &result, 0 );
    PtGetResources( widget, 1, &arg );
    return *result;
    }

String resources (pointer method)

If you're getting string resources using the pointer method:

When PtGetResources() is called, the pointer specified is set to point to the widget's internal storage for the string resource. For example:

const char *getstr1( PtWidget_t *widget, long type ) {
    PtArg_t arg; const char *str;

    PtSetArg( &arg, type, &str, 0 );
    PtGetResources( widget, 1, &arg );
    return str;
    }

Alloc resources (pointer method)

If you're getting alloc resources using the pointer method:

When PtGetResources() is called, the pointer specified is set to point to the widget's internal data.

Array resources (pointer method)

If you're getting array resources using the pointer method:

When PtGetResources() is called:

Pointer resources (pointer method)

If you're getting pointer resources using the pointer method:

When PtGetResources() is called, the pointer specified is set to point to the same data as the widget's internal pointer. The data is external to the widget; you might be able to modify it, depending on the resource.

Link resources (pointer method)

If you're getting link resources using the pointer method:

When PtGetResources() is called, The pointer given by value is set to point to the first node of the widget's internal linked list.


Note: If you get a callback resource, the value argument to PtSetArg() is the address of a pointer to a PtCallbackList_t structure. For more information, see "Examining callbacks" in the Creating Widgets in Application Code chapter.

Struct resources (pointer method)

If you're getting struct resources using the pointer method:

When PtGetResources() is called, the pointer specified is set to point to the widget's internal storage for the struct resource.

Boolean resources (pointer method)

Version 1.13 and earlier

If you're getting boolean resources using the pointer method in Photon 1.13 or earlier:

When PtGetResources() is called, you get a pointer into the widget's memory where the bit is stored. If len is a pointer, the address it points to is set to be the mask. If 0, len is used to store the mask. You'll need to use the mask to check the value of the bit.

For example, to get the Pt_ARG_SHOW_ARROWS resource of a PtScrollbar, passing a pointer for the mask:

PtArg_t   arg;
const int *bool;
long      mask;

PtSetArg( &arg[0], Pt_ARG_SHOW_ARROWS, &bool, &mask );
PtGetResources (ABW_scrollbar, 1, arg);

if ( *bool & *mask ) {
  // Arrows are on
}

Here's how to use len to store the mask:

PtArg_t   arg;
const int *bool;

PtSetArg( &arg[0], Pt_ARG_SHOW_ARROWS, &bool, 0 );
PtGetResources (ABW_scrollbar, 1, arg);

if ( *bool & arg.len ) {
  // Arrows are on
}

Version 1.14 and later

The method used in Photon version 1.13 and earlier isn't suited to applications that run on different machines because of problems with big- and little-endian representations. In version 1.14 and later, if you're getting boolean resources using the pointer method:

When PtGetResources() is called, the int is set to 1 if the Boolean is true, or 0 if it's false.

For example, to get the Pt_ARG_SHOW_ARROWS resource of a PtScrollbar:

PtArg_t arg;
int     bool;

PtSetArg( &arg[0], Pt_ARG_SHOW_ARROWS, &bool, 0 );
PtGetResources (ABW_scrollbar, 1, arg);

if ( bool ) {
  // Arrows are on
}

Calling PtGetResources()

Use PtGetResources() to obtain the values of each of the resources identified in an argument list:

int PtGetResources( PtWidget_t *widget,
                    int n_args,
                    PtArg_t *args );

The arguments to this function are the identifier for the widget, the number of entries in the argument list, and the argument list itself.

PtGetResources() returns 0 on success, or -1 if an error occurs. A return code of -1 might indicate that you've tried to get the value of a resource that isn't defined for the widget.


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