/* Copyright (C) 2009 Red Hat, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include "common.h" #include "event_sources.h" #include "debug.h" #include "utils.h" bool EventSources_p::process_system_events() { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { return true; } TranslateMessage(&msg); DispatchMessage(&msg); } return false; } void EventSources_p::add_event(HANDLE event, EventSource* source) { int size = _events.size(); _events.resize(size + 1); _handles.resize(size + 1); _events[size] = source; _handles[size] = event; } void EventSources_p::remove_event(EventSource* source) { int size = _events.size(); for (int i = 0; i < size; i++) { if (_events[i] == source) { for (i++; i < size; i++) { _events[i - 1] = _events[i]; _handles[i - 1] = _handles[i]; } _events.resize(size - 1); _handles.resize(size - 1); return; } } THROW("event not found"); } EventSources::EventSources() { } EventSources::~EventSources() { } bool EventSources::wait_events(int timeout_ms) { if (_handles.empty()) { if (WaitMessage()) { return process_system_events(); } else { THROW("wait failed %d", GetLastError()); } } DWORD wait_res = MsgWaitForMultipleObjectsEx(_handles.size(), &_handles[0], timeout_ms, QS_ALLINPUT, 0); if (wait_res == WAIT_TIMEOUT) { return false; } if (wait_res == WAIT_FAILED) { THROW("wait failed %d", GetLastError()); } size_t event_index = wait_res - WAIT_OBJECT_0; if (event_index == _handles.size()) { return process_system_events(); } else if ((event_index >= 0) && (event_index < _handles.size())) { _events[event_index]->action(); return false; } else { THROW("invalid event id"); } } void EventSources::add_socket(Socket& socket) { HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!event) { THROW("create event failed"); } if (WSAEventSelect(socket.get_socket(), event, FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) { CloseHandle(event); THROW("event select failed"); } add_event(event, &socket); } void EventSources::remove_socket(Socket& socket) { int size = _events.size(); for (int i = 0; i < size; i++) { if (_events[i] == &socket) { if (WSAEventSelect(socket.get_socket(), NULL, 0) == SOCKET_ERROR) { THROW("event select failed"); } u_long arg = 0; if (ioctlsocket(socket.get_socket(), FIONBIO, &arg) == SOCKET_ERROR) { THROW("set blocking mode failed"); } CloseHandle(_handles[i]); for (i++; i < size; i++) { _events[i - 1] = _events[i]; _handles[i - 1] = _handles[i]; } _events.resize(size - 1); _handles.resize(size - 1); return; } } THROW("socket not found"); } void EventSources::add_handle(Handle& handle) { add_event(handle.get_handle(), &handle); } void EventSources::remove_handle(Handle& handle) { remove_event(&handle); } Handle_p::Handle_p() { if (!(_event = CreateEvent(NULL, FALSE, FALSE, NULL))) { THROW("create event failed"); } } Handle_p::~Handle_p() { CloseHandle(_event); } void EventSources::add_trigger(Trigger& trigger) { add_event(trigger.get_handle(), &trigger); } void EventSources::remove_trigger(Trigger& trigger) { remove_event(&trigger); } EventSources::Trigger::Trigger() { } EventSources::Trigger::~Trigger() { } void EventSources::Trigger::trigger() { if (!SetEvent(_event)) { THROW("set event failed"); } } void EventSources::Trigger::reset() { if (!ResetEvent(_event)) { THROW("set event failed"); } } void EventSources::Trigger::action() { on_event(); } void EventSources::add_file(File& file) { } void EventSources::remove_file(File& file) { }