Merge branch 'genete_master'
[synfig.git] / synfig-osx / launcher / darwin-input.c
1 /* darwin-input.c -- code to manage the input event queue
2    $Id: darwin-input.c,v 1.4 2002/12/13 00:22:51 jharper Exp $ */
3
4 /*
5  * Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved.
6  * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Except as contained in this notice, the name(s) of the above copyright
27  * holders shall not be used in advertising or otherwise to promote the sale,
28  * use or other dealings in this Software without prior written authorization.
29  */
30
31 #include "darwin.h"
32
33 #include "mipointer.h"          // mi software cursor
34
35 #include <pthread.h>
36
37 #define QUEUE_SIZE 256
38
39 static struct {
40     pthread_mutex_t mutex;
41
42     /* DIX looks at these two integer values, when they're equal
43        it won't call ProcessInputEvents (). */
44     HWEventQueueType head, tail;
45
46     xEvent events[QUEUE_SIZE];
47 } event_queue;
48
49 /* fd[0] = reading, fd[1] = writing */
50 static int event_fd[2];
51
52 void
53 DarwinEnqueueEvent (const xEvent *e)
54 {
55     int newtail, oldtail;
56     int need_write = FALSE;
57
58     pthread_mutex_lock (&event_queue.mutex);
59
60     oldtail = (event_queue.tail - 1) % QUEUE_SIZE;
61
62     if (e->u.u.type == MotionNotify
63         && event_queue.tail != event_queue.head
64         && event_queue.events[oldtail].u.u.type == MotionNotify)
65     {
66         /* Two adjacent motion notify events. Coalesce them. */
67
68         memcpy (&event_queue.events[oldtail], e, sizeof (xEvent));
69     }
70     else
71     {
72         newtail = (event_queue.tail + 1) % QUEUE_SIZE;
73
74         if (newtail != event_queue.head)
75         {       
76             memcpy (&event_queue.events[event_queue.tail], e, sizeof (xEvent));
77             event_queue.tail = newtail;
78             need_write = TRUE;
79         }
80     }
81
82     pthread_mutex_unlock (&event_queue.mutex);
83
84     if (need_write)
85         write (event_fd[1], &need_write, sizeof (need_write));
86 }
87
88 Bool
89 DarwinDequeueEvent (xEvent *e)
90 {
91     Bool ret = FALSE;
92     int unused;
93
94     pthread_mutex_lock (&event_queue.mutex);
95
96     if (event_queue.head != event_queue.tail)
97     {
98         memcpy (e, &event_queue.events[event_queue.head], sizeof (xEvent));
99         event_queue.head = (event_queue.head + 1) % QUEUE_SIZE;
100         ret = TRUE;
101     }
102         
103     pthread_mutex_unlock (&event_queue.mutex);
104
105     if (ret)
106         read (event_fd[0], &unused, sizeof (unused));
107
108     return ret;
109 }
110
111 void
112 DarwinInputPreInit (void)
113 {
114     if (pipe (event_fd) != 0)
115     {
116         perror ("pipe");
117         exit (1);
118     }
119
120     event_queue.head = event_queue.tail = 0;
121     pthread_mutex_init (&event_queue.mutex, NULL);
122 }
123
124 void
125 DarwinInputInit (void)
126 {
127     SetInputCheck (&event_queue.head, &event_queue.tail);
128 }
129
130 \f
131 /*
132  =============================================================================
133
134  mouse and keyboard callbacks
135
136  =============================================================================
137 */
138
139 /*
140  * DarwinChangePointerControl
141  *  Set mouse acceleration and thresholding
142  *  FIXME: We currently ignore the threshold in ctrl->threshold.
143  */
144 static void DarwinChangePointerControl(DeviceIntPtr device, PtrCtrl *ctrl)
145 {
146     /* do nothing here */
147 }
148
149
150 /*
151  * DarwinMouseProc
152  *  Handle the initialization, etc. of a mouse
153  */
154
155 int DarwinMouseProc(DeviceIntPtr pPointer, int what)
156 {
157     char map[6];
158
159     switch (what) {
160
161         case DEVICE_INIT:
162             pPointer->public.on = FALSE;
163
164             // Set button map.
165             map[1] = 1;
166             map[2] = 2;
167             map[3] = 3;
168             map[4] = 4;
169             map[5] = 5;
170             InitPointerDeviceStruct( (DevicePtr)pPointer,
171                         map,
172                         5,   // numbuttons (4 & 5 are scroll wheel)
173                         miPointerGetMotionEvents,
174                         DarwinChangePointerControl,
175                         0 );
176             break;
177
178         case DEVICE_ON:
179             pPointer->public.on = TRUE;
180             AddEnabledDevice(event_fd[0]);
181             return Success;
182
183         case DEVICE_CLOSE:
184         case DEVICE_OFF:
185             pPointer->public.on = FALSE;
186             RemoveEnabledDevice(event_fd[0]);
187             return Success;
188     }
189
190     return Success;
191 }
192
193 /*
194  * DarwinKeybdProc
195  *  Callback from X
196  */
197 int DarwinKeybdProc(DeviceIntPtr pDev, int onoff)
198 {
199     switch ( onoff ) {
200         case DEVICE_INIT:
201             DarwinKeyboardInit( pDev );
202             break;
203         case DEVICE_ON:
204             pDev->public.on = TRUE;
205             AddEnabledDevice(event_fd[0]);
206             break;
207         case DEVICE_OFF:
208             pDev->public.on = FALSE;
209             RemoveEnabledDevice(event_fd[0]);
210             break;
211         case DEVICE_CLOSE:
212             break;
213     }
214
215     return Success;
216 }