/[soft]/drakx-kbd-mouse-x11/trunk/lib/mouse.pm
ViewVC logotype

Contents of /drakx-kbd-mouse-x11/trunk/lib/mouse.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2477 - (show annotations) (download)
Sun Dec 18 20:57:14 2011 UTC (12 years, 4 months ago) by colin
File size: 23023 byte(s)
Convert mouse helper to use udevadm in order to work with udev 175+
1 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 = "";
197 for (split /^/, run_program::get_stdout('udevadm', 'info', '--query', 'env', '--path', $input->{sysfs_path})) {
198 if (/^ID_SERIAL=(.*)/) {
199 $ID_SERIAL = $1;
200 $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
201 break;
202 }
203 }
204 my $sysfs_device = "input/by-id/usb-$ID_SERIAL-event-mouse"; #- from /etc/udev/rules.d/60-persistent-input.rules
205 if ($::isInstall || -e "/dev/$sysfs_device") {
206 $sysfs_device;
207 } else {
208 log::l("$sysfs_device missing");
209 ();
210 }
211 }
212
213 sub _probe_usb_wacom_devices() {
214 detect_devices::hasWacom() or return;
215
216 eval { modules::load("wacom", "evdev") };
217
218 map { _input_entry_to_device_by_id($_) } detect_devices::usbWacom();
219 }
220
221 sub _detect_serial() {
222 my ($t, $mouse, @wacom);
223
224 #- Whouah! probing all devices from ttyS0 to ttyS3 once a time!
225 detect_devices::probeSerialDevices();
226
227 #- check new probing methods keep everything used here intact!
228 foreach (0..3) {
229 $t = detect_devices::probeSerial("/dev/ttyS$_") or next;
230 if ($t->{CLASS} eq 'MOUSE') {
231 $t->{MFG} ||= $t->{MANUFACTURER};
232
233 my $name = 'Generic 2 Button Mouse';
234 $name = 'Microsoft IntelliMouse' if $t->{MFG} eq 'MSH' && $t->{MODEL} eq '0001';
235 $name = 'Logitech MouseMan' if $t->{MFG} eq 'LGI' && $t->{MODEL} =~ /^80/;
236 $name = 'Genius NetMouse' if $t->{MFG} eq 'KYE' && $t->{MODEL} eq '0003';
237
238 $mouse ||= fullname2mouse("serial|$name", device => "ttyS$_");
239 last;
240 } elsif ($t->{CLASS} eq "PEN" || $t->{MANUFACTURER} eq "WAC") {
241 push @wacom, "ttyS$_";
242 }
243 }
244 $mouse, @wacom;
245 }
246
247 sub _mice2evdev {
248 my (@mice) = @_;
249
250 [ map {
251 #- we always use HWheelRelativeAxisButtons for evdev, it tells mice with no horizontal wheel to skip those buttons
252 #- that way we ensure 6 & 7 is always horizontal wheel
253 #- (cf patch skip-HWheelRelativeAxisButtons-even-if-unused in x11-driver-input-evdev)
254 { device => "/dev/$_", HWheelRelativeAxisButtons => "7 6" };
255 } map { _input_entry_to_device_by_id($_) } @mice ];
256 }
257
258 sub _detect_evdev_mice {
259 my (@mice) = @_;
260
261 foreach (@mice) {
262 my @l = $_->{usb} && $_->{usb}{driver} =~ /^Mouse:(.*)/ ? split('\|', $1) : ();
263 foreach my $opt (@l) {
264 if ($opt eq 'evdev') {
265 $_->{want_evdev} = 1;
266 }
267 }
268 if ($_->{HWHEEL}) {
269 $_->{want_evdev} = 1;
270 }
271 }
272
273 my @evdev_mice = grep { $_->{want_evdev} } @mice;
274
275 log::l("configuring mice for evdev (" . join(' ', map { "$_->{vendor}:$_->{product}" } @evdev_mice) . ")") if @evdev_mice;
276
277 { evdev_mice_all => _mice2evdev(@mice),
278 if_(@evdev_mice, evdev_mice => _mice2evdev(@evdev_mice)) };
279 }
280
281 sub detect {
282 my ($modules_conf) = @_;
283
284 # let more USB tablets and touchscreens magically work at install time
285 # through /dev/input/mice multiplexing:
286 detect_devices::probe_category('input/tablet');
287 detect_devices::probe_category('input/touchscreen');
288
289 my @wacom = _probe_usb_wacom_devices();
290
291 $modules_conf->get_probeall("usb-interface") and eval { modules::load('usbhid') };
292 if (detect_devices::is_virtualbox()) {
293 fullname2mouse("Universal|VirtualBox mouse");
294 } elsif (detect_devices::is_vmware()) {
295 fullname2mouse("Universal|VMware mouse");
296 } elsif (my @mice = grep { $_->{Handlers}{mouse} } detect_devices::getInputDevices_and_usb()) {
297 my @synaptics = map {
298 { ALPS => $_->{ALPS} };
299 } grep { $_->{Synaptics} || $_->{ALPS} } @mice;
300
301 my $evdev_opts = _detect_evdev_mice(@mice);
302
303 my $fullname = detect_devices::is_xbox() ?
304 'Universal|Microsoft Xbox Controller S' :
305 arch() eq "ppc" ?
306 'USB|1 button' :
307 'Universal|Any PS/2 & USB mice';
308
309 fullname2mouse($fullname, wacom => \@wacom,
310 synaptics => $synaptics[0],
311 if_($evdev_opts, %$evdev_opts));
312 } elsif (arch() eq 'ppc') {
313 # No need to search for an ADB mouse. If I did, the PPC kernel would
314 # find one whether or not I had one installed! So.. default to it.
315 fullname2mouse("busmouse|1 button");
316 } elsif (arch() =~ /^sparc/) {
317 fullname2mouse("sunmouse|Sun - Mouse");
318 } else {
319 #- probe serial device to make sure a wacom has been detected.
320 eval { modules::load("serial") };
321 my ($serial_mouse, @serial_wacom) = _detect_serial();
322 push @wacom, @serial_wacom;
323 if ($serial_mouse) {
324 { wacom => \@wacom, %$serial_mouse };
325 } elsif (@wacom) {
326 #- in case only a wacom has been found, assume an inexistant mouse (necessary).
327 fullname2mouse('none|No mouse', wacom => \@wacom);
328 } else {
329 fullname2mouse('Universal|Any PS/2 & USB mice', unsafe => 1);
330 }
331 }
332 }
333
334 sub load_modules {
335 my ($mouse) = @_;
336 my @l;
337 push @l, qw(hid mousedev usbmouse) if $mouse->{type} =~ /USB/;
338 push @l, qw(serial) if $mouse->{type} =~ /serial/ || any { /ttyS/ } @{$mouse->{wacom}};
339 push @l, qw(wacom evdev) if any { /event/ } @{$mouse->{wacom}};
340 push @l, qw(evdev) if $mouse->{synaptics} || $mouse->{evdev_mice};
341
342 eval { modules::load(@l) };
343 }
344
345 sub set_xfree_conf {
346 my ($mouse, $xfree_conf, $b_keep_auxmouse_unchanged) = @_;
347
348 my @mice = map {
349 {
350 (member($_->{Protocol}, qw(vboxmouse vmmouse)) ? "Driver" : "Protocol") => $_->{Protocol},
351 Device => devices::make($_->{device}),
352 if_($_->{Emulate3Buttons} || $_->{EmulateWheel}, Emulate3Buttons => undef, Emulate3Timeout => 50),
353 if_($_->{EmulateWheel}, EmulateWheel => undef, EmulateWheelButton => 2),
354 };
355 } $mouse;
356
357 if ($mouse->{evdev_mice}) {
358 push @mice, @{$mouse->{evdev_mice}};
359 } elsif (!$mouse->{synaptics} && $b_keep_auxmouse_unchanged) {
360 my (undef, @l) = $xfree_conf->get_mice;
361 push @mice, @l;
362 }
363
364 $xfree_conf->set_mice(@mice);
365
366 if (my @wacoms = @{$mouse->{wacom} || []}) {
367 $xfree_conf->set_wacoms(map { { Device => "/dev/$_", USB => to_bool(m|input/by-path/event|) } } @wacoms);
368 }
369 }
370
371 sub various_xfree_conf {
372 my ($do_pkgs, $mouse) = @_;
373
374 -e "/usr/bin/X" or return;
375
376 #- we don't need this anymore. Remove it for upgrades
377 unlink("$::prefix/etc/X11/xinit.d/mouse_buttons");
378 {
379 my $f = "$::prefix/etc/X11/xinit.d/xpad";
380 if ($mouse->{name} !~ /^Microsoft Xbox Controller/) {
381 unlink($f);
382 } else {
383 output_with_perm($f, 0755, "xset m 1/8 1\n");
384 }
385 }
386
387 require Xconfig::card;
388 my $inputdrvpath = Xconfig::card::modules_dir() . '/input';
389 my $pkgs = [
390 if_($mouse->{synaptics}, ['x11-driver-input-synaptics', "$inputdrvpath/synaptics_drv.so"]),
391 if_($mouse->{evdev_mice}, ['x11-driver-input-evdev', "$inputdrvpath/evdev_drv.so"]),
392 if_($mouse->{Protocol} eq 'vboxmouse', ['x11-driver-input-vboxmouse', "$inputdrvpath/vboxmouse_drv.so"]),
393 if_(@{$mouse->{wacom}}, ['x11-driver-input-wacom', "$inputdrvpath/wacom_drv.so"]),
394 if_($mouse->{name} =~ /VMware/i, ['x11-driver-input-vmmouse', "$inputdrvpath/vmmouse_drv.so"]),
395 ];
396 $do_pkgs->ensure_files_are_installed($pkgs, 1);
397
398 }
399
400 #- write_conf : write the mouse infos into the Xconfig files.
401 #- input :
402 #- $mouse : the hashtable containing the informations
403 #- $mouse input
404 #- $mouse->{nbuttons} : number of buttons : integer
405 #- $mouse->{device} : device of the mouse : string : ex 'psaux'
406 #- $mouse->{Protocol} : type of the mouse for X : string (eg 'PS/2')
407 #- $mouse->{type} : type (generic ?) of the mouse : string : ex 'PS/2'
408 #- $mouse->{name} : name of the mouse : string : ex 'Standard'
409 #- $mouse->{MOUSETYPE} : type of the mouse : string : ex "ps/2"
410 sub write_conf {
411 my ($do_pkgs, $modules_conf, $mouse, $b_keep_auxmouse_unchanged) = @_;
412
413 &write($do_pkgs, $mouse);
414 $modules_conf->write if $mouse->{device} eq "input/mice" && !$::testing;
415
416 eval {
417 require Xconfig::xfree;
418 my $xfree_conf = Xconfig::xfree->read;
419 set_xfree_conf($mouse, $xfree_conf, $b_keep_auxmouse_unchanged);
420 $xfree_conf->write;
421 };
422 }
423
424 sub _xmouse2xId {
425 #- xmousetypes must be sorted as found in /usr/include/X11/extensions/xf86misc.h
426 #- so that first mean "0", etc
427 my @xmousetypes = (
428 "Microsoft",
429 "MouseSystems",
430 "MMSeries",
431 "Logitech",
432 "BusMouse", #MouseMan,
433 "Logitech",
434 "PS/2",
435 "MMHittab",
436 "GlidePoint",
437 "IntelliMouse",
438 "ThinkingMouse",
439 "IMPS/2",
440 "ThinkingMousePS/2",
441 "MouseManPlusPS/2",
442 "GlidePointPS/2",
443 "NetMousePS/2",
444 "NetScrollPS/2",
445 "SysMouse",
446 "Auto",
447 "AceCad",
448 "ExplorerPS/2",
449 "USB",
450 );
451 my ($id) = @_;
452 $id = 'BusMouse' if $id eq 'MouseMan';
453 $id = 'IMPS/2' if $id eq 'ExplorerPS/2' && $::isInstall;
454 eval { find_index { $_ eq $id } @xmousetypes } || 0;
455 }
456
457 sub change_mouse_live {
458 my ($mouse, $old) = @_;
459
460 my $xId = _xmouse2xId($mouse->{Protocol});
461 $old->{device} ne $mouse->{device} || $xId != _xmouse2xId($old->{Protocol}) or return;
462
463 log::l("telling X server to use another mouse ($mouse->{Protocol}, $xId)");
464 eval { modules::load('serial') } if $mouse->{device} =~ /ttyS/;
465
466 if (!$::testing) {
467 devices::make($mouse->{device});
468 symlinkf($mouse->{device}, "/dev/mouse");
469 eval {
470 require xf86misc::main;
471 xf86misc::main::setMouseLive($ENV{DISPLAY}, $xId, $mouse->{Emulate3Buttons});
472 };
473 }
474 1;
475 }
476
477 sub test_mouse_install {
478 my ($mouse, $x_protocol_changed) = @_;
479 require ugtk2;
480 ugtk2->import(qw(:wrappers :create));
481 my $w = ugtk2->new(N("Testing the mouse"), disallow_big_help => 1);
482 my $darea = Gtk2::DrawingArea->new;
483 $darea->set_events([ 'button_press_mask', 'button_release_mask' ]); #$darea must be unrealized.
484 gtkadd($w->{window},
485 gtkpack(my $vbox_grab = Gtk2::VBox->new(0, 0),
486 $darea,
487 gtkset_sensitive(create_okcancel($w, undef, '', 'edge'), 1)
488 ),
489 );
490 test_mouse($mouse, $darea, $x_protocol_changed);
491 $w->sync; # HACK
492 Gtk2::Gdk->pointer_grab($vbox_grab->window, 1, 'pointer_motion_mask', $vbox_grab->window, undef, 0);
493 my $r = $w->main;
494 Gtk2::Gdk->pointer_ungrab(0);
495 $r;
496 }
497
498 sub _fullnames() {
499 map_each {
500 my $type = $::a;
501 grep { $_ } map {
502 if ($_) {
503 my $l = _raw2mouse($type, $_);
504 "$type|$l->{name}";
505 } else {
506 $type .= "|[" . N("Other") . "]";
507 '';
508 }
509 } @{$::b->[1]};
510 } _all_mice();
511 }
512
513 sub select {
514 my ($in, $mouse) = @_;
515
516 my $prev = my $fullname = $mouse->{type} . '|' . $mouse->{name};
517
518 $in->ask_from_({ messages => N("Please choose your type of mouse."),
519 title => N("Mouse choice"),
520 interactive_help_id => 'selectMouse',
521 if_($mouse->{unsafe}, cancel => ''),
522 },
523 [ { list => [ _fullnames() ], separator => '|', val => \$fullname,
524 format => sub { join('|', map { translate($_) } split('\|', $_[0])) } } ]) or return;
525
526 if ($fullname ne $prev) {
527 my $mouse_ = fullname2mouse($fullname, device => $mouse->{device});
528 if ($fullname =~ /evdev/) {
529 $mouse_->{evdev_mice} = $mouse_->{evdev_mice_all} = $mouse->{evdev_mice_all};
530 }
531 %$mouse = %$mouse_;
532 }
533
534 if ($mouse->{nbuttons} < 3 && $::isStandalone) {
535 $mouse->{Emulate3Buttons} = $in->ask_yesorno('', N("Emulate third button?"), 1);
536 }
537
538 if ($mouse->{type} eq 'serial') {
539 $in->ask_from_({ title => N("Mouse Port"),
540 messages => N("Please choose which serial port your mouse is connected to."),
541 interactive_help_id => 'selectSerialPort',
542 }, [ { list => [ detect_devices::serialPorts() ], format => \&detect_devices::serialPort2text, val => \$mouse->{device} } ]) or return &select;
543 }
544
545 if (arch() =~ /ppc/ && $mouse->{nbuttons} == 1) {
546 #- set a sane default F11/F12
547 $mouse->{button2_key} = 87;
548 $mouse->{button3_key} = 88;
549 $in->ask_from('', N("Buttons emulation"),
550 [
551 { label => N("Button 2 Emulation"), val => \$mouse->{button2_key}, list => [ _ppc_one_button_keys() ], format => \&_ppc_one_button_key2text },
552 { label => N("Button 3 Emulation"), val => \$mouse->{button3_key}, list => [ _ppc_one_button_keys() ], format => \&_ppc_one_button_key2text },
553 ]) or return;
554 }
555 1;
556 }
557
558 sub test_mouse {
559 my ($mouse, $darea, $b_x_protocol_changed) = @_;
560
561 require ugtk2;
562 ugtk2->import(qw(:wrappers));
563 my $suffix = $mouse->{nbuttons} <= 2 ? '2b' : $mouse->{nbuttons} == 3 ? '3b' : '3b+';
564 my %offsets = (mouse_2b_right => [ 93, 0 ], mouse_3b_right => [ 117, 0 ],
565 mouse_2b_middle => [ 82, 80 ], mouse_3b_middle => [ 68, 0 ], 'mouse_3b+_middle' => [ 85, 67 ]);
566 my %image_files = (
567 mouse => "mouse_$suffix",
568 left => 'mouse_' . ($suffix eq '3b+' ? '3b' : $suffix) . '_left',
569 right => 'mouse_' . ($suffix eq '3b+' ? '3b' : $suffix) . '_right',
570 if_($mouse->{nbuttons} > 2, middle => 'mouse_' . $suffix . '_middle'),
571 up => 'arrow_up',
572 down => 'arrow_down');
573 my %images = map { $_ => ugtk2::gtkcreate_pixbuf("$image_files{$_}.png") } keys %image_files;
574 my $width = $images{mouse}->get_width;
575 my $height = round_up($images{mouse}->get_height, 6);
576
577 my $draw_text = sub {
578 my ($t, $y) = @_;
579 my $layout = $darea->create_pango_layout($t);
580 my ($w) = $layout->get_pixel_size;
581 $darea->window->draw_layout($darea->style->black_gc,
582 ($darea->allocation->width-$w)/2,
583 ($darea->allocation->height-$height)/2 + $y,
584 $layout);
585 };
586 my $draw_pixbuf = sub {
587 my ($p, $x, $y, $w, $h) = @_;
588 $w = $p->get_width;
589 $h = $p->get_height;
590 $p->render_to_drawable($darea->window, $darea->style->bg_gc('normal'), 0, 0,
591 ($darea->allocation->width-$width)/2 + $x, ($darea->allocation->height-$height)/2 + $y,
592 $w, $h, 'none', 0, 0);
593 };
594 my $draw_by_name = sub {
595 my ($name) = @_;
596 my $file = $image_files{$name};
597 my ($x, $y) = @{$offsets{$file} || [ 0, 0 ]};
598 $draw_pixbuf->($images{$name}, $x, $y);
599 };
600 my $drawarea = sub {
601 $draw_by_name->('mouse');
602 if ($::isInstall || 1) {
603 $draw_text->(N("Please test the mouse"), 200);
604 if ($b_x_protocol_changed && $mouse->{nbuttons} > 3 && $mouse->{device} eq 'psaux' && member($mouse->{Protocol}, 'IMPS/2', 'ExplorerPS/2')) {
605 $draw_text->(N("To activate the mouse,"), 240);
606 $draw_text->(N("MOVE YOUR WHEEL!"), 260);
607 }
608 }
609 };
610
611 my $timeout;
612 my $paintButton = sub {
613 my ($nb) = @_;
614 $timeout or $drawarea->();
615 if ($nb == 0) {
616 $draw_by_name->('left');
617 } elsif ($nb == 2) {
618 $draw_by_name->('right');
619 } elsif ($nb == 1) {
620 if ($mouse->{nbuttons} >= 3) {
621 $draw_by_name->('middle');
622 } else {
623 my ($x, $y) = @{$offsets{mouse_2b_middle}};
624 $darea->window->draw_arc($darea->style->black_gc,
625 1, ($darea->allocation->width-$width)/2 + $x, ($darea->allocation->height-$height)/2 + $y, 20, 25,
626 0, 360 * 64);
627 }
628 } elsif ($mouse->{nbuttons} > 3) {
629 my ($x, $y) = @{$offsets{$image_files{middle}}};
630 if ($nb == 3) {
631 $draw_pixbuf->($images{up}, $x+6, $y-10);
632 } elsif ($nb == 4) {
633 $draw_pixbuf->($images{down}, $x+6, $y + $images{middle}->get_height + 2);
634 }
635 $draw_by_name->('middle');
636 $timeout and Glib::Source->remove($timeout);
637 $timeout = Glib::Timeout->add(100, sub { $drawarea->(); $timeout = 0; 0 });
638 }
639 };
640
641 $darea->signal_connect(button_press_event => sub { $paintButton->($_[1]->button - 1) });
642 $darea->signal_connect(scroll_event => sub { $paintButton->($_[1]->direction eq 'up' ? 3 : 4) });
643 $darea->signal_connect(button_release_event => $drawarea);
644 $darea->signal_connect(expose_event => $drawarea);
645 $darea->set_size_request($width, $height);
646 }
647
648
649 =begin
650
651 =head1 NAME
652
653 mouse - Perl functions to handle mice
654
655 =head1 SYNOPSYS
656
657 require modules;
658 require mouse;
659 mouse::detect(modules::any_conf->read);
660
661 =head1 DESCRIPTION
662
663 C<mouse> is a perl module used by mousedrake to detect and configure the mouse.
664
665 =head1 COPYRIGHT
666
667 Copyright (C) 2000-2006 Mandriva <tvignaud@mandriva.com>
668
669 This program is free software; you can redistribute it and/or modify
670 it under the terms of the GNU General Public License as published by
671 the Free Software Foundation; either version 2, or (at your option)
672 any later version.
673
674 This program is distributed in the hope that it will be useful,
675 but WITHOUT ANY WARRANTY; without even the implied warranty of
676 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
677 GNU General Public License for more details.
678
679 You should have received a copy of the GNU General Public License
680 along with this program; if not, write to the Free Software
681 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
682
683 =cut

  ViewVC Help
Powered by ViewVC 1.1.30