/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c,v 3.2 1998/07/25 16:57:01 dawes Exp $ */
/*
 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
 * Copyright 1993 by David Dawes <dawes@xfree86.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the names of Thomas Roell and David Dawes 
 * not be used in advertising or publicity pertaining to distribution of 
 * the software without specific, written prior permission.  Thomas Roell and
 * David Dawes makes no representations about the suitability of this 
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 *
 * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO 
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES BE LIABLE FOR 
 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */
/* $XConsortium: std_kbdEv.c /main/4 1996/03/11 10:47:33 kaleb $ */

#include "X.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"

/*MU added*/
/* 2001/01/14 Miguel Freitas <miguel@cetuc.puc-rio.br>
 *
 * USB Keyboard to PC-AT Keyboard HACK
 *
 * Included routines from Linux Kernel to handle usb keyboard events.
 * I don't know if there are any license issues here. Any code written
 * by me in this file is under the terms of the GNU General Public
 * License as described below.
 *
*/

/*
 * $Id: keybdev.c,v 1.3 2000/05/28 17:31:36 vojtech Exp $
 *
 *  Copyright (c) 1999-2000 Vojtech Pavlik
 *
 *  Input driver to keyboard driver binding.
 *
 *  Sponsored by SuSE
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Should you need to contact me, the author, you can do so either by
 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
 */

#include <linux/input.h>

static unsigned short x86_keycodes[256] =
	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
	 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
	 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
	 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
	 80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90,
	284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339,
	367,294,293,286,350, 92,334,512,116,377,109,111,373,347,348,349,
	360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355,
	103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361,
	291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114,
	118,117,125,374,379,259,260,261,262,263,264,265,266,267,268,269,
	271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307,
	308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330,
	332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 };

static void handle_scancode(unsigned char scancode, int down)
{
        char up_flag = down ? 0 : 0200;

        xf86PostKbdEvent(scancode | up_flag);
}

static int emulate_raw(unsigned int keycode, int down)
{
	if (keycode > 255 || !x86_keycodes[keycode])
		return -1; 

	if (keycode == KEY_PAUSE) {
		handle_scancode(0xe1, 1);
		handle_scancode(0x1d, down);
		handle_scancode(0x45, down);
		return 0;
	} 

	if (x86_keycodes[keycode] & 0x100)
		handle_scancode(0xe0, 1);

	handle_scancode(x86_keycodes[keycode] & 0x7f, down);

	if (keycode == KEY_SYSRQ) {
		handle_scancode(0xe0, 1);
		handle_scancode(0x37, down);
	}

	return 0;
}


static void keybdev_event(unsigned int type, unsigned int code, int down)
{
	if (type != EV_KEY) return;

	emulate_raw(code, down);
}

/*MU end*/


void
xf86KbdEvents()
{
    /*MU change*/
    if ( MUtype == eMUnone || MUtype == eMUconsole )
    {
	unsigned char rBuf[64];
	int nBytes, i;

	if ((nBytes = read( xf86Info.consoleFd, (char *)rBuf, sizeof(rBuf)))
	    > 0)
	{
		for (i = 0; i < nBytes; i++)
			xf86PostKbdEvent(rBuf[i]);
	}
    }
    else
    {
 	struct s_input_event {
 	       struct timeval time;
 	       unsigned short type;
    	       unsigned short code;
    	       unsigned int value;
	} input_event;

 	int nBytes, i;
	while ((nBytes = read( xf86Info.kbdFd, (char *)&input_event, sizeof(input_event)))
 	    > 0)
 	{
	    keybdev_event( input_event.type, input_event.code, input_event.value );
 	}
    }
    /*MU end*/
}

