|
|
1.1 ! root 1: /* $Id: mouse.c,v 1.1 2003/07/31 01:35:28 fredette Exp $ */ ! 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> ! 37: _TME_RCSID("$Id: mouse.c,v 1.1 2003/07/31 01:35:28 fredette Exp $"); ! 38: ! 39: /* includes: */ ! 40: #include <tme/generic/mouse.h> ! 41: ! 42: /* macros: */ ! 43: ! 44: /* types: */ ! 45: ! 46: /* this creates a new mouse buffer: */ ! 47: struct tme_mouse_buffer * ! 48: tme_mouse_buffer_new(unsigned int size) ! 49: { ! 50: struct tme_mouse_buffer *buffer; ! 51: ! 52: /* round the buffer size up to a power of two: */ ! 53: if (size & (size - 1)) { ! 54: do { ! 55: size &= (size - 1); ! 56: } while (size & (size - 1)); ! 57: size <<= 1; ! 58: } ! 59: ! 60: /* allocate the buffer: */ ! 61: buffer = tme_new0(struct tme_mouse_buffer, 1); ! 62: ! 63: /* set the buffer size: */ ! 64: buffer->tme_mouse_buffer_size = size; ! 65: ! 66: /* set the head and tail pointers: */ ! 67: buffer->tme_mouse_buffer_head = 0; ! 68: buffer->tme_mouse_buffer_tail = 0; ! 69: ! 70: /* allocate the buffer events: */ ! 71: buffer->tme_mouse_buffer_events ! 72: = tme_new(struct tme_mouse_event, size); ! 73: ! 74: /* done: */ ! 75: return (buffer); ! 76: } ! 77: ! 78: /* this destroys a mouse buffer: */ ! 79: void ! 80: tme_mouse_buffer_destroy(struct tme_mouse_buffer *buffer) ! 81: { ! 82: ! 83: /* free the events: */ ! 84: tme_free(buffer->tme_mouse_buffer_events); ! 85: ! 86: /* destroy the buffer itself: */ ! 87: tme_free(buffer); ! 88: } ! 89: ! 90: /* this copies an event into a mouse buffer: */ ! 91: int ! 92: tme_mouse_buffer_copyin(struct tme_mouse_buffer *buffer, ! 93: _tme_const struct tme_mouse_event *event) ! 94: { ! 95: unsigned int buffer_head, buffer_size_mask; ! 96: ! 97: buffer_head = buffer->tme_mouse_buffer_head; ! 98: buffer_size_mask = buffer->tme_mouse_buffer_size - 1; ! 99: ! 100: /* if the buffer is full: */ ! 101: if (((buffer_head + 1) & buffer_size_mask) ! 102: == buffer->tme_mouse_buffer_tail) { ! 103: return (EAGAIN); ! 104: } ! 105: ! 106: /* put this event into the buffer: */ ! 107: buffer->tme_mouse_buffer_events[buffer_head] ! 108: = *event; ! 109: ! 110: /* advance the head: */ ! 111: buffer->tme_mouse_buffer_head ! 112: = (buffer_head + 1) & buffer_size_mask; ! 113: ! 114: return (TME_OK); ! 115: } ! 116: ! 117: /* this copies an event out of a mouse buffer: */ ! 118: int ! 119: tme_mouse_buffer_copyout(struct tme_mouse_buffer *buffer, ! 120: struct tme_mouse_event *events, ! 121: unsigned int count) ! 122: { ! 123: unsigned int buffer_head, buffer_tail; ! 124: unsigned int buffer_size, buffer_size_mask; ! 125: unsigned int resid; ! 126: ! 127: /* get the head, tail, and size mask: */ ! 128: buffer_head = buffer->tme_mouse_buffer_head; ! 129: buffer_tail = buffer->tme_mouse_buffer_tail; ! 130: buffer_size_mask = buffer->tme_mouse_buffer_size - 1; ! 131: ! 132: for (resid = count; resid > 0; ) { ! 133: ! 134: /* if the buffer is empty: */ ! 135: if (buffer_tail == buffer->tme_mouse_buffer_head) { ! 136: ! 137: /* we're done copying out: */ ! 138: break; ! 139: } ! 140: ! 141: /* otherwise, the buffer is not empty, meaning there is always some ! 142: data starting at the buffer tail. if the buffer tail > the ! 143: buffer head, there is space from the buffer tail up to the end ! 144: of the buffer, otherwise there is space from the buffer tail up ! 145: to the buffer head: */ ! 146: buffer_size = ((buffer_tail > buffer_head) ! 147: ? (buffer_size_mask - buffer_tail) + 1 ! 148: : (buffer_head - buffer_tail)); ! 149: ! 150: /* don't copy out more data than there is space available: */ ! 151: buffer_size = TME_MIN(buffer_size, resid); ! 152: assert(buffer_size > 0); ! 153: ! 154: /* copy out the data: */ ! 155: memcpy(events, ! 156: buffer->tme_mouse_buffer_events + buffer_tail, ! 157: sizeof(struct tme_mouse_event) * buffer_size); ! 158: events += buffer_size; ! 159: ! 160: /* update and loop: */ ! 161: buffer_tail = (buffer_tail + buffer_size) & buffer_size_mask; ! 162: resid -= buffer_size; ! 163: } ! 164: ! 165: buffer->tme_mouse_buffer_tail = buffer_tail; ! 166: return (count - resid); ! 167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.