Showing posts with label horizontal scroll. Show all posts
Showing posts with label horizontal scroll. Show all posts

Sunday, 17 January 2016

FreeBSD 10.2 on Lenevo R61


This is a setup guide supplementary to the official handbook and FreeBSD 10.1 Desktop. With these settings you should be able to turn your R61 into a (almost) fully working laptop (see list below). Although these settings are tested on ThinkPad R61 only, if it works for your model, please make a comment and share your experience.

It assumes you're familiar with at least one text editor, the UNIX/Linux style commands and the setup files of FreeBSD, i.e. rc.conf, sysctl.conf, loader.conf. For a more general FreeBSD desktop setup guide, you're suggested to read these two articles apart from the excellent handbook:

 So, what works:
  • Most hotkeys and with OSD, i.e battery info, suspend, bluetooth switch, trackpoint/touchpad switch, hibernate, mute, vol up/down, brightness up/down, ThinkLight, ThinkVantage key
  • Multimedia keys (Fn + arrow keys)
  • TrackPoint and Touchpad with vertical and horizontal scrolling
  • Suspend/resume, hibernate
  • Fingerprint sensor
What doesn't or not tested:
  • A few hotkeys, i.e. video switch, dock eject, zoom (Fn + spacebar)
  • TPM device (it breaks suspend/resume)
For setting up the fingerprint reader, you may want to check out Gawen's blog since it's not specific to ThinkPad R61.


Update: On 10.2-RELEASE-p10, the X mouse driver refused to play nicely with moused. In my case, I had to
  1. turn off the "-V -H" options for moused in /etc/rc.conf
  2. use XAxisMapping and YAxisMapping instead of ZAxisMapping in /usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf

The list of files edited:
/boot/loader.conf
/etc/sysctl.conf
/etc/rc.conf
/usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf
/etc/devd/tp.conf
/usr/local/bin/acpi_osd
/usr/local/sbin/acpi_oem_exec.sh
/usr/local/etc/sudoers.d/moused


1. Now let's get down to business. First, install a few packages:

# pkg install nvidia-driver-340 xosd fprintd sudo
# pkg install xf86-input-synaptics xf86-input-mouse


2. Load the kernel modules:

/boot/loader.conf
zfs_load="YES"
acpi_ibm_load="YES"
acpi_dock_load="YES"
acpi_wmi_load="YES"

ichsmb_load="YES"
ichwd_load="YES"
coretemp_load="YES"


# NVIDIA module needs linux ABI
nvidia_load="YES"
linux_load="YES"


linsysfs_load="YES"
linprocfs_load="YES"
smb_load="YES"
speaker_load="yes"


# Filesystems in Userspace (for NTFS mount)
fuse_load="YES"


sbp_load="YES"


# Firewire module
fwe_load="YES"

i915kms_load="YES"


# For brightness
acpi_video_load="YES"

# Userland char device driver for webcams
cuse4bsd_load="YES"

# Asynchronous I/O
aio_load="YES"

#hw.acpi.reset_video=1

# Required by gamin
kern.maxfiles="25000"
hw.psm.synaptics_support="1"

# Reduce interrupt rate to save power
kern.hz=100

# Use vt instead of sc
#kern.vty=vt
#kern.vt.fb.default_mode="1440x900"
#hw.vga.textmode=1



/etc/sysctl.conf
# Enable horizontal scrolling
hw.psm.synaptics.vscroll_hor_area=1300


# Enable multiple sound input
dev.pcm.0.play.vchans=4
dev.pcm.0.rec.vchans=4


# Allow users to mount USB disks

vfs.usermount=1

dev.acpi_ibm.0.events=1
dev.acpi_ibm.0.handlerevents=0x17

# Enable shared memory support for Chromium
kern.ipc.shm_allow_removed=1




3. Start up services.


/etc/rc.conf
# Set up hosntame
hostname="your_hostname.domain"

# Keymap and fonts
keymap="us.pc-ctrl"

# Network setup with wireless fallback
ifconfig_em0="up"
wlans_ath0="wlan0"
ifconfig_wlan0="WPA"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport wlan0 laggport em0 DHCP"

# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"

# Enable high resolution (with sc only)
allscreens_flags="MODE_357"

# Enable SSH
sshd_enable="YES"

# Enable moused

moused_enable="YES"
moused_flags="-a 1.3 -A 1.6 -VH -z 4 5 6 7"
moused_type="auto"
moused_port="/dev/psm0"

# Device permissions for normal users
devd_enable="YES"
devfs_system_ruleset="system"

# Enable ntpd
ntpd_enable="YES"
ntpd_sync_on_start="YES"

# Enable powerd
powerd_enable="YES"
performance_cx_lowest="Cmax"
economy_cx_lowest="Cmax"


# Enable this for ZFS

zfs_enable="YES"

# Webcam daemon
dbus_enable="YES"
webcamd_enable="YES"

# Enable SMART
smartd_enable="YES"

# Clear temporary files
clear_tmp_enable="YES"
clear_tmp_X="YES"

# Add bridged networking support for VBox
vboxnet_enable="YES"





4. Now the exciting part. The pointing devices with scrolling.


/usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf
Section "InputClass"
        Identifier "sysmouse0"
        MatchDevicePath "/dev/sysmouse"
        Option "Buttons" "15"
        Option "EmulateWheel" "true"
        Option "EmulateWheelButton" "2"
        #Option "YAxisMapping" "4 5"
        #Option "XAxisMapping" "6 7"
        Option "ZAxisMapping" "4 5 6 7"
EndSection

If you start your X session with startx, add the following line to your ~/.xinitrc. If you use KDE or GNOME, add it to your Autostart script.

xinput set-button-map sysmouse 1 2 3 5 4 7 6 5 4 7 6

This part deserves a bit of explanation. There are lots of discussions on the Internet about setting up scrolling for both the UltraNav device (TrackPoint and Touchpad). They usually suggest turning off moused. Bad move!

In order for them to work properly (I mean with scrolling), we need moused (on /dev/psm0) with proper parameters. Moused will then pass the mouse input information through to /dev/sysmouse. Then we tell X to use /dev/sysmouse.

The result: scrolling up, down, left, right on TrackPoint are translated into buttons 4 5 6 7, whereas Touchpad 8 9 10 11. Finally, we map buttons 8 9 10 11 (of Touchpad) to 4 5 6 7 with xinput.

Note that for the touchpad, it's two finger scroll. Personally, I prefer the edge (and circular) scroll which I couldn't get it to work unfortunately.


5. The hotkeys

This file tells devd to call /usr/local/sbin/acpi_oem_exec.sh for all IBM ACPI events.
/etc/devd/tp.conf
notify 10 {
        match "system"      "ACPI";
        match "subsystem"   "IBM";
        action              "/usr/local/sbin/acpi_oem_exec.sh $notify ibm";
};




You need to run acpi_osd when launching X. Adding the following lines to .xinitrc if you use startx, or your Autostart script:
if [ -x /usr/local/bin/acpi_osd ]; then
        /usr/local/bin/acpi_osd &
fi

All mouse events come from moused and since it is run as root, the suspend mouse event hotkey (Fn + F8 ) needs the help of sudo.
/usr/local/etc/sudoers.d/moused
 ALL ALL = NOPASSWD: /usr/bin/killall -USR1 moused


This file handles the hotkey events and setup OSD messages. You might want to tweak/extend it to suit your need, e.g. customize what the ThinkVantage button does, the video switching hotkey (Fn + F7), the zoom hotkey (Fn + spacebar). Right now they do nothing (and honestly I don't need them at all).
/usr/local/sbin/acpi_oem_exec.sh
#!/bin/sh

if [ "$1" = "" -o "$2" = "" ]
then
        echo "usage: $0 notify oem_name"
        exit 1
fi
NOTIFY=`echo $1`
LOGGER="logger"
CALC="bc"
BC_PRECOMMANDS="scale=2"
ECHO="echo"
CUT="cut"
MAX_LCD_BRIGHTNESS=7
MAX_VOLUME=14
OEM=$2
DISPLAY_PIPE=/tmp/acpi_${OEM}_display
ACPICMD="acpiconf"

case ${NOTIFY} in
        0x05)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.bluetooth`
                if [ "$LEVEL" = "1" ]
                then
                        sysctl dev.acpi_${OEM}.0.bluetooth=0
                        MESSAGE="bluetooth disabled"
                else
                        sysctl dev.acpi_${OEM}.0.bluetooth=1
                        MESSAGE="bluetooth enabled"
                fi
                ;;
        0x10|0x11)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.lcd_brightness`
                PERCENT=`${ECHO} "${BC_PRECOMMANDS} ; \
                        ${LEVEL} / ${MAX_LCD_BRIGHTNESS} * 100" |\
                        ${CALC} | ${CUT} -d . -f 1`
                PERCENT=`sysctl -n hw.acpi.video.lcd0.brightness`
                MESSAGE="brightness level ${PERCENT}%"
                ;;
        0x12)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.thinklight`
                if [ "$LEVEL" = "1" ]
                then
                        MESSAGE="thinklight enabled"
                else
                        MESSAGE="thinklight disabled"
                fi
                ;;
        0x15|0x16)
                case ${NOTIFY} in
                        0x15)
                                (( LEVEL-- ))
                                mixer vol -7
                                ;;
                        0x16)
                                (( LEVEL++ ))
                                mixer vol +7
                                ;;
                        *)
                                ;;
                esac
                MESSAGE="`mixer -s vol`%"
                ;;
        0x17)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.mute`
                if [ "$LEVEL" = "1" ]
                then
                        MESSAGE="volume muted"
                else
                        MESSAGE="volume unmuted"
                fi
                ;;
        0x02)
                MESSAGE="screen lock on"
                # FIXME
                DISPLAY=localhost:0 xscreensaver-command -lock
                ;;
        0x03)
                LEVEL=`${ACPICMD} -i0 | awk '/Remaining capacity/ {print $NF}'`
                MESSAGE=`${ACPICMD} -i0 | awk '/Remaining capacity/'`
                ${ACPICMD} -i0 | $OSD_CAT
                ;;
        0x08)
                killall -USR1 moused
                MESSAGE="TrackPoint/Trackpad toggle"
                ;;
        0x14)
                MESSAGE="Zoom"
                ;;
        0x18)
                MESSAGE="ThinkVantage Button"
                ;;
        0x04)
                MESSAGE="suspend to RAM"
                ${ACPICMD} -s 3
                ;;
        0x0c)
                MESSAGE="suspend to disk"
                ${ACPICMD} -s 4
                ;;
        *)
                ;;
esac
${LOGGER} "${MESSAGE}"
if [ -p ${DISPLAY_PIPE} ]
then
        ${ECHO} "${MESSAGE}" >> ${DISPLAY_PIPE} &
fi
exit 0





6. Volume keys and multimedia keys (Fn + arrow keys)

These keys generate standard XF86Audio keycodes. It may work for your DE (GNOME or KDE) out of the box. Otherwise you'll need to add them manually to your WM as keyboard shortcuts.

Here's the relevant section of my .bbkeysrc config:
  [Execute]  (XF86AudioLowerVolume) {/usr/local/sbin/acpi_oem_exec.sh 0x15 ibm}
  [Execute]  (XF86AudioRaiseVolume) {/usr/local/sbin/acpi_oem_exec.sh 0x16 ibm}
  [Execute]  (XF86AudioPrev) {xmms --rew}
  [Execute]  (XF86AudioPlay) {xmms --play-pause}
  [Execute]  (XF86AudioNext) {xmms --fwd}
  [Execute]  (XF86AudioStop) {xmms --stop}



7. Display OSD

This file sets up a fifo that waits for messages to be displayed onscreen.
/usr/local/bin/acpi_osd
#!/bin/sh

DISPLAY_PIPE=/tmp/acpi_ibm_display
OSD="osd_cat"
FONT="-*-lucidatypewriter-*-*-*-*-*-240-*-*-*-*-*-*"
COLOR=Green
TIME=1
OPTS="--font=$FONT -c $COLOR -p bottom -o -10 -i 50 -d $TIME"

trap "rm -f $DISPLAY_PIPE" EXIT

[ -p $DISPLAY_PIPE ] || mkfifo $DISPLAY_PIPE

while true
do
        if read line <$DISPLAY_PIPE; then
                echo $line | $OSD $OPTS
        fi
done

exit 0 


8. Now restart the computer. Voila.





Saturday, 12 December 2015

Horizontal scroll on FreeBSD guest

Setting up horizontal scroll on a FreeBSD Guest in VirtualBox


One of the annoyance I came across on FreeBSD as a VirtualBox guest is the mouse. Although not a heavy mouse user, I rely very much on scrolling, both horizontal and vertical. Unfortunately scrolling doesn't work out-of-the-box. The relevant section in the handbook doesn't specify clearly how things work (or outdated?).

So even with the guest additions installed often than not one or more of these happen:
  • the mouse cursor doesn't move
  • none of the mouse buttons work - no mouse click detected
  • scrolling doesn't work - no button 4, 5, 6 or 7 (more on that later)

If you share the same fate as I do, the instructions below will hopefully save you some hours of trial and error and hair pulling moments.

NOTE: The instructions are tested for a Linux host + FreeBSD guest environment only. As of writing, I can't get the horizontal scroll working on a Windows host. Some claim that Windows (or the Synaptics driver) doesn't implement horizontal scroll properly. Comments are welcome.

Quick instructions for the impatient

 

1. Test your moused setting

In a virtual terminal, log in as root and type:

# moused -df -p /dev/psm0 -t auto -z 4 5 6 7

Now moused is in debug mode. As you move the mouse you'll see lots of messages spitted out by moused.

moused: mstate[2]->count:6
moused: button 3  count 0


Note the lines with mstate[n] and button m. It should reflect the buttons you press. For a mouse with scroll wheel the mappings are:

1 - left button
2 - middle button
3 - right button
4 - scroll up
5 - scroll down
6 - scroll left
7 - scroll right

If that's what you see, congrats. Now hit control-c to quit moused and move on.


2. Enable moused in /etc/rc.conf

Add these lines to /etc/rc.conf:
moused_enable="YES"
moused_flags="-z 4 5 6 7"
moused_type="auto"
moused_port="/dev/psm0"

Now start moused:
/etc/rc.d/moused start


3. Set up InputClass in xorg.conf

Copy and paste the following lines to /usr/local/etc/X11/xorg.conf.d/10-vboxmouse.conf.

NOTE: The below setting is for FreeBSD as VirtualBox guest only. If you're running FreeBSD on Thinkpad models with the UltraNav (TrackPoint + Touchpad) device, I'll write another article on that.

Section "InputClass"
        Identifier "sysmouse0"
        MatchDevicePath "/dev/sysmouse"
        Option "Buttons" "7"
        Option "EmulateWheel" "true"
        Option "EmulateWheelButton" "2"
        Option "YAxisMapping" "4 5"
        Option "XAxisMapping" "6 7"
EndSection


Section "InputClass"
        Identifier "vboxguest0"
        MatchDevicePath "/dev/vboxguest"
        Driver "vboxmouse"
        Option "Protocol" "auto"
EndSection



4. Test it in X

Fire up X the usual way. For me it's:
> startx &

Open a terminal and type
> xev

Move the cursor inside the Event Tester window and try some clicks and scrolling. You should see the mouse button events get printed in the terminal. Scrolling should report button 4 and 5. And here's the fun stuff. Hold down the middle button and move the mouse. You should see button 4 and 5 reported with scrolling up and down, while button 6 and 7 scrolling left and right.

If you don't like that just comment out the EmulateWheel and EmulateWheelButton lines in 10-vboxmouse.conf.

That's it. Your pointing device should work in the virtual terminals as well as X. Any mice plugged in after X fired up should work too.


The long explanation

 

Why not turning off AutoAddDevices? 

Many of the solutions on the Internet suggest turning off AutoAddDevices and adding an InputDevice section in /usr/local/etc/X11/xorg.conf. That might work for you but I think it's not the perfect solution. It has a few downsides:
  1. It requires disabling moused. No more copy and paste in virtual terminals.
  2. Any mice plugged in after X fired up won't work unless you use InputClass instead of hardcoding InputDevice. But the behavior of each pointing device is not consistent.

The perfect solution - moused

Moused acts as a hub connecting all the physical pointing devices and talks to X as one logical device (dough). So you get a consistent behavior across them. Copy & paste works in virtual terminals, as well as vert and horiz scrolling.

So in the case of VirtualBox, all physical pointing devices are nicely emulated by /dev/psm0. Moused binds to /dev/psm0 (the emulated device that FreeBSD thinks is the physical device) and the combined signal goes to /dev/sysmouse. X then reads the signal from /dev/sysmouse.

Any newly plugged-in devices are automagically picked up by moused so everything just works, both in X and the virtual terminals. Nicely, isn't it?


What about /dev/vboxguest?

In order for the pointing devices to work properly in VirtualBox, the X server needs to see one more logical device, namely /dev/vboxguest.

For reasons not understood (these are found out by reverse engineering), VirtualBox emulates cursor movements and all mouse button events san button 2 to /dev/sysmouse, while /dev/vboxguest reports button 2 events to the guest. Mouse Integration with the host is also implemented via /dev/vboxguest.


How scrolling works?

There is no such thing as "scrolling signal". Instead they are represented by mouse button events just like clicking the left or right buttons. Scrolling up usually maps to button 4 event, down 5, left 6 and right 7. (Even events 8 - 11 are possible with the UltraNav device since there are basically 2 physical devices).


More explanations on the settings

The important setting with moused is "-z 4 5 6 7". I discourage the use of -V and -H cuz as soon as the middle button is clicked in X, button event > 4 stops working. And since the -z option has already taken care of the scrolling signals, why bothered with -V and -H?

If horizontal scroll still doesn't work for you, before bashing your mouse you may try to replace the XAxisMapping and YAxisMapping lines with

Option ZAxisMapping "4 5 6 7"


Or if you're like me, prefer "natural scrolling", i.e. scroll the page itself instead of the scroll bars:

Option ZAxisMapping "5 4 7 6"


Enjoy scrolling. :)