105b261ecSmrg/* 205b261ecSmrg * Copyright (c) 1997 Metro Link Incorporated 305b261ecSmrg * 405b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 505b261ecSmrg * copy of this software and associated documentation files (the "Software"), 605b261ecSmrg * to deal in the Software without restriction, including without limitation 705b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 805b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the 905b261ecSmrg * Software is furnished to do so, subject to the following conditions: 1005b261ecSmrg * 1105b261ecSmrg * The above copyright notice and this permission notice shall be included in 1205b261ecSmrg * all copies or substantial portions of the Software. 1305b261ecSmrg * 1405b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1705b261ecSmrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 1805b261ecSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 1905b261ecSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2005b261ecSmrg * SOFTWARE. 2105b261ecSmrg * 2205b261ecSmrg * Except as contained in this notice, the name of the Metro Link shall not be 2305b261ecSmrg * used in advertising or otherwise to promote the sale, use or other dealings 2405b261ecSmrg * in this Software without prior written authorization from Metro Link. 2505b261ecSmrg * 2605b261ecSmrg */ 2705b261ecSmrg 2805b261ecSmrg/* 2905b261ecSmrg X Input Serial Buffer routines for use in any XInput driver that accesses 3005b261ecSmrg a serial device. 3105b261ecSmrg*/ 3205b261ecSmrg 3305b261ecSmrg/***************************************************************************** 3405b261ecSmrg * Standard Headers 3505b261ecSmrg ****************************************************************************/ 3605b261ecSmrg 3705b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 3805b261ecSmrg#include <xorg-config.h> 3905b261ecSmrg#endif 4005b261ecSmrg 4105b261ecSmrg#include <misc.h> 4205b261ecSmrg#include <xf86.h> 4305b261ecSmrg#include <xf86_OSproc.h> 4405b261ecSmrg#include <xf86_OSlib.h> 4505b261ecSmrg#include <xf86Xinput.h> 4605b261ecSmrg#include "xisb.h" 4705b261ecSmrg 4805b261ecSmrg/***************************************************************************** 4905b261ecSmrg * Local Headers 5005b261ecSmrg ****************************************************************************/ 5105b261ecSmrg 5205b261ecSmrg/***************************************************************************** 5305b261ecSmrg * Variables without includable headers 5405b261ecSmrg ****************************************************************************/ 5505b261ecSmrg 5605b261ecSmrg/***************************************************************************** 5705b261ecSmrg * Local Variables 5805b261ecSmrg ****************************************************************************/ 5905b261ecSmrg 6005b261ecSmrg/***************************************************************************** 6105b261ecSmrg * Function Definitions 6205b261ecSmrg ****************************************************************************/ 6305b261ecSmrg 646747b715SmrgXISBuffer * 6535c4bbdfSmrgXisbNew(int fd, ssize_t size) 6605b261ecSmrg{ 6735c4bbdfSmrg XISBuffer *b; 6835c4bbdfSmrg 6935c4bbdfSmrg b = malloc(sizeof(XISBuffer)); 7035c4bbdfSmrg if (!b) 7135c4bbdfSmrg return NULL; 7235c4bbdfSmrg b->buf = malloc((sizeof(unsigned char) * size)); 7335c4bbdfSmrg if (!b->buf) { 7435c4bbdfSmrg free(b); 7535c4bbdfSmrg return NULL; 7635c4bbdfSmrg } 7735c4bbdfSmrg 7835c4bbdfSmrg b->fd = fd; 7935c4bbdfSmrg b->trace = 0; 8035c4bbdfSmrg b->block_duration = 0; 8135c4bbdfSmrg b->current = 1; /* force it to be past the end to trigger initial read */ 8235c4bbdfSmrg b->end = 0; 8335c4bbdfSmrg b->buffer_size = size; 8435c4bbdfSmrg return b; 8505b261ecSmrg} 8605b261ecSmrg 876747b715Smrgvoid 8835c4bbdfSmrgXisbFree(XISBuffer * b) 8905b261ecSmrg{ 9035c4bbdfSmrg free(b->buf); 9135c4bbdfSmrg free(b); 9205b261ecSmrg} 9305b261ecSmrg 946747b715Smrgint 9535c4bbdfSmrgXisbRead(XISBuffer * b) 9605b261ecSmrg{ 9735c4bbdfSmrg int ret; 9835c4bbdfSmrg 9935c4bbdfSmrg if (b->current >= b->end) { 10035c4bbdfSmrg if (b->block_duration >= 0) { 10135c4bbdfSmrg if (xf86WaitForInput(b->fd, b->block_duration) < 1) 10235c4bbdfSmrg return -1; 10335c4bbdfSmrg } 10435c4bbdfSmrg else { 10535c4bbdfSmrg /* 10635c4bbdfSmrg * automatically clear it so if XisbRead is called in a loop 10735c4bbdfSmrg * the next call will make sure there is data with select and 10835c4bbdfSmrg * thus prevent a blocking read 10935c4bbdfSmrg */ 11035c4bbdfSmrg b->block_duration = 0; 11135c4bbdfSmrg } 11235c4bbdfSmrg 11335c4bbdfSmrg ret = xf86ReadSerial(b->fd, b->buf, b->buffer_size); 11435c4bbdfSmrg switch (ret) { 11535c4bbdfSmrg case 0: 11635c4bbdfSmrg return -1; /* timeout */ 11735c4bbdfSmrg case -1: 11835c4bbdfSmrg return -2; /* error */ 11935c4bbdfSmrg default: 12035c4bbdfSmrg b->end = ret; 12135c4bbdfSmrg b->current = 0; 12235c4bbdfSmrg break; 12335c4bbdfSmrg } 12435c4bbdfSmrg } 12535c4bbdfSmrg if (b->trace) 12635c4bbdfSmrg ErrorF("read 0x%02x (%c)\n", b->buf[b->current], 12735c4bbdfSmrg isprint(b->buf[b->current]) ? b->buf[b->current] : '.'); 12835c4bbdfSmrg 12935c4bbdfSmrg return b->buf[b->current++]; 13005b261ecSmrg} 13105b261ecSmrg 13205b261ecSmrg/* the only purpose of this function is to provide output tracing */ 1336747b715Smrgssize_t 13435c4bbdfSmrgXisbWrite(XISBuffer * b, unsigned char *msg, ssize_t len) 13505b261ecSmrg{ 13635c4bbdfSmrg if (b->trace) { 13705b261ecSmrg int i = 0; 13835c4bbdfSmrg 13905b261ecSmrg for (i = 0; i < len; i++) 14035c4bbdfSmrg ErrorF("\t\twrote 0x%02x (%c)\n", msg[i], msg[i]); 14105b261ecSmrg } 14235c4bbdfSmrg return (xf86WriteSerial(b->fd, msg, len)); 14305b261ecSmrg} 14405b261ecSmrg 14505b261ecSmrg/* turn tracing of this buffer on (1) or off (0) */ 1466747b715Smrgvoid 14735c4bbdfSmrgXisbTrace(XISBuffer * b, int trace) 14805b261ecSmrg{ 14935c4bbdfSmrg b->trace = trace; 15005b261ecSmrg} 15105b261ecSmrg 15205b261ecSmrg/* 15305b261ecSmrg * specify a block_duration of -1 when you know the buffer's fd is ready to 15405b261ecSmrg * read. After a read, it is automatically set to 0 so that the next read 15505b261ecSmrg * will use check to select for data and prevent a block. 15605b261ecSmrg * It is the caller's responsibility to set the block_duration to -1 if it 15705b261ecSmrg * knows that there is data to read (because the main select loop triggered 158ed6184dfSmrg * the read) and wants to avoid the unnecessary overhead of the select call 15905b261ecSmrg * 16005b261ecSmrg * a zero or positive block duration will cause the select to block for the 16105b261ecSmrg * give duration in usecs. 16205b261ecSmrg */ 16305b261ecSmrg 1646747b715Smrgvoid 16535c4bbdfSmrgXisbBlockDuration(XISBuffer * b, int block_duration) 16605b261ecSmrg{ 16735c4bbdfSmrg b->block_duration = block_duration; 16805b261ecSmrg} 169