diff options
author | Peter Osterlund <petero2@telia.com> | 2005-01-03 16:17:21 +0100 |
---|---|---|
committer | Peter Osterlund <petero2@telia.com> | 2006-04-09 04:03:00 +0200 |
commit | ca5d65f1cd8aef6f3cc1ed5168eac35e82541e2a (patch) | |
tree | e37c2f3705dd75ba354b7bdcbed3dc135c08c017 | |
parent | 9f5ae2b7da6a6aa8ecd1bc5929700edb2caca9f7 (diff) |
Better fix for the crash fixed in change
cbee47a1f26038ade7386fa52b41d1828036dd1e. The shared
memory area is now removed at DEVICE_CLOSE time but recreated if
necessary at DEVICE_INIT time. This fixes the problem where the shared
memory area was not deleted when exiting the X server, thereby fooling
the synclient program to think the driver was still active.
-rw-r--r-- | synaptics.c | 116 | ||||
-rw-r--r-- | synaptics.h | 10 |
2 files changed, 87 insertions, 39 deletions
diff --git a/synaptics.c b/synaptics.c index e86a924..baa90a9 100644 --- a/synaptics.c +++ b/synaptics.c @@ -121,6 +121,7 @@ static Bool ConvertProc(LocalDevicePtr, int, int, int, int, int, int, int, int, static Bool DeviceInit(DeviceIntPtr); static Bool DeviceOn(DeviceIntPtr); static Bool DeviceOff(DeviceIntPtr); +static Bool DeviceClose(DeviceIntPtr); InputDriverRec SYNAPTICS = { @@ -203,6 +204,62 @@ SetDeviceAndProtocol(LocalDevicePtr local) } /* + * Allocate and initialize memory for the SynapticsSHM data to hold driver + * parameter settings. + * The function will allocate shared memory if priv->shm_config is TRUE. + * The allocated data is initialized from priv->synpara_default. + */ +static Bool alloc_param_data(LocalDevicePtr local) +{ + int shmid; + SynapticsPrivate *priv = local->private; + + if (priv->synpara) + return TRUE; /* Already allocated */ + + if (priv->shm_config) { + if ((shmid = xf86shmget(SHM_SYNAPTICS, 0, 0)) != -1) + xf86shmctl(shmid, XF86IPC_RMID, NULL); + if ((shmid = xf86shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), + 0777 | XF86IPC_CREAT)) == -1) { + xf86Msg(X_ERROR, "%s error shmget\n", local->name); + return FALSE; + } + if ((priv->synpara = (SynapticsSHM*)xf86shmat(shmid, NULL, 0)) == NULL) { + xf86Msg(X_ERROR, "%s error shmat\n", local->name); + return FALSE; + } + } else { + priv->synpara = xcalloc(1, sizeof(SynapticsSHM)); + if (!priv->synpara) + return FALSE; + } + + *(priv->synpara) = priv->synpara_default; + return TRUE; +} + +/* + * Free SynapticsSHM data previously allocated by alloc_param_data(). + */ +static void free_param_data(SynapticsPrivate *priv) +{ + int shmid; + + if (!priv->synpara) + return; + + if (priv->shm_config) { + if ((shmid = xf86shmget(SHM_SYNAPTICS, 0, 0)) != -1) + xf86shmctl(shmid, XF86IPC_RMID, NULL); + } else { + xfree(priv->synpara); + } + + priv->synpara = NULL; +} + +/* * called by the module loader for initialization */ static InputInfoPtr @@ -216,7 +273,6 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) pointer optList; #endif char *str_par; - int shmid; unsigned long now; SynapticsSHM *pars; char *repeater; @@ -280,28 +336,10 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) priv->touch_on.millis = now; /* install shared memory or normal memory for parameters */ - priv->shm_config = FALSE; - if (xf86SetBoolOption(local->options, "SHMConfig", FALSE)) { - if ((shmid = xf86shmget(SHM_SYNAPTICS, 0, 0)) != -1) - xf86shmctl(shmid, XF86IPC_RMID, NULL); - if ((shmid = xf86shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), - 0777 | XF86IPC_CREAT)) == -1) { - xf86Msg(X_ERROR, "%s error shmget\n", local->name); - goto SetupProc_fail; - } - else if ((priv->synpara = (SynapticsSHM*) xf86shmat(shmid, NULL, 0)) == NULL) { - xf86Msg(X_ERROR, "%s error shmat\n", local->name); - goto SetupProc_fail; - } - priv->shm_config = TRUE; - } else { - priv->synpara = xcalloc(1, sizeof(SynapticsSHM)); - if (!priv->synpara) - goto SetupProc_fail; - } + priv->shm_config = xf86SetBoolOption(local->options, "SHMConfig", FALSE); /* read the parameters */ - pars = priv->synpara; + pars = &priv->synpara_default; pars->left_edge = xf86SetIntOption(local->options, "LeftEdge", 1900); pars->right_edge = xf86SetIntOption(local->options, "RightEdge", 5400); pars->top_edge = xf86SetIntOption(local->options, "TopEdge", 1900); @@ -370,6 +408,9 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) priv->largest_valid_x = MIN(pars->right_edge, XMAX_NOMINAL); + if (!alloc_param_data(local)) + goto SetupProc_fail; + priv->comm.buffer = XisbNew(local->fd, 200); DBG(9, XisbTrace(priv->comm.buffer, 1)); @@ -417,14 +458,7 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) if (priv->comm.buffer) XisbFree(priv->comm.buffer); - if (priv->synpara) { - if (priv->shm_config) { - if ((shmid = xf86shmget(SHM_SYNAPTICS, 0, 0)) != -1) - xf86shmctl(shmid, XF86IPC_RMID, NULL); - } else { - xfree(priv->synpara); - } - } + free_param_data(priv); /* Freeing priv makes the X server crash. Don't know why. xfree(priv); */ @@ -456,17 +490,16 @@ DeviceControl(DeviceIntPtr dev, int mode) switch (mode) { case DEVICE_INIT: - DeviceInit(dev); - RetValue = Success; + RetValue = DeviceInit(dev); break; case DEVICE_ON: - RetValue = DeviceOn( dev ); + RetValue = DeviceOn(dev); break; case DEVICE_OFF: - RetValue = DeviceOff( dev ); + RetValue = DeviceOff(dev); break; case DEVICE_CLOSE: - RetValue = DeviceOff( dev ); + RetValue = DeviceClose(dev); break; default: RetValue = BadValue; @@ -532,6 +565,18 @@ DeviceOff(DeviceIntPtr dev) } static Bool +DeviceClose(DeviceIntPtr dev) +{ + Bool RetValue; + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; + SynapticsPrivate *priv = (SynapticsPrivate *) local->private; + + RetValue = DeviceOff(dev); + free_param_data(priv); + return RetValue; +} + +static Bool DeviceInit(DeviceIntPtr dev) { LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; @@ -559,6 +604,9 @@ DeviceInit(DeviceIntPtr dev) xf86MotionHistoryAllocate(local); + if (!alloc_param_data(local)) + return !Success; + return Success; } diff --git a/synaptics.h b/synaptics.h index c66917f..3e68e24 100644 --- a/synaptics.h +++ b/synaptics.h @@ -148,15 +148,15 @@ enum TapButtonState { typedef struct _SynapticsPrivateRec { - /* shared memory pointer */ - SynapticsSHM *synpara; - + SynapticsSHM synpara_default; /* Default parameter settings, read from + the X config file */ + SynapticsSHM *synpara; /* Current parameter settings. Will point to + shared memory if shm_config is true */ struct SynapticsProtocolOperations* proto_ops; struct SynapticsHwState hwState; - /* Data read from the touchpad */ - struct SynapticsHwInfo synhw; + struct SynapticsHwInfo synhw; /* Data read from the touchpad */ Bool shm_config; /* True when shared memory area allocated */ OsTimerPtr timer; /* for up/down-button repeat, tap processing, etc */ |