[PATCH] Re-enabled Xnest fix for focus in + modifier bug.

Peter Hutterer peter.hutterer at who-t.net
Tue Jun 15 16:11:27 PDT 2010


On Sat, Jun 12, 2010 at 04:40:54PM +0800, Xiaoyang Yu (Max) wrote:
> Signed-off-by: Xiaoyang Yu (Max) <max.a.yu at intel.com>
> Reviewed-by: Mikhail Gusarov <dottedmag at dottedmag.net>

Thanks, I've merged this into my tree. Keith, don't merge this patch please,
i want to add a blurb to the commit message so it's identifiable what this
patch actually does.

Cheers,
  Peter
> ---
>  hw/kdrive/ephyr/ephyr.c |  107 ++++++++++++++++++++---------------------------
>  1 files changed, 45 insertions(+), 62 deletions(-)
> 
> diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
> index b968516..e734522 100644
> --- a/hw/kdrive/ephyr/ephyr.c
> +++ b/hw/kdrive/ephyr/ephyr.c
> @@ -38,6 +38,8 @@
>  #include "ephyrglxext.h"
>  #endif /* XF86DRI */
>  
> +#include "xkbsrv.h"
> +
>  extern int KdTsPhyScreen;
>  #ifdef GLXEXT
>  extern Bool noGlxVisualInit;
> @@ -748,75 +750,55 @@ ephyrScreenFini (KdScreenInfo *screen)
>  void
>  ephyrUpdateModifierState(unsigned int state)
>  {
> -#if 0
> -  DeviceIntPtr pkeydev;
> -  KeyClassPtr  keyc;
> -  int          i;
> -  CARD8        mask;
> -
> -  pkeydev = inputInfo.keyboard;
>  
> -  if (!pkeydev)
> -    return;
> +  DeviceIntPtr pDev = inputInfo.keyboard;
> +  KeyClassPtr keyc = pDev->key;
> +  int i;
> +  CARD8 mask;
> +  int xkb_state;
>    
> -/* This is pretty broken.
> - *
> - * What should happen is that focus out should do as a VT switch does in
> - * traditional servers: fake releases for all keys (and buttons too, come
> - * to think of it) currently down.  Then, on focus in, get the state from
> - * the host, and fake keypresses for everything currently down.
> - *
> - * So I'm leaving this broken for a little while.  Sorry, folks.
> - *
> - * -daniels
> - */
> +  if (!pDev)
> +      return;
>  
> -  keyc = pkeydev->key;
> -  
> +  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
>    state = state & 0xff;
> -  
> -  if (keyc->state == state)
> +
> +  if (xkb_state == state)
>      return;
> -  
> -  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) 
> -    {
> -      int key;
>        
> -      /* Modifier is down, but shouldn't be   */
> -      if ((keyc->state & mask) && !(state & mask)) 
> -	{
> -	  int count = keyc->modifierKeyCount[i];
> -	  
> -	  for (key = 0; key < MAP_LENGTH; key++)
> -	    if (keyc->xkbInfo->desc->map->modmap[key] & mask)
> -	      {
> -		int bit;
> -		BYTE *kptr;
> -		
> -		kptr = &keyc->down[key >> 3];
> -		bit = 1 << (key & 7);
> -		
> -		if (*kptr & bit && ephyrKbd &&
> -                    ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
> -		  KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
> -		
> -		if (--count == 0)
> -		  break;
> -	      }
> -	}
> -       
> -      /* Modifier shoud be down, but isn't   */
> -      if (!(keyc->state & mask) && (state & mask))
> -	for (key = 0; key < MAP_LENGTH; key++)
> -	  if (keyc->xkbInfo->desc->map->modmap[key] & mask)
> -	    {
> -              if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
> -                  ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
> -	          KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
> -	      break;
> -	    }
> +  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
> +    int key;
> +
> +    /* Modifier is down, but shouldn't be
> +     */
> +    if ((xkb_state & mask) && !(state & mask)) {
> +      int count = keyc->modifierKeyCount[i];
> +
> +      for (key = 0; key < MAP_LENGTH; key++)
> +        if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
> +          int bit;
> +          BYTE *kptr;
> +
> +          kptr = &keyc->down[key >> 3];
> +          bit = 1 << (key & 7);
> +
> +          if (*kptr & bit)
> +	        KdEnqueueKeyboardEvent (ephyrKbd, key, TRUE);
> +
> +          if (--count == 0)
> +            break;
> +        }
>      }
> -#endif
> +
> +    /* Modifier shoud be down, but isn't
> +     */
> +    if (!(xkb_state & mask) && (state & mask))
> +      for (key = 0; key < MAP_LENGTH; key++)
> +        if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
> +	        KdEnqueueKeyboardEvent (ephyrKbd, key, FALSE);
> +          break;
> +        }
> +  }
>  }
>  
>  static void
> @@ -998,6 +980,7 @@ ephyrPoll(void)
>            if (!ephyrKbd ||
>                !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
>                continue;
> +      ephyrUpdateModifierState(ev.key_state);
>  	  KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
>  	  break;
>  
> -- 
> 1.7.0
> 
> 

> From: Xiaoyang Yu (Max) <max.a.yu at intel.com>
> Date: Fri, 4 Jun 2010 17:17:53 +0800
> Subject: [PATCH] Re-enabled Xnest fix for focus in + modifier bug.
>   * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
> 
> Signed-off-by: Xiaoyang Yu (Max) <max.a.yu at intel.com>
> Reviewed-by: Mikhail Gusarov <dottedmag at dottedmag.net>
> ---
>  hw/kdrive/ephyr/ephyr.c |  107 ++++++++++++++++++++---------------------------
>  1 files changed, 45 insertions(+), 62 deletions(-)
> 
> diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
> index b968516..e734522 100644
> --- a/hw/kdrive/ephyr/ephyr.c
> +++ b/hw/kdrive/ephyr/ephyr.c
> @@ -38,6 +38,8 @@
>  #include "ephyrglxext.h"
>  #endif /* XF86DRI */
>  
> +#include "xkbsrv.h"
> +
>  extern int KdTsPhyScreen;
>  #ifdef GLXEXT
>  extern Bool noGlxVisualInit;
> @@ -748,75 +750,55 @@ ephyrScreenFini (KdScreenInfo *screen)
>  void
>  ephyrUpdateModifierState(unsigned int state)
>  {
> -#if 0
> -  DeviceIntPtr pkeydev;
> -  KeyClassPtr  keyc;
> -  int          i;
> -  CARD8        mask;
> -
> -  pkeydev = inputInfo.keyboard;
>  
> -  if (!pkeydev)
> -    return;
> +  DeviceIntPtr pDev = inputInfo.keyboard;
> +  KeyClassPtr keyc = pDev->key;
> +  int i;
> +  CARD8 mask;
> +  int xkb_state;
>    
> -/* This is pretty broken.
> - *
> - * What should happen is that focus out should do as a VT switch does in
> - * traditional servers: fake releases for all keys (and buttons too, come
> - * to think of it) currently down.  Then, on focus in, get the state from
> - * the host, and fake keypresses for everything currently down.
> - *
> - * So I'm leaving this broken for a little while.  Sorry, folks.
> - *
> - * -daniels
> - */
> +  if (!pDev)
> +      return;
>  
> -  keyc = pkeydev->key;
> -  
> +  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
>    state = state & 0xff;
> -  
> -  if (keyc->state == state)
> +
> +  if (xkb_state == state)
>      return;
> -  
> -  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) 
> -    {
> -      int key;
>        
> -      /* Modifier is down, but shouldn't be   */
> -      if ((keyc->state & mask) && !(state & mask)) 
> -	{
> -	  int count = keyc->modifierKeyCount[i];
> -	  
> -	  for (key = 0; key < MAP_LENGTH; key++)
> -	    if (keyc->xkbInfo->desc->map->modmap[key] & mask)
> -	      {
> -		int bit;
> -		BYTE *kptr;
> -		
> -		kptr = &keyc->down[key >> 3];
> -		bit = 1 << (key & 7);
> -		
> -		if (*kptr & bit && ephyrKbd &&
> -                    ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
> -		  KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
> -		
> -		if (--count == 0)
> -		  break;
> -	      }
> -	}
> -       
> -      /* Modifier shoud be down, but isn't   */
> -      if (!(keyc->state & mask) && (state & mask))
> -	for (key = 0; key < MAP_LENGTH; key++)
> -	  if (keyc->xkbInfo->desc->map->modmap[key] & mask)
> -	    {
> -              if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
> -                  ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
> -	          KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
> -	      break;
> -	    }
> +  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
> +    int key;
> +
> +    /* Modifier is down, but shouldn't be
> +     */
> +    if ((xkb_state & mask) && !(state & mask)) {
> +      int count = keyc->modifierKeyCount[i];
> +
> +      for (key = 0; key < MAP_LENGTH; key++)
> +        if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
> +          int bit;
> +          BYTE *kptr;
> +
> +          kptr = &keyc->down[key >> 3];
> +          bit = 1 << (key & 7);
> +
> +          if (*kptr & bit)
> +	        KdEnqueueKeyboardEvent (ephyrKbd, key, TRUE);
> +
> +          if (--count == 0)
> +            break;
> +        }
>      }
> -#endif
> +
> +    /* Modifier shoud be down, but isn't
> +     */
> +    if (!(xkb_state & mask) && (state & mask))
> +      for (key = 0; key < MAP_LENGTH; key++)
> +        if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
> +	        KdEnqueueKeyboardEvent (ephyrKbd, key, FALSE);
> +          break;
> +        }
> +  }
>  }
>  
>  static void
> @@ -998,6 +980,7 @@ ephyrPoll(void)
>            if (!ephyrKbd ||
>                !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
>                continue;
> +      ephyrUpdateModifierState(ev.key_state);
>  	  KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
>  	  break;
>  
> -- 
> 1.7.0
> 


More information about the xorg-devel mailing list