Annotation of tme/generic/mouse.c, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.