VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/vboxmouse/vboxmouse.c@ 39811

Last change on this file since 39811 was 39811, checked in by vboxsync, 13 years ago

Additions/x11/vboxmouse: filename clean-up.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 10.5 KB
Line 
1/** @file
2 * VirtualBox X11 Guest Additions, mouse driver for X.Org server 1.5
3 */
4
5/*
6 * Copyright (C) 2006-2007 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 * --------------------------------------------------------------------
16 *
17 * This code is based on evdev.c from X.Org with the following copyright
18 * and permission notice:
19 *
20 * Copyright © 2004-2008 Red Hat, Inc.
21 *
22 * Permission to use, copy, modify, distribute, and sell this software
23 * and its documentation for any purpose is hereby granted without
24 * fee, provided that the above copyright notice appear in all copies
25 * and that both that copyright notice and this permission notice
26 * appear in supporting documentation, and that the name of Red Hat
27 * not be used in advertising or publicity pertaining to distribution
28 * of the software without specific, written prior permission. Red
29 * Hat makes no representations about the suitability of this software
30 * for any purpose. It is provided "as is" without express or implied
31 * warranty.
32 *
33 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
34 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
35 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
36 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
37 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
38 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
39 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40 *
41 * Authors:
42 * Kristian Høgsberg ([email protected])
43 * Adam Jackson ([email protected])
44 */
45
46#include <VBox/VMMDev.h>
47#include <VBox/VBoxGuestLib.h>
48#include <iprt/err.h>
49#include <xf86.h>
50#include <xf86Xinput.h>
51#include <mipointer.h>
52
53#include <xf86Module.h>
54
55#ifdef VBOX_GUESTR3XF86MOD
56# define _X_EXPORT
57#else
58# include <errno.h>
59# include <fcntl.h>
60# include <unistd.h>
61#endif
62
63#include "product-generated.h"
64
65enum
66{
67 /** The minumum value our device can return */
68 RANGE_MIN = 0,
69 /** The maximum value our device can return */
70 RANGE_MAX = 0xFFFF
71};
72
73static void
74VBoxReadInput(InputInfoPtr pInfo)
75{
76 uint32_t cx, cy, fFeatures;
77
78 /* Read a byte from the device to acknowledge the event */
79 char c;
80 read(pInfo->fd, &c, 1);
81 /* The first test here is a workaround for an apparent bug in Xorg Server 1.5 */
82 if (
83#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 2
84 miPointerCurrentScreen() != NULL
85#else
86 miPointerGetScreen(pInfo->dev) != NULL
87#endif
88 && RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy))
89 && (fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
90 {
91#if ABI_XINPUT_VERSION == SET_ABI_VERSION(2, 0)
92 /* Bug in the 1.4 X server series - conversion_proc was no longer
93 * called, but the server didn't yet do the conversion itself. */
94 cx = (cx * screenInfo.screens[0]->width) / 65535;
95 cy = (cy * screenInfo.screens[0]->height) / 65535;
96#endif
97 /* send absolute movement */
98 xf86PostMotionEvent(pInfo->dev, 1, 0, 2, cx, cy);
99 }
100}
101
102static void
103VBoxPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
104{
105 /* Nothing to do, dix handles all settings */
106}
107
108static int
109VBoxInit(DeviceIntPtr device)
110{
111 CARD8 map[2] = { 0, 1 };
112 Atom axis_labels[2] = { 0, 0 };
113 Atom button_labels[2] = { 0, 0 };
114 if (!InitPointerDeviceStruct((DevicePtr)device, map, 2,
115#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
116 button_labels,
117#endif
118#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 2
119 miPointerGetMotionEvents, VBoxPtrCtrlProc,
120 miPointerGetMotionBufferSize()
121#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
122 GetMotionHistory, VBoxPtrCtrlProc,
123 GetMotionHistorySize(), 2 /* Number of axes */
124
125#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
126 VBoxPtrCtrlProc, GetMotionHistorySize(),
127 2 /* Number of axes */
128#else
129# error Unsupported version of X.Org
130#endif
131#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
132 , axis_labels
133#endif
134 ))
135 return !Success;
136
137 /* Tell the server about the range of axis values we report */
138#if ABI_XINPUT_VERSION <= SET_ABI_VERSION(2, 0)
139 xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1);
140 xf86InitValuatorAxisStruct(device, 1, 0, -1, 1, 0, 1);
141#else
142 xf86InitValuatorAxisStruct(device, 0,
143# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
144 axis_labels[0],
145# endif
146 RANGE_MIN /* min X */, RANGE_MAX /* max X */,
147 10000, 0, 10000
148# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
149 , Absolute
150# endif
151 );
152
153 xf86InitValuatorAxisStruct(device, 1,
154# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
155 axis_labels[1],
156# endif
157 RANGE_MIN /* min Y */, RANGE_MAX /* max Y */,
158 10000, 0, 10000
159# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
160 , Absolute
161# endif
162 );
163#endif
164 xf86InitValuatorDefaults(device, 0);
165 xf86InitValuatorDefaults(device, 1);
166 xf86MotionHistoryAllocate(device->public.devicePrivate);
167
168 return Success;
169}
170
171static int
172VBoxProc(DeviceIntPtr device, int what)
173{
174 InputInfoPtr pInfo;
175 int rc, xrc;
176 uint32_t fFeatures = 0;
177
178 pInfo = device->public.devicePrivate;
179
180 switch (what)
181 {
182 case DEVICE_INIT:
183 xrc = VBoxInit(device);
184 if (xrc != Success) {
185 VbglR3Term();
186 return xrc;
187 }
188 break;
189
190 case DEVICE_ON:
191 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
192 if (device->public.on)
193 break;
194 /* Tell the host that we want absolute co-ordinates */
195 rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
196 if (RT_SUCCESS(rc))
197 rc = VbglR3SetMouseStatus( fFeatures
198 | VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
199 | VMMDEV_MOUSE_NEW_PROTOCOL);
200 if (!RT_SUCCESS(rc)) {
201 xf86Msg(X_ERROR, "%s: Failed to switch guest mouse into absolute mode\n",
202 pInfo->name);
203 return !Success;
204 }
205
206 xf86AddEnabledDevice(pInfo);
207 device->public.on = TRUE;
208 break;
209
210 case DEVICE_OFF:
211 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
212 rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
213 if (RT_SUCCESS(rc))
214 rc = VbglR3SetMouseStatus( fFeatures
215 & ~VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
216 & ~VMMDEV_MOUSE_NEW_PROTOCOL);
217 xf86RemoveEnabledDevice(pInfo);
218 device->public.on = FALSE;
219 break;
220
221 case DEVICE_CLOSE:
222 VbglR3Term();
223 xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
224 break;
225
226 default:
227 return BadValue;
228 }
229
230 return Success;
231}
232
233static int
234VBoxProbe(InputInfoPtr pInfo)
235{
236 int rc = VbglR3Init();
237 if (!RT_SUCCESS(rc)) {
238 xf86Msg(X_ERROR, "%s: Failed to open the VirtualBox device (error %d)\n",
239 pInfo->name, rc);
240 return BadMatch;
241 }
242
243 return Success;
244}
245
246static Bool
247VBoxConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
248 int v3, int v4, int v5, int *x, int *y)
249{
250 if (first == 0) {
251 *x = xf86ScaleAxis(v0, 0, screenInfo.screens[0]->width, 0, 65536);
252 *y = xf86ScaleAxis(v1, 0, screenInfo.screens[0]->height, 0, 65536);
253 return TRUE;
254 } else
255 return FALSE;
256}
257
258static int
259VBoxPreInitInfo(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
260{
261 const char *device;
262 int rc;
263
264 /* Initialise the InputInfoRec. */
265 pInfo->device_control = VBoxProc;
266 pInfo->read_input = VBoxReadInput;
267 /* Unlike evdev, we set this unconditionally, as we don't handle keyboards. */
268 pInfo->type_name = XI_MOUSE;
269 pInfo->flags |= XI86_ALWAYS_CORE;
270
271 device = xf86SetStrOption(pInfo->options, "Device",
272 "/dev/vboxguest");
273
274 xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
275 do {
276 pInfo->fd = open(device, O_RDWR, 0);
277 }
278 while (pInfo->fd < 0 && errno == EINTR);
279
280 if (pInfo->fd < 0) {
281 xf86Msg(X_ERROR, "Unable to open VirtualBox device \"%s\".\n", device);
282 return BadMatch;
283 }
284
285 rc = VBoxProbe(pInfo);
286 if (rc != Success)
287 return rc;
288
289 return Success;
290}
291
292#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
293static InputInfoPtr
294VBoxPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
295{
296 InputInfoPtr pInfo;
297 const char *device;
298
299 if (!(pInfo = xf86AllocateInput(drv, 0)))
300 return NULL;
301
302 /* Initialise the InputInfoRec. */
303 pInfo->name = dev->identifier;
304 pInfo->conf_idev = dev;
305 pInfo->conversion_proc = VBoxConvert;
306 pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
307
308 xf86CollectInputOptions(pInfo, NULL, NULL);
309 xf86ProcessCommonOptions(pInfo, pInfo->options);
310
311 if (VBoxPreInitInfo(drv, pInfo, flags) != Success) {
312 xf86DeleteInput(pInfo, 0);
313 return NULL;
314 }
315
316 pInfo->flags |= XI86_CONFIGURED;
317 return pInfo;
318}
319#endif
320
321_X_EXPORT InputDriverRec VBOXMOUSE = {
322 1,
323 "vboxmouse",
324 NULL,
325#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
326 VBoxPreInit,
327#else
328 VBoxPreInitInfo,
329#endif
330 NULL,
331 NULL,
332 0
333};
334
335static pointer
336VBoxPlug(pointer module,
337 pointer options,
338 int *errmaj,
339 int *errmin)
340{
341 xf86AddInputDriver(&VBOXMOUSE, module, 0);
342 xf86Msg(X_CONFIG, "Load address of symbol \"VBOXMOUSE\" is %p\n",
343 (void *)&VBOXMOUSE);
344 return module;
345}
346
347static XF86ModuleVersionInfo VBoxVersionRec =
348{
349 "vboxmouse",
350 VBOX_VENDOR,
351 MODINFOSTRING1,
352 MODINFOSTRING2,
353 0, /* Missing from SDK: XORG_VERSION_CURRENT, */
354 1, 0, 0,
355 ABI_CLASS_XINPUT,
356 ABI_XINPUT_VERSION,
357 MOD_CLASS_XINPUT,
358 {0, 0, 0, 0}
359};
360
361_X_EXPORT XF86ModuleData vboxmouseModuleData =
362{
363 &VBoxVersionRec,
364 VBoxPlug,
365 NULL
366};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette