From c555a3f96836d0be562894a54e9e100b1897cfbf Mon Sep 17 00:00:00 2001 From: Felipe Date: Thu, 30 Jan 2014 13:43:54 -0300 Subject: [PATCH] Put SynapticsSHM back into the driver to be able to use synclient -m once again Merged and solved all conflicts --- include/Makefile.am | 2 +- src/alpscomm.c | 1 + src/eventcomm.c | 1 + src/properties.c | 1 + src/ps2comm.c | 1 + src/psmcomm.c | 1 + src/synaptics.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++- src/synapticsstr.h | 4 ++ src/synproto.c | 1 + tools/synclient.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 10 files changed, 245 insertions(+), 5 deletions(-) diff --git a/include/Makefile.am b/include/Makefile.am index 8234020..f078e5e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -18,4 +18,4 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -sdk_HEADERS = synaptics-properties.h +sdk_HEADERS = synaptics.h synaptics-properties.h diff --git a/src/alpscomm.c b/src/alpscomm.c index c565636..b7f1e65 100644 --- a/src/alpscomm.c +++ b/src/alpscomm.c @@ -33,6 +33,7 @@ #endif #include +#include "synaptics.h" #include "synproto.h" #include "synapticsstr.h" #include "ps2comm.h" diff --git a/src/eventcomm.c b/src/eventcomm.c index 9e81b86..d7de480 100644 --- a/src/eventcomm.c +++ b/src/eventcomm.c @@ -41,6 +41,7 @@ #include #include #include "synproto.h" +#include "synaptics.h" #include "synapticsstr.h" #include #include diff --git a/src/properties.c b/src/properties.c index 718d054..dba7dbb 100644 --- a/src/properties.c +++ b/src/properties.c @@ -35,6 +35,7 @@ #include #include +#include "synaptics.h" #include "synapticsstr.h" #include "synaptics-properties.h" diff --git a/src/ps2comm.c b/src/ps2comm.c index ed2f751..74431c1 100644 --- a/src/ps2comm.c +++ b/src/ps2comm.c @@ -38,6 +38,7 @@ #include #include "synproto.h" +#include "synaptics.h" #include "synapticsstr.h" #include "ps2comm.h" #include diff --git a/src/psmcomm.c b/src/psmcomm.c index 4086aba..63c4536 100644 --- a/src/psmcomm.c +++ b/src/psmcomm.c @@ -44,6 +44,7 @@ #include #include #include +#include "synaptics.h" #include "synproto.h" #include "synapticsstr.h" #include "ps2comm.h" /* ps2_print_ident() */ diff --git a/src/synaptics.c b/src/synaptics.c index d5db457..92c57ae 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -64,11 +64,12 @@ #include #include #include +#include #include #include #include #include - +#include "synaptics.h" #include #include #include @@ -297,6 +298,64 @@ SetDeviceAndProtocol(InputInfoPtr pInfo) return (priv->proto_ops != NULL); } +/* + * Allocate and initialize read-only memory for the SynapticsParameters data to hold + * driver settings. + * The function will allocate shared memory if priv->shm_config is TRUE. + */ +static Bool +alloc_shm_data(InputInfoPtr pInfo) +{ + int shmid; + SynapticsPrivate *priv = pInfo->private; + + if (priv->synshm) + return TRUE; /* Already allocated */ + + if (priv->shm_config) { + if ((shmid = shmget(SHM_SYNAPTICS, 0, 0)) != -1) + shmctl(shmid, IPC_RMID, NULL); + if ((shmid = shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), + 0774 | IPC_CREAT)) == -1) { + xf86IDrvMsg(pInfo, X_ERROR, "error shmget\n"); + return FALSE; + } + if ((priv->synshm = (SynapticsSHM *) shmat(shmid, NULL, 0)) == NULL) { + xf86IDrvMsg(pInfo, X_ERROR, "error shmat\n"); + return FALSE; + } + } + else { + priv->synshm = calloc(1, sizeof(SynapticsSHM)); + if (!priv->synshm) + return FALSE; + } + + return TRUE; +} + +/* + * Free SynapticsParameters data previously allocated by alloc_shm_data(). + */ +static void +free_shm_data(SynapticsPrivate * priv) +{ + int shmid; + + if (!priv->synshm) + return; + + if (priv->shm_config) { + if ((shmid = shmget(SHM_SYNAPTICS, 0, 0)) != -1) + shmctl(shmid, IPC_RMID, NULL); + } + else { + free(priv->synshm); + } + + priv->synshm = NULL; +} + static void calculate_edge_widths(SynapticsPrivate * priv, int *l, int *r, int *t, int *b) { @@ -579,6 +638,12 @@ set_default_parameters(InputInfoPtr pInfo) int grab_event_device = 0; const char *source; + /* read the parameters */ + if (priv->synshm) + priv->synshm->version = + (PACKAGE_VERSION_MAJOR * 10000 + PACKAGE_VERSION_MINOR * 100 + + PACKAGE_VERSION_PATCHLEVEL); + /* The synaptics specs specify typical edge widths of 4% on x, and 5.4% on * y (page 7) [Synaptics TouchPad Interfacing Guide, 510-000080 - A * Second Edition, http://www.synaptics.com/support/dev_support.cfm, 8 Sep @@ -899,12 +964,17 @@ SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) /* read hardware dimensions */ ReadDevDimensions(pInfo); + /* install shared memory or normal memory for parameters */ + priv->shm_config = xf86SetBoolOption(pInfo->options, "SHMConfig", FALSE); + set_default_parameters(pInfo); #ifndef NO_DRIVER_SCALING CalculateScalingCoeffs(priv); #endif + if (!alloc_shm_data(pInfo)) + goto SetupProc_fail; priv->comm.buffer = XisbNew(pInfo->fd, INPUT_BUFFER_SIZE); @@ -929,6 +999,7 @@ SynapticsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) if (priv->comm.buffer) XisbFree(priv->comm.buffer); + free_shm_data(priv); free(priv->proto_data); free(priv->timer); free(priv); @@ -1109,6 +1180,7 @@ DeviceClose(DeviceIntPtr dev) RetValue = DeviceOff(dev); TimerFree(priv->timer); priv->timer = NULL; + free_shm_data(priv); free(priv->touch_axes); priv->touch_axes = NULL; SynapticsHwStateFree(&priv->hwState); @@ -1363,6 +1435,9 @@ DeviceInit(DeviceIntPtr dev) priv->comm.hwState = SynapticsHwStateAlloc(priv); + if (!alloc_shm_data(pInfo)) + goto fail; + InitDeviceProperties(pInfo); XIRegisterPropertyHandler(pInfo->dev, SetProperty, NULL, NULL); @@ -1371,6 +1446,7 @@ DeviceInit(DeviceIntPtr dev) return Success; fail: + free_shm_data(priv); free(priv->local_hw_state); free(priv->hwState); free(priv->open_slots); @@ -3074,6 +3150,33 @@ reset_hw_state(struct SynapticsHwState *hw) hw->fingerWidth = 0; } +/* Update the hardware state in shared memory. This is read-only these days, + * nothing in the driver reads back from SHM. SHM configuration is a thing of the past. + */ +static void +update_shm(const InputInfoPtr pInfo, const struct SynapticsHwState *hw) +{ + int i; + SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private); + SynapticsSHM *shm = priv->synshm; + + if (!shm) + return; + + shm->x = hw->x; + shm->y = hw->y; + shm->z = hw->z; + shm->numFingers = hw->numFingers; + shm->fingerWidth = hw->fingerWidth; + shm->left = hw->left; + shm->right = hw->right; + shm->up = hw->up; + shm->down = hw->down; + for (i = 0; i < 8; i++) + shm->multi[i] = hw->multi[i]; + shm->middle = hw->middle; +} + /* * React on changes in the hardware state. This function is called every time * the hardware state changes. The return value is used to specify how many @@ -3101,6 +3204,14 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now, Bool using_cumulative_coords = FALSE; Bool ignore_motion; + update_shm(pInfo, hw); + + /* If touchpad is switched off, we skip the whole thing and return delay */ + if (para->touchpad_off == TOUCHPAD_OFF) { + UpdateTouchState(pInfo, hw); + return delay; + } + /* We need both and x/y, the driver can't handle just one of the two * yet. But since it's possible to hit a phys button on non-clickpads * without ever getting motion data first, we must continue with 0/0 for diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 4bd32ac..023a7c1 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -23,6 +23,7 @@ #define _SYNAPTICSSTR_H_ #include "synproto.h" +#include "synaptics.h" #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 18 #define LogMessageVerbSigSafe xf86MsgVerb @@ -231,6 +232,9 @@ typedef struct _SynapticsParameters { struct _SynapticsPrivateRec { SynapticsParameters synpara; /* Default parameter settings, read from the X config file */ + SynapticsSHM *synshm; /* Current parameter settings. Will point to + shared memory if shm_config is true */ + Bool shm_config; struct SynapticsProtocolOperations *proto_ops; void *proto_data; /* protocol-specific data */ diff --git a/src/synproto.c b/src/synproto.c index 91e20e6..409722e 100644 --- a/src/synproto.c +++ b/src/synproto.c @@ -23,6 +23,7 @@ #include "synproto.h" #include "synapticsstr.h" +#include "synaptics.h" static int HwStateAllocTouch(struct SynapticsHwState *hw, SynapticsPrivate * priv) diff --git a/tools/synclient.c b/tools/synclient.c index ac31a66..df1e6a7 100644 --- a/tools/synclient.c +++ b/tools/synclient.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include "synaptics-properties.h" +#include "synaptics.h" #ifndef XATOM_FLOAT #define XATOM_FLOAT "FLOAT" @@ -192,6 +194,108 @@ parse_cmd(char *cmd, struct Parameter **par) return 0; } +static int +is_equal(SynapticsSHM * s1, SynapticsSHM * s2) +{ + int i; + + if ((s1->x != s2->x) || + (s1->y != s2->y) || + (s1->z != s2->z) || + (s1->numFingers != s2->numFingers) || + (s1->fingerWidth != s2->fingerWidth) || + (s1->left != s2->left) || + (s1->right != s2->right) || + (s1->up != s2->up) || + (s1->down != s2->down) || (s1->middle != s2->middle)) + return 0; + + for (i = 0; i < 8; i++) + if (s1->multi[i] != s2->multi[i]) + return 0; + + return 1; +} + +static double +get_time(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +} + +static void +shm_monitor(SynapticsSHM * synshm, int delay) +{ + int header = 0; + SynapticsSHM old; + double t0 = get_time(); + + memset(&old, 0, sizeof(SynapticsSHM)); + old.x = -1; /* Force first equality test to fail */ + + while (1) { + SynapticsSHM cur = *synshm; + + if (!is_equal(&old, &cur)) { + if (!header) { + printf("%8s %4s %4s %3s %s %2s %2s %s %s %s %s %8s " + "%2s %2s %2s %3s %3s\n", + "time", "x", "y", "z", "f", "w", "l", "r", "u", "d", "m", + "multi", "gl", "gm", "gr", "gdx", "gdy"); + header = 20; + } + header--; + printf + ("%8.3f %4d %4d %3d %d %2d %2d %d %d %d %d %d%d%d%d%d%d%d%d\n", + get_time() - t0, cur.x, cur.y, cur.z, cur.numFingers, + cur.fingerWidth, cur.left, cur.right, cur.up, cur.down, + cur.middle, cur.multi[0], cur.multi[1], cur.multi[2], + cur.multi[3], cur.multi[4], cur.multi[5], cur.multi[6], + cur.multi[7]); + fflush(stdout); + old = cur; + } + usleep(delay * 1000); + } +} + +/** Init and return SHM area or NULL on error */ +static SynapticsSHM * +shm_init() +{ + SynapticsSHM *synshm = NULL; + int shmid = 0; + + if ((shmid = shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), 0)) == -1) { + if ((shmid = shmget(SHM_SYNAPTICS, 0, 0)) == -1) + fprintf(stderr, + "Can't access shared memory area. SHMConfig disabled?\n"); + else + fprintf(stderr, + "Incorrect size of shared memory area. Incompatible driver version?\n"); + } + else if ((synshm = (SynapticsSHM *) shmat(shmid, NULL, SHM_RDONLY)) == NULL) + perror("shmat"); + + return synshm; +} + +static void +shm_process_commands(int do_monitor, int delay) +{ + SynapticsSHM *synshm = NULL; + + synshm = shm_init(); + if (!synshm) + return; + + if (do_monitor) + shm_monitor(synshm, delay); +} + /** Init display connection or NULL on error */ static Display * dp_init() @@ -469,7 +573,11 @@ dp_show_settings(Display * dpy, XDevice * dev) static void usage(void) { - fprintf(stderr, "Usage: synclient [-h] [-l] [-V] [-?] [var1=value1 [var2=value2] ...]\n"); + fprintf(stderr, + "Usage: synclient [-m interval] [-h] [-l] [-V] [-?] [var1=value1 [var2=value2] ...]\n"); + fprintf(stderr, + " -m monitor changes to the touchpad state (implies -s)\n" + " interval specifies how often (in ms) to poll the touchpad state\n"); fprintf(stderr, " -l List current user settings\n"); fprintf(stderr, " -V Print synclient version string and exit\n"); fprintf(stderr, " -? Show this help message\n"); @@ -481,7 +589,9 @@ int main(int argc, char *argv[]) { int c; + int delay = -1; int dump_settings = 0; + int do_monitor = 0; int first_cmd; Display *dpy; @@ -491,8 +601,13 @@ main(int argc, char *argv[]) dump_settings = 1; /* Parse command line parameters */ - while ((c = getopt(argc, argv, "lV?")) != -1) { + while ((c = getopt(argc, argv, "m:lV?")) != -1) { switch (c) { + case 'm': + do_monitor = 1; + if ((delay = atoi(optarg)) < 0) + usage(); + break; case 'l': dump_settings = 1; break; @@ -506,9 +621,13 @@ main(int argc, char *argv[]) } first_cmd = optind; - if (!dump_settings && first_cmd == argc) + if (!do_monitor && !dump_settings && first_cmd == argc) usage(); + /* Connect to the shared memory area */ + if (do_monitor) + shm_process_commands(do_monitor, delay); + dpy = dp_init(); if (!dpy || !(dev = dp_get_device(dpy))) return 1;