|
|
1.1.1.2 ! root 1: /* $Id: mouse.c,v 1.2 2006/09/30 12:34:16 fredette Exp $ */ 1.1 root 2: 3: /* generic/mouse.c - generic mouse implementation support: */ 4: 5: /* 6: * Copyright (c) 2003 Matt Fredette 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by Matt Fredette. 20: * 4. The name of the author may not be used to endorse or promote products 21: * derived from this software without specific prior written permission. 22: * 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33: * POSSIBILITY OF SUCH DAMAGE. 34: */ 35: 36: #include <tme/common.h> 1.1.1.2 ! root 37: _TME_RCSID("$Id: mouse.c,v 1.2 2006/09/30 12:34:16 fredette Exp $"); 1.1 root 38: 39: /* includes: */ 40: #include <tme/generic/mouse.h> 1.1.1.2 ! root 41: #include <errno.h> 1.1 root 42: 43: /* macros: */ 44: 45: /* types: */ 46: 47: /* this creates a new mouse buffer: */ 48: struct tme_mouse_buffer * 49: tme_mouse_buffer_new(unsigned int size) 50: { 51: struct tme_mouse_buffer *buffer; 52: 53: /* round the buffer size up to a power of two: */ 54: if (size & (size - 1)) { 55: do { 56: size &= (size - 1); 57: } while (size & (size - 1)); 58: size <<= 1; 59: } 60: 61: /* allocate the buffer: */ 62: buffer = tme_new0(struct tme_mouse_buffer, 1); 63: 64: /* set the buffer size: */ 65: buffer->tme_mouse_buffer_size = size; 66: 67: /* set the head and tail pointers: */ 68: buffer->tme_mouse_buffer_head = 0; 69: buffer->tme_mouse_buffer_tail = 0; 70: 71: /* allocate the buffer events: */ 72: buffer->tme_mouse_buffer_events 73: = tme_new(struct tme_mouse_event, size); 74: 75: /* done: */ 76: return (buffer); 77: } 78: 79: /* this destroys a mouse buffer: */ 80: void 81: tme_mouse_buffer_destroy(struct tme_mouse_buffer *buffer) 82: { 83: 84: /* free the events: */ 85: tme_free(buffer->tme_mouse_buffer_events); 86: 87: /* destroy the buffer itself: */ 88: tme_free(buffer); 89: } 90: 91: /* this copies an event into a mouse buffer: */ 92: int 93: tme_mouse_buffer_copyin(struct tme_mouse_buffer *buffer, 94: _tme_const struct tme_mouse_event *event) 95: { 96: unsigned int buffer_head, buffer_size_mask; 97: 98: buffer_head = buffer->tme_mouse_buffer_head; 99: buffer_size_mask = buffer->tme_mouse_buffer_size - 1; 100: 101: /* if the buffer is full: */ 102: if (((buffer_head + 1) & buffer_size_mask) 103: == buffer->tme_mouse_buffer_tail) { 104: return (EAGAIN); 105: } 106: 107: /* put this event into the buffer: */ 108: buffer->tme_mouse_buffer_events[buffer_head] 109: = *event; 110: 111: /* advance the head: */ 112: buffer->tme_mouse_buffer_head 113: = (buffer_head + 1) & buffer_size_mask; 114: 115: return (TME_OK); 116: } 117: 118: /* this copies an event out of a mouse buffer: */ 119: int 120: tme_mouse_buffer_copyout(struct tme_mouse_buffer *buffer, 121: struct tme_mouse_event *events, 122: unsigned int count) 123: { 124: unsigned int buffer_head, buffer_tail; 125: unsigned int buffer_size, buffer_size_mask; 126: unsigned int resid; 127: 128: /* get the head, tail, and size mask: */ 129: buffer_head = buffer->tme_mouse_buffer_head; 130: buffer_tail = buffer->tme_mouse_buffer_tail; 131: buffer_size_mask = buffer->tme_mouse_buffer_size - 1; 132: 133: for (resid = count; resid > 0; ) { 134: 135: /* if the buffer is empty: */ 136: if (buffer_tail == buffer->tme_mouse_buffer_head) { 137: 138: /* we're done copying out: */ 139: break; 140: } 141: 142: /* otherwise, the buffer is not empty, meaning there is always some 143: data starting at the buffer tail. if the buffer tail > the 144: buffer head, there is space from the buffer tail up to the end 145: of the buffer, otherwise there is space from the buffer tail up 146: to the buffer head: */ 147: buffer_size = ((buffer_tail > buffer_head) 148: ? (buffer_size_mask - buffer_tail) + 1 149: : (buffer_head - buffer_tail)); 150: 151: /* don't copy out more data than there is space available: */ 152: buffer_size = TME_MIN(buffer_size, resid); 153: assert(buffer_size > 0); 154: 155: /* copy out the data: */ 156: memcpy(events, 157: buffer->tme_mouse_buffer_events + buffer_tail, 158: sizeof(struct tme_mouse_event) * buffer_size); 159: events += buffer_size; 160: 161: /* update and loop: */ 162: buffer_tail = (buffer_tail + buffer_size) & buffer_size_mask; 163: resid -= buffer_size; 164: } 165: 166: buffer->tme_mouse_buffer_tail = buffer_tail; 167: return (count - resid); 168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.