diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2008-02-18 16:46:07 +1030 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2008-02-18 16:46:07 +1030 |
commit | 088067c891a78670d9509f48f56bf3ff9c16a30d (patch) | |
tree | 1364eb96828ecccaf570a7789ac09daab66b5faf | |
parent | 660739c6bc84cb74f43a277052ce163fae654417 (diff) |
Xi: even if ChangeDeviceHierarchy fails, we may need to send an event.
Changes are committed instantly, so if at least one change was successful, we
must send an event to the client, even if subsequent ones fail.
-rw-r--r-- | Xi/chdevhier.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c index b7495678a..e9a5076a9 100644 --- a/Xi/chdevhier.c +++ b/Xi/chdevhier.c @@ -84,6 +84,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client) int required_len = sizeof(xChangeDeviceHierarchyReq); char n; int rc; + int nchanges = 0; deviceHierarchyChangedEvent ev; REQUEST(xChangeDeviceHierarchyReq); @@ -115,7 +116,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client) if (rc != Success) { xfree(name); - return rc; + goto unwind; } if (!c->sendCore) @@ -130,6 +131,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client) EnableDevice(keybd); } xfree(name); + nchanges++; } break; case CH_RemoveMasterDevice: @@ -143,18 +145,22 @@ ProcXChangeDeviceHierarchy(ClientPtr client) rc = dixLookupDevice(&ptr, r->deviceid, client, DixDestroyAccess); if (rc != Success) - return rc; + goto unwind; if (!ptr->isMaster) { client->errorValue = r->deviceid; - return BadDevice; + rc = BadDevice; + goto unwind; } /* XXX: For now, don't allow removal of VCP, VCK */ if (ptr == inputInfo.pointer || ptr == inputInfo.keyboard) - return BadDevice; + { + rc = BadDevice; + goto unwind; + } /* disable keyboards first */ if (IsPointerDevice(ptr)) @@ -164,7 +170,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client) client, DixDestroyAccess); if (rc != Success) - return rc; + goto unwind; } else { @@ -174,7 +180,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client) client, DixDestroyAccess); if (rc != Success) - return rc; + goto unwind; } @@ -189,23 +195,25 @@ ProcXChangeDeviceHierarchy(ClientPtr client) rc = dixLookupDevice(&newptr, r->returnPointer, client, DixWriteAccess); if (rc != Success) - return rc; + goto unwind; if (!newptr->isMaster) { client->errorValue = r->returnPointer; - return BadDevice; + rc = BadDevice; + goto unwind; } rc = dixLookupDevice(&newkeybd, r->returnKeyboard, client, DixWriteAccess); if (rc != Success) - return rc; + goto unwind; if (!newkeybd->isMaster) { client->errorValue = r->returnKeyboard; - return BadDevice; + rc = BadDevice; + goto unwind; } for (attached = inputInfo.devices; @@ -229,6 +237,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client) RemoveDevice(keybd); RemoveDevice(ptr); + nchanges++; } break; case CH_ChangeAttachment: @@ -238,12 +247,13 @@ ProcXChangeDeviceHierarchy(ClientPtr client) rc = dixLookupDevice(&ptr, c->deviceid, client, DixWriteAccess); if (rc != Success) - return rc; + goto unwind; if (ptr->isMaster) { client->errorValue = c->deviceid; - return BadDevice; + rc = BadDevice; + goto unwind; } if (c->changeMode == Floating) @@ -254,21 +264,25 @@ ProcXChangeDeviceHierarchy(ClientPtr client) rc = dixLookupDevice(&newmaster, c->newMaster, client, DixWriteAccess); if (rc != Success) - return rc; + goto unwind; if (!newmaster->isMaster) { client->errorValue = c->newMaster; - return BadDevice; + rc = BadDevice; + goto unwind; } if ((IsPointerDevice(newmaster) && !IsPointerDevice(ptr)) || (IsKeyboardDevice(newmaster) && !IsKeyboardDevice(ptr))) - return BadDevice; + { + rc = BadDevice; + goto unwind; + } AttachDevice(client, ptr, newmaster); } - + nchanges++; } break; } @@ -276,14 +290,20 @@ ProcXChangeDeviceHierarchy(ClientPtr client) any = (xAnyHierarchyChangeInfo*)((char*)any + any->length); } - ev.type = GenericEvent; - ev.extension = IReqCode; - ev.length = 0; - ev.evtype = XI_DeviceHierarchyChangedNotify; - ev.time = GetTimeInMillis(); +unwind: - SendEventToAllWindows(&dummyDev, XI_DeviceHierarchyChangedMask, - (xEvent*)&ev, 1); - return Success; + if (nchanges > 0) /* even if an error occured, we need to send an event if + we changed anything in the hierarchy. */ + { + ev.type = GenericEvent; + ev.extension = IReqCode; + ev.length = 0; + ev.evtype = XI_DeviceHierarchyChangedNotify; + ev.time = GetTimeInMillis(); + + SendEventToAllWindows(&dummyDev, XI_DeviceHierarchyChangedMask, + (xEvent*)&ev, 1); + } + return rc; } |