How to switch off a screen laptop under Linux

In this post, I describe how to write a shell script that switches off a laptop screen. The instructions are tested with Ubuntu Linux 5.10 (Breezy) on a Dell Latitude C810.

First, set the governor for the CPU frequency with the following command.

echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

This command can be run automatically at run-level 2 by putting it in /etc/rc2.d/S30freq-scaling.

Out of the box Breezy is configured to manage power, but we need additional configuration for some laptops.

First, on the C810 the kernel needs the acpi_irq_balance option in order to report certain ACPI events (for example, closing the lid). We fix this by adding the kernel option acpi_irq_balance in GRUB’s menu.lst.

title           Ubuntu, kernel 2.6.12-9-686 
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.12-9-686 root=/dev/hda1 acpi_irq_balance ro quiet splash resume=/dev/hda5
initrd          /boot/initrd.img-2.6.12-9-686
savedefault
boot

Second, it seems that the command xset dpms force off does not switch off the screen. Instead, we must use the command vbetool to do this. Although it is reported to cause unexpected behaviour, it works with the C810.

After configuring the kernel as describe above, we can write the script /etc/acpi/screen.sh to turn on and to turn off the laptop screen.

#!/bin/sh

case "$1" in
        on)
                /usr/sbin/vbetool dpms on
                ;;
        off)
                /usr/sbin/vbetool dpms off
                ;;
        *)
                N=/etc/acpi/screen.sh
                echo "Usage: $N {on|off}"
                ;;

esac

The script takes as argument on or off, as in the example below.

/etc/acpi/screen.sh off

Rapid web development

Lately, I have been experimenting with a technique to accelerate web application development in Java. It does without custom servlets and relies on Java Server Pages (JSP).

Here is how it is implemented.

First, define an interface called Controller. Declare a method called handleRequest that takes as arguments an HttpServletRequest and an HttpServletResponse. The method must throw an Exception.

package web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Controller {

    public void handleRequest(HttpServletRequest request, 
            HttpServletResponse response) throws Exception;
}

Next, create a hierarchy of directories and JSP files. The structure must follow the logical organisation of the application. For example, assuming we are writing a page for users to register new accounts, we create the following files in a directory called /user/register.

  •  index.jsp — the entry point for our controller
  • default.jsp — the default view
  • success.jsp — the view for a successful registration

Next, in file index.jsp, write the following code.

<% web.Controller c = new web.Controller() {

    public void handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        account = null;

        messages = new java.util.ArrayList();

        username = request.getParameter(username);
        password1 = request.getParameter(password1);
        password2 = request.getParameter(password2);
        email = request.getParameter(email);

        if (request.getParameter(register) != null) {
            registerActionPerformed(request, response);
        }

        request.setAttribute(messages, messages);

        request.setAttribute(username, username);
        request.setAttribute(email, email);

        if (account != null) {
            request.getRequestDispatcher(success.jsp).
                    forward(request, response);
        } else {
            request.getRequestDispatcher(default.jsp).
                    forward(request, response);
        }
    }

    protected void registerActionPerformed(HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        if (validate()) {
            model.user.Account existing = model.user.AccountRepository.
                    getByUsername(username);
            if (existing != null)
                messages.add(error.duplicate_username);

            existing = model.user.AccountRepository.getByEmail(email);
            if (existing != null)
                messages.add(error.duplicate_email);

            if (messages.isEmpty()) {
                model.user.RegisterAccountService service = 
                        new model.user.RegisterAccountService();
                account = service.register(username, password1, email);
            }
        }
    }

    protected boolean validate() throws Exception {
        if (username == null || username.trim().length() == 0)
            messages.add(error.username_missing);

        if (password1 == null || password1.trim().length() == 0)
            messages.add(error.password_missing);

        if (password1 != null)
            if (!password1.equals(password2))
                messages.add(error.password_mismatch);

        if (email == null || email.trim().length() == 0)
            messages.add(error.email_missing);

        return messages.isEmpty();
    }

    private model.user.Account account;

    private java.util.ArrayList messages;

    private String username;
    private String password1, password2;
    private String email;
};

c.handleRequest(request, response);
%>

Next, create files default.jsp and success.jsp. File default.jsp could look like this:

< %@page contentType=text/html%>
< %@page pageEncoding=UTF-8%>
< %@taglib uri=http://java.sun.com/jsp/jstl/core prefix=c%> 
< %@taglib uri=http://java.sun.com/jsp/jstl/fmt prefix=fmt%> 

< !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN
   http://www.w3.org/TR/html4/loose.dtd>

<html>
    <body>
        <h1><fmt:message key=title.register_account /></h1>
    </body>
</html>

So far this approach has shown the following benefits.

  • index.jsp becomes a controller.
  • Because JSP are compiled automatically, I avoid manual compilation.
  • I don’t have to map individual JSP files, as I do with servlets.
  • URLs are consistent.

This technique is unsuitable for large projects but is good enough for writing quick web application projects.

How to handle spam efficiently

Opening messages to decide whether they must be read or be discarded works well with low volumes of email. However, with ever increasing messages and more sophisticated spam techniques, this filtering method becomes unsustainable.

Spam filters based on statistics and heuristics are useful to cut down the number of unnecessary messages that we have to open and read, but they still need us to check for false-positives—mail that have been incorrectly identified as spam. We need a better technique.

Typically, messages from known contacts and with familiar subject lines are likely genuine; in contrast, messages from strangers and with suspicious subject lines are rarely read. Based on this observation, we can set up  our email client to segregate messages in two categories, as follows.

  • Create folders for known correspondents and subjects.
  • Create filter rules to move desirable messages to the new folders. Leave the rest in the inbox.
  • When reading email, read the messages that have been moved to specific folders first; you can read messages in the inbox later, as they are considered to be less important.

For this method to work, we must continually create rules as we increase our contacts and the subjects that are of interest.

Better Software Faster

I rediscovered the website for the book Better Software Faster. Bizarrely, although very good, this book is hardly ever referenced. Describing similar modelling techniques as but written much earlier than Domain-Driven Design, it can be considered as the latter’s precursor. Unlike DDD, however, it includes practical examples and source code, which make the techniques more comprehensible.

Domain-Driven Design, the quest for software perfection

I have been reading Domain-Driven Design by Eric Evans since last August. Although the topic is interesting, it has been difficult to read the book—at least for me.

Eric explains domain models in great detail but provides few practical examples. As a developer, I am primarily interested in implementation. So, I have to pause frequently in order to translate his ideas into code. Eventually I had to accept the fact that DDD is only guidance for modelling and that implementation decisions are left to the programmer. This realisation made the book more enjoyable.

Considering software development as an engineering discipline, we tend to be rigid in how we write programs. We think that technical problems can be solved by science and maths alone. But coding is also a creative activity. And we can say that in this art, DDD is both style and inspiration.

Copy/paste command-line utilities

Inspired by the programs pbcopy and pbpaste in Mac OS X, I created similar utilities in Windows.

.NET Framework 1.1 is required for these programs to work.

clipin.cs
using System;
using System.IO;
using System.Windows.Forms;

public class ClipboardCopy
{
    public static void Main(string[] args)
    {
        string input = Console.In.ReadToEnd();

        Clipboard.SetDataObject(input, true);

        Console.WriteLine("Text copied to clipboard.");
    }
}
clipout.cs
using System;
using System.IO;
using System.Windows.Forms;

public class ClipboardPaste 
{
    public static void Main(string[] args)
    {
        IDataObject data = Clipboard.GetDataObject();

        if (data.GetDataPresent(DataFormats.Text) )
        {
            Console.Out.WriteLine("n" + data.GetData(DataFormats.Text)) ;
        }
    }
}
Usage: C:\<command> | clipin.exe 

Usage: C:\clipout.exe | <command>