[patch] Re: "Internet Keyboard" support for Linux

Pavel Machek (pavel@suse.cz)
Fri, 10 Dec 1999 10:36:27 +0100


Hi!

> > >
> > >If you want to use these, attach keycodes using the setkeycodes utility.
> > >Then attach actions or strings to these keycodes using loadkeys.
> > >
> > >Andries
>
> Simply attaching strings and such to the keys are not acceptable. I want to be
> able to have keypresses send signals, launch applications, do netscape -remote
> stuff, etc, etc
>
> My system involves a kernelspace driver to intercept these codes, and a
> user-space daemon to process them.

But you want to do that even on non-internet keybaords! For example
mouse emulation on keyboard is easy that way.

I called it keylink, but it never got to standart distribution. (There
should be hooks to actually call it, add them yourself.)

/*
* Keylink - for making keyboard combinations call userland
*
* Copyright 1998 Pavel Machek <pavel@ucw.cz>, distribute
* under terms of GPL
*
* Loosely based on msbusmouse.c.
*/

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/irq.h>

static struct wait_queue *wait;
static int active = 0;

#define RING 0x100
static char ringbuf[ RING ];
static int head = 0, tail = 0;

#define INC( a ) a = (a+1) & (RING-1)

void keylink_pushkey( char c )
{
INC( head );
if (head == tail)
printk( "keylink: ring buffer overrun, keys lost\n" );
ringbuf[ head ] = c;
wake_up_interruptible(&wait);
}

static int release_keylink(struct inode * inode, struct file * file)
{
if (--active)
return 0;
MOD_DEC_USE_COUNT;
return 0;
}

static int open_keylink(struct inode * inode, struct file * file)
{
if (active++)
return 0;
MOD_INC_USE_COUNT;
return 0;
}

static ssize_t write_keylink(struct file * file,
const char * buffer, size_t count, loff_t *ppos)
{
return -EINVAL;
}

static ssize_t read_keylink(struct file * file,
char * buffer, size_t count, loff_t *ppos)
{
int i;

if (head==tail)
interruptible_sleep_on( &wait );
for (i = 0; i < count; i++) {
if (head==tail)
break;
INC( tail );
put_user(ringbuf[tail], buffer + i);
}
return i;
}

static unsigned int keylink_poll(struct file *file, poll_table * local_wait)
{
poll_wait(file, &wait, local_wait);
return 0;
}

struct file_operations keylink_fops = {
NULL, /* keylink_seek */
read_keylink,
write_keylink,
NULL, /* keylink_readdir */
keylink_poll, /* keylink_poll */
NULL, /* keylink_ioctl */
NULL, /* keylink_mmap */
open_keylink,
release_keylink,
NULL,
};

static struct miscdevice misc_keylink = {
KEYLINK_MINOR, "keylink", &keylink_fops
};

__initfunc(int keylink_init(void))
{
head = tail = 0;
wait = NULL;

printk(KERN_INFO "Keylink installed.\n");
misc_register(&misc_keylink);
return 0;
}

#ifdef MODULE
int init_module(void)
{
return keylink_init();
}

void cleanup_module(void)
{
misc_deregister(&misc_keylink);
}
#endif

-- 
I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel.  Pavel
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/