1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <math.h> 33#include <X11/X.h> 34#include <X11/Xproto.h> 35#include <X11/keysym.h> 36#include "misc.h" 37#include "inputstr.h" 38#include "exevents.h" 39#include "eventstr.h" 40#include <xkbsrv.h> 41#include <ctype.h> 42#include "events.h" 43 44/***====================================================================***/ 45 46void 47XkbProcessKeyboardEvent(DeviceEvent *event, DeviceIntPtr keybd) 48{ 49KeyClassPtr keyc = keybd->key; 50XkbSrvInfoPtr xkbi; 51int key; 52XkbBehavior behavior; 53unsigned ndx; 54 55 xkbi = keyc->xkbInfo; 56 key = event->detail.key; 57 if (xkbDebugFlags & 0x8) 58 DebugF("[xkb] XkbPKE: Key %d %s\n",key,(event->type == ET_KeyPress?"down":"up")); 59 60 if (xkbi->repeatKey == key && event->type== ET_KeyRelease && 61 !(xkbi->desc->ctrls->enabled_ctrls & XkbRepeatKeysMask)) 62 AccessXCancelRepeatKey(xkbi, key); 63 64 behavior = xkbi->desc->server->behaviors[key]; 65 /* The "permanent" flag indicates a hard-wired behavior that occurs */ 66 /* below XKB, such as a key that physically locks. XKB does not */ 67 /* do anything to implement the behavior, but it *does* report that */ 68 /* key is hardwired */ 69 70 if (!(behavior.type & XkbKB_Permanent)) { 71 switch (behavior.type) { 72 case XkbKB_Default: 73 /* Neither of these should happen in practice, but ignore them 74 anyway. */ 75 if (event->type == ET_KeyPress && !event->key_repeat && 76 key_is_down(keybd, key, KEY_PROCESSED)) 77 return; 78 else if (event->type == ET_KeyRelease && 79 !key_is_down(keybd, key, KEY_PROCESSED)) 80 return; 81 break; 82 case XkbKB_Lock: 83 if (event->type == ET_KeyRelease) 84 return; 85 else if (key_is_down(keybd, key, KEY_PROCESSED)) 86 event->type = ET_KeyRelease; 87 break; 88 case XkbKB_RadioGroup: 89 ndx= (behavior.data&(~XkbKB_RGAllowNone)); 90 if ( ndx<xkbi->nRadioGroups ) { 91 XkbRadioGroupPtr rg; 92 93 if (event->type == ET_KeyRelease) 94 return; 95 96 rg = &xkbi->radioGroups[ndx]; 97 if ( rg->currentDown == event->detail.key) { 98 if (behavior.data&XkbKB_RGAllowNone) { 99 event->type = ET_KeyRelease; 100 XkbHandleActions(keybd, keybd, event); 101 rg->currentDown= 0; 102 } 103 return; 104 } 105 if ( rg->currentDown!=0 ) { 106 int key = event->detail.key; 107 event->type = ET_KeyRelease; 108 event->detail.key = rg->currentDown; 109 XkbHandleActions(keybd, keybd, event); 110 event->type = ET_KeyPress; 111 event->detail.key = key; 112 } 113 rg->currentDown= key; 114 } 115 else ErrorF("[xkb] InternalError! Illegal radio group %d\n",ndx); 116 break; 117 case XkbKB_Overlay1: case XkbKB_Overlay2: 118 { 119 unsigned which; 120 if (behavior.type==XkbKB_Overlay1) which= XkbOverlay1Mask; 121 else which= XkbOverlay2Mask; 122 if ( (xkbi->desc->ctrls->enabled_ctrls&which)==0 ) 123 break; 124 if ((behavior.data>=xkbi->desc->min_key_code)&& 125 (behavior.data<=xkbi->desc->max_key_code)) { 126 event->detail.key = behavior.data; 127 /* 9/11/94 (ef) -- XXX! need to match release with */ 128 /* press even if the state of the */ 129 /* corresponding overlay control */ 130 /* changes while the key is down */ 131 } 132 } 133 break; 134 default: 135 ErrorF("[xkb] unknown key behavior 0x%04x\n",behavior.type); 136 break; 137 } 138 } 139 XkbHandleActions(keybd, keybd, event); 140 return; 141} 142 143void 144ProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd) 145{ 146 147 KeyClassPtr keyc = keybd->key; 148 XkbSrvInfoPtr xkbi = NULL; 149 ProcessInputProc backup_proc; 150 xkbDeviceInfoPtr xkb_priv = XKBDEVICEINFO(keybd); 151 DeviceEvent *event = &ev->device_event; 152 int is_press = (event->type == ET_KeyPress); 153 int is_release = (event->type == ET_KeyRelease); 154 155 /* We're only interested in key events. */ 156 if (!is_press && !is_release) { 157 UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc); 158 keybd->public.processInputProc(ev, keybd); 159 COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc, 160 xkbUnwrapProc); 161 return; 162 } 163 164 xkbi = keyc->xkbInfo; 165 166 /* If AccessX filters are active, then pass it through to 167 * AccessXFilter{Press,Release}Event; else, punt to 168 * XkbProcessKeyboardEvent. 169 * 170 * If AXF[PK]E don't intercept anything (which they probably won't), 171 * they'll punt through XPKE anyway. */ 172 if ((xkbi->desc->ctrls->enabled_ctrls & XkbAllFilteredEventsMask)) { 173 if (is_press) 174 AccessXFilterPressEvent(event, keybd); 175 else if (is_release) 176 AccessXFilterReleaseEvent(event, keybd); 177 return; 178 } 179 else { 180 XkbProcessKeyboardEvent(event, keybd); 181 } 182 183 return; 184} 185