2006-11-26 11:13:41 -07:00
/*
Copyright 1987 , 1998 The Open Group
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 .
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS
OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT .
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM , DAMAGES OR
OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE .
Except as contained in this notice , the name of The Open Group shall
not be used in advertising or otherwise to promote the sale , use or
other dealings in this Software without prior written authorization
from The Open Group .
Copyright 1987 by Digital Equipment Corporation , Maynard , Massachusetts ,
All Rights Reserved
Permission to use , copy , modify , and distribute this software and its
documentation for any purpose and without fee is hereby granted ,
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 name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific , written prior permission .
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE , INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS , IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL , INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS ,
WHETHER IN AN action OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION ,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE .
*/
# ifdef HAVE_DIX_CONFIG_H
# include <dix-config.h>
# endif
# include <X11/X.h>
# include "misc.h"
# include <X11/Xproto.h>
2010-07-27 13:02:24 -06:00
# include <X11/extensions/XI2.h>
2006-11-26 11:13:41 -07:00
# include "windowstr.h"
# include "inputstr.h"
# include "cursorstr.h"
# include "dixgrabs.h"
2008-11-02 08:26:08 -07:00
# include "xace.h"
2010-07-27 13:02:24 -06:00
# include "exevents.h"
2012-06-10 07:21:05 -06:00
# include "exglobals.h"
# include "inpututils.h"
# include "client.h"
2006-11-26 11:13:41 -07:00
# define BITMASK(i) (((Mask)1) << ((i) & 31))
# define MASKIDX(i) ((i) >> 5)
# define MASKWORD(buf, i) buf[MASKIDX(i)]
# define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
# define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
# define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
2011-11-05 07:32:40 -06:00
void
PrintDeviceGrabInfo ( DeviceIntPtr dev )
{
ClientPtr client ;
LocalClientCredRec * lcc ;
int i , j ;
GrabInfoPtr devGrab = & dev - > deviceGrab ;
GrabPtr grab = devGrab - > grab ;
2012-06-10 07:21:05 -06:00
Bool clientIdPrinted = FALSE ;
2011-11-05 07:32:40 -06:00
2012-06-10 07:21:05 -06:00
ErrorF ( " Active grab 0x%lx (%s) on device '%s' (%d): \n " ,
2011-11-05 07:32:40 -06:00
( unsigned long ) grab - > resource ,
2012-06-10 07:21:05 -06:00
( grab - > grabtype = = XI2 ) ? " xi2 " :
( ( grab - > grabtype = = CORE ) ? " core " : " xi1 " ) , dev - > name , dev - > id ) ;
2011-11-05 07:32:40 -06:00
client = clients [ CLIENT_ID ( grab - > resource ) ] ;
2012-06-10 07:21:05 -06:00
if ( client ) {
pid_t clientpid = GetClientPid ( client ) ;
const char * cmdname = GetClientCmdName ( client ) ;
const char * cmdargs = GetClientCmdArgs ( client ) ;
if ( ( clientpid > 0 ) & & ( cmdname ! = NULL ) ) {
ErrorF ( " client pid %ld %s %s \n " ,
( long ) clientpid , cmdname , cmdargs ? cmdargs : " " ) ;
clientIdPrinted = TRUE ;
}
else if ( GetLocalClientCreds ( client , & lcc ) ! = - 1 ) {
ErrorF ( " client pid %ld uid %ld gid %ld \n " ,
( lcc - > fieldsSet & LCC_PID_SET ) ? ( long ) lcc - > pid : 0 ,
( lcc - > fieldsSet & LCC_UID_SET ) ? ( long ) lcc - > euid : 0 ,
( lcc - > fieldsSet & LCC_GID_SET ) ? ( long ) lcc - > egid : 0 ) ;
FreeLocalClientCreds ( lcc ) ;
clientIdPrinted = TRUE ;
}
2011-11-05 07:32:40 -06:00
}
2012-06-10 07:21:05 -06:00
if ( ! clientIdPrinted ) {
ErrorF ( " (no client information available for client %d) \n " ,
CLIENT_ID ( grab - > resource ) ) ;
2011-11-05 07:32:40 -06:00
}
/* XXX is this even correct? */
if ( devGrab - > sync . other )
ErrorF ( " grab ID 0x%lx from paired device \n " ,
( unsigned long ) devGrab - > sync . other - > resource ) ;
ErrorF ( " at %ld (from %s grab)%s (device %s, state %d) \n " ,
( unsigned long ) devGrab - > grabTime . milliseconds ,
devGrab - > fromPassiveGrab ? " passive " : " active " ,
devGrab - > implicitGrab ? " (implicit) " : " " ,
2012-06-10 07:21:05 -06:00
devGrab - > sync . frozen ? " frozen " : " thawed " , devGrab - > sync . state ) ;
2011-11-05 07:32:40 -06:00
2012-06-10 07:21:05 -06:00
if ( grab - > grabtype = = CORE ) {
2011-11-05 07:32:40 -06:00
ErrorF ( " core event mask 0x%lx \n " ,
( unsigned long ) grab - > eventMask ) ;
}
2012-06-10 07:21:05 -06:00
else if ( grab - > grabtype = = XI ) {
2011-11-05 07:32:40 -06:00
ErrorF ( " xi1 event mask 0x%lx \n " ,
devGrab - > implicitGrab ? ( unsigned long ) grab - > deviceMask :
2012-06-10 07:21:05 -06:00
( unsigned long ) grab - > eventMask ) ;
2011-11-05 07:32:40 -06:00
}
2012-06-10 07:21:05 -06:00
else if ( grab - > grabtype = = XI2 ) {
for ( i = 0 ; i < xi2mask_num_masks ( grab - > xi2mask ) ; i + + ) {
const unsigned char * mask ;
2011-11-05 07:32:40 -06:00
int print ;
2012-06-10 07:21:05 -06:00
2011-11-05 07:32:40 -06:00
print = 0 ;
2012-06-10 07:21:05 -06:00
for ( j = 0 ; j < XI2MASKSIZE ; j + + ) {
mask = xi2mask_get_one_mask ( grab - > xi2mask , i ) ;
if ( mask [ j ] ) {
2011-11-05 07:32:40 -06:00
print = 1 ;
break ;
}
}
if ( ! print )
continue ;
ErrorF ( " xi2 event mask for device %d: 0x " , dev - > id ) ;
2012-06-10 07:21:05 -06:00
for ( j = 0 ; j < xi2mask_mask_size ( grab - > xi2mask ) ; j + + )
ErrorF ( " %x " , mask [ j ] ) ;
2011-11-05 07:32:40 -06:00
ErrorF ( " \n " ) ;
}
}
2012-06-10 07:21:05 -06:00
if ( devGrab - > fromPassiveGrab ) {
2011-11-05 07:32:40 -06:00
ErrorF ( " passive grab type %d, detail 0x%x, "
" activating key %d \n " , grab - > type , grab - > detail . exact ,
devGrab - > activatingKey ) ;
}
ErrorF ( " owner-events %s, kb %d ptr %d, confine %lx, cursor 0x%lx \n " ,
grab - > ownerEvents ? " true " : " false " ,
grab - > keyboardMode , grab - > pointerMode ,
grab - > confineTo ? ( unsigned long ) grab - > confineTo - > drawable . id : 0 ,
grab - > cursor ? ( unsigned long ) grab - > cursor - > id : 0 ) ;
}
void
UngrabAllDevices ( Bool kill_client )
{
DeviceIntPtr dev ;
ClientPtr client ;
ErrorF ( " Ungrabbing all devices%s; grabs listed below: \n " ,
kill_client ? " and killing their owners " : " " ) ;
2012-06-10 07:21:05 -06:00
for ( dev = inputInfo . devices ; dev ; dev = dev - > next ) {
2011-11-05 07:32:40 -06:00
if ( ! dev - > deviceGrab . grab )
continue ;
PrintDeviceGrabInfo ( dev ) ;
client = clients [ CLIENT_ID ( dev - > deviceGrab . grab - > resource ) ] ;
if ( ! client | | client - > clientGone )
dev - > deviceGrab . DeactivateGrab ( dev ) ;
2012-06-10 07:21:05 -06:00
if ( kill_client )
CloseDownClient ( client ) ;
2011-11-05 07:32:40 -06:00
}
ErrorF ( " End list of ungrabbed devices \n " ) ;
}
2006-11-26 11:13:41 -07:00
GrabPtr
2012-06-10 07:21:05 -06:00
AllocGrab ( void )
{
GrabPtr grab = calloc ( 1 , sizeof ( GrabRec ) ) ;
if ( grab ) {
grab - > xi2mask = xi2mask_new ( ) ;
if ( ! grab - > xi2mask ) {
free ( grab ) ;
grab = NULL ;
}
}
return grab ;
}
GrabPtr
CreateGrab ( int client , DeviceIntPtr device , DeviceIntPtr modDevice , WindowPtr window , enum InputLevel grabtype , GrabMask * mask , GrabParameters * param , int type , KeyCode keybut , /* key or button */
WindowPtr confineTo , CursorPtr cursor )
2006-11-26 11:13:41 -07:00
{
GrabPtr grab ;
2012-06-10 07:21:05 -06:00
grab = AllocGrab ( ) ;
2006-11-26 11:13:41 -07:00
if ( ! grab )
2012-06-10 07:21:05 -06:00
return ( GrabPtr ) NULL ;
2006-11-26 11:13:41 -07:00
grab - > resource = FakeClientID ( client ) ;
grab - > device = device ;
grab - > window = window ;
2012-06-10 07:21:05 -06:00
grab - > eventMask = mask - > core ; /* same for XI */
2009-09-06 13:44:18 -06:00
grab - > deviceMask = 0 ;
2010-07-27 13:02:24 -06:00
grab - > ownerEvents = param - > ownerEvents ;
grab - > keyboardMode = param - > this_device_mode ;
grab - > pointerMode = param - > other_devices_mode ;
grab - > modifiersDetail . exact = param - > modifiers ;
2006-11-26 11:13:41 -07:00
grab - > modifiersDetail . pMask = NULL ;
grab - > modifierDevice = modDevice ;
grab - > type = type ;
2010-07-27 13:02:24 -06:00
grab - > grabtype = grabtype ;
2006-11-26 11:13:41 -07:00
grab - > detail . exact = keybut ;
grab - > detail . pMask = NULL ;
grab - > confineTo = confineTo ;
grab - > cursor = cursor ;
2009-09-06 13:44:18 -06:00
grab - > next = NULL ;
2010-07-27 13:02:24 -06:00
2012-06-10 07:21:05 -06:00
if ( grabtype = = XI2 )
xi2mask_merge ( grab - > xi2mask , mask - > xi2mask ) ;
2006-11-26 11:13:41 -07:00
if ( cursor )
2012-06-10 07:21:05 -06:00
cursor - > refcnt + + ;
2006-11-26 11:13:41 -07:00
return grab ;
}
2012-06-10 07:21:05 -06:00
void
2006-11-26 11:13:41 -07:00
FreeGrab ( GrabPtr pGrab )
{
2012-06-10 07:21:05 -06:00
if ( pGrab - > grabtype = = XI2 & & pGrab - > type = = XI_TouchBegin )
TouchListenerGone ( pGrab - > resource ) ;
2011-11-05 07:32:40 -06:00
free ( pGrab - > modifiersDetail . pMask ) ;
free ( pGrab - > detail . pMask ) ;
2006-11-26 11:13:41 -07:00
if ( pGrab - > cursor )
2012-06-10 07:21:05 -06:00
FreeCursor ( pGrab - > cursor , ( Cursor ) 0 ) ;
2006-11-26 11:13:41 -07:00
2012-06-10 07:21:05 -06:00
xi2mask_free ( & pGrab - > xi2mask ) ;
2010-12-05 08:36:02 -07:00
free ( pGrab ) ;
2006-11-26 11:13:41 -07:00
}
2012-06-10 07:21:05 -06:00
Bool
CopyGrab ( GrabPtr dst , const GrabPtr src )
{
Mask * mdetails_mask = NULL ;
Mask * details_mask = NULL ;
XI2Mask * xi2mask ;
if ( src - > cursor )
src - > cursor - > refcnt + + ;
if ( src - > modifiersDetail . pMask ) {
int len = MasksPerDetailMask * sizeof ( Mask ) ;
mdetails_mask = malloc ( len ) ;
if ( ! mdetails_mask )
return FALSE ;
memcpy ( mdetails_mask , src - > modifiersDetail . pMask , len ) ;
}
if ( src - > detail . pMask ) {
int len = MasksPerDetailMask * sizeof ( Mask ) ;
details_mask = malloc ( len ) ;
if ( ! details_mask ) {
free ( mdetails_mask ) ;
return FALSE ;
}
memcpy ( details_mask , src - > detail . pMask , len ) ;
}
if ( ! dst - > xi2mask ) {
xi2mask = xi2mask_new ( ) ;
if ( ! xi2mask ) {
free ( mdetails_mask ) ;
free ( details_mask ) ;
return FALSE ;
}
}
else {
xi2mask = dst - > xi2mask ;
xi2mask_zero ( xi2mask , - 1 ) ;
}
* dst = * src ;
dst - > modifiersDetail . pMask = mdetails_mask ;
dst - > detail . pMask = details_mask ;
dst - > xi2mask = xi2mask ;
xi2mask_merge ( dst - > xi2mask , src - > xi2mask ) ;
return TRUE ;
}
2006-11-26 11:13:41 -07:00
int
DeletePassiveGrab ( pointer value , XID id )
{
2007-11-24 10:55:21 -07:00
GrabPtr g , prev ;
2012-06-10 07:21:05 -06:00
GrabPtr pGrab = ( GrabPtr ) value ;
2006-11-26 11:13:41 -07:00
/* it is OK if the grab isn't found */
prev = 0 ;
2012-06-10 07:21:05 -06:00
for ( g = ( wPassiveGrabs ( pGrab - > window ) ) ; g ; g = g - > next ) {
if ( pGrab = = g ) {
if ( prev )
prev - > next = g - > next ;
else if ( ! ( pGrab - > window - > optional - > passiveGrabs = g - > next ) )
CheckWindowOptionalNeed ( pGrab - > window ) ;
break ;
}
prev = g ;
2006-11-26 11:13:41 -07:00
}
FreeGrab ( pGrab ) ;
return Success ;
}
static Mask *
2010-07-27 13:02:24 -06:00
DeleteDetailFromMask ( Mask * pDetailMask , unsigned int detail )
2006-11-26 11:13:41 -07:00
{
2007-11-24 10:55:21 -07:00
Mask * mask ;
int i ;
2006-11-26 11:13:41 -07:00
2010-12-05 08:36:02 -07:00
mask = malloc ( sizeof ( Mask ) * MasksPerDetailMask ) ;
2012-06-10 07:21:05 -06:00
if ( mask ) {
if ( pDetailMask )
for ( i = 0 ; i < MasksPerDetailMask ; i + + )
mask [ i ] = pDetailMask [ i ] ;
else
for ( i = 0 ; i < MasksPerDetailMask ; i + + )
mask [ i ] = ~ 0L ;
BITCLEAR ( mask , detail ) ;
2006-11-26 11:13:41 -07:00
}
2012-06-10 07:21:05 -06:00
return mask ;
2006-11-26 11:13:41 -07:00
}
static Bool
2012-06-10 07:21:05 -06:00
IsInGrabMask ( DetailRec firstDetail ,
DetailRec secondDetail , unsigned int exception )
2006-11-26 11:13:41 -07:00
{
2012-06-10 07:21:05 -06:00
if ( firstDetail . exact = = exception ) {
if ( firstDetail . pMask = = NULL )
return TRUE ;
/* (at present) never called with two non-null pMasks */
if ( secondDetail . exact = = exception )
return FALSE ;
if ( GETBIT ( firstDetail . pMask , secondDetail . exact ) )
return TRUE ;
2006-11-26 11:13:41 -07:00
}
2012-06-10 07:21:05 -06:00
2006-11-26 11:13:41 -07:00
return FALSE ;
}
2012-06-10 07:21:05 -06:00
static Bool
IdenticalExactDetails ( unsigned int firstExact ,
unsigned int secondExact , unsigned int exception )
2006-11-26 11:13:41 -07:00
{
if ( ( firstExact = = exception ) | | ( secondExact = = exception ) )
2012-06-10 07:21:05 -06:00
return FALSE ;
2006-11-26 11:13:41 -07:00
if ( firstExact = = secondExact )
2012-06-10 07:21:05 -06:00
return TRUE ;
2006-11-26 11:13:41 -07:00
return FALSE ;
}
2012-06-10 07:21:05 -06:00
static Bool
DetailSupersedesSecond ( DetailRec firstDetail ,
DetailRec secondDetail , unsigned int exception )
2006-11-26 11:13:41 -07:00
{
if ( IsInGrabMask ( firstDetail , secondDetail , exception ) )
2012-06-10 07:21:05 -06:00
return TRUE ;
if ( IdenticalExactDetails ( firstDetail . exact , secondDetail . exact , exception ) )
return TRUE ;
2006-11-26 11:13:41 -07:00
return FALSE ;
}
static Bool
GrabSupersedesSecond ( GrabPtr pFirstGrab , GrabPtr pSecondGrab )
{
2012-06-10 07:21:05 -06:00
unsigned int any_modifier = ( pFirstGrab - > grabtype = = XI2 ) ?
( unsigned int ) XIAnyModifier : ( unsigned int ) AnyModifier ;
2006-11-26 11:13:41 -07:00
if ( ! DetailSupersedesSecond ( pFirstGrab - > modifiersDetail ,
2012-06-10 07:21:05 -06:00
pSecondGrab - > modifiersDetail , any_modifier ) )
return FALSE ;
2006-11-26 11:13:41 -07:00
if ( DetailSupersedesSecond ( pFirstGrab - > detail ,
2012-06-10 07:21:05 -06:00
pSecondGrab - > detail , ( unsigned int ) AnyKey ) )
return TRUE ;
2006-11-26 11:13:41 -07:00
return FALSE ;
}
2009-09-06 13:44:18 -06:00
/**
* Compares two grabs and returns TRUE if the first grab matches the second
* grab .
*
* A match is when
* - the devices set for the grab are equal ( this is optional ) .
* - the event types for both grabs are equal .
* - XXX
*
* @ param ignoreDevice TRUE if the device settings on the grabs are to be
* ignored .
* @ return TRUE if the grabs match or FALSE otherwise .
*/
2006-11-26 11:13:41 -07:00
Bool
2009-09-06 13:44:18 -06:00
GrabMatchesSecond ( GrabPtr pFirstGrab , GrabPtr pSecondGrab , Bool ignoreDevice )
2006-11-26 11:13:41 -07:00
{
2012-06-10 07:21:05 -06:00
unsigned int any_modifier = ( pFirstGrab - > grabtype = = XI2 ) ?
( unsigned int ) XIAnyModifier : ( unsigned int ) AnyModifier ;
2010-07-27 13:02:24 -06:00
if ( pFirstGrab - > grabtype ! = pSecondGrab - > grabtype )
return FALSE ;
2012-06-10 07:21:05 -06:00
if ( pFirstGrab - > grabtype = = XI2 ) {
2010-07-27 13:02:24 -06:00
if ( pFirstGrab - > device = = inputInfo . all_devices | |
2012-06-10 07:21:05 -06:00
pSecondGrab - > device = = inputInfo . all_devices ) {
2010-07-27 13:02:24 -06:00
/* do nothing */
2012-06-10 07:21:05 -06:00
}
else if ( pFirstGrab - > device = = inputInfo . all_master_devices ) {
2010-07-27 13:02:24 -06:00
if ( pSecondGrab - > device ! = inputInfo . all_master_devices & &
! IsMaster ( pSecondGrab - > device ) )
return FALSE ;
2012-06-10 07:21:05 -06:00
}
else if ( pSecondGrab - > device = = inputInfo . all_master_devices ) {
2010-07-27 13:02:24 -06:00
if ( pFirstGrab - > device ! = inputInfo . all_master_devices & &
! IsMaster ( pFirstGrab - > device ) )
return FALSE ;
2012-06-10 07:21:05 -06:00
}
else if ( pSecondGrab - > device ! = pFirstGrab - > device )
2009-09-06 13:44:18 -06:00
return FALSE ;
2012-06-10 07:21:05 -06:00
}
else if ( ! ignoreDevice & &
( ( pFirstGrab - > device ! = pSecondGrab - > device ) | |
( pFirstGrab - > modifierDevice ! = pSecondGrab - > modifierDevice ) ) )
return FALSE ;
2009-09-06 13:44:18 -06:00
if ( pFirstGrab - > type ! = pSecondGrab - > type )
2012-06-10 07:21:05 -06:00
return FALSE ;
2006-11-26 11:13:41 -07:00
if ( GrabSupersedesSecond ( pFirstGrab , pSecondGrab ) | |
2012-06-10 07:21:05 -06:00
GrabSupersedesSecond ( pSecondGrab , pFirstGrab ) )
return TRUE ;
2006-11-26 11:13:41 -07:00
if ( DetailSupersedesSecond ( pSecondGrab - > detail , pFirstGrab - > detail ,
2012-06-10 07:21:05 -06:00
( unsigned int ) AnyKey )
& &
DetailSupersedesSecond ( pFirstGrab - > modifiersDetail ,
pSecondGrab - > modifiersDetail , any_modifier ) )
return TRUE ;
2006-11-26 11:13:41 -07:00
if ( DetailSupersedesSecond ( pFirstGrab - > detail , pSecondGrab - > detail ,
2012-06-10 07:21:05 -06:00
( unsigned int ) AnyKey )
& &
DetailSupersedesSecond ( pSecondGrab - > modifiersDetail ,
pFirstGrab - > modifiersDetail , any_modifier ) )
return TRUE ;
2006-11-26 11:13:41 -07:00
return FALSE ;
}
2007-11-24 10:55:21 -07:00
static Bool
GrabsAreIdentical ( GrabPtr pFirstGrab , GrabPtr pSecondGrab )
{
2012-06-10 07:21:05 -06:00
unsigned int any_modifier = ( pFirstGrab - > grabtype = = XI2 ) ?
( unsigned int ) XIAnyModifier : ( unsigned int ) AnyModifier ;
2010-07-27 13:02:24 -06:00
if ( pFirstGrab - > grabtype ! = pSecondGrab - > grabtype )
return FALSE ;
2012-06-10 07:21:05 -06:00
if ( pFirstGrab - > device ! = pSecondGrab - > device | |
( pFirstGrab - > modifierDevice ! = pSecondGrab - > modifierDevice ) | |
( pFirstGrab - > type ! = pSecondGrab - > type ) )
2007-11-24 10:55:21 -07:00
return FALSE ;
2012-06-10 07:21:05 -06:00
if ( ! ( DetailSupersedesSecond ( pFirstGrab - > detail ,
pSecondGrab - > detail ,
( unsigned int ) AnyKey ) & &
DetailSupersedesSecond ( pSecondGrab - > detail ,
pFirstGrab - > detail , ( unsigned int ) AnyKey ) ) )
return FALSE ;
2010-07-27 13:02:24 -06:00
2012-06-10 07:21:05 -06:00
if ( ! ( DetailSupersedesSecond ( pFirstGrab - > modifiersDetail ,
pSecondGrab - > modifiersDetail ,
any_modifier ) & &
DetailSupersedesSecond ( pSecondGrab - > modifiersDetail ,
pFirstGrab - > modifiersDetail , any_modifier ) ) )
2007-11-24 10:55:21 -07:00
return FALSE ;
return TRUE ;
}
/**
* Prepend the new grab to the list of passive grabs on the window .
* Any previously existing grab that matches the new grab will be removed .
* Adding a new grab that would override another client ' s grab will result in
* a BadAccess .
*
* @ return Success or X error code on failure .
*/
2006-11-26 11:13:41 -07:00
int
2008-11-02 08:26:08 -07:00
AddPassiveGrabToList ( ClientPtr client , GrabPtr pGrab )
2006-11-26 11:13:41 -07:00
{
GrabPtr grab ;
2008-11-02 08:26:08 -07:00
Mask access_mode = DixGrabAccess ;
int rc ;
2006-11-26 11:13:41 -07:00
2012-06-10 07:21:05 -06:00
for ( grab = wPassiveGrabs ( pGrab - > window ) ; grab ; grab = grab - > next ) {
if ( GrabMatchesSecond ( pGrab , grab , ( pGrab - > grabtype = = CORE ) ) ) {
if ( CLIENT_BITS ( pGrab - > resource ) ! = CLIENT_BITS ( grab - > resource ) ) {
FreeGrab ( pGrab ) ;
return BadAccess ;
}
}
2006-11-26 11:13:41 -07:00
}
2012-06-10 07:21:05 -06:00
if ( pGrab - > keyboardMode = = GrabModeSync | |
pGrab - > pointerMode = = GrabModeSync )
access_mode | = DixFreezeAccess ;
2008-11-02 08:26:08 -07:00
rc = XaceHook ( XACE_DEVICE_ACCESS , client , pGrab - > device , access_mode ) ;
if ( rc ! = Success )
2012-06-10 07:21:05 -06:00
return rc ;
2008-11-02 08:26:08 -07:00
2007-11-24 10:55:21 -07:00
/* Remove all grabs that match the new one exactly */
2012-06-10 07:21:05 -06:00
for ( grab = wPassiveGrabs ( pGrab - > window ) ; grab ; grab = grab - > next ) {
if ( GrabsAreIdentical ( pGrab , grab ) ) {
2007-11-24 10:55:21 -07:00
DeletePassiveGrabFromList ( grab ) ;
break ;
2012-06-10 07:21:05 -06:00
}
2007-11-24 10:55:21 -07:00
}
2012-06-10 07:21:05 -06:00
if ( ! pGrab - > window - > optional & & ! MakeWindowOptional ( pGrab - > window ) ) {
FreeGrab ( pGrab ) ;
return BadAlloc ;
2006-11-26 11:13:41 -07:00
}
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
pGrab - > next = pGrab - > window - > optional - > passiveGrabs ;
pGrab - > window - > optional - > passiveGrabs = pGrab ;
2012-06-10 07:21:05 -06:00
if ( AddResource ( pGrab - > resource , RT_PASSIVEGRAB , ( pointer ) pGrab ) )
return Success ;
2006-11-26 11:13:41 -07:00
return BadAlloc ;
}
/* the following is kinda complicated, because we need to be able to back out
* if any allocation fails
*/
Bool
DeletePassiveGrabFromList ( GrabPtr pMinuendGrab )
{
2007-11-24 10:55:21 -07:00
GrabPtr grab ;
2006-11-26 11:13:41 -07:00
GrabPtr * deletes , * adds ;
Mask * * * updates , * * details ;
int i , ndels , nadds , nups ;
Bool ok ;
2010-07-27 13:02:24 -06:00
unsigned int any_modifier ;
unsigned int any_key ;
2006-11-26 11:13:41 -07:00
# define UPDATE(mask,exact) \
if ( ! ( details [ nups ] = DeleteDetailFromMask ( mask , exact ) ) ) \
ok = FALSE ; \
else \
updates [ nups + + ] = & ( mask )
i = 0 ;
for ( grab = wPassiveGrabs ( pMinuendGrab - > window ) ; grab ; grab = grab - > next )
2012-06-10 07:21:05 -06:00
i + + ;
2006-11-26 11:13:41 -07:00
if ( ! i )
2012-06-10 07:21:05 -06:00
return TRUE ;
2010-12-05 08:36:02 -07:00
deletes = malloc ( i * sizeof ( GrabPtr ) ) ;
adds = malloc ( i * sizeof ( GrabPtr ) ) ;
updates = malloc ( i * sizeof ( Mask * * ) ) ;
details = malloc ( i * sizeof ( Mask * ) ) ;
2012-06-10 07:21:05 -06:00
if ( ! deletes | | ! adds | | ! updates | | ! details ) {
free ( details ) ;
free ( updates ) ;
free ( adds ) ;
free ( deletes ) ;
return FALSE ;
2006-11-26 11:13:41 -07:00
}
2010-07-27 13:02:24 -06:00
2012-06-10 07:21:05 -06:00
any_modifier = ( pMinuendGrab - > grabtype = = XI2 ) ?
( unsigned int ) XIAnyModifier : ( unsigned int ) AnyModifier ;
any_key = ( pMinuendGrab - > grabtype = = XI2 ) ?
( unsigned int ) XIAnyKeycode : ( unsigned int ) AnyKey ;
2006-11-26 11:13:41 -07:00
ndels = nadds = nups = 0 ;
ok = TRUE ;
for ( grab = wPassiveGrabs ( pMinuendGrab - > window ) ;
2012-06-10 07:21:05 -06:00
grab & & ok ; grab = grab - > next ) {
if ( ( CLIENT_BITS ( grab - > resource ) ! = CLIENT_BITS ( pMinuendGrab - > resource ) )
| | ! GrabMatchesSecond ( grab , pMinuendGrab , ( grab - > grabtype = = CORE ) ) )
continue ;
if ( GrabSupersedesSecond ( pMinuendGrab , grab ) ) {
deletes [ ndels + + ] = grab ;
}
else if ( ( grab - > detail . exact = = any_key )
& & ( grab - > modifiersDetail . exact ! = any_modifier ) ) {
UPDATE ( grab - > detail . pMask , pMinuendGrab - > detail . exact ) ;
}
else if ( ( grab - > modifiersDetail . exact = = any_modifier )
& & ( grab - > detail . exact ! = any_key ) ) {
UPDATE ( grab - > modifiersDetail . pMask ,
pMinuendGrab - > modifiersDetail . exact ) ;
}
else if ( ( pMinuendGrab - > detail . exact ! = any_key )
& & ( pMinuendGrab - > modifiersDetail . exact ! = any_modifier ) ) {
GrabPtr pNewGrab ;
2010-07-27 13:02:24 -06:00
GrabParameters param ;
2006-11-26 11:13:41 -07:00
2012-06-10 07:21:05 -06:00
UPDATE ( grab - > detail . pMask , pMinuendGrab - > detail . exact ) ;
2006-11-26 11:13:41 -07:00
2010-07-27 13:02:24 -06:00
memset ( & param , 0 , sizeof ( param ) ) ;
param . ownerEvents = grab - > ownerEvents ;
param . this_device_mode = grab - > keyboardMode ;
param . other_devices_mode = grab - > pointerMode ;
param . modifiers = any_modifier ;
2012-06-10 07:21:05 -06:00
pNewGrab = CreateGrab ( CLIENT_ID ( grab - > resource ) , grab - > device ,
grab - > modifierDevice , grab - > window ,
2010-07-27 13:02:24 -06:00
grab - > grabtype ,
2012-06-10 07:21:05 -06:00
( GrabMask * ) & grab - > eventMask ,
& param , ( int ) grab - > type ,
pMinuendGrab - > detail . exact ,
grab - > confineTo , grab - > cursor ) ;
if ( ! pNewGrab )
ok = FALSE ;
else if ( ! ( pNewGrab - > modifiersDetail . pMask =
DeleteDetailFromMask ( grab - > modifiersDetail . pMask ,
pMinuendGrab - > modifiersDetail .
exact ) )
| | ( ! pNewGrab - > window - > optional & &
! MakeWindowOptional ( pNewGrab - > window ) ) ) {
FreeGrab ( pNewGrab ) ;
ok = FALSE ;
}
else if ( ! AddResource ( pNewGrab - > resource , RT_PASSIVEGRAB ,
( pointer ) pNewGrab ) )
ok = FALSE ;
else
adds [ nadds + + ] = pNewGrab ;
}
else if ( pMinuendGrab - > detail . exact = = any_key ) {
UPDATE ( grab - > modifiersDetail . pMask ,
pMinuendGrab - > modifiersDetail . exact ) ;
}
else {
UPDATE ( grab - > detail . pMask , pMinuendGrab - > detail . exact ) ;
}
2006-11-26 11:13:41 -07:00
}
2012-06-10 07:21:05 -06:00
if ( ! ok ) {
for ( i = 0 ; i < nadds ; i + + )
FreeResource ( adds [ i ] - > resource , RT_NONE ) ;
for ( i = 0 ; i < nups ; i + + )
free ( details [ i ] ) ;
2006-11-26 11:13:41 -07:00
}
2012-06-10 07:21:05 -06:00
else {
for ( i = 0 ; i < ndels ; i + + )
FreeResource ( deletes [ i ] - > resource , RT_NONE ) ;
for ( i = 0 ; i < nadds ; i + + ) {
grab = adds [ i ] ;
grab - > next = grab - > window - > optional - > passiveGrabs ;
grab - > window - > optional - > passiveGrabs = grab ;
}
for ( i = 0 ; i < nups ; i + + ) {
free ( * updates [ i ] ) ;
* updates [ i ] = details [ i ] ;
}
2006-11-26 11:13:41 -07:00
}
2010-12-05 08:36:02 -07:00
free ( details ) ;
free ( updates ) ;
free ( adds ) ;
free ( deletes ) ;
2006-11-26 11:13:41 -07:00
return ok ;
# undef UPDATE
}
2012-06-10 07:21:05 -06:00
Bool
GrabIsPointerGrab ( GrabPtr grab )
{
return ( grab - > type = = ButtonPress | |
grab - > type = = DeviceButtonPress | | grab - > type = = XI_ButtonPress ) ;
}
Bool
GrabIsKeyboardGrab ( GrabPtr grab )
{
return ( grab - > type = = KeyPress | |
grab - > type = = DeviceKeyPress | | grab - > type = = XI_KeyPress ) ;
}