diff options
Diffstat (limited to 'client/windows/event_sources_p.cpp')
-rw-r--r-- | client/windows/event_sources_p.cpp | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/client/windows/event_sources_p.cpp b/client/windows/event_sources_p.cpp new file mode 100644 index 00000000..4a11b779 --- /dev/null +++ b/client/windows/event_sources_p.cpp @@ -0,0 +1,209 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + 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, see <http://www.gnu.org/licenses/>. +*/ + +#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()); + } + + int event_index = wait_res - WAIT_OBJECT_0; + if (event_index == _handles.size()) { + return process_system_events(); + } else if ((event_index >= 0) && (event_index < (int)_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) +{ +} + |