aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/dix')
-rw-r--r--xorg-server/dix/cursor.c29
-rw-r--r--xorg-server/dix/devices.c59
-rw-r--r--xorg-server/dix/dispatch.c4
-rw-r--r--xorg-server/dix/dixutils.c8
-rw-r--r--xorg-server/dix/eventconvert.c23
-rw-r--r--xorg-server/dix/events.c89
-rw-r--r--xorg-server/dix/getevents.c61
-rw-r--r--xorg-server/dix/grabs.c21
-rw-r--r--xorg-server/dix/main.c7
-rw-r--r--xorg-server/dix/pixmap.c2
-rw-r--r--xorg-server/dix/registry.c25
-rw-r--r--xorg-server/dix/touch.c118
-rw-r--r--xorg-server/dix/window.c15
13 files changed, 315 insertions, 146 deletions
diff --git a/xorg-server/dix/cursor.c b/xorg-server/dix/cursor.c
index 1ee127ac5..cd8305c6c 100644
--- a/xorg-server/dix/cursor.c
+++ b/xorg-server/dix/cursor.c
@@ -114,9 +114,13 @@ FreeCursor(pointer value, XID cid)
ScreenPtr pscr;
DeviceIntPtr pDev = NULL; /* unused anyway */
- if (--pCurs->refcnt != 0)
+
+ UnrefCursor(pCurs);
+ if (CursorRefCount(pCurs) != 0)
return Success;
+ BUG_WARN(CursorRefCount(pCurs) < 0);
+
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
pscr = screenInfo.screens[nscr];
(void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
@@ -127,6 +131,29 @@ FreeCursor(pointer value, XID cid)
return Success;
}
+CursorPtr
+RefCursor(CursorPtr cursor)
+{
+ if (cursor)
+ cursor->refcnt++;
+ return cursor;
+}
+
+CursorPtr
+UnrefCursor(CursorPtr cursor)
+{
+ if (cursor)
+ cursor->refcnt--;
+ return cursor;
+}
+
+int
+CursorRefCount(const CursorPtr cursor)
+{
+ return cursor ? cursor->refcnt : 0;
+}
+
+
/*
* We check for empty cursors so that we won't have to display them
*/
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index be236dd70..a680ed8d7 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -112,8 +112,8 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
* Transform is the user supplied (affine) transform
* InvScale scales coordinates back up into their native range
*/
- sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
- sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
+ sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1;
+ sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
/* invscale */
pixman_f_transform_init_scale(&scale, sx, sy);
@@ -281,7 +281,6 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
dev->deviceGrab.grabTime = currentTime;
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
- dev->deviceGrab.activeGrab = AllocGrab();
dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
XkbSetExtension(dev, ProcessKeyboardEvent);
@@ -795,6 +794,7 @@ FreeDeviceClass(int type, pointer *class)
free((*t)->touches[i].valuators);
}
+ free((*t)->touches);
free((*t));
break;
}
@@ -976,7 +976,8 @@ CloseDevice(DeviceIntPtr dev)
}
}
- FreeGrab(dev->deviceGrab.activeGrab);
+ if (dev->deviceGrab.grab)
+ FreeGrab(dev->deviceGrab.grab);
free(dev->deviceGrab.sync.event);
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
free(dev->last.scroll);
@@ -1051,6 +1052,7 @@ CloseDownDevices(void)
inputInfo.pointer = NULL;
XkbDeleteRulesDflts();
+ XkbDeleteRulesUsed();
OsReleaseSignals();
}
@@ -1275,6 +1277,9 @@ InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels,
ButtonClassPtr butc;
int i;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->button != NULL, FALSE);
+
butc = calloc(1, sizeof(ButtonClassRec));
if (!butc)
return FALSE;
@@ -1335,8 +1340,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
int i;
ValuatorClassPtr valc;
- if (!dev)
- return FALSE;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
if (numAxes > MAX_VALUATORS) {
LogMessage(X_WARNING,
@@ -1365,7 +1369,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
valc->numMotionEvents = numMotionEvents;
valc->motionHintWindow = NullWindow;
- if (mode & OutOfProximity)
+ if ((mode & OutOfProximity) && !dev->proximity)
InitProximityClassDeviceStruct(dev);
dev->valuator = valc;
@@ -1445,6 +1449,9 @@ InitFocusClassDeviceStruct(DeviceIntPtr dev)
{
FocusClassPtr focc;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->focus != NULL, FALSE);
+
focc = malloc(sizeof(FocusClassRec));
if (!focc)
return FALSE;
@@ -1464,6 +1471,9 @@ InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
{
PtrFeedbackPtr feedc;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->ptrfeed != NULL, FALSE);
+
feedc = malloc(sizeof(PtrFeedbackClassRec));
if (!feedc)
return FALSE;
@@ -1505,6 +1515,9 @@ InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev,
int i;
StringFeedbackPtr feedc;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->stringfeed != NULL, FALSE);
+
feedc = malloc(sizeof(StringFeedbackClassRec));
if (!feedc)
return FALSE;
@@ -1539,6 +1552,9 @@ InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
{
BellFeedbackPtr feedc;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->bell != NULL, FALSE);
+
feedc = malloc(sizeof(BellFeedbackClassRec));
if (!feedc)
return FALSE;
@@ -1558,6 +1574,9 @@ InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev, LedCtrlProcPtr controlProc)
{
LedFeedbackPtr feedc;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->leds != NULL, FALSE);
+
feedc = malloc(sizeof(LedFeedbackClassRec));
if (!feedc)
return FALSE;
@@ -1578,6 +1597,9 @@ InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev,
{
IntegerFeedbackPtr feedc;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->intfeed != NULL, FALSE);
+
feedc = malloc(sizeof(IntegerFeedbackClassRec));
if (!feedc)
return FALSE;
@@ -1598,6 +1620,11 @@ InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
{
DeviceIntPtr dev = (DeviceIntPtr) device;
+ BUG_RETURN_VAL(dev == NULL, FALSE);
+ BUG_RETURN_VAL(dev->button != NULL, FALSE);
+ BUG_RETURN_VAL(dev->valuator != NULL, FALSE);
+ BUG_RETURN_VAL(dev->ptrfeed != NULL, FALSE);
+
return (InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
numMotionEvents, Relative) &&
@@ -1618,14 +1645,13 @@ InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
TouchClassPtr touch;
int i;
- if (device->touch || !device->valuator)
- return FALSE;
+ BUG_RETURN_VAL(device == NULL, FALSE);
+ BUG_RETURN_VAL(device->touch != NULL, FALSE);
+ BUG_RETURN_VAL(device->valuator == NULL, FALSE);
/* Check the mode is valid, and at least X and Y axes. */
- if (mode != XIDirectTouch && mode != XIDependentTouch)
- return FALSE;
- if (num_axes < 2)
- return FALSE;
+ BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE);
+ BUG_RETURN_VAL(num_axes < 2, FALSE);
if (num_axes > MAX_VALUATORS) {
LogMessage(X_WARNING,
@@ -2766,9 +2792,10 @@ AllocDevicePair(ClientPtr client, const char *name,
keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
/* The ClassesRec stores the device classes currently not used. */
- pointer->unused_classes = calloc(1, sizeof(ClassesRec));
-
- keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
+ if (IsMaster(pointer)) {
+ pointer->unused_classes = calloc(1, sizeof(ClassesRec));
+ keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
+ }
*ptr = pointer;
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c
index 8d6173525..51d0de25f 100644
--- a/xorg-server/dix/dispatch.c
+++ b/xorg-server/dix/dispatch.c
@@ -465,6 +465,7 @@ Dispatch(void)
free(clientReady);
dispatchException &= ~DE_RESET;
SmartScheduleLatencyLimited = 0;
+ ResetOsBuffers();
}
static int VendorRelease = VENDOR_RELEASE;
@@ -3398,6 +3399,7 @@ CloseDownClient(ClientPtr client)
clientinfo.setup = (xConnSetup *) NULL;
CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
}
+ TouchListenerGone(client->clientAsMask);
FreeClientResources(client);
/* Disable client ID tracking. This must be done after
* ClientStateCallback. */
@@ -3942,7 +3944,6 @@ void
AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
- assert(!new->current_master);
xorg_list_add(&new->output_head, &pScreen->output_slave_list);
new->current_master = pScreen;
}
@@ -3959,7 +3960,6 @@ void
AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
{
assert(new->isGPU);
- assert(!new->current_master);
xorg_list_add(&new->offload_head, &pScreen->offload_slave_list);
new->current_master = pScreen;
}
diff --git a/xorg-server/dix/dixutils.c b/xorg-server/dix/dixutils.c
index 3f24629b4..c250bb1db 100644
--- a/xorg-server/dix/dixutils.c
+++ b/xorg-server/dix/dixutils.c
@@ -849,7 +849,7 @@ DeleteCallbackList(CallbackListPtr *pcbl)
}
void
-InitCallbackManager(void)
+DeleteCallbackManager(void)
{
int i;
@@ -861,3 +861,9 @@ InitCallbackManager(void)
numCallbackListsToCleanup = 0;
listsToCleanup = NULL;
}
+
+void
+InitCallbackManager(void)
+{
+ DeleteCallbackManager();
+}
diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c
index 2c411cf40..f7ecdba77 100644
--- a/xorg-server/dix/eventconvert.c
+++ b/xorg-server/dix/eventconvert.c
@@ -501,9 +501,7 @@ appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info,
info->min.frac = 0;
info->max.integral = dce->valuators[axisnumber].max;
info->max.frac = 0;
- /* FIXME: value */
- info->value.integral = 0;
- info->value.frac = 0;
+ info->value = double_to_fp3232(dce->valuators[axisnumber].value);
info->resolution = dce->valuators[axisnumber].resolution;
info->number = axisnumber;
info->mode = dce->valuators[axisnumber].mode;
@@ -684,17 +682,18 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac);
xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac);
- if (ev->type == ET_TouchUpdate)
- xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
- else
- xde->flags = ev->flags;
+ if (IsTouchEvent((InternalEvent *)ev)) {
+ if (ev->type == ET_TouchUpdate)
+ xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
- if (IsTouchEvent((InternalEvent *) ev) &&
- ev->flags & TOUCH_POINTER_EMULATED)
- xde->flags |= XITouchEmulatingPointer;
+ if (ev->flags & TOUCH_POINTER_EMULATED)
+ xde->flags |= XITouchEmulatingPointer;
+ } else {
+ xde->flags = ev->flags;
- if (ev->key_repeat)
- xde->flags |= XIKeyRepeat;
+ if (ev->key_repeat)
+ xde->flags |= XIKeyRepeat;
+ }
xde->mods.base_mods = ev->mods.base;
xde->mods.latched_mods = ev->mods.latched;
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index 051205233..e5db348c6 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -931,8 +931,7 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
(*pScreen->DisplayCursor) (pDev, pScreen, cursor);
FreeCursor(pSprite->current, (Cursor) 0);
- pSprite->current = cursor;
- pSprite->current->refcnt++;
+ pSprite->current = RefCursor(cursor);
}
}
@@ -1427,21 +1426,23 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
for (i = 0; i < mouse->touch->num_touches; i++) {
TouchPointInfoPtr ti = mouse->touch->touches + i;
+ TouchListener *listener = &ti->listeners[0];
GrabPtr grab = mouse->deviceGrab.grab;
if (ti->active &&
- CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
- ti->listeners[0].listener = grab->resource;
- ti->listeners[0].level = grab->grabtype;
- ti->listeners[0].state = LISTENER_IS_OWNER;
- ti->listeners[0].window = grab->window;
+ CLIENT_BITS(listener->listener) == grab->resource) {
+ listener->listener = grab->resource;
+ listener->level = grab->grabtype;
+ listener->state = LISTENER_IS_OWNER;
+ listener->window = grab->window;
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
- ti->listeners[0].type = LISTENER_POINTER_GRAB;
+ listener->type = LISTENER_POINTER_GRAB;
else
- ti->listeners[0].type = LISTENER_GRAB;
- ti->listeners[0].grab = grab;
+ listener->type = LISTENER_GRAB;
+ FreeGrab(listener->grab);
+ listener->grab = AllocGrab(grab);
}
}
}
@@ -1466,6 +1467,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
TimeStamp time, Bool autoGrab)
{
GrabInfoPtr grabinfo = &mouse->deviceGrab;
+ GrabPtr oldgrab = grabinfo->grab;
WindowPtr oldWin = (grabinfo->grab) ?
grabinfo->grab->window : mouse->spriteInfo->sprite->win;
Bool isPassive = autoGrab & ~ImplicitGrabMask;
@@ -1488,16 +1490,15 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
grabinfo->grabTime = syncEvents.time;
else
grabinfo->grabTime = time;
- if (grab->cursor)
- grab->cursor->refcnt++;
- CopyGrab(grabinfo->activeGrab, grab);
- grabinfo->grab = grabinfo->activeGrab;
+ grabinfo->grab = AllocGrab(grab);
grabinfo->fromPassiveGrab = isPassive;
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
PostNewCursor(mouse);
UpdateTouchesForGrab(mouse);
CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
(Bool) grab->keyboardMode);
+ if (oldgrab)
+ FreeGrab(oldgrab);
}
/**
@@ -1547,13 +1548,13 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
if (grab->confineTo)
ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
PostNewCursor(mouse);
- if (grab->cursor)
- FreeCursor(grab->cursor, (Cursor) 0);
if (!wasImplicit && grab->grabtype == XI2)
ReattachToOldMaster(mouse);
ComputeFreezes();
+
+ FreeGrab(grab);
}
/**
@@ -1566,6 +1567,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
Bool passive)
{
GrabInfoPtr grabinfo = &keybd->deviceGrab;
+ GrabPtr oldgrab = grabinfo->grab;
WindowPtr oldWin;
/* slave devices need to float for the duration of the grab. */
@@ -1591,12 +1593,13 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
grabinfo->grabTime = syncEvents.time;
else
grabinfo->grabTime = time;
- CopyGrab(grabinfo->activeGrab, grab);
- grabinfo->grab = grabinfo->activeGrab;
+ grabinfo->grab = AllocGrab(grab);
grabinfo->fromPassiveGrab = passive;
grabinfo->implicitGrab = passive & ImplicitGrabMask;
CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
(Bool) grab->pointerMode);
+ if (oldgrab)
+ FreeGrab(oldgrab);
}
/**
@@ -1638,6 +1641,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
ReattachToOldMaster(keybd);
ComputeFreezes();
+
+ FreeGrab(grab);
}
void
@@ -1742,6 +1747,16 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
}
break;
}
+
+ /* We've unfrozen the grab. If the grab was a touch grab, we're now the
+ * owner and expected to accept/reject it. Reject == ReplayPointer which
+ * we've handled in ComputeFreezes() (during DeactivateGrab) above,
+ * anything else is accept.
+ */
+ if (newState != NOT_GRABBED /* Replay */ &&
+ IsTouchEvent((InternalEvent*)grabinfo->sync.event)) {
+ TouchAcceptAndEnd(thisDev, grabinfo->sync.event->touchid);
+ }
}
/**
@@ -1974,7 +1989,7 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
else
return FALSE;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return FALSE;
tempGrab->next = NULL;
@@ -3194,11 +3209,10 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
pSprite->pEnqueueScreen = screenInfo.screens[0];
pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
}
- if (pCursor)
- pCursor->refcnt++;
+ pCursor = RefCursor(pCursor);
if (pSprite->current)
FreeCursor(pSprite->current, None);
- pSprite->current = pCursor;
+ pSprite->current = RefCursor(pCursor);
if (pScreen) {
(*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
@@ -3277,9 +3291,7 @@ UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
pSprite->hotLimits.x2 = pScreen->width;
pSprite->hotLimits.y2 = pScreen->height;
pSprite->win = win;
- pCursor = wCursor(win);
- if (pCursor)
- pCursor->refcnt++;
+ pCursor = RefCursor(wCursor(win));
if (pSprite->current)
FreeCursor(pSprite->current, 0);
pSprite->current = pCursor;
@@ -3881,7 +3893,7 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
if (!grab)
return NULL;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
/* Fill out the grab details, but leave the type for later before
* comparing */
@@ -4839,7 +4851,6 @@ ProcGrabPointer(ClientPtr client)
GrabPtr grab;
GrabMask mask;
WindowPtr confineTo;
- CursorPtr oldCursor;
BYTE status;
REQUEST(xGrabPointerReq);
@@ -4862,15 +4873,10 @@ ProcGrabPointer(ClientPtr client)
return rc;
}
- oldCursor = NullCursor;
grab = device->deviceGrab.grab;
- if (grab) {
- if (grab->confineTo && !confineTo)
- ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE,
- FALSE);
- oldCursor = grab->cursor;
- }
+ if (grab && grab->confineTo && !confineTo)
+ ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE);
mask.core = stuff->eventMask;
@@ -4880,9 +4886,6 @@ ProcGrabPointer(ClientPtr client)
if (rc != Success)
return rc;
- if (oldCursor && status == GrabSuccess)
- FreeCursor(oldCursor, (Cursor) 0);
-
rep = (xGrabPointerReply) {
.type = X_Reply,
.status = status,
@@ -4938,9 +4941,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
(CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
return Success;
oldCursor = grab->cursor;
- grab->cursor = newCursor;
- if (newCursor)
- newCursor->refcnt++;
+ grab->cursor = RefCursor(newCursor);
PostNewCursor(device);
if (oldCursor)
FreeCursor(oldCursor, (Cursor) 0);
@@ -5070,7 +5071,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
else {
GrabPtr tempGrab;
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
tempGrab->next = NULL;
tempGrab->window = pWin;
@@ -5085,7 +5086,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
else
xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
tempGrab->device = dev;
- tempGrab->cursor = cursor;
+ tempGrab->cursor = RefCursor(cursor);
tempGrab->confineTo = confineTo;
tempGrab->grabtype = grabtype;
(*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);
@@ -5426,7 +5427,7 @@ ProcUngrabKey(ClientPtr client)
client->errorValue = stuff->modifiers;
return BadValue;
}
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return BadAlloc;
tempGrab->resource = client->clientAsMask;
@@ -5620,7 +5621,7 @@ ProcUngrabButton(ClientPtr client)
ptr = PickPointer(client);
- tempGrab = AllocGrab();
+ tempGrab = AllocGrab(NULL);
if (!tempGrab)
return BadAlloc;
tempGrab->resource = client->clientAsMask;
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index a4f192cf0..51d4fd4da 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -277,6 +277,7 @@ CreateClassesChangedEvent(InternalEvent *event,
dce->valuators[i].mode = slave->valuator->axes[i].mode;
dce->valuators[i].name = slave->valuator->axes[i].label;
dce->valuators[i].scroll = slave->valuator->axes[i].scroll;
+ dce->valuators[i].value = slave->valuator->axisVal[i];
}
}
if (slave->key) {
@@ -297,11 +298,11 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
if (from && from->min_value < from->max_value) {
fmin = from->min_value;
- fmax = from->max_value;
+ fmax = from->max_value + 1;
}
if (to && to->min_value < to->max_value) {
tmin = to->min_value;
- tmax = to->max_value;
+ tmax = to->max_value + 1;
}
if (fmin == tmin && fmax == tmax)
@@ -769,6 +770,29 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
}
+static void
+scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
+{
+ double x;
+ ValuatorClassPtr v = dev->valuator;
+ int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
+ int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
+
+ double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
+ double device_ratio = 1.0 * xrange/yrange;
+ double resolution_ratio = 1.0;
+ double ratio;
+
+ if (!valuator_mask_fetch_double(mask, 0, &x))
+ return;
+
+ if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
+ resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
+
+ ratio = device_ratio/resolution_ratio/screen_ratio;
+ valuator_mask_set_double(mask, 0, x * ratio);
+}
+
/**
* Move the device's pointer by the values given in @valuators.
*
@@ -780,27 +804,14 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{
int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+ ValuatorClassPtr v = dev->valuator;
/* for abs devices in relative mode, we've just scaled wrong, since we
mapped the device's shape into the screen shape. Undo this. */
- if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
- dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
-
- double ratio = 1.0 * screenInfo.width/screenInfo.height;
-
- if (ratio > 1.0) {
- double y;
- if (valuator_mask_fetch_double(mask, 1, &y)) {
- y *= ratio;
- valuator_mask_set_double(mask, 1, y);
- }
- } else {
- double x;
- if (valuator_mask_fetch_double(mask, 0, &x)) {
- x *= ratio;
- valuator_mask_set_double(mask, 0, x);
- }
- }
+ if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
+ v->axes[0].min_value < v->axes[0].max_value &&
+ v->axes[1].min_value < v->axes[1].max_value) {
+ scale_for_device_resolution(dev, mask);
}
/* calc other axes, clip, drop back into valuators */
@@ -913,9 +924,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
/* scale x&y to desktop coordinates */
*screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
- screenInfo.x, screenInfo.width - 1);
+ screenInfo.x, screenInfo.width);
*screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
- screenInfo.y, screenInfo.height - 1);
+ screenInfo.y, screenInfo.height);
*devx = x;
*devy = y;
@@ -1355,6 +1366,12 @@ QueuePointerEvents(DeviceIntPtr device, int type,
* is the last coordinate on the first screen and must be rescaled for the
* event to be m. XI2 clients that do their own coordinate mapping would
* otherwise interpret the position of the device elsewere to the cursor.
+ * However, this scaling leads to losses:
+ * if we have two ScreenRecs we scale from e.g. [0..44704] (Wacom I4) to
+ * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen
+ * coordinate 1023.954. Scaling that back into the device coordinate range
+ * gives us 44703. So off by one device unit. It's a bug, but we'll have to
+ * live with it because with all this scaling, we just cannot win.
*
* @return the number of events written into events.
*/
diff --git a/xorg-server/dix/grabs.c b/xorg-server/dix/grabs.c
index 3b02352df..a03897af4 100644
--- a/xorg-server/dix/grabs.c
+++ b/xorg-server/dix/grabs.c
@@ -189,7 +189,7 @@ UngrabAllDevices(Bool kill_client)
}
GrabPtr
-AllocGrab(void)
+AllocGrab(const GrabPtr src)
{
GrabPtr grab = calloc(1, sizeof(GrabRec));
@@ -201,6 +201,12 @@ AllocGrab(void)
}
}
+ if (src && !CopyGrab(grab, src)) {
+ free(grab->xi2mask);
+ free(grab);
+ grab = NULL;
+ }
+
return grab;
}
@@ -213,7 +219,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
{
GrabPtr grab;
- grab = AllocGrab();
+ grab = AllocGrab(NULL);
if (!grab)
return (GrabPtr) NULL;
grab->resource = FakeClientID(client);
@@ -235,13 +241,11 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
grab->detail.exact = keybut;
grab->detail.pMask = NULL;
grab->confineTo = confineTo;
- grab->cursor = cursor;
+ grab->cursor = RefCursor(cursor);
grab->next = NULL;
if (grabtype == XI2)
xi2mask_merge(grab->xi2mask, mask->xi2mask);
- if (cursor)
- cursor->refcnt++;
return grab;
}
@@ -249,8 +253,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
void
FreeGrab(GrabPtr pGrab)
{
- if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
- TouchListenerGone(pGrab->resource);
+ BUG_RETURN(!pGrab);
free(pGrab->modifiersDetail.pMask);
free(pGrab->detail.pMask);
@@ -269,9 +272,6 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
Mask *details_mask = NULL;
XI2Mask *xi2mask;
- if (src->cursor)
- src->cursor->refcnt++;
-
if (src->modifiersDetail.pMask) {
int len = MasksPerDetailMask * sizeof(Mask);
@@ -309,6 +309,7 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
dst->modifiersDetail.pMask = mdetails_mask;
dst->detail.pMask = details_mask;
dst->xi2mask = xi2mask;
+ dst->cursor = RefCursor(src->cursor);
xi2mask_merge(dst->xi2mask, src->xi2mask);
diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c
index bea1a8d5a..e69cd931f 100644
--- a/xorg-server/dix/main.c
+++ b/xorg-server/dix/main.c
@@ -211,6 +211,9 @@ main(int argc, char *argv[], char *envp[])
ScreenPtr pScreen = screenInfo.gpuscreens[i];
if (!CreateScratchPixmapsForScreen(pScreen))
FatalError("failed to create scratch pixmaps");
+ if (pScreen->CreateScreenResources &&
+ !(*pScreen->CreateScreenResources) (pScreen))
+ FatalError("failed to create screen resources");
}
for (i = 0; i < screenInfo.numScreens; i++) {
@@ -355,12 +358,16 @@ main(int argc, char *argv[], char *envp[])
dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
serverClient->devPrivates = NULL;
+ dixFreeRegistry();
+
FreeFonts();
FreeAllAtoms();
FreeAuditTimer();
+ DeleteCallbackManager();
+
if (dispatchException & DE_TERMINATE) {
CloseWellKnownConnections();
}
diff --git a/xorg-server/dix/pixmap.c b/xorg-server/dix/pixmap.c
index 241881262..fe9214739 100644
--- a/xorg-server/dix/pixmap.c
+++ b/xorg-server/dix/pixmap.c
@@ -243,6 +243,8 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region)
}
dst = dirty->slave_dst->master_pixmap;
+ if (!dst)
+ dst = dirty->slave_dst;
RegionTranslate(dirty_region, -dirty->x, -dirty->y);
n = RegionNumRects(dirty_region);
diff --git a/xorg-server/dix/registry.c b/xorg-server/dix/registry.c
index 5bad0fdd4..82a3340e1 100644
--- a/xorg-server/dix/registry.c
+++ b/xorg-server/dix/registry.c
@@ -280,14 +280,9 @@ LookupResourceName(RESTYPE resource)
return resources[resource] ? resources[resource] : XREGISTRY_UNKNOWN;
}
-/*
- * Setup and teardown
- */
void
-dixResetRegistry(void)
+dixFreeRegistry(void)
{
- ExtensionEntry extEntry = { .name = CORE };
-
/* Free all memory */
while (nmajor--) {
while (nminor[nmajor])
@@ -315,9 +310,23 @@ dixResetRegistry(void)
nmajor = nevent = nerror = nresource = 0;
+ if (fh) {
+ fclose(fh);
+ fh = NULL;
+ }
+}
+
+/*
+ * Setup and teardown
+ */
+void
+dixResetRegistry(void)
+{
+ ExtensionEntry extEntry = { .name = CORE };
+
+ dixFreeRegistry();
+
/* Open the protocol file */
- if (fh)
- fclose(fh);
fh = fopen(FILENAME, "r");
if (!fh)
LogMessage(X_WARNING,
diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c
index 891cc7803..a4b6d7eea 100644
--- a/xorg-server/dix/touch.c
+++ b/xorg-server/dix/touch.c
@@ -263,6 +263,7 @@ void
TouchFreeTouchPoint(DeviceIntPtr device, int index)
{
TouchPointInfoPtr ti;
+ int i;
if (!device->touch || index >= device->touch->num_touches)
return;
@@ -271,6 +272,9 @@ TouchFreeTouchPoint(DeviceIntPtr device, int index)
if (ti->active)
TouchEndTouch(device, ti);
+ for (i = 0; i < ti->num_listeners; i++)
+ TouchRemoveListener(ti, ti->listeners[0].listener);
+
valuator_mask_free(&ti->valuators);
free(ti->sprite.spriteTrace);
ti->sprite.spriteTrace = NULL;
@@ -365,6 +369,8 @@ TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid,
void
TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
{
+ int i;
+
if (ti->emulate_pointer) {
GrabPtr grab;
@@ -376,6 +382,9 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
}
}
+ for (i = 0; i < ti->num_listeners; i++)
+ TouchRemoveListener(ti, ti->listeners[0].listener);
+
ti->active = FALSE;
ti->pending_finish = FALSE;
ti->sprite.spriteTraceGood = 0;
@@ -474,7 +483,21 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
DeviceEvent *ev = &ti->history[i];
ev->flags |= TOUCH_REPLAYING;
- DeliverTouchEvents(dev, ti, (InternalEvent *) ev, resource);
+ ev->resource = resource;
+ /* FIXME:
+ We're replaying ti->history which contains the TouchBegin +
+ all TouchUpdates for ti. This needs to be passed on to the next
+ listener. If that is a touch listener, everything is dandy.
+ If the TouchBegin however triggers a sync passive grab, the
+ TouchUpdate events must be sent to EnqueueEvent so the events end
+ up in syncEvents.pending to be forwarded correctly in a
+ subsequent ComputeFreeze().
+
+ However, if we just send them to EnqueueEvent the sync'ing device
+ prevents handling of touch events for ownership listeners who
+ want the events right here, right now.
+ */
+ dev->public.processInputProc((InternalEvent*)ev, dev);
}
}
@@ -620,14 +643,14 @@ TouchConvertToPointerEvent(const InternalEvent *event,
BUG_WARN_MSG(!(event->device_event.flags & TOUCH_POINTER_EMULATED),
"Non-emulating touch event\n");
- *motion_event = *event;
+ motion_event->device_event = event->device_event;
motion_event->any.type = ET_Motion;
motion_event->device_event.detail.button = 0;
motion_event->device_event.flags = XIPointerEmulated;
if (nevents > 1) {
BUG_RETURN_VAL(!button_event, 0);
- *button_event = *event;
+ button_event->device_event = event->device_event;
button_event->any.type = ptrtype;
button_event->device_event.flags = XIPointerEmulated;
/* detail is already correct */
@@ -678,15 +701,23 @@ void
TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
enum InputLevel level, enum TouchListenerType type,
enum TouchListenerState state, WindowPtr window,
- GrabPtr grab)
+ const GrabPtr grab)
{
+ GrabPtr g = NULL;
+
+ /* We need a copy of the grab, not the grab itself since that may be
+ * deleted by a UngrabButton request and leaves us with a dangling
+ * pointer */
+ if (grab)
+ g = AllocGrab(grab);
+
ti->listeners[ti->num_listeners].listener = resource;
ti->listeners[ti->num_listeners].resource_type = resource_type;
ti->listeners[ti->num_listeners].level = level;
ti->listeners[ti->num_listeners].state = state;
ti->listeners[ti->num_listeners].type = type;
ti->listeners[ti->num_listeners].window = window;
- ti->listeners[ti->num_listeners].grab = grab;
+ ti->listeners[ti->num_listeners].grab = g;
if (grab)
ti->num_grabs++;
ti->num_listeners++;
@@ -704,21 +735,25 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
int i;
for (i = 0; i < ti->num_listeners; i++) {
- if (ti->listeners[i].listener == resource) {
- int j;
+ int j;
+ TouchListener *listener = &ti->listeners[i];
- if (ti->listeners[i].grab) {
- ti->listeners[i].grab = NULL;
- ti->num_grabs--;
- }
+ if (listener->listener != resource)
+ continue;
- for (j = i; j < ti->num_listeners - 1; j++)
- ti->listeners[j] = ti->listeners[j + 1];
- ti->num_listeners--;
- ti->listeners[ti->num_listeners].listener = 0;
- ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
- return TRUE;
+ if (listener->grab) {
+ FreeGrab(listener->grab);
+ listener->grab = NULL;
+ ti->num_grabs--;
}
+
+ for (j = i; j < ti->num_listeners - 1; j++)
+ ti->listeners[j] = ti->listeners[j + 1];
+ ti->num_listeners--;
+ ti->listeners[ti->num_listeners].listener = 0;
+ ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
+
+ return TRUE;
}
return FALSE;
}
@@ -874,7 +909,7 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
SpritePtr sprite = &ti->sprite;
WindowPtr win;
- if (dev->deviceGrab.grab)
+ if (dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab)
TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
/* We set up an active touch listener for existing touches, but not any
@@ -954,11 +989,11 @@ TouchListenerGone(XID resource)
continue;
for (j = 0; j < ti->num_listeners; j++) {
- if (ti->listeners[j].listener != resource)
+ if (CLIENT_BITS(ti->listeners[j].listener) != resource)
continue;
nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
- resource, 0);
+ ti->listeners[j].listener, 0);
for (k = 0; k < nev; k++)
mieqProcessDeviceEvent(dev, events + k, NULL);
@@ -1061,3 +1096,46 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev)
FreeEventList(eventlist, GetMaximumEventsNum());
}
+
+/**
+ * Generate and deliver a TouchEnd event.
+ *
+ * @param dev The device to deliver the event for.
+ * @param ti The touch point record to deliver the event for.
+ * @param flags Internal event flags. The called does not need to provide
+ * TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
+ * they are set appropriately.
+ * @param resource The client resource to deliver to, or 0 for all clients.
+ */
+void
+TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
+{
+ InternalEvent event;
+
+ /* We're not processing a touch end for a frozen device */
+ if (dev->deviceGrab.sync.frozen)
+ return;
+
+ flags |= TOUCH_CLIENT_ID;
+ if (ti->emulate_pointer)
+ flags |= TOUCH_POINTER_EMULATED;
+ TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
+ GetDixTouchEnd(&event, dev, ti, flags);
+ DeliverTouchEvents(dev, ti, &event, resource);
+ if (ti->num_grabs == 0)
+ UpdateDeviceState(dev, &event.device_event);
+}
+
+void
+TouchAcceptAndEnd(DeviceIntPtr dev, int touchid)
+{
+ TouchPointInfoPtr ti = TouchFindByClientID(dev, touchid);
+ if (!ti)
+ return;
+
+ TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
+ if (ti->pending_finish)
+ TouchEmitTouchEnd(dev, ti, 0, 0);
+ if (ti->num_listeners <= 1)
+ TouchEndTouch(dev, ti);
+}
diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c
index a9297f3c8..8950f9766 100644
--- a/xorg-server/dix/window.c
+++ b/xorg-server/dix/window.c
@@ -547,8 +547,7 @@ InitRootWindow(WindowPtr pWin)
(*pScreen->PositionWindow) (pWin, 0, 0);
pWin->cursorIsNone = FALSE;
- pWin->optional->cursor = rootCursor;
- rootCursor->refcnt++;
+ pWin->optional->cursor = RefCursor(rootCursor);
if (party_like_its_1989) {
MakeRootTile(pWin);
@@ -1416,8 +1415,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
else if (pWin->parent && pCursor == wCursor(pWin->parent))
checkOptional = TRUE;
pOldCursor = pWin->optional->cursor;
- pWin->optional->cursor = pCursor;
- pCursor->refcnt++;
+ pWin->optional->cursor = RefCursor(pCursor);
pWin->cursorIsNone = FALSE;
/*
* check on any children now matching the new cursor
@@ -3323,8 +3321,7 @@ MakeWindowOptional(WindowPtr pWin)
parentOptional = FindWindowWithOptional(pWin)->optional;
optional->visual = parentOptional->visual;
if (!pWin->cursorIsNone) {
- optional->cursor = parentOptional->cursor;
- optional->cursor->refcnt++;
+ optional->cursor = RefCursor(parentOptional->cursor);
}
else {
optional->cursor = None;
@@ -3412,8 +3409,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
pNode->cursor = None;
else {
- pNode->cursor = pCursor;
- pCursor->refcnt++;
+ pNode->cursor = RefCursor(pCursor);
}
pNode = pPrev = NULL;
@@ -3421,8 +3417,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
if (pNode->cursor == None) { /* inherited from parent */
- pNode->cursor = pOldCursor;
- pOldCursor->refcnt++;
+ pNode->cursor = RefCursor(pOldCursor);
}
else if (pNode->cursor == pCursor) {
pNode->cursor = None;