[PATCH 18/18] Make action strings configurable via synclient

Takashi Iwai tiwai at suse.de
Fri Oct 8 10:22:42 PDT 2010


Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 include/synaptics-properties.h |   10 ++++++
 src/keymap.c                   |   58 ++++++++++++++++++++++++++----------
 src/properties.c               |   63 ++++++++++++++++++++++++++++++++++++++++
 src/synaptics.c                |   60 ++++++++++++++++++-------------------
 src/synapticsstr.h             |   28 +++++++++---------
 tools/synclient.c              |   49 ++++++++++++++++++++++++++++--
 6 files changed, 203 insertions(+), 65 deletions(-)

diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
index c31c53c..7267669 100644
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -185,4 +185,14 @@
 /* 32 bit, 2 values */
 #define SYNAPTICS_PROP_THREEFINGER_DELTA "Synaptics Three-Finger Delta"
 
+/* STR */
+#define SYNAPTICS_PROP_ZOOM_IN_ACTION "Synaptics Zoom-In Action"
+#define SYNAPTICS_PROP_ZOOM_OUT_ACTION "Synaptics Zoom-Out Action"
+
+/* STR */
+#define SYNAPTICS_PROP_3FINGER_LEFT_ACTION "Synaptics 3-Finger Left Action"
+#define SYNAPTICS_PROP_3FINGER_RIGHT_ACTION "Synaptics 3-Finger Right Action"
+#define SYNAPTICS_PROP_3FINGER_UP_ACTION "Synaptics 3-Finger Up Action"
+#define SYNAPTICS_PROP_3FINGER_DOWN_ACTION "Synaptics 3-Finger Down Action"
+
 #endif /* _SYNAPTICS_PROPERTIES_H_ */
diff --git a/src/keymap.c b/src/keymap.c
index b1e7cc6..0c365a2 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -142,15 +142,30 @@ static int string_to_keysym(const char *str)
 }
 
 int SynapticsParseActionStr(LocalDevicePtr local, const char *_str,
-			    int *action, int max_actions)
+			    SynapticsAction *action)
 {
     char *item;
     char *str, *next;
-    int num_actions = 0;
 
-    str = xstrdup(_str);
+    if (action->str) {
+	if (_str && !strcmp(action->str, _str))
+	    return TRUE;
+	free(action->str);
+	action->str = NULL;
+    }
+
+    action->num_actions = 0;
+    if (!_str)
+	return TRUE;
+
+    str = strdup(_str);
     if (!str)
-	return 0;
+	return FALSE;
+    action->str = strdup(_str);
+    if (!action->str) {
+	free(str);
+	return FALSE;
+    }
     for (item = str; item && *item; item = next) {
 	int button, keysym, keycode;
 
@@ -160,7 +175,8 @@ int SynapticsParseActionStr(LocalDevicePtr local, const char *_str,
 	if (!*item)
 	    continue;
 	if (sscanf(item, "Button%d", &button) == 1) {
-	    action[num_actions++] = (ACTION_BUTTON << 16) | button;
+	    action->action[action->num_actions++] =
+		(ACTION_BUTTON << 16) | button;
 	} else {
 	    keysym = string_to_keysym(item);
 	    if (keysym == NoSymbol) {
@@ -175,15 +191,17 @@ int SynapticsParseActionStr(LocalDevicePtr local, const char *_str,
 		continue;
 	    }
 	    if (get_modifier(keysym))
-		action[num_actions++] = (ACTION_KEYMOD << 16) | keycode;
+		action->action[action->num_actions++] =
+		    (ACTION_KEYMOD << 16) | keycode;
 	    else
-		action[num_actions++] = (ACTION_KEY << 16) | keycode;
+		action->action[action->num_actions++] =
+		    (ACTION_KEY << 16) | keycode;
 	}
-	if (num_actions >= max_actions)
+	if (action->num_actions >= MAX_ACTIONS)
 	    break;
     }
     free(str);
-    return num_actions;
+    return TRUE;
 }
 
 static void
@@ -196,13 +214,13 @@ Bool SynapticsInitKeyboard(DeviceIntPtr dev)
     return InitKeyboardDeviceStruct(dev, NULL, NULL, synaptics_kbdctrl);
 }
 
-void SynapticsSendAction(LocalDevicePtr local, int num_actions, int *action)
+void SynapticsSendAction(LocalDevicePtr local, SynapticsAction *action)
 {
     int n;
 
-    for (n = 0; n < num_actions; n++) {
-	int val = action[n] & 0xffff;
-	switch ((action[n] >> 16) & 0xf) {
+    for (n = 0; n < action->num_actions; n++) {
+	int val = action->action[n] & 0xffff;
+	switch ((action->action[n] >> 16) & 0xf) {
 	case ACTION_KEYMOD:
 	    xf86PostKeyboardEvent(local->dev, val, TRUE);
 	    break;
@@ -216,12 +234,20 @@ void SynapticsSendAction(LocalDevicePtr local, int num_actions, int *action)
 	    break;
 	}
     }
-    for (n = num_actions - 1; n >= 0; n--) {
-	int val = action[n] & 0xffff;
-	switch ((action[n] >> 16) & 0xf) {
+    for (n = action->num_actions - 1; n >= 0; n--) {
+	int val = action->action[n] & 0xffff;
+	switch ((action->action[n] >> 16) & 0xf) {
 	case ACTION_KEYMOD:
 	    xf86PostKeyboardEvent(local->dev, val, FALSE);
 	    break;
 	}
     }
 }
+
+void SynapticsFreeAction(SynapticsAction *action)
+{
+    if (action && action->str) {
+	free(action->str);
+	action->str = NULL;
+    }
+}
diff --git a/src/properties.c b/src/properties.c
index 9977b28..e694189 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -92,6 +92,12 @@ Atom prop_multi_touch_pinch     = 0;
 Atom prop_gesture_mode_notify   = 0;
 Atom prop_gesture_mode          = 0;
 Atom prop_threefinger           = 0;
+Atom prop_zoom_in_action        = 0;
+Atom prop_zoom_out_action       = 0;
+Atom prop_3finger_left_action   = 0;
+Atom prop_3finger_right_action  = 0;
+Atom prop_3finger_up_action     = 0;
+Atom prop_3finger_down_action   = 0;
 
 static Atom
 InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values)
@@ -141,6 +147,38 @@ InitFloatAtom(DeviceIntPtr dev, char *name, int nvalues, float *values)
     return atom;
 }
 
+static Atom
+InitStringAtom(DeviceIntPtr dev, char *name, char *val)
+{
+    Atom atom;
+
+    if (!val)
+	val = "";
+    atom = MakeAtom(name, strlen(name), TRUE);
+    XIChangeDeviceProperty(dev, atom, XA_STRING, 8, PropModeReplace,
+                           strlen(val), (unsigned char *)val, FALSE);
+    XISetDevicePropertyDeletable(dev, atom, FALSE);
+    return atom;
+}
+
+static int
+SetActionStr(LocalDevicePtr local, XIPropertyValuePtr prop,
+	     SynapticsAction *action)
+{
+    if (prop->format != 8 || prop->type != XA_STRING)
+	return BadMatch;
+    if (prop->data && prop->size > 0) {
+	char *str = calloc(1, prop->size + 1);
+	if (!str)
+	    return BadAlloc;
+	memcpy(str, prop->data, prop->size);
+	SynapticsParseActionStr(local, str, action);
+	free(str);
+    } else
+	SynapticsParseActionStr(local, NULL, action);
+    return Success;
+}
+
 void
 InitDeviceProperties(InputInfoPtr pInfo)
 {
@@ -311,6 +349,13 @@ InitDeviceProperties(InputInfoPtr pInfo)
     values[0] =  para->threefinger_delta_horiz;
     values[1] =  para->threefinger_delta_vert;
     prop_threefinger = InitAtom(local->dev, SYNAPTICS_PROP_THREEFINGER_DELTA, 32, 2, values);
+
+    prop_zoom_in_action = InitStringAtom(local->dev, SYNAPTICS_PROP_ZOOM_IN_ACTION, priv->zoom_in_action.str);
+    prop_zoom_out_action = InitStringAtom(local->dev, SYNAPTICS_PROP_ZOOM_OUT_ACTION, priv->zoom_out_action.str);
+    prop_3finger_left_action = InitStringAtom(local->dev, SYNAPTICS_PROP_3FINGER_LEFT_ACTION, priv->threefinger_left_action.str);
+    prop_3finger_right_action = InitStringAtom(local->dev, SYNAPTICS_PROP_3FINGER_RIGHT_ACTION, priv->threefinger_right_action.str);
+    prop_3finger_up_action = InitStringAtom(local->dev, SYNAPTICS_PROP_3FINGER_UP_ACTION, priv->threefinger_up_action.str);
+    prop_3finger_down_action = InitStringAtom(local->dev, SYNAPTICS_PROP_3FINGER_DOWN_ACTION, priv->threefinger_down_action.str);
 }
 
 int
@@ -744,6 +789,24 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
         delta = (INT32*)prop->data;
 	para->threefinger_delta_horiz = delta[0];
 	para->threefinger_delta_vert = delta[1];
+    } else if (property == prop_zoom_in_action)
+    {
+	return SetActionStr(local, prop, &priv->zoom_in_action);
+    } else if (property == prop_zoom_out_action)
+    {
+	return SetActionStr(local, prop, &priv->zoom_out_action);
+    } else if (property == prop_3finger_left_action)
+    {
+	return SetActionStr(local, prop, &priv->threefinger_left_action);
+    } else if (property == prop_3finger_right_action)
+    {
+	return SetActionStr(local, prop, &priv->threefinger_right_action);
+    } else if (property == prop_3finger_up_action)
+    {
+	return SetActionStr(local, prop, &priv->threefinger_up_action);
+    } else if (property == prop_3finger_down_action)
+    {
+	return SetActionStr(local, prop, &priv->threefinger_down_action);
     }
 
     return Success;
diff --git a/src/synaptics.c b/src/synaptics.c
index 747bdb9..dfbc873 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -823,33 +823,41 @@ static void setup_zoom_actions(LocalDevicePtr local)
     action = xf86FindOptionValue(local->options, "ZoomInAction");
     if (!action)
 	action = "Control+Button4";
-    priv->zoom_in_num_actions =
-	SynapticsParseActionStr(local, action, priv->zoom_in_action, MAX_ACTIONS);
+    SynapticsParseActionStr(local, action, &priv->zoom_in_action);
     action = xf86FindOptionValue(local->options, "ZoomOutAction");
     if (!action)
 	action = "Control+Button5";
-    priv->zoom_out_num_actions =
-	SynapticsParseActionStr(local, action, priv->zoom_out_action, MAX_ACTIONS);
+    SynapticsParseActionStr(local, action, &priv->zoom_out_action);
     action = xf86FindOptionValue(local->options, "ThreeFingerLeftAction");
     if (!action)
 	action = "Alt+Left";
-    priv->threefinger_left_num_actions =
-	SynapticsParseActionStr(local, action, priv->threefinger_left_action, MAX_ACTIONS);
+    SynapticsParseActionStr(local, action, &priv->threefinger_left_action);
     action = xf86FindOptionValue(local->options, "ThreeFingerRightAction");
     if (!action)
 	action = "Alt+Right";
-    priv->threefinger_right_num_actions =
-	SynapticsParseActionStr(local, action, priv->threefinger_right_action, MAX_ACTIONS);
+    SynapticsParseActionStr(local, action, &priv->threefinger_right_action);
     action = xf86FindOptionValue(local->options, "ThreeFingerUpAction");
     if (!action)
 	action = "Control+Tab";
-    priv->threefinger_up_num_actions =
-	SynapticsParseActionStr(local, action, priv->threefinger_up_action, MAX_ACTIONS);
+    SynapticsParseActionStr(local, action, &priv->threefinger_up_action);
     action = xf86FindOptionValue(local->options, "ThreeFingerDownAction");
     if (!action)
 	action = "Control+Shift+Tab";
-    priv->threefinger_down_num_actions =
-	SynapticsParseActionStr(local, action, priv->threefinger_down_action, MAX_ACTIONS);
+    SynapticsParseActionStr(local, action, &priv->threefinger_down_action);
+}
+
+static void free_zoom_actions(LocalDevicePtr local)
+{
+    SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+
+    if (!priv)
+	return;
+    SynapticsFreeAction(&priv->zoom_in_action);
+    SynapticsFreeAction(&priv->zoom_out_action);
+    SynapticsFreeAction(&priv->threefinger_left_action);
+    SynapticsFreeAction(&priv->threefinger_right_action);
+    SynapticsFreeAction(&priv->threefinger_up_action);
+    SynapticsFreeAction(&priv->threefinger_down_action);
 }
 
 /*
@@ -860,6 +868,7 @@ static void SynapticsUnInit(InputDriverPtr drv,
                             int            flags)
 {
     SynapticsPrivate *priv = ((SynapticsPrivate *)pInfo->private);
+    free_zoom_actions(local);
     if (priv && priv->timer)
         free(priv->timer);
     if (priv && priv->proto_data)
@@ -2615,18 +2624,14 @@ static void send_threefinger_event(LocalDevicePtr local, int xd, int yd)
     SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
 
     if (xd < 0) {
-	SynapticsSendAction(local, priv->threefinger_left_num_actions,
-			    priv->threefinger_left_action);
+	SynapticsSendAction(local, &priv->threefinger_left_action);
     } else if (xd > 0) {
-	SynapticsSendAction(local, priv->threefinger_right_num_actions,
-			    priv->threefinger_right_action);
+	SynapticsSendAction(local, &priv->threefinger_right_action);
     }
     if (yd < 0) {
-	SynapticsSendAction(local, priv->threefinger_up_num_actions,
-			    priv->threefinger_up_action);
+	SynapticsSendAction(local, &priv->threefinger_up_action);
     } else if (yd > 0) {
-	SynapticsSendAction(local, priv->threefinger_down_num_actions,
-			    priv->threefinger_down_action);
+	SynapticsSendAction(local, &priv->threefinger_down_action);
     }
 }
 
@@ -2772,20 +2777,13 @@ static void send_zoom_event(LocalDevicePtr local, int zoom_in, int zoom_out)
 {
     SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
     int dir = zoom_out - zoom_in;
-    int num_actions;
-    int *action;
 
     if (!dir)
 	return;
-    if (dir < 0) {
-	num_actions = priv->zoom_in_num_actions;
-	action = priv->zoom_in_action;
-    } else {
-	num_actions = priv->zoom_out_num_actions;
-	action = priv->zoom_out_action;
-    }
-
-    SynapticsSendAction(local, num_actions, action);
+    if (dir < 0)
+	SynapticsSendAction(local, &priv->zoom_in_action);
+    else
+	SynapticsSendAction(local, &priv->zoom_out_action);
 }
 
 #define SWAP(a, b) do { int _tmp = (a); (a) = (b); (b) = _tmp; } while (0)
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 440521a..1e5f486 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -196,6 +196,11 @@ enum GestureMode {
 
 #define MAX_ACTIONS	4
 enum { ACTION_BUTTON = 1, ACTION_KEY, ACTION_KEYMOD };
+typedef struct _SynapticsActionRec {
+    int num_actions;
+    int action[MAX_ACTIONS];
+    char *str;
+} SynapticsAction;
 
 typedef struct _SynapticsPrivateRec
 {
@@ -288,22 +293,16 @@ typedef struct _SynapticsPrivateRec
 
     enum GestureMode gesture_mode;
 
-    int zoom_in_num_actions;
-    int zoom_in_action[MAX_ACTIONS];
-    int zoom_out_num_actions;
-    int zoom_out_action[MAX_ACTIONS];
+    SynapticsAction zoom_in_action;
+    SynapticsAction zoom_out_action;
 
     enum TouchpadModel model;          /* The detected model */
 
     int threefinger_x, threefinger_y;
-    int threefinger_left_num_actions;
-    int threefinger_left_action[MAX_ACTIONS];
-    int threefinger_right_num_actions;
-    int threefinger_right_action[MAX_ACTIONS];
-    int threefinger_up_num_actions;
-    int threefinger_up_action[MAX_ACTIONS];
-    int threefinger_down_num_actions;
-    int threefinger_down_action[MAX_ACTIONS];
+    SynapticsAction threefinger_left_action;
+    SynapticsAction threefinger_right_action;
+    SynapticsAction threefinger_up_action;
+    SynapticsAction threefinger_down_action;
 
 } SynapticsPrivate;
 
@@ -313,7 +312,8 @@ extern void SynapticsDefaultDimensions(InputInfoPtr pInfo);
 /* keymap.c */
 Bool SynapticsInitKeyboard(DeviceIntPtr dev);
 int SynapticsParseActionStr(LocalDevicePtr local, const char *_str,
-			    int *action, int max_actions);
-void SynapticsSendAction(LocalDevicePtr local, int num_actions, int *action);
+			    SynapticsAction *action);
+void SynapticsSendAction(LocalDevicePtr local, SynapticsAction *action);
+void SynapticsFreeAction(SynapticsAction *action);
 
 #endif /* _SYNAPTICSSTR_H_ */
diff --git a/tools/synclient.c b/tools/synclient.c
index 247d65d..b4b58fe 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -60,7 +60,8 @@ union flong { /* Xlibs 64-bit property handling madness */
 enum ParaType {
     PT_INT,
     PT_BOOL,
-    PT_DOUBLE
+    PT_DOUBLE,
+    PT_STR
 };
 
 struct Parameter {
@@ -153,11 +154,17 @@ static struct Parameter params[] = {
     {"GestureModeNotify",     PT_BOOL,   0, 1,     SYNAPTICS_PROP_GESTURE_MODE_NOTIFY,	8,	0},
     {"HorizThreeFingerDelta", PT_INT,    0, 4000,  SYNAPTICS_PROP_THREEFINGER_DELTA,	32,	0},
     {"VertThreeFingerDelta",  PT_INT,    0, 4000,  SYNAPTICS_PROP_THREEFINGER_DELTA,	32,	1},
+    {"ZoomInAction",          PT_STR,    0, 0,     SYNAPTICS_PROP_ZOOM_IN_ACTION,	8,	0},
+    {"ZoomOutAction",         PT_STR,    0, 0,     SYNAPTICS_PROP_ZOOM_OUT_ACTION,	8,	0},
+    {"ThreeFingerLeftAction", PT_STR,    0, 0,     SYNAPTICS_PROP_3FINGER_LEFT_ACTION,	8,	0},
+    {"ThreeFingerRightAction", PT_STR,   0, 0,     SYNAPTICS_PROP_3FINGER_RIGHT_ACTION,	8,	0},
+    {"ThreeFingerUpAction",   PT_STR,    0, 0,     SYNAPTICS_PROP_3FINGER_UP_ACTION,	8,	0},
+    {"ThreeFingerDownAction", PT_STR,    0, 0,     SYNAPTICS_PROP_3FINGER_DOWN_ACTION,	8,	0},
     { NULL, 0, 0, 0, 0 }
 };
 
 static double
-parse_cmd(char* cmd, struct Parameter** par)
+parse_cmd(char* cmd, struct Parameter** par, char **strvalp)
 {
     char *eqp = index(cmd, '=');
     *par = NULL;
@@ -173,8 +180,14 @@ parse_cmd(char* cmd, struct Parameter** par)
 	    }
 	}
 	if (found) {
-	    double val = atof(&eqp[1]);
+	    double val;
+
 	    *par = &params[j];
+	    if ((*par)->type == PT_STR) {
+		*strvalp = eqp + 1;
+		return 0;
+	    }
+	    val = atof(&eqp[1]);
 
 	    if (val < (*par)->min_val)
 		val = (*par)->min_val;
@@ -429,7 +442,8 @@ dp_set_variables(Display *dpy, XDevice* dev, int argc, char *argv[], int first_c
 	fprintf(stderr, "Float properties not available.\n");
 
     for (i = first_cmd; i < argc; i++) {
-	val = parse_cmd(argv[i], &par);
+	char *strval = NULL;
+	val = parse_cmd(argv[i], &par, &strval);
 	if (!par)
 	    continue;
 
@@ -445,6 +459,20 @@ dp_set_variables(Display *dpy, XDevice* dev, int argc, char *argv[], int first_c
 	XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, AnyPropertyType,
 				&type, &format, &nitems, &bytes_after, &data);
 
+	if (par->type == PT_STR) {
+	    if (format != 8 || type != XA_STRING)
+		fprintf(stderr, "   %-23s = invalid string property\n",
+			par->name);
+	    else {
+		XChangeDeviceProperty(dpy, dev, prop, type, format,
+				      PropModeReplace,
+				      (unsigned char *)strval, strlen(strval));
+		XFlush(dpy);
+	    }
+	    XFree(data);
+	    continue;
+	}
+
 	switch(par->prop_format)
 	{
 	    case 8:
@@ -510,6 +538,19 @@ dp_show_settings(Display *dpy, XDevice *dev)
 	if (!a)
 	    continue;
 
+	if (par->type == PT_STR) {
+	    XGetDeviceProperty(dpy, dev, a, 0, 1000, False,
+			       AnyPropertyType, &type, &format,
+			       &nitems, &bytes_after, &data);
+	    if (format != 8 || type != XA_STRING)
+		fprintf(stderr, "   %-23s = invalid string property\n",
+			par->name);
+	    else
+		printf("    %-23s = %s\n", par->name, data ? (char*)data : "");
+	    XFree(data);
+	    continue;
+	}
+
 	len = 1 + ((par->prop_offset * (par->prop_format ? par->prop_format : 32)/8))/4;
 
 	XGetDeviceProperty(dpy, dev, a, 0, len, False,
-- 
1.7.3.1



More information about the xorg-devel mailing list