VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/xmouse/xorg15/vboxmouse.c@ 15946

Last change on this file since 15946 was 15946, checked in by vboxsync, 16 years ago

Additions/x11: fix a segfault in vboxmouse with Xorg server 1.5 under some circumstances

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.2 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 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17 * Clara, CA 95054 USA or visit http://www.sun.com if you need
18 * additional information or have any questions.
19 * --------------------------------------------------------------------
20 *
21 * This code is based on evdev.c from X.Org with the following copyright
22 * and permission notice:
23 *
24 * Copyright © 2004-2008 Red Hat, Inc.
25 *
26 * Permission to use, copy, modify, distribute, and sell this software
27 * and its documentation for any purpose is hereby granted without
28 * fee, provided that the above copyright notice appear in all copies
29 * and that both that copyright notice and this permission notice
30 * appear in supporting documentation, and that the name of Red Hat
31 * not be used in advertising or publicity pertaining to distribution
32 * of the software without specific, written prior permission. Red
33 * Hat makes no representations about the suitability of this software
34 * for any purpose. It is provided "as is" without express or implied
35 * warranty.
36 *
37 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
39 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
40 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
41 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
42 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
43 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 *
45 * Authors:
46 * Kristian Høgsberg ([email protected])
47 * Adam Jackson ([email protected])
48 */
49
50#ifdef HAVE_CONFIG_H
51#include "config.h"
52#endif
53
54#include <VBox/VBoxGuest.h>
55#include <xf86.h>
56#include <xf86Xinput.h>
57#include <exevents.h>
58#include <mipointer.h>
59
60#include <xf86Module.h>
61
62#include <errno.h>
63#include <fcntl.h>
64
65static void
66VBoxReadInput(InputInfoPtr pInfo)
67{
68 uint32_t cx, cy, fFeatures;
69
70 /* The first test here is a workaround for an apparant bug in Xorg Server 1.5 */
71 if ( miPointerGetScreen(pInfo->dev) != NULL
72 && RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy)))
73 /* send absolute movement */
74 xf86PostMotionEvent(pInfo->dev, 1, 0, 2, cx, cy);
75}
76
77static int
78VBoxInit(DeviceIntPtr device)
79{
80 InputInfoPtr pInfo;
81
82 pInfo = device->public.devicePrivate;
83
84 if (!InitValuatorClassDeviceStruct(device, 2, GetMotionHistory,
85 GetMotionHistorySize(), Absolute)) {
86 xf86Msg(X_ERROR, "%s: InitValuatorClassDeviceStruct failed\n",
87 pInfo->name);
88 return BadAlloc;
89 }
90
91 /* Tell the server about the range of axis values we report */
92 xf86InitValuatorAxisStruct(device, 0, 0 /* min X */, 65536 /* max X */,
93 10000, 0, 10000);
94 xf86InitValuatorDefaults(device, 0);
95
96 xf86InitValuatorAxisStruct(device, 1, 0 /* min Y */, 65536 /* max Y */,
97 10000, 0, 10000);
98 xf86InitValuatorDefaults(device, 1);
99 xf86MotionHistoryAllocate(pInfo);
100
101 return Success;
102}
103
104static int
105VBoxProc(DeviceIntPtr device, int what)
106{
107 InputInfoPtr pInfo;
108 int rc, xrc;
109
110 pInfo = device->public.devicePrivate;
111
112 switch (what)
113 {
114 case DEVICE_INIT:
115 xrc = VBoxInit(device);
116 if (xrc != Success) {
117 VbglR3Term();
118 return xrc;
119 }
120 xf86Msg(X_CONFIG, "%s: Mouse Integration associated with screen %d\n",
121 pInfo->name,
122 xf86SetIntOption(pInfo->options, "ScreenNumber", 0));
123 break;
124
125 case DEVICE_ON:
126 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
127 if (device->public.on)
128 break;
129 /* Tell the host that we want absolute co-ordinates */
130 rc = VbglR3SetMouseStatus(VBOXGUEST_MOUSE_GUEST_CAN_ABSOLUTE);
131 if (!RT_SUCCESS(rc)) {
132 xf86Msg(X_ERROR, "%s: Failed to switch guest mouse into absolute mode\n",
133 pInfo->name);
134 return !Success;
135 }
136
137 xf86AddEnabledDevice(pInfo);
138 device->public.on = TRUE;
139 break;
140
141 case DEVICE_OFF:
142 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
143 VbglR3SetMouseStatus(0);
144 xf86RemoveEnabledDevice(pInfo);
145 device->public.on = FALSE;
146 break;
147
148 case DEVICE_CLOSE:
149 VbglR3Term();
150 xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
151 break;
152 }
153
154 return Success;
155}
156
157static int
158VBoxProbe(InputInfoPtr pInfo)
159{
160 int rc = VbglR3Init();
161 if (!RT_SUCCESS(rc)) {
162 xf86Msg(X_ERROR, "%s: Failed to open the VirtualBox device (error %d)\n",
163 pInfo->name, rc);
164 return !Success;
165 }
166
167 return Success;
168}
169
170static InputInfoPtr
171VBoxPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
172{
173 InputInfoPtr pInfo;
174 const char *device;
175
176 if (!(pInfo = xf86AllocateInput(drv, 0)))
177 return NULL;
178
179 /* Initialise the InputInfoRec. */
180 pInfo->name = dev->identifier;
181 pInfo->device_control = VBoxProc;
182 pInfo->read_input = VBoxReadInput;
183 pInfo->conf_idev = dev;
184 /* Unlike evdev, we set this unconditionally, as we don't handle keyboards. */
185 pInfo->type_name = XI_MOUSE;
186 pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
187 XI86_ALWAYS_CORE | XI86_OPEN_ON_INIT;
188
189 xf86CollectInputOptions(pInfo, NULL, NULL);
190 xf86ProcessCommonOptions(pInfo, pInfo->options);
191
192 device = xf86CheckStrOption(dev->commonOptions, "Device",
193 "/dev/vboxadd");
194
195 xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
196 do {
197 pInfo->fd = open(device, O_RDWR, 0);
198 }
199 while (pInfo->fd < 0 && errno == EINTR);
200
201 if (pInfo->fd < 0) {
202 xf86Msg(X_ERROR, "Unable to open VirtualBox device \"%s\".\n", device);
203 xf86DeleteInput(pInfo, 0);
204 return NULL;
205 }
206
207 if (VBoxProbe(pInfo) != Success) {
208 xf86DeleteInput(pInfo, 0);
209 return NULL;
210 }
211
212 pInfo->flags |= XI86_CONFIGURED;
213 return pInfo;
214}
215
216_X_EXPORT InputDriverRec VBOXMOUSE = {
217 1,
218 "vboxmouse",
219 NULL,
220 VBoxPreInit,
221 NULL,
222 NULL,
223 0
224};
225
226static pointer
227VBoxPlug(pointer module,
228 pointer options,
229 int *errmaj,
230 int *errmin)
231{
232 xf86AddInputDriver(&VBOXMOUSE, module, 0);
233 return module;
234}
235
236static XF86ModuleVersionInfo VBoxVersionRec =
237{
238 "vboxmouse",
239 "Sun Microsystems Inc.",
240 MODINFOSTRING1,
241 MODINFOSTRING2,
242 0, /* Missing from SDK: XORG_VERSION_CURRENT, */
243 1, 0, 0,
244 ABI_CLASS_XINPUT,
245 ABI_XINPUT_VERSION,
246 MOD_CLASS_XINPUT,
247 {0, 0, 0, 0}
248};
249
250_X_EXPORT XF86ModuleData vboxmouseModuleData =
251{
252 &VBoxVersionRec,
253 VBoxPlug,
254 NULL
255};
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