1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | #include <errno(*__error()).h> |
33 | #include <fcntl.h> |
34 | #include <stdlib.h> |
35 | #include <stdio.h> |
36 | #include <string.h> |
37 | #include <unistd.h> |
38 | |
39 | #include <xorg-server.h> |
40 | #include <fb.h> |
41 | #include <micmap.h> |
42 | #include <mipointer.h> |
43 | #include <shadow.h> |
44 | #include <xf86.h> |
45 | #include <xf86Module.h> |
46 | #include <xf86str.h> |
47 | #include <xf86_OSproc.h> |
48 | #include <xkbsrv.h> |
49 | |
50 | #ifdef HAVE_CONFIG_H1 |
51 | #include "config.h" |
52 | #endif |
53 | |
54 | #include "client.h" |
55 | #include "nested_input.h" |
56 | |
57 | #define SYSCALL(call)while (((call) == -1) && ((*__error()) == 4)) while (((call) == -1) && (errno(*__error()) == EINTR4)) |
58 | |
59 | #define NUM_MOUSE_BUTTONS6 6 |
60 | #define NUM_MOUSE_AXES2 2 |
61 | |
62 | static pointer |
63 | NestedInputPlug(pointer module, pointer options, int *errmaj, int *errmin); |
64 | static void |
65 | NestedInputUnplug(pointer p); |
66 | |
67 | static void |
68 | NestedInputReadInput(InputInfoPtr pInfo); |
69 | static int |
70 | NestedInputControl(DeviceIntPtr device,int what); |
71 | |
72 | static int |
73 | _nested_input_init_keyboard(DeviceIntPtr device); |
74 | static int |
75 | _nested_input_init_buttons(DeviceIntPtr device); |
76 | static int |
77 | _nested_input_init_axes(DeviceIntPtr device); |
78 | |
79 | typedef struct _NestedInputDeviceRec { |
80 | NestedClientPrivatePtr clientData; |
81 | int version; |
82 | } NestedInputDeviceRec, *NestedInputDevicePtr; |
83 | |
84 | static XF86ModuleVersionInfo NestedInputVersionRec = { |
85 | "nestedinput", |
86 | MODULEVENDORSTRING"X.Org Foundation", |
87 | MODINFOSTRING10xef23fdc5, |
88 | MODINFOSTRING20x10dc023a, |
89 | XORG_VERSION_CURRENT(((1) * 10000000) + ((18) * 100000) + ((99) * 1000) + 1), |
90 | PACKAGE_VERSION_MAJOR0, PACKAGE_VERSION_MINOR1, |
91 | PACKAGE_VERSION_PATCHLEVEL0, |
92 | ABI_CLASS_XINPUT"X.Org XInput driver", |
93 | ABI_XINPUT_VERSION((((22) << 16) & 0xFFFF0000) | ((1) & 0x0000FFFF )), |
94 | MOD_CLASS_XINPUT"X.Org XInput Driver", |
95 | {0, 0, 0, 0} |
96 | }; |
97 | |
98 | _X_EXPORT__attribute__((visibility("default"))) XF86ModuleData nestedInputModuleData = { |
99 | &NestedInputVersionRec, |
100 | &NestedInputPlug, |
101 | &NestedInputUnplug |
102 | }; |
103 | |
104 | int |
105 | NestedInputPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { |
106 | NestedInputDevicePtr pNestedInput; |
107 | |
108 | pNestedInput = calloc(1, sizeof(NestedInputDeviceRec)); |
109 | |
110 | if (!pNestedInput) |
111 | return BadAlloc11; |
112 | |
113 | pInfo->private = pNestedInput; |
114 | pInfo->type_name = XI_MOUSE"MOUSE"; |
115 | pInfo->read_input = NestedInputReadInput; |
116 | pInfo->switch_mode = NULL((void*)0); |
117 | pInfo->device_control = NestedInputControl; |
118 | |
119 | return Success0; |
120 | } |
121 | |
122 | void |
123 | NestedInputUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { |
124 | } |
125 | |
126 | static pointer |
127 | NestedInputPlug(pointer module, pointer options, int *errmaj, int *errmin) { |
128 | return NULL((void*)0); |
129 | } |
130 | |
131 | static void |
132 | NestedInputUnplug(pointer p) { |
133 | } |
134 | |
135 | static void |
136 | NestedInputUpdateKeymap(DeviceIntPtr device) { |
137 | InputInfoPtr pInfo = device->public.devicePrivate; |
138 | NestedInputDevicePtr pNestedInput = pInfo->private; |
139 | KeySymsRec keySyms; |
140 | XkbControlsRec ctrls; |
141 | CARD8 modmap[MAP_LENGTH256]; |
142 | |
143 | if(!NestedClientGetKeyboardMappings(pNestedInput->clientData, &keySyms, modmap, &ctrls)) { |
144 | xf86Msg(X_ERROR, "%s: Failed to get keyboard mappings.\n", pInfo->name); |
145 | return; |
146 | } |
147 | |
148 | #ifdef _XSERVER641 |
149 | { |
150 | unsigned long *keymap64 = (unsigned long *)keySyms.map; |
151 | size_t len = (keySyms.maxKeyCode - keySyms.minKeyCode + 1) * keySyms.mapWidth; |
152 | size_t i; |
153 | |
154 | keySyms.map = malloc(len * sizeof(KeySym)); |
155 | if (!keySyms.map) { |
156 | xf86Msg(X_ERROR, "%s: Failed to get keyboard mappings.\n", pInfo->name); |
157 | free(keymap64); |
158 | return; |
159 | } |
160 | |
161 | for(i = 0; i < len; ++i) |
162 | keySyms.map[i] = keymap64[i]; |
163 | free(keymap64); |
164 | } |
165 | #endif |
166 | |
167 | XkbApplyMappingChange(device, &keySyms, keySyms.minKeyCode, |
168 | keySyms.maxKeyCode - keySyms.minKeyCode + 1, |
169 | modmap, serverClient); |
170 | XkbDDXChangeControls(device, &ctrls, &ctrls); |
171 | |
172 | free(keySyms.map); |
173 | |
174 | if (inputInfo.keyboard != device) |
175 | XkbCopyDeviceKeymap(inputInfo.keyboard, device); |
176 | } |
177 | |
178 | static int |
179 | _nested_input_init_keyboard(DeviceIntPtr device) { |
180 | InputInfoPtr pInfo = device->public.devicePrivate; |
181 | |
182 | if (!InitKeyboardDeviceStruct(device, NULL((void*)0), NULL((void*)0), NULL((void*)0))) { |
183 | xf86Msg(X_ERROR, "%s: Failed to register keyboard.\n", pInfo->name); |
184 | return BadAlloc11; |
185 | } |
186 | |
187 | return Success0; |
188 | } |
189 | static int |
190 | _nested_input_init_buttons(DeviceIntPtr device) { |
191 | InputInfoPtr pInfo = device->public.devicePrivate; |
192 | CARD8 *map; |
193 | Atom buttonLabels[NUM_MOUSE_BUTTONS6] = {0}; |
194 | |
195 | map = calloc(NUM_MOUSE_BUTTONS6, sizeof(CARD8)); |
196 | |
197 | int i; |
198 | for (i = 0; i < NUM_MOUSE_BUTTONS6; i++) |
199 | map[i] = i; |
200 | |
201 | if (!InitButtonClassDeviceStruct(device, NUM_MOUSE_BUTTONS6, buttonLabels, map)) { |
202 | xf86Msg(X_ERROR, "%s: Failed to register buttons.\n", pInfo->name); |
203 | |
204 | free(map); |
205 | return BadAlloc11; |
206 | } |
207 | |
208 | return Success0; |
209 | } |
210 | |
211 | static int |
212 | _nested_input_init_axes(DeviceIntPtr device) { |
213 | if (!InitValuatorClassDeviceStruct(device, |
214 | NUM_MOUSE_AXES2, |
215 | (Atom*)GetMotionHistory, |
216 | GetMotionHistorySize(), |
217 | (Atom)0)) { |
218 | return BadAlloc11; |
219 | } |
220 | |
221 | int i; |
222 | for (i = 0; i < NUM_MOUSE_AXES2; i++) { |
223 | xf86InitValuatorAxisStruct(device, i, (Atom)0, -1, -1, 1, 1, 1, Absolute1); |
224 | xf86InitValuatorDefaults(device, i); |
225 | } |
226 | |
227 | return Success0; |
228 | } |
229 | |
230 | static CARD32 |
231 | nested_input_on(OsTimerPtr timer, CARD32 time, pointer arg) { |
232 | DeviceIntPtr device = arg; |
233 | InputInfoPtr pInfo = device->public.devicePrivate; |
234 | NestedInputDevicePtr pNestedInput = pInfo->private; |
235 | |
236 | if(device->public.on) |
237 | { |
238 | pInfo->fd = NestedClientGetFileDescriptor(pNestedInput->clientData); |
239 | xf86FlushInput(pInfo->fd); |
240 | xf86AddEnabledDevice(pInfo); |
241 | } |
242 | return 0; |
243 | } |
244 | |
245 | static int |
246 | NestedInputControl(DeviceIntPtr device, int what) { |
247 | int err; |
248 | InputInfoPtr pInfo = device->public.devicePrivate; |
249 | |
250 | switch (what) { |
251 | case DEVICE_INIT0: |
252 | err = _nested_input_init_keyboard(device); |
253 | if (err != Success0) |
254 | return err; |
255 | |
256 | err = _nested_input_init_buttons(device); |
257 | if (err != Success0) |
258 | return err; |
259 | |
260 | err = _nested_input_init_axes(device); |
261 | if (err != Success0) |
262 | return err; |
263 | |
264 | break; |
265 | case DEVICE_ON1: |
266 | xf86Msg(X_INFO, "%s: On.\n", pInfo->name); |
267 | |
268 | if (device->public.on) |
269 | break; |
270 | |
271 | device->public.on = TRUE1; |
272 | TimerSet(NULL((void*)0), 0, 1, nested_input_on, device); |
273 | break; |
274 | case DEVICE_OFF2: |
275 | xf86Msg(X_INFO, "%s: Off.\n", pInfo->name); |
276 | |
277 | if (!device->public.on) |
278 | break; |
279 | |
280 | xf86RemoveEnabledDevice(pInfo); |
281 | |
282 | pInfo->fd = -1; |
283 | device->public.on = FALSE0; |
284 | break; |
285 | case DEVICE_CLOSE3: |
286 | break; |
287 | } |
288 | |
289 | return Success0; |
290 | } |
291 | |
292 | static CARD32 |
293 | nested_input_ready(OsTimerPtr timer, CARD32 time, pointer arg) { |
294 | NestedClientPrivatePtr clientData = arg; |
295 | NestedClientCheckEvents(clientData); |
296 | return 0; |
297 | } |
298 | |
299 | static void |
300 | NestedInputReadInput(InputInfoPtr pInfo) { |
301 | NestedInputDevicePtr pNestedInput = pInfo->private; |
302 | TimerSet(NULL((void*)0), 0, 1, nested_input_ready, pNestedInput->clientData); |
303 | } |
304 | |
305 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION)(((((((22) << 16) & 0xFFFF0000) | ((1) & 0x0000FFFF ))) & 0xFFFF0000) >> 16) < 14 |
306 | static InputOption* |
307 | input_option_new(InputOption* list, char *key, char *value) |
308 | { |
309 | InputOption *tmp; |
310 | |
311 | tmp = calloc(1, sizeof(*tmp)); |
312 | tmp->key = key; |
313 | tmp->value = value; |
314 | tmp->next = list; |
315 | |
316 | return tmp; |
317 | } |
318 | |
319 | static void |
320 | input_option_free_list(InputOption **list) |
321 | { |
322 | InputOption *iopts = *list; |
323 | |
324 | while(iopts) |
325 | { |
326 | InputOption *tmp = iopts->next; |
327 | free(iopts->key); |
328 | free(iopts->value); |
329 | free(iopts); |
330 | iopts = tmp; |
331 | } |
332 | |
333 | *list = NULL((void*)0); |
334 | } |
335 | #endif |
336 | |
337 | |
338 | void |
339 | NestedInputLoadDriver(NestedClientPrivatePtr clientData) { |
340 | DeviceIntPtr dev; |
341 | InputInfoPtr pInfo; |
342 | NestedInputDevicePtr pNestedInput; |
343 | |
344 | |
345 | InputOption* options = NULL((void*)0); |
346 | options = input_option_new(options, strdup("identifier"), strdup("nestedinput")); |
347 | options = input_option_new(options, strdup("driver"), strdup("nestedinput")); |
| |
| |
348 | |
349 | |
350 | |
351 | int ret = NewInputDeviceRequest(options, NULL((void*)0), &dev); |
352 | |
353 | input_option_free_list(&options); |
354 | |
355 | if (ret != Success0) { |
356 | FatalError("Failed to load input driver.\n"); |
357 | } |
358 | |
359 | pInfo = dev->public.devicePrivate; |
360 | pNestedInput = pInfo->private; |
361 | pNestedInput->clientData = clientData; |
362 | |
363 | |
364 | NestedInputUpdateKeymap(dev); |
365 | |
366 | |
367 | |
368 | NestedClientSetDevicePtr(clientData, dev); |
369 | } |
370 | |
371 | void |
372 | NestedInputPostMouseMotionEvent(DeviceIntPtr dev, int x, int y) { |
373 | xf86PostMotionEvent(dev, TRUE1, 0, 2, x, y); |
374 | } |
375 | |
376 | void |
377 | NestedInputPostButtonEvent(DeviceIntPtr dev, int button, int isDown) { |
378 | xf86PostButtonEvent(dev, 0, button, isDown, 0, 0); |
379 | } |
380 | |
381 | void |
382 | NestedInputPostKeyboardEvent(DeviceIntPtr dev, unsigned int keycode, int isDown) { |
383 | xf86PostKeyboardEvent(dev, keycode, isDown); |
384 | } |