Want more features on Pastebin? Sign Up, it's FREE!
Guest

xf86-input-synaptics-clickpad-led-1.4.0.patch

By: a guest on Mar 19th, 2011  |  syntax: Diff  |  size: 19.79 KB  |  views: 1,360  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. diff -uprN a/include/synaptics-properties.h b/include/synaptics-properties.h
  2. --- a/include/synaptics-properties.h    2011-02-20 20:46:37.000000000 -0500
  3. +++ b/include/synaptics-properties.h    2011-03-19 18:07:43.268845823 -0400
  4. @@ -155,6 +155,15 @@
  5.  /* 32 bit, 4 values, left, right, top, bottom */
  6.  #define SYNAPTICS_PROP_AREA "Synaptics Area"
  7.  
  8. +/* 8 bit (BOOL, read-only), has_led */
  9. +#define SYNAPTICS_PROP_LED "Synaptics LED"
  10. +
  11. +/* 8 bit (BOOL), led_status (on/off) */
  12. +#define SYNAPTICS_PROP_LED_STATUS "Synaptics LED Status"
  13. +
  14. +/* 8 bit (BOOL), double-tap action on LED corner (on/off) */
  15. +#define SYNAPTICS_PROP_LED_DOUBLE_TAP "Synaptics LED Dobule Tap"
  16. +
  17.  /* 32 Bit Integer, 2 values, horizontal hysteresis, vertical hysteresis */
  18.  #define SYNAPTICS_PROP_NOISE_CANCELLATION "Synaptics Noise Cancellation"
  19.  
  20. diff -uprN a/man/synaptics.man b/man/synaptics.man
  21. --- a/man/synaptics.man 2011-02-20 20:50:51.000000000 -0500
  22. +++ b/man/synaptics.man 2011-03-19 18:07:43.269845760 -0400
  23. @@ -564,6 +564,19 @@ coordinates are less than MaxTapMove uni
  24.  A "touch" event happens when the Z value goes above FingerHigh, and an
  25.  "untouch" event happens when the Z value goes below FingerLow.
  26.  .
  27. +.TP
  28. +.BI "Option \*qLEDDoubleTap\*q \*q" boolean \*q
  29. +.
  30. +Enables/disables the touchpad-control by double-tapping on the top-left
  31. +corner LED.
  32. +.
  33. +Some devices have an LED on the top-left corner to indicate the
  34. +touchpad state.  User can double-tap on the LED to toggle the touchpad
  35. +state.  This option controls whether this action is enabled or not.
  36. +The double-tap size is same as specified in MaxDoubleTapTime.
  37. +The default value is ON.
  38. +Property: "Synaptics LED Double Tap"
  39. +.
  40.  .LP
  41.  The MaxDoubleTapTime parameter has the same function as the MaxTapTime
  42.  parameter, but for the second, third, etc tap in a tap sequence.
  43. @@ -753,6 +766,15 @@ and finger movement distance.
  44.  Trackstick mode is exited when the finger pressure drops below
  45.  FingerLow or when the finger is moved further than MaxTapMove away
  46.  from the initial position.
  47. +.
  48. +When the input device reports a device with a single left button
  49. +and without multi-fingers, the driver assumes it's a Synaptics
  50. +Clickpad device and handles it in ClickZone mode.  In this mode,
  51. +a left/right/middle button event is generated according to the
  52. +position you click.  When Clickpad is enabled, the touchpad area
  53. +is shrunk as default in 20% and the bottom area is used as the
  54. +click-button area.  The area can be configurable via options or
  55. +properties below.
  56.  
  57.  .SH "DEVICE PROPERTIES"
  58.  Synaptics 1.0 and higher support input device properties if the driver is
  59. @@ -927,6 +949,19 @@ right button, two-finger detection, thre
  60.  .BI "Synaptics Pad Resolution"
  61.  32 bit unsigned, 2 values (read-only), vertical, horizontal in units/millimeter.
  62.  
  63. +.TP 7
  64. +.BI "Synaptics LED"
  65. +8 bit (BOOL, read-only), indicating whether the device has an embedded
  66. +LED support or not.
  67. +
  68. +.TP 7
  69. +.BI "Synaptics LED Status"
  70. +8 bit (BOOL), the light status of the embedded LED.
  71. +
  72. +.TP 7
  73. +.BI "Synaptics LED Double Tap"
  74. +8 bit (BOOL), enable/disable the double-tap on LED.
  75. +
  76.  .SH "NOTES"
  77.  There is an example hal policy file in
  78.  .I ${sourcecode}/fdi/11-x11-synaptics.fdi
  79. diff -uprN a/src/eventcomm.c b/src/eventcomm.c
  80. --- a/src/eventcomm.c   2011-03-03 21:35:56.000000000 -0500
  81. +++ b/src/eventcomm.c   2011-03-19 18:07:39.623954123 -0400
  82. @@ -51,6 +51,8 @@
  83.  #define LONG(x)  ((x) / LONG_BITS)
  84.  #define TEST_BIT(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
  85.  
  86. +#define SYNAPTICS_LED_SYS_FILE "/sys/class/leds/psmouse::synaptics/brightness"
  87. +
  88.  /*****************************************************************************
  89.   *     Function Definitions
  90.   ****************************************************************************/
  91. @@ -166,6 +168,32 @@ event_query_info(InputInfoPtr pInfo)
  92.      }
  93.  }
  94.  
  95. +static void
  96. +event_query_led(InputInfoPtr pInfo)
  97. +{
  98. +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
  99. +
  100. +    priv->synpara.has_led = !access(SYNAPTICS_LED_SYS_FILE, W_OK);
  101. +}
  102. +
  103. +static void EventUpdateLED(InputInfoPtr pInfo)
  104. +{
  105. +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
  106. +
  107. +    if (priv->synpara.has_led) {
  108. +        char *val = priv->synpara.led_status ? "255" : "0";
  109. +        int fd = open(SYNAPTICS_LED_SYS_FILE, O_WRONLY);
  110. +        int err;
  111. +
  112. +        if (fd < 0)
  113. +            return;
  114. +        err = write(fd, val, strlen(val));
  115. +        close(fd);
  116. +        if (err < 0)
  117. +           xf86Msg(X_WARNING, "%s can't write LED value %s\n", pInfo->name, val);
  118. +    }
  119. +}
  120. +
  121.  /* Query device for axis ranges */
  122.  static void
  123.  event_query_axis_ranges(InputInfoPtr pInfo)
  124. @@ -266,6 +294,13 @@ event_query_axis_ranges(InputInfoPtr pIn
  125.            strcat(buf, " double");
  126.         if ((priv->has_triple = (TEST_BIT(BTN_TOOL_TRIPLETAP, keybits) != 0)))
  127.            strcat(buf, " triple");
  128. +      
  129. +       /* clickpad device reports only the single left button mask */
  130. +       if (priv->has_left && !priv->has_right && !priv->has_middle) {
  131. +           priv->is_clickpad = TRUE;
  132. +           xf86Msg(X_INFO, "%s: is Clickpad device\n", pInfo->name);
  133. +  }
  134. +
  135.  
  136.         if ((TEST_BIT(BTN_0, keybits) != 0) ||
  137.             (TEST_BIT(BTN_1, keybits) != 0) ||
  138. @@ -436,6 +471,7 @@ EventReadDevDimensions(InputInfoPtr pInf
  139.      if (event_query_is_touchpad(pInfo->fd, (need_grab) ? *need_grab : TRUE))
  140.         event_query_axis_ranges(pInfo);
  141.      event_query_info(pInfo);
  142. +    event_query_led(pInfo);
  143.  }
  144.  
  145.  static Bool
  146. @@ -495,5 +531,6 @@ struct SynapticsProtocolOperations event
  147.      EventQueryHardware,
  148.      EventReadHwState,
  149.      EventAutoDevProbe,
  150. -    EventReadDevDimensions
  151. +    EventReadDevDimensions,
  152. +    EventUpdateLED,
  153.  };
  154. diff -uprN a/src/properties.c b/src/properties.c
  155. --- a/src/properties.c  2011-02-20 20:46:37.000000000 -0500
  156. +++ b/src/properties.c  2011-03-19 18:07:43.271845640 -0400
  157. @@ -82,6 +82,9 @@ Atom prop_gestures              = 0;
  158.  Atom prop_capabilities          = 0;
  159.  Atom prop_resolution            = 0;
  160.  Atom prop_area                  = 0;
  161. +Atom prop_led                   = 0;
  162. +Atom prop_led_status            = 0;
  163. +Atom prop_led_double_tap        = 0;
  164.  Atom prop_noise_cancellation    = 0;
  165.  
  166.  static Atom
  167. @@ -280,6 +283,11 @@ InitDeviceProperties(InputInfoPtr pInfo)
  168.      values[3] = para->area_bottom_edge;
  169.      prop_area = InitAtom(pInfo->dev, SYNAPTICS_PROP_AREA, 32, 4, values);
  170.  
  171. +    prop_led = InitAtom(pInfo->dev, SYNAPTICS_PROP_LED, 8, 1, &para->has_led);
  172. +    prop_led_status = InitAtom(pInfo->dev, SYNAPTICS_PROP_LED_STATUS, 8, 1, &para->led_status);
  173. +    prop_led_double_tap = InitAtom(pInfo->dev, SYNAPTICS_PROP_LED_DOUBLE_TAP, 8, 1, &para->led_double_tap);
  174. +
  175. +
  176.      values[0] = para->hyst_x;
  177.      values[1] = para->hyst_y;
  178.      prop_noise_cancellation = InitAtom(pInfo->dev,
  179. @@ -510,6 +518,19 @@ SetProperty(DeviceIntPtr dev, Atom prope
  180.              return BadValue;
  181.  
  182.          para->touchpad_off = off;
  183. +        if (!checkonly && para->has_led &&
  184. +           para->led_status != para->touchpad_off) {
  185. +            para->led_status = para->touchpad_off;
  186. +            if (priv->proto_ops && priv->proto_ops->UpdateLED)
  187. +                priv->proto_ops->UpdateLED(pInfo);
  188. +        }
  189. +    } else if (property == prop_led_double_tap)
  190. +    {
  191. +        if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
  192. +            return BadMatch;
  193. +
  194. +        para->led_double_tap = *(CARD8*)prop->data;
  195. +
  196.      } else if (property == prop_gestures)
  197.      {
  198.          BOOL *gestures;
  199. @@ -656,6 +677,16 @@ SetProperty(DeviceIntPtr dev, Atom prope
  200.          para->area_right_edge  = area[1];
  201.          para->area_top_edge    = area[2];
  202.          para->area_bottom_edge = area[3];
  203. +    } else if (property == prop_led_status)
  204. +    {
  205. +        if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
  206. +            return BadMatch;
  207. +
  208. +        if (para->has_led) {
  209. +            para->led_status = *(BOOL*)prop->data;
  210. +            if (priv->proto_ops && priv->proto_ops->UpdateLED)
  211. +                priv->proto_ops->UpdateLED(pInfo);
  212. +        }
  213.      } else if (property == prop_noise_cancellation) {
  214.          INT32 *hyst;
  215.          if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER)
  216. @@ -671,3 +702,13 @@ SetProperty(DeviceIntPtr dev, Atom prope
  217.      return Success;
  218.  }
  219.  
  220. +void SynapticsToggleOffProperty(DeviceIntPtr dev, Bool off)
  221. +{
  222. +        uint8_t val;
  223. +
  224. +        if (!prop_off)
  225. +                return;
  226. +        val = off;
  227. +        XIChangeDeviceProperty(dev, prop_off, XA_INTEGER, 8,
  228. +                               PropModeReplace, 1, &val, FALSE);
  229. +}
  230. diff -uprN a/src/synaptics.c b/src/synaptics.c
  231. --- a/src/synaptics.c   2011-03-03 21:36:15.000000000 -0500
  232. +++ b/src/synaptics.c   2011-03-19 18:07:43.273845526 -0400
  233. @@ -134,6 +134,7 @@ static void CalculateScalingCoeffs(Synap
  234.  void InitDeviceProperties(InputInfoPtr pInfo);
  235.  int SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
  236.                  BOOL checkonly);
  237. +void SynapticsToggleOffProperty(DeviceIntPtr dev, Bool off);
  238.  
  239.  InputDriverRec SYNAPTICS = {
  240.      1,
  241. @@ -513,6 +514,18 @@ static void set_default_parameters(Input
  242.          vertResolution = priv->resy;
  243.      }
  244.  
  245. +    /* Clickpad mode -- bottom area is used as buttons */
  246. +    if (priv->is_clickpad) {
  247. +       int button_bottom;
  248. +       /* Clickpad devices usually the button area at the bottom, and
  249. +        * its size seems ca. 20% of the touchpad height no matter how
  250. +        * large the pad is.
  251. +        */
  252. +       button_bottom = priv->maxy - (abs(priv->maxy - priv->miny) * 20) / 100;
  253. +       if (button_bottom < b && button_bottom >= t)
  254. +           b = button_bottom;
  255. +    }
  256. +
  257.      /* set the parameters */
  258.      pars->left_edge = xf86SetIntOption(opts, "LeftEdge", l);
  259.      pars->right_edge = xf86SetIntOption(opts, "RightEdge", r);
  260. @@ -593,6 +606,7 @@ static void set_default_parameters(Input
  261.      pars->tap_and_drag_gesture = xf86SetBoolOption(opts, "TapAndDragGesture", TRUE);
  262.      pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", horizResolution);
  263.      pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", vertResolution);
  264. +    pars->led_double_tap = xf86SetBoolOption(opts, "LEDDoubleTap", TRUE);
  265.  
  266.      /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
  267.      if (pars->top_edge > pars->bottom_edge) {
  268. @@ -876,6 +890,10 @@ DeviceOn(DeviceIntPtr dev)
  269.      xf86AddEnabledDevice(pInfo);
  270.      dev->public.on = TRUE;
  271.  
  272. +    /* update LED */
  273. +    if (priv->proto_ops && priv->proto_ops->UpdateLED)
  274. +        priv->proto_ops->UpdateLED(pInfo);
  275. +
  276.      return Success;
  277.  }
  278.  
  279. @@ -1213,6 +1231,7 @@ timerFunc(OsTimerPtr timer, CARD32 now,
  280.  {
  281.      InputInfoPtr pInfo = arg;
  282.      SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
  283. +    SynapticsParameters *para = &priv->synpara;
  284.      struct SynapticsHwState hw;
  285.      int delay;
  286.      int sigstate;
  287. @@ -1224,6 +1243,13 @@ timerFunc(OsTimerPtr timer, CARD32 now,
  288.      hw.millis = now;
  289.      delay = HandleState(pInfo, &hw);
  290.  
  291. +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
  292. +    if (priv->prop_change_pending & 1) {
  293. +       SynapticsToggleOffProperty(pInfo->dev, para->touchpad_off);
  294. +       priv->prop_change_pending = 0;
  295. +    }
  296. +#endif
  297. +
  298.      /*
  299.       * Workaround for wraparound bug in the TimerSet function. This bug is already
  300.       * fixed in CVS, but this driver needs to work with XFree86 versions 4.2.x and
  301. @@ -1274,6 +1300,10 @@ ReadInput(InputInfoPtr pInfo)
  302.         hw.millis = GetTimeInMillis();
  303.         priv->hwState = hw;
  304.         delay = HandleState(pInfo, &hw);
  305. +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
  306. +       if (priv->prop_change_pending)
  307. +           delay = MIN(10, delay);
  308. +#endif
  309.         newDelay = TRUE;
  310.      }
  311.  
  312. @@ -2241,6 +2271,125 @@ handle_clickfinger(SynapticsParameters *
  313.      }
  314.  }
  315.  
  316. +#define LED_TOGGLE_X_AREA      0.10
  317. +#define LED_TOGGLE_Y_AREA      0.08
  318. +
  319. +static int
  320. +in_led_toggle_area(InputInfoPtr pInfo, struct SynapticsHwState *hw)
  321. +{
  322. +    SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
  323. +    int click_led_x, click_led_y;
  324. +
  325. +    click_led_x = (priv->maxx - priv->minx) * LED_TOGGLE_X_AREA + priv->minx;
  326. +    click_led_y = (priv->maxy - priv->miny) * LED_TOGGLE_Y_AREA + priv->miny;
  327. +    return (hw->x < click_led_x && hw->y < click_led_y);
  328. +}
  329. +
  330. +/* clicpad button toggle point:
  331. + * some devices have a LED at the upper-left corner, and double-tapping it
  332. + * toggles the touchpad enable/disable
  333. + */
  334. +static int
  335. +handle_toggle_led(InputInfoPtr pInfo, struct SynapticsHwState *hw, int finger)
  336. +{
  337. +    SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
  338. +    SynapticsParameters *para = &priv->synpara;
  339. +    int diff;
  340. +
  341. +    if (finger) {
  342. +        if (!in_led_toggle_area(pInfo, hw)) {
  343. +            /* outside the toggle area */
  344. +            priv->led_touch_state = FALSE;
  345. +            priv->led_tapped = FALSE;
  346. +            return finger;
  347. +        }
  348. +        if (!priv->led_touch_state) {
  349. +            /* touch start */
  350. +            priv->led_touch_millis = hw->millis;
  351. +            priv->led_touch_state = TRUE;
  352. +        }
  353. +        return 0; /* already processed; ignore this finger event */
  354. +    }
  355. +
  356. +    if (!priv->led_touch_state)
  357. +        return finger; /* nothing happened */
  358. +
  359. +    /* touch-released */
  360. +    priv->led_touch_state = FALSE;
  361. +    diff = TIME_DIFF(priv->led_touch_millis + para->tap_time, hw->millis);
  362. +    if (diff < 0) { /* non-tap? */
  363. +       priv->led_tapped = FALSE;
  364. +        return finger;
  365. +    }
  366. +    if (priv->led_tapped) {
  367. +        /* double-tapped? */
  368. +        diff = TIME_DIFF(priv->led_tap_millis + para->tap_time_2, hw->millis);
  369. +        if (diff >= 0) {
  370. +            para->touchpad_off = !para->touchpad_off;
  371. +            if (priv->proto_ops && priv->proto_ops->UpdateLED)
  372. +                priv->proto_ops->UpdateLED(pInfo);
  373. +           priv->prop_change_pending = 1;
  374. +            priv->led_tapped = FALSE;
  375. +        }
  376. +    } else
  377. +        priv->led_tapped = TRUE;
  378. +    priv->led_tap_millis = hw->millis;
  379. +    return 0; /* already processed; ignore this finger event */
  380. +}
  381. +
  382. +/* clickpad event handling */
  383. +static void
  384. +handle_clickpad(InputInfoPtr pInfo, struct SynapticsHwState *hw, edge_type edge)
  385. +{
  386. +    SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
  387. +    SynapticsParameters *para = &priv->synpara;
  388. +
  389. +    if (edge & BOTTOM_EDGE) {
  390. +       /* button area */
  391. +       int width = priv->maxx - priv->minx;
  392. +       int left_button_x, right_button_x;
  393. +
  394. +       /* left and right clickpad button ranges;
  395. +        * the gap between them is interpreted as a middle-button click
  396. +        */
  397. +       left_button_x = width * 2/ 5 + priv->minx;
  398. +       right_button_x = width * 3 / 5 + priv->minx;
  399. +
  400. +       /* clickpad reports only one button, and we need
  401. +        * to fake left/right buttons depending on the touch position
  402. +        */
  403. +       if (hw->left) { /* clicked? */
  404. +           hw->left = 0;
  405. +           if (hw->x < left_button_x)
  406. +               hw->left = 1;
  407. +           else if (hw->x > right_button_x)
  408. +               hw->right = 1;
  409. +           else
  410. +               hw->middle = 1;
  411. +       }
  412. +
  413. +       /* Don't move pointer position in the button area during clicked,
  414. +        * except for horiz/vert scrolling is enabled.
  415. +        *
  416. +        * The synaptics driver tends to be pretty sensitive.  This hack
  417. +        * is to avoid that the pointer moves slightly and misses the
  418. +        * poistion you aimed to click.
  419. +        *
  420. +        * Also, when the pointer movement is reported, the dragging
  421. +        * (with a sort of multi-touching) doesn't work well, too.
  422. +        */
  423. +       if (hw->left || !(para->scroll_edge_horiz ||
  424. +                         ((edge & RIGHT_EDGE) && para->scroll_edge_vert)))
  425. +           hw->z = 0; /* don't move pointer */
  426. +
  427. +    } else if (hw->left) {
  428. +       /* dragging */
  429. +       hw->left = priv->prev_hw.left;
  430. +       hw->right = priv->prev_hw.right;
  431. +       hw->middle = priv->prev_hw.middle;
  432. +    }
  433. +    priv->prev_hw = *hw;
  434. +}
  435.  
  436.  /* Update the hardware state in shared memory. This is read-only these days,
  437.   * nothing in the driver reads back from SHM. SHM configuration is a thing of the past.
  438. @@ -2314,6 +2463,12 @@ update_hw_button_state(const InputInfoPt
  439.      SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
  440.      SynapticsParameters *para = &priv->synpara;
  441.  
  442. +    edge_type edge = edge_detection(priv, hw->x, hw->y);
  443. +
  444. +    /* Clickpad handling for button area */
  445. +    if (para->touchpad_off != 1 && priv->is_clickpad)
  446. +       handle_clickpad(pInfo, hw, edge);
  447. +
  448.      /* Treat the first two multi buttons as up/down for now. */
  449.      hw->up |= hw->multi[0];
  450.      hw->down |= hw->multi[1];
  451. @@ -2429,7 +2584,7 @@ HandleState(InputInfoPtr pInfo, struct S
  452.      update_shm(pInfo, hw);
  453.  
  454.      /* If touchpad is switched off, we skip the whole thing and return delay */
  455. -    if (para->touchpad_off == 1)
  456. +    if (para->touchpad_off == 1 && !(para->has_led && para->led_double_tap))
  457.         return delay;
  458.  
  459.      /* apply hysteresis before doing anything serious. This cancels
  460. @@ -2473,6 +2628,15 @@ HandleState(InputInfoPtr pInfo, struct S
  461.         finger = SynapticsDetectFinger(priv, hw);
  462.      }
  463.  
  464. +    if (para->has_led && para->led_double_tap) {
  465. +       if (inside_active_area)
  466. +               finger = handle_toggle_led(pInfo, hw, finger);
  467. +        if (para->touchpad_off == 1) {
  468. +            priv->finger_state = finger;
  469. +            return delay;
  470. +        }
  471. +    }
  472. +
  473.      /* tap and drag detection. Needs to be performed even if the finger is in
  474.       * the dead area to reset the state. */
  475.      timeleft = HandleTapProcessing(priv, hw, finger, inside_active_area);
  476. diff -uprN a/src/synapticsstr.h b/src/synapticsstr.h
  477. --- a/src/synapticsstr.h        2011-03-03 21:35:56.000000000 -0500
  478. +++ b/src/synapticsstr.h        2011-03-19 18:07:43.276845370 -0400
  479. @@ -160,6 +160,9 @@ typedef struct _SynapticsParameters
  480.      unsigned int resolution_horiz;          /* horizontal resolution of touchpad in units/mm */
  481.      unsigned int resolution_vert;           /* vertical resolution of touchpad in units/mm */
  482.      int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
  483. +    Bool has_led;                           /* has an embedded LED */
  484. +    Bool led_status;                        /* Current status of LED (1=on) */
  485. +    Bool led_double_tap;                   /* double-tap period in ms for touchpad LED control */
  486.      int hyst_x, hyst_y;                     /* x and y width of hysteresis box */
  487.  } SynapticsParameters;
  488.  
  489. @@ -239,6 +242,14 @@ typedef struct _SynapticsPrivateRec
  490.      Bool has_pressure;                 /* device reports pressure */
  491.      Bool has_width;                    /* device reports finger width */
  492.      Bool has_scrollbuttons;            /* device has physical scrollbuttons */
  493. +    Bool is_clickpad;                  /* is Clickpad device (one-button) */
  494. +    struct SynapticsHwState prev_hw;   /* previous h/w state (for clickpad) */
  495. +    int prop_change_pending;
  496. +    Bool led_touch_state;
  497. +    Bool led_tapped;
  498. +    int led_touch_millis;
  499. +    int led_tap_millis;
  500. +
  501.  
  502.      enum TouchpadModel model;          /* The detected model */
  503.  } SynapticsPrivate;
  504. diff -uprN a/src/synproto.h b/src/synproto.h
  505. --- a/src/synproto.h    2011-03-03 21:35:56.000000000 -0500
  506. +++ b/src/synproto.h    2011-03-19 18:07:39.626953966 -0400
  507. @@ -91,6 +91,7 @@ struct SynapticsProtocolOperations {
  508.                         struct CommData *comm, struct SynapticsHwState *hwRet);
  509.      Bool (*AutoDevProbe)(InputInfoPtr pInfo);
  510.      void (*ReadDevDimensions)(InputInfoPtr pInfo);
  511. +    void (*UpdateLED)(InputInfoPtr pInfo);
  512.  };
  513.  
  514.  extern struct SynapticsProtocolOperations psaux_proto_operations;
  515. diff -uprN a/tools/synclient.c b/tools/synclient.c
  516. --- a/tools/synclient.c 2011-02-16 19:59:16.000000000 -0500
  517. +++ b/tools/synclient.c 2011-03-19 18:07:43.277845322 -0400
  518. @@ -143,6 +143,8 @@ static struct Parameter params[] = {
  519.      {"AreaRightEdge",         PT_INT,    0, 10000, SYNAPTICS_PROP_AREA,        32,     1},
  520.      {"AreaTopEdge",           PT_INT,    0, 10000, SYNAPTICS_PROP_AREA,        32,     2},
  521.      {"AreaBottomEdge",        PT_INT,    0, 10000, SYNAPTICS_PROP_AREA,        32,     3},
  522. +    {"LEDStatus",             PT_BOOL,   0, 1,     SYNAPTICS_PROP_LED_STATUS,  8,      0},
  523. +    {"LEDDoubleTap",          PT_BOOL,   0, 1,     SYNAPTICS_PROP_LED_DOUBLE_TAP,      8,      0},
  524.      { NULL, 0, 0, 0, 0 }
  525.  };
clone this paste RAW Paste Data