Tablet PC rotation HOW TO

Write tutorials for Linux Mint here
More tutorials on https://github.com/orgs/linuxmint/discu ... /tutorials and (archive) on https://community.linuxmint.com/tutorial
Forum rules
Don't add support questions to tutorials; start your own topic in the appropriate sub-forum instead. Before you post read forum rules
Post Reply
Favux

Tablet PC rotation HOW TO

Post by Favux »

Relocation of: How to Rotate the Screen for a TX2000 Tablet PC

Last Updated: January 12, 2013

Preliminaries
The rotation HOW TO assumes the Wacom digitizer is working on your tablet PC. Either because the release's default wacom.ko (the usb kernel driver/module) and xserver-xorg-input-wacom (the xf86-input-wacom X driver and xsetwacom) package work for your tablet PC (check Synaptic Package Manager or Software Sources) or you have successfully compiled and installed the Wacom drivers using the Linux Wacom HOW TO or the Wacom Bamboo Pen and Touch tablet HOW TO. Configuration for Isadora/Lucid is through the 10-wacom.conf and for Julia/Maverick and up it is the 50-wacom.conf. Although you can still use the xorg.conf if you prefer.

There has been a change to the Wacom input tool device naming convention. To get your devices to rotate enter xinput list in a terminal. In the output find the "device name", e.g.:

Code: Select all

⎜   ↳ Wacom ISDv4 93 Pen stylus               	id=11	[slave  pointer  (2)]
⎜   ↳ Wacom ISDv4 93 Finger touch             	id=12	[slave  pointer  (2)]
⎜   ↳ Wacom ISDv4 93 Pen eraser               	id=16	[slave  pointer  (2)]
that correspond to the input tools you have. For a tablet PC these would be stylus, eraser (if you have one), and touch (if you have it). Then substitute the longer more descriptive "device name" (with the quotes) in for stylus, eraser, and touch in the script's xsetwacom commands. For example:

Code: Select all

xsetwacom set stylus rotate ccw
becomes

Code: Select all

xsetwacom set "Wacom ISDv4 93 Pen stylus" rotate ccw
You can also use the ID numbers if you are not hot plugging devices, otherwise the ID #'s can change. Starting with xf86-input-wacom-0.11.0 (i.e. Lisa/Oneiric) the xsetwacom Rotate parameter has been made tablet wide so you need to only rotate the parent device. This means for a serial (ISDV4) tablet PC the only xsetwacom Rotate command you need is for the stylus, and the others (eraser and touch) can be left out of the script. For usb tablet PCs with touch you need both the stylus and the touch lines in the script because they are exported from the kernel as two separate devices.

There is a bug using the Isadora/Lucid default wacom.ko (from linuxwacom version 0.8.4-1(?)). Stylus and touch are the same in the xinput list output, namely "Wacom ISDv4 93", for TX2500 & TX2000's. So for at least touch use the ID number. If you've compiled and installed linuxwacom 0.8.6-2 (or up) or the input-wacom wacom.ko this bug is fixed.


Summary
The first method below invokes the xrandr command line interface to find the screen orientation in the output of the server system's current state. Then the script uses the appropriate xrandr and xsetwacom commands to rotate the screen and input tools. These scripts work for all tablet PCs. Method 2 provides automatic rotation through a shell script if your tablet PC and the system software support it. Method three does the same but through a Python gtk application called Magick Rotation that adds other features besides automatic rotation. Magick Rotation supports Dell, Fujitsu, HP, and Lenovo tablet PCs. The fourth method relies on a C daemon and a shell command. It works for all tablet PCs. "Implementing a Script" describes how to make your script executable and how methods 1 & 4 can be implemented by a Launcher (which can be placed in a panel or a dock) or alternatively bound to a hardware key. Appendix 1 has a little bit on enabling rotation in your video driver (if needed) and appendix 2 discusses how to enable tablet PC bezel buttons. Appendix 3 shows you how to set up a HP Elitebook's thumb scroll bezel button.


Method 1: "xrandr -q --verbose" & grep
This is a “general” script that works for all tablet PC's. This script relies on the output of xrandr -q --verbose, which gives current screen state. One line of the output includes current screen orientation. They all, regardless of video chipset or driver, have a common current screen orientation line which shares a common term and format. This allows one script/command line to deal with all.

So this script should work for any Tablet PC that has a line similar to the following in it's xrandr -q --verbose output:

Code: Select all

default connected 1280x800+0+0 (0x1ad) normal (normal left inverted right) 0mm x 0mm
What you are looking for is "connected" and ") normal (". Where "normal" is the current orientation (normal or left or inverted or right) bracketed by parenthesis ")" & "(".

Substitute in the appropriate "device name" for stylus, eraser, and touch in the folllowing scripts.

360 degree shell script:

Code: Select all

#!/bin/sh

# Find the line in "xrandr -q --verbose" output that contains current screen orientation and "strip" out current orientation.

rotation="$(xrandr -q --verbose | grep 'connected' | egrep -o  '\) (normal|left|inverted|right) \(' | egrep -o '(normal|left|inverted|right)')"

# Using current screen orientation proceed to rotate screen and input tools.

case "$rotation" in
    normal)
    # rotate to the left
    xrandr -o left
    xsetwacom set stylus rotate ccw
    xsetwacom set touch rotate ccw
    xsetwacom set eraser rotate ccw
    ;;
    left)
    # rotate to inverted
    xrandr -o inverted
    xsetwacom set stylus rotate half
    xsetwacom set touch rotate half
    xsetwacom set eraser rotate half
    ;;
    inverted)
    # rotate to the right
    xrandr -o right
    xsetwacom set stylus rotate  cw
    xsetwacom set touch rotate cw
    xsetwacom set eraser rotate cw
    ;;
    right)
    # rotate to normal
    xrandr -o normal
    xsetwacom set stylus rotate none
    xsetwacom set touch rotate none
    xsetwacom set eraser rotate none
    ;; 
esac
This will cause the screen to rotate through 360 degrees counter-clockwise in four 90 degree steps.
* remember with xf86-input-wacom-0.11.0 and later for a serial (ISDv4) tablet PC all you would need is the stylus line, while for a USB tablet PC you need both stylus and touch lines if you have touch

A tablet PC screen is usually hinged to swivel 180 degrees in only one direction. From laptop (usually landscape orientation) mode before locking down in tablet mode. Most prefer portrait orientation in tablet mode so the script really only needs to rotate the screen orientation 90 degrees to portrait and then 90 degrees back to landscape. Since a right handed person holds the tablet in the left arm (and most like the battery pointing to their hand as a handle) the following simplified scripts generally serve.

Right handed script:

Code: Select all

#!/bin/sh

# Find the line in "xrandr -q --verbose" output that contains current screen orientation and "strip" out current orientation.

rotation="$(xrandr -q --verbose | grep 'connected' | egrep -o  '\) (normal|left|inverted|right) \(' | egrep -o '(normal|left|inverted|right)')"

# Using current screen orientation proceed to rotate screen and input tools.

case "$rotation" in
    normal)
    # rotate to the right
    xrandr -o right
    xsetwacom set stylus rotate  cw
    xsetwacom set touch rotate cw
    xsetwacom set eraser rotate cw
    ;;
    right)
    # rotate to normal
    xrandr -o normal
    xsetwacom set stylus rotate none
    xsetwacom set touch rotate none
    xsetwacom set eraser rotate none
    ;;
esac
Left handed script:

Code: Select all

#!/bin/sh

# Find the line in "xrandr -q --verbose" output that contains current screen orientation and "strip" out current orientation.

rotation="$(xrandr -q --verbose | grep 'connected' | egrep -o  '\) (normal|left|inverted|right) \(' | egrep -o '(normal|left|inverted|right)')"

# Using current screen orientation proceed to rotate screen and input tools.

case "$rotation" in
    normal)
    # rotate to the left
    xrandr -o left
    xsetwacom set stylus rotate ccw
    xsetwacom set touch rotate ccw
    xsetwacom set eraser rotate ccw
    ;;
    left)
    # rotate to normal
    xrandr -o normal
    xsetwacom set stylus rotate none
    xsetwacom set touch rotate none
    xsetwacom set eraser rotate none
    ;;
esac
You will need to place the script into a text file, name it, and make it executable. See a) Script in Implementing a Script with a Launcher or Key Binding below. From the examples in should be clear how to make a script for inverted orientation, given the linuxwacom equivalent of xrandr's inverted is half.
* Thank you to martinjochimsen and manu7irl for helping to validate method 1 for the TX2500.


Method 2: Tablet PC Automatic Rotation Script
Red_Lion got auto-magic rotation working. He developed a script that uses the 'tablet' signal ('dock' for the original unpatched HP-WMI) of HP-WMI as a trigger to provide rotation. While the following script was developed for HP tablet PC's originally, Lenovo ThinkPads (and very likely other tablet pc's) should be able to use it too with a minor modification.

Determine your "device names" with xinput list entered in a terminal. Then substitute them for stylus, eraser, and touch (if you have it) in the following shell script using the quotes around the "device name". Only use the xsetwacom commands for the devices you have.

Notice the script assumes you have CellWriter installed. You can substitute the onscreen keyboard of your choice or comment out or remove the lines.

Code: Select all

#!/bin/bash

old="0"
while true; do
	if [[ -e /sys/devices/platform/hp-wmi/tablet ]]; then
		new=`cat /sys/devices/platform/hp-wmi/tablet`
		if [[ $new != $old ]]; then
			if [[ $new == "0" ]]; then
				echo "Rotate to landscape, hide CellWriter."
				xrandr -o normal
				xsetwacom set stylus rotate none
				xsetwacom set eraser rotate none
				xsetwacom set touch rotate none
				cellwriter --hide-window
			elif [[ $new == "1" ]]; then
				echo "Rotate to portrait, show CellWriter."
				xrandr -o right
				xsetwacom set stylus rotate cw
				xsetwacom set eraser rotate cw
				xsetwacom set touch rotate cw
				cellwriter --show-window
			fi
		fi
		old=$new
		sleep 1s
	fi
done

# From Red_Lion post #576:  http://ubuntuforums.org/showthread.php?t=845911&page=58
Save it in "/home/yourusername/" as ".automagic_rotation.sh" (without the quotes), or whatever you want to name it. Make the file executable and add it to your Startup Applications. See a) Script in Implementing a Script with a Launcher or Key Binding below.

For the ThinkPad all you should need to do is change the lines.

Code: Select all

	if [[ -e /sys/devices/platform/hp-wmi/tablet ]]; then
		new=`cat /sys/devices/platform/hp-wmi/tablet`
to

Code: Select all

	if [[ -e /sys/devices/platform/thinkpad_acpi/hotkey_tablet_mode ]]; then
		new=`cat /sys/devices/platform/thinkpad_acpi/hotkey_tablet_mode`
Using these examples, if your tablet pc Brand & model also reports the swivel hinge state, you should be able to modify the script to work for you. Unfortunately the fujitsu-tablet.ko does not report to /sys/devices/platform so there is no hinge switch signal file to cat. So this script will not work for Fujitsu tablet PCs.

See:
The original Auto-magic Rotation Script HOW TO at post #225.
MisteR2's original instructions, the hp-wmi patch, and .fdi for it in posts #104 and #106 on the "How to Rotate the Screen for a TX2000 Tablet PC" thread.
MisteR2's new instructions and attachments (with new files) at post #206.
Red_Lion's first post of the auto-magic rotation script in post #576 on the "Info and help for HP TX2500 Series" thread.


Method 3: The Magick Rotation application for Dell, Fujitsu, HP, and Lenovo tablet PC's. It automatically rotates screen orientation and devices/tools that use the Wacom or evdev drivers. Versions have worked in Arch, Fedora, Gentoo, Mandriva, and openSUSE among others.

MisteR2 tracked down the swivel hinge signal to the HP-WMI kernel module, solving the mystery of no detectable signal. This sits on top of WMI, which is the Windows Management Instrumentation mapper device. WMI is a proprietary extension to ACPI that exposes parts of the ACPI firmware and is available for some BIOS's. Matthew Garrett (the module maintainer) separated out the swivel hinge signal from the docking event (on MisteR2's request) for us and provided a patch. The patch is called hp-wmi.diff.txt and is in post #106. It creates a new event called 'tablet' as opposed to 'dock' and will be included in the hp-wmi kernel module for the 2.6.31 (Helena/Karmic). Red_Lion then got auto-magic rotation actually working with his first script. He also wrote the first version of the Magick Rotation applet in Python gtk. Not only does it automatically rotate the screen orientation (along with the input tools) when you pivoted the screen to tablet mode it also allows for handy shell commands.

Magick Rotation 1.6.2 applet released (10-3-12) is on Launchpad: https://launchpad.net/magick-rotation In addition to automatic rotation and selection of rotation direction it offers other features such as a touch toggle function and display of an onscreen keyboard when rotated. Magick Rotation works for Dell, Fujitsu, HP, & Lenovo tablet PC's if they have auto-magic rotation in Windows (a swivel hinge switch sends a signal) and their bios supports ACPI implementation of the signal either through WMI (and hence hp-wmi or dell-wmi) or a straight OEM ACPI module (thinkpad_acpi or fujitsu-tablet).

Note: Dell XT & XT2 and Fujitsu users. The dell-wmi from the kernel does not report the swivel hinge switch state. To get a dell-wmi.ko that works correctly (in a dkms implementation) see the MagickExtras folder in the magick-rotation folder. Instructions are there or in a FAQ at the Launchpad site. MagickExtras also contains a dkms for fujitsu-table.ko that will compile on Isadora/Lucid through Maya/Precise. This is the fujitsu-tablet.ko that will be included in the 3.4 kernel.

Note: Python 3. The shebang lines in Magick Rotation 1.6.2 have been changed from python to python2. That specifies Python 2 (required by Magick) for Distro's that have switched to Python 3. As long as there is a python2 symlink in /usr/bin pointing to the install of Python 2 (usually Python 2.7.x) Magick Rotation should work. For more information and instructions on how to create a symlink see this Magick Rotation FAQ.

Advanced Setup command examples (note use of semi-colon to separate commands):
[Run before switch to tablet:] killall -9 cairo-dock; gconftool-2 --set /apps/panel/toplevels/top_panel_screen0/size --type integer 42
[Run after switch to tablet:] cellwriter --show-window; cairo-dock -o
[Exec. before switch to normal:] killall -9 cairo-dock; gconftool-2 --set /apps/panel/toplevels/top_panel_screen0/size --type integer 24
[Exec. after switch to normal:] cellwriter --hide-window; cairo-dock -o

CellWriter is assumed installed by default; the commands show it in portrait and hide it in landscape. The Cairo (or Glx) Dock commands are to close the dock and restart it after rotation so it resizes correctly. This is no longer necessary with recent versions. The gconftool command, which is for Gnome 2, resizes the top panel to a larger size (from the default 24) in portrait so it is more touch friendly. For the bottom panel just substitute bottom_panel_screen0 for top_panel_screen0. To verify what your default panel size is use Configuration Editor (you may have to make it visible through System > Preferences > Main Menu). Go to Applications > System Tools > Configuration Editor. Then look in apps > panel > default_setup > toplevels, then top_panel or bottom_panel.


Method 4: The wacomrotate daemon
Tom Jaeger, developer of EasyStroke, came up with an elegant solution. He wrote a daemon in C called wacomrotate that detects current screen orientation and automatically rotates the Wacom input tools stylus, eraser, and touch to the same orientation. This method should work for all Wacom based tablet PCs.

Go to Tom's repository and download the appropriate deb package that contains his C daemon for your release and install type i.e. 32-bit v.s. 64-bit. For e.g., if you have a 64-bit install of Isadora/Lucid, it would be “wacomrotate_0.3.1_amd64.deb” dated 4-13-10. For a 32-bit install of Julia/Maverick it would be “wacomrotate_0.3.1-0thjaeger1_i386.deb” dated 9-15-10, etc. For Maya/Precise use version 0.3.2 dated 5-20-12. Save to desktop. Then double-click on it and let the deb package installer install it. It will automatically install itself into Startup Applications so that it is auto-started at boot. If you grabbed the wrong deb by mistake the Debian Installer will tell you so and refuse to install the package.

He also supplied the following command line command to be used in conjunction with his wacomrotate daemon.
For right handed Portrait rotation use:

Code: Select all

  xrandr -q | grep -q '+\w* (' && xrandr -o right || xrandr -o normal
or for left handed Portrait rotation use:

Code: Select all

  xrandr -q | grep -q '+\w* (' && xrandr -o left || xrandr -o normal
You'll want to put the command into a Launcher or create a Key Binding as described below.

There is a git repository of wacomrotate on github, although it doesn't appear to have had any recent commits like for 3.2. He also has a Useful packages for (wacom) Tablet PCs PPA you might want to take a look at.


Implementing a Script with a Launcher or Key Binding
a) Script
1) Open Text Editor (gedit) and create a new .txt file.
2) Into it place the script of your choice. Obviously if you're going to use the wacomrotate daemon you'll need Tom's command (or you can skip this and with his command go straight to the key binding method below).
3) Name the script and Save the script as .yourscriptname.sh. The period in front of the name is makes it a hidden file. This is useful if you place the file in your /home/yourusername directory. That will help prevent directory clutter. If you decide to create a folder/directory bin (/home/yourusername/bin) for your scripts you probably won't want to make it hidden.
4) Now you need to make the script file executable. Right click on the text file and choose Properties. In the Permissions tab check the “Allow executing file as a program” and close. Or in a terminal:

Code: Select all

chmod +x ~/.yourscriptname.sh
5) The Tablet PC Automatic Rotation Script needs to be set up to auto-start. Go to System->Preferences->Startup Applications and click on Add and for the command enter /home/yourusername/.automagic_rotation.sh. And title it “Auto-magic Rotation” or whatever you like.

b) Launcher: for methods 1 & 4
1) Next create a launcher on the desktop by right clicking on it and choosing Create Launcher... Give it a name and in the Command box type the path to the text file you made executable i.e. /home/yourusername/Desktop/.yourscriptname.sh.
Note: when you clean up the Desktop and move the script to say, /home/yourusername or /home/yourusername/bin directory, remember to change the path in the Launcher's command box to reflect the new path.
2) Double click on the launcher's icon and watch the screen rotate! Check that your stylus, eraser, and touch are oriented and working correctly. Double click again and rotate back.
3) If you want, move the launcher to a panel or to a dock, like Cairo-dock, and then a single click will rotate the screen.

c) Button/key Binding: for methods 1 & 4. To further integrate screen rotation into your tablet PC you can do a key binding to a key, preferably a bezel button. A bezel button is one of the buttons on the edge of the screen still accessible in tablet mode.
While a HP TX2000 is used as an example on how to set up the bezel buttons, most of the information should generalize to other tablet PC's. For further explanation see Appendix 2 below. With the TX2000 only 2 bezel buttons ever worked, see Miscellaneous Notes below. And starting with Lucid the DVD button also stopped working, leaving only the "Q" button.
1) To get the DVD button working again and launching the mediaplayer as it did before Lucid edit the hewlett-packard keymap in /lib/udev/keymaps with:

Code: Select all

gksudo gedit /lib/udev/keymaps/hewlett-packard
like so:

Code: Select all

#0x08e dvd
0x08e media
2) To assign the "Q" button to the XF86Launch5 KeySym first edit the hewlett-packard-pavilion keymap in /lib/udev/keymaps using:

Code: Select all

gksudo gedit /lib/udev/keymaps/hewlett-packard-pavilion
And make the following change:

Code: Select all

#0x88 media # FIXME: quick play
0x88
Now edit rc.local in /etc:

Code: Select all

gksudo gedit /etc/rc.local
and add:

Code: Select all

setkeycodes e008 184
above the exit 0 line and reboot.
3) Open the CompizConfig Settings Manager (CCSM). You may need to install it first. In General open Commands. Make sure the Enable Commands box is checked. In the Commands tab pick a command line and type in the name and path of the executable rotation script text file and close. If you're running the wacomrotate daemon you can put in Tom's command directly instead of the path to the rotation script.
4) Next select the Key Bindings tab. Pick the Run command line that has the same number as the Command line # you put the rotation script file name (and path) in. Click on the Disabled button to the right of Run command #. Click the Enabled box and then the Grab key combination button. Press the Q button. You should see XF86Launch5 appear. Close CompizConfig.
5) Now press the "Q" bezel button and watch your screen rotate!


Miscellaneous Notes
With HP TX2000's we never got a signal, in xev or anything else, from the two blue led buttons on the bottom right edge of our screen, one of which is the original rotation button. Starting with Karmic we lost the DVD bezel button too. And the Q key (which we were using as a substitute rotation key) became the only active bezel button. It now codes XF86AudioMedia and launches the mediaplayer like the DVD key used to and should do. Presumably this is due to a bug(s) in hp-wmi. Red_Lion looking at his DSDT thinks the "bezel buttons parsing via PNP0C09 method _Q16." PNP0C09 is the Microsoft acpi-compatible embedded controller. A summary of what we have learned so far is in posts #273 & 274 on this thread. There are similar problems with HP's TX2500 and TX2z bezel buttons, again presumably due to the same hp-wmi bug.
Bezel Button Update 2: tipp98 has solved the missing bezel buttons!!! He submitted his solution to the RedHat bugzilla.. See post #2 below for instructions.
Bezel Button Update 1: tipp98 is currently investigating the problem and has made progress! He's provided a summary of his findings to date on post #601. Even more information is available on this linux-acpi mailing list thread.

For us HP TX2000, TX2500, & TX2z owners to get auto-magic rotation we needed to detect a signal from our swivel hinge. Nothing came through on xev, or acpi_listen and in /var/log/messages either. Then MisteR2 located the signal to the HP-WMI kernel module.

Previous versions of Magick Rotation (Red_Lion's applet for auto-magic rotation in pygtk): 0.5 is at post #528. 0.4 (first to support Lucid) is at post #484; 0.3-3 is at post #315; 0.2-5 is at post #291; 0.2-4 is at post #279. Also 0.2-3 at post #272 & 0.2-2 at post #265.

The Auto-magic Rotation Script HOW TO is at post #225.

Both the Automatic Rotation script and Magick Rotation (they use the swivel hinge switch signal) work in Isadora/Lucid and later releases for HP (TC4200, TC4400, TX2000, TX2500, TX2z, 2710p, 2730p, and TM2t) and Lenovo (ThinkPad) tablet PCs. Magick Rotation also works for Dell and Fujitsu tablet PCs if they add the appropriate kernel module, dell-wmi or fujitsu-tablet respectively.


Sources
Many thanks to the Tom Jaeger and the authors of the following excellent tutorials and associated threads among others:
by mirosol (alternative TX2000 rotation script): http://mirosol.kapsi.fi/tx2020/tx2000howto.htm
alternative TX2500 rotation script by Shm (typo corrected by Pietro Battiston: http://www.pietrobattiston.it/wiki/doku ... ion_tx2500): http://ubuntuforums.org/showthread.php?t=845911&page=35
toobaz (Pietro Battiston) has updated his TX2500 wiki for Karmic. He has an interesting take on setting up the rotation scripts there.
Toshiba M700 rotation script: https://wiki.ubuntu.com/SergioZanchetta ... ortegeM700


Appendix 1: enabling video driver rotation
The proprietary Nvidia driver requires the following option in the xorg.conf:

Code: Select all

	Option		"RandRRotation"  "on"
in Section "Device" with the Identifier labeled "Configured Video Device" or "Default Device", depending on your Xserver version.

Most Intel MB chipsets using the Xorg Intel video driver don't require any extra configuration. However some may require the same option, those chipsets that need a xorg.conf for proper configuration.

The ATI proprietary "fglrx" driver through Catalyst should work without any xorg.conf or option added to it. If you have any video issues check out the Unofficial Wiki for the AMD Linux Driver site.

Appendix 2: Bezel Buttons; using mainly the HP TX2000 as an example
[needs more work]
First you want to check if the keys are emitting a keycode. There are several diagnostic tests to look for a keycode among them xev and evtest. Let's use xev. In a terminal type:

Code: Select all

xev
and hit enter. A little box pops up. Press one of the keys/buttons in question and then close the box. The terminal will fill with output. You are looking for keywords like KeyPress, keycode, and keysym. You can copy and paste the output into gedit and then do a find for them. You are looking for the keycode number and the little sections of output that contain it. There should be two, one for the KeyPress event and one for the KeyRelease event. Then repeat for the next key. Remember the keycodes you get from xev are the X keycodes (hence the x in the name, xev = X event). If there are keycodes you should be able to assign them through Xmodmap, xbindkeys, xdotool, etc.

Now if there is no X keycode that is another situation and there are several possibilities.
1) Something is going wrong with the chain: kernel keycode > udev key mapping (keysym assignment) > X keycode. This is what the rest of appendix 2 deals with, a step by step guide to diagnose the chain.

Other possibilities include:
2) The BIOS has changed key assignments and the kernel driver code that is reading the key assignment needs to be changed to reflect that. Examples of that would be the code in hp-wmi.c or thinkpad-acpi.c. The compiled versions of those are the hp-wmi.ko and thinkpad-acpi.ko (ko = kernel object i.e module/driver) you see in /lib/modules/yourcurrentkernel/kernel/drivers/platform/x86. In which case you may need to work with the kernel source code of the appropriate kernel module/driver and change the hex/scan code assignments. Then compile the module to test your changes. Examples of that being done for the dell-wmi.c are in post #1176 and post #1587 of the N-Trig HOW TO.
3) The final possiblity is either a kernel module/driver has never been written or, if one of the current modules is the appropriate driver, the code has never been written for it to support the buttons/keys in question. Fujitsu tablet PCs "enjoy" a special case of this. While the fujitsu-tablet.c (fujitsu-tablet.ko) module which supports the bezel buttons has been written and submitted to the kernel for unknown reasons it has never been accepted. So to obtain the kernel module/driver (which comes in the fjbtndrv package) you need to use either Robert Gerlach's fjbtndrv PPA or SourceForge site and compile it.

a) kernel codes The first step is to find the bezel button's kernel scan codes. Enter a console with <ctrl-alt-F1>; to get back to X enter <ctrl-alt-F7>. Then enter showkey -s in the console and press the bezel buttons. Only the scan code from the Q key (none of the other 3 do anything) appears: 0xe0 0x6d 0xe0 0xed. Next find the kernel keycodes by entering showkey -k and press the buttons which shows (the two bottom buttons did nothing until tipp98 came up with his fix in December 2012; see post #2 below): DVD button = 389 and Q button = 226. So the bezel button assignments from the kernel are:

Code: Select all

DVD button         scan code = ???                   keycode = 389
Q   button         scan code = 0xe0 0x6d 0xe0 0xed   keycode = 226
Rotation button    N/A
Brightness button  N/A
The keys and their corresponding key codes are defined in input.h at /usr/include/linux.

b) udev codes Now using the README at /usr/share/doc/udev/README.keymap.txt let's dump the current mapping and determine the udev scan codes and key codes. To do this we need to know the input/event the keyboard is on. Enter in a terminal /lib/udev/findkeyboards. The output shows the keyboard is on event 5.
USB keyboard: input/event5
Or use ls -l /dev/input/by-path and look for -event-kbd.
lrwxrwxrwx 1 root root 9 2011-06-01 16:05 platform-i8042-serio-0-event-kbd -> ../event5
Then using that event# dump the current udev keymapping into a text file for reference:

Code: Select all

sudo /lib/udev/keymap input/event5 > /home/yourusername/orig-map.txt
[B]or[/B]
sudo /lib/udev/keymap input/event5 > ~/orig-map.txt
To determine the udev codes run in a terminal the following command: sudo /lib/udev/keymap -i input/event5 Then press the bezel button(s) or multimedia/function keys of interest. Use esc to exit. If it shows a tendency to scroll away, use: sudo /lib/udev/keymap -i input/event5 | less And after pressing the bezel buttons, again enter esc to exit, and you will see the scan codes and the associated udev key codes. Enter ctrl-z to exit less. The output shows:

Code: Select all

scan code: 0x8E   key code: dvd
scan code: 0x88   key code: media
So now the bezel button assignments from the kernel and udev are:

Code: Select all

DVD button   scan code = ???                   keycode = 389   scan code: 0x8E   keycode: dvd
Q   button   scan code = 0xe0 0x6d 0xe0 0xed   keycode = 226   scan code: 0x88   keycode: media
Note: to find the corresponding X keycode add 8 to the kernel keycode. See e) below.

c) udev rules and keymaps
In /lib/udev/rules.d you'll see the Hewlett-Packard rules in the 95-keymap.rules file. They will apply all the keymaps that the rules match. The match is made to the Vendor and then the dmi id's product_name or product_version (/sys/class/dmi/id). Or if need be board_version etc., whatever is needed to give a unique match. Another way to determine the content of those files in /sys/class/dmi/id is to query with dmidecode, e.g.:

Code: Select all

sudo dmidecode --string system-product-name

sudo dmidecode --string baseboard-product-name
The results being:
HP Pavilion tx2000 Notebook PC
30E5
So the rule matches cause the following hewlett-packard keymaps in /lib/udev/keymaps to be applied: hewlett-packard, hewlett-packard-tablet, hewlett-packard-pavilion, and hewlett-packard-tx2. Looking in them we discover that hewlett-packard contains 0x08e dvd and hewlett-packard-pavilion has 0x88 media. Now we know where the udev codes are coming from.

c) changing udev keymaps
Clearly we can edit and change the rules or the keymaps. While the DVD button seems to be recognized by udev it appears to do nothing and acts broken. Can we get it to do anything? Editing the hewlett-packard keymap in /lib/udev/keymaps like so:

Code: Select all

#0x08e dvd
0x08e media
Results in, after a reboot, the DVD bezel key suddenly working again! And it launches the mediaplayer like it used to do and just like the Q key does now. So we are back to two working bezel buttons. But we don't need both assigned to media so let's remove the media assignment from the Q button. Edit the hewlett-packard-pavilion keymap in /lib/udev/keymaps using:

Code: Select all

gksudo gedit /lib/udev/keymaps/hewlett-packard-pavilion
And make the following change:

Code: Select all

#0x88 media # FIXME: quick play
0x88
After a reboot if you check the keymap:

Code: Select all

sudo /lib/udev/keymap input/event4 > /home/username/mod-key-map.txt
You'll find 0x088 media changed to 0x088 reserved indicating the Q button is unassigned.

d) assign the Q button to the XF86Launch5 KeySym with setkeycodes in rc.local
To find the usable form of the kernel scan code needed by setkeycodes press the Q button and run:

Code: Select all

dmesg | grep atkbd
You should see:
[ 109.500951] atkbd serio0: Unknown key pressed (translated set 2, code 0x88 on isa0060/serio0).
[ 109.500956] atkbd serio0: Use 'setkeycodes e008 <keycode>' to make it known.
[ 109.502910] atkbd serio0: Unknown key released (translated set 2, code 0x88 on isa0060/serio0).
[ 109.502914] atkbd serio0: Use 'setkeycodes e008 <keycode>' to make it known.
Dmesg has kindly done the conversion for us and e008 is what we want to use.

Now we need to assign the "Q" button to XF86Launch5 in order to bind it into a rotation script. We've been traditionally using XF86Launch5 to avoid conflicting with any other key assignment. To determine the keycode for XF86Launch5 run this command:

Code: Select all

xmodmap -pke | grep XF86
In the output we see:
keycode 192 = XF86Launch5 NoSymbol XF86Launch5
Notice as the command name xmodmap implies 192 is a X keycode. Recall to get the kernel keycode you need to subtract 8 from the X keycode. So 192 - 8 = 184. Now using 184 enter in rc.local in /etc the following:

Code: Select all

setkeycodes e008 184
above the exit 0 line and reboot. By adding it to rc.local we avoid prefacing it with sudo since rc.local runs before X starts. Now the Q button is assigned to XF86Launch5 and is ready to be bound in CCSM to a rotation script (see "Implementing a Script" c) above). You can verify this by opening up a terminal and running “xev”. A box will pop up. Press the Q bezel button and then close the xev box. In the ouput you will see for the bezel key press XF86Launch5.

TA DA! We're back to where we were pre-Lucid (well OK, Karmic). Two working bezel buttons with DVD calling the music player and Q the rotation script.

Another example of using setkeycodes is the Thinkpad X201t script "setX201tKeys.sh" by linuxd00 from "[HOW TO]Lenovo X201 tablet. Enable your Tablet buttons and some little surprises".

Code: Select all

#!/bin/bash

sudo setkeycodes 0x67 148 # unlabeled(rotating arrow) button mapped to KeySym:	XF86Launch1 - X keycode is 156
sudo setkeycodes 0x6c 120 # Rotatebutton button mapped to KeySym: 		XF86LaunchA - X keycode is 128
sudo setkeycodes 0x68 204 # Toolbarbutton button mapped to KeySym: 		XF86LaunchB - X keycode is 212
sudo setkeycodes 0x66 149 # Padlock button mapped to KeySym:  			XF86Launch2 - X keycode is 157
The Thinkwiki.org has more on Thinkpad bezel buttons.

e) X keycodes
The Xserver currently doesn't process keycodes greater than 255 due to core protocol limitations. This is why some keys don't generate any events. X also requires an offset of 8 from the kernel key code. Recall there is a list of kernel key values in input.h. To get the corresponding X keycode simply add 8 to the kernel keycode:

Code: Select all

X keycode = kernel keycode + 8 (provided the new X keycode is not greater than 255)
So for example the Q button's X keycode would be:

Code: Select all

X key code = 234 = 226 + 8
f) Xmodmap (method used prior to Lucid)
1) Open up a terminal. Type “xev” and enter. A box will pop up. Press the bezel button and then close the xev box. Then look for the returned keycode value for the bezel key press. (For a HP TX2000 it was keycode 201 for the “Q” key in Intrepid (205 in Hardy)).
2) Open a text file on the desktop. In it enter the keycode e.g. 201:

Code: Select all

  keycode 201 = XF86Launch5
where in this example XF86Launch5 is a key label not being used by any other key code. Save the text file as “.Xmodmap” in your home/user/ directory. The Xmodmap will become active on reboot.
After restart open up a terminal and run “xev”. Press the bezel key. You should see the keycode number as before now associated with in our example XF86Launch5.
*thanks to Ayuthia for his assistance

Appendix 3: HP Elitebook Tablet PC Thumb Scroll Bezel Button
Sometimes the showkey command in appendix 2 a) doesn't yield a scan code. In this example this Elitebook's thumb scroll scan codes were found in the kern.log.

Code: Select all

    Mar  6 12:30:22 MisfitToy kernel: [13086.240796] atkbd serio0: Unknown key released (translated set 2, code 0x86 on isa0060/serio0).
    Mar  6 12:30:22 MisfitToy kernel: [13086.240806] atkbd serio0: Use 'setkeycodes e006 <keycode>' to make it known.
    Mar  6 12:30:22 MisfitToy kernel: [13086.531892] atkbd serio0: Unknown key pressed (translated set 2, code 0x87 on isa0060/serio0).
    Mar  6 12:30:22 MisfitToy kernel: [13086.531902] atkbd serio0: Use 'setkeycodes e007 <keycode>' to make it known.
Looking in the:

Code: Select all

xmodmap -pke > xmodmap-pke.txt
output shows these X keycodes which are of interest.

Code: Select all

keycode 111 = Up NoSymbol Up
keycode 112 = Prior NoSymbol Prior

keycode 116 = Down NoSymbol Down
keycode 117 = Next NoSymbol Next
To get the thumb scroll button to work we'll elect to use Prior and Next. Remembering to subtract 8 from the X keycodes, enter in rc.local:

Code: Select all

    setkeycodes e006 104
    setkeycodes e007 109
above the exit 0 line and reboot. TA DA! Your thumb rocker switch now scrolls.
*thanks to robbyb413 on his "Thumb scrolling switch [HP TabletPC, Mint 12/Gnome3]" thread
Last edited by Favux on Sat Jan 12, 2013 2:01 pm, edited 3 times in total.
Favux

Re: Tablet PC rotation HOW TO

Post by Favux »

HOW TO activate missing HP convertible tablet PC bezel buttons


Discussion
The first fix should work for the HP TX2000, TX2500, and TX2z convertible tablet PC models. I don't know about the HP TM2. The Elitebooks (HP 2700 series) already have all the bezel buttons working so this doesn't apply to them.

The second fix should work for the HP TC4200 and TC4400. A little modification should get it working for the TC1100 also.

Last Updated: April 9, 2013


I. Activate the missing HP TX2*** convertible tablet PC bezel buttons
Eureka! Kyle has found the secret sauce to activate the two missing bezel buttons! The long saga has ended. You need to patch hp-wmi.c and compile it. Actually only a few lines need to be added. Kyle submitted his solution to the RedHat bugzilla and then to the kernel's Linux x86 Platform Driver Development list.
Update: The Add_support_for_SMBus_hotkeys.patch has been accepted into the 3.9 kernel! Congratulations Kyle. http://ubuntuforums.org/showthread.php? ... st12585293


Download the hp-wmi.c source code, patch it, compile it, and install the new hp-wmi.ko.
First rename the original hp-wmi.ko so you have a backup.

Code: Select all

sudo mv /lib/modules/`uname -r`/kernel/drivers/platform/x86/hp-wmi.ko /lib/modules/`uname -r`/kernel/drivers/platform/x86/hp-wmi.ko.orig
Then download the attached Add_support_for_SMBus_hotkeys.patch tar onto your Desktop and extract it. Next download the kernel source code:

Code: Select all

cd Desktop

sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)

apt-get source linux-image-$(uname -r)
This can take a few minutes depending on your connection speed. Patch hp-wmi-c with the Add_support_for_SMBus_hotkeys.patch.

Code: Select all

cd linux-3.2.0

patch -p1 < ~/Desktop/Add_support_for_SMBus_hotkeys.patch
Now compile the patched hp-wmi.c to get a patched hp-wmi.ko.

Code: Select all

cd drivers/platform/x86

make -C /lib/modules/`uname -r`/build M=`pwd` modules
Copy it into place and rebuild all module dependencies.

Code: Select all

sudo cp hp-wmi.ko /lib/modules/`uname -r`/kernel/drivers/platform/x86/

sudo depmod -a
Reboot.

With the patch finally all 4 bezel buttons emit keycodes. The two newly active lower right corner bezel buttons (laptop orientation) on the HP TX2000:

Code: Select all

Rotate bezel button keycode: 161
Mobility Center bezel button keycode: 149
You should see essentially the same thing for the HP TX2500. The HP TX2z has 3 not 4 bezel buttons. I think only one, the big Multimedia key, wasn't working.


II. Activate the missing HP TC**00 convertible tablet PC bezel buttons
To get the 3 bezel buttons of the HP TC4400 working. Should also work for the HP TC4200 and TC1100 also. Gco reminds us that the TC's need code to enable their 3 stylus activated bezel buttons and then proceeded to figure out how to get them working in Precise on xf86-input-wacom-0.19.0.

Sources
Igor Galarraga's fix: http://code.google.com/p/linuxwacom-pat ... loads/list
Erich Hoover's fix, submitted to linuxwacom-devel: http://sourceforge.net/mailarchive/foru ... acom-devel
gco's tutorial: http://ubuntuforums.org/showpost.php?p= ... tcount=628


Apply the following two patches to xf86-input-wacom-0.19.0, but should work on any recent xf86-input-wacom:
  1. frankenserver's - from http://forums.linuxmint.com/viewtopic.php?f=42&t=110408 (section II)
  2. Add-HP-TC4400-bezel-button.patch - attached below. Which adds the lines below to wcmIDSV4.c:801

Code: Select all

        /* Soft keys outside tabletPC  TC4400 */
	if ((data[0] & 0xC1)==0xC1) { 
		switch (data[1]) {
			case 0x01: /* Edit */
				/*DBG(8, priv->debugLevel, ErrorF("isdv4Parse special key EDIT\n"));*/
				/*Simulate mouse button 15 press when EDIT */
				xf86PostButtonEvent(pInfo->dev, 1, 15, 1,0,0);
				xf86PostButtonEvent(pInfo->dev, 1, 15, 0,0,0);
				break;
			case 0x02: /* Recicle */
				/*DBG(8, priv->debugLevel, ErrorF("isdv4Parse special key RECICLE\n"));*/
				/*Simulate mouse button 16 press when RECICLE */
				xf86PostButtonEvent(pInfo->dev, 1, 16, 1,0,0);
				xf86PostButtonEvent(pInfo->dev, 1, 16, 0,0,0);
				break;
			case 0x04: /* Quick */
				/*DBG(8, priv->debugLevel, ErrorF("isdv4Parse special key QUICK\n"));*/
				/*Simulate mouse button 17 press when QUICK */				
				xf86PostButtonEvent(pInfo->dev, 1, 17, 1,0,0);
				xf86PostButtonEvent(pInfo->dev, 1, 17, 0,0,0);
				break;
			default: /* Not reconized */
				break;
		}
	}

Patch is from linuxwacom-patch-for-tc4400 by Igor Galarraga. Finish compiling and installing xf86-input-wacom. After reboot, xev should start detecting the bezel button keycodes.


Then you can use xbindkeys to bind mouse buttons 15, 16 and 17 respectively to Writing tool, Rotate and Q-Menu buttons. Add the following lines to .xbindkeysrc config file:

Code: Select all

# Binds TC4400's bezel buttons

# Writing tool
# "MyScriptStylus" in my case, but "Cellwriter" is a more commom choice
"MyScriptStylus"
   b:15 + Release

# Rotate
# Used a script provided by Brancaleone at http://ubuntuforums.org/showthread.php?t=1483623&page=4
# Magick-Rotation is still responsible for automatic rotation when switching the screen from one mode to another; while this sh script deals with Rotate bezel button. Perhaps I could use only Magick-Rotation features here.
"/usr/bin/rotator"
   b:16 + Release

# Q-Menu
# Still trying to open Unity's launcher panel here (without using xdotool), but you can bind it to whatever you want. In my case, I set Unity's Launcher to hide when not focused, so it would be nice if I could use Q button to open/focus it. I couldn't yet find a way to do that without xdotool though.  
"[do something]"
   b:17 + Release
The rotation script rotator.sh by Brancaleone attached below.
Post Reply

Return to “Tutorials”