Catching keystrokes

We are trying to write an application that receives messages from
another (non-Photon) process and also needs to catch keystrokes from the
keyboard. So far, we are using PtAppAddInput to add an input handler
that does the other messages. How do we go about catching keystrokes?
We found function PtReadEvent but don’t quite know how to invoke it
since we don’t seem to be able to get a callback when using PtMainLoop.
Should we make our own main loop? Or is there another way to get called
back. We are using PhAB.

Thanks in advance

Dean

Dean Douthat <ddouthat@faac.com> wrote:

We are trying to write an application that receives messages from
another (non-Photon) process and also needs to catch keystrokes from the
keyboard. So far, we are using PtAppAddInput to add an input handler
that does the other messages. How do we go about catching keystrokes?

Create (from code - you can’t do it in PhAB - see “Creating
Widgets in Application Code” in the Photon Programmer’s Guide) a
PtRegion widget owned by your application that sits on the root
side of the Device Region. Make it sensitive to keyboard events
(and non-opaque to them too, if you don’t want to block keyboard
events to all other applications. Attach (again from code) a
filter or raw callback to the PtRegion, and grab your keyboard
events there. There’s a bit on emitting key events in the Events
section of the Programmer’s Guide which will help you understand
what you’re looking at.

This is very brief (the current (QNX 6) Photon Advanced course
covers this general topic in about 100 pages…), but if you work
through the “Photon Architecture”, “Regions” and “Events”
chapters of the 1.14 Programmer’s Guide, you should be able to
get enough background to see what I’m on about above.

We found function PtReadEvent but don’t quite know how to invoke it
since we don’t seem to be able to get a callback when using PtMainLoop.
Should we make our own main loop? Or is there another way to get called
back. We are using PhAB.

You definitely don’t need your own main loop. Go with the
PtRegion + Raw (or Filter) callback approach.



Just on the chance it will help, I’ll drop in the callback code
from two of the samples from the Advanced Photon course. Note
that this is QNX6 code, and neither does quite what you want.
Still, it should show you a few of the tricks involved.


Hope this helps.


Norbert Black
QSSL Training Services


********** code from “emitter” begins **************************

/* callbacks.c

This application demonstrates the use of the PtRegion
widget.

This file contains:

base_btn_createregion_activateCB()
Callback type: Pt_CB_ACTIVATE
Widget: base_btn_createregion

This function demonstrates how to create a region
using the PtRegion widget. Its parent is set to
be the Device region, which puts the widget closer
to the user than that region.



base_btn_emitQ_activateCB()
Callback type: Pt_CB_ACTIVATE
Widget: base_btn_emitQ

This function shows how to emit both key down and key
up events as raw key events to be focused, consumed
and remitted by the Device region. The events are
emitted towards the root region.

\

/


/
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 “abimport.h”
#include “proto.h”


/
***************************


*** global variables ***


**************************/
PtWidget_t region_widget = NULL;


/
--------------------------------------------------------------------

*

  • base_btn_createregion_activateCB

--------------------------------------------------------------------/
int
base_btn_createregion_activateCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhArea_t area;
PtArg_t arg[20];
short nargs = 0;
long fields;

fields = Ph_REGION_FLAGS |
Ph_REGION_OWNER |
Ph_REGION_PARENT;

/*

  • this specifies which resources we are setting below.
    *‘fields’ is set above. Be sure to update the list if you
  • change which resources are being set.
    /
    PtSetArg( &arg[nargs++], Pt_ARG_REGION_FIELDS, fields, fields );


    /
  • parent is the Device region; this will put our new
  • region closer to the user than that region
    /
    PtSetArg( &arg[nargs++], Pt_ARG_REGION_PARENT, Ph_DEV_RID, 0 );


    /
  • owner is our process; we set this so that we can recognize
  • the region as belonging to us when we use the “phin” tool
    */
    PtSetArg( &arg[nargs++], Ph_REGION_OWNER,
    PtWidgetRid( ABW_base ), 0 );

/*

  • our region should be a keyboard region, since we’ll be using
  • it to emit key-related events
    /
    PtSetArg( &arg[nargs++], Pt_ARG_REGION_FLAGS,
    Ph_KBD_REGION, Ph_KBD_REGION );


    /
  • we want our region to cover the visible x/y plane, which
  • extends from 0 to SHRT_MAX along both axes; setting Pt_ARG_AREA
  • causes Pt_ARG_REGION_ORIGIN and Pt_ARG_REGION_RECT to be set
  • accordingly
    /
    area.pos.x = area.pos.y = 0;
    area.size.w = area.size.h = -(SHRT_MIN) + SHRT_MAX;
    PtSetArg( &arg[nargs++], Pt_ARG_AREA, &area, 0 );


    /
  • we’ll make the region have a transparent fill color so
  • we can see through it…
    */
    PtSetArg( &arg[nargs++], Pt_ARG_FILL_COLOR, Pg_TRANSPARENT, 0 );

/*

  • create the widget
    /
    if( ( region_widget = PtCreateWidget( PtRegion, Pt_NO_PARENT,
    nargs, arg ) )
    == NULL )
    {
    perror( “emitter: failed PtCreateWidget()” );
    return( Pt_CONTINUE );
    }


    /
  • put the widget into Photon event space
    /
    if( ( PtRealizeWidget( region_widget ) ) == -1 )
    {
    perror( “emitter: failed PtRealizeWidget()” );
    return( Pt_CONTINUE );
    }


    /
  • disable this button so that we don’t have more than one
  • dynamically created PtRegion
    */
    nargs = 0;
    PtSetArg( &arg[nargs++], Pt_ARG_FLAGS, Pt_GHOST,
    Pt_GETS_FOCUS |Pt_GHOST | Pt_SELECTABLE );
    PtSetResources( widget, nargs, arg );

/*

  • enable the “Emit a Q” button, which requires our new region
  • to do its work
    */
    nargs = 0;
    PtSetArg( &arg[nargs++], Pt_ARG_FLAGS,
    Pt_GETS_FOCUS |Pt_SELECTABLE,
    Pt_GETS_FOCUS |Pt_GHOST | Pt_SELECTABLE );
    PtSetResources( ABW_base_btn_emitQ, nargs, arg );

/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}



/--------------------------------------------------------------------
*

  • base_btn_emitQ_activateCB

--------------------------------------------------------------------/ int
base_btn_emitQ_activateCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhEvent_t event;
PhRawKeyEvent_t key_data;
PhRect_t event_rect;

memset( &event, 0, sizeof( event ) );
memset( &key_data, 0, sizeof( key_data ) );


/*

  • this is going to be a Raw event, not a key event, because
  • we want to emit it rootwards towards the Device region,
  • which will consume, focus, and reemit our event as a true
  • key event
    */
    event.type = Ph_EV_RAW;
    event.subtype = Ph_EV_RAW_KEY;
    event.emitter.rid = PtWidgetRid( region_widget );
    event.collector.rid = Ph_DEV_RID;
    event.input_group = PhInputGroup( NULL );
    event.data_len = sizeof( key_data );
    event.num_rects = 1;

/*

  • the event’s rectangle covers the entire event space;
  • this saves us from finding out the extent of the
  • collector’s region
    /
    event_rect.ul.x = event_rect.ul.y = SHRT_MIN;
    event_rect.lr.x = event_rect.lr.y = SHRT_MAX;


    /
  • describe the key involved in this event
    /
    key_data.key_cap = Pk_q; /
    we’re using the “q” /
    key_data.key_sym = Pk_Q; /
    modified, it’s a “Q” /
    key_data.key_mods = Pk_KM_Shift; /
    these are the modifiers used */

/*

  • emit key down
    /
    key_data.key_flags = Pk_KF_Key_Down | Pk_KF_Sym_Valid |
    Pk_KF_Cap_Valid;
    PhEventEmit( &event, &event_rect, &key_data );


    /
  • emit key up - note that we toggle the status of the key_down
  • field - it must be clear for this event to be recognised as
  • a key up event
    /
    key_data.key_flags &= ~(Pk_KF_Key_Down);
    PhEventEmit( &event, &event_rect, &key_data );


    /
    eliminate ‘unreferenced’ warnings */
    widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}


********** code from “ptregion” begins **************************

/* callbacks.c /
/
/
/
This application demonstrates the use of the PtRegion /
/
widget. /
/
/
/
IMPORTANT: We are setting the parent region using /
/
Pt_ARG_REGION_PARENT and setting the region that is /
/
front of our region using Pt_ARG_REGION_INFRONT. The /
/
parent is being set to the root region (Ph_ROOT_RID) /
/
and the region in front is being set to the device /
/
region (Ph_DEV_RID). By saying that we want the /
/
device region to be in front we are also saying that /
/
we want it to be our brother. Well, if the device /
/
region is to be our brother then it’s parent had /
/
better also be the same are our parent (the root /
/
region). /
/
/
/
This file contains: /
/
/
/
base_btn_createregion_activateCB() /
/
Callback type: Pt_CB_ACTIVATE /
/
Widget: base_btn_createregion /
/
/
/
This function demonstrates how to create a region /
/
using the PtRegion widget. /
/
/
/
-------------------------------------------------------/
/
/
/
eventsCB() /
/
Callback type: Pt_CB_RAW /
/
Widget: the PtRegion created in /
/
createRegionCB() /
/
/
/
This simply prints out that it got an event. /
/
/
/
-------------------------------------------------------/
/
/
/
PhotonGetWindowPosn() /
/
Function type: called by createRegionCB() /
/
Widget: none /
/
/
/
This function returns the absolute coordinates of /
/
the top,left corner of the base window’s frame and /
/
the size inside the frame. /
/
/
/
Operation: /
/
/
/
To get the size this simply gets the value of the /
/
Pt_ARG_DIM resource. /
/
/
/
To get the coordinates this calls /
/
PtGetAbsPosition() to get the absolute position /
/
of the window inside the frame. It then calls /
/
PtWindowFrameSize() to get the height and width /
/
of the frame. Next, it subtracts the frame /
/
height from the absolute y coordinate inside the /
/
frame to get the absolute y coordiante of the /
/
frame. It does the same for the x coordinate. /
/
/
/
AppBuilder Photon Code Lib /
/
Version 1.11B */

/* 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 “abimport.h”
#include “proto.h”


/
***************************


*** global variables ***


**************************/
PtWidget_t regionWidget;


/
--------------------------------------------------------------------

*

  • base_btn_createregion_activateCB

--------------------------------------------------------------------/
int
base_btn_createregion_activateCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhArea_t area;
PtArg_t arg[20];
short numargs = 0;
long fields;

fields =
//Ph_REGION_ORIGIN
//Ph_REGION_RECT
Ph_REGION_PARENT
//Ph_REGION_HANDLE
//Ph_REGION_OWNER
|Ph_REGION_EV_SENSE
//Ph_REGION_EV_OPAQUE
|Ph_REGION_IN_FRONT
|Ph_REGION_INPUT_GROUP
;


/*

  • this specifies which resources we are setting below.
  • ‘fields’ is set above. Be sure to update the list if you change
  • which resources are being set.
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_FIELDS, fields, fields );

/*

  • the position and size of the region will be the same as the
  • window. PhotonGetWindowPosn() is a function written below
    */
    PhotonGetWindowPosn( ABW_base, &area.pos.y, &area.pos.x,
    &area.size.h, &area.size.w );

/*

  • setting Pt_ARG_AREA causes Pt_ARG_REGION_ORIGIN and
  • Pt_ARG_REGION_RECT to be set accordingly
    */
    PtSetArg( &arg[numargs++], Pt_ARG_AREA, &area, 0 );

/*

  • parent is the root region. Necessary because child
  • regions only get events for the areas of their region that
  • overlaps their parent’s region. If we used the base
  • window’s region then we would only get events that are in
  • the area when the child region and the base window overlap.
  • The root region, however, the covers all possible areas and
  • so we get events for our entire region no matter where it is.
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_PARENT, Ph_ROOT_RID, 0 );

/*

  • this region is sensitive only to key events
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_SENSE, Ph_EV_KEY,
    Ph_EV_KEY );

/*

  • this region is opaque only to key events
    */
    //PtSetArg( &arg[numargs++], Pt_ARG_REGION_OPAQUE,
    // Ph_EV_KEY, Ph_EV_KEY );

/*

  • the device region will be in front of our region (i.e.
  • we will be behind the device region
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_INFRONT, Ph_DEV_RID, 0 );

/*

  • this defaults to 0
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_INPUT_GROUP,
    cbinfo->event->input_group, 0 );

PtSetArg( &arg[numargs++], Pt_ARG_FILL_COLOR, Pg_GREEN, 0 );

regionWidget = PtCreateWidget( PtRegion, NULL, numargs, arg );
PtAddEventHandler( regionWidget, Ph_EV_KEY, eventsCB, NULL );
PtRealizeWidget( regionWidget );

/*

  • disable this button so that we don’t have more than one
  • dynamically created PtRegion
    /
    numargs = 0;
    PtSetArg( &arg[numargs++], Pt_ARG_FLAGS, Pt_GHOST,
    Pt_GETS_FOCUS |Pt_GHOST | Pt_SELECTABLE );
    PtSetResources( widget, numargs, arg );


    /
    eliminate ‘unreferenced’ warnings */
    widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}

/--------------------------------------------------------------------
*

  • eventsCB

-------------------------------------------------------------------/
int
eventsCB (PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo)
{
printf( “got an event\n” );

/* eliminate ‘unreferenced’ warnings */
widget = widget, data = data, cbinfo = cbinfo;

return( Pt_CONTINUE );
}

/--------------------------------------------------------------------
*

  • PhotonGetWindowPosn

-------------------------------------------------------------------/
void
PhotonGetWindowPosn (PtWidget_t *window, short *top, short *left,
unsigned short *height, unsigned short *width)
{
PtArg_t arg[1];
PhPoint_t *dim;
PhRect_t window_rect;
int framebottom, frameleft, frameright, frametop;
short xpos, ypos;

PtSetArg( &arg[0], Pt_ARG_DIM, &dim, 0 );
PtGetResources( window, 1, arg );

PtGetAbsPosition( window, &xpos, &ypos );

PtWindowFrameSize( NULL, window, &window_rect );
frametop = window_rect.ul.y;
framebottom = window_rect.lr.y;
frameleft = window_rect.ul.x;
frameright = window_rect.lr.x;

*top = ypos - frametop;
*left = xpos - frameleft;
*height = dim->y + frametop + framebottom;
*width = dim->x + frameleft + frameright;
}

Thanks, Norbert!

I am an associate of Dean Douthat.

I attempted to create a region as you suggested, using the main window’s
Realize callback to create the REGION. Since I couldn’t use
PtWindowFrameSize(), I used arbitrary values of {0,1000} and {0, 1000} for
the area.

I modified your code such that the color is TRANSPARENT as opposed to GREEN.
This works fairly well.

The problem I am having now is that I cannot realize any other windows. I
get a Memory Fault. Does this Region code conflict with the realization of
other dialogs/window?

“Norbert Black” <nblack@qnx.com> wrote in message
news:9vqdbu$i3d$1@nntp.qnx.com

Dean Douthat <> ddouthat@faac.com> > wrote:
We are trying to write an application that receives messages from
another (non-Photon) process and also needs to catch keystrokes from the
keyboard. So far, we are using PtAppAddInput to add an input handler
that does the other messages. How do we go about catching keystrokes?

Create (from code - you can’t do it in PhAB - see “Creating
Widgets in Application Code” in the Photon Programmer’s Guide) a
PtRegion widget owned by your application that sits on the root
side of the Device Region. Make it sensitive to keyboard events
(and non-opaque to them too, if you don’t want to block keyboard
events to all other applications. Attach (again from code) a
filter or raw callback to the PtRegion, and grab your keyboard
events there. There’s a bit on emitting key events in the Events
section of the Programmer’s Guide which will help you understand
what you’re looking at.

This is very brief (the current (QNX 6) Photon Advanced course
covers this general topic in about 100 pages…), but if you work
through the “Photon Architecture”, “Regions” and “Events”
chapters of the 1.14 Programmer’s Guide, you should be able to
get enough background to see what I’m on about above.

We found function PtReadEvent but don’t quite know how to invoke it
since we don’t seem to be able to get a callback when using PtMainLoop.
Should we make our own main loop? Or is there another way to get called
back. We are using PhAB.

You definitely don’t need your own main loop. Go with the
PtRegion + Raw (or Filter) callback approach.



Just on the chance it will help, I’ll drop in the callback code
from two of the samples from the Advanced Photon course. Note
that this is QNX6 code, and neither does quite what you want.
Still, it should show you a few of the tricks involved.


Hope this helps.


Norbert Black
QSSL Training Services


********** code from “emitter” begins **************************

/* callbacks.c

This application demonstrates the use of the PtRegion
widget.

This file contains:

base_btn_createregion_activateCB()
Callback type: Pt_CB_ACTIVATE
Widget: base_btn_createregion

This function demonstrates how to create a region
using the PtRegion widget. Its parent is set to
be the Device region, which puts the widget closer
to the user than that region.



base_btn_emitQ_activateCB()
Callback type: Pt_CB_ACTIVATE
Widget: base_btn_emitQ

This function shows how to emit both key down and key
up events as raw key events to be focused, consumed
and remitted by the Device region. The events are
emitted towards the root region.

\

/


/
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 “abimport.h”
#include “proto.h”


/
***************************


*** global variables ***


**************************/
PtWidget_t region_widget = NULL;


/
--------------------------------------------------------------------

*

  • base_btn_createregion_activateCB

--------------------------------------------------------------------/
int
base_btn_createregion_activateCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhArea_t area;
PtArg_t arg[20];
short nargs = 0;
long fields;

fields = Ph_REGION_FLAGS |
Ph_REGION_OWNER |
Ph_REGION_PARENT;

/*

  • this specifies which resources we are setting below.
    *‘fields’ is set above. Be sure to update the list if you
  • change which resources are being set.
    /
    PtSetArg( &arg[nargs++], Pt_ARG_REGION_FIELDS, fields, fields );


    /
  • parent is the Device region; this will put our new
  • region closer to the user than that region
    /
    PtSetArg( &arg[nargs++], Pt_ARG_REGION_PARENT, Ph_DEV_RID, 0 );


    /
  • owner is our process; we set this so that we can recognize
  • the region as belonging to us when we use the “phin” tool
    */
    PtSetArg( &arg[nargs++], Ph_REGION_OWNER,
    PtWidgetRid( ABW_base ), 0 );

/*

  • our region should be a keyboard region, since we’ll be using
  • it to emit key-related events
    /
    PtSetArg( &arg[nargs++], Pt_ARG_REGION_FLAGS,
    Ph_KBD_REGION, Ph_KBD_REGION );


    /
  • we want our region to cover the visible x/y plane, which
  • extends from 0 to SHRT_MAX along both axes; setting Pt_ARG_AREA
  • causes Pt_ARG_REGION_ORIGIN and Pt_ARG_REGION_RECT to be set
  • accordingly
    /
    area.pos.x = area.pos.y = 0;
    area.size.w = area.size.h = -(SHRT_MIN) + SHRT_MAX;
    PtSetArg( &arg[nargs++], Pt_ARG_AREA, &area, 0 );


    /
  • we’ll make the region have a transparent fill color so
  • we can see through it…
    */
    PtSetArg( &arg[nargs++], Pt_ARG_FILL_COLOR, Pg_TRANSPARENT, 0 );

/*

  • create the widget
    /
    if( ( region_widget = PtCreateWidget( PtRegion, Pt_NO_PARENT,
    nargs, arg ) )
    == NULL )
    {
    perror( “emitter: failed PtCreateWidget()” );
    return( Pt_CONTINUE );
    }


    /
  • put the widget into Photon event space
    /
    if( ( PtRealizeWidget( region_widget ) ) == -1 )
    {
    perror( “emitter: failed PtRealizeWidget()” );
    return( Pt_CONTINUE );
    }


    /
  • disable this button so that we don’t have more than one
  • dynamically created PtRegion
    */
    nargs = 0;
    PtSetArg( &arg[nargs++], Pt_ARG_FLAGS, Pt_GHOST,
    Pt_GETS_FOCUS |Pt_GHOST | Pt_SELECTABLE );
    PtSetResources( widget, nargs, arg );

/*

  • enable the “Emit a Q” button, which requires our new region
  • to do its work
    */
    nargs = 0;
    PtSetArg( &arg[nargs++], Pt_ARG_FLAGS,
    Pt_GETS_FOCUS |Pt_SELECTABLE,
    Pt_GETS_FOCUS |Pt_GHOST | Pt_SELECTABLE );
    PtSetResources( ABW_base_btn_emitQ, nargs, arg );

/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}



/--------------------------------------------------------------------
*

  • base_btn_emitQ_activateCB

--------------------------------------------------------------------/
int
base_btn_emitQ_activateCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhEvent_t event;
PhRawKeyEvent_t key_data;
PhRect_t event_rect;

memset( &event, 0, sizeof( event ) );
memset( &key_data, 0, sizeof( key_data ) );


/*

  • this is going to be a Raw event, not a key event, because
  • we want to emit it rootwards towards the Device region,
  • which will consume, focus, and reemit our event as a true
  • key event
    */
    event.type = Ph_EV_RAW;
    event.subtype = Ph_EV_RAW_KEY;
    event.emitter.rid = PtWidgetRid( region_widget );
    event.collector.rid = Ph_DEV_RID;
    event.input_group = PhInputGroup( NULL );
    event.data_len = sizeof( key_data );
    event.num_rects = 1;

/*

  • the event’s rectangle covers the entire event space;
  • this saves us from finding out the extent of the
  • collector’s region
    /
    event_rect.ul.x = event_rect.ul.y = SHRT_MIN;
    event_rect.lr.x = event_rect.lr.y = SHRT_MAX;


    /
  • describe the key involved in this event
    /
    key_data.key_cap = Pk_q; /
    we’re using the “q” /
    key_data.key_sym = Pk_Q; /
    modified, it’s a “Q” /
    key_data.key_mods = Pk_KM_Shift; /
    these are the modifiers used */

/*

  • emit key down
    /
    key_data.key_flags = Pk_KF_Key_Down | Pk_KF_Sym_Valid |
    Pk_KF_Cap_Valid;
    PhEventEmit( &event, &event_rect, &key_data );


    /
  • emit key up - note that we toggle the status of the key_down
  • field - it must be clear for this event to be recognised as
  • a key up event
    /
    key_data.key_flags &= ~(Pk_KF_Key_Down);
    PhEventEmit( &event, &event_rect, &key_data );


    /
    eliminate ‘unreferenced’ warnings */
    widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}


********** code from “ptregion” begins **************************

/* callbacks.c /
/
/
/
This application demonstrates the use of the PtRegion /
/
widget. /
/
/
/
IMPORTANT: We are setting the parent region using /
/
Pt_ARG_REGION_PARENT and setting the region that is /
/
front of our region using Pt_ARG_REGION_INFRONT. The /
/
parent is being set to the root region (Ph_ROOT_RID) /
/
and the region in front is being set to the device /
/
region (Ph_DEV_RID). By saying that we want the /
/
device region to be in front we are also saying that /
/
we want it to be our brother. Well, if the device /
/
region is to be our brother then it’s parent had /
/
better also be the same are our parent (the root /
/
region). /
/
/
/
This file contains: /
/
/
/
base_btn_createregion_activateCB() /
/
Callback type: Pt_CB_ACTIVATE /
/
Widget: base_btn_createregion /
/
/
/
This function demonstrates how to create a region /
/
using the PtRegion widget. /
/
/
/
-------------------------------------------------------/
/
/
/
eventsCB() /
/
Callback type: Pt_CB_RAW /
/
Widget: the PtRegion created in /
/
createRegionCB() /
/
/
/
This simply prints out that it got an event. /
/
/
/
-------------------------------------------------------/
/
/
/
PhotonGetWindowPosn() /
/
Function type: called by createRegionCB() /
/
Widget: none /
/
/
/
This function returns the absolute coordinates of /
/
the top,left corner of the base window’s frame and /
/
the size inside the frame. /
/
/
/
Operation: /
/
/
/
To get the size this simply gets the value of the /
/
Pt_ARG_DIM resource. /
/
/
/
To get the coordinates this calls /
/
PtGetAbsPosition() to get the absolute position /
/
of the window inside the frame. It then calls /
/
PtWindowFrameSize() to get the height and width /
/
of the frame. Next, it subtracts the frame /
/
height from the absolute y coordinate inside the /
/
frame to get the absolute y coordiante of the /
/
frame. It does the same for the x coordinate.
/
/
/
/
AppBuilder Photon Code Lib /
/
Version 1.11B */

/* 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 “abimport.h”
#include “proto.h”


/
***************************


*** global variables ***


**************************/
PtWidget_t regionWidget;


/
--------------------------------------------------------------------

*

  • base_btn_createregion_activateCB

--------------------------------------------------------------------/
int
base_btn_createregion_activateCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhArea_t area;
PtArg_t arg[20];
short numargs = 0;
long fields;

fields =
//Ph_REGION_ORIGIN
//Ph_REGION_RECT
Ph_REGION_PARENT
//Ph_REGION_HANDLE
//Ph_REGION_OWNER
|Ph_REGION_EV_SENSE
//Ph_REGION_EV_OPAQUE
|Ph_REGION_IN_FRONT
|Ph_REGION_INPUT_GROUP
;


/*

  • this specifies which resources we are setting below.
  • ‘fields’ is set above. Be sure to update the list if you change
  • which resources are being set.
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_FIELDS, fields, fields );

/*

  • the position and size of the region will be the same as the
  • window. PhotonGetWindowPosn() is a function written below
    */
    PhotonGetWindowPosn( ABW_base, &area.pos.y, &area.pos.x,
    &area.size.h, &area.size.w );

/*

  • setting Pt_ARG_AREA causes Pt_ARG_REGION_ORIGIN and
  • Pt_ARG_REGION_RECT to be set accordingly
    */
    PtSetArg( &arg[numargs++], Pt_ARG_AREA, &area, 0 );

/*

  • parent is the root region. Necessary because child
  • regions only get events for the areas of their region that
  • overlaps their parent’s region. If we used the base
  • window’s region then we would only get events that are in
  • the area when the child region and the base window overlap.
  • The root region, however, the covers all possible areas and
  • so we get events for our entire region no matter where it is.
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_PARENT, Ph_ROOT_RID, 0 );

/*

  • this region is sensitive only to key events
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_SENSE, Ph_EV_KEY,
    Ph_EV_KEY );

/*

  • this region is opaque only to key events
    */
    //PtSetArg( &arg[numargs++], Pt_ARG_REGION_OPAQUE,
    // Ph_EV_KEY, Ph_EV_KEY );

/*

  • the device region will be in front of our region (i.e.
  • we will be behind the device region
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_INFRONT, Ph_DEV_RID, 0 );

/*

  • this defaults to 0
    */
    PtSetArg( &arg[numargs++], Pt_ARG_REGION_INPUT_GROUP,
    cbinfo->event->input_group, 0 );

PtSetArg( &arg[numargs++], Pt_ARG_FILL_COLOR, Pg_GREEN, 0 );

regionWidget = PtCreateWidget( PtRegion, NULL, numargs, arg );
PtAddEventHandler( regionWidget, Ph_EV_KEY, eventsCB, NULL );
PtRealizeWidget( regionWidget );

/*

  • disable this button so that we don’t have more than one
  • dynamically created PtRegion
    /
    numargs = 0;
    PtSetArg( &arg[numargs++], Pt_ARG_FLAGS, Pt_GHOST,
    Pt_GETS_FOCUS |Pt_GHOST | Pt_SELECTABLE );
    PtSetResources( widget, numargs, arg );


    /
    eliminate ‘unreferenced’ warnings */
    widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}

/--------------------------------------------------------------------
*

  • eventsCB

-------------------------------------------------------------------/
int
eventsCB (PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo)
{
printf( “got an event\n” );

/* eliminate ‘unreferenced’ warnings */
widget = widget, data = data, cbinfo = cbinfo;

return( Pt_CONTINUE );
}

/--------------------------------------------------------------------
*

  • PhotonGetWindowPosn

-------------------------------------------------------------------/
void
PhotonGetWindowPosn (PtWidget_t *window, short *top, short *left,
unsigned short *height, unsigned short *width)
{
PtArg_t arg[1];
PhPoint_t *dim;
PhRect_t window_rect;
int framebottom, frameleft, frameright, frametop;
short xpos, ypos;

PtSetArg( &arg[0], Pt_ARG_DIM, &dim, 0 );
PtGetResources( window, 1, arg );

PtGetAbsPosition( window, &xpos, &ypos );

PtWindowFrameSize( NULL, window, &window_rect );
frametop = window_rect.ul.y;
framebottom = window_rect.lr.y;
frameleft = window_rect.ul.x;
frameright = window_rect.lr.x;

*top = ypos - frametop;
*left = xpos - frameleft;
*height = dim->y + frametop + framebottom;
*width = dim->x + frameleft + frameright;
}

David Hurlburt <dhurlburt@faac.com> wrote:

I am an associate of Dean Douthat.

I attempted to create a region as you suggested, using the main window’s
Realize callback to create the REGION. Since I couldn’t use
PtWindowFrameSize(), I used arbitrary values of {0,1000} and {0, 1000} for
the area.

Fine to start. Think carefully about both region position and
size for your eventual application. For something parented on
the Root region (necessary to get the Device region as brother in
front), you’ll be using absolute coordinates for the position.
Position (0,0) and size (1000, 1000) will cover console 1 and
part of some adjacent consoles (in most resolutions), but leave
other consoles uncovered.

I modified your code such that the color is TRANSPARENT as opposed to GREEN.

Good decision! :slight_smile: When first working with this stuff, I usually
leave the colour opaque, just to make sure I’m getting the
region where I think I am.

This works fairly well.

The problem I am having now is that I cannot realize any other windows. I
get a Memory Fault. Does this Region code conflict with the realization of
other dialogs/window?

It shouldn’t.

How are you realizing your other dialogs/windows? Are you
perhaps trying to call PtRealizeWidget( ABW_somewidget ) before
ABW_somewidget holds a meaningful value? That would give you
this kind of result. Normally, if you’re trying to manipulate
modules, you’d use ApCreateModule( ABM_somemodule ) which both
creates and realizes a dialog/window module.



Norbert Black
QSSL Training Services

“Norbert Black” <nblack@qnx.com> wrote in message
news:9vsumc$elv$1@nntp.qnx.com

Fine to start. Think carefully about both region position and
size for your eventual application. For something parented on
the Root region (necessary to get the Device region as brother in
front), you’ll be using absolute coordinates for the position.
Position (0,0) and size (1000, 1000) will cover console 1 and
part of some adjacent consoles (in most resolutions), but leave
other consoles uncovered.

I understand. I don’t foresee the end user caring too much about the other
consoles, but I wanted to pick a choice size incase they increase the size
of their console 1.

The problem I am having now is that I cannot realize any other windows.
I
get a Memory Fault. Does this Region code conflict with the realization
of
other dialogs/window?

It shouldn’t.

How are you realizing your other dialogs/windows? Are you
perhaps trying to call PtRealizeWidget( ABW_somewidget ) before
ABW_somewidget holds a meaningful value? That would give you
this kind of result. Normally, if you’re trying to manipulate
modules, you’d use ApCreateModule( ABM_somemodule ) which both
creates and realizes a dialog/window module.

Just to get back to you incase you were wondering - I modified abmain.c and
am keeping an extra copy of it since PhAB likes to overwrite it everytime.
I added some features to 1 dialog that was not getting created correctly
from my old abmain.c
Thanks so much for your help.

Perhaps you can aid me in a follow on issue:

In the eventsCB which I lifted from you, I am now trying to filter the key
event. I have the following code:

PhEvent_t *pEvent;

pEvent = cbinfo->event;

if ( pEvent->type == Ph_EV_KEY ) // verify region code is working
{
printf(“got event type %d\n”, pEvent->type);
}

What I need to do is determine if the event was a “W” or a ‘w’. An “up
arrow” or a “down arrow”. But I do not see how to extract this info.

The help that we have says forPh_EV_KEY: Emitted when a key state changes.
This event’s rectangle set consists of a point source that indicates the
current focus. The event data is a PhKeyEvent_t structure.

I do not know how to access this event data. There isn’t a place in
PhEvent_t. or is there?

Thanks in advance…

“David Hurlburt” <dhurlburt@faac.com> wrote in message
news:9vtgiv$4t1$1@inn.qnx.com

Perhaps you can aid me in a follow on issue:

In the eventsCB which I lifted from you, I am now trying to filter the key
event. I have the following code:

PhEvent_t *pEvent;

pEvent = cbinfo->event;

if ( pEvent->type == Ph_EV_KEY ) // verify region code is working
{
printf(“got event type %d\n”, pEvent->type);
}

What I need to do is determine if the event was a “W” or a ‘w’. An “up
arrow” or a “down arrow”. But I do not see how to extract this info.

The help that we have says forPh_EV_KEY: Emitted when a key state changes.
This event’s rectangle set consists of a point source that indicates the
current focus. The event data is a PhKeyEvent_t structure.

I do not know how to access this event data. There isn’t a place in
PhEvent_t. or is there?

I think I figured it out. I’m doing this:

phKeyEvent_t *pKeyEvent;

pKeyEvent = (PhKeyEvent_t *)PhGetData(pEvent);

I can see the keys, although I don’t understand where the codes like uparrow
come from. But I can deal with that. The problem I NOW have it that when I
terminate my application, all the key strokes that I have done are now
listed on the command line - and there is a max buffer that gets filled. Is
there a way to stop this from happening?

Hi David

David Hurlburt <dhurlburt@faac.com> wrote:

Just to get back to you incase you were wondering - I modified abmain.c and
am keeping an extra copy of it since PhAB likes to overwrite it everytime.
I added some features to 1 dialog that was not getting created correctly
from my old abmain.c

=;-o

Yipe! No no no no no no! Never (ever!) mess with a file
named ab* in a PhAB process. Bad Things Are Likely To Happen.
<cue theme music from “Jaws”>

Seriously - don’t put your own code in that file. If you need to
do application-level setup stuff, you’re far better off doing it
in an application initialization function. Just remember not to
try to access any PhAB-defined widgets in this function - the
various ABW_mumble pointers won’t have meaningful data in them at
this stage.

As for your creating a PtRegion, that makes sense in the base
window module’s Pt_CB_WINDOW_OPENING callback. At that stage,
the window and its children will have performed all their
geometry negotiation, so you can use PtGetResources() to find out
about the PtWindow’s size and position without worry of them not
being meaningful values.

I’d avoid doing any work that calls PtRealizeWidget() from inside
a window’s Pt_CB_REALIZED callback - the callback is called from
within PtRealizeWidget(). The library is supposed to handle the
recursion gracefully, but it never hurts to avoid that kind of
thing…



Thanks so much for your help.

Glad to help when I have the cycles free (well, sort of free –
I was letting a problem in the new course module I’m writing stew
gently in the back of my mind while catching up on by qdn
reading…).

Perhaps you can aid me in a follow on issue:

In the eventsCB which I lifted from you, I am now trying to filter the key
event. I have the following code:

PhEvent_t *pEvent;

pEvent = cbinfo->event;

if ( pEvent->type == Ph_EV_KEY ) // verify region code is working
{
printf(“got event type %d\n”, pEvent->type);
}

What I need to do is determine if the event was a “W” or a ‘w’. An “up
arrow” or a “down arrow”. But I do not see how to extract this info.

“W” or “w” - look at the modifiers to the key (held in the
key_cap field in the PhKeyEvent_t structure). Here’s a snippet
(again of QNX 6 code from the Photon Advanced course, since
that’s what I’ve got to hand, but most of it is backwards
compatible) that shows how to look for upper case keys:

*************************** begins ******************************
int
base_txt_filterCB( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhKeyEvent_t *key_data;

/*

  • always make sure that you’re dealing with the
  • event type you think you are – it’s all too easy
  • for someone to change the event mask and not update
  • the code in the callback…
    /
    switch( cbinfo->event->type )
    {
    case Ph_EV_KEY:
    /
  • extract the data structure that accompanies this event;
  • note that this structure is not held in the event
  • itself
    */
    key_data = PhGetData( cbinfo->event );

/*

  • if the shift, shiftlock capslock key is pressed, this
  • key is upper case - we’ll stop the event processing
  • before the key effects the widget’s text string
    /
    if( ( key_data->key_mods & Pk_KM_Shift ) ||
    ( key_data->key_mods & Pk_KM_Caps_Lock ) ||
    ( key_data->key_mods & Pk_KM_Shift_Lock ) )
    {
    printf( “filter_out_uppercase: consumed uppercase key\n” );
    return( Pt_CONSUME );
    }
    /
  • other types of key we allow to fall through as normal
    */
    else
    return( Pt_PROCESS );

default:
/*

  • you could use PtAlert() here to yell at the developer
    */
    }

/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}

*************************** ends **************************

As for the various arrow keys, they’re defined in
/usr/include/photon/PkKeyDef.h –

#define Pk_Left 0xF051 /* Move left, left arrow /
#define Pk_Up 0xF052 /
Move up, up arrow /
#define Pk_Right 0xF053 /
Move right, right arrow /
#define Pk_Down 0xF054 /
Move down, down arrow */
#define Pk_leftarrow 0x8fb
#define Pk_uparrow 0x8fc
#define Pk_rightarrow 0x8fd
#define Pk_downarrow 0x8fe

That’s also where you’ll find the various definitions for
alphanumeric keys, etc. Also, take a look at the docs on
PkKeyEvent_t.


Good luck!


Norbert Black
QSSL Training Services

“Norbert Black” <nblack@qnx.com> wrote in message
news:9vvplb$hl0$1@nntp.qnx.com

Hi David

David Hurlburt <> dhurlburt@faac.com> > wrote:
Just to get back to you incase you were wondering - I modified abmain.c
and
am keeping an extra copy of it since PhAB likes to overwrite it
everytime.
I added some features to 1 dialog that was not getting created correctly
from my old abmain.c

=;-o

Yipe! No no no no no no! Never (ever!) mess with a file
named ab* in a PhAB process. Bad Things Are Likely To Happen.
cue theme music from “Jaws”

Seriously - don’t put your own code in that file. If you need to
do application-level setup stuff, you’re far better off doing it
in an application initialization function. Just remember not to
try to access any PhAB-defined widgets in this function - the
various ABW_mumble pointers won’t have meaningful data in them at
this stage.

Hi Norbert,

I need to instantiate an input handler: PtAppAddInput();
Where would I do that if I don’t do it in main()?

As for your creating a PtRegion, that makes sense in the base
window module’s Pt_CB_WINDOW_OPENING callback. At that stage,
the window and its children will have performed all their
geometry negotiation, so you can use PtGetResources() to find out
about the PtWindow’s size and position without worry of them not
being meaningful values.

Okay…I’ve changed the main window to maximized and then I get the
geometry to use these values as the “REGION”'s area of interest.

Thanks for including the code for “base_txt_filtersCB”. I had already
utilized PhGetData().

Now what I am trying to do is this:

When the user presses a ‘w’ it needs to set a particular togglebutton on a
certain dialog. If they hit ‘W’ it needs to unset it. (There are about 3
dozen keys that need to used to activate other widgets on other dialogs)
(and the particular dialog - and therefore which widget - varies on
initialization data that is set in the beginning of the application’s
execution).

I am not sure how to get that pseudo event to the appropriate widget. I
have looked at a couple of options:

  1. use PtSetArgs and PtSetResources
    I have successfully got the toggle to push in, but I can’t
    get the widget to activate it’s ActivateCallback.

  2. PtSendEventToWidget()
    For a togglebutton I need to do a Ph_EV_BUT_PRESS but I
    don’t know what all I need to send. The help seems very
    specific to these types of events. I don’t know about
    the rect or PhPoint_t pos variable.

Hi David

David Hurlburt <dhurlburt@faac.com> wrote:

“Norbert Black” <> nblack@qnx.com> > wrote in message
I need to instantiate an input handler: PtAppAddInput();
Where would I do that if I don’t do it in main()?

Either in the application initialization function, or in the base
window’s setup function - you can define these in PhAB via the
Application/Startup… menu item

As for your creating a PtRegion, that makes sense in the base
window module’s Pt_CB_WINDOW_OPENING callback.

Just as an aside, one of the R&D guys passed on the reasonable
suggestion that the base window’s post-realize setup function is
another good place to do this kind of work.


Now what I am trying to do is this:

When the user presses a ‘w’ it needs to set a particular togglebutton on a
certain dialog. If they hit ‘W’ it needs to unset it. (There are about 3
dozen keys that need to used to activate other widgets on other dialogs)
(and the particular dialog - and therefore which widget - varies on
initialization data that is set in the beginning of the application’s
execution).

I am not sure how to get that pseudo event to the appropriate widget. I
have looked at a couple of options:

  1. use PtSetArgs and PtSetResources
    I have successfully got the toggle to push in, but I can’t
    get the widget to activate it’s ActivateCallback.

Expected - the callbacks run in response to Photon events, not to
patterns of resource allocation.

  1. PtSendEventToWidget()

That’s your baby. :slight_smile:

For a togglebutton I need to do a Ph_EV_BUT_PRESS but I
don’t know what all I need to send. The help seems very
specific to these types of events. I don’t know about
the rect or PhPoint_t pos variable.

Cue another bit of source code from the Advanced Photon course…
(again, a reminder that this was written for QNX 6, so no
promises that everything in this code will work as written for
Photon 1.1x):


****************** begins ***************************
/* callbacks.c

  • This application demonstrates how to create and emit
  • fake keyboard and pointer (mouse) events, and target
  • them at a specific widget using PtSendEventToWidget()

*-------------------------------------------------------
*

  • base_btn_EmitFakeKeyEvent_activateCB()
  • Callback type: Pt_CB_ACTIVATE
  • Widget: base_btn_EmitFakeKeyEvent
  • Operation:
  •  This function creates and emits a fake "Q" key
    
  •  down event, followed by a key up.  Both are directed
    
  •  at the application's text widget using
    
  •  PtSendEventToWidget().
    

*-------------------------------------------------------
*

  • base_btn_EmitFakePtrEvents_activateCB()
  • Callback type: Pt_CB_ACTIVATE
  • Widget: base_btn_EmitFakePtrEvents
  • Operation:
  •  This function creates and emits a fake left
    
  •  mouse button press event followed by three
    
  •  fake left mouse button release events at the
    
  •  base_btn_EmitFakeKeyEvent widget.  The reason
    
  •  for the three is explained in the comments to
    
  •  the relevant section of the code.
    

*-------------------------------------------------------
*

  • base_setup()
  • Callback type: post-realize setup function for the
  •               base window module
    
  • Widget: base
  • Operation: We use this function to calculate the
  •   position of the widgets we'll be using as
    
  •   targets for the various fake events we'll be
    
  •   generating in the callback functions
    

*-------------------------------------------------------
/


PhPoint_t textwidgetpos;
PhPoint_t btnwidgetpos;
int debug = 1;


struct
{
PhEvent_t event;
PhRect_t rect;
PhKeyEvent_t keydata;
} MyFakeKeyEvent;
/
The elements in this structure must be in this order and no
other because this is what the widget library expects to see
when it gets an event – a PhEvent_t structure, a series of
one or more PhRect_t structures (equal in number to the value
in the num_rects field of the PhEvent_t structure), and then a
structure holding event-specific data whose length matches the
data_len field of the PhEvent_t structure. */

struct
{
PhEvent_t event;
PhRect_t rect;
PhPointerEvent_t ptrdata;
} MyFakePtrEvent;


/*-------------------------------------------------------
*

  • base_setup()

-----------------------------------------------------/
int
base_setup( PtWidget_t *link_instance, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PtArg_t arg[1];

/*

  • we’ll want a location for the text and button widgets
  • that will be the target of the various fake events, so
  • let’s get them once, and park them in globals for
  • other functions to use…
    */
    PtSetArg( &arg[0], Pt_ARG_POS, &textwidgetpos, 0 );
    PtGetResources( ABW_base_txt, 1, arg );
    PtSetArg( &arg[0], Pt_ARG_POS, &btnwidgetpos, 0 );
    PtGetResources( ABW_base_btn_EmitFakeKeyEvent, 1, arg );

/* eliminate ‘unreferenced’ warnings */
link_instance = link_instance, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}


/*-------------------------------------------------------
*

  • base_btn_EmitFakeKeyEvent_activateCB()

-----------------------------------------------------/
int
base_btn_EmitFakeKeyEvent_activateCB( PtWidget_t *widget,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
memset( &MyFakeKeyEvent, 0, sizeof( MyFakeKeyEvent ) );

/*

  • fill in the event structure to reflect the emission of
  • a fake key event
    */
    MyFakeKeyEvent.event.type = Ph_EV_KEY;
    MyFakeKeyEvent.event.emitter.rid =
    MyFakeKeyEvent.event.collector.rid = PtWidgetRid( ABW_base );
    MyFakeKeyEvent.event.processing_flags = Ph_FAKE_EVENT;
    MyFakeKeyEvent.event.input_group = PhInputGroup( NULL );
    MyFakeKeyEvent.event.flags = Ph_EVENT_INCLUSIVE;
    MyFakeKeyEvent.event.data_len = sizeof( MyFakeKeyEvent.keydata );
    MyFakeKeyEvent.event.num_rects = 1;

/*

  • the event is a point-source event, so we will use the
  • Pt_ARG_POS associated with the widget we want to target
  • to define a 1x1 pixel rectangle
    */
    MyFakeKeyEvent.rect.ul.x =
    MyFakeKeyEvent.rect.lr.x = textwidgetpos.x;
    MyFakeKeyEvent.rect.ul.y =
    MyFakeKeyEvent.rect.lr.y = textwidgetpos.y;

/*

  • give us the data associated with the key ‘Q’
    */
    MyFakeKeyEvent.keydata.key_cap = Pk_q;
    MyFakeKeyEvent.keydata.key_flags = Pk_KF_Cap_Valid |
    Pk_KF_Key_Down |
    Pk_KF_Sym_Valid;
    MyFakeKeyEvent.keydata.key_mods = Pk_KM_Shift;
    MyFakeKeyEvent.keydata.key_sym = Pk_Q;

/* emit key down */
if( debug )
printf( “sending a fake key down event\n” );
PtSendEventToWidget( ABW_base_txt,
(PhEvent_t *) &MyFakeKeyEvent );

/* emit key up */
if( debug )
printf( “sending a fake key up event\n” );
MyFakeKeyEvent.keydata.key_flags &= ~( Pk_KF_Key_Down );
PtSendEventToWidget( ABW_base_txt,
(PhEvent_t ) &MyFakeKeyEvent );


/
eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}


/*-------------------------------------------------------
*

  • base_btn_EmitFakePtrEvents_activateCB()

-----------------------------------------------------/
int
base_btn_EmitFakePtrEvents_activateCB( PtWidget_t *widget,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
memset( &MyFakePtrEvent, 0, sizeof( MyFakePtrEvent ) );

/*

  • fill in the event structure to reflect the emission of
  • a fake pointer event
    */
    MyFakePtrEvent.event.emitter.rid =
    MyFakePtrEvent.event.collector.rid = PtWidgetRid( ABW_base );
    MyFakePtrEvent.event.processing_flags = Ph_FAKE_EVENT;
    MyFakePtrEvent.event.input_group = PhInputGroup( NULL );
    MyFakePtrEvent.event.flags = Ph_EVENT_INCLUSIVE;
    MyFakePtrEvent.event.data_len = sizeof( MyFakePtrEvent.ptrdata );
    MyFakePtrEvent.event.num_rects = 1;

/*

  • the event is a point-source event, so we will use the
  • Pt_ARG_POS associated with the widget we want to target
  • to define a 1x1 pixel rectangle
    */
    MyFakePtrEvent.rect.ul.x =
    MyFakePtrEvent.rect.lr.x = btnwidgetpos.x;
    MyFakePtrEvent.rect.ul.y =
    MyFakePtrEvent.rect.lr.y = btnwidgetpos.y;

/*

  • give us the data associated with the a single click
  • of the left mouse button
    /
    MyFakePtrEvent.ptrdata.pos.x = btnwidgetpos.x;
    MyFakePtrEvent.ptrdata.pos.y = btnwidgetpos.y;
    MyFakePtrEvent.ptrdata.click_count = 1;
    MyFakePtrEvent.ptrdata.buttons =
    MyFakePtrEvent.ptrdata.button_state =
    Ph_BUTTON_SELECT; /
    left mouse btn. */

/* emit mouse button press */
if( debug )
printf( “sending a fake left mouse btn press event\n” );
MyFakePtrEvent.event.type = Ph_EV_BUT_PRESS;
PtSendEventToWidget( ABW_base_btn_EmitFakeKeyEvent,
(PhEvent_t ) &MyFakePtrEvent );


/

  • emit button release events:
  • Ph_EV_RELEASE_REAL goes to the widget where the
    
  •    release genuinely took place
    
  • Ph_EV_RELEASE_PHANTOM goes to the widget where the
    
  •    press event went (to let it be able to handle
    
  •    things like Disarm callbacks)
    
  • Ph_EV_RELEASE_ENDCLICK lets the widget know that
    
  •    any sequence of multiple clicks that might have
    
  •    been in progress have now stopped.
    

*/
MyFakePtrEvent.event.type = Ph_EV_BUT_RELEASE;
if( debug )
printf( “sending fake mouse btn release (real) event\n” );
MyFakePtrEvent.event.subtype = Ph_EV_RELEASE_REAL;
PtSendEventToWidget( ABW_base_btn_EmitFakeKeyEvent,
(PhEvent_t *) &MyFakePtrEvent );

if( debug )
printf( “sending fake mouse btn release (phantom) event\n” );
MyFakePtrEvent.event.subtype = Ph_EV_RELEASE_PHANTOM;
PtSendEventToWidget( ABW_base_btn_EmitFakeKeyEvent,
(PhEvent_t *) &MyFakePtrEvent );

if( debug )
printf( “sending fake mouse btn release (endclick) event\n” );
MyFakePtrEvent.event.subtype = Ph_EV_RELEASE_ENDCLICK;
PtSendEventToWidget( ABW_base_btn_EmitFakeKeyEvent,
(PhEvent_t ) &MyFakePtrEvent );


/
eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );
}


******************* ends ****************************



I hope this helps.


Norbert Black
QSSL Training Services