| @@ -1,992 +1,994 @@ | | | @@ -1,992 +1,994 @@ |
1 | /* | | 1 | /* |
2 | * Copyright © 2005-2009,2011 Matthieu Herrb | | 2 | * Copyright © 2005-2009,2011 Matthieu Herrb |
3 | * | | 3 | * |
4 | * Permission to use, copy, modify, and distribute this software for any | | 4 | * Permission to use, copy, modify, and distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | | 5 | * purpose with or without fee is hereby granted, provided that the above |
6 | * copyright notice and this permission notice appear in all copies. | | 6 | * copyright notice and this permission notice appear in all copies. |
7 | * | | 7 | * |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | | 15 | */ |
16 | /* $OpenBSD: ws.c,v 1.33 2011/07/16 17:51:30 matthieu Exp $ */ | | 16 | /* $OpenBSD: ws.c,v 1.33 2011/07/16 17:51:30 matthieu Exp $ */ |
17 | | | 17 | |
18 | #ifdef HAVE_CONFIG_H | | 18 | #ifdef HAVE_CONFIG_H |
19 | #include "config.h" | | 19 | #include "config.h" |
20 | #endif | | 20 | #endif |
21 | | | 21 | |
22 | #include <unistd.h> | | 22 | #include <unistd.h> |
23 | #include <errno.h> | | 23 | #include <errno.h> |
24 | #include <sys/ioctl.h> | | 24 | #include <sys/ioctl.h> |
25 | #include <sys/time.h> | | 25 | #include <sys/time.h> |
26 | #include <dev/wscons/wsconsio.h> | | 26 | #include <dev/wscons/wsconsio.h> |
27 | | | 27 | |
28 | #include <xorg-server.h> | | 28 | #include <xorg-server.h> |
29 | #include <xf86.h> | | 29 | #include <xf86.h> |
30 | #include <xf86_OSproc.h> | | 30 | #include <xf86_OSproc.h> |
31 | #include <X11/extensions/XI.h> | | 31 | #include <X11/extensions/XI.h> |
32 | #include <X11/extensions/XIproto.h> | | 32 | #include <X11/extensions/XIproto.h> |
33 | #include <xf86Xinput.h> | | 33 | #include <xf86Xinput.h> |
34 | #include <exevents.h> | | 34 | #include <exevents.h> |
35 | #include <xisb.h> | | 35 | #include <xisb.h> |
36 | #include <mipointer.h> | | 36 | #include <mipointer.h> |
37 | #include <extinit.h> | | 37 | #include <extinit.h> |
38 | | | 38 | |
39 | #include "ws.h" | | 39 | #include "ws.h" |
40 | | | 40 | |
41 | #include <X11/Xatom.h> | | 41 | #include <X11/Xatom.h> |
42 | #include "ws-properties.h" | | 42 | #include "ws-properties.h" |
43 | #include <xserver-properties.h> | | 43 | #include <xserver-properties.h> |
44 | | | 44 | |
45 | | | 45 | |
46 | static MODULESETUPPROTO(SetupProc); | | 46 | static MODULESETUPPROTO(SetupProc); |
47 | static void TearDownProc(pointer); | | 47 | static void TearDownProc(pointer); |
48 | | | 48 | |
49 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 | | 49 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 |
50 | static InputInfoPtr wsPreInit(InputDriverPtr, IDevPtr, int); | | 50 | static InputInfoPtr wsPreInit(InputDriverPtr, IDevPtr, int); |
51 | #endif | | 51 | #endif |
52 | static int wsPreInit12(InputDriverPtr, InputInfoPtr, int); | | 52 | static int wsPreInit12(InputDriverPtr, InputInfoPtr, int); |
53 | static int wsProc(DeviceIntPtr, int); | | 53 | static int wsProc(DeviceIntPtr, int); |
54 | static int wsDeviceInit(DeviceIntPtr); | | 54 | static int wsDeviceInit(DeviceIntPtr); |
55 | static int wsDeviceOn(DeviceIntPtr); | | 55 | static int wsDeviceOn(DeviceIntPtr); |
56 | static void wsDeviceOff(DeviceIntPtr); | | 56 | static void wsDeviceOff(DeviceIntPtr); |
57 | static void wsReadInput(InputInfoPtr); | | 57 | static void wsReadInput(InputInfoPtr); |
58 | static void wsSendButtons(InputInfoPtr, int); | | 58 | static void wsSendButtons(InputInfoPtr, int); |
59 | static int wsChangeControl(InputInfoPtr, xDeviceCtl *); | | 59 | static int wsChangeControl(InputInfoPtr, xDeviceCtl *); |
60 | static int wsSwitchMode(ClientPtr, DeviceIntPtr, int); | | 60 | static int wsSwitchMode(ClientPtr, DeviceIntPtr, int); |
61 | static Bool wsOpen(InputInfoPtr); | | 61 | static Bool wsOpen(InputInfoPtr); |
62 | static void wsClose(InputInfoPtr); | | 62 | static void wsClose(InputInfoPtr); |
63 | static void wsControlProc(DeviceIntPtr , PtrCtrl *); | | 63 | static void wsControlProc(DeviceIntPtr , PtrCtrl *); |
64 | | | 64 | |
65 | static void wsInitProperty(DeviceIntPtr); | | 65 | static void wsInitProperty(DeviceIntPtr); |
66 | static int wsSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL); | | 66 | static int wsSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL); |
67 | | | 67 | |
68 | static Atom prop_calibration = 0; | | 68 | static Atom prop_calibration = 0; |
69 | static Atom prop_swap = 0; | | 69 | static Atom prop_swap = 0; |
70 | | | 70 | |
71 | #ifdef DEBUG | | 71 | #ifdef DEBUG |
72 | int ws_debug_level = 0; | | 72 | int ws_debug_level = 0; |
73 | #endif | | 73 | #endif |
74 | | | 74 | |
75 | static XF86ModuleVersionInfo VersionRec = { | | 75 | static XF86ModuleVersionInfo VersionRec = { |
76 | "ws", | | 76 | "ws", |
77 | MODULEVENDORSTRING, | | 77 | MODULEVENDORSTRING, |
78 | MODINFOSTRING1, | | 78 | MODINFOSTRING1, |
79 | MODINFOSTRING2, | | 79 | MODINFOSTRING2, |
80 | XORG_VERSION_CURRENT, | | 80 | XORG_VERSION_CURRENT, |
81 | PACKAGE_VERSION_MAJOR, | | 81 | PACKAGE_VERSION_MAJOR, |
82 | PACKAGE_VERSION_MINOR, | | 82 | PACKAGE_VERSION_MINOR, |
83 | PACKAGE_VERSION_PATCHLEVEL, | | 83 | PACKAGE_VERSION_PATCHLEVEL, |
84 | ABI_CLASS_XINPUT, | | 84 | ABI_CLASS_XINPUT, |
85 | ABI_XINPUT_VERSION, | | 85 | ABI_XINPUT_VERSION, |
86 | MOD_CLASS_XINPUT, | | 86 | MOD_CLASS_XINPUT, |
87 | {0, 0, 0, 0} | | 87 | {0, 0, 0, 0} |
88 | }; | | 88 | }; |
89 | | | 89 | |
90 | #define WS_NOZMAP 0 | | 90 | #define WS_NOZMAP 0 |
91 | | | 91 | |
92 | XF86ModuleData wsModuleData = {&VersionRec, | | 92 | XF86ModuleData wsModuleData = {&VersionRec, |
93 | SetupProc, TearDownProc }; | | 93 | SetupProc, TearDownProc }; |
94 | | | 94 | |
95 | | | 95 | |
96 | InputDriverRec WS = { | | 96 | InputDriverRec WS = { |
97 | 1, | | 97 | 1, |
98 | "ws", | | 98 | "ws", |
99 | NULL, | | 99 | NULL, |
100 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 | | 100 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 |
101 | wsPreInit, | | 101 | wsPreInit, |
102 | #else | | 102 | #else |
103 | wsPreInit12, | | 103 | wsPreInit12, |
104 | #endif | | 104 | #endif |
105 | NULL, | | 105 | NULL, |
106 | NULL, | | 106 | NULL, |
107 | 0 | | 107 | 0 |
108 | }; | | 108 | }; |
109 | | | 109 | |
110 | static pointer | | 110 | static pointer |
111 | SetupProc(pointer module, pointer options, int *errmaj, int *errmin) | | 111 | SetupProc(pointer module, pointer options, int *errmaj, int *errmin) |
112 | { | | 112 | { |
113 | static Bool Initialised = FALSE; | | 113 | static Bool Initialised = FALSE; |
114 | | | 114 | |
115 | if (!Initialised) { | | 115 | if (!Initialised) { |
116 | xf86AddInputDriver(&WS, module, 0); | | 116 | xf86AddInputDriver(&WS, module, 0); |
117 | Initialised = TRUE; | | 117 | Initialised = TRUE; |
118 | } | | 118 | } |
119 | return module; | | 119 | return module; |
120 | } | | 120 | } |
121 | | | 121 | |
122 | static void | | 122 | static void |
123 | TearDownProc(pointer p) | | 123 | TearDownProc(pointer p) |
124 | { | | 124 | { |
125 | DBG(1, ErrorF("WS TearDownProc called\n")); | | 125 | DBG(1, ErrorF("WS TearDownProc called\n")); |
126 | } | | 126 | } |
127 | | | 127 | |
128 | | | 128 | |
129 | static int | | 129 | static int |
130 | wsPreInit12(InputDriverPtr drv, InputInfoPtr pInfo, int flags) | | 130 | wsPreInit12(InputDriverPtr drv, InputInfoPtr pInfo, int flags) |
131 | { | | 131 | { |
132 | WSDevicePtr priv; | | 132 | WSDevicePtr priv; |
133 | MessageType buttons_from = X_CONFIG; | | 133 | MessageType buttons_from = X_CONFIG; |
134 | char *s; | | 134 | char *s; |
135 | const char *cs; | | 135 | const char *cs; |
136 | int rc; | | 136 | int rc; |
137 | | | 137 | |
138 | priv = (WSDevicePtr)calloc(1, sizeof(WSDeviceRec)); | | 138 | priv = (WSDevicePtr)calloc(1, sizeof(WSDeviceRec)); |
139 | if (priv == NULL) { | | 139 | if (priv == NULL) { |
140 | rc = BadAlloc; | | 140 | rc = BadAlloc; |
141 | goto fail; | | 141 | goto fail; |
142 | } | | 142 | } |
143 | pInfo->private = priv; | | 143 | pInfo->private = priv; |
144 | | | 144 | |
145 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 | | 145 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 |
146 | xf86CollectInputOptions(pInfo, NULL, NULL); | | 146 | xf86CollectInputOptions(pInfo, NULL, NULL); |
147 | xf86ProcessCommonOptions(pInfo, pInfo->options); | | 147 | xf86ProcessCommonOptions(pInfo, pInfo->options); |
148 | #else | | 148 | #else |
149 | xf86CollectInputOptions(pInfo, NULL); | | 149 | xf86CollectInputOptions(pInfo, NULL); |
150 | #endif | | 150 | #endif |
151 | #ifdef DEBUG | | 151 | #ifdef DEBUG |
152 | ws_debug_level = xf86SetIntOption(pInfo->options, "DebugLevel", | | 152 | ws_debug_level = xf86SetIntOption(pInfo->options, "DebugLevel", |
153 | ws_debug_level); | | 153 | ws_debug_level); |
154 | xf86Msg(X_INFO, "%s: debuglevel %d\n", pInfo->name, | | 154 | xf86Msg(X_INFO, "%s: debuglevel %d\n", pInfo->name, |
155 | ws_debug_level); | | 155 | ws_debug_level); |
156 | #endif | | 156 | #endif |
157 | priv->devName = xf86FindOptionValue(pInfo->options, "Device"); | | 157 | priv->devName = xf86FindOptionValue(pInfo->options, "Device"); |
158 | if (priv->devName == NULL) { | | 158 | if (priv->devName == NULL) { |
159 | xf86Msg(X_ERROR, "%s: No Device specified.\n", | | 159 | xf86Msg(X_ERROR, "%s: No Device specified.\n", |
160 | pInfo->name); | | 160 | pInfo->name); |
161 | rc = BadValue; | | 161 | rc = BadValue; |
162 | goto fail; | | 162 | goto fail; |
163 | } | | 163 | } |
164 | priv->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0); | | 164 | priv->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0); |
165 | if (priv->buttons == 0) { | | 165 | if (priv->buttons == 0) { |
166 | priv->buttons = DFLTBUTTONS; | | 166 | priv->buttons = DFLTBUTTONS; |
167 | buttons_from = X_DEFAULT; | | 167 | buttons_from = X_DEFAULT; |
168 | } | | 168 | } |
169 | priv->negativeZ = priv->positiveZ = WS_NOZMAP; | | 169 | priv->negativeZ = priv->positiveZ = WS_NOZMAP; |
170 | s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5 6 7"); | | 170 | s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5 6 7"); |
171 | if (s) { | | 171 | if (s) { |
172 | int b1, b2; | | 172 | int b1, b2; |
173 | | | 173 | |
174 | if (sscanf(s, "%d %d", &b1, &b2) == 2 && | | 174 | if (sscanf(s, "%d %d", &b1, &b2) == 2 && |
175 | b1 > 0 && b1 <= NBUTTONS && | | 175 | b1 > 0 && b1 <= NBUTTONS && |
176 | b2 > 0 && b2 <= NBUTTONS) { | | 176 | b2 > 0 && b2 <= NBUTTONS) { |
177 | priv->negativeZ = b1; | | 177 | priv->negativeZ = b1; |
178 | priv->positiveZ = b2; | | 178 | priv->positiveZ = b2; |
179 | xf86Msg(X_CONFIG, | | 179 | xf86Msg(X_CONFIG, |
180 | "%s: ZAxisMapping: buttons %d and %d\n", | | 180 | "%s: ZAxisMapping: buttons %d and %d\n", |
181 | pInfo->name, b1, b2); | | 181 | pInfo->name, b1, b2); |
182 | } else { | | 182 | } else { |
183 | xf86Msg(X_WARNING, "%s: invalid ZAxisMapping value: " | | 183 | xf86Msg(X_WARNING, "%s: invalid ZAxisMapping value: " |
184 | "\"%s\"\n", pInfo->name, s); | | 184 | "\"%s\"\n", pInfo->name, s); |
185 | } | | 185 | } |
186 | } | | 186 | } |
187 | if (priv->negativeZ > priv->buttons) { | | 187 | if (priv->negativeZ > priv->buttons) { |
188 | priv->buttons = priv->negativeZ; | | 188 | priv->buttons = priv->negativeZ; |
189 | buttons_from = X_CONFIG; | | 189 | buttons_from = X_CONFIG; |
190 | } | | 190 | } |
191 | if (priv->positiveZ > priv->buttons) { | | 191 | if (priv->positiveZ > priv->buttons) { |
192 | priv->buttons = priv->positiveZ; | | 192 | priv->buttons = priv->positiveZ; |
193 | buttons_from = X_CONFIG; | | 193 | buttons_from = X_CONFIG; |
194 | } | | 194 | } |
195 | priv->negativeW = priv->positiveW = WS_NOZMAP; | | 195 | priv->negativeW = priv->positiveW = WS_NOZMAP; |
196 | s = xf86SetStrOption(pInfo->options, "WAxisMapping", NULL); | | 196 | s = xf86SetStrOption(pInfo->options, "WAxisMapping", NULL); |
197 | if (s) { | | 197 | if (s) { |
198 | int b1, b2; | | 198 | int b1, b2; |
199 | | | 199 | |
200 | if (sscanf(s, "%d %d", &b1, &b2) == 2 && | | 200 | if (sscanf(s, "%d %d", &b1, &b2) == 2 && |
201 | b1 > 0 && b1 <= NBUTTONS && | | 201 | b1 > 0 && b1 <= NBUTTONS && |
202 | b2 > 0 && b2 <= NBUTTONS) { | | 202 | b2 > 0 && b2 <= NBUTTONS) { |
203 | priv->negativeW = b1; | | 203 | priv->negativeW = b1; |
204 | priv->positiveW = b2; | | 204 | priv->positiveW = b2; |
205 | xf86Msg(X_CONFIG, | | 205 | xf86Msg(X_CONFIG, |
206 | "%s: WAxisMapping: buttons %d and %d\n", | | 206 | "%s: WAxisMapping: buttons %d and %d\n", |
207 | pInfo->name, b1, b2); | | 207 | pInfo->name, b1, b2); |
208 | } else { | | 208 | } else { |
209 | xf86Msg(X_WARNING, "%s: invalid WAxisMapping value: " | | 209 | xf86Msg(X_WARNING, "%s: invalid WAxisMapping value: " |
210 | "\"%s\"\n", pInfo->name, s); | | 210 | "\"%s\"\n", pInfo->name, s); |
211 | } | | 211 | } |
212 | } | | 212 | } |
213 | if (priv->negativeW > priv->buttons) { | | 213 | if (priv->negativeW > priv->buttons) { |
214 | priv->buttons = priv->negativeW; | | 214 | priv->buttons = priv->negativeW; |
215 | buttons_from = X_CONFIG; | | 215 | buttons_from = X_CONFIG; |
216 | } | | 216 | } |
217 | if (priv->positiveW > priv->buttons) { | | 217 | if (priv->positiveW > priv->buttons) { |
218 | priv->buttons = priv->positiveW; | | 218 | priv->buttons = priv->positiveW; |
219 | buttons_from = X_CONFIG; | | 219 | buttons_from = X_CONFIG; |
220 | } | | 220 | } |
221 | | | 221 | |
222 | priv->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0); | | 222 | priv->screen_no = xf86SetIntOption(pInfo->options, "ScreenNo", 0); |
223 | xf86Msg(X_CONFIG, "%s associated screen: %d\n", | | 223 | xf86Msg(X_CONFIG, "%s associated screen: %d\n", |
224 | pInfo->name, priv->screen_no); | | 224 | pInfo->name, priv->screen_no); |
225 | if (priv->screen_no >= screenInfo.numScreens || | | 225 | if (priv->screen_no >= screenInfo.numScreens || |
226 | priv->screen_no < 0) { | | 226 | priv->screen_no < 0) { |
227 | priv->screen_no = 0; | | 227 | priv->screen_no = 0; |
228 | } | | 228 | } |
229 | | | 229 | |
230 | | | 230 | |
231 | priv->swap_axes = xf86SetBoolOption(pInfo->options, "SwapXY", 0); | | 231 | priv->swap_axes = xf86SetBoolOption(pInfo->options, "SwapXY", 0); |
232 | if (priv->swap_axes) { | | 232 | if (priv->swap_axes) { |
233 | xf86Msg(X_CONFIG, | | 233 | xf86Msg(X_CONFIG, |
234 | "%s device will work with X and Y axes swapped\n", | | 234 | "%s device will work with X and Y axes swapped\n", |
235 | pInfo->name); | | 235 | pInfo->name); |
236 | } | | 236 | } |
237 | priv->inv_x = 0; | | 237 | priv->inv_x = 0; |
238 | priv->inv_y = 0; | | 238 | priv->inv_y = 0; |
239 | cs = xf86FindOptionValue(pInfo->options, "Rotate"); | | 239 | cs = xf86FindOptionValue(pInfo->options, "Rotate"); |
240 | if (cs) { | | 240 | if (cs) { |
241 | if (xf86NameCmp(cs, "CW") == 0) { | | 241 | if (xf86NameCmp(cs, "CW") == 0) { |
242 | priv->inv_x = 1; | | 242 | priv->inv_x = 1; |
243 | priv->inv_y = 0; | | 243 | priv->inv_y = 0; |
244 | priv->swap_axes = 1; | | 244 | priv->swap_axes = 1; |
245 | } else if (xf86NameCmp(cs, "CCW") == 0) { | | 245 | } else if (xf86NameCmp(cs, "CCW") == 0) { |
246 | priv->inv_x = 0; | | 246 | priv->inv_x = 0; |
247 | priv->inv_y = 1; | | 247 | priv->inv_y = 1; |
248 | priv->swap_axes = 1; | | 248 | priv->swap_axes = 1; |
249 | } else if (xf86NameCmp(cs, "UD") == 0) { | | 249 | } else if (xf86NameCmp(cs, "UD") == 0) { |
250 | priv->inv_x = 1; | | 250 | priv->inv_x = 1; |
251 | priv->inv_y = 1; | | 251 | priv->inv_y = 1; |
252 | } else { | | 252 | } else { |
253 | xf86Msg(X_ERROR, "\"%s\" is not a valid value " | | 253 | xf86Msg(X_ERROR, "\"%s\" is not a valid value " |
254 | "for Option \"Rotate\"\n", cs); | | 254 | "for Option \"Rotate\"\n", cs); |
255 | xf86Msg(X_ERROR, "Valid options are \"CW\", \"CCW\"," | | 255 | xf86Msg(X_ERROR, "Valid options are \"CW\", \"CCW\"," |
256 | " or \"UD\"\n"); | | 256 | " or \"UD\"\n"); |
257 | } | | 257 | } |
258 | } | | 258 | } |
259 | if (wsOpen(pInfo) != Success) { | | 259 | if (wsOpen(pInfo) != Success) { |
260 | rc = BadValue; | | 260 | rc = BadValue; |
261 | goto fail; | | 261 | goto fail; |
262 | } | | 262 | } |
263 | if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) { | | 263 | if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) { |
264 | wsClose(pInfo); | | 264 | wsClose(pInfo); |
265 | rc = BadValue; | | 265 | rc = BadValue; |
266 | goto fail; | | 266 | goto fail; |
267 | } | | 267 | } |
268 | | | 268 | |
269 | /* assume screen coordinate space until proven wrong */ | | 269 | /* assume screen coordinate space until proven wrong */ |
270 | priv->min_x = 0; | | 270 | priv->min_x = 0; |
271 | priv->max_x = screenInfo.screens[priv->screen_no]->width - 1; | | 271 | priv->max_x = screenInfo.screens[priv->screen_no]->width - 1; |
272 | priv->min_y = 0; | | 272 | priv->min_y = 0; |
273 | priv->max_y = screenInfo.screens[priv->screen_no]->height - 1; | | 273 | priv->max_y = screenInfo.screens[priv->screen_no]->height - 1; |
274 | priv->raw = 0; | | 274 | priv->raw = 0; |
275 | | | 275 | |
276 | /* don't rely on the device type - we may be listening to a mux */ | | 276 | /* don't rely on the device type - we may be listening to a mux */ |
277 | if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, | | 277 | if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, |
278 | &priv->coords) != 0) { | | 278 | &priv->coords) != 0) { |
279 | /* can't get absolute coordinate space - assume mouse */ | | 279 | /* can't get absolute coordinate space - assume mouse */ |
280 | pInfo->type_name = XI_MOUSE; | | 280 | pInfo->type_name = XI_MOUSE; |
281 | } else if (priv->coords.samplelen == WSMOUSE_CALIBCOORDS_RESET) { | | 281 | } else if (priv->coords.samplelen == WSMOUSE_CALIBCOORDS_RESET) { |
282 | /* | | 282 | /* |
283 | * we're getting raw coordinates - update accordingly and hope | | 283 | * we're getting raw coordinates - update accordingly and hope |
284 | * that there is no other absolute positioning device on the | | 284 | * that there is no other absolute positioning device on the |
285 | * same mux | | 285 | * same mux |
286 | */ | | 286 | */ |
287 | priv->min_x = priv->coords.minx; | | 287 | priv->min_x = priv->coords.minx; |
288 | priv->max_x = priv->coords.maxx; | | 288 | priv->max_x = priv->coords.maxx; |
289 | priv->min_y = priv->coords.miny; | | 289 | priv->min_y = priv->coords.miny; |
290 | priv->max_y = priv->coords.maxy; | | 290 | priv->max_y = priv->coords.maxy; |
291 | priv->raw = 1; | | 291 | priv->raw = 1; |
292 | pInfo->type_name = XI_TOUCHSCREEN; | | 292 | pInfo->type_name = XI_TOUCHSCREEN; |
293 | } else { | | 293 | } else { |
294 | /* | | 294 | /* |
295 | * touchscreen not in raw mode, should send us screen | | 295 | * touchscreen not in raw mode, should send us screen |
296 | * coordinates | | 296 | * coordinates |
297 | */ | | 297 | */ |
298 | pInfo->type_name = XI_TOUCHSCREEN; | | 298 | pInfo->type_name = XI_TOUCHSCREEN; |
299 | } | | 299 | } |
300 | | | 300 | |
301 | /* | | 301 | /* |
302 | * Force TPANEL type for muxes have have calibration data. A mux | | 302 | * Force TPANEL type for muxes have have calibration data. A mux |
303 | * may have a mix of absolute and relative positioning devices, | | 303 | * may have a mix of absolute and relative positioning devices, |
304 | * and we need to ensure that the xinput layer translates raw | | 304 | * and we need to ensure that the xinput layer translates raw |
305 | * absolute position events for us. | | 305 | * absolute position events for us. |
306 | */ | | 306 | */ |
307 | if (priv->raw && priv->type != WSMOUSE_TYPE_TPANEL) { | | 307 | if (priv->raw && priv->type != WSMOUSE_TYPE_TPANEL) { |
308 | xf86Msg(X_INFO, "%s detected calibration data in raw mode, " | | 308 | xf86Msg(X_INFO, "%s detected calibration data in raw mode, " |
309 | "using touch panel mode\n", pInfo->name); | | 309 | "using touch panel mode\n", pInfo->name); |
310 | priv->type = WSMOUSE_TYPE_TPANEL; | | 310 | priv->type = WSMOUSE_TYPE_TPANEL; |
311 | } | | 311 | } |
312 | | | 312 | |
313 | if (priv->raw) { | | 313 | if (priv->raw) { |
314 | xf86Msg(X_CONFIG, | | 314 | xf86Msg(X_CONFIG, |
315 | "%s device will work in raw mode\n", | | 315 | "%s device will work in raw mode\n", |
316 | pInfo->name); | | 316 | pInfo->name); |
317 | } | | 317 | } |
318 | | | 318 | |
319 | /* Allow options to override this */ | | 319 | /* Allow options to override this */ |
320 | priv->min_x = xf86SetIntOption(pInfo->options, "MinX", priv->min_x); | | 320 | priv->min_x = xf86SetIntOption(pInfo->options, "MinX", priv->min_x); |
321 | xf86Msg(X_INFO, "%s minimum x position: %d\n", | | 321 | xf86Msg(X_INFO, "%s minimum x position: %d\n", |
322 | pInfo->name, priv->min_x); | | 322 | pInfo->name, priv->min_x); |
323 | priv->max_x = xf86SetIntOption(pInfo->options, "MaxX", priv->max_x); | | 323 | priv->max_x = xf86SetIntOption(pInfo->options, "MaxX", priv->max_x); |
324 | xf86Msg(X_INFO, "%s maximum x position: %d\n", | | 324 | xf86Msg(X_INFO, "%s maximum x position: %d\n", |
325 | pInfo->name, priv->max_x); | | 325 | pInfo->name, priv->max_x); |
326 | priv->min_y = xf86SetIntOption(pInfo->options, "MinY", priv->min_y); | | 326 | priv->min_y = xf86SetIntOption(pInfo->options, "MinY", priv->min_y); |
327 | xf86Msg(X_INFO, "%s minimum y position: %d\n", | | 327 | xf86Msg(X_INFO, "%s minimum y position: %d\n", |
328 | pInfo->name, priv->min_y); | | 328 | pInfo->name, priv->min_y); |
329 | priv->max_y = xf86SetIntOption(pInfo->options, "MaxY", priv->max_y); | | 329 | priv->max_y = xf86SetIntOption(pInfo->options, "MaxY", priv->max_y); |
330 | xf86Msg(X_INFO, "%s maximum y position: %d\n", | | 330 | xf86Msg(X_INFO, "%s maximum y position: %d\n", |
331 | pInfo->name, priv->max_y); | | 331 | pInfo->name, priv->max_y); |
332 | | | 332 | |
333 | pInfo->device_control = wsProc; | | 333 | pInfo->device_control = wsProc; |
334 | pInfo->read_input = wsReadInput; | | 334 | pInfo->read_input = wsReadInput; |
335 | pInfo->control_proc = wsChangeControl; | | 335 | pInfo->control_proc = wsChangeControl; |
336 | pInfo->switch_mode = wsSwitchMode; | | 336 | pInfo->switch_mode = wsSwitchMode; |
337 | pInfo->private = priv; | | 337 | pInfo->private = priv; |
338 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 | | 338 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 |
339 | pInfo->conversion_proc = NULL; | | 339 | pInfo->conversion_proc = NULL; |
340 | pInfo->reverse_conversion_proc = NULL; | | 340 | pInfo->reverse_conversion_proc = NULL; |
341 | pInfo->old_x = -1; | | 341 | pInfo->old_x = -1; |
342 | pInfo->old_y = -1; | | 342 | pInfo->old_y = -1; |
343 | #endif | | 343 | #endif |
344 | xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, priv->buttons); | | 344 | xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, priv->buttons); |
345 | | | 345 | |
346 | wsClose(pInfo); | | 346 | wsClose(pInfo); |
347 | | | 347 | |
348 | wsmbEmuPreInit(pInfo); | | 348 | wsmbEmuPreInit(pInfo); |
349 | return Success; | | 349 | return Success; |
350 | | | 350 | |
351 | fail: | | 351 | fail: |
352 | if (priv != NULL) { | | 352 | if (priv != NULL) { |
353 | free(priv); | | 353 | free(priv); |
354 | pInfo->private = NULL; | | 354 | pInfo->private = NULL; |
355 | } | | 355 | } |
356 | return rc; | | 356 | return rc; |
357 | } | | 357 | } |
358 | | | 358 | |
359 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 | | 359 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 |
360 | static InputInfoPtr | | 360 | static InputInfoPtr |
361 | wsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) | | 361 | wsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) |
362 | { | | 362 | { |
363 | InputInfoPtr pInfo = NULL; | | 363 | InputInfoPtr pInfo = NULL; |
364 | | | 364 | |
365 | pInfo = xf86AllocateInput(drv, 0); | | 365 | pInfo = xf86AllocateInput(drv, 0); |
366 | if (pInfo == NULL) { | | 366 | if (pInfo == NULL) { |
367 | return NULL; | | 367 | return NULL; |
368 | } | | 368 | } |
369 | pInfo->name = dev->identifier; | | 369 | pInfo->name = dev->identifier; |
370 | pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; | | 370 | pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; |
371 | pInfo->conf_idev = dev; | | 371 | pInfo->conf_idev = dev; |
372 | pInfo->close_proc = NULL; | | 372 | pInfo->close_proc = NULL; |
373 | pInfo->private_flags = 0; | | 373 | pInfo->private_flags = 0; |
374 | pInfo->always_core_feedback = NULL; | | 374 | pInfo->always_core_feedback = NULL; |
375 | | | 375 | |
376 | if (wsPreInit12(drv, pInfo, flags) != Success) { | | 376 | if (wsPreInit12(drv, pInfo, flags) != Success) { |
377 | xf86DeleteInput(pInfo, 0); | | 377 | xf86DeleteInput(pInfo, 0); |
378 | return NULL; | | 378 | return NULL; |
379 | } | | 379 | } |
380 | /* mark the device configured */ | | 380 | /* mark the device configured */ |
381 | pInfo->flags |= XI86_CONFIGURED; | | 381 | pInfo->flags |= XI86_CONFIGURED; |
382 | return pInfo; | | 382 | return pInfo; |
383 | } | | 383 | } |
384 | #endif | | 384 | #endif |
385 | | | 385 | |
386 | static int | | 386 | static int |
387 | wsProc(DeviceIntPtr pWS, int what) | | 387 | wsProc(DeviceIntPtr pWS, int what) |
388 | { | | 388 | { |
389 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; | | 389 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; |
390 | | | 390 | |
391 | switch (what) { | | 391 | switch (what) { |
392 | case DEVICE_INIT: | | 392 | case DEVICE_INIT: |
393 | return wsDeviceInit(pWS); | | 393 | return wsDeviceInit(pWS); |
394 | | | 394 | |
395 | case DEVICE_ON: | | 395 | case DEVICE_ON: |
396 | return wsDeviceOn(pWS); | | 396 | return wsDeviceOn(pWS); |
397 | | | 397 | |
398 | case DEVICE_OFF: | | 398 | case DEVICE_OFF: |
399 | wsDeviceOff(pWS); | | 399 | wsDeviceOff(pWS); |
400 | break; | | 400 | break; |
401 | | | 401 | |
402 | case DEVICE_CLOSE: | | 402 | case DEVICE_CLOSE: |
403 | DBG(1, ErrorF("WS DEVICE_CLOSE\n")); | | 403 | DBG(1, ErrorF("WS DEVICE_CLOSE\n")); |
404 | wsClose(pInfo); | | 404 | wsClose(pInfo); |
405 | break; | | 405 | break; |
406 | | | 406 | |
407 | default: | | 407 | default: |
408 | xf86Msg(X_ERROR, "WS: unknown command %d\n", what); | | 408 | xf86Msg(X_ERROR, "WS: unknown command %d\n", what); |
409 | return !Success; | | 409 | return !Success; |
410 | } /* switch */ | | 410 | } /* switch */ |
411 | return Success; | | 411 | return Success; |
412 | } /* wsProc */ | | 412 | } /* wsProc */ |
413 | | | 413 | |
414 | static int | | 414 | static int |
415 | wsDeviceInit(DeviceIntPtr pWS) | | 415 | wsDeviceInit(DeviceIntPtr pWS) |
416 | { | | 416 | { |
417 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; | | 417 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; |
418 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 418 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
419 | unsigned char map[NBUTTONS + 1]; | | 419 | unsigned char map[NBUTTONS + 1]; |
420 | int i, xmin, xmax, ymin, ymax; | | 420 | int i, xmin, xmax, ymin, ymax; |
421 | Atom btn_labels[NBUTTONS] = {0}; | | 421 | Atom btn_labels[NBUTTONS] = {0}; |
422 | Atom axes_labels[NAXES] = {0}; | | 422 | Atom axes_labels[NAXES] = {0}; |
423 | | | 423 | |
424 | DBG(1, ErrorF("WS DEVICE_INIT\n")); | | 424 | DBG(1, ErrorF("WS DEVICE_INIT\n")); |
425 | | | 425 | |
426 | btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); | | 426 | btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); |
427 | btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); | | 427 | btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); |
428 | btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); | | 428 | btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); |
429 | for (i = 0; i < NBUTTONS; i++) | | 429 | for (i = 0; i < NBUTTONS; i++) |
430 | map[i + 1] = i + 1; | | 430 | map[i + 1] = i + 1; |
431 | if (!InitButtonClassDeviceStruct(pWS, | | 431 | if (!InitButtonClassDeviceStruct(pWS, |
432 | min(priv->buttons, NBUTTONS), | | 432 | min(priv->buttons, NBUTTONS), |
433 | btn_labels, | | 433 | btn_labels, |
434 | map)) | | 434 | map)) |
435 | return !Success; | | 435 | return !Success; |
436 | | | 436 | |
437 | if (priv->type == WSMOUSE_TYPE_TPANEL) { | | 437 | if (priv->type == WSMOUSE_TYPE_TPANEL) { |
438 | xmin = priv->min_x; | | 438 | xmin = priv->min_x; |
439 | xmax = priv->max_x; | | 439 | xmax = priv->max_x; |
440 | ymin = priv->min_y; | | 440 | ymin = priv->min_y; |
441 | ymax = priv->max_y; | | 441 | ymax = priv->max_y; |
442 | } else { | | 442 | } else { |
443 | xmin = -1; | | 443 | xmin = -1; |
444 | xmax = -1; | | 444 | xmax = -1; |
445 | ymin = -1; | | 445 | ymin = -1; |
446 | ymax = -1; | | 446 | ymax = -1; |
447 | } | | 447 | } |
448 | | | 448 | |
449 | if (priv->swap_axes) { | | 449 | if (priv->swap_axes) { |
450 | int tmp; | | 450 | int tmp; |
451 | tmp = xmin; | | 451 | tmp = xmin; |
452 | xmin = ymin; | | 452 | xmin = ymin; |
453 | ymin = tmp; | | 453 | ymin = tmp; |
454 | tmp = xmax; | | 454 | tmp = xmax; |
455 | xmax = ymax; | | 455 | xmax = ymax; |
456 | ymax = tmp; | | 456 | ymax = tmp; |
457 | } | | 457 | } |
458 | if ((priv->type == WSMOUSE_TYPE_TPANEL)) { | | 458 | if ((priv->type == WSMOUSE_TYPE_TPANEL)) { |
459 | axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); | | 459 | axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); |
460 | axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); | | 460 | axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); |
461 | } else { | | 461 | } else { |
462 | axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); | | 462 | axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); |
463 | axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); | | 463 | axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); |
464 | } | | 464 | } |
465 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 | | 465 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 |
466 | axes_labels[HSCROLL_AXIS] = | | 466 | axes_labels[HSCROLL_AXIS] = |
467 | XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); | | 467 | XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); |
468 | axes_labels[VSCROLL_AXIS] = | | 468 | axes_labels[VSCROLL_AXIS] = |
469 | XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); | | 469 | XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); |
470 | #endif | | 470 | #endif |
471 | if (!InitValuatorClassDeviceStruct(pWS, | | 471 | if (!InitValuatorClassDeviceStruct(pWS, |
472 | NAXES, | | 472 | NAXES, |
473 | axes_labels, | | 473 | axes_labels, |
474 | GetMotionHistorySize(), | | 474 | GetMotionHistorySize(), |
475 | priv->type == WSMOUSE_TYPE_TPANEL ? | | 475 | priv->type == WSMOUSE_TYPE_TPANEL ? |
476 | Absolute : Relative)) | | 476 | Absolute : Relative)) |
477 | return !Success; | | 477 | return !Success; |
478 | if (!InitPtrFeedbackClassDeviceStruct(pWS, wsControlProc)) | | 478 | if (!InitPtrFeedbackClassDeviceStruct(pWS, wsControlProc)) |
479 | return !Success; | | 479 | return !Success; |
480 | | | 480 | |
481 | xf86InitValuatorAxisStruct(pWS, 0, | | 481 | xf86InitValuatorAxisStruct(pWS, 0, |
482 | axes_labels[0], | | 482 | axes_labels[0], |
483 | xmin, xmax, 1, 0, 1 | | 483 | xmin, xmax, 1, 0, 1 |
484 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 | | 484 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 |
485 | , priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative | | 485 | , priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative |
486 | #endif | | 486 | #endif |
487 | ); | | 487 | ); |
488 | xf86InitValuatorDefaults(pWS, 0); | | 488 | xf86InitValuatorDefaults(pWS, 0); |
489 | | | 489 | |
490 | xf86InitValuatorAxisStruct(pWS, 1, | | 490 | xf86InitValuatorAxisStruct(pWS, 1, |
491 | axes_labels[1], | | 491 | axes_labels[1], |
492 | ymin, ymax, 1, 0, 1 | | 492 | ymin, ymax, 1, 0, 1 |
493 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 | | 493 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 |
494 | , priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative | | 494 | , priv->type == WSMOUSE_TYPE_TPANEL ? Absolute : Relative |
495 | #endif | | 495 | #endif |
496 | ); | | 496 | ); |
497 | xf86InitValuatorDefaults(pWS, 1); | | 497 | xf86InitValuatorDefaults(pWS, 1); |
498 | | | 498 | |
499 | | | 499 | |
500 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 | | 500 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 |
501 | xf86InitValuatorAxisStruct(pWS, HSCROLL_AXIS, | | 501 | xf86InitValuatorAxisStruct(pWS, HSCROLL_AXIS, |
502 | axes_labels[HSCROLL_AXIS], 0, -1, 0, 0, 0, Relative); | | 502 | axes_labels[HSCROLL_AXIS], 0, -1, 0, 0, 0, Relative); |
503 | xf86InitValuatorAxisStruct(pWS, VSCROLL_AXIS, | | 503 | xf86InitValuatorAxisStruct(pWS, VSCROLL_AXIS, |
504 | axes_labels[VSCROLL_AXIS], 0, -1, 0, 0, 0, Relative); | | 504 | axes_labels[VSCROLL_AXIS], 0, -1, 0, 0, 0, Relative); |
505 | priv->scroll_mask = valuator_mask_new(MAX_VALUATORS); | | 505 | priv->scroll_mask = valuator_mask_new(MAX_VALUATORS); |
506 | if (!priv->scroll_mask) { | | 506 | if (!priv->scroll_mask) { |
507 | return !Success; | | 507 | return !Success; |
508 | } | | 508 | } |
509 | | | 509 | |
510 | /* | | 510 | /* |
511 | * The value of an HSCROLL or VSCROLL event is the fraction | | 511 | * The value of an HSCROLL or VSCROLL event is the fraction |
512 | * motion_delta / scroll_distance | | 512 | * motion_delta / scroll_distance |
513 | * in [*.12] fixed-point format. The 'increment' attribute of the | | 513 | * in [*.12] fixed-point format. The 'increment' attribute of the |
514 | * scroll axes is constant: | | 514 | * scroll axes is constant: |
515 | */ | | 515 | */ |
516 | SetScrollValuator(pWS, HSCROLL_AXIS, SCROLL_TYPE_HORIZONTAL, 4096, 0); | | 516 | SetScrollValuator(pWS, HSCROLL_AXIS, SCROLL_TYPE_HORIZONTAL, 4096, 0); |
517 | SetScrollValuator(pWS, VSCROLL_AXIS, SCROLL_TYPE_VERTICAL, 4096, 0); | | 517 | SetScrollValuator(pWS, VSCROLL_AXIS, SCROLL_TYPE_VERTICAL, 4096, 0); |
518 | #endif | | 518 | #endif |
519 | | | 519 | |
520 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 | | 520 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 |
521 | xf86MotionHistoryAllocate(pInfo); | | 521 | xf86MotionHistoryAllocate(pInfo); |
522 | AssignTypeAndName(pWS, pInfo->atom, pInfo->name); | | 522 | AssignTypeAndName(pWS, pInfo->atom, pInfo->name); |
523 | #endif | | 523 | #endif |
524 | pWS->public.on = FALSE; | | 524 | pWS->public.on = FALSE; |
525 | if (wsOpen(pInfo) != Success) { | | 525 | if (wsOpen(pInfo) != Success) { |
526 | return !Success; | | 526 | return !Success; |
527 | } | | 527 | } |
528 | wsInitProperty(pWS); | | 528 | wsInitProperty(pWS); |
529 | XIRegisterPropertyHandler(pWS, wsSetProperty, NULL, NULL); | | 529 | XIRegisterPropertyHandler(pWS, wsSetProperty, NULL, NULL); |
530 | wsmbEmuInitProperty(pWS); | | 530 | wsmbEmuInitProperty(pWS); |
531 | return Success; | | 531 | return Success; |
532 | } | | 532 | } |
533 | | | 533 | |
534 | static int | | 534 | static int |
535 | wsDeviceOn(DeviceIntPtr pWS) | | 535 | wsDeviceOn(DeviceIntPtr pWS) |
536 | { | | 536 | { |
537 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; | | 537 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; |
538 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 538 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
539 | #ifndef __NetBSD__ | | 539 | #ifndef __NetBSD__ |
540 | struct wsmouse_calibcoords coords; | | 540 | struct wsmouse_calibcoords coords; |
541 | #endif | | 541 | #endif |
542 | | | 542 | |
543 | DBG(1, ErrorF("WS DEVICE ON\n")); | | 543 | DBG(1, ErrorF("WS DEVICE ON\n")); |
544 | if ((pInfo->fd < 0) && (wsOpen(pInfo) != Success)) { | | 544 | if ((pInfo->fd < 0) && (wsOpen(pInfo) != Success)) { |
545 | xf86Msg(X_ERROR, "wsOpen failed %s\n", | | 545 | xf86Msg(X_ERROR, "wsOpen failed %s\n", |
546 | strerror(errno)); | | 546 | strerror(errno)); |
547 | return !Success; | | 547 | return !Success; |
548 | } | | 548 | } |
549 | | | 549 | |
550 | #ifndef __NetBSD__ | | 550 | #ifndef __NetBSD__ |
551 | if (priv->type == WSMOUSE_TYPE_TPANEL) { | | 551 | if (priv->type == WSMOUSE_TYPE_TPANEL) { |
552 | /* get calibration values */ | | 552 | /* get calibration values */ |
553 | if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &coords) != 0) { | | 553 | if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &coords) != 0) { |
554 | xf86Msg(X_ERROR, "GCALIBCOORS failed %s\n", | | 554 | xf86Msg(X_ERROR, "GCALIBCOORS failed %s\n", |
555 | strerror(errno)); | | 555 | strerror(errno)); |
556 | return !Success; | | 556 | return !Success; |
557 | } | | 557 | } |
558 | memcpy(&priv->coords, &coords, sizeof coords); | | 558 | memcpy(&priv->coords, &coords, sizeof coords); |
559 | /* set raw mode */ | | 559 | /* set raw mode */ |
560 | if (coords.samplelen != priv->raw) { | | 560 | if (coords.samplelen != priv->raw) { |
561 | coords.samplelen = priv->raw; | | 561 | coords.samplelen = priv->raw; |
562 | if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, | | 562 | if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, |
563 | &coords) != 0) { | | 563 | &coords) != 0) { |
564 | xf86Msg(X_ERROR, "SCALIBCOORS failed %s\n", | | 564 | xf86Msg(X_ERROR, "SCALIBCOORS failed %s\n", |
565 | strerror(errno)); | | 565 | strerror(errno)); |
566 | return !Success; | | 566 | return !Success; |
567 | } | | 567 | } |
568 | } | | 568 | } |
569 | } | | 569 | } |
570 | #endif | | 570 | #endif |
571 | priv->buffer = XisbNew(pInfo->fd, | | 571 | priv->buffer = XisbNew(pInfo->fd, |
572 | sizeof(struct wscons_event) * NUMEVENTS); | | 572 | sizeof(struct wscons_event) * NUMEVENTS); |
573 | if (priv->buffer == NULL) { | | 573 | if (priv->buffer == NULL) { |
574 | xf86Msg(X_ERROR, "cannot alloc xisb buffer\n"); | | 574 | xf86Msg(X_ERROR, "cannot alloc xisb buffer\n"); |
575 | wsClose(pInfo); | | 575 | wsClose(pInfo); |
576 | return !Success; | | 576 | return !Success; |
577 | } | | 577 | } |
578 | xf86AddEnabledDevice(pInfo); | | 578 | xf86AddEnabledDevice(pInfo); |
579 | wsmbEmuOn(pInfo); | | 579 | wsmbEmuOn(pInfo); |
580 | pWS->public.on = TRUE; | | 580 | pWS->public.on = TRUE; |
581 | return Success; | | 581 | return Success; |
582 | } | | 582 | } |
583 | | | 583 | |
584 | static void | | 584 | static void |
585 | wsDeviceOff(DeviceIntPtr pWS) | | 585 | wsDeviceOff(DeviceIntPtr pWS) |
586 | { | | 586 | { |
587 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; | | 587 | InputInfoPtr pInfo = (InputInfoPtr)pWS->public.devicePrivate; |
588 | WSDevicePtr priv = pInfo->private; | | 588 | WSDevicePtr priv = pInfo->private; |
589 | #ifndef __NetBSD__ | | 589 | #ifndef __NetBSD__ |
590 | struct wsmouse_calibcoords coords; | | 590 | struct wsmouse_calibcoords coords; |
591 | #endif | | 591 | #endif |
592 | | | 592 | |
593 | DBG(1, ErrorF("WS DEVICE OFF\n")); | | 593 | DBG(1, ErrorF("WS DEVICE OFF\n")); |
594 | wsmbEmuFinalize(pInfo); | | 594 | wsmbEmuFinalize(pInfo); |
595 | #ifndef __NetBSD__ | | 595 | #ifndef __NetBSD__ |
596 | if (priv->type == WSMOUSE_TYPE_TPANEL) { | | 596 | if (priv->type == WSMOUSE_TYPE_TPANEL) { |
597 | /* Restore calibration data */ | | 597 | /* Restore calibration data */ |
598 | memcpy(&coords, &priv->coords, sizeof coords); | | 598 | memcpy(&coords, &priv->coords, sizeof coords); |
599 | if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { | | 599 | if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { |
600 | xf86Msg(X_ERROR, "SCALIBCOORS failed %s\n", | | 600 | xf86Msg(X_ERROR, "SCALIBCOORS failed %s\n", |
601 | strerror(errno)); | | 601 | strerror(errno)); |
602 | } | | 602 | } |
603 | } | | 603 | } |
604 | #endif | | 604 | #endif |
605 | if (pInfo->fd >= 0) { | | 605 | if (pInfo->fd >= 0) { |
606 | xf86RemoveEnabledDevice(pInfo); | | 606 | xf86RemoveEnabledDevice(pInfo); |
607 | wsClose(pInfo); | | 607 | wsClose(pInfo); |
608 | } | | 608 | } |
609 | if (priv->buffer) { | | 609 | if (priv->buffer) { |
610 | XisbFree(priv->buffer); | | 610 | XisbFree(priv->buffer); |
611 | priv->buffer = NULL; | | 611 | priv->buffer = NULL; |
612 | } | | 612 | } |
613 | pWS->public.on = FALSE; | | 613 | pWS->public.on = FALSE; |
614 | } | | 614 | } |
615 | | | 615 | |
616 | static void | | 616 | static void |
617 | wsReadInput(InputInfoPtr pInfo) | | 617 | wsReadInput(InputInfoPtr pInfo) |
618 | { | | 618 | { |
619 | WSDevicePtr priv; | | 619 | WSDevicePtr priv; |
620 | static struct wscons_event eventList[NUMEVENTS]; | | 620 | static struct wscons_event eventList[NUMEVENTS]; |
621 | int n, c; | | 621 | int n, c; |
622 | struct wscons_event *event = eventList; | | 622 | struct wscons_event *event = eventList; |
623 | unsigned char *pBuf; | | 623 | unsigned char *pBuf; |
624 | int ax, ay; | | 624 | int ax, ay; |
625 | | | 625 | |
626 | priv = pInfo->private; | | 626 | priv = pInfo->private; |
627 | | | 627 | |
628 | XisbBlockDuration(priv->buffer, -1); | | 628 | XisbBlockDuration(priv->buffer, -1); |
629 | pBuf = (unsigned char *)eventList; | | 629 | pBuf = (unsigned char *)eventList; |
630 | n = 0; | | 630 | n = 0; |
631 | while (n < sizeof(eventList) && (c = XisbRead(priv->buffer)) >= 0) { | | 631 | while (n < sizeof(eventList) && (c = XisbRead(priv->buffer)) >= 0) { |
632 | pBuf[n++] = (unsigned char)c; | | 632 | pBuf[n++] = (unsigned char)c; |
633 | } | | 633 | } |
634 | | | 634 | |
635 | if (n == 0) | | 635 | if (n == 0) |
636 | return; | | 636 | return; |
637 | | | 637 | |
638 | n /= sizeof(struct wscons_event); | | 638 | n /= sizeof(struct wscons_event); |
639 | while( n-- ) { | | 639 | while( n-- ) { |
640 | int buttons = priv->lastButtons; | | 640 | int buttons = priv->lastButtons; |
641 | int dx = 0, dy = 0, dz = 0, dw = 0; | | 641 | int dx = 0, dy = 0, dz = 0, dw = 0; |
642 | int zbutton = 0, wbutton = 0; | | 642 | int zbutton = 0, wbutton = 0; |
643 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 | | 643 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 |
644 | int hscroll = 0, vscroll = 0; | | 644 | int hscroll = 0, vscroll = 0; |
645 | #endif | | 645 | #endif |
646 | | | 646 | |
647 | ax = 0; ay = 0; | | 647 | ax = 0; ay = 0; |
648 | switch (event->type) { | | 648 | switch (event->type) { |
649 | case WSCONS_EVENT_MOUSE_UP: | | 649 | case WSCONS_EVENT_MOUSE_UP: |
650 | | | 650 | |
651 | buttons &= ~(1 << event->value); | | 651 | buttons &= ~(1 << event->value); |
652 | DBG(4, ErrorF("Button %d up %x\n", event->value, | | 652 | DBG(4, ErrorF("Button %d up %x\n", event->value, |
653 | buttons)); | | 653 | buttons)); |
654 | break; | | 654 | break; |
655 | case WSCONS_EVENT_MOUSE_DOWN: | | 655 | case WSCONS_EVENT_MOUSE_DOWN: |
656 | buttons |= (1 << event->value); | | 656 | buttons |= (1 << event->value); |
657 | DBG(4, ErrorF("Button %d down %x\n", event->value, | | 657 | DBG(4, ErrorF("Button %d down %x\n", event->value, |
658 | buttons)); | | 658 | buttons)); |
659 | break; | | 659 | break; |
660 | case WSCONS_EVENT_MOUSE_DELTA_X: | | 660 | case WSCONS_EVENT_MOUSE_DELTA_X: |
661 | dx = event->value; | | 661 | dx = event->value; |
662 | DBG(4, ErrorF("Relative X %d\n", event->value)); | | 662 | DBG(4, ErrorF("Relative X %d\n", event->value)); |
663 | break; | | 663 | break; |
664 | case WSCONS_EVENT_MOUSE_DELTA_Y: | | 664 | case WSCONS_EVENT_MOUSE_DELTA_Y: |
665 | dy = -event->value; | | 665 | dy = -event->value; |
666 | DBG(4, ErrorF("Relative Y %d\n", event->value)); | | 666 | DBG(4, ErrorF("Relative Y %d\n", event->value)); |
667 | break; | | 667 | break; |
668 | case WSCONS_EVENT_MOUSE_ABSOLUTE_X: | | 668 | case WSCONS_EVENT_MOUSE_ABSOLUTE_X: |
669 | DBG(4, ErrorF("Absolute X %d\n", event->value)); | | 669 | DBG(4, ErrorF("Absolute X %d\n", event->value)); |
670 | if (event->value == 4095) | | 670 | if (event->value == 4095) |
671 | break; | | 671 | break; |
672 | ax = event->value; | | 672 | ax = event->value; |
673 | if (priv->inv_x) | | 673 | if (priv->inv_x) |
674 | ax = priv->max_x - ax + priv->min_x; | | 674 | ax = priv->max_x - ax + priv->min_x; |
675 | break; | | 675 | break; |
676 | case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: | | 676 | case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: |
677 | DBG(4, ErrorF("Absolute Y %d\n", event->value)); | | 677 | DBG(4, ErrorF("Absolute Y %d\n", event->value)); |
678 | ay = event->value; | | 678 | ay = event->value; |
679 | if (priv->inv_y) | | 679 | if (priv->inv_y) |
680 | ay = priv->max_y - ay + priv->min_y; | | 680 | ay = priv->max_y - ay + priv->min_y; |
681 | break; | | 681 | break; |
682 | case WSCONS_EVENT_MOUSE_DELTA_Z: | | 682 | case WSCONS_EVENT_MOUSE_DELTA_Z: |
683 | DBG(4, ErrorF("Relative Z %d\n", event->value)); | | 683 | DBG(4, ErrorF("Relative Z %d\n", event->value)); |
684 | dz = event->value; | | 684 | dz = event->value; |
685 | break; | | 685 | break; |
686 | case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: | | 686 | case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: |
687 | /* ignore those */ | | 687 | /* ignore those */ |
688 | ++event; | | 688 | ++event; |
689 | continue; | | 689 | continue; |
690 | break; | | 690 | break; |
691 | case WSCONS_EVENT_MOUSE_DELTA_W: | | 691 | case WSCONS_EVENT_MOUSE_DELTA_W: |
692 | DBG(4, ErrorF("Relative W %d\n", event->value)); | | 692 | DBG(4, ErrorF("Relative W %d\n", event->value)); |
693 | dw = event->value; | | 693 | dw = event->value; |
694 | break; | | 694 | break; |
695 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 | | 695 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 |
696 | case WSCONS_EVENT_HSCROLL: | | 696 | case WSCONS_EVENT_HSCROLL: |
697 | hscroll = event->value; | | 697 | hscroll = event->value; |
698 | DBG(4, ErrorF("Horiz. Scrolling %d\n", event->value)); | | 698 | DBG(4, ErrorF("Horiz. Scrolling %d\n", event->value)); |
699 | break; | | 699 | break; |
700 | case WSCONS_EVENT_VSCROLL: | | 700 | case WSCONS_EVENT_VSCROLL: |
701 | vscroll = event->value; | | 701 | vscroll = event->value; |
702 | DBG(4, ErrorF("Vert. Scrolling %d\n", event->value)); | | 702 | DBG(4, ErrorF("Vert. Scrolling %d\n", event->value)); |
703 | break; | | 703 | break; |
704 | #endif | | 704 | #endif |
705 | default: | | 705 | default: |
706 | xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n", | | 706 | xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n", |
707 | pInfo->name, event->type); | | 707 | pInfo->name, event->type); |
708 | ++event; | | 708 | ++event; |
709 | continue; | | 709 | continue; |
710 | } /* case */ | | 710 | } /* case */ |
711 | | | 711 | |
712 | if (dx || dy) { | | 712 | if (dx || dy) { |
713 | /* relative motion event */ | | 713 | /* relative motion event */ |
714 | DBG(3, ErrorF("postMotionEvent dX %d dY %d\n", | | 714 | DBG(3, ErrorF("postMotionEvent dX %d dY %d\n", |
715 | dx, dy)); | | 715 | dx, dy)); |
716 | xf86PostMotionEvent(pInfo->dev, 0, 0, 2, | | 716 | xf86PostMotionEvent(pInfo->dev, 0, 0, 2, |
717 | dx, dy); | | 717 | dx, dy); |
718 | } | | 718 | } |
719 | if (dz && priv->negativeZ != WS_NOZMAP | | 719 | if (dz && priv->negativeZ != WS_NOZMAP |
720 | && priv->positiveZ != WS_NOZMAP) { | | 720 | && priv->positiveZ != WS_NOZMAP) { |
721 | buttons &= ~(priv->negativeZ | priv->positiveZ); | | 721 | buttons &= ~(priv->negativeZ | priv->positiveZ); |
722 | if (dz < 0) { | | 722 | if (dz < 0) { |
723 | DBG(4, ErrorF("Z -> button %d\n", | | 723 | DBG(4, ErrorF("Z -> button %d\n", |
724 | priv->negativeZ)); | | 724 | priv->negativeZ)); |
725 | zbutton = 1 << (priv->negativeZ - 1); | | 725 | zbutton = 1 << (priv->negativeZ - 1); |
726 | } else { | | 726 | } else { |
727 | DBG(4, ErrorF("Z -> button %d\n", | | 727 | DBG(4, ErrorF("Z -> button %d\n", |
728 | priv->positiveZ)); | | 728 | priv->positiveZ)); |
729 | zbutton = 1 << (priv->positiveZ - 1); | | 729 | zbutton = 1 << (priv->positiveZ - 1); |
730 | } | | 730 | } |
731 | buttons |= zbutton; | | 731 | buttons |= zbutton; |
732 | dz = 0; | | 732 | dz = 0; |
733 | } | | 733 | } |
734 | if (dw && priv->negativeW != WS_NOZMAP | | 734 | if (dw && priv->negativeW != WS_NOZMAP |
735 | && priv->positiveW != WS_NOZMAP) { | | 735 | && priv->positiveW != WS_NOZMAP) { |
736 | buttons &= ~(priv->negativeW | priv->positiveW); | | 736 | buttons &= ~(priv->negativeW | priv->positiveW); |
737 | if (dw < 0) { | | 737 | if (dw < 0) { |
738 | DBG(4, ErrorF("W -> button %d\n", | | 738 | DBG(4, ErrorF("W -> button %d\n", |
739 | priv->negativeW)); | | 739 | priv->negativeW)); |
740 | wbutton = 1 << (priv->negativeW - 1); | | 740 | wbutton = 1 << (priv->negativeW - 1); |
741 | } else { | | 741 | } else { |
742 | DBG(4, ErrorF("W -> button %d\n", | | 742 | DBG(4, ErrorF("W -> button %d\n", |
743 | priv->positiveW)); | | 743 | priv->positiveW)); |
744 | wbutton = 1 << (priv->positiveW - 1); | | 744 | wbutton = 1 << (priv->positiveW - 1); |
745 | } | | 745 | } |
746 | buttons |= wbutton; | | 746 | buttons |= wbutton; |
747 | dw = 0; | | 747 | dw = 0; |
748 | } | | 748 | } |
749 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 | | 749 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 14 |
750 | static int warned = 0; | | 750 | if (hscroll || vscroll) { |
751 | if ((hscroll || vscroll) && !warned) { | | 751 | static int warned = 0; |
752 | warned = 1; | | 752 | if (!warned) { |
753 | xf86Msg(X_WARNING, "%s: hscroll=%d, vscroll=%d\n", | | 753 | warned = 1; |
754 | pInfo->name, hscroll, vscroll); | | 754 | xf86Msg(X_WARNING, "%s: hscroll=%d, vscroll=%d\n", |
| | | 755 | pInfo->name, hscroll, vscroll); |
| | | 756 | } |
755 | valuator_mask_zero(priv->scroll_mask); | | 757 | valuator_mask_zero(priv->scroll_mask); |
756 | valuator_mask_set_double(priv->scroll_mask, | | 758 | valuator_mask_set_double(priv->scroll_mask, |
757 | HSCROLL_AXIS, (double) hscroll); | | 759 | HSCROLL_AXIS, (double) hscroll); |
758 | valuator_mask_set_double(priv->scroll_mask, | | 760 | valuator_mask_set_double(priv->scroll_mask, |
759 | VSCROLL_AXIS, (double) vscroll); | | 761 | VSCROLL_AXIS, (double) vscroll); |
760 | xf86PostMotionEventM(pInfo->dev, FALSE, priv->scroll_mask); | | 762 | xf86PostMotionEventM(pInfo->dev, FALSE, priv->scroll_mask); |
761 | } | | 763 | } |
762 | #endif | | 764 | #endif |
763 | if (priv->lastButtons != buttons) { | | 765 | if (priv->lastButtons != buttons) { |
764 | /* button event */ | | 766 | /* button event */ |
765 | wsSendButtons(pInfo, buttons); | | 767 | wsSendButtons(pInfo, buttons); |
766 | } | | 768 | } |
767 | if (zbutton != 0) { | | 769 | if (zbutton != 0) { |
768 | /* generate a button up event */ | | 770 | /* generate a button up event */ |
769 | buttons &= ~zbutton; | | 771 | buttons &= ~zbutton; |
770 | wsSendButtons(pInfo, buttons); | | 772 | wsSendButtons(pInfo, buttons); |
771 | } | | 773 | } |
772 | if (priv->swap_axes) { | | 774 | if (priv->swap_axes) { |
773 | int tmp; | | 775 | int tmp; |
774 | | | 776 | |
775 | tmp = ax; | | 777 | tmp = ax; |
776 | ax = ay; | | 778 | ax = ay; |
777 | ay = tmp; | | 779 | ay = tmp; |
778 | } | | 780 | } |
779 | if (ax) { | | 781 | if (ax) { |
780 | /* absolute position event */ | | 782 | /* absolute position event */ |
781 | DBG(3, ErrorF("postMotionEvent X %d\n", ax)); | | 783 | DBG(3, ErrorF("postMotionEvent X %d\n", ax)); |
782 | xf86PostMotionEvent(pInfo->dev, 1, 0, 1, ax); | | 784 | xf86PostMotionEvent(pInfo->dev, 1, 0, 1, ax); |
783 | } | | 785 | } |
784 | if (ay) { | | 786 | if (ay) { |
785 | /* absolute position event */ | | 787 | /* absolute position event */ |
786 | DBG(3, ErrorF("postMotionEvent y %d\n", ay)); | | 788 | DBG(3, ErrorF("postMotionEvent y %d\n", ay)); |
787 | xf86PostMotionEvent(pInfo->dev, 1, 1, 1, ay); | | 789 | xf86PostMotionEvent(pInfo->dev, 1, 1, 1, ay); |
788 | } | | 790 | } |
789 | ++event; | | 791 | ++event; |
790 | } | | 792 | } |
791 | return; | | 793 | return; |
792 | } /* wsReadInput */ | | 794 | } /* wsReadInput */ |
793 | | | 795 | |
794 | static void | | 796 | static void |
795 | wsSendButtons(InputInfoPtr pInfo, int buttons) | | 797 | wsSendButtons(InputInfoPtr pInfo, int buttons) |
796 | { | | 798 | { |
797 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 799 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
798 | int button, mask; | | 800 | int button, mask; |
799 | | | 801 | |
800 | for (button = 1; button < NBUTTONS; button++) { | | 802 | for (button = 1; button < NBUTTONS; button++) { |
801 | mask = 1 << (button - 1); | | 803 | mask = 1 << (button - 1); |
802 | if ((mask & priv->lastButtons) != (mask & buttons)) { | | 804 | if ((mask & priv->lastButtons) != (mask & buttons)) { |
803 | if (!wsmbEmuFilterEvent(pInfo, button, | | 805 | if (!wsmbEmuFilterEvent(pInfo, button, |
804 | (buttons & mask) != 0)) { | | 806 | (buttons & mask) != 0)) { |
805 | xf86PostButtonEvent(pInfo->dev, TRUE, | | 807 | xf86PostButtonEvent(pInfo->dev, TRUE, |
806 | button, (buttons & mask) != 0, | | 808 | button, (buttons & mask) != 0, |
807 | 0, 0); | | 809 | 0, 0); |
808 | DBG(3, ErrorF("post button event %d %d\n", | | 810 | DBG(3, ErrorF("post button event %d %d\n", |
809 | button, (buttons & mask) != 0)) | | 811 | button, (buttons & mask) != 0)) |
810 | } | | 812 | } |
811 | } | | 813 | } |
812 | } /* for */ | | 814 | } /* for */ |
813 | priv->lastButtons = buttons; | | 815 | priv->lastButtons = buttons; |
814 | } /* wsSendButtons */ | | 816 | } /* wsSendButtons */ |
815 | | | 817 | |
816 | | | 818 | |
817 | static int | | 819 | static int |
818 | wsChangeControl(InputInfoPtr pInfo, xDeviceCtl *control) | | 820 | wsChangeControl(InputInfoPtr pInfo, xDeviceCtl *control) |
819 | { | | 821 | { |
820 | return BadMatch; | | 822 | return BadMatch; |
821 | } | | 823 | } |
822 | | | 824 | |
823 | static int | | 825 | static int |
824 | wsSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode) | | 826 | wsSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode) |
825 | { | | 827 | { |
826 | return BadMatch; | | 828 | return BadMatch; |
827 | } | | 829 | } |
828 | | | 830 | |
829 | static Bool | | 831 | static Bool |
830 | wsOpen(InputInfoPtr pInfo) | | 832 | wsOpen(InputInfoPtr pInfo) |
831 | { | | 833 | { |
832 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 834 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
833 | #ifdef __NetBSD__ | | 835 | #ifdef __NetBSD__ |
834 | int version = WSMOUSE_EVENT_VERSION; | | 836 | int version = WSMOUSE_EVENT_VERSION; |
835 | #endif | | 837 | #endif |
836 | | | 838 | |
837 | DBG(1, ErrorF("WS open %s\n", priv->devName)); | | 839 | DBG(1, ErrorF("WS open %s\n", priv->devName)); |
838 | pInfo->fd = xf86OpenSerial(pInfo->options); | | 840 | pInfo->fd = xf86OpenSerial(pInfo->options); |
839 | if (pInfo->fd == -1) { | | 841 | if (pInfo->fd == -1) { |
840 | xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); | | 842 | xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); |
841 | return !Success; | | 843 | return !Success; |
842 | } | | 844 | } |
843 | #ifdef __NetBSD__ | | 845 | #ifdef __NetBSD__ |
844 | if (ioctl(pInfo->fd, WSMOUSEIO_SETVERSION, &version) == -1) { | | 846 | if (ioctl(pInfo->fd, WSMOUSEIO_SETVERSION, &version) == -1) { |
845 | xf86Msg(X_ERROR, "%s: cannot set wsmouse event version\n", | | 847 | xf86Msg(X_ERROR, "%s: cannot set wsmouse event version\n", |
846 | pInfo->name); | | 848 | pInfo->name); |
847 | return !Success; | | 849 | return !Success; |
848 | } | | 850 | } |
849 | #endif | | 851 | #endif |
850 | return Success; | | 852 | return Success; |
851 | } | | 853 | } |
852 | | | 854 | |
853 | static void | | 855 | static void |
854 | wsClose(InputInfoPtr pInfo) | | 856 | wsClose(InputInfoPtr pInfo) |
855 | { | | 857 | { |
856 | xf86CloseSerial(pInfo->fd); | | 858 | xf86CloseSerial(pInfo->fd); |
857 | pInfo->fd = -1; | | 859 | pInfo->fd = -1; |
858 | } | | 860 | } |
859 | | | 861 | |
860 | static void | | 862 | static void |
861 | wsControlProc(DeviceIntPtr device, PtrCtrl *ctrl) | | 863 | wsControlProc(DeviceIntPtr device, PtrCtrl *ctrl) |
862 | { | | 864 | { |
863 | InputInfoPtr pInfo = device->public.devicePrivate; | | 865 | InputInfoPtr pInfo = device->public.devicePrivate; |
864 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 866 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
865 | | | 867 | |
866 | DBG(1, ErrorF("wsControlProc\n")); | | 868 | DBG(1, ErrorF("wsControlProc\n")); |
867 | priv->num = ctrl->num; | | 869 | priv->num = ctrl->num; |
868 | priv->den = ctrl->den; | | 870 | priv->den = ctrl->den; |
869 | priv->threshold = ctrl->threshold; | | 871 | priv->threshold = ctrl->threshold; |
870 | } | | 872 | } |
871 | | | 873 | |
872 | static void | | 874 | static void |
873 | wsInitProperty(DeviceIntPtr device) | | 875 | wsInitProperty(DeviceIntPtr device) |
874 | { | | 876 | { |
875 | InputInfoPtr pInfo = device->public.devicePrivate; | | 877 | InputInfoPtr pInfo = device->public.devicePrivate; |
876 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 878 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
877 | int rc; | | 879 | int rc; |
878 | | | 880 | |
879 | DBG(1, ErrorF("wsInitProperty\n")); | | 881 | DBG(1, ErrorF("wsInitProperty\n")); |
880 | if (priv->type != WSMOUSE_TYPE_TPANEL) | | 882 | if (priv->type != WSMOUSE_TYPE_TPANEL) |
881 | return; | | 883 | return; |
882 | | | 884 | |
883 | prop_calibration = MakeAtom(WS_PROP_CALIBRATION, | | 885 | prop_calibration = MakeAtom(WS_PROP_CALIBRATION, |
884 | strlen(WS_PROP_CALIBRATION), TRUE); | | 886 | strlen(WS_PROP_CALIBRATION), TRUE); |
885 | rc = XIChangeDeviceProperty(device, prop_calibration, XA_INTEGER, 32, | | 887 | rc = XIChangeDeviceProperty(device, prop_calibration, XA_INTEGER, 32, |
886 | PropModeReplace, 4, &priv->min_x, FALSE); | | 888 | PropModeReplace, 4, &priv->min_x, FALSE); |
887 | if (rc != Success) | | 889 | if (rc != Success) |
888 | return; | | 890 | return; |
889 | | | 891 | |
890 | XISetDevicePropertyDeletable(device, prop_calibration, FALSE); | | 892 | XISetDevicePropertyDeletable(device, prop_calibration, FALSE); |
891 | | | 893 | |
892 | prop_swap = MakeAtom(WS_PROP_SWAP_AXES, | | 894 | prop_swap = MakeAtom(WS_PROP_SWAP_AXES, |
893 | strlen(WS_PROP_SWAP_AXES), TRUE); | | 895 | strlen(WS_PROP_SWAP_AXES), TRUE); |
894 | rc = XIChangeDeviceProperty(device, prop_swap, XA_INTEGER, 8, | | 896 | rc = XIChangeDeviceProperty(device, prop_swap, XA_INTEGER, 8, |
895 | PropModeReplace, 1, &priv->swap_axes, FALSE); | | 897 | PropModeReplace, 1, &priv->swap_axes, FALSE); |
896 | if (rc != Success) | | 898 | if (rc != Success) |
897 | return; | | 899 | return; |
898 | return; | | 900 | return; |
899 | } | | 901 | } |
900 | | | 902 | |
901 | static int | | 903 | static int |
902 | wsSetProperty(DeviceIntPtr device, Atom atom, XIPropertyValuePtr val, | | 904 | wsSetProperty(DeviceIntPtr device, Atom atom, XIPropertyValuePtr val, |
903 | BOOL checkonly) | | 905 | BOOL checkonly) |
904 | { | | 906 | { |
905 | InputInfoPtr pInfo = device->public.devicePrivate; | | 907 | InputInfoPtr pInfo = device->public.devicePrivate; |
906 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; | | 908 | WSDevicePtr priv = (WSDevicePtr)pInfo->private; |
907 | struct wsmouse_calibcoords coords; | | 909 | struct wsmouse_calibcoords coords; |
908 | int need_update = 0; | | 910 | int need_update = 0; |
909 | AxisInfoPtr ax = device->valuator->axes, | | 911 | AxisInfoPtr ax = device->valuator->axes, |
910 | ay = device->valuator->axes + 1; | | 912 | ay = device->valuator->axes + 1; |
911 | | | 913 | |
912 | DBG(1, ErrorF("wsSetProperty %s\n", NameForAtom(atom))); | | 914 | DBG(1, ErrorF("wsSetProperty %s\n", NameForAtom(atom))); |
913 | | | 915 | |
914 | /* Ignore non panel devices */ | | 916 | /* Ignore non panel devices */ |
915 | if (priv->type != WSMOUSE_TYPE_TPANEL) | | 917 | if (priv->type != WSMOUSE_TYPE_TPANEL) |
916 | return Success; | | 918 | return Success; |
917 | | | 919 | |
918 | if (atom == prop_calibration) { | | 920 | if (atom == prop_calibration) { |
919 | if (val->format != 32 || val->type != XA_INTEGER) | | 921 | if (val->format != 32 || val->type != XA_INTEGER) |
920 | return BadMatch; | | 922 | return BadMatch; |
921 | if (val->size != 4 && val->size != 0) | | 923 | if (val->size != 4 && val->size != 0) |
922 | return BadMatch; | | 924 | return BadMatch; |
923 | if (!checkonly) { | | 925 | if (!checkonly) { |
924 | if (val->size == 0) { | | 926 | if (val->size == 0) { |
925 | DBG(1, ErrorF(" uncalibrate\n")); | | 927 | DBG(1, ErrorF(" uncalibrate\n")); |
926 | priv->min_x = 0; | | 928 | priv->min_x = 0; |
927 | priv->max_x = -1; | | 929 | priv->max_x = -1; |
928 | priv->min_y = 0; | | 930 | priv->min_y = 0; |
929 | priv->max_y = -1; | | 931 | priv->max_y = -1; |
930 | } else { | | 932 | } else { |
931 | priv->min_x = ((int *)(val->data))[0]; | | 933 | priv->min_x = ((int *)(val->data))[0]; |
932 | priv->max_x = ((int *)(val->data))[1]; | | 934 | priv->max_x = ((int *)(val->data))[1]; |
933 | priv->min_y = ((int *)(val->data))[2]; | | 935 | priv->min_y = ((int *)(val->data))[2]; |
934 | priv->max_y = ((int *)(val->data))[3]; | | 936 | priv->max_y = ((int *)(val->data))[3]; |
935 | DBG(1, ErrorF(" calibrate %d %d %d %d\n", | | 937 | DBG(1, ErrorF(" calibrate %d %d %d %d\n", |
936 | priv->min_x, priv->max_x, | | 938 | priv->min_x, priv->max_x, |
937 | priv->min_y, priv->max_y)); | | 939 | priv->min_y, priv->max_y)); |
938 | need_update++; | | 940 | need_update++; |
939 | } | | 941 | } |
940 | /* Update axes descriptors */ | | 942 | /* Update axes descriptors */ |
941 | if (!priv->swap_axes) { | | 943 | if (!priv->swap_axes) { |
942 | ax->min_value = priv->min_x; | | 944 | ax->min_value = priv->min_x; |
943 | ax->max_value = priv->max_x; | | 945 | ax->max_value = priv->max_x; |
944 | ay->min_value = priv->min_y; | | 946 | ay->min_value = priv->min_y; |
945 | ay->max_value = priv->max_y; | | 947 | ay->max_value = priv->max_y; |
946 | } else { | | 948 | } else { |
947 | ax->min_value = priv->min_y; | | 949 | ax->min_value = priv->min_y; |
948 | ax->max_value = priv->max_y; | | 950 | ax->max_value = priv->max_y; |
949 | ay->min_value = priv->min_x; | | 951 | ay->min_value = priv->min_x; |
950 | ay->max_value = priv->max_x; | | 952 | ay->max_value = priv->max_x; |
951 | } | | 953 | } |
952 | } | | 954 | } |
953 | } else if (atom == prop_swap) { | | 955 | } else if (atom == prop_swap) { |
954 | if (val->format != 8 || val->type != XA_INTEGER || | | 956 | if (val->format != 8 || val->type != XA_INTEGER || |
955 | val->size != 1) | | 957 | val->size != 1) |
956 | return BadMatch; | | 958 | return BadMatch; |
957 | if (!checkonly) { | | 959 | if (!checkonly) { |
958 | priv->swap_axes = *((BOOL *)val->data); | | 960 | priv->swap_axes = *((BOOL *)val->data); |
959 | DBG(1, ErrorF("swap_axes %d\n", priv->swap_axes)); | | 961 | DBG(1, ErrorF("swap_axes %d\n", priv->swap_axes)); |
960 | need_update++; | | 962 | need_update++; |
961 | } | | 963 | } |
962 | } | | 964 | } |
963 | if (need_update) { | | 965 | if (need_update) { |
964 | /* Update the saved values to be restored on device off */ | | 966 | /* Update the saved values to be restored on device off */ |
965 | priv->coords.minx = priv->min_x; | | 967 | priv->coords.minx = priv->min_x; |
966 | priv->coords.maxx = priv->max_x; | | 968 | priv->coords.maxx = priv->max_x; |
967 | priv->coords.miny = priv->min_y; | | 969 | priv->coords.miny = priv->min_y; |
968 | priv->coords.maxy = priv->max_y; | | 970 | priv->coords.maxy = priv->max_y; |
969 | #ifndef __NetBSD__ | | 971 | #ifndef __NetBSD__ |
970 | priv->coords.swapxy = priv->swap_axes; | | 972 | priv->coords.swapxy = priv->swap_axes; |
971 | #endif | | 973 | #endif |
972 | | | 974 | |
973 | /* Update the kernel calibration table */ | | 975 | /* Update the kernel calibration table */ |
974 | coords.minx = priv->min_x; | | 976 | coords.minx = priv->min_x; |
975 | coords.maxx = priv->max_x; | | 977 | coords.maxx = priv->max_x; |
976 | coords.miny = priv->min_y; | | 978 | coords.miny = priv->min_y; |
977 | coords.maxy = priv->max_y; | | 979 | coords.maxy = priv->max_y; |
978 | #ifndef __NetBSD__ | | 980 | #ifndef __NetBSD__ |
979 | coords.swapxy = priv->swap_axes; | | 981 | coords.swapxy = priv->swap_axes; |
980 | #endif | | 982 | #endif |
981 | coords.samplelen = priv->raw; | | 983 | coords.samplelen = priv->raw; |
982 | #ifndef __NetBSD__ | | 984 | #ifndef __NetBSD__ |
983 | coords.resx = priv->coords.resx; | | 985 | coords.resx = priv->coords.resx; |
984 | coords.resy = priv->coords.resy; | | 986 | coords.resy = priv->coords.resy; |
985 | #endif | | 987 | #endif |
986 | if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { | | 988 | if (ioctl(pInfo->fd, WSMOUSEIO_SCALIBCOORDS, &coords) != 0) { |
987 | xf86Msg(X_ERROR, "SCALIBCOORDS failed %s\n", | | 989 | xf86Msg(X_ERROR, "SCALIBCOORDS failed %s\n", |
988 | strerror(errno)); | | 990 | strerror(errno)); |
989 | } | | 991 | } |
990 | } | | 992 | } |
991 | return Success; | | 993 | return Success; |
992 | } | | 994 | } |