/*
 * Atari Mouse Driver for Linux
 * by Robert de Vries (robert@and.nl) 19Jul93
 */

#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/atarikb.h>
#include <linux/atari_mouse.h>
#include <asm/segment.h>

static struct mouse_status mouse;

void mouse_interrupt(char *buf)
{
/*    ikbd_mouse_disable(); */

    mouse.buttons = buf[0] & 0x3;
    mouse.dx = buf[1];
    mouse.dy = buf[2];
    mouse.ready = 1;
    wake_up_interruptible(&mouse.wait);

/*    ikbd_mouse_rel_pos(); */
}

static void release_mouse(struct inode *inode, struct file *file)
{
    ikbd_mouse_disable();

    mouse.active = 0;
    mouse.ready = 1;
}

static int open_mouse(struct inode *inode, struct file *file)
{
    int minor = MINOR(inode->i_rdev);

    if (minor != ATARI_MOUSE_MINOR)
	return -ENODEV;
    if (mouse.active)
	return -EBUSY;
    mouse.active = 1;
    mouse.ready = 0;
    ikbd_mouse_rel_pos();
    return 0;
}

static int write_mouse(struct inode *inode, struct file *file, char *buffer, int count)
{
    return -EINVAL;
}

static int read_mouse(struct inode *inode, struct file *file, char *buffer, int count)
{
    int i;

    if (count < 3)
	return -EINVAL;
    if (!mouse.ready)
	return -EAGAIN;
    /* ikbd_mouse_disable */
    put_fs_byte(mouse.buttons, buffer++);
    put_fs_byte(mouse.dx, buffer++);
    put_fs_byte(mouse.dy, buffer++);
    for (i = 3; i < count; i++)
	put_fs_byte(0, buffer++);
    mouse.ready = 0;
    /* ikbd_mouse_rel_pos(); */
    return i;
}

static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table *wait)
{
    if (sel_type != SEL_IN)
	return 0;
    if (mouse.ready)
	return 1;
    select_wait(&mouse.wait, wait);
    return 0;
}

struct file_operations mouse_fops = {
    NULL,		/* mouse_seek */
    read_mouse,
    write_mouse,
    NULL,		/* mouse_readdir */
    mouse_select,
    NULL,		/* mouse_ioctl */
    NULL,		/* mouse_mmap */
    open_mouse,
    release_mouse
};

unsigned long mouse_init(unsigned long kmem_start)
{
    mouse.active = 0;
    mouse.ready = 0;
    mouse.wait = NULL;

    if (register_chrdev(10, "mouse", &mouse_fops))
	printk("unable to get major 10 for mouse devices\n");
    printk("Atari mouse driver installed.\n");
    
    return kmem_start;
}
