>># 
>># Copyright 1990, 1991 by the Massachusetts Institute of Technology and
>># UniSoft Group Limited.
>># 
>># Permission to use, copy, modify, distribute, and sell this software and
>># its documentation for any purpose is hereby granted without fee,
>># provided that the above copyright notice appear in all copies and that
>># both that copyright notice and this permission notice appear in
>># supporting documentation, and that the names of MIT and UniSoft not be
>># used in advertising or publicity pertaining to distribution of the
>># software without specific, written prior permission.  MIT and UniSoft
>># make no representations about the suitability of this software for any
>># purpose.  It is provided "as is" without express or implied warranty.
>># 
>># $XConsortium: grbbttn.m,v 1.13 92/06/11 17:12:59 rws Exp $
>># 
>>#      SCCS:  @(#)  EAcc1.mc Rel 1.4	    (10/2/91)
>>#      SCCS:  @(#)  ECur.mc Rel 1.8	    (2/21/92)
>>#      SCCS:  @(#)  EVal.mc Rel 1.5	    (10/10/91)
>>#      SCCS:  @(#)  EVal.mc Rel 1.5	    (10/10/91)
>>#      SCCS:  @(#)  EVal.mc Rel 1.5	    (10/10/91)
>>#      SCCS:  @(#)  EVal.mc Rel 1.5	    (10/10/91)
>>#      SCCS:  @(#)  EVal.mc Rel 1.5	    (10/10/91)
>>#
>>TITLE XGrabButton CH07
>>ASSERTION B XGrabButton-1
A call to XGrabButton establishes a passive grab that is
activated in the future by the specified button being
logically pressed, the modifier keys given by modifiers
being logically down, no other buttons or modifier keys
being logically down and the pointer being contained in the
grab_window.
>>STRATEGY
Call XGrabButton as touch test.
If extensions available:
  Warp pointer into grab window.
  Simulate a button press of button.
  Verify that pointer is now grabbed.
  Release grab.

  Set up a grab with XGrabButton for a button.
  Warp pointer into grab window.
  Simulate press of another button.
  Simulate the button press.
  Verify that the pointer is not grabbed.
  Release grab.

  Set up a grab with XGrabButton for a button and modifier keys.
  Warp pointer to grab window.
  Simulate modifier key presses.
  Simulate the button press.
  Verify that the pointer is grabbed.
  Release grab.

  Set up a grab with XGrabButton for a button and modifier keys.
  Warp pointer to grab window.
  Simulate modifier key presses.
  Simulate extra modifier key presses.
  Simulate the button press.
  Verify that the pointer is not grabbed.
  Release grab.
>>ASSERTION B XGrabButton-2
When the conditions for activating the grab are otherwise
satisfied and the pointer is already grabbed, then no active
grab is established.
>>STRATEGY
If extensions are available:
  Create two windows that do not overlap.
  Call XGrabButton with one of the windows as the confine_to.
  Activate grab with a button press.
  Check that pointer is within that window.
  Call XGrabButton with confine_to as the other window.
  Press button in grab_window.
  Verify that pointer has not been warped to second confine_to window.
else
  Report untested.
>>ASSERTION B XGrabButton-3
When the conditions for activating the grab are otherwise
satisfied and the confine_to window is not viewable, then no
active grab is established.
>>STRATEGY
If extensions are available:
  Create a confine_to window.
  Unmap the confine to window.
  Set up a passive grab.
  Move pointer to grab window.
  Attempt to activate grab by simulating a button press.
  Verify that grab is not activated.
else
  Report untested.
>>ASSERTION B XGrabButton-4
When the conditions for activating the grab are otherwise
satisfied and a passive grab on the same button/key
combination exists for an ancestor of grab_window, then no
active grab is established.
>>STRATEGY
If extensions are available:
  Call XGrabButton to place a passive grab.
  Create a child of the grab_window.
  Place a passive grab for the same key/button combination on the child.
  Move pointer into the child.
  Attempt to activate grab by simulating button press.
  Verify that pointer is not grabbed by the child window.
else
  Report untested.
>>ASSERTION B XGrabButton-5
When the conditions for activating the grab are satisfied,
then the last-pointer-grab time is set to the time at which
the button was pressed and a ButtonPress event is generated.
>>STRATEGY
If extensions are available:
  Call XGrabButton to place passive grab.
  Enable events on grab window.
  Move pointer into grab window.
  Activate grab with simulated device events.
  Verify that a ButtonPress event is generated.
else
  Report untested.
>>ASSERTION B XGrabButton-6
When the grab subsequently becomes active and later the
logical state of the pointer has all buttons released, then
the active grab is terminated automatically.
>>STRATEGY
If extensions are available:
  Place passive grab with XGrabButton.
  Activate grab with simulated device events.
  Simulate pressing some modifier keys.
  Release the button.
  Verify that the grab has been released.
else
  Report untested.
>>ASSERTION B XGrabButton-7
A call to XGrabButton overrides all previous passive grabs
by the same client on the same button/key combinations on
the same window.
>>STRATEGY
If extensions are available:
  Place a passive grab with no confine_to window.
  Place a passive grab as before but with a confine_to window.
  Move pointer to grab_window and activate grab.
  Verify that pointer is warped to the confine_to window and thus the second
  grab overrode the first.
else
  Report untested.
>>ASSERTION B XGrabButton-8
A modifiers argument of AnyModifier is equivalent to
issuing the grab request for all possible modifier
combinations including no modifiers.
>>STRATEGY
If extensions are available:
  Place passive grab with a modifiers of AnyModifier.
  Press a bunch of modifier keys.
  Press button to activate grab.
  Verify that grab is activated.
  Release button and keys.

  Press button (no modifiers).
  Verify that grab is active.
else
  Perform touch test.
  Report untested.
>>ASSERTION B XGrabButton-9
It is not required that all modifiers specified have
currently assigned KeyCodes.
>>STRATEGY
If extensions are available:
  Get a modifier mask.
  Remove the keycode for the modifier from the map.
  Call XGrabButton to set up a passive grab with that modifier.
  Reset the keycode in the modifier map.
  Verify that the grab can be activated with the newly set modifier.
else
  Report untested.
>>ASSERTION B XGrabButton-10
A button argument of AnyButton is equivalent to issuing the
grab request for all possible buttons.
>>STRATEGY
If extensions are available:
  Set up a passive grab using AnyButton.
  Move pointer to grab window.
  Simulate a button press.
  Verify that pointer is grabbed.
  Repeat for other buttons.
else
  Touch test using AnyButton.
  Report untested.
>>ASSERTION B XGrabButton-11
It is not required that the specified button currently be
assigned to a physical button.
>>STRATEGY
If extensions are available:
  Remove a button from the button map.
  Set a passive grab with that button.
  Replace the button in the map.
  Simulate pressing button in window.
  Verify that grab is activated.
else
  Report untested.
>>ASSERTION B XGrabButton-12
When owner_events is False and the grab is now active, then
all generated pointer events that are selected by the
event_mask are reported with respect to the grab_window.
>>STRATEGY
If extensions are available:
  Set owner_events to False.
  Set event_mask to select for PointerMotion.
  Set passive grab.
  Activate grab by simulated button press.
  Create a window.
  Select events on the window.
  Warp pointer into window.
  Verify MotionNotify reported to grab_window.
else
  Report untested.
>>ASSERTION B XGrabButton-13
When owner_events is True, the grab is now active and a
pointer event is generated that would normally be reported
to the client, then it is reported on the window that it
would normally be reported on.
>>STRATEGY
If extensions are available:
  Set owner_events to True.
  Set passive grab.
  Activate grab by simulated button press.
  Create a window.
  Select events on the window.
  Warp pointer into window.
  Verify events are reported on window.
else
  Report untested.
>>ASSERTION B XGrabButton-14
When owner_events is True, the grab is now active, a
pointer event is generated that would not normally be
reported to the client and it is selected by event_mask,
then it is reported on the grab_window.
>>STRATEGY
If extensions are available:
  Set owner_events to True.
  Set passive grab.
  Activate grab by simulated button press.
  Create a window.
  Warp pointer into window and simulate a button press/release.
  Verify events are reported to grab_window.
else
  Report untested.
>>ASSERTION B XGrabButton-15
When pointer_mode is GrabModeAsync and the grab is now
active, then pointer event processing continues normally.
>>STRATEGY
If extensions are available:
  Set pointer_mode to GrabModeAsync.
  Set passive grab.
  Press button in grab_window to activate grab.
  Verify that pointer is not frozen.
else
  Report untested.
>>ASSERTION B XGrabButton-16
When pointer_mode is GrabModeSync and the grab is now
active, then the state of the pointer, as seen by client
applications, appears to freeze, and no further pointer
events are generated until the grabbing client calls
XAllowEvents or until the grab is released.
>>STRATEGY
If extensions are available:
  Set pointer_mode to GrabModeSync.
  Set grab with XGrabButton and activate.
  Verify that pointer is frozen.
  Allow events with XAllowEvents().
  Verify that pointer is not frozen.
  Release the grab and restore the device state.
  Set grab with XGrabButton and activate.
  Verify that pointer is frozen.
  Release grab.
  Verify that pointer is not frozen.
else
  Report untested.
>>ASSERTION B XGrabButton-17
When the pointer is frozen, then the actual pointer changes
are not lost and are processed after the grab is released or
the client calls XAllowEvents.
>>STRATEGY
If extensions are available:
  Set pointer_mode to GrabModeSync.
  Set grab with XGrabButton and activate.
  Check that no pointer events are generated.
  Release grab.
  Verify that events are now received.
  Release the grab and restore the device state.
  Set grab with XGrabButton and activate.
  Check that no pointer events are generated.
  Allow events with XAllowEvents().
  Verify that events are now received.
else
  Report untested.
>>ASSERTION B XGrabButton-18
When keyboard_mode is GrabModeAsync, then keyboard event
processing is unaffected by activation of the grab.
>>STRATEGY
If extensions are available:
  Set keyboard_mode to GrabModeAsync.
  Set grab with XGrabButton and activate.
  Verify that keyboard is not frozen.
else
  Report untested.
>>ASSERTION B XGrabButton-19
When keyboard_mode is GrabModeSync and the grab is now
active, then the state of the keyboard, as seen by client
applications, appears to freeze, and no further keyboard
events are generated until the grabbing client calls
XAllowEvents or until the grab is released.
>>STRATEGY
If extensions are available:
  Set keyboard_mode to GrabModeSync.
  Set grab with XGrabButton and activate.
  Verify that keyboard is frozen.
  Allow events with XAllowEvents().
  Verify that keyboard is not frozen.
  Release the grab and restore the device state.
  Set grab with XGrabButton and activate.
  Verify that keyboard is frozen.
  Release grab.
  Verify that keyboard is not frozen.
else
  Report untested.
>>ASSERTION B XGrabButton-20
When the pointer is frozen, then the actual keyboard
changes are not lost and are processed after the grab is
released or the client calls XAllowEvents.
>>STRATEGY
If extensions are available:
  Enable key press events.
  Set keyboard_mode to GrabModeSync.
  Set grab with XGrabButton and activate.
  Press key.
  Check that no pointer events are generated.
  Allow events with XAllowEvents().
  Verify that events are now received.
  Release the grab and restore the device state.
  Set grab with XGrabButton and activate.
  Press key.
  Check that no pointer events are generated.
  Release grab.
  Verify that events are now received.
else
  Report untested.
>>ASSERTION B XGrabButton-21
When cursor is a valid cursor and the grab is now active,
then it is displayed regardless of which window the pointer
is in.
>>STRATEGY
If extensions available:
  Make a tree of windows rooted at grab_window, all with default cursor.
  Make a non-overlapping sibling of grab_window, the cursor window.
  Set that window's cursor to be a good, non default, cursor.
  Call XGrabButton with cursor = the good cursor.
  Activate grab by simulating button press.
  Warp pointer to all windows in the tree, root and cursor window, and
    validate that current cursor is equal to that of cursor window
    using extension.
else:
  Perform touch test.
>>ASSERTION B XGrabButton-22
When cursor is None and the grab is now active, then the
normal cursor is displayed for the grab_window and its
subwindows and the grab_window cursor is displayed for all
other windows.
>>STRATEGY
If extensions available:
  Make a tree of windows rooted at grab_window (parent), all with default cursor.
  Set grab_window to be one of its own children (child2), which has its own
    child (grandchild).
  Set grab_window's cursor to be a good, non default, cursor.
  Set grab_window's child's (grandchild) cursor to be yet another good,
    non default, cursor.
  Call XGrabButton with cursor = None.
  Activate grab by simulating button press.
  Warp pointer to all windows in the tree, plus root, and
    validate that current cursor is equal to that of grab_window & grandchild,
    respectively, when in the corresponding windows, but equal to that of
    grab_window otherwise, using extension.
else
  Report untested.
>>ASSERTION B XGrabButton-23
When confine_to is specified and the grab is now active,
then the pointer is confined to that window.
>>STRATEGY
If extensions are available:
  Create a confine_to window.
  Set up grab with XGrabButton.
  Active grab.
  Verify that pointer is within confine_to window.
else
  Report untested.
>>ASSERTION B XGrabButton-24
When the pointer is not initially contained in the
confine_to window, then it is warped automatically to the
closest edge just before the grab activates and enter and
leave events are generated.
>>STRATEGY
If extensions are available:
  Create confine_to window.
  Enable events on the grab_window and the confine_to windows.
  Set owner_events to True.
  Set and activate button grab.
  Verify that a leave event is generated on the window the pointer was in.
  Verify that an enter event is generated on the confine_to window.
else
  Report untested.
>>ASSERTION B XGrabButton-25
When the confine_to window is subsequently reconfigured and
the grab is now active, then the pointer is warped
automatically to keep it within the window.
>>STRATEGY
If extensions are available:
  Create confine_to window.
  Set up and activate button grab,
  Move confine_to so that it does not overlap with it's previous position.
  Verify that the pointer has been warped to the new position.
else
  Report untested.
>>ASSERTION D XGrabButton-26
If multiple screens are supported: It is valid for the
confine_to window to be on a different screen to the
grab_window.
>>STRATEGY
If only one screen
  UNSUPPORTED.
If extensions are available:
  Create grab_window on default screen.
  Create confine_to window on alternate screen.
  Set up and activate grab.
  Verify that pointer is warped to other screen.
else
  Touch test with grab_window and confine_to on different screens.
>>ASSERTION B XGrabButton-27
When the button/key combination is pressed and the grab
becomes active, then the last-pointer-grab time is set to
the time the button was pressed.
>>STRATEGY
If extensions available:
  Call XGrabButton to set up passive grab.
  Press button.
  Get the ButtonPress event.
  Save the time field in the event.
  Release grab by releasing button.
  Attempt to grab pointer using the saved time - 1.
  Verify that pointer is not grabbed.
  Attempt to grab pointer using the saved time.
  Verify that pointer is grabbed.
>>ASSERTION B XGrabButton-28
A call to XGrabButton has no effect on an active grab.
>>STRATEGY
If extensions available:
  Create window.
  Grab pointer on this window.
  Set up passive grab on another window.
  Verify that pointer is still grabbed on first window.
>>ASSERTION B XGrabButton-29
When the grab_window or confine_to window becomes not
viewable during an active pointer grab, then the grab is
released.
>>STRATEGY
If extensions are available:
  Create grab and confine_to windows.
  Set up passive grab with XGrabButton.

  Activate grab with a button press.
  Unmap grab_window.
  Verify that pointer is not grabbed.

  Re-map grab_window.
  Activate grab with a button press.
  Unmap confine_to window.
  Verify that pointer is not grabbed.
else
  Report untested.
>>ASSERTION B XGrabButton-30
When window reconfiguration causes the confine_to window to
lie completely outside the boundaries of the root window
during an active pointer grab, then the grab is released.
>>STRATEGY
If extensions are available:
  Create grab and confine_to windows.
  Set up and activate grab.
  Move confine_to window off the root window.
  Verify that grab is released.
else
  Report untested.
>>ASSERTION A XGrabButton-31
When an attempt to grab a key/button combination already
grabbed by another client is made, then a BadAccess error
occurs.
>>STRATEGY
Grab a button.
Create new client, client1.
Attempt to grab same button with client1.
Verify that a BadAccess error occurs.
>>ASSERTION A XGrabButton-32
When a cursor argument does not name a valid Cursor, then a
BadCursor error occurs.
>>STRATEGY
Create cursor with shape XT_FONTCURSOR_GOOD in font cursor.
Free cursor.
Call test function using bad cursor as the cursor argument.
Verify that a BadCursor error occurs.
>>ASSERTION A XGrabButton-33
When the value of event_mask is not a bitwise combination
of ButtonPressMask, ButtonReleaseMask, EnterWindowMask,
LeaveWindowMask, PointerMotionMask, PointerMotionHintMask,
Button1MotionMask, Button2MotionMask, Button3MotionMask,
Button4MotionMask, Button5MotionMask, ButtonMotionMask or
KeymapStateMask, then a BadValue error occurs.
>>STRATEGY
Obtain a sequence of values which are not in the list specified by VALUE_LIST.
For each value:
  Call test function with this value in the VALUE_ARG argument.
  Verify that a BadValue error occurs.
>>ASSERTION A XGrabButton-34
When the value of modifiers is not a bitwise combination of
ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask,
Mod3Mask, Mod4Mask, Mod5Mask or AnyModifier, then a
BadValue error occurs.
>>STRATEGY
Obtain a sequence of values which are not in the list specified by VALUE_LIST.
For each value:
  Call test function with this value in the VALUE_ARG argument.
  Verify that a BadValue error occurs.
>>ASSERTION A XGrabButton-35
When the value of pointer_mode is other than GrabModeSync
or GrabModeAsync, then a BadValue error occurs.
>>STRATEGY
Obtain a sequence of values which are not in the list specified by VALUE_LIST.
For each value:
  Call test function with this value in the VALUE_ARG argument.
  Verify that a BadValue error occurs.
>>ASSERTION A XGrabButton-36
When the value of keyboard_mode is other than GrabModeSync
or GrabModeAsync, then a BadValue error occurs.
>>STRATEGY
Obtain a sequence of values which are not in the list specified by VALUE_LIST.
For each value:
  Call test function with this value in the VALUE_ARG argument.
  Verify that a BadValue error occurs.
>>ASSERTION A XGrabButton-37
When the value of owner_events is other than True or False,
then a BadValue error occurs.
>>STRATEGY
Obtain a sequence of values which are not in the list specified by VALUE_LIST.
For each value:
  Call test function with this value in the VALUE_ARG argument.
  Verify that a BadValue error occurs.
>>ASSERTION A XGrabButton-38
When the grab_window argument does not name a valid Window,
then a BadWindow error occurs.
>>STRATEGY
Set grab_window to invalid window.
Call XGrabButton.
Verify that a BadWindow error occurs.
>>ASSERTION A XGrabButton-39
When the confine_to argument does not name a valid Window
or None, then a BadWindow error occurs.
>>STRATEGY
Set confine_to to invalid window.
Call XGrabButton.
Verify that a BadWindow error occurs.
