Home
Support

Knowledge Base

BSPs and drivers
Community resources
Product documentation
Questions?
Contact us

How to control the mouse pointer w/o mouse
 
________________________________________________________________________

Applicable Environment
________________________________________________________________________
  • Topic: Photon: Control mouse pointer without mouse
  • SDP: 6.4.1
  • Host/Target: Any supported target
________________________________________________________________________

Recommendation
________________________________________________________________________


This needs a little effort, since clicking a mousebutton is not as trivial as it may seem. Especially to tell a click and a drag apart. The main function move the mouse pointer is:
PhMoveCursorRel( 1, dx, dy )

This is some example code to demonstrate 'smooth' movements with variable speed:

---->
/*
* Helperfunction to emulate mouse buttons
*/
static void EmitPtrEvent( int ig, unsigned long type, unsigned short
subtype,
unsigned short button_state, PhPoint_t *pos ) {
PhPointerEvent_t pev;
PhEvent_t event;
PhRect_t rect;
short x, y;

PtGetAbsPosition( ABW_base, &x, &y );

memset( &event, 0, sizeof event );

event.type = type;
event.subtype = subtype;
event.processing_flags = 0;
event.emitter.rid = 1;
event.emitter.handle = 0;
event.input_group = 1;
event.flags = 0;
event.timestamp = time( NULL );
event.translation.x = -x;
event.translation.y = -y;
event.num_rects = 1;
event.data_len = sizeof pev +1;

pev.pos = *pos;
pev.click_count = 1;
pev.z = 0;
pev.flags = 0;
pev.button_state = button_state;
pev.buttons = Ph_BUTTON_SELECT;
pev.key_mods = 0;

rect.ul = rect.lr = *pos;

PhEventEmit( &event, &rect, &pev );
}

/*
* The actual Emulation. A TimerEvent controls the updates, either
* movement or click. Most of the code is handling the delta
* values to realize a smooth movement.
*/

static int TmrActivateCb( PtWidget_t *widget, void *data, PtCallbackInfo_t
*cbinfo ) {
PhCursorInfo_t info;
PtWidget_t *tgt_wgt;
PhArea_t tgt_area;
double d, h;
short x, y;
int cur_x, cur_y;
int tgt_x, tgt_y;
int dx, dy;
int v; // desired velocity

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

if ( TgtIdx >= NumSimWgts )
return Pt_CONTINUE;

PhQueryCursor( 1, &info );

switch ( State ) {
case 0: // Movement - see below
break;

case 1: // Button press
EmitPtrEvent( cbinfo->event->input_group, Ph_EV_BUT_PRESS, 0,
Ph_BUTTON_SELECT, &info.pos );
State++;
return Pt_CONTINUE;

case 2: // Button release
// Release with current mouse position
EmitPtrEvent( cbinfo->event->input_group, Ph_EV_BUT_RELEASE,
Ph_EV_RELEASE_REAL, 0, &info.pos );
// Release with mouse position when button was pressed
EmitPtrEvent( cbinfo->event->input_group, Ph_EV_BUT_RELEASE,
Ph_EV_RELEASE_PHANTOM, 0, &info.pos );
// Single click, don't wait for another
EmitPtrEvent( cbinfo->event->input_group, Ph_EV_BUT_RELEASE,
Ph_EV_RELEASE_ENDCLICK, 0, &info.pos );
State = 0;

if ( ++TgtIdx >= NumSimWgts )
Sims_Stop();

return Pt_CONTINUE;
}

tgt_wgt = SimWgts[TgtIdx];
cur_x = info.pos.x;
cur_y = info.pos.y;

PtWidgetArea( tgt_wgt, &tgt_area );
PtGetAbsPosition( tgt_wgt, &x, &y );
tgt_area.pos.x = x;
tgt_area.pos.y = y;
tgt_x = x + ( tgt_area.size.w / 2 );
tgt_y = y + ( tgt_area.size.h / 2 );

dx = tgt_x - cur_x;
dy = tgt_y - cur_y;

d = hypot( dx, dy );
h = RadNorm( atan2( dy, dx ) );

if ( d < 5 ) {
if ( ( cur_x >= tgt_area.pos.x ) && ( cur_x < tgt_area.pos.x +
tgt_area.size.w )
&& ( cur_y >= tgt_area.pos.y ) && ( cur_y < tgt_area.pos.y +
tgt_area.size.h ) ) {
State = 1;
return Pt_CONTINUE;
}
}

v = sqrt( .25 + 2 * d ) - 0.5;

if ( v > Velocity ) {
if ( ( Velocity += 5 ) > v )
Velocity = v;
}
else if ( v < Velocity )
Velocity -= 1;

if ( h > Heading ) {
if ( fabs( h - Heading ) < PI )
Heading += ( h - Heading ) / 3;
else
Heading = RadNorm( Heading - ( ( PI2 - h + Heading ) / 3 ) );
}
else {
if ( fabs( Heading - h ) < PI )
Heading -= ( Heading - h ) / 3;
else
Heading = RadNorm( Heading + ( ( PI2 + h - Heading ) / 3 ) );
}

dx = cos( Heading ) * Velocity;
dy = sin( Heading ) * Velocity;

PhMoveCursorRel( 1, (int) dx, (int) dy );

return Pt_CONTINUE;
}
<----

________________________________________________________________________
NOTE: This entry has been validated against the SDP version listed above. Use caution when considering this advice for any other SDP version. For supported releases, please reach out to QNX Technical Support if you have any questions/concerns.
________________________________________________________________________


Related Attachments
 None Found





Please contact us with your questions or concerns.