Thursday, July 24, 2008

Experiencing Stumpwm

What Emacs is to editors, Stumpwm is to window managers.
--Bill Clementson (link)

Introduction

Recently I switched from GNOME to Stumpwm (wiki), which means that I jumped out of a desktop environment to a simple window manager. So far, I'm very satisfied with such a change and never looked back. Stumpwm, as its website says, is a tiling, keyboard driven X11 Window Manager written entirely in Common Lisp. This definition summarizes the reasons why Stumpwm is so suitable for me.

First, Stumpwm is a tiling, keyboard driven window manager. This is very useful to boost productivity. When working, it is desirable to minimize context switching. Tilting combined with keyboard driven enables working with several applications simultaneously as if your are dealing with one single program. Let me give an example. As described in previous post, with Emacs as development environment, it is easy to fire up one browser within Emacs itself to preview blog post. However it is painful to switch between Emacs and browser. Before using Stumpwm, I am considering ways to integrate Emacs and Firefox together. With Stumpwm, such dream is just trivial to fulfill: one can show Emacs and browser side by side, with a few keystrokes to switch between them. Everytime you make changes in Emacs and request the results to be shown in Firefox, they are shown simultaneously. No more need to leave your hand for mouse to click back and forth between Emacs and Firefox. This gives you the feeling of integrated environment. Note that I just use Emacs and Firefox as an example, and such convenience is applicable for every application. Currently, the problem is that I'm so accustomed to Stumpwm keystrokes that I somehow confused the keystrokes of switching between windows in Stumpwm and Emacs!

Second, Stumpwm is written in Common Lisp. which means that you can build Stumpwm with your favorite CL implementation and you have a Lisp runtime when you work under Stumpwm. A powerful programming language is just embedded within your window manager and you can invoke it at any time. The other benefit is that you can configure your window manager as you like, even when it is running!

You may get a feeling on how Stumpwm works by watching this nice video.

Installation

Given the above lengthy introduction of Stumpwm, you may wonder how to install this gem. Here we assume that you have some knowledge about Common Lisp. Basically, installing Stumpwm is to compile it with your preferred CL implementation, and tell your system to run Stumpwm as your window manager.

Installing Stumpwm on Gentoo Linux is straightforward. Throughout this section, we will assume that SBCL is the CL implementation. Stumpwm website suggests turn off threading support in SBCL (disable USE flag threads) for better performance. To install, simply type emerge stumpwm. Note that at the time of writing, there is also an ebuild called stumpwm-cvs. Simply ignore it since it is actually a very old version, not the bleeding edge version suggested by its name. Advanced users might consider to get git version for latest cool features.

There are mainly two ways to invoke Stumpwm. One is to run it by calling SBCL, the other is to dump a core image containing Stumpwm within SBCL and invoke that image. We will take the latter approach. To proceed, first start SBCL by typing sbcl. Next issue the following in REPL sequentially:

(asdf:oos 'asdf:load-op :stumpwm)
(sb-ext:save-lisp-and-die "stumpwm" :executable t
                          :toplevel #'(lambda () (stumpwm:stumpwm ":0")))

Next, put the generated executable stumpwm somewhere in PATH (I put it under /usr/local/bin). Since I always start X Window by typing startx, following command is used to use Stumpwm as my window manager:

$ echo "exec stumpwm" >> ~/.xinitrc

Using Stumpwm

Configuration

All stumpwm configurations are stored in file ~/.stumpwmrc, which is written in Common Lisp. Just like .emacs, this file allows you to fully customize Stumpwm. Following is my current configuration:

;;;; -*- Mode: Lisp -*-

(in-package :stumpwm)

;; Load swank.
(load "/usr/share/emacs/site-lisp/slime/swank-loader.lisp")
(swank-loader:init)
(define-stumpwm-command "swank" ()
  (setf stumpwm:*top-level-error-action* :break)
  (swank:create-server :port 4005
                       :style swank:*communication-style*
                       :dont-close t)
  (echo-string (current-screen) "Starting swank."))
(define-key *root-map* (kbd "C-s") "swank")       

;; Customize bars and modeline.
(setf *message-window-gravity* :center)
(setf *input-window-gravity* :center)
;; Turn on mode line.
(toggle-mode-line (current-screen) (current-head))
(setf *screen-mode-line-format* 
      (list "%w | "
            '(:eval (run-shell-command "date | tr -d '[:cntrl:]'" t))))

(set-prefix-key (kbd "C-i"))
(define-key *root-map* (kbd "c") 
  "exec urxvt +sb -fn \"xft:Bitstream Vera Sans Mono:pixelsize=20\"")

(define-stumpwm-command "firefox" ()
  "Run or switch to firefox."
  (run-or-raise "firefox" '(:class "Firefox")))
(define-key *root-map* (kbd "f") "firefox")

Some explanations of my configuration:

  • Prefix key: I use C-i instead of default C-t. The reason is that C-t is used in Firefox to open a new tab and also in Emacs for transpose. Then why choose C-i? I'd like to admit that it is quite difficult to select a prefix key for Emacs user. Before settle down on C-i, I fired up Emacs to see whether there is any key binding C-x where x from a to z is not used by Emacs. Unfortunately (fortunately?), Emacs binds every combination. So I can only choose one prefix key which is easy to type and I uses infrequently in Emacs. Then C-i is selected. Note that you can send C-i to application like Emacs by typing C-i i. For the following sections, please replace C-i with your favorite prefix key.
  • SLIME: the section staring with comments Load swank provides ways to load swank. Type C-i C-s to start swank. To connect to swank, simply run Emacs, and type slime-connect within Emacs, and type RET and RET to accept default host (127.0.0.1) and default port (4005). Then you can play with Stumpwm as you wish: change parameters, add your own functions etc. Note that I do not start swank automatically for security reasons.
  • Key bindings: I use C-i c to start console: urxvt instead of xterm. Note that I have also set the font for urxvt. In addition I have setup using C-i f to start Firefox in case Firefox is not started, or bring Firefox window to front if it is already running.

Key Bindings

Following is a list of key bindings I used frequently. For simplicity, I have omitted the prefix key.

  • ?: Stumpwm help
  • ;: Run Stumpwm commands
  • :: Send commands to Common Lisp interpreter.
  • Space: Go to next window
  • c: Run X terminal
  • e: Run Emacs or raise it if it is already running
  • f: Run Firefox or raise it if it is already running
  • k: Kill current window
  • g c: Create a new group
  • g k: Kill current group
  • g m: Move current window to a specified group
  • g Space: Next group
  • o: Focus shifts to next frame
  • Q: Remove all splits
  • s: Vertical split
  • S: Horizontal split

Wednesday, May 21, 2008

Using PulseAudio for OSS Applications

In my previous post, I discussed how to use PulseAudio to enable sound for coLinux. This works fine for programs like MPlayer, but has issues with some programs e.g. Solfege.

The solution is simple: if the problematic applications have support for OSS, then emerge them with OSS USE flag on. In addition, PulseAudio should also be emerged with OSS USE flag (to enable the building of padsp, a PulseAudio OSS wrapper, which will be discussed below). Under Gentoo Linux, one way is to simply add OSS USE flag to /etc/make.conf. Alternative way is to enable the USE flag application by application. For example, to enable OSS USE flag for Solfege, type the following:

# echo "media-sound/solfege oss" >> /etc/portage/package.use

When running these applications, prefix the command line with padsp like the following:

$ padsp solfege

Note that you may need additional configurations in the application to use OSS for audio output.

Monday, May 5, 2008

HV30: Camcorder and Accessories

I just bought Canon HV30 (Amazon, Review) recently for my baby. Before buying HV30, I was agonizing over the selection between HV30 and Canon HF10 (Amazon, Review) (although I know that HF100 is better than HF10 from money point of view since the internal 16GB flash drive of HF10 does not justify the price difference, I do like the black paint job of HF10 and HV30).

Comparison of HV30 vs. HF10

So why I chose HV30 over HF10? The following is my comparison.

FeaturesHV30HF10Comments
Price MSRP price is $999 in US and ¥10580.00 (about $1514) in China MSRP price is $1099 in US and ¥14080.00 (about $2014) in China The price difference in China is quite significant, which is true even for street price.
Performance 1/2.7 in. sensor 1/3.2 in. sensor According to the review, HV30 has slightly better performance over HF10 thanks to larger sensor, however the gain seems to be marginal for most cases.
Functionalities Viewfinder, Zebra, Peaking
Accessories Standard accessory shoe Canon proprietary accessory shoe
Backup Tapes are cheap for backup Additional backup is needed since SDHC cards are expensive and will be reused.
Community A mature community (looking at hv20.com for example) Situation will improve
Form Factor 88x82x138 mm (3.5x3.2x5.4 in.), 535 g (1.2 lb.) 73x64x129 mm (2.9x2.5x5.1 in.), 380 g (13.4 oz) HF10 is small and light, which is ideal for traveling. Normally the camcorder which you takes out often is the most useful one.
Media Tape SDHC card + internal Flash Flash card is really convenient: just like small DCs. No hassles for rewinding and no worry for overriding.
Zoom 10x optical zoom 12x optical zoom
Noise Tape noise can be heard in silent environment No such noise since flash card is used.

Accessories

What I have:

  • Battery and charger: compatible ones
  • Camera bag: Lowepro Edit 120+
  • CPL filter: Kenko 43mm
  • HDMI cable
  • IEEE 1394 cable: Belkin 4-pin to 4-pin
  • Lens cap
  • miniSD: Transcend 2G. Not sure whether 4G could be used (the manual only states that up to 2G has been tested).
  • Tape: Panasonic AY-DVM63PQ
  • UV filter: Kenko MC-UV 43mm

For future purchase:

  • 35mm adapter
  • Close-up lens: +1/+2/+4
  • Mic: Canon DM-50, or combination of Rode Videomic and stereo mic. Maybe XLR adapters with XLR Mics?
  • Neutral density filters: ND2/4/8
  • Shoulder strap
  • Steadicam Merlin
  • Telephoto lens: Canon TL-H43 (any black version?)
  • Tripod and fluid head: Manfrotto 190XPROB (tripod) + 701RC2 (fluid head) + MBAG70 (bag)
  • Video light: Canon VL-3
  • Wide angle lens: Canon WD-H43 (any black version?)
  • Wrist strap

Final Words

After over 1 month's usage of HV30, I'm pretty satisfied with it. There is a lot of things for me to learn: how to shoot, how to edit, just to name a few. But all the efforts are worthy when you view the video clips produced from it.

Friday, May 2, 2008

Automatic Backup

We need to backup our stuff in case that some disasters might happen. One way is to backup to some external medias like tape, USB drives, or CD/DVDs. However working with them is somehow tedious and manual intervention is needed. People tend to be lazy therefore we are reluctant to backup if the process is inconvenient. If we have one additional machine with link in between (throughout this article, we assume the remote machine is named as remotebox), we can setup an automatic backup mechanism.

Overview

We use crontab to schedule rsync jobs to backup our files to another machine. Since rsync is secured with SSH, to suppress the password prompt, we have to setup SSH keychain.

Setup SSH Keychain

Generate Keys

This section mainly follows this nice guide.

We use the DSA approach.

$ ssh-keygen -t dsa
$ scp ~/.ssh/id_dsa.pub user@remotebox

Then log in to remotebox and append the public key to ~/.ssh/authorized_keys file like so:

cat id_dsa.pub >> ~/.ssh/authorized_keys
rm id_dsa.pub

Install Keychain

Keychain is a nice package which prompt you for your passphrase once you log into the system, and automatically provides passwords for later SSH session. Note this incurs security risks (there are always tradeoffs between security and convenience) therefore attention is needed.

This part mainly follows this guide.

First install keychain by typing emerge keychain.

Then add following lines to your ~/.bash_profile.

/keychain id_dsa
. ~/.keychain/$HOSTNAME-sh

Setup Crontab Job

We can then setup our automatic backup system now. Since there are almost infinite number of combinations of crontab and rsync patterns, I just shown one example below (many interesting examples of rsync usage can be found by typing man rsync).

0 9,16 * * 1-5 rsync -az -e ssh --delete ~/work/ remotebox:~/backup/

The above example synchronizes local directory ~/work to remote directory ~/backup on host remotebox, on 9 a.m. and 4 p.m. of every working day. Note that I have used option --delete, which will try to delete extraneous files from destination directory. This can ensure that the destination directory is an exact copy of source directory but it would be dangerous if the destination directory contains some files already. So test this option before you actually use it.

Switching Browsers in Emacs

Recently, I have met one dilemma in Emacs. Since I'm using Emacs for my blog writing, Firefox is used for previewing. Also as an Common Lisp user, I use emacs-w3m to read HyperSpec. Here comes the problem: I can only set one browser for browse-url-browser-function. How can I suit my requirements simultaneously?

Fortunately, Emacs is highly extensible. I just write one simple interactive function toggle-browser, which can toggle between Firefox and emacs-w3m when pressing M-x toggle-browser. Following is the code:

(defun toggle-browser ()
  "Toggle browser between Firefox and emacs-w3m."
  (interactive)
  (setq browse-url-browser-function 
        (if (eql browse-url-browser-function 'browse-url-firefox)
            'w3m-browse-url
          'browse-url-firefox))
  (message "%s" browse-url-browser-function))

Update: please look at the 1st comment from pedro for a better solution.