#include "darwin.h"
#include "mipointer.h" // mi software cursor
#include <pthread.h>
#define QUEUE_SIZE 256
static struct {
pthread_mutex_t mutex;
HWEventQueueType head, tail;
xEvent events[QUEUE_SIZE];
} event_queue;
static int event_fd[2];
void
DarwinEnqueueEvent (const xEvent *e)
{
int newtail, oldtail;
int need_write = FALSE;
pthread_mutex_lock (&event_queue.mutex);
oldtail = (event_queue.tail - 1) % QUEUE_SIZE;
if (e->u.u.type == MotionNotify
&& event_queue.tail != event_queue.head
&& event_queue.events[oldtail].u.u.type == MotionNotify)
{
memcpy (&event_queue.events[oldtail], e, sizeof (xEvent));
}
else
{
newtail = (event_queue.tail + 1) % QUEUE_SIZE;
if (newtail != event_queue.head)
{
memcpy (&event_queue.events[event_queue.tail], e, sizeof (xEvent));
event_queue.tail = newtail;
need_write = TRUE;
}
}
pthread_mutex_unlock (&event_queue.mutex);
if (need_write)
write (event_fd[1], &need_write, sizeof (need_write));
}
Bool
DarwinDequeueEvent (xEvent *e)
{
Bool ret = FALSE;
int unused;
pthread_mutex_lock (&event_queue.mutex);
if (event_queue.head != event_queue.tail)
{
memcpy (e, &event_queue.events[event_queue.head], sizeof (xEvent));
event_queue.head = (event_queue.head + 1) % QUEUE_SIZE;
ret = TRUE;
}
pthread_mutex_unlock (&event_queue.mutex);
if (ret)
read (event_fd[0], &unused, sizeof (unused));
return ret;
}
void
DarwinInputPreInit (void)
{
if (pipe (event_fd) != 0)
{
perror ("pipe");
exit (1);
}
event_queue.head = event_queue.tail = 0;
pthread_mutex_init (&event_queue.mutex, NULL);
}
void
DarwinInputInit (void)
{
SetInputCheck (&event_queue.head, &event_queue.tail);
}
static void DarwinChangePointerControl(DeviceIntPtr device, PtrCtrl *ctrl)
{
}
int DarwinMouseProc(DeviceIntPtr pPointer, int what)
{
char map[6];
switch (what) {
case DEVICE_INIT:
pPointer->public.on = FALSE;
map[1] = 1;
map[2] = 2;
map[3] = 3;
map[4] = 4;
map[5] = 5;
InitPointerDeviceStruct( (DevicePtr)pPointer,
map,
5, miPointerGetMotionEvents,
DarwinChangePointerControl,
0 );
break;
case DEVICE_ON:
pPointer->public.on = TRUE;
AddEnabledDevice(event_fd[0]);
return Success;
case DEVICE_CLOSE:
case DEVICE_OFF:
pPointer->public.on = FALSE;
RemoveEnabledDevice(event_fd[0]);
return Success;
}
return Success;
}
int DarwinKeybdProc(DeviceIntPtr pDev, int onoff)
{
switch ( onoff ) {
case DEVICE_INIT:
DarwinKeyboardInit( pDev );
break;
case DEVICE_ON:
pDev->public.on = TRUE;
AddEnabledDevice(event_fd[0]);
break;
case DEVICE_OFF:
pDev->public.on = FALSE;
RemoveEnabledDevice(event_fd[0]);
break;
case DEVICE_CLOSE:
break;
}
return Success;
}