1 |
dmorgan |
391 |
package mouse; # $Id: mouse.pm 267529 2010-04-13 13:48:09Z pzanoni $ |
2 |
|
|
|
3 |
|
|
#use diagnostics; |
4 |
|
|
#use strict; |
5 |
|
|
|
6 |
|
|
#-###################################################################################### |
7 |
|
|
#- misc imports |
8 |
|
|
#-###################################################################################### |
9 |
|
|
use common; |
10 |
|
|
use modules; |
11 |
|
|
use detect_devices; |
12 |
|
|
use run_program; |
13 |
|
|
use devices; |
14 |
|
|
use modules; |
15 |
|
|
use any; |
16 |
|
|
use log; |
17 |
|
|
|
18 |
|
|
sub _all_mice() { |
19 |
|
|
arch() =~ /^sparc/ ? |
20 |
|
|
( |
21 |
|
|
'sunmouse' => |
22 |
|
|
[ [ 'sunmouse' ], |
23 |
|
|
[ [ 3, 'sun', 'sun', N_("Sun - Mouse") ] |
24 |
|
|
] ] |
25 |
|
|
) : |
26 |
|
|
( |
27 |
|
|
'PS/2' => |
28 |
|
|
[ [ 'psaux' ], |
29 |
|
|
[ [ 2, 'ps/2', 'PS/2', N_("Standard") ], |
30 |
|
|
[ 5, 'ps/2', 'MouseManPlusPS/2', N_("Logitech MouseMan+") ], |
31 |
|
|
[ 5, 'imps2', 'IMPS/2', N_("Generic PS2 Wheel Mouse") ], |
32 |
|
|
[ 5, 'ps/2', 'GlidePointPS/2', N_("GlidePoint") ], |
33 |
|
|
[ 5, 'imps2', 'auto', N_("Automatic") ], |
34 |
|
|
'', |
35 |
|
|
[ 5, 'ps/2', 'ThinkingMousePS/2', N_("Kensington Thinking Mouse") ], |
36 |
|
|
[ 5, 'netmouse', 'NetMousePS/2', N_("Genius NetMouse") ], |
37 |
|
|
[ 5, 'netmouse', 'NetScrollPS/2', N_("Genius NetScroll") ], |
38 |
|
|
[ 7, 'ps/2', 'ExplorerPS/2', N_("Microsoft Explorer") ], |
39 |
|
|
] ], |
40 |
|
|
|
41 |
|
|
'USB' => |
42 |
|
|
[ [ 'input/mice' ], |
43 |
|
|
[ [ 1, 'ps/2', 'ExplorerPS/2', N_("1 button") ], |
44 |
|
|
[ 2, 'ps/2', 'ExplorerPS/2', N_("Generic 2 Button Mouse") ], |
45 |
|
|
[ 3, 'ps/2', 'ExplorerPS/2', N_("Generic") ], |
46 |
|
|
[ 3, 'ps/2', 'ExplorerPS/2', N_("Generic 3 Button Mouse with Wheel emulation"), 'wheel' ], |
47 |
|
|
[ 5, 'ps/2', 'ExplorerPS/2', N_("Wheel") ], |
48 |
|
|
[ 7, 'ps/2', 'ExplorerPS/2', N_("Microsoft Explorer") ], |
49 |
|
|
] ], |
50 |
|
|
|
51 |
|
|
N_("serial") => |
52 |
|
|
[ [ map { "ttyS$_" } 0..3 ], |
53 |
|
|
[ [ 2, 'Microsoft', 'Microsoft', N_("Generic 2 Button Mouse") ], |
54 |
|
|
[ 3, 'Microsoft', 'Microsoft', N_("Generic 3 Button Mouse") ], |
55 |
|
|
[ 3, 'Microsoft', 'Microsoft', N_("Generic 3 Button Mouse with Wheel emulation"), 'wheel' ], |
56 |
|
|
[ 5, 'ms3', 'IntelliMouse', N_("Microsoft IntelliMouse") ], |
57 |
|
|
[ 3, 'MouseMan', 'MouseMan', N_("Logitech MouseMan") ], |
58 |
|
|
[ 3, 'MouseMan', 'MouseMan', N_("Logitech MouseMan with Wheel emulation"), 'wheel' ], |
59 |
|
|
[ 2, 'MouseSystems', 'MouseSystems', N_("Mouse Systems") ], |
60 |
|
|
'', |
61 |
|
|
[ 3, 'logim', 'MouseMan', N_("Logitech CC Series") ], |
62 |
|
|
[ 3, 'logim', 'MouseMan', N_("Logitech CC Series with Wheel emulation"), 'wheel' ], |
63 |
|
|
[ 5, 'pnp', 'IntelliMouse', N_("Logitech MouseMan+/FirstMouse+") ], |
64 |
|
|
[ 5, 'ms3', 'IntelliMouse', N_("Genius NetMouse") ], |
65 |
|
|
[ 2, 'MMSeries', 'MMSeries', N_("MM Series") ], |
66 |
|
|
[ 2, 'MMHitTab', 'MMHittab', N_("MM HitTablet") ], |
67 |
|
|
[ 3, 'Logitech', 'Logitech', N_("Logitech Mouse (serial, old C7 type)") ], |
68 |
|
|
[ 3, 'Logitech', 'Logitech', N_("Logitech Mouse (serial, old C7 type) with Wheel emulation"), 'wheel' ], |
69 |
|
|
[ 3, 'Microsoft', 'ThinkingMouse', N_("Kensington Thinking Mouse") ], |
70 |
|
|
[ 3, 'Microsoft', 'ThinkingMouse', N_("Kensington Thinking Mouse with Wheel emulation"), 'wheel' ], |
71 |
|
|
] ], |
72 |
|
|
|
73 |
|
|
N_("busmouse") => |
74 |
|
|
[ [ arch() eq 'ppc' ? 'adbmouse' : ('atibm', 'inportbm', 'logibm') ], |
75 |
|
|
[ if_(arch() eq 'ppc', [ 1, 'Busmouse', 'BusMouse', N_("1 button") ]), |
76 |
|
|
[ 2, 'Busmouse', 'BusMouse', N_("2 buttons") ], |
77 |
|
|
[ 3, 'Busmouse', 'BusMouse', N_("3 buttons") ], |
78 |
|
|
[ 3, 'Busmouse', 'BusMouse', N_("3 buttons with Wheel emulation"), 'wheel' ], |
79 |
|
|
] ], |
80 |
|
|
|
81 |
|
|
N_("Universal") => |
82 |
|
|
[ [ 'input/mice' ], |
83 |
|
|
[ [ 7, 'ps/2', 'ExplorerPS/2', N_("Any PS/2 & USB mice") ], |
84 |
|
|
[ 7, 'ps/2', 'ExplorerPS/2', N_("Force evdev") ], #- evdev is magically handled in mouse::select() |
85 |
|
|
if_(detect_devices::is_xbox(), [ 5, 'ps/2', 'IMPS/2', N_("Microsoft Xbox Controller S") ]), |
86 |
|
|
if_(detect_devices::is_virtualbox(), [ 7, 'ps/2', 'vboxmouse', N_("VirtualBox mouse") ]), |
87 |
|
|
if_(detect_devices::is_vmware(), [ 7, 'ps/2', 'vmmouse', N_("VMware mouse") ]), |
88 |
|
|
] ], |
89 |
|
|
|
90 |
|
|
N_("none") => |
91 |
|
|
[ [ 'none' ], |
92 |
|
|
[ [ 0, 'none', 'Microsoft', N_("No mouse") ], |
93 |
|
|
] ], |
94 |
|
|
); |
95 |
|
|
} |
96 |
|
|
|
97 |
|
|
#- Logitech MX700 |
98 |
|
|
#- |
99 |
|
|
#- I: Bus=0003 Vendor=046d Product=c506 Version=1600 |
100 |
|
|
#- N: Name="Logitech USB Receiver" |
101 |
|
|
#- P: Phys=usb-0000:00:11.3-2/input0 |
102 |
|
|
#- S: Sysfs=/class/input/input5 |
103 |
|
|
#- H: Handlers=mouse2 ts2 event3 |
104 |
|
|
#- B: EV=7 |
105 |
|
|
#- B: KEY=ffff0000 0 0 0 0 0 0 0 0 |
106 |
|
|
#- B: REL=103 |
107 |
|
|
#- |
108 |
|
|
#- T: Bus=05 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 4 Spd=1.5 MxCh= 0 |
109 |
|
|
#- D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 |
110 |
|
|
#- P: Vendor=046d ProdID=c506 Rev=16.00 |
111 |
|
|
#- S: Manufacturer=Logitech |
112 |
|
|
#- S: Product=USB Receiver |
113 |
|
|
#- C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 50mA |
114 |
|
|
#- I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=usbhid |
115 |
|
|
#- E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms |
116 |
|
|
|
117 |
|
|
|
118 |
|
|
my %mouse_btn_keymap = ( |
119 |
|
|
0 => "NONE", |
120 |
|
|
67 => "F9", |
121 |
|
|
68 => "F10", |
122 |
|
|
87 => "F11", |
123 |
|
|
88 => "F12", |
124 |
|
|
85 => "F13", |
125 |
|
|
89 => "F14", |
126 |
|
|
90 => "F15", |
127 |
|
|
56 => "L-Option/Alt", |
128 |
|
|
125 => "L-Command (Apple)", |
129 |
|
|
98 => "Num: /", |
130 |
|
|
55 => "Num: *", |
131 |
|
|
117 => "Num: =", |
132 |
|
|
96 => "Enter", |
133 |
|
|
); |
134 |
|
|
sub _ppc_one_button_keys() { keys %mouse_btn_keymap } |
135 |
|
|
sub _ppc_one_button_key2text { $mouse_btn_keymap{$_[0]} } |
136 |
|
|
|
137 |
|
|
my @mouses_fields = qw(nbuttons MOUSETYPE Protocol name EmulateWheel); |
138 |
|
|
|
139 |
|
|
sub _raw2mouse { |
140 |
|
|
my ($type, $raw) = @_; |
141 |
|
|
$raw or return; |
142 |
|
|
|
143 |
|
|
my %l; @l{@mouses_fields} = @$raw; |
144 |
|
|
+{ %l, type => $type, if_($l{nbuttons} < 3, Emulate3Buttons => 1) }; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
sub fullname2mouse { |
148 |
|
|
my ($fname, %opts) = @_; |
149 |
|
|
my ($type, @l) = split '\|', $fname; |
150 |
|
|
my $name = pop @l; #- ensure we get rid of "[Other]" |
151 |
|
|
my %mice = _all_mice(); |
152 |
|
|
|
153 |
|
|
if (my @devices = @{$mice{$type}[0]}) { |
154 |
|
|
member($opts{device}, @devices) or delete $opts{device}; |
155 |
|
|
$opts{device} ||= $devices[0]; |
156 |
|
|
} |
157 |
|
|
foreach (@{$mice{$type}[1]}) { |
158 |
|
|
my $l = _raw2mouse($type, $_); |
159 |
|
|
$name eq $l->{name} and return { %$l, %opts }; |
160 |
|
|
} |
161 |
|
|
die "$fname not found ($type, $name)"; |
162 |
|
|
} |
163 |
|
|
|
164 |
|
|
sub read() { |
165 |
|
|
my %mouse = getVarsFromSh "$::prefix/etc/sysconfig/mouse"; |
166 |
|
|
eval { fullname2mouse($mouse{FULLNAME}, device => $mouse{device}) } || \%mouse; |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
sub write { |
170 |
|
|
my ($do_pkgs, $mouse) = @_; |
171 |
|
|
|
172 |
|
|
setVarsInSh("$::prefix/etc/sysconfig/mouse", { |
173 |
|
|
device => $mouse->{device}, |
174 |
|
|
MOUSETYPE => $mouse->{MOUSETYPE}, |
175 |
|
|
FULLNAME => qq($mouse->{type}|$mouse->{name}), |
176 |
|
|
}); |
177 |
|
|
|
178 |
|
|
various_xfree_conf($do_pkgs, $mouse); |
179 |
|
|
|
180 |
|
|
if (arch() =~ /ppc/) { |
181 |
|
|
my $s = join('', |
182 |
|
|
"dev.mac_hid.mouse_button_emulation = " . to_bool($mouse->{button2_key} || $mouse->{button3_key}) . "\n", |
183 |
|
|
if_($mouse->{button2_key}, "dev.mac_hid.mouse_button2_keycode = $mouse->{button2_key}\n"), |
184 |
|
|
if_($mouse->{button3_key}, "dev.mac_hid.mouse_button3_keycode = $mouse->{button3_key}\n"), |
185 |
|
|
); |
186 |
|
|
substInFile { |
187 |
|
|
$_ = '' if /^\Qdev.mac_hid.mouse_button/; |
188 |
|
|
$_ .= $s if eof; |
189 |
|
|
} "$::prefix/etc/sysctl.conf"; |
190 |
|
|
} |
191 |
|
|
} |
192 |
|
|
|
193 |
|
|
sub _input_entry_to_device_by_id { |
194 |
|
|
my ($input) = @_; |
195 |
|
|
|
196 |
|
|
my $ID_SERIAL = chomp_(run_program::get_stdout('usb_id', $input->{sysfs_path})); |
197 |
|
|
$ID_SERIAL =~ s/[^\w#+\-.:=@_]/_/g; #- udev do a further cleanup, eg: "Wacom_Co.,Ltd._MTE-450" => "Wacom_Co._Ltd._MTE-450". cf ALLOWED_CHARS udev.h |
198 |
|
|
my $sysfs_device = "input/by-id/usb-$ID_SERIAL-event-mouse"; #- from /etc/udev/rules.d/60-persistent-input.rules |
199 |
|
|
if ($::isInstall || -e "/dev/$sysfs_device") { |
200 |
|
|
$sysfs_device; |
201 |
|
|
} else { |
202 |
|
|
log::l("$sysfs_device missing"); |
203 |
|
|
(); |
204 |
|
|
} |
205 |
|
|
} |
206 |
|
|
|
207 |
|
|
sub _probe_usb_wacom_devices() { |
208 |
|
|
detect_devices::hasWacom() or return; |
209 |
|
|
|
210 |
|
|
eval { modules::load("wacom", "evdev") }; |
211 |
|
|
|
212 |
|
|
map { _input_entry_to_device_by_id($_) } detect_devices::usbWacom(); |
213 |
|
|
} |
214 |
|
|
|
215 |
|
|
sub _detect_serial() { |
216 |
|
|
my ($t, $mouse, @wacom); |
217 |
|
|
|
218 |
|
|
#- Whouah! probing all devices from ttyS0 to ttyS3 once a time! |
219 |
|
|
detect_devices::probeSerialDevices(); |
220 |
|
|
|
221 |
|
|
#- check new probing methods keep everything used here intact! |
222 |
|
|
foreach (0..3) { |
223 |
|
|
$t = detect_devices::probeSerial("/dev/ttyS$_") or next; |
224 |
|
|
if ($t->{CLASS} eq 'MOUSE') { |
225 |
|
|
$t->{MFG} ||= $t->{MANUFACTURER}; |
226 |
|
|
|
227 |
|
|
my $name = 'Generic 2 Button Mouse'; |
228 |
|
|
$name = 'Microsoft IntelliMouse' if $t->{MFG} eq 'MSH' && $t->{MODEL} eq '0001'; |
229 |
|
|
$name = 'Logitech MouseMan' if $t->{MFG} eq 'LGI' && $t->{MODEL} =~ /^80/; |
230 |
|
|
$name = 'Genius NetMouse' if $t->{MFG} eq 'KYE' && $t->{MODEL} eq '0003'; |
231 |
|
|
|
232 |
|
|
$mouse ||= fullname2mouse("serial|$name", device => "ttyS$_"); |
233 |
|
|
last; |
234 |
|
|
} elsif ($t->{CLASS} eq "PEN" || $t->{MANUFACTURER} eq "WAC") { |
235 |
|
|
push @wacom, "ttyS$_"; |
236 |
|
|
} |
237 |
|
|
} |
238 |
|
|
$mouse, @wacom; |
239 |
|
|
} |
240 |
|
|
|
241 |
|
|
sub _mice2evdev { |
242 |
|
|
my (@mice) = @_; |
243 |
|
|
|
244 |
|
|
[ map { |
245 |
|
|
#- we always use HWheelRelativeAxisButtons for evdev, it tells mice with no horizontal wheel to skip those buttons |
246 |
|
|
#- that way we ensure 6 & 7 is always horizontal wheel |
247 |
|
|
#- (cf patch skip-HWheelRelativeAxisButtons-even-if-unused in x11-driver-input-evdev) |
248 |
|
|
{ device => "/dev/$_", HWheelRelativeAxisButtons => "7 6" }; |
249 |
|
|
} map { _input_entry_to_device_by_id($_) } @mice ]; |
250 |
|
|
} |
251 |
|
|
|
252 |
|
|
sub _detect_evdev_mice { |
253 |
|
|
my (@mice) = @_; |
254 |
|
|
|
255 |
|
|
foreach (@mice) { |
256 |
|
|
my @l = $_->{usb} && $_->{usb}{driver} =~ /^Mouse:(.*)/ ? split('\|', $1) : (); |
257 |
|
|
foreach my $opt (@l) { |
258 |
|
|
if ($opt eq 'evdev') { |
259 |
|
|
$_->{want_evdev} = 1; |
260 |
|
|
} |
261 |
|
|
} |
262 |
|
|
if ($_->{HWHEEL}) { |
263 |
|
|
$_->{want_evdev} = 1; |
264 |
|
|
} |
265 |
|
|
} |
266 |
|
|
|
267 |
|
|
my @evdev_mice = grep { $_->{want_evdev} } @mice; |
268 |
|
|
|
269 |
|
|
log::l("configuring mice for evdev (" . join(' ', map { "$_->{vendor}:$_->{product}" } @evdev_mice) . ")") if @evdev_mice; |
270 |
|
|
|
271 |
|
|
{ evdev_mice_all => _mice2evdev(@mice), |
272 |
|
|
if_(@evdev_mice, evdev_mice => _mice2evdev(@evdev_mice)) }; |
273 |
|
|
} |
274 |
|
|
|
275 |
|
|
sub detect { |
276 |
|
|
my ($modules_conf) = @_; |
277 |
|
|
|
278 |
|
|
# let more USB tablets and touchscreens magically work at install time |
279 |
|
|
# through /dev/input/mice multiplexing: |
280 |
|
|
detect_devices::probe_category('input/tablet'); |
281 |
|
|
detect_devices::probe_category('input/touchscreen'); |
282 |
|
|
|
283 |
ennael |
759 |
# evdev needs to be loaded before calling getInputDevices_and_usb |
284 |
|
|
# else it will lead to a crash |
285 |
|
|
eval { modules::load("evdev") }; |
286 |
|
|
|
287 |
dmorgan |
391 |
my @wacom = _probe_usb_wacom_devices(); |
288 |
|
|
|
289 |
|
|
$modules_conf->get_probeall("usb-interface") and eval { modules::load('usbhid') }; |
290 |
|
|
if (detect_devices::is_virtualbox()) { |
291 |
|
|
fullname2mouse("Universal|VirtualBox mouse"); |
292 |
|
|
} elsif (detect_devices::is_vmware()) { |
293 |
|
|
fullname2mouse("Universal|VMware mouse"); |
294 |
|
|
} elsif (my @mice = grep { $_->{Handlers}{mouse} } detect_devices::getInputDevices_and_usb()) { |
295 |
|
|
my @synaptics = map { |
296 |
|
|
{ ALPS => $_->{ALPS} }; |
297 |
|
|
} grep { $_->{Synaptics} || $_->{ALPS} } @mice; |
298 |
|
|
|
299 |
|
|
my $evdev_opts = _detect_evdev_mice(@mice); |
300 |
|
|
|
301 |
|
|
my $fullname = detect_devices::is_xbox() ? |
302 |
|
|
'Universal|Microsoft Xbox Controller S' : |
303 |
|
|
arch() eq "ppc" ? |
304 |
|
|
'USB|1 button' : |
305 |
|
|
'Universal|Any PS/2 & USB mice'; |
306 |
|
|
|
307 |
|
|
fullname2mouse($fullname, wacom => \@wacom, |
308 |
|
|
synaptics => $synaptics[0], |
309 |
|
|
if_($evdev_opts, %$evdev_opts)); |
310 |
|
|
} elsif (arch() eq 'ppc') { |
311 |
|
|
# No need to search for an ADB mouse. If I did, the PPC kernel would |
312 |
|
|
# find one whether or not I had one installed! So.. default to it. |
313 |
|
|
fullname2mouse("busmouse|1 button"); |
314 |
|
|
} elsif (arch() =~ /^sparc/) { |
315 |
|
|
fullname2mouse("sunmouse|Sun - Mouse"); |
316 |
|
|
} else { |
317 |
|
|
#- probe serial device to make sure a wacom has been detected. |
318 |
|
|
eval { modules::load("serial") }; |
319 |
|
|
my ($serial_mouse, @serial_wacom) = _detect_serial(); |
320 |
|
|
push @wacom, @serial_wacom; |
321 |
|
|
if ($serial_mouse) { |
322 |
|
|
{ wacom => \@wacom, %$serial_mouse }; |
323 |
|
|
} elsif (@wacom) { |
324 |
|
|
#- in case only a wacom has been found, assume an inexistant mouse (necessary). |
325 |
|
|
fullname2mouse('none|No mouse', wacom => \@wacom); |
326 |
|
|
} else { |
327 |
|
|
fullname2mouse('Universal|Any PS/2 & USB mice', unsafe => 1); |
328 |
|
|
} |
329 |
|
|
} |
330 |
|
|
} |
331 |
|
|
|
332 |
|
|
sub load_modules { |
333 |
|
|
my ($mouse) = @_; |
334 |
|
|
my @l; |
335 |
|
|
push @l, qw(hid mousedev usbmouse) if $mouse->{type} =~ /USB/; |
336 |
|
|
push @l, qw(serial) if $mouse->{type} =~ /serial/ || any { /ttyS/ } @{$mouse->{wacom}}; |
337 |
|
|
push @l, qw(wacom evdev) if any { /event/ } @{$mouse->{wacom}}; |
338 |
|
|
push @l, qw(evdev) if $mouse->{synaptics} || $mouse->{evdev_mice}; |
339 |
|
|
|
340 |
|
|
eval { modules::load(@l) }; |
341 |
|
|
} |
342 |
|
|
|
343 |
|
|
sub set_xfree_conf { |
344 |
|
|
my ($mouse, $xfree_conf, $b_keep_auxmouse_unchanged) = @_; |
345 |
|
|
|
346 |
|
|
my @mice = map { |
347 |
|
|
{ |
348 |
|
|
(member($_->{Protocol}, qw(vboxmouse vmmouse)) ? "Driver" : "Protocol") => $_->{Protocol}, |
349 |
|
|
Device => devices::make($_->{device}), |
350 |
|
|
if_($_->{Emulate3Buttons} || $_->{EmulateWheel}, Emulate3Buttons => undef, Emulate3Timeout => 50), |
351 |
|
|
if_($_->{EmulateWheel}, EmulateWheel => undef, EmulateWheelButton => 2), |
352 |
|
|
}; |
353 |
|
|
} $mouse; |
354 |
|
|
|
355 |
|
|
if ($mouse->{evdev_mice}) { |
356 |
|
|
push @mice, @{$mouse->{evdev_mice}}; |
357 |
|
|
} elsif (!$mouse->{synaptics} && $b_keep_auxmouse_unchanged) { |
358 |
|
|
my (undef, @l) = $xfree_conf->get_mice; |
359 |
|
|
push @mice, @l; |
360 |
|
|
} |
361 |
|
|
|
362 |
|
|
$xfree_conf->set_mice(@mice); |
363 |
|
|
|
364 |
|
|
if (my @wacoms = @{$mouse->{wacom} || []}) { |
365 |
|
|
$xfree_conf->set_wacoms(map { { Device => "/dev/$_", USB => to_bool(m|input/by-path/event|) } } @wacoms); |
366 |
|
|
} |
367 |
|
|
} |
368 |
|
|
|
369 |
|
|
sub various_xfree_conf { |
370 |
|
|
my ($do_pkgs, $mouse) = @_; |
371 |
|
|
|
372 |
|
|
-e "/usr/bin/X" or return; |
373 |
|
|
|
374 |
|
|
#- we don't need this anymore. Remove it for upgrades |
375 |
|
|
unlink("$::prefix/etc/X11/xinit.d/mouse_buttons"); |
376 |
|
|
{ |
377 |
|
|
my $f = "$::prefix/etc/X11/xinit.d/xpad"; |
378 |
|
|
if ($mouse->{name} !~ /^Microsoft Xbox Controller/) { |
379 |
|
|
unlink($f); |
380 |
|
|
} else { |
381 |
|
|
output_with_perm($f, 0755, "xset m 1/8 1\n"); |
382 |
|
|
} |
383 |
|
|
} |
384 |
|
|
|
385 |
|
|
require Xconfig::card; |
386 |
|
|
my $inputdrvpath = Xconfig::card::modules_dir() . '/input'; |
387 |
|
|
my $pkgs = [ |
388 |
|
|
if_($mouse->{synaptics}, ['x11-driver-input-synaptics', "$inputdrvpath/synaptics_drv.so"]), |
389 |
|
|
if_($mouse->{evdev_mice}, ['x11-driver-input-evdev', "$inputdrvpath/evdev_drv.so"]), |
390 |
|
|
if_($mouse->{Protocol} eq 'vboxmouse', ['x11-driver-input-vboxmouse', "$inputdrvpath/vboxmouse_drv.so"]), |
391 |
|
|
if_(@{$mouse->{wacom}}, ['x11-driver-input-wacom', "$inputdrvpath/wacom_drv.so"]), |
392 |
|
|
if_($mouse->{name} =~ /VMware/i, ['x11-driver-input-vmmouse', "$inputdrvpath/vmmouse_drv.so"]), |
393 |
|
|
]; |
394 |
|
|
$do_pkgs->ensure_files_are_installed($pkgs, 1); |
395 |
|
|
|
396 |
|
|
} |
397 |
|
|
|
398 |
|
|
#- write_conf : write the mouse infos into the Xconfig files. |
399 |
|
|
#- input : |
400 |
|
|
#- $mouse : the hashtable containing the informations |
401 |
|
|
#- $mouse input |
402 |
|
|
#- $mouse->{nbuttons} : number of buttons : integer |
403 |
|
|
#- $mouse->{device} : device of the mouse : string : ex 'psaux' |
404 |
|
|
#- $mouse->{Protocol} : type of the mouse for X : string (eg 'PS/2') |
405 |
|
|
#- $mouse->{type} : type (generic ?) of the mouse : string : ex 'PS/2' |
406 |
|
|
#- $mouse->{name} : name of the mouse : string : ex 'Standard' |
407 |
|
|
#- $mouse->{MOUSETYPE} : type of the mouse : string : ex "ps/2" |
408 |
|
|
sub write_conf { |
409 |
|
|
my ($do_pkgs, $modules_conf, $mouse, $b_keep_auxmouse_unchanged) = @_; |
410 |
|
|
|
411 |
|
|
&write($do_pkgs, $mouse); |
412 |
|
|
$modules_conf->write if $mouse->{device} eq "input/mice" && !$::testing; |
413 |
|
|
|
414 |
|
|
eval { |
415 |
|
|
require Xconfig::xfree; |
416 |
|
|
my $xfree_conf = Xconfig::xfree->read; |
417 |
|
|
set_xfree_conf($mouse, $xfree_conf, $b_keep_auxmouse_unchanged); |
418 |
|
|
$xfree_conf->write; |
419 |
|
|
}; |
420 |
|
|
} |
421 |
|
|
|
422 |
|
|
sub _xmouse2xId { |
423 |
|
|
#- xmousetypes must be sorted as found in /usr/include/X11/extensions/xf86misc.h |
424 |
|
|
#- so that first mean "0", etc |
425 |
|
|
my @xmousetypes = ( |
426 |
|
|
"Microsoft", |
427 |
|
|
"MouseSystems", |
428 |
|
|
"MMSeries", |
429 |
|
|
"Logitech", |
430 |
|
|
"BusMouse", #MouseMan, |
431 |
|
|
"Logitech", |
432 |
|
|
"PS/2", |
433 |
|
|
"MMHittab", |
434 |
|
|
"GlidePoint", |
435 |
|
|
"IntelliMouse", |
436 |
|
|
"ThinkingMouse", |
437 |
|
|
"IMPS/2", |
438 |
|
|
"ThinkingMousePS/2", |
439 |
|
|
"MouseManPlusPS/2", |
440 |
|
|
"GlidePointPS/2", |
441 |
|
|
"NetMousePS/2", |
442 |
|
|
"NetScrollPS/2", |
443 |
|
|
"SysMouse", |
444 |
|
|
"Auto", |
445 |
|
|
"AceCad", |
446 |
|
|
"ExplorerPS/2", |
447 |
|
|
"USB", |
448 |
|
|
); |
449 |
|
|
my ($id) = @_; |
450 |
|
|
$id = 'BusMouse' if $id eq 'MouseMan'; |
451 |
|
|
$id = 'IMPS/2' if $id eq 'ExplorerPS/2' && $::isInstall; |
452 |
|
|
eval { find_index { $_ eq $id } @xmousetypes } || 0; |
453 |
|
|
} |
454 |
|
|
|
455 |
|
|
sub change_mouse_live { |
456 |
|
|
my ($mouse, $old) = @_; |
457 |
|
|
|
458 |
|
|
my $xId = _xmouse2xId($mouse->{Protocol}); |
459 |
|
|
$old->{device} ne $mouse->{device} || $xId != _xmouse2xId($old->{Protocol}) or return; |
460 |
|
|
|
461 |
|
|
log::l("telling X server to use another mouse ($mouse->{Protocol}, $xId)"); |
462 |
|
|
eval { modules::load('serial') } if $mouse->{device} =~ /ttyS/; |
463 |
|
|
|
464 |
|
|
if (!$::testing) { |
465 |
|
|
devices::make($mouse->{device}); |
466 |
|
|
symlinkf($mouse->{device}, "/dev/mouse"); |
467 |
|
|
eval { |
468 |
|
|
require xf86misc::main; |
469 |
|
|
xf86misc::main::setMouseLive($ENV{DISPLAY}, $xId, $mouse->{Emulate3Buttons}); |
470 |
|
|
}; |
471 |
|
|
} |
472 |
|
|
1; |
473 |
|
|
} |
474 |
|
|
|
475 |
|
|
sub test_mouse_install { |
476 |
|
|
my ($mouse, $x_protocol_changed) = @_; |
477 |
|
|
require ugtk2; |
478 |
|
|
ugtk2->import(qw(:wrappers :create)); |
479 |
|
|
my $w = ugtk2->new(N("Testing the mouse"), disallow_big_help => 1); |
480 |
|
|
my $darea = Gtk2::DrawingArea->new; |
481 |
|
|
$darea->set_events([ 'button_press_mask', 'button_release_mask' ]); #$darea must be unrealized. |
482 |
|
|
gtkadd($w->{window}, |
483 |
|
|
gtkpack(my $vbox_grab = Gtk2::VBox->new(0, 0), |
484 |
|
|
$darea, |
485 |
|
|
gtkset_sensitive(create_okcancel($w, undef, '', 'edge'), 1) |
486 |
|
|
), |
487 |
|
|
); |
488 |
|
|
test_mouse($mouse, $darea, $x_protocol_changed); |
489 |
|
|
$w->sync; # HACK |
490 |
|
|
Gtk2::Gdk->pointer_grab($vbox_grab->window, 1, 'pointer_motion_mask', $vbox_grab->window, undef, 0); |
491 |
|
|
my $r = $w->main; |
492 |
|
|
Gtk2::Gdk->pointer_ungrab(0); |
493 |
|
|
$r; |
494 |
|
|
} |
495 |
|
|
|
496 |
|
|
sub _fullnames() { |
497 |
|
|
map_each { |
498 |
|
|
my $type = $::a; |
499 |
|
|
grep { $_ } map { |
500 |
|
|
if ($_) { |
501 |
|
|
my $l = _raw2mouse($type, $_); |
502 |
|
|
"$type|$l->{name}"; |
503 |
|
|
} else { |
504 |
|
|
$type .= "|[" . N("Other") . "]"; |
505 |
|
|
''; |
506 |
|
|
} |
507 |
|
|
} @{$::b->[1]}; |
508 |
|
|
} _all_mice(); |
509 |
|
|
} |
510 |
|
|
|
511 |
|
|
sub select { |
512 |
|
|
my ($in, $mouse) = @_; |
513 |
|
|
|
514 |
|
|
my $prev = my $fullname = $mouse->{type} . '|' . $mouse->{name}; |
515 |
|
|
|
516 |
|
|
$in->ask_from_({ messages => N("Please choose your type of mouse."), |
517 |
|
|
title => N("Mouse choice"), |
518 |
|
|
interactive_help_id => 'selectMouse', |
519 |
|
|
if_($mouse->{unsafe}, cancel => ''), |
520 |
|
|
}, |
521 |
|
|
[ { list => [ _fullnames() ], separator => '|', val => \$fullname, |
522 |
|
|
format => sub { join('|', map { translate($_) } split('\|', $_[0])) } } ]) or return; |
523 |
|
|
|
524 |
|
|
if ($fullname ne $prev) { |
525 |
|
|
my $mouse_ = fullname2mouse($fullname, device => $mouse->{device}); |
526 |
|
|
if ($fullname =~ /evdev/) { |
527 |
|
|
$mouse_->{evdev_mice} = $mouse_->{evdev_mice_all} = $mouse->{evdev_mice_all}; |
528 |
|
|
} |
529 |
|
|
%$mouse = %$mouse_; |
530 |
|
|
} |
531 |
|
|
|
532 |
|
|
if ($mouse->{nbuttons} < 3 && $::isStandalone) { |
533 |
|
|
$mouse->{Emulate3Buttons} = $in->ask_yesorno('', N("Emulate third button?"), 1); |
534 |
|
|
} |
535 |
|
|
|
536 |
|
|
if ($mouse->{type} eq 'serial') { |
537 |
|
|
$in->ask_from_({ title => N("Mouse Port"), |
538 |
|
|
messages => N("Please choose which serial port your mouse is connected to."), |
539 |
|
|
interactive_help_id => 'selectSerialPort', |
540 |
|
|
}, [ { list => [ detect_devices::serialPorts() ], format => \&detect_devices::serialPort2text, val => \$mouse->{device} } ]) or return &select; |
541 |
|
|
} |
542 |
|
|
|
543 |
|
|
if (arch() =~ /ppc/ && $mouse->{nbuttons} == 1) { |
544 |
|
|
#- set a sane default F11/F12 |
545 |
|
|
$mouse->{button2_key} = 87; |
546 |
|
|
$mouse->{button3_key} = 88; |
547 |
|
|
$in->ask_from('', N("Buttons emulation"), |
548 |
|
|
[ |
549 |
|
|
{ label => N("Button 2 Emulation"), val => \$mouse->{button2_key}, list => [ _ppc_one_button_keys() ], format => \&_ppc_one_button_key2text }, |
550 |
|
|
{ label => N("Button 3 Emulation"), val => \$mouse->{button3_key}, list => [ _ppc_one_button_keys() ], format => \&_ppc_one_button_key2text }, |
551 |
|
|
]) or return; |
552 |
|
|
} |
553 |
|
|
1; |
554 |
|
|
} |
555 |
|
|
|
556 |
|
|
sub test_mouse { |
557 |
|
|
my ($mouse, $darea, $b_x_protocol_changed) = @_; |
558 |
|
|
|
559 |
|
|
require ugtk2; |
560 |
|
|
ugtk2->import(qw(:wrappers)); |
561 |
|
|
my $suffix = $mouse->{nbuttons} <= 2 ? '2b' : $mouse->{nbuttons} == 3 ? '3b' : '3b+'; |
562 |
|
|
my %offsets = (mouse_2b_right => [ 93, 0 ], mouse_3b_right => [ 117, 0 ], |
563 |
|
|
mouse_2b_middle => [ 82, 80 ], mouse_3b_middle => [ 68, 0 ], 'mouse_3b+_middle' => [ 85, 67 ]); |
564 |
|
|
my %image_files = ( |
565 |
|
|
mouse => "mouse_$suffix", |
566 |
|
|
left => 'mouse_' . ($suffix eq '3b+' ? '3b' : $suffix) . '_left', |
567 |
|
|
right => 'mouse_' . ($suffix eq '3b+' ? '3b' : $suffix) . '_right', |
568 |
|
|
if_($mouse->{nbuttons} > 2, middle => 'mouse_' . $suffix . '_middle'), |
569 |
|
|
up => 'arrow_up', |
570 |
|
|
down => 'arrow_down'); |
571 |
|
|
my %images = map { $_ => ugtk2::gtkcreate_pixbuf("$image_files{$_}.png") } keys %image_files; |
572 |
|
|
my $width = $images{mouse}->get_width; |
573 |
|
|
my $height = round_up($images{mouse}->get_height, 6); |
574 |
|
|
|
575 |
|
|
my $draw_text = sub { |
576 |
|
|
my ($t, $y) = @_; |
577 |
|
|
my $layout = $darea->create_pango_layout($t); |
578 |
|
|
my ($w) = $layout->get_pixel_size; |
579 |
|
|
$darea->window->draw_layout($darea->style->black_gc, |
580 |
|
|
($darea->allocation->width-$w)/2, |
581 |
|
|
($darea->allocation->height-$height)/2 + $y, |
582 |
|
|
$layout); |
583 |
|
|
}; |
584 |
|
|
my $draw_pixbuf = sub { |
585 |
|
|
my ($p, $x, $y, $w, $h) = @_; |
586 |
|
|
$w = $p->get_width; |
587 |
|
|
$h = $p->get_height; |
588 |
|
|
$p->render_to_drawable($darea->window, $darea->style->bg_gc('normal'), 0, 0, |
589 |
|
|
($darea->allocation->width-$width)/2 + $x, ($darea->allocation->height-$height)/2 + $y, |
590 |
|
|
$w, $h, 'none', 0, 0); |
591 |
|
|
}; |
592 |
|
|
my $draw_by_name = sub { |
593 |
|
|
my ($name) = @_; |
594 |
|
|
my $file = $image_files{$name}; |
595 |
|
|
my ($x, $y) = @{$offsets{$file} || [ 0, 0 ]}; |
596 |
|
|
$draw_pixbuf->($images{$name}, $x, $y); |
597 |
|
|
}; |
598 |
|
|
my $drawarea = sub { |
599 |
|
|
$draw_by_name->('mouse'); |
600 |
|
|
if ($::isInstall || 1) { |
601 |
|
|
$draw_text->(N("Please test the mouse"), 200); |
602 |
|
|
if ($b_x_protocol_changed && $mouse->{nbuttons} > 3 && $mouse->{device} eq 'psaux' && member($mouse->{Protocol}, 'IMPS/2', 'ExplorerPS/2')) { |
603 |
|
|
$draw_text->(N("To activate the mouse,"), 240); |
604 |
|
|
$draw_text->(N("MOVE YOUR WHEEL!"), 260); |
605 |
|
|
} |
606 |
|
|
} |
607 |
|
|
}; |
608 |
|
|
|
609 |
|
|
my $timeout; |
610 |
|
|
my $paintButton = sub { |
611 |
|
|
my ($nb) = @_; |
612 |
|
|
$timeout or $drawarea->(); |
613 |
|
|
if ($nb == 0) { |
614 |
|
|
$draw_by_name->('left'); |
615 |
|
|
} elsif ($nb == 2) { |
616 |
|
|
$draw_by_name->('right'); |
617 |
|
|
} elsif ($nb == 1) { |
618 |
|
|
if ($mouse->{nbuttons} >= 3) { |
619 |
|
|
$draw_by_name->('middle'); |
620 |
|
|
} else { |
621 |
|
|
my ($x, $y) = @{$offsets{mouse_2b_middle}}; |
622 |
|
|
$darea->window->draw_arc($darea->style->black_gc, |
623 |
|
|
1, ($darea->allocation->width-$width)/2 + $x, ($darea->allocation->height-$height)/2 + $y, 20, 25, |
624 |
|
|
0, 360 * 64); |
625 |
|
|
} |
626 |
|
|
} elsif ($mouse->{nbuttons} > 3) { |
627 |
|
|
my ($x, $y) = @{$offsets{$image_files{middle}}}; |
628 |
|
|
if ($nb == 3) { |
629 |
|
|
$draw_pixbuf->($images{up}, $x+6, $y-10); |
630 |
|
|
} elsif ($nb == 4) { |
631 |
|
|
$draw_pixbuf->($images{down}, $x+6, $y + $images{middle}->get_height + 2); |
632 |
|
|
} |
633 |
|
|
$draw_by_name->('middle'); |
634 |
|
|
$timeout and Glib::Source->remove($timeout); |
635 |
|
|
$timeout = Glib::Timeout->add(100, sub { $drawarea->(); $timeout = 0; 0 }); |
636 |
|
|
} |
637 |
|
|
}; |
638 |
|
|
|
639 |
|
|
$darea->signal_connect(button_press_event => sub { $paintButton->($_[1]->button - 1) }); |
640 |
|
|
$darea->signal_connect(scroll_event => sub { $paintButton->($_[1]->direction eq 'up' ? 3 : 4) }); |
641 |
|
|
$darea->signal_connect(button_release_event => $drawarea); |
642 |
|
|
$darea->signal_connect(expose_event => $drawarea); |
643 |
|
|
$darea->set_size_request($width, $height); |
644 |
|
|
} |
645 |
|
|
|
646 |
|
|
|
647 |
|
|
=begin |
648 |
|
|
|
649 |
|
|
=head1 NAME |
650 |
|
|
|
651 |
|
|
mouse - Perl functions to handle mice |
652 |
|
|
|
653 |
|
|
=head1 SYNOPSYS |
654 |
|
|
|
655 |
|
|
require modules; |
656 |
|
|
require mouse; |
657 |
|
|
mouse::detect(modules::any_conf->read); |
658 |
|
|
|
659 |
|
|
=head1 DESCRIPTION |
660 |
|
|
|
661 |
|
|
C<mouse> is a perl module used by mousedrake to detect and configure the mouse. |
662 |
|
|
|
663 |
|
|
=head1 COPYRIGHT |
664 |
|
|
|
665 |
|
|
Copyright (C) 2000-2006 Mandriva <tvignaud@mandriva.com> |
666 |
|
|
|
667 |
|
|
This program is free software; you can redistribute it and/or modify |
668 |
|
|
it under the terms of the GNU General Public License as published by |
669 |
|
|
the Free Software Foundation; either version 2, or (at your option) |
670 |
|
|
any later version. |
671 |
|
|
|
672 |
|
|
This program is distributed in the hope that it will be useful, |
673 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
674 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
675 |
|
|
GNU General Public License for more details. |
676 |
|
|
|
677 |
|
|
You should have received a copy of the GNU General Public License |
678 |
|
|
along with this program; if not, write to the Free Software |
679 |
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
680 |
|
|
|
681 |
|
|
=cut |