On Fri, Jul 16, 2010 at 09:21:19AM -0400, Chase Douglas wrote: > The XI2 protocol supports per-axis modes, but the server so far does > not. This change adds support in the server. > > A complication is the fact that XI1 does not support per-axis modes. > The solution provided here is to set a per-device mode that defines the > mode of at least the first two valuators (X and Y). The per-axis > valuator mode defaults to Relative, so any absolute axes must be > explicitly set. Note that initializing the first two axes to a different > mode than the device mode will fail. > > For XI1 events, any axes following the first two that have the same mode > will be sent to clients, up to the first axis that has a different mode. > Thus, if a device has relative, then absolute, then relative mode axes, > only the first block of relative axes will be sent over XI1. > > Since the XI2 protocol supports per-axis modes, all axes are sent to the > client. > > Signed-off-by: Chase Douglas <chase.doug...@canonical.com> > --- > Xi/exevents.c | 1 + > Xi/xiquerydevice.c | 2 +- > dix/devices.c | 3 +-- > dix/eventconvert.c | 14 +++++++++++++- > dix/getevents.c | 23 ++++++++++++++++------- > hw/dmx/input/dmxmotion.c | 7 +++---- > include/inputstr.h | 1 + > 7 files changed, 36 insertions(+), 15 deletions(-) > > diff --git a/Xi/exevents.c b/Xi/exevents.c > index e990aeb..26084f5 100644 > --- a/Xi/exevents.c > +++ b/Xi/exevents.c > @@ -1145,6 +1145,7 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, > Atom label, int minval, int > ax->min_resolution = min_res; > ax->max_resolution = max_res; > ax->label = label; > + ax->mode = dev->valuator->mode;
shouldn't this be another parameter then? > } > > static void > diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c > index 303c8b2..c8b3d7e 100644 > --- a/Xi/xiquerydevice.c > +++ b/Xi/xiquerydevice.c > @@ -349,7 +349,7 @@ ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, > int axisnumber, > info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16)); > info->resolution = v->axes[axisnumber].resolution; > info->number = axisnumber; > - info->mode = v->mode; /* Server doesn't have per-axis mode yet */ > + info->mode = v->axes[axisnumber].mode; > info->sourceid = v->sourceid; > > if (!reportState) > diff --git a/dix/devices.c b/dix/devices.c > index ac5806a..e4048e4 100644 > --- a/dix/devices.c > +++ b/dix/devices.c > @@ -2366,8 +2366,7 @@ RecalculateMasterButtons(DeviceIntPtr slave) > event.valuators[i].min = master->valuator->axes[i].min_value; > event.valuators[i].max = master->valuator->axes[i].max_value; > event.valuators[i].resolution = > master->valuator->axes[i].resolution; > - /* This should, eventually, be a per-axis mode */ > - event.valuators[i].mode = master->valuator->mode; > + event.valuators[i].mode = master->valuator->axes[i].mode; > event.valuators[i].name = master->valuator->axes[i].label; > } > } > diff --git a/dix/eventconvert.c b/dix/eventconvert.c > index 4e3de0b..991298e 100644 > --- a/dix/eventconvert.c > +++ b/dix/eventconvert.c > @@ -252,6 +252,12 @@ eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, > int *count) > } > > num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */ > + if (num_events <= 0) > + { > + *count = 0; > + return BadMatch; > + } > + > num_events++; /* the actual event event */ > > *xi = calloc(num_events, sizeof(xEvent)); > @@ -309,6 +315,12 @@ countValuators(DeviceEvent *ev, int *first) > > for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) > { > + /* Assume mode of 0th valuator matches XI1 device mode. Stop when the > + * event mode changes since XI1 can't handle mixed mode devices. > + */ why is this assumption necessary? valuator->mode still stores what the XI1 device mode is. > + if (ev->valuators.mode[i] != ev->valuators.mode[0]) > + break; > + > if (BitIsOn(ev->valuators.mask, i)) > { > if (first_valuator == -1) > @@ -431,7 +443,7 @@ appendValuatorInfo(DeviceChangedEvent *dce, > xXIValuatorInfo *info, int axisnumbe > info->value.frac = 0; > info->resolution = dce->valuators[axisnumber].resolution; > info->number = axisnumber; > - info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have > per-axis mode yet */ > + info->mode = dce->valuators[axisnumber].mode; > info->sourceid = dce->sourceid; > > return info->length * 4; > diff --git a/dix/getevents.c b/dix/getevents.c > index 20cc79b..72daa16 100644 > --- a/dix/getevents.c > +++ b/dix/getevents.c > @@ -208,7 +208,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, > uint8_t *mask, > if (BitIsOn(mask, i)) > { > SetBit(event->valuators.mask, i); > - if (dev->valuator->mode == Absolute) > + if (dev->valuator->axes[i].mode == Absolute) > SetBit(event->valuators.mode, i); > event->valuators.data[i] = valuators[i]; > event->valuators.data_frac[i] = > @@ -253,8 +253,7 @@ CreateClassesChangedEvent(EventList* event, > dce->valuators[i].min = slave->valuator->axes[i].min_value; > dce->valuators[i].max = slave->valuator->axes[i].max_value; > dce->valuators[i].resolution = > slave->valuator->axes[i].resolution; > - /* This should, eventually, be a per-axis mode */ > - dce->valuators[i].mode = slave->valuator->mode; > + dce->valuators[i].mode = slave->valuator->axes[i].mode; > dce->valuators[i].name = slave->valuator->axes[i].label; > } > } > @@ -372,8 +371,15 @@ AllocateMotionHistory(DeviceIntPtr pDev) > */ > if (IsMaster(pDev)) > size = sizeof(INT32) * 3 * MAX_VALUATORS; > - else > - size = sizeof(INT32) * pDev->valuator->numAxes; > + else { > + int numAxes; > + /* XI1 doesn't understand mixed mode devices */ > + for (numAxes = 0; numAxes < pDev->valuator->numAxes; numAxes++) > + if ((pDev->valuator->axes[numAxes].mode & DeviceMode) != > + (pDev->valuator->mode & DeviceMode)) > + break; i think having a ValuatorClassPtr v = pDev->valuator would make the code easier to read. > + size = sizeof(INT32) * numAxes; > + } > > size += sizeof(Time); > > @@ -554,7 +560,10 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, > uint8_t *mask, > > for (i = 0; i < MAX_VALUATORS; i++) > { > - if (i >= v->numAxes) > + /* XI1 doesn't support mixed mode devices */ > + if (i >= v->numAxes || > + (pDev->valuator->axes[i].mode & DeviceMode) != > + (pDev->valuator->mode & DeviceMode)) > break; > if (!BitIsOn(mask, i)) > { > @@ -768,7 +777,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y, > if (BitIsOn(mask, i)) > { > dev->last.valuators[i] += valuators[i]; > - if (dev->valuator->mode == Absolute) > + if (dev->valuator->axes[i].mode == Absolute) > clipAxis(dev, i, &dev->last.valuators[i]); > valuators[i] = dev->last.valuators[i]; > } > diff --git a/hw/dmx/input/dmxmotion.c b/hw/dmx/input/dmxmotion.c > index a86b62e..1aae5fe 100644 > --- a/hw/dmx/input/dmxmotion.c > +++ b/hw/dmx/input/dmxmotion.c > @@ -125,12 +125,11 @@ void dmxPointerPutMotionEvent(DeviceIntPtr pDevice, > /* Initialize the data from the known > * values (if Absolute) or to zero (if > * Relative) */ > - if (pDevice->valuator->mode == Absolute) { > - for (i = 0; i < numAxes; i++) > + for (i = 0; i < numAxes; i++) { > + if (pDevice->valuator->axes[i].mode == Absolute) > dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] > = dmxLocal->valuators[i]; > - } else { > - for (i = 0; i < numAxes; i++) > + else > dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0; > } > > diff --git a/include/inputstr.h b/include/inputstr.h > index 1b504e9..d0e9f45 100644 > --- a/include/inputstr.h > +++ b/include/inputstr.h > @@ -217,6 +217,7 @@ typedef struct _AxisInfo { > int min_value; > int max_value; > Atom label; > + CARD8 mode; > } AxisInfo, *AxisInfoPtr; > > typedef struct _ValuatorAccelerationRec { > -- > 1.7.0.4 > Cheers, Peter _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel