Aaaaar, I didn't see Dianne's response (nor Niko's) when I posted my
last response, because I didn't realize that there was a "page 2".

Thanks, Dianne, for your explanation and for posting the examples!

-- PJ



On Nov 16, 1:57 am, PJ <pjbar...@gmail.com> wrote:
> I think I've figured it out for you, Dave.  :)  Bear with me.
>
> Let's look at the constants in MotionEvent:
>
> ACTION_MASK = 0x000000ff
> ACTION_POINTER_ID_MASK = 0x0000ff00
> ACTION_POINTER_ID_SHIFT = 8
>
> This confirms that the lowest order byte represents the action and the
> next byte represents the pointer ID.
>
> Now, the inconsistency that you observed (0 vs. 5, 1 vs. 6) can be
> explained by the fact that the action values for the primary pointer
> are different from the action values for non-primary pointers:
>
> For primary pointers:
> ACTION_DOWN = 0
> ACTION_UP = 1
>
> For non-primary pointers:
> ACTION_POINTER_DOWN = 5
> ACTION_POINTER_UP = 6
>
> So, hopefully that explains why you experienced those
> "inconsistencies".
>
> Now, notice that there are some "convenience constants" that we can
> use to prevent doing all of this dirty work ourselves.  Let's see if
> they jive:
>
> ACTION_POINTER_2_DOWN = 261 = 0x0100 | 0x0005
> ACTION_POINTER_2_UP = 262 = 0x0100 | 0x0006
> ACTION_POINTER_3_DOWN = 517 = 0x0200 | 0x0005
> ACTION_POINTER_3_UP = 518 = 0x0200 | 0x0006
>
> Important: Notice that the numbers "2" and "3" in the constant names
> are 1-based and not 0-based.  However, PointerID's 0-based.  So, for
> example, "POINTER_2" means PointerID = 0x01.
>
> So, "POINTER_1" should mean PointerID = 0x00.  And note that the
> documentation says "Pointer IDs start at 0, with 0 being the primary
> (first) pointer in the motion."
>
> Now, let's look at the following values:
> ACTION_POINTER_1_DOWN = 5
> ACTION_POINTER_1_UP = 6
>
> POINTER_1 represents PointerID=0.  So, here we might have an apparent
> contradiction in documentation.  Why would PointerID=0, a primary
> pointer, generate non-primary actions?
>
> However, one possibility is that PointerID=0 ceases to become a
> "primary pointer" when 2+ fingers are touching the device.  I don't
> see that documented anywhere, but that's the only explanation I can
> think of for your Motorola Droid's behavior.
>
> Based on the scenario you described above, my best guess is that your
> Droid is following these interpretations/rules:
> * If there is only one finger touching the device, it is treated as
> PointerID=0 and as a primary, and so only ACTION_DOWN (0) and
> ACTION_UP (1) events are generated.
> * If there are 2+ fingers touching the device, then the first finger
> is still treated as PointerID=0, but NOT as a "primary" (e.g. it
> generates ACTION_POINTER_UP=6, not ACTION_UP=1).
> * Whenever there are 2 fingers touching the device and one finger is
> lifted, the sole remaining finger becomes PointerID=0 and "primary",
> even if it was originally a "2nd" or higher finger.
>
> If you apply these rules, it would explain your Droid's behavior:
>
> > Press finger 1 to the screen (action value of 0)
>
> Correct: 0x0000 | 0x0000 (finger 1 is a primary)
>
> > Press finger 2 to the screen (action value of 261)
>
> Correct: 0x0100 | 0x0005 (neither finger is a primary)
>
> > Lift finger 1 from the screen (action value of 6)
>
> Correct: 0x0000 | 0x0006 (finger 1 is no longer a primary; finger 2 is
> the only finger so it becomes PointerID=0 and primary)
>
> > Lift finger 2 from the screen (action value of 1)
>
> Correct: 0x0000 | 0x0001 (finger 2 is primary)
>
> So, that should explain your Droid's behavior.
>
> Now, I'm not saying that those extra interpretations/rules are correct
> and will/should be adopted by all devices.  But I think it's a decent
> interpretation.  I'm not terribly surprised that your Droid is acting
> like that.
>
> What do you think?
> -- PJ
>
> On Nov 15, 3:41 pm, davemac <davemac...@gmail.com> wrote:
>
>
>
> > I think I've got this figured out. Almost. With multi-touch support,
> > getAction() can return a compound value representing the pointerID in
> > the second byte and the action value in the first byte. For example,
> > if two fingers are down, and pointerID 1 is lifted (i.e., finger 2),
> > getAction() returns a value of 262 (0x100 or 256 to represent
> > pointerID 1, and 6 to represent up for a compound value of 0x106 or
> > 262). I'm curious why it was done this way instead of using 0 for down
> > and 1 for up, even when pointers are involved. Things get a little
> > weird because of the differences. Here's an example (note I'm using a
> > Motorola Droid phone here so this may behave differently on other
> > devices):
>
> > Press finger 1 to the screen (action value of 0)
> >     finger 1 gets pointerID 0, no problem, pointerID is 0, down is 0
> > Press finger 2 to the screen (action value of 261)
> >     finger 2 gets pointerID 1, a little weird, could have been 256
> > instead?
> > Lift finger 1 from the screen (action value of 6)
> >     finger 2 is still pointerID 1, action could still have been 1?
> > Lift finger 2 from the screen (action value of 1)
> >     finger 2 is still pointerID 1, but the action value is not 262 or
> > 257 it's 1
>
> > It would seem I can't use the bitmasks reliably in all cases. If I
> > always inspect the action value for the pointerID and the action
> > value, I get messed up at the end because pointerID has vanished. And
> > 0 seems to be equivalent to 5, and 1 to 6.
>
> > Is this something you'd consider a bug or is this how it's supposed to
> > work? Should we expect it to continue to work this way?
>
> > Thanks for your help.
>
> > - dave
>
> > On Oct 27, 4:28 pm, Dianne Hackborn <hack...@android.com> wrote:
>
> > > On Tue, Oct 27, 2009 at 2:02 PM, MrChaz <mrchazmob...@googlemail.com> 
> > > wrote:
>
> > > > Thanks for the info,
>
> > > > Wouldn't this
> > > > Finger 1 up: MotionEvent ACTION_POINTER_1_UP with one pointer, whose
> > > > ID is
> > > > 1.
> > > > need to be ID of 0?  Or am I mis-understanding the purpose of the UP
> > > > action?
>
> > > Good point.  Actually my example was not very good because at the places
> > > where there is an up transition, the last position of the pointer going up
> > > is included in the event stream -- so in all of these, you would receive
> > > both 0 and 1.  It is in the following move event that you will only get 
> > > the
> > > information for the pointers that are currently down.
>
> > > --
> > > Dianne Hackborn
> > > Android framework engineer
> > > hack...@android.com
>
> > > Note: please don't send private questions to me, as I don't have time to
> > > provide private support, and so won't reply to such e-mails.  All such
> > > questions should be posted on public forums, where I and others can see 
> > > and
> > > answer them.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to