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