xkbPrKeyEv.c revision 35c4bbdf
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; 12435c4bbdfSmrg 12535c4bbdfSmrg if (behavior.type == XkbKB_Overlay1) 12635c4bbdfSmrg which = XkbOverlay1Mask; 12735c4bbdfSmrg else 12835c4bbdfSmrg which = XkbOverlay2Mask; 12935c4bbdfSmrg if ((xkbi->desc->ctrls->enabled_ctrls & which) == 0) 13035c4bbdfSmrg break; 13135c4bbdfSmrg if ((behavior.data >= xkbi->desc->min_key_code) && 13235c4bbdfSmrg (behavior.data <= xkbi->desc->max_key_code)) { 13335c4bbdfSmrg event->detail.key = behavior.data; 13435c4bbdfSmrg /* 9/11/94 (ef) -- XXX! need to match release with */ 13535c4bbdfSmrg /* press even if the state of the */ 13635c4bbdfSmrg /* corresponding overlay control */ 13735c4bbdfSmrg /* changes while the key is down */ 13835c4bbdfSmrg } 13935c4bbdfSmrg } 14035c4bbdfSmrg break; 14135c4bbdfSmrg default: 14235c4bbdfSmrg ErrorF("[xkb] unknown key behavior 0x%04x\n", behavior.type); 14335c4bbdfSmrg break; 14435c4bbdfSmrg } 14505b261ecSmrg } 1466747b715Smrg XkbHandleActions(keybd, keybd, event); 14705b261ecSmrg return; 14805b261ecSmrg} 14905b261ecSmrg 15005b261ecSmrgvoid 1516747b715SmrgProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd) 15205b261ecSmrg{ 15305b261ecSmrg 15405b261ecSmrg KeyClassPtr keyc = keybd->key; 15505b261ecSmrg XkbSrvInfoPtr xkbi = NULL; 15605b261ecSmrg ProcessInputProc backup_proc; 15705b261ecSmrg xkbDeviceInfoPtr xkb_priv = XKBDEVICEINFO(keybd); 1586747b715Smrg DeviceEvent *event = &ev->device_event; 1596747b715Smrg int is_press = (event->type == ET_KeyPress); 1606747b715Smrg int is_release = (event->type == ET_KeyRelease); 16105b261ecSmrg 16205b261ecSmrg /* We're only interested in key events. */ 16305b261ecSmrg if (!is_press && !is_release) { 16405b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc); 1656747b715Smrg keybd->public.processInputProc(ev, keybd); 16605b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc, 16705b261ecSmrg xkbUnwrapProc); 16805b261ecSmrg return; 16905b261ecSmrg } 17005b261ecSmrg 1716747b715Smrg xkbi = keyc->xkbInfo; 1726747b715Smrg 17305b261ecSmrg /* If AccessX filters are active, then pass it through to 17405b261ecSmrg * AccessXFilter{Press,Release}Event; else, punt to 17505b261ecSmrg * XkbProcessKeyboardEvent. 17605b261ecSmrg * 17705b261ecSmrg * If AXF[PK]E don't intercept anything (which they probably won't), 17805b261ecSmrg * they'll punt through XPKE anyway. */ 17905b261ecSmrg if ((xkbi->desc->ctrls->enabled_ctrls & XkbAllFilteredEventsMask)) { 18005b261ecSmrg if (is_press) 1816747b715Smrg AccessXFilterPressEvent(event, keybd); 18205b261ecSmrg else if (is_release) 1836747b715Smrg AccessXFilterReleaseEvent(event, keybd); 1846747b715Smrg return; 1856747b715Smrg } 1866747b715Smrg else { 1876747b715Smrg XkbProcessKeyboardEvent(event, keybd); 18805b261ecSmrg } 1896747b715Smrg 19005b261ecSmrg return; 19105b261ecSmrg} 192