1 /*
2 * Copyright 2007-2008 by Sascha Hlusiak. <saschahlusiak@freedesktop.org>
3 * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the names of copyright holders not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. The copyright holders make no
12 * representations about the suitability of this software for any purpose. It
13 * is provided "as is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30
31 #include <xorg-server.h>
32 #include <xf86.h>
33 #include <xf86Xinput.h>
34 #include <X11/extensions/XKBsrv.h>
35 #include <X11/keysym.h>
36 #include <X11/XF86keysym.h>
37 #include <xf86Optrec.h>
38
39 #include "jstk.h"
40 #include "jstk_key.h"
41
42 #include <xkbsrv.h>
43
44 #define MIN_KEYCODE 8
45 #define GLYPHS_PER_KEY 2
46
47 #define AltMask Mod1Mask
48 #define NumLockMask Mod2Mask
49 #define AltLangMask Mod3Mask
50 #define KanaMask Mod4Mask
51 #define ScrollLockMask Mod5Mask
52
53 static void
jstkKbdCtrl(DeviceIntPtr device,KeybdCtrl * ctrl)54 jstkKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
55 {
56 }
57
58
59 /*
60 ***************************************************************************
61 *
62 * jstkInitKeys --
63 *
64 * Sets up the keymap, modmap and the keyboard device structs
65 *
66 ***************************************************************************
67 */
68 static int
jstkInitKeys(DeviceIntPtr pJstk,JoystickDevPtr priv)69 jstkInitKeys(DeviceIntPtr pJstk, JoystickDevPtr priv)
70 {
71 XkbSrvInfoPtr xkbi;
72 XkbControlsPtr ctrls;
73
74 if (!InitKeyboardDeviceStruct(pJstk, &priv->rmlvo, NULL, jstkKbdCtrl))
75 {
76 ErrorF("unable to init keyboard device\n");
77 return !Success;
78 }
79
80 /* Set Autorepeat and Delay */
81 if ((priv->repeat_delay || priv->repeat_interval) &&
82 pJstk->key &&
83 pJstk->key->xkbInfo)
84 {
85 xkbi = pJstk->key->xkbInfo;
86 if (xkbi && xkbi->desc)
87 {
88 ctrls = xkbi->desc->ctrls;
89 ctrls->repeat_delay = priv->repeat_delay;
90 ctrls->repeat_interval = priv->repeat_interval;
91 }
92 }
93
94 return Success;
95 }
96
97
98
99 /*
100 ***************************************************************************
101 *
102 * jstkGenerateKeys
103 *
104 * Generates a series of keydown or keyup events of the specified
105 * KEYSCANCODES
106 *
107 ***************************************************************************
108 */
109 void
jstkGenerateKeys(InputInfoPtr device,KEYSCANCODES keys,char pressed)110 jstkGenerateKeys(InputInfoPtr device, KEYSCANCODES keys, char pressed)
111 {
112 int i;
113 unsigned int k;
114
115 if (device == NULL)
116 return;
117 for (i=0;i<MAXKEYSPERBUTTON;i++) {
118 if (pressed != 0)
119 k = keys[i];
120 else k = keys[MAXKEYSPERBUTTON - i - 1];
121
122 if (k != 0) {
123 DBG(2, ErrorF("Generating key %s event with keycode %d\n",
124 (pressed)?"press":"release", k));
125 xf86PostKeyboardEvent(device->dev, k, pressed);
126 }
127 }
128 }
129
130
131 /*
132 ***************************************************************************
133 *
134 * jstkKeyboardDeviceControlProc --
135 *
136 * Handles the initialization, etc. of the keyboard device
137 *
138 ***************************************************************************
139 */
140 Bool
jstkKeyboardDeviceControlProc(DeviceIntPtr dev,int what)141 jstkKeyboardDeviceControlProc(DeviceIntPtr dev,
142 int what)
143 {
144 InputInfoPtr pInfo = dev->public.devicePrivate;
145 JoystickDevPtr priv = pInfo->private;
146 if (!priv) {
147 DBG(2, ErrorF("jstkKeyboardDeviceControlProc: priv == NULL\n"));
148 return !Success;
149 }
150 switch (what) {
151 case DEVICE_INIT:
152 DBG(2, ErrorF("jstkKeyboardDeviceControlProc what=DEVICE_INIT\n"));
153 if (InitFocusClassDeviceStruct(dev) == FALSE) {
154 ErrorF("unable to init Focus class device\n");
155 return !Success;
156 }
157 if (jstkInitKeys(dev, priv) != Success)
158 return !Success;
159 break;
160 case DEVICE_ON:
161 DBG(2, ErrorF("jstkKeyboardDeviceControlProc what=DEVICE_ON\n"));
162 dev->public.on = TRUE;
163 break;
164 case DEVICE_OFF:
165 DBG(2, ErrorF("jstkKeyboardDeviceControlProc what=DEVICE_OFF\n"));
166 dev->public.on = FALSE;
167 break;
168 case DEVICE_CLOSE:
169 DBG(2, ErrorF("jstkKeyboardDeviceControlProc what=DEVICE_CLOSE\n"));
170 dev->public.on = FALSE;
171 break;
172 default:
173 return BadValue;
174 }
175
176 return Success;
177 }
178
179
180 /*
181 ***************************************************************************
182 *
183 * jstkKeyboardPreInit --
184 *
185 * See comment in jstkCorePreInit() for details.
186 *
187 ***************************************************************************
188 */
189
jstkKeyboardPreInit(InputDriverPtr drv,InputInfoPtr pInfo,int flags)190 int jstkKeyboardPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
191 {
192 JoystickDevPtr priv = NULL;
193 char *s;
194
195 pInfo->private = priv = calloc(1, sizeof(JoystickDevRec));
196 if (!priv)
197 return BadAlloc;
198
199 pInfo->device_control = jstkKeyboardDeviceControlProc;
200 pInfo->read_input = NULL;
201 pInfo->control_proc = NULL;
202 pInfo->switch_mode = NULL;
203 if (!(pInfo->flags & XI86_SERVER_FD))
204 pInfo->fd = -1;
205 pInfo->type_name = XI_JOYSTICK;
206
207 /* parse keyboard-related options */
208 priv->repeat_delay = 0;
209 priv->repeat_interval = 0;
210
211 /* Parse option for autorepeat */
212 if ((s = xf86SetStrOption(pInfo->options, "AutoRepeat", NULL))) {
213 int delay, rate;
214 if (sscanf(s, "%d %d", &delay, &rate) != 2) {
215 xf86Msg(X_ERROR, "%s: \"%s\" is not a valid AutoRepeat value",
216 pInfo->name, s);
217 } else {
218 priv->repeat_delay = delay;
219 if (rate != 0)
220 priv->repeat_interval = 1000/rate;
221 else priv->repeat_interval = 0;
222 DBG(1, xf86Msg(X_CONFIG, "Autorepeat set to delay=%d, interval=%d\n",
223 priv->repeat_delay,priv->repeat_interval));
224 }
225 free(s);
226 }
227
228 priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", NULL);
229 if (!priv->rmlvo.rules)
230 priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "XkbRules", "evdev");
231
232 priv->rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", NULL);
233 if (!priv->rmlvo.model)
234 priv->rmlvo.model = xf86SetStrOption(pInfo->options, "XkbModel", "evdev");
235
236 priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", NULL);
237 if (!priv->rmlvo.layout)
238 priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "XkbLayout", "us");
239
240 priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", NULL);
241 if (!priv->rmlvo.variant)
242 priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "XkbVariant", "");
243
244 priv->rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", NULL);
245 if (!priv->rmlvo.options)
246 priv->rmlvo.options = xf86SetStrOption(pInfo->options, "XkbOptions", "");
247
248 return Success;
249 }
250
251 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 14
252 static InputOption*
input_option_new(InputOption * list,char * key,char * value)253 input_option_new(InputOption* list, char *key, char *value)
254 {
255 InputOption *tmp;
256
257 tmp = calloc(1, sizeof(*tmp));
258 tmp->key = key;
259 tmp->value = value;
260 tmp->next = list;
261
262 return tmp;
263 }
264
265 static void
input_option_free_list(InputOption ** list)266 input_option_free_list(InputOption **list)
267 {
268 InputOption *iopts = *list;
269
270 while(iopts)
271 {
272 InputOption *tmp = iopts->next;
273 free(iopts->key);
274 free(iopts->value);
275 free(iopts);
276 iopts = tmp;
277 }
278
279 *list = NULL;
280 }
281
282 #endif
283
284 InputInfoPtr
jstkKeyboardHotplug(InputInfoPtr pInfo,int flags)285 jstkKeyboardHotplug(InputInfoPtr pInfo, int flags)
286 {
287 int rc;
288 char name[512] = {0};
289 InputAttributes *attrs = NULL;
290 InputOption *iopts = NULL;
291 DeviceIntPtr dev;
292 XF86OptionPtr opts;
293
294 /* duplicate option list, append to name */
295 opts = xf86OptionListDuplicate(pInfo->options);
296 strcpy(name, pInfo->name);
297 strcat(name, " (keys)");
298 opts = xf86ReplaceStrOption(opts, "Name", name);
299 opts = xf86ReplaceStrOption(opts, "_source", "_driver/joystick");
300 opts = xf86AddNewOption(opts, "Driver", pInfo->driver);
301
302 while(opts)
303 {
304 iopts = input_option_new(iopts,
305 xf86OptionName(opts),
306 xf86OptionValue(opts));
307 opts = xf86NextOption(opts);
308 }
309
310 /* duplicate attribute list */
311 attrs = DuplicateInputAttributes(pInfo->attrs);
312
313 rc = NewInputDeviceRequest(iopts, attrs, &dev);
314
315 input_option_free_list(&iopts);
316
317 FreeInputAttributes(attrs);
318
319 return (rc == Success) ? dev->public.devicePrivate : NULL;
320 }
321
322
323 /*
324 ***************************************************************************
325 *
326 * jstkKeyboardUnInit --
327 *
328 * Called when the keyboard slave device gets removed
329 *
330 ***************************************************************************
331 */
332 void
jstkKeyboardUnInit(InputDriverPtr drv,InputInfoPtr pInfo,int flags)333 jstkKeyboardUnInit(InputDriverPtr drv,
334 InputInfoPtr pInfo,
335 int flags)
336 {
337 JoystickDevPtr device = (JoystickDevPtr) pInfo->private;
338 DBG(2, ErrorF("jstkKeyboardUnInit.\n"));
339
340 device->keyboard_device = NULL;
341 pInfo->private = NULL;
342
343 xf86DeleteInput(pInfo, 0);
344 }
345
346