Skip to Content »

Tech Life of Recht » archive for 'ubuntu'

 Karmic Koala

  • October 29th, 2009
  • 9:50 pm

Ubuntu 9.10 (Karmic Koala) is out, so I decided to upgrade. The upgrade process itself went fine, but it seems there were some other changes to the system, which affected me.

I'm running on a MacBook Pro Santa Rosa with 4 GB mem, which means that if I use the standard 32 bit kernel, I cannot use all of the memory. That's not really a problem, I just recompile the kernel to support PAE.
However, I also use XMonad (because it's the best window manager available), and previously I launched it from ~/.xsession. However, the new version of GDM doesn't support that anymore, so now you have to drop a file in /usr/share/xsessions/xmonad.desktop - mine contains this:

CODE:
  1. [Desktop Entry]
  2. Encoding=UTF-8
  3. Name=xmonad
  4. Comment=xmonad
  5. Exec=/pack/haskell/bin/runxmonad.sh
  6. Type=Application

Other than that, simply follow this little guide to make the keyboard and touchpad work properly.

 Upgrading to Ubuntu Jaunty

  • April 26th, 2009
  • 9:20 pm

I've just finished upgrading my two machines (a MacBook Pro, Santa Rosa, and an iMac) to Ubuntu 9.04 (Jaunty). Everything went pretty smoothless, although the download did take some time.

I have only made two adjustments:

  • Fn keys enabled by default - previously, you would add "options hid pb_fnmode=2" to a file in /etc/modprobe.d - now it should be "options hid_apple fnmode=2" instead. This can also be changed at runtime in /sys/module/hid_apple/parameters/fnmode
  • Compiled a new kernel with highmem support (by following this little guide)

Other than that, everything seems to work without any trouble, and nothing broke. Sweet.

 2008 wishes

  • December 29th, 2007
  • 3:02 pm

The coming of a new year usually attracts a number of predictions, some more accurate than others. I'm no good at predicting, so I'll give my wishes for the new year instead:

  • Get my Macbook Pro to work with the DVI-VGA adapter (done)
  • I'd like to be convinced that the dynamic languages are really the way forward. I see that they can do smart stuff, but I sorely miss some kind of help using whatever APIs are developed, besides the source code, and I can't get used to working without a proper editor. I can probably live without the editor, but having methods like def initialize (options = {}) just hurts my eyes. I haven't used Ruby/Rails that much, but I've already dug around more source code than I care to in order to find out what the legal options were.
  • Release Java 7 with proper closures. This probably won't happen, and even when it does, it will take a couple of years before it's adopted.
  • Already, I know that I'm going to spend a good part of my time fiddling around with huge WSDLs and schemas. Could somebody find a way to stop the black hole that is Web Services?
  • As for Linux on the desktop, that will still not happen, even though it should, especially when you look at the new distributions such as Ubuntu. However, I'm pretty satisfied, now I just need xmonad to support dynamic twinview, so I can add a monitor without restarting X
  • And to Apple: please take corporate customers seriously and make a docking station for the Macbook (Pro). I'm getting tired of plugging and unplugging 5 different cables every time I have to move my laptop.
  • Less focus on creating big monolithic systems, more on distributing across autonomous nodes.
  • Finally, it would be great with a proper vi-mode for Eclipse - like vimperator for Firefox.

 DVI adapter with Macbook Pro and Linux

  • December 29th, 2007
  • 2:36 am

I recently discovered that using the DVI adapter with the Macbook Pro wasn't as easy as I thought. The MBP comes with a DVI connector, which is great, and it works just fine when you plug a DVI monitor into it. However, when doing presentations, you almost always have to use a regular VGA connector. Even though the driver (nvidia) could see the screen, it refused to display anything.
Now I've finally worked out a solution, and luckily it's not that complicated. The trick is that even though the monitor is recognized, it is still treated as a DVI monitor. In order to get the driver to treat it as a normal VGA monitor, add this to xorg.conf:

CODE:
  1. Section "Device"
  2.   ...
  3.   Option "ConnectedMonitor" "DFP-0,DFP-1,CRT-0"
  4.   Option "MetaModes" "DFP-0: 1440x900, DFP-1: 1680x1050; DFP-0: 1440x900, CRT-0: 1280x1024"
  5. EndSection

Of course, the modes should be adjusted according to the setup. The MetaModes line should contain the valid combinations, separated by ;. In this case, I've specified that the internal display should always run at 1440x900, and then I either have a DVI monitor connected at 1680x1050 or a VGA monitor at 1280x1024. Of course, it's also possible just to specify one monitor if you're not using TwinView.

The trick now is that when running in X, xrandr can be used to switch between the monitors. When running xrandr, it should display something like this:

CODE:
  1. Screen 0: minimum 1280 x 900, current 1440 x 900, maximum 2720 x 1024
  2. default connected 1440x900+0+0 (normal left inverted right) 0mm x 0mm
  3.    1440x900    50.0*   51.0    54.0
  4.    2720x1024   52.0    50.0
  5.    2464x900    53.0
  6.    1280x1024   55.0

The tricky part now is that the nvidia driver "hides" the monitor configuration in the refresh rate. For example, the 1280x1024 resolution has only one rate, which means that this resolution is unique to one monitor. Switching to this mode with 'xrandr -s 1280x1024' will enable the VGA monitor and disable the internal display.
However, the mode 2720x1024 has two refresh rates, 52 and 50. Unfortunately there's no easy way of telling it, but the 52 rate is with the internal display and the VGA monitor on, while the 50 is with only the internal display on (and a larger desktop, something you probably don't want to use). Switching on the VGA monitor then requires two arguments: xrandr -s 2720x1024 --rate 52.

This isn't the easiest to work with, so I've created a small Perl script which can query the nvidia driver directly to find the available modes, and then call xrandr. Download the script here. To use it, the X11::Protocol Perl package must be installed, and of course xrandr and the nvidia driver. To use the script, simply call it without any arguments to get a list of the supported resolutions and monitors. Select a configuration by calling the script with -s where id is one of the numbers in the first column. That's about as simple as it gets.

 xmonad 0.5

  • December 16th, 2007
  • 12:57 am

xmonad 0.5 is out, and I haven't upgraded my installation in a while. It's pretty nice that configuration is now done in /.xmonad/xmonad.hs, then there's no need to recompile xmonad all the time. The configuration change did require a reorganisation of my old Config.hs, so I took a look at some of the samples to see what other people did.
I ended up with something which looks like this:

xmonad

This is my xmonad.hs:

CODE:
  1. -- XMonad Core
  2. import XMonad
  3. import XMonad.Layout
  4. import XMonad.Operations
  5. import qualified XMonad.StackSet as W
  6.  
  7. -- GHC hierarchical libraries
  8. import Data.Bits ((.|.))
  9. import qualified Data.Map as M
  10. import Graphics.X11
  11. import Graphics.X11.Xlib
  12. import Graphics.X11.Xlib.Extras
  13. import System.IO
  14.  
  15. -- Contribs
  16. import XMonad.Actions.CycleWS
  17. import XMonad.Actions.SwapWorkspaces
  18. import XMonad.Actions.Submap
  19. import XMonad.Actions.WindowBringer
  20. import XMonad.Actions.FloatKeys
  21.  
  22. import XMonad.Hooks.UrgencyHook
  23. import XMonad.Layout.NoBorders
  24. import XMonad.Layout.Tabbed
  25. import XMonad.Layout.WindowNavigation
  26. import XMonad.Layout.Grid
  27. import XMonad.Layout.LayoutHints
  28. import XMonad.Layout.Dishes
  29. import XMonad.Util.EZConfig
  30. import XMonad.Util.Run
  31.  
  32. import XMonad.Prompt.Shell
  33. import XMonad.Prompt
  34.  
  35. import XMonad.Hooks.DynamicLog   ( PP(..), dynamicLogWithPP, dzenColor, wrap, defaultPP )
  36.  
  37. myfont = "\"-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1\""
  38. fgcolor = "black"
  39. bgcolor = "white"
  40.  
  41. statusBarCmd= "dzen2 -e '' -w 660 -h 15 -ta l -xs 1 -fg " ++ fgcolor ++ " -bg " ++ bgcolor ++ " -fn " ++ myfont
  42.  
  43. -- Get ready!
  44. main = do din <- spawnPipe statusBarCmd
  45.           xmonad $ withUrgencyHook dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"] }
  46.               $ defaultConfig
  47.                 { workspaces     = workspaces'
  48.                 , modMask        = modMask'
  49.                 , numlockMask    = 0
  50.                 , layoutHook     = layoutHook'
  51.                 , terminal       = "urxvtc || urxvt"
  52.     , normalBorderColor = "#dddddd"
  53.     , focusedBorderColor = "#3499dd"
  54.     , defaultGaps = [(15,0,0,0)]
  55.     , logHook = dynamicLogWithPP $ myPP din
  56.                 }
  57.                 `additionalKeys` keys'
  58.  
  59. modMask'    = mod4Mask
  60. workspaces' = map show [1] ++ ["web", "mail", "chat", "code"] ++ map show [6 .. 9 :: Int]
  61.  
  62. layoutHook' =
  63.     configurableNavigation noNavigateBorders $
  64.     layouts
  65. layouts =
  66.         Mirror tiled
  67.     ||| tiled
  68.     ||| Grid
  69.     ||| layoutHints Full
  70.     ||| Dishes 2 (1/5)
  71.     ||| noBorders (tabbed shrinkText
  72.                           defaultTConf { fontName = myfont })
  73.   where
  74.      tiled   = Tall nmaster delta ratio
  75.      nmaster = 2     -- The default number of windows in the master pane
  76.      ratio   = 1/2   -- Default proportion of screen occupied by master pane
  77.      delta   = 3/100 -- Percent of screen to increment by when resizing panes
  78. noFollow CrossingEvent {} = return False
  79. noFollow _                = return True
  80. keys' =
  81.     [ ((modMask' .|. shiftMask, xK_d        ), spawn "date | dzen2 -p 2 -xs 1") -- %! Print current date
  82.      , ((modMask', xK_p), shellPrompt defaultXPConfig)
  83.     ]
  84.     ++
  85.     -- modMask'-[1..0] %! Switch to workspace N
  86.     -- modMask'-shift-[1..0] %! Move client to workspace N
  87.     [((m .|. modMask', k), windows $ f i)
  88.         | (i, k) <- zip workspaces' $ [xK_1 .. xK_9] ++ [xK_0]
  89.         , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]
  90.     ++
  91.     -- modMask'-{e,r} %! Switch to physical/Xinerama screens 1 or 2
  92.     -- modMask'-shift-{e,r} %! Move client to screen 1 or 2
  93.     [((m .|. modMask', key), screenWorkspace sc>>= flip whenJust (windows . f))
  94.         | (key, sc) <- zip [xK_e, xK_w] [0..]
  95.         , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]
  96.     ++
  97.     [((modMask' .|. mod1Mask, k), windows $ swapWithCurrent i)
  98.         | (i, k) <- zip workspaces' $ [xK_1 .. xK_9] ++ [xK_0]]
  99.     -- float keys
  100.     ++
  101.     [
  102.       ((modMask',               xK_d     ), withFocused (keysResizeWindow (-10,-10) (1,1)))
  103.     , ((modMask',               xK_s     ), withFocused (keysResizeWindow (10,10) (1,1)))
  104.     , ((modMask',               xK_a     ), withFocused (keysMoveWindowTo (512,384) (1, 0)))
  105.     ]
  106.  
  107.  
  108. myPP h = defaultPP
  109.          { ppCurrent  = dzenColor "white" "#cd8b00" . pad
  110.          , ppVisible  = dzenColor "white" "#666666" . pad
  111.          , ppHidden   = dzenColor "black" "#cccccc" . pad
  112.          , ppHiddenNoWindows = dzenColor "#999999" "#cccccc" . pad
  113.          , ppWsSep    = dzenColor "#bbbbbb" "#cccccc" "^r(1x18)"
  114.          , ppSep      = dzenColor "#bbbbbb" "#cccccc" "^r(1x18)"
  115.          , ppLayout   = dzenColor "black" "#cccccc" .
  116.                         (\ x -> case x of
  117.                                   "TilePrime Horizontal" ->
  118.                                     " ^i(/home/emertens/images/tile_horz.xpm) "
  119.                                   "TilePrime Vertical"   ->
  120.                                     " ^i(/home/emertens/images/tile_vert.xpm) "
  121.                                   "Hinted Full"          ->
  122.                                     " ^i(/home/emertens/images/fullscreen.xpm) "
  123.                                   _                      -> pad x
  124.                         )
  125.          , ppTitle    = (' ':) . escape
  126.          , ppOutput   = hPutStrLn h
  127.          }
  128.   where
  129.   escape = concatMap (\x -> if x == '^' then "^^" else [x])
  130.   pad = wrap " " " "

I use a simple shell script for starting xmonad:

CODE:
  1. ssh-add ~/.ssh/id_dsa </dev/null>/dev/null
  2. Esetroot /usr/share/backgrounds/warty-final-ubuntu.png
  3. unclutter -idle 2 &
  4. urxvtd -f -o
  5. irxevent -d
  6.  
  7. gnome-settings-daemon &
  8. gnome-volume-manager &
  9.  
  10. export PATH=$PATH:`dirname $0`
  11. `dirname $0`/status &
  12.  
  13. xmonad

Finally, the dzen2 status bar is run using this script:

CODE:
  1. #!/bin/sh
  2.  
  3. BG=white
  4. FG=black
  5. FONT="-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1"
  6.  
  7. BFG="#444"
  8.  
  9. gcpubar -i 2 -fg '#444' -w 30 -h 10 | dzen2 -e '' -x 1360 -fg $FG \
  10.    -bg $BG -fn $FONT -h 15 -xs 1 &
  11.  
  12. while :; do
  13. MEM=`memstatus.awk /proc/meminfo`
  14. CPU=`cpustatus.awk`
  15. DATE=`date +"%d-%m %k:%M"`
  16.  
  17. REM=`awk '/remaining capacity/ { print $3 }' /proc/acpi/battery/BAT0/state`
  18. LAST=`awk '/last full/ { print $4}' /proc/acpi/battery/BAT0/info`
  19. STATE=`awk '{print $2}' /proc/acpi/ac_adapter/ADP1/state`
  20. if [ "$STATE" = "on-line" ]; then
  21.   BAT=$(echo $REM $LAST | awk '{printf "Bat: %.1f%%, AC", ($1/$2)*100'})
  22. else
  23.   PRESENT=`awk '/present rate/ { print $3}' /proc/acpi/battery/BAT0/state`
  24.   BAT=$(echo $REM $LAST $PRESENT | \
  25.     awk '{printf "Bat: %.1f%%, %d min", ($1/$2)*100, ($1/$3)*60}')
  26. fi
  27.  
  28. LOAD=`awk '{print $1 " " $2 " " $3}' /proc/loadavg`
  29.  
  30. echo "$CPU $MEM | $DATE | $BAT | $LOAD"
  31. sleep 5
  32. done | dzen2 -e '' -x 660 -w 700 -fg $FG -bg $BG -fn $FONT -h 15 -xs 1

Two awk scripts are used - one for the memory usage and one for CPU frequencies. Why awk? No idea, it just seemed like a good choice at the time.

memstatus.awk:

CODE:
  1. #!/usr/bin/awk -f
  2. BEGIN {
  3.   BG="darkgrey";
  4.   FG="#444";
  5.   WIDTH=30;
  6.   HEIGHT=10;
  7. }
  8.  
  9. /MemTotal/ {t=$2};
  10. /MemFree/ {f=$2};
  11. /SwapTotal/ {st=$2};
  12. /SwapFree/ {sf=$2};
  13.  
  14. END {
  15.   mw=int(WIDTH*(t-f)/t);
  16.   fw=WIDTH-mw;
  17.   sw=int(WIDTH*(st-sf)/st);
  18.  
  19.   printf("Mem: ^ib(1)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)" \
  20.     "^fg(%s)^r(2x%d)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)^ib(0)^fg()\n",
  21.     FG, mw, HEIGHT,
  22.     BG, fw, HEIGHT,
  23.     "black",
  24.     HEIGHT, BG, WIDTH-sw,
  25.     HEIGHT, FG, sw, HEIGHT);
  26. }

CODE:
  1. #!/usr/bin/awk -f
  2. BEGIN {
  3.   BG="darkgrey"
  4.   FG="#444"
  5.   WIDTH=30
  6.   HEIGHT=10
  7.   CPUS=0
  8.  
  9.   cmd = "ls /sys/devices/system/cpu"
  10.   while ((cmd | getline)> 0) {
  11.     if ($1 ~ /cpu/) {
  12.       CPUS++
  13.     }
  14.   }
  15.   close(cmd)
  16.  
  17.   printf "CPU: "
  18.   for (i=0; i <CPUS; i++) {
  19.     cfn="/sys/devices/system/cpu/cpu" i "/cpufreq/scaling_cur_freq"
  20.     mfn="/sys/devices/system/cpu/cpu" i "/cpufreq/scaling_max_freq"
  21.     getline cf <cfn
  22.     getline mf <mfn
  23.     cw=int(WIDTH*(mf-cf)/mf)
  24.  
  25.     printf("^ib(1)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)^ib(0)^fg()",
  26.       FG, cw, HEIGHT, BG, WIDTH-cw, HEIGHT)
  27.  
  28.     close(cfn)
  29.     close(mfn)
  30.  
  31.     if (i <CPUS - 1) {
  32.       printf("^ib(0)^fg()^r(5x0)^ib(1)")
  33.     }
  34.  
  35.   }
  36.   printf("\n");
  37. }

 Remote control with MacBook Pro and Ubuntu

  • October 28th, 2007
  • 5:44 pm

I managed to get the remote control to work with my MacBook Pro and Ubuntu. It should work out of the box according to almost everybody when you google for it, but it just didn't. I know, I said ealier that I didn't know what to use it for, but that doesn't really matter. What matters is that I had a piece of hardware which didn't work, and that's just not good enough.
After digging around a little in lsusb and the module source code, I found out that on the most recent MacBooks, the IR receiver has been assigned a new device id. The original receivers had id 0x8240 while mine has 0x8242. It doesn't look like anything else has changed, and after recompiling the module with the correct device it, it suddenly worked like it should.

Compiling the module isn't exactly for the faint of heart, so I won't describe the details here - let me know if you want it, and I'll post it. However, it does include "apt-get source linux-ubuntu-modules-2.6.22-14-generic".

Also, remember that the appleir module must be loaded before usbhid. To do this on a running system do
"rmmod appleir usbhid; modprobe appleir; modprobe udbhid"
Remember to do it on one line, or you will lose keyboard input after running rmmod.

Other than this, follow this guide to configure the remote control. So far, my .lircrc contains the following, supporting slide change in OOImpress and Amarok:

CODE:
  1. begin
  2.         prog = irxevent
  3.         button = KEY_MENU
  4.         button = KEY_PP
  5.         config = Key space amarokapp
  6.         flags = quit
  7. end
  8. begin
  9.         prog = irxevent
  10.         button = KEY_MENU
  11.         button = KEY_N
  12.         config = Key ctrl-alt-b amarokapp
  13.         flags = quit
  14. end
  15.  
  16. begin
  17.         prog = irxevent
  18.         button = KEY_MENU
  19.         button = KEY_MENU
  20.         config = Key Escape CurrentWindow
  21. end
  22.  
  23.  
  24. begin
  25.         prog = irxevent
  26.         button = KEY_P
  27.         config = Key Page_Up CurrentWindow
  28. end
  29. begin
  30.         prog = irxevent
  31.         button = KEY_N
  32.         config = Key Page_Down CurrentWindow
  33. end

Btw, I've filed a bug with Ubuntu, so hopefully the module will be fixed at some point.

 Suspend success

  • October 27th, 2007
  • 12:37 am

as I wrote about yesterday, I had some problems getting software suspend to work with Ubuntu and my MacBook Pro. Well, it looks like the problem has been solved. As reported here, it looks like there's a bug in the kernel, so downgrading a little should fix it. However, in my case I also had to disable gnome-power-manager - not really an issue. After changing these two things, I've been able to suspend and resume without problems - at least for now.

 My xmonad start script

  • October 25th, 2007
  • 10:54 pm

After reinstalling xmonad on my laptop using Ubuntu as the base distribution, I've finally got a setup I like, so I thought I'd share it. So, here is my script which starts xmonad:

CODE:
  1. ssh-add ~/.ssh/id_dsa </dev/null>/dev/null
  2.  
  3. Esetroot /usr/share/backgrounds/warty-final-ubuntu.png
  4. unclutter -idle 2 &
  5.  
  6. urxvtd -f -o
  7.  
  8. gnome-settings-daemon &
  9. gnome-power-manager
  10. gnome-volume-manager &
  11.  
  12. BG=white
  13. FG=black
  14. FONT="-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1"
  15.  
  16. export PATH=$PATH:`dirname $0`
  17.  
  18. # create a pipe for xmonad to talk to
  19. PIPE=$HOME/.xmonad-status
  20. rm -f $PIPE
  21. mkfifo -m 600 $PIPE
  22. [ -p $PIPE ] || exit
  23.  
  24. # and a workspace status bar, reading's xmonad's stdout
  25. dzen2 -e '' -w 680 -ta l -fg $FG -bg $BG -fn $FONT -h 15 <$PIPE &
  26.  
  27. `dirname $0`/status &
  28.  
  29. xmonad> $PIPE &
  30. wait $!
  31.  
  32. pkill -HUP dzen2
  33.  
  34. wait

This script is launched from ~/.xsession. It uses dzen and some of the dzen gadgets (which must be compiled separately from dzen/gadgets). It also starts some of the Gnome daemons which normally run under Ubuntu. This means that power management and sound volume goes through Gnome, and devices are mounted automatically when they are added to the system.

Two dzens are launched: One for displaying workspaces and one for general status. The general status script looks like this:

CODE:
  1. #!/bin/sh
  2.  
  3. BG=white
  4. FG=black
  5. FONT="-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1"
  6.  
  7. while :; do
  8. MEM=`awk '/MemTotal/ {t=$2}; /MemFree/ {f=$2}; END {print t-f " " t}' \
  9.   /proc/meminfo | dbar -s ':' -l 'Mem:' -w 10`
  10. CF0=$(echo `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq` \
  11.   `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq` | dbar -w 7 -l 'CPU0:')
  12. CF1=$(echo `cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq` \
  13.   `cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq` | dbar -w 7 -l 'CPU1:')
  14. DATE=`date +"%d-%m %k:%M"`
  15.  
  16. REM=`grep 'remaining capacity' /proc/acpi/battery/BAT0/state | awk '{print $3}'`
  17. LAST=`grep 'last full' /proc/acpi/battery/BAT0/info |awk '{print $4}'`
  18. STATE=`awk '{print $2}' /proc/acpi/ac_adapter/ADP1/state`
  19. if [ "$STATE" = "on-line" ]; then
  20.   BAT=$(echo $REM $LAST | awk '{printf "Bat: %.1f%%, AC", ($1/$2)*100'})
  21. else
  22.   PRESENT=`grep 'present rate' /proc/acpi/battery/BAT0/state | awk '{print $3}'`
  23.   BAT=$(echo $REM $LAST $PRESENT | awk '{printf "Bat: %.1f%%, %d min", ($1/$2)*100, ($1/$3)*60}')
  24. fi
  25.  
  26. LOAD=`awk '{print $1 " " $2 " " $3}' /proc/loadavg`
  27.  
  28. echo "$CF0 $CF1 $MEM | $DATE | $BAT | $LOAD"
  29. sleep 5
  30. done | dzen2 -e '' -x 440 -w 1000 -fg $FG -bg $BG -fn $FONT -h 15

The script is made for a MacBook Pro with a two core processor and acpi. It displays the CPU frequencies in a dbar, memory usage, battery status, and load. I would like to display network status too, but I can't figure out how to dig around in dbus efficiently, so that's still missing.