Signed-off-by: Takashi Iwai <[email protected]>
---
 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

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to