>># 
>># 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: grbky.m,v 1.9 92/06/11 17:13:08 rws Exp $
>># 
>>#      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:  @(#)  EAcc1.mc Rel 1.4	    (10/2/91)
>>#      SCCS:  @(#)  EWin.mc Rel 1.4	    (7/19/91)
>>#
>>TITLE XGrabKey CH07
>>ASSERTION B XGrabKey-1
A call to XGrabKey establishes a passive grab on the
keyboard that is activated in the future by the specified
key being logically pressed, the specified modifier keys
being logically down, no other modifier keys being logically
down, the grab_window being the focus window or an ancestor
of the focus window or being a descendant of the focus
window that contains the pointer and a passive grab on the
same key combination not existing on any ancestor of
grab_window.
>>STRATEGY
Call XGrabKey as touch test.
If extensions available:
  Set focus to grab window.
  Simulate a key press of key.
  Verify that keyboard is now grabbed.
  Release grab & key.

  Set up a grab with XGrabKey for a key.
  Set focus to grab window.
  Simulate press of another key.
  Simulate the key press.
  Verify that the keyboard is not grabbed.
  Release grab & key.

  Set up a grab with XGrabKey for a key and modifier keys.
  Set focus to grab window.
  Simulate modifier key presses.
  Simulate the key press.
  Verify that the keyboard is grabbed.
  Release grab & key.

  Set up a grab with XGrabKey for a key and modifier keys.
  Set focus to grab window.
  Simulate modifier key presses.
  Simulate extra modifier key presses.
  Simulate the key press.
  Verify that the keyboard is not grabbed.
  Release grab & key.

  Make a child of current grab_window become focus window.
  Call XGrabKey for a passive grab with no modifiers on parent.
  Set focus window to child of grab window.
  Activate the grab.
  Check if grabbed.
  Release key & grab.

  Have grab_window a child of focus window and containing the pointer.
  Call XGrabKey with no modifiers.
  Activate the grab.
  Check if grabbed.
  Release key & grab.

  Have grab_window a child of focus window and not containing the pointer.
  Call XGrabKey with no modifiers.
  Activate the grab.
  Check not grabbed.
  Release key & grab.

  Set grab with no modifiers and grab_window a top-level window.
  Set another grab on child of top-level window.
  Discard event queue.
  Attempt to activate second grab (in child).
  Check event reported w.r.t. parent.
  Check that no event reported for child.
  Check no further events outstanding.
  Check that a grab is active.
  Release parent grab and check grab not active on child.
  Activate child and check key grabbed.
  Release any grabs and keys outstanding.

>>ASSERTION B XGrabKey-2
When the conditions for activating the grab are otherwise
satisfied and the keyboard is already grabbed, then no
active grab is established.
>>STRATEGY
If extensions are available:
  Create two windows that do not overlap.
  Check that at least two keycodes are available.
  Set and activate grab on first window.
  Check grab activated.
  Set grab on second window on another keycode.
  Attempt to activate grab on second window, using other keycode.
  Check that only one KeyPress event received.
  Check it was reported from first grab window.
  Check grab still outstanding.
  Release keys & grabs.
else
  Report untested.
>>ASSERTION B XGrabKey-3
When the conditions for activating the grab are satisfied
and the grab subsequently becomes active, then the
last-keyboard-grab time is set to the time at which the key
was pressed.
>>STRATEGY
If extensions are available:
  Set and activate grab.
  Check activated.
  Check activating event received.
  Check event type and event window are KeyPress and grab_window.
  Attempt XUngrabKeyboard at time just before event time.
  Check still grabbed.
  Attempt XUngrabKeyboard at time equal to event time.
  Check no longer grabbed.
  Release grab & key.
else
  Report untested.
>>ASSERTION B XGrabKey-4
When the grab subsequently becomes active and later the
logical state of the keyboard has the specified key
released, then the active grab is terminated automatically.
>>STRATEGY
If extension available:
    Set grab with modifiers.
    Activate grab.
    Check grabbed.
    Simulate keycode only key release with testing extension.
    Check for grab release.
    Simulate modifiers only key release with testing extension.
    Check for grab release.
    Release grab & keys.
  Repeat but in opposite order with grab release expected on keycode up only.
  Do the same for keycode = AnyKey, no modifiers.
    (releasing the grab with XUngrabKey before expected !kgrabbed() tests.)
else
  Report untested.
>>ASSERTION B XGrabKey-5
A call to XGrabKey overrides all previous passive grabs by
the same client on the same key combinations on the same
window.
>>STRATEGY
If extensions available:
  Create a window for event reporting and set event mask to KeyPressMask.
  Set a grab with owner_events False on another window.
  Set a grab with owner_events True on this other window.
  Activate the grab.
  Check it activated.
  Simulate a KeyPress in the reporting window.
  Check that the reported event has event window equal to reporting
    window rather than grab_window showing that second overrode first.
  Release grabs & keys.
else
  Report untested.
>>ASSERTION B XGrabKey-6
When the modifiers argument is AnyModifier, then this is
equivalent to separate calls to XGrabKey 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 keycode to activate grab.
  Verify that grab is activated.
  Release keys & grab.

  Press keycode (no modifiers).
  Verify that grab is active.
else
  Perform touch test.
  Report untested.
>>ASSERTION B XGrabKey-7
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 XGrabKey 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 XGrabKey-8
When the keycode argument is AnyKey, then this is
equivalent to separate calls to XGrabKey for all possible
KeyCodes.
>>STRATEGY
If extensions are available:
  Set up a passive grab using AnyKey.
    Activate grab with simulated key press.
    Verify that keyboard is grabbed.
    Release key & grab.
    Repeat for other keycodes in range min_keycode to max_keycode.
  Release all grabs & keys.
else
  Touch test using AnyKey.
  Report untested.
>>ASSERTION B XGrabKey-9
When the event window for an active grab becomes not
viewable, then the grab is released automatically.
>>STRATEGY
If extension is available:
  Set up grab on a child window (to avoid window manager interference).
  Activate grab.
  Check grabbed.
  Unmap grab_window.
  Map grab_window back again (to perform grab check).
  Check no longer grabbed.
  Release key & grab.
else
  Report untested.
>>ASSERTION A XGrabKey-10
When the specified keycode is not in the range specified by
min_keycode and max_keycode in the connection setup or
AnyKey, then a BadValue error occurs.
>>STRATEGY
Call XGrabKey with keycode less than min_keycode.
Verify that a BadValue error occurs.
Call XGrabKey with keycode greater than max_keycode if it is less than 255.
Verify that a BadValue error occurs.
>>ASSERTION A XGrabKey-11
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 XGrabKey-12
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 XGrabKey-13
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 XGrabKey-14
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 XGrabKey-15
When an attempt to grab a key/button combination already
grabbed by another client is made, then a BadAccess error
occurs.
>>STRATEGY
Grab key/modifier.
Create client2.
Attempt to grab same key modifier for client2.
Verify BadAccess error.
>>ASSERTION A XGrabKey-16
When a window argument does not name a valid Window, then a
BadWindow error occurs.
>>STRATEGY
Create a bad window by creating and destroying a window.
Call test function using bad window as the window argument.
Verify that a BadWindow error occurs.
