[PATCH 1/4] xkb: LockMods can lock another group on key release #865

Andreas Wettstein wettstein509 at solnet.ch
Sat Nov 10 08:08:20 PST 2012


Two unused bytes in 'XkbModAction' are used to allow 'LockMods' to
perform group locks as well.  These two bytes are interpreted as the
'flags' and the 'group_XXX' bytes in 'XkbGroupAction'.  When the key
that 'LockMods' is assigned to is pressed and released before any
other key is pressed, a group lock as specified by these two bytes is
performed.  Otherwise, 'LockMods' operates according to the XKB
protocol specification.  If the two bytes are zero, which is the case
by default, also no group change happens, so 'LockMods' operates
according to the specification.

Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
---
 include/xkbstr.h |  3 +++
 xkb/xkbActions.c |  7 +++++++
 xkb/xkbtext.c    | 26 ++++++++++++++++++++++++--
 3 Dateien geändert, 34 Zeilen hinzugefügt(+), 2 Zeilen entfernt(-)

diff --git a/include/xkbstr.h b/include/xkbstr.h
index 935330c..8fd7daf 100644
--- a/include/xkbstr.h
+++ b/include/xkbstr.h
@@ -127,6 +127,9 @@ typedef struct _XkbModAction {
     /* FIXME: Make this an int. */
     unsigned char vmods1;
     unsigned char vmods2;
+    /* The effect on groups is an extension beyond the XKB specification */
+    unsigned char group_flags;
+    char	  group_XXX;
 } XkbModAction;
 
 #define	XkbModActionVMods(a) ((short) (((a)->vmods1 << 8) | (a)->vmods2))
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 1adb389..8cd5f5c 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -366,6 +366,13 @@ _XkbFilterLockState(XkbSrvInfoPtr xkbi,
         xkbi->clearMods = filter->upAction.mods.mask;
         if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
             xkbi->state.locked_mods &= ~filter->priv;
+	if (filter->upAction.mods.group_flags & XkbSA_GroupAbsolute)
+	     xkbi->state.locked_group = XkbSAGroup(&filter->upAction.mods);
+	else xkbi->state.locked_group += XkbSAGroup(&filter->upAction.mods);
+    }else if(pAction){
+	/* Another key has been pressed: do not change group on release */
+	XkbSASetGroup(&filter->upAction.mods, 0);
+	filter->upAction.mods.group_flags &= ~XkbSA_GroupAbsolute;
     }
     return 1;
 }
diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c
index fdf1d17..a10639f 100644
--- a/xkb/xkbtext.c
+++ b/xkb/xkbtext.c
@@ -737,6 +737,7 @@ CopyModActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
 {
     XkbModAction *act;
     unsigned tmp;
+    char tbuf[32];
 
     act = &action->mods;
     tmp = XkbModActionVMods(act);
@@ -749,8 +750,29 @@ CopyModActionArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
     }
     else
         TryCopyStr(buf, "none", sz);
-    if (act->type == XkbSA_LockMods)
-        return TRUE;
+    if (act->type == XkbSA_LockMods){
+	switch (act->flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
+	case XkbSA_LockNoLock:
+	    sprintf(tbuf, ",affect=unlock"); break;
+	case XkbSA_LockNoUnlock:
+	    sprintf(tbuf, ",affect=lock"); break;
+	case XkbSA_LockNoUnlock | XkbSA_LockNoLock:
+	    sprintf(tbuf, ",affect=neither"); break;
+	default:
+	    sprintf(tbuf, ""); break;
+	}
+	TryCopyStr(buf, tbuf, sz);
+	if(XkbSAGroup(act) != 0 || (act->group_flags & XkbSA_GroupAbsolute)){
+	    TryCopyStr(buf, ",group=", sz);
+	    if (act->group_flags & XkbSA_GroupAbsolute)
+		sprintf(tbuf, "%d", XkbSAGroup(act)+1);
+	    else if (XkbSAGroup(act) < 0)
+		sprintf(tbuf, "%d", XkbSAGroup(act));
+	    else sprintf(tbuf, "+%d", XkbSAGroup(act));
+	    TryCopyStr(buf, tbuf, sz);
+	}
+	return TRUE;
+    }
     if (act->flags & XkbSA_ClearLocks)
         TryCopyStr(buf, ",clearLocks", sz);
     if (act->flags & XkbSA_LatchToLock)
-- 
1.7.11.3



More information about the xorg-devel mailing list