Tuesday 24 January 2012

VirtualBox tips and tricks - awesome wm integration

Hiding the menu and statusbar of VirtualBox

I finally managed to set up awesome wm to work just as I want. I only had some minor problems and customisation needs with my windows VirtualBox guest:

- Scale mode simply freezes my guest OS, so I do not use it.
- In seamless, fullscreen or scale modes Virtualbox's host key has to be pressed to leave the guest window. As I use almost every window management opertion by keystrokes, it was a bit annoying not to be able to switch out from my windows guest with a simple keystroke but I had to press the host key first. Fortunately in normal view (with the menu bar and the status bar on the top and bottom of the window) you can switch out directly from the guest without using the host key.
- In normal mode the menu and status bars take a bit of a place needlessly.

I tried some tricks to resize my VB guest in floating mode to "overlflow" my screen but these tricks did not work well. Finally I found the solution here.

You can hide the menu and status bars of the VirtualBox window with this simple command:

vboxmanage setextradata global GUI/Customizations noMenuBar,noStatusBar

Restart Virtualbox and that's it, you are done! :)

Disabling the "Win" key

I configured my window manager to use the "Win" key as the major alt key of keystrokes. Under my virtual windows guest I had a small annoyance, i.e. when using the "win" key for a window management task the windows menu always shown up. If you have the same issue, you can disable the "win" key under windows by simply downloading and executing the appropriate "Fix it" binary provided by Microsoft's support page.

UPDATE: recently I installed a Windows guest machine to a new computer. The method above eliminated the Win key under the guest but my tiling window manager did not work well. The window manager's "Win" key bindings did not work when I was inside the virtualbox guest. To change this behavior:

Open the VirtualBox GUI, go to "File" > "Preferences" menu, then choose the "Input", uncheck the box labeled "Auto Capture Keyboard". There is no need to restart the VM if it's running, so this can be changed "on the fly". Thanks to the Ubuntu folks here.

Hiding the recycle bin

A small cosmetics on the windows desktop: hide your recycle bin.

After all these treatments my win7 guest OS looks likesimple and clean and above all integrates very well ito my window manager.


Also, please take a look at this post if you are interested in a solution for opening windows files in VirtualBox directly from your Linux host.

Friday 20 January 2012

Opening files under VirtualBox guest from the Linux host


Updated: 08/06/2015

I have been using VirtualBox to run windows software on my linux box for a while. I always wondered how nice it would be to simply click on a windows file (.doc, .xls, .exe, etc.) under linux to open it with the appropriate application (winword, excel, etc.) under the virtual machine instead of saving the file and looking it up under windows. I did not find any solution for this so I looked around and invented my own one. The operation is based on the VBoxManage guestcontrol utility provided by VirtualBox. This command allows you to initiate program execution inside the guest from the host. A small bash script handles this on the host by converting the filename to windows format and opening the file inside the guest Windows machine.

The steps for setting all these up:

Add the / directory to the windows guest

Install VirtualBox guest additions if it is not installed already. I do not want to describe how to install guest additions, it is well documented elsewhere. Briefly under Arch Linux you have to install the virtualbox-additions AUR package, add /usr/lib/virtualbox/additions/VBoxGuestAdditions.iso to your VirtualBox storage and install the guest additions under the guest.

Create a shared folder under VirtualBox settings and add your linux host's root (/) filesystem. Now let's say your linux / direcrory is the f: drive under the windows guest.



As a result a file named /home/<your_username>/document.doc under linux looks like f:\home\<your_username>\document.doc under the guest.



Install Quiet.exe under the windows guest

UPDATE: Under my latest Win7 guest installation cmd.exe works just fine without bringing up a command window and without the need of setting up environment variables. If this is not the case you can use Quiet.exe instead.

To open files remotely you can use cmd.exe or the start command but both opens a console window besides the program that you want to run which I find quite annoying. To hide it you have to use additional software: a hand-made vbs script or a third-party tool like hstart, cmdow or Quiet. I will follow the last one, this simple tool works fine.

Download Quiet from their website and copy the Quiet.exe anywhere you like under your windows guest.

Let's say it will be here:
c:\Users\<your_windows_username>\Quiet.exe

Enable passwordless guest control under the windows guest

If you do not use password in your windows guest (like me), the guest's group policy must be changed under the guest OS. To do so, open the group policy editor on the command line by typing gpedit.msc, open the key Computer Configuration \ Windows Settings \ Security Settings \ Local Policies \ Security Options and change the value of Accounts: Limit local account use of blank passwords to console logon only to Disabled.

Without this step you will get an error when trying use VboxManage:
VBoxManage: error: The specified user was not able to logon on guest.

Install detox for cleaning up filenames

Not only me but VboxManage also hates special characters and spaces in filenames. Detox is a handy tool for swiping such garbages out of filenames. It will replace spaces to underline sign, convert characters with accents for the non-accent version and remove special characters. You can install it from AUR then use it in your scripts (like I did below).

Create the winopen.sh script

UPDATE: since Virtualbox 5.0.0 the execute subcommand of VBoxManage guestcontrol is deprecated. Use run instead with the --exe option (see the script below)

UPDATE: since Virtualbox 5.0.0 instead of --environment use the --putenv option in your "VBoxManage guestcontrol ... run" command (see the script below)

UPDATE: since Virtualbox 5.1.x instead of run use start! run gives session problems, commands stuck after termination. run works for me. Oracle's documentation sucks by the way.
 
Create a winopen.sh bash script under the linux host. This will be the command for opening windows files within the guest.

#!/bin/bash

# stdout and errors go here:
exec 2>>"/home/<your_linux_username>/.xlog<or_anything_you_like>"
exec 1>&2

script="$(basename "$0")"
vmname="<the_name_of_your_windows_guest_under_Virtuabox>"
driveletter="f:"  #your ROOT folder's drive letter comes here 

# Start vm if not running already
if [ $(VBoxManage list runningvms | wc -l) = 0 ]; then
   VBoxManage startvm $vmname
   echo "Please wait, starting virtual PC..."
   sleep 5s
fi

until VBoxManage showvminfo $vmname | grep '"Graphics Mode": active/running' > /dev/null
 do
  sleep 0.5s
 done

# Set the absolute full path of the file in the linux host
for i in "$@"
do
 if echo $i | grep '^/' > /dev/null
   then targetfullpath=$i
   else targetfullpath=$PWD'/'$i
 fi

#Cleanup filename, you need detox installed! 

cleanpath=$(detox -vs utf_8 "$targetfullpath" | tail -1 | awk '{print $NF}')

# The same filepath under the windows guest machine
winfullpath=$(echo $driveletter$cleanpath | sed 's/\//\\/g')

# Open the file under windows
echo $script": opening "$targetfullpath" ("$winfullpath") in Virtualbox"
#sleep 1   # uncomment and increase this if you see empty Winword windows

#In newer Windows installations try this:
VBoxManage guestcontrol "$vmname" start --exe "cmd.exe" --username 'cuh' --putenv "USERPROFILE=C:\Users\<your_windows_username>" --putenv "APPDATA=C:\Users\<your_windows_username>\AppData\Roaming" -- "cmd" "/c" $winfullpath &
# For older installations:
#VBoxManage guestcontrol "$vmname" execute --image "cmd.exe" --username "<your_windows_username>" -- "cmd" "/c" $winfullpath & 
# If you want to use quiet.exe or have problems with environment variables, try this:
#VBoxManage guestcontrol "$vmname" execute --image "C:\Users\<your_windows_username>\Quiet.exe" --wait-exit --username "<your_windows_username>" --environment "USERPROFILE=C:\Users\<your_windows_username>" --environment "APPDATA=C:\Users\<your_windows_username>\AppData\Roaming" -- "cmd" "/c" $winfullpath &

done


Make your script executable, i.e.:
chmod 755 winopen.sh

Optionally place winopen.sh to your path, (i.e. /home/<your_username>/bin/winopen.sh and put export PATH=$PATH:~/bin under your .bashrc).

Important notices on environment variables:
Without the --environment "USERPROFILE=C:\Users\<your_windows_username>" attribute in your winopen.sh script your guest OS sometimes does not get this environment variable and cannot open your files. You get errors like this:
"your AutoCorrect file, MSO1038.acl could not be saved." or "Microsoft Excel cannot access the file ... There are several possible reasons: The file name or path does not exist..."

The lack of the --environment "APPDATA=C:\Users\<your_windows_username>\AppData\Roaming" attribute can slow down Word document spell checking.

In general all the environment variables should be the same as in the Windows guest environment but I was just lazy to write all the environment set to the VboxManage command.


Usage

Invoking the winopen.sh script with one or more filenames will start your Virtualbox (if it was not running already), clean up your filename(s) (if there were special characters in them) and open the file(s) under the windows guest. For example:

winopen.sh /home/<your_username>/document.doc
or simply (with relative pathname):
winopen.sh document.doc

You can configure Thunderbird, Firefox, file managers, etc. to use winopen.sh when opening windows files (.doc, .xls, ppt, .exe, etc.), so you simply need to click on an e-mail document attachment or an excel link and it will open automatically under windows.





Any improvements are welcome!

Wednesday 18 January 2012

Arch Linux on Thinkpad Edge 11

I use Arch Linux on my Thinkpad Edge 11 notebook (Intel version with Core i3 Duo (i3-380UM)). This is my office device and I spend my everyday life using this tiny little computer. I briefly concluded the first steps and some minor issues during installation here. Now I am collecting all the device-specific settings I made for fine-tuning Arch Linux for this laptop model.

TP smapi
This feature set provides Thinkpad users with detailed battery charge/discharge control, battery status information and hard disk protection.
The package is called tp_smapi and can be installed from AUR. After installation add tp_smapi to your MODULES array of your /etc/rc.conf.
Details can be found in the tp_smapi page of the Arch Wiki.

After installation and loading the tp_smapi module several useful information can be read out and set up from the /sys/devices/platform/smapi/ directory.

The default battery is BAT0, its details can be read from the files under
/sys/devices/platform/smapi/BAT0/

I show some examples how this service can be used:

Battery indicator
I use simple tiling window managers (like awesome and wmfs) and I created a statusbar script to show (among others) the actual battery percentage and status, The bash code for showing a text like "80% charging" is like this:

echo "`cat /sys/devices/platform/smapi/BAT0/remaining_percent`"% "`cat /sys/devices/platform/smapi/BAT0/state`"

See my wmfs-status script here.

Battery notification script
I created a notification script that uses the notify-send command as part of a notification daemon (xfce4-notifyd or similar):

state=`cat /sys/devices/platform/smapi/BAT0/state`
if [ "$state" = 'discharging' ];
  then batt=`cat /sys/devices/platform/smapi/BAT0/remaining_percent`
  if (($batt <= 30));
    then if (($batt <= 10));
           then notify-send -u critical "Battery is low!
`acpi -b | tail -c 24 | head -c 10` remaining" ;
           else notify-send "Battery is critical!
`acpi -b | tail -c 24 | head -c 10` remaining" ;
         fi
  fi
fi


You can run this script  from your .xinitrc like:
 (while true; do sleep 300s; /home/cuh/bin/battwarning.sh; done) &

As a result you will be notified every 5 minutes when your battery goes below 30% and you get a critical warning when your voltage is under 10%.

See my full .xinitrc here.


Battery protection
Some parameters under /sys/devices/platform/smapi/BAT0/ can be set by writing to the files of this directory. For example you can force discharging the battery even if the power supply is plugged in (it can be useful when your battery is over the stop_charge_thresh, see below) by setting the force_discharge parameter to 1 (the default value is 0) by this command:

echo 1 > /sys/devices/platform/smapi/BAT0/force_discharge

or you can set the battery charging thresholds for keeping the current capacity between 30% and 80% for protecting your LiIon battery from low and high percentages (see here) by setting the start_charge_thresh and stop_charge_thresh values. Unfortunately on my Thinkpad Edge 11 there seems to be a bug in this area because I cannot set both threshold limits. Changing one changes the other so that start_charge_thresh is always a higher value than the stop_charge_thresh (who understands...). Anyway, I do not really need to set the lower threshold level because when I am on DC power and my battery discharges I get a notification to plug in the power supply and if I am in a situation that I can plug it in I do it so. I limit the upper threshold to 80% to protect my battery from overcharging. To do so I put this line to my /etc/rc.local to set the threshold at every boot:

echo 80 > /sys/devices/platform/smapi/BAT0/stop_charge_thresh

HDD drop protection - not working on Edge 11
According to the tp_smapi documentation this package contains the hdaps driver as well, which is responsible for HDD protection against physical shocks by means of a built-in accelerometer's signals. After installing tp_smapi I loaded the module:

modprobe hdaps

The module is loaded but dmesg says:

thinkpad_ec: thinkpad_ec_read_row: failed requesting row: (0x01:0x00)->0xfffffff0

At the same time my battery status modules stopped working, I cannot access the contents of the /sys/devices/platform/smapi/BAT0 files.


I read that a temporary workaround might be to switch off my laptop, unplug the power supply, remove the battery and place it back after some minutes. Funny that this can be a workaround, but I faced the same with the malfunctioning Fn buttons, too (see below). This time it did not help, now I cannot even load the hdaps driver.

I tried to overwrite the native kernel hdaps driver by the tp_smapi driver:

mv /lib/modules/3.0-ARCH/kernel/drivers/platform/x86/hdaps.ko.gz /lib/modules/3.0-ARCH/kernel/drivers/platform/x86/hdaps.ko.gz_backup

cp /lib/modules/3.0-ARCH/extra/hdaps.ko.gz /lib/modules/3.0-ARCH/kernel/drivers/platform/x86/hdaps.ko.gz

and this time I got back to the loadable module with the dmesg warning and switched-off battery framework.

I looked around and some people say that the hdaps service is not available on this Thinkpad model, I can confirm this.

cpu_frequtils
See the details at www.thinkwiki.org.CPU scaling and profiling works fine on the Edge 11, the Extra repository contains the cpufrequtils package and the Arch Wiki is pretty helpful as usual. Instead of setting up your frequency scaling manually you can use Laptop Mode Tools, see below. After installing cpufrequtils and setting up LMT you only need to add acpi-cpufreq to your MODULES in /etc/rc.conf and edit the /etc/laptop-mode/conf.d/cpufreq.conf file to your taste.

Laptop Mode Tools
Laptop Mode Tools is a centralised power management solution featuring several power saving services. These services are controlled by only one daemon. In practice this means that you only need to install the laptop-mode-tools package, place laptop-mode to your DAEMONS list of your /etc/rc.conf and tune the power saving options as you like with the appropriate config files: /etc/laptop-mode/laptop-mode.conf and /etc/laptop-mode/conf.d/* . You can set up different CPU governors, different LCD brightness, auto switching off your WiFi antenna when idle, etc. features according to the actual power state (AC / DC) of your laptop. Installation and configuration is well described in the LMT Arch Wiki.

Strange bug of Thinkpad function buttons
Sometimes I have problems with the brightness and volume Fn buttons. They simply do not work. Nothing helps here, neither restarting daemons, nor rebooting the machine. Very strangely the only solution is to switch the laptop off, remove the battery and place it back after 5 secs, and boot up the machine again. I haven't faced this problem for a while, maybe a kernel upgrade (or who knows what) solved it permanently.

Synaptics touchpad
To fine-tune the touchpad you have to install the xf86-input-synaptics package and set up the options under /etc/X11/xorg.conf.d/10-synaptics.conf

With the default settings I had an odd problem with double taps that wanted to drag and drop elements instead of releasing the mouse click. I worked a lot to achieve a functioning, fast and responsive touchpad. My config looks like this:

Section "InputClass"
Identifier "touchpad catchall"
Driver "synaptics"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Option "TapButton1" "1"
Option "TapButton2" "2"
Option "TapButton3" "3"
Option "VertEdgeScroll" "on"
Option "VertTwoFingerScroll" "on"
Option "VertResolution" "100"
Option "HorizResolution" "100"
Option "MaxDoubleTapTime" "100"
EndSection