diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2008-08-01 16:32:37 +0930 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@redhat.com> | 2008-08-13 16:43:22 +0930 |
commit | 2fa7edd30d5d48bf6fa83dc179bbf37e55e3b72c (patch) | |
tree | 8a302554b3d32885266a67bcf019a617fae41735 /xkb | |
parent | 50382652afc13021f041c42ae6e8893643ea2bfa (diff) |
xkb: ProcXkbBell should work on all attached SDs.
If called with XkbUseCoreKbd, run through all attached SDs and replicate the
call. This way, we keep the SDs in sync with the MD as long as core clients
control the MDs.
(cherry picked from commit 31afd51dd49c0d0db2465fbc987044fab8b89f22)
Diffstat (limited to 'xkb')
-rw-r--r-- | xkb/xkb.c | 231 |
1 files changed, 140 insertions, 91 deletions
@@ -348,17 +348,119 @@ ProcXkbSelectEvents(ClientPtr client) } /***====================================================================***/ +/** + * Ring a bell on the given device for the given client. + */ +static int +_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, + int bellClass, int bellID, int pitch, int duration, + int percent, int forceSound, int eventOnly, Atom name) +{ + int base; + pointer ctrl; + int oldPitch, oldDuration; + int newPercent; + + if (bellClass == KbdFeedbackClass) { + KbdFeedbackPtr k; + if (bellID==XkbDfltXIId) + k= dev->kbdfeed; + else { + for (k=dev->kbdfeed; k; k=k->next) { + if (k->ctrl.id == bellID) + break; + } + } + if (!k) { + client->errorValue = _XkbErrCode2(0x5,bellID); + return BadValue; + } + base = k->ctrl.bell; + ctrl = (pointer) &(k->ctrl); + oldPitch= k->ctrl.bell_pitch; + oldDuration= k->ctrl.bell_duration; + if (pitch!=0) { + if (pitch==-1) + k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; + else k->ctrl.bell_pitch= pitch; + } + if (duration!=0) { + if (duration==-1) + k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; + else k->ctrl.bell_duration= duration; + } + } + else if (bellClass == BellFeedbackClass) { + BellFeedbackPtr b; + if (bellID==XkbDfltXIId) + b= dev->bell; + else { + for (b=dev->bell; b; b=b->next) { + if (b->ctrl.id == bellID) + break; + } + } + if (!b) { + client->errorValue = _XkbErrCode2(0x6,bellID); + return BadValue; + } + base = b->ctrl.percent; + ctrl = (pointer) &(b->ctrl); + oldPitch= b->ctrl.pitch; + oldDuration= b->ctrl.duration; + if (pitch!=0) { + if (pitch==-1) + b->ctrl.pitch= defaultKeyboardControl.bell_pitch; + else b->ctrl.pitch= pitch; + } + if (duration!=0) { + if (duration==-1) + b->ctrl.duration= defaultKeyboardControl.bell_duration; + else b->ctrl.duration= duration; + } + } + else { + client->errorValue = _XkbErrCode2(0x7, bellClass);; + return BadValue; + } + + newPercent = (base * percent)/100; + if (percent < 0) + newPercent = base + newPercent; + else newPercent = base - newPercent + percent; + + XkbHandleBell(forceSound, eventOnly, + dev, newPercent, ctrl, bellClass, + name, pWin, client); + if ((pitch!=0)||(duration!=0)) { + if (bellClass == KbdFeedbackClass) { + KbdFeedbackPtr k; + k= (KbdFeedbackPtr)ctrl; + if (pitch!=0) + k->ctrl.bell_pitch= oldPitch; + if (duration!=0) + k->ctrl.bell_duration= oldDuration; + } + else { + BellFeedbackPtr b; + b= (BellFeedbackPtr)ctrl; + if (pitch!=0) + b->ctrl.pitch= oldPitch; + if (duration!=0) + b->ctrl.duration= oldDuration; + } + } + + return Success; +} -/* FIXME: Needs to ding on all core-sending devices. */ int ProcXkbBell(ClientPtr client) { REQUEST(xkbBellReq); DeviceIntPtr dev; WindowPtr pWin; - int rc, base; - int newPercent,oldPitch,oldDuration; - pointer ctrl; + int rc; REQUEST_SIZE_MATCH(xkbBellReq); @@ -368,6 +470,7 @@ ProcXkbBell(ClientPtr client) CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); CHK_ATOM_OR_NONE(stuff->name); + /* device-independent checks request for sane values */ if ((stuff->forceSound)&&(stuff->eventOnly)) { client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly); return BadMatch; @@ -390,68 +493,7 @@ ProcXkbBell(ClientPtr client) stuff->bellClass= KbdFeedbackClass; else stuff->bellClass= BellFeedbackClass; } - if (stuff->bellClass == KbdFeedbackClass) { - KbdFeedbackPtr k; - if (stuff->bellID==XkbDfltXIId) - k= dev->kbdfeed; - else { - for (k=dev->kbdfeed; k; k=k->next) { - if (k->ctrl.id == stuff->bellID) - break; - } - } - if (!k) { - client->errorValue= _XkbErrCode2(0x5,stuff->bellID); - return BadValue; - } - base = k->ctrl.bell; - ctrl = (pointer) &(k->ctrl); - oldPitch= k->ctrl.bell_pitch; - oldDuration= k->ctrl.bell_duration; - if (stuff->pitch!=0) { - if (stuff->pitch==-1) - k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; - else k->ctrl.bell_pitch= stuff->pitch; - } - if (stuff->duration!=0) { - if (stuff->duration==-1) - k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; - else k->ctrl.bell_duration= stuff->duration; - } - } - else if (stuff->bellClass == BellFeedbackClass) { - BellFeedbackPtr b; - if (stuff->bellID==XkbDfltXIId) - b= dev->bell; - else { - for (b=dev->bell; b; b=b->next) { - if (b->ctrl.id == stuff->bellID) - break; - } - } - if (!b) { - client->errorValue = _XkbErrCode2(0x6,stuff->bellID); - return BadValue; - } - base = b->ctrl.percent; - ctrl = (pointer) &(b->ctrl); - oldPitch= b->ctrl.pitch; - oldDuration= b->ctrl.duration; - if (stuff->pitch!=0) { - if (stuff->pitch==-1) - b->ctrl.pitch= defaultKeyboardControl.bell_pitch; - else b->ctrl.pitch= stuff->pitch; - } - if (stuff->duration!=0) { - if (stuff->duration==-1) - b->ctrl.duration= defaultKeyboardControl.bell_duration; - else b->ctrl.duration= stuff->duration; - } - } - else { - client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);; - return BadValue; - } + if (stuff->window!=None) { rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) { @@ -461,32 +503,39 @@ ProcXkbBell(ClientPtr client) } else pWin= NULL; - newPercent= (base*stuff->percent)/100; - if (stuff->percent < 0) - newPercent= base+newPercent; - else newPercent= base-newPercent+stuff->percent; - XkbHandleBell(stuff->forceSound, stuff->eventOnly, - dev, newPercent, ctrl, stuff->bellClass, - stuff->name, pWin, client); - if ((stuff->pitch!=0)||(stuff->duration!=0)) { - if (stuff->bellClass == KbdFeedbackClass) { - KbdFeedbackPtr k; - k= (KbdFeedbackPtr)ctrl; - if (stuff->pitch!=0) - k->ctrl.bell_pitch= oldPitch; - if (stuff->duration!=0) - k->ctrl.bell_duration= oldDuration; - } - else { - BellFeedbackPtr b; - b= (BellFeedbackPtr)ctrl; - if (stuff->pitch!=0) - b->ctrl.pitch= oldPitch; - if (stuff->duration!=0) - b->ctrl.duration= oldDuration; - } + /* Client wants to ring a bell on the core keyboard? + Ring the bell on the core keyboard (which does nothing, but if that + fails the client is screwed anyway), and then on all extension devices. + Fail if the core keyboard fails but not the extension devices. this + may cause some keyboards to ding and others to stay silent. Fix + your client to use explicit keyboards to avoid this. + + dev is the device the client requested. + */ + rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, + stuff->pitch, stuff->duration, stuff->percent, + stuff->forceSound, stuff->eventOnly, stuff->name); + + if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || + (stuff->deviceSpec == XkbUseCorePtr))) + { + DeviceIntPtr other; + for (other = inputInfo.devices; other; other = other->next) + { + if ((other != dev) && other->key && other->coreEvents) + { + rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); + if (rc == Success) + _XkbBell(client, other, pWin, stuff->bellClass, + stuff->bellID, stuff->pitch, stuff->duration, + stuff->percent, stuff->forceSound, + stuff->eventOnly, stuff->name); + } + } + rc = Success; /* reset to success, that's what we got for the VCK */ } - return Success; + + return rc; } /***====================================================================***/ |