Can't get PhEmit to emit Key event

Hi, hopefully somebody can help me here. I’m trying to get an application to emit a key event and the QNX documentation is rather sparse on what exactly I’m supposed to do. I would like to use this eventually for scripting of Photon events (pointer events and key events) for test automation. I already have pointer events working. Currently the code is being invoked from a button activation callback.

Here is the code in question:

PhEvent_t event;
PhPointerEvent_t ptrEventData;
PhKeyEvent_t keyEventData;
PhRect_t rect;

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

memset( &event, 0, sizeof(event) );
memset( &ptrEventData, 0, sizeof(ptrEventData) );
memset( &keyEventData, 0, sizeof(keyEventData) );
memset( &rect, 0, sizeof(rect) );

event.type = Ph_EV_BUT_PRESS;
event.subtype = 0;
event.flags = 0;
event.num_rects = 1;
event.data_len = sizeof(ptrEventData);
event.emitter.rid = Ph_DEV_RID;
rect.ul.x = rect.lr.x = 537;
rect.ul.y = rect.lr.y = 462;
ptrEventData.buttons = Ph_BUTTON_SELECT;
ptrEventData.flags = 0;
PhEmit( &event, &rect, &ptrEventData );

delay( 80 );

event.type = Ph_EV_BUT_RELEASE;
PhEmit( &event, &rect, &ptrEventData );

delay( 1500 );

event.type = Ph_EV_KEY;
event.data_len = sizeof( keyEventData );
//rect.ul.x = rect.lr.y = 0;
//rect.lr.x = rect.lr.x = 0;
keyEventData.key_cap = 0x09;
keyEventData.key_sym = 0x09;
keyEventData.key_scan = 0x09;
keyEventData.key_mods = 0;
keyEventData.key_flags = ( Pk_KF_Key_Down | Pk_KF_Sym_Valid | Pk_KF_Cap_Valid );
PhEmit( &event, &rect, &keyEventData );

delay( 220 );

keyEventData.key_flags = Pk_KF_Cap_Valid;
PhEmit( &event, &rect, &keyEventData );

delay( 2000 );

event.type = Ph_EV_BUT_PRESS;
event.data_len = sizeof(ptrEventData);
rect.ul.x = rect.lr.x = 841;
rect.ul.y = rect.lr.y = 717;
ptrEventData.buttons = Ph_BUTTON_SELECT;
ptrEventData.flags = 0;
PhEmit( &event, &rect, &ptrEventData );

delay( 450 );

event.type = Ph_EV_BUT_RELEASE;
PhEmit( &event, &rect, &ptrEventData );

return( Pt_CONTINUE );

A note about the scan codes. I’m not sure which type I’m supposed to use (XT or AT) or where they’re supposed to go (key_cap, key_sym, or key_scan). 0x09 is supposed to be the ‘8’ key.

How is it that you know that the events aren’t being emitted? There’s an issue of position. If the events are emitted from in front of where you want them caught, they will be emitted but lost.

They are being emitted, but as to what exactly is happening, I am unsure. This code is supposed to select a textbox in the target app, enter a number, then click a button on the target app. For test purposes I simply had a ped (photon editor) window fill the whole screen (instead of the target app), which was filled with “+” signs. When my test program clicked in the target area, I quickly entered a number myself. Then, when the key event occured, a “>” sign was generated. However, if I didn’t enter any text first, then no character would appear from the key event.

I have experimented with different combinations of using key_scan vs. key_sym vs. key_cap. I’ve also tried setting the rectangle to (0,0), and leaving it where it is. Leaving it where it is means it’s over the target window (or widget) since it still contains the value of the last pointer click.

There are a number of other fields in the PhKeyEvent_t structure that aren’t well documented. Based on other code I’ve looked at, I’m assuming I don’t have to worry about them.

How do I know if events are being emitted in front of my target or not? Also, shouldn’t the current focus change when the pointer event is emitted. The mouse cursor always ends up in the right place, but depending on what application is exposed there, sometimes it will come to the front, and sometimes it won’t. Is there a reason for this?

To Reply properly I’d have to dig in and get my hands dirty. I know that in order to receive key strokes, a field would need to have received the “focus”. You are right that a pointer operation should do this. To make sure it occurs, you could put a diagnostic in the mouse-click call back. As far as where you are emitting from, when you emit an event, you emit it from a region. If you create the region yourself, then you would have to place it behind your application at creation time. In your code, it looks like you are using the Ph_DEV_RID, which should work, if the code is otherwise correct. If you need to test that the application side is working ok, you could try running it via phditto, which has the same problems of emitting events that you have.

Maybe your need somthing like this?

This work for me:
memset( &reg_event, 0 , sizeof( reg_event) );
reg_event.event.processing_flags = Ph_FAKE_EVENT;
reg_event.pevent.click_count = 1;
reg_event.pevent.buttons = Ph_BUTTON_SELECT;
reg_event.event.num_rects = 1;

reg_event.event.type = Ph_EV_BUT_PRESS;
PtSendEventToWidget( widget, (PhEvent_t *) &reg_event.event);
reg_event.event.type = Ph_EV_BUT_RELEASE;
PtSendEventToWidget( widget, (PhEvent_t *) &reg_event.event);

Ok, so I’ve finally figured out what was going on here. The first main thing, is that some programs, such as “ped” use some of the normally unused fields. Thus you have to fill in the “pos” field of the PhPointer_t struct, otherwise, “ped” will move its cursor, but then let the event pass through to whatever window is behind it. Also, a button release is really two events, a REAL and a PHANTOM. I modified the code for the pointer events and that seemed to fix the issues of acquiring focus.

For the key event, I put a breakpoint in a text modifying callback for a different application. I took the “event” field of PtCallbackInfo_t and passed it to PhGetData() to get the PhKeyEvent_t struct. Here I learned that “key_cap” and “key_sym” are ASCII codes, not scan codes. I changed them to ASCII codes in my emit program, and now all is good. Here is the updated code:

PhEvent_t event;
PhPointerEvent_t ptrEventData;
PhKeyEvent_t keyEventData;
PhRect_t rect;

/* eliminate 'unreferenced' warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

memset( &event, 0, sizeof(event) );
memset( &ptrEventData, 0, sizeof(ptrEventData) );
memset( &keyEventData, 0, sizeof(keyEventData) );
memset( &rect, 0, sizeof(rect) );

event.type = Ph_EV_BUT_PRESS;
event.subtype = 0;
event.flags = 0;
event.num_rects = 1;
event.data_len = sizeof(ptrEventData);
event.emitter.rid = Ph_DEV_RID;
rect.ul.x = rect.lr.x = ptrEventData.pos.x = 537;
rect.ul.y = rect.lr.y = ptrEventData.pos.y = 462;
ptrEventData.buttons = Ph_BUTTON_SELECT;
ptrEventData.button_state = Ph_BUTTON_SELECT;
ptrEventData.flags = 0;
PhEmit( &event, &rect, &ptrEventData );

delay( 80 );

event.type = Ph_EV_BUT_RELEASE;
event.subtype = Ph_EV_RELEASE_REAL;
ptrEventData.button_state = 0;
PhEmit( &event, &rect, &ptrEventData );
event.type = Ph_EV_BUT_RELEASE;
event.subtype = Ph_EV_RELEASE_PHANTOM;
PhEmit( &event, &rect, &ptrEventData );

delay( 1500 );

event.type = Ph_EV_KEY;
event.subtype = 0;
event.data_len = sizeof( keyEventData );
//rect.ul.x = rect.lr.y = 0;
//rect.lr.x = rect.lr.x = 0;
keyEventData.key_cap = 0x38;        // These are ASCII codes
keyEventData.key_sym = 0x38;
keyEventData.key_scan = 0x09;       // These are scan codes
keyEventData.key_mods = 0;
keyEventData.key_flags = ( Pk_KF_Key_Down | Pk_KF_Sym_Valid | Pk_KF_Cap_Valid );
PhEmit( &event, &rect, &keyEventData );

delay( 220 );

keyEventData.key_flags = Pk_KF_Cap_Valid;
PhEmit( &event, &rect, &keyEventData );

delay( 2000 );

event.type = Ph_EV_BUT_PRESS;
event.data_len = sizeof(ptrEventData);
rect.ul.x = rect.lr.x = ptrEventData.pos.x = 841;
rect.ul.y = rect.lr.y = ptrEventData.pos.y = 717;
ptrEventData.buttons = Ph_BUTTON_SELECT;
ptrEventData.button_state = Ph_BUTTON_SELECT;
ptrEventData.flags = 0;
PhEmit( &event, &rect, &ptrEventData );

delay( 450 );

event.type = Ph_EV_BUT_RELEASE;
event.subtype = Ph_EV_RELEASE_REAL;
ptrEventData.button_state = 0;
PhEmit( &event, &rect, &ptrEventData );
event.type = Ph_EV_BUT_RELEASE;
event.subtype = Ph_EV_RELEASE_PHANTOM;
PhEmit( &event, &rect, &ptrEventData );

return( Pt_CONTINUE );