Setting up my JVC XP 731

If you'd be interested in joining a mailing list on running linux on JVC's subnotebooks, do drop me a line -- I'd set up one once I've got, say, five people asking.

The JVC being such a fine machine, I'm looking for spare parts and complete systems (if mine breaks down, I want minimal downtime :-). So, if you want to sell yours, make an offer (email below).

Installing Linux on the JVC XP 731 (a.k.a. Asus S200 N) is not a big deal -- it's a fairly standard Centrino machine. The only thing that may cause you headache is the installation medium. If you don't have a USB cdrom, I recommend netbooting the beast. You can access the setup menu by pressing Alt-F2 while the machine shows its BIOS screen (by default, it's some flashy picture, though there is a BIOS setting that gives you a more informative output). You'll find more info on the basic setup on the corresponding pages on TuxMobil.

However, as usual, power management and video issues remain. On this page, I'll tell you what I did. Most of it should be fairly distribution-neutral, but some points will need adaption. I'm running Debian Etch on my box, with a self-built 2.6.27.4 kernel (kernel .config). I don't see why a fairly recent distribution kernel shouldn't work.

Though hotplug/udev do save you quite a bit of hardware detection hassles, I've found it convenient to help it at boot time by having an /etc/modules (in Debian -- other distributions may use different files) with:

# /etc/modules: kernel modules to load at boot time.
#
# This file should contain the names of kernel modules that are
# to be loaded at boot time, one per line.  Comments begin with
# a "#", and everything on the line after them are ignored.

psmouse
pcspkr
e100
rtc
snd_intel8x0
snd_mixer_oss
snd_pcm_oss
asus_laptop
fuse
acpi_cpufreq

File: /etc/modules

Version Warning: Starting with kernel 2.6.18 and continuing up to about 2.6.19.1, there's an issue with the acpi thermal module and the jvc causing the machine to freeze when resuming from suspend to RAM. Either make sure you unload the thermal module (probably just adding it to critical_modules below would do) or comment out the call to acpi_thermal_check(tz) in .../drivers/acpi/thermal.c, function acpi_thermal_resume (that's line 1418 in 2.6.19.1). More recent kernels are ok.

Version Warning: With 2.6.25.x kernels, the machine has trouble waking up reliably in certain kernel configs. I haven't investigated the issue properly but believe it's related to the high precision timer and/or tickless system options. I'd suggest you leave them out unless you're willing to do some digging.

ACPI -- sleep, wake up, hotkey

Hotkeys

To make ACPI work, you must have acpid installed. It is usually configured in a bunch of files in /etc/acpid. Your distribution may already have populated that directory. Unless you understand what these guys have been doing, I advise you move that cruft out and give it a fresh start.

Let's first get the hotkeys working. They are handled by the asus_acpi module. Once you have it inserted in your kernel, acpid receives the relevant events. You just need to tell it what to do with them. Creating /etc/acpi/events/hotkeys and putting

event=hotkey.*
action=/etc/acpi/hotkey.sh %e

File: /etc/acpi/events/hotkeys

in there (the syntax for the files in .../event is a bit Debian-specific, so man acpid) tells it to call /etc/acpi/hotkey.sh for each event starting with "hotkey". Some sort of keycode is passed to that script as its third argument. Thus, for the XP 731, hotkey.sh could look like this:

#!/bin/sh
case "$3" in
	0000006c)  # Sleep button
		/etc/acpi/doze.sh
		;;
	0000006d)  # Suspend to disk button
		/etc/acpi/sleep.sh
		;;
	00000031)  # decrease volume
		amixer set Master 5%-
		;;
	00000030)  # increase volume
		amixer set Master 5%+
		;;
	00000032)  # mute
		amixer set Master toggle
		;;
	00000035)  # the key with the screen
		if [ -f /var/run/video_off ]
		then
			vbetool dpms on
			rm -f /var/run/video_off
		else
			vbetool dpms off
			touch /var/run/video_off
		fi
		;;
	*)
#		logger "$0: Unknown hotkey: $@"
		;;
esac

File: /etc/acpi/hotkey.sh

I'll give my doze.sh and sleep.sh scripts below. The rest assumes you're running ALSA (you should) and that you have vbetools installed (you should as well, otherwise suspend to ram won't work).

What this does is let the volume keys work as advertised. Also, the silly key supposed to switch internal lcd and external crt is used to toggle power to the internal screen. Unfortunately, the ACPI bios has some function on that key already. This causes the screen to turn on an off several times and also gives video ACPI events. I'll check the DSDT some day -- maybe this can be turned off.

If you need the key to toggle the video signal for the external video port, you could look into i855crt and run that instead of vbetool. I, however, do that differently (see below).

Software Suspend

We want two ways of sleeping: Suspend to RAM and suspend to disk. Suspend to RAM is far more difficult, so let's look at suspend to disk first. The hotkeys above expect the script in /etc/acpi/sleep.sh:

#!/bin/bash

. /etc/acpi/utils.sh
if [ -z "$stateDir" ]
then
	logger "$0: utils.sh could not be sourced"
	exit 1
fi

getLoadedCriticalModules
unloadCriticalModules

logger "$0: Putting machine in software suspend"
cp /boot/grub/menu.lst.resume /boot/grub/menu.lst

sync; sync

echo shutdown > /sys/power/disk
echo disk > /sys/power/state

logger "$0: Coming back from software suspend"

# Waking up, make sure we don't resume if we crash or reboot
cp /boot/grub/menu.lst.noresume /boot/grub/menu.lst

reloadCriticalModules

File: /etc/acpi/sleep.sh

with the following /etc/acpi/utils.sh:

# This script defines a few functions useful for all things acpi-related


criticalModules="ohci1394 ehci_hcd uhci_hcd video battery"
stateDir=/var/run/sleep
sleepLockFile=$stateDir/lock
lastWakeupFile=$stateDir/lastWakeup


dieNoSuspend() {
	reloadCriticalModules
	if [ -f /etc/acpi/nosleep.wav ]
	then
		amixer set Master 100
		amixer set PCM 100
		sox /etc/acpi/nosleep.wav -t ossdsp /dev/dsp &
	fi
	logger "$0: Won't suspend: $*"
	exit 1
}

reloadCriticalModules() {
# This only works if unloadCriticalModules has been called before.
	for modName in $unloadedModules
	do
		modprobe $modName
	done
}

unloadCriticalModules() {
# You need to call getLoadedCriticalModules first, it sets the global
# loadedCriticalModules
	modStatus="ok"
	unloadedModules=""
	for modName in $loadedCriticalModules
	do
		rmmod $modName || modStatus="fail"
		unloadedModules=`echo $unloadedModules $modName`
	done
	# first attempt may have failed because someone was looking at
	# some bad file for an instant, try again once
	if [ $modStatus == "fail" ]
	then
		logger "$1: Unload modules failed, retrying once."
		reloadCriticalModules
		for modName in $loadedCriticalModules
		do
			rmmod $modName  2> /var/run/sleep/rmmod.prot || dieNoSuspend "$modName in use:" `cat /var/run/sleep/rmmod.prot`
			unloadedModules=`echo $unloadedModules $modName`
		done
	fi
}


filterLoadedModules() {
	for modname in $*
	do
		lsmod | grep "^$modname " | awk '{print $1}'
	done 
}

getLoadedCriticalModules() {
	loadedCriticalModules=`filterLoadedModules $criticalModules`
}


dieIfSleepLocked() {
	if lockfile -! -r 0 $sleepLockFile
	then
		logger "$0: Sleep processing in progress, ignoring request"
		exit 1
	fi
	trap unlockSleep EXIT
}


unlockSleep() {
	rm -f $sleepLockFile
}

File: /etc/acpi/utils.sh

The functions in utils use crude locking to keep multiple instances of sleep scripts from running. I believe acpid serializes event handlers anyway, so this kind of locking may not be necessary, but I wouldn't bet. Make sure /var/run/sleep exists and is only writable by root.

There are also functions to identify which modules out of a predefined set are loaded, to remove them, and to reload removed modules. These exchange information through global variables. Yikes. Feel free to amend the list of critical modules or take some out. You shouldn't remove the usb modules from this list, though. Under certain circumstances they'll go mad on wakeup, enticing the kernel to disable all kinds of interrupts. This then basically kills most of the PCI I/O the machine does (e.g., network).

The script will refuse to suspend if any of the modules cannot be removed (e.g., because you've still mounted a file system from a usb disk). So, always check that the machine is really sleeping before you put it into bags or tight spaces with insufficient ventilation. You can drop a wav file named nosleep.wav into /etc/acpi. It will be played at full volume if the machine can't sleep, which may help warn you.

The sleep.sh itself uses the Linux software suspend rather than the ACPI one -- it's much less hassle and about as fast. Just compile support for that into your kernel. Software suspend works by writing out the RAM to a swap partition before turning the box off and then passing a kernel option when booting. The kernel option tells the machine to restore the RAM from the swap partition.

Though, as far as I know, the machine will not attempt resumption unless it sees the proper signature on the swap partition, I like to play it safe and keep two copies of grub's menu.lst around, one for resuming (which is activated by the first cp) and one for normal rebooting (which is activated by the second cp).

If you roll your own kernel, bypassing the debian kernel build system (which I don't recommend but practise myself), you could have (in addition to whatever global settings you need)

title		Debian GNU/Linux, default kernel no resume
root		(hd0,0)
kernel		/vmlinux root=/dev/hda1 ro noresume
savedefault
boot

in /boot/grub/menu.lst.noresume and accordingly

title		Debian GNU/Linux, default kernel resuming
root		(hd0,0)
kernel		/vmlinuz root=/dev/hda1 ro resume=/dev/hda5 
savedefault
boot

in /boot/grub/menu.lst.resume. Of course, you must adapt the values of root and resume, with the latter pointing to your swap partition. There are probably better ways to do this -- in particular, doing this immediately locks you out of any kernel management your distribution might do.

Suspend to RAM

While software suspend needs very little of the built-in ACPI machinery, suspend to RAM critically depends on it. Unfortunately, there's much that can and will go wrong in the cooperation between ACPI and the kernel, there are oodles of possible race conditions and deadlocks and other nasty software monsters.

In other words: it's quite possible that your machine may freeze on wakeup. Have a pin or paper clip ready for the hardware reset button on the XP's left side. Having said that: If you don't try crazy stunts, suspend to RAM should work nicely, and you have your machine up and down within a couple of seconds. I'm regularly seeing hundreds of suspend/resume cycles without a glitch. Just don't touch anything and, more importantly, don't plug anything in while the machine is waking up.

The main problem with Linux and ACPI usually is Video (see Documentation/power/video.txt in your kernel tree). vbetool lets you get around this to some extent (also, kernels newer than 2.6.25 supposedly do much better here, but I haven't found time to experiment here as yet). So, here's my /etc/acpi/doze.sh:

#!/bin/bash

VIDEOHACK=true

criticalModules="ohci1394 ehci_hcd uhci_hcd video pcmcia battery"
# ignore suspend requests for this many seconds after wakeup.
deadtime=5 

. /etc/acpi/utils.sh
if [ -z "$stateDir" ]
then
	logger "$0: utils.sh could not be sourced"
	exit 1
fi

if test -f $lastWakeupFile && 
   test $((`date +"%s"` - `date -r $lastWakeupFile +"%s"`)) -lt $deadtime
then
   logger "$0: suppressing suspend request (deadtime not over)"
	 exit 1
fi

dieIfSleepLocked

logger "$0: Putting machine in memory suspend"
cp /boot/grub/menu.lst.noresume /boot/grub/menu.lst

getLoadedCriticalModules
unloadCriticalModules

if [ t$VIDEOHACK != tfalse ]; then
	chvt 1
	vbetool vbestate save > $stateDir/vbe_saved
fi

sync; sync

echo -n mem > /sys/power/state

logger "$0: Waking up from memory suspend"

touch $lastWakeupFile

if [ t$VIDEOHACK != tfalse ]; then
	vbetool post
	vbetool vbestate restore < $stateDir/vbe_saved
	chvt 7
fi

reloadCriticalModules


# A little expeimental gimmick: Dump a file wakeup.wav into /etc/acpi,
# have sox and oss (emulation), and the thing should play the sound
# on wakeup
if [ -f /etc/acpi/wakeup.wav ]
then
	sox /etc/acpi/wakeup.wav -t ossdsp /dev/dsp &
fi

File: /etc/acpi/doze.sh

Basically, I do the same module magic as for software suspend. In addition, I switch to a text screen (otherwise Xorg notices we've been sleeping, doesn't really know what to do and gets horribly confused), save the video bios state and sleep. After waking up, I run the POST of the video chip (which takes surprisingly little time) and then restore the state saved when going to sleep. Finally, I switch back to the X screen. If you're not always in X, you may want to change things here.

As I said, the thing is a bit sensitive to fiddling with the machine while it's waking up. I believe there are problems that can only be fixed in the DSDT. If I find some more time, I'll look into this. For now, just make sure you've written out all important data before putting the machine to sleep and relax until the machine is up.

To let the machine sleep when you close the lid, add /etc/acpi/events/lid with the contents

event=button/lid.*
action=/etc/acpi/lid.sh

File: /etc/acpi/events/lid

and then say something like

#!/bin/bash

. /etc/acpi/utils.sh
if [ -z "$stateDir" ]
then
  looger "$0: utils.sh could not be sourced"
  exit 1
fi

if [ ! -f $sleepLockFile ]
then
  /etc/acpi/doze.sh
else
  logger "$0: Lid event while sleep in progress -- ignoring."
fi

File: /etc/acpi/lid.sh

in /etc/acpi/lid.sh. With kernels starting with 2.6.20, you need the primitive state mangagement built in above -- there is a deadtime in which requests to put the machine to sleep are ignored. Otherwise, the lid event generated by opening the box would put your machine to sleep again, and that's not so nice:-).

You could also bind the software suspend to the power button in an analogous fashion.

Note: For reasons I haven't investigated, suspend to RAM and software suspend don't mix very well right now (i.e., kernel 2.6.2x); when woken up from a suspend to RAM after having resumed a software suspend, the machine sometimes or always locks. If anyone feels like gathering data here, be my guest. It's not likely that I'll do research here since I only rarely suspend to disk.

Video

I use my machine in all kinds of setups -- giving demos with a beamer, having an external screen connected, using the machine to run X clients, running stellarium to have a pocket planetarium, whatever. Also, my default X server doesn't do 3D (partly because that wouldn't survive a suspend in the olden days, partly because I suspect it makes the video chip draw more power). Depending on what the machine is supposed to be doing, I have a couple of scripts setting up the environment. Since I'm using sawfish as my window manager, running a startx is quite cheap. If you insist on heavyweight environments, the following might not be for you.

The way this works is that I have a simple /etc/X11/xorg-internal.conf like this:

# xorg.conf (Xorg X Window System server configuration file)
# This is MD's default configuration.  It runs without GL acceleration.
# If you're not crazy like me, you probably want to comment in and
# adapt the Xkb stuff.

Section "Files"
  FontPath  "unix/:7100"      # local font server
  # if the local font server has problems, we can fall back on these
  FontPath  "/usr/share/fonts/X11/misc"
  FontPath  "/usr/share/fonts/X11/cyrillic"
  FontPath  "/usr/share/fonts/X11/100dpi/:unscaled"
  FontPath  "/usr/share/fonts/X11/75dpi/:unscaled"
  FontPath  "/usr/share/fonts/X11/Type1"
  FontPath  "/usr/share/fonts/X11/CID"
  FontPath  "/usr/share/fonts/X11/100dpi"
  FontPath  "/usr/share/fonts/X11/75dpi"
  FontPath  "/usr/share/fonts/X11/local"
EndSection

Section "Module"
#  Load  "GLcore"   # Right!
  Load  "bitmap"
  Load  "dbe"
  Load  "ddc"
#  Load  "dri"
  Load  "extmod"
  Load  "freetype"
#  Load  "glx"      # don't want no stinkin' GL here.
  Load  "int10"
  Load  "record"
  Load  "speedo"
  Load  "type1"
  Load  "vbe"
  Load  "evdev"
EndSection

Section "ServerFlags"
  Option "DefaultServerLayout" "Default Layout"
  Option "AllowMouseOpenFail"
  Option "RandR" "on"
  Option "DontVTSwitch" "off"
  Option "DontZap" "off"
  Option "HandleSpecialKeys" "always"
  Option "XkbDisable" "true"         # You probably want to change this
EndSection

Section "InputDevice"
  Identifier  "Generic Keyboard"
  Driver    "keyboard"
  Option    "CoreKeyboard"
#  Option    "XkbRules"  "xorg"       # and this, too
#  Option    "XkbModel"  "pc104"
#  Option    "XkbLayout"  "us"
#  Option    "XkbOptions"  "nodeadkeys"
EndSection

Section "InputDevice"    
# This will work for the built-in stick as well as for usb mice
# with wheels you could plug in.
  Identifier  "Configured Mouse"
  Driver    "mouse"
  Option    "CorePointer"
  Option    "Device"    "/dev/input/mice"
  Option    "Protocol"    "ImPS/2"
  Option    "ZAxisMapping"    "4 5"
EndSection

Section "Device"
  Identifier  "i-LCD"
  Driver      "i810"
  Option      "VBERestore" "on"
  Option      "DRI" "off"
  Option      "MonitorLayout" "CRT,LFP"
  VideoRAM    65536
EndSection

Section "Monitor"
  Identifier  "LCD"
  Option    "DPMS"
  Option    "StandbyTime" "1"
  Option    "SuspendTime" "3"
  Option    "OffTime"     "3"
  HorizSync  28-50
  VertRefresh  43-75
  Modeline        "1024x600" 50 1024 1104 1176 1248 600 603 619 630
EndSection

Section "Screen"
  Identifier  "Builtin LCD"
  Device    "i-LCD"
  Monitor    "LCD"
  DefaultDepth  24
  SubSection "Display"
    Depth    16
    Modes    "1024x600" "800x600" "640x480"
  EndSubSection
  SubSection "Display"
    Depth    24
    Modes    "1024x600" "800x600" "640x480"
  EndSubSection
EndSection

Section "ServerLayout"
  Identifier   "Default Layout"
  Screen       "Builtin LCD"
  InputDevice  "Generic Keyboard"
  InputDevice  "Configured Mouse"
EndSection

File: /etc/X11/xorg-internal.conf

Now say

command=/usr/X11R6/bin/X -audit 0 -config xorg-internal.conf

in the [server-Standard]-Section of /etc/gdm/gdm.conf. This makes gdm use the small, no-frills config for its servers, so that's what you get when you log in. Other login managers should have similar options, and it's trivial to figure out what to do if you're using startx.

All the exciting junk (GL...) goes into /etc/X11/xorg.conf. For me, this currently looks like this:

# xorg.conf (Xorg X Window System server configuration file)
# This is MD's configuration for "hand-started" X Servers.  It contains
# all sorts of screens and layouts for various purposes.
# If you're not crazy like me, you probably want to comment in and
# adapt the Xkb stuff.

Section "Files"
  FontPath        "unix/:7100"                        # local font server
  # if the local font server has problems, we can fall back on these
  FontPath  "/usr/share/fonts/X11/misc"
  FontPath  "/usr/share/fonts/X11/cyrillic"
  FontPath  "/usr/share/fonts/X11/Type1"
  FontPath  "/usr/share/fonts/X11/CID"
  FontPath  "/usr/share/fonts/X11/100dpi"
  FontPath  "/usr/share/fonts/X11/75dpi"
EndSection

Section "Module"
        Load        "bitmap"
        Load        "dbe"
        Load        "ddc"
        Load        "dri"
        Load        "extmod"
        Load        "freetype"
        Load        "glx"
        Load        "int10"
        Load        "record"
        Load        "vbe"
        Load        "evdev"
EndSection

Section "ServerFlags"
   Option "DefaultServerLayout" "Default Layout"
   Option "AllowMouseOpenFail"
   Option "RandR" "on"
   Option "DontVTSwitch" "off"
   Option "DontZap" "off"
   Option "AllowClosedownGrabs" "on"
   Option "AllowDeactivateGrabs" "on"
   Option "HandleSpecialKeys" "always"
   Option "XkbDisable" "false"         # You probably want to change this
EndSection

Section "InputDevice"
  Identifier  "Generic Keyboard"
  Driver      "keyboard"
  Option      "CoreKeyboard"
  Option     "XkbRules"       "xorg"  # And these, too
  Option     "XkbModel"       "pc104"
  Option     "XkbLayout"      "us"
  Option     "XkbOptions"     "nodeadkeys"
EndSection

Section "InputDevice"
  Identifier  "Configured Mouse"
  Driver      "mouse"
  Option      "CorePointer"
  Option      "Device"             "/dev/input/mice"
  Option      "Protocol"           "ImPS/2"
  Option      "ZAxisMapping"       "4 5"
EndSection

Section "Device"
# Cloned display on internal and external display
  Identifier   "i-LCD-Cloned"
  Driver       "i810"
  Option       "VBERestore"    "on"
  Option       "MonitorLayout" "CRT,LFP"
  Option       "Clone"         "true"
  BusID        "PCI:0:2:0"
  VideoRAM     65536
EndSection

Section "Device"
# Internal display only
  Identifier    "i-LCD"
  Driver        "i810"
  Option        "VBERestore"    "on"
  Option        "MonitorLayout" "CRT,LFP"
  BusID         "PCI:0:2:0"
  VideoRAM      65536
EndSection

Section "Device"
# Cloned display, but xv overlay on both screens
  Identifier      "i-LCD-Cloned for video"
  Driver          "i810"
  Option          "VBERestore"     "on"
  Option          "MonitorLayout"  "None,CRT+LFP"
  Option          "FlipPrimary"    "true"
  Option          "DevicePresence" "off"
  VideoRAM        65536
EndSection

Section "Device"
# External Display only
  Identifier      "i-CRT"
  Driver          "i810"
  Option          "VBERestore"     "on"
  Option          "MonitorLayout"  "CRT,None"
  Option          "DevicePresence" "off"
  Option          "DDC"            "on"
  VideoRAM        65536
EndSection

Section "Device"
# External Display in dual head configuration
  Identifier      "i-CRT-1"
  Driver          "i810"
  BusID           "PCI:0:2:0"
  Option          "MonitorLayout"  "CRT,LFP"
  Screen          1
  VideoRAM        65536
  Option          "DDC"            "on"
EndSection


Section "Monitor"
# An external CRT
  Identifier       "ExternalMonitor"
  HorizSync        31-90
  VertRefresh      56-95
  Option           "DPMS"
EndSection

Section "Monitor"
# A lousy VGA to TV converter
  Identifier       "TVview"
  HorizSync        30-50
  VertRefresh      50-61
  Option           "DPMS"
  Modeline "640x480" 31500 640 655 719 839 480 480 483 499
EndSection

Section "Monitor"
# An external LCD, refresh rate forced down
  Identifier       "ExternalLCD"
  HorizSync        31-70
  VertRefresh      40-65
  Option           "DPMS"
  # This may work some day, but doesn't as of end 2005
  Option           "ForceBios"         "640x480=1280x1024"
EndSection

Section "Monitor"
  Identifier      "InternalLCD"
  Option          "DPMS"
  HorizSync       28-50
  VertRefresh     43-75
  Modeline        "1024x600" 50 1024 1104 1176 1248 600 603 619 630
EndSection

Section "Screen"
  Identifier       "ExternalCRT"
  Device           "i-CRT"
  Monitor          "ExternalMonitor"
  DefaultDepth     24
  SubSection "Display"
    Depth          16
    Modes          "1280x1024" "1024x768" "800x600" "640x480" "480x300"
  EndSubSection
  SubSection "Display"
    Depth          24
    Modes          "1280x1024" "1024x768" "800x600" "640x480" "480x300"
  EndSubSection
EndSection

Section "Screen"
  Identifier       "ExternalCRT1"
  Device           "i-CRT-1"
  Monitor          "ExternalMonitor"
  DefaultDepth     24
  SubSection "Display"
    Depth          24
    Modes          "1280x1024" "1024x768" "800x600" "640x480" "480x300"
  EndSubSection
EndSection


Section "Screen"
  Identifier        "BuiltinLCD"
  Device            "i-LCD"
  Monitor           "InternalLCD"
  DefaultDepth      24
  SubSection "Display"
    Depth                16
    Modes                "1024x600" "800x600" "640x480"
  EndSubSection
  SubSection "Display"
    Depth                24
    Modes                "1024x600" "800x600" "640x480"
  EndSubSection
EndSection


Section "Screen"
# This is for working a beamer -- we usually don't want 16:9 with
# those, and thus we force 800x600
  Identifier        "Cloned LCD"
  Device            "i-LCD-Cloned"
  Monitor           "InternalLCD"
  DefaultDepth      24
  SubSection "Display"
    Depth                16
    Modes                "800x600" "640x480"
  EndSubSection
  SubSection "Display"
    Depth                24
    Modes                "800x600" "640x480"
  EndSubSection
EndSection

Section "Screen"
  Identifier        "Cloned LCD for video"
  Device            "i-LCD-Cloned for video"
  Monitor           "InternalLCD"
  DefaultDepth      24
  SubSection "Display"
    Depth                16
    Modes                "800x600" "640x480"
  EndSubSection
  SubSection "Display"
    Depth                24
    Modes                "800x600" "640x480"
  EndSubSection
EndSection

Section "Screen"
  Identifier        "LoRes Video"
  Device            "i-LCD-Cloned for video"
  Monitor           "TVview"
  DefaultDepth      16
  SubSection "Display"
    Depth                16
    Modes                "640x480"
  EndSubSection
  SubSection "Display"
    Depth                24
    Modes                "640x480"
  EndSubSection
EndSection

Section "Screen"
  Identifier        "ExternalLCDOnly"
  Device            "i-CRT"
  Monitor           "ExternalLCD"
  DefaultDepth      24
  SubSection "Display"
    Depth                16
    Modes                "1600x1200" "1280x1024" "1024x768" "800x600" "640x480"
  EndSubSection
  SubSection "Display"
    Depth                24
    Modes                "1280x1024@60Hz" "1024x768" "800x600" "640x480"
  EndSubSection
EndSection


Section "ServerLayout"
# Just GL accelerated internal screen
  Identifier      "Default Layout"
  Screen          "BuiltinLCD"
  InputDevice     "Generic Keyboard"
  InputDevice     "Configured Mouse"
EndSection

Section "ServerLayout"
  Identifier      "Cloned"
  Screen          "Cloned LCD"
  InputDevice     "Generic Keyboard"
  InputDevice     "Configured Mouse"
EndSection

Section "ServerLayout"
  Identifier      "Cloned-video"
  Screen          "Cloned LCD for video"
  InputDevice     "Generic Keyboard"
  InputDevice     "Configured Mouse"
EndSection

Section "ServerLayout"
  Identifier      "LoResVideo"
  Screen          "LoRes Video"
  InputDevice     "Generic Keyboard"
  InputDevice     "Configured Mouse"
EndSection

Section "ServerLayout"
  Identifier      "External-only"
  Screen          "ExternalLCDonly"
  InputDevice     "Generic Keyboard"
  InputDevice     "Configured Mouse"
EndSection

Section "ServerLayout"
   Identifier   "Dual-Head"
   Screen       0                  "BuiltinLCD"
   Screen       1                  "ExternalCRT1" RightOf "BuiltinLCD"
   InputDevice  "Generic Keyboard"
   InputDevice  "Configured Mouse"
   Option       "Xinerama"         "off"
EndSection

Section "DRI"
        Mode        0666
EndSection

Section "Extensions"
    Option "Composite" "Enable"
EndSection
# vi:et:

File: /etc/X11/xorg.conf

This gives you plenty of screens and layouts. I regularly use scripts calling stuff like

# The following gives you a GL server on vt 8
startx -- :1 
# External 1280x1024 display
startx -- :1 -layout External-only 
# 800x600 cloned display for presenting
startx -- :1 -layout Cloned 
# cloned display, xv overlay on beamer
startx -- :1 -layout Cloned-video 

Usually, you're not allowed to start servers from within an X session, which causes these commands to bomb out. To enable this, in Debian you have to dpkg-reconfigure xserver-common (or edit /etc/X11/Xwrapper.config by hand, saying allowed_users=anybody).

What doesn't work nicely right now real dual-head operation. I didn't try too hard since I use dmx when the machine is "docked". This has the added advantage that I only need an ethernet cable to dock the machine and don't need to mess with the video dongle. Also, the video output from the machine is quite lousy on CRTs, so for larger resolutions you're probably better off having a video card in a PC. Make sure you're safe here -- the X protocol can easily be eavesdropped if people have access to the network packets, and X over ipsec sucks. With a crossover cable or a switch on your desk, you're fine, though. What works quite well in more hostile environments is starting your window manager through an ssh tunnel (basically, startx /usr/bin/ssh -X >hostname< sawfish -- :1). This has the added benefit that you can turn off the XP's display for about 30% power savings.

Still, with a decent TFT you may get a good picture even from the XP's video port, so you may want to investigate dual-head operation. The show-stopper right now is that the video bios insists on ridiculous modes on the external screen in dual head (where single head allows 1600x1200). I believe futzing around with tools like 855resolution would fix this.

ACPI viewing

The JVC has two batteries, which is something most applets don't really provide for. That's why I started hacking wmacpimon. My current result is available here. I'll do a proper release some day, and I'll give it a name of its own, because it doesn't have that terribly much in common with wmacpimon any more. Do let me know if you use it. It would definitely be a motivation to develop this thing into some well-behaved nice, cpu-saving monitor applet.

Note that at least on my machine, the calibration of the external battery is way off. If claims to have about three times the capacity it really has. In consequence, the applet right now estimates the power consumption of the machine way too high while running from the external battery (about 30 Watts instead of about 12 Watts). This, in turn, means that the running time from the internal battery is grossly underestimated. When the machine switches from external to internal battery you'll note that the power drain drops and the remaining run time increases dramatically (you should get about one hour out of the internal battery). If anyone has a good suggestion on how to fix this, please let me know (I wonder how Windows copes with shit like that -- if it does at all, that is).


If you've got stuff to contribute: msdemlei@cl.uni-heidelberg.de