                      Release 6 Public Patch #09
                             X Consortium

This patch comes in two parts: this file and the file "XHPKeymaps.uu".

To apply this patch:

cd to the top of the source tree (to the directory containing the "xc"
and "contrib" subdirectories) and do:
        patch -p -s < ThisFile
Patch will work silently unless an error occurs.  If you want to
watch patch do its thing, leave out the "-s" argument to patch.

Next, from the same top-level directory do:
	rm -f xc/programs/Xserver/hw/hp/README
	rm -f xc/programs/Xserver/hw/hp/input/beeper.c
	rm -f xc/programs/Xserver/hw/hp/input/drivers/x_serialdrv.h
	rm -f xc/programs/Xserver/hw/hp/input/x_threebut.c

Next, from the same top-level directory do:
	uudecode < XHPKeymaps.uu
	uncompress xc/programs/Xserver/hw/hp/input/drivers/XHPKeymaps

This patch creates the following new files:
    xc/programs/Xserver/hw/hp/Xhp.man
    xc/programs/Xserver/hw/hp/ngle/hyperScrn.c
    xc/programs/Xserver/hw/hp/input/drivers/X0screens
    xc/programs/Xserver/hw/hp/input/drivers/hil_driver.c
    xc/programs/Xserver/hw/hp/input/drivers/XHPKeymaps
If you are using a symbolic link tree, you will need to create new links.

If you do not build the Xhp server, no rebuild is necessary.  Otherwise,
cd to the "xc" subdirectory and do:
        make Everything >& every.log

This patch provides updated X server support for HP display hardware.
Only the HP device-dependent code is changed.

Prereq: public-patch-8

*** -	Wed Jan 25 18:23:15 1995
--- xc/bug-report	Wed Jan 25 18:23:14 1995
***************
*** 3,9 ****
  
       VERSION:
  
! R6, public-patch-8
  [X Consortium public patches edit this line to indicate the patch level]
  
       CLIENT MACHINE and OPERATING SYSTEM:
--- 3,9 ----
  
       VERSION:
  
! R6, public-patch-9
  [X Consortium public patches edit this line to indicate the patch level]
  
       CLIENT MACHINE and OPERATING SYSTEM:
*** -	Wed Jan 25 18:47:47 1995
--- xc/programs/Xserver/hw/hp/Imakefile	Wed Jan 25 18:47:46 1995
***************
*** 1,4 ****
! XCOMM $XConsortium: Imakefile,v 3.7 94/05/28 15:39:04 dpw Exp $
  #include <Server.tmpl>
  
  #define IHaveSubdirs
--- 1,4 ----
! XCOMM $XConsortium: Imakefile,v 3.8 95/01/24 01:39:46 dpw Exp $
  #include <Server.tmpl>
  
  #define IHaveSubdirs
***************
*** 41,44 ****
--- 41,45 ----
  NormalRelocatableTarget(hp,$(OBJS))
  SpecialCObjectRule(hpInit,$(ICONFIGFILES),$(LIB_DEFINES))
  DependTarget()
+ InstallManPage(Xhp,$(MANDIR))
  
*** /dev/null	Wed Jan 25 18:47:48 1995
--- xc/programs/Xserver/hw/hp/Xhp.man	Wed Jan 25 18:47:48 1995
***************
*** 0 ****
--- 1,141 ----
+ .\" $XConsortium: Xhp.man,v 1.2 95/01/24 19:51:14 gildea Exp $
+ .\" Copyright (c) 1994  Hewlett-Packard Company
+ .\" Copyright (c) 1994  X Consortium
+ .\" 
+ .\" 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 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 
+ .\" THE X CONSORTIUM 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.
+ .\" 
+ .\" Except as contained in this notice, the name of the X Consortium shall not 
+ .\" be used in advertising or otherwise to promote the sale, use or other 
+ .\" dealing in this Software without prior written authorization from the 
+ .\" X Consortium.
+ .\"
+ .\" HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFWARE, 
+ .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
+ .\" AND FITNESS FOR A PARTICULAR PURPOSE.  Hewlett-Packard shall not be liable 
+ .\" for errors contained herein or direct, indirect, special, incidental or
+ .\" consequential damages in connection with the furnishing, performance, or 
+ .\" use of this material.
+ .TH Xhp 1 "Release 6" "X Version 11"
+ .SH NAME
+ Xhp \- cfb-based X window system server for Hewlett-Packard workstations
+ .SH SYNOPSIS
+ .PP
+ This cfb-based X server implementation is contributed by Hewlett-Packard
+ as a sample implementation for HP workstations.  Its performance on HP
+ workstations will be inferior to the product X servers available from
+ Hewlett-Packard.  Not all graphics display devices available from 
+ Hewlett-Packard are supported by this implementation.
+ .PP
+ .SH "SUPPORTED GRAPHICS DEVICES"
+ .PP
+ Please refer to the HP catalog or to the apropriate data sheets
+ for the displays.  The data that follows relates the use of the 
+ product names with their official HP product numbers.
+ .PP
+ The following graphics display devices are supported by this implementation:
+ .sp
+ .TP
+ .I HPA4070A
+ This graphics device, known as "HCRX", is a 1280x1024 color device that has 
+ 8 planes.
+ .TP
+ .I HPA4071A
+ This graphics device, known as "HCRX24", is a 1280x1024 color device that has
+ 24 planes.  It is optionally available with a hardware accelerator, in which
+ case the product number is HPA4071A_Z.
+ .TP
+ .I HPA1659A
+ This graphics device, known as "CRX", is a 1280x1024 color device that has 
+ 8 planes.
+ .TP
+ .I HPA1439A
+ This graphics device, known as "CRX24", is a 1280x1024 color device that has
+ 24 planes.  It is optionally available with a hardware accelerator.
+ .TP
+ .I HPA1924A
+ This graphics device, known as "GRX" is a 1280x1024 grayscale device that has
+ 8 planes.
+ .TP
+ .I HPA2269A
+ This graphics device, known as "Dual CRX" is a 1280x1024 color device that has
+ 8 planes.  It implements support for two displays on a single graphics card.
+ .TP
+ .I HP710C
+ This graphics device is the internal graphics support optionally available on 
+ the HP9000s710 SPU.  It supports 1280x1024 color displays and has 8 planes.
+ .TP
+ .I HP710G
+ This graphics device is the internal graphics support optionally available on 
+ the HP9000s710 SPU.  It supports 1280x1024 grayscale displays and has 8 planes.
+ .TP
+ .I HP710L
+ This graphics device is the internal graphics support optionally available on 
+ the HP9000s710 SPU.  It supports 1024x768 color displays and has 8 planes.
+ .TP
+ .I HP712
+ This graphics device is the internal graphics support available on 
+ the HP9000s712 SPU.  It supports 640x480, 1024x768 or 1280x1024 color displays 
+ and has 8 planes.
+ .PP
+ .SH "MULTIPLE SCREEN SUPPORT"
+ .PP
+ This Xhp X11 sample server supports multiple physical screens connected to a 
+ single X server.  To use this feature, you must have an SPU that allows
+ the installation of  a second graphics display card.  The file 
+ $(LIBDIR)/X*screens is read by the X11 server 
+ to determine information about the system screen configuration.
+ You must modify this file to add information for the second graphics display.
+ .sp
+ $(LIBDIR) is /usr/X11R6/lib/X11 by default.
+ .sp
+ For a complete description of the X*screens file, refer to the HP-UX manuals, 
+ or view the sample file in $(LIBDIR).
+ .SH "24 PLANE SUPPORT FOR HCRX24 AND CRX24"
+ .PP
+ This Xhp X11 sample server supports two modes for the HCRX24 and CRX24 display
+ hardware:  8 plane and 24 plane, with 8 plane being the default.
+ To run the server in 24 plane mode, you must add a depth parameter to
+ the X*screens file.  For example:
+ .sp
+ /dev/crt  depth 24
+ .sp
+ .PP
+ In depth 24 mode, the default visual type is DirectColor.
+ .PP
+ .SH "KEYMAP FILE"
+ .PP
+ This Xhp server loads a keymap that is appropriate for the attached keyboard 
+ from the XHPKeymaps file, which resides in $(LIBDIR).  The XHPKeymaps file
+ supplied with this Xhp server is a minimal file that supports US English, 
+ French, Spanish, German, and Japanese JIS keyboards.  If you have some other 
+ keyboard, the appropriate keymap may not be contained in the XHPKeymaps file.  
+ In this case, if you have access to the Hewlett-Packard product X server, you 
+ can copy its keymap file (found in /usr/lib/X11/XHPKeymaps) to $(LIBDIR).
+ .SH "FAST SCROLLING OPTION"
+ .PP
+ Since scrolling speed is especially slow on this server compared
+ to HP's product server, we have supplied fast scrolling support,
+ using a .o to link into the server.  Using HP's fast scrolling
+ is optional.  To enable the fast scrolling, set the token
+ "HPFastScrolling" to TRUE in the config/hp.cf file.  If you want
+ to use the CFB scrolling module, simply remove the define in
+ config/hp.cf, remake the Makefiles, and recompile.
+ .SH TRADEMARKS
+ .PP
+ X Window System is a trademark of X Consortium, Inc.
*** -	Wed Jan 25 18:47:49 1995
--- xc/programs/Xserver/hw/hp/hpInit.c	Wed Jan 25 18:47:49 1995
***************
*** 1,4 ****
! /* $XConsortium: hpInit.c,v 1.4 94/05/28 15:39:14 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
--- 1,4 ----
! /* $XConsortium: hpInit.c,v 1.5 95/01/24 01:43:05 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
***************
*** 227,235 ****
  
      do 
      {
! 	if (-1 == AddScreen(
! 	   ddxScreenInitPointer[pScreenInfo->numScreens], argc,argv))
! 	      FatalError("Could not add screen.\n");
  
      } while ( pScreenInfo->numScreens != hpNumScreens );
  
--- 227,235 ----
  
      do 
      {
! 	if (-1 == AddScreen(ddxScreenInitPointer[pScreenInfo->numScreens],
! 		    argc,argv))
! 	    FatalError("Could not add screen.\n");
  
      } while ( pScreenInfo->numScreens != hpNumScreens );
  
*** -	Wed Jan 25 18:47:51 1995
--- xc/programs/Xserver/hw/hp/ddx_info.c	Wed Jan 25 18:47:50 1995
***************
*** 1,4 ****
! /* $XConsortium: ddx_info.c,v 1.2 94/05/28 15:39:13 dpw Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: ddx_info.c,v 1.3 95/01/24 01:43:05 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 61,69 ****
  #   ifndef S9000_ID_TOMCAT          /* 2-headed ELK; sorry, no P/N yet */
  #       define S9000_ID_TOMCAT          0x27FCCB6D
  #   endif
! #   ifndef S9000_ID_ARTIST          /* Artist 712 mother board graphics */
  #       define S9000_ID_ARTIST          0x2B4DED6D
  #   endif
  #endif
  
  /* Declare the external initialization functions */
--- 61,72 ----
  #   ifndef S9000_ID_TOMCAT          /* 2-headed ELK; sorry, no P/N yet */
  #       define S9000_ID_TOMCAT          0x27FCCB6D
  #   endif
! #   ifndef S9000_ID_ARTIST          /* Artist 712/715 mother board graphics */
  #       define S9000_ID_ARTIST          0x2B4DED6D
  #   endif
+ #   ifndef S9000_ID_HCRX            /* Hyperdrive A4071A */
+ #       define S9000_ID_HCRX          0x2BCB015A
+ #   endif
  #endif
  
  /* Declare the external initialization functions */
***************
*** 136,141 ****
--- 139,145 ----
  	case S9000_ID_TIMBER:	    /* Bushmaster (710) Graphics */
  	case S9000_ID_A1439A:	    /* CRX24 (24-plane Color) */
  	case S9000_ID_ARTIST:	    /* 712 (8-plane Color) Graphics */
+ 	case S9000_ID_HCRX:         /* Hyperdrive (8 or 24 plane) */
  
  	    return_value = ngleScreenInit;
  	    break;
*** -	Wed Jan 25 18:47:52 1995
--- xc/programs/Xserver/hw/hp/hpCursorUtils.c	Wed Jan 25 18:47:52 1995
***************
*** 1,4 ****
! /* $XConsortium: hpCursorUtils.c,v 1.2 94/04/17 20:30:05 rws Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
--- 1,4 ----
! /* $XConsortium: hpCursorUtils.c,v 1.3 95/01/24 01:43:05 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
***************
*** 81,87 ****
  extern int hpActiveScreen;		/* Stacked mode, >1 head */
  extern WindowPtr *WindowTable;		/* Defined by DIX */
  
- static BoxRec LimitTheCursor;
  static CursorPtr currentCursors[MAXSCREENS];
  
  void hpBlottoCursors()
--- 81,86 ----
***************
*** 91,139 ****
  }
  
  /************************************************************
-  * hpConstrainCursor
-  *
-  * This function simply sets the box to which the cursor 
-  * is limited.  
-  * 
-  * ASSUMPTION:  a single BoxRec is used for recording
-  * the cursor limits, instead of one per screen.  This is 
-  * done, in part, because the bogus hpConstrainXY routine
-  * (see below) is not passed a pScreen pointer.
-  *
-  * THEREFORE:  Zaphod mode code will have to call this routine
-  * to establish new limits when the cursor leaves one screen
-  * for another.
-  *
-  ************************************************************/
- 
- void 
- hpConstrainCursor (pScreen,pBox)
- ScreenPtr pScreen;    /* Screen to which it should be constrained */
- BoxPtr   pBox;        /* Box in which... */
- {
- 	LimitTheCursor = *pBox;
- }
- 
- /************************************************************
-  * hpConstrainXY
-  *
-  * This function is called directly from x_hil.c
-  * It adjusts the cursor position to fit within the current 
-  * constraints.
-  *
-  ************************************************************/
- 
- Bool
- hpConstrainXY(px,py)
-     int *px, *py;
- {
-     *px = max( LimitTheCursor.x1, min( LimitTheCursor.x2,*px));
-     *py = max( LimitTheCursor.y1, min( LimitTheCursor.y2,*py));
-     return TRUE;
- }
- 
- /************************************************************
   * hpCursorLimits
   *      Return a box within which the given cursor may move on the given
   *      screen. We assume that the HotBox is actually on the given screen,
--- 90,95 ----
***************
*** 156,162 ****
--- 112,122 ----
  }
  
  /************************************************************
+  *
   * hpSetCursorPosition
+  *
+  *      This routine is called from DIX when the X11 sprite/cursor is warped.
+  *
   ************************************************************/
  
  Bool 
***************
*** 171,208 ****
  
      php 	= (hpPrivPtr) pScreen->devPrivate;
  
!     /* Check to see if we've switched screens: */
      InDev = GET_HPINPUTDEVICE((DeviceIntPtr)LookupPointerDevice());
-     if (pScreen != InDev->pScreen)
-     {
-         WindowPtr pRootWindow = WindowTable[InDev->pScreen->myNum];
- 
-         /*
-         ********************************************************************
-         ** Turn old cursor off, blank/unblank screens for stacked mode,
-         ** let DIX know there is a new screen, set the input driver variable
-         ** to the new screen number.
-         ********************************************************************
-         */
- 
-         (*((hpPrivPtr)(InDev->pScreen->devPrivate))->CursorOff)
-         (InDev->pScreen);                     /* Old cursor off */
-         php->ChangeScreen(pScreen);      /* Stacked mode switch */
-         NewCurrentScreen(pScreen, xhot, yhot);/* Let DIX know */
-         hpActiveScreen = pScreen->myNum;      /* Input driver global */
-     }
- 
- 
-     /* Must Update the Corvallis Input Driver's Variables: */
      InDev->pScreen = pScreen;
      InDev->coords[0] = xhot;
      InDev->coords[1] = yhot;
  
!     if (!generateEvent)
!     {
! 	(*php->MoveMouse)(pScreen, xhot, yhot, 0); /* Do the move now */
!     }
!     else
      {
          queue_motion_event(InDev);  /* Enqueue motion event, in x_hil.c */
          isItTimeToYield++;          /* Insures client get the event! */
--- 131,146 ----
  
      php 	= (hpPrivPtr) pScreen->devPrivate;
  
!     /* Must Update the Input Driver's Variables: */
      InDev = GET_HPINPUTDEVICE((DeviceIntPtr)LookupPointerDevice());
      InDev->pScreen = pScreen;
      InDev->coords[0] = xhot;
      InDev->coords[1] = yhot;
  
!     /* Do the move now */
!     (*php->MoveMouse)(pScreen, xhot, yhot, 0);
! 
!     if (generateEvent)
      {
          queue_motion_event(InDev);  /* Enqueue motion event, in x_hil.c */
          isItTimeToYield++;          /* Insures client get the event! */
***************
*** 210,213 ****
  
      return(TRUE);
  
! }
--- 148,151 ----
  
      return(TRUE);
  
! } /* hpSetCursorPosition() */
*** -	Wed Jan 25 18:47:53 1995
--- xc/programs/Xserver/hw/hp/include/XHPproto.h	Wed Jan 25 18:47:53 1995
***************
*** 1,10 ****
! /* $XConsortium: XHPproto.h,v 1.1 93/08/08 12:56:03 rws Exp $ */
! #ifndef XHPPROTO_H
! #define XHPPROTO_H
! /*
! 
! Copyright (c) 1986, 1987 by Hewlett-Packard Company
! 
  Permission to use, copy, modify, and distribute this
  software and its documentation for any purpose and without
  fee is hereby granted, provided that the above copyright
--- 1,8 ----
! /* $XConsortium: XHPproto.h,v 1.2 95/01/24 01:46:26 dpw Exp $ */
! /*************************************************************************
!  * 
!  * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
!  *
  Permission to use, copy, modify, and distribute this
  software and its documentation for any purpose and without
  fee is hereby granted, provided that the above copyright
***************
*** 14,32 ****
  advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.
  
! HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
  TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  PURPOSE.  Hewlett-Packard shall not be liable for errors
  contained herein or direct, indirect, special, incidental or
  consequential damages in connection with the furnishing,
  performance, or use of this material.
  
- This software is not subject to any license of the American
- Telephone and Telegraph Company or of the Regents of the
- University of California.
- 
- */
  /* Definitions for HP extensions used by the server and C bindings*/
  
  #ifndef XMD_H
--- 12,29 ----
  advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.
  
!  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
  TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  PURPOSE.  Hewlett-Packard shall not be liable for errors
  contained herein or direct, indirect, special, incidental or
  consequential damages in connection with the furnishing,
  performance, or use of this material.
+  
+  *************************************************************************/
+ #ifndef XHPPROTO_H
+ #define XHPPROTO_H
  
  /* Definitions for HP extensions used by the server and C bindings*/
  
  #ifndef XMD_H
***************
*** 188,197 ****
  #define REL_807_SERVER		5	/* HP-UX 8.07 (IF2) */
  #define REL_90_SERVER		6	/* HP-UX 9.0 R5 */
  #define REL_903_SERVER		7	/* HP-UX 9.03 R5 */
  
  
  #define VR_MIT_RELEASE		5
! #define VR_HP_RELEASE		REL_903_SERVER
  #define VR_HP_PATCH_LEVEL	0
  
  #define HP_VRN(mit_release, hp_release, hp_patch_level)  	\
--- 185,200 ----
  #define REL_807_SERVER		5	/* HP-UX 8.07 (IF2) */
  #define REL_90_SERVER		6	/* HP-UX 9.0 R5 */
  #define REL_903_SERVER		7	/* HP-UX 9.03 R5 */
+ #define REL_905_SERVER		8	/* HP-UX 9.05 R5 */
+ #define REL_100_SERVER		9	/* HP-UX 10.0 R5 */
  
  
  #define VR_MIT_RELEASE		5
! #ifdef hpV4
! #define VR_HP_RELEASE		REL_100_SERVER
! #else
! #define VR_HP_RELEASE		REL_905_SERVER
! #endif /* hpV4 */
  #define VR_HP_PATCH_LEVEL	0
  
  #define HP_VRN(mit_release, hp_release, hp_patch_level)  	\
*** -	Wed Jan 25 18:47:55 1995
--- xc/programs/Xserver/hw/hp/ngle/Imakefile	Wed Jan 25 18:47:55 1995
***************
*** 1,15 ****
! /* $XConsortium: Imakefile,v 1.4 93/09/06 15:25:28 rws Exp $ */
  #include <Server.tmpl>
  
  ORIG_SRCS =	nglescreen.c	\
  		nglecolormap.c	\
  		nglecursor.c    \
! 		nglenoop.c
  
  ORIG_OBJS =	nglescreen.o	\
  		nglecolormap.o	\
  		nglecursor.o	\
! 		nglenoop.o
  
  #ifdef HPFastScrolling
  SCROLLING_SRC = nglecopy.c      \
--- 1,17 ----
! /* $XConsortium: Imakefile,v 1.6 95/01/25 23:37:39 gildea Exp $ */
  #include <Server.tmpl>
  
  ORIG_SRCS =	nglescreen.c	\
  		nglecolormap.c	\
  		nglecursor.c    \
! 		nglenoop.c	\
! 		hyperScrn.c
  
  ORIG_OBJS =	nglescreen.o	\
  		nglecolormap.o	\
  		nglecursor.o	\
! 		nglenoop.o	\
! 		hyperScrn.o
  
  #ifdef HPFastScrolling
  SCROLLING_SRC = nglecopy.c      \
*** -	Wed Jan 25 18:47:56 1995
--- xc/programs/Xserver/hw/hp/ngle/dregs.h	Wed Jan 25 18:47:56 1995
***************
*** 1,4 ****
! /* $XConsortium: dregs.h,v 1.2 94/05/28 15:45:25 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
--- 1,4 ----
! /* $XConsortium: dregs.h,v 1.3 95/01/24 01:54:12 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
***************
*** 46,100 ****
      } b;
  } dreg_cplx_t;
  
! 
! 
  typedef volatile struct {
      long int pad1[70];
!     unsigned long int reg1;
!     long int pad2[217];
!     unsigned long int reg2;
      long int pad3[7];
!     unsigned long int reg3;
      long int pad4[63];
!     unsigned long int reg22;
      long int pad5[7];
!     unsigned long int reg23;
      long int pad6[15];
!     unsigned long int reg4;
      long int pad7[39];
!     unsigned long int reg5;
      long int pad8[87];
!     dreg_cplx_t reg6;
!     dreg_cplx_t reg7;
!     dreg_cplx_t reg24;
      long int pad9[5];
!     unsigned long int reg8;
!     long int pad10[120];
!     dreg_cplx_t reg9;
      long int pad10a[62];
!     dreg_cplx_t reg25;
      long int pad11[23871];
!     unsigned long int reg10;
!     unsigned long int reg11;
      long int pad12[1];
!     unsigned long int reg12;
!     long int pad13[2];
!     unsigned long int reg13;
!     dreg_cplx_t reg14;
      long int pad15[499704];    
!     dreg_cplx_t reg15;
!     dreg_cplx_t reg16;
!     long int pad17[62];
!     dreg_cplx_t reg17;
!     dreg_cplx_t reg18;
      long int pad18[4];
!     unsigned long int reg26;
      long int pad19[57];
!     dreg_cplx_t reg19;
      long int pad20[1];
!     dreg_cplx_t reg20;
      long int pad21[3];
!     dreg_cplx_t reg21;
      long int pad22[59];
!     dreg_cplx_t reg27;
  } ngle_dregs_t;
--- 46,123 ----
      } b;
  } dreg_cplx_t;
  
! 
  typedef volatile struct {
      long int pad1[70];
!     unsigned long int	reg1;
!     long int pad2[193];
!     unsigned long int	reg28;
!     long int pad24[23];
!     unsigned long int	reg2;
      long int pad3[7];
!     unsigned long int	reg3;
      long int pad4[63];
!     unsigned long int	reg22;
      long int pad5[7];
!     unsigned long int	reg23;
      long int pad6[15];
!     unsigned long int	reg4;
      long int pad7[39];
!     unsigned long int	reg5;
      long int pad8[87];
!     dreg_cplx_t		reg6;
!     dreg_cplx_t		reg7;
!     dreg_cplx_t		reg24;
      long int pad9[5];
!     unsigned long int	reg8;
!     long int pad10[72];
!     dreg_cplx_t		reg37;
!     long int pad13[47];
!     dreg_cplx_t		reg9;
      long int pad10a[62];
!     dreg_cplx_t		reg25;
      long int pad11[23871];
!     unsigned long int	reg10;
!     unsigned long int	reg11;
      long int pad12[1];
!     unsigned long int	reg12;
!     unsigned long int	reg35;
!     unsigned long int	reg36;
!     unsigned long int	reg13;
!     dreg_cplx_t		reg14;
      long int pad15[499704];    
!     dreg_cplx_t		reg15;
!     dreg_cplx_t		reg16;
!     dreg_cplx_t		reg34;
!     long int pad17[61];
!     dreg_cplx_t		reg17;
!     dreg_cplx_t		reg18;
      long int pad18[4];
!     unsigned long int	reg26;
      long int pad19[57];
!     dreg_cplx_t		reg19;
      long int pad20[1];
!     dreg_cplx_t		reg20;
      long int pad21[3];
!     dreg_cplx_t		reg21;
      long int pad22[59];
!     dreg_cplx_t		reg27;
!     long int pad23[16189];
!     dreg_cplx_t		reg29;
!     unsigned long int	reg30;
!     unsigned long int	reg31;
!     long int pad25[5];
!     unsigned long int	reg38;
!     unsigned long int	reg41;
!     unsigned long int	reg42;
!     unsigned long int	reg43;
!     unsigned long int	reg44;
!     unsigned long int	reg45;
!     long int pad26[1];
!     unsigned long int	reg32;
!     unsigned long int	reg33;
!     long int pad27[55];
!     unsigned long int   reg39;
!     long int pad28[3];
!     unsigned long int	reg40;
  } ngle_dregs_t;
*** /dev/null	Wed Jan 25 18:47:57 1995
--- xc/programs/Xserver/hw/hp/ngle/hyperScrn.c	Wed Jan 25 18:47:57 1995
***************
*** 0 ****
--- 1,266 ----
+ /* $XConsortium: hyperScrn.c,v 1.1 95/01/25 16:14:36 gildea Exp $ */
+ /*************************************************************************
+  * 
+  * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
+  * 
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, 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 Hewlett Packard not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+ 
+ HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
+ TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.  Hewlett-Packard shall not be liable for errors
+ contained herein or direct, indirect, special, incidental or
+ consequential damages in connection with the furnishing,
+ performance, or use of this material.
+ 
+  *
+  *************************************************************************/
+ 
+ /******************************************************************************
+  *
+  *	This file contains various global variables and routines concerning
+  *	the Screen structure.  This includes the ngleScreenInit routine.
+  *
+  ******************************************************************************/
+ 
+ 
+ #include "ngle.h"
+ 
+ Bool hyperResetPlanes(
+     NgleScreenPrivPtr           pScreenPriv,
+     Card32                      serverState);
+ 
+ static void hyperUndoITE(
+     NgleScreenPrivPtr       pScreenPriv);
+ 
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Utility Procedure:	hyperResetPlanes
+  *
+  * Description:
+  *
+  *	This routine implements pNgleScreenInit->InitPlanes and
+  *	pScreenPriv->ngleResetPlanes.  It resets the image, overlay 
+  *	and attribute planes to a known state.  This includes doing 
+  *	what is necessary to counteract what the ITE has done as well 
+  *	as supporting friendly boot operation.
+  *
+  * Assumptions:
+  *
+  *	- default colormap has already been initialized and installed
+  *	- fast-locking has been initialized.
+  *
+  *	Does not assume a lock is in effect.
+  *
+  ******************************************************************************/
+ 
+ Bool hyperResetPlanes(
+     NgleScreenPrivPtr	pScreenPriv,
+     Card32		serverState)
+ {
+     NgleHdwPtr		pDregs 		= (NgleHdwPtr) pScreenPriv->pDregs;
+     Card32		controlPlaneReg;
+     Card32		planeEnableMask;
+ 
+ 
+     NGLE_LOCK(pScreenPriv);
+ 
+     if (IS_24_DEVICE(pScreenPriv))
+ 	if (pScreenPriv->devDepth == 24)
+ 	    controlPlaneReg = 0x04000F00;
+ 	else
+ 	    controlPlaneReg = 0x00000F00;   /* 0x00000800 should be enought, but lets clear all 4 bits */
+     else
+ 	controlPlaneReg = 0x00000F00;	    /* 0x00000100 should be enought, but lets clear all 4 bits */
+ 
+     switch(serverState)
+     {
+     case SERVER_INIT:
+ 	/**************************************************
+ 	 ** Need to clear screen 
+ 	 **************************************************/
+ 	if (IS_24_DEVICE(pScreenPriv))
+ 	    ngleDepth24_ClearImagePlanes(pScreenPriv);
+ 	else
+ 	    ngleDepth8_ClearImagePlanes(pScreenPriv);
+ 
+ 	/* Paint attribute planes for default case.
+ 	 * On Hyperdrive, this means all windows using overlay cmap 0.
+ 	 */
+ 	ngleResetAttrPlanes(pScreenPriv, controlPlaneReg);
+ 
+     	/* Clear overlay planes:
+ 	 *
+ 	 * If on Hyperdrive and doing Friendly Boot, we want a smooth 
+ 	 * transition when VUE starts up.  There are 3 cases to worry
+ 	 * about: 1) If only the friendly boot slate is visible on the 
+ 	 * screen and ITE console messages are not, then we need to clear 
+ 	 * the text planes so that the ITE messages don't flash on screen.  
+ 	 * This will create a smooth transition when the vuelogin window 
+ 	 * appears.  2) If only ITE console messages are visible and the
+ 	 * friendly boot slate is not, then we need to clear the planes
+ 	 * containing the slate.  3) If both the friendly boot slate and
+ 	 * ITE console messages are visible, then we don't need to bother
+ 	 * clearing any of the overlay planes.
+ 	 *
+ 	 * Side note:  The above is correct if the default visual is in
+ 	 * the overlays.  If the default visual is in the image planes,
+ 	 * then clear all of the overlay planes to prevent color flashing
+ 	 * of slate which will happen when smooth cmap is installed in
+ 	 * overlays.
+ 	 *
+ 	 * STI uses the upper 5 overlay planes for the friendly boot slate 
+ 	 * and the lower 3 overlay planes for ITE console messages.  These
+ 	 * planes are enabled/disabled via the FDR register on Marathon.
+ 	 */
+ 
+ 	if ( pScreenPriv->myNum == 0 && pScreenPriv->devDepth == 8 )
+ 	{   /* isDefaultVisualInOverlays == TRUE */
+ 	    SETUP_HW(pDregs); /* Wait for hw to be ready */
+ 	    planeEnableMask = NGLE_READ32(pDregs->reg32);
+ 
+ 	    if ((planeEnableMask & 0xffff0000) == 0xf8f80000)
+ 	    {
+ 		/* only slate is visible so need to clear text planes */
+ 		ngleClearOverlayPlanes(pScreenPriv, 0x7, 0);
+ 	    }
+ 	    else if ((planeEnableMask & 0xffff0000) == 0x07070000)
+ 	    {
+ 		/* only text is visible so need to clear slate planes */
+ 		ngleClearOverlayPlanes(pScreenPriv, 0xf8, 0);
+ 	    }
+ 	    /* else if ((planeEnableMask & 0xffff0000) == 0xffff0000) */
+ 		/* both slate and text are visible so clear isn't necessary */
+ 	}
+ 	else
+ 	{
+ 	    /* Not in friendly boot mode and/or default visual is 
+ 	     * in image planes so clear all overlay planes 
+ 	     */
+ 	    ngleClearOverlayPlanes(pScreenPriv, 0xff, 255);
+ 	}
+ 
+ 	/**************************************************
+ 	 ** Also need to counteract ITE settings 
+ 	 **************************************************/
+ 	hyperUndoITE(pScreenPriv);
+ 	break;
+ 
+     case SERVER_EXIT:
+ 	/**************************************************
+ 	 ** Need to clear screen 
+ 	 **************************************************/
+ 	if (IS_24_DEVICE(pScreenPriv))
+ 	    ngleDepth24_ClearImagePlanes(pScreenPriv);
+ 	else
+ 	    ngleDepth8_ClearImagePlanes(pScreenPriv);
+ 	ngleResetAttrPlanes(pScreenPriv, controlPlaneReg);
+ 	ngleClearOverlayPlanes(pScreenPriv, 0xff, 0);
+ 	break;
+ 
+     case SERVER_RECOVERY:
+ 	/**************************************************
+ 	 ** Need to counteract ITE settings 
+ 	 **************************************************/
+ 	hyperUndoITE(pScreenPriv);
+ 
+ 	/**************************************************
+ 	 * Reset attribute planes to known state 
+ 	 **************************************************/
+ 	ngleResetAttrPlanes(pScreenPriv, controlPlaneReg);
+ 	break;
+     }
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+     return(TRUE);
+ 
+ } /* hyperResetPlanes */
+ 
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Utility Procedure:	hyperUndoITE
+  *
+  * Description:
+  *
+  *	This local routine counteracts what the ITE has done on
+  *	Hyperdrive.
+  *
+  * 	STI uses the upper 5 overlay planes for the friendly boot slate 
+  * 	and the lower 3 overlay planes for ITE console messages.  These
+  * 	planes are enabled/disabled via the FDR register on Marathon.
+  *
+  * 	ITE has set transparency enable mask to a non-zero
+  * 	value.  Make sure that it's set to zero.  Method is per
+  * 	Curtis McAllister.
+  *
+  * 	Before clearing the transparency, write zeroes to the overlay
+  * 	planes (to avoid flashing display of colors that are no longer
+  * 	transparent).
+  *
+  * Assumptions:
+  *
+  *	Assumes fast-locking has been initialized.
+  *	Does not assume a lock is in effect.
+  *
+  ******************************************************************************/
+ 
+ static void hyperUndoITE(
+     NgleScreenPrivPtr       pScreenPriv)
+ {
+     NgleHdwPtr              pDregs;
+     Int32		    nFreeFifoSlots = 0;
+     Card32		    fbAddr;
+ 
+     pDregs 	= (NgleHdwPtr) pScreenPriv->pDregs;
+ 
+     NGLE_LOCK(pScreenPriv);
+ 
+ 
+     /**********************************************
+      * Display enable all overlay planes
+      **********************************************/
+ 
+     /*
+      * On Hyperdrive, plane enable done via FDR register on Marathon.
+      * Enable all planes (image and overlay).
+      */
+     GET_FIFO_SLOTS(nFreeFifoSlots,1);
+     NGLE_WRITE32(pDregs->reg32,0xffffffff);
+ 
+ 
+     /**********************************************
+      * Write overlay transparency mask so only entry 255 is transparent
+      **********************************************/
+ 
+     /* Hardware setup for full-depth write to "magic" location */
+     GET_FIFO_SLOTS(nFreeFifoSlots, 7);
+     NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	BA(IndexedDcd, Otc04, Ots08, AddrLong,
+ 	   BAJustPoint(0), BINovly, BAIndexBase(0)));
+     NGLE_QUICK_SET_IMAGE_BITMAP_OP(
+ 	IBOvals(RopSrc, MaskAddrOffset(0),
+ 		BitmapExtent08, StaticReg(FALSE),
+ 		DataDynamic, MaskOtc, BGx(FALSE), FGx(FALSE)));
+ 
+     /* Now prepare to write to the "magic" location */
+     fbAddr = (Card32) NGLE_LONG_FB_ADDRESS(0, 1532, 0);
+     NGLE_BINC_SET_DSTADDR(fbAddr);
+     NGLE_REALLY_SET_IMAGE_PLANEMASK(0xffffff);
+     NGLE_BINC_SET_DSTMASK(~0UL);
+ 
+     /* Finally, write a zero to clear the mask */
+     NGLE_BINC_WRITE32(0);
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+ } /* hyperUndoITE */
*** -	Wed Jan 25 18:47:59 1995
--- xc/programs/Xserver/hw/hp/ngle/ngle.h	Wed Jan 25 18:47:58 1995
***************
*** 1,4 ****
! /* $XConsortium: ngle.h,v 1.2 94/05/28 15:45:30 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
--- 1,4 ----
! /* $XConsortium: ngle.h,v 1.3 95/01/24 01:55:45 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
***************
*** 25,34 ****
--- 25,43 ----
  #ifndef NGLE_H
  #define NGLE_H
  
+ /* Rummor has it that NDEBUG is defined by default in X build environment.
+  * It is used to activate assert statements (see /usr/include/assert.h).
+  *	Compiling with the preprocessor option -DNDEBUG (see cpp(1)), or with
+  *	the preprocessor control statement #define NDEBUG ahead of the
+  *	#include <assert.h> statement, stops assertions from being compiled
+  *	into the program.
+  */
+ 
  #include <unistd.h>         /* keys off _[POSIX|HPUX|XOPEN]_SOURCE */
  #include <stdlib.h>         /* For prototype of getenv() */
  #include <stdio.h>
  #include <errno.h>
+ #include <assert.h>         /* For assert() statements */
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/sysmacros.h>
***************
*** 96,103 ****
  #       define CRX24_OVERLAY_PLANES	0x920825AA
  #   endif
  
! #   ifndef S9000_ID_ARTIST		/* Artist (Gecko) Graphics */
  #       define S9000_ID_ARTIST          0x2B4DED6D
  #   endif
  
  #define hpGivingUp  (dispatchException & DE_TERMINATE)
--- 105,116 ----
  #       define CRX24_OVERLAY_PLANES	0x920825AA
  #   endif
  
! #   ifndef S9000_ID_ARTIST		/* Artist (Gecko/712 & 715) Graphics */
  #       define S9000_ID_ARTIST          0x2B4DED6D
+ #   endif
+ 
+ #   ifndef S9000_ID_HCRX		/* hyperdrive Graphics */
+ #       define S9000_ID_HCRX		0x2BCB015A
  #   endif
  
  #define hpGivingUp  (dispatchException & DE_TERMINATE)
*** -	Wed Jan 25 18:48:00 1995
--- xc/programs/Xserver/hw/hp/ngle/nglehdw.h	Wed Jan 25 18:48:00 1995
***************
*** 1,4 ****
! /* $XConsortium: nglehdw.h,v 1.2 94/05/28 15:45:32 dpw Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: nglehdw.h,v 1.3 95/01/24 01:58:28 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 24,68 ****
   *************************************************************************/
  
  
! #ifndef NGLEHDW_H
  #define NGLEHDW_H
  
  
  typedef ngle_dregs_t	NgleHdwRec;
  typedef ngle_dregs_t	*NgleHdwPtr;
  
! #define SETUP_HW(pDregs) {						\
! 	    char stat;							\
! 	    volatile char * pstat = &((pDregs)->reg15.b.b0);		\
! 	    do {							\
! 		stat = *pstat;						\
! 		if (!stat)						\
! 		    stat = *pstat;					\
! 	    } while(stat);						\
! 	}
! 
! #define SETUP_FB(pDregs,ID, depth) {					\
! 	    SETUP_HW(pDregs);						\
! 	    switch (ID) {						\
! 		case S9000_ID_ARTIST:					\
! 		case S9000_ID_A1659A:					\
!     		    (pDregs)->reg10 = 0x13601000;			\
! 		    break;						\
! 		case S9000_ID_A1439A:					\
!     		    if (depth == 24)					\
! 		        (pDregs)->reg10 = 0xBBA0A000;			\
! 		    else  /* depth = 8 */				\
!     			(pDregs)->reg10 = 0x13601000;			\
! 		    break; 						\
! 		case S9000_ID_TIMBER:					\
! 		case CRX24_OVERLAY_PLANES:				\
! 		    (pDregs)->reg10 = 0x13602000;			\
! 		    break;						\
! 	    }								\
! 	    (pDregs)->reg14.all = 0x83000300;				\
! 	    SETUP_HW(pDregs);						\
! 	    (pDregs)->reg16.b.b1 = 1;					\
! 	}
  
  #define START_CURSOR_COLORMAP_ACCESS(pDregs) {				\
  	    SETUP_HW(pDregs);						\
--- 24,108 ----
   *************************************************************************/
  
  
! #ifndef NGLEHDW_H /*[ NGLEHDW_H */
  #define NGLEHDW_H
  
+ /* Define pointer to NGLE registers */
+ #ifndef DREGS_PTR
+ #define DREGS_PTR pDregs
+ #endif
+ 
+ #define NGLE_LOCK(pScreenPriv)
+ #define NGLE_UNLOCK(pScreenPriv)
+ 
+ #define NGLE_READ32(source) ((long)(source))
+ #define NGLE_WRITE32(dest, data) ((dest) = (long)(data))
  
  typedef ngle_dregs_t	NgleHdwRec;
  typedef ngle_dregs_t	*NgleHdwPtr;
  
! #define SETUP_HW(pDregs)						\
! {									\
!     char stat;								\
!     volatile char * pstat = &((pDregs)->reg15.b.b0);			\
!     do {								\
! 	stat = *pstat;							\
! 	if (!stat)							\
! 	    stat = *pstat;						\
!     } while(stat);							\
! }
! 
! #define SETUP_FB(pDregs, ID, depth)					\
! {									\
!     SETUP_HW(pDregs);							\
!     switch (ID)								\
!     {									\
! 	case S9000_ID_ARTIST:						\
! 	case S9000_ID_A1659A:						\
! 	    (pDregs)->reg10 = 0x13601000;				\
! 	    break;							\
! 	case S9000_ID_A1439A:						\
! 	    if (depth == 24)						\
! 		(pDregs)->reg10 = 0xBBA0A000;				\
! 	    else  /* depth = 8 */					\
! 		(pDregs)->reg10 = 0x13601000;				\
! 	    break;							\
! 	case S9000_ID_HCRX:						\
! 	    if (depth == 24)						\
! 		(pDregs)->reg10 = 0xBBA0A000;				\
! 	    else  /* depth = 8 */					\
! 		(pDregs)->reg10 = 0x13602000;				\
! 	    break; 							\
! 	case S9000_ID_TIMBER:						\
! 	case CRX24_OVERLAY_PLANES:					\
! 	    (pDregs)->reg10 = 0x13602000;				\
! 	    break;							\
!     }									\
!     (pDregs)->reg14.all = 0x83000300;					\
!     SETUP_HW(pDregs);							\
!     (pDregs)->reg16.b.b1 = 1;						\
! }
! 
! #ifdef HPUX_ANSIC_ACKNOWLEDGES_VOLATILE_STRUCTURE /* [ */
! #define GET_FIFO_SLOTS( cnt, numslots)					\
! {									\
!     while (cnt < numslots)						\
!     {									\
! 	cnt = DREGS_PTR->reg34.all;					\
!     }									\
!     cnt -= numslots;							\
! }
! #else /* Compiler does not treat pDregs as volatile ][ use local volatile */
! #define GET_FIFO_SLOTS( cnt, numslots)					\
! {									\
!     volatile unsigned long * pHwFifoFreeCnt = &(DREGS_PTR->reg34.all);	\
!     while (cnt < numslots)						\
!     {									\
! 	cnt = *pHwFifoFreeCnt;						\
!     }									\
!     cnt -= numslots;							\
! }
! #endif  /* Use local volatile ] */
  
  #define START_CURSOR_COLORMAP_ACCESS(pDregs) {				\
  	    SETUP_HW(pDregs);						\
***************
*** 94,106 ****
  	    (pDregs)->reg13 = ~0;					\
  	}
  
! #define WRITE_IMAGE_COLOR(pDregs,index,color) {				\
  	    SETUP_HW(pDregs);						\
  	    (pDregs)->reg3 = ((0x100+index) << 2);			\
  	    (pDregs)->reg4 = (color);					\
  	}
  
! #define FINISH_IMAGE_COLORMAP_ACCESS(pDregs,ID, depth) {		\
  	    (pDregs)->reg2 = 0x400;					\
  	    if (depth == 24)						\
      		(pDregs)->reg1 = 0x83000100;				\
--- 134,146 ----
  	    (pDregs)->reg13 = ~0;					\
  	}
  
! #define WRITE_IMAGE_COLOR(pDregs, index, color) {			\
  	    SETUP_HW(pDregs);						\
  	    (pDregs)->reg3 = ((0x100+index) << 2);			\
  	    (pDregs)->reg4 = (color);					\
  	}
  
! #define FINISH_IMAGE_COLORMAP_ACCESS(pDregs, ID, depth) {		\
  	    (pDregs)->reg2 = 0x400;					\
  	    if (depth == 24)						\
      		(pDregs)->reg1 = 0x83000100;				\
***************
*** 111,117 ****
  		else							\
  		    (pDregs)->reg1 = 0x80000100;			\
  	    }								\
! 	    SETUP_FB(pDregs,ID,depth);					\
  	}
  
  #define GET_CURSOR_SPECS(pDregs,pScreenPriv) {				      \
--- 151,157 ----
  		else							\
  		    (pDregs)->reg1 = 0x80000100;			\
  	    }								\
! 	    SETUP_FB(pDregs, ID, depth);				\
  	}
  
  #define GET_CURSOR_SPECS(pDregs,pScreenPriv) {				      \
***************
*** 203,208 ****
--- 243,252 ----
  	    *(pAuxControlSpace+2) = 0x03000000;				\
  	}
  
+ #define HCRX_SETUP_RAMDAC(pDregs) {					\
+ 	    NGLE_WRITE32(pDregs->reg32,0xffffffff);			\
+ 	}
+ 
  #define CRX24_SET_OVLY_MASK(pDregs) {					\
  	    SETUP_HW(pDregs);						\
  	    (pDregs)->reg11 = 0x13a02000;				\
***************
*** 211,217 ****
              (pDregs)->reg13 = 0xffffffff;				\
              (pDregs)->reg22 = (long) (~0UL);				\
              (pDregs)->reg23 = 0x0;					\
!     }
  
  
  #define ENABLE_DISPLAY(pDregs) {					\
--- 255,261 ----
              (pDregs)->reg13 = 0xffffffff;				\
              (pDregs)->reg22 = (long) (~0UL);				\
              (pDregs)->reg23 = 0x0;					\
! 	}
  
  
  #define ENABLE_DISPLAY(pDregs) {					\
***************
*** 274,284 ****
--- 318,406 ----
  	    (pDregs)->reg27.all = *pDregsMiscCtl   & ~0x00800000;	\
  	}
  
+ #define HYPER_CONFIG_PLANES_24         0x00000100
+ #define IS_24_DEVICE(pScreenPriv) \
+     (pScreenPriv->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)
+ 
+ #define IS_888_DEVICE(pScreenPriv) (!(IS_24_DEVICE(pScreenPriv)))
+ 
+ #define HYPER_CURSOR_DATA_BIT 0x80
+ #define HYPER_CURSOR_ENABLE_BIT 0x80000000
+ 
+ #define HYPER_SET_CURSOR_ADDRESS(value)					\
+     NGLE_WRITE32(DREGS_PTR->reg30, (value))
+ 
+ #define HYPER_WRITE_CURSOR_DATA(value)					\
+     NGLE_WRITE32(DREGS_PTR->reg31, (value))
+ 
+ #define HYPER_CURSOR_XY(x,y)						\
+     (((x<0)?(((-x & 0xfff) | 0x1000)<<16):((x & 0xfff)<<16)) |		\
+     ((y<0)?((-y & 0xfff) | 0x1000):(y & 0x1fff)));
+ 
+ #define HYPER_ENABLE_CURSOR(pScreenPriv, hypCursorXYValue)		\
+ {									\
+     /* Only called if cursor is visible */				\
+     assert(pScreenPriv->sprite.visible == TRUE);			\
+ 									\
+     /* Save value written for use by disable cursor */\
+     pScreenPriv->sprite.enabledCursorXYValue = (hypCursorXYValue);\
+     NGLE_WRITE32(pScreenPriv->pDregs->reg29.all, (hypCursorXYValue) |	\
+ 		 HYPER_CURSOR_ENABLE_BIT);				\
+ 									\
+ }
+ 
+ #define HYPER_DISABLE_CURSOR(pScreenPriv)				\
+ {									\
+     long enabledCursorValue = pScreenPriv->sprite.enabledCursorXYValue;	\
+ 									\
+     NGLE_WRITE32(pScreenPriv->pDregs->reg29.all, (enabledCursorValue &	\
+ 		~(HYPER_CURSOR_ENABLE_BIT)));				\
+ }
+ 
+ /* Macros for controlling cursor position, used in ngleMoveSprite() */
+ #define HYPER_ACCEL_BUSY_DODGER_IDLE					\
+     ((NGLE_READ32(DREGS_PTR->reg15.all) &  0xc001000) == 0x00010000)
+ 
+         /* not FIFO paced */
+ #define HYPER_CPC(pScreenPriv,bifCursorXYValue)				\
+     pScreenPriv->sprite.enabledCursorXYValue = (bifCursorXYValue);	\
+     NGLE_WRITE32(DREGS_PTR->reg17.all,					\
+ 	(bifCursorXYValue) | HYPER_CURSOR_ENABLE_BIT);
+ 
+         /* FIFO paced */
+ #define HYPER_FIFO_CP(pScreenPriv,hypCursorXYValue)			\
+     GET_FIFO_SLOTS(nFreeFifoSlots,2);					\
+     HYPER_GET_VID_BUS_ACCESS;						\
+     HYPER_ENABLE_CURSOR(pScreenPriv, hypCursorXYValue);
+ 
+ #define HYPER_GET_VID_BUS_ACCESS					\
+     NGLE_WRITE32(DREGS_PTR->reg28,0);
+ 
+ #define HYPER_ENABLE_DISPLAY(pDregs)					\
+ {									\
+     volatile unsigned long *pDregsHypMiscVideo = 			\
+ 		&((pDregs)->reg33);					\
+ 									\
+     SETUP_HW(pDregs);							\
+     (pDregs)->reg33 = *pDregsHypMiscVideo | 0x0A000000;			\
+ }
+ 
+ #define HYPER_DISABLE_DISPLAY(pDregs)					\
+ {									\
+     volatile unsigned long *pDregsHypMiscVideo = 			\
+ 		&((pDregs)->reg33);					\
+ 									\
+     SETUP_HW(pDregs);							\
+     (pDregs)->reg33 = *pDregsHypMiscVideo & ~0x0A000000;		\
+ }
  
+ /* define the various BufferNumber used by SETUP_ATTR_ACCESS */
  #define BUFF0_CMAP0 0x00001e02
  #define BUFF1_CMAP0 0x02001e02
  #define BUFF1_CMAP3 0x0c001e02
  #define ARTIST_CMAP0 0x00000102
+ #define HYPER_CMAP8  0x00000100
+ #define HYPER_CMAP24 0x00000800
  
  #define SETUP_ATTR_ACCESS(pDregs,BufferNumber) {			\
  	    SETUP_HW(pDregs);						\
***************
*** 303,308 ****
  #define SETUP_COPYAREA(pDregs)						\
  	    (pDregs)->reg16.b.b1 = 0;
  
  
  
! #endif /* NGLEHDW_H */
--- 425,523 ----
  #define SETUP_COPYAREA(pDregs)						\
  	    (pDregs)->reg16.b.b1 = 0;
  
+ #define	    IndexedDcd	0	/* Pixel data is indexed (pseudo) color */
+ #define	    Otc04	2	/* Pixels in each longword transfer (4) */
+ #define	    Otc32	5	/* Pixels in each longword transfer (32) */
+ #define	    Ots08	3	/* Each pixel is size (8)d transfer (1) */
+ #define	    OtsIndirect	6	/* Each bit goes through FG/BG color(8) */
+ #define	    AddrLong	5	/* FB address is Long aligned (pixel) */
+ #define	    BINovly	0x2	/* 8 bit overlay */
+ #define	    BINapp0I	0x0	/* Application Buffer 0, Indexed */
+ #define	    BINapp1I	0x1	/* Application Buffer 1, Indexed */
+ #define	    BINapp0F8	0xa	/* Application Buffer 0, Fractional 8-8-8 */
+ #define	    BINattr	0xd	/* Attribute Bitmap */
+ #define	    RopSrc 	0x3
+ #define	    BitmapExtent08  3	/* Each write hits ( 8) bits in depth */
+ #define	    BitmapExtent32  5	/* Each write hits (32) bits in depth */
+ #define	    DataDynamic	    0	/* Data register reloaded by direct access */
+ #define	    MaskDynamic	    1	/* Mask register reloaded by direct access */
+ #define	    MaskOtc	    0	/* Mask contains Object Count valid bits */
+ 
+ #define MaskAddrOffset(offset) (offset)
+ #define StaticReg(en) (en)
+ #define BGx(en) (en)
+ #define FGx(en) (en)
+ 
+ #define BAJustPoint(offset) (offset)
+ #define BAIndexBase(base) (base)
+ #define BA(F,C,S,A,J,B,I)						\
+ 	(((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I))
+ 
+ #define IBOvals(R,M,X,S,D,L,B,F)					\
+ 	(((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F))
+ 
+ #define NGLE_QUICK_SET_IMAGE_BITMAP_OP(val)				\
+ 	NGLE_WRITE32(DREGS_PTR->reg14.all, val)
+ 
+ #define NGLE_QUICK_SET_DST_BM_ACCESS(val)				\
+ 	NGLE_WRITE32(DREGS_PTR->reg11, val)
+ 
+ #define NGLE_QUICK_SET_CTL_PLN_REG(val)					\
+ 	NGLE_WRITE32(DREGS_PTR->reg12, val)
+ 
+ #define NGLE_REALLY_SET_IMAGE_PLANEMASK(plnmsk32)			\
+ 	NGLE_WRITE32(DREGS_PTR->reg13, plnmsk32)
+ 
+ #define NGLE_REALLY_SET_IMAGE_FG_COLOR(fg32)				\
+ 	NGLE_WRITE32(DREGS_PTR->reg35,fg32)
+ 
+ #define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) (void *) (		\
+ 	(unsigned long) (fbaddrbase) +					\
+ 	    (								\
+ 		(unsigned int)  ( (y) << 13      ) |			\
+ 		(unsigned int)  ( (x) << 2       )			\
+ 	    )								\
+ 	)
+ 
+ #define NGLE_BINC_SET_DSTADDR(addr)					\
+ 	NGLE_WRITE32(DREGS_PTR->reg3, (addr))
+ 
+ #define NGLE_BINC_SET_SRCADDR(addr)					\
+ 	NGLE_WRITE32(DREGS_PTR->reg2, (addr))
+ 
+ #define NGLE_BINC_SET_DSTMASK(mask)					\
+ 	NGLE_WRITE32(DREGS_PTR->reg22, (mask))
+ 
+ #define NGLE_BINC_WRITE32(data32)					\
+ 	NGLE_WRITE32(DREGS_PTR->reg23, (data32))
+ 
+ #define NGLE_MFGP_REGISTER_TYPE  dreg_cplx_t
+ #define NGLE_MFGP_REGISTER_TYPE_ASLONG(ngleMfgpReg)     ngleMfgpReg.all
+ 
+ #define NGLE_SET_TRANSFERDATA(trandata32)				\
+ 	NGLE_WRITE32(DREGS_PTR->reg8, (trandata32))
+ 
+ #define HYPER_SET_LENXY_START_FAST_RECFILL(value)			\
+ 	NGLE_WRITE32(DREGS_PTR->reg37.all, (value))
+ 
+ #define NGLE_SET_LENXY_START_RECFILL(lenxy32)				\
+ 	NGLE_WRITE32(DREGS_PTR->reg9.all, (lenxy32))
+ 
+ #define SET_LENXY_START_RECFILL(lenxy32)				\
+ 	NGLE_SET_LENXY_START_RECFILL(NGLE_MFGP_REGISTER_TYPE_ASLONG(lenxy32))
+ 
+ #define NGLE_SET_SCOREBOARD_OVERRIDE(data32)
+ /*
+ 	NGLE_WRITE32(DREGS_PTR->bifSBO, data32)
+ */
+ #define NGLE_SET_DSTXY(xy32)						\
+ 	NGLE_WRITE32(DREGS_PTR->reg6.all, (xy32))
+ 
+ #define PACK_2CARD16(dest32, highcard16, lowcard16)			\
+ 	dest32.w.high   = (highcard16);					\
+ 	dest32.w.low    = (lowcard16);
  
+ #define START_COLORMAPLOAD(cmapBltCtlData32)				\
+ 	NGLE_WRITE32(pDregs->reg38, (cmapBltCtlData32))
  
! #endif /* NGLEHDW_H ]*/
*** -	Wed Jan 25 18:48:02 1995
--- xc/programs/Xserver/hw/hp/ngle/nglecolormap.c	Wed Jan 25 18:48:01 1995
***************
*** 1,4 ****
! /* $XConsortium: nglecolormap.c,v 1.1 93/08/08 12:56:41 rws Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: nglecolormap.c,v 1.2 95/01/24 02:00:06 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 40,55 ****
  
  #include "ngle.h"
  
  
  /* Gray Scale support: calculate intensity from rgb using NTSC weights */
! #define CALCULATE_GRAYSCALE_INTENSITY(intensity, red8, grn8, blu8)\
! {\
!     intensity   = (Card8)			    \
! 		( (float) ((red8) & 0xff) * 0.30   \
! 		+ (float) ((grn8) & 0xff) * 0.59   \
! 		+ (float) ((blu8) & 0xff) * 0.11   \
! 		);				    \
!     intensity   &= 0xff;			    \
  }
  
  
--- 40,66 ----
  
  #include "ngle.h"
  
+ extern NgleLutBltCtl setNgleLutBltCtl(
+     Card32              deviceID,
+     Int32		devDepth,
+     Card32              offsetWithinLut,
+     Card32              length);            /* #entries to update */
+ 
+ extern NgleLutBltCtl setHyperLutBltCtl(
+     Card32              deviceID,
+     Int32		devDepth,
+     Card32              offsetWithinLut,
+     Card32              length);            /* #entries to update */
  
  /* Gray Scale support: calculate intensity from rgb using NTSC weights */
! #define CALCULATE_GRAYSCALE_INTENSITY(intensity, red8, grn8, blu8)	\
! {									\
!     intensity   = (Card8)						\
! 		( (float) ((red8) & 0xff) * 0.30			\
! 		+ (float) ((grn8) & 0xff) * 0.59			\
! 		+ (float) ((blu8) & 0xff) * 0.11			\
! 		);							\
!     intensity   &= 0xff;						\
  }
  
  
***************
*** 385,393 ****
          }
      }
  
!     /* cleanup colormap hardware */
!     FINISH_IMAGE_COLORMAP_ACCESS(pDregs,pScreenPriv->deviceID,
  				   pScreenPriv->devDepth);
      pScreenPriv->installedMap = cmap;
      WalkTree(cmap->pScreen, TellGainedMap, (char *) &(cmap->mid));
  
--- 396,422 ----
          }
      }
  
!     if (pScreenPriv->deviceID == S9000_ID_HCRX)
!     {
! 	NgleLutBltCtl	lutBltCtl;
! 
! 	lutBltCtl   = setHyperLutBltCtl(pScreenPriv->deviceID,
! 			pScreenPriv->devDepth,
! 			0,      /* Offset w/i LUT */
! 			256);   /* Load entire LUT */
! 	NGLE_BINC_SET_SRCADDR((Card32)
! 		NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); /* 0x100 is same as used in
! 						     * WRITE_IMAGE_COLOR() */
! 	START_COLORMAPLOAD(lutBltCtl.all);
! 	SETUP_FB(pDregs, pScreenPriv->deviceID, pScreenPriv->devDepth);
!     }
!     else
!     {
! 	/* cleanup colormap hardware */
! 	FINISH_IMAGE_COLORMAP_ACCESS(pDregs,pScreenPriv->deviceID,
  				   pScreenPriv->devDepth);
+     }
+ 
      pScreenPriv->installedMap = cmap;
      WalkTree(cmap->pScreen, TellGainedMap, (char *) &(cmap->mid));
  
***************
*** 524,532 ****
          }
      }
  
!     /* cleanup colormap hardware */
!     FINISH_IMAGE_COLORMAP_ACCESS(pDregs,pScreenPriv->deviceID,
  				   pScreenPriv->devDepth);
  
  }   /* ngleStoreColors() */
  
--- 553,578 ----
          }
      }
  
!     if (pScreenPriv->deviceID == S9000_ID_HCRX)
!     {
! 	NgleLutBltCtl	lutBltCtl;
! 
! 	lutBltCtl   = setHyperLutBltCtl(pScreenPriv->deviceID,
! 			pScreenPriv->devDepth,
! 			0,      /* Offset w/i LUT */
! 			256);   /* Load entire LUT */
! 	NGLE_BINC_SET_SRCADDR((Card32)
! 		NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); /* 0x100 is same as used in
! 						     * WRITE_IMAGE_COLOR() */
! 	START_COLORMAPLOAD(lutBltCtl.all);
! 	SETUP_FB(pDregs, pScreenPriv->deviceID, pScreenPriv->devDepth);
!     }
!     else
!     {
! 	/* cleanup colormap hardware */
! 	FINISH_IMAGE_COLORMAP_ACCESS(pDregs,pScreenPriv->deviceID,
  				   pScreenPriv->devDepth);
+     }
  
  }   /* ngleStoreColors() */
  
***************
*** 667,670 ****
  
    return;
  
! }
--- 713,788 ----
  
    return;
  
! } /* ngleResolvePseudoColor() */
! 
! 
! NgleLutBltCtl setNgleLutBltCtl(
!     Card32              deviceID,
!     Int32		devDepth,
!     Card32              offsetWithinLut,
!     Card32              length)             /* #entries to update */
! {
!     NgleLutBltCtl       lutBltCtl;
! 
!     /* set enable, zero reserved fields */
!     lutBltCtl.all           = 0x80000000;
! 
!     lutBltCtl.fields.length = length;
! 
!     if (deviceID == S9000_ID_A1439A) /* CRX24 */
!     {
!         if (devDepth == 8)
!         {
!             lutBltCtl.fields.lutType    = NGLE_CMAP_OVERLAY_TYPE;
!             lutBltCtl.fields.lutOffset  = 0;
!         }
!         else
!         {
!             lutBltCtl.fields.lutType    = NGLE_CMAP_INDEXED0_TYPE;
!             lutBltCtl.fields.lutOffset  = 0 * 256;
!         }
!     }
!     else if (deviceID == S9000_ID_ARTIST)
!     {
!         lutBltCtl.fields.lutType    = NGLE_CMAP_INDEXED0_TYPE;
!         lutBltCtl.fields.lutOffset  = 0 * 256;
!     }
!     else
!     {
!         lutBltCtl.fields.lutType   = NGLE_CMAP_INDEXED0_TYPE;
!         lutBltCtl.fields.lutOffset = 0;
!     }
! 
!     /* Offset points to start of LUT.  Adjust for within LUT */
!     lutBltCtl.fields.lutOffset += offsetWithinLut;
! 
!     return(lutBltCtl);
! 
! }   /* setNgleLutBltCtl() */
! 
! NgleLutBltCtl setHyperLutBltCtl(
!     Card32              deviceID,
!     Int32		devDepth,
!     Card32              offsetWithinLut,
!     Card32              length)             /* #entries to update */
! {
!     NgleLutBltCtl       lutBltCtl;
! 
!     /* set enable, zero reserved fields */
!     lutBltCtl.all           = 0x80000000;
! 
!     lutBltCtl.fields.length = length;
!     lutBltCtl.fields.lutType    = HYPER_CMAP_TYPE;
! 
!     /* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps*/
!     if (devDepth == 8)
! 	lutBltCtl.fields.lutOffset  = 2 * 256;
!     else
! 	lutBltCtl.fields.lutOffset  = 0 * 256;
! 
!     /* Offset points to start of LUT.  Adjust for within LUT */
!     lutBltCtl.fields.lutOffset += offsetWithinLut;
! 
!     return(lutBltCtl);
! 
! }   /* setHyperLutBltCtl() */
*** -	Wed Jan 25 18:48:03 1995
--- xc/programs/Xserver/hw/hp/ngle/nglecolormap.h	Wed Jan 25 18:48:03 1995
***************
*** 1,4 ****
! /* $XConsortium: nglecolormap.h,v 1.1 93/08/08 12:56:48 rws Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: nglecolormap.h,v 1.2 95/01/24 02:02:01 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 33,38 ****
--- 33,57 ----
  #ifndef NGLECOLORMAP_H
  #define NGLECOLORMAP_H
  
+ #define HYPER_CMAP_TYPE				0
+ #define NGLE_CMAP_INDEXED0_TYPE			0
+ #define NGLE_CMAP_OVERLAY_TYPE			3
+ 
+ /* Typedef of LUT (Colormap) BLT Control Register */
+ typedef union
+ {   /* Note assumption that fields are packed left-to-right */
+     unsigned long   all;
+     struct
+     {
+         unsigned    enable              :  1;
+         unsigned    waitBlank           :  1;
+         unsigned    reserved1           :  4;
+         unsigned    lutOffset           : 10;   /* Within destination LUT */
+         unsigned    lutType             :  2;   /* Cursor, image, overlay */
+         unsigned    reserved2           :  4;
+         unsigned    length              : 10;
+     } fields;
+ } NgleLutBltCtl;
  
  extern void ngleInstallColormap(
      ColormapPtr pColormap);
*** -	Wed Jan 25 18:48:05 1995
--- xc/programs/Xserver/hw/hp/ngle/nglecursor.c	Wed Jan 25 18:48:04 1995
***************
*** 1,4 ****
! /* $XConsortium: nglecursor.c,v 1.2 94/05/28 15:45:31 dpw Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: nglecursor.c,v 1.3 95/01/24 02:05:50 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 44,49 ****
--- 44,139 ----
  
  /******************************************************************************
   *
+  * NGLE DDX Procedure:		hyperInitSprite()
+  *
+  * Description:
+  *
+  *	This routine is called at ScreenInit() time to initialize various
+  *	cursor/sprite structures and the NGLE sprite code.
+  *
+  ******************************************************************************/
+ 
+ Bool hyperInitSprite(
+     ScreenPtr		pScreen)
+ {
+     NgleScreenPrivPtr	pScreenPriv = NGLE_SCREEN_PRIV(pScreen);
+     hpPrivPtr		php 	    = (hpPrivPtr)pScreen->devPrivate;
+     NgleHdwPtr          pDregs 	    = pScreenPriv->pDregs;
+     Int32		nScanlinesToZero;
+     Int32		curaddr;
+     Int32		nFreeFifoSlots = 0;
+ 
+     NGLE_LOCK(pScreenPriv);
+ 
+     /* Initialize the pScreen Cursor Procedure Pointers: */
+     pScreen->PointerNonInterestBox  = ngleNoop;
+     pScreen->CursorLimits 	    = hpCursorLimits;
+     pScreen->ConstrainCursor 	    = hpConstrainCursor;
+     pScreen->DisplayCursor 	    = hyperDisplayCursor;
+     pScreen->SetCursorPosition 	    = hpSetCursorPosition;
+     pScreen->RealizeCursor 	    = ngleNoopTrue;
+     pScreen->UnrealizeCursor 	    = ngleNoopTrue;
+     pScreen->RecolorCursor 	    = ngleRecolorCursor;
+ 
+ 
+     /* Initialize the Cursor Procedure Pointers: */
+     php->MoveMouse 	= ngleMoveSprite;
+     php->ChangeScreen	= ngleChangeScreen;
+     php->CursorOff	= ngleDisableSprite;
+ 
+     /* Initialize the pScreenPriv->sprite Structure: */
+     pScreenPriv->sprite.visible = FALSE;
+     pScreenPriv->sprite.x 	= (pScreenPriv->screenWidth >> 1);
+     pScreenPriv->sprite.y 	= (pScreenPriv->screenHeight >> 1);
+     pScreenPriv->sprite.width 	= 0;
+     pScreenPriv->sprite.height 	= 0;
+     pScreenPriv->sprite.pCursor = NULL;
+     pScreenPriv->sprite.firstCallTo_DisplayCursor = TRUE;
+     pScreenPriv->sprite.nTopPadLines = 0;
+     pScreenPriv->sprite.moveOnVBlank = FALSE;
+ 
+     /* Zero out cursor mask and data:
+      * Each load of cursor data/mask will write minimum necessary
+      * to overwrite previous cursor.
+      */
+     /* Zero out 64 bits (2 longs) in each mask scanline */
+     nScanlinesToZero = NGLE_MAX_SPRITE_SIZE;
+ 
+     /* to protect against VID bus data loss */
+     SETUP_HW(pDregs);
+ 
+     GET_FIFO_SLOTS(nFreeFifoSlots,2);
+     HYPER_GET_VID_BUS_ACCESS;
+ 
+     /* Write to mask area */
+     HYPER_SET_CURSOR_ADDRESS(0);
+     do
+         {
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 	HYPER_WRITE_CURSOR_DATA(0);
+ 	HYPER_WRITE_CURSOR_DATA(0);
+         } while (--nScanlinesToZero);
+ 
+     /* Zero out 64 bits (2 longs) in each data scanline */
+     nScanlinesToZero = NGLE_MAX_SPRITE_SIZE;
+     GET_FIFO_SLOTS(nFreeFifoSlots, 1);
+     HYPER_SET_CURSOR_ADDRESS(HYPER_CURSOR_DATA_BIT);
+     do
+         {
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 	HYPER_WRITE_CURSOR_DATA(0);
+ 	HYPER_WRITE_CURSOR_DATA(0);
+         } while (--nScanlinesToZero);
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+     return(TRUE);
+ 
+ } /* hyperInitSprite() */
+ 
+ 
+ /******************************************************************************
+  *
   * NGLE DDX Procedure:		ngleInitSprite()
   *
   * Description:
***************
*** 544,549 ****
--- 634,875 ----
  
  } /* ngleDisplayCursor() */
  
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Procedure:		hyperDisplayCursor()
+  *
+  * Description:
+  *
+  *	This routine is called by DIX (and the input driver?)
+  *	whenever the sprite/cursor is changed 1) from one "cursor" (i.e. image
+  *	and mask bits, foreground and background color) to another 2) from one
+  *	screen to another.  This routine downloads the cursor image/mask and
+  *	foreground and background colors to the hardware cursor.
+  *
+  *      Cloned from ngleDisplayCursor to use new hyperdrive cursor model and
+  *      to avoid ugly bug workarounds in ngle code.
+  *
+  ******************************************************************************/
+ 
+ Bool hyperDisplayCursor(
+     ScreenPtr		pScreen,
+     CursorPtr		pCursor)
+ {
+     NgleScreenPrivPtr	pScreenPriv = NGLE_SCREEN_PRIV(pScreen);
+     WindowPtr		pRootWindow;
+     NgleHdwPtr		pDregs	    = pScreenPriv->pDregs;
+     Card32		*pSrcStart;
+     Card32		*pSrc;
+     Int32		nScanlines; /* loop variable */
+     Int32		heightPlus1;
+     Int32		sourceIncrement;
+     Int32		x0, y0;	    /* Sprite origin (not hotspot) */
+     Int32		i;
+     Int32               curaddr;
+     Card32		srcMask;
+     Int32		nFreeFifoSlots = 0; 
+     Card32		cursorXYValue = 0;  
+     int 		nBotPadLines = 0;
+ 
+ 
+     /*
+     ***************************************************************************
+     ** We are called during initialization as a side effect of doing a change
+     ** screens to insure screen 0 is on top.  At that time, there is no root
+     ** window so we should just abort and wait for a call that has a cursor
+     ** to display.
+     **
+     ** After the first time this routine is called (i.e. after the side effect
+     ** call), if pCursor is NULL it means that the Corvallis input driver is
+     ** changing screens and wants this screen to use the same "cursor" (i.e.
+     ** image and mask bits, etc.) as the last time that the sprite was on
+     ** this screen.  However, the second time that pScreen->DisplayCursor is
+     ** called, pCursor is NULL, but since there wasn't a previous cursor,
+     ** the driver should use the Root Window's cursor (which is the side
+     ** effect that the input driver and/or DIX wants to acheive).
+     ***************************************************************************
+     */
+     if (!(pRootWindow = WindowTable[pScreen->myNum]))
+ 	return(TRUE);
+ 
+     if (pScreenPriv->sprite.firstCallTo_DisplayCursor)
+     {
+ 	pScreenPriv->sprite.firstCallTo_DisplayCursor = FALSE;
+ 
+ 	if (pCursor == NULL)
+ 	    pCursor = pRootWindow->optional->cursor;
+     }
+ 
+     /* Now if the cursor is still null, abort because we are using the
+      * same cursor as before:
+      */
+ 
+     if (pCursor == NULL)
+ 	return(FALSE);
+ 
+     /* Check for a valid sized cursor: (hyper same as ngle) */
+     if ((pCursor->bits->width  > NGLE_MAX_SPRITE_SIZE) ||
+         (pCursor->bits->height > NGLE_MAX_SPRITE_SIZE))
+         return(FALSE);  /* Cursor is TOO big */
+ 
+     /* Lock the device: */
+     NGLE_LOCK(pScreenPriv);
+ 
+     /* to protect against VID bus data loss */
+     SETUP_HW(pDregs);
+ 
+     GET_FIFO_SLOTS(nFreeFifoSlots,2);
+     HYPER_GET_VID_BUS_ACCESS;
+     if (pScreenPriv->sprite.visible == TRUE)
+     {
+ 	/**** Before loading the new image, mask, and colors into the hardware
+ 	 **** cursor, turn it off so we don't get flicker:
+ 	 ****/
+ 	 /* Accessing asynchronous register: no need to check FIFO */
+ 	 HYPER_DISABLE_CURSOR(pScreenPriv);
+ 
+     }
+ 
+     /* Calculate cursor origin (not hotspot) and number of scanlines not
+      * actually displayed.
+      */
+ 
+     x0 = pScreenPriv->sprite.x - pCursor->bits->xhot;
+     y0 	= pScreenPriv->sprite.y
+ 	- (pCursor->bits->yhot);
+     nBotPadLines = NGLE_MAX_SPRITE_SIZE - pCursor->bits->height;
+     
+     /* If cursor has changed, write the image, mask, and cursor colormap
+      * to the hardware cursor: 
+      */
+     if ((pCursor != pScreenPriv->sprite.pCursor)
+       ||(pCursor->bits != pScreenPriv->sprite.pCursor->bits))
+     {
+ 
+ 	pScreenPriv->sprite.pCursor = pCursor;
+ 
+ 	heightPlus1 = pCursor->bits->height + 1;
+ 
+ 	/* Start out writing the mask */
+ 	pSrcStart = (Card32 *) pCursor->bits->mask;
+ 	curaddr = 0; /* Mask Area */
+ 
+ 	/**** Write the image and mask to the hardware cursor: ****/
+ 	for (i = 0; i < 2; i++)
+ 	{
+ 	    /* Source is long-aligned: */
+ 	    assert((Card32) pSrcStart == ((Card32)(pSrcStart) >> 2) << 2);
+ 
+ 	    /* Like all pixmaps created by NGLE DDX, each scanline
+ 	     * of the source and mask pixmaps are padded on the right
+ 	     * to a long-word boundary.  For a NGLE sprite, this means
+ 	     * the scanline is either 32 or 64 bits.
+ 	     *
+ 	     * Padding is NOT necessarily 0!
+ 	     */
+ 
+ 	    if (pCursor->bits->width <= 32)
+ 	    {
+ 		pSrc = pSrcStart;
+ 
+ 		/* Form left justified mask of meaningful bits in cursor
+ 		 * data and mask.  Alas, masking is performed on CPU
+ 		 * on source data rather than using the ELK mask
+ 		 * register.  Reason: old cursor may be larger and
+ 		 * needs to be zeroed out, not left unchanged.
+ 		 */
+ 		srcMask = 0xffffffffUL << (32 - pCursor->bits->width);
+ 
+ 		/* Ngle cares whether old cursor was small enough that */
+ 		/* we dont have to zero all 64 bits.  Hyperdrive       */
+ 		/* its a dont-care since you can either write the 0 or */
+ 		/* write the new address.                              */
+ 
+ 		nScanlines = heightPlus1;
+ 		GET_FIFO_SLOTS(nFreeFifoSlots, 1);
+ 		HYPER_SET_CURSOR_ADDRESS(curaddr);
+ 		while (--nScanlines)
+ 		    {
+ 		        GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 		        HYPER_WRITE_CURSOR_DATA((*pSrc++ & srcMask));
+ 		        HYPER_WRITE_CURSOR_DATA(0);
+ 		    }
+ 		nScanlines = nBotPadLines + 1;
+ 		while (--nScanlines)
+ 		    {
+ 		        GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 		        HYPER_WRITE_CURSOR_DATA(0);
+ 		        HYPER_WRITE_CURSOR_DATA(0);
+ 		    }
+ 	    }
+ 	    else
+ 	    {   /* Width == 64 */
+ 
+ 		/* Form left justified mask of meaningful bits
+ 		 * second word in cursor data and mask.
+ 		 */
+ 		srcMask = 0xffffffffUL << (64 - pCursor->bits->width);
+ 
+ 		/* Destination bitmap address already set to (0,0) */
+ 		pSrc = pSrcStart;
+ 
+ 		nScanlines = heightPlus1;
+ 		GET_FIFO_SLOTS(nFreeFifoSlots, 1);
+ 		HYPER_SET_CURSOR_ADDRESS(curaddr);
+ 		while (--nScanlines)
+ 		{
+ 		    GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 		    HYPER_WRITE_CURSOR_DATA(*pSrc++);
+ 		    HYPER_WRITE_CURSOR_DATA((*pSrc++ & srcMask));
+ 		}
+ 		nScanlines = nBotPadLines + 1;
+ 		while (--nScanlines)
+ 		{
+ 		    GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 		    HYPER_WRITE_CURSOR_DATA(0);
+ 		    HYPER_WRITE_CURSOR_DATA(0);
+ 		}
+ 	    }
+ 	/* Now do the data */
+     	pSrcStart = (Card32 *) pCursor->bits->source;
+ 	curaddr = HYPER_CURSOR_DATA_BIT;
+ 	}
+ 
+ 	/* Load the correct colors into the hardware cursor: */
+ 	ngleLoadCursorColormap(pScreen, pCursor);
+     }
+ 
+     /* Load cursor position into NGLE:
+      * X11 hotspot hasn't changed position, but NGLE stores
+      * origin of cursor, and relative distance between hotspot
+      * and origin may have changed.
+      */
+ 
+     /* if y0 < 0, y0 has already been set to 0 above */
+     cursorXYValue = HYPER_CURSOR_XY(x0,y0);
+ 
+     /* Update values maintained in pScreenPriv->sprite */
+     pScreenPriv->sprite.visible = TRUE;
+     pScreenPriv->sprite.width 	= pCursor->bits->width;
+     pScreenPriv->sprite.height 	= pCursor->bits->height;
+ 
+     /**** Now, that we have loaded the correct bits into the hardware
+      **** cursor, turn it back on:
+      ****/
+ 
+     /* If cursor is at top of screen, hotspot may be displayed
+      * but origin is at (y<0).  NGLE hardware stores this value
+      * in same register as cursor enable bit, so pass as parameter.
+      */
+     HYPER_ENABLE_CURSOR(pScreenPriv, cursorXYValue);
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+     return(TRUE);
+ 
+ } /* hyperDisplayCursor() */
+ 
  
  
  /******************************************************************************
***************
*** 604,609 ****
--- 930,937 ----
  			xHi,
  			xLo;
      Card32		cursorXYValue = 0;  
+     NgleHdwPtr		pDregs;
+     Int32         	nFreeFifoSlots = 0;
  
  #ifdef XTESTEXT1
      extern Int32	on_steal_input; /* Defined in xtestext1di.c */
***************
*** 613,618 ****
--- 941,947 ----
  #endif /* XTESTEXT1 */
  
      pScreenPriv = NGLE_SCREEN_PRIV(pScreen);
+     pDregs	= pScreenPriv->pDregs;
  
      /* Only move if cursor defined and position changed.
       *
***************
*** 633,677 ****
  	{
  	    /* Calculate cursor origin */
  	    x0 = xhot - pCursorBits->xhot;
      	    y0 = yhot - pCursorBits->yhot - pScreenPriv->sprite.nTopPadLines;
  
! 	    /* Calculate number of scanlines not displayed
! 	     * because cursor is partly off the top of the screen.
! 	     * (X11 requires hotspot to remain on-screen,
! 	     * but not the sprite origin).
! 	     */
! 	    if (y0 < 0)
! 	    {
! 		nOffscreenScanlines = - y0;
! 		y0 = 0;
  	    }
- 
- 	    /* Update cursor X/Y position register, which contains
- 	     * all cursor position information except the number
- 	     * of scanlines hidden.
- 	     */
- 	    hbp_times_vi = (pScreenPriv->sprite.horizBackPorch *
- 			    pScreenPriv->sprite.videoInterleave);
- 	    xHi = ((x0 + hbp_times_vi) / pScreenPriv->sprite.videoInterleave)
- 		- pScreenPriv->sprite.pipelineDelay;
- 	    if (pScreenPriv->deviceID != S9000_ID_ARTIST)
- 		xLo = x0 % pScreenPriv->sprite.videoInterleave;
- 	    else
- 		xLo = (x0 + hbp_times_vi) % pScreenPriv->sprite.videoInterleave;
- 
- 	    /* if y0 < 0, y0 has already been set to 0 above */
-     	    cursorXYValue = 
- 		(   (xHi << 19)
- 		|   (xLo << 16)
- 		|   (pScreenPriv->sprite.maxYLine - y0)
- 		);
- 
- 	    /* Now update number of cursor scan lines hidden. 
- 	     * It's in same register as the enable cursor bit, and this macro
- 	     * also enables cursor, but this position cursor routine is only 
- 	     * called if cursor is visible.
- 	     */
- 	    ENABLE_CURSOR(pScreenPriv, cursorXYValue, nOffscreenScanlines);
  	}
      }
  } /* ngleMoveSprite() */
--- 962,1037 ----
  	{
  	    /* Calculate cursor origin */
  	    x0 = xhot - pCursorBits->xhot;
+ 	    /* Not all cursors start at first scan line of cursor BINs
+              * (to work around hardware problem w/ghosting and tearing
+              * on Biff/Mojave-based graphics cards).  Number of padding
+              * padding lines is set when cursor loaded.
+              */
      	    y0 = yhot - pCursorBits->yhot - pScreenPriv->sprite.nTopPadLines;
  
! 	    if (pScreenPriv->deviceID == S9000_ID_HCRX)
!             { /* ie NGLE_II_HW_CURSOR */
!                 cursorXYValue = HYPER_CURSOR_XY(x0,y0);
!                 assert(pScreenPriv->sprite.visible == TRUE);
! 
!                 /* This test is an optimization for thunder */
!                 if (HYPER_ACCEL_BUSY_DODGER_IDLE)
!                 {
!                     if (HYPER_ACCEL_BUSY_DODGER_IDLE)
!                     {
!                         /* FIFO slot not required for this write */
!                         HYPER_CPC(pScreenPriv, cursorXYValue);
!                     }
!                     else
!                     {
!                         HYPER_FIFO_CP(pScreenPriv, cursorXYValue);
!                     }
!                 }
!                 else
!                 {
!                     HYPER_FIFO_CP(pScreenPriv, cursorXYValue);
!                 }
! 	    }
!             else
!             {
! 		/* Calculate number of scanlines not displayed
! 		 * because cursor is partly off the top of the screen.
! 		 * (X11 requires hotspot to remain on-screen,
! 		 * but not the sprite origin).
! 		 */
! 		if (y0 < 0)
! 		{
! 		    nOffscreenScanlines = - y0;
! 		    y0 = 0;
! 		}
! 
! 		/* Update cursor X/Y position register, which contains
! 		 * all cursor position information except the number
! 		 * of scanlines hidden.
! 		 */
! 		hbp_times_vi = (pScreenPriv->sprite.horizBackPorch *
! 				pScreenPriv->sprite.videoInterleave);
! 		xHi = ((x0 + hbp_times_vi) / pScreenPriv->sprite.videoInterleave)
! 		    - pScreenPriv->sprite.pipelineDelay;
! 		if (pScreenPriv->deviceID != S9000_ID_ARTIST)
! 		    xLo = x0 % pScreenPriv->sprite.videoInterleave;
! 		else
! 		    xLo = (x0 + hbp_times_vi) % pScreenPriv->sprite.videoInterleave;
! 
! 		/* if y0 < 0, y0 has already been set to 0 above */
! 		cursorXYValue = 
! 		    (   (xHi << 19)
! 		    |   (xLo << 16)
! 		    |   (pScreenPriv->sprite.maxYLine - y0)
! 		    );
! 
! 		/* Now update number of cursor scan lines hidden. 
! 		 * It's in same register as the enable cursor bit, and this macro
! 		 * also enables cursor, but this position cursor routine is only 
! 		 * called if cursor is visible.
! 		 */
! 		ENABLE_CURSOR(pScreenPriv, cursorXYValue, nOffscreenScanlines);
  	    }
  	}
      }
  } /* ngleMoveSprite() */
*** -	Wed Jan 25 18:48:06 1995
--- xc/programs/Xserver/hw/hp/ngle/nglecursor.h	Wed Jan 25 18:48:06 1995
***************
*** 1,4 ****
! /* $XConsortium: nglecursor.h,v 1.1 93/08/08 12:57:15 rws Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: nglecursor.h,v 1.2 95/01/24 02:07:13 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 116,127 ****
--- 116,129 ----
   ******************************************************************************
   */
  extern Bool	ngleInitSprite();
+ extern Bool	hyperInitSprite();
  extern Bool	ngleUninitSprite();
  
  extern void	ngleDisableSprite();
  extern void	ngleChangeScreen();
  
  extern Bool	ngleDisplayCursor();
+ extern Bool     hyperDisplayCursor();
  extern void	ngleRecolorCursor();
  
  extern Bool	ngleSetCursorPosition();
*** -	Wed Jan 25 18:48:07 1995
--- xc/programs/Xserver/hw/hp/ngle/nglescreen.h	Wed Jan 25 18:48:07 1995
***************
*** 1,4 ****
! /* $XConsortium: nglescreen.h,v 1.1 93/08/08 12:58:00 rws Exp $ */
  
  /*************************************************************************
   * 
--- 1,4 ----
! /* $XConsortium: nglescreen.h,v 1.2 95/01/24 02:10:27 dpw Exp $ */
  
  /*************************************************************************
   * 
***************
*** 54,59 ****
--- 54,64 ----
      Card32			deviceID;	/* Is this an Elk or Rattler */
      NgleHdwPtr			pDregs;		/* Pointer to the hardware */
      pointer			fbaddr;		/* Pointer to the framebuffer */
+     char                        *crt_region[CRT_MAX_REGIONS]; /* Other regions
+                                                  * associated with frame buffer
+                                                  * that might be mapped in.
+                                                  * Obtained from GCDESCRIBE.
+                                                  */
      NgleDevRomDataPtr           pDevRomData;	/* Pointer to the ROM */
      Bool			isGrayScale;	/* GRX (Not color device) */
  
***************
*** 82,94 ****
       */
      Bool			lastDeviceOnThisSgcToClose;
  
      /* 
       * Pointers to various functions returned from cfbScreenInit(),
       * used for wrapper routines.
       */
      Bool (* CreateGC)();
  
- 
  } NgleScreenPrivRec, *NgleScreenPrivPtr;
  
  
--- 87,103 ----
       */
      Bool			lastDeviceOnThisSgcToClose;
  
+     /* Hyperdrive (and probably other future devices) has configuration bits */
+     /* to tell frame buffer depth (8:88 or 8:24) and accelerator present
+     */
+     unsigned Int32              deviceSpecificConfig;
+ 
      /* 
       * Pointers to various functions returned from cfbScreenInit(),
       * used for wrapper routines.
       */
      Bool (* CreateGC)();
  
  } NgleScreenPrivRec, *NgleScreenPrivPtr;
  
  
***************
*** 116,121 ****
--- 125,135 ----
  #define CURSOR_AT_VBLANK_ALWAYS		1
  #define CURSOR_AT_VBLANK_DRIVEROPTION	0
  #define CURSOR_AT_VBLANK_NEVER		-1
+ 
+ /* Server state values used by hyperResetPlanes() */
+ #define SERVER_INIT             1
+ #define SERVER_EXIT             2
+ #define SERVER_RECOVERY         3
  
  
  #endif /* NGLESCREEN */
*** -	Wed Jan 25 18:48:09 1995
--- xc/programs/Xserver/hw/hp/ngle/nglescreen.c	Wed Jan 25 18:48:08 1995
***************
*** 1,4 ****
! /* $XConsortium: nglescreen.c,v 1.2 94/05/28 15:45:33 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
--- 1,4 ----
! /* $XConsortium: nglescreen.c,v 1.3 95/01/24 02:15:14 dpw Exp $ */
  /*************************************************************************
   * 
   * (c)Copyright 1992 Hewlett-Packard Co.,  All Rights Reserved.
***************
*** 36,41 ****
--- 36,46 ----
  #define DEFAULT_CRX_MONITOR_DIAGONAL 19	/* inches */
  #define LOWRES_CRX_MONITOR_DIAGONAL  16 /* inches */
  
+ #define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES	4
+ #define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE	8
+ #define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE		10
+ #define HYPERBOWL_MODE2_8_24					15
+ 
  /* Can this graphics device be an ITE console?
   * Most all NGLE graphics devices can be.
   * The sole exception at this point (May'91) is the right-head of 
***************
*** 83,95 ****
  
  extern Bool 		(*ddxScreenInitPointer[])();
  extern hpPrivPtr	hpPrivates[MAXSCREENS];
  
  Int32			ngleScreenPrivIndex = 0;
  
  /* FORWARD (procedures defined below in this file) */
  
! static void elkSetupPlanes(
!     NgleScreenPrivPtr       pScreenPriv);
  
  static void rattlerSetupPlanes(
      NgleScreenPrivPtr	    pScreenPriv);
--- 88,101 ----
  
  extern Bool 		(*ddxScreenInitPointer[])();
  extern hpPrivPtr	hpPrivates[MAXSCREENS];
+ extern Bool 		hyperResetPlanes();
  
  Int32			ngleScreenPrivIndex = 0;
  
  /* FORWARD (procedures defined below in this file) */
  
! static void hyperSetupPlanes(
!     NgleScreenPrivPtr	    pScreenPriv);
  
  static void rattlerSetupPlanes(
      NgleScreenPrivPtr	    pScreenPriv);
***************
*** 98,103 ****
--- 104,112 ----
      NgleScreenPrivPtr	    pScreenPriv,
      Card32		    BufferNumber);
  
+ static void elkSetupPlanes(
+     NgleScreenPrivPtr       pScreenPriv);
+ 
  static Bool ngleClearScreen(
      ScreenPtr	pScreen);
  
***************
*** 111,116 ****
--- 120,130 ----
  
  static Bool ngleCloseScreen();
  
+ static void nglePolyPaintAttr(
+     NgleScreenPrivPtr           pScreenPriv,
+     Card32			ctlPlaneReg,
+     Int32			nBoxes,
+     BoxPtr			pBoxes);
  
  /* OWN */
  
***************
*** 184,190 ****
  static int calculateDPI(
      int xsize, int ysize,
      int diagonal_length)
-    
  {
      static int old_diagonal_length = 0;
      int dpi = 0;
--- 198,203 ----
***************
*** 251,258 ****
   ******************************************************************************/
  
  static NgleDevRomDataPtr ngleGetDeviceRomData(
!     NgleScreenPrivPtr	pScreenPriv
! )
  {
      crt_frame_buffer_t	gcDescribe;
      Card32		*pBytePerLongDevDepData;/* data byte == LSB */
--- 264,270 ----
   ******************************************************************************/
  
  static NgleDevRomDataPtr ngleGetDeviceRomData(
!     NgleScreenPrivPtr	pScreenPriv)
  {
      crt_frame_buffer_t	gcDescribe;
      Card32		*pBytePerLongDevDepData;/* data byte == LSB */
***************
*** 294,301 ****
  				gcDescribe.crt_region[NGLEDEVDEPROM_CRT_REGION];
  
  	/* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480.
! 	 * This code reads the index into a device dependent ROM array containing
! 	 * the device's currently selected resolution.
  	 */
  	if (pScreenPriv->deviceID == S9000_ID_TOMCAT)
  	{
--- 306,313 ----
  				gcDescribe.crt_region[NGLEDEVDEPROM_CRT_REGION];
  
  	/* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480.
! 	 * This code reads the index into a device dependent ROM array
! 	 * containing the device's currently selected resolution.
  	 */
  	if (pScreenPriv->deviceID == S9000_ID_TOMCAT)
  	{
***************
*** 563,568 ****
--- 575,581 ----
  	&&  (gcDescribe.crt_id != S9000_ID_TOMCAT)	/* Dual CRX */
  	&&  (gcDescribe.crt_id != S9000_ID_A1439A)	/* CRX24 */
  	&&  (gcDescribe.crt_id != S9000_ID_ARTIST)	/* Artist */
+ 	&&  (gcDescribe.crt_id != S9000_ID_HCRX)	/* Hyperdrive */
  	)
      {
  	ioctl(fildes, GCUNMAP, &mapOrigin);
***************
*** 595,608 ****
      pScreenPriv->devWidth 	= gcDescribe.crt_total_x; 
      pScreenPriv->screenWidth 	= gcDescribe.crt_x; 
      pScreenPriv->screenHeight 	= gcDescribe.crt_y; 
      
      /* Set the device frame buffer depth.  The default depth is set to
       * 8, but can be changed by setting the depth parameter in the
!      * Xnscreens file.  Currently, we only support depth 24 on CRX24,
       * and depth 8 on the remaining displays.
       */
      
!     if (pScreenPriv->deviceID == S9000_ID_A1439A)
          pScreenPriv->devDepth = php->depth;
      else
  	pScreenPriv->devDepth = 8;
--- 608,627 ----
      pScreenPriv->devWidth 	= gcDescribe.crt_total_x; 
      pScreenPriv->screenWidth 	= gcDescribe.crt_x; 
      pScreenPriv->screenHeight 	= gcDescribe.crt_y; 
+ 
+     for (i=0; i < CRT_MAX_REGIONS; i++)
+     {
+ 	pScreenPriv->crt_region[i]   = gcDescribe.crt_region[i];
+     }
      
      /* Set the device frame buffer depth.  The default depth is set to
       * 8, but can be changed by setting the depth parameter in the
!      * Xnscreens file.  Currently, we only support depth 24 on CRX24 & HCRX24,
       * and depth 8 on the remaining displays.
       */
      
!     if ((pScreenPriv->deviceID == S9000_ID_A1439A) ||
! 	(pScreenPriv->deviceID == S9000_ID_HCRX))
          pScreenPriv->devDepth = php->depth;
      else
  	pScreenPriv->devDepth = 8;
***************
*** 664,677 ****
  	pScreenPriv->deviceID   = S9000_ID_A1659A;
  	break;
  
!     case S9000_ID_ARTIST:	/* Artist */
  
! 	pScreenPriv->isGrayScale = FALSE;
  	break;
  
      case S9000_ID_A1659A:	/* CRX */
  	
! 	pScreenPriv->isGrayScale = FALSE;
  	break;
  
      case S9000_ID_TIMBER:	/* HP9000/710 Graphics */
--- 683,740 ----
  	pScreenPriv->deviceID   = S9000_ID_A1659A;
  	break;
  
!     case S9000_ID_HCRX:		/* Hyperdrive */
! 	/* Hyperdrive doesn't use STI ROM info so don't bother reading it */
! 	pScreenPriv->pDevRomData = NULL; /* #### strange #### */
! 	NGLE_LOCK(pScreenPriv);
! 	{
! 	    CARD32          *sti_rom_address;
! 	    CARD32          temp;
! 	    /*
! 	     * In order to read the Hyperdrive configuration bits, we need to
! 	     * read the STI ROM.  But, the STI ROM is not always mapped into
! 	     * the STI ROM space.  Sometimes the STI ROM is mapped into the
! 	     * BOOT ROM space.  To find the true STI ROM space, we need to
! 	     * look at the crt_region array in the gcDescribe structure.
! 	     * The STI ROM address will either be in entry 0 or entry 1.
! 	     * If entry 0 is mapped into the same space as the control space,
! 	     * then this is the true STI ROM space.  If entry 0 is in another
! 	     * space, then entry 1 has the true STI ROM space.  The space bits
! 	     * of the address are the upper 6 bits of the address.  For example,
! 	     * if the address is 0xf4100000, then the space is 0xf4000000.
! 	     */
! 	    if (((CARD32) pScreenPriv->pDregs & 0xfc000000) ==
! 		((CARD32) pScreenPriv->crt_region[0] & 0xfc000000))
! 	    {
! 		sti_rom_address = (CARD32 *) pScreenPriv->crt_region[0];
! 	    }
! 	    else
! 	    {
! 		sti_rom_address = (CARD32 *) pScreenPriv->crt_region[1];
! 	    }
  
! 	    /*
! 	     * Ok, grab the configuration bits from the hardware.  These bits
! 	     * come from Dodger and are added to any data read from the STI ROM.
! 	     * When reading the STI ROM, we need to avoid a potential race
! 	     * condition by doing a couple of things.  We first need to read
! 	     * some unbuffered register like BIFF status.  Next we need to wait
! 	     * for Dodger to go not busy.  Then we can safely read the STI ROM.
! 	     */
! 	    temp = NGLE_READ32(pDregs->reg15.all);
! 	    SETUP_HW(pDregs);
! 	    pScreenPriv->deviceSpecificConfig = *sti_rom_address;
! 	}
! 	NGLE_UNLOCK(pScreenPriv);
! 	
! 	pScreenPriv->isGrayScale = FALSE;   /* No grayscale version */
  	break;
  
+     case S9000_ID_ARTIST:	/* Artist */
+     case S9000_ID_A1439A:	/* CRX24 */
      case S9000_ID_A1659A:	/* CRX */
  	
! 	pScreenPriv->isGrayScale = FALSE;   /* No grayscale version */
  	break;
  
      case S9000_ID_TIMBER:	/* HP9000/710 Graphics */
***************
*** 731,744 ****
  	pScreenPriv->deviceID   = S9000_ID_A1659A;
  	break;
  
-     case S9000_ID_A1439A:	/* CRX24 */
- 	pScreenPriv->isGrayScale = FALSE;   /* No grayscale version */
- 	break;
- 
      default:
  	FatalError("Undefined device id!\n");
  	break;
!     }
  
  
      /*
--- 794,803 ----
  	pScreenPriv->deviceID   = S9000_ID_A1659A;
  	break;
  
      default:
  	FatalError("Undefined device id!\n");
  	break;
!     } /* switch (pScreenPriv->deviceID) */
  
  
      /*
***************
*** 827,832 ****
--- 886,943 ----
      /*
       **************************************************************************
       **
+      ** 11.     Call pNgleScreenInit->InitMiscConfig to perform
+      **         device-dependent configuration and initialization
+      **         that does not change the hardware state.
+      **
+      **             FIRST READ-ONLY ACCESS TO HARDWARE BY SERVER
+      **     (not counting indirect access via kernel ioctl calls)
+      **************************************************************************
+      */
+     if (pScreenPriv->deviceID == S9000_ID_HCRX)
+     {
+ 	Card32          hyperbowl;
+         Int32           nFreeFifoSlots = 0;
+ 
+ 	/* Initialize Hyperbowl registers */
+         GET_FIFO_SLOTS(nFreeFifoSlots, 7);
+         if (IS_24_DEVICE(pScreenPriv))
+         {
+             if (pScreenPriv->devDepth == 24)
+                 hyperbowl = HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE;
+             else
+                 hyperbowl = HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE;
+ 
+ 	    /* First write to Hyperbowl must happen twice (bug) */
+ 	    NGLE_WRITE32(pDregs->reg40, hyperbowl);
+ 	    NGLE_WRITE32(pDregs->reg40, hyperbowl);
+ 
+ 	    NGLE_WRITE32(pDregs->reg39, HYPERBOWL_MODE2_8_24);
+ 
+ 	    NGLE_WRITE32(pDregs->reg42, 0x014c0148); /* Set lut 0 to be the direct color */
+ 	    NGLE_WRITE32(pDregs->reg43, 0x404c4048);
+ 	    NGLE_WRITE32(pDregs->reg44, 0x034c0348);
+ 	    NGLE_WRITE32(pDregs->reg45, 0x444c4448);
+         }
+         else
+         {
+             hyperbowl = HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES;
+ 
+ 	    /* First write to Hyperbowl must happen twice (bug) */
+ 	    NGLE_WRITE32(pDregs->reg40, hyperbowl);
+ 	    NGLE_WRITE32(pDregs->reg40, hyperbowl);
+ 
+ 	    NGLE_WRITE32(pDregs->reg42, 0);
+ 	    NGLE_WRITE32(pDregs->reg43, 0);
+ 	    NGLE_WRITE32(pDregs->reg44, 0);
+ 	    NGLE_WRITE32(pDregs->reg45, 0x444c4048);
+         }
+     }
+ 
+ 
+     /*
+      **************************************************************************
+      **
       **		Call CFB routines to begin setting up of screen and
       **		visual default values.
       **
***************
*** 925,937 ****
      pScreen->SaveScreen			= ngleSaveScreen;
  
      /**** Colormap Procedures: ****/
!     pScreen->CreateColormap = ngleCreateColormap;
!     pScreen->DestroyColormap = ngleDestroyColormap; 
!     pScreen->InstallColormap = ngleInstallColormap;
!     pScreen->UninstallColormap = ngleUninstallColormap;
!     pScreen->ListInstalledColormaps = ngleListInstalledColormaps;
!     pScreen->StoreColors = ngleStoreColors;
!     pScreen->ResolveColor = ngleResolvePseudoColor;
  
  
      /*
--- 1036,1048 ----
      pScreen->SaveScreen			= ngleSaveScreen;
  
      /**** Colormap Procedures: ****/
!     pScreen->CreateColormap		= ngleCreateColormap;
!     pScreen->DestroyColormap		= ngleDestroyColormap; 
!     pScreen->InstallColormap		= ngleInstallColormap;
!     pScreen->UninstallColormap		= ngleUninstallColormap;
!     pScreen->ListInstalledColormaps	= ngleListInstalledColormaps;
!     pScreen->StoreColors		= ngleStoreColors;
!     pScreen->ResolveColor		= ngleResolvePseudoColor;
  
  
      /*
***************
*** 1018,1033 ****
       **************************************************************************
       */
  
!     ngleInitSprite(pScreen);
  
      /*
       **************************************************************************
       **
!      ** 	Initialize the image planes.
       **
       **************************************************************************
       */
  
      /* On CRX24, ITE has set up overlay planes to be 3-plane
       * device.  Set up overlays to be 8 planes and write all
       * pixels to transparent.  Then set up the framebuffer colormap
--- 1129,1160 ----
       **************************************************************************
       */
  
!     if (pScreenPriv->deviceID == S9000_ID_HCRX)
!     {
! 	hyperInitSprite(pScreen);
!     }
!     else
!     {
! 	ngleInitSprite(pScreen);
!     }
  
      /*
       **************************************************************************
       **
!      ** 20.     Call hyperResetPlanes() to initialize the image,
!      **         overlay and attribute planes.  This includes doing what is
!      **         necessary to counteract what the ITE has done
       **
       **************************************************************************
       */
  
+     if (pScreenPriv->deviceID == S9000_ID_HCRX)
+     {
+ 	hyperResetPlanes(pScreenPriv, SERVER_INIT);
+     }
+ 
+      /* Initialize the non HCRX image planes. */
+ 
      /* On CRX24, ITE has set up overlay planes to be 3-plane
       * device.  Set up overlays to be 8 planes and write all
       * pixels to transparent.  Then set up the framebuffer colormap
***************
*** 1037,1052 ****
       * all 8 bits.
       */
      
!     if (pScreenPriv->deviceID == S9000_ID_A1439A)
      {
  	rattlerSetupPlanes(pScreenPriv);
      }
!     else
      {
  	elkSetupPlanes(pScreenPriv);
      }
  
!     /* Clear attribute planes on Artist, CRX, CRX24 and GRX devices.
       */
      if ((pScreenPriv->deviceID == S9000_ID_A1659A) ||	/* CRX or GRX */
  	(pScreenPriv->deviceID == S9000_ID_A1439A) ||	/* CRX24 */
--- 1164,1181 ----
       * all 8 bits.
       */
      
!     else if (pScreenPriv->deviceID == S9000_ID_A1439A)	/* CRX24 */
      {
  	rattlerSetupPlanes(pScreenPriv);
      }
!     else if ((pScreenPriv->deviceID == S9000_ID_A1659A) || /* CRX or GRX */
! 	     (pScreenPriv->deviceID == S9000_ID_ARTIST)    /* Artist */
! 	)
      {
  	elkSetupPlanes(pScreenPriv);
      }
  
!     /* Clear attribute planes on non HCRX devices.
       */
      if ((pScreenPriv->deviceID == S9000_ID_A1659A) ||	/* CRX or GRX */
  	(pScreenPriv->deviceID == S9000_ID_A1439A) ||	/* CRX24 */
***************
*** 1054,1069 ****
         )
      {
  	if (pScreenPriv->devDepth == 24)
! 	    ngleSetupAttrPlanes(pScreenPriv,BUFF1_CMAP3);
  	else  /* depth = 8 */
  	    if (pScreenPriv->deviceID == S9000_ID_ARTIST)
! 		ngleSetupAttrPlanes(pScreenPriv,ARTIST_CMAP0);
  	    else
! 		ngleSetupAttrPlanes(pScreenPriv,BUFF1_CMAP0);
! 	
      }
  
- 
      /*
       **************************************************************************
       **
--- 1183,1196 ----
         )
      {
  	if (pScreenPriv->devDepth == 24)
! 	    ngleSetupAttrPlanes(pScreenPriv, BUFF1_CMAP3);
  	else  /* depth = 8 */
  	    if (pScreenPriv->deviceID == S9000_ID_ARTIST)
! 		ngleSetupAttrPlanes(pScreenPriv, ARTIST_CMAP0);
  	    else
! 		ngleSetupAttrPlanes(pScreenPriv, BUFF1_CMAP0);
      }
  
      /*
       **************************************************************************
       **
***************
*** 1124,1130 ****
       **********************************************/
      SETUP_RAMDAC(pDregs);
      
!     SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth);
  
  }   /* elkSetupPlanes() */
  
--- 1251,1257 ----
       **********************************************/
      SETUP_RAMDAC(pDregs);
      
!     SETUP_FB(pDregs, pScreenPriv->deviceID, pScreenPriv->devDepth);
  
  }   /* elkSetupPlanes() */
  
***************
*** 1152,1163 ****
       **********************************************/
      CRX24_SETUP_RAMDAC(pDregs);
      
! 	
!     SETUP_FB(pDregs, CRX24_OVERLAY_PLANES,pScreenPriv->devDepth);
  	
      for (y=0; y < pScreenPriv->screenHeight; y++)
      {
! 	bits = (Card32 *) ((char *)pScreenPriv->fbaddr + y * pScreenPriv->devWidth);
  	x = pScreenPriv->screenWidth >> 2;
  	do 
  	{
--- 1279,1290 ----
       **********************************************/
      CRX24_SETUP_RAMDAC(pDregs);
      
!     SETUP_FB(pDregs, CRX24_OVERLAY_PLANES, pScreenPriv->devDepth);
  	
      for (y=0; y < pScreenPriv->screenHeight; y++)
      {
! 	bits = (Card32 *) ((char *)pScreenPriv->fbaddr + y * 
! 					pScreenPriv->devWidth);
  	x = pScreenPriv->screenWidth >> 2;
  	do 
  	{
***************
*** 1174,1197 ****
  
  /******************************************************************************
   *
   * NGLE DDX Utility Procedure:	ngleSetupAttrPlanes
   *
   ******************************************************************************/
  
  static void ngleSetupAttrPlanes(
- 
      NgleScreenPrivPtr	    pScreenPriv,
      Card32		    BufferNumber)
  {
      NgleHdwPtr	    pDregs = pScreenPriv->pDregs;
  
!     SETUP_ATTR_ACCESS(pDregs,BufferNumber);
  
!     SET_ATTR_SIZE(pDregs,pScreenPriv->screenWidth,pScreenPriv->screenHeight);
  
      FINISH_ATTR_ACCESS(pDregs);
  
!     SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth);
  
  } /* ngleSetupAttrPlanes() */
  
--- 1301,1376 ----
  
  /******************************************************************************
   *
+  * NGLE DDX Utility Procedure:	hyperSetupPlanes
+  *
+  ******************************************************************************/
+ 
+ static void hyperSetupPlanes(
+     NgleScreenPrivPtr       pScreenPriv)
+ {
+     NgleHdwPtr		pDregs;
+     Int32		x, y;
+     Card32		*bits;
+ 
+     pDregs 	= (NgleHdwPtr) pScreenPriv->pDregs;
+ 
+     /**************************************************
+      ** Need to clear screen
+      **************************************************/
+ /*
+     if (IS_24_DEVICE(pScreenPriv))
+ 	ngleDepth24_ClearImagePlanes(pScreenPriv);
+     else
+ 	ngleDepth8_ClearImagePlanes(pScreenPriv);
+ 
+ */
+     /**********************************************
+      * Write RAMDAC pixel read mask register so all overlay
+      * planes are display-enabled.  (CRX24 uses Bt462 pixel
+      * read mask register for overlay planes, not image planes).
+      **********************************************/
+     HCRX_SETUP_RAMDAC(pDregs);
+     
+ 	
+     SETUP_FB(pDregs, S9000_ID_HCRX, pScreenPriv->devDepth);
+ 	
+     for (y=0; y < pScreenPriv->screenHeight; y++)
+     {
+ 	bits = (Card32 *) ((char *)pScreenPriv->fbaddr + y * 
+ 					pScreenPriv->devWidth);
+ 	x = pScreenPriv->screenWidth >> 2;
+ 	do 
+ 	{
+ 	    *bits++ = 0xffffffff;
+ 	}  while (x--);
+     }
+     
+     CRX24_SET_OVLY_MASK(pDregs);
+     SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth);
+ 
+ }   /* hyperSetupPlanes() */
+ 
+ 
+ 
+ /******************************************************************************
+  *
   * NGLE DDX Utility Procedure:	ngleSetupAttrPlanes
   *
   ******************************************************************************/
  
  static void ngleSetupAttrPlanes(
      NgleScreenPrivPtr	    pScreenPriv,
      Card32		    BufferNumber)
  {
      NgleHdwPtr	    pDregs = pScreenPriv->pDregs;
  
!     SETUP_ATTR_ACCESS(pDregs, BufferNumber);
  
!     SET_ATTR_SIZE(pDregs, pScreenPriv->screenWidth, pScreenPriv->screenHeight);
  
      FINISH_ATTR_ACCESS(pDregs);
  
!     SETUP_FB(pDregs, pScreenPriv->deviceID, pScreenPriv->devDepth);
  
  } /* ngleSetupAttrPlanes() */
  
***************
*** 1211,1217 ****
   ******************************************************************************/
  
  static Bool ngleClearScreen(
- 
      ScreenPtr	pScreen)
  {
      NgleScreenPrivPtr       pScreenPriv;
--- 1390,1395 ----
***************
*** 1244,1259 ****
          } 
      }
  
!     /* Clear attribute planes on Artist, CRX, CRX24 and GRX devices.
       */
      if ((pScreenPriv->deviceID == S9000_ID_A1659A) ||	/* CRX or GRX */
  	(pScreenPriv->deviceID == S9000_ID_A1439A) ||   /* CRX24 */
! 	(pScreenPriv->deviceID == S9000_ID_ARTIST)      /* Artist */
         )
      {
! 	ngleSetupAttrPlanes(pScreenPriv,BUFF0_CMAP0);
      }
! }
  
  
  
--- 1422,1438 ----
          } 
      }
  
!     /* Clear attribute planes on Hyperdrive, Artist, CRX, CRX24 and GRX devices.
       */
      if ((pScreenPriv->deviceID == S9000_ID_A1659A) ||	/* CRX or GRX */
  	(pScreenPriv->deviceID == S9000_ID_A1439A) ||   /* CRX24 */
! 	(pScreenPriv->deviceID == S9000_ID_ARTIST) ||   /* Artist */
! 	(pScreenPriv->deviceID == S9000_ID_HCRX)	/* Hyperdrive */
         )
      {
! 	ngleSetupAttrPlanes(pScreenPriv, BUFF0_CMAP0);
      }
! } /* ngleClearScreen() */
  
  
  
***************
*** 1299,1310 ****
  	{
  	    ARTIST_DISABLE_DISPLAY(pDregs);
  	}
  	else
  	{   /* CRX and like elk */
  	    DISABLE_DISPLAY(pDregs);
  	}
      }
!     else
      {	/* Turn off screen blanking */
  
  	/* If the cursor is on this screen, display it.
--- 1478,1493 ----
  	{
  	    ARTIST_DISABLE_DISPLAY(pDregs);
  	}
+ 	else if (pScreenPriv->deviceID == S9000_ID_HCRX)
+ 	{
+ 	    HYPER_DISABLE_DISPLAY(pDregs);
+ 	}
  	else
  	{   /* CRX and like elk */
  	    DISABLE_DISPLAY(pDregs);
  	}
      }
!     else /* if (blankOrUnblank == SCREEN_SAVER_OFF) */
      {	/* Turn off screen blanking */
  
  	/* If the cursor is on this screen, display it.
***************
*** 1314,1321 ****
  	extern int hpActiveScreen; /* active screen index in x_hil.c */
      	if (pScreenPriv->myNum == hpActiveScreen)
  	{
! 	    ngleDisplayCursor(pScreenPriv->pScreen,
! 		pScreenPriv->sprite.pCursor);
  	}
  
  	/* Enable image display by disabling display of
--- 1497,1512 ----
  	extern int hpActiveScreen; /* active screen index in x_hil.c */
      	if (pScreenPriv->myNum == hpActiveScreen)
  	{
! 	    if (pScreenPriv->deviceID == S9000_ID_HCRX)
! 	    {
! 		hyperDisplayCursor(pScreenPriv->pScreen,
! 		    pScreenPriv->sprite.pCursor);
! 	    }
! 	    else
! 	    {
! 		ngleDisplayCursor(pScreenPriv->pScreen,
! 		    pScreenPriv->sprite.pCursor);
! 	    }
  	}
  
  	/* Enable image display by disabling display of
***************
*** 1329,1334 ****
--- 1520,1529 ----
  	{
  	    ARTIST_ENABLE_DISPLAY(pDregs);
  	}
+ 	else if (pScreenPriv->deviceID == S9000_ID_HCRX)
+ 	{
+ 	    HYPER_ENABLE_DISPLAY(pDregs);
+ 	}
  	else
  	{   /* CRX and like elk */
  	    ENABLE_DISPLAY(pDregs);
***************
*** 1418,1424 ****
      if (hpGivingUp)
      {
  	(*php->CursorOff)(pScreen);
! 	ngleClearScreen(pScreen);
      }
  
      /* Turn off screen saver (if on) */
--- 1613,1626 ----
      if (hpGivingUp)
      {
  	(*php->CursorOff)(pScreen);
! 	if (pScreenPriv->deviceID == S9000_ID_HCRX)
! 	{
! 	    hyperResetPlanes(pScreenPriv, SERVER_EXIT);
! 	}
! 	else
! 	{
! 	    ngleClearScreen(pScreen);
! 	}
      }
  
      /* Turn off screen saver (if on) */
***************
*** 1436,1443 ****
       * (which is only head that can be an ITE console on Tomcat).
       */
  #define GCTERM _IOWR('G',20,int)
!     if ((hpGivingUp)
!     && (!IS_NOT_FIRST_HEAD_ON_THIS_SGC_SLOT(pScreenPriv->dev_sc)))
      {
  	int garbage=0;
  	ioctl(pScreenPriv->fildes, GCTERM, &garbage);
--- 1638,1645 ----
       * (which is only head that can be an ITE console on Tomcat).
       */
  #define GCTERM _IOWR('G',20,int)
!     if ((hpGivingUp) && 
! 	(!IS_NOT_FIRST_HEAD_ON_THIS_SGC_SLOT(pScreenPriv->dev_sc)))
      {
  	int garbage=0;
  	ioctl(pScreenPriv->fildes, GCTERM, &garbage);
***************
*** 1468,1470 ****
--- 1670,2070 ----
      return(TRUE);
  
  } /* ngleCloseScreen() */
+ 
+ 
+ /******************************************************************************
+  *
+  *  And now for some new routines to handle HCRX8 and HCRX24
+  *
+  ******************************************************************************/
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Procedure:		ngleDepth8_ClearImagePlanes()
+  *
+  * Description:
+  *
+  *	This routine clears the image planes for depth 8 devices.
+  *
+  * Assumptions:
+  *	Assumptions fast-locking has been initialized.
+  *	Does not assume a lock is in effect.
+  *
+  ******************************************************************************/
+ 
+ void ngleDepth8_ClearImagePlanes(
+     NgleScreenPrivPtr       pScreenPriv)
+ {
+     NgleHdwPtr              pDregs;
+     NGLE_MFGP_REGISTER_TYPE packedLenXY;
+     NGLE_MFGP_REGISTER_TYPE packedDstXY;
+     Int32		    nFreeFifoSlots = 0;
+ 
+     pDregs 	= (NgleHdwPtr) pScreenPriv->pDregs;
+ 
+     NGLE_LOCK(pScreenPriv);
+ 
+     /* Common Hardware setup */
+     GET_FIFO_SLOTS(nFreeFifoSlots, 5);
+ 
+     /* Re-use dstX/Y and transfer data for multiple recfills.  */
+     NGLE_SET_SCOREBOARD_OVERRIDE(0x30003);
+     NGLE_SET_TRANSFERDATA(0xffffffff);   /* Write foreground color */
+ 
+     NGLE_REALLY_SET_IMAGE_FG_COLOR(0);	
+     NGLE_REALLY_SET_IMAGE_PLANEMASK(0xff);
+ 
+     PACK_2CARD16(packedDstXY, 0, 0);
+     PACK_2CARD16(packedLenXY, pScreenPriv->screenWidth,
+ 		 pScreenPriv->screenHeight);
+     NGLE_SET_DSTXY(NGLE_MFGP_REGISTER_TYPE_ASLONG(packedDstXY));
+ 
+     /* Device-specific image buffer clear */
+     switch(pScreenPriv->deviceID)
+     {
+     case S9000_ID_ARTIST:
+ 	/* Write zeroes to buffer */
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 3);
+ 	NGLE_QUICK_SET_IMAGE_BITMAP_OP(
+ 	    IBOvals(RopSrc, MaskAddrOffset(0),
+ 		    BitmapExtent08, StaticReg(FALSE),
+ 		    DataDynamic, MaskOtc, BGx(FALSE), FGx(FALSE)));
+ 	NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	    BA(     IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 		BAJustPoint(0), BINapp0I, BAIndexBase(0)));
+ 	SET_LENXY_START_RECFILL(packedLenXY);
+ 	break;
+ 
+     case S9000_ID_A1659A:   /* ELK_DEVICE_ID */
+ 	/* Write zeroes to buffer 0 */
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 3);
+ 	NGLE_QUICK_SET_IMAGE_BITMAP_OP(
+ 	    IBOvals(RopSrc, MaskAddrOffset(0),
+ 		    BitmapExtent08, StaticReg(FALSE),
+ 		    DataDynamic, MaskOtc, BGx(FALSE), FGx(FALSE)));
+ 	NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	    BA(	IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 		BAJustPoint(0), BINapp0I, BAIndexBase(0)));
+ 	SET_LENXY_START_RECFILL(packedLenXY);
+ 
+ 	/* Write zeroes to buffer 1 */
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 	NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	    BA(	IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 		BAJustPoint(0), BINapp1I, BAIndexBase(0)));
+ 	SET_LENXY_START_RECFILL(packedLenXY);
+ 	break;
+ 
+     case S9000_ID_HCRX:
+ 	/* Write zeroes to buffer 0 */
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 3);
+ 	NGLE_QUICK_SET_IMAGE_BITMAP_OP(IBOvals(RopSrc, MaskAddrOffset(0),
+ 				  BitmapExtent08, StaticReg(FALSE),
+ 				  MaskDynamic, MaskOtc,
+ 				  BGx(TRUE), FGx(FALSE)));
+ 	NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	    BA(	IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 	    BAJustPoint(0), BINapp0I, BAIndexBase(0)));
+ 	HYPER_SET_LENXY_START_FAST_RECFILL(packedLenXY.all);
+ 
+ 	/* Write zeroes to buffer 1 */
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 	NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	    BA(	IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 		    BAJustPoint(0), BINapp1I, BAIndexBase(0)));
+ 	HYPER_SET_LENXY_START_FAST_RECFILL(packedLenXY.all);
+ 	break;
+ 
+     /* There is no default */
+     }   /* Device-specific image buffer clear */
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+ } /* ngleDepth8_ClearImagePlanes() */
+ 
+ 
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Utility Procedure:		ngleDepth24_ClearImagePlanes
+  *
+  * Description:
+  *
+  *	This routine clears all 24 image planes to zeroes.
+  *
+  * Assumptions:
+  *	Assumptions fast-locking has been initialized.
+  *	Does not assume a lock is in effect.
+  *
+  ******************************************************************************/
+ 
+ void ngleDepth24_ClearImagePlanes(
+     NgleScreenPrivPtr       pScreenPriv)
+ {
+     NgleHdwPtr              pDregs;
+     NGLE_MFGP_REGISTER_TYPE packedLenXY;
+     NGLE_MFGP_REGISTER_TYPE packedDstXY;
+     Int32		    nFreeFifoSlots = 0;
+ 
+     pDregs 	= (NgleHdwPtr) pScreenPriv->pDregs;
+ 
+     NGLE_LOCK(pScreenPriv);
+ 
+     /* Hardware setup */
+     GET_FIFO_SLOTS(nFreeFifoSlots, 8);
+     NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	BA(IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 	   BAJustPoint(0), BINapp0F8, BAIndexBase(0)));
+     NGLE_SET_SCOREBOARD_OVERRIDE(0);
+     NGLE_SET_TRANSFERDATA(0xffffffff);   	/* Write foreground color */
+ 
+     NGLE_REALLY_SET_IMAGE_FG_COLOR(0);		/* load with zero */
+     NGLE_REALLY_SET_IMAGE_PLANEMASK(0xffffff);
+ 
+     PACK_2CARD16(packedDstXY, 0, 0);
+     PACK_2CARD16(packedLenXY, pScreenPriv->screenWidth,
+ 		 pScreenPriv->screenHeight);
+     NGLE_SET_DSTXY(NGLE_MFGP_REGISTER_TYPE_ASLONG(packedDstXY));
+ 
+     /* Write zeroes to all 24 planes of image buffer */
+     NGLE_QUICK_SET_IMAGE_BITMAP_OP(IBOvals(RopSrc, MaskAddrOffset(0),
+ 	    BitmapExtent32, StaticReg(FALSE),
+ 	    DataDynamic, MaskOtc, BGx(FALSE), FGx(FALSE)));
+     SET_LENXY_START_RECFILL(packedLenXY);
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+ } /* ngleDepth24_ClearImagePlanes */
+ 
+ 
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Procedure:		ngleClearOverlayPlanes()
+  *
+  * Description:
+  *
+  *	This routine "clears" the overlay planes to the pased in value.
+  *
+  * Assumptions:
+  *	Assumptions fast-locking has been initialized.
+  *	Does not assume a lock is in effect.
+  *
+  ******************************************************************************/
+ 
+ void ngleClearOverlayPlanes(
+     NgleScreenPrivPtr       pScreenPriv,
+     Card32                  planeMask,
+     Card32                  planeData)
+ {
+     NgleHdwPtr              pDregs;
+     NGLE_MFGP_REGISTER_TYPE packedLenXY;
+     NGLE_MFGP_REGISTER_TYPE packedDstXY;
+     Int32		    nFreeFifoSlots = 0;
+ 
+     pDregs 	= (NgleHdwPtr) pScreenPriv->pDregs;
+ 
+     NGLE_LOCK(pScreenPriv);
+ 
+     /* Hardware setup */
+     GET_FIFO_SLOTS(nFreeFifoSlots, 8);
+     NGLE_QUICK_SET_DST_BM_ACCESS(
+ 	BA( IndexedDcd, Otc32, OtsIndirect, AddrLong,
+ 	    BAJustPoint(0), BINovly, BAIndexBase(0)));
+     NGLE_SET_SCOREBOARD_OVERRIDE(0);
+     NGLE_SET_TRANSFERDATA(0xffffffff);	/* Write foreground color */
+ 
+     NGLE_REALLY_SET_IMAGE_FG_COLOR(planeData);	/* fill with input data value */
+     NGLE_REALLY_SET_IMAGE_PLANEMASK(planeMask);
+ 
+     PACK_2CARD16(packedDstXY, 0, 0);
+     PACK_2CARD16(packedLenXY, pScreenPriv->screenWidth,
+ 		 pScreenPriv->screenHeight);
+     NGLE_SET_DSTXY(NGLE_MFGP_REGISTER_TYPE_ASLONG(packedDstXY));
+ 
+     /* Write zeroes to overlay planes. */
+     NGLE_QUICK_SET_IMAGE_BITMAP_OP(
+ 	IBOvals(RopSrc, MaskAddrOffset(0),
+ 		BitmapExtent08, StaticReg(FALSE),
+ 		DataDynamic, MaskOtc, BGx(FALSE), FGx(FALSE)));
+     SET_LENXY_START_RECFILL(packedLenXY);
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+ } /* ngleClearOverlayPlanes() */
+ 
+ 
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Procedure:		ngleResetAttrPlanes()
+  *
+  * Description:
+  *
+  *	This routine resets the attribute planes to an initial state.
+  *
+  * Assumptions:
+  *	Assumptions fast-locking has been initialized.
+  *	Does not assume a lock is in effect.
+  *
+  ******************************************************************************/
+ 
+ void ngleResetAttrPlanes(
+     NgleScreenPrivPtr       pScreenPriv,
+     Card32                  controlPlaneReg)
+ {
+     BoxRec		    box;
+ 
+ 
+     box.x1 = 0;
+     box.y1 = 0;
+     box.x2 = pScreenPriv->screenWidth;
+     box.y2 = pScreenPriv->screenHeight;
+     nglePolyPaintAttr(pScreenPriv, controlPlaneReg, 1, &box);
+ 
+ } /* ngleResetAttrPlanes() */
+ 
+ 
+ 
+ /******************************************************************************
+  *
+  * NGLE DDX Procedure:		nglePolyPaintAttr()
+  *
+  * Description:
+  *
+  *	This routine is called by other NGLE DDX driver routines to perform
+  *	a series of solid color, rectangle fills of the attribute plane(s).
+  *
+  * 	Useful comments about attribute painting:
+  *
+  *	    The Control Plane Register (CPR) is the equivalent of
+  *	    foreground and background pixel registers for the attribute
+  *	    planes.
+  *
+  *	    The most significant byte (CFC:  Control Foreground Color)
+  *	    determines what's written if the foreground color is written
+  *	    to the attribute planes.
+  *
+  *	    The next most significant byte (CBC:  Control Background
+  *	    Color) determines what's written if a zero is written.
+  *
+  *	    The third byte (CPM:  Control Plane Mask Byte) indicates
+  *	    which group of planes is active.
+  *
+  *	    Control Bitmap Operation (CBO) determines whether foreground
+  *	    or background color is transparent or opaque.  Here, we
+  *	    choose opaque for foreground and background (the latter is a
+  *	    don't-care).
+  *
+  *          The ctlPlaneReg parameter which is passed into this routine
+  *	    represents the value to be loaded into the CPR.  The CPR
+  *	    value is device specific, as each device has its own
+  *	    particular mapping of bits in the CPR fields to the devices
+  *	    attribute planes.  But, the CPR register appears at the same
+  *	    address in each of the devices control register space.
+  *	    Therefore, each device can use this common routine to paint
+  *	    attribute planes.
+  *
+  ******************************************************************************/
+ 
+ static void nglePolyPaintAttr(
+     NgleScreenPrivPtr           pScreenPriv,
+     Card32			ctlPlaneReg,
+     Int32			nBoxes,
+     BoxPtr			pBoxes)
+ {
+     Int32			nFreeFifoSlots = 0;
+ /*## For now, treat as 32-bit integers so that we don't have to unpack: ##*/
+ /*##    Int16			*pBox;##*/
+     Int32			*pBox;
+     NgleHdwPtr			pDregs;
+     NGLE_MFGP_REGISTER_TYPE	packedDstXY;
+     NGLE_MFGP_REGISTER_TYPE	packedLenXY;
+ 
+ 
+     /* Return early if there's nothing to do: */
+     if (nBoxes <= 0)
+ 	return;
+ 
+     pDregs = pScreenPriv->pDregs; 
+     NGLE_LOCK(pScreenPriv);
+ 
+ 
+     /*
+      **************************************************************************
+      **
+      ** Paint the Boxes in the Attribute Planes:
+      **
+      **************************************************************************
+      */
+ 
+     GET_FIFO_SLOTS(nFreeFifoSlots, 4);
+     NGLE_QUICK_SET_DST_BM_ACCESS(BA(IndexedDcd, Otc32, OtsIndirect,
+ 					AddrLong, BAJustPoint(0),
+ 					BINattr, BAIndexBase(0)));
+     NGLE_QUICK_SET_CTL_PLN_REG(ctlPlaneReg);
+     NGLE_SET_TRANSFERDATA(0xffffffff);
+ 
+     /* Loop on boxes: */
+     pBox = (Int32 *) pBoxes;
+     NGLE_QUICK_SET_IMAGE_BITMAP_OP(IBOvals(RopSrc, MaskAddrOffset(0),
+ 					BitmapExtent08, StaticReg(TRUE),
+ 					DataDynamic, MaskOtc,
+ 					BGx(TRUE), FGx(FALSE)));
+     do
+     {
+ 	packedDstXY.all = *pBox++;
+ 	packedLenXY.all = (*pBox++) - packedDstXY.all;
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 	NGLE_SET_DSTXY(NGLE_MFGP_REGISTER_TYPE_ASLONG(packedDstXY));
+ 	SET_LENXY_START_RECFILL(packedLenXY);
+     } while (--nBoxes > 0);
+ 
+ 
+     /*
+      **************************************************************************
+      **
+      ** In order to work around an ELK hardware problem (Buffy doesn't
+      ** always flush it's buffers when writing to the attribute
+      ** planes), at least 4 pixels must be written to the attribute
+      ** planes starting at (X == 1280) and (Y != to the last Y written
+      ** by BIF):
+      **
+      **************************************************************************
+     */
+ 
+     if (pScreenPriv->deviceID == S9000_ID_A1659A)   /* ELK_DEVICE_ID */
+     {
+ 	/*## NOTE: This may cause problems on a 2K-wide device: ##*/
+ 	if (packedLenXY.xy.y > 0)
+ 	{
+ 	    /* It's safe to use scanline zero: */
+ 	    PACK_2CARD16(packedDstXY, 1280, 0);
+ 	}
+ 	else
+ 	{
+ 	    /* Must generate a safe scanline: */
+ 	    if (packedDstXY.xy.y > 0)
+ 	    {
+ 		PACK_2CARD16(packedDstXY, 1280, 0);
+ 	    }
+ 	    else
+ 	    {
+ 		PACK_2CARD16(packedDstXY, 1280, 1);
+ 	    }
+ 	}
+ 
+ 	GET_FIFO_SLOTS(nFreeFifoSlots, 2);
+ 	NGLE_SET_DSTXY(NGLE_MFGP_REGISTER_TYPE_ASLONG(packedDstXY));
+ 	PACK_2CARD16(packedLenXY, 4, 1);
+ 	SET_LENXY_START_RECFILL(packedLenXY);
+     }   /* ELK Hardware Kludge */
+ 
+ 
+     /**** Finally, set the Control Plane Register back to zero: ****/
+     GET_FIFO_SLOTS(nFreeFifoSlots, 1);
+     NGLE_QUICK_SET_CTL_PLN_REG(0);
+ 
+     NGLE_UNLOCK(pScreenPriv);
+ 
+ } /* nglePolyPaintAttr() */
*** -	Wed Jan 25 18:48:12 1995
--- xc/programs/Xserver/hw/hp/input/Imakefile	Wed Jan 25 18:48:11 1995
***************
*** 1,77 ****
! XCOMM $XConsortium: Imakefile,v 1.5 94/05/28 15:50:16 dpw Exp $
  #include <Server.tmpl>
  
  #define IHaveSubdirs
  
  SUBDIRS=drivers
  
- #if defined(HPArchitecture) || defined(HPOSFArchitecture)
- 
  SRCS1 =	\
  	hpKeyMap.c	\
  	x_hil.c		\
  	x_hilinit.c	\
- 	beeper.c	\
- 	x_threebut.c	\
  	xtest1imp.c	\
  	getkeysym.c
  
- #if defined(__hp9000s800)
  
  SRCS2 = \
          cr16.s          \
          get_tv.c
  
- #endif  /* __hp9000s800 */
  
  NONHILOBJS = \
  	hpKeyMap.o	\
- 	x_threebut.o	\
  	xtest1imp.o	\
  	getkeysym.o
  
- #if defined(__hp9000s800) 
  
  NONHILOBJS2 = \
          cr16.o          \
          get_tv.o
  
- #endif  /* __hp9000s800 */
- 
- #else
- 
- SRCS1 =	\
- 	hpKeyMap.c	\
- 	x_hil.c		\
- 	x_hilinit.c	\
- 	beeper.c	\
- 	x_threebut.c	\
- 	xtest1imp.c	\
- 	getkeysym.c
- 
- NONHILOBJS = \
- 	hpKeyMap.o	\
- 	x_threebut.o	\
- 	xtest1imp.o	\
- 	getkeysym.o
- 
- #endif	/* HPArchitecture */
  
  SRCS = $(SRCS1) $(SRCS2) 
  
  
  HILOBJS = \
  	x_hil.o		\
! 	x_hilinit.o	\
! 	beeper.o	
! 
! #ifdef __hp9000s700
! HILOBJS800 = \
! 	x_hil800.o		\
! 	x_hilinit800.o	\
! 	beeper800.o	
! OBJS800 = $(NONHILOBJS) $(HILOBJS800)
! #endif
  
  OBJS = $(NONHILOBJS) $(NONHILOBJS2) $(HILOBJS)
  
--- 1,40 ----
! XCOMM $XConsortium: Imakefile,v 1.6 95/01/24 02:41:07 dpw Exp $
  #include <Server.tmpl>
  
  #define IHaveSubdirs
  
  SUBDIRS=drivers
  
  SRCS1 =	\
  	hpKeyMap.c	\
  	x_hil.c		\
  	x_hilinit.c	\
  	xtest1imp.c	\
  	getkeysym.c
  
  
  SRCS2 = \
          cr16.s          \
          get_tv.c
  
  
  NONHILOBJS = \
  	hpKeyMap.o	\
  	xtest1imp.o	\
  	getkeysym.o
  
  
  NONHILOBJS2 = \
          cr16.o          \
          get_tv.o
  
  
  SRCS = $(SRCS1) $(SRCS2) 
  
  
  HILOBJS = \
  	x_hil.o		\
! 	x_hilinit.o
  
  OBJS = $(NONHILOBJS) $(NONHILOBJS2) $(HILOBJS)
  
***************
*** 79,86 ****
  	hpKeyMap.ln	\
  	x_hil.ln	\
  	x_hilinit.ln	\
- 	beeper.ln	\
- 	x_threebut.ln	\
  	xtest1imp.ln	\
  	getkeysym.ln
  
--- 42,47 ----
***************
*** 99,114 ****
  NormalLibraryObjectRule()
  NormalLibraryTarget(hp,$(OBJS))
  
- #ifdef __hp9000s700
- /* 800 mu server only .o's */
- ObjectFromSpecialSource(beeper800,beeper,-U__hp9000s700)
- ObjectFromSpecialSource(x_hil800,x_hil,-U__hp9000s700)
- ObjectFromSpecialSource(x_hilinit800,x_hilinit,-U__hp9000s700)
- 
- NormalLibraryTarget(hp800,$(OBJS800))
- #endif
- 
  SpecialCObjectRule(x_hilinit,$(ICONFIGFILES),$(LIB_DEFINES))
  SpecialCObjectRule(getkeysym,$(ICONFIGFILES),$(LIB_DEFINES))
  DependTarget()
  
--- 60,67 ----
  NormalLibraryObjectRule()
  NormalLibraryTarget(hp,$(OBJS))
  
  SpecialCObjectRule(x_hilinit,$(ICONFIGFILES),$(LIB_DEFINES))
+ SpecialCObjectRule(x_hil,$(ICONFIGFILES),$(LIB_DEFINES))
  SpecialCObjectRule(getkeysym,$(ICONFIGFILES),$(LIB_DEFINES))
  DependTarget()
  
*** -	Wed Jan 25 18:48:13 1995
--- xc/programs/Xserver/hw/hp/input/hildef.h	Wed Jan 25 18:48:12 1995
***************
*** 1,9 ****
  #ifndef HILDEF_H
  #define HILDEF_H
! /* $XConsortium: hildef.h,v 8.34 94/04/17 20:30:12 rws Exp $ */
  /*
  
! Copyright (c) 1986, 1987  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
--- 1,9 ----
  #ifndef HILDEF_H
  #define HILDEF_H
! /* $XConsortium: hildef.h,v 8.36 95/01/24 21:13:11 gildea Exp $ */
  /*
  
! Copyright (c) 1988  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
***************
*** 30,52 ****
  from the X Consortium.
  
  
! Copyright (c) 1986, 1987 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this
! software and its documentation for any purpose and without
! fee is hereby granted, 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 Hewlett-Packard not be used in
! advertising or publicity pertaining to distribution of the
! software without specific, written prior permission.
  
  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
! PURPOSE.  Hewlett-Packard shall not be liable for errors 
! contained herein or direct, indirect, special, incidental or 
! consequential damages in connection with the furnishing, 
  performance, or use of this material.
  
  This software is not subject to any license of the American
--- 30,52 ----
  from the X Consortium.
  
  
! Copyright (c) 1988 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this software 
! and its documentation for any purpose and without fee is hereby 
! granted, 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 
! Hewlett-Packard not be used in advertising or publicity 
! pertaining to distribution of the software without specific, written 
! prior permission.
  
  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE.  Hewlett-Packard shall not be liable for errors
! contained herein or direct, indirect, special, incidental or
! consequential damages in connection with the furnishing,
  performance, or use of this material.
  
  This software is not subject to any license of the American
***************
*** 54,60 ****
  University of California.
  
  */
- 
  /*
  ** 	File: hildefs.h
  **
--- 54,59 ----
***************
*** 62,67 ****
--- 61,67 ----
  **
  */
  
+ #include  "x_serialdrv.h"
  #include  "sys/param.h"
  #include  "X.h"
  #include  "scrnintstr.h"
***************
*** 72,77 ****
--- 72,78 ----
  /* KEEP THE FOLLOWING IN SYNC WITH THE DIX DEFINITION          */
  /***************************************************************/
  
+ #define	MAXNAMLEN		255
  #define READ_SIZ	     	2000	/* leave room for partial packets*/
  #define BUF_SIZ			2048	/* size of static buffer to use  */
  
***************
*** 132,196 ****
  #define NLOCK		3
  #define CAPSCODE	0x37
  #define KBSIZE		32	/* bytes to hold 256 bits (1 per key/button */
! #define LedOn(dev, d,cd,data) \
! (dev->key->modifierMap[cd] & d->led[0] ? ioctl(d->file_ds,LedCmd[0].on,data) : \
!  dev->key->modifierMap[cd] & d->led[1] ? ioctl(d->file_ds,LedCmd[1].on,data) : \
!  dev->key->modifierMap[cd] & d->led[2] ? ioctl(d->file_ds,LedCmd[2].on,data) : \
!  ioctl(d->file_ds, LedCmd[3].on, data))
! #define LedOff(dev, d,cd,data) \
! (dev->key->modifierMap[cd] & d->led[0] ? ioctl(d->file_ds,LedCmd[0].off,data): \
!  dev->key->modifierMap[cd] & d->led[1] ? ioctl(d->file_ds,LedCmd[1].off,data): \
!  dev->key->modifierMap[cd] & d->led[2] ? ioctl(d->file_ds,LedCmd[2].off,data): \
!  ioctl(d->file_ds, LedCmd[3].off, data))
! #define LatchKey(d,code) (d->kb_latched[code>>3] |= (1<<(code & 7)))
! #define LatchButton(d,code) (LatchKey(d,code))
! #define UnlatchKey(d,code) (d->kb_latched[code>>3] &= ~(1<<(code & 7)))
! #define UnlatchButton(d,code) (UnlatchKey(d,code))
! #define DeviceHasLeds(d) (d->hil_header.iob & HILIOB_NPA)
  #define KeyHasLed(dev,d,cd) ((dev->key->modifierMap[cd] & d->led[0]) || \
  (dev->key->modifierMap[cd] & d->led[1]) || \
  (dev->key->modifierMap[cd] & d->led[2]) || \
  (dev->key->modifierMap[cd] & d->led[3]))
  
! #define KeyIsLatched(d,code) (d->kb_latched[code>>3] & (1<<(code & 7)))
  #define KeyIsIgnored(d,code) (d->kb_ignore[code>>3] & (1<<(code & 7)))
  #define IgnoreKey(d,code) (d->kb_ignore[code>>3] |= (1<<(code & 7)))
  #define UnignoreKey(d,code) (d->kb_ignore[code>>3] &= ~(1<<(code & 7)))
- #define ButtonIsLatched(d,code) (KeyIsLatched(d,code))
- #define ButtonIsIgnored(d,code) (KeyIsIgnored(d,code))
- #define IgnoreButton(d,code) (IgnoreKey(d,code))
- #define UnignoreButton(d,code) (UnignoreKey(d,code))
  
  #define KeyDownEvent(ev) (ev->u.u.type==KeyPress | ev->u.u.type==DeviceKeyPress)
  #define ButtonDownEvent(ev) (ev->u.u.type==ButtonPress | \
  			     ev->u.u.type==DeviceButtonPress)
  #define KeyUpEvent(ev) (ev->u.u.type==KeyRelease | \
  			     ev->u.u.type==DeviceKeyRelease)
! #define IsLockKey(dev,code) (dev->key->modifierMap[code] & LockMask)
  
  #define KeyIsDown(dev, code) (dev->key && \
      (dev->key->down[code >> 3] & (1 << (code & 7))))
  #define KeyIsRepeating(dev, code) (dev->kbdfeed && \
      (dev->kbdfeed->ctrl.autoRepeats[code >> 3] & (1 << (code & 7))))
  
- struct	hil_desc_record {
-     int		resx;		/* x-axis counts / meter	*/
-     int		resy;		/* x-axis counts / meter	*/
-     int		size_x;		/* maximum x value   		*/
-     int		size_y;		/* maximum y value   		*/
-     char	*keymap_name;	/* name of keymap               */
-     u_char	flags; 		/* device characteristics	*/
-     u_char	ax_num;		/* number of axes		*/
-     u_short 	min_kcode;	/* minimum keycode           	*/
-     u_short 	max_kcode;	/* maximum keycode           	*/
-     u_char	id;		/* device HIL id		*/
-     u_char	iob;		/* I/O descriptor Byte 		*/
-     u_char	p_button_count;	 /* count of physical buttons 	*/
-     u_char	v_button_count;	 /* count of virtual buttons  	*/
-     u_char 	num_keys; 	 /* number of keys            	*/
-     u_char 	num_leds; 	 /* number of leds            	*/
- } ;
- 
  typedef struct _DeviceClients *DeviceClientsPtr;
  
  typedef struct _DeviceClients {
--- 133,182 ----
  #define NLOCK		3
  #define CAPSCODE	0x37
  #define KBSIZE		32	/* bytes to hold 256 bits (1 per key/button */
! #define ExpectUpKey(d,code) (d->kb_exp_up[code>>3] |= (1<<(code & 7)))
! #define DontExpectUpKey(d,code) (d->kb_exp_up[code>>3] &= ~(1<<(code & 7)))
! #define DeviceHasLeds(d) (d->iob & HILIOB_NPA)
  #define KeyHasLed(dev,d,cd) ((dev->key->modifierMap[cd] & d->led[0]) || \
  (dev->key->modifierMap[cd] & d->led[1]) || \
  (dev->key->modifierMap[cd] & d->led[2]) || \
  (dev->key->modifierMap[cd] & d->led[3]))
  
! #define UpIsExpected(d,code) (d->kb_exp_up[code>>3] & (1<<(code & 7)))
  #define KeyIsIgnored(d,code) (d->kb_ignore[code>>3] & (1<<(code & 7)))
  #define IgnoreKey(d,code) (d->kb_ignore[code>>3] |= (1<<(code & 7)))
  #define UnignoreKey(d,code) (d->kb_ignore[code>>3] &= ~(1<<(code & 7)))
  
  #define KeyDownEvent(ev) (ev->u.u.type==KeyPress | ev->u.u.type==DeviceKeyPress)
  #define ButtonDownEvent(ev) (ev->u.u.type==ButtonPress | \
  			     ev->u.u.type==DeviceButtonPress)
  #define KeyUpEvent(ev) (ev->u.u.type==KeyRelease | \
  			     ev->u.u.type==DeviceKeyRelease)
! 
! #define ITF_KATAKANA	0xdd
! #define ITF_JAPANESE	0xc2
! #define PS2_HIL_JIS	0xc1
! #define PS2_DIN_JIS	"PS2_DIN_JIS"
! #define IsLockKey(dev,code) (dev->key->modifierMap[code] & LockMask ? \
! 				LockMapIndex : 0)
! #define IsMod2Key(dev,code) (dev->key->modifierMap[code] & Mod2Mask ? \
! 				Mod2MapIndex : 0)
! #define IsJapaneseEnv(pHP)  (pHP->id == ITF_KATAKANA || \
!                              pHP->id == ITF_JAPANESE || \
!                              pHP->id == PS2_HIL_JIS || \
!                              !strcmp(pHP->d.keymap_name, PS2_DIN_JIS))
! 
! #define IsToggleKey(dev,pHP,code) (IsLockKey(dev,code))
! 
! /* This is the Kana Lock solution that APPO initially wanted.
! #define IsToggleKey(dev,pHP,code) (IsLockKey(dev,code) || \
!        (IsJapaneseEnv(pHP) && IsMod2Key(dev,code)))
! */
  
  #define KeyIsDown(dev, code) (dev->key && \
      (dev->key->down[code >> 3] & (1 << (code & 7))))
  #define KeyIsRepeating(dev, code) (dev->kbdfeed && \
      (dev->kbdfeed->ctrl.autoRepeats[code >> 3] & (1 << (code & 7))))
  
  typedef struct _DeviceClients *DeviceClientsPtr;
  
  typedef struct _DeviceClients {
***************
*** 202,214 ****
  } DeviceClients;
  
  typedef  struct	 _indevices {
!     struct  	hil_desc_record hil_header;  /* HIL hdr 	*/
      float	scaleX; 	/* Tablet scaling 		*/
      float	scaleY; 	/* Tablet scaling 		*/
-     int	        file_ds;        /* file descriptor              */
      DeviceClientsPtr clients;	/* clients using device 	*/
      ScreenPtr	pScreen;  	/* Screen pointer is on         */
-     int   	repeat_rate;	/* keyboard repeat rate         */
      int   	coords[MAX_AXES];/* current coords of device    */
      Atom	x_atom;		/* atom for x type		*/
      u_int	button_state;   /* device button state          */
--- 188,199 ----
  } DeviceClients;
  
  typedef  struct	 _indevices {
!     u_char	id;		/* device HIL id		*/
!     u_char	iob;		/* I/O descriptor Byte 		*/
      float	scaleX; 	/* Tablet scaling 		*/
      float	scaleY; 	/* Tablet scaling 		*/
      DeviceClientsPtr clients;	/* clients using device 	*/
      ScreenPtr	pScreen;  	/* Screen pointer is on         */
      int   	coords[MAX_AXES];/* current coords of device    */
      Atom	x_atom;		/* atom for x type		*/
      u_int	button_state;   /* device button state          */
***************
*** 223,244 ****
      u_char  	ignoremask;	/* for button emulation         */
      u_char  	savebutton;	/* saved button			*/
      char	x_type;		/* MOUSE or KEYBOARD		*/ 
-     u_char	dev_id;	  	/* device X id			*/ 
      u_char	mode;     	/* abs or rel movement  	*/
!     u_char	sndx;		/* index of serialproc entry    */
!     u_char	pad1;		/* reserved                     */
      u_char	pad2;		/* reserved              	*/
-     char	open_cnt;	/* # clients accessing device   */
-     char	dev_name[MAX_X_NAMELEN];
-     char	x_name[MAX_X_NAMELEN];
-     u_char	bell1[4];	/* arrays for the s300 beeper params */
-     u_char	bell2[4];
-     u_char	bell3[4];
      u_char	hpflags;	/* hp-specific feature flags    */
      u_char	led[NLOCK+1];
!     u_char	kb_latched[KBSIZE];
      u_char	kb_ignore[KBSIZE];
  }  HPInputDevice;
  
  struct	dev_info {
      unsigned int	timestamp;
--- 208,228 ----
      u_char  	ignoremask;	/* for button emulation         */
      u_char  	savebutton;	/* saved button			*/
      char	x_type;		/* MOUSE or KEYBOARD		*/ 
      u_char	mode;     	/* abs or rel movement  	*/
!     u_char	use;		/* device use                   */
      u_char	pad2;		/* reserved              	*/
      u_char	hpflags;	/* hp-specific feature flags    */
      u_char	led[NLOCK+1];
!     u_char	kb_exp_up[KBSIZE];
      u_char	kb_ignore[KBSIZE];
+     char 	entry[MAX_NM];
+     char	driver_name[MAX_NM];   /* filled in by X server	*/
+     int		*dpmotionBuf;
+     int		*dheadmotionBuf;
+     HPInputDeviceHeader d;
+     SerialProcs s;
  }  HPInputDevice;
+ 
  
  struct	dev_info {
      unsigned int	timestamp;
*** -	Wed Jan 25 18:48:14 1995
--- xc/programs/Xserver/hw/hp/input/getkeysym.c	Wed Jan 25 18:48:14 1995
***************
*** 1,4 ****
! /* $XConsortium: getkeysym.c,v 1.6 94/05/28 15:50:21 dpw Exp $ */
  /*
  
  Copyright (c) 1986, 1987 by Hewlett-Packard Company
--- 1,4 ----
! /* $XConsortium: getkeysym.c,v 1.7 95/01/24 02:45:23 dpw Exp $ */
  /*
  
  Copyright (c) 1986, 1987 by Hewlett-Packard Company
***************
*** 33,38 ****
--- 33,39 ----
  #define LIBDIR "/usr/lib/X11"
  #endif
  #endif
+ 
  #include <stdio.h>
  #include <X11/XHPlib.h>
  
***************
*** 196,205 ****
  
      if (name[0] != '/')
      {
! 	sprintf(filename, "%s/%s",LIBDIR,name);
      }
!     else
! 	strcpy(filename, name);
  
      if (NULL == (keysym_file = fopen(filename,"r")))
  	return False;
--- 197,205 ----
  
      if (name[0] != '/')
      {
!       sprintf(filename, "%s/%s",LIBDIR,name);
      }
!     else strcpy(filename, name);
  
      if (NULL == (keysym_file = fopen(filename,"r")))
  	return False;
*** -	Wed Jan 25 18:48:16 1995
--- xc/programs/Xserver/hw/hp/input/hpKeyMap.c	Wed Jan 25 18:48:16 1995
***************
*** 1,4 ****
! /* $XConsortium: hpKeyMap.c,v 1.2 94/04/17 20:30:13 rws Exp $ */
  /*
  
  Copyright (c) 1986, 1987  X Consortium
--- 1,4 ----
! /* $XConsortium: hpKeyMap.c,v 1.3 95/01/24 02:46:58 dpw Exp $ */
  /*
  
  Copyright (c) 1986, 1987  X Consortium
***************
*** 58,66 ****
  #include	"keysym.h"
  #include	"X.h"			/* MUST come after above includes */
  #include	"input.h"
- /*  The following two lines wer added to let this compile
-  *  in the pure MIT tree
-  */
  #include      "HPkeysym.h"
  #include      "ap_keysym.h"
  
--- 58,63 ----
***************
*** 71,76 ****
--- 68,74 ----
   * Jack Palevich, HP-Labs
   */
  
+ static int try_and_load_maps();
  
      /* A keymap filled with NoSymbol is all (1) columns.
       * This will be used when the keyboard is unknown and is not in a
***************
*** 781,793 ****
    return TRUE;
  }
  
! static int try_and_load_maps();
  
      /* 
       * Input:
       *   keymap_file:  Name of the file that contains keymaps.  If NULL,
       *		       only look in /usr/lib/X11/XHPKeymaps (the
!      *		       default) (can be overridden, see HPKsetup()).
       *   keymap_name:  Name of the keymap to load.  Sometime like
       *		       "button-box".
       *   keysyms_rec:  Pointer to a KeySymsRec to fill in.
--- 779,794 ----
    return TRUE;
  }
  
! 
! extern char *getenv();
  
      /* 
       * Input:
       *   keymap_file:  Name of the file that contains keymaps.  If NULL,
       *		       only look in /usr/lib/X11/XHPKeymaps (the
!      *		       default) (can be overridden, see HPKsetup()).  This
!      *		       can be filled in by the device driver if it (for some
!      *		       reason) doesn't want to use the default.
       *   keymap_name:  Name of the keymap to load.  Sometime like
       *		       "button-box".
       *   keysyms_rec:  Pointer to a KeySymsRec to fill in.
***************
*** 798,811 ****
       * Returns:
       *   TRUE : everything went as expected
       *   FALSE: Something went screwie, using null maps.
       */
  int HPKget_kb_info_by_name(keymap_file, keymap_name, keysyms_rec, modmap)
    char *keymap_file, *keymap_name; KeySymsRec *keysyms_rec; CARD8 **modmap;
  {
!   if (try_and_load_maps((char *)NULL, keymap_name, keysyms_rec, modmap) ||
!       (keymap_file &&
!        try_and_load_maps(keymap_file, keymap_name, keysyms_rec, modmap)))
      return TRUE;
  
    ErrorF("Unable to load keymap \"%s\" - using defaults (NULL maps).\n",
        keymap_name);
--- 799,849 ----
       * Returns:
       *   TRUE : everything went as expected
       *   FALSE: Something went screwie, using null maps.
+      * Notes:
+      *   There are four possible keymap files:
+      *     - /usr/lib/X11/XHPKeymaps.  This is the system default.  It is
+      *       supposed to remain untouched so that it can be overwritten by
+      *       the system updates.
+      *     - A file specified by the environment variable XHPKEYMAPFILE.
+      *       This overrides XHPKeymaps.
+      *     - A file specified by the device driver.  For example, if a
+      *       company writes a driver for xyz keyboard, they can ship a
+      *       keymap without having to have the user modify XHPKeymaps.
+      *     - /usr/lib/X11/XHPKeymaps.usr.  This is the users "personal"
+      *       keymap file.  If they want to make changes to keymaps in
+      *       XHPKeymaps, they should put the changed keymaps in
+      *       XHPKeymaps.usr and leave XHPKeymaps unchanged.
+      *   Here is the order in which keymap files are tried:
+      *     If XHPKEYMAPFILE exists, use this load order:
+      *       - The file specified by XHPKEYMAPFILE.
+      *       - The user modifiable keymap file (XHPKeymaps.usr).
+      *       - The drivers keymap file (if not NULL).
+      *     If XHPKEYMAPFILE doesn't exist, use this order:
+      *       - The user modifiable keymap file (XHPKeymaps.usr).
+      *       - The drivers keymap file (if not NULL).
+      *       - The default (system) keymap (/usr/lib/X11/XHPKeymaps).
       */
+ #define KEYMAP_ENV_VAR	"XHPKEYMAPFILE"
+ #define USERS_KEYMAP	"XHPKeymaps.usr"
  int HPKget_kb_info_by_name(keymap_file, keymap_name, keysyms_rec, modmap)
    char *keymap_file, *keymap_name; KeySymsRec *keysyms_rec; CARD8 **modmap;
  {
!   if (getenv(KEYMAP_ENV_VAR))
!   {
!     if (try_and_load_maps((char *)NULL, keymap_name, keysyms_rec, modmap)  ||
! 	try_and_load_maps(USERS_KEYMAP, keymap_name, keysyms_rec, modmap)  ||
! 	(keymap_file &&
!          try_and_load_maps(keymap_file, keymap_name, keysyms_rec, modmap)))
      return TRUE;
+   }
+   else
+   {
+     if (try_and_load_maps(USERS_KEYMAP, keymap_name, keysyms_rec, modmap)  ||
+ 	(keymap_file &&
+          try_and_load_maps(keymap_file, keymap_name, keysyms_rec, modmap)) ||
+ 	try_and_load_maps((char *)NULL, keymap_name, keysyms_rec, modmap))
+     return TRUE;
+   }
  
    ErrorF("Unable to load keymap \"%s\" - using defaults (NULL maps).\n",
        keymap_name);
*** -	Wed Jan 25 18:48:17 1995
--- xc/programs/Xserver/hw/hp/input/xtest1imp.c	Wed Jan 25 18:48:17 1995
***************
*** 1,4 ****
! /* $XConsortium: xtest1imp.c,v 1.2 94/04/17 20:30:19 rws Exp $ */
  /*
   *	File: xtest1dd.c
   *
--- 1,4 ----
! /* $XConsortium: xtest1imp.c,v 1.3 95/01/24 02:59:30 dpw Exp $ */
  /*
   *	File: xtest1dd.c
   *
***************
*** 157,163 ****
  	coords[0] = xdiff;
  	coords[1] = jy - hpPointer->coords[1];
  	process_motion (inputInfo.pointer, hpPointer, hpPointer, coords);
! 	ev = format_ev (MotionNotify, 0, GetTimeInMillis(), hpPointer, NULL);
  	ProcessInputEvents();
  }
  
--- 157,163 ----
  	coords[0] = xdiff;
  	coords[1] = jy - hpPointer->coords[1];
  	process_motion (inputInfo.pointer, hpPointer, hpPointer, coords);
! 	ev = format_ev (inputInfo.pointer, MotionNotify, 0, GetTimeInMillis(), hpPointer, NULL);
  	ProcessInputEvents();
  }
  
***************
*** 189,194 ****
--- 189,195 ----
  int	mousex;
  int	mousey;
  {
+ 	DeviceIntPtr		dev;
  	HPInputDevice		*tmp_ptr;
          xEvent			*format_ev(), *ev;
  
***************
*** 198,209 ****
--- 199,212 ----
  	 */
  	if (dev_type == MOUSE)
  	{
+ 		dev = inputInfo.pointer;
  		hpPointer->coords[0] = mousex;
  		hpPointer->coords[1] = mousey;
  		tmp_ptr = hpPointer;
  	}
  	else
  	{
+ 		dev = inputInfo.keyboard;
  		hpPointer->coords[0] = mousex;
  		hpPointer->coords[1] = mousey;
  		tmp_ptr = hpKeyboard;
***************
*** 245,251 ****
  	/*
  	 * put a key/button input action into the servers input event queue
  	 */
! 	ev = format_ev (keystate, keycode, GetTimeInMillis(), tmp_ptr, NULL);
  	/*
  	 * Tell the server to process all of the events in its input queue.
  	 * This makes sure that key/button event we just put in the queue
--- 248,254 ----
  	/*
  	 * put a key/button input action into the servers input event queue
  	 */
! 	ev = format_ev (dev, keystate, keycode, GetTimeInMillis(), tmp_ptr, NULL);
  	/*
  	 * Tell the server to process all of the events in its input queue.
  	 * This makes sure that key/button event we just put in the queue
*** -	Wed Jan 25 18:48:19 1995
--- xc/programs/Xserver/hw/hp/input/screentab.h	Wed Jan 25 18:48:18 1995
***************
*** 1,7 ****
! /* $XConsortium: screentab.h,v 1.2 94/04/17 20:30:14 rws Exp $ */
  /*
  
! Copyright (c) 1986, 1987  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
--- 1,7 ----
! /* $XConsortium: screentab.h,v 1.4 95/01/24 23:31:56 gildea Exp $ */
  /*
  
! Copyright (c) 1988  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
***************
*** 28,50 ****
  from the X Consortium.
  
  
! Copyright (c) 1986, 1987 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this
! software and its documentation for any purpose and without
! fee is hereby granted, 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 Hewlett-Packard not be used in
! advertising or publicity pertaining to distribution of the
! software without specific, written prior permission.
  
  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
! PURPOSE.  Hewlett-Packard shall not be liable for errors 
! contained herein or direct, indirect, special, incidental or 
! consequential damages in connection with the furnishing, 
  performance, or use of this material.
  
  This software is not subject to any license of the American
--- 28,50 ----
  from the X Consortium.
  
  
! Copyright (c) 1988 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this software 
! and its documentation for any purpose and without fee is hereby 
! granted, 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 
! Hewlett-Packard not be used in advertising or publicity 
! pertaining to distribution of the software without specific, written 
! prior permission.
  
  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE.  Hewlett-Packard shall not be liable for errors
! contained herein or direct, indirect, special, incidental or
! consequential damages in connection with the furnishing,
  performance, or use of this material.
  
  This software is not subject to any license of the American
***************
*** 52,58 ****
  University of California.
  
  */
- 
  /*
   * Header file which declares structures to initialize and close
   * each type of screen supported by the X server.
--- 52,57 ----
*** -	Wed Jan 25 18:48:20 1995
--- xc/programs/Xserver/hw/hp/input/x_serialdrv.h	Wed Jan 25 18:48:19 1995
***************
*** 1,4 ****
! /* $XConsortium: x_serialdrv.h,v 1.1 93/08/08 13:00:10 rws Exp $ */
  /************************************************************
  Copyright (c) 1992 by Hewlett-Packard Company, Palo Alto, California.
  
--- 1,4 ----
! /* $XConsortium: x_serialdrv.h,v 1.3 95/01/24 23:37:51 gildea Exp $ */
  /************************************************************
  Copyright (c) 1992 by Hewlett-Packard Company, Palo Alto, California.
  
***************
*** 29,34 ****
--- 29,35 ----
   */
  
  #ifndef _X_SERIALDRV_H_
+ #define _X_SERIALDRV_H_
  #include <dl.h>
  
  #define X_KEYMAP_NAME		"/etc/kbdlang"
***************
*** 56,64 ****
  #define IN_PROXIMITY		0
  #define OUT_OF_PROXIMITY	1
  
! #define SCROLLLOCK_LED		1 << 0
! #define NUMLOCK_LED		1 << 1 
! #define CAPSLOCK_LED		1 << 2
  
  #define _XSetDeviceMode		0
  #define _XSetDeviceValuators	1
--- 57,65 ----
  #define IN_PROXIMITY		0
  #define OUT_OF_PROXIMITY	1
  
! #define SCROLLLOCK_LED		(1 << 0)
! #define NUMLOCK_LED		(1 << 1) 
! #define CAPSLOCK_LED		(1 << 2)
  
  #define _XSetDeviceMode		0
  #define _XSetDeviceValuators	1
***************
*** 66,71 ****
--- 67,78 ----
  #define _XChangeFeedbackControl	3
  #define _XChangeKeyboardControl	4
  #define _XChangePointerControl	5
+ #define _XBell			6
+ 
+ typedef struct {
+ 	int	class;
+ 	int	bell_percent;
+ } HPBell;
  
  typedef struct {
  	int	class;
***************
*** 146,162 ****
      ReadProc		read;		/* filled in by driver		*/
      WriteProc		write;		/* filled in by driver		*/
      CloseProc		close;		/* filled in by driver		*/
-     shl_t		ldr_module_id;	/* filled in by X server	*/
-     int			fd;		/* filled in by X server	*/
-     char		driver_name[MAX_NM];   /* filled in by X server	*/
-     char		*keymap_name;   /* filled in by X server	*/
-     char		*keymap_file;   /* filled in by X server	*/
-     int         	num_fdbk;       /* filled in by X server       	*/
-     u_char		*feedbacks;	/* filled in by X server        */
-     int         	num_ledf;       /* filled in by X server       	*/
-     u_char		*ledf; 		/* filled in by X server        */
-     int         	num_strf;       /* filled in by X server      	*/
-     HPStrF		*strf;          /* filled in by X server        */
      } SerialProcs; 
  
  typedef struct _HPInputDeviceHeader
--- 153,158 ----
***************
*** 168,174 ****
      int		resolution;	/* resolution in counts/cm         	*/
      int         max_x;        	/* maximum x value in counts    	*/
      int         max_y;          /* maximum y value in counts    	*/
!     int         file_ds;        /* file descriptor              	*/
      int         num_fdbk;       /* length of list that follows  	*/
      u_char	*feedbacks;	/* kbd, ptr, bell, and integer feedbacks*/
      int         num_ledf;       /* length of list that follows  	*/
--- 164,170 ----
      int		resolution;	/* resolution in counts/cm         	*/
      int         max_x;        	/* maximum x value in counts    	*/
      int         max_y;          /* maximum y value in counts    	*/
!     int         file_ds;       	/* file descriptor              	*/
      int         num_fdbk;       /* length of list that follows  	*/
      u_char	*feedbacks;	/* kbd, ptr, bell, and integer feedbacks*/
      int         num_ledf;       /* length of list that follows  	*/
***************
*** 184,188 ****
--- 180,185 ----
      u_char	reset;		/* keycode to cause X server reset      */
      u_char	reset_mods;	/* mask of modifiers for server reset   */
      u_char	button_chording;/* interval (ms) if chording enabled    */
+     u_char	reserved[8];    /* reserved for future use              */
      }HPInputDeviceHeader;
  #endif /* _X_SERIALDRV_H_ */
*** -	Wed Jan 25 18:48:27 1995
--- xc/programs/Xserver/hw/hp/input/x_hil.c	Wed Jan 25 18:48:27 1995
***************
*** 1,4 ****
! /* $XConsortium: x_hil.c,v 8.143 94/05/28 15:50:23 dpw Exp $ */
  
  /*******************************************************************
  **
--- 1,4 ----
! /* $XConsortium: x_hil.c,v 8.145 95/01/24 23:28:35 gildea Exp $ */
  
  /*******************************************************************
  **
***************
*** 79,128 ****
  
  */
  
- #include "stdio.h"
- 
- #ifndef __apollo
- #include "termio.h"
- #else
- #include "/sys5/usr/include/sys/termio.h"
- #endif	/* __apollo */
- 
  #define	 NEED_EVENTS
  #include "X.h"
  #include "XI.h"
  #include "Xproto.h"
  #include "hildef.h"
- #include "hppriv.h"
- #include "windowstr.h"
  #include "XHPproto.h"
  #include "x_hil.h"
  #include "x_serialdrv.h"
  #include "hpkeys.h"
  #include "inputstr.h"
  #include "../../../os/osdep.h"
  #include <sys/times.h>
- #ifdef __apollo
- #include "../apollo/xshscreenpriv.h"
- #endif /* __apollo */
- #ifdef __hp_osf
- #include <hp/hilioctl.h>
- extern	HILQ *hil_qp;
- #endif /* __hp_osf */
- #ifdef __hpux
  #include <sys/hilioctl.h>
- #endif /* __hpux */
  
  #define	FIRST_EXTENSION_EVENT	64
- 
  #define	MIN_KEYCODE		8	
- #define REPEAT_ARROW		0x2
  
! #define SERIAL_DRIVER_WRITE(f, type, ptr) \
! 	{ int i; \
! 	for (i=0; i<num_serial_devices; i++) \
! 	    if (f==serialprocs[i].fd) { \
! 		if ((*(serialprocs[i].write)) (f, type, ptr)==WRITE_SUCCESS) \
! 		    return Success; } }
  
  #ifdef XTESTEXT1
  /*
--- 79,108 ----
  
  */
  
  #define	 NEED_EVENTS
  #include "X.h"
  #include "XI.h"
  #include "Xproto.h"
  #include "hildef.h"
  #include "XHPproto.h"
  #include "x_hil.h"
  #include "x_serialdrv.h"
  #include "hpkeys.h"
+ #include "windowstr.h"
  #include "inputstr.h"
  #include "../../../os/osdep.h"
+ #include "hppriv.h"
  #include <sys/times.h>
  #include <sys/hilioctl.h>
  
  #define	FIRST_EXTENSION_EVENT	64
  #define	MIN_KEYCODE		8	
  
! #define ENQUEUE_EVENT(ev) \
!     {if (xE.b.u.u.type != 0)	/* at least 1 motion event */ \
!         {ev = allocate_event();/* get current queue pointer*/ \
!         *ev = xE;		/* copy from global struct  */ \
!         xE = zxE;}}		/* mark it as processed	    */ 
  
  #ifdef XTESTEXT1
  /*
***************
*** 139,149 ****
   */
  
  extern char	*mflg;
- extern int num_serial_devices;
- extern SerialProcs serialprocs[];
- 
  xEvent	*format_ev();
- 
  xHPEvent  xE, zxE;
  
  #ifdef	XINPUT
--- 119,125 ----
***************
*** 156,163 ****
  extern	int		ProximityIn;
  extern	int		ProximityOut;
  #endif	/* XINPUT */
- int			*dheadmotionBuf[MAX_LOGICAL_DEVS];
- int			*dpmotionBuf[MAX_LOGICAL_DEVS];
  extern	int 		axes_changed;
  extern	int 		keyboard_click;
  extern	int 		screenIsSaved;
--- 132,137 ----
***************
*** 169,175 ****
  extern	HPInputDevice	*hptablet_extension;
  extern	WindowPtr 	*WindowTable;
  extern	InputInfo 	inputInfo;
- extern	TimeStamp	lastDeviceEventTime;
  extern	DeviceIntPtr	screen_change_dev;
  extern	DeviceIntPtr	tablet_extension_device;
  
--- 143,148 ----
***************
*** 180,196 ****
  extern	u_int		tablet_width;
  
  static	Bool		in_tablet_extension = FALSE;
  
  u_char		pointer_amt_bits[3];
  u_char		ptr_mods, mv_mods, rs_mods, bw_mods;
- u_char		buf[BUF_SIZ];
- u_char		*pkt_ptr = buf;
  Bool		screen_was_changed = FALSE;
  Bool		reset_enabled = TRUE;
  int 		hpActiveScreen = 0; 		/* active screen ndx (Zaphod) */
  int		queue_events_free = MAX_EVENTS;
- int		data_cnt = 0;
- int		data_fd = -1;
  int		pending_index;
  int		pending_bytes;
  float		acceleration;
--- 153,167 ----
  extern	u_int		tablet_width;
  
  static	Bool		in_tablet_extension = FALSE;
+ static  BoxRec 		LimitTheCursor;
+ 
  
  u_char		pointer_amt_bits[3];
  u_char		ptr_mods, mv_mods, rs_mods, bw_mods;
  Bool		screen_was_changed = FALSE;
  Bool		reset_enabled = TRUE;
  int 		hpActiveScreen = 0; 		/* active screen ndx (Zaphod) */
  int		queue_events_free = MAX_EVENTS;
  int		pending_index;
  int		pending_bytes;
  float		acceleration;
***************
*** 198,210 ****
  struct		x11EventQueue *events_queue;	/* pointer to events queue.  */
  xHPEvent	*allocate_event();
  struct		dev_info hil_info;		/* holds hil_data */
- Bool		display_borrowed = FALSE;
  #ifdef XINPUT
  DeviceIntPtr	LookupDeviceIntRec ();
  #endif /* XINPUT */
- #if defined(__hp9000s800) && !defined(__hp9000s700)
- unsigned long 	timediff;
- #endif /* __hp9000s800 */
  
  /******************************************************************
   *
--- 169,177 ----
***************
*** 214,220 ****
  
  static	DeviceIntPtr find_deviceintrec();
  static	int  process_inputs();
- static	void process_hil_data();
  static	void process_serial_data();
  static	check_subset_and_scale();
  static	move_sprite();
--- 181,186 ----
***************
*** 223,229 ****
  static	move_mouse();
  static	u_char	last_direction;
  static	u_char	last_key;
- static	u_char	last_arrow = REPEAT_ARROW;/*keycode of arrow key pressed last */
  static	int	k_down_flag[4];
  static	int	k_down_incx[4];
  static	int	k_down_incy[4];
--- 189,194 ----
***************
*** 244,287 ****
   *
   */
  
! store_inputs(mask)
!     long	mask[];
      {
      int	    i;
      int     checkfd = max_input_fd;		/* max fd valid for input*/
      int     checkword = MASKIDX(checkfd);	/* max valid word of mask*/
-     long    checkmask[mskcnt];
- #if defined(__hp9000s800) && !defined(__hp9000s700)  /* building for s800 */
-     struct tms 		buffer;
-     int newtime;
-     struct timeval tv, get_tv();
- 
-     /**********************************************************************
-      *
-      * On s800 machines, the time reported in HIL events has its origin at
-      * the time of machine power-up.  The time reported by gettimeofday(),
-      * which will be called by UpdateCurrentTime when a grab is done, always
-      * has its origin at Jan. 1, 1970.  On s800s, we must compute a difference
-      * to be added to the HIL times to keep the two in sync.  We must also
-      * check each time via get_tv (PA-RISC fast gettimeofday) to see if the
-      * time reported by gettimeofday has been changed via the date() command.
-      * If so, our time difference is invalid and must be recalculated.
-      */
  
!     tv = get_tv();
!     newtime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
!     if (newtime < lastDeviceEventTime.milliseconds)
! 	timediff = GetTimeInMillis() - (times(&buffer)*10);
! #endif /* __hp9000s800 */
  
      for (i=0; i<mskcnt; i++)
  	checkmask[i] = 0;
  
-     if (data_cnt > 0)				/* we have leftover data*/
- 	{
- 	process_inputs (data_fd);		/* go process it	*/
- 	}
- 
      BITSET(checkmask, checkfd);			/* corresponding mask	*/
  
      for (i=checkword; i>=0; i--)		/* for all mask words   */
--- 209,234 ----
   *
   */
  
! CheckInput (data, result, LastSelectMask)
!     pointer data;
!     unsigned long result;
!     long LastSelectMask[];
      {
+     long mask[mskcnt], checkmask[mskcnt];
+     extern long EnabledDevices[];
      int	    i;
      int     checkfd = max_input_fd;		/* max fd valid for input*/
      int     checkword = MASKIDX(checkfd);	/* max valid word of mask*/
  
!     if (result <= 0)
! 	return;
!     MASKANDSETBITS(mask, LastSelectMask, EnabledDevices);
!     if (!ANYSET(mask)) 
! 	return;
  
      for (i=0; i<mskcnt; i++)
  	checkmask[i] = 0;
  
      BITSET(checkmask, checkfd);			/* corresponding mask	*/
  
      for (i=checkword; i>=0; i--)		/* for all mask words   */
***************
*** 316,323 ****
   *
   */
  
- #define TIME_POLL_BYTES		5	/* bytes indicating time and poll*/
- 
  static int process_inputs (file_ds)
      int	file_ds;			/* file_ds to read from      	 */
      {
--- 263,268 ----
***************
*** 330,336 ****
  
      for (i=0; i<MAX_LOGICAL_DEVS; i++)
  	{
! 	if (file_ds == l_devs[i].file_ds) 
  	    {
  	    indevice = &(l_devs[i]);
  	    break;
--- 275,281 ----
  
      for (i=0; i<MAX_LOGICAL_DEVS; i++)
  	{
! 	if (file_ds == l_devs[i].d.file_ds) 
  	    {
  	    indevice = &(l_devs[i]);
  	    break;
***************
*** 339,375 ****
  	
      dev = find_deviceintrec(indevice);
  
!     if (data_cnt == 0 &&	 		/* no leftover data	    */
!       !(indevice->hpflags & IS_SERIAL_DEVICE))
! 	{
! 	pkt_ptr = buf;
! 	data_cnt = read (file_ds, buf, READ_SIZ);
! 	}
!     while (data_cnt > 0 || 			/* data yet to be processed */
!       (indevice->hpflags & IS_SERIAL_DEVICE && !done))
  	{
  	if (queue_events_free <= MAXHILEVENTS)	/* no room on server queue  */
- 	    {
- 	    if (data_fd == -1)
- 		data_fd = file_ds;		/* save the file descriptor */
  	    return;
- 	    }
  	hil_ptr = (unsigned char *) &hil_info;/* place to copy packet to*/
! 	if (indevice->hpflags & IS_SERIAL_DEVICE)
! 	    {
! 	    done = get_serial_event (hil_ptr);
! 	    process_serial_data (dev, hil_info.hil_dev, &(hil_info));
! 	    }
! 	else
! 	    {
! 	    get_hil_event (file_ds, hil_ptr);
! #if defined(__hp9000s800) && !defined(__hp9000s700)  /* building for s800 */
! 	    hil_info.timestamp += timediff;
! #endif /* __hp9000s800 */
! 	    process_hil_data (dev, hil_info.hil_dev, &(hil_info));
! 	    }
  	}
-     data_fd = -1;
      if (xE.b.u.u.type != 0)			/* at least 1 motion event */
  	{
          xHP = allocate_event();			/* get current queue pointer*/
--- 284,297 ----
  	
      dev = find_deviceintrec(indevice);
  
!     while (!done)				/* data yet to be processed */
  	{
  	if (queue_events_free <= MAXHILEVENTS)	/* no room on server queue  */
  	    return;
  	hil_ptr = (unsigned char *) &hil_info;/* place to copy packet to*/
! 	done = get_serial_event (hil_ptr);
! 	process_serial_data (dev, hil_info.hil_dev, &(hil_info));
  	}
      if (xE.b.u.u.type != 0)			/* at least 1 motion event */
  	{
          xHP = allocate_event();			/* get current queue pointer*/
***************
*** 400,406 ****
  	{
  	hil_info.hil_dev = indevice;		/* input device struct ptr  */
  	if (hptablet_extension &&
! 	    indevice->file_ds==hptablet_extension->file_ds && 
  	    in_tablet_extension)
  	    {
  	    hil_info.hil_dev = hptablet_extension;
--- 322,328 ----
  	{
  	hil_info.hil_dev = indevice;		/* input device struct ptr  */
  	if (hptablet_extension &&
! 	    indevice->d.file_ds==hptablet_extension->d.file_ds && 
  	    in_tablet_extension)
  	    {
  	    hil_info.hil_dev = hptablet_extension;
***************
*** 413,420 ****
  		(indevice->hpflags & MERGED_DEVICE)))
  	    dev = inputInfo.pointer;
  #ifdef XINPUT
! 	else
! 	    dev = LookupDeviceIntRec (indevice->dev_id);
  
      	p = dev->ptrfeed;
  	if (p != NULL)
--- 335,348 ----
  		(indevice->hpflags & MERGED_DEVICE)))
  	    dev = inputInfo.pointer;
  #ifdef XINPUT
! 	else{
! 	    for (dev = inputInfo.devices;
! 		dev && ((HPInputDevice *)dev->public.devicePrivate != indevice);
! 		dev = dev->next)
! 		;
! 	    if (!dev)
! 		FatalError ("X server couldn't find current input device - Aborting.\n");
! 	}
  
      	p = dev->ptrfeed;
  	if (p != NULL)
***************
*** 433,641 ****
  
  /****************************************************************************
   *
-  * Get one HIL data packet from the data that was previously read.
-  * If the buffer only contains a partial packet, read the rest.
-  *
-  * This function may also be called from x_threebut.c.
-  *
-  */
- 
- #define MAX_PACKET (sizeof(struct dev_info) - sizeof(HPInputDevice *))
- 
- get_hil_event (fd, dest)
-     int		fd;
-     char	*dest;
-     {
-     int	packet_size;
-     int	i;
-     struct dev_info *info = (struct dev_info *) dest;
- 
-     packet_size = *pkt_ptr++;		/* 1st byte is size	    */
-     if (packet_size > MAX_PACKET)
- 	{
- 	data_cnt = 0;
- 	pkt_ptr=buf;
- 	pending_index = 0;
- 	if (mflg)
- 	    ErrorF("Invalid length %d in HIL data packet, clearing data.\n",packet_size);
- 	return;
- 	}
-     if(data_cnt < packet_size)		/* We got a partial packet  */
- 	{
- 	data_cnt += read(fd,		/* get rest of packet */ 
- 			pkt_ptr + data_cnt, 
- 			packet_size - data_cnt);
- 
- 	if(data_cnt != packet_size)
- 	    FatalError ("Unable to read all of an HIL data packet.  Server exiting! \n");
- 	}
-     for (i=1; i<packet_size; i++)	/* copy the current packet  */
-         *dest++ = *pkt_ptr++;
- 
-     info->timestamp = (info->timestamp - 1) * 10;
-     info->poll_hdr &= HIL_POLL_HDR_BITS;/* zero nonsignifcant bits  */
-     data_cnt -= packet_size;		/* fix unprocessed data cnt */
-     pending_index = 0;
-     pending_bytes = packet_size - 1  - TIME_POLL_BYTES;
-     }
- 
- /****************************************************************************
-  *
-  * process the HIL data packet and generate X input events as needed.
-  *
-  */
- 
- #define UP_LEFT_ARROW		0xf8	/* HIL key codes for arrow keys. */
- #define DOWN_LEFT_ARROW		0xf9
- #define UP_DOWN_ARROW		0xfa
- #define DOWN_DOWN_ARROW		0xfb
- #define UP_UP_ARROW		0xfc
- #define DOWN_UP_ARROW		0xfd
- #define UP_RIGHT_ARROW		0xfe
- #define DOWN_RIGHT_ARROW	0xff
- #define HIL_PROXIMITY		0x4f
- 
- static u_char	code[2];
- 
- static void process_hil_data (dev, phys, info)
-     DeviceIntPtr 	dev;
-     HPInputDevice	*phys;
-     struct		dev_info	*info;
-     {
-     xEvent		*ev;
-     int			count;
-     u_char		type, keyset, kcode, bcode, *hil_code;
-     struct hil_desc_record *h = &phys->hil_header;
- 
-     while (pending_index < pending_bytes ) 
- 	{  
- 	if (!(info->poll_hdr & (MOTION_MASK | KEY_DATA_MASK)))
- 	    {
- 	    pending_index = pending_bytes = 0;
- 	    if (mflg)
- 		ErrorF("Invalid HIL data header \'%x\' received, ignoring event.\n",info->poll_hdr);
- 	    break;
- 	    }
- 
- 	if (info->poll_hdr & MOTION_MASK)
- 	    {
- 	    handle_motion_event (dev, phys, info);
- 	    info->poll_hdr &= ~MOTION_MASK;
- 	    }
-     
- 	if (info->poll_hdr & KEY_DATA_MASK)
- 	    {  
- 	    keyset   = info->poll_hdr & HILPRH_KEYSET;
- 	    hil_code = code;
- 	    if (phys->hpflags & DATA_IS_8_BITS)
- 		*hil_code = (info->dev_data)[pending_index++];
- 	    else if (phys->hpflags & DATA_IS_16_BITS)
- 		{
- 		*hil_code = ((info->dev_data)[pending_index] << 8) |
- 		    (info->dev_data)[pending_index+1];
- 		pending_index += 2;
- 		}
- 	    /* Check if cursor keys are repeating. */
-     
- 	    switch (*hil_code)
- 		{
- 		case DOWN_DOWN_ARROW	:
- 		case UP_DOWN_ARROW		:
- 		case UP_LEFT_ARROW		:
- 		case DOWN_LEFT_ARROW	:
- 		case UP_RIGHT_ARROW		:
- 		case DOWN_RIGHT_ARROW	:
- 		case UP_UP_ARROW		:
- 		case DOWN_UP_ARROW		:
- 		    last_arrow = *hil_code;
- 		    break;
- 		case	REPEAT_ARROW		:
- 		    if ((keyset==HILPRH_KEYSET1) && last_arrow!=REPEAT_ARROW)
- 		        *hil_code = last_arrow;
- 		    break;
- 		default:
- 		    break;
- 		}
- 
- 
- 	    if (phys->dev_type == BARCODE)
- 		hil_code = ascii_to_code[*hil_code];
- 
- 	    for (count=0; (count==0 || *hil_code != 0); count++)
- 		{
- #ifdef XINPUT
- 		/* proximity HIL codes cause a different event type.
- 		   However, proximity is not reported for devices being
- 		   used as the X pointer, unless they have no buttons
- 		   (like a touchscreen), in which case the proximity is
- 		   treated as button 1.
- 		   */
- 
- 		kcode = ((u_char) *hil_code) >> 1;	/* same code up & down*/
- 		kcode += MIN_KEYCODE;		        /* avoid mouse codes. */
- 
- 		/* Check to see if this is a "down" keycode for a key that is
- 		   already down.  If so, and autorepeat has been disabled for
- 		   this key, ignore the key and return.
- 		   */
- 
- 		if (!(*hil_code % 2) && KeyIsDown(dev,kcode) &&
- 		    !KeyIsRepeating(dev,kcode))
- 		    return;
- 
- 		bcode = *(hil_code++);
- 		if ((h->iob & HILIOB_PIO) && kcode == HIL_PROXIMITY)
- 		    if (dev!=inputInfo.pointer)
- 			{
- 			type = (bcode & UP_MASK) ? ProximityOut : ProximityIn;
- 			ev= format_ev (type, 0, info->timestamp, phys, NULL);
- 			return;
- 			}
- 		    else if (h->p_button_count == 0)
- 			bcode -= 0x0e;			/* make it button 1 */
- 		    else
- 			return;	/* proximity not reported for X pointer */
- #endif /* XINPUT */
- 		if (bcode >= BUTTON_BASE && bcode < PROXIMITY_IN)
- 		    {
- 		    if (phys == hptablet_extension && phys->clients == NULL)
- 			return;
- 		    if (dev==inputInfo.pointer)
- 			if (bcode & UP_MASK) 
- 			    type = ButtonRelease;
- 			else
- 			    type = ButtonPress;
- 		    else
- 			if (bcode & UP_MASK) 
- 			    type = DeviceButtonRelease;
- 			else
- 			    type = DeviceButtonPress;
- 		    ev= format_ev (type, kcode, info->timestamp, phys, NULL);
- 		    process_button (ev, dev, info, bcode, h->p_button_count);
- 		    }
- 		else
- 		    {
- 		    if (dev==inputInfo.keyboard || dev==inputInfo.pointer)
- 			if (bcode & UP_MASK) 
- 			    type = KeyRelease;
- 			else
- 			    type = KeyPress;
- 		    else
- 			if (bcode & UP_MASK) 
- 			    type = DeviceKeyRelease;
- 			else
- 			    type = DeviceKeyPress;
- 		    ev= format_ev (type, kcode, info->timestamp, phys, NULL);
- 
- 		    parse_keycode (dev, phys, ev);
- 		    }
- 	        }
- 	    }
- 	}
-    }
- 
- /****************************************************************************
-  *
   * process the serial data packet and generate X input events as needed.
   *
   */
--- 361,366 ----
***************
*** 648,657 ****
      struct		dev_info	*info;
      {
      xEvent		*ev;
-     int			count;
      u_int		*hil_code;
      u_char		type, kcode;
-     int button_count = phys->hil_header.p_button_count;
  
      while (pending_index < pending_bytes ) 
  	{  
--- 373,380 ----
***************
*** 680,685 ****
--- 403,413 ----
  		(info->dev_data)[pending_index];
  	    pending_index += 4;
  	    }
+ 	else
+ 	    {
+ 	    pending_index = pending_bytes;
+ 	    return;
+ 	    }
  
  	if (info->poll_hdr & KEY_DATA)
  	    {
***************
*** 706,727 ****
  		    type = DeviceKeyPress;
  		}
  
! 	    ev= format_ev (type, kcode, info->timestamp, phys, NULL);
  	    parse_keycode (dev, phys, ev);
  	    }
  	else if (info->poll_hdr & BUTTON_DATA)
  	    {
- 	    extern HPInputDevice	*bd;
  
- 	    if (phys == hptablet_extension && phys->clients == NULL)
- 	        return;
  	    if (dev==inputInfo.pointer)
! 		type = ButtonPress;
  	    else
! 		type = DeviceButtonPress;
! 	    ev= format_ev (type,(*hil_code >>1) + 1,info->timestamp,phys,NULL);
! 	    bd = phys;
! 	    put_button_event (dev, ev, info, phys, *hil_code + 2);
  	    }
  #ifdef XINPUT
  	else if (info->poll_hdr & PROXIMITY_DATA)
--- 434,465 ----
  		    type = DeviceKeyPress;
  		}
  
! 	    ev= format_ev (dev, type, kcode, info->timestamp, phys, NULL);
  	    parse_keycode (dev, phys, ev);
  	    }
  	else if (info->poll_hdr & BUTTON_DATA)
  	    {
  
  	    if (dev==inputInfo.pointer)
! 		type = (*hil_code & UP_MASK) ? ButtonRelease : ButtonPress;
  	    else
! 		type = (*hil_code & UP_MASK) ? DeviceButtonRelease 
! 					     : DeviceButtonPress;
! 
! 	    ev= format_ev (dev, type,(*hil_code >>1) + 1,info->timestamp,phys,NULL);
! #ifdef	XTESTEXT1
! 	    {
! 	    extern int	on_steal_input;	/* steal input mode is on.	*/
! 	    extern int	exclusive_steal;
! 
! 	    if (on_steal_input)
! 		XTestStealKeyData(ev->u.u.detail, ev->u.u.type, MOUSE, 
! 		    phys->coords[0], phys->coords[1]);
! 
! 	    if (exclusive_steal)
! 		deallocate_event(ev);
! 	    }
! #endif	/* XTESTEXT1 */
  	    }
  #ifdef XINPUT
  	else if (info->poll_hdr & PROXIMITY_DATA)
***************
*** 735,755 ****
  	    if (dev!=inputInfo.pointer)
  		{
  		type = (*hil_code & UP_MASK) ? ProximityOut : ProximityIn;
! 		ev= format_ev (type, 0, info->timestamp, phys, NULL);
  		return;
  		}
! 	    else if (button_count == 0)
  		{
! 		kcode = 1;			/* make it button 1 */
! 	        ev= format_ev (type, kcode, info->timestamp, phys, NULL);
! 		if (phys == hptablet_extension && phys->clients == NULL)
! 		    return;
! 		process_button (ev, dev, info, kcode, button_count);
  		}
  	    else
  		return;	/* proximity not reported for X pointer */
  	    }
  #endif /* XINPUT */
  	}
     }
  
--- 473,495 ----
  	    if (dev!=inputInfo.pointer)
  		{
  		type = (*hil_code & UP_MASK) ? ProximityOut : ProximityIn;
! 		ev= format_ev (dev, type, 0, info->timestamp, phys, NULL);
  		return;
  		}
! 	    else if (phys->d.num_buttons == 0)
  		{
! 		type = (*hil_code & UP_MASK) ? ButtonRelease : ButtonPress;
! 	        ev= format_ev (dev, type, 1, info->timestamp, phys, NULL);
  		}
  	    else
  		return;	/* proximity not reported for X pointer */
  	    }
  #endif /* XINPUT */
+ 	else
+ 	    {
+ 	    pending_index = pending_bytes;
+ 	    return;
+ 	    }
  	}
     }
  
***************
*** 787,803 ****
      else
  	bytes_coord = 1;
  
!     pending_index += phys->hil_header.ax_num * bytes_coord;
  
!     if (phys->hil_header.flags & HIL_ABSOLUTE)		/* absolute device */
  	{
  	udata = info->dev_data; 
! 	for (i=0; i < (u_char) phys->hil_header.ax_num; i++, udata+=bytes_coord)
  	    if (bytes_coord == 1)
  		coords[i] = *udata;
  	    else if (bytes_coord == 2)
  		coords[i] = *udata | *(udata+1) << 8;
! 	    else if (bytes_coord == 4)
  		coords[i] = *udata | (*(udata+1) << 8) | (*(udata+2) << 16) | 
  			    (*(udata+3) << 24);
  
--- 527,543 ----
      else
  	bytes_coord = 1;
  
!     pending_index += phys->d.ax_num * bytes_coord;
  
!     if (phys->hpflags & ABSOLUTE_DATA)		/* absolute device */
  	{
  	udata = info->dev_data; 
! 	for (i=0; i < (u_char) phys->d.ax_num; i++, udata+=bytes_coord)
  	    if (bytes_coord == 1)
  		coords[i] = *udata;
  	    else if (bytes_coord == 2)
  		coords[i] = *udata | *(udata+1) << 8;
! 	    else
  		coords[i] = *udata | (*(udata+1) << 8) | (*(udata+2) << 16) | 
  			    (*(udata+3) << 24);
  
***************
*** 807,818 ****
      else
  	{
  	sdata = (char *) info->dev_data; 
! 	for (i=0; i < (u_char) phys->hil_header.ax_num; i++, sdata+=bytes_coord)
  	    if (bytes_coord == 1)
  		coords[i] = *sdata;
  	    else if (bytes_coord == 2)
  		coords[i] = *(sdata+1) << 8 | (*sdata & 0x0ff);
! 	    else if (bytes_coord == 4)
  		coords[i] = (*(sdata+3) << 24) | ((*(sdata+2) << 16) & 0x0ff)|
  			    ((*(sdata+1) << 8) & 0xff) | (*sdata & 0x0ff);
  	}
--- 547,558 ----
      else
  	{
  	sdata = (char *) info->dev_data; 
! 	for (i=0; i < (u_char) phys->d.ax_num; i++, sdata+=bytes_coord)
  	    if (bytes_coord == 1)
  		coords[i] = *sdata;
  	    else if (bytes_coord == 2)
  		coords[i] = *(sdata+1) << 8 | (*sdata & 0x0ff);
! 	    else 
  		coords[i] = (*(sdata+3) << 24) | ((*(sdata+2) << 16) & 0x0ff)|
  			    ((*(sdata+1) << 8) & 0xff) | (*sdata & 0x0ff);
  	}
***************
*** 826,838 ****
  	else
  	    coords[1] = coords[y_axis];
  	}
-     if (!(phys->hil_header.flags & HIL_ABSOLUTE) &&
- 	!(phys->hpflags & IS_SERIAL_DEVICE) &&
- 	phys->dev_type != NINE_KNOB)
- 	coords[1] = -coords[1];
- 
      process_motion (dev, phys, log, coords, info->timestamp);
!     (void) format_ev (type, 0, info->timestamp, log, &xE);
      }
  
  /*******************************************************************
--- 566,573 ----
  	else
  	    coords[1] = coords[y_axis];
  	}
      process_motion (dev, phys, log, coords, info->timestamp);
!     (void) format_ev (dev, type, 0, info->timestamp, log, &xE);
      }
  
  /*******************************************************************
***************
*** 850,858 ****
      int			c[];
      {	
      extern u_char screen_change_amt;
!     int i, n_axes = phys->hil_header.ax_num;
  
!     if (tablet_width)
  	if (c[0]< tablet_xorg || c[0] > tablet_xlimit ||
  	    c[1]> tablet_yorg || c[1] < tablet_ylimit)
  	    {
--- 585,593 ----
      int			c[];
      {	
      extern u_char screen_change_amt;
!     int i, n_axes = phys->d.ax_num;
  
!     if (tablet_width && hptablet_extension)
  	if (c[0]< tablet_xorg || c[0] > tablet_xlimit ||
  	    c[1]> tablet_yorg || c[1] < tablet_ylimit)
  	    {
***************
*** 878,884 ****
  	{
  	if (*dev == screen_change_dev)
  	    c[0] -= screen_change_amt;
!         c[1] = phys->hil_header.size_y - c[1]; /* Y-coord  reversed.*/
  	}
      if (c[0]==(*log)->coords[0] && c[1]==(*log)->coords[1])
  	return (FALSE);
--- 613,619 ----
  	{
  	if (*dev == screen_change_dev)
  	    c[0] -= screen_change_amt;
!         c[1] = phys->d.max_y - c[1]; /* Y-coord  reversed.*/
  	}
      if (c[0]==(*log)->coords[0] && c[1]==(*log)->coords[1])
  	return (FALSE);
***************
*** 887,894 ****
      return (TRUE);
      }
  
- unsigned char lockcode;
- 
  /****************************************************************************
   *
   * parse_keycode (dev, phys, ev, x_type)
--- 622,627 ----
***************
*** 897,908 ****
   *
   */
  
! #if defined(__hpux) || defined(__hp_osf)
! struct	 _LedCmd {
!     int 	on;
!     int		off;
!     } LedCmd[] = {{HILP1,HILA1},{HILP2,HILA2},{HILP3,HILA3},{HILP3,HILA3}};
! #endif
  
  int parse_keycode (dev, phys, ev)
      DeviceIntPtr 	dev;
--- 630,642 ----
   *
   */
  
! #define FIX_LED_CTRL(dev, d, ev, index, led) \
! 	{if (KeyUpEvent(ev) && dev->key->modifierKeyCount[index] <= 1) { \
! 	    d.leds &= ~led; \
! 	    dev->kbdfeed->ctrl.leds &= ~led; } \
! 	else { \
! 	    d.leds |= led; \
! 	    dev->kbdfeed->ctrl.leds |= led; }}
  
  int parse_keycode (dev, phys, ev)
      DeviceIntPtr 	dev;
***************
*** 913,1042 ****
      extern u_char	xtest_command_key;	 /* defined in xtestext1dd.c */
  #endif	/* XTESTEXT1 */
      u_char	down_mods;
!     char 	ioctl_data[12];
  
      if (hpPointer->x_type == KEYBOARD)
  	if (hpKeyboard->hpflags & SECOND_LOGICAL_DEVICE &&
! 	    ((ev->u.keyButtonPointer.pad1==hpKeyboard->dev_id ||
! 	      ev->u.keyButtonPointer.pad1==hpPointer->dev_id ) &&
  	     move_sprite (dev, hpPointer, ev)))
  		return;
  	else
! 	    if (ev->u.keyButtonPointer.pad1==hpPointer->dev_id &&
  		(move_sprite (dev, hpPointer, ev)))
  		return;
-     
-     /* allow borrow-mode switching on Domain/OS machines */
- #ifdef __apollo
- 
-     if (ev->u.u.detail==borrow_mode)
- 	if ((hpKeyboard->hpflags & SECOND_LOGICAL_DEVICE &&
- 	    (ev->u.keyButtonPointer.pad1==hpKeyboard->dev_id ||
- 	     ev->u.keyButtonPointer.pad1==hpPointer->dev_id)) ||
- 	    ev->u.keyButtonPointer.pad1==hpKeyboard->dev_id)
- 	{
- 	get_down_modifiers (inputInfo.keyboard, &down_mods);
- 	if ((bw_mods & down_mods) == bw_mods)
- 	    {
- 	    extern unsigned char last_code;	/* in smd_input.c */
- 	    unsigned long timestamp;
- 
- 	    timestamp = ev->u.keyButtonPointer.time;
- 	    deallocate_event (ev);	/* eat the borrow mode key */
- 	    ev = format_ev (KeyRelease, borrow_mode_mods[0]+MIN_KEYCODE,
- 		timestamp, phys, NULL);
- 	    ev = format_ev (KeyRelease, borrow_mode_mods[1]+MIN_KEYCODE,
- 		timestamp, phys, NULL);
- 	    last_code = 0;
- 	    leave_X();
- 	    }
- 	}
- #endif /* __apollo */
- 
  
      /* allow reset only from the X system keyboard,
  	   and only if reset is enabled.		*/
  
!     if (ev->u.u.detail==reset && reset_enabled)
  	if ((hpKeyboard->hpflags & SECOND_LOGICAL_DEVICE &&
! 	    (ev->u.keyButtonPointer.pad1==hpKeyboard->dev_id ||
! 	     ev->u.keyButtonPointer.pad1==hpPointer->dev_id)) ||
! 	    ev->u.keyButtonPointer.pad1==hpKeyboard->dev_id)
  	{
  	get_down_modifiers (inputInfo.keyboard, &down_mods);
  	if ((rs_mods & down_mods) == rs_mods)
  	    GiveUp(0);
  	}
  
! #if defined(__hpux) || defined(__hp_osf)
! 
!     /* Special case handling for the Caps Lock modifier and LED.
!        If a key is pressed that is bound to the Lock modifier,
!        turn on the Caps Lock LED and treat the key as latched.
!        However, do this only if a client has not overridden the
!        default use of the Caps Lock LED via the HPConfigureInput
!        protocol request.  */
  
!     if (IsLockKey(dev, ev->u.u.detail))		/* lock modifier pressed */
! 	{
! 	if (ev->u.u.detail != lockcode)		/* was changed by xmodmap*/
! 	    {
! 	    UnlatchKey(phys, lockcode);
! 	    LatchKey(phys, ev->u.u.detail);
! 	    lockcode = ev->u.u.detail;
! 	    }
! 	}
!     else if (ev->u.u.detail == lockcode) 	/* is former lock modifier */
  	{
! 	UnlatchKey(phys, lockcode);
! 	lockcode = 0xff;
! 	}
! 
!     if (KeyIsLatched(phys, ev->u.u.detail))
! 	if (KeyIsIgnored(phys,ev->u.u.detail))
  	    {
  	    if (KeyDownEvent(ev))
! 	        UnignoreKey(phys,ev->u.u.detail);
  	    deallocate_event (ev);
  	    return;
  	    }
  	else if (KeyDownEvent(ev))
! 	    IgnoreKey(phys,ev->u.u.detail);
! 
!     if (DeviceHasLeds(phys) && KeyHasLed(dev,phys,ev->u.u.detail))
! 	if (KeyUpEvent(ev) && 
! 	    dev->key->modifierKeyCount[LockMapIndex] <= 1)
! 	    if (phys->hpflags & IS_SERIAL_DEVICE){
! 		HPKeyboardFeedbackControl	d;
! 		copy_kbd_ctrl_params (&d, &dev->kbdfeed->ctrl);
! 		d.leds &= ~CAPSLOCK_LED;
! 		SERIAL_DRIVER_WRITE(phys->file_ds, _XChangeFeedbackControl, &d);
! 	    }
! 	    else
! 		LedOff(dev, phys, ev->u.u.detail, ioctl_data);
! 	else
! 	    if (phys->hpflags & IS_SERIAL_DEVICE){
! 		HPKeyboardFeedbackControl	d;
! 		copy_kbd_ctrl_params (&d, &dev->kbdfeed->ctrl);
! 		d.leds |= CAPSLOCK_LED;
! 		SERIAL_DRIVER_WRITE(phys->file_ds, _XChangeFeedbackControl, &d);
  	    }
! 	    else
! 		LedOn(dev, phys, ev->u.u.detail, ioctl_data);
  
! #endif /* __hpux */
  
  #ifdef	XTESTEXT1
      if (on_steal_input)
  	{ 
! 	XTestStealKeyData(ev->u.u.detail, ev->u.u.type, phys->x_type, 
  	    ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootY);
  	if (exclusive_steal)
  	    { 
! 	    if (ev->u.u.detail != xtest_command_key)
  		deallocate_event (ev);
  	    }
! 	else if (ev->u.u.detail == xtest_command_key)
  	    deallocate_event (ev);
  	}
  #endif /* XTESTEXT1 */
--- 647,732 ----
      extern u_char	xtest_command_key;	 /* defined in xtestext1dd.c */
  #endif	/* XTESTEXT1 */
      u_char	down_mods;
!     u_char 	key = ev->u.u.detail;
  
      if (hpPointer->x_type == KEYBOARD)
  	if (hpKeyboard->hpflags & SECOND_LOGICAL_DEVICE &&
! 	    ((ev->u.keyButtonPointer.pad1==inputInfo.keyboard->id ||
! 	      ev->u.keyButtonPointer.pad1==inputInfo.pointer->id ) &&
  	     move_sprite (dev, hpPointer, ev)))
  		return;
  	else
! 	    if (ev->u.keyButtonPointer.pad1==inputInfo.pointer->id &&
  		(move_sprite (dev, hpPointer, ev)))
  		return;
  
      /* allow reset only from the X system keyboard,
  	   and only if reset is enabled.		*/
  
!     if (key==reset && reset_enabled)
  	if ((hpKeyboard->hpflags & SECOND_LOGICAL_DEVICE &&
! 	    (ev->u.keyButtonPointer.pad1==inputInfo.keyboard->id ||
! 	     ev->u.keyButtonPointer.pad1==inputInfo.pointer->id)) ||
! 	    ev->u.keyButtonPointer.pad1==inputInfo.keyboard->id)
  	{
  	get_down_modifiers (inputInfo.keyboard, &down_mods);
  	if ((rs_mods & down_mods) == rs_mods)
  	    GiveUp(0);
  	}
  
!     /* Special case handling for toggling keys.  These are keys
!        that are bound to one of the X modifiers, and have been
!        made into toggling keys.  This currently only includes Caps Lock.
!        If a key is pressed that is bound to a toggling key,   
!        turn on the appropriate LED and treat the key as a toggle.
!      */
  
!     if (IsToggleKey(dev, phys, key))     	/* toggling key pressed */
  	{
! 	if (KeyIsIgnored(phys,key))
  	    {
  	    if (KeyDownEvent(ev))
! 	        UnignoreKey(phys,key);
! 	    ExpectUpKey(phys,key);		/* for handling autorepeat */
  	    deallocate_event (ev);
  	    return;
  	    }
  	else if (KeyDownEvent(ev))
! 	    {
! 	    if (UpIsExpected(phys,key))		/* key is autorepeating */
! 		{
! 	        deallocate_event (ev);
! 		return;
! 		}
! 	    IgnoreKey(phys,key);
  	    }
! 	else if (KeyUpEvent(ev))
! 	    DontExpectUpKey(phys,key);
  
!         if (DeviceHasLeds(phys))
! 	    {
! 	    int led, index;
! 	    HPKeyboardFeedbackControl	d;
! 
! 	    copy_kbd_ctrl_params (&d, &dev->kbdfeed->ctrl);
! 	    if (index = IsLockKey(dev, key))
! 	       FIX_LED_CTRL(dev, d, ev, index, CAPSLOCK_LED);
! 
! 	    (*(phys->s.write)) (phys->d.file_ds, _XChangeFeedbackControl, &d);
! 	    }
! 	}
  
  #ifdef	XTESTEXT1
      if (on_steal_input)
  	{ 
! 	XTestStealKeyData(key, ev->u.u.type, phys->x_type, 
  	    ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootY);
  	if (exclusive_steal)
  	    { 
! 	    if (key != xtest_command_key)
  		deallocate_event (ev);
  	    }
! 	else if (key == xtest_command_key)
  	    deallocate_event (ev);
  	}
  #endif /* XTESTEXT1 */
***************
*** 1166,1172 ****
      time = ev->u.keyButtonPointer.time;
      deallocate_event(ev);
      process_motion (inputInfo.pointer, phys, hpPointer, coords, time);
!     ev = format_ev (MotionNotify, 0, time, hpPointer, &xE);
      return (1);
      }
  
--- 856,862 ----
      time = ev->u.keyButtonPointer.time;
      deallocate_event(ev);
      process_motion (inputInfo.pointer, phys, hpPointer, coords, time);
!     ev = format_ev (inputInfo.pointer, MotionNotify, 0, time, hpPointer, &xE);
      return (1);
      }
  
***************
*** 1215,1228 ****
  #define EDGE_T			1 << 2
  #define EDGE_B			1 << 3
  
! #define OffRightEdge(log)  (log->coords[0] > (log->change_xmax + \
! 			    (int) log->change_amt) ? EDGE_R : 0)
! #define OffLeftEdge(log)   (log->coords[0] < (log->change_xmin - \
! 			    (int) log->change_amt) ? EDGE_L : 0) 
! #define OffTopEdge(log)    (log->coords[1] < (log->change_ymin - \
! 			    (int) log->change_amt) ? EDGE_T : 0) 
! #define OffBottomEdge(log) (log->coords[1] > (log->change_ymax + \
! 			    (int) log->change_amt) ? EDGE_B : 0) 
  
  process_motion (dev, phys, log, c, timestamp)
      DeviceIntPtr dev;
--- 905,925 ----
  #define EDGE_T			1 << 2
  #define EDGE_B			1 << 3
  
! /*
!  * Use the change_xmax and change_amt from the physical device.
!  * This is needed for the case where an absolute device like a tablet
!  * has its input merged with a relative device like a mouse.
!  *
!  */
! 
! #define OffRightEdge(log, phys)  (log->coords[0] > (phys->change_xmax + \
! 			    (int) phys->change_amt) ? EDGE_R : 0)
! #define OffLeftEdge(log, phys)   (log->coords[0] < (phys->change_xmin - \
! 			    (int) phys->change_amt) ? EDGE_L : 0) 
! #define OffTopEdge(log, phys)    (log->coords[1] < (phys->change_ymin - \
! 			    (int) phys->change_amt) ? EDGE_T : 0) 
! #define OffBottomEdge(log, phys) (log->coords[1] > (phys->change_ymax + \
! 			    (int) phys->change_amt) ? EDGE_B : 0) 
  
  process_motion (dev, phys, log, c, timestamp)
      DeviceIntPtr dev;
***************
*** 1233,1238 ****
--- 930,936 ----
      int		i;
      unsigned int state = 0;
      extern int playback_on;
+     ScreenPtr newScreen = log->pScreen;
     
      /* Compute x,y taking care of desired threshold and acceleration
       * No acceleration if we're playing back a recorded test script.
***************
*** 1242,1251 ****
  
      if (!playback_on)
  	{
! 	if (!(phys->hil_header.flags & HIL_ABSOLUTE) && 
  	    (acceleration != DEF_ACCELERATION))
  	    {
! 	    for (i=0; i < (u_char) log->hil_header.ax_num; i++)
  	        if ( (c[i] - threshold) > 0)
  		    c[i] = threshold + (c[i] - threshold) * acceleration;
  	        else if ( (c[i] + threshold) < 0)
--- 940,949 ----
  
      if (!playback_on)
  	{
! 	if (!(phys->hpflags & ABSOLUTE_DATA) && 
  	    (acceleration != DEF_ACCELERATION))
  	    {
! 	    for (i=0; i < (u_char) log->d.ax_num; i++)
  	        if ( (c[i] - threshold) > 0)
  		    c[i] = threshold + (c[i] - threshold) * acceleration;
  	        else if ( (c[i] + threshold) < 0)
***************
*** 1259,1289 ****
       * If this is a relative device, save the current movement.
       */
  
!     if (log == hpPointer || (phys->hil_header.flags & HIL_ABSOLUTE))
! 	for (i=0; i< (int) log->hil_header.ax_num; i++)
  	    log->coords[i] = log->coords[i] + c[i];
      else
! 	for (i=0; i< (u_char) log->hil_header.ax_num; i++)
  	    log->coords[i] = c[i];
  
      /*
!      * Active Zaphod implementation:
!      *    Change the screen if we have more than one screen,
!      *	  and the screen change device has gone off one of the edges,
!      *    and the device is not grabbed and confined.
       */
  
- 
- #if defined(__hpux) || defined(__hp_osf)
      if ( screenInfo.numScreens > 1 && 
! 	 log->dev_id == screen_change_dev->id &&
          (!dev->grab || !dev->grab->confineTo))
  	{
! 	if (state = (OffRightEdge(log) | OffLeftEdge(log) | 
! 	    OffTopEdge(log) | OffBottomEdge(log)))
  	    {
  	    if (!screen_was_changed)
! 		change_the_screen (dev, phys, log, state);
  	    }
  	else 
  	    /*
--- 957,984 ----
       * If this is a relative device, save the current movement.
       */
  
!     if (log == hpPointer || (phys->hpflags & ABSOLUTE_DATA))
! 	for (i=0; i< (int) log->d.ax_num; i++)
  	    log->coords[i] = log->coords[i] + c[i];
      else
! 	for (i=0; i< (u_char) log->d.ax_num; i++)
  	    log->coords[i] = c[i];
  
      /*
!      * Change the screen if we have more than one screen,
!      * and the screen change device has gone off one of the edges,
!      * and the device is not grabbed and confined.
       */
  
      if ( screenInfo.numScreens > 1 && 
! 	 dev->id == screen_change_dev->id &&
          (!dev->grab || !dev->grab->confineTo))
  	{
! 	if ((state=OffRightEdge(log,phys)) || (state=OffLeftEdge(log,phys)) || 
! 	    (state = OffTopEdge(log,phys)) || (state = OffBottomEdge(log,phys)))
  	    {
  	    if (!screen_was_changed)
! 		change_the_screen (dev, phys, log, state, &newScreen);
  	    }
  	else 
  	    /*
***************
*** 1294,1308 ****
  	     */
  	    screen_was_changed = FALSE;
  	}
- #endif /* __hpux */
      if (phys == hptablet_extension && phys->clients == NULL)
  	return;
      /*
       * Clip the cursor to stay within the bound of screen.
       */
!     if (log == hpPointer &&
!         (!hpConstrainXY (&log->coords[0], &log->coords[1])))
! 	   return;
      move_mouse (log, timestamp);
      }
  
--- 989,1006 ----
  	     */
  	    screen_was_changed = FALSE;
  	}
      if (phys == hptablet_extension && phys->clients == NULL)
  	return;
      /*
       * Clip the cursor to stay within the bound of screen.
       */
!     if (log == hpPointer)
! 	{
! 	log->coords[0] = 
! 	    max( LimitTheCursor.x1, min( LimitTheCursor.x2,log->coords[0]));
! 	log->coords[1] = 
! 	    max( LimitTheCursor.y1, min( LimitTheCursor.y2,log->coords[1]));
! 	}
      move_mouse (log, timestamp);
      }
  
***************
*** 1314,1321 ****
   *
   */
  
- #if defined(__hpux) || defined(__hp_osf)
- 
  #define INCREMENT_SCREEN_BY_ONE(p,l) (screenInfo.screens[(p->myNum+1) % \
      screenInfo.numScreens])
  
--- 1012,1017 ----
***************
*** 1330,1343 ****
      screenInfo.screens[p->myNum-2] : \
      screenInfo.screens[p->myNum + screenInfo.numScreens - 2])
  
! change_the_screen (dev, phys, log, state)
      DeviceIntPtr dev;
      HPInputDevice *phys, *log;				/* logical device */
      unsigned int state;
      {
!     ScreenPtr  	pScreen;
!     WindowPtr	pRootWin;
!     int		tx, ty;
  
      if (screen_col_wrap == DEFAULT)
  	{
--- 1026,1038 ----
      screenInfo.screens[p->myNum-2] : \
      screenInfo.screens[p->myNum + screenInfo.numScreens - 2])
  
! change_the_screen (dev, phys, log, state, newScreen)
      DeviceIntPtr dev;
      HPInputDevice *phys, *log;				/* logical device */
      unsigned int state;
+     ScreenPtr *newScreen;
      {
!     ScreenPtr  	oldScreen = log->pScreen;
  
      if (screen_col_wrap == DEFAULT)
  	{
***************
*** 1355,1545 ****
  	    screen_row_wrap = NOWRAP;
  	}
  
-     pScreen = log->pScreen;
  
      switch (state)
  	{
  	case EDGE_L:
  	    if (screen_row_wrap == NOWRAP &&
  		(screen_orientation == VERTICAL ||
! 	        (pScreen->myNum == 0  ||
! 	        (pScreen->myNum == 2 && screen_orientation == MATRIX ))))
  		return;
  
  	    if (screen_orientation == VERTICAL)
  		{
  		if (screen_row_wrap == CHANGE_BY_TWO)
  		    {
! 		    log->pScreen = DECREMENT_SCREEN_BY_TWO(pScreen,log);
  		    }
  		}
  	    else if (screen_orientation == HORIZONTAL)
  		{
! 		log->pScreen = DECREMENT_SCREEN_BY_ONE(pScreen,log);
  		}
! 	    else if (screen_orientation == MATRIX)
  		{
! 		if (pScreen->myNum % 2)
  		    {
! 		    log->pScreen = DECREMENT_SCREEN_BY_ONE(pScreen,log);
  		    }
  	        else if (screen_row_wrap == WRAP)
  		    {
! 		    if (!(screenInfo.numScreens == 3 && pScreen->myNum == 2))
  	    	        {
! 		        log->pScreen = INCREMENT_SCREEN_BY_ONE(pScreen,log);
  		        }
  		    }
  		else
  		    break;
  		}
      
! 	    if (!(log->hil_header.flags & HIL_ABSOLUTE))
! 		log->coords[0] += (log->pScreen->width - log->change_xmin);
  	    break;
  	case EDGE_R:
  	    if (screen_row_wrap == NOWRAP &&
  		(screen_orientation == VERTICAL ||
! 	        (pScreen->myNum == 3  ||
! 	        (pScreen->myNum == 1 && screen_orientation == MATRIX ))))
  		return;
  
  	    if (screen_orientation == VERTICAL)
  		{
  		if (screen_row_wrap == CHANGE_BY_TWO)
  		    {
! 		    log->pScreen = INCREMENT_SCREEN_BY_TWO(pScreen,log);
  		    }
  		}
  	    else if (screen_orientation == HORIZONTAL)
  		{
! 		log->pScreen = INCREMENT_SCREEN_BY_ONE(pScreen,log);
  		}
! 	    else if (screen_orientation == MATRIX)
  		{
! 	        if (pScreen->myNum % 2)
  		    {
  	            if (screen_row_wrap == WRAP)
  		        {
! 		        log->pScreen = DECREMENT_SCREEN_BY_ONE(pScreen,log);
  		        }
  		    else
  			break;
  		    }
! 		else if (!(screenInfo.numScreens == 3 && pScreen->myNum == 2))
  		    {
! 		    log->pScreen = INCREMENT_SCREEN_BY_ONE(pScreen,log);
  		    }
  		else if (screen_row_wrap != WRAP)
  		    break;
  		}
  
! 	    if (!(log->hil_header.flags & HIL_ABSOLUTE))
! 		log->coords[0] -= (pScreen->width);
  	    break;
  	case EDGE_T:
  	    if (screen_col_wrap == NOWRAP &&
  		(screen_orientation == HORIZONTAL ||
! 	        (pScreen->myNum == 3  ||
! 	        (pScreen->myNum == 2 && screen_orientation == MATRIX ))))
  		return;
  
  	    if (screen_orientation == HORIZONTAL)
  		{
  		if (screen_col_wrap == CHANGE_BY_TWO)
  		    {
! 		    log->pScreen = INCREMENT_SCREEN_BY_TWO(pScreen,log);
  		    }
  		}
  	    else if (screen_orientation == VERTICAL)
  		{
! 		log->pScreen = INCREMENT_SCREEN_BY_ONE(pScreen,log);
  		}
! 	    else if (screen_orientation == MATRIX)
  	        {
! 		if (pScreen->myNum >= 2) 
  		    {
  		    if (screen_col_wrap == WRAP)
  		        {
! 		        log->pScreen = DECREMENT_SCREEN_BY_TWO(pScreen,log);
  		        }
  		    else
  			break;
  		    }
! 		else if (!(screenInfo.numScreens == 3 && pScreen->myNum == 1))
  		    {
! 		    log->pScreen = INCREMENT_SCREEN_BY_TWO(pScreen,log);
  		    }
  		else if (screen_col_wrap != WRAP)
  		    break;
  		}
      
! 	    if (!(log->hil_header.flags & HIL_ABSOLUTE))
! 		log->coords[1] += (pScreen->height);
  	    break;
  	case EDGE_B:
  	    if (screen_col_wrap == NOWRAP &&
  		(screen_orientation == HORIZONTAL ||
! 	        (pScreen->myNum == 0  ||
! 	        (pScreen->myNum == 1 && screen_orientation == MATRIX))))
  		return;
  
  	    if (screen_orientation == HORIZONTAL)
  		{
  		if (screen_col_wrap == CHANGE_BY_TWO)
  		    {
! 		    log->pScreen = DECREMENT_SCREEN_BY_TWO(pScreen,log);
  		    }
  		}
  	    else if (screen_orientation == VERTICAL)
  		{
! 		log->pScreen = DECREMENT_SCREEN_BY_ONE(pScreen,log);
  		}
! 	    else if (screen_orientation == MATRIX)
  	        {
! 		if (pScreen->myNum >= 2) 
  		    {
! 		    log->pScreen = DECREMENT_SCREEN_BY_TWO(pScreen,log);
  		    }
  		else if (screen_col_wrap == WRAP)
  		    {
! 		    if (! (screenInfo.numScreens == 3 && pScreen->myNum == 1))
  		        {
! 		        log->pScreen = INCREMENT_SCREEN_BY_TWO(pScreen,log);
  		        }
  		    }
  		else
  		    break;
  		}
  
! 	    if (!(log->hil_header.flags & HIL_ABSOLUTE))
! 		log->coords[1] -= (pScreen->height);
  	    break;
  	}
  
!     (*((hpPrivPtr) pScreen->devPrivate)->CursorOff)(pScreen);
!     pScreen = log->pScreen;
!     screen_was_changed = TRUE;
!     set_scale_and_screen_change (log);
!     (*((hpPrivPtr) pScreen->devPrivate)->ChangeScreen)(pScreen);
!     if (phys == hptablet_extension)
! 	{
! 	tx = phys->coords[0] < tablet_xorg ? 0 : pScreen->width;
!         ty = (float) phys->coords[1] * phys->scaleY;
! 	NewCurrentScreen(pScreen, tx, ty);
  	}
      else
!         NewCurrentScreen(pScreen, log->coords[0], log->coords[1]);
  
!     hpActiveScreen = pScreen->myNum;
!     if (dev->grab && dev->grab->cursor)
! 	pScreen->DisplayCursor(pScreen,dev->grab->cursor);
!     else if (!(pRootWin = WindowTable[pScreen->myNum]))
! 	pScreen->DisplayCursor(pScreen,(CursorPtr) NULL);
      else
! 	pScreen->DisplayCursor(pScreen,pRootWin->optional->cursor);
      }
- #endif /* __hpux || __hp_osf */
  
  /****************************************************************************
   *
--- 1050,1261 ----
  	    screen_row_wrap = NOWRAP;
  	}
  
  
      switch (state)
  	{
  	case EDGE_L:
  	    if (screen_row_wrap == NOWRAP &&
  		(screen_orientation == VERTICAL ||
! 	        (oldScreen->myNum == 0  ||
! 	        (oldScreen->myNum == 2 && screen_orientation == MATRIX ))))
  		return;
  
  	    if (screen_orientation == VERTICAL)
  		{
  		if (screen_row_wrap == CHANGE_BY_TWO)
  		    {
! 		    *newScreen = DECREMENT_SCREEN_BY_TWO(oldScreen,log);
  		    }
  		}
  	    else if (screen_orientation == HORIZONTAL)
  		{
! 		*newScreen = DECREMENT_SCREEN_BY_ONE(oldScreen,log);
  		}
! 	    else 					/* MATRIX */
  		{
! 		if (oldScreen->myNum % 2)
  		    {
! 		    *newScreen = DECREMENT_SCREEN_BY_ONE(oldScreen,log);
  		    }
  	        else if (screen_row_wrap == WRAP)
  		    {
! 		    if (!(screenInfo.numScreens == 3 && oldScreen->myNum == 2))
  	    	        {
! 		        *newScreen = INCREMENT_SCREEN_BY_ONE(oldScreen,log);
  		        }
  		    }
  		else
  		    break;
  		}
      
! 	    if (!(phys->hpflags & ABSOLUTE_DATA))
! 		log->coords[0] += (oldScreen->width - log->change_xmin);
  	    break;
  	case EDGE_R:
  	    if (screen_row_wrap == NOWRAP &&
  		(screen_orientation == VERTICAL ||
! 	        (oldScreen->myNum == (screenInfo.numScreens-1)  ||
! 	        (oldScreen->myNum == 1 && screen_orientation == MATRIX ))))
  		return;
  
  	    if (screen_orientation == VERTICAL)
  		{
  		if (screen_row_wrap == CHANGE_BY_TWO)
  		    {
! 		    *newScreen = INCREMENT_SCREEN_BY_TWO(oldScreen,log);
  		    }
  		}
  	    else if (screen_orientation == HORIZONTAL)
  		{
! 		*newScreen = INCREMENT_SCREEN_BY_ONE(oldScreen,log);
  		}
! 	    else 					/* MATRIX */
  		{
! 	        if (oldScreen->myNum % 2)
  		    {
  	            if (screen_row_wrap == WRAP)
  		        {
! 		        *newScreen = DECREMENT_SCREEN_BY_ONE(oldScreen,log);
  		        }
  		    else
  			break;
  		    }
! 		else if (!(screenInfo.numScreens == 3 && oldScreen->myNum == 2))
  		    {
! 		    *newScreen = INCREMENT_SCREEN_BY_ONE(oldScreen,log);
  		    }
  		else if (screen_row_wrap != WRAP)
  		    break;
  		}
  
! 	    if (!(phys->hpflags & ABSOLUTE_DATA))
! 		log->coords[0] -= (oldScreen->width);
  	    break;
  	case EDGE_T:
  	    if (screen_col_wrap == NOWRAP &&
  		(screen_orientation == HORIZONTAL ||
! 	        (oldScreen->myNum == (screenInfo.numScreens-1)  ||
! 	        (oldScreen->myNum == 2 && screen_orientation == MATRIX ))))
  		return;
  
  	    if (screen_orientation == HORIZONTAL)
  		{
  		if (screen_col_wrap == CHANGE_BY_TWO)
  		    {
! 		    *newScreen = INCREMENT_SCREEN_BY_TWO(oldScreen,log);
  		    }
  		}
  	    else if (screen_orientation == VERTICAL)
  		{
! 		*newScreen = INCREMENT_SCREEN_BY_ONE(oldScreen,log);
  		}
! 	    else 						/* MATRIX */
  	        {
! 		if (oldScreen->myNum >= 2) 
  		    {
  		    if (screen_col_wrap == WRAP)
  		        {
! 		        *newScreen = DECREMENT_SCREEN_BY_TWO(oldScreen,log);
  		        }
  		    else
  			break;
  		    }
! 		else if (!(screenInfo.numScreens == 3 && oldScreen->myNum == 1))
  		    {
! 		    *newScreen = INCREMENT_SCREEN_BY_TWO(oldScreen,log);
  		    }
  		else if (screen_col_wrap != WRAP)
  		    break;
  		}
      
! 	    if (!(phys->hpflags & ABSOLUTE_DATA))
! 		log->coords[1] += (oldScreen->height);
  	    break;
  	case EDGE_B:
  	    if (screen_col_wrap == NOWRAP &&
  		(screen_orientation == HORIZONTAL ||
! 	        (oldScreen->myNum == 0  ||
! 	        (oldScreen->myNum == 1 && screen_orientation == MATRIX))))
  		return;
  
  	    if (screen_orientation == HORIZONTAL)
  		{
  		if (screen_col_wrap == CHANGE_BY_TWO)
  		    {
! 		    *newScreen = DECREMENT_SCREEN_BY_TWO(oldScreen,log);
  		    }
  		}
  	    else if (screen_orientation == VERTICAL)
  		{
! 		*newScreen = DECREMENT_SCREEN_BY_ONE(oldScreen,log);
  		}
! 	    else 						/* MATRIX */
  	        {
! 		if (oldScreen->myNum >= 2) 
  		    {
! 		    *newScreen = DECREMENT_SCREEN_BY_TWO(oldScreen,log);
  		    }
  		else if (screen_col_wrap == WRAP)
  		    {
! 		    if (! (screenInfo.numScreens == 3 && oldScreen->myNum == 1))
  		        {
! 		        *newScreen = INCREMENT_SCREEN_BY_TWO(oldScreen,log);
  		        }
  		    }
  		else
  		    break;
  		}
  
! 	    if (!(phys->hpflags & ABSOLUTE_DATA))
! 		log->coords[1] -= (oldScreen->height);
  	    break;
  	}
  
!     hpMoveCursorToNewScreen(*newScreen, log);
!     }
! 
! /****************************************************************************
!  *
!  * hpMoveCursorToNewScreen()
!  * Turn the cursor off on the old screen.
!  * Call the display driver ChangeScreen routine.
!  * This routine is also called from the display driver SetCursorPosition
!  * routine.
!  *
!  */
! 
! #include <stdio.h>
! 
! hpMoveCursorToNewScreen(newScreen, InDev)
!     ScreenPtr newScreen;
!     HPInputDevice *InDev;
!     {
!     WindowPtr	pRootWin;
!     int tx, ty;
!     hpPrivPtr php = (hpPrivPtr) InDev->pScreen->devPrivate;
! 
!     php->CursorOff (InDev->pScreen);
!     set_scale_and_screen_change (inputInfo.pointer, InDev, newScreen);
!     (*((hpPrivPtr)(newScreen->devPrivate))->ChangeScreen) (newScreen);
!     InDev->pScreen = newScreen;
!     if (InDev == hptablet_extension)
! 	{
! 	tx = InDev->coords[0] < tablet_xorg ? 0 : newScreen->width;
! 	ty = (float) InDev->coords[1] * InDev->scaleY;
! 	NewCurrentScreen(newScreen, tx, ty);
  	}
      else
! 	NewCurrentScreen(newScreen, InDev->coords[0], InDev->coords[1]);
!     hpActiveScreen = newScreen->myNum;
!     screen_was_changed = TRUE;
  
!     if (inputInfo.pointer->grab && inputInfo.pointer->grab->cursor)
! 	newScreen->DisplayCursor(newScreen,inputInfo.pointer->grab->cursor);
!     else if (!(pRootWin = WindowTable[newScreen->myNum]))
! 	newScreen->DisplayCursor(newScreen,(CursorPtr) NULL);
      else
! 	newScreen->DisplayCursor(newScreen,pRootWin->optional->cursor);
      }
  
  /****************************************************************************
   *
***************
*** 1558,1597 ****
      int	event_time;				/* event timestamp */
      {
      int			i;
!     int			id 	= log->dev_id;
!     int			axes = log->hil_header.ax_num;
!    
! #if defined(__hpux) || defined(__hp_osf)
!     register 		hpPrivPtr phpPriv =  (hpPrivPtr) 
! 			   log->pScreen->devPrivate;
!     if (log == hpPointer)
! #ifdef SPECIAL_68K_OSF
! 	miPointerMoveCursor(log->pScreen, log->coords[0], log->coords[1], 1);
! #else
!         (*phpPriv->MoveMouse) (log->pScreen, log->coords[0], log->coords[1], 1);
! #endif
! #endif /* __hpux */
  
- #ifdef __apollo
      if (log == hpPointer)
! 	{
! 	xshScreenPrivPtr pScreenPriv;
  
! 	pScreenPriv = XSH_SCREEN_PRIV (log->pScreen);
! 	(*pScreenPriv->MoveCursor) (pScreenPriv,log->coords[0],log->coords[1]);
! #ifdef XTESTEXT1
! 	if (on_steal_input)
! 	    check_for_motion_steal (log->coords[0], log->coords[1]);
! #endif /* XTESTEXT1 */
! 	}
! #endif /* __apollo */
! 
!     *dpmotionBuf[id]++ = event_time;
      for (i=0; i<axes; i++)
! 	*dpmotionBuf[id]++ = log->coords[i];
      
!     if((dheadmotionBuf[id] + 100 * (axes+1)) == dpmotionBuf[id])
! 	dpmotionBuf[id] = dheadmotionBuf[id];
      }
  
  /**************************************************************************
--- 1274,1290 ----
      int	event_time;				/* event timestamp */
      {
      int			i;
!     int			axes = log->d.ax_num;
  
      if (log == hpPointer)
! 	(*log->pScreen->SetCursorPosition) (log->pScreen, log->coords[0], log->coords[1], FALSE);
  
!     *log->dpmotionBuf++ = event_time;
      for (i=0; i<axes; i++)
! 	*log->dpmotionBuf++ = log->coords[i];
      
!     if((log->dheadmotionBuf + 100 * (axes+1)) == log->dpmotionBuf)
! 	log->dpmotionBuf = log->dheadmotionBuf;
      }
  
  /**************************************************************************
***************
*** 1617,1658 ****
   * that controls screen changes.
   *
   */
! set_scale_and_screen_change (d)
      HPInputDevice *d;
      {
!     int tmp, resx_mm, resy_mm;
  
      /* Absolute device: graphics tablet or touchscreen */
  
!     if (d->hil_header.flags & HIL_ABSOLUTE)
  	{
! 	resx_mm = d->hil_header.resx / 1000;
! 	resy_mm = d->hil_header.resy / 1000;
  
      	/* Tablet subsetting enabled and this is the pointer region.
      	   This is called only during initialization, since when
      	   we change screens, the device is the second logical device. */
  
! 	if (tablet_width && d->dev_id == inputInfo.pointer->id)
  	    {
! 	    tablet_xorg = tablet_xorigin * resx_mm;
! 	    tablet_xlimit = tablet_xorg + tablet_width * resx_mm;
! 	    tmp  = d->hil_header.size_y - (tablet_yorigin * resy_mm);
  	    tablet_yorg = tmp > 0 ? tmp : 0;
! 	    tmp = tablet_yorg - (tablet_height * resy_mm);
  	    if (tmp > 0)
  		tablet_ylimit = tmp;
  	    else
  		{
  		tablet_ylimit = 0;
! 		tablet_height = tablet_yorg / resy_mm;
! 		}
! 	    d->scaleX = ((float) d->pScreen->width) /
! 	        ((float)tablet_width * resx_mm );
! 	    d->scaleY = ((float) d->pScreen->height) /
! 		((float)tablet_height * resy_mm );
  	    d->change_xmin = 0;
! 	    d->change_xmax = d->pScreen->width;
  	    d->change_amt = 0;
  	    }
  	else
--- 1310,1354 ----
   * that controls screen changes.
   *
   */
! set_scale_and_screen_change (dev,d,newScreen)
!     DeviceIntPtr dev;
      HPInputDevice *d;
+     ScreenPtr newScreen;
      {
!     int tmp, res_mm;
  
      /* Absolute device: graphics tablet or touchscreen */
  
!     if (d->hpflags & ABSOLUTE_DATA)
  	{
! 	res_mm = d->d.resolution / 1000;
  
      	/* Tablet subsetting enabled and this is the pointer region.
      	   This is called only during initialization, since when
      	   we change screens, the device is the second logical device. */
  
! 	if (tablet_width && dev->id == inputInfo.pointer->id)
  	    {
! 	    tablet_xorg = tablet_xorigin * res_mm;
! 	    tablet_xlimit = tablet_xorg + tablet_width * res_mm;
! 	    tmp  = d->d.max_y - (tablet_yorigin * res_mm);
  	    tablet_yorg = tmp > 0 ? tmp : 0;
! 	    tmp = tablet_yorg - (tablet_height * res_mm);
  	    if (tmp > 0)
  		tablet_ylimit = tmp;
  	    else
  		{
  		tablet_ylimit = 0;
! 		tablet_height = tablet_yorg / res_mm;
! 		if (!tablet_height)
! 		    tablet_height = 1;
! 		}
! 	    d->scaleX = ((float) newScreen->width) /
! 	        ((float)tablet_width * res_mm );
! 	    d->scaleY = ((float) newScreen->height) /
! 		((float)tablet_height * res_mm );
  	    d->change_xmin = 0;
! 	    d->change_xmax = newScreen->width;
  	    d->change_amt = 0;
  	    }
  	else
***************
*** 1668,1677 ****
  	      Set scale for the case where the tablet is the X pointer.
  	      The scale is also returned to clients via XHPListInputDevices.
  	     */
! 	    d->scaleX = ((float) (d->pScreen->width+2*screen_change_amt)) /
! 		((float)d->hil_header.size_x);
! 	    d->scaleY = ((float)d->pScreen->height) /
! 		((float)d->hil_header.size_y);
  	    if (tablet_width)
  		{
  		/* If this is the second logical device, we must also
--- 1364,1373 ----
  	      Set scale for the case where the tablet is the X pointer.
  	      The scale is also returned to clients via XHPListInputDevices.
  	     */
! 	    d->scaleX = ((float) (newScreen->width+2*screen_change_amt)) /
! 		((float)d->d.max_x);
! 	    d->scaleY = ((float)newScreen->height) /
! 		((float)d->d.max_y);
  	    if (tablet_width)
  		{
  		/* If this is the second logical device, we must also
***************
*** 1679,1692 ****
  		   absolute extension devices is not scaled, the
  		   screen change amounts units are tablet counts.
  		 */
! 		hpPointer->scaleX = ((float) d->pScreen->width) /
! 	            ((float)tablet_width * resx_mm );
! 		hpPointer->scaleY = ((float) d->pScreen->height) /
! 		    ((float)tablet_height * resy_mm );
! 		d->change_xmin =  resx_mm * screen_change_amt;
! 		d->change_xmax = d->hil_header.size_x - d->change_xmin;
! 		d->change_ymin =  resy_mm * screen_change_amt;
! 		d->change_ymax = d->hil_header.size_y - d->change_xmin;
  		d->change_amt = 0;
  		}
  	    else
--- 1375,1388 ----
  		   absolute extension devices is not scaled, the
  		   screen change amounts units are tablet counts.
  		 */
! 		hpPointer->scaleX = ((float) newScreen->width) /
! 	            ((float)tablet_width * res_mm );
! 		hpPointer->scaleY = ((float) newScreen->height) /
! 		    ((float)tablet_height * res_mm );
! 		d->change_xmin =  res_mm * screen_change_amt;
! 		d->change_xmax = d->d.max_x - d->change_xmin;
! 		d->change_ymin =  res_mm * screen_change_amt;
! 		d->change_ymax = d->d.max_y - d->change_xmin;
  		d->change_amt = 0;
  		}
  	    else
***************
*** 1695,1703 ****
  		 */
  		{
  		d->change_xmin =  1;
! 		d->change_xmax = d->pScreen->width - 2;
  		d->change_ymin =  1;
! 		d->change_ymax = d->pScreen->height - 2;
  		d->change_amt = 0;
  		}
  	    }
--- 1391,1399 ----
  		 */
  		{
  		d->change_xmin =  1;
! 		d->change_xmax = newScreen->width - 2;
  		d->change_ymin =  1;
! 		d->change_ymax = newScreen->height - 2;
  		d->change_amt = 0;
  		}
  	    }
***************
*** 1713,1721 ****
  
  	{
  	d->change_xmin = 0;
! 	d->change_xmax = d->pScreen->width;
  	d->change_ymin = 0;
! 	d->change_ymax = d->pScreen->height;
  	d->change_amt = screen_change_amt;
  	}
      }
--- 1409,1417 ----
  
  	{
  	d->change_xmin = 0;
! 	d->change_xmax = newScreen->width;
  	d->change_ymin = 0;
! 	d->change_ymax = newScreen->height;
  	d->change_amt = screen_change_amt;
  	}
      }
***************
*** 1732,1742 ****
  queue_motion_event (dev_p)
      HPInputDevice	*dev_p;
      {
!     static int		coords[MAX_AXES] = {0,0,0,0,0,0,0,0};
      extern		TimeStamp currentTime;
  
!     process_motion (inputInfo.pointer, dev_p, dev_p, coords, currentTime.milliseconds);
!     (void) format_ev (MotionNotify, 0, currentTime.milliseconds, dev_p, NULL);
      xE.b.u.u.type = 0;
      }
  
--- 1428,1446 ----
  queue_motion_event (dev_p)
      HPInputDevice	*dev_p;
      {
!     int			i;
!     int			axes = dev_p->d.ax_num;
      extern		TimeStamp currentTime;
+     int			ev_time = currentTime.milliseconds;
+ 
+     *dev_p->dpmotionBuf++ = ev_time;
+     for (i=0; i<axes; i++)
+ 	*dev_p->dpmotionBuf++ = dev_p->coords[i];
+     
+     if((dev_p->dheadmotionBuf + 100 * (axes+1)) == dev_p->dpmotionBuf)
+ 	dev_p->dpmotionBuf = dev_p->dheadmotionBuf;
  
!     (void) format_ev (inputInfo.pointer, MotionNotify, 0, ev_time, dev_p, NULL);
      xE.b.u.u.type = 0;
      }
  
***************
*** 1751,1781 ****
  #define AXES_PER_EVENT 6
  
  xEvent *
! format_ev (type, detail, event_time, log, event)
      u_char		type;
      u_char		detail;
      unsigned  int 	event_time;
      HPInputDevice	*log;
      xHPEvent		*event;
      {
      int i, j;
!     int n_axes = log->hil_header.ax_num;
      INT32 *ip;
      xEvent *ret = NULL;
      Bool compressing = FALSE;
  
      for (i=0; (i==0 || i<n_axes); i+=AXES_PER_EVENT)
  	{
  	if (event==NULL)
  	    {
! 	    if (xE.b.u.u.type != 0)	/* we have a previous motion event  */
! 		{
!         	event = allocate_event();/* queue it before the new event    */
!         	*event = xE;
! 		xE = zxE;			/* mark it as processed	    */
! 		}
  	    event = allocate_event();
  	    }
  	else
  	    compressing = TRUE;
  	if (!ret)
--- 1455,1498 ----
  #define AXES_PER_EVENT 6
  
  xEvent *
! format_ev (dev, type, detail, event_time, log, event)
!     DeviceIntPtr	dev;
      u_char		type;
      u_char		detail;
      unsigned  int 	event_time;
      HPInputDevice	*log;
      xHPEvent		*event;
      {
+     int first_val = 0, val_data = 0;
      int i, j;
!     int n_axes = log->d.ax_num;
      INT32 *ip;
      xEvent *ret = NULL;
      Bool compressing = FALSE;
  
+     if (log->hpflags & NON_CONTIGUOUS_DATA)
+ 	for (j=0; j < (u_char) log->d.ax_num; j++)
+ 	    if (log->coords[j]!=0)
+ 		{
+ 		first_val = j;
+ 		val_data = log->coords[j];
+ 		break;
+ 		}
+ 
      for (i=0; (i==0 || i<n_axes); i+=AXES_PER_EVENT)
  	{
  	if (event==NULL)
  	    {
! 	    ENQUEUE_EVENT(event);
  	    event = allocate_event();
  	    }
+ 	else if ((event->b.u.keyButtonPointer.pad1 & 0x7f) != dev->id ||
+ 	    ((log->hpflags & NON_CONTIGUOUS_DATA) &&
+ 	    event->x.first_valuator != first_val))
+ 	    {
+ 	    ENQUEUE_EVENT(event);
+ 	    event = &xE;
+ 	    }
  	else
  	    compressing = TRUE;
  	if (!ret)
***************
*** 1786,1827 ****
  	event->b.u.keyButtonPointer.time = event_time;
  	event->b.u.keyButtonPointer.rootX = hpPointer->coords[0];
  	event->b.u.keyButtonPointer.rootY = hpPointer->coords[1];
! 	event->b.u.keyButtonPointer.pad1 = log->dev_id;
  #ifdef XINPUT
  	if (type >= FIRST_EXTENSION_EVENT)
  	    {
  	    event->b.u.keyButtonPointer.pad1 |= MORE_EVENTS;
  	    event->x.type = DeviceValuator;
! 	    event->x.deviceid = log->dev_id;
  
  	    if (log->hpflags & NON_CONTIGUOUS_DATA)
! 		for (j=0; j < (u_char) log->hil_header.ax_num; j++)
! 		    {
! 		    if (log->coords[j]!=0)
! 			{
! 			event->x.num_valuators = 1;
! 			event->x.first_valuator = j;
! 			if (compressing && 
! 			   !(log->hil_header.flags & HIL_ABSOLUTE))
! 			    event->x.valuator0 += log->coords[j];
! 			else
! 			    event->x.valuator0 = log->coords[j];
! 			return (ret);
! 			}
! 		    }
  	    else
  		{
  		event->x.num_valuators = 
! 		    log->hil_header.ax_num < AXES_PER_EVENT ?
! 		    log->hil_header.ax_num : i==0 ? AXES_PER_EVENT:
! 		    log->hil_header.ax_num - AXES_PER_EVENT;
  
  		event->x.first_valuator = i;
  		ip = &event->x.valuator0;
  		for (j=i; j<i+6; j++)
! 		    if ( j < (u_char) log->hil_header.ax_num)
  			if (compressing &&
! 			   !(log->hil_header.flags & HIL_ABSOLUTE))
  			    *ip++ +=  log->coords[j];
  			else
  			    *ip++ =  log->coords[j];
--- 1503,1539 ----
  	event->b.u.keyButtonPointer.time = event_time;
  	event->b.u.keyButtonPointer.rootX = hpPointer->coords[0];
  	event->b.u.keyButtonPointer.rootY = hpPointer->coords[1];
! 	event->b.u.keyButtonPointer.pad1 = dev->id;
  #ifdef XINPUT
  	if (type >= FIRST_EXTENSION_EVENT)
  	    {
  	    event->b.u.keyButtonPointer.pad1 |= MORE_EVENTS;
  	    event->x.type = DeviceValuator;
! 	    event->x.deviceid = dev->id;
  
  	    if (log->hpflags & NON_CONTIGUOUS_DATA)
! 		{
! 		event->x.num_valuators = 1;
! 		event->x.first_valuator = first_val;
! 		if (compressing && !(log->hpflags & ABSOLUTE_DATA))
! 		    event->x.valuator0 += val_data;
! 		else
! 		    event->x.valuator0 = val_data;
! 		return (ret);
! 		}
  	    else
  		{
  		event->x.num_valuators = 
! 		    log->d.ax_num < AXES_PER_EVENT ?
! 		    log->d.ax_num : i==0 ? AXES_PER_EVENT:
! 		    log->d.ax_num - AXES_PER_EVENT;
  
  		event->x.first_valuator = i;
  		ip = &event->x.valuator0;
  		for (j=i; j<i+6; j++)
! 		    if ( j < (u_char) log->d.ax_num)
  			if (compressing &&
! 			   !(log->hpflags & ABSOLUTE_DATA))
  			    *ip++ +=  log->coords[j];
  			else
  			    *ip++ =  log->coords[j];
***************
*** 1844,1871 ****
   *
   */
  
! #define CLICK_VOICE 		2
! 
! void
! ProcessInputEvents()
      {
!     int	click, id, i;
      INT32 *ip;
      int	count;
      xHPEvent	*event;
      DeviceIntPtr	dev;
      Bool checkedscreensave = FALSE;
  
- #if defined(__hp_osf)
-     if (hil_qp->hil_evqueue.head != hil_qp->hil_evqueue.tail)
- 	read_shmhil();
- #endif /* __hp_osf */
- 
      while ( events_queue->head != events_queue->tail) 
  	{
  	if (!checkedscreensave)
  	    {
! 	    if (screenIsSaved==SCREEN_SAVER_ON && !display_borrowed)
  		SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
  	    checkedscreensave = TRUE;
  	    }
--- 1556,1575 ----
   *
   */
  
! void ProcessInputEvents()
      {
!     int	id, i;
      INT32 *ip;
      int	count;
      xHPEvent	*event;
      DeviceIntPtr	dev;
      Bool checkedscreensave = FALSE;
  
      while ( events_queue->head != events_queue->tail) 
  	{
  	if (!checkedscreensave)
  	    {
! 	    if (screenIsSaved==SCREEN_SAVER_ON)
  		SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
  	    checkedscreensave = TRUE;
  	    }
***************
*** 1875,1908 ****
  	    {
  	    case KeyPress:
  	        if (keyboard_click)
! 		    beep(CLICK_VOICE,800,keyboard_click,1);
  	    case KeyRelease:
  		dev = (DeviceIntPtr) LookupKeyboardDevice ();
! 		(*dev->public.processInputProc) ((xEventPtr)event, dev, 1);
  	        break;
  	    case ButtonPress:
  	    case ButtonRelease:
  	    case MotionNotify:
! 		dev = (DeviceIntPtr) LookupPointerDevice ();
! 		(*dev->public.processInputProc) ((xEventPtr)event, dev, 1);
! 	        break;
! 	    default:
! #ifdef XINPUT
! 		id = event->b.u.keyButtonPointer.pad1 & DEVICE_BITS;
! 		if (!(event->b.u.keyButtonPointer.pad1 & MORE_EVENTS))
! 		    count=1;
! 		else
! 		    count=2;
! 		dev = LookupDeviceIntRec (id);
  		if (dev == NULL)
  		    break;
  		if (event->b.u.u.type == DeviceKeyPress)
  		    {
! 		    if (dev->kbdfeed)
! 		        click = (int)((double)(dev->kbdfeed->ctrl.click) * 
! 				15.0 / 100.0);
! 		    if (click)
! 		        beep(CLICK_VOICE,800,click,1);
  		    }
  		else if (event->b.u.u.type == DeviceMotionNotify)
  		    {
--- 1579,1620 ----
  	    {
  	    case KeyPress:
  	        if (keyboard_click)
! 		    {
!     		    KeybdCtrl ctrl;
! 		    dev = (DeviceIntPtr) LookupKeyboardDevice ();
! 		    ctrl.click = dev->kbdfeed->ctrl.click;
! 		    ctrl.bell = 0;
! 		    hpBell(0, dev, &ctrl, 0);
! 		    }
  	    case KeyRelease:
  		dev = (DeviceIntPtr) LookupKeyboardDevice ();
! 		(*dev->public.processInputProc) ((xEventPtr) event, dev, 1);
  	        break;
  	    case ButtonPress:
  	    case ButtonRelease:
  	    case MotionNotify:
! 		    dev = (DeviceIntPtr) LookupPointerDevice ();
! 		    (*dev->public.processInputProc) ((xEventPtr) event, dev, 1);
! 		    break;
! 		default:
!     #ifdef XINPUT
! 		    id = event->b.u.keyButtonPointer.pad1 & DEVICE_BITS;
! 		    if (!(event->b.u.keyButtonPointer.pad1 & MORE_EVENTS))
! 			count=1;
! 		    else
! 			count=2;
! 		    dev = LookupDeviceIntRec (id);
  		if (dev == NULL)
  		    break;
  		if (event->b.u.u.type == DeviceKeyPress)
  		    {
! 		    if (dev->kbdfeed && dev->kbdfeed->ctrl.click)
! 		        {
!     		        KeybdCtrl ctrl;
! 		        ctrl.click = dev->kbdfeed->ctrl.click;
! 		        ctrl.bell = 0;
! 		        hpBell(0, dev, &ctrl, 0);
! 		        }
  		    }
  		else if (event->b.u.u.type == DeviceMotionNotify)
  		    {
***************
*** 1910,1916 ****
  		    for (i=0; i < (u_char) event->x.num_valuators; i++)
  			dev->valuator->axisVal[i] = *(ip+i);
  		    }
! 		(*dev->public.processInputProc) ((xEventPtr)event, dev, count);
  #endif /* XINPUT */
  	    break;
  	    }
--- 1622,1628 ----
  		    for (i=0; i < (u_char) event->x.num_valuators; i++)
  			dev->valuator->axisVal[i] = *(ip+i);
  		    }
! 		(*dev->public.processInputProc) ((xEventPtr) event, dev, count);
  #endif /* XINPUT */
  	    break;
  	    }
***************
*** 1924,2018 ****
      queue_events_free	= WR_EVENTS;
      }
  
- #ifdef __hp_osf
- /******************************************************************
-  * 
-  * This routine removes data from the HIL shared memory event queue,
-  * and processes it through the server ddx input event processing code.
-  *
-  */
- 
- #define		NONDATA_BYTES	7
- #define		MAXNAMLEN	255
- 
- read_shmhil()
-     {
-     int			i, head;
-     char		dev_name[MAXNAMLEN];
-     u_char		*buf;
-     DeviceIntPtr 	dev;
-     void		process_hil_data();
-     xHPEvent		*xHP;
- 
-     while (hil_qp->hil_evqueue.head != hil_qp->hil_evqueue.tail)
-         {
- 	head = hil_qp->hil_evqueue.head;
- 	sprintf (dev_name, "/dev/hil%d", hil_qp->hil_event[head].dev);
- 	for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 	    if (strcmp (l_devs[i].dev_name, dev_name) == 0)
- 		break;
- 
- 	if (i==MAX_LOGICAL_DEVS)
- 	   	    FatalError ("Can't find input device %s\n queue head = %d\n queue tail = %d\n event timestamp = 0x%x\n event pollheader = 0x%x\n event size = %d\n",
- 			dev_name,
- 			head,hil_qp->hil_evqueue.tail,
- 			hil_qp->hil_event[head].tstamp,
- 			hil_qp->hil_event[head].poll_hdr,
- 			hil_qp->hil_event[head].size);
- 	dev = find_deviceintrec (&l_devs[i]);
- 	buf = (u_char *) &hil_qp->hil_event[head].tstamp;
- 	hil_info.timestamp = ((*buf & 0x0ff) << 24) |
- 			     ((*(buf+1) & 0x0ff) << 16) |
- 			     ((*(buf+2) & 0x0ff) << 8) |
- 			     ( *(buf+3) & 0x0ff);
- 
- 	hil_info.timestamp = (hil_info.timestamp - 1) * 10;
- 	hil_info.poll_hdr = hil_qp->hil_event[head].poll_hdr & HIL_POLL_HDR_BITS;
- 
- 	pending_bytes = hil_qp->hil_event[head].size - NONDATA_BYTES;
- 	pending_index = 0;
- 	for (i=0; i < pending_bytes; i++)
- 	    hil_info.dev_data[i] = hil_qp->hil_event[head].dev_data[i];
- 
- 	process_hil_data (dev, hil_info.hil_dev, &(hil_info));
-         hil_qp->hil_evqueue.head = (hil_qp->hil_evqueue.head + 1) % 
- 		hil_qp->hil_evqueue.size;	/* MUST use real head pointer,
- 						   process_button may have
- 						   incremented it.      */
- 	}
- 
-     if (xE.b.u.u.type != 0)			/* at least 1 motion event */
- 	{
-         xHP = allocate_event();			/* get current queue pointer*/
-         *xHP = xE;				/* copy from global struct  */
-         xE.b.u.u.type = 0;			/* mark it as processed	    */
- 	}
-     }
- #endif /* __hp_osf */
- 
  Bool
  get_serial_event (hil_ptr)
      struct dev_info *hil_ptr;				/* holds hil_data */
      {
!     int i, status;
  
      hil_ptr->timestamp = GetTimeInMillis();
      hil_ptr->poll_hdr = 0;
      pending_index=0;
      pending_bytes=0;
      bzero (hil_ptr->dev_data, 36);
!     for (i=0; i<num_serial_devices; i++)
! 	if (hil_ptr->hil_dev->file_ds==serialprocs[i].fd)
! 	    {
!  	    status = (*(serialprocs[i].read))
! 		(hil_ptr->hil_dev->file_ds,
! 	    	hil_ptr->dev_data, 
! 		&hil_ptr->poll_hdr, 
! 		&pending_bytes);
! 	    break;
! 	    }
      if (status==READ_SUCCESS)
  	return(FALSE);
      else
  	return(TRUE);
      }
--- 1636,1683 ----
      queue_events_free	= WR_EVENTS;
      }
  
  Bool
  get_serial_event (hil_ptr)
      struct dev_info *hil_ptr;				/* holds hil_data */
      {
!     HPInputDevice *d = hil_ptr->hil_dev;
!     int status;
  
      hil_ptr->timestamp = GetTimeInMillis();
      hil_ptr->poll_hdr = 0;
      pending_index=0;
      pending_bytes=0;
      bzero (hil_ptr->dev_data, 36);
!     status = (*(d->s.read))
! 	(d->d.file_ds, hil_ptr->dev_data, &hil_ptr->poll_hdr, &pending_bytes);
      if (status==READ_SUCCESS)
  	return(FALSE);
      else
  	return(TRUE);
      }
+ 
+ /************************************************************
+  * hpConstrainCursor
+  *
+  * This function simply sets the box to which the cursor 
+  * is limited.  
+  * 
+  * A single BoxRec is used for recording the cursor limits, 
+  * instead of one per screen.  This is ok because DIX will
+  * call this routine to establish new limits anytime the 
+  * cursor leaves one screen for another.
+  *
+  ************************************************************/
+ 
+ void 
+ hpConstrainCursor (pScreen,pBox)
+ ScreenPtr pScreen;    /* Screen to which it should be constrained */
+ BoxPtr   pBox;        /* Box in which... */
+ {
+     HPInputDevice *d;
+ 
+     LimitTheCursor = *pBox;
+     d = GET_HPINPUTDEVICE (inputInfo.pointer);
+     if (d->pScreen !=pScreen)
+ 	hpMoveCursorToNewScreen(pScreen, d);
+ }
*** -	Wed Jan 25 18:48:30 1995
--- xc/programs/Xserver/hw/hp/input/x_hil.h	Wed Jan 25 18:48:29 1995
***************
*** 1,9 ****
  #ifndef X_HIL_H
  #define X_HIL_H
! /* $XConsortium: x_hil.h,v 1.2 94/04/17 20:30:16 rws Exp $ */
  /*
  
! Copyright (c) 1986, 1987  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
--- 1,9 ----
  #ifndef X_HIL_H
  #define X_HIL_H
! /* $XConsortium: x_hil.h,v 1.4 95/01/24 23:29:42 gildea Exp $ */
  /*
  
! Copyright (c) 1988  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
***************
*** 30,52 ****
  from the X Consortium.
  
  
! Copyright (c) 1986, 1987 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this
! software and its documentation for any purpose and without
! fee is hereby granted, 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 Hewlett-Packard not be used in
! advertising or publicity pertaining to distribution of the
! software without specific, written prior permission.
  
  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
! PURPOSE.  Hewlett-Packard shall not be liable for errors 
! contained herein or direct, indirect, special, incidental or 
! consequential damages in connection with the furnishing, 
  performance, or use of this material.
  
  This software is not subject to any license of the American
--- 30,52 ----
  from the X Consortium.
  
  
! Copyright (c) 1988 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this software 
! and its documentation for any purpose and without fee is hereby 
! granted, 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 
! Hewlett-Packard not be used in advertising or publicity 
! pertaining to distribution of the software without specific, written 
! prior permission.
  
  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE.  Hewlett-Packard shall not be liable for errors
! contained herein or direct, indirect, special, incidental or
! consequential damages in connection with the furnishing,
  performance, or use of this material.
  
  This software is not subject to any license of the American
***************
*** 54,60 ****
  University of California.
  
  */
- 
  #include "hpext.h"
  
  /* MAXHILEVENTS is the maximum number of X events that can
--- 54,59 ----
*** -	Fri Jan 27 14:25:44 1995
--- xc/programs/Xserver/hw/hp/input/x_hilinit.c	Fri Jan 27 14:25:44 1995
***************
*** 1,7 ****
! /* $XConsortium: x_hilinit.c,v 8.202 94/05/28 15:50:24 dpw Exp $ */
  /*
  
! Copyright (c) 1988-1992  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
--- 1,7 ----
! /* $XConsortium: x_hilinit.c,v 8.205 95/01/27 19:02:07 gildea Exp $ */
  /*
  
! Copyright (c) 1988  X Consortium
  
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
***************
*** 28,61 ****
  from the X Consortium.
  
  
! Copyright (c) 1988-1992 by Hewlett-Packard Corporation, Palo Alto,
!               California
! 	      
  Permission to use, copy, modify, and distribute this software 
  and its documentation for any purpose and without fee is hereby 
  granted, 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 
! Hewlett-Packard not be used in advertising or 
! publicity pertaining to distribution of the software without specific, 
! written prior permission.
! 
! HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
! ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
! HP 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.
  
  */
! 
! #define SERIAL_DRIVER_WRITE(f, type, ptr) \
! 	{ int i; \
! 	for (i=0; i<num_serial_devices; i++) \
! 	    if (f==serialprocs[i].fd) { \
! 		if ((*(serialprocs[i].write)) (f, type, ptr)==WRITE_SUCCESS) \
! 		    return Success; } }
  
  #ifndef LIBDIR
  #if OSMAJORVERSION >= 10
--- 28,73 ----
  from the X Consortium.
  
  
! Copyright (c) 1988 by Hewlett-Packard Company
! 
  Permission to use, copy, modify, and distribute this software 
  and its documentation for any purpose and without fee is hereby 
  granted, 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 
! Hewlett-Packard not be used in advertising or publicity 
! pertaining to distribution of the software without specific, written 
! prior permission.
! 
! HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE.  Hewlett-Packard shall not be liable for errors
! contained herein or direct, indirect, special, incidental or
! consequential damages in connection with the furnishing,
! performance, or use of this material.
! 
! This software is not subject to any license of the American
! Telephone and Telegraph Company or of the Regents of the
! University of California.
  
  */
! #define	NEED_EVENTS
! #define NITEMS(array) (sizeof(array)/sizeof(array[0]))
! #define BEEPER_DEVICE   "/dev/rhil"
! #define UNINITIALIZED	1
! #define EXPLICIT	0x80
! #define XEXTENSION	3
! #define XPTR_USE 	(1 << XPOINTER)
! #define XKBD_USE 	(1 << XKEYBOARD)
! #define XOTH_USE 	(1 << XOTHER)
! #define XEXT_USE 	(1 << XEXTENSION)
! #define DIN_KBD_DRVR	"hp7lc2k.sl"
! #define DIN_KBD_INIT	"hp7lc2k_Init"
! #define DIN_KBD_PATH	"/dev/ps2kbd"
! #define DIN_MOUSE_DRVR	"hp7lc2m.sl"
! #define DIN_MOUSE_INIT	"hp7lc2m_Init"
! #define DIN_MOUSE_PATH	"/dev/ps2mouse"
  
  #ifndef LIBDIR
  #if OSMAJORVERSION >= 10
***************
*** 63,97 ****
  #else
  #define LIBDIR "/usr/lib/X11"
  #endif
  #endif
- #define DRVRLIBDIR LIBDIR/**/"/extensions/"
- 
- #define	 MAXNAMLEN	255
- #define  spare  	MAX_LOGICAL_DEVS - 2
- #define	 NEED_EVENTS
- #include <stdio.h>
- #include <errno.h>
- 
- #if defined(__hpux) || defined(__hp_osf)
- #define BEEPER_DEVICE   "/dev/rhil"
  
! #ifdef __hp_osf
! #include <hp/hilioctl.h>
! #include <sys/mman.h>
! #else
! #include <sys/hilioctl.h>
  #endif
  
! #include <fcntl.h>
  #include <dl.h>
! #include <sys/utsname.h>
  #include "ps2io.h"
- #endif /* __hpux */
  
  #include "X.h"
  #include "Xproto.h"
  #include "hildef.h"
  #include "XHPproto.h"				/* extension constants	*/
  #include "x_hilinit.h"
  #include "x_hil.h"
  #include "x_serialdrv.h"
--- 75,98 ----
  #else
  #define LIBDIR "/usr/lib/X11"
  #endif
+ #define DRVRLIBDIR "/usr/lib/X11/extensions"
  #endif
  
! #ifndef DRVRLIBDIR
! #define DRVRLIBDIR LIBDIR/**/"/extensions"
  #endif
  
! #include <stdio.h>
! #include <errno.h>
  #include <dl.h>
! #include <sys/fcntl.h>
  #include "ps2io.h"
  
  #include "X.h"
  #include "Xproto.h"
  #include "hildef.h"
  #include "XHPproto.h"				/* extension constants	*/
+ #include "XHPlib.h"				/* DEFAULT_DIRECTORY  	*/
  #include "x_hilinit.h"
  #include "x_hil.h"
  #include "x_serialdrv.h"
***************
*** 106,117 ****
  #define Absolute 1
  #endif /* XINPUT */
  
- #ifdef __apollo
- #include "screenint.h"
- #include "../apollo/apollo.h"
- #include "../apollo/smd.h"
- #endif /* __apollo */
- 
  /******************************************************************
   *
   * Externs and global variables that may be referenced by other files.
--- 107,112 ----
***************
*** 119,142 ****
   */
  
  char	*mflg="TRUE";
- int		num_serial_devices;
- SerialProcs 	serialprocs[MAX_DEVICES];
  HPInputDevice	*hpKeyboard;
  HPInputDevice	*hpPointer;
  HPInputDevice	*hptablet_extension;
  
- #ifdef __hp_osf
- HILQ *hil_qp;
- int hil_qd;
- #endif /* __hp_osf */
- 
- #ifdef __apollo
- extern long	*apECV;
- extern long	*apLastECV;
- static int	fdApollo = 0;
- status_$t       status;
- #endif /* __apollo */
- 
  #ifdef XINPUT
  extern	int	BadDevice;
  extern	int	BadMode;
--- 114,123 ----
***************
*** 146,190 ****
  extern	int	DeviceButtonPress;
  extern	int	DeviceButtonRelease;
  extern	int	DeviceMotionNotify; 
! XID	hp_device_ids[MAX_DEVICES];
  XID		x_device_ids[MAX_DEVICES];
  #endif  /* XINPUT */
  
- extern	int	*dpmotionBuf[];
- extern	int	*dheadmotionBuf[];
- extern  void 	SetBellAttributes();
- extern  void 	hpBell();
- extern  u_char	identity_map[];
  extern  u_char	mv_mods, ptr_mods, rs_mods, bw_mods;
  extern  u_char	pointer_amt_bits[];
  extern  char   	*display;		/* display number as a string */
  extern  int	queue_events_free;
  extern  struct	x11EventQueue *events_queue;
  extern 	InputInfo 	inputInfo;
- extern 	unsigned char lockcode;
  
  int 	axes_changed = FALSE;
  int 	keyboard_click;
  int	allocated_dev_names = FALSE;
  int	x_axis, y_axis;
  
  int  otherndx;
- int  beeper_fd = -1;
  int  max_input_fd;
- char ldigit = '\0';
  unsigned char	xhp_kbdid;
  unsigned tablet_xlimit;
  unsigned tablet_ylimit;
  unsigned tablet_xorg;
  unsigned tablet_yorg;
  
! HPInputDevice	l_devs[MAX_LOGICAL_DEVS];
  DeviceIntPtr	LookupDeviceIntRec ();
  DeviceIntPtr	tablet_extension_device;
  DeviceIntPtr	screen_change_dev;
  
  int     HPType;
- int     device_ndx;
  
  /******************************************************************
   *
--- 127,164 ----
  extern	int	DeviceButtonPress;
  extern	int	DeviceButtonRelease;
  extern	int	DeviceMotionNotify; 
! XID		hp_device_ids[MAX_DEVICES];
  XID		x_device_ids[MAX_DEVICES];
  #endif  /* XINPUT */
  
  extern  u_char	mv_mods, ptr_mods, rs_mods, bw_mods;
  extern  u_char	pointer_amt_bits[];
  extern  char   	*display;		/* display number as a string */
  extern  int	queue_events_free;
  extern  struct	x11EventQueue *events_queue;
  extern 	InputInfo 	inputInfo;
  
+ int	hpddxScreenPrivIndex;
+ u_char	identity_map[256];
  int 	axes_changed = FALSE;
  int 	keyboard_click;
  int	allocated_dev_names = FALSE;
  int	x_axis, y_axis;
  
  int  otherndx;
  int  max_input_fd;
  unsigned char	xhp_kbdid;
  unsigned tablet_xlimit;
  unsigned tablet_ylimit;
  unsigned tablet_xorg;
  unsigned tablet_yorg;
  
! HPInputDevice	l_devs[MAX_DEVICES];
  DeviceIntPtr	LookupDeviceIntRec ();
  DeviceIntPtr	tablet_extension_device;
  DeviceIntPtr	screen_change_dev;
  
  int     HPType;
  
  /******************************************************************
   *
***************
*** 192,274 ****
   *
   */
  
- static Bool din_mouse_present();
- static Bool din_kbd_present();
- static int init_hil_devs ();
- static int get_device_details();
- static int get_device_type();
- static void SetAutoRepeat ();
- static int device_files ();
  static DevicePtr hpAddInputDevice();
  static void RecordOpenRequest();
  static void SetInputDevice();
  static void mask_from_kcodes();
  
- static	int	loopnum;
- static	struct	utsname uts_name;
- static	char	hilpath[MAXNAMLEN+1];
- 
  void		ProcessOtherEvent();
  
  static	xHPEvent	events_array[MAX_EVENTS];	/* input event buffer*/
  static	struct		x11EventQueue ev_queue;
- static	int 		count [NUM_DEV_TYPES];
  
! #if defined(__hpux) || defined(__hp_osf)
! static	int prompt[] = {HILP, HILP1, HILP2, HILP3, HILP4, HILP5, HILP6, HILP7};
! static	int ack[] = {HILA, HILA1, HILA2, HILA3, HILA4, HILA5, HILA6, HILA7};
! #endif /* __hpux */
! 
! static char  *dev_names[MAX_LOGICAL_DEVS];
! 
! #if defined(__hp9000s300) || defined(__hp9000s700) || defined(__hp_osf)
! static char  *default_names[MAX_LOGICAL_DEVS] =
!     { 
!     "/dev/hil1",
!     "/dev/hil2",
!     "/dev/hil3",
!     "/dev/hil4",
!     "/dev/hil5",
!     "/dev/hil6",
!     "/dev/hil7",
!     "",
!     "/dev/null"};
! #else				/* building for s800 */
! char beeper_name[] = "/dev/hilkbd ";
! static char  *default_names[MAX_LOGICAL_DEVS] =
!     { 
!     "/dev/hil_0.1",
!     "/dev/hil_0.2",
!     "/dev/hil_0.3",
!     "/dev/hil_0.4",
!     "/dev/hil_0.5",
!     "/dev/hil_0.6",
!     "/dev/hil_0.7",
!     "/dev/hil_1.1",
!     "/dev/hil_1.2",
!     "/dev/hil_1.3",
!     "/dev/hil_1.4",
!     "/dev/hil_1.5",
!     "/dev/hil_1.6",
!     "/dev/hil_1.7",
!     "/dev/hil_2.1",
!     "/dev/hil_2.2",
!     "/dev/hil_2.3",
!     "/dev/hil_2.4",
!     "/dev/hil_2.5",
!     "/dev/hil_2.6",
!     "/dev/hil_2.7",
!     "/dev/hil_3.1",
!     "/dev/hil_3.2",
!     "/dev/hil_3.3",
!     "/dev/hil_3.4",
!     "/dev/hil_3.5",
!     "/dev/hil_3.6",
!     "/dev/hil_3.7",
!     "",
!     "/dev/null"};
! #endif	/* building on __hp9000s300 or for s700 */
  
  
  /****************************************************************************
   *
--- 166,202 ----
   *
   */
  
  static DevicePtr hpAddInputDevice();
  static void RecordOpenRequest();
  static void SetInputDevice();
  static void mask_from_kcodes();
  
  void		ProcessOtherEvent();
  
  static	xHPEvent	events_array[MAX_EVENTS];	/* input event buffer*/
  static	struct		x11EventQueue ev_queue;
  
! recalculate_x_name () {}
  
+ void 	hpBell(percent, dev, ctrl, foo)
+     int percent, foo;
+     DeviceIntPtr dev;
+     KeybdCtrl *ctrl;
+ {
+     HPKeyboardFeedbackControl	dc;
+     HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) dev);
+ 
+     dc.class = KbdFeedbackClass;
+     dc.bell_pitch = ctrl->bell_pitch;
+     dc.bell_duration = ctrl->bell_duration;
+ 
+     dc.bell_percent = percent;
+     if (!percent)
+       dc.click = ctrl->click;
+     else
+       dc.click = 0;
+     (*(d->s.write)) (d->d.file_ds, _XBell, &dc);
+ }
  
  /****************************************************************************
   *
***************
*** 281,333 ****
      DevicePtr pDevice;
      IntegerCtrl *ctrl;
      {
!     HPIntegerFeedbackControl	dctrl;
      HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
  
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dctrl.class = IntegerFeedbackClass;
! 	dctrl.resolution = ctrl->resolution;
! 	dctrl.max_value = ctrl->max_value;
! 	dctrl.integer_displayed = ctrl->integer_displayed;
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeFeedbackControl, &dctrl);
! 	}
      }
  
! static StringCtrlProcPtr hpChangeStringControl(pDevice, ctrl)
      DevicePtr pDevice;
      StringCtrl *ctrl;
      {
!     HPStringFeedbackControl	dctrl;
      HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
  
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dctrl.class = StringFeedbackClass;
! 	dctrl.max_symbols = ctrl->max_symbols;
! 	dctrl.num_symbols_supported = ctrl->num_symbols_supported;
! 	dctrl.num_symbols_displayed = ctrl->num_symbols_displayed;
! 	dctrl.symbols_supported = (int *) ctrl->symbols_supported;
! 	dctrl.symbols_displayed = (int *) ctrl->symbols_displayed;
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeFeedbackControl, &dctrl);
! 	}
      }
  
! static BellCtrlProcPtr hpChangeBellControl(pDevice, ctrl)
      DevicePtr pDevice;
      BellCtrl *ctrl;
      {
!     HPBellFeedbackControl	dctrl;
      HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
  
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dctrl.class = BellFeedbackClass;
! 	dctrl.percent = ctrl->percent;
! 	dctrl.pitch = ctrl->pitch;
! 	dctrl.duration = ctrl->duration;
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeFeedbackControl, &dctrl);
! 	}
      }
  
  /****************************************************************************
--- 209,252 ----
      DevicePtr pDevice;
      IntegerCtrl *ctrl;
      {
!     HPIntegerFeedbackControl	dc;
      HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
  
!     dc.class = IntegerFeedbackClass;
!     dc.resolution = ctrl->resolution;
!     dc.max_value = ctrl->max_value;
!     dc.integer_displayed = ctrl->integer_displayed;
!     (*(d->s.write)) (d->d.file_ds, _XChangeFeedbackControl, &dc);
      }
  
! static hpChangeStringControl(pDevice, ctrl)
      DevicePtr pDevice;
      StringCtrl *ctrl;
      {
!     HPStringFeedbackControl	dc;
      HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
  
!     dc.class = StringFeedbackClass;
!     dc.max_symbols = ctrl->max_symbols;
!     dc.num_symbols_supported = ctrl->num_symbols_supported;
!     dc.num_symbols_displayed = ctrl->num_symbols_displayed;
!     dc.symbols_supported = (int *) ctrl->symbols_supported;
!     dc.symbols_displayed = (int *) ctrl->symbols_displayed;
!     (*(d->s.write)) (d->d.file_ds, _XChangeFeedbackControl, &dc);
      }
  
! static hpChangeBellControl(pDevice, ctrl)
      DevicePtr pDevice;
      BellCtrl *ctrl;
      {
!     HPBellFeedbackControl	dc;
      HPInputDevice *d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
  
!     dc.class = BellFeedbackClass;
!     dc.percent = ctrl->percent;
!     dc.pitch = ctrl->pitch;
!     dc.duration = ctrl->duration;
!     (*(d->s.write)) (d->d.file_ds, _XChangeFeedbackControl, &dc);
      }
  
  /****************************************************************************
***************
*** 345,354 ****
      PtrCtrl *ctrl;
      {
      HPInputDevice *d;
!     HPPointerFeedbackControl	dctrl;
  #ifdef XINPUT
      PtrFeedbackPtr b;
  
      b = ((DeviceIntPtr) pDevice)->ptrfeed;
  
      b->ctrl = *ctrl;
--- 264,281 ----
      PtrCtrl *ctrl;
      {
      HPInputDevice *d;
!     HPPointerFeedbackControl	dc;
  #ifdef XINPUT
      PtrFeedbackPtr b;
  
+     /* Set the default initial acceleration to 1 if this isn't the X pointer */
+ 
+     if ((DeviceIntPtr) pDevice != inputInfo.pointer && !pDevice->on)
+ 	{
+ 	ctrl->num = 1;
+ 	ctrl->den = 1;
+ 	}
+ 
      b = ((DeviceIntPtr) pDevice)->ptrfeed;
  
      b->ctrl = *ctrl;
***************
*** 363,427 ****
  #endif /* XINPUT */
  
      d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
! #ifdef __apollo
!     {
!     smd_$pos_t pos;
!     extern smd_unit_event_data_t olddata;
! 
!     if ((DeviceIntPtr) pDevice == inputInfo.pointer)
! 	{
! 	pos.column = d->coords[0];
! 	pos.line = d->coords[1];
! 	olddata.pos = pos;
! 	smd_$set_unit_cursor_pos (1, pos, &status);
! 	}
!     }
! #endif /* __apollo */
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dctrl.class = PtrFeedbackClass;
! 	dctrl.num = ctrl->num;
! 	dctrl.den = ctrl->den;
! 	dctrl.threshold = ctrl->threshold;
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeFeedbackControl, &dctrl);
! 	}
!     }
! 
! /****************************************************************************
!  *
!  * Turn LEDs on or off.
!  *
!  */
! 
! static SetLeds (d, leds, mask)
!     HPInputDevice *d;
!     unsigned int leds, mask;
!     {
!     int			i, iob;
!     char 		ioctl_data[12];
! 
! #if defined(__hpux) || defined(__hp_osf)
! 
!     if (d->hil_header.iob & HILIOB_PAA)		/* general prompt */
! 	{
! 	if (leds & 1)
! 	    ioctl (d->file_ds, HILP, ioctl_data);
! 	else
! 	    ioctl (d->file_ds, HILA, ioctl_data);
! 	leds >>= 1;
! 	}
! 
!     if (iob = ((u_char) (d->hil_header.iob & HILIOB_NPA) >> 4))/* prompt 1-7 */
! 	for (i=1; i<=iob; i++)
! 	    {
! 	    if (leds & 1)
! 		ioctl (d->file_ds, prompt[i], ioctl_data);
! 	    else
! 		ioctl (d->file_ds, ack[i], ioctl_data);
!     	    leds >>= 1;
! 	    }
! #endif /* __hpux */
! 
      }
  
  /****************************************************************************
--- 290,300 ----
  #endif /* XINPUT */
  
      d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
!     dc.class = PtrFeedbackClass;
!     dc.num = ctrl->num;
!     dc.den = ctrl->den;
!     dc.threshold = ctrl->threshold;
!     (*(d->s.write)) (d->d.file_ds, _XChangeFeedbackControl, &dc);
      }
  
  /****************************************************************************
***************
*** 438,454 ****
      LedCtrl *ctrl;
      {
      HPInputDevice	*d;
!     HPLedFeedbackControl	dctrl;
  
      d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
!     SetLeds(d, ctrl->led_values, ctrl->led_mask);
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dctrl.class = LedFeedbackClass;
! 	dctrl.led_values = ctrl->led_values;
! 	dctrl.led_mask = ctrl->led_mask;
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeFeedbackControl, &dctrl);
! 	}
      }
  
  /****************************************************************************
--- 311,323 ----
      LedCtrl *ctrl;
      {
      HPInputDevice	*d;
!     HPLedFeedbackControl	dc;
  
      d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
!     dc.class = LedFeedbackClass;
!     dc.led_values = ctrl->led_values;
!     dc.led_mask = ctrl->led_mask;
!     (*(d->s.write)) (d->d.file_ds, _XChangeFeedbackControl, &dc);
      }
  
  /****************************************************************************
***************
*** 468,492 ****
      KeybdCtrl *ctrl;
      {
      HPInputDevice	*d;
!     HPKeyboardFeedbackControl	dctrl;
  
      if (inputInfo.keyboard &&
          ((DeviceIntPtr) pDevice)->id==inputInfo.keyboard->id)
          keyboard_click = (int)((double)(ctrl->click) * 15.0 / 100.0);
  
      d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
!     SetAutoRepeat(d, ctrl->autoRepeat);
!     SetBellAttributes(d, ctrl);
!     SetLeds(d, ctrl->leds, 0xffffffff);
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	copy_kbd_ctrl_params (&dctrl, ctrl);
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeFeedbackControl, &dctrl);
! 	}
      }
  
  copy_kbd_ctrl_params (dctrl, ctrl)
!     HPKeyboardFeedbackControl	*dctrl;
      KeybdCtrl *ctrl;
      {
      dctrl->class = KbdFeedbackClass;
--- 337,355 ----
      KeybdCtrl *ctrl;
      {
      HPInputDevice	*d;
!     HPKeyboardFeedbackControl	dc;
  
      if (inputInfo.keyboard &&
          ((DeviceIntPtr) pDevice)->id==inputInfo.keyboard->id)
          keyboard_click = (int)((double)(ctrl->click) * 15.0 / 100.0);
  
      d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice);
!     copy_kbd_ctrl_params (&dc, ctrl);
!     (*(d->s.write)) (d->d.file_ds, _XChangeFeedbackControl, &dc);
      }
  
  copy_kbd_ctrl_params (dctrl, ctrl)
!     HPKeyboardFeedbackControl   *dctrl;
      KeybdCtrl *ctrl;
      {
      dctrl->class = KbdFeedbackClass;
***************
*** 504,529 ****
   * hpGetDeviceMotionEvents.
   *
   */
- 
  static int hpGetDeviceMotionEvents (dev, coords, start, stop, pScreen)
      DeviceIntPtr  dev;
      CARD32 start, stop;
!     xTimecoord  *coords;
      ScreenPtr pScreen;
      {
!     HPInputDevice 	*pHPDev = (HPInputDevice *) dev->public.devicePrivate;
!     int			i;
!     int			evcount = 0;
!     int			size = pHPDev->hil_header.ax_num + 1;
      int 		*first, *last, 	*curr;
      int 		*buffp = (int *) coords;
!     int 		*pmBuf = dpmotionBuf[dev->id];
!     int 		*hmBuf = dheadmotionBuf[dev->id];
  
      if (pmBuf == hmBuf)
  	{
          if (*pmBuf == 0)			/* no events yet           */
  	    return 0;
  	else
  	    last = hmBuf + (99 * size);
  	}
--- 367,392 ----
   * hpGetDeviceMotionEvents.
   *
   */
  static int hpGetDeviceMotionEvents (dev, coords, start, stop, pScreen)
      DeviceIntPtr  dev;
      CARD32 start, stop;
!     xTimecoord *coords;
      ScreenPtr pScreen;
      {
!     HPInputDevice 	*pHP = (HPInputDevice *) dev->public.devicePrivate;
!     int			i, evcount = 0;
!     int			size = pHP->d.ax_num + 1;
      int 		*first, *last, 	*curr;
      int 		*buffp = (int *) coords;
!     int 		*pmBuf = pHP->dpmotionBuf;
!     int 		*hmBuf = pHP->dheadmotionBuf;
  
      if (pmBuf == hmBuf)
  	{
          if (*pmBuf == 0)			/* no events yet           */
+ 	    {
  	    return 0;
+ 	    }
  	else
  	    last = hmBuf + (99 * size);
  	}
***************
*** 577,605 ****
   *
   */
  
  static Bool hpDeviceProc(pDev, onoff)
      DevicePtr pDev;
      int onoff;
      {
-     char 		*x_basename ();
-     int			keyId;
-     unsigned int	mask;
      KeySymsRec		*key_syms, keysym_rec;
      CARD8		*the_modmap;
- #ifdef __apollo
- #define SHORT_STRLEN 4
-     char            kbdtypestr[SHORT_STRLEN];
-     short           kbdtypestrlen;
-     static char     kbdtype, kbdsubtype;
- #endif /* __apollo */
      DeviceIntPtr	dev = 		(DeviceIntPtr) pDev;
!     HPInputDevice 	*pHPDev = 	(HPInputDevice *) pDev->devicePrivate;
!     struct		hil_desc_record	*h = &pHPDev->hil_header;
!     int			i;
!     int			button_count =	h->v_button_count ?
! 			                h->v_button_count : 3;
!     int			mbufsiz =  (h->ax_num * sizeof(int) + sizeof(Time)) *
  				   MOTION_BUFFER_SIZE;
  #ifdef XINPUT
      char		*strchr();
  #endif /* XINPUT */
--- 440,475 ----
   *
   */
  
+ #define DIN_MINKEYCODE	16
+ unsigned char DIN_AUTOREPEATS[] = 
+ {0xff,0xff,0xff,0xf3,0xfb,0xff,0xff,0xff, 
+  0xfb,0xff,0xff,0xff,0xf9,0xff,0xff,0xff, 
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+ 
+ #define HIL_MINKEYCODE	8
+ #define HIL_MINKEYCODE2	10
+ unsigned char HIL_AUTOREPEATS[] = 
+ {0x00,0x82,0xff,0xff,0xff,0xff,0xff,0xff, 
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+ 
  static Bool hpDeviceProc(pDev, onoff)
      DevicePtr pDev;
      int onoff;
      {
      KeySymsRec		*key_syms, keysym_rec;
      CARD8		*the_modmap;
      DeviceIntPtr	dev = 		(DeviceIntPtr) pDev;
!     HPInputDevice 	*pHP = 	(HPInputDevice *) pDev->devicePrivate;
!     HPInputDeviceHeader	*pd = 	&pHP->d;
!     int			i, j;
!     int			mbufsiz =(pHP->d. ax_num * sizeof(int) + sizeof(Time)) *
  				   MOTION_BUFFER_SIZE;
+     unsigned char 	*ptrf;
+     HPStrF		*ptrs;
+     char		*x_basename();
  #ifdef XINPUT
      char		*strchr();
  #endif /* XINPUT */
***************
*** 608,809 ****
          {
  	case DEVICE_INIT: 
  	    pDev->on = FALSE;
! 	    pHPDev->pScreen = screenInfo.screens[0];
!     	    AssignTypeAndName (pDev, pHPDev->x_atom, x_basename(pHPDev->x_name));
  
! 	    if (h->num_keys)
  		{
! #if defined(__hpux) || defined(__hp_osf)
! 
! 		if (pHPDev->id_detail & HP_HIL && h->iob & HILIOB_NPA)
! 		    {
! 		    keyId = hil_to_kbd_id(h->id + 0x20);
! 		    pHPDev->id_detail |= PC101_KBD;
! 		    }
! 		else
! 		    keyId = hil_to_kbd_id(h->id);
! #endif
! #ifdef __apollo
! 		/*
! 		 * Detect keyboard type and do initialization accordingly.
! 		 * Note:
! 		 *   If the keyboard is "3x" but not one of the known types, its
! 		 *     probably an ISO keyboard.  The Swedish/Finish keymap is
! 		 *     a superset of ISO (according to Dan G) so I use that.
! 		 *   Otherwise, use North American as a default.
! 		 */
! 
! 		smd_$inq_kbd_type(SHORT_STRLEN, kbdtypestr, &kbdtypestrlen, &status);
! 		kbdtype    = (kbdtypestrlen > 0) ? kbdtypestr[0] : '2';
! 		kbdsubtype = (kbdtypestrlen > 1) ? kbdtypestr[1] : ' ';
! 
!  		keyId = 33;	/* assume North American (subtype ' ') */
! 		if (kbdtype == '3')
! 		    switch (kbdsubtype)
! 			{
! 			case ' ': keyId = 33; break;	/* North American */
! 			case 'a': keyId = 34; break;	/* German */
! 			case 'b': keyId = 35; break;	/* French */
! 			case 'c': keyId = 36; break;	/* Norwegian/Danish */
! 			case 'd': keyId = 37; break;	/* Swedish/Finish */
! 			case 'e': keyId = 38; break;	/* UK */
! 			case 'g': keyId = 39; break;	/* Swiss */
! 			case 'f': keyId = 40; break;	/* Japanese */
! 			default:  keyId = 37;		/* unknown - ISO ? */
! 			}
! #endif /* __apollo */
! 
! 		if (pHPDev->hpflags & IS_SERIAL_DEVICE)
! 		    {
! 		    i = pHPDev->sndx;
! 		    if (!HPKget_kb_info_by_name(serialprocs[i].keymap_file, 
! 			serialprocs[i].keymap_name, &keysym_rec, &the_modmap))
! 			FatalError ("Can't find a keymap in the %s/XHPKeymaps file for device %s.\n", LIBDIR, pHPDev->x_name);
! 		    h->keymap_name = serialprocs[i].keymap_name;
! 		    }
! 		else
! 		    HPKget_maps_by_id(keyId, &keysym_rec, &the_modmap);
  		key_syms = &keysym_rec;
- 		h->min_kcode = key_syms->minKeyCode;
- 		h->max_kcode = key_syms->maxKeyCode;
- 		h->num_keys = key_syms->maxKeyCode - key_syms->minKeyCode + 1;
- 		pHPDev->x_type = KEYBOARD;
  		if (dev->id == inputInfo.keyboard->id)
  		    {
! 		    InitKeyboardDeviceStruct(pDev, key_syms, the_modmap, hpBell,
  			(KbdCtrlProcPtr) hpChangeKeyboardControl);
  		    get_pointerkeys();
  		    fix_modifierkeys();
  		    }
  #ifdef XINPUT
  		else
  		    {
  		    InitKeyClassDeviceStruct (dev, key_syms, the_modmap);
! 		    InitKbdFeedbackClassDeviceStruct (dev, hpBell,
  			(KbdCtrlProcPtr) hpChangeKeyboardControl);
  		    InitFocusClassDeviceStruct (dev);
  		    }
! 		}
! 
! 	    if (h->num_leds && dev->id != inputInfo.pointer->id && 
! 		dev->id != inputInfo.keyboard->id)
! 		{
! 		LedFeedbackPtr led;
! 		InitLedFeedbackClassDeviceStruct(dev,(LedCtrlProcPtr) hpChangeLedControl);
! 		mask=0;
! 		for (i=0; i<h->num_leds; i++)
! 		    mask |= (1 << i);
! 		for (led=dev->leds; led; led = led->next)
! 		    led->ctrl.led_mask = mask;
! 		}
! 
! 	    if (pHPDev->hpflags & IS_SERIAL_DEVICE)
! 		{ 
! 		int j;
! 		unsigned char *ptrf;
! 		HPStrF	*ptrs;
! 
! 		i = pHPDev->sndx;
! 		for (j=0, ptrf=serialprocs[i].feedbacks; 
! 		    j<serialprocs[i].num_fdbk; j++,ptrf++)
! 		    if (*ptrf == IntegerFeedbackClass)
! 			InitIntegerFeedbackClassDeviceStruct (
! 			    dev, (IntegerCtrlProcPtr) hpChangeIntegerControl);
! 		    else if (*ptrf == BellFeedbackClass)
! 			InitBellFeedbackClassDeviceStruct (
! 			    dev, hpBell, (BellCtrlProcPtr) hpChangeBellControl);
! 		    else if (*ptrf == KbdFeedbackClass)
! 			InitKbdFeedbackClassDeviceStruct( dev, hpBell, 
! 			    (KbdCtrlProcPtr) hpChangeKeyboardControl);
! 		    else if (*ptrf == PtrFeedbackClass)
! 			InitPtrFeedbackClassDeviceStruct(
! 			    dev, (PtrCtrlProcPtr) hpChangePointerControl);
! 		for (j=0, ptrf=serialprocs[i].ledf; 
! 		     j<serialprocs[i].num_ledf; j++,ptrf++)
! 		    InitLedFeedbackClassDeviceStruct ( dev, (LedCtrlProcPtr) hpChangeLedControl);
! 		for (j=0, ptrs=serialprocs[i].strf; 
! 		     j<serialprocs[i].num_strf; j++, ptrs++)
! 		    InitStringFeedbackClassDeviceStruct ( dev, 
! 			(StringCtrlProcPtr) hpChangeStringControl, 
! 			ptrs->max_symbols,
! 			ptrs->num_symbols_supported,
! 			(KeySym *) ptrs->symbols_supported);
! 		}
! 
  #endif /* XINPUT */
  
! 	    if (h->ax_num)
  		{
  		if (dev->id == inputInfo.pointer->id)
  		    {
! 		    if (pHPDev->dev_type == NULL_DEVICE)
  			{
! 	        	pHPDev->coords[0] = pHPDev->pScreen->width;
! 	        	pHPDev->coords[1] = pHPDev->pScreen->height;
  			}
  		    else
  			{
! 	        	pHPDev->coords[0] = pHPDev->pScreen->width / 2;
! 	        	pHPDev->coords[1] = pHPDev->pScreen->height / 2;
  			}
! #ifdef __apollo
! 		    smd_$pos_t pos;
! 		    extern smd_unit_event_data_t olddata;
! 		
! 		    pos.column = pHPDev->coords[0];
! 		    pos.line = pHPDev->coords[1];
! 		    olddata.pos = pos;
! 		    smd_$set_unit_cursor_pos (1, pos, &status);
! #endif /* __apollo */
! 		    InitPointerDeviceStruct (pDev, ptr_button_map, button_count,
! 			hpGetDeviceMotionEvents, (PtrCtrlProcPtr) hpChangePointerControl, 
  			    MOTION_BUFFER_SIZE);
  		    }
  #ifdef XINPUT
  		else
  		    {
  		    InitFocusClassDeviceStruct (dev);
! #if defined(__hpux) || defined(__hp_osf)
! 		    if (h->iob & HILIOB_PIO)
  			InitProximityClassDeviceStruct (dev);
! #endif /* __hpux */
! 		    InitValuatorClassDeviceStruct (dev, h->ax_num, 
  			hpGetDeviceMotionEvents, 100, 
! 			(h->flags & HIL_ABSOLUTE)?1:0);
  		    InitPtrFeedbackClassDeviceStruct (dev, 
  			(PtrCtrlProcPtr) hpChangePointerControl);
  		    }
! 		InitValuatorAxisStruct (dev, 0, 0, (unsigned int) h->size_x, 
! 		    (unsigned int) h->resx, 0, (unsigned int) h->resx);
! 		if (h->ax_num > 1)
! 		    InitValuatorAxisStruct (dev, 1, 0, (unsigned int) h->size_y,
! 		    (unsigned int) h->resy, 0, (unsigned int) h->resy);
  		if (dev->id != inputInfo.pointer->id)
! 		    for (i=2; i < (u_char) h->ax_num; i++)
! 			InitValuatorAxisStruct (dev, i, 0, (unsigned int) h->size_x,
! 			(unsigned int) h->resx, 0, (unsigned int) h->resx);
! 
! 		dpmotionBuf[dev->id] = (int *) Xalloc (mbufsiz);
! 		memset (dpmotionBuf[dev->id], 0, mbufsiz);
! 		dheadmotionBuf[dev->id] = dpmotionBuf[dev->id];
  		}
  
! 	    if (h->p_button_count && dev->id != inputInfo.pointer->id)
!     		InitButtonClassDeviceStruct (dev, button_count, identity_map);
  #endif /* XINPUT */
   	    break;
  	case DEVICE_ON: 
  	    pDev->on = TRUE;
! 	    if ( pHPDev != NULL) 
  		{
! #ifndef __hp_osf
!         	if (pHPDev->dev_type != NULL_DEVICE)
! 		    AddEnabledDevice( pHPDev->file_ds );
! #endif /* __hp_osf */
! 		if (h->ax_num)
! 		    set_scale_and_screen_change (pHPDev);
  	        }
- 	    SetAutoRepeat(pHPDev, TRUE);
  	    break;
  	case DEVICE_OFF:
  	    pDev->on = FALSE;
--- 478,609 ----
          {
  	case DEVICE_INIT: 
  	    pDev->on = FALSE;
! 	    pHP->pScreen = screenInfo.screens[0];
!     	    AssignTypeAndName (pDev, pHP->x_atom, x_basename(pd->x_name));
  
! 	    if (pd->num_keys > 0)
  		{
! 		if (!HPKget_kb_info_by_name(pd->keymap_file, 
! 		    pd->keymap_name, &keysym_rec, &the_modmap))
! 		    FatalError ("Can't find a keymap in the %s/XHPKeymaps file for device %s.\n", 
! 			LIBDIR, pd->x_name);
  		key_syms = &keysym_rec;
  		if (dev->id == inputInfo.keyboard->id)
  		    {
! 		    KeyCode tmp;
!     		    extern KeyCode xtest_command_key; /* see xtestext1dd.c */
! 
! 		    InitKeyboardDeviceStruct(pDev, key_syms, the_modmap, 
! 			(BellProcPtr) hpBell, 
  			(KbdCtrlProcPtr) hpChangeKeyboardControl);
  		    get_pointerkeys();
  		    fix_modifierkeys();
+ 		    if ((tmp=HPKeySymToKeyCode (dev, XK_F9)))
+     		        xtest_command_key = tmp;
+ 		
  		    }
  #ifdef XINPUT
  		else
  		    {
  		    InitKeyClassDeviceStruct (dev, key_syms, the_modmap);
! 		    InitKbdFeedbackClassDeviceStruct (dev, 
! 		    (BellProcPtr) hpBell,
  			(KbdCtrlProcPtr) hpChangeKeyboardControl);
  		    InitFocusClassDeviceStruct (dev);
  		    }
! 		if (dev->key->curKeySyms.minKeyCode==DIN_MINKEYCODE)
! 		    memmove(dev->kbdfeed->ctrl.autoRepeats, DIN_AUTOREPEATS, 32);
! 		else if (dev->key->curKeySyms.minKeyCode==HIL_MINKEYCODE ||
! 		         dev->key->curKeySyms.minKeyCode==HIL_MINKEYCODE2)
! 		    memmove(dev->kbdfeed->ctrl.autoRepeats, HIL_AUTOREPEATS, 32);
! 		}
! 
! 	    for (j=0, ptrf=pd->feedbacks; j<pd->num_fdbk; j++,ptrf++)
! 		if (*ptrf == IntegerFeedbackClass)
! 		    InitIntegerFeedbackClassDeviceStruct ( dev, 
! 			(IntegerCtrlProcPtr) hpChangeIntegerControl);
! 		else if (*ptrf == BellFeedbackClass)
! 		    InitBellFeedbackClassDeviceStruct ( dev, 
! 		        (BellProcPtr) hpBell, 
! 			(BellCtrlProcPtr) hpChangeBellControl);
! 		else if (*ptrf == KbdFeedbackClass)
! 		    InitKbdFeedbackClassDeviceStruct( dev, 
! 			(BellProcPtr) hpBell, 
! 			(KbdCtrlProcPtr) hpChangeKeyboardControl);
! 		else if (*ptrf == PtrFeedbackClass)
! 		    InitPtrFeedbackClassDeviceStruct( dev, 
! 			(PtrCtrlProcPtr) hpChangePointerControl);
! 	    for (j=0, ptrf=pd->ledf; j<pd->num_ledf; j++,ptrf++)
! 		InitLedFeedbackClassDeviceStruct ( dev, 
! 		(LedCtrlProcPtr) hpChangeLedControl);
! 	    for (j=0, ptrs=pd->strf; j<pd->num_strf; j++, ptrs++)
! 		InitStringFeedbackClassDeviceStruct ( dev, 
! 		    (StringCtrlProcPtr) hpChangeStringControl, 
! 		    ptrs->max_symbols,
! 		    ptrs->num_symbols_supported, 
! 		    (KeySym *) ptrs->symbols_supported);
  #endif /* XINPUT */
  
! 	    if (pd->ax_num)
  		{
  		if (dev->id == inputInfo.pointer->id)
  		    {
! 		    if (pHP->dev_type == NULL_DEVICE)
  			{
! 	        	pHP->coords[0] = pHP->pScreen->width;
! 	        	pHP->coords[1] = pHP->pScreen->height;
  			}
  		    else
  			{
! 	        	pHP->coords[0] = pHP->pScreen->width / 2;
! 	        	pHP->coords[1] = pHP->pScreen->height / 2;
  			}
! 		    InitPointerDeviceStruct (pDev, ptr_button_map, 
! 			(pd->num_buttons ? pd->num_buttons : 3),
! 			hpGetDeviceMotionEvents, 
! 			(PtrCtrlProcPtr) hpChangePointerControl, 
  			    MOTION_BUFFER_SIZE);
  		    }
  #ifdef XINPUT
  		else
  		    {
  		    InitFocusClassDeviceStruct (dev);
! 		    if (pHP->iob & HILIOB_PIO)
  			InitProximityClassDeviceStruct (dev);
! 		    InitValuatorClassDeviceStruct (dev, pd->ax_num, 
  			hpGetDeviceMotionEvents, 100, 
! 			(pHP->hpflags & ABSOLUTE_DATA)?1:0);
  		    InitPtrFeedbackClassDeviceStruct (dev, 
  			(PtrCtrlProcPtr) hpChangePointerControl);
  		    }
! 		InitValuatorAxisStruct (dev, 0, 0, (u_int) pd->max_x, 
! 		    (u_int) pd->resolution, 0, (u_int) pd->resolution);
! 		if (pd->ax_num > 1)
! 		    InitValuatorAxisStruct (dev, 1, 0, (u_int) pd->max_y,
! 		    (u_int) pd->resolution, 0, (u_int) pd->resolution);
  		if (dev->id != inputInfo.pointer->id)
! 		    for (i=2; i < (u_char) pd->ax_num; i++)
! 			InitValuatorAxisStruct (dev, i, 0, (u_int) pd->max_x,
! 			(u_int) pd->resolution, 0, (u_int) pd->resolution);
! 
! 		pHP->dpmotionBuf = (int *) Xalloc (mbufsiz);
! 		memset (pHP->dpmotionBuf, 0, mbufsiz);
! 		pHP->dheadmotionBuf = pHP->dpmotionBuf;
  		}
  
! 	    if (pd->num_buttons && dev->id != inputInfo.pointer->id)
!     		InitButtonClassDeviceStruct(dev, pd->num_buttons, identity_map);
  #endif /* XINPUT */
   	    break;
  	case DEVICE_ON: 
  	    pDev->on = TRUE;
! 	    if (pHP != NULL) 
  		{
!         	if (pHP->dev_type != NULL_DEVICE)
! 		    AddEnabledDevice (pd->file_ds);
! 		if (pd->ax_num)
! 		    set_scale_and_screen_change (dev, pHP, pHP->pScreen);
  	        }
  	    break;
  	case DEVICE_OFF:
  	    pDev->on = FALSE;
***************
*** 811,820 ****
  		memset(dev->button->down, 0, DOWN_LENGTH);
  		dev->button->state = 0;
  		dev->button->buttonsDown = 0;
! 		pHPDev->button_state = 0;
! 		pHPDev->ignoremask = 0;
! 		pHPDev->sent_button = 0;
! 		pHPDev->savebutton = 0;
  	    }
  	    if (dev->key) {
  		memset(dev->key->down, 0, DOWN_LENGTH);
--- 611,617 ----
  		memset(dev->button->down, 0, DOWN_LENGTH);
  		dev->button->state = 0;
  		dev->button->buttonsDown = 0;
! 		pHP->button_state = 0;
  	    }
  	    if (dev->key) {
  		memset(dev->key->down, 0, DOWN_LENGTH);
***************
*** 822,855 ****
  		dev->key->prev_state = 0;
  	    }
  	    if (dev->id != inputInfo.pointer->id &&
! 		pHPDev->file_ds == hpPointer->file_ds)
  		break;
! 	    if (pHPDev != NULL && pHPDev->file_ds >= 0)
  		{
! #ifndef __hp_osf
! 		RemoveEnabledDevice(pHPDev->file_ds);
! #endif /* __hp_osf */
!     	        close_device (pHPDev);
  		}
  	    break;
  	case DEVICE_CLOSE: 
! 	    if ( pHPDev != NULL && pHPDev->file_ds >= 0)
  		{
! #ifndef __hp_osf
! 		RemoveEnabledDevice( pHPDev->file_ds);
! #endif /* __hp_osf */
!     	        close_device (pHPDev);
  		}
  #ifdef XINPUT
! 	    if (dheadmotionBuf[dev->id])
  		{
! 		Xfree (dheadmotionBuf[dev->id]);
! 		dheadmotionBuf[dev->id] = NULL;
! 		dpmotionBuf[dev->id] = NULL;
  		}
  #endif /* XINPUT */
- 	    if (dev->id == inputInfo.pointer->id)
- 		close (beeper_fd);
  	    break;
  	}
      return(Success);
--- 619,646 ----
  		dev->key->prev_state = 0;
  	    }
  	    if (dev->id != inputInfo.pointer->id &&
! 		pd->file_ds == hpPointer->d.file_ds)
  		break;
! 	    if (pHP != NULL && pd->file_ds>= 0)
  		{
! 		RemoveEnabledDevice(pd->file_ds);
!     	        close_device (pHP);
  		}
  	    break;
  	case DEVICE_CLOSE: 
! 	    if ( pHP != NULL && pd->file_ds >= 0)
  		{
! 		RemoveEnabledDevice (pd->file_ds);
!     	        close_device (pHP);
  		}
  #ifdef XINPUT
! 	    if (pHP->dheadmotionBuf)
  		{
! 		Xfree (pHP->dheadmotionBuf);
! 		pHP->dheadmotionBuf = NULL;
! 		pHP->dpmotionBuf = NULL;
  		}
  #endif /* XINPUT */
  	    break;
  	}
      return(Success);
***************
*** 862,871 ****
   *
   */
  
! struct	opendevs serial[MAX_DEVICES];
!  
! void
! InitInput(argc, argv)
      int     	  argc;
      char    	  **argv;
      {
--- 653,659 ----
   *
   */
  
! void InitInput(argc, argv)
      int     	  argc;
      char    	  **argv;
      {
***************
*** 874,879 ****
--- 662,668 ----
      int CheckInput();
  
      mflg = (char *)getenv("XHPPRINTDEBUGMSG");
+     max_input_fd = 0;
      x_axis = 0;
      y_axis = 1;
      axes_changed = FALSE;
***************
*** 882,950 ****
      hptablet_extension = NULL;
      tablet_width = 0;
      otherndx = 2;
-     device_ndx = MAX_POSITIONS - 1;
      for (i=0; i<256; i++)
  	identity_map[i]=i;
-     for (i=0; i<NUM_DEV_TYPES; i++)
- 	count[i] = 0;
-     if (din_mouse_present())
- 	count[MOUSE]++;
-     if (din_kbd_present())
- 	count[KEYBOARD]++;
-     serial[XPOINTER].name[0]='\0';
-     serial[XKEYBOARD].name[0]='\0';
-     lockcode = 0;
-     uname(&uts_name);
- 
- #ifdef __hp_osf
-     if (!hil_qp)
-     {
-     if ((beeper_fd = open(BEEPER_DEVICE,O_RDWR)) < 0)
-  	ErrorF ("Unable to open beeper device \"%s\".\n",BEEPER_DEVICE);
- #ifdef SPECIAL_68K_OSF
-     if ((ioctl (beeper_fd, HILALLOCQ, &hil_qd)) < 0)
- 	FatalError ("Error allocating HIL event queue.\n");
- 
-     if ((int) (hil_qp = (HILQ *) mmap (0, sizeof(HILQ), PROT_READ|PROT_WRITE,
- 	MAP_FILE|MAP_SHARED, beeper_fd, hil_qd*sizeof(HILQ))) <0)
- 	FatalError("Unable to map /dev/rhil\n");
- #else
-     if ((ioctl (beeper_fd, HILALLOCQ, &hil_qp)) < 0)
- 	FatalError ("Error allocating HIL event queue.\n");
- #endif /* SPECIAL_68K_OSF */
-     SetInputCheck(&hil_qp->hil_evqueue.head, &hil_qp->hil_evqueue.tail);
-     }
- 
-     /* discard all the current input events  */
-     hil_qp->hil_evqueue.head = hil_qp->hil_evqueue.tail;
- 
-     AddEnabledDevice (beeper_fd);
- #endif /* __hp_osf */
  
      RegisterBlockAndWakeupHandlers ((BlockHandlerProcPtr) NoopDDA, 
! 				    (WakeupHandlerProcPtr) CheckInput, 
! 				    (pointer) NULL);
!     loopnum = atoi(display);
!     hilpath[0] = '\0';
!     ldigit = '\0';
      get_pointerkeys();
!     init_l_devs ();
!     init_events_queue ( &ev_queue);
! #if defined(__hpux)
!     init_beeper();			/* beeper_fd = /dev/rhil */
! #endif /* __hpux */
  
      /*
       * Now initialize the devices as far as X is concerned.
       */
  
      for (i=0, j=0; i<MAX_DEVICES && j < MAX_LOGICAL_DEVS; j++) 
  	{
! 	if (l_devs[j].hil_header.id == 1 ||		/* inaccessible device*/
  	    (l_devs[j].dev_type == NULL_DEVICE && 
  	     !(l_devs[j].hpflags & OPEN_THIS_DEVICE)))
  		continue;
! 	if (l_devs[j].file_ds != -1)
  	    (void) x_init_device (&l_devs[j], TRUE);
  	else
  	    (void) x_init_device (&l_devs[j], FALSE);
--- 671,704 ----
      hptablet_extension = NULL;
      tablet_width = 0;
      otherndx = 2;
      for (i=0; i<256; i++)
  	identity_map[i]=i;
  
      RegisterBlockAndWakeupHandlers ((BlockHandlerProcPtr) NoopDDA, 
! 	(WakeupHandlerProcPtr) CheckInput, (pointer) NULL);
      get_pointerkeys();
!     for (i=0; i<MAX_LOGICAL_DEVS; i++)
!         clear_device_private(&l_devs[i]);
!     init_dynamic_devs (l_devs); 		/* load input drivers. */
  
+     if (hpPointer->x_type == KEYBOARD)
+ 	{
+ 	hpPointer->d.num_buttons = 8;
+ 	hpPointer->d.ax_num = 2;
+ 	}
+ 
+     init_events_queue ( &ev_queue);
      /*
       * Now initialize the devices as far as X is concerned.
       */
  
      for (i=0, j=0; i<MAX_DEVICES && j < MAX_LOGICAL_DEVS; j++) 
  	{
! 	if (l_devs[j].id == 1 ||		/* inaccessible device*/
  	    (l_devs[j].dev_type == NULL_DEVICE && 
  	     !(l_devs[j].hpflags & OPEN_THIS_DEVICE)))
  		continue;
! 	if (l_devs[j].d.file_ds != -1)
  	    (void) x_init_device (&l_devs[j], TRUE);
  	else
  	    (void) x_init_device (&l_devs[j], FALSE);
***************
*** 952,957 ****
--- 706,765 ----
  	}
      }
  
+ HPInputDevice *next_device_private()
+   {
+   int i;
+   HPInputDevice *d = l_devs;
+ 
+   for (i=0; i<MAX_DEVICES; i++, d++)
+     if (d->id == 1)
+ 	return d;
+ 
+   for (i=0,--d; i<MAX_DEVICES; i++, d--)
+     if (d->d.file_ds <= 1 && d->driver_name[0] == '\0')
+ 	return d;
+ 
+   return NULL;
+   }
+ 
+ /***********************************************************
+  *
+  * Set up the tablet for subsetting.
+  *
+  */
+ fix_tablet_subsetting()
+     {
+     int i;
+     HPInputDevice *d;
+ 
+     if (hpPointer->d.x_name != NULL && !strstr (hpPointer->d.x_name, "TABLET"))
+ 	{
+ 	for (i=MAX_LOGICAL_DEVS-1; i>=0; i--)
+ 	    if (l_devs[i].d.x_name != NULL &&
+ 	        strstr(l_devs[i].d.x_name, "TABLET"))
+ 		break;
+ 	if (i>=0)
+     	    {
+ 	    if (hpPointer->hpflags & SECOND_LOGICAL_DEVICE)
+ 		{
+ 		hpPointer->hpflags &= ~SECOND_LOGICAL_DEVICE;
+ 		hpPointer->d.file_ds = -1;
+ 		}
+ 	    else
+ 		close_device(hpPointer);
+ 	    hpPointer = &l_devs[i];
+ 	    open_device(hpPointer);
+ 	    }
+ 	else
+ 	    return;
+ 	}
+     if (d = next_device_private())
+       {
+       *d = *hpPointer; /* will also be an extension device */
+       d->hpflags |= SECOND_LOGICAL_DEVICE;
+       }
+     }
+ 
  /***********************************************************
   *
   * Perform X initialization for the device.
***************
*** 970,998 ****
  	{
  	RegisterKeyboardDevice(pXDev);
          if (dev->dev_type == KEYBOARD)
! 	    xhp_kbdid = dev->hil_header.id - 0xA0;
  	}
!     else if (dev==hpPointer)
  	{
  	RegisterPointerDevice(pXDev);
- #ifdef SPECIAL_68K_OSF
- 	miRegisterPointerDevice(screenInfo.screens[0], pXDev);
- #endif
  	if (dev->x_type == KEYBOARD)
! 	    InitKbdFeedbackClassDeviceStruct ((DeviceIntPtr) pXDev, hpBell,
  		(KbdCtrlProcPtr) hpChangeKeyboardControl);
  	screen_change_dev = (DeviceIntPtr) pXDev;
  	if (screen_change_amt == SCREEN_CHANGE_DEFAULT)
! 	    if (dev->hil_header.flags & HIL_ABSOLUTE)
  		screen_change_amt = 0;
  	    else
  		screen_change_amt = 30;
  	}
  #ifdef XINPUT
!     else
      	{
  	RegisterOtherDevice(pXDev);
! 	if (tablet_width && dev->file_ds==hpPointer->file_ds)
  	    {
  	    tablet_extension_device = (DeviceIntPtr) pXDev;
  	    hptablet_extension = dev;
--- 778,804 ----
  	{
  	RegisterKeyboardDevice(pXDev);
          if (dev->dev_type == KEYBOARD)
! 	    xhp_kbdid = dev->id - 0xA0;
  	}
!     if (dev==hpPointer)
  	{
  	RegisterPointerDevice(pXDev);
  	if (dev->x_type == KEYBOARD)
! 	    InitKbdFeedbackClassDeviceStruct ((DeviceIntPtr) pXDev, 
! 		(BellProcPtr) hpBell,
  		(KbdCtrlProcPtr) hpChangeKeyboardControl);
  	screen_change_dev = (DeviceIntPtr) pXDev;
  	if (screen_change_amt == SCREEN_CHANGE_DEFAULT)
! 	    if (dev->hpflags & ABSOLUTE_DATA)
  		screen_change_amt = 0;
  	    else
  		screen_change_amt = 30;
  	}
  #ifdef XINPUT
!     if (dev != hpPointer && dev != hpKeyboard)
      	{
  	RegisterOtherDevice(pXDev);
! 	if (tablet_width && dev->d.file_ds==hpPointer->d.file_ds)
  	    {
  	    tablet_extension_device = (DeviceIntPtr) pXDev;
  	    hptablet_extension = dev;
***************
*** 1004,1908 ****
      return ((DeviceIntPtr) pXDev);
      }
  
- /*****************************************************************
-  *
-  * Initialize the l_devs array of structures.
-  * There is one per logical input device.
-  *
-  */
-  
- init_l_devs()
-     {
-     int		i;
-     int		dev_num = 2;
-     int		sdev_num = 2;
-     FILE	*fp;
-     char	fname[MAXNAMLEN];
-     struct	opendevs opendevs [MAX_LOGICAL_DEVS];
- 
-     for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 	{
- 	opendevs[i].type = -1;
- 	opendevs[i].pos = -1;
- 	opendevs[i].name[0] = '\0';
- 	opendevs[i].path[0] = '\0';
- 	}
- 
-     for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 	{
- 	memset(&l_devs[i], 0, sizeof(HPInputDevice));
-         l_devs[i].hil_header.id = 1;
-         l_devs[i].hil_header.keymap_name = "";
-         l_devs[i].mode = ABSOLUTE;
- 	l_devs[i].file_ds = -1;
- 	l_devs[i].id_detail = HP_HIL;
- #if defined(__hpux) || defined(__hp_osf)
-         l_devs[i].repeat_rate = HILER1;
- #endif /* __hpux */
- 	}
- 
-     sprintf(fname, "%s/X%sdevices",LIBDIR,display);
-     fp = fopen ( fname, "r");
-     if (fp) 
- 	{
-         dev_num = device_files (fp, opendevs, &sdev_num);
- 	fclose (fp);
- 	}
-     compute_device_names (opendevs, dev_num);
- 
- #if defined(__hpux) || defined(__hp_osf)
-     init_hil_devs (opendevs, dev_num);
- #endif /* __hpux */
- #ifdef __apollo
-     init_apollo_devs (opendevs, dev_num);
- #endif /* __apollo */
- 
-     /*
-      * Check for any dynamically loaded input device drivers.
-      */
- 
-     init_dynamic_devs (opendevs, sdev_num);
- 
-     if (hpPointer->x_type == KEYBOARD)
- 	{
- 	hpPointer->hil_header.v_button_count = 8;
- 	hpPointer->hil_header.p_button_count = 8;
- 	hpPointer->hil_header.ax_num = 2;
- 	}
-     }
- 
- /********************************************************************
-  *
-  * Compute the names of the input devices we should use.
-  * If a path for the input devices has been specified, use it.
-  * Otherwise use /dev/hil.
-  * If we have multiple HIL loops (series 800), and the display number
-  * is between 0 and 3, use the corresponding loop.  Otherwise, search
-  * all loops.
-  *
-  */
- 
- compute_device_names (opendevs, dev_num)
-     struct	opendevs opendevs [];
-     int		dev_num;
-     {
-     int		ndx = MAX_POSITIONS - 1;
-     int		i;
-     int 	hlen = strlen(hilpath);
- 
- #if defined(__hp9000s800) && !defined(__hp9000s700)
- 
-     if (hlen > 0 && isdigit (hilpath[hlen-1]))	/* hilpath ends in digit */
- 	{
- 	ldigit = hilpath[hlen-1];
- 	hilpath[hlen-1] = '\0';
- 	}
-     else if (loopnum >= 0 && loopnum < 4)	/* X invoked with display # */
- 	ldigit = display[0];
- #endif /* __hp9000s800 */
- 
-     if (hlen > 0)
- 	allocated_dev_names = TRUE;
-     else
- 	allocated_dev_names = FALSE;
- 
-     for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 	{
- 	if (hlen > 0 && i<MAX_POSITIONS)
- 	    {
- 	    if (allocated_dev_names == TRUE)
- 		Xfree (dev_names[i]);
- 	    dev_names[i] = (char *) Xalloc (strlen (hilpath) + 4);
- 	    if (ldigit == '\0' || i < 7)				
- 		{
- 		strcpy (dev_names[i], hilpath);
- 		strcat (dev_names[i], suffix[i]);
- 		}
- 	    }
- 	else
- 	    dev_names[i] = default_names[i];
- 	}
- 
- #if defined(__hp9000s800) && !defined(__hp9000s700)
-     if (ldigit != '\0')
-         for (i=0; i<MAX_POSITIONS; i++)
- 	    {
- 	    if (i < 7)				
- 		{
- 		suffix [i][0] = ldigit;
- 		dev_names[i][9] = ldigit;
- 		}
- 	    else
- 		{
- 		dev_names[i][0] = '\0';
- 		suffix [i][0] = '\0';
- 		}
- 	    }
- #endif /* __hp9000s800 */
- 
-     while (--dev_num >= 0)
- 	{
- 	if (opendevs[dev_num].path[0] == '\0')
- 	    continue;
- 	for (i=0; i<MAX_POSITIONS; i++)
- 	    if (strcmp (opendevs[dev_num].path, dev_names[i]) == 0)
- 		break;
- 	if (i==MAX_POSITIONS)
- 	    strcpy (dev_names[ndx--], opendevs[dev_num].path);
- 	   
- 	}
-     for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 	strcpy (l_devs[i].dev_name,dev_names[i]);
-     }
- 
- /********************************************************************
-  *
-  * Find the requested key and pointer devices.
-  * If no key or pointer device was named, find a default one.
-  *
-  */
- 
- #define DEFAULT_DEV 	0
- #define EXPLICIT_DEV	1
- 
- #if defined(__hpux) || defined(__hp_osf)
- static int init_hil_devs (opendevs, numdev)
-     struct	opendevs opendevs [];
-     int		numdev;
-     {
-     Bool OnlyOpenExplicit = FALSE;
-     int	i, j;
-     HPInputDevice	*d, *last_mouse=NULL, *last_pointer=NULL, 
- 			*last_keyboard=NULL, *last_key_device=NULL;
- 
- /*****************************************************************************
-  *
-  * Attempt to open all devices and find out what they are.
-  * Find out which will be the default devices.
-  * Count them so that we can assign names by position.
-  * A device that can't be opened is considered not present.
-  *
-  */
-     if (opendevs[XKEYBOARD].path[0] != '\0' &&
-         opendevs[XPOINTER].path[0] != '\0')
- 	OnlyOpenExplicit = TRUE;
- 
-     for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 	{
- 	d = &l_devs[i];
- 	if (OnlyOpenExplicit)
- 	    {
- 	    for (j=0; j<numdev; j++)
- 		if (strcmp (opendevs[j].path, d->dev_name) == 0)
- 		    break;
- 	    if (j==numdev)
- 		continue;
- 	    }
- 	if (open_device (d) >= 0)
- 	    {
- 	    for (j=0; j<numdev; j++)
- 		{
- 	        if ((d->dev_type == opendevs[j].type && 
- 		     count[d->dev_type]==opendevs[j].pos) ||
- 		    (opendevs[j].type == -1 && 
- 		     strcmp (opendevs[j].path, d->dev_name) == 0))
- 		    {
- 		    d->hpflags |= OPEN_THIS_DEVICE;
- 		    if (j==XKEYBOARD && hpKeyboard==NULL){
- 			hpKeyboard = d;
- 			hpKeyboard->pad2 = EXPLICIT_DEV;
- 			}
- 		    else if (j==XPOINTER && hpPointer==NULL){
- 			hpPointer = d;
- 			hpPointer->pad2 = EXPLICIT_DEV;
- 			}
- 		    else
- 			{
- 			d->hpflags |= MERGED_DEVICE;
- 			d->open_cnt=1;
- 			}
- 		    }
- 		}
- 	    count[d->dev_type]++;
- 	    if (d->dev_type == MOUSE)
- 		last_mouse = d;
- 	    else if (d->dev_type == KEYBOARD)
- 		last_keyboard = d;
- 	    else if (d->x_type == KEYBOARD)
- 		last_key_device = d;
- 	    else if (d->x_type == MOUSE)
- 		last_pointer = d;
- 	    }
- 	}
- 
- /*****************************************************************************
-  *
-  * If the user didn't pick a keyboard and pointer, assign a default.
-  * If present, defaults are the last keyboard and last mouse.
-  *
-  */
- 
-     if (hpKeyboard==NULL)
- 	{
-         if (last_keyboard != NULL)
- 	    hpKeyboard = last_keyboard;
- 	else if (last_key_device != NULL)
- 	    hpKeyboard = last_key_device;
- 	else {
- 	    for (i=0; i<MAX_LOGICAL_DEVS; i++)
- 		if (l_devs[i].file_ds != -1 &&
- 		    !(l_devs[i].hpflags & OPEN_THIS_DEVICE))
- 		    close_device (&l_devs[i]);
- 	    return;				/* must be serial keyboard */
- 	    }
- 	hpKeyboard->hpflags |= OPEN_THIS_DEVICE;
- 	hpKeyboard->hpflags &= ~MERGED_DEVICE;
- 	hpKeyboard->pad2 = DEFAULT_DEV;
- 	}
- 
-     if (hpPointer==NULL)
- 	{
-         if (last_mouse != NULL)
- 	    hpPointer = last_mouse;
- 	else if (last_pointer != NULL)
- 	    hpPointer = last_pointer;
- 	else
- 	    hpPointer = hpKeyboard;
- 	hpPointer->hpflags |= OPEN_THIS_DEVICE;
- 	hpPointer->hpflags &= ~MERGED_DEVICE;
- 	hpPointer->pad2 = DEFAULT_DEV;
- 	}
- 
-     if (hpPointer == hpKeyboard)
- 	{
- 	hpKeyboard->hpflags |= SECOND_LOGICAL_DEVICE;
- 	l_devs[spare] = *hpKeyboard;
- 	hpPointer = &l_devs[spare];
- 	}
- 
- /*****************************************************************************
-  *
-  * If tablet subsetting specified and the pointer is not a tablet,
-  * force the last tablet (if there is one) to be the pointer. 
-  * The tablet must also be accessible as an extension device.
-  *
-  */
- 
-     if (tablet_width)
- 	{
- 	if (hpPointer->dev_type != TABLET)
- 	    {				   
- 	    for (i=MAX_LOGICAL_DEVS-1; i>=0; i--)
- 	        if (l_devs[i].dev_type == TABLET)
- 		    break;
- 	    if (i>=0)
- 		{
- 	        hpPointer->hpflags &= ~OPEN_THIS_DEVICE;
- 		hpPointer = &l_devs[i];
- 	        hpPointer->hpflags |= OPEN_THIS_DEVICE;
- 		l_devs[spare] = *hpPointer; /* will also be extension device */
- 	        l_devs[spare].hpflags |= SECOND_LOGICAL_DEVICE;
- 	        l_devs[spare].open_cnt = 1;
- 		}
- 	    }
- 	else
- 	    {
- 	    l_devs[spare] = *hpPointer; /* will also be an extension device */
- 	    l_devs[spare].hpflags |= SECOND_LOGICAL_DEVICE;
- 	    l_devs[spare].open_cnt = 1;
- 	    }
- 	}
- 
  /***********************************************************************
   *
!  * Now close all the devices that X was not instructed to use.
   *
   */
  
!     for (i=0; i<MAX_LOGICAL_DEVS; i++)
! 	if (l_devs[i].file_ds != -1 &&
! 	    !(l_devs[i].hpflags & OPEN_THIS_DEVICE))
! 	    close_device (&l_devs[i]);
! 
!     }
! #endif /* __hpux */
! 
! /***********************************************************************
!  *
!  * Open the beeper device.
!  * On s800 machines, this is /dev/hilkbd#, where # is 0...3.
!  * On s300 and s700, this is /dev/rhil.
!  *
!  */
! 
! #if defined(__hpux)
! 
! init_beeper()
      {
! 
! #if defined(__hp9000s300) || defined(__hp9000s700)
!     if ((beeper_fd = open(BEEPER_DEVICE,O_RDWR)) < 0 &&
! 	((beeper_fd = open("/dev/beep",O_RDWR)) < 0) &&
! 	((strcmp(uts_name.machine, "9000/7LC") != 0) &&
! 	 (strcmp(uts_name.machine, "9000/712") != 0)))
!  	    ErrorF ("Unable to open beeper device \"%s\".\n",BEEPER_DEVICE);
! #endif /*__hp9000s300 or __hp9000s700 */
! 
! #if defined(__hp9000s800) && !defined(__hp9000s700)
!     int		len;
! 
!     if (ldigit != '\0')
! 	beeper_name[11] = ldigit;
!     else 
! 	{
!         len = strlen (hpKeyboard->dev_name);
! 	beeper_name[11] = hpKeyboard->dev_name[len-3];
! 	}
!     if ((beeper_name[11] >= '0' && beeper_name[11] < '4') &&
!         (beeper_fd = open(beeper_name,O_RDWR)) < 0)
! 	ErrorF ("Unable to open beeper device \"%s\".\n",beeper_name);
! #endif /*__hp9000s800 && !__hp9000s700 */
! 
!     }
! #endif /* __hpux */
! 
! /***********************************************************************
!  *
!  * Initialize Domain input devices.
!  *
!  */
! 
! #ifdef __apollo
! static int init_apollo_devs (opendevs, numdev)
!     struct	opendevs opendevs [];
!     int		numdev;
!     {
!     if (!fdApollo)
!         fdApollo = MakeSMDStream();
!     strcpy (l_devs[0].dev_name, "Apollo_internal");
!     strcpy (l_devs[1].dev_name, "Apollo_internal");
! 
!     l_devs[1].x_type = KEYBOARD;
!     l_devs[1].dev_type = KEYBOARD;
!     l_devs[1].hil_header.id = 0xdf;
!     l_devs[0].hil_header.num_keys = 113;
!     strcpy(l_devs[1].x_name,"FIRST_KEYBOARD");
!     l_devs[1].x_atom = MakeAtom ("KEYBOARD", 8, 0);
!     l_devs[1].file_ds = fdApollo;
! 
!     l_devs[0].x_type = MOUSE;
!     l_devs[0].dev_type = MOUSE;
!     l_devs[0].hil_header.id = 0x68;
!     l_devs[0].hil_header.ax_num = 2;
!     l_devs[0].hil_header.p_button_count = 3;
!     l_devs[0].hil_header.v_button_count = 5;
!     l_devs[0].hil_header.size_x = screenInfo.screens[0]->width;
!     l_devs[0].hil_header.size_y = screenInfo.screens[0]->height;
!   
!     strcpy(l_devs[0].x_name,"FIRST_MOUSE");
!     l_devs[0].x_atom = MakeAtom ("MOUSE", 5, 0);
!     l_devs[0].file_ds = fdApollo;
! 
!     if (opendevs[XPOINTER].type == KEYBOARD)
! 	{
! 	l_devs[1].hpflags |= SECOND_LOGICAL_DEVICE;
! 	l_devs[MAX_LOGICAL_DEVS-2] = l_devs[1];
! 	l_devs[0].file_ds = -1;
! 	hpPointer = &l_devs[MAX_LOGICAL_DEVS-2];
! 	}
!     else if (hpPointer==NULL || open_device(hpPointer) < 0)
! 	hpPointer = &l_devs[0];
!     else
  	{
! 	l_devs[0].hil_header.id = 1;
! 	l_devs[0].file_ds = -1;
  	}
- 
-     if (hpKeyboard==NULL || open_device(hpKeyboard) < 0)
- 	hpKeyboard = &l_devs[1];
      }
- #endif /* __apollo */
  
  /****************************************************************************
   *
   * open_device opens one of the input devices.
!  * The dev_name is filled in by device_files(), or is the default.
   * If the open fails, it may be because the keyboard and pointer
   * are the same device, and the device is already open.
   *
   */
  
- HPInputDeviceHeader zdhdr;
- 
  open_device (d)
      HPInputDevice	*d;
      {
-     HPInputDeviceHeader dhdr;
-     int		fd;
  
- #ifdef __apollo
-     if (!strcmp (d->dev_name, "Apollo_internal"))
- 	fd = fdApollo;
-     else
- #endif /* __apollo */
      d->led[NLOCK] = LockMask;
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dhdr = zdhdr;
! 	strcpy (dhdr.path, d->dev_name);
! 	dhdr.file_ds = HP_VENDOR_RELEASE_NUMBER;
! 	if (button_chording == CHORDING_ON)
! 	    dhdr.button_chording = 100;
! 	if ((*(serialprocs[d->sndx].configure)) (&dhdr) != 
! 	    INIT_SUCCESS)
! 	    return(-1);
! 	serialprocs[d->sndx].fd = fd = dhdr.file_ds;
! 	}
!     else
! 	{
! 	fd = open (d->dev_name, O_RDWR | O_NDELAY);
! 	if (fd < 0) 
! 	    return (fd);
! 
! 	if (get_device_details (fd, d) < 0)
! 	    return (-1);
! 	}
! 
!     d->file_ds = fd;
!     if (fd > max_input_fd)
! 	max_input_fd = fd;
! 
! #ifdef __hp_osf
! #ifdef SPECIAL_68K_OSF
!     if (d->dev_type != NULL_DEVICE &&
!         ioctl (d->file_ds, HILMAPQ, &hil_qd) < 0)
! 	FatalError ("HILMAPQ failed for device %s\n",d->dev_name);
! #else
!     if (d->dev_type != NULL_DEVICE &&
!         ioctl (d->file_ds, HILMAPQ, &hil_qp->hil_evqueue.qnum) < 0)
! 	{
! 	FatalError ("HILMAPQ failed for device %s, file_ds=%d errno=%d\n",
! 	    d->dev_name, d->file_ds, errno);
! 	}
! #endif /* SPECIAL_68K_OSF */
! #endif /* __hp_osf */
! 
!     return (fd);
!     }
! 
! /****************************************************************************
!  *
!  * Query the hil device for detailed information.
!  *
!  */
! 
! static int get_device_details(file_ds, input_dev)
!     int file_ds;
!     HPInputDevice *input_dev;
!     {
!     int 	i, dev_status;
!     u_char	describe[11], iob;
!     struct	hil_desc_record		*hd;
!     int		hi_resol =0;
!     int 	lo_resol = 0;
!     int 	support_it = TRUE;
! #if defined(__hpux) || defined(__hp_osf)
! 
!     for (i=0; i<11; i++)
! 	describe[i] = 0;
!     dev_status = ioctl (file_ds, HILID, &(describe[0]));
!     hd = &(input_dev->hil_header);
! 
!     if (dev_status >= 0) 
! 	{
! 	hd->id  = describe[0];
! 	if (hd->id >= 0xE0)			/* HP98203C - not supported */
  	    {
! 	    close (file_ds);
! 	    return (-1);
  	    }
! 	else if (hd->id >= 0xA0 && hd->id < 0xC0) /* compressed keyboard      */
! 	    {
! 	    close (file_ds);
! 	    return (-1);
! 	    }
! 
! 	hd->flags = describe[1];
! 	input_dev->hpflags |= DATA_IS_8_BITS;
! 	hd->ax_num = (hd->flags & HIL_NUM_AXES);
! 
! 	/*
! 	 *
! 	 * if # of axes indicate it is a positional device
! 	 * then gather resolution.	
! 	 * if 16 bits of information are reported, resolution is
! 	 * in counts/ cm.  In this case, convert to counts/ meter.
! 	 *
! 	 */
! 
! 	if ( hd->ax_num) 
! 	    {
! 	    lo_resol =  describe[2];
! 	    hi_resol =  describe[3];
! 	    hd->resx = hd->resy = (hi_resol << 8) + lo_resol;
! 	    if (hd->flags & HIL_16_BITS)
! 		{
! 		input_dev->hpflags |= DATA_IS_16_BITS;
! 		hd->resx = hd->resy =  hd->resx * 100;
! 		}
! 	    /* If it is an absolute device, gather size */
! 	    if (hd->flags & HIL_ABSOLUTE)
! 		{
! 		switch ( hd->ax_num) 
! 		    {
! 		    case 2:
! 		        hd->size_y = (int)describe[6]|((int)describe[7] << 8);
! 		    case 1:
! 			 hd->size_x = (int)describe[4]|((int)describe[5] << 8);
! 		    default:
! 			 break;
! 		    }
! 		iob = describe[4 + hd->ax_num * 2];
! 		}
! 	    else
! 		iob = describe[4];
! 	    }
! 	else 
! 	    {
! 	    iob = describe[2];
! 	    hd->resx = hd->resy = 0;
! 	    }
! 		   
! 	if (hd->flags & HIL_IOB)
! 	    hd->iob=iob;
! 	if (hd->iob & HILIOB_BUTTONS) 
! 	   {
! 	   hd->p_button_count = hd->iob & HILIOB_BUTTONS ;
! 	   hd->v_button_count = hd->iob & HILIOB_BUTTONS ;
! 
! 	   /*
! 	    * initialize structures for emulating 3 buttons
! 	    * where we have 2, or 5 buttons where we have 3.
! 	    */
! 
! 	    if (hd->p_button_count == 2)  
! 	       hd->v_button_count = 3;  
! 	    else if (hd->p_button_count == 3 || hd->p_button_count == 4)  
! 	       hd->v_button_count = 5;  
! 	   }
!         if (hd->iob & HAS_LEDS)
! 	    {
! 	    hd->num_leds = hd->iob & HILIOB_NPA;
! 	    if (!hd->num_leds)
! 	        hd->num_leds=1;
! 	    }
!         get_device_type (input_dev, hd->id);
! 	}
!     else
! 	{
! 	hd->size_x = hd->size_y = 1000;
! 	hd->resx = hd->resy = 1000;
! 	hd->ax_num = 2;
! 	hd->p_button_count = 3;
! 	hd->v_button_count = 3;
! 	hd->min_kcode = 10;
! 	hd->max_kcode = 135;
! 	hd->num_keys = 109;
! 	input_dev->hil_header.id = 0xd5;
!         input_dev->dev_type = NULL_DEVICE;
!         input_dev->x_type = XOTHER;
! 	strcpy (input_dev->x_name,"FIRST_NULL");
! 	support_it = FALSE;
! 	}
! #endif /* __hpux */
!     return ( support_it);
      }
  
! /****************************************************************************
!  *
!  * This routine determines the type of the input device.
!  * dev_type is the actual type, x_type is what X considers it to be
!  * (mouse or keyboard).
!  * The 9-knob box and quadrature box have the same HIL id.
!  * But if it doesn't have 3 axes, it's not a 9-knob box.
!  *
!  */
  
! static
! get_device_type (dev, id)
!     HPInputDevice *dev;
!     int	id;
      {
!     char	*nptr;
!     int		i, dev_count;
  
!     for (i=0; devices[i].dev_type != NULL_DEVICE; i++)
! 	if (id >= devices[i].lowid && id <= devices[i].highid)
! 	    {
!     	    if (id == NINE_KNOB_ID && dev->hil_header.ax_num != 3)
! 		i = QUAD_INDEX;
! 	    dev->hil_header.min_kcode = devices[i].min_kcode;
! 	    dev->hil_header.max_kcode = devices[i].max_kcode;
! 	    dev->hil_header.num_keys = devices[i].num_keys;
! 	    dev->dev_type = devices[i].dev_type;
! 	    dev->x_type    = devices[i].x_type;
! 	    dev_count = count [dev->dev_type];
! 	    strcpy (dev->x_name, position[dev_count]);
! 	    strcat (dev->x_name, "_");
! 	    if (nptr = strrchr(devices[i].name,'-'))
! 	        strcat (dev->x_name, (nptr+1));
! 	    else 
! 	        strcat (dev->x_name, devices[i].name);
! 	    dev->x_atom = MakeAtom (devices[i].name, strlen(devices[i].name),0);
! 	    break;
! 	    }
!     }
  
! /****************************************************************************
!  *
!  * This routine recalculates the device x_name.
!  * The x_name is a string created by concatenating the device type and position.
!  * The position may change if a device that was previously inaccessible
!  * to X is made accessible.
!  *
!  */
  
! recalculate_x_name ()
!     {
!     int	i;
!     int	j;
  
!     for (i=0; i<NUM_DEV_TYPES; i++)
! 	count[i] = 0;
!     
!     for (i=0; i<MAX_LOGICAL_DEVS; i++)
! 	for (j=0; j<MAX_LOGICAL_DEVS; j++)
! 	    if (strcmp (l_devs[j].dev_name,"/dev/null") == 0)
! 		continue;
! 	    else if (strcmp (dev_names[i], l_devs[j].dev_name) == 0)
  		{
! 		if (l_devs[j].file_ds != -1)
! 		    {
! 		    if (l_devs[j].hpflags & SECOND_LOGICAL_DEVICE)
! 			continue;
! 		    get_device_type (&l_devs[j], l_devs[j].hil_header.id);
! 		    count [l_devs[j].dev_type]++;
! 		    }
! 		else if (open_device (&l_devs[j]) > 0)
! 		    {
! 		    count [l_devs[j].dev_type]++;
! 		    close_device(&l_devs[j]);
! 		    }
! 		else 
! 		    l_devs[j].x_name[0] = '\0';
  		break;
  		}
!     }
! 
! /****************************************************************************
!  *
!  * SetAutoRepeat (onoff)
!  *  Enable or disable the auto repeat feature of the specified device.
!  */
! 
! static void SetAutoRepeat (d, onoff)
!     HPInputDevice	*d;
!     int onoff;
!     {
! #if defined(__hpux) || defined(__hp_osf)
!     char ioctl_data[12];
!     int state = HILDKR;
! 	
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	return;
!     if (onoff)
! 	state = d->repeat_rate;
! 
!     if (d->file_ds != -1)
! 	{
! 	ioctl (d->file_ds, state, ioctl_data);
! 	}
! #endif /*__hpux */
!     }
! 
! /********************************************************************
!  *
!  * If the file LIBDIR/X[display#]devices exists, this routine 
!  * processes it.
!  * It translates the strings in the file to a device type and relative
!  * position on the HIL.
!  *
!  */
! 
! 
! static int device_files (fd, opendevs, sdev_num)
!     FILE	*fd;
!     struct	opendevs opendevs [];
!     int		*sdev_num;
!     {
!     char buf[MAXNAMLEN+1];
!     char devuse[MAXNAMLEN+1];
!     char path[MAXNAMLEN+1];
!     char pos[MAXNAMLEN+1];
!     char *fgets();
!     int	i;
!     int	other = XOTHER;
!     int	sother = XOTHER;
!     int parms;
! 
!     while (fgets(buf,MAXNAMLEN+1,fd) != NULL)
! 	{
! 	buf[strlen(buf)-1] = '\0';
! 	if (other == MAX_LOGICAL_DEVS)
! 	    {
! 	    ErrorF ("Too many X*devices entries. Ignoring \"%s\".\n",buf);
  	    continue;
- 	    }
- 	pos[0] = '\0';
- 	path[0] = '\0';
- 	devuse[0] = '\0';
- 	parms = sscanf (buf, "%s%s%s", pos, path, devuse);
  
! 	if (pos[0] == '#')	/* comment, skip it */
! 	    continue;
! 	else if (path[0] == '#')/* 1 parm           */
! 	    parms = 1;
! 	else if (devuse[0] == '#')/* 2 parms        */
! 	    parms = 2;
! 
! 	if (parms == EOF)		/* blank line            */
! 	    continue;
! 	else if (parms == 1)
! 	    {
! 	    for (i=0; i<strlen(pos); i++)
! 		pos[i] = toupper(pos[i]);
! 	    if (strcmp (pos,"BEGIN_DEVICE_DESCRIPTION") == 0)
! 		parse_description (fd, serial, &sother, sdev_num);
! 	    else
  		{
! 		ErrorF("Invalid X*devices entry: \"%s\" - Entry skipped\n",buf);
! 		continue;
  		}
! 	    }
! 	else if (parms == 2)	/* device name specified */
! 	    parse_2_parms (pos, path, opendevs, &other);
! 	else if (parms ==3)
! 	    parse_3_parms (pos, path, devuse, opendevs, &other);
! 
! 	}
!     return (other);
!     }
! 
! /***********************************************************************
!  *
!  * This routine is invoked when two parameters are specified.
!  * Either they are a device path and intended use, or a device loop path.
!  *
!  */
! 
! parse_2_parms (dev, use, o, ondx)
!     char *dev;
!     char *use;
!     struct	opendevs o[];
!     int  *ondx;
!     {
!     int i;
!     int ndx;
!     int len = strlen(use);
  
!     for (i=0; i<len; i++)
! 	use[i] = toupper(use[i]);
  
!     if (strcmp (use,"HIL_PATH") == 0)
! 	{
! 	strcpy (hilpath,dev);
! 	return;
! 	}
!     else if (strcmp (use, "POINTER") == 0)
! 	ndx = XPOINTER;
!     else if (strcmp (use, "KEYBOARD") == 0)
! 	ndx = XKEYBOARD;
!     else if (strcmp (use, "OTHER") == 0)
! 	ndx = (*ondx)++;
!     else
! 	{
! 	ErrorF ("Bad device use \"%s\" in X*devices file - Entry skipped.\n",
! 		use);
! 	return;
  	}
! 
!     o[ndx].type = -1;
!     o[ndx].pos = -1;
!     strcpy (o[ndx].path, dev);
      }
  
! /***********************************************************************
!  *
!  * This routine is invoked when three parameters are specified.
!  * They are a position, a device type, and its intended use.
   *
!  */
! 
! parse_3_parms (pos, name, use, o, ondx)
!     char *pos;
!     char *name;
!     char *use;
!     struct	opendevs o[];
!     int  *ondx;
!     {
!     int i;
!     int ndx;
! 
!     for (i=0; i<strlen(pos); i++)
! 	pos[i] = toupper(pos[i]);
!     for (i=0; i<strlen(use); i++)
! 	use[i] = toupper(use[i]);
! 
!     if (strcmp (use, "POINTER") == 0)
! 	ndx = XPOINTER;
!     else if (strcmp (use, "KEYBOARD") == 0)
! 	ndx = XKEYBOARD;
!     else if (strcmp (use, "OTHER") == 0)
! 	ndx = *ondx;
!     else
! 	{
! 	ErrorF ("Bad device use \"%s\" in X*devices file - Entry skipped.\n",
! 	    use);
! 	return;
! 	}
! 
!     for (i=0; i<MAX_POSITIONS; i++)
! 	if (strcmp (position[i], pos) == 0)
! 	    {
! 	    o[ndx].pos = i;
! 	    break;
! 	    }
! 
!     if (i == MAX_POSITIONS) /* failed, skip to next */
! 	{
! 	ErrorF ("Bad ordinal \"%s\" in X*devices file - Entry skipped.\n",
! 	    pos);
! 	return;
! 	}
  
!     for (i=0; i<strlen(name); i++)
! 	name[i] = toupper(name[i]);
  
!     for (i=0; i<MAX_DEV_TYPES; i++)
! 	if (strcmp (devices[i].name,name) == 0)
! 	    {
! 	    o[ndx].type = devices[i].dev_type;
! 	    break;
  	    }
! 
!     if (i == MAX_DEV_TYPES) /* failed, skip to next */
! 	{
! 	ErrorF ("Bad device type \"%s\" in X*devices file - Entry skipped.\n",
! 		name);
! 	return;
! 	}
!     else if (ndx == *ondx)
! 	(*ondx)++;
      }
  
  /********************************************************************
--- 810,1004 ----
      return ((DeviceIntPtr) pXDev);
      }
  
  /***********************************************************************
   *
!  * Initialize default input devices.
!  * If this machine supports HIL, use the last keyboard and mouse.
!  * If none are present, use the last key and pointer device.
   *
   */
  
! clear_device_private(d)
!     HPInputDevice *d;
      {
! 	
!     memset(d, 0, sizeof(HPInputDevice));
!     d->id = UNINITIALIZED;
!     d->d.keymap_name = "";
!     d->d.file_ds = -1;
!     d->driver_name[0] = '\0';
!     d->d.path[0] = '\0';
!     d->d.file_ds = HP_VENDOR_RELEASE_NUMBER;
!     d->d.button_chording = 0;
!     if (button_chording == CHORDING_ON)
  	{
! 	d->d.button_chording = 100;
! 	d->d.reserved[0] = button_latching;
  	}
      }
  
  /****************************************************************************
   *
   * open_device opens one of the input devices.
!  * The path is filled in by device_files(), or is the default.
   * If the open fails, it may be because the keyboard and pointer
   * are the same device, and the device is already open.
   *
   */
  
  open_device (d)
      HPInputDevice	*d;
      {
  
      d->led[NLOCK] = LockMask;
!     d->d.reserved[0] = 0;
!     d->d.reserved[2] = 0;
!     d->d.file_ds = HP_VENDOR_RELEASE_NUMBER;
!     if (button_chording == CHORDING_ON)
  	    {
! 	    d->d.button_chording = 100;
! 	    d->d.reserved[0] = button_latching;
  	    }
!     if ((*(d->s.configure)) (&d->d) != INIT_SUCCESS)
! 	return(-1);
!     init_device_private (d, FALSE);
!     return (d->d.file_ds);
      }
  
! /* ******************************************************************** */
! /* ************************* Parse X*devices ************************** */
! /* ******************************************************************** */
  
! static struct _X_devices
      {
!     char *x_name; 
!     int dev_type;
!     } X_devices[] = {{XI_KEYBOARD, KEYBOARD},
! 		     {"NULL", NULL_DEVICE}};
  
! static char *h_position[] = 
! {
!   "FIRST",
!   "SECOND",
!   "THIRD",
!   "FOURTH",
!   "FIFTH",
!   "SIXTH",
!   "SEVENTH"
!   };
! 
! static void uppercase(str) char *str;	/* convert str to upper case */
!   { for (; *str; str++) *str = toupper(*str); }
! 
! 
! /* 
!  * Formats:
!  *   |#comment
!  *   |   #comment
!  *   |word [#comment]
!  *   |  word [#comment]
!  *   |word word  [#comment]
!  *   |word word word [#comment]
!  *   |word word word word [#comment]
!  */
! 
! static int is_null_needed(null_needed, keyboard_is_pointer)
!     Bool *null_needed;
!     int *keyboard_is_pointer;
!     {
!     FILE *fp;
!     int i, parms, ipos, itype, use_as;
!     char fname[256], buf[256], pos[256], x_name[256], use[256];
  
!     sprintf(fname, "%s/X%sdevices",LIBDIR, display);
!     fp = fopen (fname, "r");
!     if (fp == NULL)
! 	return;
!     while (fgets(buf,MAXNAMLEN+1,fp) != NULL)
! 	{
! 	buf[strlen(buf)-1] = pos[0] = x_name[0] = use[0] = '\0';
  
! 	parms = sscanf(buf, "%s%s%s", pos, x_name, use);
! 	if (parms != 3 || pos[0] == '#' || x_name[0] == '#' || use[0] == '#')
! 	    continue; 				/* blank or comment, skip it */
! 	              				/* or not the syntax we want */
! 
!     /* Parse lines with 3 parameters, such as:
!      *   first keyboard pointer
!      *   first null     keyboard
!      *   first null     pointer
!      */
  
! 	uppercase(pos);
! 	for (i=0; i<NITEMS(h_position); i++)
! 	    if (0 == strcmp(h_position[i], pos))
  		{
! 		ipos = i + 1;	/* h_position[0] = "FIRST" == 1 */
  		break;
  		}
! 	if (i >= 7)                  /* failed, skip this entry */
  	    continue;
  
! 	uppercase(x_name);
! 	for (i=0; i<NITEMS(X_devices); i++)
! 	    if (0 == strcmp(X_devices[i].x_name,x_name))
  		{
! 		itype = X_devices[i].dev_type;
! 		break;
  		}
! 	if (i == NITEMS(devices)) /* failed, skip this entry */
! 	    continue;
  
! 	uppercase(use);
! 	if      (0 == strcmp(use, "POINTER"))  use_as = XPTR_USE;
! 	else if (0 == strcmp(use, "KEYBOARD")) use_as = XKBD_USE;
! 	else if (0 == strcmp(use, "OTHER"))    use_as = XOTH_USE;
! 	else
! 	    continue;
  
! 	if (itype == NULL_DEVICE && use_as == XKBD_USE)
! 	    *null_needed = TRUE;
! 	if (itype == NULL_DEVICE && use_as == XPTR_USE)
! 	    *null_needed = TRUE;
! 	if (itype == KEYBOARD && use_as == XPTR_USE)
! 	    *keyboard_is_pointer = TRUE;
  	}
!     fclose(fp);
      }
  
! /********************************************************************
   *
!  * check_for_duplicates().
!  * 
!  * Check to see if a device that is already open has been specified.
!  *
!  */
  
! static Bool check_for_duplicates(d)
!     HPInputDevice *d;
!     {
!     int i;
!     HPInputDevice *tmp;
  
!     for (i=0,tmp=l_devs; i<NITEMS(l_devs); i++,tmp++)
! 	if (strcmp(tmp->d.path, d->d.path)==0 && tmp->d.file_ds >= 0 &&
! 	    tmp->d.file_ds != HP_VENDOR_RELEASE_NUMBER)
! 	    {
! 	    if (strcmp(d->entry, DIN_KBD_INIT)==0 && (d->use & XPTR_USE))
! 		{
! 		*d = *tmp;
! 		tmp->hpflags |= SECOND_LOGICAL_DEVICE;
! 	   	hpPointer = d;
! 		hpPointer->use = XPTR_USE;
! 		return FALSE;
! 		}
! 	    d->d.path[0] = '\0';
! 	    d->driver_name[0] = '\0';
! 	    d->entry[0] = '\0';
! 	    d->use = 0;
! 	    return FALSE;
  	    }
!     return TRUE;
      }
  
  /********************************************************************
***************
*** 1912,1998 ****
   *
   */
  
! parse_description(fd, o, ondx, sdev_num)
      FILE	*fd;
!     struct	opendevs o[];
!     int  	*ondx;
!     int  	*sdev_num;
!     {
!     int		ndx = -1, i, len;
!     char buf[256], ubuf[256], name[256], uname[256], path[256], var[64], 
! 	use[64], entry[64];
      char *fgets();
  
!     name[0] = '\0';
!     entry[0] = '\0';
!     while (fgets(buf,256,fd) != NULL)
! 	{
! 	len = strlen(buf);
! 	for (i=0; i<len; i++)
! 	    ubuf[i] = toupper(buf[i]);
! 	if (sscanf (ubuf,"PATH %s", var) == 1)
! 	    sscanf (buf,"%s %s", var, path);
! 	else if (sscanf (ubuf,"NAME %s", uname) == 1)
! 	    sscanf (buf,"%s %s", var, name);
! 	else if (sscanf (ubuf,"ENTRYPOINT %s", var) == 1)
! 	    sscanf (buf,"%s %s", var, entry);
! 	else if (sscanf (ubuf,"USE %s",use) == 1)
! 	    {
! 	    if (!strcmp(use,"POINTER"))
! 		{
! 		ndx = XPOINTER;
! 		o[ndx].use = XPOINTER;
! 		}
! 	    else if (!strcmp(use,"KEYBOARD"))
! 		{
! 		ndx = XKEYBOARD;
! 		o[ndx].use = XKEYBOARD;
! 		}
! 	    else if (!strcmp(use,"OTHER"))
! 		{
! 		ndx = (*ondx)++;
! 		o[ndx].use = XOTHER;
! 		}
! 	    else	/* assume used as extension device */
! 		{
! 		ndx = (*ondx)++;
! 		o[ndx].use = XOTHER+1;
! 		}
  	     }
! 	else if (sscanf (ubuf," %s",var) == 1 &&
! 		 strcmp (var,"END_DEVICE_DESCRIPTION")==0)
! 	    {
! 	    if (device_ndx < 0)
! 		{
! 		ErrorF("Too many devices in X*devices file - entry skipped.\n");
! 		return;
! 		}
! 	    if (ndx != -1 && path)
! 		{
! 		o[ndx].type = 99;
! 		strcpy (o[ndx].path, path);
! 		strcpy (o[ndx].name, name);
! 		if (entry[0])
! 		    strcpy (o[ndx].entry, entry);
! 		else
! 		    {
! 		    len = strcspn (name,".");
! 		    strncpy (o[ndx].entry, name, len);
! 		    o[ndx].entry[len] = '\0';
! 		    strcat (o[ndx].entry, "_Init");
! 		    }
! 		(*sdev_num)++;
! 		}
! 	    return;
! 	    }
! 	else
! 	    {
! 	    ErrorF ("Invalid line in device description - ignored.\n");
! 	    ErrorF ("line was: %s",buf);
! 	    }
! 	}
!     ErrorF("No END_DESCRIPTION line in X*devices file - description skipped.\n");
      }
  
  /********************************************************************
   *
--- 1008,1074 ----
   *
   */
  
! get_next_device(fd, d)
      FILE	*fd;
!     HPInputDevice *d;
!     {
!     int	len;
!     char buf[256], key[256], var[64];
      char *fgets();
+     char pos[MAXNAMLEN+1];
+     int parms;
  
!     if (d->driver_name[0] != '\0')	
! 	return TRUE;
!     d->entry[0]='\0';
!     while (fgets(buf,MAXNAMLEN+1,fd) != NULL)
! 	{
! 	buf[strlen(buf)-1] = '\0';
! 	pos[0] = '\0';
! 
! 	if ((sscanf(buf,"%s",pos) == EOF) || pos[0] == '#')
! 	    continue; 				/* blank or comment, skip it */
! 
! 	uppercase(pos);
! 	if (strcmp (pos,"BEGIN_DEVICE_DESCRIPTION") != 0)
! 	    continue;
! 
!         while (fgets(buf,256,fd) != NULL) {
! 	    if (((parms = sscanf(buf,"%s%s",key,var)) == EOF) || key[0] == '#')
! 		continue; 			/* blank or comment, skip it */
! 
! 	    uppercase(key);
! 	    if (parms == 1 && strcmp (key,"END_DEVICE_DESCRIPTION")==0)
! 		return (check_for_duplicates(d));
! 
! 	    if (strcmp(key,"PATH") == 0)
! 		strcpy(d->d.path, var);
! 	    else if (strcmp(key,"NAME") == 0) {
! 		sprintf(d->driver_name, "%s/%s", DRVRLIBDIR, var);
! 		if (*d->entry == '\0') {
! 		    len = strcspn (var,".");
! 		    strncpy (d->entry, var, len);
! 		    d->entry[len] = '\0';
! 		    strcat (d->entry, "_Init");
! 		}
! 	    }
! 	    else if (strcmp(key,"ENTRYPOINT") == 0)
! 		strcpy(d->entry, var);
! 	    else if (strcmp(key,"USE") == 0) {
! 		uppercase(var);
! 		if (!strcmp(var,"POINTER"))
! 		    d->use = EXPLICIT | XPTR_USE;
! 		else if (!strcmp(var,"KEYBOARD"))
! 		    d->use = EXPLICIT | XKBD_USE;
! 		else if (!strcmp(var,"OTHER"))
! 		    d->use = XOTH_USE;
! 		else	/* assume used as extension device */
! 		    d->use = XEXT_USE;
  	     }
! 	 }
      }
+     return FALSE;
+ }
  
  /********************************************************************
   *
***************
*** 2014,2020 ****
      Bool	makeupper;
      {
      int		i;
-     KeySym	sym;
  
      if (makeupper)
  	for (i=0; i<strlen(key); i++)
--- 1090,1095 ----
***************
*** 2032,2038 ****
  		*code = strings[i].value;
  		return (0);
  		}
!     for (i=0; keyset1[i].keystr; i++)
          if (strcmp (key, keyset1[i].keystr) == 0)
  	    break;
      if (!inputInfo.keyboard)
--- 1107,1113 ----
  		*code = strings[i].value;
  		return (0);
  		}
!     for (i=0; *keyset1[i].keystr; i++)
          if (strcmp (key, keyset1[i].keystr) == 0)
  	    break;
      if (!inputInfo.keyboard)
***************
*** 2060,2065 ****
--- 1135,1141 ----
  	    return (i + rec->minKeyCode);
  	syms += rec->mapWidth;
  	}
+     return(0);
  }
  
  /********************************************************************
***************
*** 2131,2136 ****
--- 1207,1213 ----
  	u_int 	*iptr;
  	} codevar;
  
+     button_3 = 0;
      if (inputInfo.keyboard) {
  	get_codes ("KEYPAD_2", &code, KEY, FALSE);
  	cursor_down = (unsigned char) code;
***************
*** 2151,2157 ****
  	get_codes ("KEYPAD_7", &code, KEY, FALSE);
  	button_5 = (unsigned char) code;
  	}
!     sprintf(fname, "%s/X%spointerkeys",LIBDIR,display);
      fp = fopen ( fname, "r");
      if (fp == NULL)
  	return;
--- 1228,1234 ----
  	get_codes ("KEYPAD_7", &code, KEY, FALSE);
  	button_5 = (unsigned char) code;
  	}
!     sprintf(fname, "%s/X%spointerkeys",LIBDIR, display);
      fp = fopen ( fname, "r");
      if (fp == NULL)
  	return;
***************
*** 2207,2245 ****
  
  /****************************************************************************
   *
!  * hpAddInputDevice(deviceProc, autoStart, pHPDev)
!  * create an X input device, then assign pHPDev to it's devicePrivate field.
   *
   */
  
! static DevicePtr hpAddInputDevice(deviceProc, autoStart, pHPDev)
      DeviceProc deviceProc;
      Bool autoStart;
!     HPInputDevice *pHPDev;
      {
      DevicePtr pXDev;
  
      if ((pXDev = AddInputDevice(deviceProc, autoStart)) == NULL)
  	FatalError ("Too many input devices - X server terminating!\n");
-     pHPDev->dev_id = ((DeviceIntPtr) pXDev)->id;
  #ifdef XINPUT
!     if (pHPDev == hpPointer)
  	{
! 	hp_device_ids[pHPDev->dev_id] = XPOINTER;
! 	x_device_ids[XPOINTER] = pHPDev->dev_id;
  	}
!     else if (pHPDev == hpKeyboard)
  	{
! 	hp_device_ids[pHPDev->dev_id] = XKEYBOARD;
! 	x_device_ids[XKEYBOARD] = pHPDev->dev_id;
  	}
      else
  	{
! 	hp_device_ids[pHPDev->dev_id] = otherndx;
! 	x_device_ids[otherndx++] = pHPDev->dev_id;
  	}
  #endif /* XINPUT */
!     pXDev->devicePrivate = (pointer) pHPDev;
      return  pXDev;
      }
  
--- 1284,1323 ----
  
  /****************************************************************************
   *
!  * hpAddInputDevice(deviceProc, autoStart, pHP)
!  * create an X input device, then assign pHP to it's devicePrivate field.
   *
   */
  
! static DevicePtr hpAddInputDevice(deviceProc, autoStart, pHP)
      DeviceProc deviceProc;
      Bool autoStart;
!     HPInputDevice *pHP;
      {
      DevicePtr pXDev;
+     int id;
  
      if ((pXDev = AddInputDevice(deviceProc, autoStart)) == NULL)
  	FatalError ("Too many input devices - X server terminating!\n");
  #ifdef XINPUT
!     id = ((DeviceIntPtr) pXDev)->id;
!     if (pHP == hpPointer)
  	{
! 	hp_device_ids[id] = XPOINTER;
! 	x_device_ids[XPOINTER] = id;
  	}
!     else if (pHP == hpKeyboard)
  	{
! 	hp_device_ids[id] = XKEYBOARD;
! 	x_device_ids[XKEYBOARD] = id;
  	}
      else
  	{
! 	hp_device_ids[id] = otherndx;
! 	x_device_ids[otherndx++] = id;
  	}
  #endif /* XINPUT */
!     pXDev->devicePrivate = (pointer) pHP;
      return  pXDev;
      }
  
***************
*** 2266,2301 ****
  close_device(d)
      HPInputDevice	*d;
      {
!     int i, tmp_fd = d->file_ds;
  
! #ifdef __apollo
!     if (!strcmp (d->dev_name, "Apollo_internal"))
! 	return;
! #endif /* __apollo */
! #ifdef __hp_osf
!     if (d->file_ds != -1)
! 	ioctl(d->file_ds, HILUNMAPQ, &hil_qp->hil_evqueue.qnum);
!     if (max_input_fd == 0)
! 	{
! 	RemoveEnabledDevice (beeper_fd);
! 	ioctl (beeper_fd, HILFREEQ, &hil_qp->hil_evqueue.qnum);
! 	close (beeper_fd);
! 	hil_qp = 0;
! 	}
! #endif /* __hp_osf */
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	(*(serialprocs[d->sndx].close)) (d->file_ds);
!     else
! 	close (d->file_ds);
!     d->file_ds = -1;
      if (tmp_fd == max_input_fd) 
  	{
  	max_input_fd = 0;
  	for (i=0; i<MAX_LOGICAL_DEVS; i++)
! 	    if (l_devs[i].file_ds > max_input_fd)
! 		max_input_fd = l_devs[i].file_ds;
  	}
- 
      }
  
  /*****************************
--- 1344,1361 ----
  close_device(d)
      HPInputDevice	*d;
      {
!     int i, tmp_fd = d->d.file_ds;
  
!     (*(d->s.close)) (d->d.file_ds);
!     d->d.file_ds = -1;
      if (tmp_fd == max_input_fd) 
  	{
  	max_input_fd = 0;
  	for (i=0; i<MAX_LOGICAL_DEVS; i++)
! 	    if (l_devs[i].d.file_ds != HP_VENDOR_RELEASE_NUMBER &&
! 	        l_devs[i].d.file_ds > max_input_fd)
! 		max_input_fd = l_devs[i].d.file_ds;
  	}
      }
  
  /*****************************
***************
*** 2363,2397 ****
      queue_events_free++;
      }
  
- extern int apLeave_X, apReenter_X;      /*  in hp/apollo/apInit2.c */
- 
- CheckInput (data, result, LastSelectMask)
-     pointer data;
-     unsigned long result;
-     long LastSelectMask[];
-     {
-     long devicesReadable[mskcnt];
-     extern long EnabledDevices[];
-     extern Bool	display_borrowed;	/* in x_hil.c */
- 
-     if (result <= 0)
- 	return;
-     MASKANDSETBITS(devicesReadable, LastSelectMask, EnabledDevices);
- #ifdef __apollo
-     if (apReenter_X) apReturnFromDM();
-     if (display_borrowed) return;
- 
-     while (GetSMDEvent(TRUE, NULL))
- 	;
-     if (apLeave_X)   apReturnToDM();
-     BITCLEAR (devicesReadable, fdApollo);
- #endif /* __apollo */
- #ifdef __hp_osf
-     BITCLEAR (devicesReadable, beeper_fd);
- #endif /* __hp_osf */
-     if (ANYSET(devicesReadable)) 
- 	store_inputs (devicesReadable);
-     }
  
  #ifdef XINPUT
  AddOtherInputDevices ()
--- 1423,1428 ----
***************
*** 2422,2429 ****
  		break;
  		}
  	    }
! 	if (found == FALSE && hp->x_name[0] != '\0' && 
! 		(strcmp (hp->dev_name,"/dev/null") != 0))
  	    {
  	    dev = x_init_device (hp, TRUE);
  	    dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
--- 1453,1460 ----
  		break;
  		}
  	    }
! 	if (found == FALSE && hp->d.x_name != NULL && 
! 		(strcmp (hp->d.path,"/dev/null") != 0))
  	    {
  	    dev = x_init_device (hp, TRUE);
  	    dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
***************
*** 2445,2451 ****
      hp_device_ids[new_dev->id] = XKEYBOARD;
      hp_device_ids[old_dev->id] = tmp;
      x_device_ids[XKEYBOARD] = new_dev->id;
!     x_device_ids[tmp] = old->dev_id;
      hpKeyboard = new;
      return (Success);
      }
--- 1476,1482 ----
      hp_device_ids[new_dev->id] = XKEYBOARD;
      hp_device_ids[old_dev->id] = tmp;
      x_device_ids[XKEYBOARD] = new_dev->id;
!     x_device_ids[tmp] = old_dev->id;
      hpKeyboard = new;
      return (Success);
      }
***************
*** 2479,2495 ****
      hp_device_ids[new_dev->id] = XPOINTER;
      hp_device_ids[old_dev->id] = tmp;
      x_device_ids[XPOINTER] = new_dev->id;
!     x_device_ids[tmp] = old->dev_id;
      hpPointer = new;
- #ifdef __apollo
-     {
-     smd_$pos_t pos;
- 
-     pos.column = hpPointer->coords[0];
-     pos.line = hpPointer->coords[1];
-     smd_$set_unit_cursor_pos (1, pos, &status);
-     }
- #endif /* __apollo */
      InitFocusClassDeviceStruct(old_dev);
      return (Success);
      }
--- 1510,1517 ----
      hp_device_ids[new_dev->id] = XPOINTER;
      hp_device_ids[old_dev->id] = tmp;
      x_device_ids[XPOINTER] = new_dev->id;
!     x_device_ids[tmp] = old_dev->id;
      hpPointer = new;
      InitFocusClassDeviceStruct(old_dev);
      return (Success);
      }
***************
*** 2517,2530 ****
      *status = Success;
  
      d = GET_HPINPUTDEVICE (dev);
!     if (d->file_ds  == -1)			/* device not yet open   */
          {
          if (open_device (d) < 0)		/* couldn't open device  */
  	    {
  	    *status = BadDevice;
  	    return;
  	    }
-         recalculate_x_name ();			/* recalculate names	*/
          }
      else
  	{
--- 1539,1551 ----
      *status = Success;
  
      d = GET_HPINPUTDEVICE (dev);
!     if (d->d.file_ds  == -1)			/* device not yet open   */
          {
          if (open_device (d) < 0)		/* couldn't open device  */
  	    {
  	    *status = BadDevice;
  	    return;
  	    }
          }
      else
  	{
***************
*** 2584,2590 ****
      new_client->count = 1;
      new_client->mode = token;
  
!     AddResource((XID) new_client->resource, (RESTYPE) HPType, (pointer) id);
      }
  
  
--- 1605,1611 ----
      new_client->count = 1;
      new_client->mode = token;
  
!     AddResource(new_client->resource, HPType, (pointer) id);
      }
  
  
***************
*** 2635,2647 ****
      	       }
          if (dev && d->clients == NULL)
      	    {
!     	    if (d->open_cnt == 0)
      	        DisableDevice(dev);
- 	    else
- 		{
- 		d->mode = ABSOLUTE;
- 		d->hpflags |= MERGED_DEVICE;
- 		}
  	    }
  	}
      }
--- 1656,1664 ----
      	       }
          if (dev && d->clients == NULL)
      	    {
!     	    if (!(d->hpflags & MERGED_DEVICE) || 
! 		(d->hpflags & SECOND_LOGICAL_DEVICE))
      	        DisableDevice(dev);
  	    }
  	}
      }
***************
*** 2692,2705 ****
      {
  
      if ((mode & DEVICE_EVENTS) == DEVICE_EVENTS)
- 	{
- 	d->mode = RELATIVE;
  	d->hpflags &= ~MERGED_DEVICE;
- 	}
      else
  	{
  	mode |= ABSOLUTE;
-         d->mode = ABSOLUTE;
          d->hpflags |= MERGED_DEVICE;
  	}
  
--- 1709,1718 ----
***************
*** 2707,2721 ****
  	{
  	d->coords[0] = hpPointer->coords[0];
  	d->coords[1] = hpPointer->coords[1];
! 	d->mode = ABSOLUTE;
  	}
      else
  	{
- #if defined(__hpux) || defined(__hp_osf)
  	d->coords[0] = 0;
  	d->coords[1] = 0;
! #endif /* __hpux */
! 	d->mode = RELATIVE;
  	}
      }
  
--- 1720,1733 ----
  	{
  	d->coords[0] = hpPointer->coords[0];
  	d->coords[1] = hpPointer->coords[1];
! 	d->hpflags |= ABSOLUTE_DATA;
  	}
      else
  	{
  	d->coords[0] = 0;
  	d->coords[1] = 0;
! 	if (!(d->d.flags & ABSOLUTE_DATA))
! 	    d->hpflags &= ~ABSOLUTE_DATA;
  	}
      }
  
***************
*** 2733,2746 ****
      DeviceIntPtr dev;
      int		mode;
      {
-     int i;
      HPInputDevice *d;
  
      d = GET_HPINPUTDEVICE (dev);
      if (d->dev_type == NULL_DEVICE)
  	return Success;
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XSetDeviceMode, &mode);
      return BadMatch;
      }
  
--- 1745,1757 ----
      DeviceIntPtr dev;
      int		mode;
      {
      HPInputDevice *d;
  
      d = GET_HPINPUTDEVICE (dev);
      if (d->dev_type == NULL_DEVICE)
  	return Success;
!     if ((*(d->s.write)) (d->d.file_ds, _XSetDeviceMode, &mode)==WRITE_SUCCESS)
! 	return Success;
      return BadMatch;
      }
  
***************
*** 2771,2783 ****
  	    dev->valuator->axisVal[i] = *(valuators+i);
      if (d->dev_type == NULL_DEVICE)
  	return Success;
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	ctrl.first_valuator = first_valuator;
! 	ctrl.num_valuators = num_valuators;
! 	ctrl.resolutions = valuators;
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XSetDeviceValuators, &ctrl);
! 	}
      return BadMatch;
      }
  
--- 1782,1792 ----
  	    dev->valuator->axisVal[i] = *(valuators+i);
      if (d->dev_type == NULL_DEVICE)
  	return Success;
!     ctrl.first_valuator = first_valuator;
!     ctrl.num_valuators = num_valuators;
!     ctrl.resolutions = valuators;
!     if ((*(d->s.write)) (d->d.file_ds, _XSetDeviceValuators, &ctrl)==WRITE_SUCCESS)
! 	return Success;
      return BadMatch;
      }
  
***************
*** 2796,2835 ****
      xDeviceCtl	*control;
      {
      HPInputDevice *d;
!     xDeviceResolutionCtl *dctrl;
!     HPResolutionControl ctrl;
  
      d = GET_HPINPUTDEVICE (dev);
      if (d->dev_type == NULL_DEVICE)
  	return Success;
!     if (d->hpflags & IS_SERIAL_DEVICE)
! 	{
! 	dctrl = (xDeviceResolutionCtl *) control;
! 	ctrl.first_valuator = dctrl->first_valuator;
! 	ctrl.num_valuators = dctrl->num_valuators;
! 	ctrl.resolutions =  (int *) (dctrl+1);
! 	SERIAL_DRIVER_WRITE(d->file_ds, _XChangeDeviceControl, &ctrl);
! 	}
      return BadMatch;
      }
  #endif /* XINPUT */
  
- #if defined(__hpux) || defined(__hp_osf)
  #define	LEFT_SHIFT_CODE		0x05
  #define	RIGHT_SHIFT_CODE	0x04
  #define	LEFT_MOD1_CODE		0x03
  #define	RIGHT_MOD1_CODE		0x02
  #define	RIGHT_CONTROL_CODE	0x00
  #define	LEFT_CONTROL_CODE	0x06
- #endif /* __hpux */
- 
- #ifdef __apollo
- #define	LEFT_SHIFT_CODE		0x5e
- #define	RIGHT_SHIFT_CODE	0x6a
- #define	LEFT_MOD1_CODE		0x75
- #define	RIGHT_MOD1_CODE		0x77
- #define	LEFT_CONTROL_CODE	0x43
- #endif /* __apollo */
  
  #define	LEFT_SHIFT_BIT		0x20
  #define	RIGHT_SHIFT_BIT		0x10
--- 1805,1831 ----
      xDeviceCtl	*control;
      {
      HPInputDevice *d;
!     xDeviceResolutionCtl *dctrl = (xDeviceResolutionCtl *) control;
!     HPResolutionControl c;
  
      d = GET_HPINPUTDEVICE (dev);
      if (d->dev_type == NULL_DEVICE)
  	return Success;
!     c.first_valuator = dctrl->first_valuator;
!     c.num_valuators = dctrl->num_valuators;
!     c.resolutions =  (int *) (dctrl+1);
!     if ((*(d->s.write)) (d->d.file_ds, _XChangeDeviceControl, &c)==WRITE_SUCCESS)
! 	return Success;
      return BadMatch;
      }
  #endif /* XINPUT */
  
  #define	LEFT_SHIFT_CODE		0x05
  #define	RIGHT_SHIFT_CODE	0x04
  #define	LEFT_MOD1_CODE		0x03
  #define	RIGHT_MOD1_CODE		0x02
  #define	RIGHT_CONTROL_CODE	0x00
  #define	LEFT_CONTROL_CODE	0x06
  
  #define	LEFT_SHIFT_BIT		0x20
  #define	RIGHT_SHIFT_BIT		0x10
***************
*** 2868,2906 ****
      HPInputDevice *d;
  
      d = GET_HPINPUTDEVICE (inputInfo.keyboard);
-     if (!(d->id_detail & HP_HIL)){
-         for (i=0; i<MAX_KEY_MODS; i++, src++)
- 	    if (*src != 0xff)
- 		*dst |= inputInfo.keyboard->key->modifierMap[(*src+8)];
-     return;
-     }
- 
      for (i=0; i<MAX_KEY_MODS; i++, src++)
! 	switch (*src)
! 	    {
! 	    case LEFT_SHIFT_CODE:
! 		*dst |= LEFT_SHIFT_BIT;
! 		break;
! 	    case RIGHT_SHIFT_CODE:
! 		*dst |= RIGHT_SHIFT_BIT;
! 		break;
! 	    case LEFT_MOD1_CODE:
! 		*dst |= LEFT_MOD1_BIT;
! 		break;
! 	    case RIGHT_MOD1_CODE:
! 		*dst |= RIGHT_MOD1_BIT;
! 		break;
! 	    case LEFT_CONTROL_CODE:
! 		*dst |= LEFT_CONTROL_BIT;
! 		break;
! #if defined(__hpux) || defined(__hp_osf)
! 	    case RIGHT_CONTROL_CODE:
! 		*dst |= RIGHT_CONTROL_BIT;
! 		break;
! #endif /* __hpux || __hp_osf */
! 	    default:
! 		break;
! 	    }
      }
  
  get_down_modifiers(dev, down_mods)
--- 1864,1873 ----
      HPInputDevice *d;
  
      d = GET_HPINPUTDEVICE (inputInfo.keyboard);
      for (i=0; i<MAX_KEY_MODS; i++, src++)
! 	if (*src != 0xff)
! 	    *dst |= inputInfo.keyboard->key->modifierMap[(*src+8)];
!     return;
      }
  
  get_down_modifiers(dev, down_mods)
***************
*** 2908,3212 ****
      unsigned char *down_mods;
      {
      u_char *kptr = dev->key->down;
- 
- #if defined(__hpux) || defined(__hp_osf)
-     HPInputDevice *d;
- 
-     d = GET_HPINPUTDEVICE (dev);
-     if (d->id_detail & HP_HIL)
- 	*down_mods = kptr[1] & 0x7d;	/* mask off break and repeat cursor */
-     else
- 	*down_mods = dev->key->state;	/* get X modifier bits 		    */
- #endif /* __hpux */
- #ifdef __apollo
-     *down_mods = 0;
-     if (kptr[9] & 0x08)
- 	*down_mods |= LEFT_CONTROL_BIT;
-     if (kptr[12] & 0x40)
- 	*down_mods |= LEFT_SHIFT_BIT;
-     if (kptr[14] & 0x04)
- 	*down_mods |= RIGHT_SHIFT_BIT;
-     if (kptr[15] & 0x80)
- 	*down_mods |= RIGHT_MOD1_BIT;
-     if (kptr[15] & 0x20)
- 	*down_mods |= LEFT_MOD1_BIT;
- #endif /* __apollo */
-     }
- 
- #ifdef __apollo
- 
- DisableAllInput ()
-     {
-     register DeviceIntPtr dev, next;
-     HPInputDevice *d;
- 
- 
-     for (dev = inputInfo.devices; dev; dev = next)
- 	{
- 	next = dev->next;
- 	d = GET_HPINPUTDEVICE (dev);
- 	RemoveEnabledDevice( d->file_ds);
- 	}
-     }
- 
- EnableAllInput ()
-     {
-     register DeviceIntPtr dev, next;
      HPInputDevice *d;
  
!     for (dev = inputInfo.devices; dev; dev = next)
! 	{
! 	next = dev->next;
! 	if (dev->inited && dev->startup)
! 	    {
! 	    d = GET_HPINPUTDEVICE (dev);
! 	    AddEnabledDevice( d->file_ds);
! 	    }
! 	}
      }
  
- int xosWindowPrivateIndex;
- 
- #endif /* __apollo */
- 
  /*****************************************************************************
   *
!  * Dynamically load drivers to support non-HIL input devices.
   *
   */
  
! init_dynamic_devs(opendevs, numdev)
!     struct	opendevs opendevs [];
!     int		numdev;
!     {
!     int i, j, k, fd, sndx=0;
!     HPInputDeviceHeader dhdr;
!     Bool keyboard_is_pointer = FALSE;
!     Bool (*driverInit)();
!     shl_t ldr_module_id;
!     long ldr_module_entry;
!     int ret_val;
!     char driver_path[255], driver_init[255];
  
     /*
      * See if we can access a DIN mouse and keyboard.  If so, we need to load
!     * a driver to support them.
      *
      */
  
!     find_din_kbd_use(opendevs, &keyboard_is_pointer, &numdev, &sndx);
!     find_din_mouse_use(&keyboard_is_pointer, &numdev, &sndx);
  
     /*
!     * For each device, 
!     *     1). find an available device private struct,
!     *     2). make sure the user has told us the device path and use,
!     *     3). make sure the driver knows about this device,
!     *     4). call the driver to open and configure it.
      */
  
!     for (i=0; i<numdev; i++)
! 	{
! 	if (!serial[i].name[0])
! 	    continue;
  
! 	strcpy (driver_path, DRVRLIBDIR);
! 	strcat (driver_path, serial[i].name);
! #if defined(__hp9000s300)
! 	strcpy (driver_init, "_");
! 	strcat (driver_init, serial[i].entry);
! #else
! 	strcpy (driver_init, serial[i].entry);
! #endif /* __hp9000s300 */
  
! 	for (j=0; j<num_serial_devices; j++)
! 	    if (strcmp (serialprocs[j].driver_name, serial[i].name)==0)
! 		break;
! 	if (j==num_serial_devices)   /* this driver wasn't previously loaded */
! 	    {
! 	    /*
! 	     * Dynamically load the driver.
! 	     */
  
! 	    ldr_module_id = shl_load( driver_path, BIND_IMMEDIATE, 0L);
  
! 	    if ( ldr_module_id == NULL ) 
! 		{
! 		ErrorF ("Failed to load serial input device driver %s, errno %d\n",
! 		    driver_path, errno);
! 		ErrorF ("Check spelling and case of device name.\n");
! 		continue;
! 		}
! 	    }
! 	else
! 	    ldr_module_id = serialprocs[j].ldr_module_id;
  
! 	sndx = j;
  
! 	/*
! 	 * Now look for the main entry point by name.
! 	 */
  
! 	ret_val = shl_findsym( &ldr_module_id, driver_init, TYPE_PROCEDURE,
!                           &ldr_module_entry );
! 	if ( ret_val ) 
! 	    {
! 	    ErrorF ("Couldn't find main entry point %s in serial input device driver %s, retval is %x\n",
! 		driver_init, driver_path, ret_val);
! 	    ErrorF ("Check spelling and case of device name and entrypoint.\n");
! 	    continue;
! 	    }
  
! 	/*
! 	 * Call that entry point to initialize driver.
! 	 */
! 
! 	driverInit = (pfrb) ldr_module_entry;
! 	ret_val = (*driverInit)(&serialprocs[sndx]);
! 	if (ret_val!=INIT_SUCCESS)
! 	    {
! 	    ErrorF ("Couldn't initialize serial input device driver %s\n",
! 		driver_path);
! 	    continue;
! 	    }
  
! 	dhdr = zdhdr;
! 	dhdr.file_ds = HP_VENDOR_RELEASE_NUMBER;
! 	strcpy (dhdr.path, serial[i].path);
! 	if (button_chording == CHORDING_ON)
! 	    dhdr.button_chording = 100;
! 	button_3 = 0;
! 	if ((*(serialprocs[sndx].configure))(&dhdr) == INIT_SUCCESS)
! 	    {
  
! 	    for (k=MAX_DEVICES-1; l_devs[k].hil_header.id != 1 && k>=0; k--)
! 	        ;
! 	    if (k<0)
! 	        for (k=MAX_DEVICES-1; (l_devs[k].hpflags & OPEN_THIS_DEVICE) && k>=0; k--)
! 	        ;
! 	    serialprocs[sndx].fd = dhdr.file_ds;
! 	    serialprocs[sndx].keymap_name = dhdr.keymap_name;
! 	    serialprocs[sndx].keymap_file = dhdr.keymap_file;
! 	    serialprocs[sndx].feedbacks = dhdr.feedbacks;
! 	    serialprocs[sndx].num_fdbk = dhdr.num_fdbk;
! 	    serialprocs[sndx].strf = dhdr.strf;
! 	    serialprocs[sndx].num_strf = dhdr.num_strf;
! 	    serialprocs[sndx].ledf = dhdr.ledf;
! 	    serialprocs[sndx].num_ledf = dhdr.num_ledf;
! 	    strcpy(l_devs[k].x_name, dhdr.x_name);
! 	    l_devs[k].x_atom = MakeAtom (dhdr.x_name, strlen(dhdr.x_name),0);
! 	    if (!l_devs[k].x_atom)
! 	        l_devs[k].x_atom = MakeAtom(dhdr.x_name, strlen(dhdr.x_name),1);
! 	    x_init_dynamic_device(&l_devs[k], &dhdr);
! 	    l_devs[k].sndx = sndx;
! 	    if (serial[i].use==XPOINTER)
! 		{
! 		if (hpPointer && hpPointer->file_ds != -1)
! 		    {
! 		    close (hpPointer->file_ds);
! 		    for (j=0, fd=hpPointer->file_ds; j<MAX_DEVICES; j++)
! 			if (l_devs[j].file_ds == fd)
! 			    l_devs[j].file_ds = -1;
! 		    }
! 		hpPointer = &l_devs[k];
! 		}
! 	    else if (serial[i].use==XKEYBOARD)
! 		{
! 		if (hpKeyboard && hpKeyboard->file_ds != -1)
! 		    {
! 		    close (hpKeyboard->file_ds);
! 		    for (j=0, fd=hpKeyboard->file_ds; j<MAX_DEVICES; j++)
! 			if (l_devs[j].file_ds == fd)
! 			    l_devs[j].file_ds = -1;
! 		    }
  
! 		hpKeyboard = &l_devs[k];
! 		if (dhdr.reset)
! 		    {
! 		    reset = dhdr.reset;
! 		    rs_mods = dhdr.reset_mods;
! 		    }
! 		}
! 	    if (serial[i].use==XOTHER+1)
! 		{
! 		serialprocs[sndx].close(dhdr.file_ds);
! 		serialprocs[sndx].fd = -1;
! 		}
! 	    else
! 		{
! 		if (serial[i].use==XOTHER) {
! 	            l_devs[k].hpflags |= MERGED_DEVICE;
! 	            l_devs[k].open_cnt = 1;
! 		    }
! 	        l_devs[k].file_ds = dhdr.file_ds;
! 		if (dhdr.file_ds > max_input_fd)
! 		    max_input_fd = dhdr.file_ds;
  
! 		if (keyboard_is_pointer)
! 		    {
! 		    hpKeyboard->hpflags |= SECOND_LOGICAL_DEVICE;
! 		    l_devs[spare+1] = *hpKeyboard;
! 		    hpPointer = &l_devs[spare+1];
! 		    }
! 		}
! 	    if (sndx==num_serial_devices)
! 		{
! 	        strcpy (serialprocs[sndx].driver_name, serial[i].name);
! 		serialprocs[sndx].ldr_module_id = ldr_module_id;
! 		num_serial_devices++;
! 		}
! 	    }
! 	else
! 	    ErrorF ("Couldn't initialize serial input device %s\n",
! 		serial[i].name);
  	}
!     if (!hpPointer)
! 	FatalError ("Couldn't open X pointer device!  Is there one attached?\n");
!     if (!hpKeyboard)
! 	FatalError ("Couldn't open X keyboard!  Is there one attached?\n");
      }
  
! #define DYNAMIC_DEVICE 	0xffff
! x_init_dynamic_device(d, dhdr)
!  HPInputDevice *d;
!  HPInputDeviceHeader *dhdr;
!  {
!  strcpy (d->dev_name, dhdr->path);
!  d->hil_header.resx = dhdr->resolution * 100;
!  d->hil_header.resy = dhdr->resolution * 100;
!  d->hil_header.size_x = dhdr->max_x;
!  d->hil_header.size_y = dhdr->max_y;
!  d->hil_header.ax_num = dhdr->ax_num;
!  if (dhdr->ax_num)
!  	d->x_type = MOUSE;
!  d->hil_header.num_keys = dhdr->num_keys;
!  if (dhdr->num_keys)
!  	d->x_type = KEYBOARD;
!  d->hil_header.p_button_count = dhdr->num_buttons;
!  d->hil_header.v_button_count = dhdr->num_buttons;
!  if (dhdr->num_ledf)
!      d->hil_header.iob |= HAS_LEDS;
! 
!  if (dhdr->flags & ABSOLUTE_DATA)
!     {
!     d->mode = ABSOLUTE;
!     d->hil_header.flags = HIL_ABSOLUTE;
!     }
!  else
!     d->mode = RELATIVE;
! 
!  if (dhdr->flags & REPORTS_PROXIMITY)
!     d->hil_header.iob = HILIOB_PIO;
! 
!  d->hpflags = IS_SERIAL_DEVICE;
!  if (d->file_ds)
!      d->hpflags |= OPEN_THIS_DEVICE;
!  d->hpflags |= (dhdr->flags & DATA_SIZE_BITS);
! 
!  d->dev_type = DYNAMIC_DEVICE;
!  d->hil_header.id = 0;
!  d->id_detail &= ~HP_HIL;
  }
  /******************************************************************************
   *
   * shl_driver_load() is passed the path of a shared library to load, and the
--- 1875,2117 ----
      unsigned char *down_mods;
      {
      u_char *kptr = dev->key->down;
      HPInputDevice *d;
  
!     *down_mods = dev->key->state;	/* get X modifier bits 		    */
      }
  
  /*****************************************************************************
   *
!  * Dynamically load drivers to support input devices.
   *
   */
  
! #define DYNAMIC_DEVICE 	0xffff
! #define HIL_DRIVER	"hil_driver.sl"
! #define HILDRVR_ENTRY	"hil_driver_Init"
! FILE	*fp;
! 
! init_dynamic_devs(devs)
!     HPInputDevice *devs;
! {
!     int i, keyboard_is_pointer = FALSE;
!     HPInputDevice *d;
!     Bool (*driverInit)() = NULL, null_needed = FALSE;
!     char fname[MAXNAMLEN];
! 
!    /*
!     * Check the X*devices file for NULL device specifications.  If they are
!     * specified, we need to load the HIL driver to support them.
!     *
!     */
! 
!     is_null_needed(&null_needed, &keyboard_is_pointer);
  
     /*
      * See if we can access a DIN mouse and keyboard.  If so, we need to load
!     * a driver to support them.  The DIN devices will be used as the X pointer
!     * and keyboard unless some other device is explicitly specified.
      *
      */
  
!     find_din_kbd_use(keyboard_is_pointer);
!     find_din_mouse_use(&keyboard_is_pointer);
  
     /*
!     * Check to see if this machine supports HIL devices.
!     * If so, load the driver and call it to process the X0devices file
!     * for old-style syntax.
      */
  
!     sprintf(fname, "%s/X%sdevices",LIBDIR, display);
!     if (((fp = fopen(BEEPER_DEVICE,"r")) != NULL) || null_needed) {
! 	fclose (fp);
! 	d = next_device_private();
!         sprintf(d->driver_name, "%s/%s",DRVRLIBDIR,HIL_DRIVER);
! 	sprintf(d->d.path,"X*devices:Recycle:%s",fname);
!         strcpy (d->entry, HILDRVR_ENTRY);
  
!     	load_and_init_dev (d, &driverInit, TRUE);
  
!     /*
!      * The request to recycle the HIL input device state does not return
!      * a valid input device.  It is normally reused, but not if there are
!      * no HIL input devices attached.  Clear it to make sure it is treated 
!      * as uninitialized.
!      */
  
! 	clear_device_private(d);
  
! 	if (d->d.reserved[3] && (!hpPointer || hpPointer->dev_type != KEYBOARD))
! 	    keyboard_is_pointer = TRUE;
  
! 	for (i=0; i<MAX_DEVICES; i++) {
! 	    sprintf(d->d.path,"X*devices:");
!     	    if (load_and_init_dev (d, &driverInit, FALSE))
! 		break;
! 	    if (!(d=next_device_private()))
! 	        break;
! 	}
!     } 
  
!    /*
!     * Now process the X*devices configuration file for new-style entries.
!     * These specify dynamically loaded input device drivers.
!     * If the system doesn't support HIL devices, get_next_device will
!     * return any explicitly specified dynamically loaded input devices.
!     */
  
!     fp = fopen ( fname, "r");
!     if (fp) {
! 	if (d=next_device_private()) {
! 	  while (get_next_device (fp,d)) {
!     	    driverInit = NULL;
!     	    load_and_init_dev (d, &driverInit, TRUE);
! 	    if (!(d=next_device_private()))
! 	        break;
! 	  }
! 	}
!       fclose(fp);
!       }
  
!     if (!hpPointer)
! 	FatalError ("Couldn't open X pointer device!  Is one attached?\n");
!     if (!hpKeyboard)
! 	FatalError ("Couldn't open X keyboard!  Is one attached?\n");
!     if (tablet_width)
! 	fix_tablet_subsetting();
! }
  
! /*****************************************************************************
!  *
!  * Initialize the input device private structure.
!  *
!  */
  
! char *x_basename (name)
!     char *name;
!     {
!     int i;
!     char *nptr = strchr (name, '_');
!     char *ordinal[] = {"FIRST", "SECOND", "THIRD", "FOURTH",
! 			"FIFTH", "SIXTH", "SEVENTH"};
  
!     if (!nptr)
! 	return (name);
  
!     for (i=0; i<7; i++)
! 	if (!strncmp(name, ordinal[i], strlen(ordinal[i])))
! 	    return(++nptr);
!     return (name);
!     }
! 
! close_default_device (thisDev, otherDev)
!     HPInputDevice *thisDev, *otherDev;
!     {
!     int i, fd;
! 
!     if (otherDev && (otherDev->d.file_ds != thisDev->d.file_ds))
!         {
!         thisDev->s.close(thisDev->d.file_ds);
! 	for (i=0, fd=thisDev->d.file_ds; i<MAX_DEVICES; i++)
! 	    if (l_devs[i].d.file_ds == fd)
! 	        l_devs[i].d.file_ds = -1;
!         }
!     else
! 	{
!         thisDev->id = UNINITIALIZED;
! 	thisDev->driver_name[0] = '\0';
! 	thisDev->d.x_name = NULL;
  	}
!     thisDev->d.file_ds = -1;
      }
  
! init_device_private (d, close)
!     HPInputDevice *d;
!     Bool close;
!     {
!     int j, fd;
!     HPInputDeviceHeader *dh = &(d->d);
!     char *nptr;
! 
!     if (dh->file_ds == HP_VENDOR_RELEASE_NUMBER)
! 	{
! 	clear_device_private (d);
! 	return;
! 	}
!     nptr = x_basename (dh->x_name);
!     d->x_atom = MakeAtom (nptr, strlen(nptr),0);
!     if (!d->x_atom)
!         d->x_atom = MakeAtom(nptr, strlen(nptr),1);
!     dh->resolution *= 100;
!     if (dh->num_keys)
!      	d->x_type = KEYBOARD;
!     else if (dh->ax_num)
!      	d->x_type = MOUSE;
!     else
!      	d->x_type = XOTHER;
!     if (dh->num_ledf)
!          d->iob |= HAS_LEDS;
!     if (dh->flags & REPORTS_PROXIMITY)
!         d->iob = HILIOB_PIO;
!     d->hpflags = dh->flags & ~REPORTS_PROXIMITY;
!     if (dh->file_ds >= 0)
!         d->hpflags |= OPEN_THIS_DEVICE;
!     d->hpflags |= (dh->flags & DATA_SIZE_BITS);
!     d->id_detail = SERIAL;
!     d->dev_type = DYNAMIC_DEVICE;
!     d->id = 0;
!     if (d->d.reserved[0] & HP_HIL) {
! 	d->id_detail = d->d.reserved[0];
! 	d->id = d->d.min_kcode;
! 	d->iob = d->d.max_kcode;
! 	d->dev_type = d->d.reserved[1];
! 	d->use = d->d.reserved[2];
!     }
!     if (hpPointer && ((d->use & XPTR_USE) && !(d->use & EXPLICIT)))
! 	d->use &= ~XPTR_USE;
!     if (hpKeyboard && ((d->use & XKBD_USE) && !(d->use & EXPLICIT)))
! 	d->use &= ~XKBD_USE;
!     if (!d->use)
! 	d->use = XEXT_USE;
! 
!     if (d->use & XPTR_USE)
! 	{
! 	if (hpPointer)
! 	    close_default_device (hpPointer, hpKeyboard);
! 	hpPointer = d;
! 	}
!     if (d->use & XKBD_USE)
! 	{
! 	HPInputDevice *d2;
!         if (d->use & XPTR_USE && (d2=next_device_private()))
! 	    {
! 	    *d2 = *d;
! 	    d->use = XKBD_USE;
! 	    d->hpflags |= SECOND_LOGICAL_DEVICE;
! 	    hpPointer = d2;
! 	    hpPointer->use = XPTR_USE;
! 	    }
! 	if (hpKeyboard)
! 	    close_default_device (hpKeyboard, hpPointer);
! 	hpKeyboard = d;
! 	if (dh->reset)
! 	    {
! 	    reset = dh->reset;
! 	    rs_mods = dh->reset_mods;
! 	    }
! 	}
!     if ((d->use & XEXT_USE) && close)
! 	{
! 	d->s.close(dh->file_ds);
! 	dh->file_ds = -1;
! 	}
!     if (d->use & XOTH_USE)
!         d->hpflags |= MERGED_DEVICE;
!     if (dh->file_ds > max_input_fd)
! 	max_input_fd = dh->file_ds;
  }
+ 
  /******************************************************************************
   *
   * shl_driver_load() is passed the path of a shared library to load, and the
***************
*** 3257,3263 ****
      *
      * Load driver into the current VA space.
      */
!    ldr_module_id = shl_load( driver_path, (BIND_IMMEDIATE | BIND_VERBOSE), 0L );
  
     if ( ldr_module_id == NULL )
  	FatalError ("X server failed to load shared library %s, errno is %d\n", 
--- 2162,2168 ----
      *
      * Load driver into the current VA space.
      */
!    ldr_module_id = shl_load( driver_path, (BIND_DEFERRED | BIND_VERBOSE), 0L );
  
     if ( ldr_module_id == NULL )
  	FatalError ("X server failed to load shared library %s, errno is %d\n", 
***************
*** 3288,3300 ****
  din_mouse_present()
      {
      int fd;
!     unsigned char cmdbuf[2];
  
      fd = open("/dev/ps2mouse", O_RDWR);
!     ioctl (fd, PS2_PORTSTAT, &cmdbuf[0]);
!     ioctl (fd, PS2_IDENT, &cmdbuf[1]);
      close (fd);
!     if (cmdbuf[0] != 1 || cmdbuf[1] != 0)
  	return FALSE;
      return TRUE;
      }
--- 2193,2207 ----
  din_mouse_present()
      {
      int fd;
!     struct ps2_4 statbuf, idbuf;
  
      fd = open("/dev/ps2mouse", O_RDWR);
!     if (fd < 0)
! 	return FALSE;
!     ioctl (fd, PS2_PORTSTAT, &statbuf);
!     ioctl (fd, PS2_IDENT, &idbuf);
      close (fd);
!     if (statbuf.b[0] != PS2_MOUSE || idbuf.b[0] != 0)
  	return FALSE;
      return TRUE;
      }
***************
*** 3305,3338 ****
   *
   */
  
! find_din_mouse_use(keyboard_is_pointer, numdev, sndx)
!     int *keyboard_is_pointer, *numdev, *sndx;
      {
  
      if (!din_mouse_present())          		/* no DIN mouse attached */
  	{
  	if (!hpPointer || 			/* no HIL pointer device */
! 	     (hpPointer->dev_type != MOUSE &&	/* or it's not a motion device  */
! 	     hpPointer->pad2 != EXPLICIT_DEV))	/* and not explicitly specified */
  	    *keyboard_is_pointer = TRUE;
  	return;
  	}
  
!     if ((serial[XPOINTER].name[0] != '\0') || 	   /* RS232 pointer specified */
! 	(hpPointer && hpPointer->pad2 == EXPLICIT_DEV)||/* HIL ptr specified  */
! 	*keyboard_is_pointer)
! 	{
! 	*sndx = (*numdev)++;
! 	serial[*sndx].use = XOTHER+1;
! 	}
      else
! 	{
! 	*sndx = XPOINTER;
! 	serial[*sndx].use = XPOINTER;
! 	}
!     strcpy (serial[*sndx].name, "hp7lc2m.sl");
!     strcpy (serial[*sndx].entry, "hp7lc2m_Init");
!     strcpy (serial[*sndx].path, "/dev/ps2mouse");
      }
  
  /***********************************************************************
--- 2212,2246 ----
   *
   */
  
! find_din_mouse_use(keyboard_is_pointer)
!     int *keyboard_is_pointer;
      {
+     HPInputDevice *d;
+     Bool (*driverInit)() = NULL;
  
      if (!din_mouse_present())          		/* no DIN mouse attached */
  	{
  	if (!hpPointer || 			/* no HIL pointer device */
! 	     (hpPointer->dev_type != MOUSE &&	/* or it's not a motion device*/
! 	     !(hpPointer->use & EXPLICIT)))	/* and not explicitly named   */
  	    *keyboard_is_pointer = TRUE;
  	return;
  	}
  
!     if (!(d=next_device_private()))		    /* too many devices */
! 	return;
! 
!     if ((hpPointer && hpPointer->use & EXPLICIT) || *keyboard_is_pointer)
! 	d->use = XEXT_USE; 			/* explicit ptr specified  */
      else
! 	d->use = XPTR_USE;
! 
!     sprintf(d->driver_name, "%s/%s", DRVRLIBDIR, DIN_MOUSE_DRVR);
!     strcpy (d->entry, DIN_MOUSE_INIT);
!     strcpy (d->d.path, DIN_MOUSE_PATH);
! 
!     load_and_init_dev (d, &driverInit, TRUE);
!     d->id_detail = PS2;
      }
  
  /***********************************************************************
***************
*** 3345,3357 ****
  din_kbd_present()
      {
      int fd;
!     unsigned char cmdbuf[2];
  
      fd = open("/dev/ps2kbd", O_RDWR);
!     ioctl (fd, PS2_PORTSTAT, &cmdbuf[0]);
!     ioctl (fd, PS2_IDENT, &cmdbuf[1]);
!     close (fd);
!     if (cmdbuf[0]!=2 && cmdbuf[1]!=0xab && cmdbuf[2]!=0x83) /* no DIN kbd  */
  	return FALSE;
      return TRUE;
      }
--- 2253,2268 ----
  din_kbd_present()
      {
      int fd;
!     struct ps2_4 statbuf, idbuf;
  
      fd = open("/dev/ps2kbd", O_RDWR);
!     if (fd < 0)
! 	return FALSE;
!     ioctl (fd, PS2_PORTSTAT, &statbuf);
!     ioctl (fd, PS2_IDENT, &idbuf);
! 	close (fd);
!     if (statbuf.b[0]!=PS2_KEYBD && 
! 	idbuf.b[0]!=0xab && idbuf.b[1]!=0x83) /* no DIN kbd*/
  	return FALSE;
      return TRUE;
      }
***************
*** 3362,3407 ****
   *
   */
  
! find_din_kbd_use(opendevs, keyboard_is_pointer, numdev, sndx)
!     struct	opendevs opendevs [];
!     int *keyboard_is_pointer, *numdev, *sndx;
      {
  
      if (!din_kbd_present())				/* no DIN kbd  */
  	return;
  
!     if ((serial[XKEYBOARD].name[0]!='\0') ||           /* RS232 kbd specified */
! 	(hpKeyboard && hpKeyboard->pad2 == EXPLICIT_DEV))/* HIL kbd specified */
! 	{
! 	*sndx = (*numdev)++;
! 	serial[*sndx].use = XOTHER+1;
! 	}
      else
! 	{
! 	*sndx = XKEYBOARD;
! 	serial[*sndx].use = XKEYBOARD;
! 	}
!     if (opendevs[XPOINTER].type == KEYBOARD && opendevs[XPOINTER].pos == 0)
! 	*keyboard_is_pointer = TRUE;
  
!     strcpy (serial[*sndx].name, "hp7lc2k.sl");
!     strcpy (serial[*sndx].entry, "hp7lc2k_Init");
!     strcpy (serial[*sndx].path, "/dev/ps2kbd");
      }
  
! char *x_basename (name)
!     char *name;
!     {
!     int i;
!     char *nptr = strchr (name, '_');
!     char *ordinal[] = {"FIRST", "SECOND", "THIRD", "FOURTH", "FIFTH", "SIXTH", 
! 	"SEVENTH"};
  
!     if (!nptr)
! 	return (name);
  
!     for (i=0; i<7; i++)
! 	if (!strncmp(name, ordinal[i], strlen(ordinal[i])))
! 	    return(++nptr);
!     return (name);
      }
--- 2273,2335 ----
   *
   */
  
! find_din_kbd_use(keyboard_is_pointer)
!     int keyboard_is_pointer;
      {
+     Bool (*driverInit)() = NULL;
+     HPInputDevice *d;
  
      if (!din_kbd_present())				/* no DIN kbd  */
  	return;
  
!     if (!(d=next_device_private()))		    /* too many devices */
! 	return;
! 
!     if (hpKeyboard && hpKeyboard->use & EXPLICIT)  /* kbd explicitly spec'd */
! 	d->use = XEXT_USE;
      else
! 	d->use = XKBD_USE;
! 
!     if (keyboard_is_pointer)
! 	d->use |= XPTR_USE;
  
!     sprintf(d->driver_name, "%s/%s", DRVRLIBDIR, DIN_KBD_DRVR);
!     strcpy (d->entry, DIN_KBD_INIT);
!     strcpy (d->d.path, DIN_KBD_PATH);
! 
!     load_and_init_dev (d, &driverInit, TRUE);
!     d->id_detail = PS2 | PC101_KBD;
      }
  
! /***********************************************************************
!  *
!  * load_and_init_dev
!  *
!  */
  
! load_and_init_dev (d, driverInit, fatal)
!     HPInputDevice *d;
!     Bool (**driverInit)();
!     Bool fatal;
!     {
!     int ret_val;
!     void *(*foo)();
  
!     if (! *driverInit)
!          *driverInit = shl_driver_load(d->driver_name, d->entry, &foo, "x");
!     ret_val = (**driverInit)(&(d->s)); 		/* Initialize driver. */
!     if (ret_val!=INIT_SUCCESS)
!         FatalError ("Couldn't initialize input device driver %s\n", 
! 	    d->driver_name);
!     if ((*(d->s.configure)) (&(d->d))!=INIT_SUCCESS)
!         if (fatal)
!             FatalError ("Couldn't configure input device driver %s\n", 
! 	        d->driver_name);
! 	else
! 	    {
! 	    clear_device_private (d);
! 	    return 1;
! 	    }
!     init_device_private (d, TRUE);
!     return 0;
      }
*** -	Wed Jan 25 18:48:22 1995
--- xc/programs/Xserver/hw/hp/input/X11/XHPlib.h	Wed Jan 25 18:48:21 1995
***************
*** 1,32 ****
! #ifndef XHPLIB_H
! #define XHPLIB_H
! /* $XConsortium: XHPlib.h,v 1.1 93/08/08 12:58:15 rws Exp $ */
! /*
  
! Copyright (c) 1986, 1987 by Hewlett-Packard Company
  
! Permission to use, copy, modify, and distribute this
! software and its documentation for any purpose and without
! fee is hereby granted, 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 Hewlett Packard not be used in
! advertising or publicity pertaining to distribution of the
! software without specific, written prior permission.
  
! HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
! TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE.  Hewlett-Packard shall not be liable for errors
! contained herein or direct, indirect, special, incidental or
! consequential damages in connection with the furnishing,
! performance, or use of this material.
! 
! This software is not subject to any license of the American
! Telephone and Telegraph Company or of the Regents of the
! University of California.
  
- */
  /* Definitions used by Xlib and the client */
  
  #include "XHPproto.h"
--- 1,30 ----
! /* $XConsortium: XHPlib.h,v 1.3 95/01/24 23:40:16 gildea Exp $ */
! /************************************************************
! Copyright (c) 1992 by Hewlett-Packard Company, Palo Alto, California.
! 
! 			All Rights Reserved
! 
! Permission to use, copy, modify, and distribute this software and its
! documentation for any purpose and without fee is hereby granted,
! 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 Hewlett-Packard not be
! used in advertising or publicity pertaining to distribution of the
! software without specific, written prior permission.
  
! HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
! ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
! HEWLETT-PACKARD 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.
  
! ********************************************************/
  
! #ifndef XHPLIB_H
! #define XHPLIB_H
  
  /* Definitions used by Xlib and the client */
  
  #include "XHPproto.h"
***************
*** 362,374 ****
  #define K16_NLIOSTATE  1
  #define K16_ALTSTATE   2
  
! /* The following block of defines are required for XHPSetKeyboardMapping */
  
! #define DEF_FILENAME	"XHPKeymaps"
! #define DEF_DIRECTORY	"/usr/lib/X11/"
! #define VERIFY_MAGIC	"HPKeyMap Rev 1.0"
  
! #define MAGIC_SIZE 20
  
  struct XHP_keymap_header {
      int kbd;
--- 360,379 ----
  #define K16_NLIOSTATE  1
  #define K16_ALTSTATE   2
  
!     /* The following block of defines are required for XHPSetKeyboardMapping,
!      *   the server and other things that use XHPKeymaps.
!      */
! #ifdef hpV4
! #define DEF_DIRECTORY		"/etc/X11/"
! #else
! #define DEF_DIRECTORY		"/usr/lib/X11/"
! #endif	/* hpV4 */
  
! #define SHL_DIRECTORY		"/usr/lib/X11/"
! #define DEF_FILENAME		"XHPKeymaps"
  
! #define VERIFY_MAGIC		"HPKeyMap Rev 1.0"
! #define MAGIC_SIZE		20	/* sizeof(VERIFY_MAGIC) + some slop */
  
  struct XHP_keymap_header {
      int kbd;
***************
*** 445,452 ****
  #define KB_Romanian		106	/* Romanian Keymap - NO KEYBOARD */
  #define KB_Rumanian		106	/* alternate spelling */
  #define KB_Turkish		107	/* Turkey Keymap - NO KEYBOARD */
! #define KB_Greek		108	/* Greek Keymap - NO KEYBOARD */
! #define KB_Arabic		109	/* Greek Keymap - NO KEYBOARD */
  
  
  	/* PS2 ethereal keyboards (which may never exist) */
--- 450,457 ----
  #define KB_Romanian		106	/* Romanian Keymap - NO KEYBOARD */
  #define KB_Rumanian		106	/* alternate spelling */
  #define KB_Turkish		107	/* Turkey Keymap - NO KEYBOARD */
! #define KB_Greek		108	/* Greek  Keymap - NO KEYBOARD */
! #define KB_Arabic		109	/* Arabic Keymap - NO KEYBOARD */
  
  
  	/* PS2 ethereal keyboards (which may never exist) */
***************
*** 459,466 ****
  #define KB_PS2_Romanian		156	/* Romanian Keymap - NO KEYBOARD */
  #define KB_PS2_Rumanian 	156	/* alternate spelling */
  #define KB_PS2_Turkish		157	/* Turkey Keymap - NO KEYBOARD */
! #define KB_PS2_Greek		158	/* Greek Keymap - NO KEYBOARD */
! #define KB_PS2_Arabic		159	/* Greek Keymap - NO KEYBOARD */
  
  /* ******************** HP hil PS2 keyboards *************** */
  
--- 464,471 ----
  #define KB_PS2_Romanian		156	/* Romanian Keymap - NO KEYBOARD */
  #define KB_PS2_Rumanian 	156	/* alternate spelling */
  #define KB_PS2_Turkish		157	/* Turkey Keymap - NO KEYBOARD */
! #define KB_PS2_Greek		158	/* Greek  Keymap - NO KEYBOARD */
! #define KB_PS2_Arabic		159	/* Arabic Keymap - NO KEYBOARD */
  
  /* ******************** HP hil PS2 keyboards *************** */
  
***************
*** 488,493 ****
--- 493,499 ----
  #define KB_PS2_Canada_English	84
  #define KB_PS2_Swiss_French	88
  #define KB_PS2_Japanese		89
+ #define KB_JIS_Japanese		90
  
  #define KB_NULL		201	/* Device that needs a null keymap, modmap */
  #define KB_BUTTON_BOX	202	/* HP button box(es) */
***************
*** 501,507 ****
  /* Function definitions for clients. */
  
  Status      XHPSetKeyboardMapping();
- KEYBOARD_ID XHPGetKeyboardID();
  
  /* End of entries required for XHPSetKeyboardMapping. */
  
--- 507,512 ----
*** -	Wed Jan 25 18:48:23 1995
--- xc/programs/Xserver/hw/hp/input/drivers/Imakefile	Wed Jan 25 18:48:23 1995
***************
*** 1,4 ****
! XCOMM $XConsortium: Imakefile,v 1.3 94/05/30 17:18:11 rws Exp $
  
  #include <Server.tmpl>
  
--- 1,4 ----
! XCOMM $XConsortium: Imakefile,v 1.4 95/01/24 02:38:39 dpw Exp $
  
  #include <Server.tmpl>
  
***************
*** 8,14 ****
  
  DRVRLIBDIR = $(LIBDIR)/extensions
  PICFLAGS = +z
! SRCS = hp7lc2k.c hp7lc2m.c
  
  #define DriverTarget(name)						@@\
  AllTarget(name.sl)							@@\
--- 8,16 ----
  
  DRVRLIBDIR = $(LIBDIR)/extensions
  PICFLAGS = +z
! SRCS = hp7lc2k.c hp7lc2m.c hil_driver.c
! INCLUDES = -I. -I.. -I../../../../../../include \
!            -I../../../../../../include/extensions
  
  #define DriverTarget(name)						@@\
  AllTarget(name.sl)							@@\
***************
*** 21,31 ****
--- 23,36 ----
  	$(MV) $@~ $@							@@\
  									@@\
  InstallTarget(install,name.sl,$(INSTPGMFLAGS),$(DRVRLIBDIR))		@@\
+ InstallTarget(install,XHPKeymaps,$(INSTPGMFLAGS),$(LIBDIR))		@@\
+ InstallTarget(install,X0screens,$(INSTPGMFLAGS),$(LIBDIR))		@@\
  									@@\
  clean::									@@\
  	$(RM) name.sl
  
  DriverTarget(hp7lc2k)
  DriverTarget(hp7lc2m)
+ DriverTarget(hil_driver)
  
  DependTarget()
*** /dev/null	Wed Jan 25 18:48:25 1995
--- xc/programs/Xserver/hw/hp/input/drivers/X0screens	Wed Jan 25 18:48:25 1995
***************
*** 0 ****
--- 1,3 ----
+ # $XConsortium: X0screens,v 1.1 95/01/23 21:56:39 dpw Exp $
+ 
+ /dev/crt
*** /dev/null	Wed Jan 25 18:48:35 1995
--- xc/programs/Xserver/hw/hp/input/drivers/hil_driver.c	Wed Jan 25 18:48:35 1995
***************
*** 0 ****
--- 1,3582 ----
+ /* $XConsortium: hil_driver.c,v 1.2 95/01/25 17:24:43 gildea Exp $ */
+ /************************************************************
+ 
+ Copyright (c) 1993 by Hewlett-Packard Company, Palo Alto, California
+ 
+ 			All Rights Reserved
+ 
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ 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 Hewlett-Packard not be
+ used in advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+ 
+ HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ HEWLETT-PACKARD 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.
+ 
+ ********************************************************/
+ /* 
+ cc -DTEST -g hil_driver.c -Aa -D_HPUX_SOURCE -I.. -I/usr/include/X11R5/X11 -I/usr/include/X11R5/X11/extensions
+ 
+ cc +z -c -O hil_driver.c -Aa -D_HPUX_SOURCE -I.. -I/usr/include/X11R5/X11 -I/usr/include/X11R5/X11/extensions
+ ld -b hil_driver.o -o hil_driver.sl
+ cp hil_driver.sl /usr/lib/X11/extensions
+ 
+ In /etc/X11/X0devices:
+    first NULL keyboard
+    Begin_Device_Description
+    name hil_driver.sl
+    use keyboard
+    path keyboard
+    End_Device_Description
+ 
+    Begin_Device_Description
+    name hil_driver.sl
+    use pointer
+    path mouse
+    End_Device_Description
+ 
+  */
+ 
+ static char what[] = "@(#)hil_driver : HIL device driver for X v1.0";
+ #define WHAT (&what[4])
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <fcntl.h>
+ #include <sys/hilioctl.h>
+ #include "x_serialdrv.h"
+ #include "X.h"
+ #include "XI.h"
+ 
+ #ifndef TRUE
+ #define TRUE  1
+ #define FALSE 0
+ #endif
+ 
+ #define XOTHER		2	/* not defined in XI.h */
+ #define XEXTENSION	3	/* not defined in XI.h */
+ 
+ #define XPTR_USE	(1<<XPOINTER)
+ #define XKBD_USE	(1<<XKEYBOARD)
+ #define XOTH_USE	(1<<XOTHER)
+ #define XEXT_USE	(1<<XEXTENSION)
+ #define EXPLICIT	0x80
+ 
+ 
+ /* ******************************************************************** */
+ /* ******************* Misc Routines and Constants ******************** */
+ /* ******************************************************************** */
+ 
+ static int imin(a,b) register int a,b; { return (a < b) ? a : b; }
+ static int imax(a,b) register int a,b; { return (a > b) ? a : b; }
+ 
+ static void uppercase(str) char *str;	/* convert str to upper case */
+   { for (; *str; str++) *str = toupper(*str); }
+ 
+ #define NITEMS(array) (sizeof(array)/sizeof(array[0]))
+ 
+ static int remap[] = {0,1,4,5,2,3,6,7,8,9,10,11,12,13,14,15};
+ 
+ static char *h_position[] = 
+ {
+   "FIRST",
+   "SECOND",
+   "THIRD",
+   "FOURTH",
+   "FIFTH",
+   "SIXTH",
+   "SEVENTH",
+   "EIGHTH",
+   "NINTH",
+   "TENTH",
+   "ELEVENTH",
+   "TWELFTH",
+   "THIRTEENTH",
+   "FOURTEENTH",
+   "FIFTEENTH",
+   "SIXTEENTH",
+   "SEVENTEENTH",
+   "EIGHTEENTH",
+   "NINETEENTH",
+   "TWENTIETH",
+   "LAST"
+ };
+ 
+ /* ******************************************************************** */
+ /* ************************** HIL Constants *************************** */
+ /* ******************************************************************** */
+ 
+ typedef struct
+ {
+   int hil_id_low, hil_id_high;
+   char *X_name;
+   int dev_type, x_type;
+   int  (*read_device)();
+   int reverse_y_axes;
+   int  (*write_device)();
+ } HIL_DeviceType;
+ 
+ #define NULL_DEVICE		0
+ #define MOUSE			1
+ #define TABLET			2
+ #define KEYBOARD		3
+ #define QUADRATURE		4
+ #define TOUCHSCREEN		5
+ #define TOUCHPAD		6
+ #define BUTTONBOX		7
+ #define BARCODE			8
+ #define ONE_KNOB    		9
+ #define TRACKBALL		10
+ #define KEYPAD   		11
+ #define NINE_KNOB    		12
+ #define ID_MODULE 		13
+ 
+ #ifdef DEBUG
+ #define ONE_AXIS		14
+ #define NO_IOB_REL		15
+ #define ERROR_DEVICE		16
+ #define NO_AXES 		17
+ #define THREE_AXES 		18
+ #define XI_ONE_AXIS		"ONE_AXIS"
+ #define XI_NO_IOB_REL		"NO_IOB_REL"
+ #define XI_ERROR_DEVICE		"ERROR_DEVICE"
+ #define XI_NO_AXES     		"NO_AXES"
+ #define XI_THREE_AXES     	"THREE_AXES"
+ #endif /* DEBUG */
+ 
+ 
+ #define	NINE_KNOB_ID		0x61
+ #define	QUAD_ID			0x62	/* one of the quadrature ids */
+ 
+ static int
+   read_keyboard(),  read_nothing(), read_mouse(), read_barcode(),
+   write_keyboard(), write_nothing();
+ 
+ 	/* Notes:
+ 	 *   Only support button boxes with HIL ids of 0x30.  Ignore the
+ 	 *     rest of them because I don't think they exist.
+ 	 */
+ static HIL_DeviceType devices[] =
+ {
+   {	/* !!!??? */	/* This MUST remain the first device in this list! */
+     -1,-1,     "NULL",		NULL_DEVICE,	XOTHER,
+     read_nothing,	FALSE, write_nothing,
+   },
+   {
+     0x30,0x30, XI_BUTTONBOX,	BUTTONBOX,	KEYBOARD,
+     read_keyboard,	TRUE, write_keyboard,
+   },
+   {
+     0x34,0x34, XI_ID_MODULE,	 ID_MODULE,	KEYBOARD,
+     read_nothing,	FALSE, write_nothing,
+   },
+   {
+     0x5c,0x5f, XI_BARCODE,	BARCODE,	KEYBOARD,
+     read_barcode,	FALSE, write_nothing,
+   },
+   {
+     0x60,0x60, XI_ONE_KNOB,	ONE_KNOB,	MOUSE,
+     read_mouse,		FALSE, write_nothing,
+   },
+   {
+     0x61,0x61, XI_NINE_KNOB,	NINE_KNOB,	MOUSE,
+     read_mouse, 	FALSE, write_nothing,
+   },
+   {
+     0x62,0x67, XI_QUADRATURE,	QUADRATURE,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x68,0x6b, XI_MOUSE,	MOUSE,		MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x6c,0x6f, XI_TRACKBALL,	TRACKBALL,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+ #ifdef DEBUG
+   {
+     0x70,0x70, XI_ONE_AXIS,	ONE_AXIS,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x71,0x71, XI_NO_IOB_REL,	NO_IOB_REL,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x72,0x72, XI_MOUSE,	MOUSE,		MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x73,0x73, XI_ERROR_DEVICE,	ERROR_DEVICE,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x74,0x74, XI_NO_AXES,	NO_AXES,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+   {
+     0x75,0x75, XI_THREE_AXES,	THREE_AXES,	MOUSE,
+     read_mouse,		TRUE, write_nothing,
+   },
+ #endif /* DEBUG */
+   {
+     0x8c,0x8f, XI_TOUCHSCREEN,	TOUCHSCREEN,	MOUSE,
+     read_mouse,		FALSE, write_nothing,
+   },
+   {
+     0x90,0x97, XI_TABLET,	TABLET,		MOUSE,
+     read_mouse,		FALSE, write_nothing,
+   },
+   {
+     0xC0,0xDF, XI_KEYBOARD,	KEYBOARD,	KEYBOARD,
+     read_keyboard,	FALSE, write_keyboard,
+   },
+ };
+ 
+ 
+ 	/* HIL Poll Header bits: */
+ #define KEY_DATA_MASK 		0x70
+ #define MOTION_MASK 		0x0F	/* !!!??? 0x3??? */
+ #define MOTION_Y 		0x02	/* Axes Y reporting */
+ #define MOTION_XY 		0x02	/* Axes X and Y reporting */
+ #define MOTION_XYZ 		0x03	/* Axes X, Y and Z reporting */
+ 
+ #define KEY_DOWN(key)		((key) & ~1)
+ #define KEY_UP(key)		((key) | 1)
+ #define KEY_IS_DOWN(key)	(0 == ((key) & 1))	/* down is even */
+ #define KEY_IS_UP(key)		!KEY_IS_DOWN(key)
+ 
+ #define BUTTON_BASE 		0x80	/* buttons are keys 0x80 - 0x8D */
+ #define BUTTON_MAX 		0x8D	/* buttons are keys 0x80 - 0x8D */
+ #define BUTTON_DOWN(button)	KEY_DOWN(button)	/* same as keys */
+ #define BUTTON_UP(button)	KEY_UP(button)		/* same as keys */
+ #define BUTTON_IS_DOWN(button)	KEY_IS_DOWN(button)	/* same as keys */
+ #define BUTTON_IS_UP(button)	KEY_IS_UP(button)	/* same as keys */
+ #define NEXT_BUTTON(button)	(BUTTON_DOWN(button) + 2)
+ #define REDUCE_BUTTON(button)	((button) / 2)
+ #define EXPAND_BUTTON(button)	((button) * 2)
+ #define HIL_TO_BUTTON(hil,type,buttons) ((type==TABLET && buttons==4) ? \
+     remap[((hil) - BUTTON_BASE)] : ((hil) - BUTTON_BASE))
+ #define PROXIMITY_IN		0x0E	/* Actually 0x8E */
+ #define PROXIMITY_OUT		0x0F	/* Actually 0x8F */
+ #define BUTTON_BIT(button) (1 << REDUCE_BUTTON(button))
+ #define BUTTON_IS_LATCHED(d,button) (d->kb_latched & (BUTTON_BIT(button)))
+ #define BUTTON_IS_IGNORED(d,button) (d->kb_ignore & (BUTTON_BIT(button)))
+ #define IGNORE_BUTTON(d,button) (d->kb_ignore |= (BUTTON_BIT(button)))
+ #define UNIGNORE_BUTTON(d,button) (d->kb_ignore &= ~(BUTTON_BIT(button)))
+ 
+ 
+ #define	HIL_ABSOLUTE	0x40	/* Device has absolute positioning data */
+ #define HIL_16_BITS 	0x20	/* Device has position data 16 bit accuracy */
+ #define HIL_IOB		0x10	/* Device has I/O description byte */
+ #define HIL_NUM_AXES	0x03	/* Number of axes supported */
+ 
+ #define HAS_LEDS	0xf0	/* Device has leds                        */
+ #define HILIOB_PAA	0x80	/* Device supports prompt and acknowledge */
+ #define HILIOB_NPA	0x70	/* Number of prompts & acknowledges supported */
+ #define HILIOB_PIO	0x08	/* Device supports Proximity In/Out */
+ #define HILIOB_BUTTONS	0x07	/* Number of buttons on device */
+ #define HP_HIL 		0x40
+ #define HP_ITF_KBD	0x01
+ #define PC101_KBD	0x02
+ 
+ 
+ /* ******************************************************************** */
+ /* ****************** Convert HIL ID to Keymap Name ******************* */
+ /* ******************************************************************** */
+ 
+     /*
+      * Notes:
+      *   See the manual on using hp-hil devices with HP-UX for the keyboard
+      *     nationality codes; they are the low order 6 bits of the device
+      *     id; 0x1f is United States, so we'll subtract from 0x1f to give
+      *     the U.S.  a keyId of zero; The PS2 keyboards have hil ids E0-FF.
+      *   6 bits == a max of 64 different keyboards.  32 extended and 32 PS2.
+      *   George says to use 7 bits:  HIL ids in the range A0-FF.
+      *     A0-BF  Compressed keyboard.  Not used (yet).
+      *     C0-DF  Extended (ITF) keyboard
+      */
+ static char *hil_id_to_keymap(hil_id, might_be_PS2) int hil_id, might_be_PS2;
+ {
+   static char *base_table[] =
+   {
+     "31",			/* HIL=00h Undefined keyboard */
+     "HIL_JIS",			/* HIL=01h Undefined keyboard */
+     "Japanese",			/* HIL=02h */
+     "Swiss_French",		/* HIL=03h */
+     "29",			/* HIL=04h No keysym support for Portugues */
+     "28",			/* HIL=05h No keysym support for Arabic    */
+     "27",			/* HIL=06h No keysym support for Hebrew    */
+     "Canada_English",		/* HIL=07h */
+     "26",			/* HIL=08h No keysym support for Turkish   */
+     "25",			/* HIL=09h No keysym support for Greek     */
+     "24",			/* HIL=0Ah No keysym support for Thai      */
+     "Italian",			/* HIL=0Bh */
+     "Korean",			/* HIL=0Ch */
+     "Dutch",			/* HIL=0Dh */
+     "Swedish",			/* HIL=0Eh */
+     "German",			/* HIL=0Fh */
+     "S_Chinese",		/* HIL=10h */
+     "T_Chinese",		/* HIL=11h */
+     "Swiss_French2",		/* HIL=12h */
+     "Euro_Spanish",		/* HIL=13h */
+     "Swiss_German2",		/* HIL=14h */
+     "Belgian",			/* HIL=15h */
+     "Finnish",			/* HIL=16h */
+     "UK_English",		/* HIL=17h */
+     "Canada_French",		/* HIL=18h */
+     "Swiss_German",		/* HIL=19h */
+     "Norwegian",		/* HIL=1Ah */
+     "French",			/* HIL=1Bh */
+     "Danish",			/* HIL=1Ch */
+     "Katakana",			/* HIL=1Dh */
+     "Latin_Spanish",		/* HIL=1Eh */
+     "US_English",		/* HIL=1Fh */
+   };
+ 
+   if (hil_id == 0x30) return "HP46086A_Button_Box";
+ 
+   if (hil_id == 0x5c) return "ITF_US_English";	/* Barcode reader */
+ 
+   if (hil_id == 0x34) return "ITF_US_English";	/* ID Module      */
+ 
+   if (0xC0 <= hil_id && hil_id <= 0xDF)		/* Keyboard: 0xC0 - 0xDF */
+   {
+     static char buf[32];
+ 
+     if (might_be_PS2) strcpy(buf, "PS2_");
+     else	      strcpy(buf, "ITF_");
+     strcat(buf, base_table[hil_id & 0x1f]);		/* 0 - 31 */
+     return buf;
+   }
+ 
+     /* A device that is not a key device, is unknown or not yet supported
+      *   (such as a nonkbd device (like the ID module)) or Standard or
+      *   Compressed keyboards.
+      */
+   return "";
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************ General HIL stuff ************************* */
+ /* ******************************************************************** */
+ 
+ #define MAX_HIL_BUTTONS		7
+ 
+ typedef struct
+ {
+ 	/* Stuff for all devices */
+   HIL_DeviceType *device;
+   char
+     long_name[50],	/* eg FIRST_KEYBOARD, SECOND_POINTER, etc */
+     keymap[30],		/* "" or the keymap name */
+     file_name[100];	/* "/dev/hil1", "/tmp/foo", etc  */
+   int
+     fd,				/* File descriptor */
+     hil_id, use_as,
+     data_size,			/* DATA_IS_16_BITS, etc		*/
+     num_axes,			/* number of axes (motion only)	*/
+     error;			/* for device specific error handling */
+   unsigned char
+     *ptr;			/* for whatever */
+ 
+ 	/* Motion device specific stuff */
+   int
+     res_x, res_y,		/* counts / meter for x and y axis	*/
+     max_x, max_y,		/* maximum x and y value  	*/
+     latching_enabled, 		/* 0 if not enabled  */
+     latching_on,      		/* 0 if not on       */
+     chording_interval,		/* 0 if not chording */
+ 	/* Button chording state variables*/
+     chorded_button_up,
+     ignore_button1, ignore_button2;
+   char
+     kb_latched,
+     kb_ignore,
+     ignored_buttons,			/* bit 1 for ignore_button1, etc */
+     button_down[MAX_HIL_BUTTONS];	/* TRUE if button n is down */
+ 
+   unsigned char
+     device_exists,		/* TRUE if device exists and is openable */
+     flags, 			/* device characteristics	*/
+     iob,			/* I/O descriptor Byte 		*/
+     num_buttons,		/* count of physical buttons 	*/
+     num_keys,			/* number of keys            	*/
+     num_leds;			/* number of leds            	*/
+ } HIL_Device;
+ 
+ 
+     /* 
+      * Notes:
+      *   The nine knob box has the same HIL id as the quadrature port.
+      *   The nine knob box is 3 HIL devices, each with 3 axes of motion.
+      */
+ static int stat_device(ptr, fd) HIL_Device *ptr;
+ {
+   unsigned char describe[32];
+   int i, id, num_axes;
+ 
+   memset(ptr, 0, sizeof(HIL_Device));	/*  */
+ 
+   if (-1 == ioctl(fd, HILID, describe))  /* hopefully the NULL device */
+     return FALSE;
+ 
+   id = describe[0];
+ /* printf("fd is %d errno is %d id is %x\n", fd, errno, id);	/*  */
+ 
+   num_axes = (describe[1] & HIL_NUM_AXES);
+   if (id == NINE_KNOB_ID && num_axes != 3) id = QUAD_ID;
+ 
+   for (i = 0; i < NITEMS(devices); i++)
+   {
+     HIL_DeviceType *device = &devices[i];
+     int iob;
+ 
+     if (id < device->hil_id_low || device->hil_id_high < id) continue;
+ 
+     ptr->device = device;
+ 
+     ptr->hil_id = id;
+     ptr->flags = describe[1];
+     ptr->num_axes = num_axes;
+ 
+     ptr->data_size = DATA_IS_8_BITS;
+ 
+     iob = 0;
+ 
+       /* If # of axes (of motion) indicate it is a positional device then
+        *   gather resolution.
+        * If 16 bits of information are reported, resolution is in
+        *   counts/cm.  In this case, convert to counts/meter.
+        */
+     if (num_axes)
+     {
+       int lo_resol = describe[2], hi_resol = describe[3];
+ 
+       ptr->res_x = ptr->res_y = ((hi_resol << 8) + lo_resol);
+ 
+       if (ptr->flags & HIL_16_BITS)
+       {
+ 	ptr->data_size = DATA_IS_16_BITS;
+ 	ptr->res_x = ptr->res_y = (ptr->res_x * 100);
+       }
+ 
+ 	    /* If it is an absolute device, gather size */
+       if (ptr->flags & HIL_ABSOLUTE)
+       {
+ 	switch(num_axes)
+ 	{
+ 	  case 2:
+ 	    ptr->max_y = (int)describe[6] | ((int)describe[7] << 8);
+ 	    /* FALLTHOUGH */
+ 	  case 1:
+ 	    ptr->max_x = (int)describe[4] | ((int)describe[5] << 8);
+ 	}
+ 	iob = describe[4 + 2 * num_axes];
+       }
+       else
+       {
+         if (ptr->flags & HIL_IOB) iob = describe[4];
+       }
+     }
+     else		/* Not a motion device */
+     {
+       if (ptr->flags & HIL_IOB) iob = describe[2];
+       ptr->res_x = ptr->res_y = 0;
+     }
+ 
+     ptr->iob = iob;
+ 
+     if (iob & HILIOB_BUTTONS)
+     {
+       ptr->num_buttons = (iob & HILIOB_BUTTONS);
+     }
+ 
+     if (iob & HAS_LEDS)
+ 	ptr->num_leds = imax(1, ((iob & HILIOB_NPA) >> 4));
+ 
+     strcpy(ptr->keymap, hil_id_to_keymap(id, (3 == ptr->num_leds)));
+ 
+     break;
+   }
+   return TRUE;
+ }
+ 
+ static int open_device(name) char *name;
+ {
+   return open(name, O_RDWR | O_NDELAY);
+ }
+ 
+ static char hil_file_base_name[256] = "/dev/hil";
+ 
+ static int hil_open(n)	/* n in (1,7) */
+ {
+   char name[128];
+ 
+   sprintf(name, "%s%d", hil_file_base_name, n);
+   return open_device(name);
+ }
+ 
+ 	/* hil1 .. hil7 + a bunch of XOTHER devices */
+ #define MAX_HIL_DEVICES 20
+ static HIL_Device loop_device_list[MAX_HIL_DEVICES];
+ 
+ static HIL_Device *next_device(reset)
+ {
+   static int z;
+ 
+   if (reset) { z = 0; return NULL; }
+   if (z == MAX_HIL_DEVICES) return NULL;
+   return &loop_device_list[z++];
+ }
+ 
+     /* Figure out the long name of all the devices on the loop.  This is for
+      *   the list devices extension.
+      * Format:
+      *   nth_name
+      *   where:
+      *     nth is 0 .. 6 for FIRST, SECOND, ... SEVENTH
+      *     name is KEYBOARD, MOUSE, BARCODE, etc
+      * Notes:
+      *   Do this after catalog_loop().
+      */
+ static void make_name(long_name, nth, x_name) char *long_name, *x_name;
+ {
+   strcat(strcat(strcpy(long_name, h_position[nth]), "_"), x_name);
+ }
+ 
+ static void name_loop()
+ {
+   int nth, hil, i;
+ 
+   for (hil = 0; hil < NITEMS(loop_device_list); hil++)
+   {
+     HIL_Device *ptr = &loop_device_list[hil];
+ 
+     nth = 0;
+     if (ptr->device_exists)
+     {
+       for (i = 0; i < hil; i++)
+ 	if ( loop_device_list[i].device_exists	&&
+ 	    (loop_device_list[i].device->dev_type == ptr->device->dev_type))
+ 	{
+ 	  nth++;
+ 	}
+       make_name(ptr->long_name, nth, ptr->device->X_name);
+     }
+   }
+ }
+ 
+     /* The HIL loop is cataloged every time configure() is called.  This is
+      *   because I can't tell if the loop has changed.  This is probably
+      *   only a problem for people using the HP Input Extension - somebody
+      *   writing a client using the extension might be pluging and unpluging
+      *   devices and running their client.  If I didn't catalog, they would
+      *   have to restart the X server.  Note that changing one of the core
+      *   devices (while X is running) or moving it around the loop is likely
+      *   to hose X.
+      * If a device is open, assume it is OK (ie don't recatalog it).
+      * This should be quick - only have to open(), read(small amount of
+      *   data), close() and look at data.
+      */
+ static void catalog_loop()
+ {
+   HIL_Device *ptr;
+   int fd, id, hil, i;
+ 
+   ptr = loop_device_list;
+   for (hil = 1; hil <= 7; hil++, ptr++)
+   {
+     if (ptr->device_exists && ptr->fd != -1) continue;
+ 
+     fd = hil_open(hil);
+     if (fd == -1) continue;		/* Couldn't open that device */
+ 
+     if (stat_device(ptr, fd))
+     {
+       sprintf(ptr->file_name, "%s%d", hil_file_base_name, hil);
+       ptr->fd = -1;
+       ptr->device_exists = TRUE;
+     }
+     close(fd);
+   }
+ }
+ 
+     /* 
+      * Input:
+      *   path: Device file name.  Eg "/dev/hil8"
+      *   null_device:  TRUE if this is the null device, ie if path is
+      *     "/dev/null" ie "first NULL keyboard"
+      *   use_as: XKEYBOARD, XPOINTER or XOTHER
+      * Notes:
+      *   Always need to stat the device because stat_device() resets things.
+      */
+ static HIL_Device *add_device(path, null_device, use_as) char *path;
+ {
+   HIL_Device *ptr, *qtr;
+   int fd, n, device_exists;
+ 
+   ptr = NULL;
+   for (n = 7; n < NITEMS(loop_device_list); n++)
+   {
+     qtr = &loop_device_list[n];
+     device_exists = qtr->device_exists;
+     if (!device_exists || (device_exists && qtr->fd == -1))
+     {
+       ptr = qtr;
+       break;
+     }
+   }
+ 
+   if (!ptr) return NULL;	/* no open slots */
+ 
+   if (-1 == (fd = open_device(path))) return NULL;
+   if (!stat_device(ptr, fd) && !null_device)
+   {
+     close(fd);
+     return NULL;
+   }
+   ptr->fd = fd;
+   ptr->device_exists = TRUE;
+   ptr->use_as |= use_as;
+   strcpy(ptr->file_name, path);
+ 
+   return ptr;
+ }
+ 
+ static HIL_Device *find_null_device(use_as) /* and open it */
+ {
+   HIL_Device *ptr = &loop_device_list[0];
+   int hil, fd;
+ 
+   for (hil = 0; hil < NITEMS(loop_device_list); hil++, ptr++)
+     if (ptr->device_exists && ptr->device->dev_type == NULL_DEVICE)
+     {
+     ptr->use_as |= use_as;
+     if (ptr->fd == -1 && (fd = open_device("/dev/null")) != -1)
+       ptr->fd = fd;
+     return ptr;
+     }
+   return NULL;
+ }
+ 
+     /* Input:
+      *   type:  KEYBOARD, BARCODE, MOUSE, etc
+      *   which:  1 ... 7 for FIRST, SECOND ...  Find the nth device of type.
+      * Notes:
+      *   If which is out of range (ie, bigger than last device of type), the
+      *     last device of type is used.
+      */
+ static HIL_Device *find_device_by_type(type, which, use_as, x, in_use) /* and open it */
+ {
+   HIL_Device *savptr = NULL, *ptr = &loop_device_list[0];
+   int hil, savhil, fd, find_type;
+ 
+   for (hil = 0; hil < NITEMS(loop_device_list); hil++, ptr++)
+   {
+     int count = 0;
+ 
+     if (!ptr->device_exists)
+ 	continue;
+     if (x)
+ 	find_type = ptr->device->x_type;
+     else
+ 	find_type = ptr->device->dev_type;
+ 
+     if (find_type == type) 
+     {
+       count++;
+       if (!in_use && ptr->use_as)
+ 	  continue;
+       savptr = ptr;
+       savhil = hil + 1;
+       if (count == which) break;
+     }
+   }
+ 
+ 	/* Opening the device for the first time? */
+   if (savptr && savptr->fd == -1 && (fd = open_device(savptr->file_name)) != -1)
+     {
+       savptr->fd = fd;
+       savptr->use_as = use_as;
+       return savptr;
+     }
+ 
+ 	/* Opening the device for the nth time? */
+   if (savptr && savptr->fd != -1)
+     {
+       savptr->use_as |= use_as;
+       return savptr;
+     }
+ 
+   return NULL;
+ }
+ 
+ static HIL_Device *use_device_n(n, use_as)	/* n in [1,7] */
+ {
+   HIL_Device *ptr = &loop_device_list[n - 1];
+   int fd;
+ 
+   if (ptr->device_exists && ptr->fd == -1 && (fd = hil_open(n)) != -1)
+   {
+     ptr->fd = fd;
+     ptr->use_as |= use_as;
+     return ptr;
+   }
+   return NULL;
+ }
+ 
+ static HIL_Device *find_device_by_fd(fd)
+ {
+   HIL_Device *ptr = loop_device_list;
+   int hil;
+ 
+   for (hil = NITEMS(loop_device_list); hil--; ptr++)
+     if (ptr->fd == fd) return ptr;
+ 
+   return NULL;
+ }
+ 
+ static HIL_Device *find_device_by_use(use_as)
+ {
+   HIL_Device *ptr = loop_device_list;
+   int hil;
+ 
+   for (hil = NITEMS(loop_device_list); hil--; ptr++)
+     if (ptr->use_as & use_as) return ptr;
+ 
+   return NULL;
+ }
+ 
+ /**************************************************************************
+  *
+  * This routine is called by the X server to close an input device.
+  *
+  */
+ static int close_device(fd) int fd;
+ {
+   HIL_Device *ptr;
+   int i;
+ 
+   if (!(ptr = find_device_by_fd(fd)))	/* !!! I hope this never happens! */
+ 	return CLOSE_SUCCESS;
+ 
+   close(fd);
+   ptr->fd = -1;
+ 
+   return CLOSE_SUCCESS;
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************* Read HIL Devices ************************* */
+ /* ******************************************************************** */
+ 
+ typedef struct
+ {
+   unsigned char	len;
+   unsigned char	timestamp[4];
+   unsigned char	poll_hdr;
+   unsigned char	data[20];
+ } HilPacket;
+ 
+ #define MAX_PACKET_SIZE		sizeof(HilPacket)	/* bytes */
+ 
+ #define BUFFER_SIZE	600	/* Must be bigger than a (single) HIL packet */
+ #define MAX_RETRIES	10
+ 
+ static unsigned char hil_buffer[BUFFER_SIZE];
+ static int data_start, bytes_left;
+ 
+ static int read_hil(fd, force_read)
+ {
+   if (fd == -1) return bytes_left;		/* buffer check */
+   if (!force_read && bytes_left) return TRUE;	/* got data in buffer */
+ 
+ 	/* buffer empty or not enough data in buffer */
+   {
+     int n;
+ 
+     if (bytes_left == 0) data_start = 0;
+ 
+     n = read(fd, hil_buffer + data_start + bytes_left,
+ 		 BUFFER_SIZE - bytes_left);
+     /* !!! error check */
+     bytes_left += n;
+   }
+ 
+   return bytes_left;
+ }
+ 
+     /* Read (at least) enough data to fill a packet.
+      * Returns:
+      *   0 : No can do.
+      *   n : packet size
+      */
+ static int read_packet(fd)
+ {
+   int packet_size;
+ 
+   read_hil(fd,FALSE);
+   if (bytes_left == 0) return 0;	/* no packet available */
+ 
+   packet_size = hil_buffer[data_start];
+ /*  if (packet_size > MAX_PACKET_SIZE) ???
+ /* error check size!!! */
+   if (packet_size <= bytes_left) return packet_size;
+ 
+   if (fd == -1) return 0;
+ 
+ 	/* Don't have a complete packet */
+   {
+     int i;
+ 
+     if (BUFFER_SIZE < (data_start + packet_size))
+     {	/* packet won't fit in buffer */
+       memcpy(hil_buffer, hil_buffer + data_start, bytes_left);
+       data_start = 0;
+     }
+     for (i = MAX_RETRIES; i--; )
+     {
+       if (!read_hil(fd, TRUE)) return 0;	/* !!!??? */
+       if (packet_size <= bytes_left)   /* got (at least) the complete packet */
+ 	return packet_size;
+   /* !!! sleep??? */
+     }
+   }
+     /* !!! big bad errors! */
+   return 0;
+ }
+ 
+ static HilPacket a_packet;
+ static int packet_waiting = FALSE;
+ 
+ static void pop_packet() { packet_waiting = FALSE; }
+ 
+ static void *get_packet(fd)
+ {
+   if (!packet_waiting)
+   {
+     int packet_size;
+ 
+     if (!(packet_size = read_packet(fd))) return NULL;
+ /* !!! ick - two data copies */
+     memcpy(&a_packet, hil_buffer + data_start, packet_size);
+     data_start += packet_size; bytes_left -= packet_size;
+     packet_waiting = TRUE;
+   }
+   return &a_packet;
+ }
+ 
+     /* Look though the buffered HIL packets looking for a button down.  If a
+      *   button down is found, all the packets before it are thrown away.
+      * This is used for button chording.  Motion devices can send different
+      *   kinds of events in a single packet and there can be many motion
+      *   events between button presses (even if the user is trying to hold
+      *   still) - the tablet is especially bad in this reguard.
+      * Notes:
+      *   This routine has its fingers in too many things.  It has to know
+      *     too much about HIL packets.
+      * Input:
+      *   device : The motion device that has buffered data.
+      *   b1, b2:  Buttons to look for.
+      *   button : Pointer to int to be filled in if a button is found.
+      * Output:
+      *   button
+      *   The current packet is the button if TRUE returned, else unknown.
+      * Returns:
+      *   TRUE : If a button down is found.
+      */
+ static int look_for_button(device, b1, b2, button)
+   HIL_Device *device;
+   int b1, b2, *button;
+ {
+   int poll_hdr, b, z, n, save_data_start, save_bytes_left;
+ 
+   save_data_start = data_start;
+   save_bytes_left = bytes_left;
+ 
+   n = 1 + (device->data_size == DATA_IS_16_BITS);
+ 
+   while (TRUE)
+   {
+     if (!get_packet(-1)) break;		/* incomplete packet */
+     pop_packet();
+ 
+     poll_hdr = a_packet.poll_hdr;
+     if (0 == (poll_hdr & KEY_DATA_MASK)) continue;	/* not a button */
+ 
+     z = 0;
+     if (poll_hdr & MOTION_MASK)		/* motion AND key data in one packet */
+     {
+       if (poll_hdr  & MOTION_XYZ)		 z += n;	/* X axes */
+       if (poll_hdr  & MOTION_Y)			 z += n;	/* Y axes */
+       if ((poll_hdr & MOTION_XYZ) == MOTION_XYZ) z += n;	/* Z axes */
+     }
+ 
+     b = HIL_TO_BUTTON(a_packet.data[z], device->device->dev_type,
+ 	device->num_buttons);
+     if (BUTTON_IS_UP(b)) break;
+     if (BUTTON_MAX < a_packet.data[z])  break;		/* probably proximity */
+ 
+     b = REDUCE_BUTTON(b);
+ #if 1
+     *button = b;
+     if (b == b1 || b == b2)
+       return TRUE;
+ #else
+     if (b == b1 || b == b2)
+     {
+       *button = b;
+       return TRUE;
+     }
+ #endif
+ 
+     break;			/* wrong button, bail */
+   }
+ 
+ 	/* No button down in buffer, restore buffer */
+   data_start = save_data_start;
+   bytes_left = save_bytes_left;
+ 
+   return FALSE;
+ }
+ 
+ 
+ /* ******************************************************************** */
+ /* ****************** General HIL Turn Things On/Off ****************** */
+ /* ******************************************************************** */
+ 
+     /* Turn on or off LEDs.
+      * Input:
+      *   fd :  File descriptor of the HIL device.
+      *   led:  LED to turn on or off:
+      *         0 : general prompt.
+      *         1 : LED 1.
+      *         etc
+      *   on : TRUE if turn on the LED.
+      */
+   int
+     led_on[]  = { HILP, HILP1, HILP2, HILP3, HILP4, HILP5, HILP6, HILP7 },
+     led_off[] = { HILA, HILA1, HILA2, HILA3, HILA4, HILA5, HILA6, HILA7 };
+ static void set_LED(fd, led, on)
+ {
+ 
+   if (0 <= led && led <= 7)
+     if (on) ioctl(fd, led_on [led], (char *)NULL);
+     else    ioctl(fd, led_off[led], (char *)NULL);
+ }
+ 
+     /* HILER1 == Key repeat every 1/30 sec
+      * HILER2 == Key repeat every 1/60 sec
+      */
+ static void set_autorepeat(fd, mode)
+ {
+   switch (mode)
+   {
+     case AutoRepeatModeOff:
+       ioctl(fd, HILDKR, (char *)NULL);
+       break;
+     case AutoRepeatModeOn:
+     case AutoRepeatModeDefault:
+       ioctl(fd, HILER2, (char *)NULL);
+       break;
+     default:
+       ioctl(fd, HILER1, (char *)NULL);
+       break;
+   }
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************* Button Chording ************************** */
+ /* ******************************************************************** */
+ 
+ /* Button chording can allow a N button device generate 2N-1 buttons.
+  * Buttons are numbered 0,1, ...
+  * Simultaneously pressing buttons A and B (where A in [1,N) and B == A+1),
+  *   generates button N+A.
+  * Only a total of 5 buttons are supported.  This is because of motion
+  *   events and other things that George knows more about.
+  * If the device has 4 buttons, only buttons 0 and 1 can chord.
+  * If the device has 5 or more buttons, no chording is possible.  Because of
+  *   the max number of buttons.
+  * Only chord adjacent buttons ie don't chord buttons 0 and 3.  My guess is
+  *   this is historical and with 5 buttons, you don't need all those
+  *   chordings.
+  * Algorithm:
+  *   if num_buttons > 4, no chording, done.
+  *   if num_buttons <= 3, Z = [0,2]
+  *   if num_buttons == 4, Z = [0,1]
+  *   Button in Z is pressed.  X = button.
+  *   Wait E seconds (E is passed in).  Don't just wait for the device to
+  *     send data within E seconds.  This is in case the device sends (for
+  *     example) motion data before the other button.
+  *   Look though the data to see if there is a button (Y):
+  *     No:  Send button X.
+  *     Yes:
+  *       If new button (Y) is (X+1 or X-1) and Y != 3:
+  *         Yes:
+  *           Send button (N - 1) + (X + Y + 1)/2.
+  *              (N - 1) because buttons start at zero.
+  *           Discard the motion events between the buttons.
+  *         No:
+  *           Send X, and process the other data "normally".
+  * Notes:
+  *   The hard part is keeping track of the ups and downs and keeping things
+  *     in sync.
+  *   If the chording interval is long, it is possible for the buffer in the
+  *     HIL device (or kernel) to overflow while waiting.  Too bad.
+  */
+ 
+ #define MAX_X_BUTTONS			5
+ #define MAX_BUTTONS_FOR_CHORDING	4
+ 
+     /* Process a button, chording if chording turned on.
+      * Input:
+      *   button : reduced button.
+      * Returns:
+      *   TRUE  : Button chorded
+      */
+ static int chord_button(device, button,
+ 			chorded_button, ignore_button1, ignore_button2)
+   HIL_Device *device;
+   int *chorded_button, *ignore_button1, *ignore_button2;
+ {
+   int x,y,ret, max_b;
+ 
+   if (!device->chording_interval) return FALSE;
+ 
+   max_b = 3;
+   if (3 < device->num_buttons) max_b = 1;
+ 
+   x = REDUCE_BUTTON(button);
+   if (
+     BUTTON_IS_DOWN(button)			&&
+     device->chording_interval			&&
+     0 <= x && x <= max_b)
+   {
+     int x1;
+     struct timeval timeout;
+ 
+     timeout.tv_sec = 0;
+     timeout.tv_usec = device->chording_interval * 1000;
+     select(0, (int *)NULL, (int *)NULL, (int *)NULL, &timeout);
+ 
+ 	/* No response in allotted time */
+     if (!read_hil(device->fd, FALSE)) return 0;
+ 
+     if (3 == (x1 = x + 1)) x1 = 100;
+ 	/* No button => not a chording combination */
+     ret = look_for_button(device, x - 1, x1, &y);
+ #if 1
+     if (device->latching_enabled)
+     {
+ 	if (!ret && 
+ 		(x == 0 && look_for_button(device, 100,2,&y)) ||
+ 		(x == 2 && look_for_button(device, 100,0,&y)))
+ 	{
+ 	    device->latching_on = ~device->latching_on;
+ 	    if (device->latching_on)
+ 		device->kb_latched = 0xff;
+ 	    else
+ 		device->kb_latched = 0;
+             *chorded_button = -1;
+     	    pop_packet();
+     	    *ignore_button1 = BUTTON_UP(EXPAND_BUTTON(x));
+     	    *ignore_button2 = BUTTON_UP(EXPAND_BUTTON(y));
+ 	    return TRUE;
+ 	}
+     }
+ 
+     if (!ret) return FALSE;
+ #else
+     if (!ret) return FALSE;
+ #endif
+     *chorded_button = EXPAND_BUTTON(device->num_buttons - 1 + (x + y + 1)/2);
+     pop_packet();
+     *ignore_button1 = BUTTON_UP(EXPAND_BUTTON(x));
+     *ignore_button2 = BUTTON_UP(EXPAND_BUTTON(y));
+     return TRUE;
+   }
+   return FALSE;		/* Not a chording button */
+ }
+ 
+ /* ******************************************************************** */
+ /* **************************** Read Mouse **************************** */
+ /* ******************************************************************** */
+ 
+ static int find_button_down(), ignore_check(), error_check_button();
+ static void set_button_down();
+ 
+ static int get_data(data, two_bytes) unsigned char *data;
+ {
+   int z;
+ 
+   z = data[0];
+   if (two_bytes) z |= (data[1] << 8);
+ 
+   return z;
+ }
+ 
+ static void put_data(z, data, two_bytes) unsigned char *data;
+ {
+   data[0] = z;			/* the lower byte */
+   if (two_bytes) data[1] = (z >> 8);
+ }
+ 
+ #define APPEND_DATA(type, z)			\
+   *data_type |= (type);				\
+   put_data((z), &data[num_bytes], two_bytes);	\
+   num_bytes += step;				\
+   *pending = num_bytes;
+ 
+ 
+     /* Read from a motion device:  motion and button presses.
+      * Mouse, Nine Knob box, Tablet.
+      * Handles absolute devices, 1 and 2 byte data.
+      * Notes:
+      *   Mice need to have the Y axes motion data negated so the sprite
+      *     moves when the mouse moves up.  Tablets and the nine knob box
+      *     don't.
+      *   I really hate having to keep so much state information for chording
+      *     but I think I have to:  If you chord two buttons and then
+      *     repeatedly press one while keeping the other pressed, you need a
+      *     lot of state info to keep track.
+      *   Can only chord one button pair at a time.  This means that holding
+      *     down the middle button, then pressing the buttons to the right
+      *     and left of it (while holding down the middle button) will only
+      *     chord one of the pairs.
+      *   Motion devices can generate a LOT of motion data quickly.  For
+      *     example, if the X server takes a long time to render something
+      *     (like a wide dashed line) and you are moving the mouse around,
+      *     the HIL buffer (in the kernel) can overflow and data will be
+      *     lost.  This is more-or-less OK (can't do anything about it)
+      *     except in the case where a button was down (before the overflow)
+      *     and then went up after the overflow.  In this case, a button up
+      *     will never be generated.  To check for this, when there is a
+      *     button down, check to see if the button is already down and if it
+      *     is, generate ups for all down buttons.  The server sends
+      *     extraneous ups to clients but I hope that doesn't cause problems
+      *     because it is quite painful to track chording in this case.
+      */
+ static int read_mouse(mouse, data, data_type, pending)
+   HIL_Device *mouse;
+   unsigned char *data, *data_type;
+   int *pending;
+ {
+   int poll_hdr, num_bytes, two_bytes, step;
+ 
+   if (!get_packet(mouse->fd))
+   {
+     *pending = 0;
+     return READ_FAILURE;
+   }
+ 
+   two_bytes = (mouse->data_size == DATA_IS_16_BITS);
+   step = 1 + two_bytes;
+   num_bytes = 0;
+ 
+   if (mouse->error)	/* Buffer overflow, sending button ups */
+   {
+     int button;
+ 
+     button = find_button_down(mouse, -1);
+     if (button == -1)		/* No downs left */
+     {
+       mouse->error = FALSE;
+ 
+       *pending = 0;
+       return READ_SUCCESS;
+     }
+ 
+     set_button_down(mouse, button, FALSE);
+     button = BUTTON_UP(button);
+     APPEND_DATA(BUTTON_DATA, button);
+     return READ_SUCCESS;
+   }
+ 
+   poll_hdr = a_packet.poll_hdr;
+ 
+   if (poll_hdr & MOTION_MASK)		/* mouse movement */
+   {
+     int motion;
+ 
+     *data_type |= MOTION_DATA;
+ 
+     if (poll_hdr & MOTION_XYZ)			/* X axes */
+     {
+       motion = get_data(&a_packet.data[num_bytes], two_bytes);
+       put_data(motion, &data[num_bytes], two_bytes);
+       num_bytes += step;
+     }
+     if (poll_hdr & MOTION_Y)			/* Y axes */
+     {
+       motion = get_data(&a_packet.data[num_bytes], two_bytes);
+ 
+       if (mouse->device->reverse_y_axes) motion = -motion;
+ 
+       put_data(motion, &data[num_bytes], two_bytes);
+       num_bytes += step;
+     }
+     if ((poll_hdr & MOTION_XYZ) == MOTION_XYZ)	/* Z axes */
+     {
+       motion = get_data(&a_packet.data[num_bytes], two_bytes);
+       put_data(motion, &data[num_bytes], two_bytes);
+       num_bytes += step;
+     }
+   }
+ 
+   if (poll_hdr & KEY_DATA_MASK)		/* button press */
+   {
+     int button;
+ 
+     pop_packet();
+ 
+     button = HIL_TO_BUTTON(a_packet.data[num_bytes], mouse->device->dev_type,
+ 	mouse->num_buttons);
+ 
+     if (button == PROXIMITY_IN || button == PROXIMITY_OUT)
+     {
+       *data_type |= PROXIMITY_DATA;
+ 
+       put_data(
+ 	((button == PROXIMITY_IN) ? IN_PROXIMITY : OUT_OF_PROXIMITY),
+ 	&data[num_bytes], two_bytes);
+       num_bytes += step;
+     }
+     else		/* Must? be a "regular" button */
+     {
+       if (1) /*!error_check_button(mouse, button))*/
+       {
+ 	if (mouse->chorded_button_up)	/* Button chord in progress */
+ 	{
+ 	  if (BUTTON_IS_UP(button))
+ 	  {
+ 	    button = ignore_check(mouse, button, mouse->ignore_button1, 0x1);
+ 	    button = ignore_check(mouse, button, mouse->ignore_button2, 0x2);
+ 	    if (0x3 == mouse->ignored_buttons)
+ 	    {
+ 	      button = mouse->chorded_button_up;
+ 	      mouse->chorded_button_up = 0;	/* turn off chord */
+ 	    }
+ 	  }
+ 	}
+ 	else				/* not chording */
+ 	  if (chord_button(mouse, button, &button,
+ 			   &mouse->ignore_button1, &mouse->ignore_button2))
+ 	  {
+ 	    if (button == -1)
+ 	    {
+ 	        mouse->chorded_button_up = -1;
+ 		num_bytes = 0;
+ 	    }
+ 	    else
+ 	        mouse->chorded_button_up = BUTTON_UP(button);
+ 	    mouse->ignored_buttons = 0;
+ 	    set_button_down(mouse, mouse->ignore_button1, TRUE);
+ 	    set_button_down(mouse, mouse->ignore_button2, TRUE);
+ 	  }
+ 
+ 	  if (mouse->num_buttons==2 && button>=0 && button <=15)
+ 	      button = remap[button];
+ 	      
+ 	  if (button != -1 && !BUTTON_IS_IGNORED(mouse, button))
+ 	  {
+ 	    APPEND_DATA(BUTTON_DATA, button);
+ 	    set_button_down(mouse, button, BUTTON_IS_DOWN(button));
+ 	  }
+       }
+ 
+     if (button != -1)
+     {
+       if (BUTTON_IS_LATCHED(mouse, button)) 
+         if (BUTTON_IS_IGNORED(mouse, button))
+         {
+ 	  if (BUTTON_IS_DOWN(button))
+ 	    UNIGNORE_BUTTON(mouse, button);
+         }
+         else if (BUTTON_IS_DOWN(button))
+ 	  IGNORE_BUTTON(mouse, button);
+     }
+     }
+   }
+ 
+   pop_packet();
+ 
+   *pending = num_bytes;  /* might be zero in case of chording or error */
+   return READ_SUCCESS;
+ }
+ 
+ static int ignore_check(mouse, button, ignore_button, ignored_button_bit)
+   HIL_Device *mouse;
+   int button, ignore_button, ignored_button_bit;
+ {
+   if (button == ignore_button)
+   {
+     if (0 == (mouse->ignored_buttons & ignored_button_bit))
+     {
+       mouse->ignored_buttons |= ignored_button_bit;
+       set_button_down(mouse, button, FALSE);
+       return -1;		/* ignore this button */
+     }
+   }
+   return button;
+ }
+ 
+ static void set_button_down(mouse, button, state) HIL_Device *mouse;
+ {
+   mouse->button_down[REDUCE_BUTTON(button)] = state;
+ }
+ 
+ static int find_button_down(mouse, button) HIL_Device *mouse;
+ {
+   int b, z;
+ 
+   if (-1 != button)
+   {
+     b = REDUCE_BUTTON(button);
+     z = mouse->button_down[b];
+   }
+   else
+     for (b = 0; b < MAX_HIL_BUTTONS; b++)
+       if (z = mouse->button_down[b]) break;
+ 
+   if (z) return EXPAND_BUTTON(b);
+ 
+   return -1;
+ }
+ 
+     /* Notes:
+      *   If there is an error (because there is a down for a button that is
+      *     already down), turn off that button so I don't send two ups (got
+      *     a down so will get an up).
+      *   Turn off chording.
+      *   Trying not to send extraneous ups when chording is just too painful
+      *     to worry about.  The client will just have to live with extra
+      *     ups.
+      */
+ static int error_check_button(mouse, button) HIL_Device *mouse;
+ {
+   if (BUTTON_IS_DOWN(button))	/* error check */
+   {
+     if (-1 != find_button_down(mouse,button))
+     {
+       mouse->error = TRUE;
+       mouse->chorded_button_up = 0;		/* turn off chording */
+       set_button_down(mouse, button, FALSE);
+       return TRUE;
+     }
+   }
+   return FALSE;		/* no problem */
+ }
+ 
+ /* ******************************************************************** */
+ /* ***************************** Nothing ****************************** */
+ /* ******************************************************************** */
+ 
+ static int read_nothing(device, data, data_type, pending)
+   HIL_Device *device;
+   unsigned char *data, *data_type;
+   int *pending;
+ {
+   *pending = 0;
+   return READ_FAILURE;
+ }
+ 
+ static int write_nothing(device, request, data)
+   HIL_Device *device;
+   int request;
+   char *data;
+ {
+   return WRITE_FAILURE;
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************** Read Keyboard *************************** */
+ /* ******************************************************************** */
+ 
+ #define REPEAT_CURSOR		0x02
+ 
+ #define ARROW_LEFT		0xf8
+ #define ARROW_DOWN		0xfa
+ #define ARROW_UP		0xfc
+ #define ARROW_RIGHT		0xfe
+ 
+ static int last_key;		/* for arrow auto repeat */
+ 
+ static int read_keyboard(keyboard, data, data_type, pending)
+   HIL_Device *keyboard;
+   unsigned char *data, *data_type;
+   int *pending;
+ {
+   if (get_packet(keyboard->fd))
+   {
+     int poll_hdr = a_packet.poll_hdr;
+ 
+     pop_packet();
+ 
+     if (poll_hdr & KEY_DATA_MASK)	/* button press */
+     {
+       int key;
+ 
+       key = a_packet.data[0];
+ 
+       if (key == REPEAT_CURSOR) key = last_key;
+       if (KEY_IS_DOWN(key)) last_key = key;
+ 
+       *pending = 1;
+       *data_type = KEY_DATA;
+       *data = key;
+ 
+       return READ_SUCCESS;
+     }
+   }
+ 
+   *pending = 0;
+   return READ_FAILURE;
+ }
+ 
+ /* ******************************************************************** */
+ /* *************************** Bell/Beeper **************************** */
+ /* ******************************************************************** */
+ 
+ static unsigned char bell_data[4];
+ 
+ static int bell_percent, bell_pitch, bell_duration, beeper_fd = -1;
+ 
+ #define BEEPER_DEVICE   "/dev/rhil"
+ 
+ static void close_beeper()
+ {
+   if (beeper_fd != -1) close(beeper_fd);
+   beeper_fd = -1;
+ }
+ 
+ static void open_beeper()
+ {
+   if (beeper_fd > 0)
+       close_beeper();
+   if ((beeper_fd = open(BEEPER_DEVICE,O_RDWR)) < 0)
+     ; /* Don't complain, because we might be on a non-HIL machine */
+       /* and be using this driver to support NULL input devices   */
+ #if 0
+     fprintf(stderr, "Unable to open beeper device \"%s\".\n",BEEPER_DEVICE);
+ #endif
+ }
+ 
+ /*
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ; File:         beeper.c
+ ; SCCS:         %A% %G% %U%
+ ; Description:  Access Gator/Bobcat beeper
+ ; Author:       Andreas Paepcke, HPLabs/ATL
+ ; Created:      2-Aug-85
+ ; Modified:     Thu Oct 15 12:53:00 1987 (Don Bennett) bennett@hpldpb
+ ;		George and Craig
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ */
+ 
+ /*
+    We offer three voices and a noise source.  Each sound is controllable
+    in pitch, volume and duration.  Pitch goes from 0 to 1023, volume
+    goes from 0 to 15, duration is between 0 and 255 10msec intervals.  A
+    duration of 0 turns the voice on continuously.  A volume of 0 turns
+    it off.
+ 
+    The manufacturing specs give details on the programming interface.
+    Here is a summary:
+ 
+    The beeper is accessed through ioctl calls.  The request argument is
+    either "Send data to beeper" or "Read voice values from beeper".  The
+    argument is a pointer to a 4 byte buffer.  These four bytes are
+    defined here.
+ 
+    R0-R3: Register address field. In the order R2, R1, R0:
+      
+      0 0 0: Voice 1 frequency
+      0 0 1: Voice 1 attenuation
+      0 1 0: Voice 2 frequency
+      0 1 1: Voice 2 attenuation
+      1 0 0: Voice 3 frequency
+      1 0 1: Voice 3 attenuation
+      1 1 0: Noise control
+      1 1 1: Noise attentuation
+ 
+   F0-F9: 10 bits pitch
+   A0-A3: Attenuation
+   D0-D7: Duration in 10msec's
+ 
+   The placement of data in the buffer is a bit screwy:
+ 
+   Byte 0 (Frequency 1):  1 R2 R1 R0 F3 F2 F1 F0     LSB
+   Byte 1 (Frequency 2):  0  0 F9 F8 F7 F6 F5 F4
+   Byte 2 (Attenuator) :  1 R2 R1 R0 A3 A2 A1 A0
+   Byte 3 (Duration)   : D7 D6 D5 D4 D3 D2 D1 D0
+ 
+   The volume is inversely proportional to the attenuation.  In order to
+   provide rising numbers for rising loudness to the user, we expect a
+   volume and modify to get the attenuation.  The same goes for the
+   pitch.  In order to calculate frequency of the pitch, use:
+ 
+            83333/(1023-pitch)
+ 
+   It is possible at any time to request the time any voice has left to
+   run.  This is done by:
+  
+   F4: Read voice1 timer
+   F5: Read voice2 timer
+   F6: Read voice3 timer
+   F7: Read voice4 timer (noise)
+ 
+   Noise is generated using a shift register.  The following controls are
+     possible for noise:
+  
+   - Attenuation
+   - Duration
+   - Periodic or white noise
+   - 3 shift rates or output of voice 4 as shift rate
+ 
+   Bytes 0 and 1 of the data buffer must both have identical contents to
+   control the noise.  Attenuation and duration are as in the other
+   voices.  Bytes 0 and 1 should look like this:
+ 
+   1 R2 R1 R0 0 FB NF1 NF0   LSB
+ 
+   R2, R1 and R0 must be 1, 1 and 0.  If FB is 0, periodic noise is
+   generated.  If FB is 1, white noise is produced.
+ 
+   NF1 and NF2 control the shift rate of the noise generator:
+ 
+   NF1     NF2     Shift Rate
+   --------------------------
+   0       0       M/64
+   0       1       M/128
+   1       0       M/256
+   1       1       Uses tone generator 3 output
+ 
+   M is related to the clock rate.
+ 
+   The voice start routines return 0 if all is well, -1 if we had trouble
+   accessing the device file for the beeper and -2 if given parameters
+   were out of range.
+ */
+ 
+ #define ALL_OK           0
+ #define ACCESS_PROBLEM  -1
+ #define BAD_RANGE       -2
+ 
+ #define VOICE1_FREQ_REG 0x80	/* Top nibbles for byte0 for all voices: */
+ #define VOICE2_FREQ_REG 0xA0
+ #define VOICE3_FREQ_REG 0xC0
+ #define NOISE_FREQ_REG  0xE0
+ 
+ #define VOICE1_VOL_REG  0x90	/* Top nibbles for byte2 for all voices: */
+ #define VOICE2_VOL_REG  0xB0
+ #define VOICE3_VOL_REG  0xD0
+ #define NOISE_VOL_REG   0xF0
+ 
+ #define MIN_VOICE	   1	/* Legal ranges for parms from user: */
+ #define MAX_VOICE	   3
+ #define MIN_PITCH	   0
+ #define MAX_PITCH	1023
+ #define MIN_DURATION	   0
+ #define MAX_DURATION	 255
+ #define MIN_VOLUME	   0
+ #define MAX_VOLUME	  15
+ #define MIN_TYPE	   0
+ #define MAX_TYPE	   1
+ #define MIN_RATE	   0
+ #define MAX_RATE	   3
+ 
+ static void set_bell_attributes(volume, pitch, duration)
+ {
+   int attenuation, loud;
+ 
+ 	/* Map input range of 0 - 100 to hardware attenuation range of 15 -
+ 	 * 0 we use a temp variable (loud) because of C's penchant for
+ 	 * strange orders of evaluation ie to force the multiply before the
+ 	 * divide.
+ 	 */
+   volume = imin(volume,100);
+   loud = volume * MAX_VOLUME;
+   attenuation = (char) MAX_VOLUME - loud / 100;
+ 
+   duration = duration / 10;
+   pitch = (pitch == 0) ? 1023 : (83333 / pitch);
+   pitch = imax(imin(pitch, 1023), 0);
+ 
+   bell_data[0] = (VOICE1_FREQ_REG | (pitch & 0x0f));
+   bell_data[1] = (0x03f & (pitch >> 4));
+   bell_data[2] = (VOICE1_VOL_REG | attenuation);
+   bell_data[3] = imax(duration, 1);
+ }
+ 
+ 
+     /* We formerly used all three voices to get a reasonably loud volume.
+      * However, s700 audio hardware support tries to emulate the EFTSBP
+      * ioctl, and has only one voice.  The result is that distinct beeps
+      * (usually two) are heard if the duration is 100ms or less.  To avoid
+      * this, we will use only one voice.
+      */
+ static void ding(click, percent)
+ {
+   int pitch;
+   unsigned char buffer[4];
+ 
+   if (beeper_fd < 0) return;
+   if (!click)
+   {
+     ioctl(beeper_fd, EFTSBP, bell_data);
+     return;
+   }
+ 
+   click = (int)((double)(percent) * 15.0 / 100.0);
+ 
+   click = MAX_VOLUME - click;
+   pitch  = MAX_PITCH  - 800;
+   buffer[0] = VOICE2_FREQ_REG | (pitch & 0x0000000f);
+   buffer[2] = VOICE2_VOL_REG  | (percent & 0x0000000f);
+ 	/* The high 6 bits of the pitch go into byte 1: */
+   buffer[1] = 0x0000003f & (pitch >> 4);
+   buffer[3] = 1;
+   ioctl(beeper_fd,EFTSBP,buffer);
+   return;
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************** Write Keyboard ************************** */
+ /* ******************************************************************** */
+ 
+ /* !!!!!!!!!!!!!!!
+  * keyclick - in server or here?
+  * if key autorepeats but autorepeat is turned off for that key, don't click
+  *   ie down == last key && autorepeat on for key && keyclick on => click
+  * only click for downs
+  */
+ 
+ static int write_keyboard(keyboard,request,data)
+   HIL_Device *keyboard;
+   int request;
+   char *data;
+ {
+   int fd = keyboard->fd;
+ 
+ /*fprintf(stderr,"write keyboard, request is %d\n",request);		/*  */
+   switch (request)
+   {
+     case _XChangeFeedbackControl:
+     {
+       HPKeyboardFeedbackControl *kctrl = (HPKeyboardFeedbackControl *)data;
+ 
+       if (kctrl->class == KbdFeedbackClass)
+       {
+ 	int mask = kctrl->leds;
+ 
+ 	if (keyboard->device->reverse_y_axes)	/* its a button box */
+ 	{
+ 	  set_LED(fd, 0, mask & 1);
+ 	}
+ 	else		/* a keyboard */
+ 	{
+ 	  set_LED(fd, 1, mask & SCROLLLOCK_LED);
+ 	  set_LED(fd, 2, mask & NUMLOCK_LED);
+ 	  set_LED(fd, 3, mask & CAPSLOCK_LED);
+ 	}
+ 
+ 	set_autorepeat(fd, kctrl->autoRepeat);
+ 
+ 	set_bell_attributes(
+ 	  kctrl->bell_percent, kctrl->bell_pitch, kctrl->bell_duration);
+ 
+ 	return WRITE_SUCCESS;
+       }
+       break;
+     }
+     case _XBell:
+     {
+       HPKeyboardFeedbackControl *kctrl = (HPKeyboardFeedbackControl *)data;
+ 
+       if (kctrl->click)
+         ding(TRUE, kctrl->click);
+       else
+         ding(FALSE, kctrl->bell_percent);
+       return WRITE_SUCCESS;
+     }
+     case _XSetDeviceValuators:
+     case _XChangeDeviceControl:
+     case _XSetDeviceMode:
+     default:
+       break;
+   }
+   return WRITE_FAILURE;
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************** BarCode Reader ************************** */
+ /* ******************************************************************** */
+ 
+ static unsigned char ascii_to_code[128][7] =
+ {
+   {0x0c,0x0a,0x7a,0x7b,0x0b,0x0d,0},	/* 0x00 : cntl - @ */
+   {0x0c,0x5a,0x5b,0x0d,0,0,0},		/* 0x01 : cntl - a */
+   {0x0c,0x30,0x31,0x0d,0,0,0},		/* 0x02 : cntl - b */
+   {0x0c,0x34,0x35,0x0d,0,0,0},		/* 0x03 : cntl - c */
+   {0x0c,0x56,0x57,0x0d,0,0,0},		/* 0x04 : cntl - d */
+   {0x0c,0x68,0x69,0x0d,0,0,0},		/* 0x05 : cntl - e */
+   {0x0c,0x54,0x55,0x0d,0,0,0},		/* 0x06 :  cntl - f */
+   {0x0c,0x52,0x53,0x0d,0,0,0},		/* 0x07 :  cntl - g */
+   {0x0c,0x50,0x51,0x0d,0,0,0},		/* 0x08 :  cntl - h */
+   {0x0c,0xc0,0xc1,0x0d,0,0,0},		/* 0x09 :  cntl - i */
+   {0x0c,0xd0,0xd1,0x0d,0,0,0},		/* 0x0a :  cntl - j */
+   {0x0c,0xd2,0xd3,0x0d,0,0,0},		/* 0x0b :  cntl - k */
+   {0x0c,0xd4,0xd5,0x0d,0,0,0},		/* 0x0c :  cntl - l */
+   {0x0c,0xe0,0xe1,0x0d,0,0,0},		/* 0x0d :  cntl - m */
+   {0x0c,0xf0,0xf1,0x0d,0,0,0},		/* 0x0e :  cntl - n */
+   {0x0c,0xc2,0xc3,0x0d,0,0,0},		/* 0x0f :  cntl - o */
+   {0x0c,0xc4,0xc5,0x0d,0,0,0},		/* 0x10 :  cntl - p */
+   {0x0c,0x6c,0x6d,0x0d,0,0,0},		/* 0x11 :  cntl - q */
+   {0x0c,0x66,0x67,0x0d,0,0,0},		/* 0x12 :  cntl - r */
+   {0x0c,0x58,0x59,0x0d,0,0,0},		/* 0x13 :  cntl - s */
+   {0x0c,0x64,0x65,0x0d,0,0,0},		/* 0x14 :  cntl - t */
+   {0x0c,0x60,0x61,0x0d,0,0,0},		/* 0x15 :  cntl - u */
+   {0x0c,0x32,0x33,0x0d,0,0,0},		/* 0x16 :  cntl - v */
+   {0x0c,0x6a,0x6b,0x0d,0,0,0},		/* 0x17 :  cntl - w */
+   {0x0c,0x36,0x37,0x0d,0,0,0},		/* 0x18 :  cntl - x */
+   {0x0c,0x62,0x63,0x0d,0,0,0},		/* 0x19 :  cntl - y */
+   {0x0c,0x38,0x39,0x0d,0,0,0},		/* 0x1a :  cntl - z */
+   {0x0c,0xc6,0xc7,0x0d,0,0,0},		/* 0x1b :  cntl - [ */
+   {0x0c,0xca,0xcb,0x0d,0,0,0},		/* 0x1c :  cntl - \ */
+   {0x0c,0xc8,0xc9,0x0d,0,0,0},		/* 0x1d :  cntl - ] */
+   {0x0c,0x0a,0x72,0x73,0x0b,0x0d,0},	/* 0x1e :  cntl - ^ */
+   {0x0c,0x0a,0xb6,0xb7,0x0b,0x0d,0},	/* 0x1f :  cntl - _ */
+   {0xf2,0xf3,0,0,0,0,0},        	/* 0x20 :  space    */
+   {0x0a,0x7c,0x7d,0x0b,0,0,0},		/* 0x21 :  !        */
+   {0x0a,0xd8,0xd9,0x0b,0,0,0},		/* 0x22 :  "        */
+   {0x0a,0x78,0x79,0x0b,0,0,0},		/* 0x23 :  #        */
+   {0x0a,0x76,0x77,0x0b,0,0,0},		/* 0x24 :  $        */
+   {0x0a,0x74,0x75,0x0b,0,0,0},		/* 0x25 :  %        */
+   {0x0a,0x70,0x71,0x0b,0,0,0},		/* 0x26 :  &        */
+   {0xd8,0xd9,0,0,0,0,0},        	/* 0x27 :  '        */
+   {0x0a,0xb2,0xb3,0x0b,0,0,0},		/* 0x28 :  (        */
+   {0x0a,0xb4,0xb5,0x0b,0,0,0},		/* 0x29 :  )        */
+   {0x0a,0xb0,0xb1,0x0b,0,0,0},		/* 0x2a :  *        */
+   {0x0a,0xb8,0xb9,0x0b,0,0,0},		/* 0x2b :  +        */
+   {0xe2,0xe3,0,0,0,0,0},        	/* 0x2c :  ,        */
+   {0xb6,0xb7,0,0,0,0,0},        	/* 0x2d :  -        */
+   {0xe4,0xe5,0,0,0,0,0},        	/* 0x2e :  .        */
+   {0xe6,0xe7,0,0,0,0,0},        	/* 0x2f :  /        */
+   {0xb4,0xb5,0,0,0,0,0},        	/* 0x30 :  0        */
+   {0x7c,0x7d,0,0,0,0,0},        	/* 0x31 :  1        */
+   {0x7a,0x7b,0,0,0,0,0},        	/* 0x32 :  2        */
+   {0x78,0x79,0,0,0,0,0},        	/* 0x33 :  3        */
+   {0x76,0x77,0,0,0,0,0},        	/* 0x34 :  4        */
+   {0x74,0x75,0,0,0,0,0},        	/* 0x35 :  5        */
+   {0x72,0x73,0,0,0,0,0},        	/* 0x36 :  6        */
+   {0x70,0x71,0,0,0,0,0},        	/* 0x37 :  7        */
+   {0xb0,0xb1,0,0,0,0,0},        	/* 0x38 :  8        */
+   {0xb2,0xb3,0,0,0,0,0},        	/* 0x39 :  9        */
+   {0x0a,0xd6,0xd7,0x0b,0,0,0},		/* 0x3a :  :        */
+   {0xd6,0xd7,0,0,0,0,0},        	/* 0x3b :  ;        */
+   {0x0a,0xe2,0xe3,0x0b,0,0,0},		/* 0x3c :  <        */
+   {0xb8,0xb9,0,0,0,0,0},        	/* 0x3d :  =        */
+   {0x0a,0xe4,0xe5,0x0b,0,0,0},		/* 0x3e :  >        */
+   {0x0a,0xe6,0xe7,0x0b,0,0,0},		/* 0x3f :  ?        */
+   {0x0a,0x7a,0x7b,0x0b,0,0,0},		/* 0x40 :  @        */
+   {0x0a,0x5a,0x5b,0x0b,0,0,0},		/* 0x41 :  A        */
+   {0x0a,0x30,0x31,0x0b,0,0,0},		/* 0x42 :  B        */
+   {0x0a,0x34,0x35,0x0b,0,0,0},		/* 0x43 :  C        */
+   {0x0a,0x56,0x57,0x0b,0,0,0},		/* 0x44 :  D        */
+   {0x0a,0x68,0x69,0x0b,0,0,0},		/* 0x45 :  E        */
+   {0x0a,0x54,0x55,0x0b,0,0,0},		/* 0x46 :  F        */
+   {0x0a,0x52,0x53,0x0b,0,0,0},		/* 0x47 :  G        */
+   {0x0a,0x50,0x51,0x0b,0,0,0},		/* 0x48 :  H        */
+   {0x0a,0xc0,0xc1,0x0b,0,0,0},		/* 0x49 :  I        */
+   {0x0a,0xd0,0xd1,0x0b,0,0,0},		/* 0x4a :  J        */
+   {0x0a,0xd2,0xd3,0x0b,0,0,0},		/* 0x4b :  K        */
+   {0x0a,0xd4,0xd5,0x0b,0,0,0},		/* 0x4c :  L        */
+   {0x0a,0xe0,0xe1,0x0b,0,0,0},		/* 0x4d :  M        */
+   {0x0a,0xf0,0xf1,0x0b,0,0,0},		/* 0x4e :  N        */
+   {0x0a,0xc2,0xc3,0x0b,0,0,0},		/* 0x4f :  O        */
+   {0x0a,0xc4,0xc5,0x0b,0,0,0},		/* 0x50 :  P        */
+   {0x0a,0x6c,0x6d,0x0b,0,0,0},		/* 0x51 :  Q        */
+   {0x0a,0x66,0x67,0x0b,0,0,0},		/* 0x52 :  R        */
+   {0x0a,0x58,0x59,0x0b,0,0,0},		/* 0x53 :  S        */
+   {0x0a,0x64,0x65,0x0b,0,0,0},		/* 0x54 :  T        */
+   {0x0a,0x60,0x61,0x0b,0,0,0},		/* 0x55 :  U        */
+   {0x0a,0x32,0x33,0x0b,0,0,0},		/* 0x56 :  V        */
+   {0x0a,0x6a,0x6b,0x0b,0,0,0},		/* 0x57 :  W        */
+   {0x0a,0x36,0x37,0x0b,0,0,0},		/* 0x58 :  X        */
+   {0x0a,0x62,0x63,0x0b,0,0,0},		/* 0x59 :  Y        */
+   {0x0a,0x38,0x39,0x0b,0,0,0},		/* 0x5a :  Z        */
+   {0xc6,0xc7,0,0,0,0,0},        	/* 0x5b :  [        */
+   {0xca,0xcb,0,0,0,0,0},        	/* 0x5c :  \        */
+   {0xc8,0xc9,0,0,0,0,0},        	/* 0x5d :  ]        */
+   {0x0a,0x72,0x73,0x0b,0,0,0},		/* 0x5e :  ^        */
+   {0x0a,0xb6,0xb7,0x0b,0,0,0},		/* 0x5f :  _        */
+   {0x7e,0x7f,0,0,0,0,0},        	/* 0x60 :  `        */
+   {0x5a,0x5b,0,0,0,0,0},		/* 0x61 :  a        */
+   {0x30,0x31,0,0,0,0,0},		/* 0x62 :  b        */
+   {0x34,0x35,0,0,0,0,0},		/* 0x63 :  c        */
+   {0x56,0x57,0,0,0,0,0},		/* 0x64 :  d        */
+   {0x68,0x69,0,0,0,0,0},		/* 0x65 :  e        */
+   {0x54,0x55,0,0,0,0,0},		/* 0x66 :  f        */
+   {0x52,0x53,0,0,0,0,0},		/* 0x67 :  g        */
+   {0x50,0x51,0,0,0,0,0},		/* 0x68 :  h        */
+   {0xc0,0xc1,0,0,0,0,0},		/* 0x69 :  i        */
+   {0xd0,0xd1,0,0,0,0,0},		/* 0x6a :  j        */
+   {0xd2,0xd3,0,0,0,0,0},		/* 0x6b :  k        */
+   {0xd4,0xd5,0,0,0,0,0},		/* 0x6c :  l        */
+   {0xe0,0xe1,0,0,0,0,0},		/* 0x6d :  m        */
+   {0xf0,0xf1,0,0,0,0,0},		/* 0x6e :  n        */
+   {0xc2,0xc3,0,0,0,0,0},		/* 0x6f :  o        */
+   {0xc4,0xc5,0,0,0,0,0},		/* 0x70 :  p        */
+   {0x6c,0x6d,0,0,0,0,0},		/* 0x71 :  q        */
+   {0x66,0x67,0,0,0,0,0},		/* 0x72 :  r        */
+   {0x58,0x59,0,0,0,0,0},		/* 0x73 :  s        */
+   {0x64,0x65,0,0,0,0,0},		/* 0x74 :  t        */
+   {0x60,0x61,0,0,0,0,0},		/* 0x75 :  u        */
+   {0x32,0x33,0,0,0,0,0},		/* 0x76 :  v        */
+   {0x6a,0x6b,0,0,0,0,0},		/* 0x77 :  w        */
+   {0x36,0x37,0,0,0,0,0},		/* 0x78 :  x        */
+   {0x62,0x63,0,0,0,0,0},		/* 0x79 :  y        */
+   {0x38,0x39,0,0,0,0,0},		/* 0x7a :  z        */
+   {0x0a,0xc6,0xc7,0x0b,0,0,0},		/* 0x7b :  {        */
+   {0x0a,0xca,0xcb,0x0b,0,0,0},		/* 0x7c :  |        */
+   {0x0a,0xc6,0xc9,0x0b,0,0,0},		/* 0x7d :  }        */
+   {0x0a,0x7e,0x7f,0x0b,0,0,0},		/* 0x7e :  ~        */
+   {0x0a,0x3e,0x3f,0x0b,0,0,0},		/* 0x7f :  delete   */
+ };
+ 
+ 
+ static int read_barcode(device, data, data_type, pending)
+   HIL_Device *device;
+   unsigned char *data, *data_type;
+   int *pending;
+ {
+   unsigned char *ptr;
+ 
+   ptr = device->ptr;
+ 
+   if (ptr)			/* In the middle of process data */
+   {
+     if (!*ptr)
+     {
+       device->ptr = NULL;
+       return READ_SUCCESS;
+     }
+ 
+     *pending = 1;
+     *data_type = KEY_DATA;
+     *data = *ptr++;
+ 
+     device->ptr = ptr;
+ 
+     return READ_SUCCESS;
+   }
+ 
+   if (get_packet(device->fd))
+   {
+     int poll_hdr = a_packet.poll_hdr;
+ 
+     pop_packet();
+ 
+     if (poll_hdr & KEY_DATA_MASK)
+     {
+       device->ptr = ascii_to_code[a_packet.data[0]];
+       return read_barcode(device, data, data_type, pending);
+     }
+   }
+ 
+   *pending = 0;
+   return READ_FAILURE;
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************* Parse X*devices ************************** */
+ /* ******************************************************************** */
+ 
+ /* 
+   X*devices:
+     position device_name X_use
+       eg:
+       first keyboard keyboard
+       first mouse    pointer
+       first tablet   other
+ 
+     path X_use
+       eg:
+         /dev/hil3    keyboard
+ 	/tmp/foo     pointer
+ 	/dev/hil7    other
+ 
+     path  hil_path
+       Use path instead of "/dev/hil".
+  */
+ 
+ 
+ 
+ static int parse_1_parm(use, use_as) char *use; int *use_as;
+ {
+   if      (0 == strcmp(use, "POINTER"))  *use_as = XPTR_USE;
+   else if (0 == strcmp(use, "KEYBOARD")) *use_as = XKBD_USE;
+   else if (0 == strcmp(use, "OTHER"))    *use_as = XOTH_USE;
+   else
+   {
+     fprintf(stderr,
+       "Bad device use \"%s\" in X*devices file, entry skipped.\n", use);
+     return FALSE;
+   }
+   return TRUE;
+ }
+ 
+ /***********************************************************************
+  *
+  * This routine is invoked when two parameters are specified.
+  * Either they are a device path and intended use, or a device loop path.
+  */
+ 
+ static int parse_2_parms(dev, use, use_as)
+     char *dev, *use;
+     int *use_as;
+     {
+     uppercase(use);
+ 
+     if (0 == strcmp (use,"HIL_PATH"))
+ 	{
+ 	strcpy (hil_file_base_name,dev);
+ 	return FALSE;		/* Fake out configure() */
+ 	}
+ 
+     return parse_1_parm(use, use_as);
+     }
+ 
+     /* Parse lines with 3 parameters, such as:
+      *   first keyboard keyboard
+      * Params are a position, a device type, and its intended use.
+      * Input:
+      *   pos : first param
+      *   x_name : second param
+      *   use : third param
+      *   ipos : 
+      *   itype : dev_type
+      *   use_as : Pointer to int, filled in with what third parm is.
+      * Returns:
+      */
+ static int parse_three_parms(pos, x_name, use, ipos, itype, use_as)
+     char *pos, *x_name, *use;
+     int *ipos, *itype, *use_as;
+ {
+     int i;
+ 
+     uppercase(pos);
+     uppercase(use);
+ 
+     for (i=0; i<NITEMS(h_position); i++)
+ 	if (0 == strcmp(h_position[i], pos))
+ 	{
+ 	  *ipos = i + 1;	/* h_position[0] = "FIRST" == 1 */
+ 	  break;
+ 	}
+ 
+     if (i >= 7)                  /* failed, skip this entry */
+     {
+ 	fprintf(stderr,
+ 	    "Bad ordinal \"%s\" in X*devices file, entry skipped.\n",
+ 	    pos);
+ 	return FALSE;
+     }
+ 
+     uppercase(x_name);
+ 
+     for (i=0; i<NITEMS(devices); i++)
+ 	if (0 == strcmp(devices[i].X_name,x_name))
+ 	{
+ 	  *itype = devices[i].dev_type;
+ 	  break;
+ 	}
+ 
+     if (i == NITEMS(devices)) /* failed, skip this entry */
+     {
+ 	fprintf(stderr,
+ 	    "Bad device type \"%s\" in X*devices file, entry skipped.\n",
+ 	    x_name);
+ 	return FALSE;
+     }
+ 
+     return parse_1_parm(use, use_as);
+ }
+ 
+     /* 
+      * Formats:
+      *   |#comment
+      *   |   #comment
+      *   |word [#comment]
+      *   |  word [#comment]
+      *   |word word  [#comment]
+      *   |word word word [#comment]
+      *   |word word word word [#comment]
+      */
+ static int process_path(path, itype, ipos, parm1, use_as)
+   char *path, *parm1;
+   int *ipos, *itype, *use_as;
+ {
+   int parms;
+   char parm2[256], parm3[256];
+ 
+   parm1[0] = parm2[0] = parm3[0] = '\0';
+ 
+   parms = sscanf(path, "%s%s%s", parm1, parm2, parm3);
+ 
+        if (*parm1 == '#') return FALSE;	/* comment line */
+   else if (*parm2 == '#') parms = 1;	/* error */
+   else if (*parm3 == '#') parms = 2;
+ 
+   if (2 == parms)	/* device name specified */
+     return parse_2_parms (parm1, parm2, use_as);
+   if (3 == parms)
+     return parse_three_parms (parm1, parm2, parm3, ipos, itype, use_as);
+ 
+   fprintf(stderr,
+     "Bad line in X*devices file, entry skipped:\n   %s", path);
+ 
+   return FALSE;
+ }
+ 
+ #define MAX_X0devices 20
+ typedef struct
+ {
+   int live, dev_type, position, use_as, a_path;
+   char path[256];
+ } X0Device;
+ 
+ static void set_X0device(ptr, type, position, use_as, path)
+   X0Device *ptr; char *path;
+ {
+   ptr->live = TRUE;
+   ptr->dev_type = type;
+   ptr->position = position;
+   ptr->use_as |= use_as;
+   if (use_as == XKBD_USE || use_as == XPTR_USE)
+       ptr->use_as |= EXPLICIT;
+   if (type == -1)	/* 2 params, ie got a path */
+   {
+     ptr->a_path = TRUE;
+     strcpy(ptr->path, path);
+   }
+ }
+ 
+ static void pick_default_device(live, type, use_as, x, in_use)
+ {
+ 
+   if (live) return;	/* device specified, no need to pick a default */
+ 	/* return last device of type */
+   find_device_by_type(type, 100, use_as, x, in_use);
+   /* else no default */
+ }
+ 
+ static HIL_Device *do_path(path, use_as) char *path;
+ {	/* "/dev/hil3 keyboard" or "/tmp/keys keyboard" */
+   int nth, len;
+ 
+   len = strlen(hil_file_base_name);
+ 
+       /* if "/dev/hilx", use existing loop stuff */
+   nth = path[len] - '0';	/* '1' => 0x1 */
+   if (
+       (len + 1) == strlen(path)				&&
+       (0 == strncmp(path, hil_file_base_name, len))	&&
+       (1 <= nth && nth <= 7))
+   {
+     return use_device_n(nth, use_as);
+   }
+ 	/* "/tmp/keys" or "/dev/HIL" or "/dev/hil8" */
+   return add_device(path, FALSE, use_as);
+ }
+ 
+ #define RECYCLE_CMD  	"X*devices:Recycle"
+ 
+ static int process_X0devices(d) HPInputDeviceHeader *d;
+ {
+   FILE *fptr;
+   char *path;
+   int n, use_as;
+   X0Device X0devices[MAX_X0devices], *ptr;
+ 
+   path = d->path + sizeof(RECYCLE_CMD);
+   memset(X0devices, 0, sizeof(X0devices));
+   memset(loop_device_list, 0, sizeof(loop_device_list));
+ 
+   if (fptr = fopen(path, "r"))
+   {
+     char buf[256], word[256], *keyword;
+     int num_X0devices = 2, ignoring, itype, ipos;
+ 
+     buf[0] = '\0';
+     ignoring = FALSE; keyword = "BEGIN_DEVICE_DESCRIPTION";
+ 
+     while (fgets(buf, 250, fptr))
+     {
+       if (*buf == '#' || *buf == '\n') continue;  /* quick speed ups */
+ 
+       if (1 == sscanf(buf, "%s", word))
+       {
+ 	uppercase(word);
+ 	if (0 == strcmp(keyword, word))
+ 	{
+ 	  keyword = ignoring ?
+ 		"BEGIN_DEVICE_DESCRIPTION" : "END_DEVICE_DESCRIPTION";
+ 	  ignoring = !ignoring;
+ 	  continue;
+ 	}
+       }
+ 
+       itype = -1;
+       if (ignoring || !process_path(buf, &itype, &ipos, word, &use_as))
+ 	continue;
+ 
+       switch(use_as)
+       {
+ 	case XKBD_USE: n = XKEYBOARD; break;
+ 	case XPTR_USE: n = XPOINTER; break;
+ 	case XOTH_USE:
+ 	  if (MAX_X0devices == num_X0devices)
+ 	  {
+ 	    fprintf(stderr, "Too many \"other\" devices in X*devices\n");
+ 	    continue;
+ 	  }
+ 	  n = num_X0devices++;
+ 	  break;
+       }
+       set_X0device(&X0devices[n], itype, ipos, use_as, word);
+     }
+ 
+     fclose(fptr);
+   }
+ 
+   catalog_loop();
+ 
+   for (n = MAX_X0devices, ptr = X0devices; n--; ptr++)
+   {
+     if (!ptr->live) continue;
+     if (ptr->a_path) do_path(ptr->path, ptr->use_as);
+     else
+     {
+       if (ptr->dev_type == NULL_DEVICE)
+       {
+ 	HIL_Device *device;
+ 
+         if (find_null_device(ptr->use_as) == NULL)
+ 	  if (device = add_device("/dev/null", TRUE, ptr->use_as))
+ 	     device->device = &devices[0];
+       }
+       else
+         find_device_by_type(ptr->dev_type, ptr->position, ptr->use_as, FALSE, TRUE);
+     }
+   }
+ 
+   pick_default_device(X0devices[XKEYBOARD].live, KEYBOARD, XKBD_USE, FALSE, FALSE);
+   if (!find_device_by_use(XKBD_USE))		/* still no keyboard */
+     pick_default_device(FALSE, KEYBOARD, XKBD_USE, TRUE, FALSE);
+   if (!find_device_by_use(XKBD_USE))		/* still no keyboard */
+     pick_default_device(X0devices[XKEYBOARD].live, KEYBOARD, XKBD_USE, FALSE, TRUE);
+   if (!find_device_by_use(XKBD_USE))		/* still no keyboard */
+     pick_default_device(FALSE, KEYBOARD, XKBD_USE, TRUE, TRUE);
+ 
+   pick_default_device(X0devices[XPOINTER].live, MOUSE,    XPTR_USE, FALSE, FALSE);
+   if (!find_device_by_use(XPTR_USE))		/* still no pointer */
+     pick_default_device(FALSE, MOUSE, XPTR_USE, TRUE, FALSE);
+   if (!find_device_by_use(XPTR_USE))		/* still no pointer */
+     pick_default_device(X0devices[XPOINTER].live, MOUSE, XPTR_USE, FALSE, TRUE);
+   if (!find_device_by_use(XPTR_USE))		/* still no pointer */
+     pick_default_device(FALSE, MOUSE, XPTR_USE, TRUE, TRUE);
+   if (!find_device_by_use(XPTR_USE))		/* still no pointer */
+   {					/* use X keyboard (if it exists) */
+     HIL_Device *device;
+     if ((device = find_device_by_use(XKBD_USE)) && 
+ 	 device->device->dev_type != NULL_DEVICE)
+ 	 device->use_as |= XPTR_USE;
+   }
+ 
+   name_loop();
+ 
+   if (X0devices[XPOINTER].position == 1 &&	/* position is "FIRST"  */
+       X0devices[XPOINTER].dev_type == KEYBOARD) /* type is KEYBOARD     */
+       d->reserved[3] = 1;
+ 
+   return TRUE;
+ }
+ 
+ /* ******************************************************************** */
+ /* ************************ X Server Interface ************************ */
+ /* ******************************************************************** */
+ 
+ #define PARSE_KEYWORD	"X*devices:"
+ 
+     /* 
+      * Notes:
+      *   The "path" is passed in unchanged from X0devices.  I overload this:
+      *     <device_name>
+      *     <device_name>:<keymap_name>
+      *     you_pick
+      *     you_pick:<keymap_name>
+      */
+ static int configure(d) HPInputDeviceHeader *d;
+ {
+   HIL_Device *ptr;
+ 
+   if (0 == strncmp(d->path, RECYCLE_CMD, sizeof(RECYCLE_CMD) - 1))
+   {
+     open_beeper();
+     process_X0devices(d);
+     next_device(TRUE);
+ 
+     return INIT_SUCCESS;
+   }
+   else if (0 == strcmp(d->path, PARSE_KEYWORD))
+   {
+     while ((ptr = next_device(FALSE)) && !ptr->device_exists)  ;
+     if (!ptr) return INIT_FAILURE;
+     strcpy(d->path,ptr->file_name);
+   }
+   else
+   {
+     char *path, dev_path[255];
+     int i, fd, ipos, itype, use_as;
+ 
+     catalog_loop();
+ 
+     ptr = do_path(d->path, XEXT_USE);
+ 
+     if (!ptr) return INIT_FAILURE;
+ 
+     ptr->use_as &= ~EXPLICIT;
+ 
+     name_loop();
+ 
+ #ifdef VERBOSE
+ printf("Configure: %d \"%s\" %s %d %s\n",
+   ptr->fd, path, ptr->keymap, d->button_chording, ptr->long_name); 	/*  */
+ #endif /* VERBOSE */
+   }
+ 
+   d->min_kcode = (ptr->hil_id == QUAD_ID ? NINE_KNOB_ID : ptr->hil_id);
+   d->max_kcode = ptr->iob;
+   ptr->latching_enabled = d->reserved[0];
+   d->reserved[0] = HP_HIL;
+   d->reserved[1] = ptr->device->dev_type;
+   if (ptr->use_as & XKBD_USE || ptr->use_as & XPTR_USE)
+       ptr->use_as &= (XKBD_USE | XPTR_USE | EXPLICIT);
+   d->reserved[2] = ptr->use_as;
+   d->x_name = ptr->long_name;
+   d->file_ds = ptr->fd;
+   switch (ptr->device->x_type)
+   {
+     case KEYBOARD:
+       if (ptr->iob & HILIOB_NPA)
+         d->reserved[0] |= PC101_KBD;
+       else
+         d->reserved[0] |= HP_ITF_KBD;
+       set_autorepeat(ptr->fd, AutoRepeatModeOn);
+ 
+       d->keymap_name = ptr->keymap;
+       d->flags = DATA_IS_8_BITS;
+       d->num_keys = 1;
+ 
+       d->num_ledf = 1;	                 /* number of led feedbacks */
+       d->ledf = &ptr->num_leds;	         /* number of leds          */
+ 
+       d->reset = 0xf;		/* Reset keycode on HIL keyboards*/
+       d->reset_mods = (ShiftMask | ControlMask);	/* Shift Control */
+ 
+       break;
+     case MOUSE:
+       d->keymap_name = ptr->keymap;
+       d->flags = ptr->data_size;
+       if (ptr->flags & HIL_ABSOLUTE)
+ 	d->flags |= (ABSOLUTE_DATA | REPORTS_PROXIMITY);
+       d->num_keys = 0;
+       d->ax_num = ptr->num_axes;
+ 
+       ptr->error = 0;
+       ptr->chorded_button_up = 0;
+ 
+       {
+ 	int buttons = ptr->num_buttons;
+ 
+ 	if (1 < buttons && buttons <= MAX_BUTTONS_FOR_CHORDING)/* we can chord*/
+ 	{
+ 	  if (buttons==2 && d->button_chording==0)
+ 	      d->button_chording=100;
+ 	  ptr->chording_interval = d->button_chording;
+ 	  if (d->button_chording) buttons = (2 * buttons - 1);
+ 	}
+ 	if (MAX_X_BUTTONS < buttons) buttons = MAX_X_BUTTONS;
+ 	d->num_buttons = buttons;
+       }
+ 
+       d->num_keys = 0;     		/* no keys                 */
+       d->resolution = ptr->res_x / 100;	/* resolution in counts/cm */
+       d->max_x = ptr->max_x;		/* maximum x value in counts */
+       d->max_y = ptr->max_y;		/* maximum y value in counts */
+ 
+       break;
+     case XOTHER:	/* !!!??? the NULL device */
+       d->ax_num = 2;
+       d->max_x = d->max_y = 1000;
+ /*      d->res_x = d->res_y = 1000;	/*  */
+       d->resolution = 10;
+       d->num_keys = 1;
+       d->num_buttons = 3;
+       d->min_kcode = 0xd5;
+       d->keymap_name = "ITF_US_English";
+       break;
+     default: return INIT_FAILURE;
+   }
+ 
+   return INIT_SUCCESS;
+ }
+ 
+ /**************************************************************************
+  *
+  * This routine is called by the X server to read from the device driver.
+  *
+  */
+ 
+ static int read_device(fd, data, data_type, pending)
+   int fd, *pending;
+   unsigned char *data, *data_type;
+ {
+   HIL_Device *device;
+ 
+   device = find_device_by_fd(fd);
+ 
+ /*fprintf(stderr,"read_device(%d)\n", fd);	/*  */
+ 
+   if (device)
+ 	return device->device->read_device(device, data, data_type, pending);
+ 
+   *pending = 0;
+   return READ_FAILURE;
+ }
+ 
+ /**************************************************************************
+  *
+  * This routine is called by the X server to write to the device driver.
+  *
+  */
+ 
+ static int write_to_device(fd, request, data)
+   int fd, request;
+   char *data;
+ {
+   HIL_Device *device;
+ 
+   device = find_device_by_fd(fd);
+ 
+ /*fprintf(stderr,"write_device(%d)\n", fd);	/*  */
+ 
+   if (device) return device->device->write_device(device, request, data);
+ 
+   return WRITE_FAILURE;
+ }
+ 
+ /**************************************************************************
+  *
+  * This routine is called by the X server to initialize the device driver.
+  *
+  */
+ 
+ int hil_driver_Init(serialproc) SerialProcs *serialproc;
+ {
+   serialproc->configure	= configure;
+   serialproc->read	= read_device;
+   serialproc->write	= write_to_device;
+   serialproc->close	= close_device;
+ 
+   return INIT_SUCCESS;
+ }
+ 
+ #ifdef TEST
+ 
+ /* ******************************************************************** */
+ /* ***************************** TESTing ****************************** */
+ /* ******************************************************************** */
+ 
+ void read_dump(device) HIL_Device *device;
+ {
+   unsigned char data[20], data_type = 0;
+   int pending;
+ 
+   if (!device) return;
+ 
+   while (READ_SUCCESS == read_device(device->fd, &data, &data_type, &pending))
+   {
+     int i;
+ 
+ if (pending == 0) continue;
+     printf("%d %d ", device->fd, pending);
+     if (data_type & MOTION_DATA)	printf("Motion ");
+     if (data_type & PROXIMITY_DATA)	printf("Proximity ");
+     if (data_type & BUTTON_DATA)	printf("Button ");
+     if (data_type & KEY_DATA)		printf("Key ");
+     printf(": ");
+     switch (device->data_size)
+     {
+       case DATA_IS_8_BITS:
+         for (i = 0; i < pending; i++) printf("%x ", data[i]);
+ 	break;
+       case DATA_IS_16_BITS:
+         for (i = 0; i < pending; i += 2)
+ 	  printf("%x ", get_data(data + i, TRUE));
+         break;
+       default:
+         printf("read_dump():  Unknown data size: %d", device->data_size);
+ 	break;
+     }
+     printf("\n");
+     data_type = 0;
+   }
+ }
+ 
+ main()
+ {
+   HPInputDeviceHeader d;
+   HIL_Device *keyboard = NULL, *mouse = NULL;
+   int s;
+ 
+ #if 1
+   strcpy(d.path,"X*devices:Recycle:/etc/X11/X0devices");
+   configure(&d);
+   strcpy(d.path,"X*devices:");
+   while(INIT_SUCCESS == configure(&d))
+   {
+     if (d.file_ds != -1)
+     {
+       HIL_Device *ptr;
+ 
+       ptr = find_device_by_fd(d.file_ds);
+       switch (ptr->device->x_type)
+       {
+ 	case KEYBOARD: keyboard = ptr; break;
+ 	case MOUSE:    mouse = ptr;    break;
+       }
+     }
+     strcpy(d.path,"X*devices:");
+   }
+ #else
+   strcpy(d.path,"second keyboard keyboard");	/*  */
+ /*  strcpy(d.path,"third keyboard keyboard");	/*  */
+ /*  strcpy(d.path,"last keyboard keyboard");	/*  */
+ /*  strcpy(d.path,"/dev/hil4 keyboard");	/*  */
+   s = configure(&d);
+   if (s == INIT_SUCCESS) keyboard = find_device_by_fd(d.file_ds);
+   else fprintf(stderr,"Couldn't find a keyboard\n");
+ 
+   strcpy(d.path,"first mouse pointer");
+   d.button_chording = 100;
+   s = configure(&d);
+   if (s == INIT_SUCCESS) mouse = find_device_by_fd(d.file_ds);
+   else fprintf(stderr,"Couldn't find a mouse\n");
+ #endif
+ 
+   while (1)
+   {
+     read_dump(keyboard);
+     read_dump(mouse);
+   }
+ }
+ 
+ #endif	/* TEST */
+ #ifdef DEBUG
+ #include <signal.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <sys/termio.h>
+ #include <sys/ptyio.h>
+ #include <sys/hilioctl.h>
+ #include "HilCmds.h"
+ #include "HilData.h"
+ 
+ #define max( a, b ) (( a > b ) ? a : b )
+ #define min( a, b ) (( a > b ) ? b : a )
+ 
+ int BaseFiledescriptor = 99;
+ int MaxOpen;
+ int SelectMask;
+ void SignalHandler();
+ void CloseAllHilDevices();
+ void HandshakeDevice();
+ #define HOSTBUFFERSIZE 1024 
+ char Hostname[ HOSTBUFFERSIZE ];
+ #define PTY_DIR		"/tmp/"
+ #define NUM_DEVS 9
+ 
+ /*
+  * the following strings are returned by the HIL driver
+  * describing the associated HIL device in reponse to 
+  * an HILID ioctl
+  */
+ unsigned char three_axes[11] =
+   { 0x75,0x13,0x61,0x0F,0x03,   0,    0,   0,   0,   0,   0 };
+ unsigned char no_axes[11] =
+   { 0x74,0x00, 0x0b,   0,   0,   0,    0,   0,   0,   0,   0 };
+ unsigned char error_device[11] =
+   { 0x73,0x00, 0x0f,   0,   0,   0,    0,   0,   0,   0,   0 };
+ unsigned char no_iob_rel[11] =
+   { 0x71,0x01, 0x90,   0x01,   0,   0,    0,   0,   0,   0,   0 };
+ unsigned char one_axis[11] =
+   { 0x70,0x41, 0x90,   0x01,   0x03,   0x04,    0x03,   0,   0,   0,   0 };
+ unsigned char pc_keyboard[11] =
+   { 0xde,0x10, 0x30,   0,   0,   0,    0,   0,   0,   0,   0 };
+ unsigned char us_keyboard[11] =
+   { 0xdf,   0,0xc2,   0,   0,   0,    0,   0,   0,   0,   0 };
+ unsigned char asize_tablet[11] =
+   { 0x93,0x72,0x90,0x01,0x80,0x2e,0xd4,0x21,0x0c,   0,   0 };
+ unsigned char bsize_tablet[11] =
+   { 0x94,0x72,0x90,0x01,0x90,0x43,0xd4,0x2e,0x0b,   0,   0 };
+ unsigned char three_button_mouse[11] =
+   { 0x72,0x12,0xC2,0x1E,0x03,0x43,    0,   0,   0,   0,   0 };
+ unsigned char two_button_mouse[11] =
+   { 0x68,0x12,0xC2,0x1E,0x02,0x43,    0,   0,   0,   0,   0 };
+ unsigned char buttonbox[11]=
+   { 0x30,0x10,0x80,0x1E,0x00,   0,    0,   0,   0,   0,   0 };
+ unsigned char id_module[11]=
+   { 0x34,0x10,0x00,0x00,0x00,   0,    0,   0,   0,   0,   0 };
+ unsigned char nineknobbox[11] =
+   { 0x61,0x13,0x61,0x0F,0x00,   0,    0,   0,   0,   0,   0 };
+ unsigned char oneknobbox[11] =
+   { 0x60,0x11,0x61,0x0F,0x00,   0,    0,   0,   0,   0,   0 };
+ unsigned char barcode[11] =
+   { 0x5c,0,0x80,   0,   0,   0,    0,   0,   0,   0,   0 };
+ unsigned char quadrature[11] =
+   { 0x61,0x12,0x61,0x0f,0x03,0x43,    0,   0,   0,   0,   0 };
+ unsigned char touchscreen[11] =
+   { 0x8c,0x52,0x0a,0x01,0x38,0,0x2a,0,0x08,   0,   0 };
+ unsigned char bogus[11]=  
+   {    0,   0,    0,   0,   0,   0,    0,   0,   0,   0,   0 };
+ 
+ struct	HilDeviceInfo {
+     int			id;
+     char		* name;
+     unsigned char	* pHilIdString;
+     unsigned char	num_keys;
+     unsigned char	min_kcode;
+     unsigned char	max_kcode;
+ };
+ struct	 HilDeviceInfo DeviceTable[] = {
+     { X_BUTTONBOX,   "BUTTONBOX",    buttonbox, 32,8,39 },
+     { X_ID_MODULE,   "ID_MODULE",    id_module,      0,0,0 },
+     { X_BARCODE,     "BARCODE",      barcode,  109,8,135 },
+     { X_NO_AXES,     "NO_AXES",      no_axes,      0,0,0 },
+     { X_THREE_AXES,   "THREE_AXES",  three_axes,      0,0,0 },
+     { X_ONE_AXIS,    "ONE_AXIS",     one_axis,      0,0,0 },
+     { X_NO_IOB_REL,  "NO_IOB_REL",   no_iob_rel,    0,0,0 },
+     { X_ERROR_DEVICE,"ERROR_DEVICE", error_device,  0,0,0 },
+     { X_ONE_KNOB,    "ONE_KNOB",     oneknobbox,      0,0,0 },
+     { X_NINE_KNOB,   "NINE_KNOB",    nineknobbox,  0,0,0 },
+     { X_QUADRATURE,  "QUADRATURE",   quadrature,  0,0,0 },
+     { X_MOUSE_2B,    "MOUSE",        two_button_mouse,  0,0,0 },
+     { X_MOUSE_3B,    "MOUSE",        three_button_mouse,  0,0,0 },
+     { X_TOUCHSCREEN, "TOUCHSCREEN",  touchscreen,  0,0,0 },
+     { X_TABLET_ASIZE,"TABLET_ASIZE", asize_tablet,  0,0,0 },
+     { X_TABLET_BSIZE,"TABLET_BSIZE", bsize_tablet,  0,0,0 },
+     { X_KB_US,       "KEYBOARD",     us_keyboard,109,8,135 },
+     { X_KB_PC,       "KEYBOARD",     pc_keyboard,109,8,135 },
+     { 0x00,        "NULL",         bogus,  0,0,0 } 
+ };
+ 
+ struct HilLoopInfo {
+ #define MAXNAMLEN	1024
+ 	char PtyName[MAXNAMLEN];	/* device name to link the pty to  */
+ 	char SlaveName[MAXNAMLEN];	/* pty slave name		   */
+ 	int  Pty;		/* fd of master side of device pty */
+ 	int  PtyMask; 		/* select mask for same		   */
+ 	int  PtyCount;		/* number of bytes written to pty  */
+ 	struct HilDeviceInfo *pHilDeviceInfo;
+ 	struct HilCommandLog *pNext;
+ 	struct HilCommandLog *pLast;
+ } hil[NUM_DEVS];
+ 
+ struct HilCommandLog {
+         int  Command;
+ 	struct HilCommandLog *pNext;
+ };
+ 
+ unsigned char tcget_info[17] =
+   { 0,0,0,0,0x09,0x67,0,0,0,0x7f,0x1c,0x23,0x40,0x04,0,0,0 };
+ 
+ /***********************************************************
+  *  
+  * Main entry point.  This program will fork into two processes.
+  * The first is a test program that will invoke the entry points
+  * provided by this input device driver.  The second is a daemon
+  * that will handle ioctls from the driver.
+  *  
+  * Functionality to be tested:
+  *
+  *   driver initialization entry point
+  *
+  *  - touch test
+  *
+  *   configuration entry point
+  *
+  *   - default configuration with no X*devices specification
+  *	- only a non-keyboard key device
+  *	- only a keyboard
+  *	- keyboard and mouse
+  *	- non-keyboard key device and mouse
+  *	- keyboard and non-mouse pointer
+  *	- multiple keyboards and mouse
+  *	- multiple key devices and mouse
+  *	- keyboard and multiple pointing devices
+  *	- multiple key devices and multiple pointing devices
+  *	- maximum number of input devices
+  *   - configuration with an X0devices file
+  *	- non-default keyboard device
+  *	- non-default pointer device
+  *	- null keyboard and null pointer
+  *	- null keyboard and mouse
+  *	- keyboard and null mouse
+  *	- specify "other" devices
+  *	- specify non-default ordinal
+  *	- specify invalid ordinal
+  *	- specify invalid device
+  *	- specify invalid use
+  *	- specify too many input devices
+  *	- specify too many input parameters
+  *	- specify not enough input parameters
+  *
+  *   read entry point
+  *  
+  *   - read keyboard data  
+  *   - read buttonbox data 
+  *   - read barcode data 
+  *   - read mouse motion/button data
+  *   - read tablet motion/button data
+  *   - read nine-knob motion data
+  *   - button chording
+  *
+  *   write entry point
+  *  
+  *   - turn on LEDS
+  *   - turn autorepeat on/off
+  *   - turn keyclick on/off
+  *   - sound the bell
+  *  
+  *   close entry point
+  *  
+  *   - touch test  
+  *  
+  ***********************************************************/
+ main(argc,argv)
+     char *argv[];
+     int argc;
+     {
+     int i, pid;
+ 
+     for (i=0; i<NUM_TEST_CASES; i++)
+ 	{
+         if ((pid = fork()) == 0)	/* This is the child process    */
+ #if 0
+         if (argc > 1)
+ #endif
+ 	    {
+ 	    do_child_process(i);
+ 	    exit(0);
+ 	    }
+         else			
+ 	    {
+ 	    usleep(50000, 0, NULL);
+ 	    do_parent_process(i);
+ 	    waitpid (pid, NULL, 0);
+ 	    }
+         }
+     }
+ 
+ /***********************************************************
+  *  do_child_process
+  *
+  * This is the process that handles ioctls from the driver.
+  * It sets up an array of input devices that will be listed
+  * by the driver.  How they are used will be determined by
+  * the information in the X*devices file.
+  *
+  */
+ 
+ do_child_process(i)
+     int i;
+     {
+ 
+     signal( SIGINT, SignalHandler );
+     signal( SIGHUP, SignalHandler );
+     signal( SIGTERM, SignalHandler );
+     gethostname( Hostname, HOSTBUFFERSIZE );
+ 
+     SetupHILDevices (tc[i].devs);
+ 
+     /*
+      * loop, servicing the ptys when they so indicate via the select mask.
+      */
+ 
+     for ( ;; )
+ 	{
+ 	int j, ret;
+ 	int ExceptionMask = SelectMask;
+ 
+ 	ret = select( MaxOpen + 1,  NULL, NULL, &ExceptionMask,  0 );
+ 
+ 	/*
+ 	 * if the pty's emulating the HIL devices need
+ 	 * to be serviced, then handshake them.
+ 	 */
+ 	if ( ExceptionMask )
+ 	    {
+ 	    for ( j = 0; j < 32; j++ )
+ 		{
+ 		if ( ExceptionMask & 1 )
+ 		    HandshakeDevice( j - BaseFiledescriptor );
+ 		ExceptionMask >>= 1;
+ 		}
+ 	    }
+ 	}
+     }
+ 
+ /***********************************************************
+  *  do_parent_process
+  *
+  * This is the parent process.  It performs the following functions:
+  *     - Set up the X0devices file to read from the daemon ptys
+  *     - Invoke the driver initialiation and device initialization routines.
+  *     - Invoke the read routines to read data from the test input devices.
+  */
+ 
+ struct mydata
+     {
+     int valid;
+     int	type;
+     } ;
+ 
+ #define TPSENDD	 _IOW('Z', 1, struct mydata)
+ #define TPSTOPIT _IO('Z', 2)
+ 
+ do_parent_process(i)
+     int i;
+     {
+     int status, fd, count;
+     char buffer[128];
+     SerialProcs s;
+     HPInputDeviceHeader d[10], *dptr = d;
+     HIL_Device *lptr;
+     HPKeyboardFeedbackControl kctl;
+     char TruncHost[1024];
+ 
+     gethostname( Hostname, HOSTBUFFERSIZE );
+     strcpy (TruncHost, Hostname);
+     strtok (TruncHost, ".");
+ 
+     for (count=0; count<9; count++)
+ 	{
+ 	d[count].path[0]='\0';
+         d[count].button_chording = 100;
+ 	}
+     fd = creat("./X0devices.test", 0777);
+     sprintf (buffer,"/tmp/%s:hil hil_path\n",TruncHost);
+     write (fd, buffer,strlen(buffer));
+     if (strlen(tc[i].devices_file))
+         write (fd, tc[i].devices_file, strlen(tc[i].devices_file));
+     else 
+ 	{
+         sprintf (buffer,"/tmp/%s:hil7 other\n",TruncHost);
+         write (fd, buffer,strlen(buffer));
+ 	}
+     close(fd);
+ 
+     if ((status = hil_driver_Init(&s)) != INIT_SUCCESS)
+ 	{
+ 	printf("Driver initialization failure: %x\n",status);
+ 	CloseAllHilDevices();
+ 	exit(1); 
+ 	}
+ 
+     strcpy(d[0].path,"X*devices:Recycle:./X0devices.foobar");
+     status = (*(s.configure)) (d);
+     for (lptr=loop_device_list,count=0; count<10; count++,lptr++)
+ 	if (lptr->fd > 0)
+             (*(s.close)) (lptr->fd);
+     fd = creat("./X0devices.empty", 0777);
+     close(fd);
+     strcpy(d[0].path,"X*devices:Recycle:./X0devices.empty");
+     status = (*(s.configure)) (d);
+     for (lptr=loop_device_list,count=0; count<10; count++,lptr++)
+ 	if (lptr->fd > 0)
+             (*(s.close)) (lptr->fd);
+     test_configure_entry_point(&s, d, i);
+     for (dptr=d,i=0; i<10; i++,dptr++)
+ 	{
+         unsigned char device_type = dptr->min_kcode;
+ 	if (dptr->file_ds > 0 || *dptr->path=='\0')
+ 	    continue;
+ 	if (device_type == X_NINE_KNOB)
+ 	    dptr->button_chording = 0;
+         if ((status = (*(s.configure)) (dptr)) != INIT_SUCCESS)
+ 	    {
+ 	    printf("Device '%s' initialization failure status: %x\n",
+ 		dptr->path, status);
+ 	    CloseAllHilDevices();
+ 	    exit(1); 
+ 	    }
+ 	}
+     for (dptr=d,i=0; i<10; i++,dptr++)
+ 	{
+ 	if (dptr->file_ds <= 0 || *dptr->path=='\0')
+ 	    continue;
+ 	if (strcmp(dptr->x_name, "FIRST_NULL")!=0)
+             test_read_entry_point(&s, dptr);
+ 	if (i==0)
+ 	    {fd = beeper_fd; beeper_fd=-1;}
+         test_write_entry_point(&s, dptr);
+ 	if (i==0)
+ 	    beeper_fd = fd;
+ 	if (strcmp(dptr->x_name, "FIRST_NULL")!=0)
+             test_read_entry_point(&s, dptr);
+ 	}
+     for (dptr=d,i=0; i<10; i++,dptr++)
+ 	if (dptr->file_ds > 0)
+   	    ioctl(dptr->file_ds, TPSTOPIT, buffer);	/* terminate child */
+     for (dptr=d,i=0; i<10; i++,dptr++)
+ 	{
+ 	if (dptr->file_ds <= 0)
+ 	    continue;
+         if ((status = (*(s.close)) (dptr->file_ds)) != CLOSE_SUCCESS)
+ 	    {
+ 	    printf("Device '%s' close failure status: %x\n",dptr->path, status);
+ 	    CloseAllHilDevices();
+ 	    exit(1); 
+ 	    }
+ 	}
+     close_beeper();
+     close_beeper();
+     }
+ 
+ /***********************************************************
+  *  test_configure_entry_point
+  *
+  *  Test the configure() entry point of the HIL device driver.
+  */
+ 
+ test_configure_entry_point(s, dptr, i)
+     SerialProcs *s;
+     HPInputDeviceHeader *dptr;
+     {
+     int fail, status;
+     ExpectedData *expected = tc[i].expect;
+ 
+     strcpy(dptr->path,"X*devices:Recycle:./X0devices.test");
+     if ((status = (*(s->configure)) (dptr)) != INIT_SUCCESS)
+ 	{
+ 	printf("Device '%s' initialization failure status: %x\n",
+ 		dptr->path, status);
+ 	CloseAllHilDevices();
+ 	exit(1); 
+ 	}
+     strcpy(dptr->path,"X*devices:");
+     fail=0;
+     while ((status = (*(s->configure)) (dptr)) == INIT_SUCCESS)
+ 	{
+ 	if (strcmp (dptr->x_name, expected->name)!=0 ||
+ 	    dptr->file_ds != expected->fd ||
+ 	    dptr->reserved[2] != expected->use)
+ 	    {
+ 	    printf ("expected data did not match\n");
+ 	    printf ("a=%s e=%s a=%d e=%d a=%d e=%d\n", 
+ 	    dptr->x_name, expected->name,
+ 	    dptr->file_ds, expected->fd, dptr->reserved[2], expected->use);
+ #ifdef VERBOSE
+ 	    printf("Found: %s,  fd: %d,  use as: %d, path: %s\n", 
+ 		dptr->x_name, dptr->file_ds, dptr->reserved[2], dptr->path);
+ #endif /* VERBOSE */
+ 	    fail++;
+ 	    }
+ #ifdef VERBOSE
+ 	else
+ 	    printf("Found: %s,  fd: %d,  use as: %d, path: %s\n", 
+ 		dptr->x_name, dptr->file_ds, dptr->reserved[2], dptr->path);
+ #endif /* VERBOSE */
+ 	expected++;
+ 	dptr++;
+         strcpy(dptr->path,"X*devices:");
+ 	}
+     *dptr->path = '\0';
+     if (fail==0)
+ 	{
+ 	printf("Test case %d succeeded:\n%s\n",i,tc[i].message);
+ 	}
+     else
+ 	printf("Test case %d failed: \n%s\n",i,tc[i].message);
+     }
+ 
+ /***********************************************************
+  *  find_valid_data
+  *
+  *  Validate the data returned by the read routine.
+  */
+ 
+ struct valid *find_valid_data(device_type)
+     {
+     struct valid *v = NULL;
+ 
+     for (v=all_valid; (v->id != 0 && v->id != device_type); v++)
+ 	;
+     return v;
+     }
+ 
+ /***********************************************************
+  *  test_read_entry_point
+  *
+  *  Test the read() entry point of the HIL device driver.
+  */
+ 
+ test_read_entry_point(s, d)
+     SerialProcs *s;
+     HPInputDeviceHeader *d;
+     {
+     int i, size, ndx, ret, status, nbytes=0, count=0, mask;
+     unsigned char buf[128];
+     unsigned char data_type=0, device_type = d->min_kcode;
+     struct valid *v = find_valid_data(device_type);
+ 
+     generate_test_data (d->file_ds, FALSE, device_type);
+     status = (*(s->read)) (d->file_ds, buf, &data_type, &nbytes);
+     if (status != READ_FAILURE)
+         if (device_type == X_KB_US || device_type == X_BUTTONBOX)
+ 	    printf("No READ_FAILURE w/bogus data for device %s\n",d->x_name);
+ 	else if (nbytes != 0)
+ 	    printf("No READ_FAILURE w/bogus data for device %s\n",d->x_name);
+     (*(s->close)) (d->file_ds);
+     status = (*(s->read)) (d->file_ds, buf, &data_type, &nbytes);
+     (*(s->configure)) (d);
+     generate_test_data (d->file_ds, TRUE, device_type);
+     mask = 1 << d->file_ds;
+     ndx = 0;
+     while ((ret = usleep (1000, (d->file_ds + 1), &mask)) > 0)
+         while ((ret = (*(s->read)) (d->file_ds, buf, &data_type, &nbytes))==READ_SUCCESS)
+ 	{
+ 	if (nbytes == 0)
+ 	    continue;
+ 	size = v->size ? v->size : v->vdata[ndx++];
+ 
+ 	if (!(data_type & v->dtype) || nbytes != size || 
+ 	    !validate_data (buf, &v->vdata[ndx], nbytes))
+ 	    {
+ 	    printf("Invalid data: type = %x (%x), size = %d (%d) data = ",
+ 		data_type, v->dtype, nbytes, size);
+ 	    for (i=0; i<nbytes; i++)
+ 		printf ("%x (%x) ", buf[i], v->vdata[ndx+i]);
+ 	    printf ("\n");
+ 	    }
+ #ifdef VERBOSE
+ 	else
+ 	    printf("data matched\n");
+ #endif /* VERBOSE */
+ 	count++;
+ 	ndx += nbytes;
+ 	data_type = nbytes = buf[0] = 0;
+ 	}
+     }
+ 
+ /***********************************************************
+  *  validate_data
+  *
+  *  Validate the data returned by the read routine.
+  */
+ 
+ validate_data (actual, expected, size)
+     unsigned char *actual, *expected;
+     {
+     int i;
+ 
+     for (i=0; i<size; i++)
+ 	if (*actual != *expected)
+ 	    return 0;
+     return 1;
+     }
+ 
+ /***********************************************************
+  *  generate_test_data
+  *
+  *  Cause the child process to generate test data.
+  */
+ 
+ generate_test_data (fd, valid, data_type)
+     char data_type;
+     {
+ 
+     struct mydata foo;
+ 
+     foo.type = data_type;
+     foo.valid = valid;
+ 
+     ioctl(fd, TPSENDD, &foo);
+     usleep(50000, 0, NULL);
+     }
+ 
+ 
+ /***********************************************************
+  *  test_write_entry_point
+  *
+  *  Test the write() entry point of the HIL device driver.
+  */
+ 
+ test_write_entry_point(s, dptr)
+     SerialProcs *s;
+     HPInputDeviceHeader *dptr;
+     {
+     int status;
+     HPKeyboardFeedbackControl kctl;
+     HPPointerFeedbackControl  pctl;
+     HPBell                    bctl;
+     HPValuatorControl         vctl;
+     HPResolutionControl       rctl;
+ 
+     /* Test XChangeFeedbackControl */
+ 
+     kctl.class = 0xff;
+     kctl.bell_percent = 100;
+     kctl.bell_pitch = 0;
+     kctl.bell_duration = 400;
+     kctl.leds = -1;
+     kctl.autoRepeat = AutoRepeatModeOff;
+     status = (*(s->write)) (dptr->file_ds, _XChangeFeedbackControl, &kctl);
+     kctl.class = KbdFeedbackClass;
+ 
+     kctl.class = KbdFeedbackClass;
+     kctl.click = 100;
+     status = (*(s->write)) (dptr->file_ds, _XChangeFeedbackControl, &kctl);
+     kctl.bell_pitch = 100;
+     kctl.autoRepeat = AutoRepeatModeDefault;
+     kctl.leds = 0;
+     status = (*(s->write)) (dptr->file_ds, _XChangeFeedbackControl, &kctl);
+     kctl.autoRepeat = AutoRepeatModeOn;
+     status = (*(s->write)) (dptr->file_ds, _XChangeFeedbackControl, &kctl);
+     kctl.autoRepeat = -2;
+     status = (*(s->write)) (dptr->file_ds, _XChangeFeedbackControl, &kctl);
+ 
+     /* Test XBell                  */
+ 
+     bctl.class = BellFeedbackClass;
+     bctl.bell_percent = 100;
+     status = (*(s->write)) (dptr->file_ds, _XBell, &bctl);
+     kctl.click = 0;
+     status = (*(s->write)) (dptr->file_ds, _XBell, &kctl);
+ 
+     /* Test XSetDeviceValuators    */
+ 
+     vctl.first_valuator = 0;
+     vctl.num_valuators = 0;
+     vctl.valuators = NULL;
+     status = (*(s->write)) (dptr->file_ds, _XSetDeviceValuators, &vctl);
+ 
+     /* Test XChangeDeviceControl   */
+ 
+     rctl.first_valuator = 0;
+     rctl.num_valuators = 0;
+     rctl.resolutions = NULL;
+     status = (*(s->write)) (dptr->file_ds, _XChangeDeviceControl, &rctl);
+ 
+     /* Test XSetDeviceMode         */
+ 
+     status = (*(s->write)) (dptr->file_ds, _XSetDeviceMode, Absolute);
+     status = (*(s->write)) (dptr->file_ds, _XSetDeviceMode, Relative);
+     (*(s->close)) (dptr->file_ds);
+     status = (*(s->write)) (dptr->file_ds, _XSetDeviceMode, Relative);
+     (*(s->configure)) (dptr);
+ 
+     status = (*(s->write)) (dptr->file_ds, -1, &kctl);
+     }
+ 
+ /***********************************************************
+  *  GetPty
+  *
+  *  Search through all of the ptys looking for one that 
+  *  can be opened on the master side.  Return when one
+  *  is successfully opened.
+  *
+  *  On the master side, ptys have names in the range
+  *  /dev/ptyp0 ... /dev/ptyvf.  The last digit varies from
+  *  0 ... f, and the last alphabetic character varies from
+  *  p ... v.  Therefore, there are 16 * 7 = 112 ptys.
+  *
+  *  The names on the slave side are the same as the master
+  *  side, except that they are /dev/tty rather than /dev/pty.
+  ***********************************************************/
+ 
+ #define NUMPTYS		112
+ 
+ int 
+ GetPty(SlaveName)
+ char * SlaveName;
+ {
+     int NextPty = 0;
+     char MasterName[50];
+     int Fd;
+ 
+     for (NextPty=0; NextPty<NUMPTYS; NextPty++)
+     {
+         sprintf (SlaveName,"/dev/pty/tty%c%x",NextPty/16+'p',NextPty%16);
+         sprintf (MasterName,"/dev/ptym/pty%c%x",NextPty/16+'p',NextPty%16);
+         if (( Fd = open(MasterName,O_RDWR | O_NDELAY )) != -1)
+ 	{
+ 	   SelectMask |= 1 << Fd; 
+ 	   MaxOpen = max( MaxOpen, Fd );
+ 	   BaseFiledescriptor = min( BaseFiledescriptor, Fd );
+ 	   return (Fd);
+ 	}
+     }
+     printf( "GetPty: cannot open any of the pty's.\n");
+     exit( 1 );
+ }
+ 
+ 
+ /***********************************************************
+  *  SetupDevice
+  *
+  * This routine finds an available pty, then links
+  * the pty symbolically to an X0devices name in /tmp.
+  *
+  * The name is created in /tmp, using the hostname and the number
+  * of the HIL device being emulated.
+  ***********************************************************/
+ 
+ void
+ SetupDevice( hilnum )
+ int hilnum;
+ {
+     int rc;
+     struct  request_info iostuff;
+     char TruncHost[1024];
+ 
+     strcpy (TruncHost, Hostname);
+     strtok (TruncHost, ".");
+     sprintf( hil[hilnum].PtyName, "%s%s:hil%d", PTY_DIR, TruncHost, hilnum+1 );
+     /*
+      * Find an available pty 
+      */
+     hil[hilnum].Pty = GetPty (hil[hilnum].SlaveName);
+ 
+     /* Trap ioctls on pty.  These are HILID, HILDKR and HILER1  */
+ 
+     rc = 1;			/* Trap ioctls on pty */
+     if ( ioctl( hil[hilnum].Pty, TIOCTRAP, &rc) == -1)
+     {
+ 	perror( "SetupDevice: couldn't TIOCTRP pty");
+ 	exit( 1 );
+     }
+ 
+     rc = 1;			/* Disable termio processing */
+     if ( ioctl( hil[hilnum].Pty, TIOCTTY, &rc) == -1)
+     {
+ 	perror( "SetupDevice: couldn't TIOCTTY pty");
+ 	exit( 1 );
+     }
+ 
+     /*
+      * block client signals while the ioctl is being handled 
+      */
+     if (ioctl( hil[hilnum].Pty, TIOCSIGMODE, TIOCSIGBLOCK) == -1)
+     {
+ 	perror( "SetupDevice: couldn't TIOCSIGBLOCK pty");
+ 	exit( 1 );
+     }
+     /*
+      * clean up any old symlinks and link to our pty
+      */
+     unlink( hil[hilnum].PtyName);
+     if ( symlink (hil[hilnum].SlaveName, hil[hilnum].PtyName )) 
+     {
+ 	perror( "SetupDevice: couldn't link pty");
+ 	printf( "SetupDevice:    ln %s %s\n",
+ 	   hil[hilnum].SlaveName, hil[hilnum].PtyName);
+ 	exit( 1 );
+     }
+ }
+ 
+ struct HilDeviceInfo * FindHilInfo();
+ 
+ /***********************************************************
+  *  FindHilInfo
+  *
+  *      Search the HIL device information table for
+  *  information about the given device type.
+  *
+  ***********************************************************/
+ struct HilDeviceInfo *
+ FindHilInfo( Type )
+ unsigned char Type;
+ {
+      struct HilDeviceInfo * pInfo = DeviceTable;
+ 
+      while ( pInfo->id != 0 )
+      {
+ 	 if ( pInfo->id == Type )
+ 	     return( pInfo );
+ 	 pInfo++;
+      }
+      printf( "Hil.c: FindHilInfo: requested type %x not in DeviceTable.\n", Type);
+      exit( 1 );
+ }
+ 
+ /***********************************************************
+  *  SetupHILDevices
+  *
+  *     Loop through the array that defines the 
+  * HIL devices to be emulated.  For each device,
+  * obtain a pty to use to emulate the device.
+  * Then associate a HIL device information table entry with
+  * the HIL loop position.
+  *
+  ***********************************************************/
+ 
+ SetupHILDevices( LoopDefinitionArray )
+ unsigned char LoopDefinitionArray[];
+ {
+     int i;
+     int Type;
+     for ( i = 0; i < NUM_DEVS; i++ )
+     {
+ 	Type = LoopDefinitionArray[i];
+ 	if ( Type == 0 )
+ 	    break;
+ 	SetupDevice( i );
+ 	hil[i].pHilDeviceInfo = FindHilInfo( Type );
+     }
+ }
+ 
+ /***********************************************************
+  *  LogHilCommand
+  *
+  *     Log the command for the particular device.
+  *  This log can later be scanned to see if a particular
+  *  command was sent by the server.
+  *
+  *     The log is kept in a singly linked list.   The 
+  *  initial pointer to the list is indexed by the hil number,
+  *  so as to keep the logs for the devices distinct.
+  *
+  ***********************************************************/
+ 
+ LogHilCommand( hilnum, Command )
+ int hilnum;
+ int Command;
+ {
+ 	if ( hil[ hilnum ].pLast == NULL )
+ 	{
+ 	    hil[ hilnum ].pLast = ( struct HilCommandLog * )
+ 				  malloc( sizeof( struct HilCommandLog ));
+ 	    hil[ hilnum ].pLast->pNext = 0;
+ 	    hil[ hilnum ].pLast->Command = Command;
+ 
+ 	    hil[ hilnum ].pNext = hil[ hilnum ].pLast;
+ 	}
+ 	else
+ 	{
+ 	    struct HilCommandLog * pTemp;
+ 
+ 	    pTemp = hil[ hilnum ].pLast;
+ 	    hil[ hilnum ].pLast = ( struct HilCommandLog * )
+ 			           malloc( sizeof( struct HilCommandLog ));
+ 	    hil[ hilnum ].pLast->Command = Command;
+ 	    hil[ hilnum ].pLast->pNext = 0;
+ 	    pTemp->pNext = hil[ hilnum ].pLast;
+ 	}
+ }
+ 
+ /*************************************************************
+  * PrintHilCommand
+  *
+  *   This function prints the mnemonic for an HIL command
+  * or the several standard PTY commands.
+  *
+  *************************************************************/
+ 
+ void
+ PrintHilCommand( hilnum, cmd )
+ int hilnum;
+ int cmd;
+ {
+     struct _hilCommands *hp;
+ 
+     for ( hp = hilArray; hp->HilCommand; hp++ )
+     {
+         if ( hp->HilCommand == cmd )
+         {
+ 	    printf("hil: %d command: 0x%4X %s\n",
+ 		hilnum, cmd, hp->HilCommandName );
+ 	    break;
+ 	}
+     }
+     if ( hp->HilCommand == 0 )
+ 	printf("hil: %d command: 0x%4X %s\n", hilnum, cmd, "UNKNOWN" );
+ 
+ }
+ 
+ /***********************************************************
+  *  HandShakeDevice
+  *
+  * Handle an ioctl request from the driver.
+  * Use ioctl to send back the correct data.
+  *
+  ***********************************************************/
+ 
+ struct mydata foo;
+ 
+ void
+ HandshakeDevice( hilnum )
+ int hilnum;
+ {
+     struct  request_info iostuff;
+     unsigned char * pIdInfo;
+     /*
+      * find out what the HIL request is
+      */
+     ioctl (hil[hilnum].Pty, TIOCREQGET, &iostuff);
+ 
+     /*PrintHilCommand( hilnum, iostuff.request ); */
+     LogHilCommand( hilnum, iostuff.request );
+ 
+     switch( iostuff.request )
+     {
+     case HILID:
+ 
+ 	if (iostuff.argset == 0 )
+ 	{
+ 	    printf( "HandshakeDevice: argset is zero on HILID.\n");
+ 	    exit( 1 );
+ 	}
+ 
+ 	if (hil[hilnum].pHilDeviceInfo->id == X_ERROR_DEVICE)
+ 	    iostuff.return_value = -1;
+ 	pIdInfo = hil[ hilnum ].pHilDeviceInfo->pHilIdString;
+ 	ioctl (hil[hilnum].Pty, iostuff.argset, pIdInfo );
+ 
+ 
+ 	break;
+     case TCGETA:
+ 
+ 	if (iostuff.argset == 0 )
+ 	{
+ 	    printf( "HandshakeDevice: argset is zero on TCGETA.\n");
+ 	    exit( 1 );
+ 	}
+ 
+ 	ioctl (hil[hilnum].Pty, iostuff.argset, tcget_info );
+ 	break;
+     case TIOCOPEN:
+     case TIOCCLOSE:
+     case HILER1:
+     case HILER2:
+     case HILDKR:
+     case HILP:
+     case HILP1:
+     case HILP2:
+     case HILP3:
+     case HILP4:
+     case HILP5:
+     case HILP6:
+     case HILP7:
+     case HILA:
+     case HILA1:
+     case HILA2:
+     case HILA3:
+     case HILA4:
+     case HILA5:
+     case HILA6:
+     case HILA7:
+ 	break;
+     case TPSENDD:
+ 	ioctl (hil[hilnum].Pty, iostuff.argget, &foo);
+ 	send_test_data (hil[hilnum].Pty, foo.valid, foo.type);
+ 	break;
+     case TPSTOPIT:
+ 	CloseAllHilDevices();
+ 	exit(1);
+ 	break;
+     default:
+ 	    printf( "HandshakeDevice: default command %x.\n",iostuff.request);
+     }
+     if (ioctl (hil[hilnum].Pty, TIOCREQSET, &iostuff) < 0 )
+     {
+       perror( "HandshakeDevice: error on TIOCREQSET" );
+       printf( "HandshakeDevice: errno %d\n", errno);
+       exit( 1 );
+     }
+ }
+ 
+ /***********************************************************
+  *  CloseAllHilDevices
+  *
+  *   This routine closes all the opened HIL devices
+  ***********************************************************/
+ 
+ void
+ CloseAllHilDevices()
+ {
+     int i;
+ 
+     for ( i = 0; i < NUM_DEVS; i++ )
+ 	if ( hil[ i ].Pty )
+ 	{
+             close( hil[ i ].Pty );
+ 	    hil[ i ].Pty = 0;
+ 	    unlink( hil[ i ].PtyName);
+ 	}
+ }
+ 
+ /*************************************************************
+  * SignalHandler
+  *
+  *   Handle receipt of a signal.  In current use, this generally
+  * means that this process has been hit by kfork.  Kfork 
+  * sends SIGTERM by default.
+  *
+  * ACTION:  try to shut down the server, if it is connected,
+  * by sending control-shift-reset.  Then close all the pty's,
+  * unlink them, shutdown and close the sockets, and exit 
+  * gracefully.
+  *************************************************************/
+ 
+ void
+ SignalHandler()
+ {
+     CloseAllHilDevices();
+     exit( 0 );
+ }
+ 
+ /*
+  * int usleep(unsigned long microseconds, int nfds, int *readmask)
+  *	This is a microsecond "sleep" routine. It uses the select(2) system
+  *      call to delay for the desired number of micro-seconds.
+  *
+  * Arguments:
+  *	unsigned long microseconds	Number of microseconds to pause.
+  *
+  * Return value:
+  *	int		0 on successful completion, -1 otherwise.
+  *
+  * Side effects:
+  *	Program pause based upon argument value.
+  *
+  * Calls:
+  *	select(2).
+  */
+ int
+ usleep(microseconds, nfds, readmask)
+ register unsigned long microseconds;
+ register int nfds, *readmask;
+ 
+ {
+     register unsigned int seconds, usec;
+     int writefds, exceptfds;
+     struct timeval timer;
+ 
+     writefds = exceptfds = 0;
+ 
+     /* Convert to values select() understands */
+     seconds = microseconds / (unsigned long)1000000;
+     usec = microseconds % (unsigned long)1000000;
+ 
+     timer.tv_sec = seconds;
+     timer.tv_usec = usec;
+ 
+     return (select(nfds, readmask, &writefds, &exceptfds, &timer));
+ }
+ 
+ send_test_data (pty, valid, type)
+     unsigned char type;
+     {
+     switch (type)
+ 	{
+ 	case X_KB_US:
+ 	    if (valid)
+ 		write(pty, valid_key_data, sizeof(valid_key_data));
+ 	    else
+ 		write(pty, bogus_key_data, sizeof(bogus_key_data));
+ 	    break;
+ 	case X_MOUSE_3B:
+ 	    if (valid)
+ 		write(pty, valid_mouse_data, sizeof(valid_mouse_data));
+ 	    else
+ 		write(pty, bogus_mouse_data, sizeof(bogus_mouse_data));
+ 	    break;
+ 	case X_MOUSE_2B:
+ 	    if (valid)
+ 		write(pty, valid_mouse_data2, sizeof(valid_mouse_data2));
+ 	    else
+ 		write(pty, bogus_mouse_data2, sizeof(bogus_mouse_data2));
+ 	    break;
+ 	case X_TABLET_ASIZE:
+ 	case X_TABLET_BSIZE:
+ 	    if (valid)
+ 		write(pty, valid_tablet_data, sizeof(valid_tablet_data));
+ 	    else
+ 		write(pty, bogus_tablet_data, sizeof(bogus_tablet_data));
+ 	    break;
+ 	case X_QUADRATURE:
+ 	    if (valid)
+ 		write(pty, valid_quad_data, sizeof(valid_quad_data));
+ 	    else
+ 		write(pty, bogus_quad_data, sizeof(bogus_quad_data));
+ 	    break;
+ 	case X_TOUCHSCREEN:
+ 	    if (valid)
+ 		write(pty, valid_mouse_data, sizeof(valid_mouse_data));
+ 	    else
+ 		write(pty, bogus_mouse_data, sizeof(bogus_mouse_data));
+ 	    break;
+ 	case X_BARCODE:
+ 	    if (valid)
+ 		write(pty, valid_barcode_data, sizeof(valid_barcode_data));
+ 	    else
+ 		write(pty, bogus_barcode_data, sizeof(bogus_barcode_data));
+ 	    break;
+ 	case X_NINE_KNOB:
+ 	    if (valid)
+ 		write(pty, valid_9knob_data, sizeof(valid_9knob_data));
+ 	    else
+ 		write(pty, bogus_9knob_data, sizeof(bogus_9knob_data));
+ 	    break;
+ 	case X_ONE_KNOB:
+ 	    if (valid)
+ 		write(pty, valid_1knob_data, sizeof(valid_1knob_data));
+ 	    else
+ 		write(pty, bogus_1knob_data, sizeof(bogus_1knob_data));
+ 	    break;
+ 	case X_ONE_AXIS:
+ 	    if (valid)
+ 		write(pty, valid_one_axes_data, sizeof(valid_one_axes_data));
+ 	    else
+ 		write(pty, bogus_one_axes_data, sizeof(bogus_one_axes_data));
+ 	    break;
+ 	case X_NO_AXES:
+ 	    if (valid)
+ 		write(pty, valid_no_axes_data, sizeof(valid_no_axes_data));
+ 	    else
+ 		write(pty, bogus_no_axes_data, sizeof(bogus_no_axes_data));
+ 	    break;
+ 	case X_THREE_AXES:
+ 	    if (valid)
+ 		write(pty, valid_three_axes_data, sizeof(valid_three_axes_data));
+ 	    else
+ 		write(pty, bogus_three_axes_data, sizeof(bogus_three_axes_data));
+ 	    break;
+         }
+     }
+ #endif /* DEBUG */
