diff options
Diffstat (limited to 'xc/programs/Xserver/hw/hp')
49 files changed, 21453 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/hp/Imakefile b/xc/programs/Xserver/hw/hp/Imakefile new file mode 100644 index 000000000..0b47fb63e --- /dev/null +++ b/xc/programs/Xserver/hw/hp/Imakefile @@ -0,0 +1,45 @@ +XCOMM $XConsortium: Imakefile /main/9 1996/09/28 17:12:28 rws $ +#include <Server.tmpl> + +#define IHaveSubdirs + +SUBDIRS=ngle input + +SRCS = \ + ddx_info.c \ + hpCursorUtils.c \ + hpInit.c + +OBJS = \ + ddx_info.o \ + hpCursorUtils.o \ + hpInit.o \ + ngle/ngle.o \ + input/libhp.a + +LOBJS = \ + ddx_info.ln \ + hpCursorUtils.ln \ + hpInit.ln + +DEFINES = $(ANSI_DEFINES) -DOSMAJORVERSION=OSMajorVersion + +LIB_DEFINES = -DLIBDIR=\"$(LIBDIR)\" + +INCLUDES = -I. -I./include -I./input -I../../mfb -I../../cfb -I../../mi \ + -I../../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(FONTINCSRC) + +LINTLIBS = ../../dix/llib-ldix.ln ../../os/4.2bsd/llib-los.ln \ + ../mfb/llib-lmfb.ln ../mi/llib-lmi.ln ../cfb/llib-lcfb.ln + +all:: + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) + +NormalLibraryObjectRule() +NormalRelocatableTarget(hp,$(OBJS)) +SpecialCObjectRule(hpInit,$(ICONFIGFILES),$(LIB_DEFINES)) +DependTarget() +InstallManPage(Xhp,$(MANDIR)) + diff --git a/xc/programs/Xserver/hw/hp/Xhp.man b/xc/programs/Xserver/hw/hp/Xhp.man new file mode 100644 index 000000000..d9fa27e27 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/Xhp.man @@ -0,0 +1,136 @@ +.\" $TOG: Xhp.man /main/6 1998/02/10 13:10:34 kaleb $ +.\" Copyright 1994 Hewlett-Packard Company +.\" Copyright 1994, 1998 The Open Group +.\" +.\" All Rights Reserved. +.\" +.\" 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 OPEN GROUP 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 Open Group 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 +.\" The Open Group. +.\" +.\" 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.4" "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 The Open Group, Inc. diff --git a/xc/programs/Xserver/hw/hp/ddx_info.c b/xc/programs/Xserver/hw/hp/ddx_info.c new file mode 100644 index 000000000..dd8d77404 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ddx_info.c @@ -0,0 +1,169 @@ +/* $TOG: ddx_info.c /main/4 1997/07/17 21:20:02 kaleb $ */ + +/************************************************************************* + * + * (c)Copyright 1992 Hewlett-Packard Co., All Rights Reserved. + * + * RESTRICTED RIGHTS LEGEND + * Use, duplication, or disclosure by the U.S. Government is subject to + * restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in + * Technical Data and Computer Software clause in DFARS 252.227-7013. + * + * Hewlett-Packard Company + * 3000 Hanover Street + * Palo Alto, CA 94304 U.S.A. + * + * Rights for non-DOD U.S. Government Departments and Agencies are as set + * forth in FAR 52.227-19(c)(1,2). + * + *************************************************************************/ + + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/framebuf.h> +#include <fcntl.h> + +#include <X.h> +#include <Xproto.h> +#include <scrnintstr.h> +#include <pixmapstr.h> +#include <resource.h> +#include <misc.h> +#include <mi.h> +#include <servermd.h> +#include <windowstr.h> +#include <colormap.h> + +#include "hppriv.h" + +#if defined(__hp9000s700) || defined(__hp9000s300) +/* Until <graphics.h> (s400) and <framebuf.h> (s700) are updated, + * define graphics IDs returned by ioctl(GCDESCRIBE). On both + * platforms, this ID equals the upper 4 bytes of the STI ROM ID. + * + * (s400 won't support 24-plane color (Rattler); that's handled below). + */ +/* Until <framebuf.h> (s700) is updated */ +# ifndef S9000_ID_A1659A /* CRX (8-plane Color) */ +# define S9000_ID_A1659A 0x26D1482A +# endif +# ifndef S9000_ID_A1924A /* GRX (Gray Scale) */ +# define S9000_ID_A1924A 0x26D1488C +# endif +# ifndef S9000_ID_A1439A /* CRX+ (24-plane Color */ +# define S9000_ID_A1439A 0x26D148EE +# endif +# ifndef S9000_ID_TIMBER /* Bushmaster (710) Graphics */ +# define S9000_ID_TIMBER 0x27F12392 +# endif +# 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 */ + +extern Bool ngleScreenInit(); + + + /* --------------------- ddx_driver_info -------------------------- */ + /* This is an inital entry point into the hpux ddx drivers. This + procedure is called to determine if ddx driver support exists + for a given display and configuration. The display and + configuration are defined by the hp private structure passed + into this routine. A null pointer is returned if no ddx driver + support is available. If a ddx driver does exist to support the + given configuration, then a pointer to the driver's initialization + routine, which is later called by InitOutput(), routine is + returned. + */ + +Bool (*ddx_driver_info( php))() + hpPrivPtr php; +{ + struct stat statInfo; + int result; + crt_frame_buffer_t desc; + char *map_origin = NULL; + Bool (*return_value)(); + + + /* Stat the file descriptor to see if the device file exists: */ + if((result = stat( php->StandardDevice, &statInfo)) < 0) + { + return(NULL); + } + + /* Stat the file descriptor to see if the device exists: */ + if(!( statInfo.st_mode & S_IFCHR)) + { + return(NULL); + } + + /* Let's open the device: */ + if(( php->StandardFd = open(php->StandardDevice, O_RDWR)) < 0) + { + return(NULL); + } + + /* Map the device: */ + if( ioctl( php->StandardFd, GCMAP, &map_origin) < 0) + { + close(php->StandardFd); + return(NULL); + } + + /* Does the kernel know what's out there?: */ + if( ioctl( php->StandardFd, GCDESCRIBE, &desc) < 0) + { + ioctl(php->StandardFd, GCUNMAP, &map_origin ); + close(php->StandardFd ); + return(NULL); + } + + /* Let's give the driver a chance to look at the device: */ + switch(desc.crt_id) + { + /* Devices supported on s700 */ +#ifdef S9000_ID_A1924A + case S9000_ID_A1924A: /* GRX (8-plane Gray Scale) */ +#endif + case S9000_ID_A1659A: /* CRX (8-plane Color) */ +#ifdef S9000_ID_TOMCAT + case S9000_ID_TOMCAT: /* 2-Headed CRX */ +#endif +#ifdef S9000_ID_TIMBER + case S9000_ID_TIMBER: /* Bushmaster (710) Graphics */ +#endif + case S9000_ID_A1439A: /* CRX24 (24-plane Color) */ +#ifdef S9000_ID_ARTIST + case S9000_ID_ARTIST: /* 712 (8-plane Color) Graphics */ +#endif +#ifdef S9000_ID_HCRX + case S9000_ID_HCRX: /* Hyperdrive (8 or 24 plane) */ +#endif + + return_value = ngleScreenInit; + break; + + default: + return_value = NULL; + break; + } + + /* We've got our info, so lets close things down so the driver can + * re-open them: + */ + ioctl(php->StandardFd, GCUNMAP, &map_origin); + close(php->StandardFd ); + + return(return_value); +} diff --git a/xc/programs/Xserver/hw/hp/hpCursorUtils.c b/xc/programs/Xserver/hw/hp/hpCursorUtils.c new file mode 100644 index 000000000..9ffec9572 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/hpCursorUtils.c @@ -0,0 +1,145 @@ +/* $TOG: hpCursorUtils.c /main/4 1998/02/10 13:10:25 kaleb $ */ +/************************************************************************* + * + * (c)Copyright 1992 Hewlett-Packard Co., All Rights Reserved. + * + * RESTRICTED RIGHTS LEGEND + * Use, duplication, or disclosure by the U.S. Government is subject to + * restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in + * Technical Data and Computer Software clause in DFARS 252.227-7013. + * + * Hewlett-Packard Company + * 3000 Hanover Street + * Palo Alto, CA 94304 U.S.A. + * + * Rights for non-DOD U.S. Government Departments and Agencies are as set + * forth in FAR 52.227-19(c)(1,2). + * + *************************************************************************/ + +/*'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +Copyright 1988 by Hewlett-Packard Company +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, + Massachusetts + +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 names of +Hewlett-Packard or Digital not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + + +Copyright 1987, 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''*/ + + +#include "hpext.h" +#include "hildef.h" +#include "scrnintstr.h" +#include "cursorstr.h" +#include "regionstr.h" +#include "inputstr.h" +#include "opaque.h" +#include "hppriv.h" + +extern int hpActiveScreen; /* Stacked mode, >1 head */ +extern WindowPtr *WindowTable; /* Defined by DIX */ + +static CursorPtr currentCursors[MAXSCREENS]; + +void hpBlottoCursors() +{ + int j; + for (j = MAXSCREENS; j--; ) currentCursors[j] = NULL; +} + +/************************************************************ + * 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, + * since dix knows that size. + * + * Results: + * A box for the hot spot corner of the cursor. + ************************************************************/ + +void +hpCursorLimits( pScreen, pCursor, pHotBox, pResultBox) +ScreenPtr pScreen; /* Screen on which limits are desired */ +CursorPtr pCursor; /* Cursor whose limits are desired */ +BoxPtr pHotBox; /* Limits for pCursor's hot point */ +BoxPtr pResultBox; /* RETURN: limits for hot spot */ +{ + *pResultBox = *pHotBox; + pResultBox->x2 = min(pResultBox->x2,pScreen->width); + pResultBox->y2 = min(pResultBox->y2,pScreen->height); +} + +/************************************************************ + * + * hpSetCursorPosition + * + * This routine is called from DIX when the X11 sprite/cursor is warped. + * + ************************************************************/ + +Bool +hpSetCursorPosition(pScreen, xhot, yhot, generateEvent) +ScreenPtr pScreen; +short xhot; +short yhot; +Bool generateEvent; +{ + HPInputDevice *InDev; /* Input device structure */ + hpPrivPtr php; /* XOS private structure */ + + 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! */ + } + + return(TRUE); + +} /* hpSetCursorPosition() */ diff --git a/xc/programs/Xserver/hw/hp/hpInit.c b/xc/programs/Xserver/hw/hp/hpInit.c new file mode 100644 index 000000000..544b0d1c6 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/hpInit.c @@ -0,0 +1,804 @@ +/* $TOG: hpInit.c /main/6 1997/11/12 14:38:12 kaleb $ */ +/************************************************************************* + * + * (c)Copyright 1992 Hewlett-Packard Co., All Rights Reserved. + * + * RESTRICTED RIGHTS LEGEND + * Use, duplication, or disclosure by the U.S. Government is subject to + * restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in + * Technical Data and Computer Software clause in DFARS 252.227-7013. + * + * Hewlett-Packard Company + * 3000 Hanover Street + * Palo Alto, CA 94304 U.S.A. + * + * Rights for non-DOD U.S. Government Departments and Agencies are as set + * forth in FAR 52.227-19(c)(1,2). + * + *************************************************************************/ + +#include "X.h" +#include "Xproto.h" +#include <servermd.h> + +#include "screenint.h" +#include "input.h" +#include "cursor.h" +#include "misc.h" +#include "windowstr.h" +#include "scrnintstr.h" + +#include "screentab.h" +#include "gcstruct.h" +#include "errno.h" + +#include <stdio.h> +#include <ctype.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> + +#include "hppriv.h" +#include "XHPproto.h" + +#ifndef LIBDIR +#if OSMAJORVERSION >= 10 +#define LIBDIR "/etc/X11" +#else +#define LIBDIR "/usr/lib/X11" +#endif +#endif + +extern char *display; /* display number as a string */ +extern unsigned char *get_display_address(); + +extern void Xfree(); + +extern char *getenv(); /* for reading SB_DISPLAY_ADDR env var */ +extern long strtol(); + +static void ParseXnScreensFile(); +static void ResetFields(); +static void FirstTimeInitialization( ); +static int ParseNextScreen( ); +static char yygetc(); +static void ReadToNextWhiteSpace(); +static void SyntaxError(); +void Exit(); + +static int NumScreens; /* number of screens found */ + +PixmapFormatRec formats[] = { + 1, 1, BITMAP_SCANLINE_PAD, /* 1-bit deep for all */ + 8, 8, BITMAP_SCANLINE_PAD, /* 8-bit deep for most color displays */ + 24, 32, BITMAP_SCANLINE_PAD, /* 24-bit deep display */ +}; +#define NUMFORMATS (sizeof formats)/(sizeof formats[0]) +#define NUM_DEPTHS 16 + +static hpPrivPtr AllocateDataStructures(); + +int LineNumber = 1; + + +/* + * parameters defining the reserved word return values + */ +#define DEPTH 1 +#define DRIVERNAME 2 +#define DOUBLEBUFFER 3 +#define MONITORSIZE 4 + +/* + * parameters defining the return status from GetToken(). + */ +#define END_OF_LINE 1 +#define ID 2 +#define INTEGER 3 +#define RESERVED_WORD 4 + +/* + * reserved word table for parsing X*screens file + */ +static struct token { + char name[16]; + int rvalue; +} tks [] = { + "depth", DEPTH, + "drivername", DRIVERNAME, + "doublebuffer", DOUBLEBUFFER, + "monitorsize", MONITORSIZE, + "", NULL, +}; + +/************************************************************ + * InitOutput -- + * This routine is called from main() during the server + * startup initialization, and when the server is to be reset. + * The routine does the device dependent initialization for + * all of the screens this server is configured to support. + * + * Results: + * The array of ScreenRec pointers referenced by + * pScreenInfo->screen are allocated and initialized. + * The X*screens file is parsed and checked for + * validity with reference to the particular screen + * hardware. + * + ************************************************************/ + +extern int hpActiveScreen; /* active screen ndx (Zaphod), in x_hil.c */ + +Bool (*ddx_driver_info())(); +Bool (*ddxScreenInitPointer[MAXSCREENS])(); + +void +InitOutput(pScreenInfo, argc, argv) + ScreenInfo *pScreenInfo; + int argc; + char **argv; +{ + int i; + + static int firstTime = 1; + + /* Reset some cursor stuff to avoid massive confusion at server + * reset time. + */ + hpActiveScreen = 0; + hpBlottoCursors(); + + FirstTimeInitialization( pScreenInfo, argc, argv); + + /************************* + Set up signal handling + **/ + OsSignal (SIGPIPE, SIG_IGN); + OsSignal (SIGHUP, AutoResetServer); + OsSignal (SIGINT, GiveUp); + OsSignal (SIGTERM, GiveUp); +} + +hpPrivPtr hpPrivates[MAXSCREENS]; +int hpNumScreens; + +/************************************************************ + * FirstTimeInitialization + * + * This routine handles the first time initialization + * duties. + * + ************************************************************/ + +static void +FirstTimeInitialization( pScreenInfo, argc, argv) +ScreenInfo *pScreenInfo; +int argc; +char **argv; +{ + int i; + + ParseXnScreensFile( pScreenInfo ); + + /* + * Add check of device independent screen conditions -kam 9/13 + */ + + if(hpNumScreens > MAXSCREENS) + { + ErrorF("Number of screens requested exceeds allowable limit of %d screens.\n", MAXSCREENS); + ErrorF("Please reduce the number of requested screens in your "); + ErrorF("'%s/X%sscreens' file.\n", LIBDIR, display); + ErrorF("Server exiting...\n"); + Exit(UNABLE_TO_INITIALIZE_THE_DISPLAY); + } + + for(i = 0; i < hpNumScreens; i++) + { + ddxScreenInitPointer[i] = ddx_driver_info(hpPrivates[i]); + } + + + pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + pScreenInfo->numPixmapFormats = NUMFORMATS; + + + + for ( i = 0; i < NUMFORMATS; i++) + { + pScreenInfo->formats[i] = formats[i]; + } + + /* + * call the AddScreen function in dix/main.c + * This routine will fiddle with the pixmap formats, and + * then call ngleScreenInit to initialize the screen. + * + * WARNING: AddScreen has a bogosity(!) in that it uses the + * value of pScreenInfo.numScreens to determine which + * &pScreenInfo.screen[ i ] to pass to ngleScreenInit. + * Therefore the value of pScreenInfo.numScreens is manipulated + * here as a work around. ( Do we really HAVE TO call AddScreen? ). + */ + + do + { + if (-1 == AddScreen(ddxScreenInitPointer[pScreenInfo->numScreens], + argc,argv)) + FatalError("Could not add screen.\n"); + + } while ( pScreenInfo->numScreens != hpNumScreens ); + + return; +} + + +/************************************************************ + * ParseXnscreensFile + * + * This routine parses the X*screens file. + * where * refers to the display number of this server. + * + * 1) If no X*screens file exists, just set up the defaults + * and return. + * 2) Each non-comment line in the X*screens file gives a + * definition for a screen. + * + * + ************************************************************/ + +static void +ParseXnScreensFile( pScreenInfo ) +ScreenInfo * pScreenInfo; +{ + int fd; + int i; + char filename[MAX_PATH_NAME]; + FILE *str; + int status; + hpPrivPtr phpPriv; + int index; + + hpNumScreens = 0; + + phpPriv = AllocateDataStructures(); + hpPrivates[hpNumScreens] = phpPriv; + + sprintf( filename, "%s/X%sscreens", LIBDIR, display ); + str = fopen( filename, "r"); + if (str == NULL) FatalError("Cannot open the %s file.\n", filename); + + status = ParseNextScreen( phpPriv, filename, str ); + /* + * if status is -1, then the ParseNextScreen routine + * could not find ANY useful information in the + * Xnscreens file, so just setup the default + */ + if ( status == -1 ) + FatalError( + "No valid information exists in your %s/Xnscreens file.\n", LIBDIR); + /* + * + */ + for (;;) + { + phpPriv = AllocateDataStructures (); + hpNumScreens++; + status = ParseNextScreen( phpPriv, filename, str ); + /* + * status of 1 indicates end of file. + */ + if ( ( status == 1 ) || ( status == -1 ) ) + { + Xfree(phpPriv); + break; + } + hpPrivates[hpNumScreens] = phpPriv; + } + + fclose( str ); +} + +/************************************************************ + * ParseNextScreen + * + * This routine is responsible for parsing one line of the + * X*screens file. It loops until it can return valid + * information from one line of the X*screens file, or + * until EOF is encountered. The actual parsing of a + * line in the file is performed here. If a syntax error + * is encountered, the routine throws away the line, and + * tries to parse the next line. + * + * RETURNED VALUES: 0 if valid value filled out in *pScrPriv + * 1 if EOF encountered + * -1 if no valid entries (at all) found + * + * EXTERNAL VARIABLES: + * display - set in main.c, points to string giving + * display number for this server. + ************************************************************/ + +static +ParseNextScreen( phpPriv, filename, str ) +hpPrivPtr phpPriv; +char * filename; +FILE * str; +{ + int i; + int status; + char string[MAX_PATH_NAME]; + int Error = 0; + + /* + * loop until we get a valid screen line, or until + * EOF is seen. + */ + while ( 1 ) + { + ResetFields( phpPriv ); + /* + * first field must be a "/dev/crt" type field. + * read until we get an IDENTIFIER + */ + for (;;) + { + status = GetToken( str, filename, &i, string, MAX_PATH_NAME ); + if (status == -1 ) + return( -1 ); + if ( status != ID ) + { + if ( status == END_OF_LINE ) + continue; + else + { + SyntaxError( str, filename ); + Error = 1; + } + } + break; + } + if ( Error ) + { + Error = 0; + continue; + } + /* + * Hokay, we have an IDENTIFIER. This *should* + * be a device, however it is not checked for validity + * here. + */ + + strncpy( phpPriv->StandardDevice, string, MAX_PATH_NAME ); + phpPriv->LineNumber = LineNumber; + /* + * now parse for reserved words until we see an + * IDENTIFIER or END_OF_LINE + */ + while ( 1 ) + { + status = GetToken( str, filename, &i, string, MAX_PATH_NAME ); + switch( status ) + { + case -1: + return( 1 ); + case END_OF_LINE: + return( 0 ); + break; + + case RESERVED_WORD: + switch( i ) + { + case MONITORSIZE: + if ( GetANumber( str, filename, &i ) == -1 ) + { + Error = 1; + break; + } + phpPriv->MonitorDiagonal = i; + break; + case DEPTH: + if ( GetANumber (str, filename, &i ) == -1 ) + { + Error = 1; + break; + } + phpPriv->depth = i; + break; + } + /* + * end of switch on result from GetToken + */ + break; + + default: + FatalError( "An error occurred while processing %s/X*screens.", + LIBDIR); + } + if ( Error ) + break; + } + /* + * OK, now we either have satisfactorily parsed + * the primary screen device AND we have a valid secondary + * screen device, OR we have an error. + */ + if ( Error ) + { + Error = 0; + continue; + } + } +} + +/************************************************************ + * AllocateDataStructures + * + * Allocate the hp private data structures + ************************************************************/ + +static hpPrivPtr +AllocateDataStructures() +{ + hpPrivPtr phpPriv; + + phpPriv = (hpPrivPtr) Xcalloc( sizeof( hpPriv )); + + if ( phpPriv == NULL ) + { + FatalError("Cannot allocate enough memory for internal use--sorry"); + } + + return( phpPriv ); +} + +/************************************************************ + * GetANumber + * + ************************************************************/ + +int +GetANumber( str, filename, pInt ) +FILE * str; +char * filename; +int * pInt; +{ + int status; + int i; + char string[MAX_PATH_NAME]; + + status = GetToken( str, filename, &i, string, MAX_PATH_NAME ); + if (status == -1 ) + { + SyntaxError( str, filename ); + return( -1 ); /* kam 9/13 */ + } + if ( status != INTEGER ) + { + SyntaxError( str, filename ); + return( -1 ); /* kam 9/13 */ + } + *pInt = i; + return( 0 ); +} + +/************************************************************ + * GetToken + * This routine scans the X*screens file as given + * by fd for the next token. + * + * RETURNED VALUES: + * INTEGER if an integer is seen + * ID if an identifier is seen + * STRING if a device pathname is seen + * -1 if EOF is seen + * + * strptr used to fill pathname when STRING returned + * iptr used to fill id number when ID returned + * iptr used to fill integer when INTEGER returned + * + * + ************************************************************/ +int +GetToken( FileStream, FileName, iptr, strptr, MaxStrLen ) +FILE * FileStream; +char * FileName; +int * iptr; +char * strptr; +int MaxStrLen; +{ + char c; + int i; + char nextid[MAX_PATH_NAME]; + struct token *t; + char *cp; + + for (;;) { + c = yygetc( FileStream ); + if (c == '\n') + return( END_OF_LINE ); + if ( isspace( c )) + continue; + if (c == EOF) + return(-1); + if (isdigit(c)) + { + i = 1; + nextid[0] = c; + while ( isdigit( c = yygetc( FileStream ) ) + || ( c == 'x') || (c == 'X' )) + nextid[i++] = c; + nextid[i] = 0; + *iptr = atoi( nextid ); + ungetc( c, FileStream ); + if ( c == '\n' ) + LineNumber--; + return( INTEGER ); + } + else if ( ! isspace ( c )) + { + nextid[0] = c; + for (i = 1; i < MaxStrLen; i++) + { + if ( !isspace( c = yygetc( FileStream ))) + { + nextid[i] = c; + } + else + { + ungetc(c, FileStream); + if ( c == '\n' ) + LineNumber--; + nextid[i] = 0; + /* + * search for the identifier + * in the reserved word table. + */ + for (t = tks; t->rvalue; t++) + { + if ( strcmp(nextid, t->name) == 0 ) { + *iptr = t->rvalue; + return( RESERVED_WORD ); + } + } + strncpy( strptr, nextid, MaxStrLen ); + return( ID ); + } + } + /* + * error, string is too long + */ +ErrorF( "String is too long in file %s on line %d. Ignoring the line...\n", + FileName, LineNumber ); + ReadToNextWhiteSpace( FileStream); + return( GetToken( FileStream, FileName, iptr, strptr, MaxStrLen )); + + } + else + { +ErrorF( "Syntax error in file %s on line %d. Ignoring the line...\n", + FileName, LineNumber ); + ReadToNextWhiteSpace( FileStream); + return( GetToken( FileStream, FileName, iptr, strptr, MaxStrLen )); + } + } +} +/************************************************************ + * ResetFields + * This routine clears out fields in the hpPriv structure. + * This makes sure that any previous settings are cleared if we hit + * a syntax error. + * + ************************************************************/ + +static void +ResetFields( phpPriv ) +hpPrivPtr phpPriv; +{ + phpPriv->StandardDevice[0] = 0; + phpPriv->StandardDriver[0] = 0; + phpPriv->StandardNumDepths = 0; + phpPriv->StandardDoubleBuffer = 0; + phpPriv->StandardDoubleBufferDepth = 0; + + phpPriv->MonitorDiagonal = 0; + phpPriv->depth = 8; + +} +/************************************************************ + * SyntaxError + * This routine reports a syntax error regarding the + * X*screens file, and then skips over the rest of the + * current line. + * + ************************************************************/ + +static void +SyntaxError( FileStream, filename ) +FILE * FileStream; +char * filename; +{ + int i; + char Dummy[MAX_PATH_NAME]; + int status; + + ErrorF( "Syntax error in file %s on line %d. Ignoring the line...\n", + filename, LineNumber ); + do { + status = GetToken( FileStream, filename, &i, Dummy, MAX_PATH_NAME ); + if ( status == -1 ) + return; + } while ( status != END_OF_LINE ); +} + +/************************************************************ + * ReadToNextWhiteSpace + * This routine reads characters from the Xnscreens file + * until the next whitespace character is reached. + * Retain an end of line for parsing purposes if one + * is encounterd. + * + ************************************************************/ + +static void +ReadToNextWhiteSpace( FileStream ) +FILE * FileStream; +{ + char c; + + while (( c = yygetc( FileStream )) != EOF ) + { + if ( (c == ' ' ) || ( c == '\t') ) + return; + if ( c == '\n' ) + { + ungetc(c, FileStream); + LineNumber--; + return; + } + } +} + +/************************************************************ + * yygetc + * This routine reads characters from the Xnscreens file. + * The routine skips over comments ( begin with a # and go to + * the end of the line ). + * + * RETURNED VALUES: returns the next character in the file. + * + * SIDE EFFECTS: LineNumber is updated + ************************************************************/ +static char +yygetc( FileStream ) +FILE *FileStream; +{ + char c; + + if ((c = fgetc( FileStream )) == EOF) + return((char)EOF); + if (c == '\n') { + LineNumber++; + return(c); + } + else if ( c == '#' ) + { + while ( c == '#' ) + { + while (( c = fgetc( FileStream )) != EOF) + { + if (c != '\n') + continue; + else + { + LineNumber++; + return( c ); + } + } + } + } + return(c); +} + +/**************************************** +* ddxUseMsg() +* +* Called my usemsg from os/utils/c +* +*****************************************/ + +void ddxUseMsg() +{ + /* Right now, let's just do nothing */ +} + +void Exit (code) + int code; +{ + exit (code); +} + +void AbortDDX () +{ +} + +/***************************************************** + The main exit point for the server. + - throws us here when the user [Shift][CTRL][Reset]s. + - also come here upon kill -1 or kill -2 to the server +***/ +void ddxGiveUp() /* Called by GiveUp() */ +{ + /* soft reset the ITE by writing ESC-g to standard error */ + write(2, "\033g", 2); +} + +int +ddxProcessArgument (argc, argv, i) + int argc; + char *argv[]; + int i; + +{ + return(0); +} + + +/************************************************************** + * + * ErrorLine(phpPriv) + * + * This routine prints out a message that an error occurred on a + * particular line in the Xnscreens file. It does not print the + * error message, just the line number and the screen file name. + * + * Parameters: + * + * A pointer to an hpPrivRec + * + * Return Value: + * None. + * + ***************************************************************/ + +void +ErrorLine(phpPriv) + +hpPrivPtr phpPriv; + +{ + + ErrorF("Error in line %d of your %s/X%sscreens file.\n", + phpPriv->LineNumber, LIBDIR, display); + return; + +} + +#ifdef DPMSExtension +/************************************************************** + * DPMSSet(), DPMSGet(), DPMSSupported() + * + * stubs + * + ***************************************************************/ + +void DPMSSet (level) + int level; +{ +} + +int DPMSGet (level) + int* level; +{ + return -1; +} + +Bool DPMSSupported () +{ + return FALSE; +} +#endif diff --git a/xc/programs/Xserver/hw/hp/include/XHPproto.h b/xc/programs/Xserver/hw/hp/include/XHPproto.h new file mode 100644 index 000000000..448e25ab7 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/include/XHPproto.h @@ -0,0 +1,216 @@ +/* $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 +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. + + *************************************************************************/ +#ifndef XHPPROTO_H +#define XHPPROTO_H + +/* Definitions for HP extensions used by the server and C bindings*/ + +#ifndef XMD_H +#include "Xmd.h" +#endif + +/* detailed device information */ + +#define NO_DEVICE 0x00 +#define HP_ITF_KBD 0x01 +#define PC101_KBD 0x02 +#define IBM3270_KBD 0x03 +#define LK201_KBD 0x04 +#define LK401_KBD 0x05 +#define UNIX_KBD 0x06 +#define SUN3_KBD 0x07 +#define SUN4_KBD 0x08 + +#define HP_HIL 0x40 +#define PS2 0x80 +#define SERIAL 0xC0 + +#define ALLWINDOWS -1 + +#define STDEVENTS -1 +#define EXTEVENTS 0 +#define CORE_EVENTS 64 + +#define REPEAT_30 0 +#define REPEAT_60 1 + +#define OFF (0L << 0) +#define ON (1L << 0) +#define RELATIVE (0L << 1) +#define ABSOLUTE (1L << 1) +#define SYSTEM_EVENTS (0L << 2) +#define DEVICE_EVENTS (1L << 2) + +/* HP devices */ + +#define XPOINTER 0 +#define XKEYBOARD 1 +#define XOTHER 2 + +#define NUM_DEV_TYPES 19 + +#if defined(__hp9000s300) || defined(__hp9000s700) +#define MAX_POSITIONS 7 +#define MAX_LOGICAL_DEVS 9 +#else +#define MAX_POSITIONS 28 +#define MAX_LOGICAL_DEVS 30 +#endif + +#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 +#define VCD_8_DIALBOX 14 +#define MMII_1812_TABLET 15 +#define SS_SPACEBALL 16 +#define APOLLO_LPFK 17 +#define MMII_1201_TABLET 18 + +#define DVKeyClickPercent (1L<<0) +#define DVBellPercent (1L<<1) +#define DVBellPitch (1L<<2) +#define DVBellDuration (1L<<3) +#define DVLed (1L<<4) +#define DVLedMode (1L<<5) +#define DVKey (1L<<6) +#define DVAutoRepeatMode (1L<<7) +#define DVAccelNum (1L<<8) +#define DVAccelDenom (1L<<9) +#define DVThreshold (1L<<10) + +/* + * Display modes, needed by both server and clients. + * + * + */ + +#define OVERLAY_MODE 0x1 +#define IMAGE_MODE 0x2 +#define STACKED_MODE 0x3 +#define STACKED_MODE_FIRST_SCREEN 0x3 +#define STACKED_MODE_SECOND_SCREEN 0x33 +#define COMBINED_MODE 0x4 + +#define XHPOVERLAY_MODE OVERLAY_MODE +#define XHPIMAGE_MODE IMAGE_MODE +#define XHPSTACKED_SCREENS_MODE STACKED_MODE +#define XHPCOMBINED_MODE COMBINED_MODE + +/* + * Server exit error codes + * + */ +#define NORMAL_TERMINATION 0 +#define UNABLE_TO_INITIALIZE_THE_DISPLAY 1 +#define INCORRECT_SB_DISPLAY_ADDR_ENVIRONMENT_VAR 2 +#define INCORRECT_GRM_SIZE_ENVIRONMENT_VAR 3 +#define UNABLE_TO_STARTUP_OR_CONNECT_TO_THE_GRM 4 +#define DISPLAY_TYPE_UNKNOWN_TO_SERVER 5 +#define DOUBLE_BUFFERING_NOT_SUPPORTED 6 +#define DOUBLE_BUFFERING_HARDWARE_NOT_PRESENT 7 +#define CANNOT_SUPPORT_DEPTHS_OPTION_ON_THIS_DISPLAY 8 +#define UNSUPPORTED_DEPTH_SPECIFIED 9 +#define HARDWARE_AT_THIS_DEPTH_NOT_PRESENT 10 +#define DUPLICATE_DEVICE_ENTRY_IN_FILE 11 +#define CANNOT_GET_DRIVER_INFO 12 +#define COMBINED_MODE_NOT_STACKED_SCREENS_MODE 13 +#define TWO_TIMES_COMBINED_MODE 14 +#define SECONDARY_DIFFERENT_FROM_PRIMARY 15 + + + /* Vendor Release Numbering scheme. + * The new scheme is needed so that clients can better tell what + * server they are running against. + * Format of the Vendor Release Number: + * aabbppp + * aa : MIT release. Currently 5: Release 5 of X11 + * bb : An HP major release number. Increments at each major + * release of the server. + * ppp: Server patch level. Starts at 0, increments every + * release of a patched server. + * + * Numbers to update and when: + * VR_MIT_RELEASE : For example, X11 R5, this number is 5. + * VR_HP_RELEASE : What we used to use for Vendor Release + * Numbers. When a "new" server is release, increment + * this number, create a new constant that can be used by + * libraries and zero out HP_PATCH_LEVEL. + * VR_HP_PATCH_LEVEL : When a patch server is released, increment + * this number and leave the others the same. + * + * Notes: + * It is important that HP_VENDOR_RELEASE_NUMBER always increase + * when it changes. + */ + + + /* Server major release numbers: */ +#define NEXTTRACK_SERVER 0 /* HP-UX 6.2 */ +#define MERGE_SERVER 1 /* HP-UX 6.5 */ +#define REL_70_SERVER 2 /* HP-UX 7.0 */ +#define REL_701_SERVER 3 /* HP-UX 7.05 */ +#define REL_80_SERVER 4 /* HP-UX 8.0 */ +#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) \ + ( (mit_release * 100000) + (hp_release * 1000) + (hp_patch_level) ) + +#define HP_VENDOR_RELEASE_NUMBER \ + HP_VRN(VR_MIT_RELEASE, VR_HP_RELEASE, VR_HP_PATCH_LEVEL) + + + /* And now, some constants that can be used by libraries to check + * the release (for example, with a call to CheckHpExtInit()): + * Note: + * From here (9.0) on out, you (library writers) should be using + * these constants. + */ +#define VREL_90_SERVER HP_VRN(5, REL_90_SERVER, 0) /* HP-UX 9.0 R5 */ +#define VREL_903_SERVER HP_VRN(5, REL_903_SERVER, 0) /* HP-UX 9.03 R5 */ + +#endif diff --git a/xc/programs/Xserver/hw/hp/include/hppriv.h b/xc/programs/Xserver/hw/hp/include/hppriv.h new file mode 100644 index 000000000..d0e58860e --- /dev/null +++ b/xc/programs/Xserver/hw/hp/include/hppriv.h @@ -0,0 +1,111 @@ +/* $TOG: hppriv.h /main/3 1998/02/10 13:10:38 kaleb $ */ +/************************************************************************* + * + * (c)Copyright 1992 Hewlett-Packard Co., All Rights Reserved. + * + * RESTRICTED RIGHTS LEGEND + * Use, duplication, or disclosure by the U.S. Government is subject to + * restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in + * Technical Data and Computer Software clause in DFARS 252.227-7013. + * + * Hewlett-Packard Company + * 3000 Hanover Street + * Palo Alto, CA 94304 U.S.A. + * + * Rights for non-DOD U.S. Government Departments and Agencies are as set + * forth in FAR 52.227-19(c)(1,2). + * + *************************************************************************/ + +/* + +Copyright 1987, 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 1988 by Hewlett-Packard Company +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, + Massachusetts + +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 names of +Hewlett-Packard or Digital not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +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. + +*/ + + +/* + * Number of depths that we can possible have on our hardware per + * screen in the foreseeable future + */ + +#ifndef MAX_PATH_NAME +#define MAX_PATH_NAME 256 +#endif /* MAX_PATH_NAME */ + +#define MAX_DRIVER_NAME 32 +#define MAX_DEPTHS 16 + + +/* private field for XOS displays */ +typedef struct _hpPriv { + + /* Start up information from X*screens file */ + char StandardDevice[MAX_PATH_NAME]; + char StandardDriver[MAX_DRIVER_NAME]; + int StandardFd; + int StandardNumDepths; + int StandardDepths[ MAX_DEPTHS ]; + Bool StandardDoubleBuffer; + int StandardDoubleBufferDepth; + int LineNumber; + int MonitorDiagonal; /* in units of .001 inches */ + int depth; /* Device depth. Defaults to 8, */ + /* can be set via Xnscreens file */ + + /* Hooks for the input driver to communicate with the output driver */ + void (*MoveMouse)(); + void (*CursorOff)(); + void (*ChangeScreen)(); + Bool isSaved; +} hpPriv; + +typedef hpPriv *hpPrivPtr; diff --git a/xc/programs/Xserver/hw/hp/input/Imakefile b/xc/programs/Xserver/hw/hp/input/Imakefile new file mode 100644 index 000000000..d9f6a9663 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/Imakefile @@ -0,0 +1,69 @@ +XCOMM $XConsortium: Imakefile /main/7 1996/09/28 17:12:35 rws $ +#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) + +LOBJS = \ + hpKeyMap.ln \ + x_hil.ln \ + x_hilinit.ln \ + xtest1imp.ln \ + getkeysym.ln + + DEFINES = ExtensionOSDefines -DOSMAJORVERSION=OSMajorVersion + LIB_DEFINES = -DLIBDIR=\"$(LIBDIR)\" + INCLUDES = -I. -I.. -I../include -I../../../include -I./X11 \ + -I../../../cfb -I../../../mfb -I../../../mi \ + -I$(XINCLUDESRC) -I$(EXTINCSRC) -I./drivers + LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/hpux/llib-los.ln + +all:: + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) + +NormalLibraryObjectRule() +NormalLibraryTarget(hp,$(OBJS)) + +SpecialCObjectRule(x_hilinit,$(ICONFIGFILES),$(LIB_DEFINES)) +SpecialCObjectRule(x_hil,$(ICONFIGFILES),$(LIB_DEFINES)) +SpecialCObjectRule(getkeysym,$(ICONFIGFILES),$(LIB_DEFINES)) +DependTarget() + +LintLibraryTarget(hp,$(SRCS1)) +NormalLintTarget($(SRCS1)) diff --git a/xc/programs/Xserver/hw/hp/input/X11/XHPlib.h b/xc/programs/Xserver/hw/hp/input/X11/XHPlib.h new file mode 100644 index 000000000..2684b8853 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/X11/XHPlib.h @@ -0,0 +1,757 @@ +/* $XConsortium: XHPlib.h /main/4 1996/12/04 10:23:16 lehors $ */ +/************************************************************ +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" + +#ifndef _XLIB_H_ +#include <X11/Xlib.h> +#endif +#ifndef _XUTIL_H_ +#include <X11/Xutil.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define GENERAL_PROMPT 0 +#define PROMPT_1 1 +#define PROMPT_2 2 +#define PROMPT_3 3 +#define PROMPT_4 4 +#define PROMPT_5 5 +#define PROMPT_6 6 +#define PROMPT_7 7 + +#define GENERAL_ACKNOWLEDGE 0 +#define ACKNOWLEDGE_1 1 +#define ACKNOWLEDGE_2 2 +#define ACKNOWLEDGE_3 3 +#define ACKNOWLEDGE_4 4 +#define ACKNOWLEDGE_5 5 +#define ACKNOWLEDGE_6 6 +#define ACKNOWLEDGE_7 7 + +#define HPDeviceKeyPressreq 1 +#define HPDeviceKeyReleasereq 2 +#define HPDeviceButtonPressreq 3 +#define HPDeviceButtonReleasereq 4 +#define HPDeviceMotionNotifyreq 5 +#define HPDeviceFocusInreq 6 +#define HPDeviceFocusOutreq 7 +#define HPProximityInreq 8 +#define HPProximityOutreq 9 +#define HPDeviceKeymapNotifyreq 10 +#define HPDeviceMappingNotifyreq 11 + +extern int HPDeviceKeyPress; +extern int HPDeviceKeyRelease; +extern int HPDeviceButtonPress; +extern int HPDeviceButtonRelease; +extern int HPDeviceMotionNotify; +extern int HPDeviceFocusIn; +extern int HPDeviceFocusOut; +extern int HPProximityIn; +extern int HPProximityOut; +extern int HPDeviceKeymapNotify; +extern int HPDeviceMappingNotify; + +typedef int (*PtrFuncInt) (); + +typedef unsigned long XHPFilterId; + +/* structure used to split events queue between drivers and client */ + +typedef struct _XHProutines *_XHPrtnptr; + +typedef struct _XHProutines + { + Display *display; + XHPFilterId id; + Window window; + Mask std_filtermask; + Mask std_clientmask; + Mask ext_filtermask[MAX_LOGICAL_DEVS]; + Mask ext_clientmask[MAX_LOGICAL_DEVS]; + int (*callback) (); + int state_info; + _XHPrtnptr next; + } XHProutines; + +typedef struct + { + XKeyEvent ev; + XID deviceid; + } XHPDeviceKeyEvent; + +/*************************************************************** + * + * The location of the X pointer is reported in the coordinate + * fields of the ev member. The location of the device + * is determined from the previous DeviceMotionNotify event. + * + */ + +typedef struct { + XButtonEvent ev; + XID deviceid; + } XHPDeviceButtonEvent; + +/*************************************************************** + * + * The ax_num and ax_val fields contain the data reported by the + * device. The values may be absolute or relative. Any axis + * whose value changes will be reported. + * + */ + +typedef struct + { + int ax_num; + int ax_val; + } XHPAxis_data; + +/**************************************************************************** + * + * Bug fix for alignment problem on s700/ s800. + * + * XHPDeviceMotionEvent embeds an XMotionEvent struct. The XMotionEvent + * struct contains a char followed by an int. 68k CPUs add one byte of + * padding to align the int on a 16-bit boundary. PA-RISC CPUs add three + * bytes of padding to align the int on a 32-bit boudary. The result is + * that XMotionEvent structs are 58 bytes on 68k CPUs and 60 bytes on + * PA-RISC CPUs. + * + * The size is critical because the XHPScreen_events routine assumes that all + * HP input extension events contain a device id in bytes 60 - 63. + * + * The right way to fix this would be to define a 60-byte + * array and make it a union with the ev field, but this would break existing + * clients that reference this field. + * + * Instead we will ifdef the struct to make the padding come out right. + * A side effect of this is that on machines with 32-bit alignment, there's + * only room for 3 elements in the data array field, since the total XEvent + * size is 96 bytes. This is probably ok, since no HP input devices report more + * than 3 axes of motion. We will leave the s300 definition at 4 elements, + * since it was originally defined that way. We will also put in code to + * cause a compiler error for undefined machines. + * + * Mea culpa, ---gms + */ + +typedef struct + { +#if defined(__hp9000s300) || defined(__apollo) /* 68k aligns to 16 bits */ + XMotionEvent ev; + char pad; + unsigned char axes_count; + XID deviceid; + XHPAxis_data data[4]; +#else +#if defined(__hp9000s800) || defined(__hp9000s700) /* 32-bit alignment */ + XMotionEvent ev; + XID deviceid; + XHPAxis_data data[3]; + unsigned char axes_count; +#else +#if defined(__hp_osf) && defined(__mc68000) + XMotionEvent ev; + char pad; + unsigned char axes_count; + XID deviceid; + XHPAxis_data data[4]; +#else +#if defined(__hp_osf) && defined(__pa_risc) + XMotionEvent ev; + XID deviceid; + XHPAxis_data data[3]; + unsigned char axes_count; +#else +This is a bogus line to force a compiler error on undefined machines - gms. +#endif +#endif +#endif +#endif + } XHPDeviceMotionEvent; + +typedef struct + { + XFocusChangeEvent ev; + char pad[32]; + XID deviceid; + char pad1[2]; + } XHPDeviceFocusChangeEvent; + +typedef struct + { + XMappingEvent ev; + char pad[28]; + XID deviceid; + char pad1[2]; + } XHPDeviceMappingEvent; + +typedef struct + { + int type; /* ProximityIn or ProximityOut */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window of event */ + Window root; /* root window that the event occured on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + Bool same_screen; /* same screen flag */ + char pad[4]; + XID deviceid; + char pad1[2]; + } XHPProximityNotifyEvent; +typedef XHPProximityNotifyEvent XHPProximityInEvent; +typedef XHPProximityNotifyEvent XHPProximityOutEvent; + +/* generated on EnterWindow and FocusIn when KeyMapState selected */ +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + char key_vector[32]; + char pad[8]; + XID deviceid; +} XHPDeviceKeymapEvent; + +typedef struct + { + char pad[60]; + XID deviceid; + } XHP_AnyEvent; + +typedef struct + { + unsigned int resolution; + unsigned short min_val; + unsigned short max_val; + } XHPaxis_info; + +typedef struct + { + XID x_id; + char *name; + XHPaxis_info *axes; + unsigned short type; + unsigned short min_keycode; + unsigned short max_keycode; + unsigned char hil_id; + unsigned char mode; + unsigned char num_axes; + unsigned char num_buttons; + unsigned char num_keys; + unsigned char io_byte; + unsigned short detailed_id; + unsigned char pad[6]; + } XHPDeviceList; + +typedef struct { + int key_click_percent; + int bell_percent; + int bell_pitch; + int bell_duration; + int led; + int led_mode; + int key; + int auto_repeat_mode; /* On, Off, Default */ + int accelNumerator; + int accelDenominator; + int threshold; +} XHPDeviceControl; + +/* Data structure for XHPGetDeviceControl */ + +typedef struct { + int key_click_percent; + int bell_percent; + unsigned int bell_pitch, bell_duration; + unsigned long led_mask; + int global_auto_repeat; + int accelNumerator; + int accelDenominator; + int threshold; + char auto_repeats[32]; +} XHPDeviceState; + +typedef struct { + Time time; + unsigned short *data; +} XHPTimeCoord; + + +/* This structure is used to pass Nlio ioctl style commands + * to the Nlio server */ + +#define XNHPNlioctl "HPNlioctl" + +typedef struct { + int cmd; + XPointer arg; + int ret; +} XhpNlioCmd; + +/* These are the structures used for the XHPNlioctl call */ + +typedef struct { + int flags; + KeySym invoke_nlio; + KeySym terminate_nlio; + KeySym set_alternate; + KeySym unset_alternate; +} K16_state; + +/* These are the commands for the XHPNlioctl call */ +#include <sys/ioctl.h> +#define K16_FOCUS_IN _IO('X', 100) +#define K16_FOCUS_OUT _IO('X', 101) + +#define K16_EXEC_PROC 1 +#define K16_KILL_PROC 2 +#define K16_GET_STATEKEYS 3 +#define K16_SET_STATEKEYS 4 +#define K16_ALT_ON 5 +#define K16_NLIO_ON 6 +#define K16_IS_PROC 7 +#define K16_GET_ENCODING 8 +#define K16_SET_ENCODING 9 + +#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; + int offset; + int size; +}; + +#define HPK_KEYDEVICE_NAME_TABLE_ID 19998 +#define HPK_MODMAP_TABLE_ID 19999 +#define HPK_FIRST_RESERVED_ID 20000 + +typedef struct +{ + int keydevice_id, min_keycode, max_keycode, columns; + char *name, *modmap_name; +} HPKKeyDeviceInfo; + +#define MODMAP_SIZE 256 /* aka MAP_LENGTH in server/include/input.h */ + +typedef struct +{ + char *modmap_name; + CARD8 modmap[MODMAP_SIZE]; +} HPKModMap; + + +/* Error values returned by XHPSetKeyboardMapping */ + +#define XHPKB_NOKEYFILE 1 +#define XHPKB_BADMAGIC 2 +#define XHPKB_BADKBID 3 +#define XHPKB_NONHPINPUTDEV 4 +#define XHPKB_NOMEM 5 + +/* In the following list, several of the constants have duplicate names. + The duplicate names were added to provide a consistent name for the + tokens (i.e. each name represents a language). The original version + mixed country names and language names. */ + +#define KB_US_English 0 /* For use with HP46021A */ +#define KB_Latin_Spanish 1 /* For use with HP46021AM */ +#define KB_Katakana 2 /* For use with HP46021AJ */ +#define KB_Danish 3 /* For use with HP46021AY */ +#define KB_French 4 /* For use with HP46021AF */ +#define KB_Norwegian 5 /* For use with HP46021AN */ +#define KB_Swiss_German 6 /* For use with HP46020AP + : HIL-ID(lower 5 bits)=19h */ +#define KB_Canada_French 7 /* For use with HP46021AC */ +#define KB_UK_English 8 /* For use with HP46021AU */ +#define KB_Finnish 9 /* For use with HP46021AX */ +#define KB_Belgian 10 /* For use with HP46021AW */ +#define KB_Swiss_German2 11 /* For use with HP46021AP */ +#define KB_Euro_Spanish 12 /* For use with HP46021AE */ +#define KB_Swiss_French2 13 /* For use with HP46021AQ */ +#define KB_T_Chinese 14 /* Trad. Chinese (ROC): For HP46021W#ZAA */ +#define KB_S_Chinese 15 /* Simp. Chinese (PROC): For HP40621W#ZAC */ +#define KB_German 16 /* For use with HP46021AD */ +#define KB_Swedish 17 /* For use with HP46021AS */ +#define KB_Dutch 18 /* For use with HP46021AH */ +#define KB_Korean 19 /* Korean: For HP40621W#ZAB */ +#define KB_Italian 20 /* For use with HP46021AZ */ +#define KB_Canada_English 21 /* For use with HP46021AL */ +#define KB_Swiss_French 22 /* For use with HP46020AQ + : HIL-ID(lower 5 bits)=03h */ +#define KB_Japanese 23 /* For use with HP46021W#ZAL */ + + /* ITF ethereal keyboards */ +#define KB_Hebrew 100 /* Hebrew Keymap - NO KEYBOARD */ +#define KB_Cyrillic 101 /* Cyrillic Keymap - NO KEYBOARD */ +#define KB_Czech 102 /* Czech Keymap - NO KEYBOARD */ +#define KB_Hungarian 103 /* Hungarian Keymap - NO KEYBOARD */ +#define KB_SerboCroatian 104 /* SerboCroatian Keymap - NO KEYBOARD */ +#define KB_Polish 105 /* Polish Keymap - NO KEYBOARD */ +#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) */ +#define KB_PS2_Hebrew 150 /* Hebrew Keymap - NO KEYBOARD */ +#define KB_PS2_Cyrillic 151 /* Cyrillic Keymap - NO KEYBOARD */ +#define KB_PS2_Czech 152 /* Czech Keymap - NO KEYBOARD */ +#define KB_PS2_Hungarian 153 /* Hungarian Keymap - NO KEYBOARD */ +#define KB_PS2_SerboCroatian 154 /* SerboCroatian Keymap - NO KEYBOARD */ +#define KB_PS2_Polish 155 /* Polish Keymap - NO KEYBOARD */ +#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 *************** */ + +#define KB_PS2_US_English 60 +#define KB_PS2_Latin_Spanish 61 +#define KB_PS2_Katakana 62 +#define KB_PS2_Danish 63 +#define KB_PS2_French 64 +#define KB_PS2_Norwegian 65 +#define KB_PS2_Swiss_German 66 +#define KB_PS2_Canada_French 67 +#define KB_PS2_UK_English 68 +#define KB_PS2_Finnish 69 +#define KB_PS2_Belgian 70 +#define KB_PS2_Swiss_German2 71 +#define KB_PS2_Euro_Spanish 72 +#define KB_PS2_Swiss_French2 73 +#define KB_PS2_T_Chinese 74 +#define KB_PS2_S_Chinese 75 +#define KB_PS2_German 76 +#define KB_PS2_Swedish 77 +#define KB_PS2_Dutch 78 +#define KB_PS2_Korean 79 +#define KB_PS2_Italian 80 +#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) */ +#define KB_BARCODE_WAND 203 /* HP barcode reader */ + +#define KB_HPUNSUPP -1 /* For unsupported HP keyboards */ +#define KB_NONHP -2 /* For non-HP keyboards (for internal use) */ + +typedef int KEYBOARD_ID; + +/* Function definitions for clients. */ + +Status XHPSetKeyboardMapping(); + +/* End of entries required for XHPSetKeyboardMapping. */ + +typedef struct { + unsigned char * iso7to8; + unsigned char * iso8to7; + char ** mute8to7; + unsigned int mutekey; +} _XHP_transptrs; + +#define _XHP_ISO7To8(status,index) \ + ((_XHP_transptrs *) ((status)->compose_ptr)) -> iso7to8 [index] + +#define _XHP_ISO8To7(status,index) \ + ((_XHP_transptrs *) ((status)->compose_ptr)) -> iso8to7 [index] + +#define _XHP_MUTE8To7(status,index) \ + ((_XHP_transptrs *) ((status)->compose_ptr)) -> mute8to7[index-128] + +#define XHPInputInit(dpy,status) XHPNlioctl(dpy,status,K16_EXEC_PROC) + +#define XHPSetKbdMapInit(dpy,kbd,frc,status) \ + { \ + XHPNlioctl(dpy,status,K16_KILL_PROC); \ + XHPSetKeyboardMapping(dpy,kbd,frc); \ + XHPNlioctl(dpy,status,K16_EXEC_PROC); \ + } + +/* These are the tags in the compose structure for the different convert + * routines + */ + +#define _XHP_INP_NLIO 0x81000000 +#define _XHP_INP_ROM8 0x82000000 +#define _XHP_INP_7SUB 0x84000000 + +/* Function definitions for client programs */ + +PtrFuncInt XHPSetErrorHandler(); +XFontStruct *XHPGet16bitMixedFontStruct(); + +extern PtrFuncInt XHPGetEurasianCvt( + Display *dpy) ; +extern int XGetHpKeyboardId( + register Display *dpy, + unsigned char *kbd_id) ; +extern int XHPAcknowledge( + register Display *dpy, + XID device, + int ack) ; +extern int XHPDeviceAutoRepeatOff( + register Display *dpy, + XID device) ; +extern int XHPDeviceAutoRepeatOn( + register Display *dpy, + XID device, + int rate) ; +extern int XHPChangeDeviceControl( + register Display *dpy, + XID deviceid, + unsigned long mask, + XHPDeviceControl *vlist) ; +extern int XHPChangeDeviceKeyMapping( + register Display *dpy, + XID deviceid, + int first, + int syms_per_code, + KeySym *keysyms, + int count) ; +extern int XHPDisableReset( + register Display *dpy ); +extern int XHPDisableReset( + register Display *dpy ); +extern int XHPFreeDeviceList( + XHPDeviceList *list) ; +extern XHPTimeCoord * XHPGetDeviceMotionEvents( + register Display *dpy, + XID deviceid, + Window window, + Time start, + Time stop, + int *nEvents) ; +extern KeySym * XHPGetDeviceKeyMapping( + register Display *dpy, + XID deviceid, + KeyCode first, + int keycount, + int *syms_per_code) ; +extern XModifierKeymap * XHPGetDeviceModifierMapping( + register Display *dpy, + XID deviceid) ; +extern int XHPGetServerMode( + register Display *dpy, + register int screen) ; +extern int XHPGrabDeviceButton( + register Display *dpy, + XID device, + unsigned int button, + unsigned int modifiers, + Window grab_window, + Bool owner_events, + unsigned int event_mask, + int pointer_mode, + int keyboard_mode) ; +extern int XHPGrabDeviceKey( + register Display *dpy, + XID device, + unsigned int key, + unsigned int modifiers, + Window grab_window, + Bool owner_events, + int pointer_mode, + int keyboard_mode) ; +extern int XHPGrabReset( + register Display *dpy, + Atom *type) ; +extern int XHPGrabDevice( + register Display *dpy, + XID id, + Window window, + Bool ownerEvents, + int pointer_mode, + int device_mode, + Time time) ; +extern int XHPGetCurrentDeviceMask( + register Display *dpy, + Window w, + XID device, + Mask *mask) ; +extern int XHPGetExtEventMask( + register Display *dpy, + long evconst, + int *type, + Mask *mask) ; +extern int XHPGetDeviceFocus( + register Display *dpy, + XID deviceid, + Window *focus, + int *revert_to) ; +extern int XHPGetDeviceControl( + register Display *dpy, + XID deviceid, + XHPDeviceState *values) ; +extern XHPDeviceList * XHPListInputDevices( + register Display *dpy, + int *ndevices) ; +extern int XHPPrompt( + register Display *dpy, + XID device, + int prompt) ; +extern XHPFilterId XHPRegisterEventFilter( + register Display *dpy, + Window window, + int device, + Mask mask, + int (*routine)(), + int state_info) ; +extern int XHPSetInputDevice( + register Display *dpy, + register XID id, + register int mode) ; +extern int XHPSelectExtensionEvent( + register Display *dpy, + Window w, + XID device, + Mask mask) ; +extern int XHPUngrabDevice( + register Display *dpy, + XID device, + Time time) ; +extern int XHPUngrabDeviceButton( + register Display *dpy, + XID device, + unsigned int button, + unsigned int modifiers, + Window grab_window) ; +extern int XHPUngrabDeviceKey( + register Display *dpy, + XID device, + unsigned int key, + unsigned int modifiers, + Window grab_window) ; +extern int XHPSetDeviceFocus( + register Display *dpy, + XID deviceid, + Window focus, + int revert_to, + Time time) ; +extern int XHPSetDeviceModifierMapping( + register Display *dpy, + XID deviceid, + XModifierKeymap *modmap) ; +extern Cursor XHPGetWindowCursor( + register Display *dpy, + Window window) ; +extern int XHPConvertLookup( + register XKeyEvent *event, + char *buffer, + int nbytes, + KeySym *keysym, + XComposeStatus *status, + int (*convert_routine)()) ; +extern int input_isolatin1( + KeySym keysym, + int modifiers, + char *buffer_return, + int bytes_buffer, + XComposeStatus *status_in_out) ; +extern KEYBOARD_ID XHPGetKeyboardID( + Display *dpy) ; +extern void XHPUpdateKIDList( + Display *dpy, + KEYBOARD_ID kbd_id) ; +extern KEYBOARD_ID XHPGetCvtLang( + Display *dpy) ; +extern KEYBOARD_ID XHPGetHILandCvt( + Display *dpy) ; +extern int _XHPInitKbdState( + Display *dpy) ; +extern int _XHP_alt_on( + Display *dpy) ; +extern void _XHP_GetAltKeys( + Display *dpy, + K16_state *state) ; +extern void _XHP_SetAltKeys( + Display *dpy, + K16_state *state) ; +extern int _XHPIgnoreLang( + int value) ; +extern int XHPInputRoman8( + Display *display, + KeySym *keysym, + int modifiers, + unsigned char *buffer_return, + int bytes_buffer, + register XComposeStatus *status_in_out) ; +extern int XHPInputLatin1( + Display *display, + register KeySym *keysym, + int modifiers, + unsigned char *buffer_return, + int bytes_buffer, + register XComposeStatus *status_in_out) ; +extern int XHPInputISO8859_8( + Display *display, + KeySym *keysym, + unsigned int modifiers, + char *buffer_return, + int bytes_buffer, + XComposeStatus *status_in_out) ; +#ifdef __cplusplus +} /* Close scope of 'extern "C"' declaration that encloses file */ +#endif /* __cplusplus */ +#endif /* XHPLIB_H */ diff --git a/xc/programs/Xserver/hw/hp/input/cr16.s b/xc/programs/Xserver/hw/hp/input/cr16.s new file mode 100644 index 000000000..a367a7980 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/cr16.s @@ -0,0 +1,12 @@ +; $XConsortium: cr16.s,v 1.2 95/06/15 15:25:19 dpw Exp $ + .SPACE $TEXT$ + .SUBSPA $CODE$ + .export cr16 + .PROC + .CALLINFO + .ENTRY +cr16 + bv (%rp) + mfctl 16,%ret0 + .EXIT + .PROCEND diff --git a/xc/programs/Xserver/hw/hp/input/drivers/Imakefile b/xc/programs/Xserver/hw/hp/input/drivers/Imakefile new file mode 100644 index 000000000..e87ed43f9 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/Imakefile @@ -0,0 +1,36 @@ +XCOMM $XConsortium: Imakefile /main/5 1996/12/26 09:00:56 kaleb $ + +#include <Server.tmpl> + +.c.o: + $(RM) $@ + $(CC) -c $(CFLAGS) $(PICFLAGS) $*.c + +DRVRLIBDIR = $(LIBDIR)/extensions +PICFLAGS = PositionIndependentCFlags +SRCS = hp7lc2k.c hp7lc2m.c hil_driver.c +INCLUDES = -I. -I.. -I../../../../../../include \ + -I../../../../../../include/extensions + +#define DriverTarget(name) @@\ +AllTarget(name.sl) @@\ + @@\ +name.sl: name.o @@\ + $(RM) $@~ @@\ + $(LD) -o $@~ -b name.o @@\ + chmod a-w $@~ @@\ + $(RM) $@ @@\ + $(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() diff --git a/xc/programs/Xserver/hw/hp/input/drivers/X0screens b/xc/programs/Xserver/hw/hp/input/drivers/X0screens new file mode 100644 index 000000000..793b022f0 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/X0screens @@ -0,0 +1,3 @@ +# $XConsortium: X0screens,v 1.1 95/01/23 21:56:39 dpw Exp $ + +/dev/crt diff --git a/xc/programs/Xserver/hw/hp/input/drivers/XHPKeymaps b/xc/programs/Xserver/hw/hp/input/drivers/XHPKeymaps Binary files differnew file mode 100644 index 000000000..6b0aeb9f6 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/XHPKeymaps diff --git a/xc/programs/Xserver/hw/hp/input/drivers/hil_driver.c b/xc/programs/Xserver/hw/hp/input/drivers/hil_driver.c new file mode 100644 index 000000000..0ee8a6559 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/hil_driver.c @@ -0,0 +1,3584 @@ +/* $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]; +#if 0 + printf("fd is %d errno is %d id is %x\n", fd, errno, id); /* */ +#endif + + 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 */ diff --git a/xc/programs/Xserver/hw/hp/input/drivers/hp7lc2k.c b/xc/programs/Xserver/hw/hp/input/drivers/hp7lc2k.c new file mode 100644 index 000000000..92c8c0bb7 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/hp7lc2k.c @@ -0,0 +1,406 @@ +/* $XConsortium: hp7lc2k.c /main/2 1996/12/04 10:23:28 lehors $ */ +/************************************************************ + +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. + +********************************************************/ + +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include "ps2io.h" +#include <X11/X.h> +#include <X11/extensions/XI.h> +#include "x_serialdrv.h" + +/************************************************************************** + * + * hp7lc2k.c - X server input device driver. + * + * This driver provides support for PS2 keyboards attached to an HP9000700LC2 + * via the internal mini-DIN interface. + * + * The HP-UX 9.03 operating system is required by this driver. + * + * If another device is used as the X keyboard, the PS2 keyboard attached to + * the mini-DIN interface can be accessed via the X input device extension + * by adding the following lines to the /usr/lib/X11/X0devices file: + * + * Begin_Device_Description + * Name hp7lc2k.sl # PS2 DIN keyboard via mini-DIN interface + * Use Extension # access via input extension + * Path /dev/ps2kbd # use device special file /dev/ps2kbd + * End_Device_Description + * + * For documentation on using serial input devices with X, please refer + * to the manual "Using the X Window System", Chapter 3 "Preliminary + * Configuration", in the section titled "Using Special Input Devices". + * + * Sample entries for the /usr/lib/X11/X*devices file can be found in + * /etc/newconfig/X0devices. + * + */ + +#define BUFRSIZ 2048 +#define READSIZ 2000 + +static int hp7lc2k_left=READSIZ, hp7lc2k_datacnt=0; +static unsigned char hp7lc2k_buf[BUFRSIZ]; +static unsigned char *hp7lc2k_data_ptr = hp7lc2k_buf; +typedef struct ps2_4 ps2_buffer_t; + +/************************************************************************** + * + * Configure the PS/2 keyboard. Use scancode set 3, Turn indicator LEDs + * off, set all keys to typematic make/break, and set autorepeat to ~30/sec + * and delay to 250 mSec. + */ + +static int +keybd_configure ( + int fd) + { + ps2_buffer_t kbdbuf; + + /* use scancode set 3 */ + + kbdbuf.b[0] = SCANCODE_3; + ioctl (fd, PS2_SCANCODE, &kbdbuf); + + /* turn LEDs off */ + + kbdbuf.b[0] = 0; + ioctl (fd, PS2_INDICATORS, &kbdbuf); + + /* set all keys to typematic and make/break */ + + ioctl (fd, PS2_ALL_TMAT_MKBRK, &kbdbuf); + + /* set the autorepeat rate to the maximum (~30/sec) and the delay to the + minimum (250ms) */ + + kbdbuf.b[0] = 0x00; + ioctl (fd, PS2_RATEDELAY, &kbdbuf); + + } /* end keybd_configure() */ + +/************************************************************************** + * + * This routine is called by the X server to open and configure the device. + * It is passed a pointer to an HPDeviceHeader struct (defined in + * x_serialdrv.h). That struct points to the path name of the device file + * to which the input device is connected. The path is specified in the + * X*devices configuration file described above. + * + * This routine must open the device file and configure the serial port. + * It must initialize fields in the HPInputDeviceHeader struct including + * the device file descriptor, name by which the device will be known to + * X, the number of keys, buttons, and axes on the device, the keymap name + * and file, if the device has keys, and a flags field that specifies the + * size of the data returned by the device. See the serial input device + * specification described above for more details. + * + */ + +static int +hp7lc2kconfigure ( + HPInputDeviceHeader *d) + { + int ret; + ps2_buffer_t kbdbuf; + static unsigned char num_leds=3; + static char hp7lc2k_namebuf[128]; + FILE *fp; + + d->file_ds = open (d->path, O_RDWR | O_NDELAY);/* non-block read */ + if (d->file_ds < 0) + return(INIT_FAILURE); + + keybd_configure (d->file_ds); + + /* get the keyboard nationality, or default to US_English */ + + d->keymap_name = "PS2_DIN_US_English"; /* default keymap name */ + fp = fopen (X_KEYMAP_NAME, "r"); /* defined by x_serialdrv.h */ + if (fp && fscanf (fp, "%s", hp7lc2k_namebuf)) + d->keymap_name = hp7lc2k_namebuf;/* international keymap name */ + fclose(fp); + + d->x_name = "PS2_DIN_KEYBOARD"; /* device name for X server*/ + d->keymap_file = ""; /* keymap file for X server*/ + d->flags = DATA_IS_16_BITS; /* size of data for device */ + d->num_keys = 101; /* tell server we have keys*/ + d->min_kcode = 0; /* server gets from keymap */ + d->max_kcode = 0; /* server gets from keymap */ + d->num_ledf = 1; /* number of led feedbacks */ + d->ledf = &num_leds; /* number of leds */ + d->reset = 107; /* X server reset keycode */ + d->reset_mods = ShiftMask | ControlMask; /* X server reset modifiers*/ + + return (INIT_SUCCESS); + } + +/************************************************************************** + * + * Get more data and crunch the buffer if we're getting near the end. + * + */ + +static int get_more_data( + int fd) + { + int count; + + /* If we don't already have at least 1 byte of data, + * we need to read some. If we're getting near the end + * of the buffer, copy the leftover data to the beginning + * of the buffer. + */ + + if (hp7lc2k_data_ptr - hp7lc2k_buf > hp7lc2k_datacnt) + { + bcopy (hp7lc2k_data_ptr, hp7lc2k_buf, hp7lc2k_datacnt); + hp7lc2k_data_ptr = hp7lc2k_buf; + hp7lc2k_left = READSIZ - hp7lc2k_datacnt; + } + count = read (fd, hp7lc2k_data_ptr + hp7lc2k_datacnt, hp7lc2k_left); + + if (count >0) + { + hp7lc2k_datacnt += count; + hp7lc2k_left -= count; + } + + if (hp7lc2k_datacnt < 1) + return(READ_FAILURE); + + return(READ_SUCCESS); + } + +/************************************************************************** + * + * This entry point is called when the X server detects that there is data + * available to be read from the device. This routine will be called + * repeatedly until it returns READ_FAILURE. It is expected to return + * one "event" for each successful call. An "event" is one key press or + * release, one button press or release, one change in axis data, or one + * change of proximity state. One change in axis data can be reported + * along with a button or proximity change. + * + */ + +static int +hp7lc2kread ( + int fd, unsigned char *data, unsigned char *data_type, int *pending) + { + struct timeval timeout; + unsigned short code, keycode; + int count; + + get_more_data(fd); + if (hp7lc2k_datacnt < 1) + return(READ_FAILURE); + + /* PS2 keyboards return 1-byte scancode for keypresses, and a 1 byte + * constant followed by that same scancode for keyreleases. + * The X server expects key releases to have the value of the + * key press + 1, so we must multiply key codes by 2, and add 1 to the + * key releases. + * + * The minimum key code returned by the kernel is 7, but the minimum + * expected by the keymap is 16. Since the X server will also add 8 to + * the keycode after dividing by 2, to avoid the codes reserved by X for + * mouse buttons, we must add 1 before multiplying. + */ + + if (*hp7lc2k_data_ptr == 0xF0) { /* this is a key release */ + if (hp7lc2k_datacnt == 1){ /* code hasn't arrived */ + timeout.tv_sec = 0; + timeout.tv_usec = 25000; /* wait interval */ + select(0, (int *)NULL, (int *)NULL, (int *)NULL, &timeout); + get_more_data(fd); + if (hp7lc2k_datacnt < 1) + return(READ_FAILURE); + } + code = *(hp7lc2k_data_ptr+1); /* keycode is second byte */ + keycode = (code + 1) * 2 + 1; /* add 1, double it, add 1 */ + hp7lc2k_datacnt-=2; + hp7lc2k_data_ptr+=2; + } + else { + code = *hp7lc2k_data_ptr; + keycode = (code + 1) * 2; /* add 1, double it */ + hp7lc2k_datacnt-=1; + hp7lc2k_data_ptr+=1; + } + + if (code == 0xAA) { /* keyboard has reset itself */ + keybd_configure (fd); /* reconfigure the keyboard */ + hp7lc2k_datacnt=0; /* reset the data count */ + hp7lc2k_data_ptr = hp7lc2k_buf; /* reset the data pointer */ + return(READ_FAILURE); + } + *data++ = keycode; + *data = keycode >> 8; + *data_type = KEY_DATA; /* tell X it's key data */ + *pending = 2; /* two bytes are returned */ + return(READ_SUCCESS); + } + +/************************************************************************** + * + * This routine is called by the X server to write to the keyboard. + * It is called when an X request is made that causes a write to an input + * device. + * + * See the file x_serialdrv.h for the format of the data for each request. + * + * The only one we will support is _XChangeFeedbackControl, which is used + * to turn on LEDs. + * + */ + +static int +hp7lc2kwrite ( + int fd, int request, char *data) + { + int i; + HPKeyboardFeedbackControl *ctrl; + ps2_buffer_t kbdbuf; + + switch (request) + { + case _XChangeFeedbackControl: + ctrl = (HPKeyboardFeedbackControl *) data; + + if (ctrl->class != KbdFeedbackClass) + return(WRITE_FAILURE); + kbdbuf.b[0] = 0; + if (ctrl->leds & SCROLLLOCK_LED) { + kbdbuf.b[0] |= SCROLL_LED; + } + if (ctrl->leds & NUMLOCK_LED) { + kbdbuf.b[0] |= NUM_LED; + } + if (ctrl->leds & CAPSLOCK_LED) { + kbdbuf.b[0] |= CAPS_LED; + } + ioctl (fd, PS2_INDICATORS, &kbdbuf); + + if (ctrl->autoRepeat == AutoRepeatModeOff) + ioctl (fd, PS2_ALL_MKBRK, &kbdbuf); + else + ioctl (fd, PS2_ALL_TMAT_MKBRK, &kbdbuf); + break; + case _XSetDeviceValuators: + case _XChangeDeviceControl: + case _XSetDeviceMode: + default: + return(WRITE_FAILURE); + break; + } + return(WRITE_SUCCESS); + } + +/************************************************************************** + * + * This routine is called by the X server to close an input device. + * + */ + +static int +hp7lc2kclose ( + int fd) + { + close (fd); + return (CLOSE_SUCCESS); + } + +/************************************************************************** + * + * This routine is called to initialize the entry point vector for this + * serial input device driver. + * + */ + +int +hp7lc2k_Init( + SerialProcs *serialproc) + { + serialproc->configure = hp7lc2kconfigure;/* routine to init device */ + serialproc->read = hp7lc2kread; /* routine to read from dev */ + serialproc->write = hp7lc2kwrite; /* routine to write to dev */ + serialproc->close = hp7lc2kclose; /* routine to close device */ + return INIT_SUCCESS; /* indicate success */ + } + +#ifdef DEBUG +main() + { + int fd; + + makedata(); /* make the test data */ + fd = open ("data", O_RDWR); + process_test_data(fd); + close(fd); + } + +/* The PS2 keyboard returns one byte per key press and two bytes per key release. + * The keycode is the same in each case. + * + * Byte 0: + * scancode for key press, 0xF0 for key release. + * Byte 1: + * scancode for key release. + */ + +makedata () + { + int i, fd; + unsigned char buf[3]; + + fd = creat("data", 0777); + for (i=7; i<256; i++) + { + buf[0]=i; + buf[1]=0xF0; + buf[2]=i; + write (fd,buf,3); + } + close(fd); + } + +process_test_data(fd) + { + unsigned char data[32], data_type; + int pending; + + hp7lc2kread (fd, data, &data_type, &pending); + while (pending > 0) + { + printf ("%d bytes returned, type is %x, data is %x %x\n", pending, data_type, + data[0], data[1]); + pending = 0; + data[0] = data[1] = 0; + hp7lc2kread (fd, data, &data_type, &pending); + } + } +#endif /* DEBUG */ diff --git a/xc/programs/Xserver/hw/hp/input/drivers/hp7lc2m.c b/xc/programs/Xserver/hw/hp/input/drivers/hp7lc2m.c new file mode 100644 index 000000000..52709a1ec --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/hp7lc2m.c @@ -0,0 +1,934 @@ +/* $XConsortium: hp7lc2m.c /main/2 1996/12/04 10:23:42 lehors $ */ +/************************************************************ + +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. + +********************************************************/ + +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include "ps2io.h" +#include <X11/extensions/XI.h> +#include "x_serialdrv.h" + +/************************************************************************** + * + * hp7lc2m.c - X server input device driver. + * + * This driver provides support for PS2 mice attached to an HP9000700LC2 + * via the internal mini-DIN interface. + * + * The HP-UX 9.03 operating system is required by this driver. + * + * If another device is used as the X pointer, the PS2 mouse attached to + * the mini-DIN interface can be accessed via the X input device extension + * by adding the following lines to the /usr/lib/X11/X0devices file: + * + * Begin_Device_Description + * Name hp7lc2m.sl # PS2 DIN keyboard via mini-DIN interface + * Use Extension # access via input extension + * Path /dev/ps2mouse # use device special file /dev/ps2mouse + * End_Device_Description + * + * For documentation on using serial input devices with X, please refer + * to the manual "Using the X Window System", Chapter 3 "Preliminary + * Configuration", in the section titled "Using Special Input Devices". + * + * Sample entries for the /usr/lib/X11/X*devices file can be found in + * /etc/newconfig/X0devices. + * + */ + +#define BUFRSIZ 2048 +#define READSIZ 2000 +#define PKT_SIZ 3 +#define BUTTON1_AND_2 0x05 +#define BUTTON2_AND_3 0x06 +#define BUTTON1_AND_3 0x03 +#define BUTTON_BITS 0x07 +#define ONE_BUTTON_DOWN -1 +#define ILLEGAL_COMBO -2 + +static int hp7lc2m_left=READSIZ, hp7lc2m_datacnt=0; +static unsigned char hp7lc2m_buf[BUFRSIZ]; +static unsigned char *hp7lc2m_data_ptr = hp7lc2m_buf; +static unsigned int hp7lc2m_buttonmask; +static unsigned int hp7lc2m_chording_button = 0; +static unsigned int hp7lc2m_chording_interval = 0; +static int process_button(), do_button_chording(), get_more_data(), check_combo (); +typedef struct ps2_4 ps2_buffer_t; + +/************************************************************************** + * + * This routine is called by the X server to open and configure the device. + * It is passed a pointer to an HPDeviceHeader struct (defined in + * x_serialdrv.h). That struct points to the path name of the device file + * to which the input device is connected. The path is specified in the + * X*devices configuration file described above. + * + * This routine must open the device file and configure the serial port. + * It must initialize fields in the HPInputDeviceHeader struct including + * the device file descriptor, name by which the device will be known to + * X, the number of keys, buttons, and axes on the device, the keymap name + * and file, if the device has keys, and a flags field that specifies the + * size of the data returned by the device. See the serial input device + * specification described above for more details. + * + */ + +static int +hp7lc2mconfigure ( + HPInputDeviceHeader *d) + { + int ret; + ps2_buffer_t mousebuf; + + d->file_ds = open (d->path, O_RDWR | O_NDELAY);/* non-block read */ + if (d->file_ds < 0) + return(INIT_FAILURE); + + if (d->button_chording) + hp7lc2m_chording_interval = d->button_chording; + + /* set the sample rate to 100 reports/second max */ + + ioctl (d->file_ds, PS2_DISABLE); + ioctl (d->file_ds, PS2_RESET); + mousebuf.b[0] = SAMPLE_60; + ioctl (d->file_ds, PS2_SAMPLERATE, &mousebuf); + + /* put the mouse into stream mode */ + + mousebuf.b[0] = 0; + ioctl (d->file_ds, PS2_STREAMMODE, &mousebuf); + + /* set the mouse resolution to 8 counts/mm */ + + mousebuf.b[0] = RES_4; + ioctl (d->file_ds, PS2_RESOLUTION, &mousebuf); + ioctl (d->file_ds, PS2_ENABLE); + + d->x_name = "PS2_DIN_MOUSE"; /* device name for X server*/ + d->flags = DATA_IS_8_BITS; /* size of data for device */ + d->ax_num = 2; /* two axes of motion */ + if (d->button_chording) + d->num_buttons = 5; /* emulate 5 buttons */ + else + d->num_buttons = 3; /* support 3 buttons */ + d->num_keys =0; /* no keys */ + d->resolution = 80; /* resolution in counts/cm */ + d->max_x = 255; /* maximum x value in counts */ + d->max_y = 255; /* maximum y value in counts */ + + return (INIT_SUCCESS); + } + +/************************************************************************** + * + * This entry point is called when the X server detects that there is data + * available to be read from the device. This routine will be called + * repeatedly until it returns READ_FAILURE. It is expected to return + * one "event" for each successful call. An "event" is one key press or + * release, one button press or release, one change in axis data, or one + * change of proximity state. One change in axis data can be reported + * along with a button or proximity change. + * + */ + +static int +hp7lc2mread ( + int fd, unsigned char *data, unsigned char *data_type, int *pending) + { + int button, data_read=0; + unsigned int buttonmask; + int count, x, y; + + /* If we don't already have at least PKT_SIZ bytes of data, + * we need to read some. If we're getting near the end + * of the buffer, copy the leftover data to the beginning + * of the buffer. + */ + + if (hp7lc2m_datacnt < PKT_SIZ && (get_more_data (fd) == READ_FAILURE)) + return(READ_FAILURE); + + /* The PS2 mouse returns PKT_SIZ bytes for each movement of the mouse or + * button press or release. The format of the bytes is as follows: + * + * Byte 0: + * Bit 7 Y data overflow (1 = overflow) + * Bit 6 X data overflow (1 = overflow) + * Bit 5 Y data sign (1 = negative) + * Bit 4 X data sign (1 = negative) + * Bit 3 Not used (always 1) + * Bit 2 Center button (1 = depressed) + * Bit 1 Right button (1 = depressed) + * Bit 0 Left button (1 = depressed) + * Byte 1: + * X coordinate data byte (2's compliment) + * Byte 2: + * Y coordinate data byte (2's compliment) + */ + + x = (int) hp7lc2m_data_ptr[1]; + y = -((int) hp7lc2m_data_ptr[2]); + + if (x!=0 || y != 0) { + *data_type |= MOTION_DATA; + data[0] = x; + data[1] = y; + data_read = 2; + hp7lc2m_data_ptr[1] = 0; /* clear motion for reprocessing case */ + hp7lc2m_data_ptr[2] = 0; /* clear data for reprocessing case */ + } + + /* Check to see if a button has changed state */ + buttonmask = (u_char) (hp7lc2m_data_ptr[0] & BUTTON_BITS); + if (buttonmask != hp7lc2m_buttonmask) { + if (hp7lc2m_chording_interval) { + if ((button = do_button_chording(fd, &buttonmask))>=0) { + *data_type |= BUTTON_DATA; + data[data_read++] = button; + } + } + else { + button = process_button(buttonmask); + *data_type |= BUTTON_DATA; + data[data_read++] = button; + } + } + if (hp7lc2m_buttonmask == buttonmask) /* no leftover buttons */ + { + hp7lc2m_datacnt -= PKT_SIZ; + hp7lc2m_data_ptr += PKT_SIZ; + } + *pending += data_read; + return(READ_SUCCESS); + } + +/************************************************************************** + * + * Process a button from the current data packet. + * + */ + +#define hp7lc2_BUTTON1 0x01 +#define hp7lc2_BUTTON2 0x04 +#define hp7lc2_BUTTON3 0x02 +#define NUM_BUTTONS 3 + +static int process_button( + unsigned int buttonmask) + { + int i, button, bit, down, up; + + button = 1; + up = ~buttonmask & hp7lc2m_buttonmask; + for (i=0; i<NUM_BUTTONS; i++) + { + bit = (1 << i); + if (bit & up) + { + switch (bit) + { + case hp7lc2_BUTTON3: + button += 2; + case hp7lc2_BUTTON2: + button += 2; + break; + } + hp7lc2m_buttonmask = (hp7lc2m_buttonmask & ~bit); + return(button); + } + } + + down = buttonmask & ~hp7lc2m_buttonmask; + button = 0; + for (i=0; i<NUM_BUTTONS; i++) + { + bit = (1 << i); + if (bit & down) + { + switch (bit) + { + case hp7lc2_BUTTON3: + button += 2; + case hp7lc2_BUTTON2: + button += 2; + break; + } + hp7lc2m_buttonmask = (hp7lc2m_buttonmask | bit); + return(button); + } + } + } + +/************************************************************************** + * + * Get more data and crunch the buffer if we're getting near the end. + * + */ + +static int get_more_data( + int fd) + { + int count; + + if (hp7lc2m_data_ptr - hp7lc2m_buf > hp7lc2m_datacnt) + { + bcopy (hp7lc2m_data_ptr, hp7lc2m_buf, hp7lc2m_datacnt); + hp7lc2m_data_ptr = hp7lc2m_buf; + hp7lc2m_left = READSIZ - hp7lc2m_datacnt; + } + count = read (fd, hp7lc2m_data_ptr + hp7lc2m_datacnt, hp7lc2m_left); + + if (count >0) + { + hp7lc2m_datacnt += count; + hp7lc2m_left -= count; + } + + if (hp7lc2m_datacnt < PKT_SIZ) + return(READ_FAILURE); + + return(READ_SUCCESS); + } + +/************************************************************************** + * + * Handle button chording. + * + */ + +#define BUTTON1_DOWN 0 +#define BUTTON1_UP 1 +#define BUTTON2_DOWN 2 +#define BUTTON2_UP 3 +#define BUTTON3_DOWN 4 +#define BUTTON3_UP 5 +#define BUTTON4_DOWN 6 +#define BUTTON4_UP 7 +#define BUTTON5_DOWN 8 +#define BUTTON5_UP 9 + +int ignore1, ignore2, ignorecnt; + +static int do_button_chording( + int fd, + unsigned int *buttonmask) + { + int button, ret; + unsigned char *tptr; + unsigned int tmask; + struct timeval timeout; + + if (hp7lc2m_chording_button) /* waiting for chorded button up */ + { + button = process_button(*buttonmask); /* process one button */ + if (button % 2) /* odd number means button up */ + if (button == ignore1) /* up transition of chorded pair */ + { + ignore1= -1; ignorecnt--; /* dont ignore it next time */ + if (ignorecnt == 0) /* done ignoring buttons */ + { + button = hp7lc2m_chording_button; /* send chorded up */ + hp7lc2m_chording_button = 0; /* clear saved button */ + return(button); /* return chorded button */ + } + else + return(-1); /* we ignored this one */ + } + else if (button == ignore2) /* other button of chorded pair */ + { + ignore2= -1; ignorecnt--;/* dont ignore it next time */ + if (ignorecnt == 0) /* done ignoring buttons */ + { + button = hp7lc2m_chording_button; /* send chorded up */ + hp7lc2m_chording_button = 0; /* clear saved button */ + return(button); /* return chorded button */ + } + else + return(-1); /* we ignored this one */ + } + else + return(button); /* not a button to ignore */ + else + return(button); /* button down - dont ignore */ + } + else if (hp7lc2m_buttonmask==0) /* check if chording necessary */ + { + ret = check_combo (*buttonmask); + if (ret == ILLEGAL_COMBO) /* illegal combination */ + return (process_button(*buttonmask)); /* process a button */ + else if (ret != ONE_BUTTON_DOWN)/* we already chorded */ + return (ret); /* return chorded button */ + + timeout.tv_sec = 0; + timeout.tv_usec = hp7lc2m_chording_interval * 1000; /* wait interval */ + select(0, (int *)NULL, (int *)NULL, (int *)NULL, &timeout); + get_more_data(fd); + + for (tptr=hp7lc2m_data_ptr+PKT_SIZ; + tptr<hp7lc2m_data_ptr+hp7lc2m_datacnt; + tptr +=PKT_SIZ) + { +#ifdef DEBUG + if (tptr > (hp7lc2m_data_ptr + (3 * PKT_SIZ))) + break; +#endif + tmask = (u_char) (*tptr & BUTTON_BITS); + if (tmask != *buttonmask) /* a button changed */ + { + if (!(tmask & *buttonmask)) /* a button went up */ + return (process_button(*buttonmask)); + if ((ret = check_combo (tmask)) > 0) + { + if (tmask == hp7lc2m_buttonmask) + *buttonmask = hp7lc2m_buttonmask; + hp7lc2m_datacnt -= (tptr - hp7lc2m_data_ptr); + hp7lc2m_data_ptr = tptr; + return (ret); + } + else + return (process_button(*buttonmask)); + } + } + return (process_button(*buttonmask)); + } + else /* can't chord - button already down */ + { + return (process_button(*buttonmask)); + } + } + +/************************************************************************** + * + * Check to see if the current data packet indicates more than one button + * is down. If so, it is either a valid chording combingation or an + * illegal chording combination. If valid, remember which buttons we + * need to ignore the first time they go up. If invalid, we won't do + * button chording. If only one button is down, we need more data. + */ + +static int check_combo ( + int buttonmask) + { + if ((buttonmask & BUTTON1_AND_3) == BUTTON1_AND_3) /* illegal combo */ + return (ILLEGAL_COMBO); + else if ((buttonmask & BUTTON1_AND_2) == BUTTON1_AND_2) + { + process_button(buttonmask); /* eat one button */ + process_button(buttonmask); /* eat the other button */ + hp7lc2m_chording_button = BUTTON4_UP; /* save for up transition */ + ignore1 = BUTTON1_UP; /* ignore each button up */ + ignore2 = BUTTON2_UP; + ignorecnt = 2; + return (BUTTON4_DOWN); /* send the chorded down */ + } + else if ((buttonmask & BUTTON2_AND_3) == BUTTON2_AND_3) + { + process_button(buttonmask); + process_button(buttonmask); + hp7lc2m_chording_button = BUTTON5_UP; + ignore2 = BUTTON2_UP; + ignore1 = BUTTON3_UP; + ignorecnt = 2; + return (BUTTON5_DOWN); + } + else + return (ONE_BUTTON_DOWN); /* only one button - need more data */ + } + +/************************************************************************** + * + * This routine is called by the X server to write to the mouse. + * It is called when an X request is made that causes a write to an + * input device. No requests are supported here. + * + * See the file x_serialdrv.h for the format of the data for each request. + * + */ + +static int +hp7lc2mwrite ( + int fd, int request, char *data) + { + int i; + HPPointerFeedbackControl *ctrl; + ps2_buffer_t mousebuf; + + switch (request) + { + case _XChangeFeedbackControl: + ctrl = (HPPointerFeedbackControl *) data; + + if (ctrl->class != PtrFeedbackClass) + return(WRITE_FAILURE); + break; + case _XSetDeviceValuators: + case _XChangeDeviceControl: + case _XSetDeviceMode: + default: + return(WRITE_FAILURE); + break; + } + return(WRITE_SUCCESS); + } + +/************************************************************************** + * + * This routine is called by the X server to close an input device. + * + */ + +static int +hp7lc2mclose ( + int fd) + { + close (fd); + return (CLOSE_SUCCESS); + } + +/************************************************************************** + * + * This routine is called to initialize the entry point vector for this + * serial input device driver. + * + */ + +int +hp7lc2m_Init( + SerialProcs *serialproc) + { + serialproc->configure = hp7lc2mconfigure;/* routine to init device */ + serialproc->read = hp7lc2mread; /* routine to read from dev */ + serialproc->write = hp7lc2mwrite; /* routine to write to dev */ + serialproc->close = hp7lc2mclose; /* routine to close device */ + return INIT_SUCCESS; /* indicate success */ + } + +#ifdef DEBUG +char expected_button1[]= { +0,1,0,2,1,3,0,2,3,1,0,2,1,3,0,4,5,1,0,4,1,5,0,4,2,1,5,3, /* test case 1 */ +4,5,4,2,5,3,4,2,3,5,4,2,5,3,4,2,3,5,4,0,2,5,1,3, /* test case 2 */ +2,3,2,0,1,0,1,0,1,4,5,4,5,3,0,4,1,5, /* test case 3 */ +0,4,1,5,0,4,1,5,2,3,0,4,1,5, /* test case 4 */ +0,2,1,3,0,2,1,3,4,5, /* test case 5 */ +4,2,5,3,4,2,5,3, /* test case 6 */ +0,4,2,1,5,3,0,4,2,5,1,4,3,0,2,5,1,4,3,0,2,1,5,3,0,4,1,5, /* test case 7 */ +2,3,0,1,4,2,5,3,0,1,4,2,5,3, + +0,2,3,1,4,2,3,5,0,4,5,1,0,4,2,3,5,1,0,2,1,3,4,2,5,3,0,4, /* miscellaneous */ +2,1,5,3,0,2,1,4,3,0,1,5,2,3,4,2,0,1,0,1,0,1,5,3,0,1,4,2, +5,3,0,1,4,2,5,3,2,3,0,4,1,5,4,5,0,2,1,3,4,5,0,1,2,3}; + +char expected_button2[]= { +0,1,6,7,6,7,6,7,0,4,5,1,0,4,1,5,0,4,2,1,5,3, /* test case 1 */ +4,5,8,9,8,9,8,9,8,9,4,0,2,5,1,3, /* test case 2 */ +2,3,6,0,1,0,1,4,5,4,5,7,0,4,1,5, /* test case 3 */ +0,4,1,5,0,4,1,5,2,3,0,4,1,5, /* test case 4 */ +6,7,6,7,4,5, /* test case 5 */ +8,9,8,9, /* test case 6 */ +0,4,2,1,5,3,0,4,2,5,1,4,3,0,2,5,1,4,3,0,2,1,5,3,0,4,1,5, /* test case 7 */ +2,3,0,1,8,9,0,1,8,9, + +6,7,8,9,0,4,5,1,0,4,2,3,5,1,6,7,8,9,0,4,2,1,5,3,6,4,7,0,/* miscellaneous */ +1,5,2,3,8,0,1,0,1,0,1,9,0,1,8,9,0,1,8,9,2,3,0,4,1,5,4,5,6,7,4,5,0,1,2,3}; + +char testdata[][3] = { + /* Case 1: left button goes down */ + /* remains down */ + /* goes up */ + /* becomes chorded */ + /* becomes non-chordable */ +{0x08,1,1}, /* no buttons down */ +{0x08,1,1}, /* no buttons down */ +{0x09,1,1}, /* left button down 0 0 */ +{0x09,1,1}, /* left button down */ +{0x08,1,1}, /* no buttons down 1 1 */ + +{0x09,1,1}, /* left button down 0 */ +{0x09,1,1}, /* left button down */ +{0x0d,1,1}, /* left and center 2 6 */ +{0x0d,1,1}, /* left and center */ +{0x08,1,1}, /* no buttons down 1 */ + /* 3 7 */ +{0x09,1,1}, /* left button down 0 */ +{0x0d,1,1}, /* left and center 2 6 */ +{0x09,1,1}, /* left button down 3 */ +{0x08,1,1}, /* no buttons down 1 7 */ +{0x09,1,1}, /* left button down 0 */ +{0x0d,1,1}, /* left and center 2 6 */ +{0x0c,1,1}, /* center button down 1 */ +{0x08,1,1}, /* no buttons down 3 7 */ +{0x09,1,1}, /* left button down 0 */ +{0x0b,1,1}, /* left and right 4 0 */ + /* 4 */ +{0x09,1,1}, /* left button down 5 5 */ +{0x08,1,1}, /* no buttons down 1 1 */ +{0x09,1,1}, /* left button down 0 */ +{0x0b,1,1}, /* left and right 4 0 */ + /* 4 */ +{0x0a,1,1}, /* right button down 1 1 */ +{0x08,1,1}, /* no buttons down 5 5 */ +{0x09,1,1}, /* left button down 0 */ +{0x0f,1,1}, /* all buttons 4 0 */ + /* 2 4 */ + /* 2 */ +{0x0e,1,1}, /* right and center 1 1 */ +{0x08,1,1}, /* no buttons down 5 5 */ + /* 3 3 */ + + + /* Case 2: right button goes down */ + /* remains down */ + /* goes up */ + /* becomes chorded */ + /* becomes non-chordable */ +{0x08,1,1}, /* no buttons down */ +{0x08,1,1}, /* no buttons down */ +{0x0a,1,1}, /* right button down 4 4 */ +{0x0a,1,1}, /* right button down */ +{0x08,1,1}, /* no buttons down 5 5 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0e,1,1}, /* right and center 2 8 */ +{0x0e,1,1}, /* right and center */ +{0x08,1,1}, /* no buttons down 5 */ + /* 3 9 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0e,1,1}, /* right and center 2 8 */ +{0x0a,1,1}, /* right button down 3 */ +{0x08,1,1}, /* no buttons down 5 9 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0e,1,1}, /* right and center 2 8 */ +{0x0c,1,1}, /* center button down 5 */ +{0x08,1,1}, /* no buttons down 3 9 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0e,1,1}, /* right and center 2 8 */ +{0x0a,1,1}, /* right button down 3 */ +{0x08,1,1}, /* no buttons down 5 9 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0f,1,1}, /* all buttons 0 4 */ + /* 2 0 */ + /* 2 */ +{0x0d,1,1}, /* left and center 5 5 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 3 3 */ + + + /* Case 3: center button goes down */ + /* remains down */ + /* goes up */ + /* becomes chorded */ + /* becomes non-chordable */ +{0x0c,1,1}, /* center button down 2 2 */ +{0x0c,1,1}, /* center button down */ +{0x08,1,1}, /* no buttons down 3 3 */ +{0x0c,1,1}, /* center button down 2 */ +{0x0d,1,1}, /* left and center 0 6 */ +{0x0d,1,1}, /* left and center */ +{0x0c,1,1}, /* center button down 1 */ +{0x0d,1,1}, /* left and center 0 0 */ +{0x0c,1,1}, /* center button down 1 1 */ +{0x0d,1,1}, /* left and center 0 0 */ +{0x0e,1,1}, /* right and center 1 1 */ + /* 4 4 */ +{0x0c,1,1}, /* center button down 5 5 */ +{0x0e,1,1}, /* right and center 4 4 */ +{0x08,1,1}, /* no buttons down 5 5 */ + /* 3 3 */ +{0x0b,1,1}, /* left and right 4 4 */ + /* 0 0 */ +{0x08,1,1}, /* no buttons down 5 5 */ + /* 1 1 */ + + /* Case 4: left and right go down */ +{0x0b,1,1}, /* left and right 0 0 */ + /* 4 4 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 5 */ +{0x0b,1,1}, /* left and right 0 0 */ + /* 4 4 */ +{0x0c,1,1}, /* center button down 1 1 */ + /* 5 5 */ + /* 2 2 */ +{0x0b,1,1}, /* left and right 3 3 */ + /* 0 0 */ + /* 4 4 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 5 */ + + /* Case 5: left and center go down */ +{0x08,1,1}, /* no buttons down */ +{0x0d,1,1}, /* left and center 0 */ + /* 2 6 */ +{0x08,1,1}, /* no buttons down 1 7 */ + /* 3 */ +{0x0d,1,1}, /* left and center 0 6 */ + /* 2 */ +{0x0a,1,1}, /* right button down 1 7 */ + /* 3 4 */ + /* 4 */ +{0x08,1,1}, /* no buttons down 5 5 */ + + + + /* Case 6: right and center go down */ +{0x0e,1,1}, /* right and center 4 */ + /* 2 8 */ +{0x08,1,1}, /* no buttons down 5 9 */ + /* 3 */ +{0x0e,1,1}, /* right and center 4 8 */ + /* 2 */ +{0x08,1,1}, /* no buttons down 5 9 */ + /* 3 */ +{0x08,1,1}, /* no buttons down */ + + + /* Case 7: all buttons go down */ +{0x0f,1,1}, /* all buttons 0 0 */ + /* 4 4 */ + /* 2 2 */ +{0x0f,1,1}, /* all buttons */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 5 */ + /* 3 3 */ +{0x0f,1,1}, /* all buttons 0 0 */ + /* 4 4 */ + /* 2 2 */ +{0x0d,1,1}, /* left and center 5 5 */ +{0x0e,1,1}, /* right and center 1 1 */ + /* 4 4 */ +{0x0b,1,1}, /* left and right 3 3 */ + /* 0 0 */ +{0x0f,1,1}, /* all buttons 2 2 */ +{0x0d,1,1}, /* left and center 5 5 */ +{0x0e,1,1}, /* right and center 1 1 */ + /* 4 4 */ +{0x0b,1,1}, /* left and right 3 3 */ + /* 0 0 */ +{0x0f,1,1}, /* all buttons 2 2 */ +{0x0c,1,1}, /* center button down 1 1 */ + /* 5 5 */ +{0x0b,1,1}, /* left and right 3 3 */ + /* 0 0 */ + /* 4 4 */ +{0x0c,1,1}, /* center button down 1 1 */ + /* 5 5 */ + /* 2 2 */ +{0x08,1,1}, /* no buttons down 3 3 */ +{0x09,1,1}, /* left button down 0 */ +{0x0e,1,1}, /* right and center 1 0 */ + /* 4 1 */ + /* 2 8 */ +{0x09,1,1}, /* left button down 5 */ + /* 3 9 */ + /* 0 0 */ +{0x0e,1,1}, /* right and center 1 1 */ + /* 4 */ + /* 2 8 */ +{0x08,1,1}, /* no buttons down 5 */ + /* 3 9 */ + + + /* Case 8: miscellaneous tests */ +{0x09,1,1}, /* left button down 0 */ +{0x0d,1,1}, /* left and center 2 6 */ +{0x09,1,1}, /* left button down 3 */ +{0x08,1,1}, /* no buttons down 1 7 */ + +{0x0a,1,1}, /* right button down 4 */ +{0x0a,1,1}, /* right button down */ +{0x0e,1,1}, /* right and center 2 8 */ +{0x0a,1,1}, /* right button down 3 */ +{0x08,1,1}, /* no buttons down 5 9 */ + +{0x09,1,1}, /* left button down 0 0 */ +{0x0b,1,1}, /* left and right 4 4 */ +{0x09,1,1}, /* left button down 5 5 */ +{0x08,1,1}, /* no buttons down 1 1 */ + +{0x09,1,1}, /* left button down 0 0 */ +{0x0b,1,1}, /* left and right 4 4 */ +{0x0f,1,1}, /* all buttons 2 2 */ +{0x0b,1,1}, /* left and right 3 3 */ +{0x09,1,1}, /* left button down 5 5 */ +{0x08,1,1}, /* no buttons down 1 1 */ + +{0x09,1,1}, /* left button down 0 */ +{0x09,1,1}, /* left button down */ +{0x09,1,1}, /* left button down */ +{0x0d,1,1}, /* left and center 2 6 */ +{0x0d,1,1}, /* left and center */ +{0x08,1,1}, /* no buttons down 1 7 */ + /* 3 */ + +{0x0e,1,1}, /* right and center 4 8 */ + /* 2 */ +{0x08,1,1}, /* no buttons down 5 9 */ + /* 3 */ + +{0x0f,1,1}, /* all buttons 0 0 */ + /* 4 4 */ + /* 2 2 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 5 */ + /* 3 3 */ + +{0x0d,1,1}, /* left and center 0 */ + /* 2 6 */ +{0x0e,1,1}, /* right and center 1 */ + /* 4 4 */ +{0x0b,1,1}, /* left and right 3 7 */ + /* 0 0 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 5 */ +{0x0c,1,1}, /* center button down 2 2 */ +{0x08,1,1}, /* no buttons down 3 3 */ + +{0x0e,1,1}, /* right and center 4 8 */ + /* 2 */ +{0x0f,1,1}, /* all buttons 0 0 */ +{0x0e,1,1}, /* right and center 1 1 */ +{0x0f,1,1}, /* all buttons 0 0 */ +{0x0e,1,1}, /* right and center 1 1 */ +{0x0f,1,1}, /* all buttons 0 0 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 9 */ + /* 3 */ + +{0x09,1,1}, /* left button down 0 0 */ +{0x0e,1,1}, /* center, right down 1 1 */ + /* 4 8 */ + /* 2 */ +{0x09,1,1}, /* left button down 5 9 */ + /* 3 0 */ + /* 0 */ +{0x0e,1,1}, /* center, right down 1 1 */ + /* 4 8 */ + /* 2 */ +{0x08,1,1}, /* no buttons down 5 9 */ + /* 3 */ + +{0x0c,1,1}, /* center button down 2 2 */ +{0x0b,1,1}, /* left and right 3 0 */ + /* 0 4 */ + /* 4 3 */ +{0x08,1,1}, /* no buttons down 1 1 */ + /* 5 5 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0d,1,1}, /* left and center 5 6 */ + /* 0 */ + /* 2 */ +{0x08,1,1}, /* no buttons down 1 7 */ + /* 3 */ +{0x0a,1,1}, /* right button down 4 */ +{0x0a,1,1}, /* right button down */ +{0x0a,1,1}, /* right button down */ +{0x0a,1,1}, /* right button down 4 */ +{0x0a,1,1}, /* right button down */ +{0x08,1,1}, /* no buttons down 5 5 */ +{0x09,1,1}, /* left button down 0 */ +{0x09,1,1}, /* left button down */ +{0x09,1,1}, /* left button down */ +{0x09,1,1}, /* left button down 0 */ +{0x09,1,1}, /* left button down */ +{0x08,1,1}, /* no buttons down 1 1 */ +{0x0c,1,1}, /* center button down 2 */ +{0x0c,1,1}, /* center button down */ +{0x0c,1,1}, /* center button down */ +{0x0c,1,1}, /* center button down 2 */ +{0x0c,1,1}, /* center button down */ +{0x08,1,1}, /* no buttons down 3 3 */ + +{0x00,1,1}}; /* terminate data */ + +main () + { + int fd; + + makedata(); /* make the test data */ + fd = open ("data", O_RDWR); + printf("Test case 1: no button chording\n"); + process_test_data(fd, expected_button1); + close(fd); + fd = open ("data", O_RDWR); + hp7lc2m_chording_interval = 100; + printf("Test case 2: button chording enabled\n"); + process_test_data(fd, expected_button2); + close(fd); + } + +process_test_data (fd, expected) + int fd; + char *expected; + { + int pending=0, ndx=0; + unsigned char buf[128], data_type=0; + + buf[2] = 0; + while (hp7lc2mread (fd, buf, &data_type, &pending) == READ_SUCCESS) + { + if (data_type & MOTION_DATA) + ndx = 2; + if (data_type & BUTTON_DATA) + { + if (buf[ndx] != *expected) + printf ("Expected button %d received %d.\n", + *expected,buf[ndx]); + expected++; + } + data_type = 0; + buf[2]=0; + pending=0; + ndx = 0; + }; + } + +/* The PS2 mouse returns PKT_SIZ bytes for each movement of the mouse or + * button press or release. The format of the bytes is as follows: + * + * Byte 0: + * Bit 7 Y data overflow (1 = overflow) + * Bit 6 X data overflow (1 = overflow) + * Bit 5 Y data sign (1 = negative) + * Bit 4 X data sign (1 = negative) + * Bit 3 Not used (always 1) + * Bit 2 Center button (1 = depressed) + * Bit 1 Right button (1 = depressed) + * Bit 0 Left button (1 = depressed) + * Byte 1: + * X coordinate data byte (2's compliment) + * Byte 2: + * Y coordinate data byte (2's compliment) + */ + +makedata () + { + int i, fd; + + fd = creat("data", 0777); + while (testdata[i][0] != 0) + write (fd, testdata[i++], 3); + close(fd); + } +#endif /* DEBUG */ diff --git a/xc/programs/Xserver/hw/hp/input/drivers/ps2io.h b/xc/programs/Xserver/hw/hp/input/drivers/ps2io.h new file mode 100644 index 000000000..afbd2d2b7 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/drivers/ps2io.h @@ -0,0 +1,113 @@ +/* $TOG: ps2io.h /main/3 1997/09/08 13:19:15 kaleb $ */ + +#ifndef _SYS_PS2IO_INCLUDED /* allows multiple inclusion */ +#define _SYS_PS2IO_INCLUDED + +#ifndef _SYS_STDSYMS_INCLUDED +#ifdef _KERNEL_BUILD +# include "../h/stdsyms.h" +#else /* ! _KERNEL_BUILD */ +# include <sys/stdsyms.h> +#endif /* _KERNEL_BUILD */ +#endif /* _SYS_STDSYMS_INCLUDED */ + +#ifdef _KERNEL_BUILD +# include "../h/ioctl.h" +#else /* ! _KERNEL_BUILD */ +# include <sys/ioctl.h> +#endif /* _KERNEL_BUILD */ + +struct ps2_4 { + unsigned char b[4]; +}; + +/* + * Device ioctl() command defines + */ + +#define PS2_INDICATORS _IOW('P', 0x01, struct ps2_4) +#define PS2_IDENT _IOR('P', 0x02, struct ps2_4) +#define PS2_SCANCODE _IOWR('P', 0x03, struct ps2_4) +#define PS2_ENABLE _IO('P', 0x04) +#define PS2_DISABLE _IO('P', 0x05) +#define PS2_STREAMMODE _IO('P', 0x06) +#define PS2_SAMPLERATE _IOW('P', 0x07, struct ps2_4) +#define PS2_RESET _IOR('P', 0x08, struct ps2_4) +#define PS2_RESOLUTION _IOW('P', 0x09, struct ps2_4) +#define PS2_ALL_TMAT _IO('P', 0x0A) +#define PS2_ALL_MKBRK _IO('P', 0x0B) +#define PS2_ALL_TMAT_MKBRK _IO('P', 0x0C) +#define PS2_ALL_MK _IO('P', 0x0D) +#define PS2_KEY_MKBRK _IOW('P', 0x0E, struct ps2_4) +#define PS2_KEY_MAKE _IOW('P', 0x0F, struct ps2_4) +#define PS2_KEY_TMAT _IOW('P', 0x10, struct ps2_4) +#define PS2_RATEDELAY _IOW('P', 0x11, struct ps2_4) + +#define PS2_PORTSTAT _IOR('P', 0x12, struct ps2_4) +#define PS2_TEST _IOW('P', 0x13, char) +#define PS2_SETDEFAULT _IO('P', 0x14) +#define PS2_PROMPTMODE _IO('P', 0x15) +#define PS2_REPORT _IOR('P', 0x16, struct ps2_4) +#define PS2_STATUS _IOR('P', 0x17, struct ps2_4) +#define PS2_2TO1_SCALING _IO('P', 0x18) +#define PS2_1TO1_SCALING _IO('P', 0x19) + +#define PS2FAKE _IOW('P',0x0F,char) /* fake a character */ + +/* +#define _IOR('P',0x ,) + */ + +/* Values for PS2_PORTSTAT first return byte */ + +#define PS2_NONE 0 +#define PS2_MOUSE 1 +#define PS2_KEYBD 2 +#define PS2_UNKNOWN 3 + +/* Bit mask values for ps2 devices */ + +#define PS2_NONE_BIT 0x0001 +#define PS2_MOUSE_BIT 0x0002 +#define PS2_KEYBD_BIT 0x0004 +#define PS2_UNKNOWN_BIT 0x0008 + +/* Bit mask values for PS2_PORTSTAT second return byte */ + +#define INTERFACE_HAS_ITE 0x01 +#define PORT_HAS_FIRST_KEYBD 0x02 +#define PORT_HAS_FIRST_MOUSE 0x04 + +/* values for PS2_SCANCODE */ + +#define GET_SCANCODE 0x00 +#define SCANCODE_1 0x01 +#define SCANCODE_2 0x02 +#define SCANCODE_3 0x03 + +/* values for PS2_SAMPLERATE */ + +#define SAMPLE_10 0x0A +#define SAMPLE_20 0x14 +#define SAMPLE_40 0x28 +#define SAMPLE_60 0x3C +#define SAMPLE_80 0x50 +#define SAMPLE_100 0x64 +#define SAMPLE_200 0xC8 + +/* values for PS2_INDICATORS */ + +#define CAPS_LED 0x01 +#define NUM_LED 0x02 +#define SCROLL_LED 0x04 + +/* values for PS2_RESOLUTION */ +/* (RES_3 is te default) Resolution in counts/mm */ + /* 200 DPI 320 DPI */ + /*--------- ------- */ +#define RES_1 0x00 /* 1 1 */ +#define RES_2 0x01 /* 2 3 */ +#define RES_3 0x02 /* 4 6 */ +#define RES_4 0x03 /* 8 12 */ + +#endif /* _SYS_PS2IO_INCLUDED */ diff --git a/xc/programs/Xserver/hw/hp/input/get_tv.c b/xc/programs/Xserver/hw/hp/input/get_tv.c new file mode 100644 index 000000000..8cc49e97f --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/get_tv.c @@ -0,0 +1,199 @@ +/* $XConsortium: get_tv.c,v 1.1 93/08/08 12:58:41 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. + +*/ + +/* + * An alternative to gettimeofday(2) that is about 50 times faster + * if used frequently. HP-PA specific. + * Dave Holt, GSY Performance, dah@cup.hp.com + */ + +#include <time.h> +#include <assert.h> + +#ifdef NOTDEFINED /* The following is not currently used. But + * I will leave it for possible future use. + * --kam 4/22/92 + */ + +#ifdef DEBUG +#include <stdio.h> +#else /* Not DEBUG. Don't bother with printf's. */ +#define printf(s, a) +#endif /* DEBUG */ + +#define MILLION 1000000 +#define BUNCH 8192 /* must be < 32767 */ + +unsigned int cr16(); /* in cr16.s (assembly code) */ +static struct timeval slow_get_tv(); +void *malloc(); +static set_tix2usec(); + +/* This initial value for last_tv forces initialization of tix2usec[]. */ +static struct timeval last_tv = {0, 2000000}; +static unsigned int last_tix; + +/* + * tix2usec[BUNCH] is a table built by set_tix2usec() which converts + * from CR16 ticks to microseconds: + * microseconds = tix2usec[ticks >> shift] + */ +static unsigned short *tix2usec; +static int shift; + +struct timeval get_tv() /* the fast path */ +{ + unsigned int tix, delta_tix; + long delta_usec; + + tix = cr16(); + delta_tix = tix - last_tix; + last_tix = tix; + if (delta_tix < BUNCH) { /* we can use the array */ + delta_usec = tix2usec[delta_tix >> shift]; + last_tv.tv_usec += delta_usec; + if (last_tv.tv_usec < MILLION) { + return(last_tv); + } + } + return(slow_get_tv()); +} + +static struct timeval slow_get_tv() /* the slow path */ +{ + struct timezone tz; + static int first_time = 1; + + if (first_time) { + set_tix2usec(); + first_time = 0; + } + last_tix = cr16(); + gettimeofday(&last_tv, &tz); + return(last_tv); +} + +/* + * set_tix2usec() builds it by observing gettimeofday and CR16 over a + * reasonable period (~50ms). + */ +static set_tix2usec() +{ + struct timeval tv1, tv2; + struct timezone tz; + int i, tix_per_entry, delta_us; + unsigned int tix1, tix2, cr16(), delta_tix; + double tix_per_usec, usec_per_tix; + + /* make sure the code is in memory before we time it */ + tix1 = cr16(); + gettimeofday(&tv1, &tz); + + do { + tix1 = cr16(); + gettimeofday(&tv1, &tz); + do { + tix2 = cr16(); + gettimeofday(&tv2, &tz); + delta_us = (tv2.tv_sec - tv1.tv_sec) * MILLION + + (tv2.tv_usec - tv1.tv_usec); + delta_tix = tix2 - tix1; + } while (delta_us < 50000); /* loop for at least 50ms */ + } while (tv2.tv_sec - tv1.tv_sec > 2); /* retry if delta is too big */ + + tix_per_usec = 1.0 * delta_tix / delta_us; + usec_per_tix = 1 / tix_per_usec; + + /* Table should convert at least 10ms deltas. */ + tix_per_entry = tix_per_usec * 10000 / BUNCH; + for (shift = 0; + (1 << shift) < tix_per_entry; + shift++) { + } + + tix2usec = (unsigned short *) malloc(BUNCH * sizeof(unsigned short)); + assert(tix2usec != NULL); + + for (i = 0; i < BUNCH; i++) { + tix2usec[i] = i * (1 << shift) * usec_per_tix; + } + + printf("tix_per_usec = %lf\n", tix_per_usec); + printf("shift = %d\n", shift); +} + +#endif /* NOTDEFINED */ + + +void +calibrate_cr16(TicksPerMilli) + +unsigned long *TicksPerMilli; + +{ + + struct timeval start, end; + register unsigned long cr_start, cr_end; + unsigned long total_ticks = 0, total_millis = 0; + int i, j; + + for(i = 0; i < 6; i++) + { + cr_start = cr16(); + gettimeofday(&start, NULL); + + /* waste some time */ + for(j=0; j< 200000; j++) + ; + cr_end = cr16(); + gettimeofday(&end, NULL); + + if(start.tv_usec > end.tv_usec) + { + end.tv_usec += 1000000; + end.tv_sec--; + } + + /* if we have a rollover during all of this, toss this one. */ + + if(cr_end < cr_start) + { + i--; + } + else + { + total_millis += (end.tv_sec - start.tv_sec) * 1000 + + (end.tv_usec - start.tv_usec) / 1000; + total_ticks += cr_end - cr_start; + } + } + + *TicksPerMilli = total_ticks/total_millis; + +} diff --git a/xc/programs/Xserver/hw/hp/input/getkeysym.c b/xc/programs/Xserver/hw/hp/input/getkeysym.c new file mode 100644 index 000000000..69a11bfe7 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/getkeysym.c @@ -0,0 +1,428 @@ +/* $XConsortium: getkeysym.c,v 1.7 95/01/24 02:45:23 dpw 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. + +*/ + +#ifndef LIBDIR +#if OSMAJORVERSION >= 10 +#define LIBDIR "/etc/X11" +#else +#define LIBDIR "/usr/lib/X11" +#endif +#endif + +#include <stdio.h> +#include <X11/XHPlib.h> + +/*#include <X11/keysym.h>*/ /* gets sucked in by XHPlib.h */ + +#define SUCCESS 0 + +extern char *malloc(); + +static FILE *keysym_file = NULL; +static int num_headers = 0; +static struct XHP_keymap_header *header_data = NULL; +static int read_kd_name_table(); +static int read_modmap_table(); + +#if 0 /* Not used any more */ + +/* GetKeySyms() gets a key sym table from a file. + * This routine was copied and modified from XHPSetKeyboardMapping() in + * lib/Xhp/XHPSetKbd.c. + + * The routine accepts two arguments: a keyboard id (specifying which + * keymap is to be loaded) and a pointer to a keysym array to be filled in. + * If the keyboard id is in the file, that keysym table is copied into the + * keysym array. Otherwise, an error is returned and nothing is copied. + + * The routine returns zero if it succeeds. Otherwise, it returns a + * non-zero value specifying the type of error that occurred. The + * keyboard ID value (-2) is a special value used to specify a non-HP + * keyboard. The keyboard ID value (-1) is used to identify HP keyboards + * that are not supported by X (i.e. Arabic, Hebrew, Turkish, ...). + + * The first time it is called, the routine opens the file + * "/usr/lib/X11/Xkeymaps", reading a header of the keysym tables it + * contains. The header contains a magic value for identification, and + * the ID, size, and offset of each keysym table in the file. + */ + +Status GetKeySyms(kbd_id, keysyms) + KEYBOARD_ID kbd_id; + KeySym *keysyms; +{ + char magic[MAGIC_SIZE]; + int header_size; + int index; + int n, return_code = SUCCESS; + char *name; + char filename[512]; + + /* If this is the first time this routine has been called, then open + * the keysym file, read the header, and verify the magic and read in + * the keysym table. + */ + + /* get the correct keymapfile name -- use environment variable if it is + * set else use default. If name starts with '/' it describes full path + * name, else it is relative to the default directory. + */ + + if ( ( name = (char *)getenv("XHPKEYMAPFILE") ) == NULL ) + name = DEF_FILENAME; + + if (name[0] != '/') + { + sprintf(filename, "%s/%s",LIBDIR,name); + } + else + strcpy(filename, name); + + if ((keysym_file = fopen(filename,"r")) == NULL) + return(XHPKB_NOKEYFILE); + + /* Read and verify the magic number */ + + fread(magic,MAGIC_SIZE,1,keysym_file); + if ((strcmp(magic,VERIFY_MAGIC)) != 0) + { return_code = XHPKB_BADMAGIC; goto done; } + + /* Next read in the header size - it is in the next 4 bytes. + * Then read in the header table, which is found in the next + * header-size bytes of the file. + */ + + fread(&header_size,4,1,keysym_file); + if (!(header_data = (struct XHP_keymap_header *)malloc(header_size))) + { return_code = XHPKB_NOMEM; goto done; } + fread(header_data,header_size,1,keysym_file); + + num_headers = header_size / sizeof(struct XHP_keymap_header); + + /* Verify that a valid keyboard ID has been passed in. While you're + * at it, position the header_data pointer to the correct record. + */ + + for (index = 0; index < num_headers; index++) + { + if (kbd_id == header_data[index].kbd) + break; + } + + if (index >= num_headers) /* It's an illegal keyboard ID */ + { return_code = XHPKB_BADKBID; goto done; } + + /* Copy the keysym table from the file into the keysyms array */ + + fseek(keysym_file, header_data[index].offset, 0); + fread((char *)keysyms, header_data[index].size, 1, keysym_file); + +done: + free((char *)header_data); + fclose(keysym_file); + return(return_code); +} +#endif + + + /* This next stuff supersedes the above stuff. It provides support for + * keydevice names and modmap names. + * Most of this code was taken from lib/Xhp/tools/cdkeymap.c (probably + * not called that anymore). + */ + +static char *kd_name_heap = NULL, *modmap_name_heap = NULL; +static int kd_names = 0, num_modmaps = 0, + num_keydevice_names = 0; +static HPKKeyDeviceInfo *keydevice_name_table = NULL; +static HPKModMap *modmap_table = NULL; + + + /* + * input: + * file_name: If not NULL, try and open "/usr/lib/X11/<file_name>". + * Notes: + * Sequence: + * if (!HPKsetup()) error_occured + * piddle with keymaps (other routines in here) + * HPKclean_up(); + * You MUST call HPKclean_up() after calling HPKsetup() (no matter + * what HPKclean_up() returns). It resets state variables. + */ +int HPKsetup(file_name) char *file_name; +{ + char magic[MAGIC_SIZE]; + int header_size; + char *name; + char filename[512]; + + /* If this is the first time this routine has been called, then open + * the keysym file, read the header, and verify the magic and read in + * the keysym table. + */ + + /* get the correct keymapfile name -- use environment variable if it is + * set else use default. If name starts with '/' it describes full path + * name, else it is relative to the default directory. + */ + if (file_name) name = file_name; + else + if (NULL == (name = (char *)getenv("XHPKEYMAPFILE"))) + name = DEF_FILENAME; + + if (name[0] != '/') + { + sprintf(filename, "%s/%s",LIBDIR,name); + } + else strcpy(filename, name); + + if (NULL == (keysym_file = fopen(filename,"r"))) + return False; + + /* Read and verify the magic number */ + + fread(magic,MAGIC_SIZE,1,keysym_file); + if ((strcmp(magic,VERIFY_MAGIC)) != 0) return False; + + /* Next read in the header size - it is in the next 4 bytes. + * Then read in the header table, which is found in the next + * header-size bytes of the file. + */ + + fread(&header_size,4,1,keysym_file); + if (!(header_data = (struct XHP_keymap_header *)malloc(header_size))) + return False; + fread(header_data,header_size,1,keysym_file); + + num_headers = header_size / sizeof(struct XHP_keymap_header); + + read_kd_name_table(); + read_modmap_table(); + + return True; +} + + +/* ******************************************************************** */ +/* ************************* Lookup Routines ************************** */ +/* ******************************************************************** */ + + + /* Returns: + * NULL : id not found + * ptr : pointer into the header table + */ +static struct XHP_keymap_header *HPKlookup_kd_id(kd_id) +{ + int n; + struct XHP_keymap_header *ptr; + + for (n = num_headers, ptr = header_data; n--; ptr++) + if (kd_id == ptr->kbd) return ptr; + + return NULL; +} + + /* Returns: + * NULL : id not found + * ptr : pointer into name table + */ +HPKKeyDeviceInfo *HPKlookup_kd_by_id(kd_id) +{ + int n; + HPKKeyDeviceInfo *ptr; + + for (n = num_keydevice_names, ptr = keydevice_name_table; n--; ptr++) + if (kd_id == ptr->keydevice_id) return ptr; + + return NULL; +} + + /* Returns: + * NULL : modmap not found + * ptr : pointer into name table + */ +HPKModMap *HPKlookup_modmap(modmap_name) char *modmap_name; +{ + int n; + HPKModMap *ptr; + + for (n = num_modmaps, ptr = modmap_table; n--; ptr++) + if (0 == strcmp(modmap_name, ptr->modmap_name)) return ptr; + + return NULL; +} + + /* Returns: + * NULL : id not found + * ptr : pointer into name table + */ +HPKKeyDeviceInfo *HPKlookup_kd_by_name(kd_name) char *kd_name; +{ + int n; + HPKKeyDeviceInfo *ptr; + + for (n = num_keydevice_names, ptr = keydevice_name_table; n--; ptr++) + if (0 == strcmp(kd_name, ptr->name)) return ptr; + + return NULL; +} + + +/* ******************************************************************** */ +/* *************************** Read Tables **************************** */ +/* ******************************************************************** */ + +static int read_kd_name_table() +{ + int a,b,c,d,e,f, n, z, kd_id; + HPKKeyDeviceInfo *kptr; + struct XHP_keymap_header *ptr; + + if (!(ptr = HPKlookup_kd_id(HPK_KEYDEVICE_NAME_TABLE_ID))) return False; + + fseek(keysym_file, ptr->offset, 0); + + fread((char *)&num_keydevice_names, sizeof(int), 1, keysym_file); + n = num_keydevice_names; + + fread((char *)&z, sizeof(int), 1, keysym_file); /* size of names table */ + + if (!(kd_name_heap = malloc(z)) || + !(keydevice_name_table = + (HPKKeyDeviceInfo *)malloc(n*sizeof(HPKKeyDeviceInfo)))) + { + num_keydevice_names = 0; + return False; + } + + fread(kd_name_heap, z, 1, keysym_file); /* read the names */ + + for (kptr = keydevice_name_table; n--; kptr++) /* read the name table */ + { + fread((char *)&a, sizeof(int), 1, keysym_file); /* kd name offset */ + fread((char *)&b, sizeof(int), 1, keysym_file); /* key device id */ + fread((char *)&c, sizeof(int), 1, keysym_file); /* modmap name offset */ + fread((char *)&d, sizeof(int), 1, keysym_file); /* min keycode */ + fread((char *)&e, sizeof(int), 1, keysym_file); /* max keycode */ + fread((char *)&f, sizeof(int), 1, keysym_file); /* columns */ + + kptr->name = kd_name_heap + a; + kptr->keydevice_id = b; + kptr->modmap_name = kd_name_heap + c; + kptr->min_keycode = d; + kptr->max_keycode = e; + kptr->columns = f; + } + + return True; +} + +static int read_modmap_table() +{ + int n, a, z; + HPKModMap *mptr; + struct XHP_keymap_header *ptr; + + if (!(ptr = HPKlookup_kd_id(HPK_MODMAP_TABLE_ID))) return False; + + fseek(keysym_file, ptr->offset, 0); + fread((char *)&num_modmaps, sizeof(int), 1, keysym_file); + + fread((char *)&z, sizeof(int), 1, keysym_file); /* name table size */ + + if (!(modmap_name_heap = malloc(z)) || + !(modmap_table = (HPKModMap *)malloc(num_modmaps*sizeof(HPKModMap)))) + + { + num_modmaps = 0; + return False; + } + + fread(modmap_name_heap, z,1, keysym_file); /* read the name table */ + + n = num_modmaps; + for (mptr = modmap_table; n--; mptr++) /* read & build the table */ + { + fread((char *)&a, sizeof(int), 1, keysym_file); /* modmap name offset */ + fread((char *)mptr->modmap, MODMAP_SIZE,1, keysym_file); /* modmap */ + + mptr->modmap_name = modmap_name_heap + a; + } + + return True; +} + + + /* Read a keytable. + * Input: + * kd_id: id of the keytable to read. + * keysyms: pointer to an area big enough to hold the keytable. + * Returns: + * TRUE: everything went as expected. + * FALSE: couldn't find id. + */ +int HPKread_keymap(kd_id, keysyms) KeySym *keysyms; +{ + struct XHP_keymap_header *ptr; + + if (!(ptr = HPKlookup_kd_id(kd_id))) return False; + + fseek(keysym_file, ptr->offset, 0); + + fread((char *)keysyms, ptr->size, 1, keysym_file); + + return True; +} + + +/* ******************************************************************** */ +/* ***************************** Clean Up ***************************** */ +/* ******************************************************************** */ + +void HPKclean_up() +{ + if (keysym_file) fclose(keysym_file); + keysym_file = NULL; + + if (header_data) free((char *)header_data); + header_data = NULL; + + if (kd_name_heap) free((char *)kd_name_heap); + kd_name_heap = NULL; + if (keydevice_name_table) free((char *)keydevice_name_table); + keydevice_name_table = NULL; + + if (modmap_name_heap) free((char *)modmap_name_heap); + modmap_name_heap = NULL; + if (modmap_table) free((char *)modmap_table); + modmap_table = NULL; + + + num_headers = kd_names = num_modmaps = num_keydevice_names = 0; +} diff --git a/xc/programs/Xserver/hw/hp/input/hildef.h b/xc/programs/Xserver/hw/hp/input/hildef.h new file mode 100644 index 000000000..bd0aa4e38 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/hildef.h @@ -0,0 +1,228 @@ +#ifndef HILDEF_H +#define HILDEF_H +/* $TOG: hildef.h /main/5 1998/02/10 13:10:59 kaleb $ */ +/* + +Copyright 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ +/* +** File: hildefs.h +** +** defines for hil devices to the X environment. +** +*/ + +#include "x_serialdrv.h" +#include "sys/param.h" +#include "X.h" +#include "scrnintstr.h" +#include "misc.h" +#include "dixstruct.h" + +/***************************************************************/ +/* 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 */ + +# define MAX_X_NAMELEN 64 +# define MAX_AXES 8 +# define ILLEGAL -1 +# define UP_MASK 1 << 0 +# define HIL_POLL_HDR_BITS 0xE3 +# define MOTION_MASK 0x0F +# define KEY_DATA_MASK 0x70 +# define SET1_KEY_MASK 1 << 6 +# define PROXIMITY_IN 0x8e +# define PROXIMITY_OUT 0x8f +# define BUTTON_BASE 0x80 +# define BUTTON_1_OFFSET 0x7e + + +#define VERTICAL 0 +#define HORIZONTAL 1 +#define MATRIX 2 + +#define NOWRAP 0 +#define WRAP 1 +#define DEFAULT 2 +#define SAMESCREEN 3 +#define CHANGE_BY_TWO 4 + +# define CHORDING_OFF 0 +# define CHORDING_ON 1 +# define CHORDING_DEFAULT 2 + +# define LATCHING_OFF 0 +# define LATCHING_ON 1 + +# define SCREEN_CHANGE_DEFAULT 255 + +# define IS_SERIAL_DEVICE 0x40 +# define OPEN_THIS_DEVICE 0x20 +# define SECOND_LOGICAL_DEVICE 0x10 +# define MERGED_DEVICE 0x08 + +# define DATA_SIZE_BITS 0x07 + +#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 HILPRH_KEYSET 0x60 /* Keycode set bits */ +#define HILPRH_KEYSET1 0x40 /* Keycode set 1 data */ + +#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 { + DeviceClientsPtr next; + ClientPtr client; /* which client wants this device */ + XID resource; /* id for putting into resource manager */ + int mode; + int count; /* # of open requests for this client */ +} 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 */ + int change_xmax; + int change_ymax; + int change_ymin; + int change_xmin; + short change_amt; + short id_detail; + u_char dev_type; /* HIL device type */ + u_char sent_button; /* flag for button sent */ + 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; + unsigned char poll_hdr; + unsigned char dev_data[36]; + HPInputDevice *hil_dev; +}; + +#endif diff --git a/xc/programs/Xserver/hw/hp/input/hpKeyMap.c b/xc/programs/Xserver/hw/hp/input/hpKeyMap.c new file mode 100644 index 000000000..60e47b63a --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/hpKeyMap.c @@ -0,0 +1,869 @@ +/* $TOG: hpKeyMap.c /main/5 1998/02/10 13:11:10 kaleb $ */ +/* + +Copyright 1986, 1987, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ + +#include "Xmd.h" +#define XK_KATAKANA +#include "keysym.h" +#include "X.h" /* MUST come after above includes */ +#include "input.h" +#include "HPkeysym.h" +#include "ap_keysym.h" + +#include <XHPlib.h> /* for keymap ids */ + +#define MIN_KEYCODE 8 +/* This file was composed from the X10 hil_keymap.h by + * 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 + * reconized family. + * Notes: + * I know NoSymbol is 0 and won't ever change so I can sleeze and let + * the compiler initialize the table. + */ +static KeySym null_keymap[1 * 0x80]; + + +#if defined(__hpux) || defined(__hp_osf) +static KeySym USASCIIMap[4*0x82] = { + /* code values in comments at line end are actual value reported on HIL. + REMEMBER, there is an offset of MIN_KEYCODE+2 applied to this table! + The PS2 keyboard table begins at offset 0, the 46021A table begins with + the third row. */ + /* Extend Char Right -- a.k.a. Kanji? */ + XK_Control_R, NoSymbol, NoSymbol, NoSymbol, /* 0x00 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x01 */ + XK_Meta_R, NoSymbol, NoSymbol, NoSymbol, /* 0x02 */ + XK_Meta_L, NoSymbol, NoSymbol, NoSymbol, /* 0x03 */ + XK_Shift_R, NoSymbol, NoSymbol, NoSymbol, /* 0x4 */ + XK_Shift_L, NoSymbol, NoSymbol, NoSymbol, /* 0x5 */ + XK_Control_L, NoSymbol, NoSymbol, NoSymbol, /* 0x6 */ + XK_Break, XK_Reset, NoSymbol, NoSymbol, /* 0x7 */ + XK_KP_4, NoSymbol, NoSymbol, NoSymbol, /* 0x8 */ + XK_KP_8, NoSymbol, NoSymbol, NoSymbol, /* 0x9 */ + XK_KP_5, NoSymbol, NoSymbol, NoSymbol, /* 0xa */ + XK_KP_9, NoSymbol, NoSymbol, NoSymbol, /* 0xb */ + XK_KP_6, NoSymbol, NoSymbol, NoSymbol, /* 0xc */ + XK_KP_7, NoSymbol, NoSymbol, NoSymbol, /* 0xd */ + XK_KP_Separator, NoSymbol, NoSymbol, NoSymbol, /* 0xe */ + XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol, /* 0xf */ + XK_KP_1, NoSymbol, NoSymbol, NoSymbol, /* 0x10 */ + XK_KP_Divide, NoSymbol, NoSymbol, NoSymbol, /* 0x11 */ + XK_KP_2, NoSymbol, NoSymbol, NoSymbol, /* 0x12 */ + XK_KP_Add, NoSymbol, NoSymbol, NoSymbol, /* 0x13 */ + XK_KP_3, NoSymbol, NoSymbol, NoSymbol, /* 0x14 */ + XK_KP_Multiply, NoSymbol, NoSymbol, NoSymbol, /* 0x15 */ + XK_KP_0, NoSymbol, NoSymbol, NoSymbol, /* 0x16 */ + XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol, /* 0x17 */ + XK_B, NoSymbol, XK_block, NoSymbol, /* 0x18 */ + XK_V, NoSymbol, XK_section, NoSymbol, /* 0x19 */ + XK_C, NoSymbol, XK_ccedilla, XK_Ccedilla, /* 0x1a */ + XK_X, NoSymbol, XK_scaron, XK_Scaron, /* 0x1b */ + XK_Z, NoSymbol, XK_paragraph, NoSymbol, /* 0x1c */ +/* Was Kanji Left.... */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x1d */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x1e */ + XK_Escape, XK_Delete, NoSymbol, NoSymbol, /* 0x1f */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x20 */ + XK_F10, XK_KP_F2, NoSymbol, NoSymbol, /* 0x21 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x22 */ + XK_F11, XK_KP_F3, NoSymbol, NoSymbol, /* 0x23 */ + XK_KP_Decimal, NoSymbol, NoSymbol, NoSymbol, /* 0x24 */ + XK_F9, XK_KP_F1, NoSymbol, NoSymbol, /* 0x25 */ + XK_KP_Tab, XK_KP_BackTab, NoSymbol, NoSymbol, /* 0x26 */ + XK_F12, XK_KP_F4, NoSymbol, NoSymbol, /* 0x27 */ + XK_H, NoSymbol, XK_yen, NoSymbol, /* 0x28 */ + XK_G, NoSymbol, XK_currency, NoSymbol, /* 0x29 */ + XK_F, NoSymbol, XK_guilder, NoSymbol, /* 0x2a */ + XK_D, NoSymbol, XK_eth, XK_Eth, /* 0x2b */ + XK_S, NoSymbol, XK_ssharp, NoSymbol, /* 0x2c */ + XK_A, NoSymbol, XK_aring, XK_Aring, /* 0x2d */ + XK_Mode_switch, NoSymbol, NoSymbol, XK_Mode_switch, /* 0x2e */ + XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, /* 0x2f */ + XK_U, NoSymbol, XK_mute_diaeresis,NoSymbol, /* 0x30 */ + XK_Y, NoSymbol, XK_mute_asciicircum,NoSymbol, /* 0x31 */ + XK_T, NoSymbol, XK_mute_grave, NoSymbol, /* 0x32 */ + XK_R, NoSymbol, XK_mute_acute, NoSymbol, /* 0x33 */ + XK_E, NoSymbol, XK_ae, XK_AE, /* 0x34 */ + XK_W, NoSymbol, XK_asciitilde, NoSymbol, /* 0x35 */ + XK_Q, NoSymbol, XK_periodcentered, NoSymbol, /* 0x36 */ + XK_Tab, XK_BackTab, NoSymbol, NoSymbol, /* 0x37 */ + XK_7, XK_ampersand, XK_backslash, NoSymbol, /* 0x38 */ + XK_6, XK_asciicircum, XK_asciicircum, NoSymbol, /* 0x39 */ + XK_5, XK_percent, XK_onehalf, NoSymbol, /* 0x3a */ + XK_4, XK_dollar, XK_onequarter, XK_threequarters, /* 0x3b */ + XK_3, XK_numbersign, XK_numbersign, NoSymbol, /* 0x3c */ + XK_2, XK_at, XK_at, NoSymbol, /* 0x3d */ + XK_1, XK_exclam, XK_exclamdown, NoSymbol, /* 0x3e */ + XK_quoteleft, XK_asciitilde, XK_guillemotleft,XK_guillemotright,/* 0x3f */ +/* Was Mouse-L */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x40 */ +/* Was Mouse-M */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x41 */ +/* Was Mouse-R */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x42 */ +/* Was 4 button puck */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x43 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x44 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x45 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x46 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x47 */ + XK_Menu, NoSymbol, NoSymbol, NoSymbol, /* 0x48 */ + XK_F4, NoSymbol, NoSymbol, NoSymbol, /* 0x49 */ + XK_F3, NoSymbol, NoSymbol, NoSymbol, /* 0x4a */ + XK_F2, NoSymbol, NoSymbol, NoSymbol, /* 0x4b */ + XK_F1, NoSymbol, NoSymbol, NoSymbol, /* 0x4c */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x4d */ +/* Was 'Stop' */ + XK_Cancel, NoSymbol, NoSymbol, NoSymbol, /* 0x4e */ +/* Was 'Enter' */ + XK_Execute, XK_Print, NoSymbol, NoSymbol, /* 0x4f */ + XK_System, XK_User, NoSymbol, NoSymbol, /* 0x50 */ + XK_F5, NoSymbol, NoSymbol, NoSymbol, /* 0x51 */ + XK_F6, NoSymbol, NoSymbol, NoSymbol, /* 0x52 */ + XK_F7, NoSymbol, NoSymbol, NoSymbol, /* 0x53 */ + XK_F8, NoSymbol, NoSymbol, NoSymbol, /* 0x54 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x55 */ + XK_ClearLine, NoSymbol, NoSymbol, NoSymbol, /* 0x56 */ +/* Was 'Clear Display' */ + XK_Clear, NoSymbol, NoSymbol, NoSymbol, /* 0x57 */ + XK_8, XK_asterisk, XK_bracketleft, XK_braceleft, /* 0x58 */ + XK_9, XK_parenleft, XK_bracketright,XK_braceright, /* 0x59 */ + XK_0, XK_parenright, XK_questiondown,NoSymbol, /* 0x5a */ + XK_minus, XK_underscore, XK_longminus, XK_macron, /* 0x5b */ + XK_equal, XK_plus, XK_plusminus, NoSymbol, /* 0x5c */ + XK_BackSpace, NoSymbol, NoSymbol, NoSymbol, /* 0x5d */ + XK_InsertLine, NoSymbol, NoSymbol, NoSymbol, /* 0x5e */ + XK_DeleteLine, NoSymbol, NoSymbol, NoSymbol, /* 0x5f */ + + XK_I, NoSymbol, XK_mute_asciitilde,NoSymbol, /* 0x60 */ + XK_O, NoSymbol, XK_oslash, XK_Ooblique, /* 0x61 */ + XK_P, NoSymbol, XK_thorn, XK_Thorn, /* 0x62 */ + XK_bracketleft, XK_braceleft, XK_degree, NoSymbol, /* 0x63 */ + XK_bracketright, XK_braceright, XK_brokenbar, NoSymbol, /* 0x64 */ + XK_backslash, XK_bar, XK_mu, NoSymbol, /* 0x65 */ + + /* HP special might also be Insert */ + XK_InsertChar, NoSymbol, NoSymbol, NoSymbol, /* 0x66 */ + XK_DeleteChar, NoSymbol, NoSymbol, NoSymbol, /* 0x67 */ + XK_J, NoSymbol, XK_dollar, NoSymbol, /* 0x68 */ + XK_K, NoSymbol, XK_cent, NoSymbol, /* 0x69 */ + XK_L, NoSymbol, XK_sterling, NoSymbol, /* 0x6a */ + XK_semicolon, XK_colon, XK_lira, NoSymbol, /* 0x6b */ + XK_quoteright, XK_quotedbl, XK_quoteleft, XK_quoteright, /* 0x6c */ + XK_Return, NoSymbol, NoSymbol, NoSymbol, /* 0x6d */ + XK_Home, NoSymbol, NoSymbol, NoSymbol, /* 0x6e */ + /* Prev */ + XK_Prior, NoSymbol, NoSymbol, NoSymbol, /* 0x6f */ + + XK_M, NoSymbol, XK_masculine, NoSymbol, /* 0x70 */ + XK_comma, XK_less, XK_less, NoSymbol, /* 0x71 */ + XK_period, XK_greater, XK_greater, NoSymbol, /* 0x72 */ + XK_slash, XK_question, XK_underscore, NoSymbol, /* 0x73 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x74 */ + XK_Select, NoSymbol, NoSymbol, NoSymbol, /* 0x75 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x76 */ + XK_Next, NoSymbol, NoSymbol, NoSymbol, /* 0x77 */ + XK_N, NoSymbol, XK_ordfeminine, NoSymbol, /* 0x78 */ + /* "Space the final frontier..." */ + XK_space, NoSymbol, NoSymbol, NoSymbol, /* 0x79 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x7a */ + /* Kanji Right */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x7b */ + + XK_Left, NoSymbol, NoSymbol, NoSymbol, /* 0x7c */ + XK_Down, NoSymbol, NoSymbol, NoSymbol, /* 0x7d */ + XK_Up, NoSymbol, NoSymbol, NoSymbol, /* 0x7e */ + XK_Right, NoSymbol, NoSymbol, NoSymbol /* 0x7f */ +}; + + + + /* This routine converts a hil keyboard id to the X keyboard id used to + * look up the keyboard in the /usr/lib/X11/XHPKeymaps file. + * Notes: + * Modified from libXhp XHPGetHILandCvt(). + * We used to just do some math to get the extended keyboard id but we + * got some signals crossed with the NLIO guys and some of the + * keyboards got misplaced in XHPKeymaps so we now have a look up + * table. For the PS2 keyboards, we still use math. + * 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 + * E0-FF Standard keyboard. We change to be the PS2. + * Map extended keyboards to key ids 0-31. The unsupported keyboards + * are the ones with hard coded numbers. + * The apollo keyboards are 33-40 (I don't want to talk about it and + * hind sight is 20/20). + * Map PS2 keyboards to key ids 60-91. + * WARNING + * ONLY call this for HIL keyed devices. For other stuff (such as + * serial keyboards), use the named lookups. + * Input: + * hil_id: + * Returns: + * X keyboard id. + * If the hil_id is not a supported keyboard, return unsupported id. + * If the hil_id is not a keyboard, return KB_NULL. + */ +int hil_to_kbd_id(hil_id) int hil_id; +{ + int kbd_id; + static short int key_tab[] = { + 31, /* HIL=00h Undefined keyboard */ + 30, /* HIL=01h Undefined keyboard */ + KB_Japanese, /* HIL=02h */ + KB_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 */ + KB_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 */ + KB_Italian, /* HIL=0Bh */ + KB_Korean, /* HIL=0Ch */ + KB_Dutch, /* HIL=0Dh */ + KB_Swedish, /* HIL=0Eh */ + KB_German, /* HIL=0Fh */ + KB_S_Chinese, /* HIL=10h */ + KB_T_Chinese, /* HIL=11h */ + KB_Swiss_French2, /* HIL=12h */ + KB_Euro_Spanish, /* HIL=13h */ + KB_Swiss_German2, /* HIL=14h */ + KB_Belgian, /* HIL=15h */ + KB_Finnish, /* HIL=16h */ + KB_UK_English, /* HIL=17h */ + KB_Canada_French, /* HIL=18h */ + KB_Swiss_German, /* HIL=19h */ + KB_Norwegian, /* HIL=1Ah */ + KB_French, /* HIL=1Bh */ + KB_Danish, /* HIL=1Ch */ + KB_Katakana, /* HIL=1Dh */ + KB_Latin_Spanish, /* HIL=1Eh */ + KB_US_English, /* HIL=1Fh */ + }; + + if (hil_id == 0x30) return KB_BUTTON_BOX; + + if (hil_id == 0x5c) return KB_US_English; /* Barcode reader */ + + if (0xE0 <= hil_id && hil_id <= 0xFF) /* PS2 keyboard: 0xE0 - 0xFF */ + return (91 - (hil_id - 0xE0)); /* 60 - 91 */ + + if (0xC0 <= hil_id && hil_id <= 0xDF) /* ITF keyboard: 0xC0 - 0xDF */ + return key_tab[hil_id & 0x1f]; /* 0 - 31 */ + + /* Something unknown or not yet supported (such as a nonkbd device (like + * the ID module)). + */ + return KB_NULL; +} + +#endif /* __hpux */ + +#if __apollo +#include "ap_keysym.h" /* for the apXK_ keysyms */ + +static KeySym Apollo_NorthAmericanMap[] = { + + /* code values in comments at line end are actual value reported on HIL. + REMEMBER, there is an offset of MIN_KEYCODE applied to this table! */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x00 */ + XK_Select, XK_Insert, NoSymbol, NoSymbol, /* 0x01 */ + apXK_LineDel, NoSymbol, NoSymbol, NoSymbol, /* 0x02 */ + apXK_CharDel, NoSymbol, NoSymbol, NoSymbol, /* 0x03 */ + XK_F10, NoSymbol, NoSymbol, NoSymbol, /* 0x04 */ + XK_F1, NoSymbol, NoSymbol, NoSymbol, /* 0x05 */ + XK_F2, NoSymbol, NoSymbol, NoSymbol, /* 0x06 */ + XK_F3, NoSymbol, NoSymbol, NoSymbol, /* 0x07 */ + XK_F4, NoSymbol, NoSymbol, NoSymbol, /* 0x08 */ + XK_F5, NoSymbol, NoSymbol, NoSymbol, /* 0x09 */ + XK_F6, NoSymbol, NoSymbol, NoSymbol, /* 0x0a */ + XK_F7, NoSymbol, NoSymbol, NoSymbol, /* 0x0b */ + XK_F8, NoSymbol, NoSymbol, NoSymbol, /* 0x0c */ + XK_F9, NoSymbol, NoSymbol, NoSymbol, /* 0x0d */ + XK_Redo, NoSymbol, NoSymbol, NoSymbol, /* 0x0e */ + apXK_Read, NoSymbol, NoSymbol, NoSymbol, /* 0x0f */ + apXK_Edit, apXK_Save, NoSymbol, NoSymbol, /* 0x10 */ + apXK_Exit, XK_Cancel, NoSymbol, NoSymbol, /* 0x11 */ + XK_Pause, XK_Help, NoSymbol, NoSymbol, /* 0x12 */ + apXK_Copy, apXK_Cut, NoSymbol, NoSymbol, /* 0x13 */ + apXK_Paste, XK_Undo, NoSymbol, NoSymbol, /* 0x14 */ + apXK_Grow, apXK_Move, NoSymbol, NoSymbol, /* 0x15 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x16 */ + XK_Escape, NoSymbol, NoSymbol, NoSymbol, /* 0x17 */ + XK_1, XK_exclam, NoSymbol, NoSymbol, /* 0x18 */ + XK_2, XK_at, NoSymbol, NoSymbol, /* 0x19 */ + XK_3, XK_numbersign, NoSymbol, NoSymbol, /* 0x1a */ + XK_4, XK_dollar, NoSymbol, NoSymbol, /* 0x1b */ + XK_5, XK_percent, NoSymbol, NoSymbol, /* 0x1c */ + XK_6, XK_asciicircum, NoSymbol, NoSymbol, /* 0x1d */ + XK_7, XK_ampersand, NoSymbol, NoSymbol, /* 0x1e */ + XK_8, XK_asterisk, NoSymbol, NoSymbol, /* 0x1f */ + XK_9, XK_parenleft, NoSymbol, NoSymbol, /* 0x20 */ + XK_0, XK_parenright, NoSymbol, NoSymbol, /* 0x21 */ + XK_minus, XK_underscore, NoSymbol, NoSymbol, /* 0x22 */ + XK_equal, XK_plus, NoSymbol, NoSymbol, /* 0x23 */ + XK_quoteleft, XK_asciitilde, NoSymbol, NoSymbol, /* 0x24 */ + XK_BackSpace, NoSymbol, NoSymbol, NoSymbol, /* 0x25 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x26 */ + apXK_LeftBar, NoSymbol, NoSymbol, NoSymbol, /* 0x27 */ + apXK_Cmd, apXK_Shell, NoSymbol, NoSymbol, /* 0x28 */ + apXK_RightBar, NoSymbol, NoSymbol, NoSymbol, /* 0x29 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x2a */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x2b */ + XK_Tab, NoSymbol, NoSymbol, NoSymbol, /* 0x2c */ + XK_Q, NoSymbol, NoSymbol, NoSymbol, /* 0x2d */ + XK_W, NoSymbol, NoSymbol, NoSymbol, /* 0x2e */ + XK_E, NoSymbol, NoSymbol, NoSymbol, /* 0x2f */ + XK_R, NoSymbol, NoSymbol, NoSymbol, /* 0x30 */ + XK_T, NoSymbol, NoSymbol, NoSymbol, /* 0x31 */ + XK_Y, NoSymbol, NoSymbol, NoSymbol, /* 0x32 */ + XK_U, NoSymbol, NoSymbol, NoSymbol, /* 0x33 */ + XK_I, NoSymbol, NoSymbol, NoSymbol, /* 0x34 */ + XK_O, NoSymbol, NoSymbol, NoSymbol, /* 0x35 */ + XK_P, NoSymbol, NoSymbol, NoSymbol, /* 0x36 */ + XK_bracketleft, XK_braceleft, NoSymbol, NoSymbol, /* 0x37 */ + XK_bracketright, XK_braceright, NoSymbol, NoSymbol, /* 0x38 */ + XK_Mode_switch, NoSymbol, NoSymbol, NoSymbol, /* 0x39 */ + XK_Delete, NoSymbol, NoSymbol, NoSymbol, /* 0x3a */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x3b */ + XK_KP_7, NoSymbol, NoSymbol, NoSymbol, /* 0x3c */ + XK_KP_8, NoSymbol, NoSymbol, NoSymbol, /* 0x3d */ + XK_KP_9, NoSymbol, NoSymbol, NoSymbol, /* 0x3e */ + XK_KP_Add, NoSymbol, NoSymbol, NoSymbol, /* 0x3f */ + apXK_LeftBox, NoSymbol, NoSymbol, NoSymbol, /* 0x40 */ + XK_Up, NoSymbol, NoSymbol, NoSymbol, /* 0x41 */ + apXK_RightBox, NoSymbol, NoSymbol, NoSymbol, /* 0x42 */ + XK_Control_L, NoSymbol, NoSymbol, NoSymbol, /* 0x43 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x44 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x45 */ + XK_A, NoSymbol, NoSymbol, NoSymbol, /* 0x46 */ + XK_S, NoSymbol, NoSymbol, NoSymbol, /* 0x47 */ + XK_D, NoSymbol, NoSymbol, NoSymbol, /* 0x48 */ + XK_F, NoSymbol, NoSymbol, NoSymbol, /* 0x49 */ + XK_G, NoSymbol, NoSymbol, NoSymbol, /* 0x4a */ + XK_H, NoSymbol, NoSymbol, NoSymbol, /* 0x4b */ + XK_J, NoSymbol, NoSymbol, NoSymbol, /* 0x4c */ + XK_K, NoSymbol, NoSymbol, NoSymbol, /* 0x4d */ + XK_L, NoSymbol, NoSymbol, NoSymbol, /* 0x4e */ + XK_semicolon, XK_colon, NoSymbol, NoSymbol, /* 0x4f */ + XK_quoteright, XK_quotedbl, NoSymbol, NoSymbol, /* 0x50 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x51 */ + XK_Return, NoSymbol, NoSymbol, NoSymbol, /* 0x52 */ + XK_backslash, XK_bar, NoSymbol, NoSymbol, /* 0x53 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x54 */ + XK_KP_4, NoSymbol, NoSymbol, NoSymbol, /* 0x55 */ + XK_KP_5, NoSymbol, NoSymbol, NoSymbol, /* 0x56 */ + XK_KP_6, NoSymbol, NoSymbol, NoSymbol, /* 0x57 */ + XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol, /* 0x58 */ + XK_Left, NoSymbol, NoSymbol, NoSymbol, /* 0x59 */ + XK_Next, NoSymbol, NoSymbol, NoSymbol, /* 0x5a */ + XK_Right, NoSymbol, NoSymbol, NoSymbol, /* 0x5b */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x5c */ + apXK_Repeat, NoSymbol, NoSymbol, NoSymbol, /* 0x5d */ + XK_Shift_L, NoSymbol, NoSymbol, NoSymbol, /* 0x5e */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x5f */ + XK_Z, NoSymbol, NoSymbol, NoSymbol, /* 0x60 */ + XK_X, NoSymbol, NoSymbol, NoSymbol, /* 0x61 */ + XK_C, NoSymbol, NoSymbol, NoSymbol, /* 0x62 */ + XK_V, NoSymbol, NoSymbol, NoSymbol, /* 0x63 */ + XK_B, NoSymbol, NoSymbol, NoSymbol, /* 0x64 */ + XK_N, NoSymbol, NoSymbol, NoSymbol, /* 0x65 */ + XK_M, NoSymbol, NoSymbol, NoSymbol, /* 0x66 */ + XK_comma, XK_less, NoSymbol, NoSymbol, /* 0x67 */ + XK_period, XK_greater, NoSymbol, NoSymbol, /* 0x68 */ + XK_slash, XK_question, NoSymbol, NoSymbol, /* 0x69 */ + XK_Shift_R, NoSymbol, NoSymbol, NoSymbol, /* 0x6a */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x6b */ + apXK_Pop, NoSymbol, NoSymbol, NoSymbol, /* 0x6c */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x6d */ + XK_KP_1, NoSymbol, NoSymbol, NoSymbol, /* 0x6e */ + XK_KP_2, NoSymbol, NoSymbol, NoSymbol, /* 0x6f */ + XK_KP_3, NoSymbol, NoSymbol, NoSymbol, /* 0x70 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x71 */ + apXK_UpBox, NoSymbol, NoSymbol, NoSymbol, /* 0x72 */ + XK_Down, NoSymbol, NoSymbol, NoSymbol, /* 0x73 */ + apXK_DownBox, NoSymbol, NoSymbol, NoSymbol, /* 0x74 */ + XK_Alt_L, NoSymbol, NoSymbol, NoSymbol, /* 0x75 */ + XK_space, NoSymbol, NoSymbol, NoSymbol, /* 0x76 */ + XK_Alt_R, NoSymbol, NoSymbol, NoSymbol, /* 0x77 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x78 */ + XK_KP_0, NoSymbol, NoSymbol, NoSymbol, /* 0x79 */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x7a */ + XK_KP_Decimal, NoSymbol, NoSymbol, NoSymbol, /* 0x7b */ + XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol, /* 0x7c */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x7d */ + XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, /* 0x7e */ + NoSymbol, NoSymbol, NoSymbol, NoSymbol, /* 0x7f */ +}; +#endif /* __apollo */ + +static KeySym LPFKMap[] = { + XK_exclam, NoSymbol, NoSymbol, NoSymbol, /* 0x21 */ + XK_quotedbl, NoSymbol, NoSymbol, NoSymbol, /* 0x22 */ + XK_numbersign, NoSymbol, NoSymbol, NoSymbol, /* 0x23 */ + XK_dollar, NoSymbol, NoSymbol, NoSymbol, /* 0x24 */ + XK_percent, NoSymbol, NoSymbol, NoSymbol, /* 0x25 */ + XK_ampersand, NoSymbol, NoSymbol, NoSymbol, /* 0x26 */ + XK_quoteright, NoSymbol, NoSymbol, NoSymbol, /* 0x27 */ + XK_parenleft, NoSymbol, NoSymbol, NoSymbol, /* 0x28 */ + XK_parenright, NoSymbol, NoSymbol, NoSymbol, /* 0x29 */ + XK_asterisk, NoSymbol, NoSymbol, NoSymbol, /* 0x2a */ + XK_plus, NoSymbol, NoSymbol, NoSymbol, /* 0x2b */ + XK_comma, NoSymbol, NoSymbol, NoSymbol, /* 0x2c */ + XK_minus, NoSymbol, NoSymbol, NoSymbol, /* 0x2d */ + XK_period, NoSymbol, NoSymbol, NoSymbol, /* 0x2e */ + XK_slash, NoSymbol, NoSymbol, NoSymbol, /* 0x2f */ + XK_0, NoSymbol, NoSymbol, NoSymbol, /* 0x30 */ + XK_1, NoSymbol, NoSymbol, NoSymbol, /* 0x31 */ + XK_2, NoSymbol, NoSymbol, NoSymbol, /* 0x32 */ + XK_3, NoSymbol, NoSymbol, NoSymbol, /* 0x33 */ + XK_4, NoSymbol, NoSymbol, NoSymbol, /* 0x34 */ + XK_5, NoSymbol, NoSymbol, NoSymbol, /* 0x35 */ + XK_6, NoSymbol, NoSymbol, NoSymbol, /* 0x36 */ + XK_7, NoSymbol, NoSymbol, NoSymbol, /* 0x37 */ + XK_8, NoSymbol, NoSymbol, NoSymbol, /* 0x38 */ + XK_9, NoSymbol, NoSymbol, NoSymbol, /* 0x39 */ + XK_colon, NoSymbol, NoSymbol, NoSymbol, /* 0x3a */ + XK_semicolon, NoSymbol, NoSymbol, NoSymbol, /* 0x3b */ + XK_less, NoSymbol, NoSymbol, NoSymbol, /* 0x3c */ + XK_equal, NoSymbol, NoSymbol, NoSymbol, /* 0x3d */ + XK_greater, NoSymbol, NoSymbol, NoSymbol, /* 0x3e */ + XK_question, NoSymbol, NoSymbol, NoSymbol, /* 0x3f */ + XK_at, NoSymbol, NoSymbol, NoSymbol, /* 0x40 */ +}; + +KeySymsRec LPFKKeySyms = {LPFKMap, 0x21, 0x40, 4}; + + /* This structure has ONE default KeySymsRec per keyboard family per OS + * that is used in case we can't look up the correct one. + * Notes: + * All key maps SHOULD start at MIN_KEYCODE (aka 0) except HP-UX, + * where the exteneded keyboard keymaps start at 2 (because the + * extended keyboards didn't generate keycodes 0 and 1). The PS2 + * keyboards generate keycodes starting at 0 so they need a + * different MIN_KEYCODE. + * These default keymaps are overwritten so they should contain at + * least enough entries so that the largest keytable will fit. In + * most cases this means that last entry is 0x7f and the keymap size + * is max-entries x width == 0x80 x 4. + */ +static KeySymsRec DefaultKeySyms[] = { + /* map name minKeyCode maxKC width */ +#if defined(__hpux) || defined(__hp_osf) + &USASCIIMap[8], (MIN_KEYCODE + 0x02), (MIN_KEYCODE + 0x7F), 4, + USASCIIMap, (MIN_KEYCODE), (MIN_KEYCODE + 0x7F), 4, + null_keymap, (MIN_KEYCODE), (MIN_KEYCODE + 0x7F), 1, +#endif + +#if __apollo + Apollo_NorthAmericanMap, (MIN_KEYCODE), (MIN_KEYCODE + 0x7F), 4, +#endif +}; + + /* Convert a X keyboard ID into a family. + * Input: X keyboard ID + * Returns: + * 0 (ITF) + * 1 (PS2) + * 2 (null or unknown device) + * 0 Apollo + */ +static int kbd_family(key_id) +{ + int n; + +#if defined(__hpux) || defined(__hp_osf) + if ( 0 <= key_id && key_id <= 31) n = 0; /* ITF keyboard */ + else + if (60 <= key_id && key_id <= 91) n = 1; /* PS2 keyboard */ + else n = 2; /* KB_NULL */ +#endif + +#if __apollo + n = 0; +#endif + + return n; +} + + /* This routine is called to get a pointer to a KeySymRec so you can + * overwrite the key table with the correct one for the keyboard + * connected to the system. + */ +KeySymsRec *hpKeySyms(key_id) +{ + return &DefaultKeySyms[kbd_family(key_id)]; +} + + /* This routine is called if the load-keytable-from-file routine fails + * and you need a default KeySymRec. I need this for HP-UX 'cause the + * extended and PS2 keyboards have different min keycodes and I want to + * use the US Ascii keymap as the default. + */ +KeySymsRec *hpDefaultKeySyms(key_id) +{ + return hpKeySyms(key_id); +} + + +/* ******************************************************************** */ +/* ************************* Modifier Tables ************************** */ +/* ******************************************************************** */ + +#define cT (ControlMask) +#define sH (ShiftMask) +#define lK (LockMask) +#define mT (Mod1Mask) + + /* A modmap with no modifiers. To be used with null_keymap */ +static CARD8 null_modmap[MAP_LENGTH]; + + + /* Shift table values up by 8. This offset is necessary to reserve + * codes for mouse buttons. Note last 8 entries of table are + * commented out to preserve length of table. + * Note: '#define MIN_KEYCODE 8' is above + */ + +#if defined(__hpux) || defined(__hp_osf) + + /* This table is for the HP hil extended keyboards. + * For the PS2 keyboards, the only difference is keycode 0. I used to + * use the same table for both keyboard types (since keycode 0 can't + * be generated by the extended keyboard) but that caused problems + * with xmodmap. + */ +static CARD8 hil_modmap[MAP_LENGTH] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, mT, mT, sH, sH, cT, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00-0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10-1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mT, lK,/* 20-2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30-3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50-5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-6f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70-7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0-af */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0-bf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0-cf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0-df */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0-ef */ + 0, 0, 0, 0, 0, 0, 0, 0,/*0, 0, 0, 0, 0, 0, 0, 0, /* f0-ff */ +}; + + /* Same table as the hil_modmap but for PS2 keyboards. Only + * difference is keycode 0 is a control key. + */ +static CARD8 PS2_modmap[MAP_LENGTH] = { + 0, 0, 0, 0, 0, 0, 0, 0, + cT, 0, mT, mT, sH, sH, cT, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00-0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10-1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, mT, lK,/* 20-2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30-3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50-5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-6f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70-7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0-af */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0-bf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0-cf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0-df */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0-ef */ + 0, 0, 0, 0, 0, 0, 0, 0,/*0, 0, 0, 0, 0, 0, 0, 0, /* f0-ff */ +}; + +#endif + +#ifdef __apollo + + /* This table is for the Apollo NA and MN keyboards. */ +static CARD8 apollo_modmap[MAP_LENGTH] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00-0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10-1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20-2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, mT, 0, 0, 0, 0, 0, 0, /* 30-3f */ + 0, 0, 0, cT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sH, 0, /* 50-5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sH, 0, 0, 0, 0, 0, /* 60-6f */ + 0, 0, 0, 0, 0, mT, 0, mT, 0, 0, 0, 0, 0, 0, lK, 0, /* 70-7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0-af */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0-bf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0-cf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0-df */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0-ef */ + 0, 0, 0, 0, 0, 0, 0, 0,/*0, 0, 0, 0, 0, 0, 0, 0, /* f0-ff */ +}; +#endif + + /* This routine returns the modifier map to be used with the keymap that + * has keyboard/(X id) kbd_id. + * Note: This is easy because each OS we support now only has one or + * two mod maps for all keyboards it supports. + */ +CARD8 *hpModMap(kbd_id) +{ +#if defined(__hpux) || defined(__hp_osf) + switch (kbd_family(kbd_id)) + { + case 0: return hil_modmap; /* Extended keyboard */ + case 1: return PS2_modmap; /* PS2 keyboard */ + case 2: return null_modmap; /* button box */ + } +#endif + +#ifdef __apollo + return apollo_modmap; +#endif +} + + +/* ******************************************************************** */ +/* ********************************* ********************************* */ +/* ******************************************************************** */ + + /* Routines in getkeysym.c */ +extern HPKKeyDeviceInfo *HPKlookup_kd_by_id(), *HPKlookup_kd_by_name(); +extern HPKModMap *HPKlookup_modmap(); + + + /* Empty space that can be filled in when I read keyboard info from a + * file. I don't think I can just overwrite (eg) the null_maps + * because if they change keyboards, recycle and then I can't find a + * map, the default won't work anymore. + */ +static KeySym tmp_keymap[8 * 256]; /* biggest keymap */ +static CARD8 tmp_modmap[MAP_LENGTH]; + +static void maparoo(kptr, keysyms_rec, complain, modmap, default_modmap) + KeySymsRec *keysyms_rec; + HPKKeyDeviceInfo *kptr; + CARD8 **modmap, *default_modmap; +{ + CARD8 *the_modmap; + HPKModMap *mptr; + + keysyms_rec->map = tmp_keymap; + keysyms_rec->minKeyCode = kptr->min_keycode; + keysyms_rec->maxKeyCode = kptr->max_keycode; + keysyms_rec->mapWidth = kptr->columns; + + if (mptr = HPKlookup_modmap(kptr->modmap_name)) + { + memcpy(tmp_modmap, mptr->modmap, MAP_LENGTH); + the_modmap = tmp_modmap; + } + else + { + if (complain) + ErrorF("Could not find modmap \"%s\"- using default (NULL map).\n", + kptr->modmap_name); + the_modmap = default_modmap; + } + *modmap = the_modmap; +} + + /* + * Input: + * keydevice_id: The keydevice ID. On HP-UX, this is the output of + * hil_to_kbd_id(). + * keysyms_rec: Pointer to a KeySymsRec to fill in. + * modmap: Pointer to a pointer to a modmap. + * Output: + * keysyms_rec: FIlled in. + * modmap: points to a modmap to use with the keysyms_rec. + * Returns: + * TRUE : everything went as expected + * FALSE: Something went screwie, using default maps. + * Notes: + * Don't complain if can't load maps for the button box. + */ +int HPKget_maps_by_id(keydevice_id, keysyms_rec, modmap) + KeySymsRec *keysyms_rec; CARD8 **modmap; +{ + CARD8 *the_modmap; + HPKKeyDeviceInfo *kptr; + HPKModMap *mptr; + + *keysyms_rec = *hpDefaultKeySyms(keydevice_id); + *modmap = hpModMap(keydevice_id); + + if (keydevice_id == KB_NULL) return TRUE; + + if (!HPKsetup((char *)NULL)) + { + opps: + if (keydevice_id != KB_BUTTON_BOX) + ErrorF("Unable to load keymaps - using defaults.\n"); + } + else + { + if (!HPKread_keymap(keydevice_id, tmp_keymap)) goto opps; + + if (kptr = HPKlookup_kd_by_id(keydevice_id)) + maparoo(kptr, keysyms_rec, False, modmap, hpModMap(keydevice_id)); + } + + HPKclean_up(); + + 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. + * modmap: Pointer to a pointer to a modmap. + * Output: + * keysyms_rec: FIlled in. + * modmap: points to a modmap to use with the keysyms_rec. + * 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); + *keysyms_rec = *hpDefaultKeySyms(KB_NULL); + *modmap = hpModMap(KB_NULL); + + return FALSE; +} + +static int try_and_load_maps(keymap_file, keymap_name, keysyms_rec, modmap) + char *keymap_file, *keymap_name; KeySymsRec *keysyms_rec; CARD8 **modmap; +{ + HPKKeyDeviceInfo *kptr; + int all_OK = TRUE; + + if (!HPKsetup(keymap_file)) all_OK = FALSE; + else + { + if (!(kptr = HPKlookup_kd_by_name(keymap_name)) || + !HPKread_keymap(kptr->keydevice_id, tmp_keymap)) + all_OK = FALSE; + else + maparoo(kptr, keysyms_rec, True, modmap, null_modmap); + } + + HPKclean_up(); + + return all_OK; +} diff --git a/xc/programs/Xserver/hw/hp/input/hpext.h b/xc/programs/Xserver/hw/hp/input/hpext.h new file mode 100644 index 000000000..052621fd6 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/hpext.h @@ -0,0 +1,881 @@ +/* $XConsortium: hpext.h /main/4 1996/01/22 18:29:38 gildea $ */ + +/* + +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. + +*/ + +#ifndef HPEXT_H +#define HPEXT_H + +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xproto.h" +#include "X.h" +#include "XHPproto.h" /* server version definitions */ +#ifdef XINPUT +#include "XIproto.h" +#endif /* XINPUT */ + +/* Definitions for HP extensions used by the server and Xlib */ + +/********************************************************* + * + * number of hp events, errors, and extension name. + * + */ + +#define HPEVENTS 12 +#define HPERRORS 3 +#define CLIENT_REQ 1 +#define HPNAME "HPExtension" +#define MIN_EVENT_REQUEST 1 +#define MAX_EVENT_REQUEST 11 + +/********************************************************* + * + * Protocol request constants + * + */ + +#define X_GetHpKeyboardId 1 /* DO NOT CHANGE THIS LINE! */ +#define X_HPListInputDevices 2 +#define X_HPSetInputDevice 3 +#define X_HPGetExtEventMask 4 +#define X_HPGetDeviceFocus 5 +#define X_HPGetClipList 6 +#define X_HPGrabDevice 7 +#define X_HPSetDeviceFocus 8 +#define X_HPUnGrabDevice 9 +#define X_HPSelectExtensionEvent 10 +#define X_HPGetCurrentDeviceMask 11 +#define X_HPEnableReset 12 +#define X_HPDisableReset 13 +#define X_HPGetDeviceMotionEvents 14 +#define X_HPGrabDeviceButton 15 +#define X_HPUngrabDeviceButton 16 +#define X_HPGrabDeviceKey 17 +#define X_HPUngrabDeviceKey 18 +#define X_HPDeviceAutoRepeatOn 19 +#define X_HPDeviceAutoRepeatOff 20 +#define X_HPPrompt 21 +#define X_HPAcknowledge 22 +#define X_HPRegisterWindow 23 +#define X_HPUnRegisterWindow 24 +#define X_HPSynchronizeColorRange 25 +#define X_HPGetServerMode 26 +#define X_HPGetDeviceKeyMapping 27 +#define X_HPChangeDeviceKeyMapping 28 +#define X_HPGetDeviceModifierMapping 29 +#define X_HPSetDeviceModifierMapping 30 +#define X_HPGetDeviceControl 31 +#define X_HPChangeDeviceControl 32 +#define X_HPGetWindowCursor 33 +#define X_HPGrabReset 34 +#define X_HPSendDdxDriverMsg 35 +#define X_HPGetClipLists 36 +#define X_HPSSChange 37 /* Screen saver change */ + +#define sz_xHPListInputDevicesReq 4 +#define sz_xHPListInputDevicesReply 32 +#define sz_xHPSetInputDeviceReq 12 +#define sz_xHPSetInputDeviceReply 32 +#define sz_xHPGetExtEventMaskReq 8 +#define sz_xHPGetExtEventMaskReply 32 +#define sz_xHPGetDeviceFocusReq 8 +#define sz_xHPGetDeviceFocusReply 32 +#define sz_xHPGetClipListReq 16 +#define sz_xHPGetClipListReply 32 +#define sz_xHPGrabDeviceReq 24 +#define sz_xHPGrabDeviceReply 32 +#define sz_xHPSetDeviceFocusReq 20 +#define sz_xHPUnGrabDeviceReq 12 +#define sz_xHPSelectExtensionEventReq 16 +#define sz_xHPGetCurrentDeviceMaskReq 12 +#define sz_xHPGetCurrentDeviceMaskReply 32 +#define sz_xHPEnableResetReq 4 +#define sz_xHPDisableResetReq 4 +#define sz_xHPGetDeviceMotionEventsReq 20 +#define sz_xHPGetDeviceMotionEventsReply 32 +#define sz_xHPGrabDeviceButtonReq 24 +#define sz_xHPUngrabDeviceButtonReq 16 +#define sz_xHPGrabDeviceKeyReq 20 +#define sz_xHPUngrabDeviceKeyReq 16 +#define sz_xHPDeviceAutoRepeatOnReq 12 +#define sz_xHPDeviceAutoRepeatOffReq 8 +#define sz_xHPPromptReq 12 +#define sz_xHPAcknowledgeReq 12 +#define sz_xHPRegisterWindowReq 16 +#define sz_xHPRegisterWindowReply 152 +#define sz_xHPSynchronizeColorRangeReq 16 +#define sz_xHPGetServerModeReq 8 +#define sz_xHPGetServerModeReply 32 +#define sz_xHPGetDeviceKeyMappingReq 12 +#define sz_xHPGetDeviceKeyMappingReply 32 +#define sz_xHPChangeDeviceKeyMappingReq 12 +#define sz_xHPGetDeviceModifierMappingReq 8 +#define sz_xHPGetDeviceModifierMappingReply 32 +#define sz_xHPSetDeviceModifierMappingReq 12 +#define sz_xHPSetDeviceModifierMappingReply 32 +#define sz_xHPGetDeviceControlReq 8 +#define sz_xHPGetDeviceControlReply 64 +#define sz_xHPChangeDeviceControlReq 12 +#define sz_xHPGetWindowCursorReq 8 +#define sz_xHPGetWindowCursorReply 32 +#define sz_xHPGrabResetReq 4 +#define sz_xHPGrabResetReply 32 +#define sz_xHPSendDdxDriverMsgReq 16 +#define sz_xHPSendDdxDriverMsgReply 32 +#define sz_xHPGetClipListsReq 16 +#define sz_xHPGetClipListsReply 32 + +#define GET_HPINPUTDEVICE(pDev) \ + ((HPInputDevice *) ((pDev)->public.devicePrivate)) + +struct dev_select_info + { + Mask mask; + long type; + }; + +/********************************************************* + * + * Protocol request and reply structures. + * + */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPListInputDevices */ + CARD16 length; +} xHPListInputDevicesReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPListInputDevices */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ndevices B32; + CARD32 t_axes B32; + CARD32 data02 B32; + CARD32 data03 B32; + CARD32 data04 B32; + CARD32 data05 B32; + } xHPListInputDevicesReply; + + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPSetInputDevice */ + CARD16 length; + XID deviceid; + CARD32 mode; +} xHPSetInputDeviceReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPSetInputDevice */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 status B32; + CARD32 data01 B32; + CARD32 data02 B32; + CARD32 data03 B32; + CARD32 data04 B32; + CARD32 data05 B32; + } xHPSetInputDeviceReply; + + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPGetExtEventMask */ + CARD16 length; + CARD32 evconst; +} xHPGetExtEventMaskReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetExtEventMask */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 mask B32; + CARD32 evtype B32; + CARD32 data01 B32; + CARD32 data02 B32; + CARD32 data03 B32; + CARD32 data04 B32; + } xHPGetExtEventMaskReply; + +typedef struct { + CARD8 reqType; /* always HpeqCode */ + CARD8 hpReqType; /* always X_HPGetCurrentDeviceMask */ + CARD16 length; + Window window B32; + XID deviceid; +} xHPGetCurrentDeviceMaskReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetCurrentDeviceMask */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 mask B32; + CARD32 data01 B32; + CARD32 data02 B32; + CARD32 data03 B32; + CARD32 data04 B32; + CARD32 data05 B32; + } xHPGetCurrentDeviceMaskReply; + + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPGetDeviceFocus */ + CARD16 length; + XID deviceid; +} xHPGetDeviceFocusReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetDeviceFocus */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 status B32; + CARD32 focus B32; + Window revertTo B32; + CARD32 data01 B32; + CARD32 data02 B32; + CARD32 data03 B32; + } xHPGetDeviceFocusReply; + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPSetDeviceFocus */ + CARD16 length; + Window focus B32; + XID deviceid; + Time time B32; + CARD8 revertTo; + CARD8 pad00; + CARD16 pad01; +} xHPSetDeviceFocusReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGrabDevice */ + CARD16 length B16; + Window grabWindow B32; + Time time B32; + XID deviceid; + CARD32 eventMask B32; + BOOL ownerEvents; + CARD8 pad00; + CARD16 pad01 B16; +} xHPGrabDeviceReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGrabDevice */ + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 status; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xHPGrabDeviceReply; + + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPUnGrabDevice */ + CARD16 length B16; + Time time B32; + XID deviceid; +} xHPUnGrabDeviceReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPSelectExtensionEvent */ + CARD16 length B16; + Window window B32; + CARD32 extensionMask B32; + XID deviceid; +} xHPSelectExtensionEventReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPEnableReset */ + CARD16 length B16; +} xHPEnableResetReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPDisableReset */ + CARD16 length B16; +} xHPDisableResetReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGetDeviceMotionEvents*/ + CARD16 length B16; + Window window B32; + Time start B32; + Time stop B32; + XID deviceid; +} xHPGetDeviceMotionEventsReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetDeviceMotionEvents */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 nEvents B32; + INT16 axes B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xHPGetDeviceMotionEventsReply; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGrabDeviceButton */ + CARD16 length B16; + Window grabWindow B32; + XID deviceid; + CARD32 eventMask; + CARD16 modifiers B16; + BOOL ownerEvents; + CARD8 button; + BYTE pointerMode, keyboardMode; + CARD8 pad1, pad2; +} xHPGrabDeviceButtonReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPUngrabDeviceButton */ + CARD16 length B16; + Window grabWindow B32; + XID deviceid; + CARD16 modifiers B16; + CARD8 button; + CARD8 pad1; +} xHPUngrabDeviceButtonReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGrabDeviceKey */ + CARD16 length B16; + Window grabWindow B32; + XID deviceid; + CARD16 modifiers B16; + BOOL ownerEvents; + CARD8 key; + BYTE pointerMode, keyboardMode; + BYTE pad1, pad2; +} xHPGrabDeviceKeyReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPUngrabDeviceKey */ + CARD16 length B16; + Window grabWindow B32; + XID deviceid; + CARD16 modifiers B16; + CARD8 key; + CARD8 pad1; +} xHPUngrabDeviceKeyReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPDeviceAutoRepeatOn */ + CARD16 length B16; + XID deviceid; + INT32 rate; +} xHPDeviceAutoRepeatOnReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPDeviceAutoRepeatOff */ + CARD16 length B16; + XID deviceid; +} xHPDeviceAutoRepeatOffReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPPrompt */ + CARD16 length B16; + XID deviceid; + CARD8 prompt; + CARD8 pad1, pad2, pad3; +} xHPPromptReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPAcknowledge */ + CARD16 length B16; + XID deviceid; + CARD8 ack; + CARD8 pad1, pad2, pad3; +} xHPAcknowledgeReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGetServerMode */ + CARD16 length B16; + CARD32 screen B32; +} xHPGetServerModeReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetServerMode */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 mode B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xHPGetServerModeReply; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGetDeviceKeyMapping */ + CARD16 length B16; + XID deviceid; + KeyCode firstKeyCode; + CARD8 count; + CARD16 pad1 B16; +} xHPGetDeviceKeyMappingReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetDeviceKeyMapping */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD8 keySymsPerKeyCode; + CARD8 pad0; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xHPGetDeviceKeyMappingReply; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPChangeDeviceKeyMapping */ + CARD16 length B16; + XID deviceid; + CARD8 keyCodes; + KeyCode firstKeyCode; + CARD8 keySymsPerKeyCode; + CARD8 pad1; +} xHPChangeDeviceKeyMappingReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGetDeviceModifierMapping */ + CARD16 length B16; + XID deviceid; +} xHPGetDeviceModifierMappingReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetDeviceModifierMapping */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD8 numKeyPerModifier; + CARD8 pad0; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xHPGetDeviceModifierMappingReply; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPSetDeviceModifierMapping */ + CARD16 length B16; + CARD8 numKeyPerModifier; + CARD8 pad1; + CARD16 pad2 B16; + XID deviceid; +} xHPSetDeviceModifierMappingReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPSetDeviceModifierMapping */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD8 success; + CARD8 pad0; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xHPSetDeviceModifierMappingReply; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPGetDeviceControl */ + CARD16 length B16; + XID deviceid; +} xHPGetDeviceControlReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetDeviceControl */ + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL globalAutoRepeat; + CARD8 keyClickPercent; + CARD8 bellPercent; + CARD8 pad0; + CARD32 ledMask B32; + CARD16 bellPitch B16; + CARD16 bellDuration B16; + CARD16 accelNumerator B16; + CARD16 accelDenominator B16; + CARD16 threshold B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + BYTE map[32]; /* bit masks start here */ +} xHPGetDeviceControlReply; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_HPChangeDeviceControl */ + CARD16 length B16; + XID deviceid; + CARD32 mask B32; +} xHPChangeDeviceControlReq; + +typedef struct { + CARD8 reqType; + CARD8 hpReqType; /* always X_GetWindowCursor */ + CARD16 length B16; + Window window B32; +} xHPGetWindowCursorReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 hpRepType; /* always X_HPGetWindowCursor */ + CARD16 sequenceNumber B16; + CARD32 length B32; + Cursor cursor B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xHPGetWindowCursorReply; + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPGetClipList */ + CARD16 length; + CARD32 wid; /* window id */ + CARD32 gcid; /* graphics context id */ + CARD32 format; /* clip list format */ +} xHPGetClipListReq; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + INT16 x B16; /* x origin of window */ + INT16 y B16; /* y origin of window */ + CARD16 width B16; /* width of window */ + CARD16 height B16; /* height of window */ + CARD32 count B32; /* number of clipping rectanges */ + CARD32 data03 B32; + CARD32 data04 B32; + CARD32 data05 B32; + } xHPGetClipListReply; + +/* + * X_HPRegisterWindow request/reply structures... + */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* X_HPRegisterWindow or X_HPUnReg... */ + CARD16 length; + CARD32 wid; /* window id */ + CARD32 accelid; /* accelerated id */ + CARD32 flags; /* flags */ +} xHPRegisterWindowReq; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + INT32 error B32; /* error status */ + CARD32 flags B32; /* flags */ + BYTE path[80]; /* length must >= cfbPrivScreen->path */ + CARD32 depth B32; /* depth of window */ + INT32 w_class B32; /* window GRM_ID class */ + INT32 w_screen B32; /* window GRM_ID screen */ + INT32 w_window B32; /* window GRM_ID window */ + BYTE w_name[40]; /* window GRM_ID name */ + } xHPRegisterWindowReply; + +/* + * X_HPSynchronizeColorRange Request structure (no reply) + */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* X_HPRegisterWindow or X_HPUnReg... */ + CARD16 length; + CARD32 cmap; /* Colormap ID of interest */ + CARD32 start; /* Starting pixel if changes to cmap */ + CARD32 ncolors; /* number of pixels changed */ +} xHPSynchronizeColorRangeReq; + +/* + * X_HPSendDdxDriverMsg Request structure (possible reply) + */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* X_HPRegisterWindow or X_HPUnReg... */ + CARD16 length; + Window window; /* window of interest */ + INT32 nMsgBytes; /* Number of bytes in message */ + INT32 needReply; /* whether or not a reply is forthcoming */ +} xHPSendDdxDriverMsgReq; + +typedef struct { + CARD8 type; + CARD8 pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + INT32 nRepBytes; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xHPSendDdxDriverMsgReply; + +/* + * XHPGetClipLists request (not to be confused with XHPGetClipList. + * This extension gets multiple clip lists) + */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* always X_HPGetClipLists */ + CARD16 length; + CARD32 wid; /* window id */ + CARD32 gcid; /* graphics context id */ + CARD32 nClipLists; /* number of clip lists requested */ +/* To be followed by 'nClipLists' CARD32 format longwords: */ +} xHPGetClipListsReq; + + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + INT16 x B16; /* x origin of window */ + INT16 y B16; /* y origin of window */ + CARD16 width B16; /* width of window */ + CARD16 height B16; /* height of window */ + CARD32 count B32; /* number of clip lists */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +/* To be followed by 'count' xHPGetClipListsReplyData structures: */ +} xHPGetClipListsReply; + +typedef struct { + CARD16 count B16; /* number of clip boxes */ + CARD16 size B16; /* size of each clip box in bytes */ +/* To be followed by 'count * size' bytes: */ +} xHPGetClipListsReplyData; + + +/* X_HPGrabReset Request structure */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* X_HPGrabReset */ + CARD16 length; +} xHPGrabResetReq; + +typedef struct { + CARD8 repType; /* always HpReqCode */ + CARD8 hpRepType; /* X_HPGrabReset */ + CARD16 sequenceNumber B16; + CARD32 length B32; + Atom evtype B32; /* event type to expect */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xHPGrabResetReply; + +/* X_HPSSChange Request structures + * Notes: + * The sz_x numbers are sizeof(struct) padded to the to 4 bytes. This to + * make the X packets work correctly. + */ + +typedef struct { + CARD8 reqType; /* always HpReqCode */ + CARD8 hpReqType; /* X_HPSSChange */ + CARD16 length; + CARD32 flags; /* stuff */ + CARD32 wid; /* just in case */ +} xHPSSChangeReq; + +#define sz_xHPSSChangeReq 12 + +typedef struct { + CARD8 repType; /* always HpReqCode */ + CARD8 hpRepType; /* X_HPSSChange */ + CARD16 sequenceNumber B16; + CARD32 length B32; + Atom evtype B32; /* event type to expect */ + CARD32 flags B32; /* */ + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xHPSSChangeReply; + +#define sz_xHPSSChangeReply 32 + +/********************************************************** + * + * extension events. + * + */ + +typedef struct + { + INT16 ax_num; + INT16 ax_val; + } XHPaxis_data; + +typedef struct + { + BYTE type; + BYTE count; + CARD16 sequencenumber B16; + XID deviceid; + CARD32 pad00 B32; + CARD32 pad01 B32; + CARD32 pad02 B32; + CARD32 pad03 B32; + CARD32 pad04 B32; + CARD32 pad05 B32; + } xAnyExtensionEvent; + +typedef struct + { + BYTE type; + BYTE ext_type; + CARD16 sequencenumber B16; + XID deviceid; + INT16 axes_count B16; + CARD16 pad00 B16; + XHPaxis_data data[4]; + CARD32 pad01 B32; + } xHPExtensionEvent; + +typedef struct + { + xEvent b; + xAnyExtensionEvent x; + } xAnyEvent; + +typedef struct + { + xEvent b; +#ifdef XINPUT + deviceValuator x; +#else + xHPExtensionEvent x; +#endif /* XINPUT */ + } xHPEvent; + +typedef struct + { + BYTE type; + BYTE pad00; + CARD16 sequencenumber B16; + INT16 detail B16; + BYTE mode; /* really XMode */ + BYTE pad1; + XID deviceid; + Window window B32; + CARD32 pad01 B32; + CARD32 pad02 B32; + CARD32 pad03 B32; + CARD32 pad04 B32; + } xHPdevicefocus; + +typedef struct + { + BYTE type; + BYTE pad00; + CARD16 sequencenumber B16; + CARD8 request; + KeyCode firstKeyCode; + CARD8 count; + BYTE pad1; + XID deviceid; + CARD32 pad01 B32; + CARD32 pad02 B32; + CARD32 pad03 B32; + CARD32 pad04 B32; + CARD32 pad05 B32; + } xHPDeviceMappingEvent; + +typedef struct + { + BYTE type; + BYTE deviceid; + BYTE map[30]; + } xHPDeviceKeymapEvent; + +#endif diff --git a/xc/programs/Xserver/hw/hp/input/hpkeys.h b/xc/programs/Xserver/hw/hp/input/hpkeys.h new file mode 100644 index 000000000..810784c07 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/hpkeys.h @@ -0,0 +1,251 @@ +#ifndef HPKEYS_H +#define HPKEYS_H +/* $TOG: hpkeys.h /main/3 1998/02/10 13:11:15 kaleb $ */ +/* + +Copyright 1986, 1987, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ + +/*********************************************************************** + * + * file: hpkeys.h + * + * contains key definitions and other static information used by x_hil.c + * + */ + +#define DOWN 0 +#define LEFT 1 +#define RIGHT 2 +#define UP 3 + +#ifdef __apollo +u_char cursor_down = 0x7b; +u_char cursor_left = 0x61; +u_char cursor_right = 0x63; +u_char cursor_up = 0x49; +u_char button_1 = 0x44; +u_char button_2 = 0x45; +u_char button_3 = 0x46; +u_char button_4 = 0x47; +u_char button_5 = 0x5d; +u_char button_6 = 0x00; +u_char button_7 = 0x00; +u_char button_8 = 0x00; +#else +u_char cursor_down = 0x1a; +u_char cursor_left = 0x18; +u_char cursor_right = 0x1c; +u_char cursor_up = 0x12; +u_char button_1 = 0x1d; +u_char button_2 = 0x19; +u_char button_3 = 0x1b; +u_char button_4 = 0x1f; +u_char button_5 = 0x15; +u_char button_6 = 0x00; +u_char button_7 = 0x00; +u_char button_8 = 0x00; +#endif + +u_short pointer_move = 10; +u_short pointer_mod1_amt = 1; +u_short pointer_mod2_amt = 40; +u_short pointer_mod3_amt = 5; +u_char pointer_amt_mods[3] = {0xff,0xff,0xff}; +u_char pointer_key_mods[3] = {0xff,0xff,0xff}; +u_char borrow_mode_mods[3] = {0x43,0x5e,0xff}; +#ifdef __apollo +u_char borrow_mode = 0x15; +u_char reset_mods[3] = {0x43,0x5e,0xff}; +u_char reset = 0x19; +#endif +#if defined(__hpux) || defined(__hp_osf) +u_char reset_mods[3] = {0x06,0x05,0xff}; +u_char reset = 0x0f; +#endif +u_char screen_change_amt = SCREEN_CHANGE_DEFAULT; +u_char ptr_button_map[] = {0,1,2,3,4,5,6,7,8}; +u_char button_latching = LATCHING_OFF; +u_char button_chording = CHORDING_DEFAULT; +u_char screen_orientation = HORIZONTAL; +u_char screen_row_wrap = DEFAULT; +u_char screen_col_wrap = DEFAULT; +u_int tablet_xorigin = 0; +u_int tablet_yorigin = 0; +u_int tablet_width = 0; +u_int tablet_height = 0; +u_char isotropic_scaling = 0; + +u_char ascii_to_code [128][7] = { + {0x0c,0x0a,0x7a,0x7b,0x0b,0x0d,0}, /* cntl - @ */ + {0x0c,0x5a,0x5b,0x0d,0,0,0}, /* cntl - a */ + {0x0c,0x30,0x31,0x0d,0,0,0}, /* cntl - b */ + {0x0c,0x34,0x35,0x0d,0,0,0}, /* cntl - c */ + {0x0c,0x56,0x57,0x0d,0,0,0}, /* cntl - d */ + {0x0c,0x68,0x69,0x0d,0,0,0}, /* cntl - e */ + {0x0c,0x54,0x55,0x0d,0,0,0}, /* cntl - f */ + {0x0c,0x52,0x53,0x0d,0,0,0}, /* cntl - g */ + {0x0c,0x50,0x51,0x0d,0,0,0}, /* cntl - h */ + {0x0c,0xc0,0xc1,0x0d,0,0,0}, /* cntl - i */ + {0x0c,0xd0,0xd1,0x0d,0,0,0}, /* cntl - j */ + {0x0c,0xd2,0xd3,0x0d,0,0,0}, /* cntl - k */ + {0x0c,0xd4,0xd5,0x0d,0,0,0}, /* cntl - l */ + {0x0c,0xe0,0xe1,0x0d,0,0,0}, /* cntl - m */ + {0x0c,0xf0,0xf1,0x0d,0,0,0}, /* cntl - n */ + {0x0c,0xc2,0xc3,0x0d,0,0,0}, /* cntl - o */ + {0x0c,0xc4,0xc5,0x0d,0,0,0}, /* cntl - p */ + {0x0c,0x6c,0x6d,0x0d,0,0,0}, /* cntl - q */ + {0x0c,0x66,0x67,0x0d,0,0,0}, /* cntl - r */ + {0x0c,0x58,0x59,0x0d,0,0,0}, /* cntl - s */ + {0x0c,0x64,0x65,0x0d,0,0,0}, /* cntl - t */ + {0x0c,0x60,0x61,0x0d,0,0,0}, /* cntl - u */ + {0x0c,0x32,0x33,0x0d,0,0,0}, /* cntl - v */ + {0x0c,0x6a,0x6b,0x0d,0,0,0}, /* cntl - w */ + {0x0c,0x36,0x37,0x0d,0,0,0}, /* cntl - x */ + {0x0c,0x62,0x63,0x0d,0,0,0}, /* cntl - y */ + {0x0c,0x38,0x39,0x0d,0,0,0}, /* cntl - z */ + {0x0c,0xc6,0xc7,0x0d,0,0,0}, /* cntl - [ */ + {0x0c,0xca,0xcb,0x0d,0,0,0}, /* cntl - \ */ + {0x0c,0xc8,0xc9,0x0d,0,0,0}, /* cntl - ] */ + {0x0c,0x0a,0x72,0x73,0x0b,0x0d,0}, /* cntl - ^ */ + {0x0c,0x0a,0xb6,0xb7,0x0b,0x0d,0}, /* cntl - _ */ + {0xf2,0xf3,0,0,0,0,0}, /* space */ + {0x0a,0x7c,0x7d,0x0b,0,0,0}, /* ! */ + {0x0a,0xd8,0xd9,0x0b,0,0,0}, /* " */ + {0x0a,0x78,0x79,0x0b,0,0,0}, /* # */ + {0x0a,0x76,0x77,0x0b,0,0,0}, /* $ */ + {0x0a,0x74,0x75,0x0b,0,0,0}, /* % */ + {0x0a,0x70,0x71,0x0b,0,0,0}, /* & */ + {0xd8,0xd9,0,0,0,0,0}, /* ' */ + {0x0a,0xb2,0xb3,0x0b,0,0,0}, /* ( */ + {0x0a,0xb4,0xb5,0x0b,0,0,0}, /* ) */ + {0x0a,0xb0,0xb1,0x0b,0,0,0}, /* * */ + {0x0a,0xb8,0xb9,0x0b,0,0,0}, /* + */ + {0xe2,0xe3,0,0,0,0,0}, /* , */ + {0xb6,0xb7,0,0,0,0,0}, /* - */ + {0xe4,0xe5,0,0,0,0,0}, /* . */ + {0xe6,0xe7,0,0,0,0,0}, /* / */ + {0xb4,0xb5,0,0,0,0,0}, /* 0 */ + {0x7c,0x7d,0,0,0,0,0}, /* 1 */ + {0x7a,0x7b,0,0,0,0,0}, /* 2 */ + {0x78,0x79,0,0,0,0,0}, /* 3 */ + {0x76,0x77,0,0,0,0,0}, /* 4 */ + {0x74,0x75,0,0,0,0,0}, /* 5 */ + {0x72,0x73,0,0,0,0,0}, /* 6 */ + {0x70,0x71,0,0,0,0,0}, /* 7 */ + {0xb0,0xb1,0,0,0,0,0}, /* 8 */ + {0xb2,0xb3,0,0,0,0,0}, /* 9 */ + {0x0a,0xd6,0xd7,0x0b,0,0,0}, /* : */ + {0xd6,0xd7,0,0,0,0,0}, /* ; */ + {0x0a,0xe2,0xe3,0x0b,0,0,0}, /* < */ + {0xb8,0xb9,0,0,0,0,0}, /* = */ + {0x0a,0xe4,0xe5,0x0b,0,0,0}, /* > */ + {0x0a,0xe6,0xe7,0x0b,0,0,0}, /* ? */ + {0x0a,0x7a,0x7b,0x0b,0,0,0}, /* @ */ + {0x0a,0x5a,0x5b,0x0b,0,0,0}, /* A */ + {0x0a,0x30,0x31,0x0b,0,0,0}, /* B */ + {0x0a,0x34,0x35,0x0b,0,0,0}, /* C */ + {0x0a,0x56,0x57,0x0b,0,0,0}, /* D */ + {0x0a,0x68,0x69,0x0b,0,0,0}, /* E */ + {0x0a,0x54,0x55,0x0b,0,0,0}, /* F */ + {0x0a,0x52,0x53,0x0b,0,0,0}, /* G */ + {0x0a,0x50,0x51,0x0b,0,0,0}, /* H */ + {0x0a,0xc0,0xc1,0x0b,0,0,0}, /* I */ + {0x0a,0xd0,0xd1,0x0b,0,0,0}, /* J */ + {0x0a,0xd2,0xd3,0x0b,0,0,0}, /* K */ + {0x0a,0xd4,0xd5,0x0b,0,0,0}, /* L */ + {0x0a,0xe0,0xe1,0x0b,0,0,0}, /* M */ + {0x0a,0xf0,0xf1,0x0b,0,0,0}, /* N */ + {0x0a,0xc2,0xc3,0x0b,0,0,0}, /* O */ + {0x0a,0xc4,0xc5,0x0b,0,0,0}, /* P */ + {0x0a,0x6c,0x6d,0x0b,0,0,0}, /* Q */ + {0x0a,0x66,0x67,0x0b,0,0,0}, /* R */ + {0x0a,0x58,0x59,0x0b,0,0,0}, /* S */ + {0x0a,0x64,0x65,0x0b,0,0,0}, /* T */ + {0x0a,0x60,0x61,0x0b,0,0,0}, /* U */ + {0x0a,0x32,0x33,0x0b,0,0,0}, /* V */ + {0x0a,0x6a,0x6b,0x0b,0,0,0}, /* W */ + {0x0a,0x36,0x37,0x0b,0,0,0}, /* X */ + {0x0a,0x62,0x63,0x0b,0,0,0}, /* Y */ + {0x0a,0x38,0x39,0x0b,0,0,0}, /* Z */ + {0xc6,0xc7,0,0,0,0,0}, /* [ */ + {0xca,0xcb,0,0,0,0,0}, /* \ */ + {0xc8,0xc9,0,0,0,0,0}, /* ] */ + {0x0a,0x72,0x73,0x0b,0,0,0}, /* ^ */ + {0x0a,0xb6,0xb7,0x0b,0,0,0}, /* _ */ + {0x7e,0x7f,0,0,0,0,0}, /* ` */ + {0x5a,0x5b,0,0,0,0,0}, /* a */ + {0x30,0x31,0,0,0,0,0}, /* b */ + {0x34,0x35,0,0,0,0,0}, /* c */ + {0x56,0x57,0,0,0,0,0}, /* d */ + {0x68,0x69,0,0,0,0,0}, /* e */ + {0x54,0x55,0,0,0,0,0}, /* f */ + {0x52,0x53,0,0,0,0,0}, /* g */ + {0x50,0x51,0,0,0,0,0}, /* h */ + {0xc0,0xc1,0,0,0,0,0}, /* i */ + {0xd0,0xd1,0,0,0,0,0}, /* j */ + {0xd2,0xd3,0,0,0,0,0}, /* k */ + {0xd4,0xd5,0,0,0,0,0}, /* l */ + {0xe0,0xe1,0,0,0,0,0}, /* m */ + {0xf0,0xf1,0,0,0,0,0}, /* n */ + {0xc2,0xc3,0,0,0,0,0}, /* o */ + {0xc4,0xc5,0,0,0,0,0}, /* p */ + {0x6c,0x6d,0,0,0,0,0}, /* q */ + {0x66,0x67,0,0,0,0,0}, /* r */ + {0x58,0x59,0,0,0,0,0}, /* s */ + {0x64,0x65,0,0,0,0,0}, /* t */ + {0x60,0x61,0,0,0,0,0}, /* u */ + {0x32,0x33,0,0,0,0,0}, /* v */ + {0x6a,0x6b,0,0,0,0,0}, /* w */ + {0x36,0x37,0,0,0,0,0}, /* x */ + {0x62,0x63,0,0,0,0,0}, /* y */ + {0x38,0x39,0,0,0,0,0}, /* z */ + {0x0a,0xc6,0xc7,0x0b,0,0,0}, /* { */ + {0x0a,0xca,0xcb,0x0b,0,0,0}, /* | */ + {0x0a,0xc6,0xc9,0x0b,0,0,0}, /* } */ + {0x0a,0x7e,0x7f,0x0b,0,0,0}, /* ~ */ + {0x0a,0x3e,0x3f,0x0b,0,0,0}}; /* delete */ +#endif diff --git a/xc/programs/Xserver/hw/hp/input/screentab.h b/xc/programs/Xserver/hw/hp/input/screentab.h new file mode 100644 index 000000000..7d2cf9654 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/screentab.h @@ -0,0 +1,73 @@ +/* $TOG: screentab.h /main/5 1998/02/10 13:11:20 kaleb $ */ +/* + +Copyright 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ +/* + * Header file which declares structures to initialize and close + * each type of screen supported by the X server. + * + */ + +typedef struct { + char *productNumber; + char *productNickname; + Bool (*InfoScreen)(); + Bool (*InitScreen)(); + Bool (*CloseScreen)(); + } ScreenTableRec; + +typedef ScreenTableRec ScreenTable[]; + +typedef struct { + int position; + int left; + int right; + } MultiScreenRec; + +extern ScreenTable screenTable; + +extern MultiScreenRec multiScreenTable[]; diff --git a/xc/programs/Xserver/hw/hp/input/x_hil.c b/xc/programs/Xserver/hw/hp/input/x_hil.c new file mode 100644 index 000000000..316f2fdec --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/x_hil.c @@ -0,0 +1,1691 @@ +/* $TOG: x_hil.c /main/9 1998/02/10 13:11:38 kaleb $ */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: ddx/hp/hp/x_hil.c +** * +** * Contents: Input event procedures for the +** * X/Starbase Merged Server +** * +** * Created: 4/28/88 +** * +** * Last Change: 12/05/88 +** * +** * Last Release: IC2 +** * +** * Revision: A.01.00 +** * +** * Author: --gms +** * +** * Copyright: (c) 1988 Hewlett-Packard Company +** * +** ********************************************************* +** +********************************************************************/ +/* $XFree86: xc/programs/Xserver/hw/hp/input/x_hil.c,v 3.1 1998/10/04 09:38:27 dawes Exp $ */ + +/* + +Copyright 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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 +#include "X.h" +#include "XI.h" +#include "Xproto.h" +#include "Xpoll.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 "hppriv.h" +#include <sys/times.h> +#include <sys/hilioctl.h> +#ifdef XKB +#include "XKBsrv.h" +extern Bool noXkbExtension; +#endif +#ifdef XINPUT +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#endif + +#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 +/* + * defined in xtestext1di.c + */ +extern int on_steal_input; +extern int exclusive_steal; +#endif /* XTESTEXT1 */ + +/****************************************************************** + * + * Externs and variables referenced from other files. + * + */ + +extern char *mflg; +xEvent *format_ev(); +xHPEvent xE, zxE; + +#ifdef XINPUT +extern int DeviceMotionNotify; +extern int DeviceKeyPress; +extern int DeviceKeyRelease; +extern int DeviceButtonPress; +extern int DeviceButtonRelease; +extern int DeviceValuator; +extern int ProximityIn; +extern int ProximityOut; +#endif /* XINPUT */ +extern int axes_changed; +extern int keyboard_click; +extern int screenIsSaved; +extern int x_axis, y_axis; +extern int max_input_fd; +extern HPInputDevice l_devs[MAX_LOGICAL_DEVS]; +extern HPInputDevice *hpKeyboard; +extern HPInputDevice *hpPointer; +extern HPInputDevice *hptablet_extension; +extern WindowPtr *WindowTable; +extern InputInfo inputInfo; +extern DeviceIntPtr screen_change_dev; +extern DeviceIntPtr tablet_extension_device; + +extern unsigned tablet_xorg; +extern unsigned tablet_yorg; +extern unsigned tablet_xlimit; +extern unsigned tablet_ylimit; +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; +int threshold; +struct x11EventQueue *events_queue; /* pointer to events queue. */ +xHPEvent *allocate_event(); +struct dev_info hil_info; /* holds hil_data */ + +/****************************************************************** + * + * Variables global to this file. + * + */ + +static DeviceIntPtr find_deviceintrec(); +static int process_inputs(); +static void process_serial_data(); +static check_subset_and_scale(); +static move_sprite(); +static send_motion(); +static send_button(); +static move_mouse(); +static u_char last_direction; +static u_char last_key; +static int k_down_flag[4]; +static int k_down_incx[4]; +static int k_down_incy[4]; + +/**************************************************************************** + * + * Process all available data from the input devices and put it on the server's + * internal events queue. When this routine is invoked, that queue is empty + * since the server empties it each time through its main dispatch loop. + * + * The server's internal queue can hold 256 events. If the server is busy for + * a long time, it is possible for the queue to fill up. In that case we + * can return with unread data, or data that is left in a global buffer. + * This routine must be prepared to handle such leftover data. + * + * After handling leftovers, this routine finds a file descriptor with data + * ready to be read and calls process_inputs to handle it. + * + */ + +CheckInput (blockData, result, pReadmask) + pointer blockData; + int result; + pointer pReadmask; + { + fd_set* LastSelectMask = (fd_set*)pReadmask; + fd_set mask, checkmask; + extern fd_set EnabledDevices; + int i; + int checkfd = max_input_fd; /* max fd valid for input*/ + int checkword = checkfd >> 5; /* max valid word of mask*/ + + if (result <= 0) + return; + XFD_ANDSET(&mask, LastSelectMask, &EnabledDevices); + if (!XFD_ANYSET(&mask)) + return; + + FD_ZERO(&checkmask); + + FD_SET(checkfd, &checkmask); /* corresponding mask */ + + for (i=checkword; i>=0; i--) /* for all mask words */ + { + while (mask.fds_bits[i] && + checkmask.fds_bits[i]) /* while input available*/ + { + if (mask.fds_bits[i] & checkmask.fds_bits[i]) /* current fd valid */ + { + mask.fds_bits[i] &= ~checkmask.fds_bits[i]; + process_inputs(checkfd); /* process its input */ + } + checkfd--; + checkmask.fds_bits[i] = checkmask.fds_bits[i] >> 1; + } + if (i>0) + { + checkfd = (i-1) * 32 + 31; + FD_SET(checkfd, &checkmask); /* corresponding mask */ + } + } + } + +/**************************************************************************** + * + * Find the device data structure that matches the file descriptor from which + * data will be read. Read up to 2000 bytes (HIL driver buffer is only 512) + * from that file descriptor. From the data read, get 1 HIL data packet. + * That packet may contain up to 8 keycodes and 1 motion event. In the case + * of a barcode reader in ASCII mode, each keycode may generate up to 6 + * X input events. The worst case is therefore 49 X events from 1 HIL data + * packet. + * + */ + +static int process_inputs (file_ds) + int file_ds; /* file_ds to read from */ + { + int i; + u_char *hil_ptr; + HPInputDevice *indevice = NULL; + DeviceIntPtr dev; + xHPEvent *xHP; + Bool done = FALSE; + + for (i=0; i<MAX_LOGICAL_DEVS; i++) + { + if (file_ds == l_devs[i].d.file_ds) + { + indevice = &(l_devs[i]); + break; + } + } + + 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*/ + *xHP = xE; /* copy from global struct */ + xE = zxE; /* mark it as processed */ + } + } + +/*************************************************************************** + * + * Given the HP device structure, find the DIX device structure that + * logically corresponds to it. There is a one-to-one correspondence, + * expect when the keyboard is also the X pointer, a tablet is subsetted, + * or an input device is merged with the X pointer or X keyboard. + * + * Callers: process_inputs(), read_shmhil(). + * + */ + +static +DeviceIntPtr find_deviceintrec (indevice) + HPInputDevice *indevice; + { + PtrFeedbackPtr p; + DeviceIntPtr dev = NULL; + + if (indevice != NULL) + { + 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; + dev = tablet_extension_device; + } + else if (indevice==hpKeyboard || (indevice->x_type==KEYBOARD && + (indevice->hpflags & MERGED_DEVICE))) + dev = inputInfo.keyboard; + else if (indevice==hpPointer || (indevice->x_type==MOUSE && + (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) + { + threshold = p->ctrl.threshold; + acceleration = (float) p->ctrl.num / (float) p->ctrl.den; + } +#endif /* XINPUT */ + if (acceleration == 0) + acceleration = 1; + } + else + FatalError ("X server couldn't find current input device - Aborting.\n"); + return (dev); + } + +/**************************************************************************** + * + * process the serial data packet and generate X input events as needed. + * + */ + +static u_int s_code[2]; + +static void process_serial_data (dev, phys, info) + DeviceIntPtr dev; + HPInputDevice *phys; + struct dev_info *info; + { + xEvent *ev; + u_int *hil_code; + u_char type, kcode; + + while (pending_index < pending_bytes ) + { + if (info->poll_hdr & MOTION_DATA) + { + handle_motion_event (dev, phys, info); + if (pending_index >= pending_bytes) + return; + } + + hil_code = s_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+1] << 8) | + (info->dev_data)[pending_index]; + pending_index += 2; + } + else if (phys->hpflags & DATA_IS_32_BITS) + { + *hil_code = ((info->dev_data)[pending_index+3] << 24) | + (info->dev_data)[pending_index+2] << 16 | + (info->dev_data)[pending_index+1] << 8 | + (info->dev_data)[pending_index]; + pending_index += 4; + } + else + { + pending_index = pending_bytes; + return; + } + + if (info->poll_hdr & KEY_DATA) + { + /* 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. + */ + + kcode = (u_char) (*hil_code >> 1); /* same code up & down */ + kcode += MIN_KEYCODE; /* avoid mouse codes. */ + + if (*hil_code & UP_MASK) + if (dev==inputInfo.keyboard || dev==inputInfo.pointer) + type = KeyRelease; + else + type = DeviceKeyRelease; + else + { + if (KeyIsDown(dev,kcode) && !KeyIsRepeating(dev,kcode)) + return; + if (dev==inputInfo.keyboard || dev==inputInfo.pointer) + type = KeyPress; + else + 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) + { + /* 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. + */ + 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; + } + } + } + +/******************************************************************* + * + * handle_motion_event() + * + */ + +handle_motion_event (dev, phys, info) + DeviceIntPtr dev; + HPInputDevice *phys; + struct dev_info *info; + { + int i, type, bytes_coord; + int tmp, coords[MAX_AXES]; + char *sdata; + u_char *udata; + HPInputDevice *log; + + if (dev==inputInfo.pointer) + { + type = MotionNotify; + log = hpPointer; + } + else + { + type = DeviceMotionNotify; + log = phys; + } + if (phys->hpflags & DATA_IS_32_BITS) + bytes_coord = 4; + else if (phys->hpflags & DATA_IS_16_BITS) + bytes_coord = 2; + 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); + + if (!check_subset_and_scale (&dev, phys, &log, coords)) + return; + } + 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); + } + + if (phys==hpPointer && axes_changed) + { + tmp = coords[0]; + coords[0] = coords[x_axis]; + if (y_axis==0) + coords[1] = tmp; + else + coords[1] = coords[y_axis]; + } + process_motion (dev, phys, log, coords, info->timestamp); + (void) format_ev (dev, type, 0, info->timestamp, log, &xE); + } + +/******************************************************************* + * + * check_subset_and_scale() + * all we care about is the x and y coordinates. + * + */ + +static +check_subset_and_scale (dev, phys, log, c) + DeviceIntPtr *dev; + HPInputDevice *phys; + HPInputDevice **log; + 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) + { + in_tablet_extension = TRUE; + *dev = tablet_extension_device; + *log = hptablet_extension; + } + else + { + in_tablet_extension = FALSE; + } + + if (*log == hpPointer) + { + if (*dev == screen_change_dev) + c[0] = (float) (c[0]-tablet_xorg) * phys->scaleX-screen_change_amt; + else + c[0] = (float) (c[0]-tablet_xorg) * phys->scaleX; + c[1] = (*log)->pScreen->height - + ((float) (c[1]-tablet_ylimit) * phys->scaleY); + } + else + { + 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); + for (i=0; i<n_axes; i++) + c[i] -= (*log)->coords[i]; + return (TRUE); + } + +/**************************************************************************** + * + * parse_keycode (dev, phys, ev, x_type) + * Parse keycode information. + * Buttons from a three-button mouse also end up here. + * + */ + +#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; + HPInputDevice *phys; + xEvent *ev; + { +#ifdef XTESTEXT1 + 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. + */ + +#ifdef XKB + if (noXkbExtension) { +#endif + + 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 XKB + } +#endif + +#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 */ + } + +/************************************************************************ + * + * This routine checks to see if the key should be interpreted as a + * sprite movement or a button. + * + */ + +static move_sprite (dev, phys, ev) + DeviceIntPtr dev; + HPInputDevice *phys; + xEvent *ev; + { + u_char down_mods; + u_char key = ev->u.u.detail; + u_char type = ev->u.u.type; + int inc; + Bool motion_mods; + + get_down_modifiers (dev, &down_mods); + if (down_mods & (~ptr_mods & ~mv_mods)) + motion_mods = FALSE; + else if ((down_mods & ptr_mods) == ptr_mods) + motion_mods = TRUE; + else + motion_mods = FALSE; + + if (!(down_mods & mv_mods)) + inc = pointer_move; + else if ((down_mods & mv_mods) == pointer_amt_bits[0]) + inc = pointer_mod1_amt; + else if ((down_mods & mv_mods) == pointer_amt_bits[1]) + inc = pointer_mod2_amt; + else if ((down_mods & mv_mods) == pointer_amt_bits[2]) + inc = pointer_mod3_amt; + else + motion_mods = FALSE; + + k_down_incy[DOWN] = inc; + k_down_incx[RIGHT] = inc; + k_down_incy[UP] = inc * -1; + k_down_incx[LEFT] = inc * -1; + + if (key==cursor_down && type==KeyPress && motion_mods) + return (send_motion (phys, ev, 0, inc, DOWN)); + else if (key==cursor_down && type==KeyRelease) + { + k_down_flag[DOWN] = 0; + return (1); + } + else if (key==cursor_left && type==KeyPress && motion_mods) + return (send_motion (phys, ev, inc * -1, 0, LEFT)); + else if (key==cursor_left && type==KeyRelease) + { + k_down_flag[LEFT] = 0; + return (1); + } + else if (key==cursor_right && type==KeyPress && motion_mods) + return (send_motion (phys, ev, inc, 0, RIGHT)); + else if (key==cursor_right && type==KeyRelease) + { + k_down_flag[RIGHT] = 0; + return (1); + } + else if (key==cursor_up && type==KeyPress && motion_mods) + return (send_motion (phys, ev, 0, inc * -1, UP)); + else if (key==cursor_up && type==KeyRelease) + { + k_down_flag[UP] = 0; + return (1); + } + else + { + if (type==KeyPress) + type = ButtonPress; + if (type==KeyRelease) + type = ButtonRelease; + + if (key == button_1) + return (send_button (ev, type, 1)); + else if (key == button_2) + return (send_button (ev, type, 2)); + else if (key == button_3) + return (send_button (ev, type, 3)); + else if (key == button_4) + return (send_button (ev, type, 4)); + else if (key == button_5) + return (send_button (ev, type, 5)); + else if (key == button_6) + return (send_button (ev, type, 6)); + else if (key == button_7) + return (send_button (ev, type, 7)); + else if (key == button_8) + return (send_button (ev, type, 8)); + } + return (0); + } + +/**************************************************************************** + * + * Send motion information from the keyboard, when it is the pointer device. + * + */ + +static send_motion (phys, ev, x, y, which) + HPInputDevice *phys; + xEvent *ev; + int x, y, which; + { + int coords[MAX_AXES]; + unsigned int time; + int i; + + for (i=0; i<4; i++) + if (i != which && k_down_flag[i] != 0) + { + x += k_down_incx[i]; + y += k_down_incy[i]; + } + coords[0] = x; + coords[1] = y; + k_down_flag[which] = 1; + 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); + } + +/**************************************************************************** + * + * Send button information from the keyboard, when it is the pointer device. + * + */ + +static send_button (ev, direction, bcode) + xEvent *ev; + u_char direction, bcode; + { + + if (bcode == last_key && direction == last_direction) + deallocate_event(ev); + else + { + ev->u.u.type = direction; + ev->u.u.detail = bcode; + last_key = bcode; + last_direction = direction; +#ifdef XTESTEXT1 + if (on_steal_input) + XTestStealKeyData(ev->u.u.detail, ev->u.u.type, MOUSE, + ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootY); +#endif /* XTESTEXT1 */ + } + + return (1); + } + +/**************************************************************************** + * + * process_motion (hil_info) + * + * This function may also be called from x_threebut.c and x_tablet.c. + * It requires the motion passed to be a relative amount. + * dev_hp and dev are the logical devices, phys is the actual device. + * + */ + +#define DEF_ACCELERATION 1 +#define EDGE_L 1 << 0 +#define EDGE_R 1 << 1 +#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; + HPInputDevice *phys, *log; + int c[]; + unsigned int timestamp; + { + 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. + * No acceleration for absolute pointing devices. + * No acceleration if we're using the default (1) acceleration. + */ + + 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) + c[i] = (c[i] + threshold) * acceleration - threshold; + } + } + + /* + * If this is the pointer or a device whose input is merged + * with the pointer, accumulate the motion and maintain a current position. + * 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 + /* + * Needed for the case where a tablet is the X pointer device. + * Once we change screens, we want to avoid immediately changing + * back. We change when we enter the screen change area and + * do not change again until after we have left it. + */ + 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); + } + +/**************************************************************************** + * + * change_the_screen() + * We have more than one screen, and the screen_change_device has been moved + * off one of the edges. Change to another screen. + * + */ + +#define INCREMENT_SCREEN_BY_ONE(p,l) (screenInfo.screens[(p->myNum+1) % \ + screenInfo.numScreens]) + +#define DECREMENT_SCREEN_BY_ONE(p,l) (p->myNum != 0 ? \ + screenInfo.screens[p->myNum-1] : \ + screenInfo.screens[screenInfo.numScreens - 1]) + +#define INCREMENT_SCREEN_BY_TWO(p,l) (screenInfo.screens[(p->myNum+2) % \ + screenInfo.numScreens]) + +#define DECREMENT_SCREEN_BY_TWO(p,l) (p->myNum > 1 ? \ + 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) + { + if (screen_orientation == VERTICAL) + screen_col_wrap = WRAP; + else + screen_col_wrap = NOWRAP; + } + + if (screen_row_wrap == DEFAULT) + { + if (screen_orientation == HORIZONTAL) + screen_row_wrap = WRAP; + else + 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); + } + +/**************************************************************************** + * + * move_mouse () + * move the sprite, if the device is the pointer. + * Also move it if some other device is sending MotionNotify events. + * In any case, send a motion event to dix. + * + * This routine may also be called from xtest1dd.c + * + */ + +static +move_mouse (log, event_time) + HPInputDevice *log; /* logical device */ + 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; + } + +/************************************************************************** + * + * Called by: hpMouseProc during device initialization, process_motion + * whenever we change screens. + * + * This routine sets the scaling factor to be used for absolute pointing + * devices like graphics tablets. Input from these devices is scaled to + * the screen size. If we have a multi-screen environment, the scaling + * factor must be changed whenever the screen changes. + * + * This routine also sets the margin at the screen edge that will be used + * to change screens. For tablets, this is initially 0, allowing the + * entire tablet surface to be used by the application. If a tablet is + * the X pointer and a multi-screen environment is being used, the + * screen_change_amt variable should be initialized to some value (like 30) + * to define a area at the tablet edges that will cause the screen to change. + * + * Tablet subsetting adds more complications. The user can define a subset + * area that used as the X pointer, while the remainder of the tablet surface + * is treated as a second logical device. It is this second logical device + * 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 + + /* This code is called if we are initializing the second logical + device, or if tablet subsetting is not enabled. It is also + called when we are changing screens with a tablet as the X + pointer device. + + */ + { + /* + 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 + change the scale of the X pointer. Since input from + 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 + /* The tablet is the X pointer. Screen change units + are in pixels, since the input will be scaled. + */ + { + d->change_xmin = 1; + d->change_xmax = newScreen->width - 2; + d->change_ymin = 1; + d->change_ymax = newScreen->height - 2; + d->change_amt = 0; + } + } + } + else + + /* This code is called when a relative device is initialized, + and when we are changing screens with a relative device. + These devices (mice, trackballs, dialboxes, spaceballs) + cause us to change screens by generating values that are + beyond the edge of the screen. + */ + + { + d->change_xmin = 0; + d->change_xmax = newScreen->width; + d->change_ymin = 0; + d->change_ymax = newScreen->height; + d->change_amt = screen_change_amt; + } + } + +/**************************************************************************** + * + * queue_motion_event () + * This is a convenience routine for xosSetCursorPosition. + * It is used to artifically generate a motion event when WarpPointer + * request is made. + * + */ + +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; + } + +/**************************************************************************** + * + * format_ev ( ) + * format one or more key, button, motion or proximity xEvents. + * This routine assumes devices have less than 6 axes, or report only + * one axis per event. + */ + +#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) + ret = (xEvent *) event; + + event->b.u.u.type = type; + event->b.u.u.detail = detail; + 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]; + else + *ip++ = 0; + event = NULL; + } + } +#endif /* XINPUT */ + } + + return (ret); + } + +/******************************************************************** + * + * ProcessInputEvents() + * This routine is invoked from the dispatcher to route events. + * It invokes the dix routines to do this. + * + */ + +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; + } + event = &((events_queue->events)[(events_queue->head)]); + + switch (event->b.u.u.type) + { + 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) + { + ip = &event->x.valuator0; + 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; + } + + if (events_queue->head == WR_EVENTS) + events_queue->head = 0; + else + events_queue->head++; + + } + 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); +} diff --git a/xc/programs/Xserver/hw/hp/input/x_hil.h b/xc/programs/Xserver/hw/hp/input/x_hil.h new file mode 100644 index 000000000..ab21d1ddf --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/x_hil.h @@ -0,0 +1,93 @@ +#ifndef X_HIL_H +#define X_HIL_H +/* $TOG: x_hil.h /main/5 1998/02/10 13:11:44 kaleb $ */ +/* + +Copyright 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ +#include "hpext.h" + +/* MAXHILEVENTS is the maximum number of X events that can + be put on the events queue as the result of reading a + single HIL data packet. The HIL definition is that + a packet may contain one motion event and up to 8 bytes + of key data. If the key device is a barcode reader in + ASCII mode, we translate each ASCII code into up to 6 + keycodes. The maximum number of X events that can be + generated from a single HIL packet is therefore 49. + + MAX_EVENTS is the size of the server's internal queue of + input events. X input is a two-step process, with the + first step consisting of reading input events from the + device and putting them on this internal queue. Later + in the dispatch loop, that queue is emptied and all the + events are routed by DIX to the appropriate clients. + + The size of the event queue is not as large as the + theoretical maximum, but motion events are compressed + into a single event until a key or button is seen. + + The worst at all reasonable case is alternating key and + motion data, which would result in less than 50 events. + A more reasonable guess is 20 events per device. + Our queue size therefore allows for the worst case on + 5 - 10 devices simultaneously. +*/ + +#define MAXHILEVENTS 49 +#define MOTION_BUFFER_SIZE 100 +#define MAX_EVENTS 256 +#define WR_EVENTS MAX_EVENTS-1 + +struct x11EventQueue + { + xHPEvent *events; + int size; + int head; + int tail; + }; + +#endif diff --git a/xc/programs/Xserver/hw/hp/input/x_hilinit.c b/xc/programs/Xserver/hw/hp/input/x_hilinit.c new file mode 100644 index 000000000..0f404c5dd --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/x_hilinit.c @@ -0,0 +1,2385 @@ +/* $TOG: x_hilinit.c /main/10 1998/02/10 13:11:28 kaleb $ */ +/* + +Copyright 1988, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ +/* $XFree86: xc/programs/Xserver/hw/hp/input/x_hilinit.c,v 3.3 1998/10/04 09:38:28 dawes Exp $ */ + +#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 +#define LIBDIR "/etc/X11" +#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" +#include "inputstr.h" +#include "../../../os/osdep.h" + +#ifdef XINPUT +#include "XI.h" +#include "XIproto.h" +#include "XIstubs.h" +#else +#define Relative 0 +#define Absolute 1 +#endif /* XINPUT */ + +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ + +#ifdef XKB +#undef IsKeypadKey +#include <X11/extensions/XKB.h> +#include <X11/extensions/XKBstr.h> +#include <X11/extensions/XKBsrv.h> +#endif + +/****************************************************************** + * + * Externs and global variables that may be referenced by other files. + * + */ + +char *mflg="TRUE"; +HPInputDevice *hpKeyboard; +HPInputDevice *hpPointer; +HPInputDevice *hptablet_extension; + +#ifdef XINPUT +extern int BadDevice; +extern int BadMode; +extern int IReqCode; +extern int DeviceKeyPress; +extern int DeviceKeyRelease; +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 tablet_extension_device; +DeviceIntPtr screen_change_dev; + +int HPType; + +/****************************************************************** + * + * Variables that are global to this file only. + * + */ + +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); +} + +/**************************************************************************** + * + * Procedures to control Integer and String feedbacks. + * These are not used by currently supported devices, but serial input devices + * could use them. + */ + +static hpChangeIntegerControl(pDevice, ctrl) + 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); + } + +/**************************************************************************** + * + * Change acceleration & threshold. + * The DIX routine that handles the ChangePointerControl request has + * already validity checked the values and copied them into the + * DeviceIntRec. This routine just copies them into fields that are + * the same no matter what kind of device we're dealing with. + * + */ + +static hpChangePointerControl(pDevice, ctrl) + DevicePtr pDevice; + 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; +#else + extern int threshold; + extern float acceleration; + + threshold = ctrl->threshold; + acceleration = (float) ctrl->num / (float) ctrl->den; + if (acceleration <= 0) + acceleration = 1; +#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); + } + +/**************************************************************************** + * + * The members of the ledCtrl structure have the following values: + * + * mask: 1 bit per LED. + * value: if mask set, turn it on or off. + * + */ + +static hpChangeLedControl(pDevice, ctrl) + DevicePtr pDevice; + 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); + } + +/**************************************************************************** + * + * The members of the keybdCtrl structure have the following values: + * + * click: 0(off) - 100 (loud); -1 => default; + * bell: 0(off) - 100 (loud); -1 => default; + * bell_pitch: Pitch of the bell in Hz;-1 => default; + * bell_duration: in miliseconds; -1 => default; + * + * keyboard_click is checked whenever a key is pressed, in x_hil.c. + */ + +static hpChangeKeyboardControl(pDevice, ctrl) + DevicePtr pDevice; + 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; + dctrl->click = ctrl->click; + dctrl->bell_percent = ctrl->bell; + dctrl->bell_pitch = ctrl->bell_pitch; + dctrl->bell_duration = ctrl->bell_duration; + dctrl->autoRepeat = ctrl->autoRepeat; + memmove(dctrl->autoRepeats, ctrl->autoRepeats, 32); + dctrl->leds = ctrl->leds; + } + +/**************************************************************************** + * + * 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); + } + else + last = pmBuf-size; + + if (*pmBuf == 0) /* haven't wrapped yet */ + first = hmBuf; + else + first = pmBuf; + + if (start > *last) /* start time > last time */ + return 0; + else + { + curr = first; + while (*curr < start) + { + curr += size; + if (curr == hmBuf+(100*size)) + curr = hmBuf; + if (curr == first) + return 0; + } + while (*curr <= stop && *curr != 0) + { + if (dev == inputInfo.pointer) /*X pointer is 16 bits/axis */ + { + *buffp++ = *curr++; /* copy the time */ + *buffp++ = *curr << 16 | *(curr+1); /* copy data for 2 axes */ + curr += 2; + } + else /* other devices are 32 bits */ + for (i=0; i<size; i++) + *buffp++ = *curr++; + evcount++; + if (curr == hmBuf+(100*size)) + curr = hmBuf; + if (curr == first) + break; + } + } + return (evcount); + } + +/**************************************************************************** + * + * NOTE: The first parameter passed to this routine is really a DeviceIntPtr. + * The declaration used here works because the first element of the + * structure pointed to by the DeviceIntPtr is a DeviceRec. + * + */ + +#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}; + +extern Bool noXkbExtension; + +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 */ + + switch (onoff) + { + 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 */ + + +#ifdef XKB + if (noXkbExtension) { +#endif + InitKeyboardDeviceStruct(pDev, key_syms, the_modmap, + (BellProcPtr) hpBell, + (KbdCtrlProcPtr) hpChangeKeyboardControl); +#ifdef XKB + } else { + XkbComponentNamesRec names; + + names.keymap = NULL; + names.types = "types/complete"; + names.compat = "compat/complete"; + if ((pHP->id_detail & PS2_KEYBD) == PS2_KEYBD) { + names.keycodes = "keycodes/hp"; + names.symbols = "symbols/us(pc101)"; + names.geometry = "geometry/hp"; + } else { + names.keycodes = "keycodes/hp(hil)"; + names.symbols = "symbols/hp/us(hil)"; + names.geometry = "geometry/hp(hil)"; + }; + XkbInitKeyboardDeviceStruct((DeviceIntPtr) pDev, &names, + key_syms, the_modmap, (BellProcPtr) hpBell, + (KbdCtrlProcPtr) hpChangeKeyboardControl); + } +#endif + + + 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; + if (dev->button) { + 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); + dev->key->state = 0; + 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); + } + +/**************************************************************************** + * + * InitInput -- + * Initialize pointer and keyboard devices. + * + */ + +void InitInput(argc, argv) + int argc; + char **argv; + { + int i, j; + DeviceIntPtr x_init_device(); + int CheckInput(); + + mflg = (char *)getenv("XHPPRINTDEBUGMSG"); + max_input_fd = 0; + x_axis = 0; + y_axis = 1; + axes_changed = FALSE; + hpPointer = NULL; + hpKeyboard = NULL; + 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); + i++; + } + } + +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. + * + */ + +DeviceIntPtr +x_init_device (dev, start_it) + HPInputDevice *dev; + Bool start_it; + { + DevicePtr pXDev; + + pXDev = hpAddInputDevice(hpDeviceProc, start_it, dev); + if (dev==hpKeyboard) + { + 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; + screen_change_dev = tablet_extension_device; + } + } +#endif /* XINPUT */ + + 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; + } + +/******************************************************************** + * + * + * + * + */ + +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; +} + +/******************************************************************** + * + * get_codes() + * Used to assign codes to keys used to move the pointer. + * Also to assign numbers to the amount to move the pointer. + * This routine uses the index into the file to determine the keycode. + * The down keycode is (index * 2), the up keycode is that plus 1. + * If the type is NUMBER, the key string is assumed to be an ascii + * representation of a number. + * This is used as the increment to move the pointer. + * + */ + +static get_codes (key, code, type, makeupper) + char *key; + int *code; + int type; + Bool makeupper; + { + int i; + + if (makeupper) + for (i=0; i<strlen(key); i++) + *(key+i) = toupper(*(key+i)); + + if (type == UCHAR_NUMBER || type == USHORT_NUMBER || type == UINT_NUMBER) + { + *code = atoi (key); + return (0); + } + else if (type == STRING) + for (i=0; i<MAX_STRINGS; i++) + if (strcmp (key, strings[i].string) == 0) + { + *code = strings[i].value; + return (0); + } + for (i=0; *keyset1[i].keystr; i++) + if (strcmp (key, keyset1[i].keystr) == 0) + break; + if (!inputInfo.keyboard) + return(0); + *code = HPKeySymToKeyCode(inputInfo.keyboard, keyset1[i].sym); + if (*code) + return(0); + return (-1); + } + +int +HPKeySymToKeyCode (dev, sym) + DeviceIntPtr dev; + KeySym sym; +{ + int i; + register KeySym *syms; + KeySymsPtr rec; + + rec = &dev->key->curKeySyms; + syms = rec->map; + for (i=0; i<rec->maxKeyCode - rec->minKeyCode + 1; i++) + { + if (*syms == sym) + return (i + rec->minKeyCode); + syms += rec->mapWidth; + } + return(0); +} + +/******************************************************************** + * + * get_vars() + * get the address of variables to contain keycodes for pointer functions. + * + */ + +static get_vars (func, codevar, index) + char *func; + u_char **codevar; + int *index; + { + int i; + + for (i=0; i<strlen(func); i++) + *(func+i) = toupper(*(func+i)); + + for (i=0; i<MAX_POINTER_FUNCS; i++) + if (strcmp (func, pointerfunc[i].name) == 0) + { + *codevar = pointerfunc[i].code; + *index = i; + return (0); + } + return (-1); + } + +/******************************************************************** + * + * get_pointerkeys(). + * This routine provides the ability to configure keyboard keys to + * move the pointer and act like buttons on the pointer device. + * The file processed is the X*pointerkeys file, which consists + * of pairs. The form is: + * + * function key, modifier, or value + * + * Look at the pointerfunc table in x_hilinit.h to understand this code. + * There are 3 types of assignment done: + * 1). keys - have both a down and an up code to assign. + * 2). modifiers - are a bit position in a mask. + * 3). values - are a single integer number. + * Possible errors: + * 1). only 1 of the pair was specified. + * 2). an invalid function was specified. + * 3). an invalid key or modifier was specified. + */ + +get_pointerkeys() + { + char fname[MAXNAMLEN+1]; + FILE *fp; + int len; + int cret; + int vret; + int ret2; + int index; + char buf[MAXNAMLEN+1]; + char function[MAXNAMLEN+1]; + char key[MAXNAMLEN+1]; + char *fgets(); + int code; + union + { + u_char *cptr; + u_short *sptr; + u_int *iptr; + } codevar; + + button_3 = 0; + if (inputInfo.keyboard) { + get_codes ("KEYPAD_2", &code, KEY, FALSE); + cursor_down = (unsigned char) code; + get_codes ("KEYPAD_5", &code, KEY, FALSE); + cursor_up = (unsigned char) code; + get_codes ("KEYPAD_1", &code, KEY, FALSE); + cursor_left = (unsigned char) code; + get_codes ("KEYPAD_3", &code, KEY, FALSE); + cursor_right = (unsigned char) code; + get_codes ("KEYPAD_*", &code, KEY, FALSE); + button_1 = (unsigned char) code; + get_codes ("KEYPAD_/", &code, KEY, FALSE); + button_2 = (unsigned char) code; + get_codes ("KEYPAD_+", &code, KEY, FALSE); + button_3 = (unsigned char) code; + get_codes ("KEYPAD_-", &code, KEY, FALSE); + button_4 = (unsigned char) code; + 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; + + while (fgets(buf,MAXNAMLEN+1,fp) != NULL) + { + ret2 = sscanf (buf,"%s%s",function,key); + + /* comments begin with a '#'. Skip them. */ + + if (function[0] == '#') /* comment, skip it */ + continue; + + if (ret2 == 2) /* error if < 2 items */ + { + vret = get_vars (function, &codevar, &index); + if (vret < 0) /* invalid function */ + { + ErrorF ("Bad function \"%s\" skipped in X*pointerkeys file.\n", + function); + continue; /* error - skip this one*/ + } + cret = get_codes (key, &code, pointerfunc[index].type, TRUE); + if (cret < 0 && /* not a key or modifier*/ + pointerfunc[index].type == KEY) /* but must be */ + { + ErrorF ("Bad key name \"%s\" skipped in X*pointerkeys file.\n", + key); + continue; /* error - skip this one*/ + } + + if (pointerfunc[index].type==MODIFIER) /* modifier - compute bit*/ + *codevar.cptr = code - 8; + else if (pointerfunc[index].type==UINT_NUMBER) + *codevar.iptr = code; /* code for 16-bit number */ + else if (pointerfunc[index].type==USHORT_NUMBER) + *codevar.sptr = code; /* code for 16-bit number */ + else + *codevar.cptr = code; /* code for 8-bit key */ + } + else + { + len = strlen(buf) - 1; /* fgets adds a newline */ + buf[len] = '\0'; + if (len > 0) + ErrorF ("Bad entry \"%s\" skipped in X*pointerkeys file.\n", + buf); + } + } + + fclose (fp); + } + +/**************************************************************************** + * + * 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; + } + +/**************************************************************************** + * + * We allow any keycode to be specified as a modifer, Even one that can't + * be generated by our keyboard. + * + */ + +LegalModifier(key, dev) + unsigned int key; + DevicePtr dev; + { + return TRUE; + } + +/**************************************************************************** + * + * close_device closes one of the input devices. + * + */ + +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; + } + } + +/***************************** + * + * init_events_queue (queue) + * + */ + +init_events_queue(queue) + struct x11EventQueue *queue; + { + queue->events = events_array; + queue->head = 0; + queue->tail = 0; + queue->size = MAX_EVENTS; + events_queue = queue; + } + +/***************************************************************** + * + * allocate_event () + * allocates the next available event to the caller and increments + * the tail pointer of the events queue; sets queue_events_free as needed. + * + */ + +xHPEvent *allocate_event () + { + xHPEvent *event; + + event = &( (events_queue->events)[events_queue->tail]); + + if ( events_queue->tail == WR_EVENTS) + events_queue->tail = 0; + else (events_queue->tail)++; + + queue_events_free--; + if (queue_events_free == 0) + ErrorF ("Server Internal events queue is full!!!\n"); + return (event); + } + +deallocate_event (ev) + xHPEvent *ev; + { + xHPEvent *tmp, *tail, *last, *first; + + tail = &( (events_queue->events)[events_queue->tail]); + last = &( (events_queue->events)[WR_EVENTS]); + first = &( (events_queue->events)[0]); + + for (tmp=ev; tmp!=tail; tmp++) + if (tmp==last) + { + *tmp = *first; + tmp = first-1; + } + else + *tmp = *(tmp+1); + + if (events_queue->tail == 0) + events_queue->tail = WR_EVENTS; + else + events_queue->tail--; + queue_events_free++; + } + + +#ifdef XINPUT +void +AddOtherInputDevices () + { + int i; + HPInputDevice *hp, *tmphp; + DeviceIntPtr dev; + Bool found; + + for (i=0, hp=l_devs; i<MAX_LOGICAL_DEVS; hp++,i++) + { + found = FALSE; + for (dev=inputInfo.devices; dev; dev=dev->next) + { + tmphp = GET_HPINPUTDEVICE (dev); + if (hp == tmphp) + { + found = TRUE; + break; + } + } + for (dev=inputInfo.off_devices; found==FALSE && dev; dev=dev->next) + { + tmphp = GET_HPINPUTDEVICE (dev); + if (hp == tmphp) + { + found = TRUE; + 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); + } + } + } + +int +ChangeKeyboardDevice (old_dev, new_dev) + DeviceIntPtr old_dev; + DeviceIntPtr new_dev; + { + CARD8 tmp; + HPInputDevice *old = GET_HPINPUTDEVICE (old_dev); + HPInputDevice *new = GET_HPINPUTDEVICE (new_dev); + + if (old->hpflags & OPEN_THIS_DEVICE) + old->hpflags &= ~OPEN_THIS_DEVICE; + tmp = hp_device_ids[new_dev->id]; + 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); + } + +int +#if NeedFunctionPrototypes +ChangePointerDevice ( + DeviceIntPtr old_dev, + DeviceIntPtr new_dev, + unsigned char x, + unsigned char y) +#else +ChangePointerDevice (old_dev, new_dev, x, y) + DeviceIntPtr old_dev; + DeviceIntPtr new_dev; + unsigned char x,y; +#endif + { + XID tmp; + HPInputDevice *old = GET_HPINPUTDEVICE (old_dev); + HPInputDevice *new = GET_HPINPUTDEVICE (new_dev); + + if (new_dev == tablet_extension_device) + return (BadDevice); + x_axis = x; + y_axis = y; + if (x_axis != 0 || y_axis != 1) + axes_changed = TRUE; + else + axes_changed = FALSE; + + new->coords[0] = old->coords[0]; + new->coords[1] = old->coords[1]; + + if (old->hpflags & OPEN_THIS_DEVICE) + old->hpflags &= ~OPEN_THIS_DEVICE; + + screen_change_dev = new_dev; + tmp = hp_device_ids[new_dev->id]; + 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); + } + +/**************************************************************************** + * + * Turn on a non-standard device. + * + */ + +void +OpenInputDevice (dev, client, status) + DeviceIntPtr dev; + ClientPtr client; + int *status; + { + int mode; + HPInputDevice *d; + DeviceClientsPtr tmp; + + if (*status != Success) /* kludge - if not Success, */ + mode = (*status >> 8); /* called from HPSetInputDevice */ + else /* mode hidden in 2nd byte */ + mode = DEVICE_EVENTS | ON; + + *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 + { + for (tmp = (DeviceClientsPtr) d->clients; tmp!=NULL; tmp=tmp->next) + if (tmp->mode != mode) + { + *status = BadMode; + return; + } + } + SetInputDevice (d, mode); + + dev->startup = 1; + RecordOpenRequest (client, d, dev->id, mode); + } + +/*********************************************************************** + * + * Record a successful request from a client to open an input device. + * + */ + +static void +RecordOpenRequest (client, d, id, token) + register ClientPtr client; + HPInputDevice *d; + CARD8 id; + int token; + { + DeviceClientsPtr tmp; + DeviceClientsPtr new_client; + + if (d->clients != NULL) + { + for (tmp = (DeviceClientsPtr) d->clients; tmp!=NULL; tmp=tmp->next) + if (tmp->client == client) + { + tmp->count++; + return; + } + else if (tmp->next == NULL) + break; + + new_client = (DeviceClients *) Xalloc(sizeof(DeviceClients)); + tmp->next = new_client; + } + else + { + new_client = (DeviceClients *) Xalloc(sizeof(DeviceClients)); + d->clients = new_client; + } + + memset ((char *) new_client, 0, sizeof (DeviceClients)); + new_client->resource = FakeClientID(client->index); + new_client->client = client; + new_client->next = NULL; + new_client->count = 1; + new_client->mode = token; + + AddResource(new_client->resource, HPType, (pointer) id); + } + + +/*********************************************************************** + * + * Turn off a device because a client died. + * Also called when a client closes a device. + * + */ + +int HPShutDownDevice (deviceid, clientid) + CARD8 deviceid; + int clientid; + { + DeviceIntPtr dev = NULL; + DeviceClientsPtr tmp; + DeviceClientsPtr save; + HPInputDevice *d; + + if (deviceid == inputInfo.pointer->id) + d = hpPointer; + else if (deviceid == inputInfo.keyboard->id) + d = hpKeyboard; + else + { + dev = LookupDeviceIntRec(deviceid); + if (dev == NULL) + return; + d = GET_HPINPUTDEVICE (dev); + } + + if (d->clients != NULL) + { + tmp = (DeviceClientsPtr) d->clients; + if (tmp->resource == clientid) + { + d->clients = tmp->next; + Xfree (tmp); + } + else + for (save=tmp,tmp=tmp->next; tmp!=NULL; save=tmp, tmp=tmp->next) + { + if (tmp->resource == clientid) + { + save->next = tmp->next; + Xfree (tmp); + } + } + if (dev && d->clients == NULL) + { + if (!(d->hpflags & MERGED_DEVICE) || + (d->hpflags & SECOND_LOGICAL_DEVICE)) + DisableDevice(dev); + } + } + } + +/**************************************************************************** + * + * Turn off an extension device. + * This code does not allow the keyboard or pointer to be turned off. + * + */ + +void +CloseInputDevice (dev, client) + DeviceIntPtr dev; + ClientPtr client; + { + HPInputDevice *d; + DeviceClientsPtr tmp; + + d = GET_HPINPUTDEVICE (dev); + + for (tmp= (DeviceClientsPtr) d->clients; tmp!=NULL; tmp=tmp->next) + if (tmp->client == client) + { + tmp->count--; + if (tmp->count == 0) + { + FreeResource(tmp->resource, RT_NONE); + return; + } + } + } + +/**************************************************************************** + * + * Change the state of a non-standard device. + * Modes are: + * ON - turn the device on. + * OFF - turn the device off. + * SYSTEM_EVENTS - report the standard input events. + * DEVICE_EVENTS - report the extension input events. + * + */ + +static void +SetInputDevice (d, mode) + HPInputDevice *d; + int mode; + { + + if ((mode & DEVICE_EVENTS) == DEVICE_EVENTS) + d->hpflags &= ~MERGED_DEVICE; + else + { + mode |= ABSOLUTE; + d->hpflags |= MERGED_DEVICE; + } + + if ((mode & ABSOLUTE) == ABSOLUTE) + { + 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; + } + } + +/**************************************************************************** + * + * Change the mode of an extension device. + * This is for devices such as graphics tablets that can report either + * relative or absolute motion. + * We currently do not support this. + * + */ + +int +SetDeviceMode (client, dev, mode) + register ClientPtr client; + 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; + } + +/**************************************************************************** + * + * Set the value of valuators on an extension device. + * This is needed for some devices that can report both + * relative and absolute motion. Some may require that the + * initial values be set when switching modes. + * We currently do not support this. + * + */ + +int +SetDeviceValuators (client, dev, valuators, first_valuator, num_valuators) + register ClientPtr client; + DeviceIntPtr dev; + int *valuators; + int first_valuator; + int num_valuators; + { + int i; + HPInputDevice *d; + HPResolutionControl ctrl; + + d = GET_HPINPUTDEVICE (dev); + for (i=first_valuator; i<num_valuators; i++) + if (i>=0 && i < dev->valuator->numAxes) + 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; + } + +/**************************************************************************** + * + * Change the resolution of valuators on an extension device. + * This is needed for some devices that have multiple resolutions. + * We currently do not support this. + * + */ + +int +ChangeDeviceControl (client, dev, control) + register ClientPtr client; + DeviceIntPtr dev; + 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 +#define LEFT_MOD1_BIT 0x08 +#define RIGHT_MOD1_BIT 0x04 +#define RIGHT_CONTROL_BIT 0x01 +#define LEFT_CONTROL_BIT 0x40 +#define MAX_KEY_MODS 3 + +fix_modifierkeys() + { + u_char tmp[3]; + + tmp[1] = 0xff; + tmp[2] = 0xff; + tmp[0] = pointer_amt_mods[0]; + mask_from_kcodes (tmp, &pointer_amt_bits[0]); + tmp[0] = pointer_amt_mods[1]; + mask_from_kcodes (tmp, &pointer_amt_bits[1]); + tmp[0] = pointer_amt_mods[2]; + mask_from_kcodes (tmp, &pointer_amt_bits[2]); + + mask_from_kcodes (pointer_key_mods, &ptr_mods); + mask_from_kcodes (pointer_amt_mods, &mv_mods); + mask_from_kcodes (reset_mods, &rs_mods); + mask_from_kcodes (borrow_mode_mods, &bw_mods); + mv_mods &= ~ptr_mods; + } + +static void +mask_from_kcodes (src, dst) + u_char *src; + u_char *dst; + { + int i; + 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) + DeviceIntPtr dev; + 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 + * name of an entry point to find. It loads the library and returns the + * entry point address. + */ + +Bool (*shl_driver_load( driver_path, driver_init ))() +char *driver_path, *driver_init; +{ + /* + * pfrb = pointer to a function returning a Bool + */ + typedef Bool (*pfrb)(); + + shl_t ldr_module_id; + long ldr_module_entry=0; + int ret_val; + char *dummy_handle = NULL; +#define ALL_SHLIBS_HANDLE &dummy_handle + + /********************************************************************** + * + * If the driver entrypoint is already visible within the current program, + * skip the load and return the address of the routine we already have + * loaded. + * + */ + + ret_val = shl_findsym((shl_t *) PROG_HANDLE, driver_init, + TYPE_PROCEDURE, &ldr_module_entry ); + if ( ! ret_val ) { + return( (pfrb) ldr_module_entry ); + } + + /* + * If the driver entrypoint is already visible within a shared library we + * are already accessing, skip the load and return the address. + */ + ret_val = shl_findsym((shl_t *) ALL_SHLIBS_HANDLE, driver_init, + TYPE_PROCEDURE, &ldr_module_entry ); + if ( ! ret_val ) { + return( (pfrb) ldr_module_entry ); + } + + + /********************************************************************** + * + * 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", + driver_path,errno); + + + /********************************************************************** + * + * Use the module ID to find the address of the requested entry point. + */ + + ret_val = shl_findsym( &ldr_module_id, driver_init, TYPE_PROCEDURE, + &ldr_module_entry ); + if (ret_val && driver_init != NULL) + FatalError ("X server couldn't find entry point '%s' in library %s\n", + driver_init, driver_path); + + return( (pfrb) ldr_module_entry ); +} + +/*********************************************************************** + * + * din_mouse_present + * + */ + +static Bool +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; + } + +/*********************************************************************** + * + * find_din_mouse_use + * + */ + +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; + } + +/*********************************************************************** + * + * din_kbd_present + * + */ + +static Bool +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; + } + +/*********************************************************************** + * + * find_din_kbd_use + * + */ + +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; + } diff --git a/xc/programs/Xserver/hw/hp/input/x_hilinit.h b/xc/programs/Xserver/hw/hp/input/x_hilinit.h new file mode 100644 index 000000000..ce9d344f8 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/x_hilinit.h @@ -0,0 +1,460 @@ +#ifndef X_HILINIT_H +#define X_HILINIT_H +/* $TOG: x_hilinit.h /main/3 1998/02/10 13:11:34 kaleb $ */ +/* + +Copyright 1986, 1987, 1998 The Open Group + +All Rights Reserved. + +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 OPEN GROUP 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 Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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. + +*/ + +/************************************************************************** + * + * file: x_hilinit.h + * + * contains key definitions and other static information used by x_hilinit.c + * + */ + +#define STARTUP 0 +#define MAX_STRINGS (sizeof (strings) / sizeof (struct str_table)) +#define MAX_DEV_TYPES (sizeof (devices) / sizeof (struct dev_table)) +#define MAX_POINTER_FUNCS (sizeof (pointerfunc) / sizeof (struct pointerfunc)) +#define QUAD_INDEX 8 /* index of quad entry in dev_table */ +#define NINE_KNOB_ID 0x61 +#define KEY 0 +#define UCHAR_NUMBER 1 +#define STRING 2 +#define MODIFIER 3 +#define USHORT_NUMBER 4 +#define UINT_NUMBER 5 + +#include "keysym.h" +#include "HPkeysym.h" +#include "ap_keysym.h" + +struct opendevs + { + int type; + int pos; + int use; + char path[MAXNAMLEN+1]; + char name[MAXNAMLEN+1]; + char entry[MAXNAMLEN+1]; + }; + +struct dev_table + { + int lowid; + int highid; + int dev_type; + int x_type; + char *name; + unsigned char num_keys; + unsigned char min_kcode; + unsigned char max_kcode; + }; + +struct dev_table devices[] = + {{0x00,0x1f,KEYPAD,KEYBOARD,"KEYPAD",0,0,0}, + {0x2f,0x2f,APOLLO_LPFK,KEYBOARD,"LPFK-BUTTONBOX",33,64,32}, + {0x30,0x33,BUTTONBOX,KEYBOARD,"BUTTONBOX",32,10,41}, + {0x34,0x34,ID_MODULE,XOTHER,"ID_MODULE",0,0,0}, + {0x35,0x3f,BUTTONBOX,KEYBOARD,"BUTTONBOX",32,10,41}, + {0x5c,0x5f,BARCODE,KEYBOARD,"BARCODE",109,10,135}, + {0x60,0x60,ONE_KNOB,MOUSE,"ONE_KNOB",0,0,0}, + {0x61,0x61,NINE_KNOB,MOUSE,"NINE_KNOB",0,0,0}, + {0x62,0x67,QUADRATURE,MOUSE,"QUADRATURE",0,0,0}, + {0x68,0x6b,MOUSE,MOUSE,"MOUSE",0,0,0}, + {0x6c,0x6f,TRACKBALL,MOUSE,"TRACKBALL",0,0,0}, + {0x70,0x70,VCD_8_DIALBOX,MOUSE,"KNOB_BOX",0,0,0}, + {0x71,0x71,SS_SPACEBALL,MOUSE,"SPACEBALL",0,0,0}, + {0x88,0x8b,TOUCHPAD,MOUSE,"TOUCHPAD",0,0,0}, + {0x8c,0x8f,TOUCHSCREEN,MOUSE,"TOUCHSCREEN",0,0,0}, + {0x90,0x97,TABLET,MOUSE,"TABLET",0,0,0}, + {0x98,0x98,MMII_1812_TABLET,MOUSE,"MMII-TABLET",0,0,0}, + {0x99,0x99,MMII_1201_TABLET,MOUSE,"MMII-TABLET",0,0,0}, + {0xA0,0xBF,KEYBOARD,KEYBOARD,"KEYBOARD",93,10,135}, + {0xC0,0xDF,KEYBOARD,KEYBOARD,"KEYBOARD",109,10,135}, + {0xE0,0xFF,KEYBOARD,KEYBOARD,"KEYBOARD",87,10,135}, + {0x00,0x00,NULL_DEVICE,NULL_DEVICE,"NULL",0,0,0}}; + +char *position[] = + { + "FIRST", + "SECOND", + "THIRD", + "FOURTH", + "FIFTH", + "SIXTH", + "SEVENTH" + }; + +char *suffix[] = +#if defined(__hp9000s300) || defined(__hp9000s700) || defined(__hp_osf) + {"1","2","3","4","5","6","7"}; +#else + {"0.1","0.2","0.3","0.4","0.5","0.6","0.7", + "1.1","1.2","1.3","1.4","1.5","1.6","1.7", + "2.1","2.2","2.3","2.4","2.5","2.6","2.7", + "3.1","3.2","3.3","3.4","3.5","3.6","3.7"}; +#endif /* __hp9000s300 or __hp9000s700 */ + +extern u_char cursor_down; +extern u_char cursor_left; +extern u_char cursor_right; +extern u_char cursor_up; +extern u_char button_1; +extern u_char button_2; +extern u_char button_3; +extern u_char button_4; +extern u_char button_5; +extern u_char button_6; +extern u_char button_7; +extern u_char button_8; + +extern u_char pointer_key_mods[3]; +extern u_char pointer_amt_mods[3]; +extern u_char reset_mods[3]; +extern u_char borrow_mode_mods[3]; +extern u_short pointer_move; +extern u_short pointer_mod1_amt; +extern u_short pointer_mod2_amt; +extern u_short pointer_mod3_amt; +extern u_char borrow_mode; +extern u_char reset; +extern u_char screen_change_amt; +extern u_char button_chording; +extern u_char button_latching; +extern u_char ptr_button_map[]; +extern u_char isotropic_scaling; +extern u_char screen_orientation; +extern u_char screen_row_wrap; +extern u_char screen_col_wrap; +extern u_int tablet_xorigin; +extern u_int tablet_yorigin; +extern u_int tablet_width; +extern u_int tablet_height; + +struct pointerfunc + { + char *name; + u_char *code; + int type; + }; + +struct pointerfunc pointerfunc [] = + {{"POINTER_LEFT_KEY", &cursor_left, KEY}, + {"POINTER_RIGHT_KEY", &cursor_right, KEY}, + {"POINTER_UP_KEY", &cursor_up, KEY}, + {"POINTER_DOWN_KEY", &cursor_down, KEY}, + {"POINTER_KEY_MOD1", &pointer_key_mods[0], MODIFIER}, + {"POINTER_KEY_MOD2", &pointer_key_mods[1], MODIFIER}, + {"POINTER_KEY_MOD3", &pointer_key_mods[2], MODIFIER}, + {"POINTER_BUTTON1_KEY", &button_1, KEY}, + {"POINTER_BUTTON2_KEY", &button_2, KEY}, + {"POINTER_BUTTON3_KEY", &button_3, KEY}, + {"POINTER_BUTTON4_KEY", &button_4, KEY}, + {"POINTER_BUTTON5_KEY", &button_5, KEY}, + {"POINTER_BUTTON6_KEY", &button_6, KEY}, + {"POINTER_BUTTON7_KEY", &button_7, KEY}, + {"POINTER_BUTTON8_KEY", &button_8, KEY}, + {"POINTER_MOVE", (u_char *) &pointer_move, USHORT_NUMBER}, + {"POINTER_MOD1_AMT", (u_char *) &pointer_mod1_amt, USHORT_NUMBER}, + {"POINTER_MOD2_AMT", (u_char *) &pointer_mod2_amt, USHORT_NUMBER}, + {"POINTER_MOD3_AMT", (u_char *) &pointer_mod3_amt, USHORT_NUMBER}, +#ifdef __apollo + {"BORROW_MODE_KEY", &borrow_mode, KEY}, + {"BORROW_MODE_MOD1_KEY", &borrow_mode_mods[0], MODIFIER}, + {"BORROW_MODE_MOD2_KEY", &borrow_mode_mods[1], MODIFIER}, +#endif /* __apollo */ + {"RESET", &reset, KEY}, + {"RESET_MOD1", &reset_mods[0], MODIFIER}, + {"RESET_MOD2", &reset_mods[1], MODIFIER}, + {"RESET_MOD3", &reset_mods[2], MODIFIER}, + {"POINTER_AMT_MOD1", &pointer_amt_mods[0], MODIFIER}, + {"POINTER_AMT_MOD2", &pointer_amt_mods[1], MODIFIER}, + {"POINTER_AMT_MOD3", &pointer_amt_mods[2], MODIFIER}, + {"BUTTON_1_VALUE", &ptr_button_map[1], UCHAR_NUMBER}, + {"BUTTON_2_VALUE", &ptr_button_map[2], UCHAR_NUMBER}, + {"BUTTON_3_VALUE", &ptr_button_map[3], UCHAR_NUMBER}, + {"BUTTON_4_VALUE", &ptr_button_map[4], UCHAR_NUMBER}, + {"BUTTON_5_VALUE", &ptr_button_map[5], UCHAR_NUMBER}, + {"BUTTON_6_VALUE", &ptr_button_map[6], UCHAR_NUMBER}, + {"BUTTON_7_VALUE", &ptr_button_map[7], UCHAR_NUMBER}, + {"BUTTON_8_VALUE", &ptr_button_map[8], UCHAR_NUMBER}, + {"SCREEN_CHANGE_AMT", &screen_change_amt, UCHAR_NUMBER}, + {"BUTTON_CHORDING", &button_chording, STRING}, + {"BUTTON_LATCHING", &button_latching, STRING}, + {"TABLET_SUBSET_XORIGIN", (u_char *) &tablet_xorigin, UINT_NUMBER}, + {"TABLET_SUBSET_YORIGIN", (u_char *) &tablet_yorigin, UINT_NUMBER}, + {"TABLET_SUBSET_WIDTH", (u_char *) &tablet_width, UINT_NUMBER}, + {"TABLET_SUBSET_HEIGHT", (u_char *) &tablet_height, UINT_NUMBER}, + {"ISOTROPIC_SCALING", &isotropic_scaling, STRING}, + {"SCREEN_ORIENTATION", &screen_orientation, STRING}, + {"SCREEN_ROW_WRAP", &screen_row_wrap, STRING}, + {"SCREEN_COL_WRAP", &screen_col_wrap, STRING}}; + +struct str_table + { + char *string; + u_char value; + } strings [] = { + {"OFF",CHORDING_OFF}, + {"ON",CHORDING_ON}, + {"DEFAULT",CHORDING_DEFAULT}, + {"WRAP",WRAP}, + {"NOWRAP",NOWRAP}, + {"SAMESCREEN",SAMESCREEN}, + {"CHANGE_BY_TWO",CHANGE_BY_TWO}, + {"VERTICAL",VERTICAL}, + {"HORIZONTAL",HORIZONTAL}, + {"MATRIX",MATRIX}}; + +struct _keyset1 { + char *keystr; + KeySym sym; + } keyset1[] = { + {"ALT_L", XK_Alt_L}, + {"ALT_R", XK_Alt_R}, + {"LEFT_CONTROL", XK_Control_L}, + {"RIGHT_CONTROL", XK_Control_R}, + {"RIGHT_EXTEND", XK_Meta_R}, + {"LEFT_EXTEND", XK_Meta_L}, + {"RIGHT_SHIFT", XK_Shift_R}, + {"LEFT_SHIFT", XK_Shift_L}, + {"CONTROL", XK_Control_L}, + {"KEYPAD_4", XK_KP_4}, + {"KEYPAD_8", XK_KP_8}, + {"KEYPAD_5", XK_KP_5}, + {"KEYPAD_9", XK_KP_9}, + {"KEYPAD_6", XK_KP_6}, + {"KEYPAD_7", XK_KP_7}, + {"KEYPAD_COMMA", XK_KP_Separator}, + {"KEYPAD_ENTER", XK_KP_Enter}, + {"KEYPAD_1", XK_KP_1}, + {"KEYPAD_/", XK_KP_Divide}, + {"KEYPAD_2", XK_KP_2}, + {"KEYPAD_+", XK_KP_Add}, + {"KEYPAD_3", XK_KP_3}, + {"KEYPAD_*", XK_KP_Multiply}, + {"KEYPAD_0", XK_KP_0}, + {"KEYPAD_-", XK_KP_Subtract}, + {"BLANK_F10", XK_F10}, + {"BLANK_F11", XK_F11}, + {"KEYPAD_PERIOD", XK_KP_Decimal}, + {"BLANK_F9", XK_F9}, + {"KEYPAD_TAB", XK_KP_Tab}, + {"BLANK_F12", XK_F12}, + {"`", XK_quoteleft}, + {"STOP", XK_Cancel}, + {"ENTER", XK_Execute}, + {"CLEAR_LINE", XK_ClearLine}, + {"CLEAR_DISPLAY", XK_Clear}, + {"-", XK_minus}, + {"=", XK_equal}, + {"INSERT_LINE", XK_InsertLine}, + {"DELETE_LINE", XK_DeleteLine}, + {"[", XK_bracketleft}, + {"]", XK_bracketright}, + {"\\", XK_backslash}, + {"INSERT_CHAR", XK_InsertChar}, + {"DELETE_CHAR", XK_DeleteChar}, + {";", XK_semicolon}, + {"'", XK_quoteright}, + {"HOME_CURSOR", XK_Home}, + {"PREV", XK_Prior}, + {",", XK_comma}, + {".", XK_period}, + {"/", XK_slash}, + {"SPACE_BAR", XK_space}, + {".", XK_period}, + {"CURSOR_LEFT", XK_Left}, + {"CURSOR_DOWN", XK_Down}, + {"CURSOR_UP", XK_Up}, + {"CURSOR_RIGHT", XK_Right}, + {"CONTROL_R", XK_Control_R}, + {"META_R", XK_Meta_R}, + {"META_L", XK_Meta_L}, + {"SHIFT_R", XK_Shift_R}, + {"SHIFT_L", XK_Shift_L}, + {"CONTROL_L", XK_Control_L}, + {"BREAK", XK_Break}, + {"KP_4", XK_KP_4}, + {"KP_8", XK_KP_8}, + {"KP_5", XK_KP_5}, + {"KP_9", XK_KP_9}, + {"KP_6", XK_KP_6}, + {"KP_7", XK_KP_7}, + {"KP_SEPARATOR", XK_KP_Separator}, + {"KP_ENTER", XK_KP_Enter}, + {"KP_1", XK_KP_1}, + {"KP_DIVIDE", XK_KP_Divide}, + {"KP_2", XK_KP_2}, + {"KP_ADD", XK_KP_Add}, + {"KP_3", XK_KP_3}, + {"KP_MULTIPLY", XK_KP_Multiply}, + {"KP_0", XK_KP_0}, + {"KP_SUBTRACT", XK_KP_Subtract}, + {"B", XK_B}, + {"V", XK_V}, + {"C", XK_C}, + {"X", XK_X}, + {"Z", XK_Z}, + {"ESCAPE", XK_Escape}, + {"F10", XK_F10}, + {"F11", XK_F11}, + {"KP_DECIMAL", XK_KP_Decimal}, + {"F9", XK_F9}, + {"KP_TAB", XK_KP_Tab}, + {"F12", XK_F12}, + {"H", XK_H}, + {"G", XK_G}, + {"F", XK_F}, + {"D", XK_D}, + {"S", XK_S}, + {"A", XK_A}, + {"NOSYMBOL", 0}, + {"CAPS_LOCK", XK_Caps_Lock}, + {"U", XK_U}, + {"Y", XK_Y}, + {"T", XK_T}, + {"R", XK_R}, + {"E", XK_E}, + {"W", XK_W}, + {"Q", XK_Q}, + {"TAB", XK_Tab}, + {"7", XK_7}, + {"6", XK_6}, + {"5", XK_5}, + {"4", XK_4}, + {"3", XK_3}, + {"2", XK_2}, + {"1", XK_1}, + {"QUOTELEFT", XK_quoteleft}, + {"MENU", XK_Menu}, + {"F4", XK_F4}, + {"F3", XK_F3}, + {"F2", XK_F2}, + {"F1", XK_F1}, + {"CANCEL", XK_Cancel}, + {"EXECUTE", XK_Execute}, + {"SYSTEM", XK_System}, + {"F5", XK_F5}, + {"F6", XK_F6}, + {"F7", XK_F7}, + {"F8", XK_F8}, + {"CLEARLINE", XK_ClearLine}, + {"CLEAR", XK_Clear}, + {"8", XK_8}, + {"9", XK_9}, + {"0", XK_0}, + {"MINUS", XK_minus}, + {"EQUAL", XK_equal}, + {"BACKSPACE", XK_BackSpace}, + {"INSERTLINE", XK_InsertLine}, + {"DELETELINE", XK_DeleteLine}, + {"I", XK_I}, + {"O", XK_O}, + {"P", XK_P}, + {"BRACKETLEFT", XK_bracketleft}, + {"BRACKETRIGHT", XK_bracketright}, + {"BACKSLASH", XK_backslash}, + {"INSERTCHAR", XK_InsertChar}, + {"DELETECHAR", XK_DeleteChar}, + {"J", XK_J}, + {"K", XK_K}, + {"L", XK_L}, + {"SEMICOLON", XK_semicolon}, + {"QUOTERIGHT", XK_quoteright}, + {"RETURN", XK_Return}, + {"HOME", XK_Home}, + {"PRIOR", XK_Prior}, + {"M", XK_M}, + {"COMMA", XK_comma}, + {"PERIOD", XK_period}, + {"SLASH", XK_slash}, + {"SELECT", XK_Select}, + {"NEXT", XK_Next}, + {"N", XK_N}, + {"SPACE", XK_space}, + {"LEFT", XK_Left}, + {"DOWN", XK_Down}, + {"UP", XK_Up}, + {"RIGHT", XK_Right}, + {"GRAVE", XK_grave}, + {"NUMBERSIGN", XK_numbersign}, + {"KANJI", XK_Kanji}, + {"GUILLEMOTLEFT", XK_guillemotleft}, + {"EACUTE", XK_eacute}, + {"PRINT", XK_Print}, + {"ASCIICIRCUM", XK_asciicircum}, + {"SCROLL_LOCK", XK_Scroll_Lock}, + {"CEDILLA", XK_cedilla}, + {"NUM_LOCK", XK_Num_Lock}, +#ifdef __apollo + {"APCHARDEL", apXK_CharDel}, + {"REDO", XK_Redo}, + {"APREAD", apXK_Read}, + {"APEDIT", apXK_Edit}, + {"APEXIT", apXK_Exit}, + {"PAUSE", XK_Pause}, + {"APCOPY", apXK_Copy}, + {"APPASTE", apXK_Paste}, + {"APGROW", apXK_Grow}, + {"APLEFTBAR", apXK_LeftBar}, + {"APCMD", apXK_Cmd}, + {"APRIGHTBAR", apXK_RightBar}, + {"DELETE", XK_Delete}, + {"APLEFTBOX", apXK_LeftBox}, + {"APRIGHTBOX", apXK_RightBox}, + {"APOSTROPHE", XK_apostrophe}, + {"APREPEAT", apXK_Repeat}, + {"APPOP", apXK_Pop}, + {"APUPBOX", apXK_UpBox}, + {"APDOWNBOX", apXK_DownBox}, +#endif /* __apollo */ + {"", 0}}; + +#endif /* X_HILINIT_H */ diff --git a/xc/programs/Xserver/hw/hp/input/x_serialdrv.h b/xc/programs/Xserver/hw/hp/input/x_serialdrv.h new file mode 100644 index 000000000..3f267f514 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/x_serialdrv.h @@ -0,0 +1,185 @@ +/* $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. + + 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. + +********************************************************/ + +/*************************************************************************** + * + * Constants and structs for dynamically loaded serial input device drivers. + * + */ + +#ifndef _X_SERIALDRV_H_ +#define _X_SERIALDRV_H_ +#include <dl.h> + +#define X_KEYMAP_NAME "/etc/kbdlang" +#define MIN_KEYCODE 8 +#define MAX_NM 64 +#define DATA_IS_8_BITS 0x01 +#define DATA_IS_16_BITS 0x02 +#define DATA_IS_32_BITS 0x04 +#define REPORTS_PROXIMITY 0x08 +#define ABSOLUTE_DATA 0x040 +#define NON_CONTIGUOUS_DATA 0x080 +#define FALSE 0 +#define TRUE 1 +#define KEY_DATA 0x01 +#define BUTTON_DATA 0x02 +#define PROXIMITY_DATA 0x04 +#define MOTION_DATA 0x08 +#define INIT_SUCCESS 0 +#define INIT_FAILURE 1 +#define READ_SUCCESS 0 +#define READ_FAILURE 1 +#define WRITE_SUCCESS 0 +#define WRITE_FAILURE 1 +#define CLOSE_SUCCESS 0 +#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 +#define _XChangeDeviceControl 2 +#define _XChangeFeedbackControl 3 +#define _XChangeKeyboardControl 4 +#define _XChangePointerControl 5 +#define _XBell 6 + +typedef struct { + int class; + int bell_percent; +} HPBell; + +typedef struct { + int class; + int led_mask; + int led_values; +} HPLedFeedbackControl; + +typedef struct { + int class; + int click; + int bell_percent; + int bell_pitch; + int bell_duration; + int autoRepeat; + unsigned char autoRepeats[32]; + int leds; +} HPKeyboardFeedbackControl; + +typedef struct { + int class; + int num; + int den; + int threshold; +} HPPointerFeedbackControl; + +typedef struct { + int class; + int resolution; + int min_value; + int max_value; + int integer_displayed; +} HPIntegerFeedbackControl; + +typedef struct { + int max_symbols; + int num_symbols_supported; + int *symbols_supported; +} HPStrF; + +typedef struct { + int class; + int max_symbols; + int num_symbols_supported; + int num_symbols_displayed; + int *symbols_supported; + int *symbols_displayed; +} HPStringFeedbackControl; + +typedef struct { + int class; + int percent; + int pitch; + int duration; +} HPBellFeedbackControl; + +typedef struct { + int *valuators; + int first_valuator; + int num_valuators; +} HPValuatorControl; + +typedef struct { + int *resolutions; + int first_valuator; + int num_valuators; +} HPResolutionControl; + +typedef int (*pfrb)(); +typedef int (*ConfigureProc)(); +typedef int (*InitProc)(); +typedef int (*ReadProc)(); +typedef int (*WriteProc)(); +typedef int (*CloseProc)(); + +typedef struct _SerialProcs + { + ConfigureProc configure; /* filled in by driver */ + ReadProc read; /* filled in by driver */ + WriteProc write; /* filled in by driver */ + CloseProc close; /* filled in by driver */ + } SerialProcs; + +typedef struct _HPInputDeviceHeader + { + char path[MAX_NM]; /* device path - filled in by X server */ + char *x_name; /* device name */ + char *keymap_name; /* keymap name, if device has keys */ + char *keymap_file; /* keymap file, if device has keys */ + 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 */ + u_char *ledf; /* led feedbacks */ + int num_strf; /* length of list that follows */ + HPStrF *strf; /* string feedbacks */ + u_char flags; /* device characteristics */ + u_char ax_num; /* number of axes */ + u_char num_buttons; /* number of buttons */ + u_char num_keys; /* number of keys */ + u_char min_kcode; /* minimum keycode */ + u_char max_kcode; /* maximum keycode */ + 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_ */ diff --git a/xc/programs/Xserver/hw/hp/input/xtest1imp.c b/xc/programs/Xserver/hw/hp/input/xtest1imp.c new file mode 100644 index 000000000..c2515cf2a --- /dev/null +++ b/xc/programs/Xserver/hw/hp/input/xtest1imp.c @@ -0,0 +1,281 @@ +/* $TOG: xtest1imp.c /main/4 1998/02/10 13:11:24 kaleb $ */ +/* + * File: xtest1dd.c + * + * This file contains the device dependent parts of the input + * synthesis extension. + */ + +/* + + +Copyright 1986, 1987, 1988, 1998 The Open Group + +All Rights Reserved. + +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 +OPEN GROUP 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 Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation + +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 representations about the +suitability of this software for any purpose. It is provided +"as is" without express or implied warranty. + +This software is not subject to any license of the American +Telephone and Telegraph Company or of the Regents of the +University of California. + +*/ + +/*************************************************************** + * include files + ***************************************************************/ + +#define NEED_EVENTS +#define NEED_REPLIES + +#include <stdio.h> +#include "X.h" +#include "Xproto.h" +#include "inputstr.h" +#include "scrnintstr.h" +#define XTestSERVER_SIDE +#include "xtestext1.h" +/* + * the following include files are specific to HP's implementation + * of the extension. Your implementation may vary. + */ +#include "hildef.h" +#include "hpext.h" +#include "XHPproto.h" + +/* + * The following externs are specific to HP's implementation + * of the extension. Your implementation may vary. + */ +extern ScreenInfo screenInfo; +extern InputInfo inputInfo; +extern HPInputDevice *hpPointer, *hpKeyboard; + +/****************************************************************************** + * + * XTestGetPointerPos + * + * Return the position of the mouse. + * + */ +void +XTestGetPointerPos(fmousex, fmousey) + short *fmousex, *fmousey; + { + *fmousex = hpPointer->coords[0]; + *fmousey = hpPointer->coords[1]; + } + +/****************************************************************************** + * + * XTestJumpPointer + * + * Tell the server to move the mouse. + * + * This is implementation-dependent. Your implementation may vary. + */ +void +XTestJumpPointer(jx, jy, dev_type) +/* + * the x and y position to move the mouse to + */ +int jx; +int jy; +/* + * which device is supposed to move (ignored) + */ +int dev_type; +{ + int xdiff, screensize; + ScreenPtr pScreen = hpPointer->pScreen; + xEvent *format_ev(), *ev; + extern xHPEvent xE; + int coords[MAX_AXES]; + + /* + * move the mouse. + * The kludge below is an attempt to make it possible to + * test stacked screens mode. Xtm records absolute screen + * positions, so we have trouble knowing whether or not the + * screen changed. We make an arbitrary assumption here that + * if we moved more than 500 pixels in the x direction that + * we must have wrapped from one screen to another. This is + * a fairly safe assumption unless someone set the mouse + * acceleration to some unreasonably large number. + * + * In any case, translate the absolute postions into a relative + * move from the current pointer position, and pass that + * relative move to process_motion. + */ + xdiff = jx - hpPointer->coords[0]; + if (abs(xdiff) > 500 && screenInfo.numScreens > 1) + { + if (xdiff > 0) + { + if (pScreen->myNum != 0) + screensize = screenInfo.screens[pScreen->myNum-1]->width; + else + screensize = screenInfo.screens[screenInfo.numScreens-1]->width; + xdiff -= screensize; + } + else + xdiff += pScreen->width; + } + 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(); +} + +/****************************************************************************** + * + * XTestGenerateEvent + * + * Send a key/button input action to the server to be processed. + * + * This is implementation-dependent. Your implementation may vary. + */ +void +XTestGenerateEvent(dev_type, keycode, keystate, mousex, mousey) +/* + * which device supposedly performed the action + */ +int dev_type; +/* + * which key/button moved + */ +int keycode; +/* + * whether the key/button was up or down + */ +int keystate; +/* + * the x and y position of the locator when the action happenned + */ +int mousex; +int mousey; +{ + DeviceIntPtr dev; + HPInputDevice *tmp_ptr; + xEvent *format_ev(), *ev; + + /* + * the server expects to have the x and y position of the locator + * when the action happened placed in hpPointer. + */ + 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; + } + /* + * convert the keystate back into server-dependent state values + */ + if (keycode < 8 ) + { + /* + * if keycode < 8, this is really a button. + */ + if (keystate == XTestKEY_UP) + { + keystate = ButtonRelease; + } + else + { + keystate = ButtonPress; + } + } + else + { + if (keystate == XTestKEY_UP) + { + keystate = KeyRelease; + } + else + { + keystate = KeyPress; + } + } + /* + * Tell the server to process all of the events in its input queue. + * This makes sure that there is room in the server's input queue + * for a key/button input event. + */ + ProcessInputEvents(); + /* + * 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 + * is processed immediately. + */ + ProcessInputEvents(); +} + +/****************************************************************************** + * + * check_for_motion_steal + * + * Called from xosMoveMouse. + */ + +check_for_motion_steal (hotX, hotY) + register int hotX, hotY; + { +#ifdef XTESTEXT1 + extern int on_steal_input; /* defined in xtestext1di.c */ + extern short xtest_mousex; /* defined in xtestext1di.c */ + extern short xtest_mousey; /* defined in xtestext1di.c */ + + if ((on_steal_input) && + ((hotX != xtest_mousex) || (hotY != xtest_mousey))) /* mouse moved */ + { + XTestStealMotionData((hotX - xtest_mousex), + (hotY - xtest_mousey), + MOUSE, + xtest_mousex, + xtest_mousey); + } +#endif /* XTESTEXT1 */ + } + diff --git a/xc/programs/Xserver/hw/hp/ngle/Imakefile b/xc/programs/Xserver/hw/hp/ngle/Imakefile new file mode 100644 index 000000000..267905027 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/Imakefile @@ -0,0 +1,46 @@ +/* $XConsortium: Imakefile /main/7 1996/09/28 17:12:41 rws $ */ +#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 \ + ngleblt.c + +SCROLLING_OBJ = nglecopy.o \ + ngleblt.o \ + ngledoblt.o + +FAST_SCROLLING_DEFINES = -DHP_FAST_SCROLLING +#endif + +SRCS = $(ORIG_SRCS) $(SCROLLING_SRC) + +OBJS = $(ORIG_OBJS) $(SCROLLING_OBJ) + +DEFINES = $(FAST_SCROLLING_DEFINES) ExtensionOSDefines + +INCLUDES = -I. -I.. -I../include -I../../../mfb -I../../../cfb -I../../../mi \ + -I../../../include -I$(XINCLUDESRC) -I$(EXTINCSRC) \ + -I$(FONTINCSRC) + +LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/4.2bsd/llib-los.ln \ + ../../mfb/llib-lmfb.ln ../../mi/llib-lmi.ln ../../cfb/llib-lcfb.ln + +NormalLibraryObjectRule() + +NormalRelocatableTarget(ngle,$(OBJS)) + +LinkFile(ngledoblt.o,ngledoblt.o.8.07) + +DependTarget() diff --git a/xc/programs/Xserver/hw/hp/ngle/dregs.h b/xc/programs/Xserver/hw/hp/ngle/dregs.h new file mode 100644 index 000000000..afbd308da --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/dregs.h @@ -0,0 +1,123 @@ +/* $XConsortium: dregs.h,v 1.3 95/01/24 01:54:12 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 +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. + + *************************************************************************/ + +typedef union { + long int lheight; + long int ly; + struct { + short int x; + short int y; + } xy; + struct { + short int width; + short int height; + } wh; + unsigned long int all; + struct { + unsigned short int high; + unsigned short int low; + } w; + struct { + char b0; + char b1; + char b2; + char b3; + } 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; diff --git a/xc/programs/Xserver/hw/hp/ngle/hyperScrn.c b/xc/programs/Xserver/hw/hp/ngle/hyperScrn.c new file mode 100644 index 000000000..b4fba01ec --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/hyperScrn.c @@ -0,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 */ diff --git a/xc/programs/Xserver/hw/hp/ngle/ngle.h b/xc/programs/Xserver/hw/hp/ngle/ngle.h new file mode 100644 index 000000000..c8784baf0 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/ngle.h @@ -0,0 +1,121 @@ +/* $XConsortium: ngle.h,v 1.3 95/01/24 01:55:45 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 +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. + * + *************************************************************************/ + +#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> +#include <sys/framebuf.h> +#include <fcntl.h> + +#include "X.h" +#include "Xproto.h" + +#include "scrnintstr.h" +#include "cursorstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "colormapst.h" +#include "resource.h" +#include "opaque.h" + +/* included for the mi private structure */ +#include "mibstorest.h" + +#ifndef Card32 +#define Card32 unsigned int +#endif +#ifndef Int32 +#define Int32 int +#endif + +#ifndef Card16 +#define Card16 unsigned short +#endif +#ifndef Int16 +#define Int16 short +#endif + +#ifndef Card8 +#define Card8 unsigned char +#endif +#ifndef Int8 +#define Int8 char +#endif + +#include "ngleextern.h" +#include "dregs.h" +#include "ngledevrom.h" +#include "nglehdw.h" +#include "nglecursor.h" +#include "nglecopy.h" +#include "nglecolormap.h" +#include "nglenoop.h" +#include "hppriv.h" +#include "nglescreen.h" + + +# ifndef S9000_ID_TIMBER /* Bushmaster (710) Graphics */ +# define S9000_ID_TIMBER 0x27F12392 +# endif + +# ifndef S9000_ID_TOMCAT /* 2-headed ELK */ +# define S9000_ID_TOMCAT 0x27FCCB6D +# endif + +# ifndef CRX24_OVERLAY_PLANES /* Overlay planes on CRX24 */ +# 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) + +#define MAX_BITS_PER_RGB 8 /* The maximum number of bits that any + of the DACs have on our hardware. */ + +#endif /* NGLE_H */ diff --git a/xc/programs/Xserver/hw/hp/ngle/ngleblt.c b/xc/programs/Xserver/hw/hp/ngle/ngleblt.c new file mode 100644 index 000000000..f47796239 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/ngleblt.c @@ -0,0 +1,96 @@ +/* $XConsortium: ngleblt.c,v 1.1 93/08/08 12:56:35 rws Exp $ */ + +/* +**************************************************************************** +** DDX WINDOW ROUTINES +** +** (c) Copyright Hewlett-Packard Company, 1992. + +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. +** +**************************************************************************** +*/ + +#include "ngle.h" + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleBitBlt + * + * Description: + * + * This is HP's version of the cfbDoBitBltCopy() routine. This enables + * fast scrolling. + * + ******************************************************************************/ +void ngleBitBlt ( + + DrawablePtr pSrcDraw, + DrawablePtr pDstDraw, + int alu, + RegionPtr prgnDst, + DDXPointPtr pptSrc, + unsigned long planeMask) +{ + BoxPtr pbox; + int nbox; + NgleScreenPrivPtr pScreenPriv; + NgleHdwPtr pDregs; + + /* get pointers so HP's private structures */ + pScreenPriv = NGLE_SCREEN_PRIV(pDstDraw->pScreen); + pDregs = (NgleHdwPtr) pScreenPriv->pDregs; + + + /* get a pointer and count of the boxes */ + pbox = REGION_RECTS(prgnDst); + nbox = REGION_NUM_RECTS(prgnDst); + + /* call the hardware blt routine for each box, but first set up the + * hardware + */ + SETUP_COPYAREA(pDregs); + + if (pScreenPriv->devDepth == 24) + /* do the if statement at this level for performance reasons */ + { + while (nbox--) + { + ngleDepth24_CopyAreaFromToScreen(pSrcDraw, pDstDraw, + pptSrc->x, pptSrc->y, pbox, alu, planeMask); + + pbox++; + pptSrc++; + } + } + else + { + while (nbox--) + { + ngleDepth8_CopyAreaFromToScreen(pSrcDraw, pDstDraw, + pptSrc->x, pptSrc->y, pbox, alu, planeMask); + + pbox++; + pptSrc++; + } + } + + /* Now restore the hardware state so the CFB driver can use it */ + SETUP_FB(pDregs, pScreenPriv->deviceID,pScreenPriv->devDepth); +} diff --git a/xc/programs/Xserver/hw/hp/ngle/nglecolormap.c b/xc/programs/Xserver/hw/hp/ngle/nglecolormap.c new file mode 100644 index 000000000..8918fae76 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglecolormap.c @@ -0,0 +1,795 @@ +/* $TOG: nglecolormap.c /main/3 1997/10/16 16:26:56 kaleb $ */ + +/************************************************************************* + * + * (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. + * + *************************************************************************/ + +/****************************************************************************** + * + * DDX entry points relating to color for NGLE driver: + * + * ngleLoadCursorColormap() + * ngleCreateDefColormap() + * ngleCreateColormap() + * ngleInstallColormap() + * ngleStoreColors() + * ngleListInstalledColormaps() + * ngleUninstallColormap() + * ngleDestroyColormap() + * + ******************************************************************************/ + +#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; \ +} + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleLoadCursorColormap() + * + * Description: + * + * This routine is called by ngleDisplayCursor and ngleRecolorCursor + * to load into the NGLE hardware the 2-entry colormap for cursors. + * + * This procedure is internal to the NGLE driver: it is not + * called from outside the driver, neither directly nor indirectly + * through a procedure table. + * + ******************************************************************************/ + +void ngleLoadCursorColormap( + ScreenPtr pScreen, + CursorPtr pCursor) +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + NgleHdwPtr pDregs = pScreenPriv->pDregs; + Card32 color; + Card8 intensity; + + + /* Set up for drawing to the off-screen colormap table */ + START_CURSOR_COLORMAP_ACCESS(pDregs); + + /* X11 stores each R/G/B of a color in unsigned shorts (16 bits). + * Scale to 8 bits and place in lower 24 bits of color. + */ + if (pScreenPriv->isGrayScale) + { + CALCULATE_GRAYSCALE_INTENSITY(intensity, + (pCursor->backRed >> 8), + (pCursor->backGreen >> 8), + (pCursor->backBlue >> 8)); + /* Replicate intensity to red, green, and blue */ + color = (Card32) + ( (intensity << 16) + | (intensity << 8) + | intensity + ); + WRITE_CURSOR_COLOR(pDregs,color); + + CALCULATE_GRAYSCALE_INTENSITY(intensity, + (pCursor->foreRed >> 8), + (pCursor->foreGreen >> 8), + (pCursor->foreBlue >> 8)); + /* Replicate intensity to red, green, and blue */ + color = (Card32) + ( (intensity << 16) + | (intensity << 8) + | intensity + ); + WRITE_CURSOR_COLOR(pDregs,color); + } + else + { + color = ( ((Card32) (pCursor->backRed & 0xff00) << 8) + | (Card32) (pCursor->backGreen & 0xff00) + | (Card32) (pCursor->backBlue >> 8) + ); + WRITE_CURSOR_COLOR(pDregs,color); + + color = ( ((Card32) (pCursor->foreRed & 0xff00) << 8) + | (Card32) (pCursor->foreGreen & 0xff00) + | (Card32) (pCursor->foreBlue >> 8)); + WRITE_CURSOR_COLOR(pDregs,color); + } + + FINISH_CURSOR_COLORMAP_ACCESS(pDregs,pScreenPriv->deviceID, + pScreenPriv->devDepth); + +} /* ngleLoadCursorColormap() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleCreateDefColormap + * + * Description: Create a default colormap for the given screen's root window. + * + * Called by: DDX procedure ngleScreenInit + * + * Creates default colormap, initializes all of its entries, + * installs it into hardware, then points pScreen->defColormap to it. + * + ******************************************************************************/ + +Bool +ngleCreateDefColormap( + ScreenPtr pScreen) +{ + VisualPtr pVisual; + ColormapPtr pColormap; + unsigned short red_zero = 0, red_ones = ~0; + unsigned short green_zero = 0, green_ones = ~0; + unsigned short blue_zero = 0, blue_ones = ~0; + + /* Scan the table of visuals for this screen, looking for the + * rootVisual. + */ + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++) + ; + + /* Create a colormap, not allocating (reserving) any entries. */ + if (CreateColormap (pScreen->defColormap, pScreen, pVisual, + &pColormap, AllocNone, 0) != Success) + { + return FALSE; + } + + /* Reserve entries for black and white */ + if (AllocColor (pColormap, &red_zero, &green_zero, &blue_zero, + &(pScreen->blackPixel), 0) + || AllocColor(pColormap, &red_ones, &green_ones, &blue_ones, + &(pScreen->whitePixel), 0)) + { + FatalError("Unable to reserve black and white pixels.\n"); + } + + /* Install initialized colormap as default into hardware. */ + ngleInstallColormap(pColormap); + + return(TRUE); +} /* ngleCreateDefColormap() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleCreateColormap() + * + * Description: Perform device-specific initialization of new colormap. + * + * Entry: pmap points to the colormap in question + * + * Return Value: None + * + * Called by: DIX CreateColormap + * + ******************************************************************************/ + +Bool +ngleCreateColormap( + ColormapPtr pmap) +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pmap->pScreen); + xColorItem localColor; + int i; + VisualPtr pVisual = pmap->pVisual; + + localColor.flags = DoRed | DoGreen | DoBlue; + + if (pVisual->class == DirectColor ) + { + for (i = 0; i < pVisual->ColormapEntries; i++) + { + localColor.pixel = i << pVisual->offsetBlue + | i << pVisual->offsetGreen + | i << pVisual->offsetRed; + + localColor.red = pmap->red[i].co.local.red = i << 8; + localColor.green = pmap->green[i].co.local.green = i << 8; + localColor.blue = pmap->blue[i].co.local.blue = i << 8; + + ngleStoreColors(pmap, 1, &localColor); + } + } + else if (pVisual->class == PseudoColor ) + { + if (pScreenPriv->isGrayScale) + { + for(i = 0; i < pVisual->ColormapEntries; i++) + { + localColor.pixel = i; + localColor.red = pmap->red[i].co.local.red = i << 8; + localColor.green = pmap->red[i].co.local.green = i << 8; + localColor.blue = pmap->red[i].co.local.blue = i << 8; + + ngleStoreColors(pmap, 1, &localColor); + } + } + else + { + for(i = 0; i < pVisual->ColormapEntries; i++) + { + localColor.pixel = i; + localColor.red = pmap->red[i].co.local.red = (i & 0x7) << 13; + localColor.green = pmap->red[i].co.local.green = (i & 0x38) << 10; + localColor.blue = pmap->red[i].co.local.blue = (i & 0xc0) << 8; + + ngleStoreColors(pmap, 1, &localColor); + } + } + } + else + { + ErrorF("ngleCreateColormap: Unsupported visual type\n"); + } + + return(TRUE); +} /* ngleCreateColormap() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleInstallColormap() + * + * Description: Install given colormap into hardware. + * + * Results: + * None + * + * Side Effects: + * All clients requesting ColormapNotify are notified + * Colormap is installed into NGLE hardware + * + ******************************************************************************/ + +void ngleInstallColormap( + ColormapPtr cmap) +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(cmap->pScreen); + NgleHdwPtr pDregs = pScreenPriv->pDregs; + unsigned int i; + Card32 color; + int nColormapEntries = cmap->pVisual->ColormapEntries; + Card8 intensity; + unsigned short red, green, blue; + + + /* We do not need to install if this is the current map. + * it's already installed. + */ + if (cmap == pScreenPriv->installedMap) + return; + + + /* If uninstalling an explicitly installed map, tell everybody */ + if (pScreenPriv->installedMap) + { + WalkTree(pScreenPriv->installedMap->pScreen, TellLostMap, + (char *) &(pScreenPriv->installedMap->mid)); + } + + /* setup colormap hardware */ + START_IMAGE_COLORMAP_ACCESS(pDregs); + + /* Load each colormap entry into shadow RAM */ + + if (cmap->pVisual->class == DirectColor) + { + for (i=0; i < nColormapEntries; i++) + { + if (cmap->red[i].fShared) + red = cmap->red[i].co.shco.red->color; + else + red = cmap->red[i].co.local.red; + + if (cmap->green[i].fShared) + green = cmap->green[i].co.shco.green->color; + else + green = cmap->green[i].co.local.green; + + if (cmap->blue[i].fShared) + blue = cmap->blue[i].co.shco.blue->color; + else + blue = cmap->blue[i].co.local.blue; + + if (!pScreenPriv->isGrayScale) + { + color = ( ((Card32) (red & 0xff00) << 8) + | (Card32) (green & 0xff00) + | ((Card32) (blue & 0xff00) >> 8) + ); + } + else + { /* Gray Scale */ + CALCULATE_GRAYSCALE_INTENSITY(intensity, + (red >> 8), + (green >> 8), + (blue >> 8)); + color = intensity | (intensity << 8) | (intensity << 16); + } + + pScreenPriv->hwColors[i] = color; + + WRITE_IMAGE_COLOR(pDregs,i,color); + } + } + else /* PseudoColor */ + { + for (i=0; i < nColormapEntries; i++) + { + if (cmap->red[i].fShared) + { + red = cmap->red[i].co.shco.red->color; + green = cmap->red[i].co.shco.green->color; + blue = cmap->red[i].co.shco.blue->color; + } + else if (cmap->red[i].refcnt != 0) + { + red = cmap->red[i].co.local.red; + green = cmap->red[i].co.local.green; + blue = cmap->red[i].co.local.blue; + } + else + { + /* take it apart, so it can be put together again */ + red = (pScreenPriv->hwColors[i] & 0xff0000) >> 8; + green = (pScreenPriv->hwColors[i] & 0x00ff00); + blue = (pScreenPriv->hwColors[i] & 0x0000ff) << 8; + } + + if (!pScreenPriv->isGrayScale) + { + color = ( ((Card32) (red & 0xff00) << 8) + | (Card32) (green & 0xff00) + | ((Card32) (blue & 0xff00) >> 8) + ); + } + else + { /* Gray Scale */ + CALCULATE_GRAYSCALE_INTENSITY(intensity, + (red >> 8), + (green >> 8), + (blue >> 8)); + color = intensity | (intensity << 8) | (intensity << 16); + } + + pScreenPriv->hwColors[i] = color; + + WRITE_IMAGE_COLOR(pDregs,i,color); + } + } + + 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)); + +} /* ngleInstallColormap() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleStoreColors() + * + * Description: Sets the pixels in pdefs into the specified map. + * + * If the colormap being updated has been loaded into the + * NGLE hardware, update there as well. + * + * Results: + * None + * + * Parameters: + * Colors in xColorItem *pDefs are Card16's (not Card8s); + * Must be shifted right 8 before loading into 8 bit DAC. + * + * Side Effects: + * Hardware updated if colormap loaded. + * + * Note on Gray Scale: + * Intensity calculation of using a RGB weighting of (.3,.59,.11) + * is the NTSC weighting formula. + * + ******************************************************************************/ + +void +ngleStoreColors( + ColormapPtr pmap, + int ndef, + xColorItem *pdefs) +{ + Card32 index; + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pmap->pScreen); + short intensity; /* gray scale */ + NgleHdwPtr pDregs = pScreenPriv->pDregs; + Card32 color; + VisualPtr pVisual = pmap->pVisual; + int i; + + + /* We do not need to update HW if this is not the current map. + */ + if (pmap != pScreenPriv->installedMap) + return; + + /* setup colormap hardware */ + START_IMAGE_COLORMAP_ACCESS(pDregs); + + if (pVisual->class == DirectColor) + { + for (i = 0; i < ndef; i++) + { + if ((pdefs+i)->flags & DoRed) + { + index = ((pdefs+i)->pixel & pVisual->redMask) + >> pVisual->offsetRed; + color = pScreenPriv->hwColors[index]; + color = ((((pdefs+i)->red) << 8) & 0xff0000) | (color & 0xffff); + pScreenPriv->hwColors[index] = color; + + WRITE_IMAGE_COLOR(pDregs, index, color); + } + if ((pdefs+i)->flags & DoGreen) + { + index = ((pdefs+i)->pixel & pVisual->greenMask) + >> pVisual->offsetGreen; + color = pScreenPriv->hwColors[index]; + color = (((pdefs+i)->green) & 0xff00) | (color & 0xff00ff); + pScreenPriv->hwColors[index] = color; + + WRITE_IMAGE_COLOR(pDregs, index, color); + } + if ((pdefs+i)->flags & DoBlue) + { + index = ((pdefs+i)->pixel & pVisual->blueMask) + >> pVisual->offsetBlue; + color = pScreenPriv->hwColors[index]; + color = ((((pdefs+i)->blue) >> 8) & 0xff) | (color & 0xffff00); + pScreenPriv->hwColors[index] = color; + + WRITE_IMAGE_COLOR(pDregs, index, color); + } + } + } + else /* PseudoColor */ + { + while (ndef--) + { + index = pdefs->pixel&0xff; + + if (!pScreenPriv->isGrayScale) + { + color = pScreenPriv->hwColors[index]; + + if( pdefs->flags & DoRed) + { + color = (((pdefs->red) << 8) & 0xff0000) | (color & 0xffff); + } + if( pdefs->flags & DoGreen) + { + color = ((pdefs->green) & 0xff00) | (color & 0xff00ff); + } + if( pdefs->flags & DoBlue) + { + color = (((pdefs->blue) >> 8) & 0xff) | (color & 0xffff00); + } + } + else + { /* Gray Scale */ + if ((pdefs->flags & DoRed) + || (pdefs->flags & DoGreen) + || (pdefs->flags & DoBlue)) + { + CALCULATE_GRAYSCALE_INTENSITY(intensity, + ((pdefs->red) >> 8), + ((pdefs->green) >> 8), + ((pdefs->blue) >> 8)); + + color = intensity | (intensity << 8) | (intensity << 16); + } + } + + pScreenPriv->hwColors[index] = color; + + WRITE_IMAGE_COLOR(pDregs,index,color); + + pdefs++; + } + } + + 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() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleListInstalledColormaps() + * + * Description: Fills in the list with the IDs of the installed maps. + * + * Results: + * Returns the number of IDs in the list + * + * Side Effects: + * None + * + ******************************************************************************/ + +int +ngleListInstalledColormaps( + ScreenPtr pScreen, + Colormap *pCmapList) +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + + *pCmapList = pScreenPriv->installedMap->mid; + return (1); +} /* ngleListInstalledColormaps() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleUninstallColormap() + * + * Description: If given colormap installed, uninstall it. + * If the colormap's visual is the default (root) visual, + * take care that _some_ colormap is installed: + * if cmap is default colormap, leave installed, + * else install default colormap. + * Caveat: + * It is possible to receive a request to uninstall a colormap that + * is not installed. In this case, ngleUninstallColormap will mark + * the colormap as uninstalled and return correctly. + * + * Results: + * None + * + * Side Effects: + * All clients requesting ColormapNotify are notified + * + ******************************************************************************/ + +void +ngleUninstallColormap( ColormapPtr cmap) +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(cmap->pScreen); + + if (cmap == pScreenPriv->installedMap) + { + Colormap defMapID = cmap->pScreen->defColormap; + + /* Don't uninstall default colormap */ + if (cmap->mid != defMapID) + { + ColormapPtr defMap = + (ColormapPtr) LookupIDByType(defMapID, RT_COLORMAP); + + if (defMap) + ngleInstallColormap(defMap); + else + ErrorF("ngleUninstallColormap: ", + "Can't find default colormap\n"); + } + } +} /* ngleUninstallColormap() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleDestroyColormap() + * + * Description: Perform device-specific operations to destroy a colormap. + * + * Entry: pmap points to the colormap of interest. + * + * Return Value: none + * + * Called by: DIX DestroyColormap routine + * + ******************************************************************************/ + +void +ngleDestroyColormap( + ColormapPtr pmap +) +{ + return; +} /* ngleDestroyColormap */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleResolvePseudoColor() + * + * Description: Normalize colors to device. + * + ******************************************************************************/ + +void +ngleResolvePseudoColor( + Card16 *pRed, + Card16 *pGreen, + Card16 *pBlue, + VisualPtr pVisual) +{ + unsigned short mask; + unsigned short bits = pVisual->bitsPerRGBValue; + unsigned short mult = 0xffff / ((1 << bits) - 1); + unsigned short round = (1 << ( 16 - pVisual->bitsPerRGBValue))/ 2; + + + /* + * Now we need to figure out how many bits/rgb this visual + * (hardware) has and then normalize the request value to that. + */ + + mask = ((1 << bits) - 1) << (MAX_BITS_PER_RGB - bits); + *pRed = ((*pRed) - (*pRed >> pVisual->bitsPerRGBValue)) + round; + *pGreen = ((*pGreen) - (*pGreen >> pVisual->bitsPerRGBValue)) + round; + *pBlue = ((*pBlue) - (*pBlue >> pVisual->bitsPerRGBValue)) + round; + + *pRed = mult * ((((*pRed) >> MAX_BITS_PER_RGB ) & mask) >> + (MAX_BITS_PER_RGB - bits)); + *pGreen = mult * ((((*pGreen) >> MAX_BITS_PER_RGB ) & mask) >> + (MAX_BITS_PER_RGB - bits)); + *pBlue = mult * ((((*pBlue) >> MAX_BITS_PER_RGB ) & mask) >> + (MAX_BITS_PER_RGB - bits)); + + 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() */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglecolormap.h b/xc/programs/Xserver/hw/hp/ngle/nglecolormap.h new file mode 100644 index 000000000..07c8e92c2 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglecolormap.h @@ -0,0 +1,84 @@ +/* $XConsortium: nglecolormap.h,v 1.2 95/01/24 02:02:01 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 +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. + * + *************************************************************************/ + +/****************************************************************************** + * + * Defines shared structure NgleDisplayRec as well as + * DDX-specific entry points relating to color for NGLE driver. + * + ******************************************************************************/ + +#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); + +extern void ngleUninstallColormap( + ColormapPtr pColormap); + +extern int ngleListInstalledColormaps( + ScreenPtr pScreen, + Colormap *pCmapList); + +extern void ngleStoreColors( + ColormapPtr pCmap, + int ndef, + xColorItem *pdefs); + +extern Bool ngleCreateColormap( + ColormapPtr pCmap); + +extern void ngleDestroyColormap( + ColormapPtr pCmap); + +extern void ngleResolvePseudoColor( + Card16 *pRed, + Card16 *pGreen, + Card16 *pBlue, + VisualPtr pVisual); + + +#endif /* NGLECOLORMAP_H */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglecopy.c b/xc/programs/Xserver/hw/hp/ngle/nglecopy.c new file mode 100644 index 000000000..dae5c083d --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglecopy.c @@ -0,0 +1,154 @@ +/* $TOG: nglecopy.c /main/2 1997/11/11 15:45:45 msr $ */ + +/* +**************************************************************************** +** DDX WINDOW ROUTINES +** +** (c) Copyright Hewlett-Packard Company, 1992. +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. +** +**************************************************************************** +*/ + +#include "ngle.h" + +/* Extern decalarations for CFB routines */ +/* Depth 8 CFB functions */ +extern int cfbDoBitbltGeneral(); +extern int cfbDoBitbltCopy(); +extern int cfbDoBitbltXor(); +extern int cfbDoBitbltOr(); +extern RegionPtr cfbBitBlt(); + +/* Depth 24 CFB functions */ +extern int cfb32DoBitbltGeneral(); +extern int cfb32DoBitbltCopy(); +extern int cfb32DoBitbltXor(); +extern int cfb32DoBitbltOr(); +extern RegionPtr cfb32BitBlt(); + +/* Ngle routines */ + +extern int ngleBitBlt(); + +/*************************************************************************** + * + * ngleCopyArea8() + * + * This routine is a replacement for cfbCopyArea(), to allow us to + * call our own block move routine when we are in the scrolling + * case. + * + *************************************************************************** + */ + +RegionPtr ngleCopyArea8(pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty) + register DrawablePtr pSrcDrawable; + register DrawablePtr pDstDrawable; + GC *pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; +{ + int (*doBitBlt) (); + + doBitBlt = cfbDoBitbltCopy; + + if (( pSrcDrawable == pDstDrawable) && + (pSrcDrawable->type == DRAWABLE_WINDOW) && + (pDstDrawable->type == DRAWABLE_WINDOW)) + { + doBitBlt = ngleBitBlt; + } + + if (pGC->alu != GXcopy || (pGC->planemask & 0xff) != 0xff) + { + doBitBlt = cfbDoBitbltGeneral; + if ((pGC->planemask & 0xff) == 0xff) + { + switch (pGC->alu) { + case GXxor: + doBitBlt = cfbDoBitbltXor; + break; + case GXor: + doBitBlt = cfbDoBitbltOr; + break; + } + } + } + + return cfbBitBlt (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0); +} + + +/*************************************************************************** + * + * ngleCopyArea24() + * + * This routine is a replacement for cfb32CopyArea(), to allow us to + * call our own block move routine when we are in the scrolling + * case. + * + *************************************************************************** + */ + +#ifndef LOWMEMFTPT + +RegionPtr ngleCopyArea24(pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty) + register DrawablePtr pSrcDrawable; + register DrawablePtr pDstDrawable; + GC *pGC; + int srcx, srcy; + int width, height; + int dstx, dsty; +{ + int (*doBitBlt) (); + + doBitBlt = cfb32DoBitbltCopy; + + if (( pSrcDrawable == pDstDrawable) && + (pSrcDrawable->type == DRAWABLE_WINDOW) && + (pDstDrawable->type == DRAWABLE_WINDOW)) + { + doBitBlt = ngleBitBlt; + } + + if (pGC->alu != GXcopy || (pGC->planemask & 0xffffffff) != 0xffffffff) + { + doBitBlt = cfb32DoBitbltGeneral; + if ((pGC->planemask & 0xffffffff) == 0xffffffff) + { + switch (pGC->alu) { + case GXxor: + doBitBlt = cfb32DoBitbltXor; + break; + case GXor: + doBitBlt = cfb32DoBitbltOr; + break; + } + } + } + + return cfb32BitBlt (pSrcDrawable, pDstDrawable, + pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0); +} + +#endif /* ifndef LOWMEMFTPT */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglecopy.h b/xc/programs/Xserver/hw/hp/ngle/nglecopy.h new file mode 100644 index 000000000..bf9641cdf --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglecopy.h @@ -0,0 +1,39 @@ +/* $XConsortium: nglecopy.h,v 1.1 93/08/08 12:57:01 rws 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. + * + *************************************************************************/ + +#ifndef NGLECOPY +#define NGLECOPY + +/* + ****************************************************************************** + ** + ** Extern declarations + ** + ****************************************************************************** + */ + +extern RegionPtr ngleCopyArea8(); +extern RegionPtr ngleCopyArea24(); + +#endif /* NGLECOPY */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglecursor.c b/xc/programs/Xserver/hw/hp/ngle/nglecursor.c new file mode 100644 index 000000000..4813b3e01 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglecursor.c @@ -0,0 +1,1037 @@ +/* $XConsortium: nglecursor.c,v 1.3 95/01/24 02:05:50 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 +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 procedures that implement cursor + * functionality (for both sprites and echoes). + * + ******************************************************************************/ + +#include "ngle.h" + +extern WindowPtr *WindowTable; +extern int hpActiveScreen; /* input driver global */ + +/* Defined in nglecolormap.c: */ +extern void ngleLoadCursorColormap( + ScreenPtr pScreen, + CursorPtr pCursor); + + + +/****************************************************************************** + * + * 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: + * + * This routine is called at ScreenInit() time to initialize various + * cursor/sprite structures and the NGLE sprite code. + * + ******************************************************************************/ + +Bool ngleInitSprite(pScreen) + + + ScreenPtr pScreen; +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + hpPrivPtr php = (hpPrivPtr)pScreen->devPrivate; + NgleHdwPtr pDregs = pScreenPriv->pDregs; + NgleDevRomDataPtr pDevRomData = pScreenPriv->pDevRomData; + Int32 nScanlinesToZero; + + + /* Initialize the pScreen Cursor Procedure Pointers: */ + pScreen->PointerNonInterestBox = ngleNoop; + pScreen->CursorLimits = hpCursorLimits; + pScreen->ConstrainCursor = hpConstrainCursor; + pScreen->SetCursorPosition = hpSetCursorPosition; + pScreen->DisplayCursor = ngleDisplayCursor; + pScreen->RealizeCursor = ngleNoopTrue; + pScreen->UnrealizeCursor = ngleNoopTrue; + pScreen->RecolorCursor = ngleRecolorCursor; + + + /* Initialize the HP private 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; + GET_CURSOR_SPECS(pDregs,pScreenPriv); + pScreenPriv->sprite.pipelineDelay = pDevRomData->cursor_pipeline_delay; + pScreenPriv->sprite.videoInterleave = pDevRomData->video_interleaves; + if (pScreenPriv->deviceID == S9000_ID_A1439A) + { + pScreenPriv->sprite.pipelineDelay--; + } + + /* Zero out 64 bits (2 longs) in each scanline */ + START_CURSOR_MASK_ACCESS(pDregs); + nScanlinesToZero = NGLE_MAX_SPRITE_SIZE; + do + { + WRITE_CURSOR_BITS(pDregs,0,0); + } while (--nScanlinesToZero); + + /* Zero out 64 bits (2 longs) in each scanline */ + START_CURSOR_DATA_ACCESS(pDregs); + nScanlinesToZero = NGLE_MAX_SPRITE_SIZE; + do + { + WRITE_CURSOR_BITS(pDregs,0,0); + } while (--nScanlinesToZero); + + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + + return(TRUE); + +} /* ngleInitSprite() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleUninitSprite() + * + * Description: + * + * This routine is called at CloseScreen() time to free various + * cursor/sprite structures and shutdown the NGLE sprite code. + * + ******************************************************************************/ + +Bool ngleUninitSprite(pScreen) + + ScreenPtr pScreen; +{ + hpPrivPtr php; + + php = (hpPrivPtr)pScreen->devPrivate; + php->MoveMouse = ngleNoop; + php->CursorOff = ngleNoop; + php->ChangeScreen = ngleNoop; + + return(TRUE); + +} /* ngleUninitSprite() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleDisableSprite() + * + * Description: + * + * This routine is called from the input driver to disable + * a screen's sprite (make it invisible) when the cursor/sprite moves + * to another screen when the server is in a multi-headed configuration. + * The sprite is re-enabled for a screen by a call to DisplayCursor(). + * + ******************************************************************************/ + +void ngleDisableSprite(pScreen) + + ScreenPtr pScreen; +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + + + if (pScreenPriv->sprite.visible) + { + pScreenPriv->sprite.visible == FALSE; + DISABLE_CURSOR(pScreenPriv); + } + +} /* ngleDisableSprite() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleChangeScreen() + * + * Description: + * + * This routine is intended to handle changing the current screen. + * pScreen points to new screen. + * + ******************************************************************************/ + +void ngleChangeScreen(pScreen) + + ScreenPtr pScreen; +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + WindowPtr pRootWindow = WindowTable[pScreen->myNum]; + + if (pScreenPriv->sprite.pCursor == NULL) + { + /* This should only occur once and only for screens 1 and above. + * Reason: server calls DisplayCursor during initialization, + * but before rootwindow (and default cursor) have been defined. + * So DisplayCursor exited at very top - before firstCall is set false. + */ + + /* Do load and enable cursor. */ + (*pScreen->DisplayCursor)(pScreen, pRootWindow->optional->cursor); + } + +} /* ngleChangeScreen() */ + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleDisplayCursor() + * + * 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. + * + ******************************************************************************/ + +Bool ngleDisplayCursor(pScreen, pCursor) + + ScreenPtr pScreen; + CursorPtr pCursor; +{ + NgleScreenPrivPtr pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + hpPrivPtr php = (hpPrivPtr)pScreen->devPrivate; + WindowPtr pRootWindow; + NgleHdwPtr pDregs; + Card32 *pSrc; + Int32 nScanlines; /* loop variable */ + Int32 heightPlus1; + Int32 sourceIncrement; + Int32 nScanlinesToZeroPlus1; + Int32 nOffscreenScanlines = 0; + Int32 x0, y0; /* Sprite origin (not hotspot) */ + Int32 xHi, /* For cursor positioning */ + xLo; + Int32 i; + Card32 srcMask; + Card32 cursorXYValue = 0; + int nTopPadLines = 0; + int nBotPadLines = 0; + Int32 hbp_times_vi; + + + + /* + *************************************************************************** + ** 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 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: */ + if ((pCursor->bits->width > NGLE_MAX_SPRITE_SIZE) || + (pCursor->bits->height > NGLE_MAX_SPRITE_SIZE)) + return(FALSE); /* Cursor is TOO big */ + + 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: + ****/ + DISABLE_CURSOR(pScreenPriv); + } + + if ( (pScreenPriv->deviceID == S9000_ID_TIMBER) + || (pScreenPriv->deviceID == S9000_ID_A1439A)) + { + int nPadLines = NGLE_MAX_SPRITE_SIZE - pCursor->bits->height; + if (nPadLines >= NTOPLINES_FOR_TIMBER) + { + nPadLines -= NTOPLINES_FOR_TIMBER; + /* Split extra lines between top and bottom */ + nBotPadLines = nPadLines/2; + nTopPadLines = NTOPLINES_FOR_TIMBER + nPadLines - nBotPadLines; + } + else + { + nTopPadLines = nPadLines; + } + } + else + { /* ELK */ + nTopPadLines = 0; + nBotPadLines = NGLE_MAX_SPRITE_SIZE - pCursor->bits->height; + } + + /* Calculate cursor origin (not hotspot) and number of scanlines not + * actually displayed, including any padding scanlines at top. + */ + x0 = pScreenPriv->sprite.x - pCursor->bits->xhot; + y0 = pScreenPriv->sprite.y + - (pCursor->bits->yhot + nTopPadLines); + + /* If y0 is less than zero, some scanlines of cursor won't be displayed. + * This fudge factor will be used at cursor enable time. + */ + if (y0 < 0) + { + nOffscreenScanlines = - y0; + y0 = 0; + } + + pDregs = pScreenPriv->pDregs; + + /* 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; + + if (pCursor->bits->width <= 32) + { + /* Form left justified mask of meaningful bits in cursor + * data and mask. Reason: old cursor may be larger and + * needs to be zeroed out, not left unchanged. + */ + srcMask = 0xffffffffUL << (32 - pCursor->bits->width); + + /* write cursor mask to HW */ + START_CURSOR_MASK_ACCESS(pDregs); + pSrc = (Card32 *) pCursor->bits->mask; + + nScanlines = nTopPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + + nScanlines = heightPlus1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,(*pSrc++ & srcMask),0); + } + + nScanlines = nBotPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + + /* write cursor data to HW */ + START_CURSOR_DATA_ACCESS(pDregs); + pSrc = (Card32 *) pCursor->bits->source; + + nScanlines = nTopPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + + nScanlines = heightPlus1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,(*pSrc++ & srcMask),0); + } + + nScanlines = nBotPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + } + else + { /* Width == 64 */ + + /* Form left justified mask of meaningful bits + * second word in cursor data and mask. + */ + srcMask = 0xffffffffUL << (64 - pCursor->bits->width); + + /* write cursor mask to HW */ + START_CURSOR_MASK_ACCESS(pDregs); + pSrc = (Card32 *) pCursor->bits->mask; + + nScanlines = nTopPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + + nScanlines = heightPlus1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,(*pSrc++),(*pSrc++ & srcMask)); + } + + nScanlines = nBotPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + + /* write cursor data to HW */ + START_CURSOR_DATA_ACCESS(pDregs); + pSrc = (Card32 *) pCursor->bits->source; + + nScanlines = nTopPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + + nScanlines = heightPlus1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,(*pSrc++),(*pSrc++ & srcMask)); + } + + nScanlines = nBotPadLines + 1; + while (--nScanlines) + { + WRITE_CURSOR_BITS(pDregs,0,0); + } + } + + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + + /* 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. + */ + + /* Update cursor X/Y position register, which contains + * all cursor position information except the number + * of scanlines hidden. + */ + if (pScreenPriv->deviceID != S9000_ID_ARTIST) + { + xHi = (x0 / pScreenPriv->sprite.videoInterleave) + + pScreenPriv->sprite.horizBackPorch + - pScreenPriv->sprite.pipelineDelay; + xLo = x0 % pScreenPriv->sprite.videoInterleave; + } + else + { + hbp_times_vi = (pScreenPriv->sprite.horizBackPorch * + pScreenPriv->sprite.videoInterleave); + xHi = ((x0 + hbp_times_vi) / pScreenPriv->sprite.videoInterleave) + - pScreenPriv->sprite.pipelineDelay; + 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) + ); + + /* Update values maintained in pScreenPriv->sprite */ + pScreenPriv->sprite.visible = TRUE; + pScreenPriv->sprite.width = pCursor->bits->width; + pScreenPriv->sprite.height = pCursor->bits->height; + pScreenPriv->sprite.nTopPadLines = nTopPadLines; + + /* ENABLE_CURSOR macro uses value of sprite.moveOnVBlank + * in deciding whether to wait for vertical blank before moving + * cursor. + */ + switch (pScreenPriv->moveCursorOnVBlank) + { + case CURSOR_AT_VBLANK_ALWAYS: + pScreenPriv->sprite.moveOnVBlank = TRUE; + break; + + case CURSOR_AT_VBLANK_NEVER: + pScreenPriv->sprite.moveOnVBlank = FALSE; + break; + + case CURSOR_AT_VBLANK_DRIVEROPTION: + if (( (pScreenPriv->deviceID == S9000_ID_TIMBER) + || (pScreenPriv->deviceID == S9000_ID_A1439A) + ) + && (nTopPadLines < NTOPLINES_FOR_TIMBER)) + { + pScreenPriv->sprite.moveOnVBlank = TRUE; + } + else + { + pScreenPriv->sprite.moveOnVBlank = FALSE; + } + break; + } + + /**** 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. + */ + ENABLE_CURSOR(pScreenPriv, cursorXYValue, nOffscreenScanlines); + + return(TRUE); + +} /* 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() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleRecolorCursor() + * + * Description: + * + * This routine is called from DIX whenever a color(s) for a "cursor" + * (i.e. image and mask bits, foreground and background color) change. + * Since this routine may be called for a "cursor" that isn't the + * current "sprite", care must be excercised before changing the colors + * in the hardware cursor. + * + ******************************************************************************/ + +void ngleRecolorCursor(pScreen, pCursor, displayed) + + ScreenPtr pScreen; + CursorPtr pCursor; + Bool displayed; +{ + /* Since DisplayCursor updates the cursor foreground and background + * colors before displaying it, we only need to re-load the + * cursor colormap if the cursor changing colors is already being + * displayed. + */ + + if (displayed) + ngleLoadCursorColormap(pScreen, pCursor); + +} /* ngleRecolorCursor() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleMoveSprite() + * + * Description: + * + * This routine is called from the input driver whenever the + * pointer device (e.g. mouse) is moved. + * + ******************************************************************************/ + +void ngleMoveSprite(pScreen, xhot, yhot, forceit) + + ScreenPtr pScreen; + Int16 xhot,yhot; + Bool forceit; +{ + NgleScreenPrivPtr pScreenPriv; + CursorBitsPtr pCursorBits; + Int32 x0, y0; + Int32 nOffscreenScanlines = 0; + Int32 hbp_times_vi, /* For cursor positioning */ + xHi, + xLo; + Card32 cursorXYValue = 0; + NgleHdwPtr pDregs; + Int32 nFreeFifoSlots = 0; + +#ifdef XTESTEXT1 + extern Int32 on_steal_input; /* Defined in xtestext1di.c */ + + if (on_steal_input) + check_for_motion_steal(xhot, yhot); /* XTM */ +#endif /* XTESTEXT1 */ + + pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + pDregs = pScreenPriv->pDregs; + + /* Only move if cursor defined and position changed. + * + * (Cursor should be defined before this procedure called, + * but one case may occur on multi-headed server when changing + * cursor to new screen) + */ + if ((pScreenPriv->sprite.pCursor != NULL) + && ((xhot != pScreenPriv->sprite.x) || (yhot != pScreenPriv->sprite.y))) + { + /* Define local pointer to cursor xhot and yhot offsets */ + pCursorBits = pScreenPriv->sprite.pCursor->bits; + + pScreenPriv->sprite.x = xhot; + pScreenPriv->sprite.y = yhot; + + if (pScreenPriv->sprite.visible) + { + /* 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() */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglecursor.h b/xc/programs/Xserver/hw/hp/ngle/nglecursor.h new file mode 100644 index 000000000..58f22de72 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglecursor.h @@ -0,0 +1,143 @@ +/* $XConsortium: nglecursor.h,v 1.2 95/01/24 02:07:13 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 +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 macros, typedefs and extern declarations + * concerning cursors (both sprites and echoes). + * + ******************************************************************************/ + +#ifndef NGLECURSOR_H +#define NGLECURSOR_H + + +/* The following is the maximum width/height supported by the NGLE cursor + * hardware: + */ +#define NGLE_MAX_SPRITE_SIZE 64 + + +/* + ****************************************************************************** + ** + ** NGLE DDX Driver's Sprite Structure: + ** + ****************************************************************************** + */ +typedef struct _NgleSpriteRec +{ + /* The sprite's state - visible or not visible */ + Int32 visible; + + /* Location of the sprite's hotspot relative to the screen's origin: */ + Int32 x; + Int32 y; + + /* Pointer to currently installed cursor struct: */ + CursorPtr pCursor; + + /* See the comment fairly early on in ngleDisplayCursor: */ + Int32 firstCallTo_DisplayCursor; + + /* Hardware values that affect cursor positioning. + * Read in at X11 startup. + */ + Card32 horizBackPorch; + Card32 maxYLine; + Card32 pipelineDelay; + Card32 videoInterleave; + + /* Value of hardware register value written at cursor enable */ + Card32 enabledCursorXYValue; + + /* Save current cursor width and height. When new cursor requested, + * old cursor's structures (pointed to by pCursor above) may already + * have been de-allocated. Used to minimize scanlines that must be written. + */ + Int32 height; + Int32 width; + + /* Cursor Y position adjustment */ + Int32 nTopPadLines; + + /* Value related to nTopPadLines: should cursor only be moved + * while vertical blank is in progress? + * + * Set in ngleDisplayCursor() and used in ENABLE_CURSOR macro. + */ + Bool moveOnVBlank; + +} NgleSpriteRec, *NgleSpritePtr; + + +/* + ****************************************************************************** + ** + ** Macros to Access the NGLE DDX Driver's Sprite Structure: + ** + ****************************************************************************** + */ + +#define NGLE_SPRITE_FROM_SCREEN(pScreen)\ + (NGLE_SCREEN_PRIV(pScreen)->pSprite) + +#define NGLE_SPRITE_FROM_SCREEN_PRIV(pScreenPriv)\ + ((pScreenPriv)->pSprite) + + +/* + ****************************************************************************** + ** + ** NGLE DDX Driver's Cursor Internally-Visible Extern Declarations: + ** + ****************************************************************************** + */ +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(); +extern void ngleMoveSprite(); + +/* Shared HP routines for the cursor: */ +extern void hpCursorLimits(); +extern void hpConstrainCursor(); +extern Bool hpSetCursorPosition(); + + +/* The number of scanlines that must be left blank in order to end the + * ghosting/tearing problem has been empirically determined to be 12. + */ +#define NTOPLINES_FOR_TIMBER 12 + +#endif /* NGLECURSOR_H */ diff --git a/xc/programs/Xserver/hw/hp/ngle/ngledevrom.h b/xc/programs/Xserver/hw/hp/ngle/ngledevrom.h new file mode 100644 index 000000000..c221bc373 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/ngledevrom.h @@ -0,0 +1,79 @@ +/* $XConsortium: ngledevrom.h,v 1.1 93/08/08 12:57:21 rws 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 header file contains the structure definition + * of this device-dependent ROM area, after values have + * been packed (actual ROM is only 1-byte wide, so each + * long only contains a byte of data). + * + ******************************************************************************/ + + +#ifndef DEVDEPROM_H +#define DEVDEPROM_H + +/* On HP-UX ioctl(fildes, GCDESCRIBE returns pointer to device-dependent + * ROM area in crt_region[1] + */ +#define NGLEDEVDEPROM_CRT_REGION 1 + + +typedef char rom_byte_t; +typedef short rom_short_t; +typedef long rom_long_t; +typedef void *rom_addr_t; + +typedef struct { + rom_long_t video_config_reg; + rom_long_t misc_video_start; + rom_long_t horiz_timing_fmt; + rom_long_t serr_timing_fmt; + rom_long_t vert_timing_fmt; + rom_long_t horiz_state; + rom_long_t vert_state; + rom_long_t vtg_state_elements; + rom_long_t pipeline_delay; + rom_long_t misc_video_end; + } video_setup_t; + +typedef struct { + rom_short_t sizeof_ngle_data; + rom_short_t x_size_visible; /* visible screen dim in pixels */ + rom_short_t y_size_visible; + + rom_short_t pad2[15]; + + rom_short_t cursor_pipeline_delay; + rom_short_t video_interleaves; + + rom_long_t pad3[11]; + + } ngle_rom_t; + +typedef ngle_rom_t NgleDevRomDataRec; +typedef ngle_rom_t *NgleDevRomDataPtr; +#endif /* DEVDEPROM_H */ diff --git a/xc/programs/Xserver/hw/hp/ngle/ngledoblt.o.8.07 b/xc/programs/Xserver/hw/hp/ngle/ngledoblt.o.8.07 Binary files differnew file mode 100644 index 000000000..88972ebaa --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/ngledoblt.o.8.07 diff --git a/xc/programs/Xserver/hw/hp/ngle/ngleextern.h b/xc/programs/Xserver/hw/hp/ngle/ngleextern.h new file mode 100644 index 000000000..5a07303e6 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/ngleextern.h @@ -0,0 +1,46 @@ +/* $XConsortium: ngleextern.h,v 1.1 93/08/08 12:57:27 rws 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 globally-visible extern declarations for the + * NGLE DDX Driver. + * + ******************************************************************************/ + +#ifndef NGLEEXTERN +#define NGLEEXTERN + + +/* + ****************************************************************************** + ** + ** Extern declarations: + ** + ****************************************************************************** + */ +extern Bool ngleScreenInit(); + +#endif /* NGLEEXTERN */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglehdw.h b/xc/programs/Xserver/hw/hp/ngle/nglehdw.h new file mode 100644 index 000000000..74be49d58 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglehdw.h @@ -0,0 +1,523 @@ +/* $XConsortium: nglehdw.h,v 1.3 95/01/24 01:58:28 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 +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. + * + *************************************************************************/ + + +#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); \ + (pDregs)->reg10 = 0xBBE0F000; \ + (pDregs)->reg14.all = 0x03000300; \ + (pDregs)->reg13 = ~0; \ + (pDregs)->reg3 = 0; \ + (pDregs)->reg4 = 0; \ + (pDregs)->reg4 = 0; \ + } + +#define WRITE_CURSOR_COLOR(pDregs,color) { \ + (pDregs)->reg4 = (color); \ + } + +#define FINISH_CURSOR_COLORMAP_ACCESS(pDregs,ID,depth) { \ + (pDregs)->reg2 = 0; \ + if (ID == S9000_ID_ARTIST) \ + (pDregs)->reg26 = 0x80008004; \ + else \ + (pDregs)->reg1 = 0x80008004; \ + SETUP_FB(pDregs,ID,depth); \ + } + +#define START_IMAGE_COLORMAP_ACCESS(pDregs) { \ + SETUP_HW(pDregs); \ + (pDregs)->reg10 = 0xBBE0F000; \ + (pDregs)->reg14.all = 0x03000300; \ + (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; \ + else /* depth = 8 */ \ + { \ + if (ID == S9000_ID_ARTIST) \ + (pDregs)->reg26 = 0x80000100; \ + else \ + (pDregs)->reg1 = 0x80000100; \ + } \ + SETUP_FB(pDregs, ID, depth); \ + } + +#define GET_CURSOR_SPECS(pDregs,pScreenPriv) { \ + Card32 activeLinesHi, activeLinesLo; \ + \ + if ((pScreenPriv)->deviceID != S9000_ID_ARTIST) \ + (pScreenPriv)->sprite.horizBackPorch = (pDregs)->reg19.b.b1; \ + else \ + (pScreenPriv)->sprite.horizBackPorch = (pDregs)->reg19.b.b1 + \ + (pDregs)->reg19.b.b2 + \ + 2; \ + activeLinesLo = (pDregs)->reg20.b.b0; \ + activeLinesHi = ((pDregs)->reg21.b.b2) & 0xf; \ + (pScreenPriv)->sprite.maxYLine = ((activeLinesHi << 8) \ + |(activeLinesLo & 0xff)); \ + } + +#define START_CURSOR_MASK_ACCESS(pDregs) { \ + SETUP_HW(pDregs); \ + (pDregs)->reg14.all = 0x00000300; \ + (pDregs)->reg13 = ~0; \ + (pDregs)->reg11 = 0x28A07000; \ + (pDregs)->reg3 = 0; \ + } + +#define START_CURSOR_DATA_ACCESS(pDregs) { \ + SETUP_HW(pDregs); \ + (pDregs)->reg14.all = 0x00000300; \ + (pDregs)->reg11 = 0x28A06000; \ + (pDregs)->reg3 = 0; \ + } + +#define WRITE_CURSOR_BITS(pDregs,word1,word2) { \ + SETUP_HW(pDregs); \ + (pDregs)->reg4 = (word1); \ + (pDregs)->reg5 = (word2); \ + } + +#define ENABLE_CURSOR(pScreenPriv, cursorXYValue, nOffscreenScanlines) { \ + (pScreenPriv)->sprite.enabledCursorXYValue = (cursorXYValue);\ + if ((pScreenPriv)->sprite.moveOnVBlank) { \ + while (((pScreenPriv)->pDregs->reg21.all) & 0x00040000); \ + while (!(((pScreenPriv)->pDregs->reg21.all) \ + & 0x00040000)); \ + } \ + SETUP_HW(pScreenPriv->pDregs); \ + (pScreenPriv)->pDregs->reg17.all = (cursorXYValue); \ + (pScreenPriv)->pDregs->reg18.all = \ + (0x80 | nOffscreenScanlines); \ + } + +#define DISABLE_CURSOR(pScreenPriv) { \ + volatile unsigned long *pDregsCursorXY = \ + &((pScreenPriv)->pDregs->reg17.all); \ + long enabledCursorValue = \ + (pScreenPriv)->sprite.enabledCursorXYValue; \ + \ + SETUP_HW((pScreenPriv)->pDregs); \ + if ((pScreenPriv)->deviceID != S9000_ID_ARTIST) \ + *pDregsCursorXY = (enabledCursorValue & 0xe007ffff); \ + else \ + (pScreenPriv)->pDregs->reg18.all = \ + (enabledCursorValue & 0x0000003f); \ + } + +#define GET_ROMTABLE_INDEX(romTableIdx) { \ + (romTableIdx) = pDregs->reg16.b.b3 - 1; \ + } + +#define SETUP_RAMDAC(pDregs) { \ + volatile Card32 *pAuxControlSpace; \ + \ + pAuxControlSpace = (Card32 *) (((Card32) pDregs) + 0x1000); \ + SETUP_HW(pDregs); \ + *(pAuxControlSpace + (0x20>>2)) = 0x04000000; \ + *(pAuxControlSpace + (0x28>>2)) = 0xff000000; \ + } + +#define CRX24_SETUP_RAMDAC(pDregs) { \ + volatile Card32 *pAuxControlSpace; \ + \ + pAuxControlSpace = (Card32 *) (((Card32) pDregs) + 0x1000); \ + SETUP_HW(pDregs); \ + *(pAuxControlSpace) = 0x04000000; \ + *(pAuxControlSpace+1) = 0x02000000; \ + *(pAuxControlSpace+2) = 0xff000000; \ + *(pAuxControlSpace) = 0x05000000; \ + *(pAuxControlSpace+1) = 0x02000000; \ + *(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; \ + (pDregs)->reg14.all = 0x03000300; \ + (pDregs)->reg3 = 0x000017f0; \ + (pDregs)->reg13 = 0xffffffff; \ + (pDregs)->reg22 = (long) (~0UL); \ + (pDregs)->reg23 = 0x0; \ + } + + +#define ENABLE_DISPLAY(pDregs) { \ + volatile Card32 *pAuxControlSpace; \ + \ + pAuxControlSpace = (Card32 *)(((Card32)(pDregs)) + 0x1000); \ + SETUP_HW(pDregs); \ + *(pAuxControlSpace + (0x30>>2)) = 0x06000000; \ + *(pAuxControlSpace + (0x38>>2)) = 0x43000000; \ + } + +#define DISABLE_DISPLAY(pDregs) { \ + volatile Card32 *pAuxControlSpace; \ + \ + pAuxControlSpace = (Card32 *)(((Card32)(pDregs)) + 0x1000); \ + SETUP_HW(pDregs); \ + *(pAuxControlSpace + (0x30>>2)) = 0x06000000; \ + *(pAuxControlSpace + (0x38>>2)) = 0x03000000; \ + } + +#define CRX24_ENABLE_DISPLAY(pDregs) { \ + volatile Card32 *pAuxControlSpace; \ + \ + pAuxControlSpace = (Card32 *)(((Card32)(pDregs)) + 0x1000); \ + SETUP_HW(pDregs); \ + *pAuxControlSpace = 0x01000000; \ + *(pAuxControlSpace+1) = 0x02000000; \ + *(pAuxControlSpace+2) = 0x10000000; \ + } + +#define CRX24_DISABLE_DISPLAY(pDregs) { \ + volatile Card32 *pAuxControlSpace; \ + \ + pAuxControlSpace = (Card32 *)(((Card32)(pDregs)) + 0x1000); \ + SETUP_HW(pDregs); \ + *pAuxControlSpace = 0x01000000; \ + *(pAuxControlSpace+1) = 0x02000000; \ + *(pAuxControlSpace+2) = 0x30000000; \ + } + +#define ARTIST_ENABLE_DISPLAY(pDregs) { \ + volatile unsigned long *pDregsMiscVideo = \ + &((pDregs)->reg21.all); \ + volatile unsigned long *pDregsMiscCtl = \ + &((pDregs)->reg27.all); \ + \ + SETUP_HW(pDregs); \ + (pDregs)->reg21.all = *pDregsMiscVideo | 0x0A000000; \ + (pDregs)->reg27.all = *pDregsMiscCtl | 0x00800000; \ + } + +#define ARTIST_DISABLE_DISPLAY(pDregs) { \ + volatile unsigned long *pDregsMiscVideo = \ + &((pDregs)->reg21.all); \ + volatile unsigned long *pDregsMiscCtl = \ + &((pDregs)->reg27.all); \ + \ + SETUP_HW(pDregs); \ + (pDregs)->reg21.all = *pDregsMiscVideo & ~0x0A000000; \ + (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); \ + (pDregs)->reg11 = 0x2EA0D000; \ + (pDregs)->reg14.all = 0x23000302; \ + (pDregs)->reg12 = (BufferNumber); \ + (pDregs)->reg8 = 0xffffffff; \ + } + +#define SET_ATTR_SIZE(pDregs,Width,Height) { \ + (pDregs)->reg6.all = 0; \ + (pDregs)->reg9.all = (Card32)(((Width)<<16)|(Height)); \ + (pDregs)->reg6.all = 0x05000000; \ + (pDregs)->reg9.all = 0x00040001; \ + } + +#define FINISH_ATTR_ACCESS(pDregs) { \ + SETUP_HW(pDregs); \ + (pDregs)->reg12 = 0; \ + } + +#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 ]*/ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglenoop.c b/xc/programs/Xserver/hw/hp/ngle/nglenoop.c new file mode 100644 index 000000000..d65e035bd --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglenoop.c @@ -0,0 +1,68 @@ +/* $XConsortium: nglenoop.c,v 1.1 93/08/08 12:57:40 rws 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 stub procedures that do nothing or very little. */ + +#ifndef MISC_H +#include "misc.h" +#endif /* MISC_H */ +#include "nglenoop.h" + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleNoop() + * + * Description: + * + * This routine does nothing. It is useful for stubbing out a procedure + * pointer for a procedure that doesn't return anything. + * + ******************************************************************************/ + +void ngleNoop() +{ +} /* ngleNoop() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleNoopTrue() + * + * Description: + * + * This routine just returns TRUE. It is useful for stubbing out a + * procedure pointer for a procedure that returns a boolean value + * where that value should be returned as TRUE. + * + ******************************************************************************/ + +Bool ngleNoopTrue() +{ + return(TRUE); +} /* ngleNoopTrue() */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglenoop.h b/xc/programs/Xserver/hw/hp/ngle/nglenoop.h new file mode 100644 index 000000000..0133b9279 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglenoop.h @@ -0,0 +1,36 @@ +/* $XConsortium: nglenoop.h,v 1.1 93/08/08 12:57:46 rws 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. + + * + *************************************************************************/ + + +/* + ****************************************************************************** + ** + ** Extern declarations for Sprite Noop/stub procedures: + ** + ****************************************************************************** + */ + +extern void ngleNoop(); +extern Bool ngleNoopTrue(); diff --git a/xc/programs/Xserver/hw/hp/ngle/nglescreen.c b/xc/programs/Xserver/hw/hp/ngle/nglescreen.c new file mode 100644 index 000000000..5fa420269 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglescreen.c @@ -0,0 +1,2095 @@ +/* $TOG: nglescreen.c /main/4 1997/11/11 15:45:50 msr $ */ +/************************************************************************* + * + * (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. + + * + *************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/hp/ngle/nglescreen.c,v 1.3 1998/10/04 09:38:31 dawes Exp $ */ + +/****************************************************************************** + * + * This file contains various global variables and routines concerning + * the Screen structure. This includes the ngleScreenInit routine. + * + ******************************************************************************/ + + +#include "ngle.h" + +#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 + * the Dual CRX card; only the left head can be an ITE console. + * + * The answer to this question is used to determine + * whether to issue ioctl(GCON) at startup and ioctl(GCTERM) + * at server exit (only should be done if ITE may be present). + * + * Answer is encoded in bit 2 of device file's minor number. + * + */ +#define IS_NOT_FIRST_HEAD_ON_THIS_SGC_SLOT(devMinorNumber) \ + (devMinorNumber & 0x00000004) + + + +/****************************************************************************** + * + * Extern and Forward Declarations: + * + ******************************************************************************/ + +extern double sqrt(double); +extern int monitorResolution; +extern int cfbScreenPrivateIndex; +extern int cfb32ScreenPrivateIndex; + +#ifdef HP_FAST_SCROLLING +/* The following are the extern declarations for the GCOps tables that + * CFB sets up and uses. If CFB changes the GCOps tables it uses, or + * adds any, this driver will also have to mirror those changes. + */ +extern GCOps cfbTEOps1Rect; +extern GCOps cfbNonTEOps1Rect; +extern GCOps cfbTEOps; +extern GCOps cfbNonTEOps; + +extern GCOps cfb32TEOps1Rect; +extern GCOps cfb32NonTEOps1Rect; +extern GCOps cfb32TEOps; +extern GCOps cfb32NonTEOps; +#endif + + +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); + +static void ngleSetupAttrPlanes( + NgleScreenPrivPtr pScreenPriv, + Card32 BufferNumber); + +static void elkSetupPlanes( + NgleScreenPrivPtr pScreenPriv); + +static Bool ngleClearScreen( + ScreenPtr pScreen); + +static Bool ngleSaveScreen( + ScreenPtr pScreen, + Bool on); + +static void ngleBlankOrUnblankScreen( + NgleScreenPrivPtr pScreenPriv, + Bool doBlank); + +static Bool ngleCloseScreen(); + +static void nglePolyPaintAttr( + NgleScreenPrivPtr pScreenPriv, + Card32 ctlPlaneReg, + Int32 nBoxes, + BoxPtr pBoxes); + +/* OWN */ + +static Card32 ngleScreenPrivGeneration = 0; +static Card32 cfbDualHeadBug = 0; +static Int32 cfbFirstIndex = 0; + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: duplicateDeviceFileInScreensFile() + * + * Description: check if device file number of this screen has already + * been opened by this server. + * + * The least significant bit is masked before checking for duplicates + * because: + * - This bit is used to distingish overlay from image plane sets. + * (Odd == overlay, by the way). + * + ******************************************************************************/ + +static Bool duplicateDeviceFileInScreensFile( + int myIndex, + int myMajorAndMinorDeviceNumber, + int *duplicateLine) +{ + int i; + hpPrivPtr php; + struct stat statInfo; + + if (myIndex == 0) + { + return(FALSE); + } + else + { + for (i = 0; i < myIndex; i++) + { + + if (ddxScreenInitPointer[i] && (i != myIndex)) /* DDX screen */ + { + php = hpPrivates[i]; + if(stat(php->StandardDevice,&statInfo) < 0) continue; + + if ((statInfo.st_rdev & 0xfffffffe) + == (myMajorAndMinorDeviceNumber & 0xfffffffe)) + { + *duplicateLine = (hpPrivates[myIndex])->LineNumber; + return (TRUE); + } + } + } + return(FALSE); + } +} /* duplicateDeviceFileInScreensFile() */ + + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: calculateDPI + * + * Description: Returns the value to use for dpi for this monitor. + * + ****************************************************************************** + */ + +static int calculateDPI( + int xsize, int ysize, + int diagonal_length) +{ + static int old_diagonal_length = 0; + int dpi = 0; + double f_diagonal_length = 1.0; + double f_num_diagonal_pix; + + f_num_diagonal_pix = sqrt((double)((xsize * xsize + ysize * ysize))); + + if (diagonal_length < 0) + { + FatalError("Incorrect monitor size specified in your /user/lib/X11/Xnscreens file.\n"); + } + if (diagonal_length == 0) + /* either first time (use default value) OR subsequent call + (use old value) */ + { + if (!(old_diagonal_length)) + /* first time */ + { + diagonal_length = DEFAULT_CRX_MONITOR_DIAGONAL; + } + else + /* second or subsequent use */ + { + diagonal_length = old_diagonal_length; + } + } + if(monitorResolution != 0) + dpi = monitorResolution; + else + if ((diagonal_length > 0) && (diagonal_length <= 100)) + /* assume it's inches -- subtract 1 inch */ + { + dpi = (int)(f_num_diagonal_pix / (((double)diagonal_length) - 1.0)); + /* along the diagonal */ + } + else if ((diagonal_length > 100) && (diagonal_length <= 1000)) + { + /* assume it's millimeters -- subtract 25.4 mm */ + + f_diagonal_length = (double)(diagonal_length - 25.4); + + dpi = (int)((f_num_diagonal_pix / f_diagonal_length) * 25.4); + + } + else + { + FatalError("Incorrect monitor size specified in your /user/lib/X11/Xnscreens file.\n"); + } + + old_diagonal_length = diagonal_length; + return(dpi); +} /* calculateDPI */ + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: ngleGetDeviceRomData() + * + * Description: Return pointer to in-memory structure holding + * ELK device-dependent ROM values. + * + ******************************************************************************/ + +static NgleDevRomDataPtr ngleGetDeviceRomData( + NgleScreenPrivPtr pScreenPriv) +{ + crt_frame_buffer_t gcDescribe; + Card32 *pBytePerLongDevDepData;/* data byte == LSB */ + Card32 *pRomTable; + NgleDevRomDataPtr pPackedDevRomData; + Int32 sizePackedDevRomData = sizeof(NgleDevRomDataRec); + Card8 *pCard8; + Int32 i; + Card8 *mapOrigin = (Card8 *) NULL; + Int32 fildes = pScreenPriv->fildes; + NgleHdwPtr pDregs = pScreenPriv->pDregs; + Int32 romTableIdx; + + + /* Allocate space for packed structure */ + pPackedDevRomData = (NgleDevRomDataPtr) Xcalloc(sizePackedDevRomData); + + /* Get information about the device from the kernel: */ + if (ioctl(fildes, GCDESCRIBE, &gcDescribe) == -1) + { + /* 3rd parm is dontcare on s700, ptr to 0 on s400 */ + ioctl(fildes, GCUNMAP, &mapOrigin); + close(fildes); + FatalError("File %s: unable to get kernel description of display.\n", + __FILE__); + } + + SETUP_HW(pDregs); + + if (pScreenPriv->deviceID == S9000_ID_ARTIST) + { + pPackedDevRomData->cursor_pipeline_delay = 4; + pPackedDevRomData->video_interleaves = 4; + } + else + { + /* Get pointer to unpacked byte/long data in ROM */ + pBytePerLongDevDepData = (Card32 *) + 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) + { + /* jump to the correct ROM table */ + GET_ROMTABLE_INDEX(romTableIdx); + while (romTableIdx > 0) + { + pCard8 = (Card8 *) pPackedDevRomData; + pRomTable = pBytePerLongDevDepData; + /* Pack every fourth byte from ROM into structure */ + for (i = 0; i < sizePackedDevRomData; i++) + { + *pCard8++ = (Card8) (*pRomTable++); + } + + pBytePerLongDevDepData = (Card32 *) + ((Card8 *) pBytePerLongDevDepData + + pPackedDevRomData->sizeof_ngle_data); + + romTableIdx--; + } + } + + pCard8 = (Card8 *) pPackedDevRomData; + + /* Pack every fourth byte from ROM into structure */ + for (i = 0; i < sizePackedDevRomData; i++) + { + *pCard8++ = (Card8) (*pBytePerLongDevDepData++); + } + } + + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + + return(pPackedDevRomData); +} /* ngleGetDeviceRomData() */ + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: stringContainsString + * + * Description: Does string in parm1 contain string in parm2? + * + * Limitations: + * Case-sensitive + * + ******************************************************************************/ + +static Bool stringContainsString( + char *pString, + char *pSubString) +{ + char *pCurPos = pString; + int len = strlen(pSubString); + + while (pCurPos = (char *) strchr(pCurPos, pSubString[0])) + { + if (bcmp(pCurPos, pSubString, len) == 0) + return(TRUE); + else + pCurPos++; + } + return(FALSE); +} /* stringContainsString */ + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: firstScreenOpenedOnThisSgcSlot() + * + * Description: + * + * Given the possibility of 2 heads on a Dual CRX being controlled + * by a single X server, is this screen the first screen on this + * SGC slot to be opened? + * + * Assumption: + * Procedure is actually used to determined whether this screen + * will be the LAST to CLOSE. This is valid assumption because + * Server closes devices in reverse order in which they were + * opened (first device opened is last device closed). + * + * So to restate: X server first opens device at index 0 and increments + * index. It closes highest numbered indexed device first and decrements, + * closing device at index 0 last. + * + * Limitations: + * Does NOT check for identical minor numbers (i.e, same device is + * listed more than once in X*screens file). + * + ******************************************************************************/ + +static Bool firstScreenOpenedOnThisSgcSlot( + Int32 index, /* IN Current screen index */ + dev_t devMinorNumber) /* IN of current device */ +{ + int i; + hpPrivPtr php; + struct stat statInfo; + + if (index == 0) + { + return(TRUE); + } + else + { + for (i = 0; i < index; i++) + { + + if (ddxScreenInitPointer[i] && (i != index)) /* DDX screen */ + { + php = hpPrivates[i]; + if(stat(php->StandardDevice,&statInfo) < 0) continue; + + /* Dual CRX convention: use bit 2 to indicate which head. + * And don't bother checking bit 0 and bit 1, which + * should always be zero for Dual CRX. + */ + if ((statInfo.st_rdev&0xfffffff8)==(devMinorNumber&0xfffffff8)) + { + return (FALSE); + } + } + } + return(TRUE); + } +} /* firstScreenOpenedOnThisSgcSlot */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleScreenInit() + * + * Description: + * + * This routine implements pScreen->ScreenInit for the NGLE DDX Driver. + * + ******************************************************************************/ + +Bool ngleScreenInit( + Int32 index, + ScreenPtr pScreen, + Int32 argc, + char **argv) +{ + + NgleScreenPrivPtr pScreenPriv; + NgleHdwPtr pDregs; + struct stat statInfo; + hpPrivPtr php; + int duplicateLine; + int fildes; + unsigned char *mapOrigin; + Card8 *fbaddr; + crt_frame_buffer_t gcDescribe; + char *grayscaleEnvar = (char *) 0; + char *moveCursorEnvar = (char *) 0; + int monitorDiagonal = DEFAULT_CRX_MONITOR_DIAGONAL; + int dpi; + NgleDevRomDataPtr pDevRomData; + VisualPtr pVisuals; + int i; + + + /* + ************************************************************************** + ** + ** Allocate and Start Initializing the pScreenPriv Structure: + ** + ************************************************************************** + */ + + /* Allocate the private index for screen. */ + if (ngleScreenPrivGeneration != serverGeneration) + { + if ((ngleScreenPrivIndex = AllocateScreenPrivateIndex()) < 0) + return(FALSE); + ngleScreenPrivGeneration = serverGeneration; + } + + /* Allocate the screen private structure (pScreenPriv), zero it (just + * in case), point pScreen to it, and point it towards pScreen): + */ + if (!(pScreenPriv = (NgleScreenPrivPtr) Xalloc(sizeof(NgleScreenPrivRec)))) + return(FALSE); + bzero((char *) pScreenPriv, sizeof(NgleScreenPrivRec)); + pScreen->devPrivates[ngleScreenPrivIndex].ptr = (pointer) pScreenPriv; + + /* Initialize the HP Private Structure: */ + php = (hpPrivPtr) hpPrivates[pScreen->myNum]; + pScreen->devPrivate = (pointer) php; + + pScreenPriv->pScreen = pScreen; + pScreenPriv->myNum = index; + + + /* + ************************************************************************** + ** + ** Open, Map, Init and Get Information about the Device: + ** + ** Obtain values for these pScreenPriv fields via ioctl() calls: + ** - fildes (from open of device file) + ** - deviceID (from ioctl(GCDESCRIBE.crt_id) + ** - pDregs (from ioctl(GCDESCRIBE.crt_control_base) + ** - fbaddr (from ioctl(GCDESCRIBE.crt_frame_base) + ** + ************************************************************************** + */ + + /* Stat the file descriptor to see if the device exists: */ + if(stat(php->StandardDevice, &statInfo) < 0) + { + char errorString[80]; + + FatalError("Unable to stat() device file \"%s\"!\n", php->StandardDevice); + } + + /* Check for duplicate entries for the same device file */ + if (duplicateDeviceFileInScreensFile(index, statInfo.st_rdev, + &duplicateLine)) + { + ErrorLine(php); + ErrorF("Duplicate device entry in line %d.\n", duplicateLine); + FatalError("Cannot continue...\n"); + } + + /* Open the device file: */ + if((fildes = open(php->StandardDevice, O_RDWR)) == -1) + { + FatalError("Unable to open() device file \"%s\"!\n", php->StandardDevice); + } + pScreenPriv->fildes = fildes; + + mapOrigin = (Card8 *) NULL; + + /* Map the framebuffer. + * + * Note that a given process can call GCMAP for the same SGC slot + * more than once without error (can occur with server mapping + * both heads of a DualCRX). + */ + if (ioctl(fildes, GCMAP, &mapOrigin) == -1) + { + close(fildes); + FatalError("Unable to map graphics display into user space!\n"); + } + + /* Get information about the device from the kernel: */ + if (ioctl(fildes, GCDESCRIBE, &gcDescribe) == -1) + { + ioctl(fildes, GCUNMAP, &mapOrigin); + close(fildes); + FatalError("Unable to get kernel description of display!\n"); + } + + /* Reject any device not in the NGLE family */ + if ( (gcDescribe.crt_id != S9000_ID_A1659A) /* CRX */ + && (gcDescribe.crt_id != S9000_ID_ELM) /* GRX */ + && (gcDescribe.crt_id != S9000_ID_TIMBER) /* 710 Any */ + && (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); + close(fildes); + FatalError( + "Graphics device has a unrecognized graphics crt_id of 0x%08x!\n", + gcDescribe.crt_id); + } + + /* Get some values from the gcDescribe structure: + * gcDescribe.crt_id: + * on s700, will equal 4 most significant bytes of graphics ID + * stored in Standard Text Interface ROM + * (offsets 0x0013, 0x0017, 0x001b, 0x001f of STI ROM). + * gcDescribe.crt_control_base: + * on all hpux systems, will point to start of control register + * space, skipping over 1MB of ROM space. + * gcDescribe.crt_frame_base: + * on all hpux systems, will point to start of framebuffer, + * offset 16MB from start of NGLE address space. + * + * For 2-headed devices such as Dual CRX, these pDregs and fbaddr + * settings will be overridden in the device-specific processing + * below (addresses of 2nd "right" head returned as crt_regions). + */ + pScreenPriv->deviceID = gcDescribe.crt_id; + pScreenPriv->pDregs = pDregs + = (NgleHdwPtr) gcDescribe.crt_control_base; + pScreenPriv->fbaddr = (pointer) gcDescribe.crt_frame_base; + 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; + + if (pScreenPriv->deviceID == S9000_ID_TOMCAT) + { + /* If second "right" device, grab addresses of frame buffer + * and control space from crt_regions rather than the + * typical crt_frame_base and crt_control_base. + * + * Convention: bit 2 (third least significant bit) of + * device file's minor number == 1 indicates right device. + */ + if (IS_NOT_FIRST_HEAD_ON_THIS_SGC_SLOT(statInfo.st_rdev)) + { + pScreenPriv->pDregs + = pDregs + = (NgleHdwPtr) gcDescribe.crt_region[3]; + pScreenPriv->fbaddr + = (pointer) gcDescribe.crt_region[2]; + } + } + + + /* Graphics devices will typically call ioctl(CGUNMAP) at screen close. + * + * Exception: the second device on a Tomcat (Dual CRX), + * where "second" means that the other head on the same Dual CRX + * appears before it in the X*screens file. + * + * Set typical value here and allow overriding in device-specific + * processing below. + */ + pScreenPriv->lastDeviceOnThisSgcToClose = TRUE; + + + /* + ************************************************************************** + ** + ** Device Dependent Initializations + ** + ************************************************************************** + */ + + pScreenPriv->pDevRomData = ngleGetDeviceRomData(pScreenPriv); + + /* Device-specific settings */ + switch (pScreenPriv->deviceID) + { + case S9000_ID_ELM: /* A1924 Gray-Scale GRX */ + + pScreenPriv->isGrayScale = TRUE; + + /* Since A1924 is a grayscale CRX and the grayscale variable + * has just been set, set device ID + * to that of CRX so that the rest of the driver may + * appropriately consider this to be a CRX. + */ + 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 */ + /* There are 3 configurations, all with the + * same Graphics ID: + * - 1280x1024 Color + * - 1280x1024 Grayscale + * - 1024x768 Color. + * The difference in color resolutions is handled simply + * by using the width/height values in gcDescribe. + * Color vs. Grayscale is handled by placing the + * word "GRAYSCALE" in the crt_name returned in gcDescribe + * for grayscale Timber graphics devices. + */ + /* Be color unless grayscale indicated in crt_name + */ + if ( stringContainsString(gcDescribe.crt_name, "GRAYSCALE") + || stringContainsString(gcDescribe.crt_name, "Grayscale") + || stringContainsString(gcDescribe.crt_name, "grayscale")) + { + pScreenPriv->isGrayScale = TRUE; + } + else + { + pScreenPriv->isGrayScale = FALSE; + } + break; + + case S9000_ID_TOMCAT: /* Dual CRX */ + + pScreenPriv->isGrayScale = FALSE; + + /* If not the head first appearing in X*screens file: + * - set variable so ioctl(GCUNMAP) is not called at exit. + * - Initialize related screen pointers for this 2nd + * screen AND for related screen opened earlier. + */ + if (!firstScreenOpenedOnThisSgcSlot( + index, statInfo.st_rdev)) + { + pScreenPriv->lastDeviceOnThisSgcToClose = FALSE; + } + + /* Dual CRX supports several resolutions: 1280x1024, 1024x768, 640x480. + * This code reads the BIFF scratch register to get the index into a + * device dependent ROM array containing the device's currently + * selected resolution. + */ + pScreenPriv->screenWidth = pScreenPriv->pDevRomData->x_size_visible ; + pScreenPriv->screenHeight = pScreenPriv->pDevRomData->y_size_visible; + + /* Since Tomcat is a 2-headed CRX and all Tomcat-specific + * processing has just been completed, set the device ID + * to that of CRX so that the rest of the driver may + * appropriately consider this to be a CRX. + */ + pScreenPriv->deviceID = S9000_ID_A1659A; + break; + + default: + FatalError("Undefined device id!\n"); + break; + } /* switch (pScreenPriv->deviceID) */ + + + /* + ************************************************************************** + ** + ** Perform ioctl() initialization of graphics device. + ** + ************************************************************************** + */ + + ioctl(fildes, GCSTATIC_CMAP, &mapOrigin); + + + /************************************************************************** + ** + ** Set up the Ngle hardware in a byte-per-pixel mode. + ** + ************************************************************************** + */ + + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + + + /************************************************************************** + ** + ** Set up screen dimensions. These values are needed to pass + ** to cfbScreenInit(). + ** + ************************************************************************** + */ + + /* Use the hp procedure to define the screen width and height, + * using the screen's diagonal, which defaults to 19" for CRX + * but may be overridden in the X*screens file "monitorsize <n>" + * parameter (in which case php->MonitorDiagonal is non-zero). + */ + if (php->MonitorDiagonal != 0) + monitorDiagonal = php->MonitorDiagonal; + else + { /* A 1024x768 CRX (with same ID) may be offered. + * It will use 16" monitor. The following rule assumes + * that higher resolution versions will use 19" monitor + * (Currently the case with CRX and CRX24). + */ + if (pScreenPriv->screenWidth <= 1024) + { + monitorDiagonal = LOWRES_CRX_MONITOR_DIAGONAL; /* 16 inches */ + } + else + { + monitorDiagonal = DEFAULT_CRX_MONITOR_DIAGONAL; /* 19 inches */ + } + } + + dpi = calculateDPI( pScreenPriv->screenWidth, pScreenPriv->screenHeight, + monitorDiagonal); + + +#ifdef HP_FAST_SCROLLING + /* + ************************************************************************** + ** + ** Change the CFB GCOpts tables to use our CopyArea routine + ** instead of the CFB version. Do this before calling and + ** CFB initialization code. + ** + ** Note: If in the future, CFB adds / deletes / changes GCOpts + ** tables, respective changes will have to be made in this + ** code also. + ** + ************************************************************************** + */ + + cfbTEOps1Rect.CopyArea = ngleCopyArea8; + cfbNonTEOps1Rect.CopyArea = ngleCopyArea8; + cfbTEOps.CopyArea = ngleCopyArea8; + cfbNonTEOps.CopyArea = ngleCopyArea8; + +#ifndef LOWMEMFTPT + cfb32TEOps1Rect.CopyArea = ngleCopyArea24; + cfb32NonTEOps1Rect.CopyArea = ngleCopyArea24; + cfb32TEOps.CopyArea = ngleCopyArea24; + cfb32NonTEOps.CopyArea = ngleCopyArea24; +#endif /* ifndef LOWMEMFTPT */ +#endif + + + /* + ************************************************************************** + ** + ** 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. + ** + ** Call cfbScreenInit() to set up default pScreen values, but + ** first call cfbSetVisualTypes to only support a subset of the + ** possible visuals. + ** + ************************************************************************** + */ + +#ifndef LOWMEMFTPT + if (pScreenPriv->devDepth == 8) +#endif /* ifndef LOWMEMFTPT */ + /* only support PseudoColor */ + { + cfbSetVisualTypes (8, 1<<PseudoColor, 8); + + cfbScreenInit(pScreen, pScreenPriv->fbaddr, pScreenPriv->screenWidth, + pScreenPriv->screenHeight, dpi, dpi, + pScreenPriv->devWidth); + } + +#ifndef LOWMEMFTPT + else /* depth = 24 */ + /* only support Directcolor */ + { + cfbSetVisualTypes (24, 1<<DirectColor, 8); + + cfb32ScreenInit(pScreen, pScreenPriv->fbaddr, pScreenPriv->screenWidth, + pScreenPriv->screenHeight, dpi, dpi, + pScreenPriv->devWidth); + } + +#endif /* ifndef LOWMEMFTPT */ + + miInitializeBackingStore(pScreen); + + /* + * The following section of code is to correct a bug in the MIT-provided + * visual initialization code. CFB assumes that for a depth 24 display, + * all hardware writes the bits to the frame buffer in the blue - green - + * red order. For HP's Ngle family of depth 24 displays, we write + * them in RGB order, not GBR order. To correct this problem, I will + * change the affected values of the visual records to the correct + * values. + */ + + pVisuals = pScreen->visuals; + for (i = 1; i <= pScreen->numVisuals ; i++ ) + { + if ((pVisuals->class == DirectColor) && (pVisuals->nplanes == 24)) + { + /* correct the RGB masks and offsets that were set by */ + /* cfbScreenInit(). */ + pVisuals->redMask = 0xff0000; + pVisuals->greenMask = 0xff00; + pVisuals->blueMask = 0xff; + pVisuals->offsetRed = 16; + pVisuals->offsetGreen = 8; + pVisuals->offsetBlue = 0; + } + pVisuals++; + } + + + /* + * This section of code is to correct a bug in the CFB + * implementation of dual head support. + */ + + if (cfbDualHeadBug != serverGeneration) + { +#ifndef LOWMEMFTPT + if (pScreenPriv->devDepth == 8) +#endif /* ifndef LOWMEMFTPT */ + cfbFirstIndex = cfbScreenPrivateIndex; +#ifndef LOWMEMFTPT + else + cfbFirstIndex = cfb32ScreenPrivateIndex; +#endif /* ifndef LOWMEMFTPT */ + + cfbDualHeadBug = serverGeneration; + } + else + { +#ifndef LOWMEMFTPT + if (pScreenPriv->devDepth == 8) +#endif /* ifndef LOWMEMFTPT */ + pScreen->devPrivates[cfbFirstIndex].ptr = + pScreen->devPrivates[cfbScreenPrivateIndex].ptr; +#ifndef LOWMEMFTPT + else + pScreen->devPrivates[cfbFirstIndex].ptr = + pScreen->devPrivates[cfb32ScreenPrivateIndex].ptr; +#endif /* ifndef LOWMEMFTPT */ + +#ifndef LOWMEMFTPT + cfbScreenPrivateIndex = cfb32ScreenPrivateIndex = cfbFirstIndex; +#else + cfbScreenPrivateIndex = cfbFirstIndex; +#endif /* ifndef LOWMEMFTPT */ + } + + + /* + ************************************************************************** + ** + ** Fill in Many of the pScreen Procedure Pointers and Values: + ** + ************************************************************************** + */ + + /**** Random screen procedures: ****/ + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = ngleCloseScreen; + 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; + + + /* + ************************************************************************** + ** + ** Set White and Black Pixel. + ** + ************************************************************************** + */ + + /* Set the pixel index for the default black pixel and white pixel. + * Used to be always 0 and 1, respectively, but with gray scale + * default colormap ramping from 1 to 255, it made sense to make + * 255 the white pixel. + */ + pScreen->blackPixel = 0; + pScreen->whitePixel = 1; + if (pScreenPriv->isGrayScale) + { + pScreen->whitePixel = 255; + } + else if (pScreenPriv->devDepth == 24) + { + pScreen->blackPixel = 0x000000; + pScreen->whitePixel = 0xffffff; + } + + + /* + ************************************************************************** + ** + ** Fill in Many Parts of the Screen Private Structure that + ** haven't been filled in yet: + ** + ************************************************************************** + */ + + /* Allow user to override driver control over whether + * cursors are moved only during vertical blank. + */ + pScreenPriv->moveCursorOnVBlank = CURSOR_AT_VBLANK_DRIVEROPTION; + + moveCursorEnvar = getenv("HPGCRX_MOVE_CURSOR_ON_VBLANK"); + if ( (strcmp(moveCursorEnvar, "FALSE") == 0) + || (strcmp(moveCursorEnvar, "False") == 0) + || (strcmp(moveCursorEnvar, "false") == 0) + || (strcmp(moveCursorEnvar, "0") == 0)) + { + pScreenPriv->moveCursorOnVBlank = CURSOR_AT_VBLANK_NEVER; + } + else + { + if ( (strcmp(moveCursorEnvar,"TRUE") == 0) + || (strcmp(moveCursorEnvar,"True") == 0) + || (strcmp(moveCursorEnvar,"true") == 0) + || (strcmp(moveCursorEnvar,"1") == 0)) + { + pScreenPriv->moveCursorOnVBlank = CURSOR_AT_VBLANK_ALWAYS; + } + } + + + /* + ************************************************************************** + ** + ** Initialize the Colormap Structures and Code: + ** + ** Causes default colormap to be loaded into hardware, + ** so must follow general hardware setup. + ** + ************************************************************************** + */ + + pScreen->defColormap = (Colormap) FakeClientID(0); + ngleCreateDefColormap(pScreen); + + + /* + ************************************************************************** + ** + ** Initialize the Cursor (Sprite and Echo) Structures, Code, + ** and pScreen procedure pointers for cursors: + ** + ************************************************************************** + */ + + 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 + * to use all 8 bits. + * + * On CRX, set up the framebuffer colormap to use + * 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 */ + (pScreenPriv->deviceID == S9000_ID_ARTIST) /* Artist */ + ) + { + 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); + } + + /* + ************************************************************************** + ** + ** Initialize screen saver: + ** + ************************************************************************** + */ + + /* Make sure video blank enable is turned off. Could happen in + * rare case: kill -9 of blanked X server (ngleCloseScreen + * code not executed). + */ + ngleBlankOrUnblankScreen(pScreenPriv, SCREEN_SAVER_OFF); + + + /* + ************************************************************************** + ** + ** Put the Ngle hardware into a byte-per-pixel state: + ** + ************************************************************************** + */ + + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + + + /* + ************************************************************************** + ** + ** If we got to here, ngleScreenInit() was successful and we + ** should return TRUE: + ** + ************************************************************************** + */ + return(TRUE); + +} /* ngleScreenInit() */ + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: elkSetupPlanes + * + ******************************************************************************/ + +static void elkSetupPlanes( + NgleScreenPrivPtr pScreenPriv) +{ + NgleHdwPtr pDregs; + + pDregs = (NgleHdwPtr) pScreenPriv->pDregs; + + /********************************************** + * Write RAMDAC pixel read mask register so all overlay + * planes are display-enabled. (CRX uses Bt458 pixel + * read mask register). + **********************************************/ + SETUP_RAMDAC(pDregs); + + SETUP_FB(pDregs, pScreenPriv->deviceID, pScreenPriv->devDepth); + +} /* elkSetupPlanes() */ + + + +/****************************************************************************** + * + * NGLE DDX Utility Procedure: rattlerSetupPlanes + * + ******************************************************************************/ + +static void rattlerSetupPlanes( + NgleScreenPrivPtr pScreenPriv) +{ + NgleHdwPtr pDregs; + Int32 x, y; + Card32 *bits; + + pDregs = (NgleHdwPtr) pScreenPriv->pDregs; + + /********************************************** + * 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). + **********************************************/ + 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 + { + *bits++ = 0xffffffff; + } while (x--); + } + + CRX24_SET_OVLY_MASK(pDregs); + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + +} /* rattlerSetupPlanes() */ + + + +/****************************************************************************** + * + * 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() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleClearScreen() + * + * Description: + * + * This local routine clears the screen to all zeroes. + * (this is not speed-critical routine - used only at server exit) + * Slow but thorough technique: clear both application buffers + * and for Ratter, overlay planes as well. + * + ******************************************************************************/ + +static Bool ngleClearScreen( + ScreenPtr pScreen) +{ + NgleScreenPrivPtr pScreenPriv; + Int32 x, y; + Card32 *bits; + + pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + + if (pScreenPriv->devDepth == 24) /* depth 24 - need different writes */ + { + for(y=0; y<pScreenPriv->screenHeight; y++) + { + bits = (Card32 *)((char *)pScreenPriv->fbaddr + + (y * pScreenPriv->devWidth * 4)); + x = pScreenPriv->screenWidth; + do { + *bits++ = 0; + } while(--x); + } + } + else /* depth 8 */ + { + for(y=0; y<pScreenPriv->screenHeight; y++) + { + bits = (Card32 *)((char *)pScreenPriv->fbaddr + y * pScreenPriv->devWidth); + x = pScreenPriv->screenWidth >> 2; + do { + *bits++ = 0; + } while(--x); + } + } + + /* 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() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleBlankOrUnblankScreen + * + * Description: + * + * This routine is intended to be called by pScreen->SaveScreen + * (a DDX entry point), as well as at server entry and exit. + * + * Video for pScreen is turned on or off, depending on 2nd parameter. + * + ******************************************************************************/ + +static void ngleBlankOrUnblankScreen( + NgleScreenPrivPtr pScreenPriv, + Bool blankOrUnblank) +{ + NgleHdwPtr pDregs = pScreenPriv->pDregs; + + + if (blankOrUnblank == SCREEN_SAVER_ON) + { + /* Turn on screen blanking (i.e. blank the screen) */ + + /* Disable cursor */ + ngleDisableSprite(pScreenPriv->pScreen); + + /* Disable image display by enabling display of + * color 0 of the cursor. Action accomplished + * by writing commands to AUX interface. Since + * CRX24 and CRX/Timber/Tomcat use different + * Brooktree DAC parts, the commands written vary. + */ + if (pScreenPriv->deviceID == S9000_ID_A1439A) + { /* CRX24 */ + + CRX24_DISABLE_DISPLAY(pDregs); + } + else if (pScreenPriv->deviceID == S9000_ID_ARTIST) + { + 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. + * An HP input procedure (hp/hp/x_hil.c:process_motion()) + * maintains a variable indicating which screen has the cursor. + */ + 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 + * color 0 of the cursor. + */ + if (pScreenPriv->deviceID == S9000_ID_A1439A) + { /* CRX24 */ + CRX24_ENABLE_DISPLAY(pDregs); + } + else if (pScreenPriv->deviceID == S9000_ID_ARTIST) + { + ARTIST_ENABLE_DISPLAY(pDregs); + } + else if (pScreenPriv->deviceID == S9000_ID_HCRX) + { + HYPER_ENABLE_DISPLAY(pDregs); + } + else + { /* CRX and like elk */ + ENABLE_DISPLAY(pDregs); + } + } + + SETUP_FB(pDregs,pScreenPriv->deviceID,pScreenPriv->devDepth); + +} /* ngleBlankOrUnblankScreen() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleSaveScreen() + * + * Description: + * + * This routine is intended to implement pScreen->SaveScreen, + * a DDX entry point. Video for pScreen is turned on or off, + * depending on parameter "on". + * + * A lower-level procedure is called to actually perform + * the blanking or unblanking. + * + ******************************************************************************/ + +static Bool ngleSaveScreen( + ScreenPtr pScreen, + Bool on) +{ + hpPrivPtr php; + NgleScreenPrivPtr pScreenPriv; + + + pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + php = (hpPrivPtr)pScreen->devPrivate; + + if (on == SCREEN_SAVER_ON) + { /* Blank screen */ + + if (php->isSaved) return(TRUE); + php->isSaved = TRUE; + + ngleBlankOrUnblankScreen(pScreenPriv, SCREEN_SAVER_ON); + } + else + { /* Uninstall the screen saver: */ + + if (!php->isSaved) return(TRUE); + php->isSaved = FALSE; + + ngleBlankOrUnblankScreen(pScreenPriv, SCREEN_SAVER_OFF); + } + + return(TRUE); + +} /* ngleSaveScreen() */ + + + +/****************************************************************************** + * + * NGLE DDX Procedure: ngleCloseScreen() + * + * Description: + * + * This routine implements pScreen->CloseScreen for the NGLE DDX Driver. + * + ******************************************************************************/ + +static Bool ngleCloseScreen(index, pScreen) + + Int32 index; /* Screen index */ + ScreenPtr pScreen; /* Pointer to screen */ +{ + NgleScreenPrivPtr pScreenPriv; + hpPrivPtr php; + Card8 *mapOrigin; + Int32 retVal; + + + pScreenPriv = NGLE_SCREEN_PRIV(pScreen); + php = (hpPrivPtr)pScreen->devPrivate; + + /* If exiting rather than just resetting, remove cursor and clear */ + if (hpGivingUp) + { + (*php->CursorOff)(pScreen); + if (pScreenPriv->deviceID == S9000_ID_HCRX) + { + hyperResetPlanes(pScreenPriv, SERVER_EXIT); + } + else + { + ngleClearScreen(pScreen); + } + } + + /* Turn off screen saver (if on) */ + ngleSaveScreen(pScreen, SCREEN_SAVER_OFF); + + /* Allow ITE to change the colormap */ + ioctl(pScreenPriv->fildes, GCVARIABLE_CMAP, &mapOrigin); + + /* Use new and improved ITE soft reset which is almost + * finished but doesn't have a header file yet + * + * Only issue at server exit, not server recycle. + * + * For multi-headed device (Tomcat), only issue if left head + * (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); + } + + + /* Release NGLE control space */ + mapOrigin = (Card8 *) 0; + + /* If a multi-headed device, only unmap framebuffer if + * last device on the SGC card to close. + */ + if (pScreenPriv->lastDeviceOnThisSgcToClose) + { + if (ioctl(pScreenPriv->fildes, GCUNMAP, &mapOrigin) < 0) + return(FALSE); + } + + /* Free data structures */ + ngleUninitSprite(pScreen); + Xfree(hpPrivates[index]); + + close(pScreenPriv->fildes); + + /* Free NGLE private structure */ + pScreen->CloseScreen = pScreenPriv->CloseScreen; + Xfree(pScreenPriv); + + return (*pScreen->CloseScreen)(index, pScreen); + +} /* 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() */ diff --git a/xc/programs/Xserver/hw/hp/ngle/nglescreen.h b/xc/programs/Xserver/hw/hp/ngle/nglescreen.h new file mode 100644 index 000000000..e8ac1d817 --- /dev/null +++ b/xc/programs/Xserver/hw/hp/ngle/nglescreen.h @@ -0,0 +1,138 @@ +/* $XConsortium: nglescreen.h,v 1.2 95/01/24 02:10:27 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 +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. + + * + *************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/hp/ngle/nglescreen.h,v 1.2 1998/06/27 12:53:51 hohndel Exp $ */ + +/****************************************************************************** + * + * This file contains various macros, typedefs and extern declarations + * concerning the Screen structure. + * + ******************************************************************************/ + +#ifndef NGLESCREEN +#define NGLESCREEN + + +/* + ****************************************************************************** + ** + ** NGLE DDX Driver's Screen Private Structure: + ** + ****************************************************************************** + */ + +typedef struct _NgleScreenPrivRec +{ + /**** High-Level information about the screen/device: ****/ + ScreenPtr pScreen; /* Pointer to DIX structure */ + Int32 myNum; /* The number of this screen */ + Int32 fildes; /* Unix fildes of device file */ + dev_t dev_sc; /* Device file's minor number */ + + 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) */ + + /**** Device sizes: ****/ + Int32 devWidth; /* Raw width, for addr calc's */ + Int32 devDepth; /* Depth of device # of planes */ + Int32 screenWidth; /* Visible resolution: width */ + Int32 screenHeight; /* Visible resolution: height */ + + /**** X11 sprite information: ****/ + NgleSpriteRec sprite; + + /**** Installed-in-Hardware Colormap Information: ****/ + ColormapPtr installedMap; /* ptr to DIX colormap + * currently installed */ + Card32 hwColors[256]; /* Copy of installed map */ + + /**** Miscellaneous information: ****/ + /* Allow user to require that cursor updates wait for vertical blanking + */ + Int32 moveCursorOnVBlank; + + /* Added for X server controlling both heads of Tomcat (2-headed ELK): + * on server exit, only unmap the framebuffer and control space + * if the "last" head on the Tomcat for this server. + */ + 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. + */ + CloseScreenProcPtr CloseScreen; + CreateGCProcPtr CreateGC; + +} NgleScreenPrivRec, *NgleScreenPrivPtr; + + +/* + ****************************************************************************** + ** + ** Macros to Access the NGLE DDX Driver's Screen Private Structure: + ** + ****************************************************************************** + */ + +extern Int32 ngleScreenPrivIndex; +#define NGLE_SCREEN_PRIV(pScreen)\ + ((NgleScreenPrivPtr) ((pScreen)->devPrivates[ngleScreenPrivIndex].ptr)) + + +/* + ****************************************************************************** + ** + ** Values for pScreenPriv->moveCursorOnVBlank: + ** Should cursor be moved only during vertical blank? + ** + ****************************************************************************** + */ +#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 */ |