/* $Header: /host/debretts/disk2/X11R5/R5-hp300/mit/server/ddx/hpbsd/input/RCS/x_hilinit.c,v 1.2 1993/04/21 21:44:37 root Exp $ */ /******************************************************************* ** ** ********************************************************* ** * ** * File: ddx/hp/hp/x_hilinit.c ** * ** * Contents: Input initialization routines for the ** * X/Starbase Merged Server ** * ** * Created: 4/28/88 ** * ** * Last Change: 12/06/88 ** * ** * Last Release: IC2 ** * ** * Revision: A.01.00 ** * ** * Author: --gms ** * ** * Copyright: (c) 1988 Hewlett-Packard Company ** * ** ********************************************************* ** ********************************************************************/ /*'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Copyright (c) 1988 by Hewlett-Packard Company Copyright (c) 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, 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, Digital or M.I.T. 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. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''*/ #define MAXNAMLEN 255 #define NEED_EVENTS #include <stdio.h> #include <errno.h> #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) #ifdef hp9000 #define BEEPER_DEVICE "/dev/hil0" #else #define BEEPER_DEVICE "/dev/rhil" #endif #ifdef hp9000 # include <sys/types.h> # include <sys/ioctl.h> # include <hilioctl.h> # undef HILER1 # undef HILDKR # define HILER1 HILIOCAR1 # define HILDKR HILIOCAROFF #else #ifdef __hp_osf #include <hp/hilioctl.h> #include <sys/mman.h> #else #include <sys/hilioctl.h> #endif #endif #include <fcntl.h> #ifndef hp9000 #include <dl.h> #endif #endif /* __hpux */ #include "X.h" #include "Xproto.h" #include "hildef.h" #include "XHPproto.h" /* extension constants */ #include "x_hilinit.h" #include "x_hil.h" #include "x_serialdrv.h" #include "inputstr.h" #include "../../../os/osdep.h" #ifdef XINPUT #include "XI.h" #include "XIproto.h" #else #define Relative 0 #define Absolute 1 #endif /* XINPUT */ #ifdef __apollo #include "screenint.h" #include "../apollo/apollo.h" #include "../apollo/smd.h" #endif /* __apollo */ /****************************************************************** * * Externs and global variables that may be referenced by other files. * */ int num_serial_devices; SerialProcs serialprocs[MAX_DEVICES]; HPInputDevice *hpKeyboard; HPInputDevice *hpPointer; HPInputDevice *hptablet_extension; #ifdef __hp_osf HILQ *hil_qp; int hil_qd; #endif /* __hp_osf */ #ifdef __apollo extern long *apECV; extern long *apLastECV; static int fdApollo = 0; status_$t status; #endif /* __apollo */ #ifdef XINPUT extern int BadDevice; extern int BadMode; extern int IReqCode; extern int DeviceKeyPress; extern int DeviceKeyRelease; extern int DeviceButtonPress; extern int DeviceButtonRelease; extern int DeviceMotionNotify; #ifdef NOT_DONE extern XID hp_device_ids[]; #endif XID x_device_ids[MAX_DEVICES]; #endif /* XINPUT */ extern int *dpmotionBuf[]; extern int *dheadmotionBuf[]; extern void SetBellAttributes(); extern void hpBell(); extern u_char identity_map[]; extern u_char mv_mods, ptr_mods, rs_mods, bw_mods; extern u_char pointer_amt_bits[]; extern char *display; /* display number as a string */ extern int queue_events_free; extern struct x11EventQueue *events_queue; extern InputInfo inputInfo; int lastEventTime; int axes_changed = FALSE; int keyboard_click; int allocated_dev_names = FALSE; int x_axis, y_axis; int otherndx; int beeper_fd = -1; char ldigit = '\0'; unsigned char xhp_kbdid; unsigned tablet_xlimit; unsigned tablet_ylimit; unsigned tablet_xorg; unsigned tablet_yorg; struct inputs_selected valid_inputs; HPInputDevice l_devs[MAX_LOGICAL_DEVS]; DeviceIntPtr LookupDeviceIntRec (); DeviceIntPtr tablet_extension_device; DeviceIntPtr screen_change_dev; int HPType; int device_ndx; /****************************************************************** * * Variables that are global to this file only. * */ static int init_hil_devs (); static int get_device_details(); static void SetAutoRepeat (); static int device_files (); static DevicePtr hpAddInputDevice(); static void RecordOpenRequest(); static void SetInputDevice(); static void mask_from_kcodes(); static int loopnum; static char hilpath[MAXNAMLEN+1]; void ProcessOtherEvent(); static xHPEvent events_array[MAX_EVENTS]; /* input event buffer*/ static struct x11EventQueue ev_queue; static int count [NUM_DEV_TYPES]; #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) static int prompt[] = {HILP, HILP1, HILP2, HILP3, HILP4, HILP5, HILP6, HILP7}; static int ack[] = {HILA, HILA1, HILA2, HILA3, HILA4, HILA5, HILA6, HILA7}; #endif /* __hpux */ static char *dev_names[MAX_LOGICAL_DEVS]; #if defined(__hp9000s300) || defined(__hp9000s700) || defined(__hp_osf) || defined(hp300) static char *default_names[MAX_LOGICAL_DEVS] = { "/dev/hil1", "/dev/hil2", "/dev/hil3", "/dev/hil4", "/dev/hil5", "/dev/hil6", "/dev/hil7", "", "/dev/null"}; #else /* building for s800 */ char beeper_name[] = "/dev/hilkbd "; static char *default_names[MAX_LOGICAL_DEVS] = { "/dev/hil_0.1", "/dev/hil_0.2", "/dev/hil_0.3", "/dev/hil_0.4", "/dev/hil_0.5", "/dev/hil_0.6", "/dev/hil_0.7", "/dev/hil_1.1", "/dev/hil_1.2", "/dev/hil_1.3", "/dev/hil_1.4", "/dev/hil_1.5", "/dev/hil_1.6", "/dev/hil_1.7", "/dev/hil_2.1", "/dev/hil_2.2", "/dev/hil_2.3", "/dev/hil_2.4", "/dev/hil_2.5", "/dev/hil_2.6", "/dev/hil_2.7", "/dev/hil_3.1", "/dev/hil_3.2", "/dev/hil_3.3", "/dev/hil_3.4", "/dev/hil_3.5", "/dev/hil_3.6", "/dev/hil_3.7", "", "/dev/null"}; #endif /* building on __hp9000s300 or for s700 */ /**************************************************************************** * * 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 void hpChangePointerControl(pDevice, ctrl) DevicePtr pDevice; PtrCtrl *ctrl; { #ifdef XINPUT PtrFeedbackPtr b; b = ((DeviceIntPtr) pDevice)->ptrfeed; b->ctrl = *ctrl; #else extern int threshold; extern int acceleration; threshold = ctrl->threshold; acceleration = ctrl->num; if (acceleration <= 0) acceleration = 1; #endif /* XINPUT */ #ifdef __apollo { smd_$pos_t pos; extern smd_unit_event_data_t olddata; HPInputDevice *d; if ((DeviceIntPtr) pDevice == inputInfo.pointer) { d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice); pos.column = d->coords[0]; pos.line = d->coords[1]; olddata.pos = pos; smd_$set_unit_cursor_pos (1, pos, &status); } } #endif /* __apollo */ } /**************************************************************************** * * Turn LEDs on or off. * */ static void SetLeds (d, leds, mask) HPInputDevice *d; unsigned int leds, mask; { int i, iob; char ioctl_data[12]; HPLedFeedbackControl ctrl; #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) if (d->hil_header.iob & HILIOB_PAA) /* general prompt */ { if (leds & 1) ioctl (d->file_ds, HILP, ioctl_data); else ioctl (d->file_ds, HILA, ioctl_data); leds >>= 1; } if (iob = ((u_char) (d->hil_header.iob & HILIOB_NPA) >> 4))/* prompt 1-7 */ for (i=1; i<=iob; i++) { if (leds & 1) ioctl (d->file_ds, prompt[i], ioctl_data); else ioctl (d->file_ds, ack[i], ioctl_data); leds >>= 1; } #endif /* __hpux */ if (d->hpflags & IS_SERIAL_DEVICE) for (i=0; i<num_serial_devices; i++) if (d->file_ds==serialprocs[i].fd) { ctrl.class = LedFeedbackClass; ctrl.led_values = leds; ctrl.led_mask = mask; (void) (*(serialprocs[i].write)) (d->file_ds, _XChangeFeedbackControl, &ctrl ); break; } } /**************************************************************************** * * 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 void hpChangeLedControl(pDevice, ctrl) DevicePtr pDevice; LedCtrl *ctrl; { HPInputDevice *d; d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice); SetLeds(d, ctrl->led_values, ctrl->led_mask); } /**************************************************************************** * * 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 void hpChangeKeyboardControl(pDevice, ctrl) DevicePtr pDevice; KeybdCtrl *ctrl; { HPInputDevice *d; if (inputInfo.keyboard && ((DeviceIntPtr) pDevice)->id==inputInfo.keyboard->id) keyboard_click = (int)((double)(ctrl->click) * 15.0 / 100.0); d = GET_HPINPUTDEVICE ((DeviceIntPtr) pDevice); SetAutoRepeat(d, ctrl->autoRepeat); SetBellAttributes(d, ctrl); SetLeds(d, ctrl->leds, 0xffffffff); } /**************************************************************************** * * hpGetDeviceMotionEvents. * */ static int hpGetDeviceMotionEvents (dev, buff, start, stop) DeviceIntPtr dev; CARD32 start, stop; char *buff; { HPInputDevice *pHPDev = (HPInputDevice *) dev->public.devicePrivate; int i; int evcount = 0; int size = pHPDev->hil_header.ax_num + 1; int *first, *last, *curr; int *buffp = (int *) buff; int *pmBuf = dpmotionBuf[dev->id]; int *hmBuf = dheadmotionBuf[dev->id]; if (pmBuf == hmBuf) { if (*pmBuf == 0) /* no events yet */ return 0; else last = hmBuf + (99 * size); } 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. * */ static Bool hpDeviceProc(pDev, onoff) DevicePtr pDev; int onoff; { int keyId; unsigned int mask; KeySymsRec *key_syms, keysym_rec; CARD8 *the_modmap; #ifdef __apollo #define SHORT_STRLEN 4 char kbdtypestr[SHORT_STRLEN]; short kbdtypestrlen; static char kbdtype, kbdsubtype; #endif /* __apollo */ DeviceIntPtr dev = (DeviceIntPtr) pDev; HPInputDevice *pHPDev = (HPInputDevice *) pDev->devicePrivate; struct hil_desc_record *h = &pHPDev->hil_header; int i; int button_count = h->v_button_count ? h->v_button_count : 3; int mbufsiz = (h->ax_num * sizeof(int) + sizeof(Time)) * MOTION_BUFFER_SIZE; #ifdef XINPUT char *strchr(); char *nptr; #endif /* XINPUT */ switch (onoff) { case DEVICE_INIT: pDev->on = FALSE; pHPDev->pScreen = screenInfo.screens[0]; nptr = strchr (pHPDev->x_name, '_'); AssignTypeAndName (pDev, pHPDev->x_atom, ++nptr); if (h->num_keys) { #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) if (h->iob & HILIOB_NPA) /* PS2 kbd */ { keyId = hil_to_kbd_id(h->id + 0x20); pHPDev->id_detail = HP_HIL | PC101_KBD; } else keyId = hil_to_kbd_id(h->id); #endif #ifdef __apollo /* * Detect keyboard type and do initialization accordingly. * Note: * If the keyboard is "3x" but not one of the known types, its * probably an ISO keyboard. The Swedish/Finish keymap is * a superset of ISO (according to Dan G) so I use that. * Otherwise, use North American as a default. */ smd_$inq_kbd_type(SHORT_STRLEN, kbdtypestr, &kbdtypestrlen, &status); kbdtype = (kbdtypestrlen > 0) ? kbdtypestr[0] : '2'; kbdsubtype = (kbdtypestrlen > 1) ? kbdtypestr[1] : ' '; keyId = 33; /* assume North American (subtype ' ') */ if (kbdtype == '3') switch (kbdsubtype) { case ' ': keyId = 33; break; /* North American */ case 'a': keyId = 34; break; /* German */ case 'b': keyId = 35; break; /* French */ case 'c': keyId = 36; break; /* Norwegian/Danish */ case 'd': keyId = 37; break; /* Swedish/Finish */ case 'e': keyId = 38; break; /* UK */ case 'g': keyId = 39; break; /* Swiss */ case 'f': keyId = 40; break; /* Japanese */ default: keyId = 37; /* unknown - ISO ? */ } #endif /* __apollo */ if (pHPDev->hpflags & IS_SERIAL_DEVICE) { if (!HPKget_kb_info_by_name(nptr, &keysym_rec, &the_modmap) && pHPDev==hpKeyboard) FatalError ("Can't find a keymap in the /usr/lib/X11/XHPKeymaps file for the X keyboard device.\n"); } else HPKget_maps_by_id(keyId, &keysym_rec, &the_modmap); key_syms = &keysym_rec; if (dev->id == inputInfo.keyboard->id) { InitKeyboardDeviceStruct(pDev, key_syms, the_modmap, hpBell, hpChangeKeyboardControl); } #ifdef XINPUT else { InitKeyClassDeviceStruct (dev, key_syms, the_modmap); InitKbdFeedbackClassDeviceStruct (dev, hpBell, hpChangeKeyboardControl); InitFocusClassDeviceStruct (dev); } } if (h->num_leds && dev->id != inputInfo.pointer->id && dev->id != inputInfo.keyboard->id) { LedFeedbackPtr led; InitLedFeedbackClassDeviceStruct(dev,hpChangeLedControl); for (i=0; i<h->num_leds; i++) mask |= (1 << i); for (led=dev->leds; led; led = led->next) led->ctrl.led_mask = mask; } #endif /* XINPUT */ if (h->ax_num) { if (dev->id == inputInfo.pointer->id) { if (pHPDev->dev_type == NULL_DEVICE) { pHPDev->coords[0] = pHPDev->pScreen->width; pHPDev->coords[1] = pHPDev->pScreen->height; } else { pHPDev->coords[0] = pHPDev->pScreen->width / 2; pHPDev->coords[1] = pHPDev->pScreen->height / 2; } #ifdef __apollo smd_$pos_t pos; extern smd_unit_event_data_t olddata; pos.column = pHPDev->coords[0]; pos.line = pHPDev->coords[1]; olddata.pos = pos; smd_$set_unit_cursor_pos (1, pos, &status); #endif /* __apollo */ InitPointerDeviceStruct (pDev, ptr_button_map, button_count, hpGetDeviceMotionEvents, hpChangePointerControl, MOTION_BUFFER_SIZE); } #ifdef XINPUT else { InitFocusClassDeviceStruct (dev); #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) if (h->iob & HILIOB_PIO) InitProximityClassDeviceStruct (dev); #endif /* __hpux */ InitValuatorClassDeviceStruct (dev, h->ax_num, hpGetDeviceMotionEvents, 100, (h->flags & HIL_ABSOLUTE)?1:0); InitPtrFeedbackClassDeviceStruct (dev, hpChangePointerControl); for (i=2; i < (u_char) h->ax_num; i++) InitValuatorAxisStruct (dev, i, 0, 0, 0, 0, 0); } InitValuatorAxisStruct (dev, 0, 0, (unsigned int) h->size_x, (unsigned int) h->resx, 0, (unsigned int) h->resx); InitValuatorAxisStruct (dev, 1, 0, (unsigned int) h->size_y, (unsigned int) h->resy, 0, (unsigned int) h->resy); dpmotionBuf[dev->id] = (int *) Xalloc (mbufsiz); memset (dpmotionBuf[dev->id], 0, mbufsiz); dheadmotionBuf[dev->id] = dpmotionBuf[dev->id]; } if (h->p_button_count) InitButtonClassDeviceStruct (dev, button_count, identity_map); #endif /* XINPUT */ break; case DEVICE_ON: pDev->on = TRUE; if ( pHPDev != NULL) { #ifndef __hp_osf if (pHPDev->dev_type != NULL_DEVICE) AddEnabledDevice( pHPDev->file_ds ); #endif /* __hp_osf */ if (h->ax_num) set_scale_and_screen_change (pHPDev); } SetAutoRepeat(pHPDev, TRUE); break; case DEVICE_OFF: pDev->on = FALSE; if (dev->id != inputInfo.pointer->id && pHPDev->file_ds == hpPointer->file_ds) break; if (pHPDev != NULL && pHPDev->file_ds >= 0) { #ifndef __hp_osf RemoveEnabledDevice(pHPDev->file_ds); #endif /* __hp_osf */ SetAutoRepeat(pHPDev, FALSE); close_device (pHPDev); } break; case DEVICE_CLOSE: if ( pHPDev != NULL && pHPDev->file_ds >= 0) { SetAutoRepeat(pHPDev, FALSE); #ifndef __hp_osf RemoveEnabledDevice( pHPDev->file_ds); #endif /* __hp_osf */ close_device (pHPDev); } #ifdef XINPUT if (dheadmotionBuf[dev->id]) { Xfree (dheadmotionBuf[dev->id]); dheadmotionBuf[dev->id] = NULL; dpmotionBuf[dev->id] = NULL; } #endif /* XINPUT */ if (dev->id == inputInfo.pointer->id) close (beeper_fd); break; } return(Success); } /**************************************************************************** * * InitInput -- * Initialize pointer and keyboard devices. * */ InitInput(argc, argv) int argc; char **argv; { int i, j; DeviceIntPtr x_init_device(); int CheckInput(); /* Initialize lastEventTime. Also used to fake an input event for * TimeSinceLastInputEvent() so that the screen saver timeouts work * correctly when all clients die (in WaitForSomething()). --CD */ x_axis = 0; y_axis = 1; axes_changed = FALSE; hpPointer = NULL; hpKeyboard = NULL; hptablet_extension = NULL; tablet_width = 0; otherndx = 2; device_ndx = MAX_POSITIONS - 1; lastEventTime = 0; for (i=0; i<NUM_DEV_TYPES; i++) count[i] = 0; #ifdef __hp_osf if (!hil_qp) { if ((beeper_fd = open(BEEPER_DEVICE,O_RDWR)) < 0) ErrorF ("Unable to open beeper device \"%s\".\n",BEEPER_DEVICE); #ifdef SPECIAL_68K_OSF if ((ioctl (beeper_fd, HILALLOCQ, &hil_qd)) < 0) FatalError ("Error allocating HIL event queue.\n"); if ((int) (hil_qp = (HILQ *) mmap (0, sizeof(HILQ), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, beeper_fd, hil_qd*sizeof(HILQ))) <0) FatalError("Unable to map /dev/rhil\n"); #else if ((ioctl (beeper_fd, HILALLOCQ, &hil_qp)) < 0) FatalError ("Error allocating HIL event queue.\n"); #endif /* SPECIAL_68K_OSF */ SetInputCheck(&hil_qp->hil_evqueue.head, &hil_qp->hil_evqueue.tail); } /* discard all the current input events */ hil_qp->hil_evqueue.head = hil_qp->hil_evqueue.tail; AddEnabledDevice (beeper_fd); #endif /* __hp_osf */ RegisterBlockAndWakeupHandlers (NoopDDA, CheckInput, NULL); loopnum = atoi(display); hilpath[0] = '\0'; ldigit = '\0'; get_pointerkeys(); fix_modifierkeys(); init_l_devs (); init_events_queue ( &ev_queue); #if defined(__hpux) || defined(hp9000) init_beeper(); /* beeper_fd = /dev/rhil */ #endif /* __hpux */ /* * Now initialize the devices as far as X is concerned. */ for (i=0, j=0; i<MAX_DEVICES && j < MAX_LOGICAL_DEVS; j++) { if (l_devs[j].hil_header.id == 1 || /* inaccessible device*/ (l_devs[j].dev_type == NULL_DEVICE && !(l_devs[j].hpflags & OPEN_THIS_DEVICE))) continue; if (l_devs[j].file_ds != -1) { (void) x_init_device (&l_devs[j], TRUE); l_devs[j].open_cnt=1; } else (void) x_init_device (&l_devs[j], FALSE); i++; } } /*********************************************************** * * 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->hil_header.id - 0xA0; } else if (dev==hpPointer) { RegisterPointerDevice(pXDev); #ifdef SPECIAL_68K_OSF miRegisterPointerDevice(screenInfo.screens[0], pXDev); #endif if (dev->x_type == KEYBOARD) InitKbdFeedbackClassDeviceStruct (pXDev, hpBell, hpChangeKeyboardControl); screen_change_dev = (DeviceIntPtr) pXDev; if (screen_change_amt == SCREEN_CHANGE_DEFAULT) if (dev->hil_header.flags & HIL_ABSOLUTE) screen_change_amt = 0; else screen_change_amt = 30; } #ifdef XINPUT else { RegisterOtherDevice(pXDev); if (tablet_width && dev->file_ds==hpPointer->file_ds) { tablet_extension_device = (DeviceIntPtr) pXDev; hptablet_extension = dev; screen_change_dev = tablet_extension_device; } } #endif /* XINPUT */ return ((DeviceIntPtr) pXDev); } /***************************************************************** * * Initialize the l_devs array of structures. * There is one per logical input device. * */ int sdev_num = 2; init_l_devs() { int i; int dev_num = 2; FILE *fp; char fname[MAXNAMLEN]; struct opendevs opendevs [MAX_LOGICAL_DEVS]; for (i=0; i<MAX_LOGICAL_DEVS; i++) { opendevs[i].type = -1; opendevs[i].pos = -1; opendevs[i].name[0] = '\0'; opendevs[i].path[0] = '\0'; } for (i=0; i<MAX_LOGICAL_DEVS; i++) { l_devs[i].hil_header.id = 1; l_devs[i].hpflags = 0; l_devs[i].mode = ABSOLUTE; l_devs[i].open_cnt = 0; l_devs[i].file_ds = -1; l_devs[i].x_name[0] = '\0'; l_devs[i].dev_type = '\0'; #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) l_devs[i].repeat_rate = HILER1; #endif /* __hpux */ } (void) sprintf(fname, "%sX%sdevices", DEF_DIRECTORY, display); fp = fopen ( fname, "r"); if (fp) { dev_num = device_files (fp, opendevs); fclose (fp); } compute_device_names (opendevs, dev_num); #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) init_hil_devs (opendevs, dev_num); #endif /* __hpux */ #ifdef __apollo init_apollo_devs (opendevs, dev_num); #endif /* __apollo */ #ifndef hp9000 /* * Check for any dynamically loaded input device drivers. */ init_dynamic_devs (opendevs, sdev_num); #endif if (hpPointer->x_type == KEYBOARD) { hpPointer->hil_header.v_button_count = 8; hpPointer->hil_header.p_button_count = 8; hpPointer->hil_header.ax_num = 2; } } /******************************************************************** * * Compute the names of the input devices we should use. * If a path for the input devices has been specified, use it. * Otherwise use /dev/hil. * If we have multiple HIL loops (series 800), and the display number * is between 0 and 3, use the corresponding loop. Otherwise, search * all loops. * */ compute_device_names (opendevs, dev_num) struct opendevs opendevs []; int dev_num; { int ndx = MAX_POSITIONS - 1; int i; int hlen = strlen(hilpath); #if defined(__hp9000s800) && !defined(__hp9000s700) if (hlen > 0 && isdigit (hilpath[hlen-1])) /* hilpath ends in digit */ { ldigit = hilpath[hlen-1]; hilpath[hlen-1] = '\0'; } else if (loopnum >= 0 && loopnum < 4) /* X invoked with display # */ ldigit = display[0]; #endif /* __hp9000s800 */ if (hlen > 0) allocated_dev_names = TRUE; else allocated_dev_names = FALSE; for (i=0; i<MAX_LOGICAL_DEVS; i++) { if (hlen > 0 && i<MAX_POSITIONS) { if (allocated_dev_names == TRUE) Xfree (dev_names[i]); dev_names[i] = (char *) Xalloc (strlen (hilpath) + 4); if (ldigit == '\0' || i < 7) { strcpy (dev_names[i], hilpath); strcat (dev_names[i], suffix[i]); } } else dev_names[i] = default_names[i]; } #if defined(__hp9000s800) && !defined(__hp9000s700) if (ldigit != '\0') for (i=0; i<MAX_POSITIONS; i++) { if (i < 7) { suffix [i][0] = ldigit; dev_names[i][9] = ldigit; } else { dev_names[i][0] = '\0'; suffix [i][0] = '\0'; } } #endif /* __hp9000s800 */ while (--dev_num >= 0) { if (opendevs[dev_num].path[0] == '\0') continue; for (i=0; i<MAX_POSITIONS; i++) if (strcmp (opendevs[dev_num].path, dev_names[i]) == 0) break; if (i==MAX_POSITIONS) strcpy (dev_names[ndx--], opendevs[dev_num].path); } for (i=0; i<MAX_LOGICAL_DEVS; i++) strcpy (l_devs[i].dev_name,dev_names[i]); } /******************************************************************** * * Find the requested key and pointer devices. * If no key or pointer device was named, find a default one. * */ #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) static int init_hil_devs (opendevs, numdev) struct opendevs opendevs []; int numdev; { Bool OnlyOpenExplicit = FALSE; int i, j; int spare = MAX_LOGICAL_DEVS - 2; HPInputDevice *d, *last_mouse=NULL, *last_pointer=NULL, *last_keyboard=NULL, *last_key_device=NULL; /***************************************************************************** * * Attempt to open all devices and find out what they are. * Find out which will be the default devices. * Count them so that we can assign names by position. * A device that can't be opened is considered not present. * */ if (opendevs[XKEYBOARD].path[0] != '\0' && opendevs[XPOINTER].path[0] != '\0') OnlyOpenExplicit = TRUE; for (i=0; i<MAX_LOGICAL_DEVS; i++) { d = &l_devs[i]; if (OnlyOpenExplicit) { for (j=0; j<numdev; j++) if (strcmp (opendevs[j].path, d->dev_name) == 0) break; if (j==numdev) continue; } if (open_device (d) >= 0) { for (j=0; j<numdev; j++) { if ((d->dev_type==opendevs[j].type && count[d->dev_type]==opendevs[j].pos) || (opendevs[j].type == -1 && strcmp (opendevs[j].path, d->dev_name) == 0)) { d->hpflags |= OPEN_THIS_DEVICE; if (j==XKEYBOARD && hpKeyboard==NULL) hpKeyboard = d; else if (j==XPOINTER && hpPointer==NULL) hpPointer = d; else d->hpflags |= MERGED_DEVICE; } } count[d->dev_type]++; if (d->dev_type == MOUSE) last_mouse = d; else if (d->dev_type == KEYBOARD) last_keyboard = d; else if (d->x_type == KEYBOARD) last_key_device = d; else if (d->x_type == MOUSE) last_pointer = d; } } /***************************************************************************** * * If the user didn't pick a keyboard and pointer, assign a default. * If present, defaults are the last keyboard and last mouse. * */ if (hpKeyboard==NULL) { if (last_keyboard != NULL) hpKeyboard = last_keyboard; else if (last_key_device != NULL) hpKeyboard = last_key_device; else FatalError ("Couldn't find a key device - X server terminating!\n"); hpKeyboard->hpflags |= OPEN_THIS_DEVICE; hpKeyboard->hpflags &= ~MERGED_DEVICE; } if (hpPointer==NULL) { if (last_mouse != NULL) hpPointer = last_mouse; else if (last_pointer != NULL) hpPointer = last_pointer; else hpPointer = hpKeyboard; hpPointer->hpflags |= OPEN_THIS_DEVICE; hpPointer->hpflags &= ~MERGED_DEVICE; } if (hpPointer == hpKeyboard) { hpKeyboard->hpflags |= SECOND_LOGICAL_DEVICE; l_devs[spare] = *hpKeyboard; hpPointer = &l_devs[spare]; } /***************************************************************************** * * If tablet subsetting specified and the pointer is not a tablet, * force the last tablet (if there is one) to be the pointer. * The tablet must also be accessible as an extension device. * */ if (tablet_width) { if (hpPointer->dev_type != TABLET) { for (i=MAX_LOGICAL_DEVS-1; i>=0; i--) if (l_devs[i].dev_type == TABLET) break; if (i>=0) { hpPointer->hpflags &= ~OPEN_THIS_DEVICE; hpPointer = &l_devs[i]; hpPointer->hpflags |= OPEN_THIS_DEVICE; l_devs[spare] = *hpPointer; /* will also be extension device */ l_devs[spare].hpflags |= SECOND_LOGICAL_DEVICE; } } else { l_devs[spare] = *hpPointer; /* will also be an extension device */ l_devs[spare].hpflags |= SECOND_LOGICAL_DEVICE; } } /*********************************************************************** * * Now close all the devices that X was not instructed to use. * */ for (i=0; i<MAX_LOGICAL_DEVS; i++) if (!(l_devs[i].hpflags & OPEN_THIS_DEVICE)) close_device (&l_devs[i]); } #endif /* __hpux */ /*********************************************************************** * * Open the beeper device. * On s800 machines, this is /dev/hilkbd#, where # is 0...3. * On s300 and s700, this is /dev/rhil. * */ #if defined(__hpux) || defined(hp9000) init_beeper() { #if defined(__hp9000s300) || defined(__hp9000s700) || defined(hp300) if ((beeper_fd = open(BEEPER_DEVICE,O_RDWR)) < 0) ErrorF ("Unable to open beeper device \"%s\".\n",BEEPER_DEVICE); #endif /*__hp9000s300 or __hp9000s700 */ #if defined(__hp9000s800) && !defined(__hp9000s700) int len; if (ldigit != '\0') beeper_name[11] = ldigit; else { len = strlen (hpKeyboard->dev_name); beeper_name[11] = hpKeyboard->dev_name[len-3]; } if ((beeper_name[11] >= '0' && beeper_name[11] < '4') && (beeper_fd = open(beeper_name,O_RDWR)) < 0) ErrorF ("Unable to open beeper device \"%s\".\n",beeper_name); #endif /*__hp9000s800 && !__hp9000s700 */ } #endif /* __hpux */ /*********************************************************************** * * Initialize Domain input devices. * */ #ifdef __apollo static int init_apollo_devs (opendevs, numdev) struct opendevs opendevs []; int numdev; { if (!fdApollo) fdApollo = MakeSMDStream(); strcpy (l_devs[0].dev_name, "Apollo_internal"); strcpy (l_devs[1].dev_name, "Apollo_internal"); l_devs[1].x_type = KEYBOARD; l_devs[1].dev_type = KEYBOARD; l_devs[1].hil_header.id = 0xdf; l_devs[0].hil_header.num_keys = 113; strcpy(l_devs[1].x_name,"FIRST_KEYBOARD"); l_devs[1].x_atom = MakeAtom ("KEYBOARD", 8, 0); l_devs[1].file_ds = fdApollo; l_devs[0].x_type = MOUSE; l_devs[0].dev_type = MOUSE; l_devs[0].hil_header.id = 0x68; l_devs[0].hil_header.ax_num = 2; l_devs[0].hil_header.p_button_count = 3; l_devs[0].hil_header.v_button_count = 5; l_devs[0].hil_header.size_x = screenInfo.screens[0]->width; l_devs[0].hil_header.size_y = screenInfo.screens[0]->height; strcpy(l_devs[0].x_name,"FIRST_MOUSE"); l_devs[0].x_atom = MakeAtom ("MOUSE", 5, 0); l_devs[0].file_ds = fdApollo; if (opendevs[XPOINTER].type == KEYBOARD) { l_devs[1].hpflags |= SECOND_LOGICAL_DEVICE; l_devs[MAX_LOGICAL_DEVS-2] = l_devs[1]; l_devs[0].file_ds = -1; hpPointer = &l_devs[MAX_LOGICAL_DEVS-2]; } else if (hpPointer==NULL || open_device(hpPointer) < 0) hpPointer = &l_devs[0]; else { l_devs[0].hil_header.id = 1; l_devs[0].file_ds = -1; } if (hpKeyboard==NULL || open_device(hpKeyboard) < 0) hpKeyboard = &l_devs[1]; } #endif /* __apollo */ /**************************************************************************** * * open_device opens one of the input devices. * The dev_name is filled in by device_files(), or is the default. * If the open fails, it may be because the keyboard and pointer * are the same device, and the device is already open. * */ open_device (d) HPInputDevice *d; { int fd; #ifdef __apollo if (!strcmp (d->dev_name, "Apollo_internal")) fd = fdApollo; else #endif /* __apollo */ fd = open (d->dev_name, O_RDWR | O_NDELAY); if (fd < 0) return (fd); if (get_device_details (fd, d) < 0) return (-1); d->file_ds = fd; BITSET(valid_inputs.input_mask, fd); if (fd > valid_inputs.max_fd) valid_inputs.max_fd = fd; #ifdef __hp_osf #ifdef SPECIAL_68K_OSF if (d->dev_type != NULL_DEVICE && ioctl (d->file_ds, HILMAPQ, &hil_qd) < 0) FatalError ("HILMAPQ failed for device %s\n",d->dev_name); #else if (d->dev_type != NULL_DEVICE && ioctl (d->file_ds, HILMAPQ, &hil_qp->hil_evqueue.qnum) < 0) { FatalError ("HILMAPQ failed for device %s, file_ds=%d errno=%d\n", d->dev_name, d->file_ds, errno); } #endif /* SPECIAL_68K_OSF */ #endif /* __hp_osf */ return (fd); } /**************************************************************************** * * Query the hil device for detailed information. * */ static int get_device_details(file_ds, input_dev) int file_ds; HPInputDevice *input_dev; { int i, dev_status; u_char describe[11], iob; struct hil_desc_record *hd; int hi_resol =0; int lo_resol = 0; int support_it = TRUE; #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) LatchKey(input_dev, CAPSCODE); input_dev->led[NLOCK] = LockMask; for (i=0; i<11; i++) describe[i] = 0; dev_status = ioctl (file_ds, HILID, &(describe[0])); hd = &(input_dev->hil_header); if (dev_status >= 0) { #ifdef hp9000 ioctl (file_ds, HILIOCHPUX, 0); #endif hd->id = describe[0]; if (hd->id >= 0xE0) /* HP98203C - not supported */ { close (file_ds); return (-1); } else if (hd->id >= 0xA0 && hd->id < 0xC0) /* compressed keyboard */ { close (file_ds); return (-1); } hd->flags = describe[1]; input_dev->hpflags |= DATA_IS_8_BITS; hd->ax_num = (hd->flags & HIL_NUM_AXES); /* * * if # of axes indicate it is a positional device * then gather resolution. * if 16 bits of information are reported, resolution is * in counts/ cm. In this case, convert to counts/ meter. * */ if ( hd->ax_num) { lo_resol = describe[2]; hi_resol = describe[3]; hd->resx = hd->resy = (hi_resol << 8) + lo_resol; if (hd->flags & HIL_16_BITS) { input_dev->hpflags |= DATA_IS_16_BITS; hd->resx = hd->resy = hd->resx * 100; } /* If it is an absolute device, gather size */ if (hd->flags & HIL_ABSOLUTE) { switch ( hd->ax_num) { case 2: hd->size_y = (int)describe[6]|((int)describe[7] << 8); case 1: hd->size_x = (int)describe[4]|((int)describe[5] << 8); default: break; } iob = describe[4 + hd->ax_num * 2]; } else iob = describe[4]; } else { iob = describe[2]; hd->resx = hd->resy = 0; } if (hd->flags & HIL_IOB) hd->iob=iob; if (hd->iob & HILIOB_BUTTONS) { hd->p_button_count = hd->iob & HILIOB_BUTTONS ; hd->v_button_count = hd->iob & HILIOB_BUTTONS ; /* * initialize structures for emulating 3 buttons * where we have 2, or 5 buttons where we have 3. */ if (hd->p_button_count == 2) hd->v_button_count = 3; else if (hd->p_button_count == 3 || hd->p_button_count == 4) hd->v_button_count = 5; } if (hd->iob & HAS_LEDS) { hd->num_leds = hd->iob & HILIOB_NPA; if (!hd->num_leds) hd->num_leds=1; } get_device_type (input_dev, hd->id); } else { hd->size_x = hd->size_y = 0; hd->ax_num = 2; hd->p_button_count = 3; hd->v_button_count = 3; hd->min_kcode = 10; hd->max_kcode = 135; hd->num_keys = 109; input_dev->hil_header.id = 0; input_dev->dev_type = NULL_DEVICE; input_dev->x_type = XOTHER; strcpy (input_dev->x_name,"FIRST_NULL"); support_it = FALSE; } #endif /* __hpux */ return ( support_it); } /**************************************************************************** * * This routine determines the type of the input device. * dev_type is the actual type, x_type is what X considers it to be * (mouse or keyboard). * The 9-knob box and quadrature box have the same HIL id. * But if it doesn't have 3 axes, it's not a 9-knob box. * */ get_device_type (dev, id) HPInputDevice *dev; int id; { int i; int dev_count; for (i=0; devices[i].dev_type != NULL_DEVICE; i++) if (id >= devices[i].lowid && id <= devices[i].highid) { if (id == NINE_KNOB_ID && dev->hil_header.ax_num != 3) i = QUAD_INDEX; dev->hil_header.min_kcode = devices[i].min_kcode; dev->hil_header.max_kcode = devices[i].max_kcode; dev->hil_header.num_keys = devices[i].num_keys; dev->dev_type = devices[i].dev_type; dev->x_type = devices[i].x_type; dev_count = count [dev->dev_type]; strcpy (dev->x_name, position[dev_count]); strcat (dev->x_name, "_"); strcat (dev->x_name, devices[i].name); dev->x_atom = MakeAtom (devices[i].name, strlen(devices[i].name),0); break; } } /**************************************************************************** * * This routine recalculates the device x_name. * The x_name is a string created by concatenating the device type and position. * The position may change if a device that was previously inaccessible * to X is made accessible. * */ recalculate_x_name () { int i; int j; for (i=0; i<NUM_DEV_TYPES; i++) count[i] = 0; for (i=0; i<MAX_LOGICAL_DEVS; i++) for (j=0; j<MAX_LOGICAL_DEVS; j++) if (strcmp (l_devs[j].dev_name,"/dev/null") == 0) continue; else if (strcmp (dev_names[i], l_devs[j].dev_name) == 0) { if (l_devs[j].file_ds != -1) { if (l_devs[j].hpflags & SECOND_LOGICAL_DEVICE) continue; get_device_type (&l_devs[j], l_devs[j].hil_header.id); count [l_devs[j].dev_type]++; } else if (open_device (&l_devs[j]) > 0) { count [l_devs[j].dev_type]++; close_device(&l_devs[j]); } else l_devs[j].x_name[0] = '\0'; break; } } /**************************************************************************** * * SetAutoRepeat (onoff) * Enable or disable the auto repeat feature of the specified device. */ static void SetAutoRepeat (d, onoff) HPInputDevice *d; int onoff; { #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) char ioctl_data[12]; int state = HILDKR; if (d->hpflags & IS_SERIAL_DEVICE) return; if (onoff) state = d->repeat_rate; if (d->file_ds != -1) { ioctl (d->file_ds, state, ioctl_data); } #endif /*__hpux */ } /******************************************************************** * * If the file "/usr/lib/X11/X[display#]devices exists, this routine * processes it. * It translates the strings in the file to a device type and relative * position on the HIL. * */ struct opendevs serial[MAX_DEVICES]; static int device_files (fd, opendevs) FILE *fd; struct opendevs opendevs []; { char buf[MAXNAMLEN+1]; char devuse[MAXNAMLEN+1]; char path[MAXNAMLEN+1]; char pos[MAXNAMLEN+1]; char *fgets(); int i; int other = XOTHER; int sother = XOTHER; int parms; while (fgets(buf,MAXNAMLEN+1,fd) != NULL) { buf[strlen(buf)-1] = '\0'; if (other == MAX_LOGICAL_DEVS) { ErrorF ("Too many X*devices entries. Ignoring \"%s\".\n",buf); continue; } pos[0] = '\0'; path[0] = '\0'; devuse[0] = '\0'; parms = sscanf (buf, "%s%s%s", pos, path, devuse); if (pos[0] == '#') /* comment, skip it */ continue; else if (path[0] == '#')/* 1 parm */ parms = 1; else if (devuse[0] == '#')/* 2 parms */ parms = 2; if (parms == EOF) /* blank line */ continue; else if (parms == 1) { for (i=0; i<strlen(pos); i++) pos[i] = toupper(pos[i]); if (strcmp (pos,"BEGIN_DEVICE_DESCRIPTION") == 0) parse_description (fd, serial, &sother); else { ErrorF("Invalid X*devices entry: \"%s\" - Entry skipped\n",buf); continue; } } else if (parms == 2) /* device name specified */ parse_2_parms (pos, path, opendevs, &other); else if (parms ==3) parse_3_parms (pos, path, devuse, opendevs, &other); } return (other); } /*********************************************************************** * * This routine is invoked when two parameters are specified. * Either they are a device path and intended use, or a device loop path. * */ parse_2_parms (dev, use, o, ondx) char *dev; char *use; struct opendevs o[]; int *ondx; { int i; int ndx; int len = strlen(use); for (i=0; i<len; i++) use[i] = toupper(use[i]); if (strcmp (use,"HIL_PATH") == 0) { strcpy (hilpath,dev); return; } else if (strcmp (use, "POINTER") == 0) ndx = XPOINTER; else if (strcmp (use, "KEYBOARD") == 0) ndx = XKEYBOARD; else if (strcmp (use, "OTHER") == 0) ndx = (*ondx)++; else { ErrorF ("Bad device use \"%s\" in X*devices file - Entry skipped.\n", use); return; } o[ndx].type = -1; o[ndx].pos = -1; strcpy (o[ndx].path, dev); } /*********************************************************************** * * This routine is invoked when three parameters are specified. * They are a position, a device type, and its intended use. * */ parse_3_parms (pos, name, use, o, ondx) char *pos; char *name; char *use; struct opendevs o[]; int *ondx; { int i; int ndx; for (i=0; i<strlen(pos); i++) pos[i] = toupper(pos[i]); for (i=0; i<strlen(use); i++) use[i] = toupper(use[i]); if (strcmp (use, "POINTER") == 0) ndx = XPOINTER; else if (strcmp (use, "KEYBOARD") == 0) ndx = XKEYBOARD; else if (strcmp (use, "OTHER") == 0) ndx = *ondx; else { ErrorF ("Bad device use \"%s\" in X*devices file - Entry skipped.\n", use); return; } for (i=0; i<MAX_POSITIONS; i++) if (strcmp (position[i], pos) == 0) { o[ndx].pos = i; break; } if (i == MAX_POSITIONS) /* failed, skip to next */ { ErrorF ("Bad ordinal \"%s\" in X*devices file - Entry skipped.\n", pos); return; } for (i=0; i<strlen(name); i++) name[i] = toupper(name[i]); for (i=0; i<MAX_DEV_TYPES; i++) if (strcmp (devices[i].name,name) == 0) { o[ndx].type = devices[i].dev_type; break; } if (i == MAX_DEV_TYPES) /* failed, skip to next */ { ErrorF ("Bad device type \"%s\" in X*devices file - Entry skipped.\n", name); return; } else if (ndx == *ondx) (*ondx)++; } /******************************************************************** * * * * */ parse_description(fd, o, ondx) FILE *fd; struct opendevs o[]; int *ondx; { int ndx = -1, i, len; char buf[256], ubuf[256], name[256], uname[256], path[256], var[64], use[64], entry[64]; char *fgets(); name[0] = '\0'; entry[0] = '\0'; while (fgets(buf,256,fd) != NULL) { len = strlen(buf); for (i=0; i<len; i++) ubuf[i] = toupper(buf[i]); if (sscanf (ubuf,"PATH %s", var) == 1) sscanf (buf,"%s %s", var, path); else if (sscanf (ubuf,"NAME %s", uname) == 1) sscanf (buf,"%s %s", var, name); else if (sscanf (ubuf,"ENTRYPOINT %s", var) == 1) sscanf (buf,"%s %s", var, entry); else if (sscanf (ubuf,"USE %s",use) == 1) { if (!strcmp(use,"POINTER")) ndx = XPOINTER; else if (!strcmp(use,"KEYBOARD")) ndx = XKEYBOARD; else ndx = (*ondx)++; } else if (sscanf (ubuf," %s",var) == 1 && strcmp (var,"END_DEVICE_DESCRIPTION")==0) { if (device_ndx < 0) { ErrorF("Too many devices in X*devices file - entry skipped.\n"); return; } if (ndx != -1 && path) { o[ndx].type = 99; strcpy (o[ndx].path, path); strcpy (o[ndx].name, name); if (entry[0]) strcpy (o[ndx].entry, entry); else { len = strcspn (name,"."); strncpy (o[ndx].entry, name, len); o[ndx].entry[len] = '\0'; strcat (o[ndx].entry, "_Init"); } sdev_num++; } return; } else { ErrorF ("Invalid line in device description - ignored.\n"); ErrorF ("line was: %s",buf); } } ErrorF("No END_DESCRIPTION line in X*devices file - description skipped.\n"); } /******************************************************************** * * 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. * */ #define MAX_HIL_KEYS 128 static get_codes (key, code, type) char *key; int *code; int type; { int i; 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; i<MAX_HIL_KEYS; i++) if (strcmp (key, keyset1[i]) == 0) { *code = i+8; return (0); } #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) for (i=0; i<MAX_HIL_KEYS; i++) if (strcmp (key, newkeyset1[i]) == 0) { *code = i+8; return (0); } #endif /* __hpux */ return (-1); } /******************************************************************** * * 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; (void) sprintf(fname, "%sX%spointerkeys", DEF_DIRECTORY, 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); 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); } /**************************************************************************** * * TimeSinceLastInputEvent() * - aparently returns time in miliseconds since last input event * */ TimeSinceLastInputEvent() { if (lastEventTime == 0) lastEventTime = GetTimeInMillis(); return GetTimeInMillis() - lastEventTime; } /**************************************************************************** * * hpAddInputDevice(deviceProc, autoStart, pHPDev) * create an X input device, then assign pHPDev to it's devicePrivate field. * */ static DevicePtr hpAddInputDevice(deviceProc, autoStart, pHPDev) DeviceProc deviceProc; Bool autoStart; HPInputDevice *pHPDev; { DevicePtr pXDev; if ((pXDev = AddInputDevice(deviceProc, autoStart)) == NULL) FatalError ("Too many input devices - X server terminating!\n"); pHPDev->dev_id = ((DeviceIntPtr) pXDev)->id; #ifdef XINPUT if (pHPDev == hpPointer) { #ifdef NOT_DONE hp_device_ids[pHPDev->dev_id] = XPOINTER; #endif x_device_ids[XPOINTER] = pHPDev->dev_id; } else if (pHPDev == hpKeyboard) { #ifdef NOT_DONE hp_device_ids[pHPDev->dev_id] = XKEYBOARD; #endif x_device_ids[XKEYBOARD] = pHPDev->dev_id; } else { #ifdef NOT_DONE hp_device_ids[pHPDev->dev_id] = otherndx; #endif x_device_ids[otherndx++] = pHPDev->dev_id; } #endif /* XINPUT */ pXDev->devicePrivate = (pointer) pHPDev; 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) BYTE key; DeviceIntPtr dev; { return TRUE; } /**************************************************************************** * * close_device closes one of the input devices. * */ close_device(d) HPInputDevice *d; { BITCLEAR(valid_inputs.input_mask, d->file_ds); if (d->file_ds == valid_inputs.max_fd) { valid_inputs.max_fd--; } #ifdef __apollo if (!strcmp (d->dev_name, "Apollo_internal")) return; #endif /* __apollo */ #ifdef __hp_osf if (d->file_ds != -1) ioctl(d->file_ds, HILUNMAPQ, &hil_qp->hil_evqueue.qnum); if (!ANYSET(valid_inputs.input_mask)) { RemoveEnabledDevice (beeper_fd); ioctl (beeper_fd, HILFREEQ, &hil_qp->hil_evqueue.qnum); close (beeper_fd); hil_qp = 0; } #endif /* __hp_osf */ close (d->file_ds); d->file_ds = -1; } /***************************** * * 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++; } extern int apLeave_X, apReenter_X; /* in hp/apollo/apInit2.c */ CheckInput (data, result, LastSelectMask) pointer data; unsigned long result; long LastSelectMask[]; { long devicesReadable[mskcnt]; extern long EnabledDevices[]; extern Bool display_borrowed; /* in x_hil.c */ if (result <= 0) return; MASKANDSETBITS(devicesReadable, LastSelectMask, EnabledDevices); #ifdef __apollo if (apReenter_X) apReturnFromDM(); if (display_borrowed) return; while (GetSMDEvent(TRUE, NULL)) ; if (apLeave_X) apReturnToDM(); BITCLEAR (devicesReadable, fdApollo); #endif /* __apollo */ #ifdef __hp_osf BITCLEAR (devicesReadable, beeper_fd); #endif /* __hp_osf */ if (ANYSET(devicesReadable)) store_inputs (devicesReadable); } #ifdef XINPUT AddOtherInputDevices () { 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->x_name[0] != '\0' && (strcmp (hp->dev_name,"/dev/null") != 0)) { dev = x_init_device (hp, TRUE); dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); } } } 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->open_cnt--; old->hpflags &= ~OPEN_THIS_DEVICE; } #ifdef NOT_DONE tmp = hp_device_ids[new_dev->id]; hp_device_ids[new_dev->id] = XKEYBOARD; hp_device_ids[old_dev->id] = tmp; #endif x_device_ids[XKEYBOARD] = new_dev->id; x_device_ids[tmp] = old->dev_id; hpKeyboard = new; return (Success); } ChangePointerDevice (old_dev, new_dev, x, y) DeviceIntPtr old_dev; DeviceIntPtr new_dev; unsigned char x,y; { 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->open_cnt--; old->hpflags &= ~OPEN_THIS_DEVICE; } screen_change_dev = new_dev; #ifdef NOT_DONE tmp = hp_device_ids[new_dev->id]; hp_device_ids[new_dev->id] = XPOINTER; hp_device_ids[old_dev->id] = tmp; #endif x_device_ids[XPOINTER] = new_dev->id; x_device_ids[tmp] = old->dev_id; hpPointer = new; #ifdef __apollo { smd_$pos_t pos; pos.column = hpPointer->coords[0]; pos.line = hpPointer->coords[1]; smd_$set_unit_cursor_pos (1, pos, &status); } #endif /* __apollo */ InitFocusClassDeviceStruct(old_dev); return (Success); } /**************************************************************************** * * Turn on a non-standard device. * */ 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->file_ds == -1) /* device not yet open */ { if (open_device (d) < 0) /* couldn't open device */ { *status = BadDevice; return; } recalculate_x_name (); /* recalculate names */ } else { 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; d->open_cnt++; 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, 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->open_cnt -= tmp->count; d->clients = tmp->next; Xfree (tmp); } else for (save=tmp,tmp=tmp->next; tmp!=NULL; save=tmp, tmp=tmp->next) { if (tmp->resource == clientid) { d->open_cnt -= tmp->count; save->next = tmp->next; Xfree (tmp); } } if (d->clients == NULL) { if (dev && d->open_cnt == 0) DisableDevice(dev); else { d->mode = ABSOLUTE; d->hpflags |= MERGED_DEVICE; } } } } /**************************************************************************** * * Turn off an extension device. * This code does not allow the keyboard or pointer to be turned off. * */ 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--; d->open_cnt--; 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->mode = RELATIVE; d->hpflags &= ~MERGED_DEVICE; } else { mode |= ABSOLUTE; d->mode = ABSOLUTE; d->hpflags |= MERGED_DEVICE; } if ((mode & ABSOLUTE) == ABSOLUTE) { d->coords[0] = hpPointer->coords[0]; d->coords[1] = hpPointer->coords[1]; d->mode = ABSOLUTE; } else { #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) d->coords[0] = 0; d->coords[1] = 0; #endif /* __hpux */ d->mode = RELATIVE; } } /**************************************************************************** * * 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. * */ SetDeviceMode (client, dev, mode) register ClientPtr client; DeviceIntPtr dev; int mode; { int i; HPInputDevice *d; d = GET_HPINPUTDEVICE (dev); if (d->dev_type == NULL_DEVICE) return Success; if (d->hpflags & IS_SERIAL_DEVICE) for (i=0; i<num_serial_devices; i++) if (d->file_ds==serialprocs[i].fd) if ((*(serialprocs[i].write)) (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. * */ 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); if (d->dev_type == NULL_DEVICE) return Success; if (d->hpflags & IS_SERIAL_DEVICE) for (i=0; i<num_serial_devices; i++) if (d->file_ds==serialprocs[i].fd) { ctrl.first_valuator = first_valuator; ctrl.num_valuators = num_valuators; ctrl.resolutions = valuators; if ((*(serialprocs[i].write)) (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; { int i; HPInputDevice *d; xDeviceResolutionCtl *dctrl; HPResolutionControl ctrl; d = GET_HPINPUTDEVICE (dev); if (d->dev_type == NULL_DEVICE) return Success; if (d->hpflags & IS_SERIAL_DEVICE) for (i=0; i<num_serial_devices; i++) if (d->file_ds==serialprocs[i].fd) { dctrl = (xDeviceResolutionCtl *) control; ctrl.first_valuator = dctrl->first_valuator; ctrl.num_valuators = dctrl->num_valuators; ctrl.resolutions = (int *) (dctrl+1); if ((*(serialprocs[i].write)) (d->file_ds, _XChangeDeviceControl, &ctrl)==WRITE_SUCCESS) return Success; } return BadMatch; } #endif /* XINPUT */ #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) #define LEFT_SHIFT_CODE 0x05 #define RIGHT_SHIFT_CODE 0x04 #define LEFT_MOD1_CODE 0x03 #define RIGHT_MOD1_CODE 0x02 #define RIGHT_CONTROL_CODE 0x00 #define LEFT_CONTROL_CODE 0x06 #endif /* __hpux */ #ifdef __apollo #define LEFT_SHIFT_CODE 0x5e #define RIGHT_SHIFT_CODE 0x6a #define LEFT_MOD1_CODE 0x75 #define RIGHT_MOD1_CODE 0x77 #define LEFT_CONTROL_CODE 0x43 #endif /* __apollo */ #define LEFT_SHIFT_BIT 0x20 #define RIGHT_SHIFT_BIT 0x10 #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; for (i=0; i<MAX_KEY_MODS; i++, src++) switch (*src) { case LEFT_SHIFT_CODE: *dst |= LEFT_SHIFT_BIT; break; case RIGHT_SHIFT_CODE: *dst |= RIGHT_SHIFT_BIT; break; case LEFT_MOD1_CODE: *dst |= LEFT_MOD1_BIT; break; case RIGHT_MOD1_CODE: *dst |= RIGHT_MOD1_BIT; break; case LEFT_CONTROL_CODE: *dst |= LEFT_CONTROL_BIT; break; #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) case RIGHT_CONTROL_CODE: *dst |= RIGHT_CONTROL_BIT; break; #endif /* __hpux || __hp_osf */ default: break; } } get_down_modifiers(kptr, down_mods) u_char *kptr, *down_mods; { #if defined(__hpux) || defined(__hp_osf) || defined(hp9000) *down_mods = kptr[1] & 0x7d; /* mask off break and repeat cursor */ #endif /* __hpux */ #ifdef __apollo *down_mods = 0; if (kptr[9] & 0x08) *down_mods |= LEFT_CONTROL_BIT; if (kptr[12] & 0x40) *down_mods |= LEFT_SHIFT_BIT; if (kptr[14] & 0x04) *down_mods |= RIGHT_SHIFT_BIT; if (kptr[15] & 0x80) *down_mods |= RIGHT_MOD1_BIT; if (kptr[15] & 0x20) *down_mods |= LEFT_MOD1_BIT; #endif /* __apollo */ } #ifdef __apollo DisableAllInput () { register DeviceIntPtr dev, next; HPInputDevice *d; for (dev = inputInfo.devices; dev; dev = next) { next = dev->next; d = GET_HPINPUTDEVICE (dev); RemoveEnabledDevice( d->file_ds); } } EnableAllInput () { register DeviceIntPtr dev, next; HPInputDevice *d; for (dev = inputInfo.devices; dev; dev = next) { next = dev->next; if (dev->inited && dev->startup) { d = GET_HPINPUTDEVICE (dev); AddEnabledDevice( d->file_ds); } } } int xosWindowPrivateIndex; #endif /* __apollo */ #ifndef hp9000 /***************************************************************************** * * Dynamically load drivers to support non-HIL input devices. * */ HPInputDeviceHeader zdhdr; init_dynamic_devs(opendevs, numdev) struct opendevs opendevs []; int numdev; { int i, j, k, fd, use, sndx=0; HPInputDeviceHeader dhdr; Bool (*driverInit)(); char fname[255]; shl_t ldr_module_id; long ldr_module_entry; int ret_val; char driver_path[255]; char driver_init[255]; /* * For each device, * 1). find an available device private struct, * 2). make sure the user has told us the device path and use, * 3). make sure the driver knows about this device, * 4). call the driver to open and configure it. */ for (i=0; i<numdev; i++) { if (!serial[i].name[0]) continue; strcpy (driver_path, "/usr/lib/X11/extensions/"); strcat (driver_path, serial[i].name); #if defined(__hp9000s300) strcpy (driver_init, "_"); strcat (driver_init, serial[i].entry); #else strcpy (driver_init, serial[i].entry); #endif /* __hp9000s300 */ for (j=0; j<num_serial_devices; j++) if (strcmp (serialprocs[j].driver_name, serial[i].name)==0) break; if (j==num_serial_devices) /* this driver wasn't previously loaded */ { /* * Dynamically load the driver. */ ldr_module_id = shl_load( driver_path, BIND_IMMEDIATE, 0L); if ( ldr_module_id == NULL ) { ErrorF ("Failed to load serial input device driver %s\n", driver_path); ErrorF ("Check spelling and case of device name.\n"); continue; } } else ldr_module_id = serialprocs[j].ldr_module_id; sndx = j; /* * Now look for the main entry point by name. */ ret_val = shl_findsym( &ldr_module_id, driver_init, TYPE_PROCEDURE, &ldr_module_entry ); if ( ret_val ) { ErrorF ("Couldn't find main entry point %s in serial input device driver %s, retval is %x\n", driver_init, driver_path, ret_val); ErrorF ("Check spelling and case of device name and entrypoint.\n"); continue; } /* * Call that entry point to initialize driver. */ driverInit = (pfrb) ldr_module_entry; ret_val = (*driverInit)(&serialprocs[sndx]); if (ret_val!=INIT_SUCCESS) { ErrorF ("Couldn't initialize serial input device driver %s\n", driver_path); continue; } dhdr = zdhdr; strcpy (dhdr.path, serial[i].path); if ((*(serialprocs[sndx].configure))(&dhdr, &use) == INIT_SUCCESS) { for (k=0; l_devs[k].hil_header.id != 1 && k<MAX_DEVICES-1; k++) ; serialprocs[sndx].fd = dhdr.file_ds; strcpy(l_devs[k].x_name,"FIRST_"); strcpy (fname, serialprocs[sndx].x_name); strcat(l_devs[k].x_name,fname); l_devs[k].x_atom = MakeAtom (fname, strlen(fname),0); if (!l_devs[k].x_atom) l_devs[k].x_atom = MakeAtom (fname, strlen(fname),1); x_init_dynamic_device(&l_devs[k], &dhdr, use); if (i==XPOINTER) { if (hpPointer && hpPointer->file_ds != -1) { close (hpPointer->file_ds); for (j=0, fd=hpPointer->file_ds; j<MAX_DEVICES; j++) if (l_devs[j].file_ds == fd) l_devs[j].file_ds = -1; } hpPointer = &l_devs[k]; } else if (i==XKEYBOARD) { if (hpKeyboard && hpKeyboard->file_ds != -1) { close (hpKeyboard->file_ds); for (j=0, fd=hpKeyboard->file_ds; j<MAX_DEVICES; j++) if (l_devs[j].file_ds == fd) l_devs[j].file_ds = -1; } hpKeyboard = &l_devs[k]; } if (sndx==num_serial_devices) { strcpy (serialprocs[sndx].driver_name, serial[i].name); serialprocs[sndx].ldr_module_id = ldr_module_id; num_serial_devices++; } } else ErrorF ("Couldn't initialize serial input device %s\n", serial[i].name); } } #define DYNAMIC_DEVICE 0xffff x_init_dynamic_device(d, dhdr, use) HPInputDevice *d; HPInputDeviceHeader *dhdr; int use; { strcpy (d->dev_name, dhdr->path); d->hil_header.resx = dhdr->resolution * 100; d->hil_header.resy = dhdr->resolution * 100; d->hil_header.size_x = dhdr->max_x; d->hil_header.size_y = dhdr->max_y; d->file_ds = dhdr->file_ds; BITSET(valid_inputs.input_mask, dhdr->file_ds); if (dhdr->file_ds > valid_inputs.max_fd) valid_inputs.max_fd = dhdr->file_ds; d->hil_header.ax_num = dhdr->ax_num; d->hil_header.p_button_count = dhdr->num_buttons; d->hil_header.v_button_count = dhdr->num_buttons; d->hil_header.num_keys = dhdr->num_keys; d->hil_header.min_kcode = dhdr->min_kcode; d->hil_header.max_kcode = dhdr->max_kcode; if (dhdr->flags & ABSOLUTE_DATA) { d->mode = ABSOLUTE; d->hil_header.flags = HIL_ABSOLUTE; } else d->mode = RELATIVE; d->hpflags = IS_SERIAL_DEVICE | OPEN_THIS_DEVICE; d->hpflags |= (dhdr->flags & DATA_SIZE_BITS); d->dev_type = DYNAMIC_DEVICE; d->hil_header.id = 0; d->hil_header.num_leds = dhdr->num_leds; if (dhdr->num_keys) d->x_type = KEYBOARD; else d->x_type = MOUSE; if (use == XPOINTER) hpPointer = d; else if (use == XKEYBOARD) hpKeyboard = d; } #endif