
                 Using the right mouse button with evnt_multi
                 ============================================

    You will probably have noticed that very few applications for the Atari
    make much use of the  right  mouse  button.  The  reason given was that
    there was no simple way for a GEM  program  to do it. It turns out that
    there has been a legal  way  to  do  it  all  along - Atari finally got
    around to documenting it a couple of  years ago, but only to registered
    developers.

    evnt_button
    -----------

    Normally a GEM program  is  based  around  an  evnt_multi call, but for
    simplicity I will stick to  evnt_button,  which  only waits for a mouse
    button event. The parameters  are  much  the  same  but because it only
    waits for one event, there are rather less of them :)

    In C it is

    int evnt_button( int maxclicks, int mask, int state,short *x, short *y,
    short *button, short *kstate ) ;

    It takes three parameters, maxclicks  is  the  number of clicks to wait
    for, mask is a  bitmap  showing  which  buttons  you  are interested in
    (1=left, 2=right, 3=both) and state is  a  bitmap showing what state to
    wait for. It returns the number of clicks that occurred, and puts the x
    and y position of the  mouse  in  x  and  y,  the final button state in
    button and the shift key state in kstate.

    The way it is normally used is to  pass  one in mask so that it ignores
    the right button.

    Using the right button as a shift key
    -------------------------------------

    The desktop and some other applications  use the right button to select
    things in windows that aren't topped. You  have to hold the left button
    down at the same time. To do this,  or  use the right mouse button as a
    shift key like this in any other  way,  you  still use one in the mask,
    but you check button afterwards to see if the right button was down

    evnt_button( 1, 0x01, 0x01, &x, &y, &button, &kstate ) ;
                    ^        ^
                    |        Wait for left button down
                     Use left button, ignore right

    if( button & 0x02 )
         /* right button down as well */
    else
         /* left button only */

    Waiting for a right button click
    --------------------------------

    It is also possible to wait  for  a  right button click. For example if
    you want to wait for the  right  button,  and don't care about the left
    button,

    evnt_button( 1, 0x02, 0x02, &x, &y, &button, &kstate ) ;
                    ^       ^
                    |       Wait for right button down
                    Use right button, ignore left

    If you want to wait for both  buttons  to  be down, or just the left or
    just the right, you have to use three  for the mask (1+2) and the state
    to wait for in state.

    evnt_button( 1, 0x03, 0x02, &x, &y, &button, &kstate ) ;
                    ^       ^
                    |       Wait for right down, left up
                    Use both buttons

    evnt_button( 1, 0x03, 0x03, &x, &y, &button, &kstate ) ;
                    ^       ^
                    |       Wait for both to be down
                    Use both buttons

    Waiting for either click
    ------------------------

    You will notice that you can only  wait  for one state. There is no way
    of saying 'Wait for left or right  button  click'. At least, not if you
    believe the  documentation!  Here's  where  you  get  the  bit  not  in
    textbooks :-

    First...

    A historical note
    -----------------

    A method used by some older  programs,  and  in fact recommended in the
    Lattice C manual, involves some clever messing around with vectors. You
    use the VDI call vex_butv() to install a mouse button handler, and what
    you do is that whatever click you  get  you  pretend it is a left click
    and set a variable somewhere to show what sort it really is.

    Playing around with vectors like this  is  difficult in C and virtually
    impossible in basic, but  there  is  a  more  serious problem with this
    method. What happens if you are running multitos, and one program tries
    this? All the other programs will also  be affected by your routine and
    will get all their mouse clicks as left clicks.

    So Atari announced to developers  the  official  method that had always
    worked and no one knew about.

    The bit you won't find in your manuals
    --------------------------------------

    As well as  the  maximum  number  of  clicks  to  wait  for,  the first
    parameter to evnt_button has another  purpose.  If  you add 0x100 to it
    (this is 256 in decimal)  it  means  negate  the state requirement. For
    example if the state is zero, it will  wait for the button state not to
    be zero - ie for either button to be down

    evnt_button( 0x101, 0x03, 0x00, &x, &y, &button, &kstate ) ;
                    ^   ^       ^
                    |   |       Wait for NOT(no buttons down )
                   |    Look at both buttons
                   Negate state requirement, wait for one click

    If you are interested in mouse up events, then you have to wait for one
    of the buttons to be pressed and  then  either wait for the state to be
    zero, or wait for it NOT to be whatever it then is.

    evnt_button( 0x101, 0x03, 0x00, &x, &y, &button, &kstate ) ;
    /* Right, now one or the other or both is down         */
    evnt_button( 0x101, 0x03, button, &x, &y, &button, &kstate ) ;
                          ^
                          Wait for NOT( previous state )

    Summary
    -------

    Using the right button  isn't  as  difficult  as  it's  made out to be.
    Although all the examples I have done are in C, this should work in any
    language that lets you call  GEM  directly,  such  as Hisoft Basic, GFA
    Basic 3 or Assembly language (see also ASSEMBLY\EVNT_BUT folder).

    The information was originally released by Mike Fulton (Atari developer
    support). Warwick Allison posted it onto the Usenet newsgroup with some
    accompanying notes, and then Steve Taylor  posted a copy of his message
    onto Turbonet (where I read it).


                                       Mark Baker

    Email :                            mark.baker@mettav.royle.org

                                       Fidonet             2:254/108.17
                                       Turbonet  100:1011/0.17
                                       NeST                90;102/140.17
                                       Atarinet  51:502/100.17
