105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 935c4bbdfSmrgdocumentation, and that the name of Silicon Graphics not be 1035c4bbdfSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1235c4bbdfSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1635c4bbdfSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1735c4bbdfSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1935c4bbdfSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2035c4bbdfSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2135c4bbdfSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <math.h> 3305b261ecSmrg#include <X11/X.h> 3405b261ecSmrg#include <X11/Xproto.h> 3505b261ecSmrg#include <X11/keysym.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "inputstr.h" 3805b261ecSmrg#include "exevents.h" 396747b715Smrg#include "eventstr.h" 4005b261ecSmrg#include <xkbsrv.h> 4105b261ecSmrg#include <ctype.h> 426747b715Smrg#include "events.h" 4305b261ecSmrg 4405b261ecSmrg/***====================================================================***/ 4505b261ecSmrg 4605b261ecSmrgvoid 476747b715SmrgXkbProcessKeyboardEvent(DeviceEvent *event, DeviceIntPtr keybd) 4805b261ecSmrg{ 4935c4bbdfSmrg KeyClassPtr keyc = keybd->key; 5035c4bbdfSmrg XkbSrvInfoPtr xkbi; 5135c4bbdfSmrg int key; 5235c4bbdfSmrg XkbBehavior behavior; 5335c4bbdfSmrg unsigned ndx; 5405b261ecSmrg 556747b715Smrg xkbi = keyc->xkbInfo; 566747b715Smrg key = event->detail.key; 576747b715Smrg if (xkbDebugFlags & 0x8) 5835c4bbdfSmrg DebugF("[xkb] XkbPKE: Key %d %s\n", key, 5935c4bbdfSmrg (event->type == ET_KeyPress ? "down" : "up")); 6005b261ecSmrg 6135c4bbdfSmrg if (xkbi->repeatKey == key && event->type == ET_KeyRelease && 626747b715Smrg !(xkbi->desc->ctrls->enabled_ctrls & XkbRepeatKeysMask)) 6335c4bbdfSmrg AccessXCancelRepeatKey(xkbi, key); 6405b261ecSmrg 656747b715Smrg behavior = xkbi->desc->server->behaviors[key]; 6605b261ecSmrg /* The "permanent" flag indicates a hard-wired behavior that occurs */ 6705b261ecSmrg /* below XKB, such as a key that physically locks. XKB does not */ 6805b261ecSmrg /* do anything to implement the behavior, but it *does* report that */ 6905b261ecSmrg /* key is hardwired */ 7005b261ecSmrg 716747b715Smrg if (!(behavior.type & XkbKB_Permanent)) { 7235c4bbdfSmrg switch (behavior.type) { 7335c4bbdfSmrg case XkbKB_Default: 7435c4bbdfSmrg /* Neither of these should happen in practice, but ignore them 7535c4bbdfSmrg anyway. */ 7635c4bbdfSmrg if (event->type == ET_KeyPress && !event->key_repeat && 7735c4bbdfSmrg key_is_down(keybd, key, KEY_PROCESSED)) 7835c4bbdfSmrg return; 7935c4bbdfSmrg else if (event->type == ET_KeyRelease && 8035c4bbdfSmrg !key_is_down(keybd, key, KEY_PROCESSED)) 8135c4bbdfSmrg return; 8235c4bbdfSmrg break; 8335c4bbdfSmrg case XkbKB_Lock: 8435c4bbdfSmrg if (event->type == ET_KeyRelease) 8535c4bbdfSmrg return; 8635c4bbdfSmrg else if (key_is_down(keybd, key, KEY_PROCESSED)) 8735c4bbdfSmrg event->type = ET_KeyRelease; 8835c4bbdfSmrg break; 8935c4bbdfSmrg case XkbKB_RadioGroup: 9035c4bbdfSmrg ndx = (behavior.data & (~XkbKB_RGAllowNone)); 9135c4bbdfSmrg if (ndx < xkbi->nRadioGroups) { 9235c4bbdfSmrg XkbRadioGroupPtr rg; 9335c4bbdfSmrg 9435c4bbdfSmrg if (event->type == ET_KeyRelease) 956747b715Smrg return; 9635c4bbdfSmrg 9735c4bbdfSmrg rg = &xkbi->radioGroups[ndx]; 9835c4bbdfSmrg if (rg->currentDown == event->detail.key) { 9935c4bbdfSmrg if (behavior.data & XkbKB_RGAllowNone) { 10035c4bbdfSmrg event->type = ET_KeyRelease; 10135c4bbdfSmrg XkbHandleActions(keybd, keybd, event); 10235c4bbdfSmrg rg->currentDown = 0; 10335c4bbdfSmrg } 1046747b715Smrg return; 10535c4bbdfSmrg } 10635c4bbdfSmrg if (rg->currentDown != 0) { 10735c4bbdfSmrg int tmpkey = event->detail.key; 10835c4bbdfSmrg 1096747b715Smrg event->type = ET_KeyRelease; 11035c4bbdfSmrg event->detail.key = rg->currentDown; 11135c4bbdfSmrg XkbHandleActions(keybd, keybd, event); 11235c4bbdfSmrg event->type = ET_KeyPress; 11335c4bbdfSmrg event->detail.key = tmpkey; 11435c4bbdfSmrg } 11535c4bbdfSmrg rg->currentDown = key; 11635c4bbdfSmrg } 11735c4bbdfSmrg else 11835c4bbdfSmrg ErrorF("[xkb] InternalError! Illegal radio group %d\n", ndx); 11935c4bbdfSmrg break; 12035c4bbdfSmrg case XkbKB_Overlay1: 12135c4bbdfSmrg case XkbKB_Overlay2: 12235c4bbdfSmrg { 12335c4bbdfSmrg unsigned which; 1241b5d61b8Smrg unsigned overlay_active_now; 1251b5d61b8Smrg unsigned is_keyrelease = (event->type == ET_KeyRelease) ? 1 : 0; 1261b5d61b8Smrg /* Remembers whether the key was pressed while overlay was down, 1271b5d61b8Smrg * for when overlay is already released, but the key is not. */ 1281b5d61b8Smrg unsigned key_was_overlaid = 0; 12935c4bbdfSmrg 13035c4bbdfSmrg if (behavior.type == XkbKB_Overlay1) 13135c4bbdfSmrg which = XkbOverlay1Mask; 13235c4bbdfSmrg else 13335c4bbdfSmrg which = XkbOverlay2Mask; 1341b5d61b8Smrg overlay_active_now = (xkbi->desc->ctrls->enabled_ctrls & which) ? 1 : 0; 1351b5d61b8Smrg 1361b5d61b8Smrg if ((unsigned char)key == key) { 1371b5d61b8Smrg key_was_overlaid = BitIsOn(xkbi->overlay_perkey_state, key); 1381b5d61b8Smrg if (!is_keyrelease) { 1391b5d61b8Smrg if (overlay_active_now) 1401b5d61b8Smrg SetBit(xkbi->overlay_perkey_state, key); 1411b5d61b8Smrg } else { 1421b5d61b8Smrg if (key_was_overlaid) 1431b5d61b8Smrg ClearBit(xkbi->overlay_perkey_state, key); 1441b5d61b8Smrg } 1451b5d61b8Smrg } 1461b5d61b8Smrg 1471b5d61b8Smrg if ((overlay_active_now || key_was_overlaid) && 1481b5d61b8Smrg (behavior.data >= xkbi->desc->min_key_code) && 1491b5d61b8Smrg (behavior.data <= xkbi->desc->max_key_code)) { 15035c4bbdfSmrg event->detail.key = behavior.data; 15135c4bbdfSmrg } 15235c4bbdfSmrg } 15335c4bbdfSmrg break; 15435c4bbdfSmrg default: 15535c4bbdfSmrg ErrorF("[xkb] unknown key behavior 0x%04x\n", behavior.type); 15635c4bbdfSmrg break; 15735c4bbdfSmrg } 15805b261ecSmrg } 1596747b715Smrg XkbHandleActions(keybd, keybd, event); 16005b261ecSmrg return; 16105b261ecSmrg} 16205b261ecSmrg 16305b261ecSmrgvoid 1646747b715SmrgProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd) 16505b261ecSmrg{ 16605b261ecSmrg 16705b261ecSmrg KeyClassPtr keyc = keybd->key; 16805b261ecSmrg XkbSrvInfoPtr xkbi = NULL; 16905b261ecSmrg ProcessInputProc backup_proc; 17005b261ecSmrg xkbDeviceInfoPtr xkb_priv = XKBDEVICEINFO(keybd); 1716747b715Smrg DeviceEvent *event = &ev->device_event; 1726747b715Smrg int is_press = (event->type == ET_KeyPress); 1736747b715Smrg int is_release = (event->type == ET_KeyRelease); 17405b261ecSmrg 17505b261ecSmrg /* We're only interested in key events. */ 17605b261ecSmrg if (!is_press && !is_release) { 17705b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc); 1786747b715Smrg keybd->public.processInputProc(ev, keybd); 17905b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc, 18005b261ecSmrg xkbUnwrapProc); 18105b261ecSmrg return; 18205b261ecSmrg } 18305b261ecSmrg 1846747b715Smrg xkbi = keyc->xkbInfo; 1856747b715Smrg 18605b261ecSmrg /* If AccessX filters are active, then pass it through to 18705b261ecSmrg * AccessXFilter{Press,Release}Event; else, punt to 18805b261ecSmrg * XkbProcessKeyboardEvent. 18905b261ecSmrg * 19005b261ecSmrg * If AXF[PK]E don't intercept anything (which they probably won't), 19105b261ecSmrg * they'll punt through XPKE anyway. */ 19205b261ecSmrg if ((xkbi->desc->ctrls->enabled_ctrls & XkbAllFilteredEventsMask)) { 19305b261ecSmrg if (is_press) 1946747b715Smrg AccessXFilterPressEvent(event, keybd); 19505b261ecSmrg else if (is_release) 1966747b715Smrg AccessXFilterReleaseEvent(event, keybd); 1976747b715Smrg return; 1986747b715Smrg } 1996747b715Smrg else { 2006747b715Smrg XkbProcessKeyboardEvent(event, keybd); 20105b261ecSmrg } 2026747b715Smrg 20305b261ecSmrg return; 20405b261ecSmrg} 205