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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.30