PREV NEXT

Generic Logic, Inc. www.genlogic.com


2.5 Handling User Input and Other Events

Callback Events

A callback is a function or method that is invoked under certain conditions. For example, a callback is called each time a user selects something in a GLG drawing with the mouse. The code is supplied by the application developer.

A callback can be invoked for one of a few possible reasons:

In addition to these callbacks, the GLG Toolkit provides trace callbacks that are invoked whenever a GLG viewport receives any event. The trace callbacks are used as an escape mechanism to provide low-level access to native windowing events. There are two trace callbacks: a trace callback invoked before dispatching the event for processing, and a trace2 callback invoked after the event has been processed by the Toolkit.

Attaching Callbacks to a Viewport Object

A callbacks is attached to a viewport with the GlgAddCallback function, which takes the callback type and the callback function as parameters:

void GlgAddCallback( viewport, type, callback, client data )
	GlgObject viewport;
	GlgCallbackType type;
	GlgCallbackProc callback;
	GlgAnyType client_data;

The callback type may be one of GLG_INPUT_CB, GLG_SELECT_CB, GLG_TRACE_CB, GLG_TRACE2_CB or GLG_HIERARCHY_CB values defined in the GlgApi.h file.

All callbacks use the same function prototype:

typedef void (*GlgCallbackProc)( viewport, client_data, call_data )
	GlgObject viewport;
	GlgAnyType client_data;
	GlgAnyType call_data;
Parameters
viewport
A viewport handle corresponding to the viewport to which the callback was attached. For the GLG_INPUT_CB callback, it may be a light viewport.
client_data
Application defined data specified by the GlgAddCallback function.
call_data
Callback-specific data supplying information about the event which caused the callback.

A callback must be attached to a viewport before the viewport's object hierarchy is set up (after the viewport is loaded but before it is drawn). Child viewports may have their own callbacks attached, different from the callbacks of their parent viewport. Only one callback of each type can be attached to one viewport object. To remove a callback, use NULL as a callback parameter.

Adding Callbacks to a GLG Wrapper Widget

In the Motif/Xt environment, a GLG callback can also be attached to the top level viewport of the GLG Wrapper Widget's drawing as an Xt callback using the XtAddCallback function. The callback types include

XtNglgSelectCB
XtNglgMotifSelectCB
XtNglgInputCB
XtNglgMotifInputCB
XtNglgTraceCB
XtNglgTrace2CB
XtNglgHierarchyCB
XtNglgHInitCB
XtNglgVInitCB

Notice that for the select and input callbacks two callback types are provided: one following the GLG generic cross-platform format and one following the Motif calling convention. The callbacks must be added before the widget is realized and its drawing hierarchy is set up.

There are two widget initialization callbacks: HInit and VInit, which allow an application to initialize drawing's resources before it is displayed in the widget. The HInit callback is invoked after the widget's drawing is loaded, but before its hierarchy is setup. It may be used to initialize values of H resources, such as a number of instances in a series object or a number of points in a graph. The VInit callback is invoked after the hierarchy setup, but before the drawing is displayed. It may be used for initializing V resources, such as initial data values for a graph.

The Xt callbacks use the standard XtCallbackProc prototype and pass the callback information to the application using the callback's call_data parameter. The following description of specific callback types includes the description of Motif-style callbacks.

Selection Callback

The selection callback provides a simplified name-based interface to handle object selection. The input callback provides a more elaborate alternative for handling selection events using either object IDs, or custom events and selection commands which can be attached to objects in the Graphics Builder.

A selection callback is called when the user selects objects in the widget with a mouse click. If no objects are selected, the call_data parameter will be NULL. If some objects are selected by the click, the call_data parameter will contain a list of names of all selected objects. This list is a NULL-terminated list of pointers to strings, each of which represents the complete path name of one object selected by the mouse click. If more than one object is selected, the list will contain several strings. The objects drawn on top will be listed first. The pointer to the list as well as pointers to the individual strings point to internal data structures which should not be modified.

The GlgGetSelectionButton function may be used to find out which mouse button was pressed to activate the selection callback.

The path name obtained in the selection callback may be used to query or access resources of the selected object. For example, if the fifth bar of a bar graph was selected, one of the path names will be DataGroup/DataSample4. To query the value of this data sample, concatenate this path name with "Value" using the GlgConcatResNames function and use the resulting DataGroup/DataSample4/Value path name in a call to GlgGetDResource.

The following example shows how to highlight the selected data sample of a graph with a different color in the selection callback:

void Select( viewport, client_data, call_data )
	GlgObject viewport;
	GlgAnyType client_data;
	GlgAnyType call_data;
{
	int i;
	char
		** name_array,
		* name,
		* resource_name;

	if( !name_array )
		return;

	for( i=0; name = name_array[ i ]; ++i )
		if( strstr( name, "DataGroup/DataSample" ) )
		{
			/* Concatenate the name of the data sample with "FillColor". 
*/
			resource_name = GlgConcatResNames( name, "FillColor" );
			GlgSetGResource( viewport, resource_name, 
				1., 0., 0. );    /* Red.*/
			GlgFree( resource_name );
		} 
}
Motif Widget Selection Callback

The Motif version of the GLG Wrapper Widget provides the Motif-style select callback (XtNglgMotifSelectionCB) in addition to the standard GLG callback (XtNglgSelectionCB). The call_data argument supplied to Motif version of the selection callback function is a structure defined as follows:

typedef struct _GlgSelectCBStruct
{
	GlgCallbackType reason;
	XEvent * event; 			/* Event that triggered the callback */
	GlgObject viewport;			/* Viewport that received the mouse click

                    that triggered the selection

                    callback */
	Widget widget; 			/* Wrapper's widget ID */
	long num_selected;			/* The length of the selection list */
	char ** selection_list;			/* Same as in the Xt selection callback */   

} GlgSelectCBStruct;

Note that the structure contains the same list of selected objects that is sent to a callback function when using the Xt version of the Wrapper Widget.

Input Callback

The Toolkit translates the low-level events of the native windowing system, such as mouse moves, and mouse clicks, into high-level GLG events, such as object selection events, custom events and command actions associated with GLG objects, as well as input events such as slider moves and button presses. An input callback is the primary mechanism for handling any GLG events occurring in an application. It is invoked for several types of input activities:

To activate processing of selection and custom selection events on the mouse click and mouse move, the viewport's ProcessMouse attribute must be set to GLG_MOUSE_CLICK or GLG_MOUSE_MOVE_AND_CLICK, respectively. The rest of the event are always processed and do not require any additional settings.

If a system event in a viewport is translated into some GLG event, the input callback of the viewport object is invoked. If the viewport doesn't have an input callback attached, the input callback of its closest parent with input callback is invoked. The call_data parameter of the callback contains a message object used to pass all information about the event to the callback. This information is present in the message object in the form of named resources of the message object and may be obtained from it by using methods for querying resources (GlgGetSResource, GlgGetDResource and GlgGetGResource). The message object should be passed as the first parameter, and a resource name defining the resource to query should be passed as the second parameter. For example, the following code extracts the value of the message object's Origin resource:

char * origin;
GlgGetSResource( message_object, "Origin", &origin );

If the input callback was invoked in response to an activation of an action or a command attached to an object, the message will also contain the ActionObject resource that may be used to access all information associated with the action or command.

The details of the message object for each event type are described in the Message Object section on page 110.

Motif Widget Input Callback

The Motif version of the GLG Wrapper Widget provides the Motif-style input callback (XtNglgMotifInputCB) in addition to the standard GLG callback (XtNglgInputCB). The call_data argument supplied to Motif version of the input callback is a structure defined as follows:

typedef struct _GlgInputCBStruct
{
	GlgCallbackType reason;
	GlgObject viewport;			/* Viewport that received the event that 

                   triggered the input callback. */
	Widget widget;			/* Wrapper's widget ID */
	GlgObject message_obj; 			/* Same as in the Xt input callback */   

} GlgInputCBStruct;

Note that the structure contains the same message object that is sent to a callback function when using the Xt version of the Wrapper Widget; see the Message Object section, below.

Trace Callbacks

The trace callbacks are used as an escape mechanism to provide low-level access to native windowing events. They are invoked whenever a viewport receives a native windowing event and passes the event to the application code for processing. If a viewport object has a trace callback attached, the trace callback will be invoked for all events received by the viewport and all of its child viewports. There are two trace callbacks: the trace callback is invoked before the event is dispatched for processing, and the trace2 callback is invoked after the event has been processed.

As with the other callbacks, it is attached to a viewport with the GlgAddCallback function, or through the resources of the GLG Wrapper Widget.

The information necessary to completely identify an event may be gathered by parsing window data returned to the callback function, or by invoking functions in the GLG Standard or Extended API.

The call_data passed to these callback functions is a structure of platform-specific window data given by the following. In the X Windows environment, the call_data structure looks like this:

typedef _GlgTraceCBStruct
{
	GlgCallbackType reason;   /* GLG_TRACE_CB or GLG_TRACE2_CB */
	GlgObject viewport;       /* Viewport that received the event. */
	GlgObject light_viewport; /* Light viewport of the event or NULL. */
	XEvent * event;           /* Event that triggered the callback. */
	Widget widget;            /* Widget ID of the event viewport. */
	Window window;            /* Window ID of the event viewport. */
	Display * display;        /* Display of the event viewport. */
	XEvent * event1;          /* Reserved */
} GlgTraceCBStruct;

The callback structure contains enough information to determine which viewport received the event (indicated by the viewport field), and where it is. It also contains a pointer to an XEvent structure, which may be used to provide details of the event. For the mouse and key events, the light_viewport field contains the light viewport under the mouse (if any), or NULL otherwise. The widget, window and display fields provide information about the corresponding parameters of the viewport's native components. The reason field is set to the type of the callback: GLG_TRACE_CB or GLG_TRACE2_CB. The event1 pointer is reserved for future use.

Under Microsoft Windows, the trace callback structure looks like this:

typedef _GlgTraceCallbackStruct
{
	GlgCallbackType reason;   /* GLG_TRACE_CB or GLG_TRACE2_CB */
	GlgObject viewport;       /* Viewport that received the event. */
	GlgObject light_viewport; /* Light viewport of the event or NULL. */
	MSG * event;              /* Event that triggered the callback. */
	HWND widget;              /* Window of the event viewport. */
	HWND window;              /* Window of the event viewport. */
	void * display;           /* NULL */
	void * event1;            /* Reserved */
} GlgTraceCallbackStruct;

As with the X Windows version, this structure contains information enough to identify the viewport and light viewport that received the event, and to provide more detail about the event itself in the event field. The widget and window fields contain the handle of the viewport's native window. The callback_type field is set to the type of the callback: GLG_TRACE_CB or GLG_TRACE2_CB. The display field is set to NULL and the event1 pointer is reserved for future use.

In addition to native windowing system events, the trace callbacks may receive a few events generated by the GLG object engine for light viewports: GLG_LV_ENTER_NOTIFY, GLG_LV_LEAVE_NOTIFY and GLG_LV_RESIZE. Under Microsoft Windows, the GLG engine also generates viewport enter notify and leave notify events which are not generated by the native windowing system: GLG_MSW_ENTER_NOTIFY and GLG_MSW_LEAVE_NOTIFY.

Hierarchy Callback

The hierarchy callback is used to get access to the drawing to be displayed in the SubWindow object before the drawing is displayed. SubWindows may be used to switch drawings displayed in them, and an application may want to install a separate input callback for each loaded drawing to handle user interaction instead of having one giant input callback that handles input events from all drawings. An input callback has to be added to the viewport of a drawing displayed in the subwindow before the drawing is set up and drawn. The hierarchy callback is invoked with the ID of the subwindow's drawing after it is loaded but before its hierarchy is setup, making it possible to add input callbacks as well as initialize the drawing with data before it is painted on the screen.

Similarly, the hierarchy callback is also invoked for the SubDrawing objects when they load their template drawings; the callback provides an object ID of the loaded object that will be displayed in the subdrawing.

The hierarchy callback is attached to a viewport with the GlgAddCallback function. A hierarchy callback may be added to the top level viewport or any of its children viewports. If any of a subwindow's (or subdrawing's) parent viewports has a hierarchy callback added, the callback of the closest parent viewport will be invoked each time the subwindow loads a new drawing or the subdrawing loads its template. The hierarchy callback is invoked twice for each template drawing: the first time when the drawing is loaded but before it is set up, and the second time when the drawing is setup but before it is drawn.

The call_data passed to the hierarchy callback is a structure that provides an object ID of the SubWindow object that triggered the callback, as well as an object ID of the viewport of the loaded drawing:

typedef _GlgHierarchyCallbackStruct
{
	GlgCallbackType reason; /* GLG_HIERARCHY_CB */

	/* GLG_BEFORE_SETUP_CB or GLG_AFTER_SETUP_CB */
	GlgHierarchyCallbackType condition; 

	/* Subwindow or subdrawing object that loaded its template. */
	GlgObject object;

	/* Template instance of the subwindow or subdrawing. */ 
	GlgObject subobject;

} GlgHierarchyCallbackStruct;

The reason field of the callback structure is always set to GLG_HIERARCHY_CB. The condition field indicates when the callback is invoked: it is set to GLG_BEFORE_SETUP_CB when the callback is called before the hierarchy setup and to GLG_AFTER_SETUP_CB when it is invoked after the setup.

The object field provides an object ID of the SubWindow or SubDrawing object that triggered the callback. The subobject field contains an ID of the drawing that will be displayed in the subwindow, or ID of the object that will be shown in the subdrawing (the Instance attribute).

The source code of the SCADA Viewer demo provides an example of using the callback.

Message Object

A message object is a GLG object like any other. It is a group object, containing data in the form of named attributes just like other GLG objects. It is used to pass data to the input callbacks that may be associated with a viewport.

Any message object has the following named attributes:

Resource Name
Data Type
Description
Format
String
Defines the format of the message object and the resources present in it. It is defined by the event type and, for input messages, the type of the input handler which detected the input activity and sent the message. It may have values such as Button, Slider, Knob, ObjectSelection, CustomEvent.
Origin
String
Contains the name of the viewport that initiated the message.
FullOrigin
String
Contains the full path name of the viewport that initiated an input or window message, or the full path name of the object that initiated a custom event or a command message. This resource will be set to an empty string for other types of messages.
Action
String
Describes the input action occurred. It may have values such as ValueChanged, Activated, CustomEvent, MouseClick and so on, depending on the event type.
SubAction
String
Describes the action in more details. For example, for the slider's ValueChanged action it describes what caused the value change and may have values such as Click or Motion.
Object
GlgObject
The top-level object that triggered the Input callback, a custom event or a command action. This resource is present in all messages except the ObjectSelection message.
OrigObject
GlgObject
The low-level object that triggered the Input callback, a custom event or a command action. This resource is present in all messages except the ObjectSelection message.

A message object can have other resources as well, depending on the type of the event and, for input object events, the type of the input handler that generated the event. For events triggered by an Action attached to an object, such as Command or Custom Event, the message contains the ActionObject resource.

For events generated by input objects, such as a slider or a button, the message object includes handler-related resources of the input widget. For example, the message object coming from a GLG slider object may also contain such resources as ValueX, ValueY, Granularity, Increment, DisableMotion and others. These resources may be queried from either the message object or the viewport object that generated the message.

Refer to Appendix B: Message Object Resources on page 439 for a complete list of all message types and their resources. Refer to Input Handlers of the GLG User's Guide for a complete list of resources for each input handler type.

Examples of Using Callbacks in Application Code

The following examples demonstrate how to use GLG callbacks. Refer to the source code of the GLG demos for additional examples.

Adding callbacks

The following code adds both selection and input callbacks to the drawing viewport object:

GlgAddCallback( drawing, GLG_SELECT_CB, SelectCB, callback_data );
GlgAddCallback( drawing, GLG_INPUT_CB, InputCB, callback_data );

Processing Selected Objects using Selection Callback

A selection callback has several parameters, one of which is a list of names of all selected objects, including complete path identifying the place of objects in the drawing hierarchy. The following example shows a selection callback which prints names of all selected objects:

void SelectCB( drawing, client_data, call_data )
	GlgObject drawing;
	GlgAnyType client_data;
	GlgAnyType call_data;
{
	char ** name_ array;
	char * name;
	int i;
	name_array = (char **) call_data;
	if( !name_array )
	   PrintOnConsole( "Nothing was selected." );
	else
	   for( i=0; name = name_array[ i ]; ++i )
	      PrintOnConsole( name );
}

The selection callback may be used with a minimal GLG configuration, such as the Basic Edition of the Graphics Builder and the GLG Standard API.

Processing Selected Objects Using Input Callback

While the select callback provides a simplified name-based interface for handling object selection, the input callback provides a more elaborate mechanism based on object IDs. Several object selection techniques are available:

The object selection event is generated when the mouse is moved over an object in the drawing, or an object is selected with a mouse click. The custom selection events and commands are generated when the selected object has a custom event or command action. The ProcessMouse attribute of the viewport object has to include a combination of the Move and Click masks to enable object selection and custom selection events on the corresponding mouse events. Refer to Integrated Features of the GLG Drawing on page 215 of the GLG User's Guide and Builder Reference Manual for more information on object selection and custom selection events.

The following example shows how to process selection using both types of object selection messages.

void InputCB( viewport, client_data, call_data )
	GlgObject viewport;
	GlgAnyType client_data;
	GlgAnyType call_data;
{
	GlgObject
		message_obj,
		selection_array,
		selected_object,
		command,
		action_object,
		action_data;		
	char
	   * format,	/* Message format */
	   * action,	/* Message action */
		* selecte_object_name,  /* Name of the selected object. */
		* event_label,		  /* Event label of a custom event or command. */
		* command_type; /* Type of a command to be executed on object

             selection. */
	double button_index; /* Button that caused object selection. */
	int i, size;

	message_obj = (GlgObject) call_data;
	GlgGetSResource( message_obj, "Format", &format ); 
	GlgGetSResource( message_obj, "Action", &action ); 

	if( strcmp( format. "Command" ) == 0 )
	{
		/* This code handles command actions attached to an			object. 		*/

		/* Retrive command information using the Standard API. */
		GlgGetSResource( message_obj, 							
"ActionObject/Command/CommandType",					&command_type );
		GlgGetSResource( message_obj, "EventLabel", &event_label );
		GlgGetSResource( message_obj, "Object/Name",

           &selected_object_name );

		/* Retrieve the object IDs of the command and the selected

			object using the 						Intermediate 						API.				 */
		selected_object = GlgGetResourceObject( message_obj, "Object" );
		command = 
			GlgGetResourceObject( message_obj, "ActionObject/Command" );

		ExecuteCommand( selected_object, command_type, command );
	}
	else if( strcmp( format, "CustomEvent" ) == 0 )
	{
		/* This code handles custom events attached to		an	 		object.
			This code handles both custom event actions and the 
			old-style custom events. */

		GlgGetSResource( message_obj, "EventLabel", &event_label );

		/* Don't process events with empty EventLabel. An event with an
			empty EventLabel is generated for MouseOver 			events when 			the
			mouse moves away from the object, and for MouseClick events
			when the mouse button is released.
		*/
		if( strcmp( event_label, "" ) == 0 )
         return; 

		/* Retrieve command and selected object (Intermediate API). 
			*/
   		selected_object = GlgGetResourceObject( message_obj, "Object" );
		
		/* Retrieve the selected object's name using Standard API. */
		GlgGetSResource( message_obj, "Object/Name",

           &selected_object_name );
		
		/* For the old-style MouseClick actions, query the mouse button
			that 			generated 			this custom selection event (0 for custom
			MouseOver 			events). */
		GlgGetDResource( message_obj, "ButtonIndex", &button_index );

		/* Prints MouseClick or MouseOver. */
		PrintOnConsole2( "Custom event action: ", action );
		PrintOnConsole2( "Selected object: ", selected_object_name );

		/* Retrieve ActionObject resources of the message object
			(Intermediate API). 			ActionObject will be NULL 			for custom
			events added prior to 			GLG v.3.5. */
		action_obj =
			GlgGetResourceObject( message_obj, "ActionObject" ); 

      		/* Retrieve the action's ActionData. If present, its			properties 
			may be used for 	processing the event. */
		if( action_obj )
			action_data = 

GlgGetResourceObject( action_obj, "ActionData" );

	}
	/* Handle default object selection message. */
	else if( strcmp( format, "ObjectSelection" ) == 0 )
	{
		selection_array = 
			GlgGetResourceObject( message_obj, "SelectionArray" );
		if( !selection_array )
		{
			PrintToConsole( "No objects selected by ", action );
			return;
		}

		/* For MouseClick actions, query the mouse button that caused the
			the selection (0 for MouseMove events). */
		GlgGetDResource( message_obj, "ButtonIndex", &button_index );

		size = GlgGetSize( selection_array );
		for( i=0; i < size; ++i )
		{
			selected_object = GlgGetElement( selection_array, i );
			GlgGetSResource( selected_object, "Name",

	              &selected_object_name );

			/* Print MouseMove or MouseClick. */
			PrintToConsole2( "Selected by: ", action );
			if( !selected_object_name || !*selected_object_name )
					PrintToConsole( "Unnamed object is selected." );
			else
				PrintToConsole2( "Selected object: ", 

                  selected_object_name );
		}
	}
}

The Enterprise Edition of the Graphics Builder is required to add Command actions or custom event actions to objects at design time. The GLG HMI Configurator can be also used to add Command actions to objects. The GLG Intermediate API may be used for more efficient and flexible processing of the Command and Custom Event actions in the application code. In the above example, the GlgGetResourceObject Intermediate API call is used to retrieve object ID of the selected object as well as the command object.

Handling the ObjectSelection message requires the use of the GLG Intermediate API to retrieve IDs of the selected objects.

Processing Input Object Events

There are two methods for processing user input from input objects, such as a button, a slider or a text input field, in an application code:

The following example demonstrates a very simple input callback which terminates the application when a Quit button is pressed. The example demonstrates how to handle the default input object events, as well as an attached command actions.

void InputCB( drawing, client_data, call_data )
	GlgObject drawing;
	GlgAnyType client_data;
	GlgAnyType call_data;
{
	GlgObject message_object;
	char
	   * origin,	 /* Name of the input object */
	   * format,	 /* Message type */
	   * action, /* Reason */
		* command_type; /* Command to be executed */

	message_object = (GlgObject) call_data;
	GlgGetSResource( message_object, "Format", &format ); 

	/* Handle default input object events. */
	if( strcmp( format, "Button" ) == 0 )
	{
		GlgGetSResource( message_object, "Action", &action );
		/* Query the name of the button that generated the message. */
		GlgGetSResource( message_object, "Origin", &origin );

		if( strcmp( action, "Activate" ) == 0 &&
			 strcmp( origin, "Quit" ) == 0 )
	  		exit( 0 );
	}
	/* Handle command actions attached to a button. */
	else if( strcmp( format, "Command" ) == 0 )
	{
		GlgGetSResource( message_object, 
"ActionObject/Command/CommandType", &command_type );
		if( strcmp( command_type, "Quit" ) == 0 )
			exit( 0 );
	}
}

The Enterprise Edition of the Graphics Builder is required to add Input Command actions to input objects at design time. The GLG HMI Configurator can be also used to add Input Command actions. The GLG Intermediate API may be used for more efficient and flexible processing of the Input Command actions in the application code.

Refining Input Object Selection

Default Input Object Events

The following code fragment shows an example of an input callback that uses default input object events. The code determines which of the two sliders in the drawing (the temperature slider or pressure slider) received user input, and calls the appropriate function to process the new value specified by the user.

void InputCallback( viewport, client_data, call_data )
	GlgObject viewport;
	GlgAnyType client_data; 
	GlgAnyType call_data;
{
	GlgObject message_obj;
	char
		* format,
		* action,
		* full_origin;
	double value;

	message_obj = (GlgObject)call_data;

	/* Extract callback data from the message object. */
	GlgGetSResource( message_obj, "Format", &format );
	GlgGetSResource( message_obj, "Action", &action );
	GlgGetSResource( message_obj, "FullOrigin", &full_origin );

	/* Ignore if message came not from a slider or not a ValueChanged. */
	if( strcmp( format, "Slider" ) != 0 || strcmp( action, 
"ValueChanged" ) != 0 )
		return;

	/* Obtain the new value of the slider. */
	GlgGetDResource( message_obj, "Value", &value );

	/* Call an appropriate function depending on the slider name. */

	if( strcmp( full_origin, "TemperatureBlock/Slider" ) == 0 )
		ProcessTemperatureInput( widget, value );
	else if( strcmp( full_origin, "PressureBlock/Slider" ) == 0 )
		ProcessPressureInput( widget, value );
	else
		Error( "Unknown name." );
}

Alternatively, Input Command actions may be attached to the sliders to execute the attached command as shown below.

Input Commands

The following input callback code demonstrates handling Input Command actions attached to the temperature and pressure sliders in the drawing. The code is completely generic and may be used with any drawing, since it uses the command data to execute the command without any reliance on the names of input objects in the drawing. The GLG Intermediate API is used to retrieve IDs of the input object and the command object.

void InputCallback( viewport, client_data, call_data )
	GlgObject viewport;
	GlgAnyType client_data; 
	GlgAnyType call_data;
{
	GlgObject 
		message_obj,
		command_obj,
		input_obj;
	char
		* format,
		* command_type,
		* value_resource,
		* tag;
	double value;

	message_obj = (GlgObject)call_data;

	/* Extract callback data from the message object. */
	GlgGetSResource( message_obj, "Format", &format );
	if( strcmp( format, "Command" ) != 0 )
		return;

	GlgGetSResource( message_obj, "ActionObject/Command/CommandType",
				           &command_type );

	if( strcmp( command_type, "WriteValueFromWidget" ) == 0 )
	{
		command_obj = 
			GlgGetResourceObject( message_obj, 	"ActionObject/Command" );	

		/* Input object that triggered the message. */
		input_obj = GlgGetResourceObject( message_obj, "Object" );

		/* The resource path to the input object's			value.*/
		GlgGetSResource( command, "ValueResource", &value_resource );
		
		/* New value of input object. */
		GlgGetDResource( input_obj, value_resource, &value );			

		/* The process controller tag to write the value to. */
		GlgGetSResource( command, "OutputTagHolder/TagSource", &tag );			

		/* Write the new value. */
		SendValueToController( tag, value );
	}
}

Trace Callback examples

For examples of using the trace callback, refer to the source code of the GLG Diagram demo.

Hierarchy Callback examples

For examples of using the hierarchy callback, refer to the source code of the GlgSCADAViewer demo.


Generic Logic, Inc.
www.genlogic.com
PREV NEXT