[ltp] acpi_fakekey and sleep button

amateur linux-thinkpad@linux-thinkpad.org
Thu, 12 Oct 2006 15:37:02 +0800


On Wed, Oct 11, 2006 at 11:00:18PM -0400, David Abrahams wrote:
> 
> Hi,
> 
> I can suspend to ram just fine by pressing Fn-F4, but
> gnome-power-manager's suspend function doesn't work.  I'd like to make
> GPM do what Fn-F4 does but the problem is that all I know about Fn-F4
> is that it invokes
> 
>   #!/bin/bash
>   . /usr/share/acpi-support/key-constants
>   acpi_fakekey $KEY_SLEEP 
> 
> and I'm a little too inexperienced with Linux to understand the
> implications of acpi_fakekey, whose (small) source is attached.  Can
> anyone here help me track down where this event goes?
> 
> Thanks in advance,
> Dave
> 

I think acpi_fakekey just insert an key press/release event to
/dev/inputx, where /dev/inputx correspond to the keyboard device.
In this way, the upper acpid will receive a SLEEP key press/release
event, upon which it will trigger an SLEEP signal. And the system in
someway will suspend to ram. Look into the following code.

> #include <unistd.h>
> #include <fcntl.h>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <linux/input.h>
> 
> #define TestBit(bit, array) (array[(bit) / 8] & (1 << ((bit) % 8)))
> 
> int find_keyboard() {

// this function find from /dev/input[0-31] the one which correspond
// to keyboard device, and open it and returne the file descriptor.

> 	int i, j;
>         int fd;
>         char filename[32];
>         char key_bitmask[(KEY_MAX + 7) / 8];
> 
>         for (i=0; i<32; i++) {
>                 snprintf(filename,sizeof(filename), "/dev/input/event%d", i);
> 
>                 fd = open(filename, O_RDWR);
>                 ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
> 
> 		for (j = 0; j < BTN_MISC; j++) {
> 			if (TestBit(j, key_bitmask))
> 				break;
> 		}
> 
>                 if (j < BTN_MISC) {
>                         return fd;
>                 }
> 		close (fd);
>         }
>         return 0;
> }
> 
> int main(int argc, char** argv) {
> 	int fd;
> 	int key;
> 	struct input_event event;
> 
> 	if (argc == 2) {
> 		key = atoi(argv[1]);
> 	} else {
> 		return 1;
> 	}
> 
> 	fd = find_keyboard();
> 
> 	if (!fd) {
> 		return 2;
> 	}
> 

// here we already the keyboard device file descriptor. So we can
// simulate a key press/release by write into it two event.

> 	event.type = EV_KEY;
> 	event.code = key;
> 	event.value = 1;
> 	write(fd, &event, sizeof event);
> 
> 	event.type = EV_KEY;
> 	event.code = key;
> 	event.value = 0;
> 	write(fd, &event, sizeof event);
> 	
> 	return 0;
> }
> 

> 
> -- 
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com

-------------------------

-- 
Q:	How do you shoot a blue elephant?
A:	With a blue-elephant gun.

Q:	How do you shoot a pink elephant?
A:	Twist its trunk until it turns blue, then shoot it with
	a blue-elephant gun.