| |
Resuming X
At Linux Laptops we have created a fix for the problem of X
interacting poorly with suspend/resume on many systems.
Many (most?) BIOSes fail to save and restore display
controller chip registers, and X has no protocol to
be notified of resume events, so on many systems
suspend/resume is more-or-less incompatible with X.
The fix below is not perfect because it depends on several
environmental factors. According to Dirk Höhndel, future
versions of X will respond directly to a "resume" event from
the kernel or from APMD. In the meantime, this fix works.
The first part is a tiny C program. It reports the Virtual
Terminal that currently occupies the display:
-----------------------
/*
* queryvt.c - ncm - Query current virtual terminal number
*
* Copyright 1999 by Nathan C. Myers.
* Licensed under the GNU General Public License, version 2.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
int
main() {
int result = 0;
char twelve = 12;
int fd = open("/dev/tty0", O_RDWR|O_NDELAY);
if (fd < 0) {
fputs("queryvt: cannot open /dev/tty0.\n", stderr);
exit(-errno);
}
result = ioctl(fd, TIOCLINUX, &twelve);
if (result < 0) {
fputs("queryvt: cannot query console.\n", stderr);
exit(-errno);
}
exit(result+1);
}
-----------------------
The second part is a script that goes in /etc/apm/resume.d,
called xserver-resume. It checks whether X is actually on
the current display, because X servers tend to crash if they
receive display events when not in control of the display.
-----------------------
#!/bin/bash
#
# Copyright 1999 by Nathan C. Myers.
# Licensed under the GNU General Public License, version 2.
AUTHDIR=/var/state/xdm/authdir/authfiles
XVIDTUNE=/usr/X11R6/bin/xvidtune
QUERYVT=/usr/local/bin/queryvt
(
$QUERYVT # find out which vt is active.
result=$?
if \[ $result -ge 7 ]
then
# X server is active
((xid=${result}-7))
set $AUTHDIR/A:${xid}-*
if \[ $# = 1 -a -f "$1" ]; then
# cycle the display mode to reset display-chip registers.
DISPLAY=:${xid}.0 XAUTHORITY="$1" $XVIDTUNE -next
fi
fi
\echo -n >/dev/tty0
)&
-----------------------
This solution depends on these enviromental factors:
1. apmd version 3.0beta8 or later is running:
Up-to-date versions of apmd support running scripts on suspend
and resume events.
2. xdm is running:
The script needs xdm running so that the X authorization cookie
needed for the script to talk to the server is in a known place.
Of course you could hard-code the path to your own authorization
cookie file, instead, if only you log in.
3. The XF86Config file has only two, identical, modes:
The script depends on the command "xvidtune -next" to cause
no actual change to the display. This means that it works
only if only a single display resolution is used. For example,
in the "Monitor" section of my XF86Config file, I have
Modeline "1024x768a" 78.654 1024 1056 1184 1312 768 772 776 792
Modeline "1024x768b" 78.654 1024 1056 1184 1312 768 772 776 792
and no other modelines, and in my subsection "Display" I have
Modes "1024x768a" "1024x768b"
Incidentally, "fbset -x" is a good way to produce the correct
modeline for modern machines, if you have "frame buffer" support
compiled in, and have booted with a "vga=0x317" kernel option.
The approach above works. Still, in the absence of direct X
server support it would be much preferable to synthesize keyboard
events on the current console:
ctrl down
alt down
numeric '+' down
numeric '+' up
alt up
ctrl up
at a point before X (and X authorization) is involved, rather than
trying to talk directly to the X server. This would eliminate the
need for the queryvt program, and for the X authorization apparatus
in the script.
Does anybody know if this is possible?
Please write.
|
  |