📄 x_hil.c
字号:
/* $Header: /host/debretts/disk2/X11R5/R5-hp300/mit/server/ddx/hpbsd/input/RCS/x_hil.c,v 1.2 1993/04/21 21:41:28 root Exp $ *//*********************************************************************** *********************************************************** *** * 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** *** *********************************************************** ********************************************************************//********************************************************Copyright (c) 1988 by Hewlett-Packard CompanyCopyright (c) 1988 by the Massachusetts Institute of TechnologyPermission 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 M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.********************************************************/#include "stdio.h"#ifndef hp9000#ifndef __apollo#include "termio.h"#else#include "/sys5/usr/include/sys/termio.h"#endif /* __apollo */#endif#define NEED_EVENTS#include "X.h"#include "Xproto.h"#include "hildef.h"#include "hppriv.h"#include "windowstr.h"#include "XHPproto.h"#include "x_hil.h"#include "x_serialdrv.h"#include "hpkeys.h"#include "inputstr.h"#include "../../../os/osdep.h"#include <sys/times.h>#ifdef __apollo#include "../apollo/xshscreenpriv.h"#endif /* __apollo */#ifdef __hp_osf#include <hp/hilioctl.h>extern HILQ *hil_qp;#endif /* __hp_osf */#ifdef __hpux#include <sys/hilioctl.h>#endif /* __hpux */#ifdef hp9000#include <sys/ioctl.h>#include <hilioctl.h>#endif#include <errno.h>#define FIRST_EXTENSION_EVENT 64#define MIN_KEYCODE 8 #define REPEAT_ARROW 0x2#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 int num_serial_devices;extern SerialProcs serialprocs[];xEvent *format_ev();xHPEvent xE;#ifdef XINPUTextern 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 */int *dheadmotionBuf[MAX_LOGICAL_DEVS];int *dpmotionBuf[MAX_LOGICAL_DEVS];extern int axes_changed;extern int keyboard_click;extern int screenIsSaved;extern int lastEventTime;extern int x_axis, y_axis;extern struct inputs_selected valid_inputs;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;u_char pointer_amt_bits[3];u_char ptr_mods, mv_mods, rs_mods, bw_mods;u_char buf[BUF_SIZ];u_char *pkt_ptr = buf;Bool screen_was_changed = FALSE;Bool reset_enabled = TRUE;int hpActiveScreen = 0; /* active screen ndx (Zaphod) */int queue_events_free = MAX_EVENTS;int data_cnt = 0;int data_fd = -1;int pending_index;int pending_bytes;int acceleration;int threshold;struct x11EventQueue *events_queue; /* pointer to events queue. */xHPEvent *allocate_event();struct dev_info hil_info; /* holds hil_data */Bool display_borrowed = FALSE;#ifdef XINPUTDeviceIntPtr LookupDeviceIntRec ();#endif /* XINPUT */#if defined(__hp9000s800) && !defined(__hp9000s700)unsigned long timediff;Bool time_set = FALSE;#endif /* __hp9000s800 *//****************************************************************** * * Variables global to this file. * */static DeviceIntPtr find_deviceintrec();static int process_inputs();static void process_hil_data();static void process_serial_data();static check_subset_and_scale();static move_sprite();static send_motion();static send_button();static move_mouse();static u_char last_direction;static u_char last_key;static u_char last_arrow = REPEAT_ARROW;/*keycode of arrow key pressed last */static int k_down_flag[4];static int k_down_incx[4];static int k_down_incy[4];/**************************************************************************** * * 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. * */store_inputs(ready_inputs) long ready_inputs[]; { int i; int checkfd = valid_inputs.max_fd; /* max fd valid for input*/ int checkword = MASKIDX(checkfd); /* max valid word of mask*/ long mask[mskcnt]; long checkmask[mskcnt];#if defined(__hp9000s800) && !defined(__hp9000s700) /* building for s800 */ struct tms buffer; int newtime; struct timeval tv, get_tv(); /********************************************************************** * * On s800 machines, the time reported in HIL events has its origin at * the time of machine power-up. The time reported by gettimeofday(), * which will be called by UpdateCurrentTime when a grab is done, always * has its origin at Jan. 1, 1970. On s800s, we must compute a difference * to be added to the HIL times to keep the two in sync. We must also * check each time via get_tv (PA-RISC fast gettimeofday) to see if the * time reported by gettimeofday has been changed via the date() command. * If so, our time difference is invalid and must be recalculated. */ tv = get_tv(); newtime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); if (!time_set || newtime < lastEventTime) { time_set = 1; lastEventTime = GetTimeInMillis(); timediff = lastEventTime - (times(&buffer)*10); }#endif /* __hp9000s800 */ for (i=0; i<mskcnt; i++) checkmask[i] = 0; if (data_cnt > 0) /* we have leftover data*/ { process_inputs (data_fd); /* go process it */ } MASKANDSETBITS (mask, ready_inputs, valid_inputs.input_mask); BITSET(checkmask, checkfd); /* corresponding mask */ for (i=checkword; i>=0; i--) /* for all mask words */ { while (mask[i]) /* while input available*/ { if (mask[i] & checkmask[i]) /* if current fd valid */ { mask[i] &= ~checkmask[i]; process_inputs(checkfd); /* process its input */ } checkfd--; checkmask[i] = checkmask[i] >> 1; } if (i>0) { checkfd = (i-1) * 32 + 31; BITSET(checkmask, checkfd); /* 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. * */#define TIME_POLL_BYTES 5 /* bytes indicating time and poll*/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].file_ds) { indevice = &(l_devs[i]); break; } } dev = find_deviceintrec(indevice); if (data_cnt == 0 && /* no leftover data */ !(indevice->hpflags & IS_SERIAL_DEVICE)) { pkt_ptr = buf; data_cnt = read (file_ds, buf, READ_SIZ); /* We get here with nothing actually to read after a SIGHUP so ignore it */ if (data_cnt == -1 && errno == EWOULDBLOCK) { data_cnt = 0; return; } } while (data_cnt > 0 || /* data yet to be processed */ (indevice->hpflags & IS_SERIAL_DEVICE && !done)) { if (queue_events_free <= MAXHILEVENTS) /* no room on server queue */ { if (data_fd == -1) data_fd = file_ds; /* save the file descriptor */ return; } hil_ptr = (unsigned char *) &hil_info;/* place to copy packet to*/ if (indevice->hpflags & IS_SERIAL_DEVICE) { done = get_serial_event (hil_ptr); process_serial_data (dev, indevice, &(hil_info)); } else { get_hil_event (file_ds, hil_ptr);#if defined(__hp9000s800) && !defined(__hp9000s700) /* building for s800 */ hil_info.timestamp += timediff;#endif /* __hp9000s800 */ process_hil_data (dev, indevice, &(hil_info)); } lastEventTime = hil_info.timestamp; /* Used by ScreenSaver */ } data_fd = -1; if (xE.b.u.u.type != 0) /* at least 1 motion event */ { xHP = allocate_event(); /* get current queue pointer*/ *xHP = xE; /* copy from global struct */ xE.b.u.u.type = 0; /* mark it as processed */ } }/*************************************************************************** * * 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(). * */staticDeviceIntPtr 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->file_ds==hptablet_extension->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 dev = LookupDeviceIntRec (indevice->dev_id); p = dev->ptrfeed; if (p != NULL) { threshold = p->ctrl.threshold; acceleration = p->ctrl.num / p->ctrl.den; }#endif /* XINPUT */ if (acceleration == 0) acceleration = 1; } else FatalError ("X server couldn't find current input device - Aborting.\n"); return (dev); }/**************************************************************************** * * Get one HIL data packet from the data that was previously read. * If the buffer only contains a partial packet, read the rest. * * This function may also be called from x_threebut.c. * */get_hil_event (fd, dest) int fd; char *dest; { int packet_size; int i; struct dev_info *info = (struct dev_info *) dest; packet_size = *pkt_ptr++; /* 1st byte is size */ if(data_cnt < packet_size) /* We got a partial packet */ { data_cnt += read(fd, /* get rest of packet */ pkt_ptr + data_cnt, packet_size - data_cnt); if(data_cnt != packet_size) FatalError ("Unable to read all of an HIL data packet. Server exiting! \n"); } for (i=1; i<packet_size; i++) /* copy the current packet */ *dest++ = *pkt_ptr++; info->timestamp = (info->timestamp - 1) * 10; info->poll_hdr &= HIL_POLL_HDR_BITS;/* zero nonsignifcant bits */ data_cnt -= packet_size; /* fix unprocessed data cnt */ pending_index = 0; pending_bytes = packet_size - 1 - TIME_POLL_BYTES; }/**************************************************************************** * * process the HIL data packet and generate X input events as needed. * */#define UP_LEFT_ARROW 0xf8 /* HIL key codes for arrow keys. */#define DOWN_LEFT_ARROW 0xf9#define UP_DOWN_ARROW 0xfa#define DOWN_DOWN_ARROW 0xfb#define UP_UP_ARROW 0xfc#define DOWN_UP_ARROW 0xfd#define UP_RIGHT_ARROW 0xfe#define DOWN_RIGHT_ARROW 0xff#define HIL_PROXIMITY 0x4fstatic u_char code[2];static void process_hil_data (dev, phys, info) DeviceIntPtr dev; HPInputDevice *phys; struct dev_info *info; { xEvent *ev; int count; u_char type, keyset, kcode, bcode, *hil_code; struct hil_desc_record *h = &phys->hil_header; while (pending_index < pending_bytes ) { if (info->poll_hdr & MOTION_MASK) { handle_motion_event (dev, phys, info); info->poll_hdr &= ~MOTION_MASK; } if (info->poll_hdr & KEY_DATA_MASK) { keyset = info->poll_hdr & HILPRH_KEYSET; hil_code = code; if (phys->hpflags & DATA_IS_8_BITS) *hil_code = (info->dev_data)[pending_index++]; else if (phys->hpflags & DATA_IS_16_BITS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -