/* Copyright (C) 2001 Johan Rydberg. All Rights Reserved. This file is part of Crust. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include "SFEvent.h" #include "priv.h" /* We can have 256 events in the event queue before it gets flooded. */ #define EVENT_ARRAY_SIZE 256 /* Array of waiting events. And a counter that states how many events there are in the queue. */ static SFEvent event_array [EVENT_ARRAY_SIZE]; static int event_queued = 0; /* Hash table for lookup. */ static CFHashtableRef object_lookup_table = 0; /* This port set is used to receive events from all responders used by this application. */ mach_port_t _sf_event_portset = MACH_PORT_NULL; /* Insert PORT into the port set for event ports. Connect object TYPE to the port. ??? return error? */ void _SFEventInsertPort (CFTypeRef type, mach_port_t port) { int err; if (_sf_event_portset == 0) { err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, &_sf_event_portset); if (err) { CFLog ("SFEventInsertPort: Can not create event port set\n"); return; } object_lookup_table = CFHashtableCreate (); assert (object_lookup_table); } CFHashtableInsert (object_lookup_table, (int) port, (void *) type, 0); mach_port_move_member (mach_task_self (), port, _sf_event_portset); } /* Try to lookup object connected to PORT. Returns NULL if we didn't find any. */ CFTypeRef _SFEventLookupObject (mach_port_t port) { return CFHashtableLookup (object_lookup_table, (int) port); } /* Put EVENT in the queue of unfetched events. */ void _SFEventPost (SFEvent *event) { event_array [event_queued++] = *event; } /* Fetch a event from the event queue. If the event queue was empty we wait for an event in TIMEOUT miliseconds. If TIMEOUT is zero we wait forever. Returns FALSE on timeout - otherwise TRUE. Note: Reimplement. Make it multithreaded?? */ bool SFEventNext (SFEvent *event, int timeout) { extern int ws_server (mach_msg_header_t *, mach_msg_header_t *); int err; if (_sf_event_portset == MACH_PORT_NULL) return false; while (event_queued == 0) { err = mach_msg_server_timeout (ws_server, 0, _sf_event_portset, timeout ? MACH_RCV_TIMEOUT : 0, timeout); if (err == MACH_RCV_TIMED_OUT) return false; } /* Fetch event. */ memcpy (event, &event_array [0], sizeof (SFEvent)); --event_queued; if (event_queued) { memcpy (&event_array [0], &event_array [1], sizeof (SFEvent) * event_queued); } return true; }