| /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. |
| * |
| * This 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 software 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 software; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
| * USA. |
| */ |
| |
| #include <rfb_win32/EventManager.h> |
| #include <rdr/Exception.h> |
| #include <rfb/LogWriter.h> |
| |
| using namespace rfb; |
| using namespace rfb::win32; |
| |
| static LogWriter vlog("EventManager"); |
| |
| |
| EventManager::EventManager() : eventCount(0) { |
| } |
| |
| EventManager::~EventManager() { |
| } |
| |
| |
| bool EventManager::addEvent(HANDLE event, EventHandler* ecb) { |
| if (eventCount >= MAXIMUM_WAIT_OBJECTS-1) |
| return false; |
| events[eventCount] = event; |
| handlers[eventCount] = ecb; |
| eventCount++; |
| return true; |
| } |
| |
| void EventManager::removeEvent(HANDLE event) { |
| for (unsigned int i=0; i<eventCount; i++) { |
| if (events[i] == event) { |
| for (unsigned int j=i; j<eventCount-1; j++) { |
| events[j] = events[j+1]; |
| handlers[j] = handlers[j+1]; |
| } |
| eventCount--; |
| return; |
| } |
| } |
| throw rdr::Exception("Event not registered"); |
| } |
| |
| |
| int EventManager::checkTimeouts() { |
| return 0; |
| } |
| |
| BOOL EventManager::getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg) { |
| while (true) { |
| // - Process any pending timeouts |
| DWORD timeout = checkTimeouts(); |
| if (timeout == 0) |
| timeout = INFINITE; |
| |
| // - Events take precedence over messages |
| DWORD result; |
| if (eventCount) { |
| // - Check whether any events are set |
| result = WaitForMultipleObjects(eventCount, events, FALSE, 0); |
| if (result == WAIT_TIMEOUT) { |
| // - No events are set, so check for messages |
| if (PeekMessage(msg, hwnd, minMsg, maxMsg, PM_REMOVE)) |
| return msg->message != WM_QUIT; |
| |
| // - Block waiting for an event to be set, or a message |
| result = MsgWaitForMultipleObjects(eventCount, events, FALSE, timeout, |
| QS_ALLINPUT); |
| if (result == WAIT_OBJECT_0 + eventCount) { |
| // - Return the message, if any |
| if (PeekMessage(msg, hwnd, minMsg, maxMsg, PM_REMOVE)) |
| return msg->message != WM_QUIT; |
| continue; |
| } |
| } |
| } else |
| return GetMessage(msg, hwnd, minMsg, maxMsg); |
| |
| if ((result >= WAIT_OBJECT_0) && (result < (WAIT_OBJECT_0 + eventCount))) { |
| // - An event was set - call the handler |
| int index = result - WAIT_OBJECT_0; |
| handlers[index]->processEvent(events[index]); |
| } else if (result == WAIT_FAILED) { |
| // - An error has occurred, so return the error status code |
| return -1; |
| } |
| } |
| } |