TwinView & Wacom
This page describes how to setup a Wacom Intuos3 6×8 tablet for use with a dual screen setup (TwinView) in Ubuntu 10.04 LTS. I have a Dell Latitude E6410 as screen 0 (1440×900) and a Samsung SyncMaster 2243BW as screen 1 (1680×1050). This combination results in a TwinView screen of 3120×1050. The script below is run once after plugging in the tablet.
#!/bin/bash # Setup Wacom tablet to screen 1 of TwinView setup # Get all values with: xsetwacom -s get "Wacom Intuos3 6x8" all # Screen 0: 1440x900 # Screen 1: 1680x1050 # TwinView desktop: 3120x1050 # xsetwacom --get "Wacom Intuos3 6x8" TopX 0 # xsetwacom --get "Wacom Intuos3 6x8" BottomX 40640 # Twinview Desktop X value WX = 3120 # Monitor X value SX = 1680 # Tablet X value TX = 40640 # Values to use Screen 1: # TopX = TX - ( TX * WX / SX / 2 ) = 2903 # (ref: http://art.ubuntuforums.org/showthread.php?t=1461978) # Setup stylus xsetwacom --set "Wacom Intuos3 6x8" TwinView horizontal xsetwacom --set "Wacom Intuos3 6x8" Screen_No 1 xsetwacom --set "Wacom Intuos3 6x8" TopX 2903 # Setup eraser xsetwacom --set "Wacom Intuos3 6x8 eraser" TwinView horizontal xsetwacom --set "Wacom Intuos3 6x8 eraser" Screen_No 1 xsetwacom --set "Wacom Intuos3 6x8 eraser" TopX 2903 # Setup strips on pad (DOES NOT WORK) # xsetwacom --set "Wacom Intuos3 6x8 pad" StripRUp "key pgup" # xsetwacom --set "Wacom Intuos3 6x8 pad" StripRDn "key pgdn" # xsetwacom --set "Wacom Intuos3 6x8 pad" StripLUp "key +" # xsetwacom --set "Wacom Intuos3 6x8 pad" StripLDn "key -" # Setup keys on pad # --------- --------- # | | 1 | | 5 | | # | 3 |---| |---| 7 | # | | 2 | | 6 | | # |-------| |-------| # | 4 | | 8 | # --------- --------- xsetwacom --set "Wacom Intuos3 6x8 pad" Button1 "key ctrl z" # Undo last step xsetwacom --set "Wacom Intuos3 6x8 pad" Button2 "key ctrl y" # Redo last step xsetwacom --set "Wacom Intuos3 6x8 pad" Button3 "key shift e" # Eraser fuction for stylus xsetwacom --set "Wacom Intuos3 6x8 pad" Button4 "key r" # Rectangle tool for stylus xsetwacom --set "Wacom Intuos3 6x8 pad" Button5 "key n" # Pencil tool for stylus xsetwacom --set "Wacom Intuos3 6x8 pad" Button6 "key p" # Paintbrush tool for stylus xsetwacom --set "Wacom Intuos3 6x8 pad" Button7 "key k" # Ink tool for stylus xsetwacom --set "Wacom Intuos3 6x8 pad" Button8 "key a" # Airbrush tool for stylus
The tablet is activated in Gimp 2.6.8 by changing the mode of the stylus, eraser, cursor and pad to Screen. This option is set by following Edit > Preferences > Input Devices > Configure Extended Input Devices.
Outdated information:
The section below describes the configuration of the dual screen setup with Wacom tablet on a Dell XPS M1330 laptop with Ubuntu 9.04. The secondary LCD (screen 1) is a Samsung SyncMaster 2243BW, which is used with a Wacom Intuos3 tablet. The version of the restricted graphics driver is Nvidia version 180. The code below is the contents of the /etc/X11/xorg.conf file:
Section "Monitor" Identifier "Monitor0" VendorName "Dell" ModelName "LPL" HorizSync 30.0 - 75.0 VertRefresh 60.0 Option "DPMS" EndSection Section "Monitor" Identifier "Monitor1" VendorName "Samsung" ModelName "SyncMaster" HorizSync 30.0 - 81.0 VertRefresh 56.0 - 75.0 EndSection Section "Screen" Identifier "Screen0" Device "Device0" Monitor "Monitor0" Option "TwinView" "0" Option "metamodes" "DFP: 1280x800 +0+0" DefaultDepth 24 SubSection "Display" Depth 24 EndSubSection EndSection Section "Screen" Identifier "Screen1" Device "Device1" Monitor "Monitor1" DefaultDepth 24 Option "TwinView" "0" Option "TwinViewXineramaInfoOrder" "CRT-0" Option "metamodes" "CRT: 1680x1050 +0+0" SubSection "Display" Depth 24 EndSubSection EndSection Section "Module" Load "dbe" Load "extmod" Load "type1" Load "freetype" Load "glx" EndSection Section "ServerLayout" Identifier "Default Layout" Screen 0 "Screen0" 0 0 Screen 1 "Screen1" RightOf "Screen0" EndSection Section "Device" Identifier "Device0" VendorName "NVIDIA Corporation" BoardName "GeForce 8400M GS" BusID "PCI:1:0:0" Screen 0 Driver "nvidia" Option "NoLogo" "True" EndSection Section "Device" Identifier "Device1" VendorName "NVIDIA Corporation" BoardName "GeForce 8400M GS" BusID "PCI:1:0:0" Screen 1 Driver "nvidia" Option "NoLogo" "True" EndSection Section "ServerFlags" Option "Xinerama" "1" EndSection
After installing the latest Wacom drivers, the GTK+ package needs to be patched and compiled from source to correct the cursor offset in Gimp and Inkscape:
$sudo apt-get build-dep libgtk2.0-0 $sudo apt-get source libgtk2.0-0
Special thanks to some guy named “gator_ml yahoo de” for the three years old patch to gdk/x11/gdkinput-x11.c, which still needs to be applied to the current version of GTK+ (!?!):
--- gtk+-2.8.18/gdk/x11/gdkinput-x11.c.org 2006-03-04 06:25:45.000000000 +0100
+++ gtk+-2.8.18/gdk/x11/gdkinput-x11.c 2006-05-29 16:38:24.000000000 +0200
@@ -455,11 +455,19 @@
if (gdkdev->info.mode == GDK_MODE_SCREEN)
{
- x_scale = gdk_screen_get_width (gdk_drawable_get_screen (input_window->window)) / device_width;
- y_scale = gdk_screen_get_height (gdk_drawable_get_screen (input_window->window)) / device_height;
-
- x_offset = - input_window->root_x;
- y_offset = - input_window->root_y;
+ int core_pointer_x, core_pointer_y, cur_monitor;
+ GdkRectangle mon_geometry;
+ GdkScreen *cur_screen;
+ gdk_display_get_pointer(gdk_drawable_get_display(input_window->window),
+ &cur_screen,&core_pointer_x,&core_pointer_y,0);
+ cur_monitor= gdk_screen_get_monitor_at_point(cur_screen,
+ core_pointer_x,
+ core_pointer_y);
+ gdk_screen_get_monitor_geometry(cur_screen,cur_monitor,&mon_geometry);
+ x_scale = mon_geometry.width / device_width;
+ y_scale = mon_geometry.height / device_height;
+ x_offset = mon_geometry.x - input_window->root_x;
+ y_offset = mon_geometry.y - input_window->root_y;
}
else /* GDK_MODE_WINDOW */
{
Continue to compile, make and install the patched GTK+ version:
./configure --prefix=/usr --with-xinput=yes $sudo make $sudo make install
Compile the following code (gcc -O2 monitor_wacom.c -o .monitor_wacom) to create a daemon, which restores settings on a restart. Thanks to the guys on the Ubuntu forum:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <assert.h>
void log_msg(const char *msg) {
FILE *log_file = fopen(".monitor_wacom.log", "a");
if (log_file) {
time_t time_g;
time(&time_g);
char date_str[100];
strcpy(date_str, asctime(localtime(&time_g)));
date_str[strlen(date_str) - 1] = '\0'; /* get rid of the \n */
fprintf(log_file, "%s : %s\n", date_str, msg);
}
fclose(log_file);
}
void run_script(const char *filename) { /* only run xsetwacom lines */
FILE *script_file = fopen(filename, "r");
if (!script_file) {
log_msg("Failed to open script (double check your entry in Startup Applications). Terminating.");
exit(1);
}
char buf[1024];
char l_buf[1024];
int count = 0;
while ((fgets(buf, 1023, script_file))) {
if (strstr(buf, "xsetwacom")) {
int r = system(buf);
if (r != 0) {
sprintf(buf, "xsetwacom returned error on line - %s", buf);
log_msg(l_buf);
}
++count;
}
}
sprintf(l_buf, "Script ran. %d matching lines executed.", count);
log_msg(l_buf);
}
int main(int argc, char **argv) {
char script_name[1024];
if (argc != 2) {
log_msg("Script not specified, using .xinitrc");
strcpy(script_name, ".xinitrc");
} else {
strcpy(script_name, argv[1]);
}
run_script(script_name);
FILE* in = popen("dbus-monitor --session type='signal',interface='org.gnome.ScreenSaver',member='ActiveChanged'", "r");
if (!in) {
log_msg("Cannot spawn dbus-monitor process. Terminating.");
return 1;
}
while (1) {
char buf[1024];
assert(fgets(buf, 1023, in));
if (buf[0] == 's' /* early exit optimization */ && strstr(buf, "ActiveChanged") != NULL) {
assert(fgets(buf, 1023, in));
if (strstr(buf, "false") != NULL) {
/* resumed */
log_msg("Exit from screensaver detected. Running script.");
run_script(script_name);
} else {
/* put to sleep */
}
}
}
}
Add the daemon as a startup application by adding an entry to System > Preferences > Startup Applications, with the command “/home/yourusername/.monitor_wacom /home/yourusername/.xinitrc”.
The next step is to create a file in /etc/init.d for translation of the HAL device names to the names used by the Wacom drivers:
$ cat /etc/init.d/wacom # Find any Wacom devices for udi in `hal-find-by-property --key input.x11_driver --string wacom` do type=`hal-get-property --udi $udi --key input.x11_options.Type` # Rewrite the names that the Xserver will use hal-set-property --udi $udi --key info.product --string $type case $type in stylus|eraser) ;; esac done
This script can be added to the start-up modes by creating symlinks in /etc/rc{2-5}.d as S27Wacom:
$sudo update-rc.d wacom-names start 27 2 3 4 5 .
There is no need to add a custom HAL fdi file to /etc/hal/fdi/policy. The default HAL fdi is modified to add the eraser, cursor and pad devices:
$ cat /usr/share/hal/fdi/policy/20thirdparty/10-wacom.fdi
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
<device>
<match key="info.category" contains="input">
<match key="info.product" contains="Wacom">
<merge key="input.x11_driver" type="string">wacom</merge>
<merge key="input.x11_options.Type" type="string">stylus</merge>
<append key="info.callouts.add" type="strlist">hal-setup-wacom</append>
<append key="wacom.types" type="strlist">eraser</append>
<append key="wacom.types" type="strlist">cursor</append>
<append key="wacom.types" type="strlist">pad</append>
</match>
</match>
<match key="info.capabilities" contains="serial">
<match key="@info.parent:pnp.id" contains_outof="WACf001;WACf002;WACf003;WACf004;
WACf005;WACf006;WACf007;WACf008;WACf009;WACf00a;WACf00b;WACf00c;FUJ02e5">
<append key="info.capabilities" type="strlist">input</append>
<merge key="input.x11_driver" type="string">wacom</merge>
<merge key="input.x11_options.Type" type="string">stylus</merge>
<merge key="input.x11_options.ForceDevice" type="string">ISDV4</merge>
<merge key="input.device" type="copy_property">serial.device</merge>
<append key="info.callouts.add" type="strlist">hal-setup-wacom</append>
<append key="wacom.types" type="strlist">eraser</append>
<match key="@info.parent:pnp.id" contains_outof="WACf008;WACf009">
<!-- Serial tablets with touch capabilities -->
<append key="wacom.types" type="strlist">touch</append>
</match>
</match>
</match>
</device>
<!-- Match the Wacom Bluetooth A5 pen tablet -->
<device>
<match key="info.capabilities" contains="input.mouse">
<match key="info.product" contains="WACOM">
<match key="info.product" contains="Tablet">
<merge key="input.x11_driver" type="string">wacom</merge>
<merge key="input.x11_options.Type" type="string">stylus</merge>
<append key="info.callouts.add" type="strlist">hal-setup-wacom</append>
<append key="wacom.types" type="strlist">eraser</append>
<append key="wacom.types" type="strlist">cursor</append>
</match>
</match>
</match>
</device>
</deviceinfo>
The following commands should give the 4 devices of the Wacom tablet. The xidump command will give more Xinput devices than shown below:
$ xsetwacom list stylus stylus pad pad cursor cursor eraser eraser $ xidump -l stylus extension pad extension cursor extension eraser extension
The tablet is activated in Gimp 2.6 by changing the mode of the stylus, eraser, cursor and pad to Screen. This option is set by following Edit > Preferences > Input Devices > Configure Extended Input Devices.
The buttons on the pad can be programmed using a script file:
$ cat scripts/wacom #!/bin/bash # Set scrolling on right strip xsetwacom set pad StripRUp "key core pgup" xsetwacom set pad StripRDn "key core pgdn" # Set zoom on left strip xsetwacom set pad StripLUp "key core -" xsetwacom set pad StripLDn "key core +" # Button to Ctrl Z (undo) xsetwacom set pad Button3 "core key ctrl z" # Button FN2 to Ctrl Y (redo) xsetwacom set pad Button4 "core key ctrl y" # Button for pencil xsetwacom set pad Button5 "core key n" # Button for brush xsetwacom set pad Button6 "core key p" # Button for ink xsetwacom set pad Button7 "core key k" # Button for eraser xsetwacom set pad Button8 "core key shift e"