xserver/hw/xorg/os-support/linux Makefile.am, NONE, 1.1 agpgart.h, NONE, 1.1 lnx.h, NONE, 1.1 lnxResource.c, NONE, 1.1 lnx_KbdMap.c, NONE, 1.1 lnx_agp.c, NONE, 1.1 lnx_apm.c, NONE, 1.1 lnx_axp.c, NONE, 1.1 lnx_ev56.c, NONE, 1.1 lnx_init.c, NONE, 1.1 lnx_io.c, NONE, 1.1 lnx_jstk.c, NONE, 1.1 lnx_kbd.c, NONE, 1.1 lnx_kbd.h, NONE, 1.1 lnx_kmod.c, NONE, 1.1 lnx_mouse.c, NONE, 1.1 lnx_pci.c, NONE, 1.1 lnx_video.c, NONE, 1.1

Daniel Stone xserver-commit at pdx.freedesktop.org
Sun Apr 25 23:52:23 EST 2004


Committed by: daniel

Update of /cvs/xserver/xserver/hw/xorg/os-support/linux
In directory pdx:/tmp/cvs-serv17025/hw/xorg/os-support/linux

Added Files:
	Makefile.am agpgart.h lnx.h lnxResource.c lnx_KbdMap.c 
	lnx_agp.c lnx_apm.c lnx_axp.c lnx_ev56.c lnx_init.c lnx_io.c 
	lnx_jstk.c lnx_kbd.c lnx_kbd.h lnx_kmod.c lnx_mouse.c 
	lnx_pci.c lnx_video.c 
Log Message:
Xizzle is dead, long live Xorg.

Re-import the DDX from X11R6.7, complete with automakey goodness, and do the
requisite configure.ac, et al, updates; also import the XKB extension from the
6.7 DIX.

Currently it'll link and then hang solid in RADEONInitAccel(), or the next
function if you enable NoAccel.


--- NEW FILE: Makefile.am ---
if DRI
DRI_SUBDIRS=drm
DRI_LIBS=drm/libxorglinuxdrm.a
endif

lib_LIBRARIES = libxorglinux.a
libxorglinux_a_SOURCES = lnx_mouse.c lnx_kbd.c lnx_KbdMap.c \
                           lnx_init.c lnx_video.c lnx_io.c \
                           lnx_pci.c lnx_apm.c lnx_agp.c \
                           ../shared/at_scancode.c ../shared/libc_wrapper.c \
                           ../shared/bios_mmap.c ../shared/VTsw_usl.c \
                           ../shared/std_kbdEv.c ../shared/posix_tty.c \
                           ../shared/vidmem.c ../shared/sigio.c \
                           ../shared/stdResource.c \
                           ../../common/xf86PM.c ../misc/SlowBcopy.c
libxorglinux_a_LIBADD = int10/libxorglinuxint10.a \
                          $(DRI_LIBS)

sdk_INCLUDEDIR = $(includedir)/xorg
sdk_INCLUDES = agpgart.h
INCLUDES = $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS) -DUSESTDRES -DXFree86Server

SUBDIRS = int10 $(DRI_SUBDIRS)

--- NEW FILE: agpgart.h ---
/*
 * AGPGART module version 0.99
 * Copyright (C) 1999 Jeff Hartmann
 * Copyright (C) 1999 Precision Insight, Inc.
 * Copyright (C) 1999 Xi Graphics, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/agpgart.h,v 1.3 2000/06/17 00:03:33 martin Exp $ */

#ifndef _AGP_H
#define _AGP_H 1

#define AGPIOC_BASE       'A'
#define AGPIOC_INFO       _IOR (AGPIOC_BASE, 0, agp_info*)
#define AGPIOC_ACQUIRE    _IO  (AGPIOC_BASE, 1)
#define AGPIOC_RELEASE    _IO  (AGPIOC_BASE, 2)
#define AGPIOC_SETUP      _IOW (AGPIOC_BASE, 3, agp_setup*)
#define AGPIOC_RESERVE    _IOW (AGPIOC_BASE, 4, agp_region*)
#define AGPIOC_PROTECT    _IOW (AGPIOC_BASE, 5, agp_region*)
#define AGPIOC_ALLOCATE   _IOWR(AGPIOC_BASE, 6, agp_allocate*)
#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
#define AGPIOC_BIND       _IOW (AGPIOC_BASE, 8, agp_bind*)
#define AGPIOC_UNBIND     _IOW (AGPIOC_BASE, 9, agp_unbind*)

#define AGP_DEVICE      "/dev/agpgart"

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef __KERNEL__
#include <linux/types.h>
#include <asm/types.h>
#include <sys/types.h>

typedef struct _agp_version {
	__u16 major;
	__u16 minor;
} agp_version;

typedef struct _agp_info {
	agp_version version;	/* version of the driver        */
	__u32 bridge_id;	/* bridge vendor/device         */
	__u32 agp_mode;		/* mode info of bridge          */
	off_t aper_base;	/* base of aperture             */
	size_t aper_size;	/* size of aperture             */
	size_t pg_total;	/* max pages (swap + system)    */
	size_t pg_system;	/* max pages (system)           */
	size_t pg_used;		/* current pages used           */
} agp_info;

typedef struct _agp_setup {
	__u32 agp_mode;		/* mode info of bridge          */
} agp_setup;

/*
 * The "prot" down below needs still a "sleep" flag somehow ...
 */
typedef struct _agp_segment {
	off_t pg_start;		/* starting page to populate    */
	size_t pg_count;	/* number of pages              */
	int prot;		/* prot flags for mmap          */
} agp_segment;

typedef struct _agp_region {
	pid_t pid;		/* pid of process               */
	size_t seg_count;	/* number of segments           */
	struct _agp_segment *seg_list;
} agp_region;

typedef struct _agp_allocate {
	int key;		/* tag of allocation            */
	size_t pg_count;	/* number of pages              */
	__u32 type;		/* 0 == normal, other devspec   */
   	__u32 physical;         /* device specific (some devices  
				 * need a phys address of the     
				 * actual page behind the gatt    
				 * table)                        */
} agp_allocate;

typedef struct _agp_bind {
	int key;		/* tag of allocation            */
	off_t pg_start;		/* starting page to populate    */
} agp_bind;

typedef struct _agp_unbind {
	int key;		/* tag of allocation            */
	__u32 priority;		/* priority for paging out      */
} agp_unbind;

#else				/* __KERNEL__ */

#define AGPGART_MINOR 175

#define AGP_UNLOCK()      	up(&(agp_fe.agp_mutex));
#define AGP_LOCK()    		down(&(agp_fe.agp_mutex));
#define AGP_LOCK_INIT() 	sema_init(&(agp_fe.agp_mutex), 1)

#ifndef _AGP_BACKEND_H
typedef struct _agp_version {
	u16 major;
	u16 minor;
} agp_version;

#endif

typedef struct _agp_info {
	agp_version version;	/* version of the driver        */
	u32 bridge_id;		/* bridge vendor/device         */
	u32 agp_mode;		/* mode info of bridge          */
	off_t aper_base;	/* base of aperture             */
	size_t aper_size;	/* size of aperture             */
	size_t pg_total;	/* max pages (swap + system)    */
	size_t pg_system;	/* max pages (system)           */
	size_t pg_used;		/* current pages used           */
} agp_info;

typedef struct _agp_setup {
	u32 agp_mode;		/* mode info of bridge          */
} agp_setup;

/*
 * The "prot" down below needs still a "sleep" flag somehow ...
 */
typedef struct _agp_segment {
	off_t pg_start;		/* starting page to populate    */
	size_t pg_count;	/* number of pages              */
	int prot;		/* prot flags for mmap          */
} agp_segment;

typedef struct _agp_segment_priv {
	off_t pg_start;
	size_t pg_count;
	pgprot_t prot;
} agp_segment_priv;

typedef struct _agp_region {
	pid_t pid;		/* pid of process               */
	size_t seg_count;	/* number of segments           */
	struct _agp_segment *seg_list;
} agp_region;

typedef struct _agp_allocate {
	int key;		/* tag of allocation            */
	size_t pg_count;	/* number of pages              */
	u32 type;		/* 0 == normal, other devspec   */
	u32 physical;           /* device specific (some devices  
				 * need a phys address of the     
				 * actual page behind the gatt    
				 * table)                        */
} agp_allocate;

typedef struct _agp_bind {
	int key;		/* tag of allocation            */
	off_t pg_start;		/* starting page to populate    */
} agp_bind;

typedef struct _agp_unbind {
	int key;		/* tag of allocation            */
	u32 priority;		/* priority for paging out      */
} agp_unbind;

typedef struct _agp_client {
	struct _agp_client *next;
	struct _agp_client *prev;
	pid_t pid;
	int num_segments;
	agp_segment_priv **segments;
} agp_client;

typedef struct _agp_controller {
	struct _agp_controller *next;
	struct _agp_controller *prev;
	pid_t pid;
	int num_clients;
	agp_memory *pool;
	agp_client *clients;
} agp_controller;

#define AGP_FF_ALLOW_CLIENT		0
#define AGP_FF_ALLOW_CONTROLLER 	1
#define AGP_FF_IS_CLIENT		2
#define AGP_FF_IS_CONTROLLER		3
#define AGP_FF_IS_VALID 		4

typedef struct _agp_file_private {
	struct _agp_file_private *next;
	struct _agp_file_private *prev;
	pid_t my_pid;
	u32 access_flags;
} agp_file_private;

struct agp_front_data {
	struct semaphore agp_mutex;
	agp_controller *current_controller;
	agp_controller *controllers;
	agp_file_private *file_priv_list;
	u8 used_by_controller;
	u8 backend_acquired;
};

#endif				/* __KERNEL__ */

#endif				/* _AGP_H */

--- NEW FILE: lnx.h ---
/* $XFree86: Exp $ */

#ifndef LNX_H_
# ifdef __alpha__
extern unsigned long _bus_base __P ((void)) __attribute__ ((const));
extern unsigned long _bus_base_sparse __P ((void)) __attribute__ ((const));
extern int iopl __P ((int __level));

/* new pciconfig_iobase syscall added in 2.2.15 and 2.3.99 */
#  include <linux/unistd.h>
#  include <asm/pci.h>
extern long (*_iobase)(unsigned, int, int, int);

/*
 * _iobase deals with the case the __NR_pciconfig_iobase is either undefined
 * or unsupported by the kernel, but we need to make sure that the `which'
 * argument symbols are defined.
 */
#  ifndef IOBASE_HOSE
#   define IOBASE_HOSE 		0
#  endif
#  ifndef IOBASE_SPARSE_MEM
#   define IOBASE_SPARSE_MEM	1
#  endif
#  ifndef IOBASE_DENSE_MEM
#   define IOBASE_DENSE_MEM	2
#  endif
#  ifndef IOBASE_SPARSE_IO
#   define IOBASE_SPARSE_IO	3
#  endif
#  ifndef IOBASE_DENSE_IO
#   define IOBASE_DENSE_IO	4
#  endif
#  ifndef IOBASE_ROOT_BUS
#   define IOBASE_ROOT_BUS	5
#  endif
#  ifndef IOBASE_FROM_HOSE
#   define IOBASE_FROM_HOSE	0x10000
#  endif
# endif /* __alpha__ */

#define LNX_H_

#endif

--- NEW FILE: lnxResource.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnxResource.c,v 3.18 2002/01/25 21:56:19 tsi Exp $ */

/* Resource information code */

#include <X11/X.h>
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86Privstr.h"
#include "xf86Pci.h"
#include "xf86Resources.h"
#define NEED_OS_RAC_PROTOS
#include "xf86_OSlib.h"
#include "lnx.h"

/* Avoid Imakefile changes */
#include "bus/Pci.h"

resRange PciAvoid[] =
{
#if !defined(__sparc__) || !defined(INCLUDE_XF86_NO_DOMAIN)
    _PCI_AVOID_PC_STYLE,
#endif
    _END
};

#ifdef INCLUDE_XF86_NO_DOMAIN

#ifdef __alpha__

resPtr
xf86BusAccWindowsFromOS(void)
{
    resPtr ret = NULL;
    resRange range;

    RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);

    RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock);
    ret = xf86AddResToList(ret, &range, -1);
    return ret;
}

resPtr
xf86PciBusAccWindowsFromOS(void)
{
    resPtr ret = NULL;
    resRange range;
    /*
     * On the Alpha the first 16MB of every 128 Mb segment in
     * sparse address space are an image of the ISA bus range
     */
    if (_bus_base_sparse()) {
	RANGE(range, 0x00000000, 0x07ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x09000000, 0x0fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x11000000, 0x17ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x19000000, 0x1fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x21000000, 0x27ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x29000000, 0x2fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x31000000, 0x37ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x39000000, 0x3fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x41000000, 0x47ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x49000000, 0x4fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x51000000, 0x57ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x59000000, 0x5fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x61000000, 0x67ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x69000000, 0x6fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x71000000, 0x77ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x79000000, 0x7fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x81000000, 0x87ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x89000000, 0x8fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x91000000, 0x97ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0x99000000, 0x9fffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xa1000000, 0xa7ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xa9000000, 0xafffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xb1000000, 0xb7ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xb9000000, 0xbfffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xc1000000, 0xc7ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xc9000000, 0xcfffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xd1000000, 0xd7ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xd9000000, 0xdfffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xe1000000, 0xe7ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xe9000000, 0xefffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xf1000000, 0xf7ffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
	RANGE(range, 0xf9000000, 0xffffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
    } else {
	RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock);
	ret = xf86AddResToList(ret, &range, -1);
    }
    RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock);
    ret = xf86AddResToList(ret, &range, -1);
    return ret;
}

#ifdef INCLUDE_UNUSED

resPtr
xf86IsaBusAccWindowsFromOS(void)
{
    resPtr ret = NULL;
    resRange range;

    RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);

    RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock);
    ret = xf86AddResToList(ret, &range, -1);
    return ret;
}

#endif /* INCLUDE_UNUSED */

resPtr
xf86AccResFromOS(resPtr ret)
{
    resRange range;

    /*
     * Fallback is to claim the following areas:
     *
     * 0x000c0000 - 0x000effff  location of VGA and other extensions ROMS
     */

    RANGE(range, 0x000c0000, 0x000effff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);

    /*
     * Fallback would be to claim well known ports in the 0x0 - 0x3ff range
     * along with their sparse I/O aliases, but that's too imprecise.  Instead
     * claim a bare minimum here.
     */
    RANGE(range, 0x00000000, 0x000000ff, ResExcIoBlock); /* For mainboard */
    ret = xf86AddResToList(ret, &range, -1);

    /*
     * At minimum, the top and bottom resources must be claimed, so that
     * resources that are (or appear to be) unallocated can be relocated.
     */
    RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);
    RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);
/*  RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock);
    ret = xf86AddResToList(ret, &range, -1); */
    RANGE(range, 0xffffffff, 0xffffffff, ResExcIoBlock);
    ret = xf86AddResToList(ret, &range, -1);

    /* XXX add others */
    return ret;
}

#elif defined(__powerpc__) || \
      defined(__sparc__) || \
      defined(__mips__) || \
      defined(__sh__) || \
      defined(__mc68000__) || \
      defined(__arm__) || \
      defined(__s390__) || \
      defined(__hppa__)

 /*
  * XXX this isn't exactly correct but it will get the server working 
  * for now until we get something better.
  */
  
resPtr
xf86BusAccWindowsFromOS(void)
{
    resPtr ret = NULL;
    resRange range;

    RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);

#if defined(__sparc__) || defined(__powerpc__)
    RANGE(range, 0x00000000, 0x00ffffff, ResExcIoBlock);
#else
    RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock);
#endif
    ret = xf86AddResToList(ret, &range, -1);
    return ret;
}

resPtr
xf86PciBusAccWindowsFromOS(void)
{
    resPtr ret = NULL;
    resRange range;

    RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);

#if defined(__sparc__) || defined(__powerpc__)
    RANGE(range, 0x00000000, 0x00ffffff, ResExcIoBlock);
#else
    RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock);
#endif
    ret = xf86AddResToList(ret, &range, -1);
    return ret;
}

#ifdef INCLUDE_UNUSED

resPtr
xf86IsaBusAccWindowsFromOS(void)
{
    resPtr ret = NULL;
    resRange range;

    RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);

#if defined(__sparc__) || defined(__powerpc__)
    RANGE(range, 0x00000000, 0x00ffffff, ResExcIoBlock);
#else
    RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock);
#endif
    ret = xf86AddResToList(ret, &range, -1);
    return ret;
}

#endif /* INCLUDE_UNUSED */

resPtr
xf86AccResFromOS(resPtr ret)
{
    resRange range;

    /*
     * At minimum, the top and bottom resources must be claimed, so that
     * resources that are (or appear to be) unallocated can be relocated.
     */
    RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);
    RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock);
    ret = xf86AddResToList(ret, &range, -1);
    RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock);
    ret = xf86AddResToList(ret, &range, -1);
#if defined(__sparc__) || defined(__powerpc__)
    RANGE(range, 0x00ffffff, 0x00ffffff, ResExcIoBlock);
#else
    RANGE(range, 0x0000ffff, 0x0000ffff, ResExcIoBlock);
#endif
    ret = xf86AddResToList(ret, &range, -1);

    return ret;
}

#else

#error : Put your platform dependent code here!!

#endif

#endif /* INCLUDE_XF86_NO_DOMAIN */

--- NEW FILE: lnx_KbdMap.c ---
/* $XFree86$ */

/*
 * Slightly modified xf86KbdLnx.c which is
 *
 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
 */

#include <X11/X.h>
#include <X11/Xmd.h>
#include "input.h"
#include "scrnintstr.h"

#include "compiler.h"

#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "xf86Xinput.h"
#include "xf86OSKbd.h"
#include "atKeynames.h"

#include "xf86Keymap.h"
#include <X11/DECkeysym.h>

#include "lnx_kbd.h"

/*ARGSUSED*/

/*
 * KbdGetMapping --
 *	Get the national keyboard mapping. The keyboard type is set, a new map
 *      and the modifiermap is computed.
 */

static void readKernelMapping(InputInfoPtr pInfo,
                              KeySymsPtr pKeySyms, CARD8 *pModMap);
void
KbdGetMapping (InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap)
{
  KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
  KeySym        *k;
  char          type;
  int           i;

  readKernelMapping(pInfo, pKeySyms, pModMap);

  /*
   * compute the modifier map
   */
  for (i = 0; i < MAP_LENGTH; i++)
    pModMap[i] = NoSymbol;  /* make sure it is restored */
  
  for (k = map, i = MIN_KEYCODE;
       i < (NUM_KEYCODES + MIN_KEYCODE);
       i++, k += 4)
    
    switch(*k) {
      
    case XK_Shift_L:
    case XK_Shift_R:
      pModMap[i] = ShiftMask;
      break;
      
    case XK_Control_L:
    case XK_Control_R:
      pModMap[i] = ControlMask;
      break;
      
    case XK_Caps_Lock:
      pModMap[i] = LockMask;
      break;
      
    case XK_Alt_L:
    case XK_Alt_R:
      pModMap[i] = AltMask;
      break;
      
    case XK_Num_Lock:
      pModMap[i] = NumLockMask;
      break;

    case XK_Scroll_Lock:
      pModMap[i] = ScrollLockMask;
      break;

      /* kana support */
    case XK_Kana_Lock:
    case XK_Kana_Shift:
      pModMap[i] = KanaMask;
      break;

      /* alternate toggle for multinational support */
    case XK_Mode_switch:
      pModMap[i] = AltLangMask;
      break;

    }
  
  pKbd->kbdType = ioctl(pInfo->fd, KDGKBTYPE, &type) != -1 ? type : KB_101;

  pKeySyms->map        = map;
  pKeySyms->mapWidth   = GLYPHS_PER_KEY;
  pKeySyms->minKeyCode = MIN_KEYCODE;
  pKeySyms->maxKeyCode = MAX_KEYCODE; 
}

#include <linux/keyboard.h>

static KeySym linux_to_x[256] = {
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	XK_BackSpace,	XK_Tab,		XK_Linefeed,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	XK_Escape,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	XK_space,	XK_exclam,	XK_quotedbl,	XK_numbersign,
	XK_dollar,	XK_percent,	XK_ampersand,	XK_apostrophe,
	XK_parenleft,	XK_parenright,	XK_asterisk,	XK_plus,
	XK_comma,	XK_minus,	XK_period,	XK_slash,
	XK_0,		XK_1,		XK_2,		XK_3,
	XK_4,		XK_5,		XK_6,		XK_7,
	XK_8,		XK_9,		XK_colon,	XK_semicolon,
	XK_less,	XK_equal,	XK_greater,	XK_question,
	XK_at,		XK_A,		XK_B,		XK_C,
	XK_D,		XK_E,		XK_F,		XK_G,
	XK_H,		XK_I,		XK_J,		XK_K,
	XK_L,		XK_M,		XK_N,		XK_O,
	XK_P,		XK_Q,		XK_R,		XK_S,
	XK_T,		XK_U,		XK_V,		XK_W,
	XK_X,		XK_Y,		XK_Z,		XK_bracketleft,
	XK_backslash,	XK_bracketright,XK_asciicircum,	XK_underscore,
	XK_grave,	XK_a,		XK_b,		XK_c,
	XK_d,		XK_e,		XK_f,		XK_g,
	XK_h,		XK_i,		XK_j,		XK_k,
	XK_l,		XK_m,		XK_n,		XK_o,
	XK_p,		XK_q,		XK_r,		XK_s,
	XK_t,		XK_u,		XK_v,		XK_w,
	XK_x,		XK_y,		XK_z,		XK_braceleft,
	XK_bar,		XK_braceright,	XK_asciitilde,	XK_BackSpace,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
	XK_nobreakspace,XK_exclamdown,	XK_cent,	XK_sterling,
	XK_currency,	XK_yen,		XK_brokenbar,	XK_section,
	XK_diaeresis,	XK_copyright,	XK_ordfeminine,	XK_guillemotleft,
	XK_notsign,	XK_hyphen,	XK_registered,	XK_macron,
	XK_degree,	XK_plusminus,	XK_twosuperior,	XK_threesuperior,
	XK_acute,	XK_mu,		XK_paragraph,	XK_periodcentered,
	XK_cedilla,	XK_onesuperior,	XK_masculine,	XK_guillemotright,
	XK_onequarter,	XK_onehalf,	XK_threequarters,XK_questiondown,
	XK_Agrave,	XK_Aacute,	XK_Acircumflex,	XK_Atilde,
	XK_Adiaeresis,	XK_Aring,	XK_AE,		XK_Ccedilla,
	XK_Egrave,	XK_Eacute,	XK_Ecircumflex,	XK_Ediaeresis,
	XK_Igrave,	XK_Iacute,	XK_Icircumflex,	XK_Idiaeresis,
	XK_ETH,		XK_Ntilde,	XK_Ograve,	XK_Oacute,
	XK_Ocircumflex,	XK_Otilde,	XK_Odiaeresis,	XK_multiply,
	XK_Ooblique,	XK_Ugrave,	XK_Uacute,	XK_Ucircumflex,
	XK_Udiaeresis,	XK_Yacute,	XK_THORN,	XK_ssharp,
	XK_agrave,	XK_aacute,	XK_acircumflex,	XK_atilde,
	XK_adiaeresis,	XK_aring,	XK_ae,		XK_ccedilla,
	XK_egrave,	XK_eacute,	XK_ecircumflex,	XK_ediaeresis,
	XK_igrave,	XK_iacute,	XK_icircumflex,	XK_idiaeresis,
	XK_eth,		XK_ntilde,	XK_ograve,	XK_oacute,
	XK_ocircumflex,	XK_otilde,	XK_odiaeresis,	XK_division,
	XK_oslash,	XK_ugrave,	XK_uacute,	XK_ucircumflex,
	XK_udiaeresis,	XK_yacute,	XK_thorn,	XK_ydiaeresis
};

/*
 * Maps the AT keycodes to Linux keycodes
 */
static unsigned char at2lnx[NUM_KEYCODES] =
{
	0x01,	/* KEY_Escape */	0x02,	/* KEY_1 */
	0x03,	/* KEY_2 */		0x04,	/* KEY_3 */
	0x05,	/* KEY_4 */		0x06,	/* KEY_5 */
	0x07,	/* KEY_6 */		0x08,	/* KEY_7 */
	0x09,	/* KEY_8 */		0x0a,	/* KEY_9 */
	0x0b,	/* KEY_0 */		0x0c,	/* KEY_Minus */
	0x0d,	/* KEY_Equal */		0x0e,	/* KEY_BackSpace */
	0x0f,	/* KEY_Tab */		0x10,	/* KEY_Q */
	0x11,	/* KEY_W */		0x12,	/* KEY_E */
	0x13,	/* KEY_R */		0x14,	/* KEY_T */
	0x15,	/* KEY_Y */		0x16,	/* KEY_U */
	0x17,	/* KEY_I */		0x18,	/* KEY_O */
	0x19,	/* KEY_P */		0x1a,	/* KEY_LBrace */
	0x1b,	/* KEY_RBrace */	0x1c,	/* KEY_Enter */
	0x1d,	/* KEY_LCtrl */		0x1e,	/* KEY_A */
	0x1f,	/* KEY_S */		0x20,	/* KEY_D */
	0x21,	/* KEY_F */		0x22,	/* KEY_G */
	0x23,	/* KEY_H */		0x24,	/* KEY_J */
	0x25,	/* KEY_K */		0x26,	/* KEY_L */
	0x27,	/* KEY_SemiColon */	0x28,	/* KEY_Quote */
	0x29,	/* KEY_Tilde */		0x2a,	/* KEY_ShiftL */
	0x2b,	/* KEY_BSlash */	0x2c,	/* KEY_Z */
	0x2d,	/* KEY_X */		0x2e,	/* KEY_C */
	0x2f,	/* KEY_V */		0x30,	/* KEY_B */
	0x31,	/* KEY_N */		0x32,	/* KEY_M */
	0x33,	/* KEY_Comma */		0x34,	/* KEY_Period */
	0x35,	/* KEY_Slash */		0x36,	/* KEY_ShiftR */
	0x37,	/* KEY_KP_Multiply */	0x38,	/* KEY_Alt */
	0x39,	/* KEY_Space */		0x3a,	/* KEY_CapsLock */
	0x3b,	/* KEY_F1 */		0x3c,	/* KEY_F2 */
	0x3d,	/* KEY_F3 */		0x3e,	/* KEY_F4 */
	0x3f,	/* KEY_F5 */		0x40,	/* KEY_F6 */
	0x41,	/* KEY_F7 */		0x42,	/* KEY_F8 */
	0x43,	/* KEY_F9 */		0x44,	/* KEY_F10 */
	0x45,	/* KEY_NumLock */	0x46,	/* KEY_ScrollLock */
	0x47,	/* KEY_KP_7 */		0x48,	/* KEY_KP_8 */
	0x49,	/* KEY_KP_9 */		0x4a,	/* KEY_KP_Minus */
	0x4b,	/* KEY_KP_4 */		0x4c,	/* KEY_KP_5 */
	0x4d,	/* KEY_KP_6 */		0x4e,	/* KEY_KP_Plus */
	0x4f,	/* KEY_KP_1 */		0x50,	/* KEY_KP_2 */
	0x51,	/* KEY_KP_3 */		0x52,	/* KEY_KP_0 */
	0x53,	/* KEY_KP_Decimal */	0x54,	/* KEY_SysReqest */
	0x00,	/* 0x55 */		0x56,	/* KEY_Less */
	0x57,	/* KEY_F11 */		0x58,	/* KEY_F12 */
	0x66,	/* KEY_Home */		0x67,	/* KEY_Up */
	0x68,	/* KEY_PgUp */		0x69,	/* KEY_Left */
	0x5d,	/* KEY_Begin */		0x6a,	/* KEY_Right */
	0x6b,	/* KEY_End */		0x6c,	/* KEY_Down */
	0x6d,	/* KEY_PgDown */	0x6e,	/* KEY_Insert */
	0x6f,	/* KEY_Delete */	0x60,	/* KEY_KP_Enter */
	0x61,	/* KEY_RCtrl */		0x77,	/* KEY_Pause */
	0x63,	/* KEY_Print */		0x62,	/* KEY_KP_Divide */
	0x64,	/* KEY_AltLang */	0x65,	/* KEY_Break */
	0x00,	/* KEY_LMeta */		0x00,	/* KEY_RMeta */
	0x7A,	/* KEY_Menu/FOCUS_PF11*/0x00,	/* 0x6e */
	0x7B,	/* FOCUS_PF12 */	0x00,	/* 0x70 */
	0x00,	/* 0x71 */		0x00,	/* 0x72 */
	0x59,	/* FOCUS_PF2 */		0x78,	/* FOCUS_PF9 */
	0x00,	/* 0x75 */		0x00,	/* 0x76 */
	0x5A,	/* FOCUS_PF3 */		0x5B,	/* FOCUS_PF4 */
	0x5C,	/* FOCUS_PF5 */		0x5D,	/* FOCUS_PF6 */
	0x5E,	/* FOCUS_PF7 */		0x5F,	/* FOCUS_PF8 */
	0x7C,	/* JAP_86 */		0x79,	/* FOCUS_PF10 */
	0x00,	/* 0x7f */
};
#define NUM_AT2LNX (sizeof(at2lnx) / sizeof(at2lnx[0]))

#define NUM_CUSTOMKEYS	NR_KEYS

static void
readKernelMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap)
{
  KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
  KeySym        *k;
  int           i;
  int           maxkey;
  static unsigned char tbl[GLYPHS_PER_KEY] =
  {
	0,	/* unshifted */
	1,	/* shifted */
	0,	/* modeswitch unshifted */
	0	/* modeswitch shifted */
  };

  /*
   * Read the mapping from the kernel.
   * Since we're still using the XFree86 scancode->AT keycode mapping
   * routines, we need to convert the AT keycodes to Linux keycodes,
   * then translate the Linux keysyms into X keysyms.
   *
   * First, figure out which tables to use for the modeswitch columns
   * above, from the XF86Config fields.
   */
  tbl[2] = 8;	/* alt */
  tbl[3] = tbl[2] | 1;

  if (pKbd->CustomKeycodes) {
    k = map;
    maxkey = NUM_CUSTOMKEYS;
  }
  else {
    k = map+GLYPHS_PER_KEY;
    maxkey = NUM_AT2LNX;
  }

  for (i = 0; i < maxkey; ++i)
  {
    struct kbentry kbe;
    int j;

    if (pKbd->CustomKeycodes)
      kbe.kb_index = i;
    else
      kbe.kb_index = at2lnx[i];

    for (j = 0; j < GLYPHS_PER_KEY; ++j, ++k)
    {
      unsigned short kval;

      *k = NoSymbol;

      kbe.kb_table = tbl[j];
      if (
	  (!pKbd->CustomKeycodes && kbe.kb_index == 0) ||
	  ioctl(pInfo->fd, KDGKBENT, &kbe))
	continue;

      kval = KVAL(kbe.kb_value);
      switch (KTYP(kbe.kb_value))
      {
      case KT_LATIN:
      case KT_LETTER:
	*k = linux_to_x[kval];
	break;

      case KT_FN:
	if (kval <= 19)
	  *k = XK_F1 + kval;
	else switch (kbe.kb_value)
	{
	case K_FIND:
	  *k = XK_Home; /* or XK_Find */
	  break;
	case K_INSERT:
	  *k = XK_Insert;
	  break;
	case K_REMOVE:
	  *k = XK_Delete;
	  break;
	case K_SELECT:
	  *k = XK_End; /* or XK_Select */
	  break;
	case K_PGUP:
	  *k = XK_Prior;
	  break;
	case K_PGDN:
	  *k = XK_Next;
	  break;
	case K_HELP:
	  *k = XK_Help;
	  break;
	case K_DO:
	  *k = XK_Execute;
	  break;
	case K_PAUSE:
	  *k = XK_Pause;
	  break;
	case K_MACRO:
	  *k = XK_Menu;
	  break;
	default:
	  break;
	}
	break;

      case KT_SPEC:
	switch (kbe.kb_value)
	{
	case K_ENTER:
	  *k = XK_Return;
	  break;
	case K_BREAK:
	  *k = XK_Break;
	  break;
	case K_CAPS:
	  *k = XK_Caps_Lock;
	  break;
	case K_NUM:
	  *k = XK_Num_Lock;
	  break;
	case K_HOLD:
	  *k = XK_Scroll_Lock;
	  break;
	case K_COMPOSE:
          *k = XK_Multi_key;
	  break;
	default:
	  break;
	}
	break;

      case KT_PAD:
	switch (kbe.kb_value)
	{
	case K_PPLUS:
	  *k = XK_KP_Add;
	  break;
	case K_PMINUS:
	  *k = XK_KP_Subtract;
	  break;
	case K_PSTAR:
	  *k = XK_KP_Multiply;
	  break;
	case K_PSLASH:
	  *k = XK_KP_Divide;
	  break;
	case K_PENTER:
	  *k = XK_KP_Enter;
	  break;
	case K_PCOMMA:
	  *k = XK_KP_Separator;
	  break;
	case K_PDOT:
	  *k = XK_KP_Decimal;
	  break;
	case K_PPLUSMINUS:
	  *k = XK_KP_Subtract;
	  break;
	default:
	  if (kval <= 9)
	    *k = XK_KP_0 + kval;
	  break;
	}
	break;

      /*
       * KT_DEAD keys are for accelerated diacritical creation.
       */
      case KT_DEAD:
	switch (kbe.kb_value)
	  {
	  case K_DGRAVE:
	    *k = XK_dead_grave;
	    break;
	  case K_DACUTE:
	    *k = XK_dead_acute;
	    break;
	  case K_DCIRCM:
	    *k = XK_dead_circumflex;
	    break;
	  case K_DTILDE:
	    *k = XK_dead_tilde;
	    break;
	  case K_DDIERE:
	    *k = XK_dead_diaeresis;
	    break;
	  }
	break;

      case KT_CUR:
	switch (kbe.kb_value)
	{
	case K_DOWN:
	  *k = XK_Down;
	  break;
	case K_LEFT:
	  *k = XK_Left;
	  break;
	case K_RIGHT:
	  *k = XK_Right;
	  break;
	case K_UP:
	  *k = XK_Up;
	  break;
	}
	break;

      case KT_SHIFT:
	switch (kbe.kb_value)
	{
	case K_ALTGR:
	  *k = XK_Alt_R;
	  break;
	case K_ALT:
	  *k = (kbe.kb_index == 0x64 ?
		XK_Alt_R : XK_Alt_L);
	  break;
	case K_CTRL:
	  *k = (kbe.kb_index == 0x61 ?
		XK_Control_R : XK_Control_L);
	  break;
        case K_CTRLL:
	  *k = XK_Control_L;
	  break;
        case K_CTRLR:
	  *k = XK_Control_R;
	  break;
	case K_SHIFT:
	  *k = (kbe.kb_index == 0x36 ?
		XK_Shift_R : XK_Shift_L);
	  break;
        case K_SHIFTL:
	  *k = XK_Shift_L;
	  break;
        case K_SHIFTR:
	  *k = XK_Shift_R;
	  break;
	default:
	  break;
	}
	break;

      /*
       * KT_ASCII keys accumulate a 3 digit decimal number that gets
       * emitted when the shift state changes. We can't emulate that.
       */
      case KT_ASCII:
	break;

      case KT_LOCK:
	if (kbe.kb_value == K_SHIFTLOCK)
	  *k = XK_Shift_Lock;
	break;

      default:
	break;
      }
    }

    if (k[-1] == k[-2]) k[-1] = NoSymbol;
    if (k[-2] == k[-3]) k[-2] = NoSymbol;
    if (k[-3] == k[-4]) k[-3] = NoSymbol;
    if (k[-4] == k[-2] && k[-3] == k[-1]) k[-2] = k[-1] = NoSymbol;
    if (k[-1] == k[-4] && k[-2] == k[-3] && k[-2] == NoSymbol) k[-1] =NoSymbol;
  }

  if (!pKbd->CustomKeycodes)
    return;

  /*
   * Find the Mapping for the special server functions
   */
  pKbd->specialMap = (TransMapPtr) xcalloc(NUM_CUSTOMKEYS, 1);
  if (pKbd->specialMap != NULL) {
      pKbd->specialMap->end = NUM_CUSTOMKEYS;
      pKbd->specialMap->map = (unsigned char*) xcalloc(NUM_CUSTOMKEYS, 1);
      if (pKbd->specialMap == NULL) {
      	  xfree(pKbd->specialMap);
      	  pKbd->specialMap = NULL;
      }
  }
  if (pKbd->specialMap == NULL) {
      xf86Msg(X_ERROR, "%s can't allocate \"special map\"\n", pInfo->name);
      return;
  }

  for (i = 0; i < NUM_CUSTOMKEYS; ++i) {
    struct kbentry kbe;
    int special = 0;

    kbe.kb_index = i;
    kbe.kb_table = 0; /* Plain map */
    if (!ioctl(pInfo->fd, KDGKBENT, &kbe))
      switch (kbe.kb_value) {
	case K(KT_LATIN,0x7f):	/* This catches DEL too... But who cares? */
	  special = KEY_BackSpace;
	  break;
	case K_PMINUS:
	  special = KEY_KP_Minus;
	  break;
	case K_PPLUS:
	  special = KEY_KP_Plus;
	  break;
	case K_F1:
	  special = KEY_F1;
	  break;
	case K_F2:
	  special = KEY_F2;
	  break;
	case K_F3:
	  special = KEY_F3;
	  break;
	case K_F4:
	  special = KEY_F4;
	  break;
	case K_F5:
	  special = KEY_F5;
	  break;
	case K_F6:
	  special = KEY_F6;
	  break;
	case K_F7:
	  special = KEY_F7;
	  break;
	case K_F8:
	  special = KEY_F8;
	  break;
	case K_F9:
	  special = KEY_F9;
	  break;
	case K_F10:
	  special = KEY_F10;
	  break;
	case K_F11:
	  special = KEY_F11;
	  break;
	case K_F12:
	  special = KEY_F12;
	  break;
	case K_ALT:
	  special = KEY_Alt;
	  break;
	case K_ALTGR:
	  special = KEY_AltLang;
	  break;
	case K_CONS:
	  special = KEY_SysReqest;
	  break;
      }
    pKbd->specialMap->map[i] = special;
  }
}

--- NEW FILE: lnx_agp.c ---
/*
 * Abstraction of the AGP GART interface.
 *
 * This version is for both Linux and FreeBSD.
 *
 * Copyright © 2000 VA Linux Systems, Inc.
 * Copyright © 2001 The XFree86 Project, Inc.
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c,v 3.11 2003/04/03 22:47:42 dawes Exp $ */

#include <X11/X.h>
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "xf86OSpriv.h"

#if defined(linux)
#include <asm/ioctl.h>
#include <linux/agpgart.h>
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
#include <sys/agpio.h>
#endif

#ifndef AGP_DEVICE
#define AGP_DEVICE		"/dev/agpgart"
#endif
/* AGP page size is independent of the host page size. */
#ifndef AGP_PAGE_SIZE
#define AGP_PAGE_SIZE		4096
#endif
#define AGPGART_MAJOR_VERSION	0
#define AGPGART_MINOR_VERSION	99

static int gartFd = -1;
static int acquiredScreen = -1;
static Bool initDone = FALSE;
/*
 * Close /dev/agpgart.  This frees all associated memory allocated during
 * this server generation.
 */
Bool
xf86GARTCloseScreen(int screenNum)
{
	if(gartFd != -1) {
		close(gartFd);
		acquiredScreen = -1;
		gartFd = -1;
		initDone = FALSE;
	}
	return TRUE;
}

/*
 * Open /dev/agpgart.  Keep it open until xf86GARTCloseScreen is called.
 */
static Bool
GARTInit(int screenNum)
{
	struct _agp_info agpinf;

	if (initDone)
		return (gartFd != -1);

	initDone = TRUE;

	if (gartFd == -1)
		gartFd = open(AGP_DEVICE, O_RDWR, 0);
	else
		return FALSE;

	if (gartFd == -1) {
	    xf86DrvMsg(screenNum, X_ERROR,
		"GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
		strerror(errno));
	    return FALSE;
	}

	xf86AcquireGART(-1);
	/* Check the kernel driver version. */
	if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
		xf86DrvMsg(screenNum, X_ERROR,
			"GARTInit: AGPIOC_INFO failed (%s)\n", strerror(errno));
		close(gartFd);
		gartFd = -1;
		return FALSE;
	}
	xf86ReleaseGART(-1);

#if defined(linux)
	/* Per Dave Jones, every effort will be made to keep the 
	 * agpgart interface backwards compatible, so allow all 
	 * future versions.
	 */
	if (
#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
	    agpinf.version.major < AGPGART_MAJOR_VERSION ||
#endif
	    (agpinf.version.major == AGPGART_MAJOR_VERSION &&
	     agpinf.version.minor < AGPGART_MINOR_VERSION)) {
		xf86DrvMsg(screenNum, X_ERROR,
			"GARTInit: Kernel agpgart driver version is not current"
			" (%d.%d vs %d.%d)\n",
			agpinf.version.major, agpinf.version.minor,
			AGPGART_MAJOR_VERSION, AGPGART_MINOR_VERSION);
		close(gartFd);
		gartFd = -1;
		return FALSE;
	}
#endif
	
	return TRUE;
}

Bool
xf86AgpGARTSupported()
{
	return GARTInit(-1);
}

AgpInfoPtr
xf86GetAGPInfo(int screenNum)
{
	struct _agp_info agpinf;
	AgpInfoPtr info;

	if (!GARTInit(screenNum))
		return NULL;


	if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) {
		xf86DrvMsg(screenNum, X_ERROR,
			   "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
		return NULL;
	}

	if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
		xf86DrvMsg(screenNum, X_ERROR,
			   "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
			   strerror(errno));
		return NULL;
	}

	info->bridgeId = agpinf.bridge_id;
	info->agpMode = agpinf.agp_mode;
	info->base = agpinf.aper_base;
	info->size = agpinf.aper_size;
	info->totalPages = agpinf.pg_total;
	info->systemPages = agpinf.pg_system;
	info->usedPages = agpinf.pg_used;

	return info;
}

/*
 * XXX If multiple screens can acquire the GART, should we have a reference
 * count instead of using acquiredScreen?
 */

Bool
xf86AcquireGART(int screenNum)
{
	if (screenNum != -1 && !GARTInit(screenNum))
		return FALSE;

	if (screenNum == -1 || acquiredScreen != screenNum) {
		if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
			xf86DrvMsg(screenNum, X_WARNING,
				"xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
				strerror(errno));
			return FALSE;
		}
		acquiredScreen = screenNum;
	}
	return TRUE;
}

Bool
xf86ReleaseGART(int screenNum)
{
	if (screenNum != -1 && !GARTInit(screenNum))
		return FALSE;

	if (acquiredScreen == screenNum) {
		/*
		 * The FreeBSD agp driver removes allocations on release.
		 * The Linux driver doesn't.  xf86ReleaseGART() is expected
		 * to give up access to the GART, but not to remove any
		 * allocations.
		 */
#if !defined(linux)
	    if (screenNum == -1)
#endif
	    {
		if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
			xf86DrvMsg(screenNum, X_WARNING,
				"xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
				strerror(errno));
			return FALSE;
		}
		acquiredScreen = -1;
	    }
	    return TRUE;
	}
	return FALSE;
}

int
xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
			unsigned long *physical)
{
	struct _agp_allocate alloc;
	int pages;

	/*
	 * Allocates "size" bytes of GART memory (rounds up to the next
	 * page multiple) or type "type".  A handle (key) for the allocated
	 * memory is returned.  On error, the return value is -1.
	 */

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return -1;

	pages = (size / AGP_PAGE_SIZE);
	if (size % AGP_PAGE_SIZE != 0)
		pages++;

	/* XXX check for pages == 0? */

	alloc.pg_count = pages;
	alloc.type = type;

	if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
			   "allocation of %d pages failed\n\t(%s)\n", pages,
			   strerror(errno));
		return -1;
	}

	if (physical)
		*physical = alloc.physical;

	return alloc.key;
}


/* Bind GART memory with "key" at "offset" */
Bool
xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
{
	struct _agp_bind bind;
	int pageOffset;

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	if (acquiredScreen != screenNum) {
		xf86DrvMsg(screenNum, X_ERROR,
		      "xf86BindGARTMemory: AGP not acquired by this screen\n");
		return FALSE;
	}

	if (offset % AGP_PAGE_SIZE != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
			   "offset (0x%lx) is not page-aligned (%d)\n",
			   offset, AGP_PAGE_SIZE);
		return FALSE;
	}
	pageOffset = offset / AGP_PAGE_SIZE;

	xf86DrvMsgVerb(screenNum, X_INFO, 3,
		       "xf86BindGARTMemory: bind key %d at 0x%08lx "
		       "(pgoffset %d)\n", key, offset, pageOffset);

	bind.pg_start = pageOffset;
	bind.key = key;

	if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
			   "binding of gart memory with key %d\n"
			   "\tat offset 0x%lx failed (%s)\n",
			   key, offset, strerror(errno));
		return FALSE;
	}

	return TRUE;
}


/* Unbind GART memory with "key" */
Bool
xf86UnbindGARTMemory(int screenNum, int key)
{
	struct _agp_unbind unbind;

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	if (acquiredScreen != screenNum) {
		xf86DrvMsg(screenNum, X_ERROR,
		    "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
		return FALSE;
	}

	unbind.priority = 0;
	unbind.key = key;

	if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
			   "unbinding of gart memory with key %d "
			   "failed (%s)\n", key, strerror(errno));
		return FALSE;
	}

	xf86DrvMsgVerb(screenNum, X_INFO, 3,
		       "xf86UnbindGARTMemory: unbind key %d\n", key);

	return TRUE;
}


/* XXX Interface may change. */
Bool
xf86EnableAGP(int screenNum, CARD32 mode)
{
	agp_setup setup;

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	setup.agp_mode = mode;
	if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
			   "AGPIOC_SETUP with mode %ld failed (%s)\n",
			   (unsigned long)mode, strerror(errno));
		return FALSE;
	}

	return TRUE;
}


--- NEW FILE: lnx_apm.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_apm.c,v 3.12 2001/12/24 22:54:31 dawes Exp $ */

#include <X11/X.h>
#include "os.h"
#include "xf86.h"
#include "xf86Priv.h"
#define XF86_OS_PRIVS
#include "xf86_OSproc.h"
#include "lnx.h"
#include <linux/apm_bios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
 
#define APM_PROC   "/proc/apm"
#define APM_DEVICE "/dev/apm_bios"

#ifndef APM_STANDBY_FAILED
# define APM_STANDBY_FAILED 0xf000
#endif
#ifndef APM_SUSPEND_FAILED
# define APM_SUSPEND_FAILED 0xf001
#endif

static void lnxCloseAPM(void);
static pointer APMihPtr = NULL;

static struct {
    apm_event_t apmLinux;
    pmEvent xf86;
} LinuxToXF86[] = {
    { APM_SYS_STANDBY, XF86_APM_SYS_STANDBY },
    { APM_SYS_SUSPEND, XF86_APM_SYS_SUSPEND },
    { APM_NORMAL_RESUME, XF86_APM_NORMAL_RESUME },
    { APM_CRITICAL_RESUME, XF86_APM_CRITICAL_RESUME },
    { APM_LOW_BATTERY, XF86_APM_LOW_BATTERY },
    { APM_POWER_STATUS_CHANGE, XF86_APM_POWER_STATUS_CHANGE },
    { APM_UPDATE_TIME, XF86_APM_UPDATE_TIME },
    { APM_CRITICAL_SUSPEND, XF86_APM_CRITICAL_SUSPEND },
    { APM_USER_STANDBY, XF86_APM_USER_STANDBY },
    { APM_USER_SUSPEND, XF86_APM_USER_SUSPEND },
    { APM_STANDBY_RESUME, XF86_APM_STANDBY_RESUME },
#if defined(APM_CAPABILITY_CHANGED)
    { APM_CAPABILITY_CHANGED, XF86_CAPABILITY_CHANGED },
#endif
#if 0
    { APM_STANDBY_FAILED, XF86_APM_STANDBY_FAILED },
    { APM_SUSPEND_FAILED, XF86_APM_SUSPEND_FAILED }
#endif
};

#define numApmEvents (sizeof(LinuxToXF86) / sizeof(LinuxToXF86[0]))

/*
 * APM is still under construction.
 * I'm not sure if the places where I initialize/deinitialize
 * apm is correct. Also I don't know what to do in SETUP state.
 * This depends if wakeup gets called in this situation, too.
 * Also we need to check if the action that is taken on an
 * event is reasonable.
 */
static int
lnxPMGetEventFromOs(int fd, pmEvent *events, int num)
{
    int i,j,n;
    apm_event_t linuxEvents[8];

    if ((n = read( fd, linuxEvents, num * sizeof(apm_event_t) )) == -1)
	return 0;
    n /= sizeof(apm_event_t);
    if (n > num)
	n = num;
    for (i = 0; i < n; i++) {
	for (j = 0; j < numApmEvents; j++)
	    if (LinuxToXF86[j].apmLinux == linuxEvents[i]) {
		events[i] = LinuxToXF86[j].xf86;
		break;
	    }
	if (j == numApmEvents)
	    events[i] = XF86_APM_UNKNOWN;
    }
    return n;
}

static pmWait
lnxPMConfirmEventToOs(int fd, pmEvent event)
{
    switch (event) {
    case XF86_APM_SYS_STANDBY:
    case XF86_APM_USER_STANDBY:
        if (ioctl( fd, APM_IOC_STANDBY, NULL ))
	    return PM_FAILED;
	return PM_CONTINUE;
    case XF86_APM_SYS_SUSPEND:
    case XF86_APM_CRITICAL_SUSPEND:
    case XF86_APM_USER_SUSPEND:
	if (ioctl( fd, APM_IOC_SUSPEND, NULL )) {
	    if (errno == EBUSY)
		return PM_CONTINUE;
	    else
		return PM_FAILED;
	}
	return PM_CONTINUE;
    case XF86_APM_STANDBY_RESUME:
    case XF86_APM_NORMAL_RESUME:
    case XF86_APM_CRITICAL_RESUME:
    case XF86_APM_STANDBY_FAILED:
    case XF86_APM_SUSPEND_FAILED:
	return PM_CONTINUE;
    default:
	return PM_NONE;
    }
}

PMClose
xf86OSPMOpen(void)
{
    int fd, pfd;    

#ifdef DEBUG
    ErrorF("APM: OSPMOpen called\n");
#endif
    if (APMihPtr || !xf86Info.pmFlag)
	return NULL;
   
#ifdef DEBUG
    ErrorF("APM: Opening device\n");
#endif
    if ((fd = open( APM_DEVICE, O_RDWR )) > -1) {
	if (access( APM_PROC, R_OK ) ||
	    ((pfd = open( APM_PROC, O_RDONLY)) == -1)) {
	    xf86MsgVerb(X_WARNING,3,"Cannot open APM (%s) (%s)\n",
			APM_PROC, strerror(errno));
	    close(fd);
	    return NULL;
	} else
	    close(pfd);
	xf86PMGetEventFromOs = lnxPMGetEventFromOs;
	xf86PMConfirmEventToOs = lnxPMConfirmEventToOs;
	APMihPtr = xf86AddInputHandler(fd,xf86HandlePMEvents,NULL);
	xf86MsgVerb(X_INFO,3,"Open APM successful\n");
	return lnxCloseAPM;
    }
    xf86MsgVerb(X_WARNING,3,"Open APM failed (%s) (%s)\n", APM_DEVICE,
		strerror(errno));
    return NULL;
}

static void
lnxCloseAPM(void)
{
    int fd;
    
#ifdef DEBUG
   ErrorF("APM: Closing device\n");
#endif
    if (APMihPtr) {
	fd = xf86RemoveInputHandler(APMihPtr);
	close(fd);
	APMihPtr = NULL;
    }
}


--- NEW FILE: lnx_axp.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_axp.c,v 1.3 2001/02/15 11:03:56 alanh Exp $ */

#include <stdio.h>
#include <X11/X.h>
#include "os.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86Axp.h"

axpDevice lnxGetAXP(void);

typedef struct 
 { char* sysName; 
   char* sysVari; 
   char* cpu; 
   axpDevice sys; }
AXP;

static AXP axpList[] = {
  { "Tsunami", NULL, NULL, TSUNAMI },
  { "Eiger", NULL, NULL, TSUNAMI }, 
  {"Noname", NULL, NULL, LCA },
  { "AlphaBook1", NULL, NULL, LCA }, 
  {"EB66", NULL, NULL, LCA}, 
  {"EB64+",NULL,NULL, APECS}, 
  {"Noritake",NULL,"EV5",CIA},
  {"Noritake",NULL,"EV56",CIA},
  {"Noritake",NULL,NULL,APECS},
  {"XL",NULL,NULL,APECS},              
  {"Avanti",NULL,NULL,APECS},
  {"Mikasa",NULL,"EV5",CIA},
  {"Mikasa",NULL,"EV56",CIA},
  {"Mikasa",NULL,NULL,APECS},
  {"EB164","EB164",NULL,CIA},
  {"EB164","PC164", NULL,CIA},
  {"EB164","LX164",NULL, PYXIS},
  {"EB164","SX164",NULL, PYXIS},
  {"EB164","RX164",NULL, POLARIS},
  {"Alcor",NULL,NULL,CIA},
  {"Takara",NULL,NULL,CIA},
  {"Sable",NULL, "EV5",T2_GAMMA},
  {"Sable",NULL,"EV56",T2_GAMMA},
  {"Sable",NULL,NULL,T2},
  {"Rawhide",NULL,NULL,MCPCIA},
  {"Jensen",NULL,NULL,JENSEN},
  {"Miata",NULL,NULL,PYXIS_CIA},
  {"Ruffian",NULL,NULL,PYXIS_CIA},
  {"Nautilus",NULL,NULL,IRONGATE},
  {NULL,NULL,NULL,NONE}
};


axpDevice
lnxGetAXP(void)
{
  FILE *file;
  int count = 0;
  char res[256];
  char cpu[255];
  char systype[255];
  char sysvari[255];
  if (!(file = fopen("/proc/cpuinfo","r")))
    return SYS_NONE;
  do {
    if (!fgets(res,0xff,file)) return SYS_NONE;
    switch (count) {
    case 1:
      sscanf(res, "cpu model : %s",cpu);
#ifdef DEBUG
      ErrorF("CPU %s\n",cpu);
#endif
      break;
    case 5:
      sscanf(res, "system type : %s",systype);
#ifdef DEBUG
      ErrorF("system type : %s\n",systype);
#endif
      break;
    case 6:
      sscanf(res, "system variation : %s",sysvari);
#ifdef DEBUG
      ErrorF("system variation: %s\n",sysvari);
#endif
      break;
    }
    count++;
  } while (count < 8);
  
  fclose(file);
  
  count = 0;
  
  do {
    if (!axpList[count].sysName || !strcmp(axpList[count].sysName,systype)) {
      if (axpList[count].sysVari && strcmp(axpList[count].sysVari,sysvari)) {
	count++;
	continue;
      };
      if (axpList[count].cpu && strcmp(axpList[count].cpu,cpu)) {
	count++;
	continue;
      }
      return axpList[count].sys;
    } 
	count++;
  } while (1);
}

/*
 * pciconfig_iobase wrappers and dynamic i/o selection
 */
#include <linux/unistd.h>
#include <asm/pci.h>
#include <errno.h>

/* glibc versions (single hose only) */
extern void _outb(char val, unsigned long port);
extern void _outw(short val, unsigned long port);
extern void _outl(int val, unsigned long port);
extern unsigned int _inb(unsigned long port);
extern unsigned int _inw(unsigned long port);
extern unsigned int _inl(unsigned long port);

extern void _dense_outb(char, unsigned long);
extern void _dense_outw(short, unsigned long);
extern void _dense_outl(int, unsigned long);
extern unsigned int _dense_inb(unsigned long);
extern unsigned int _dense_inw(unsigned long);
extern unsigned int _dense_inl(unsigned long);

void (*_alpha_outb)(char, unsigned long) = _outb;
void (*_alpha_outw)(short, unsigned long) = _outw;
void (*_alpha_outl)(int, unsigned long) = _outl;
unsigned int (*_alpha_inb)(unsigned long) = _inb;
unsigned int (*_alpha_inw)(unsigned long) = _inw;
unsigned int (*_alpha_inl)(unsigned long) = _inl;

static long _alpha_iobase_query(unsigned, int, int, int);
long (*_iobase)(unsigned, int, int, int) = _alpha_iobase_query;

static long
_alpha_iobase(unsigned flags, int hose, int bus, int devfn)
{
#ifdef __NR_pciconfig_iobase
  if (bus < 0) {
    bus = hose;
    flags |= IOBASE_FROM_HOSE;
  }

  return syscall(__NR_pciconfig_iobase, flags, bus, devfn);
#else
  return -ENOSYS
#endif
}

static long
_alpha_iobase_legacy(unsigned flags, int hose, int bus, int devfn)
{
  if (hose > 0) return -ENODEV;
  if (flags & IOBASE_DENSE_MEM) return _bus_base();
  if (flags & IOBASE_SPARSE_MEM) return _bus_base_sparse();
  return 0;
}

static long 
_alpha_iobase_query(unsigned flags, int hose, int bus, int devfn)
{
  /*
   * Only use iobase if the syscall is supported *and* it's
   * a dense io system
   */
  if (_alpha_iobase(IOBASE_DENSE_IO, 0, 0, 0) > 0) {
    /*
     * The syscall worked and it's a dense io system - take over the
     * io subsystem
     */
    _iobase = _alpha_iobase;

#ifndef INCLUDE_XF86_NO_DOMAIN
    /* 
     * Only take over the inx/outx functions if this is a dense I/O
     * system *and* addressing domains are being used. The dense I/O
     * routines expect I/O to be mapped (as done in xf86MapDomainIO)
     */
    _alpha_outb = _dense_outb;
    _alpha_outw = _dense_outw;
    _alpha_outl = _dense_outl;
    _alpha_inb = _dense_inb;
    _alpha_inw = _dense_inw;
    _alpha_inl = _dense_inl;
#endif /* !INCLUDE_XF86_NO_DOMAIN */
  } else _iobase = _alpha_iobase_legacy;

  return _iobase(flags, hose, bus, devfn);
}


--- NEW FILE: lnx_ev56.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_ev56.c,v 3.5 2000/02/17 13:45:49 dawes Exp $ */

#include <X11/X.h>
#include "input.h"
#include "scrnintstr.h"
#include "compiler.h"

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

int readDense8(pointer Base, register unsigned long Offset);
int readDense16(pointer Base, register unsigned long Offset);
int readDense32(pointer Base, register unsigned long Offset);
void
writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
void
writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
void
writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
void
writeDense8(int Value, pointer Base, register unsigned long Offset);
void
writeDense16(int Value, pointer Base, register unsigned long Offset);
void
writeDense32(int Value, pointer Base, register unsigned long Offset);

int
readDense8(pointer Base, register unsigned long Offset)
{
    mem_barrier();
    return *(volatile CARD8*) ((unsigned long)Base+(Offset));
}

int
readDense16(pointer Base, register unsigned long Offset)
{
    mem_barrier();
    return *(volatile CARD16*) ((unsigned long)Base+(Offset));
}

int
readDense32(pointer Base, register unsigned long Offset)
{
    mem_barrier();
    return *(volatile CARD32*)((unsigned long)Base+(Offset));
}

void
writeDenseNB8(int Value, pointer Base, register unsigned long Offset)
{
    *(volatile CARD8*)((unsigned long)Base+(Offset)) = Value;
}

void
writeDenseNB16(int Value, pointer Base, register unsigned long Offset)
{
    *(volatile CARD16*)((unsigned long)Base + (Offset)) = Value;
}

void
writeDenseNB32(int Value, pointer Base, register unsigned long Offset)
{
    *(volatile CARD32*)((unsigned long)Base+(Offset)) = Value;
}

void
writeDense8(int Value, pointer Base, register unsigned long Offset)
{
    write_mem_barrier();
    *(volatile CARD8 *)((unsigned long)Base+(Offset)) = Value;
}

void
writeDense16(int Value, pointer Base, register unsigned long Offset)
{
    write_mem_barrier();
    *(volatile CARD16 *)((unsigned long)Base+(Offset)) = Value;
}

void
writeDense32(int Value, pointer Base, register unsigned long Offset)
{
    write_mem_barrier();
    *(volatile CARD32 *)((unsigned long)Base+(Offset)) = Value;
}


#ifndef INCLUDE_XF86_NO_DOMAIN

void
_dense_outb(char val, unsigned long port)
{
  if ((port & ~0xffff) == 0) return _outb(val, port);

  write_mem_barrier();
  *(volatile CARD8 *)port = val;
}

void
_dense_outw(short val, unsigned long port)
{
  if ((port & ~0xffff) == 0) return _outw(val, port);

  write_mem_barrier();
  *(volatile CARD16 *)port = val;
}

void
_dense_outl(int val, unsigned long port)
{
  if ((port & ~0xffff) == 0) return _outl(val, port);

  write_mem_barrier();
  *(volatile CARD32 *)port = val;
}

unsigned int
_dense_inb(unsigned long port)
{
  if ((port & ~0xffff) == 0) return _inb(port);

  mem_barrier();
  return *(volatile CARD8 *)port;
}

unsigned int
_dense_inw(unsigned long port)
{
  if ((port & ~0xffff) == 0) return _inw(port);

  mem_barrier();
  return *(volatile CARD16 *)port;
}

unsigned int
_dense_inl(unsigned long port)
{
  if ((port & ~0xffff) == 0) return _inl(port);

  mem_barrier();
  return *(volatile CARD32 *)port;
}

#endif /* !INCLUDE_XF86_NO_DOMAIN */


--- NEW FILE: lnx_init.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c,v 1.1.4.2.4.2 2004/03/04 20:16:46 kaleb Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c,v 3.14 2001/10/31 22:50:30 tsi Exp $ */
/*
 * Copyright 1992 by Orest Zborowski <obz at Kodak.com>
 * Copyright 1993 by David Wexelblat <dwex at goblin.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 Orest Zborowski and David Wexelblat
 * not be used in advertising or publicity pertaining to distribution of
 * the software without specific, written prior permission.  Orest Zborowski
 * and David Wexelblat make no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without express or
 * implied warranty.
 *
 * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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: lnx_init.c /main/7 1996/10/23 18:46:30 kaleb $ */

#include <X11/X.h>
#include <X11/Xmd.h>

#include "compiler.h"

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

#include <sys/stat.h>

#ifdef USE_DEV_FB
extern char *getenv(const char *);
#include <linux/fb.h>
char *fb_dev_name;
#endif

static Bool KeepTty = FALSE;
static int VTnum = -1;
static int activeVT = -1;

static int vtPermSave[4];
static char vtname[11];

static int
saveVtPerms(void)
{
    /* We need to use stat to get permissions. */
    struct stat svtp;

    /* Do them numerically ordered, hard coded tty0 first. */
    if (stat("/dev/tty0", &svtp) != 0)
	return 0;
    vtPermSave[0] = (int)svtp.st_uid;
    vtPermSave[1] = (int)svtp.st_gid;

    /* Now check the console we are dealing with. */
    if (stat(vtname, &svtp) != 0)
	return 0;
    vtPermSave[2] = (int)svtp.st_uid;
    vtPermSave[3] = (int)svtp.st_gid;

    return 1;
}

static void
restoreVtPerms(void)
{
    /* Set the terminal permissions back to before we started. */
    chown("/dev/tty0", vtPermSave[0], vtPermSave[1]);
    chown(vtname, vtPermSave[2], vtPermSave[3]);
}

void
xf86OpenConsole(void)
{
    int i, fd = -1;
    int result;
    struct vt_mode VT;
    struct vt_stat vts;
    MessageType from = X_PROBED;
#ifdef USE_DEV_FB
    struct fb_var_screeninfo var;
    int fbfd;
#endif
    char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
    char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };

    if (serverGeneration == 1)
    {
	/* check if we're run with euid==0 */
	if (geteuid() != 0)
	{
	    FatalError("xf86OpenConsole: Server must be suid root\n");
	}

	/*
	 * setup the virtual terminal manager
	 */
	if (VTnum != -1) {
	    xf86Info.vtno = VTnum;
	    from = X_CMDLINE;
	} else {
	    i=0;
	    while (tty0[i] != NULL)
	    {
		if ((fd = open(tty0[i],O_WRONLY,0)) >= 0)
		  break;
		i++;
	    }
	    if (fd < 0)
		FatalError(
		    "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
		    strerror(errno));
	    if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
		(xf86Info.vtno == -1)) {
		FatalError("xf86OpenConsole: Cannot find a free VT\n");
	    }
	    close(fd);
	}

#ifdef USE_DEV_FB
	fb_dev_name=getenv("FRAMEBUFFER");
	if (!fb_dev_name)
	    fb_dev_name="/dev/fb0current";
	if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
	    FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
	fb_dev_name, strerror(errno));
	if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var))
	    FatalError("xf86OpenConsole: Unable to get screen info\n");
#endif
	xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);

	if (!KeepTty) {
	    setpgrp();
	}

        i=0;
        while (vcs[i] != NULL)
        {
            sprintf(vtname, vcs[i], xf86Info.vtno); /* /dev/tty1-64 */
     	    if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) >= 0)
		break;
            i++;
        }

	if (xf86Info.consoleFd < 0) {
	    FatalError("xf86OpenConsole: Cannot open virtual console %d (%s)\n",
		       xf86Info.vtno, strerror(errno));
	}

	/*
	 * Grab the vt ownership before we overwrite it.
	 * Hard coded /dev/tty0 into this function as well for below.
	 */
	if (!saveVtPerms()){
	  xf86Msg(X_WARNING,
		  "xf86OpenConsole: Could not save ownership of VT\n");
	}

	/* change ownership of the vt */
	chown(vtname, getuid(), getgid());

	/*
	 * the current VT device we're running on is not "console", we want
	 * to grab all consoles too
	 *
	 * Why is this needed??
	 */
	chown("/dev/tty0", getuid(), getgid());

	/*
	 * Linux doesn't switch to an active vt after the last close of a vt,
	 * so we do this ourselves by remembering which is active now.
	 */
	if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) == 0)
	{
	    activeVT = vts.v_active;
	}

	if (!KeepTty)
	{
	    /*
	     * Detach from the controlling tty to avoid char loss
	     */
	    if ((i = open("/dev/tty",O_RDWR)) >= 0)
	    {
		ioctl(i, TIOCNOTTY, 0);
		close(i);
	    }
	}

	/*
	 * now get the VT
	 */
	SYSCALL(result = ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
	if (result != 0)
	{
	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
	}
	SYSCALL(result =
		  ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno));
	if (result != 0)
	{
	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
	}
	SYSCALL(result = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
	if (result < 0)
	{
	    FatalError("xf86OpenConsole: VT_GETMODE failed\n");
	}

	signal(SIGUSR1, xf86VTRequest);

	VT.mode = VT_PROCESS;
	VT.relsig = SIGUSR1;
	VT.acqsig = SIGUSR1;
	if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
	{
	    FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
	}
	if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
	{
	    FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
	}

	/* we really should have a InitOSInputDevices() function instead
	 * of Init?$#*&Device(). So I just place it here */
	
#ifdef USE_DEV_FB
	/* copy info to new console */
	var.yoffset=0;
	var.xoffset=0;
	if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
	    FatalError("Unable to set screen info\n");
	close(fbfd);
#endif
    }
    else
    {
	/* serverGeneration != 1 */
	/*
	 * now get the VT
	 */
	SYSCALL(result = ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
	if (result != 0)
	{
	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
	}
	SYSCALL(result =
		ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno));
	if (result != 0)
	{
	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
	}
    }
    return;
}

void
xf86CloseConsole()
{
    struct vt_mode   VT;

#if 0
    ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno);
    ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0);
#endif
    ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT);  /* Back to text mode ... */
    if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
    {
	VT.mode = VT_AUTO;
	ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
    }
    /*
     * Perform a switch back to the active VT when we were started
     */
    if (activeVT >= 0)
    {
	ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT);
	activeVT = -1;
    }
    close(xf86Info.consoleFd);                /* make the vt-manager happy */

    restoreVtPerms();		/* restore the permissions */

    return;
}

int
xf86ProcessArgument(int argc, char *argv[], int i)
{
	/*
	 * Keep server from detaching from controlling tty.  This is useful
	 * when debugging (so the server can receive keyboard signals.
	 */
	if (!strcmp(argv[i], "-keeptty"))
	{
		KeepTty = TRUE;
		return(1);
	}
	if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
	{
		if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
		{
			UseMsg();
			VTnum = -1;
			return(0);
		}
		return(1);
	}
	return(0);
}

void
xf86UseMsg()
{
	ErrorF("vtXX                   use the specified VT number\n");
	ErrorF("-keeptty               ");
	ErrorF("don't detach controlling tty (for debugging only)\n");
	return;
}

--- NEW FILE: lnx_io.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c,v 3.25 2003/08/19 17:32:34 tsi Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c,v 1.1.4.2.6.2 2004/03/04 17:48:09 eich Exp $ */
/*
 * Copyright 1992 by Orest Zborowski <obz at Kodak.com>
 * Copyright 1993 by David Dawes <dawes at 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 Orest Zborowski and David Dawes 
 * not be used in advertising or publicity pertaining to distribution of 
 * the software without specific, written prior permission.  Orest Zborowski
 * and David Dawes make no representations about the suitability of this 
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 *
 * OREST ZBOROWSKI AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD 
 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI 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: lnx_io.c /main/8 1996/10/19 18:06:28 kaleb $ */

#define NEED_EVENTS
#include <X11/X.h>

#include "compiler.h"

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

#define KBC_TIMEOUT 250        /* Timeout in ms for sending to keyboard controller */

void
xf86SoundKbdBell(int loudness, int pitch, int duration)
{
	if (loudness && pitch)
	{
		ioctl(xf86Info.consoleFd, KDMKTONE,
		      ((1193190 / pitch) & 0xffff) |
		      (((unsigned long)duration *
			loudness / 50) << 16));
	}
}

void
xf86SetKbdLeds(int leds)
{
 	ioctl(xf86Info.consoleFd, KDSETLED, leds);
}

int
xf86GetKbdLeds()
{
	int leds = 0;

 	ioctl(xf86Info.consoleFd, KDGETLED, &leds);
	return(leds);
}

/* kbd rate stuff based on kbdrate.c from Rik Faith <faith at cs.unc.edu> et.al.
 * from util-linux-2.9t package */

#include <linux/kd.h>
#include <linux/version.h>
#ifdef __sparc__
#include <asm/param.h>
#include <asm/kbio.h>
#endif

/* Deal with spurious kernel header change */
#if defined(LINUX_VERSION_CODE) && defined(KERNEL_VERSION)
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,42)
#  define rate period
# endif
#endif

static int
KDKBDREP_ioctl_ok(int rate, int delay) {
#if defined(KDKBDREP) && !defined(__sparc__)
     /* This ioctl is defined in <linux/kd.h> but is not
	implemented anywhere - must be in some m68k patches. */
   struct kbd_repeat kbdrep_s;

   /* don't change, just test */
   kbdrep_s.rate = -1;
   kbdrep_s.delay = -1;
   if (ioctl( xf86Info.consoleFd, KDKBDREP, &kbdrep_s )) {
       return 0;
   }
   /* do the change */
   if (rate == 0)				/* switch repeat off */
     kbdrep_s.rate = 0;
   else
     kbdrep_s.rate  = 10000 / rate;		/* convert cps to msec */
   if (kbdrep_s.rate < 1)
     kbdrep_s.rate = 1;
   kbdrep_s.delay = delay;
   if (kbdrep_s.delay < 1)
     kbdrep_s.delay = 1;
   
   if (ioctl( xf86Info.consoleFd, KDKBDREP, &kbdrep_s )) {
     return 0;
   }

   return 1;			/* success! */
#else /* no KDKBDREP */
   return 0;
#endif /* KDKBDREP */
}

static int
KIOCSRATE_ioctl_ok(int rate, int delay) {
#ifdef KIOCSRATE
   struct kbd_rate kbdrate_s;
   int fd;

   fd = open("/dev/kbd", O_RDONLY);
   if (fd == -1) 
     return 0;   

   kbdrate_s.rate = (rate + 5) / 10;  /* must be integer, so round up */
   kbdrate_s.delay = delay * HZ / 1000;  /* convert ms to Hz */
   if (kbdrate_s.rate > 50)
     kbdrate_s.rate = 50;

   if (ioctl( fd, KIOCSRATE, &kbdrate_s )) {
       return 0;
   }

   close( fd );

   return 1;
#else /* no KIOCSRATE */
   return 0;
#endif /* KIOCSRATE */
}

#undef rate

void xf86SetKbdRepeat(char rad)
{
#ifdef __sparc__
  int         rate  = 500;     /* Default rate */
  int         delay = 200;     /* Default delay */
#else
  int         rate  = 300;     /* Default rate */
  int         delay = 250;     /* Default delay */
#endif

#if defined(__alpha__) || defined (__i386__) || defined(__ia64__)
  int i;
  int timeout;
  int         value = 0x7f;    /* Maximum delay with slowest rate */

  static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150,
			       133, 120, 109, 100, 92, 86, 80, 75, 67,
			       60, 55, 50, 46, 43, 40, 37, 33, 30, 27,
			       25, 23, 21, 20 };
#define RATE_COUNT (sizeof( valid_rates ) / sizeof( int ))

  static int valid_delays[] = { 250, 500, 750, 1000 };
#define DELAY_COUNT (sizeof( valid_delays ) / sizeof( int ))
#endif

  if (xf86Info.kbdRate >= 0) 
    rate = xf86Info.kbdRate * 10;
  if (xf86Info.kbdDelay >= 0)
    delay = xf86Info.kbdDelay;

  if(KDKBDREP_ioctl_ok(rate, delay)) 	/* m68k? */
    return;

  if(KIOCSRATE_ioctl_ok(rate, delay))	/* sparc? */
    return;

  if (xf86IsPc98())
    return;

#if defined(__alpha__) || defined (__i386__) || defined(__ia64__)

  /* The ioport way */

  for (i = 0; i < RATE_COUNT; i++)
    if (rate >= valid_rates[i]) {
      value &= 0x60;
      value |= i;
      break;
    }

  for (i = 0; i < DELAY_COUNT; i++)
    if (delay <= valid_delays[i]) {
      value &= 0x1f;
      value |= i << 5;
      break;
    }

  timeout = KBC_TIMEOUT;
  while (((inb(0x64) & 2) == 2) && --timeout)
       usleep(1000); /* wait */

  if (timeout == 0)
      return;

  outb(0x60, 0xf3);             /* set typematic rate */
  while (((inb(0x64) & 2) == 2) && --timeout)
       usleep(1000); /* wait */

  usleep(10000);
  outb(0x60, value);

#endif /* __alpha__ || __i386__ || __ia64__ */
}

static int kbdtrans;
static struct termios kbdtty;

void
xf86KbdInit()
{
	ioctl (xf86Info.consoleFd, KDGKBMODE, &kbdtrans);
	tcgetattr (xf86Info.consoleFd, &kbdtty);
}

int
xf86KbdOn()
{
	struct termios nTty;

#ifdef __powerpc__
	if (xf86Info.kbdCustomKeycodes)
		ioctl(xf86Info.consoleFd, KDSKBMODE, K_MEDIUMRAW);
	else
#endif
	ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW);

	nTty = kbdtty;
	nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
	nTty.c_oflag = 0;
	nTty.c_cflag = CREAD | CS8;
	nTty.c_lflag = 0;
	nTty.c_cc[VTIME]=0;
	nTty.c_cc[VMIN]=1;
	cfsetispeed(&nTty, 9600);
	cfsetospeed(&nTty, 9600);
	tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
	return(xf86Info.consoleFd);
}

int
xf86KbdOff()
{
	ioctl(xf86Info.consoleFd, KDSKBMODE, kbdtrans);
	tcsetattr(xf86Info.consoleFd, TCSANOW, &kbdtty);
	return(xf86Info.consoleFd);
}


--- NEW FILE: lnx_jstk.c ---
/* $XConsortium: lnx_jstk.c /main/7 1996/02/21 17:51:36 kaleb $ */
/* Id: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp */
/*
 * Copyright 1995 by Frederic Lepied, France. <fred at sugix.frmug.fr.net>       
 *                                                                            
 * 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  name of  Frederic   Lepied not  be  used  in
 * advertising or publicity pertaining to distribution of the software without
 * specific,  written      prior  permission.     Frederic  Lepied   makes  no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.                   
 *                                                                            
 * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
 * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
 * EVENT  SHALL FREDERIC  LEPIED 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.
 *
 */

/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c,v 3.8.2.1 1998/06/05 16:23:12 dawes Exp $ */

static const char rcs_id[] = "Id: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp";

#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define inline __inline__
#include <linux/joystick.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#ifdef XFree86LOADER
#include "xf86.h"
#include "xf86_ansic.h"
#endif

#if !defined(JSIOCGTIMELIMIT)
/* make 2.1.x joystick.h backward compatable */
#define JSIOCGTIMELIMIT		JS_GET_TIMELIMIT
#define JSIOCSTIMELIMIT		JS_SET_TIMELIMIT
#define js_status		JS_DATA_TYPE
#endif


/***********************************************************************
 *
 * xf86JoystickOn --
 *
 * open the device and init timeout according to the device value.
 *
 ***********************************************************************
 */

int
xf86JoystickOn(char *name, int *timeout, int *centerX, int *centerY)
{
  int			fd;
  struct js_status	js;
    
#ifdef DEBUG
  ErrorF("xf86JoystickOn %s\n", name);
#endif

  if ((fd = open(name, O_RDWR | O_NDELAY, 0)) < 0)
    {
      xf86Msg(X_WARNING, "Cannot open joystick '%s' (%s)\n", name,
		strerror(errno));
      return -1;
    }

  if (*timeout == 0) {
    if (ioctl (fd, JSIOCGTIMELIMIT, timeout) == -1) {
      Error("joystick JSIOCGTIMELIMIT ioctl");
    }
    else {
      xf86Msg(X_CONFIG, "Joystick: timeout value = %d\n", *timeout);
    }
  }
  else {
    if (ioctl(fd, JSIOCSTIMELIMIT, timeout) == -1) {
      Error("joystick JSIOCSTIMELIMIT ioctl");
    }
  }

  /* Assume the joystick is centred when this is called */
  read(fd, &js, JS_RETURN);
  if (*centerX < 0) {
    *centerX = js.x;
    xf86Msg(X_CONFIG, "Joystick: CenterX set to %d\n", *centerX);
  }
  if (*centerY < 0) {
    *centerY = js.y;
    xf86Msg(X_CONFIG, "Joystick: CenterY set to %d\n", *centerY);
  }

  return fd;
}

/***********************************************************************
 *
 * xf86JoystickInit --
 *
 * called when X device is initialized.
 *
 ***********************************************************************
 */

void
xf86JoystickInit()
{
	return;
}

/***********************************************************************
 *
 * xf86JoystickOff --
 *
 * close the handle.
 *
 ***********************************************************************
 */

int
xf86JoystickOff(int *fd, int doclose)
{
  int   oldfd;
  
  if (((oldfd = *fd) >= 0) && doclose) {
    close(*fd);
    *fd = -1;
  }
  return oldfd;
}

/***********************************************************************
 *
 * xf86JoystickGetState --
 *
 * return the state of buttons and the position of the joystick.
 *
 ***********************************************************************
 */

int
xf86JoystickGetState(int fd, int *x, int *y, int *buttons)
{
  struct js_status	js;
  int			status;
  
  status = read(fd, &js, JS_RETURN);
 
  if (status != JS_RETURN)
    {
      Error("Joystick read");      
      return 0;
    }
  
  *x = js.x;
  *y = js.y;
  *buttons = js.buttons;
  
  return 1;
}

#ifdef XFree86LOADER
/*
 * Entry point for XFree86 Loader
 */
void
linux_jstkModuleInit(pointer *data, INT32 *magic)
{
    *magic = MAGIC_DONE;
    *data = NULL;
}
#endif

/* end of lnx_jstk.c */

--- NEW FILE: lnx_kbd.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c,v 1.4 2003/11/03 05:11:52 tsi Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c,v 1.1.4.1.6.2 2004/03/04 17:48:09 eich Exp $ */

/*
 * Copyright (c) 2002 by The XFree86 Project, Inc.
 * Author: Ivan Pascal.
 *
 * Based on the code from lnx_io.c which is
 * Copyright 1992 by Orest Zborowski <obz at Kodak.com>
 * Copyright 1993 by David Dawes <dawes at xfree86.org>
 */

#define NEED_EVENTS
#include <X11/X.h>

#include "compiler.h"

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

#include "xf86Xinput.h"
#include "xf86OSKbd.h"
#include "atKeynames.h"
#include "lnx_kbd.h"

#define KBC_TIMEOUT 250        /* Timeout in ms for sending to keyboard controller */

static KbdProtocolRec protocols[] = {
   {"standard", PROT_STD },
   { NULL, PROT_UNKNOWN_KBD }
};

extern Bool VTSwitchEnabled;
#ifdef USE_VT_SYSREQ
extern Bool VTSysreqToggle;
#endif

static void
SoundBell(InputInfoPtr pInfo, int loudness, int pitch, int duration)
{
	if (loudness && pitch)
	{
		ioctl(pInfo->fd, KDMKTONE,
		      ((1193190 / pitch) & 0xffff) |
		      (((unsigned long)duration *
			loudness / 50) << 16));
	}
}

static void
SetKbdLeds(InputInfoPtr pInfo, int leds)
{
    int real_leds = 0;

#if defined (__sparc__)
    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
    if (pKbd->sunKbd) {
  	if (leds & 0x08) real_leds |= XLED1;
  	if (leds & 0x04) real_leds |= XLED3;
  	if (leds & 0x02) real_leds |= XLED4;
  	if (leds & 0x01) real_leds |= XLED2;
        leds = real_leds;
        real_leds = 0;
    }
#endif /* defined (__sparc__) */
#ifdef LED_CAP
    if (leds & XLED1)  real_leds |= LED_CAP;
    if (leds & XLED2)  real_leds |= LED_NUM;
    if (leds & XLED3)  real_leds |= LED_SCR;
#ifdef LED_COMP
    if (leds & XLED4)  real_leds |= LED_COMP;
#else
    if (leds & XLED4)  real_leds |= LED_SCR;
#endif
#endif
    ioctl(pInfo->fd, KDSETLED, real_leds);
}

static int
GetKbdLeds(InputInfoPtr pInfo)
{
    int real_leds, leds = 0;

    ioctl(pInfo->fd, KDGETLED, &real_leds);

    if (real_leds & LED_CAP) leds |= XLED1;
    if (real_leds & LED_NUM) leds |= XLED2;
    if (real_leds & LED_SCR) leds |= XLED3;

    return(leds);
}

/* kbd rate stuff based on kbdrate.c from Rik Faith <faith at cs.unc.edu> et.al.
 * from util-linux-2.9t package */

#include <linux/kd.h>
#include <linux/version.h>
#ifdef __sparc__
#include <asm/param.h>
#include <asm/kbio.h>
#endif

/* Deal with spurious kernel header change */
#if defined(LINUX_VERSION_CODE) && defined(KERNEL_VERSION)
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,42)
#  define rate period
# endif
#endif

static int
KDKBDREP_ioctl_ok(int rate, int delay) {
#if defined(KDKBDREP) && !defined(__sparc__)
     /* This ioctl is defined in <linux/kd.h> but is not
	implemented anywhere - must be in some m68k patches. */
   struct kbd_repeat kbdrep_s;

   /* don't change, just test */
   kbdrep_s.rate = -1;
   kbdrep_s.delay = -1;
   if (ioctl( xf86Info.consoleFd, KDKBDREP, &kbdrep_s )) {
       return 0;
   }

   /* do the change */
   if (rate == 0)				/* switch repeat off */
     kbdrep_s.rate = 0;
   else
     kbdrep_s.rate  = 10000 / rate;		/* convert cps to msec */
   if (kbdrep_s.rate < 1)
     kbdrep_s.rate = 1;
   kbdrep_s.delay = delay;
   if (kbdrep_s.delay < 1)
     kbdrep_s.delay = 1;
   
   if (ioctl( xf86Info.consoleFd, KDKBDREP, &kbdrep_s )) {
       return 0;
   }

   return 1;			/* success! */
#else /* no KDKBDREP */
   return 0;
#endif /* KDKBDREP */
}

static int
KIOCSRATE_ioctl_ok(int rate, int delay) {
#ifdef KIOCSRATE
   struct kbd_rate kbdrate_s;
   int fd;

   fd = open("/dev/kbd", O_RDONLY);
   if (fd == -1) 
     return 0;   

   kbdrate_s.rate = (rate + 5) / 10;  /* must be integer, so round up */
   kbdrate_s.delay = delay * HZ / 1000;  /* convert ms to Hz */
   if (kbdrate_s.rate > 50)
     kbdrate_s.rate = 50;

   if (ioctl( fd, KIOCSRATE, &kbdrate_s )) {
       return 0;
   }

   close( fd );

   return 1;
#else /* no KIOCSRATE */
   return 0;
#endif /* KIOCSRATE */
}

#undef rate

static void
SetKbdRepeat(InputInfoPtr pInfo, char rad)
{
  KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
  int i;
  int timeout;
  int         value = 0x7f;    /* Maximum delay with slowest rate */

#ifdef __sparc__
  int         rate  = 500;     /* Default rate */
  int         delay = 200;     /* Default delay */
#else
  int         rate  = 300;     /* Default rate */
  int         delay = 250;     /* Default delay */
#endif

  static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150,
			       133, 120, 109, 100, 92, 86, 80, 75, 67,
			       60, 55, 50, 46, 43, 40, 37, 33, 30, 27,
			       25, 23, 21, 20 };
#define RATE_COUNT (sizeof( valid_rates ) / sizeof( int ))

  static int valid_delays[] = { 250, 500, 750, 1000 };
#define DELAY_COUNT (sizeof( valid_delays ) / sizeof( int ))

  if (pKbd->rate >= 0) 
    rate = pKbd->rate * 10;
  if (pKbd->delay >= 0)
    delay = pKbd->delay;

  if(KDKBDREP_ioctl_ok(rate, delay)) 	/* m68k? */
    return;

  if(KIOCSRATE_ioctl_ok(rate, delay))	/* sparc? */
    return;

  if (xf86IsPc98())
    return;

#if defined(__alpha__) || defined (__i386__) || defined(__ia64__)

  /* The ioport way */

  for (i = 0; i < RATE_COUNT; i++)
    if (rate >= valid_rates[i]) {
      value &= 0x60;
      value |= i;
      break;
    }

  for (i = 0; i < DELAY_COUNT; i++)
    if (delay <= valid_delays[i]) {
      value &= 0x1f;
      value |= i << 5;
      break;
    }

  timeout = KBC_TIMEOUT;
  while (((inb(0x64) & 2) == 2) && --timeout)
       usleep(1000); /* wait */

  if (timeout == 0)
      return;

  outb(0x60, 0xf3);             /* set typematic rate */
  while (((inb(0x64) & 2) == 2) && --timeout)
       usleep(1000); /* wait */

  usleep(10000);
  outb(0x60, value);

#endif /* __alpha__ || __i386__ || __ia64__ */
}

typedef struct {
   int kbdtrans;
   struct termios kbdtty;
} LnxKbdPrivRec, *LnxKbdPrivPtr;

static int
KbdInit(InputInfoPtr pInfo, int what)
{
    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
    LnxKbdPrivPtr priv = (LnxKbdPrivPtr) pKbd->private;

    if (pKbd->isConsole) {
        ioctl (pInfo->fd, KDGKBMODE, &(priv->kbdtrans));
        tcgetattr (pInfo->fd, &(priv->kbdtty));
    }
    if (!pKbd->CustomKeycodes) {
        pKbd->RemapScanCode = ATScancode;
    }

    return Success;
}

static int
KbdOn(InputInfoPtr pInfo, int what)
{
    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
    LnxKbdPrivPtr priv = (LnxKbdPrivPtr) pKbd->private;
    struct termios nTty;

    if (pKbd->isConsole) {
	if (pKbd->CustomKeycodes)
	    ioctl(pInfo->fd, KDSKBMODE, K_MEDIUMRAW);
	else
	    ioctl(pInfo->fd, KDSKBMODE, K_RAW);

	nTty = priv->kbdtty;
	nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
	nTty.c_oflag = 0;
	nTty.c_cflag = CREAD | CS8;
	nTty.c_lflag = 0;
	nTty.c_cc[VTIME]=0;
	nTty.c_cc[VMIN]=1;
	cfsetispeed(&nTty, 9600);
	cfsetospeed(&nTty, 9600);
	tcsetattr(pInfo->fd, TCSANOW, &nTty);
    }
    return Success;
}

static int
KbdOff(InputInfoPtr pInfo, int what)
{
    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
    LnxKbdPrivPtr priv = (LnxKbdPrivPtr) pKbd->private;

    if (pKbd->isConsole) {
	ioctl(pInfo->fd, KDSKBMODE, priv->kbdtrans);
	tcsetattr(pInfo->fd, TCSANOW, &(priv->kbdtty));
    }
    return Success;
}

static int
GetSpecialKey(InputInfoPtr pInfo, int scanCode)
{
  KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
  int specialkey = scanCode;

#if defined (__sparc__)
  if (pKbd->sunKbd) {
      switch (scanCode) {
          case 0x2b: specialkey = KEY_BackSpace; break;
          case 0x47: specialkey = KEY_KP_Minus; break;
          case 0x7d: specialkey = KEY_KP_Plus; break;
          /* XXX needs cases for KEY_KP_Divide and KEY_KP_Multiply */
          case 0x05: specialkey = KEY_F1; break;
          case 0x06: specialkey = KEY_F2; break;
          case 0x08: specialkey = KEY_F3; break;
          case 0x0a: specialkey = KEY_F4; break;
          case 0x0c: specialkey = KEY_F5; break;
          case 0x0e: specialkey = KEY_F6; break;
          case 0x10: specialkey = KEY_F7; break;
          case 0x11: specialkey = KEY_F8; break;
          case 0x12: specialkey = KEY_F9; break;
          case 0x07: specialkey = KEY_F10; break;
          case 0x09: specialkey = KEY_F11; break;
          case 0x0b: specialkey = KEY_F12; break;
          default: specialkey = 0; break;
      }
      return specialkey;
  }
#endif

  if (pKbd->CustomKeycodes) {
      specialkey = pKbd->specialMap->map[scanCode];
  }
  return specialkey;
}

#define ModifierSet(k) ((modifiers & (k)) == (k))

static
Bool SpecialKey(InputInfoPtr pInfo, int key, Bool down, int modifiers)
{
  KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;

  if(!pKbd->vtSwitchSupported)
      return FALSE;

  if ((ModifierSet(ControlMask | AltMask)) ||
      (ModifierSet(ControlMask | AltLangMask))) {
      if (VTSwitchEnabled && !xf86Info.vtSysreq) {
          switch (key) {
             case KEY_F1:
             case KEY_F2:
             case KEY_F3:
             case KEY_F4:
             case KEY_F5:
             case KEY_F6:
             case KEY_F7:
             case KEY_F8:
             case KEY_F9:
             case KEY_F10:
                  if (down) {
                    ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F1 + 1);
                    return TRUE;
                  }
             case KEY_F11:
             case KEY_F12:
                  if (down) {
                    ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F11 + 11);
                    return TRUE;
                  }
         }
      }
  }
#ifdef USE_VT_SYSREQ
    if (VTSwitchEnabled && xf86Info.vtSysreq) {
        switch (key) {
            case KEY_F1:
            case KEY_F2:
            case KEY_F3:
            case KEY_F4:
            case KEY_F5:
            case KEY_F6:
            case KEY_F7:
            case KEY_F8:
            case KEY_F9:
            case KEY_F10:
                 if (VTSysreqToggle && down) {
                     ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F1 + 1);
                     VTSysreqToggle = FALSE;
                     return TRUE;
                 }
                 break;
            case KEY_F11:
            case KEY_F12:
                 if (VTSysreqToggle && down) {
                     ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F11 + 11);
                     VTSysreqToggle = FALSE;
                     return TRUE;
                 }
                 break;
            /* Ignore these keys -- ie don't let them cancel an alt-sysreq */
            case KEY_Alt:
            case KEY_AltLang:
                 break;
            case KEY_SysReqest:
                 if ((ModifierSet(AltMask) || ModifierSet(AltLangMask)) && down)
                     VTSysreqToggle = TRUE;
                 break;
             default:
                 /*
                  * We only land here when Alt-SysReq is followed by a
                  * non-switching key.
                  */
                 if (VTSysreqToggle)
                     VTSysreqToggle = FALSE;
        }
    }
#endif /* USE_VT_SYSREQ */
    return FALSE;
} 

static void
stdReadInput(InputInfoPtr pInfo)
{
    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
    unsigned char rBuf[64];
    int nBytes, i;
    if ((nBytes = read( pInfo->fd, (char *)rBuf, sizeof(rBuf))) > 0) {
       for (i = 0; i < nBytes; i++)
           pKbd->PostEvent(pInfo, rBuf[i] & 0x7f,
                           rBuf[i] & 0x80 ? FALSE : TRUE);
       }
}

static Bool
OpenKeyboard(InputInfoPtr pInfo)
{
    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
    int i;
    KbdProtocolId prot = PROT_UNKNOWN_KBD;
    char *s;

    s = xf86SetStrOption(pInfo->options, "Protocol", NULL);
    for (i = 0; protocols[i].name; i++) {
        if (xf86NameCmp(s, protocols[i].name) == 0) {
           prot = protocols[i].id;
           break;
        }
    }

    switch (prot) {
        case PROT_STD:
           pInfo->read_input = stdReadInput;
           break;
        default:
           xf86Msg(X_ERROR,"\"%s\" is not a valid keyboard protocol name\n", s);
           xfree(s);
           return FALSE;
    }

    xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, s);
    xfree(s);

    s = xf86SetStrOption(pInfo->options, "Device", NULL);
    if (s == NULL) {
       pInfo->fd = xf86Info.consoleFd;
       pKbd->isConsole = TRUE;
    } else {
       pInfo->fd = open(s, O_RDONLY | O_NONBLOCK | O_EXCL);
       if (pInfo->fd == -1) {
           xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, s);
           xfree(s);
           return FALSE;
       }
       pKbd->isConsole = FALSE;
       xfree(s);
    }

    if (pKbd->isConsole)
         pKbd->vtSwitchSupported = TRUE;

    return TRUE;
}

Bool
xf86OSKbdPreInit(InputInfoPtr pInfo)
{
    KbdDevPtr pKbd = pInfo->private;

    pKbd->KbdInit       = KbdInit;
    pKbd->KbdOn         = KbdOn;
    pKbd->KbdOff        = KbdOff;
    pKbd->Bell          = SoundBell;
    pKbd->SetLeds       = SetKbdLeds;
    pKbd->GetLeds       = GetKbdLeds;
    pKbd->SetKbdRepeat  = SetKbdRepeat;
    pKbd->KbdGetMapping = KbdGetMapping;
    pKbd->SpecialKey    = SpecialKey;

    pKbd->RemapScanCode = NULL;
    pKbd->GetSpecialKey = GetSpecialKey;

    pKbd->OpenKeyboard = OpenKeyboard;
    pKbd->vtSwitchSupported = FALSE;

    pKbd->private = xcalloc(sizeof(LnxKbdPrivRec), 1);
    if (pKbd->private == NULL) {
       xf86Msg(X_ERROR,"can't allocate keyboard OS private data\n");
       return FALSE;
    }

#if defined(__powerpc__)
  {
    FILE *f;
    f = fopen("/proc/sys/dev/mac_hid/keyboard_sends_linux_keycodes","r");
    if (f) {
        if (fgetc(f) == '0')
            pKbd->CustomKeycodes = TRUE;
        fclose(f);
    }
  }
#endif
    return TRUE;
}

--- NEW FILE: lnx_kbd.h ---
/* $XFree86$ */

extern void KbdGetMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms,
				CARD8 *pModMap);


--- NEW FILE: lnx_kmod.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kmod.c,v 3.5 2001/10/01 13:44:14 eich Exp $ */

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include "xf86_OSlib.h"
#include "xf86.h"


#define MODPROBE_PATH_FILE      "/proc/sys/kernel/modprobe"
#define MAX_PATH                1024


#if 0
/* XFree86 #defines execl to be the xf86execl() function which does
 * a fork AND exec.  We don't want that.  We want the regular,
 * standard execl().
 */
#ifdef execl
#undef execl
#endif
#endif


/*
 * Load a Linux kernel module.
 * This is used by the DRI/DRM to load a DRM kernel module when
 * the X server starts.  It could be used for other purposes in the future.
 * Input:
 *    modName - name of the kernel module (Ex: "tdfx")
 * Return:
 *    0 for failure, 1 for success
 */
int
xf86LoadKernelModule(const char *modName)
{
   char mpPath[MAX_PATH] = "";
   int fd = -1, status, n;
   pid_t pid;

   /* get the path to the modprobe program */
   fd = open(MODPROBE_PATH_FILE, O_RDONLY);
   if (fd >= 0) {
      int count = read(fd, mpPath, MAX_PATH - 1);
      if (count <= 0) {
         mpPath[0] = 0;
      }
      else if (mpPath[count - 1] == '\n') {
         mpPath[count - 1] = 0;  /* replaces \n with \0 */
      }
      close(fd);
      /* if this worked, mpPath will be "/sbin/modprobe" or similar. */
   }

   if (mpPath[0] == 0) {
      /* we failed to get the path from the system, use a default */
      strcpy(mpPath, "/sbin/modprobe");
   }

   /* now fork/exec the modprobe command */
   /*
    * It would be good to capture stdout/stderr so that it can be directed
    * to the log file.  modprobe errors currently are missing from the log
    * file.
    */
   switch (pid = fork()) {
   case 0:  /* child */
      /* change real/effective user ID to 0/0 as we need to
       * preinstall agpgart module for some DRM modules 
       */
      if (setreuid(0,0)) {
         xf86Msg(X_WARNING,"LoadKernelModule: "
		 "Setting of real/effective user Id to 0/0 failed");
      }
      setenv("PATH","/sbin",1);
      n = execl(mpPath, "modprobe", modName, NULL);
      xf86Msg(X_WARNING,"LoadKernelModule %s\n",strerror(errno));
      exit(EXIT_FAILURE);  /* if we get here the child's exec failed */
      break;
   case -1:  /* fork failed */
      return 0;
   default:  /* fork worked */
      {
         /* XXX we loop over waitpid() because it sometimes fails on
          * the first attempt.  Don't know why!
          */
         int count = 0, p;
         do {
            p = waitpid(pid, &status, 0);
         } while (p == -1 && count++ < 4);

         if (p == -1) {
            return 0;
         }

         if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
            return 1;  /* success! */
         }
         else {
            return 0;
         }
      }
   }

   /* never get here */
   return 0;
}

--- NEW FILE: lnx_mouse.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c,v 1.2 2003/10/08 14:58:30 dawes Exp $ */

/*
 * Copyright 1999 by The XFree86 Project, Inc.
 */

#include <X11/X.h>
#include "xf86.h"
#include "xf86Xinput.h"
#include "xf86OSmouse.h"
#include "xf86_OSlib.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

static int
SupportedInterfaces(void)
{
    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
}

static const char *
DefaultProtocol(void)
{
    return "Auto";
}

#define DEFAULT_MOUSE_DEV		"/dev/mouse"
#define DEFAULT_PS2_DEV			"/dev/psaux"
#define DEFAULT_GPM_DATA_DEV		"/dev/gpmdata"
#define DEFAULT_GPM_CTL_DEV		"/dev/gpmdata"

static const char *mouseDevs[] = {
	DEFAULT_MOUSE_DEV,
	DEFAULT_PS2_DEV,
	DEFAULT_GPM_DATA_DEV,
	NULL
};

typedef enum {
	MOUSE_PROTO_UNKNOWN = 0,
	MOUSE_PROTO_SERIAL,
	MOUSE_PROTO_PS2,
	MOUSE_PROTO_MSC,
	MOUSE_PROTO_GPM
} protocolTypes;

static struct {
	protocolTypes proto;
	const char *name;
} devproto[] = {
	{ MOUSE_PROTO_UNKNOWN,	NULL },
	{ MOUSE_PROTO_PS2,	"PS/2" },
	{ MOUSE_PROTO_MSC,	"MouseSystems" },
	{ MOUSE_PROTO_GPM,	"GPM" }
};

static const char *
FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
{
    int fd = -1;
    const char **pdev;

    for (pdev = mouseDevs; *pdev; pdev++) {
	SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK | O_EXCL));
	if (fd == -1) {
#ifdef DEBUG
	    ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno));
#endif
	} else
	    break;
    }

    if (*pdev) {
	close(fd);
	/* Set the Device option. */
	pInfo->conf_idev->commonOptions =
	    xf86AddNewOption(pInfo->conf_idev->commonOptions, "Device", *pdev);
	xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n",
		pInfo->name, *pdev);
    }

    return *pdev;
}

static const char *
GuessProtocol(InputInfoPtr pInfo, int flags)
{
    int fd = -1;
    const char *dev;
    char *realdev;
    struct stat sbuf;
    int i;
    int proto = MOUSE_PROTO_UNKNOWN;

    dev = xf86SetStrOption(pInfo->conf_idev->commonOptions, "Device", NULL);
    if (!dev) {
#ifdef DEBUG
	ErrorF("xf86SetStrOption failed to return the device name\n");
#endif
	return NULL;
    }
    /* Look at the device name to guess the protocol. */
    realdev = NULL;
    if (strcmp(dev, DEFAULT_MOUSE_DEV) == 0) {
	if (lstat(dev, &sbuf) != 0) {
#ifdef DEBUG
	    ErrorF("lstat failed for %s (%s)\n", dev, strerror(errno));
#endif
	    return NULL;
	}
	if (S_ISLNK(sbuf.st_mode)) {
	    realdev = xnfalloc(PATH_MAX + 1);
	    i = readlink(dev, realdev, PATH_MAX);
	    if (i <= 0) {
#ifdef DEBUG
		ErrorF("readlink failed for %s (%s)\n", dev, strerror(errno));
#endif
		xfree(realdev);
		return NULL;
	    }
	    realdev[i] = '\0';
	}
    }
    if (!realdev)
	realdev = xnfstrdup(dev);
    else {
	/* If realdev doesn't contain a '/' then prepend "/dev/" */
	if (!strchr(realdev, '/')) {
	    char *tmp = xnfalloc(strlen(realdev) + 5 + 1);
	    sprintf(tmp, "/dev/%s", realdev);
	    xfree(realdev);
	    realdev = tmp;
	}
    }

    if (strcmp(realdev, DEFAULT_PS2_DEV) == 0)
	proto = MOUSE_PROTO_PS2;
    else if (strcmp(realdev, DEFAULT_GPM_DATA_DEV) == 0)
	proto = MOUSE_PROTO_MSC;
    else if (strcmp(realdev, DEFAULT_GPM_CTL_DEV) == 0)
	proto = MOUSE_PROTO_GPM;
    xfree(realdev);
    /*
     * If the protocol can't be guessed from the device name,
     * try to characterise it.
     */
    if (proto == MOUSE_PROTO_UNKNOWN) {
	SYSCALL (fd = open(dev, O_RDWR | O_NONBLOCK | O_EXCL));
	if (isatty(fd)) {
	    /* Serial PnP has already failed, so give up. */
	} else {
	    if (fstat(fd, &sbuf) != 0) {
#ifdef DEBUG
		ErrorF("fstat failed for %s (%s)\n", dev, strerror(errno));
#endif
		close(fd);
		return NULL;
	    }
	    if (S_ISFIFO(sbuf.st_mode)) {
		/* Assume GPM data in MSC format. */
		proto = MOUSE_PROTO_MSC;
	    } else {
		/* Default to PS/2 */
		proto = MOUSE_PROTO_PS2;
	    }
	}
	close(fd);
    }
    if (proto == MOUSE_PROTO_UNKNOWN) {
	xf86Msg(X_ERROR, "%s: GuessProtocol: Cannot find mouse protocol.\n",
		pInfo->name);
	return NULL;
    } else {
	for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); i++) {
	    if (devproto[i].proto == proto) {
		xf86Msg(X_INFO,
			"%s: GuessProtocol: "
			"setting mouse protocol to \"%s\"\n", 
			pInfo->name, devproto[i].name);
		return devproto[i].name;
	    }
	}
    }
    return NULL;
}

OSMouseInfoPtr
xf86OSMouseInit(int flags)
{
    OSMouseInfoPtr p;

    p = xcalloc(sizeof(OSMouseInfoRec), 1);
    if (!p)
	return NULL;
    p->SupportedInterfaces = SupportedInterfaces;
    p->DefaultProtocol = DefaultProtocol;
    p->FindDevice = FindDevice;
    p->GuessProtocol = GuessProtocol;
    return p;
}


--- NEW FILE: lnx_pci.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c,v 3.8 2002/04/09 15:59:37 tsi Exp $ */

#include <stdio.h>
#include <X11/X.h>
#include "os.h"
#include "xf86.h"
#include "xf86Priv.h"
#define XF86_OS_PRIVS
#include "xf86_OSproc.h"
#include "xf86Pci.h"

#ifdef __sparc__
#define PCIADDR_TYPE		long long
#define PCIADDR_IGNORE_FMT	"%*x"
#define PCIADDR_FMT		"%llx"
#else
#define PCIADDR_TYPE		long
#define PCIADDR_IGNORE_FMT	"%*x"
#define PCIADDR_FMT		"%lx"
#endif

Bool
xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
{
    FILE *file;
    char c[0x200];
    char *res;
    unsigned int bus, devfn, dev, fn;
    unsigned PCIADDR_TYPE size[7];
    unsigned int num;
    signed PCIADDR_TYPE Size;

    if (index > 7)
	return FALSE;
    
    if (!(file = fopen("/proc/bus/pci/devices","r")))
	return FALSE;
    do {
	res = fgets(c,0x1ff,file);
	if (res) {
	    num = sscanf(res,
			 /*bus+dev vendorid deviceid irq */
			 "%02x%02x\t%*04x%*04x\t%*x"
			 /* 7 PCI resource base addresses */
			 "\t" PCIADDR_IGNORE_FMT
			 "\t" PCIADDR_IGNORE_FMT
			 "\t" PCIADDR_IGNORE_FMT
			 "\t" PCIADDR_IGNORE_FMT
			 "\t" PCIADDR_IGNORE_FMT
			 "\t" PCIADDR_IGNORE_FMT
			 "\t" PCIADDR_IGNORE_FMT
			 /* 7 PCI resource sizes, and then optionally a driver name */
			 "\t" PCIADDR_FMT
			 "\t" PCIADDR_FMT
			 "\t" PCIADDR_FMT
			 "\t" PCIADDR_FMT
			 "\t" PCIADDR_FMT
			 "\t" PCIADDR_FMT
			 "\t" PCIADDR_FMT,
			 &bus,&devfn,&size[0],&size[1],&size[2],&size[3],
			 &size[4],&size[5],&size[6]);
	    if (num != 9) {  /* apparantly not 2.3 style */ 
		fclose(file);
		return FALSE;
	    }
	    dev = devfn >> 3;
	    fn = devfn & 0x7;
	    if (tag == pciTag(bus,dev,fn)) {
		*bits = 0;
		if (size[index] != 0) {
		    Size = size[index] - ((PCIADDR_TYPE) 1);
		    while (Size & ((PCIADDR_TYPE) 0x01)) {
			Size = Size >> ((PCIADDR_TYPE) 1);
			(*bits)++;
		    }
		}
		fclose(file);
		return TRUE;
	    }
	}
    } while (res);

    fclose(file);
    return FALSE;
}

--- NEW FILE: lnx_video.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v 3.67 2003/06/25 18:27:07 eich Exp $ */
/*
 * Copyright 1992 by Orest Zborowski <obz at Kodak.com>
 * Copyright 1993 by David Wexelblat <dwex at goblin.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 Orest Zborowski and David Wexelblat
 * not be used in advertising or publicity pertaining to distribution of
 * the software without specific, written prior permission.  Orest Zborowski
 * and David Wexelblat make no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without express or
 * implied warranty.
 *
 * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE
[...1074 lines suppressed...]
    *(vuip) ((unsigned long)Base + (Offset << SPARSE)) = b * 0x01010101;
}

static void
writeSparseJensenNB16(int Value, pointer Base, register unsigned long Offset)
{
    register unsigned int w = Value & 0xffffU;

    *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2))) =
      w * 0x00010001;
}

static void
writeSparseJensenNB32(int Value, pointer Base, register unsigned long Offset)
{
    *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2))) = Value;
}
#endif /* JENSEN_SUPPORT */

#endif /* __alpha__ */




More information about the xserver-commit mailing list