Post by Philip Tayl » Wed, 29 Sep 1999 04:00:00

evnt_multi in TOS 2.06 allows me to wait for the left or right
mouse button (among other events); however I want to respond
to _either_ mouse button.
The documentation says "button is ANDed with mask and tested
for equality with state".  If I could change the equality to
"greater-than-or-equal-to" then putting mask=3 and state=1 would
wait for either button; while mask values of 1 & 2 would still
work for single left & right buttons.

Despite several days dubugging inside TOS, I haven't been able
to find the AND and BEQ instructions which do the compares.
Can anyone help?

Philip Taylor,  Glasgow,  Scotland



Post by Jo Even Skarstei » Wed, 29 Sep 1999 04:00:00

> evnt_multi in TOS 2.06 allows me to wait for the left or right
> mouse button (among other events); however I want to respond
> to _either_ mouse button.

You have to add 0xff to the second argument in evnt_multi(). This is
explained in ProGEM by Tim Oren (http://atari.nvg.org/programming/ProGEM/)


** Jo Even Skarstein   http://www.stud.ntnu.no/~josk/
**   beer - maria mckee - atari falcon - babylon 5



Post by JI Log » Wed, 29 Sep 1999 04:00:00

On 28 Sep 1999 11:50:19 , Philip Taylor wrote:
|evnt_multi in TOS 2.06 allows me to wait for the left or right
|mouse button (among other events); however I want to respond
|to _either_ mouse button.

The following was posted in Ictari Issue 10. I hope no-one minds me
copying it here but as you will see from the bottom, it has been
re-copied a number of times.

John Logan

                 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


    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 */
         /* 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

    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 :-


    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 )


    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.ba...@mettav.royle.org

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

John Logan


1. Evnt_multi behaviour

While using the evnt_multi call, I encountered
a weird behaviuor of the mouse. I wonder if
this is a known bug (I'm using TOS 1.0), or
that I am missing some thing. (I hope for
the latter...)

Here is what happens:
Using evnt_multi, in a loop I sollicit for keyboard-input
and mouse-clicks:

         evnt_multi( MU_KEYBD | MU_BUTTON , ....  );

This works fine for a while, but when the mouse is moved
to the menu-bar (that is still enabled when this code
is executed), afterwards mouse-clicks are not detected
anymore. The same thing happens when the mouse is moved
to the 400th line of the display.

I considered that maybe I should call

    menu_bar( menu, 0 )

first. This helps a little, in that mere moving the
mouse to the menu-line is harmless now. Clicking on the
menu-line however is as fatal as it was before: instead of
reporting a mousclick for this click, all future mouseclicks
are ignored.

The keyboard-events are still being reported. If, in the
process_input part of code, a form-alert is called, afterwards
everything is normal again.

What magical clean-up call is it, that re-enables the
mouseclicks? I am willing to call it before every evnt_multi,
if I must... desperate as I am...

But of course, if I am doing something fundamentally wrong,
I should like to know what that is, too. All help is welcome!


dept.of Computer Science, Utrecht University  |  tel.+31-30-534129
PObox 80089, 3508TB Utrecht, the Netherlands  |  fax.+31-30-513791

2. relaying

3. AES evnt_multi with MiNT: Busy

4. 8086 & 80x86 op codes

5. Fighting evnt_multi()

6. FreeVMS 0.0.30

7. Mouse Buttons: how do you receive both using evnt_multi() ??


9. evnt_multi, uh oh...

10. Double click & evnt_multi

11. evnt_multi() mouse button event behavior?

12. AES evnt_multi with MiNT: Busy waiting?

13. detecting double clicks with evnt_multi().. HOW?!