|
|
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.