1// vi:set ft=cpp: -*- Mode: C++ -*- 2/* 3 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>, 4 * Alexander Warg <warg@os.inf.tu-dresden.de> 5 * economic rights: Technische Universität Dresden (Germany) 6 * 7 * This file is part of TUD:OS and distributed under the terms of the 8 * GNU General Public License 2. 9 * Please see the COPYING-GPL-2 file for details. 10 * 11 * As a special exception, you may use this file as part of a free software 12 * library without restriction. Specifically, if other files instantiate 13 * templates or use macros or inline functions from this file, or you compile 14 * this file and link it with other files to produce an executable, this 15 * file does not by itself cause the resulting executable to be covered by 16 * the GNU General Public License. This exception does not however 17 * invalidate any other reasons why the executable file might be covered by 18 * the GNU General Public License. 19 */ 20 21#pragma once 22 23#include <l4/re/event_enums.h> 24#include <l4/re/event> 25#include <l4/re/event-sys.h> 26#include <l4/re/util/icu_svr> 27#include <l4/cxx/minmax> 28 29#include <l4/sys/cxx/ipc_legacy> 30 31namespace L4Re { namespace Util { 32 33/** 34 * Convenience wrapper for implementing an event server. 35 * 36 * \see L4Re::Event, L4Re::Util::Event_t 37 */ 38template< typename SVR > 39class Event_svr : public Icu_cap_array_svr<SVR> 40{ 41private: 42 typedef Icu_cap_array_svr<SVR> Icu_svr; 43 44protected: 45 L4::Cap<L4Re::Dataspace> _ds; 46 typename Icu_svr::Irq _irq; 47 48public: 49 Event_svr() : Icu_svr(1, &_irq) {} 50 51 L4_RPC_LEGACY_DISPATCH(L4Re::Event); 52 L4_RPC_LEGACY_USING(Icu_svr); 53 54 /// Handle L4Re::Event protocol 55 long op_get_buffer(L4Re::Event::Rights, L4::Ipc::Cap<L4Re::Dataspace> &ds) 56 { 57 static_cast<SVR*>(this)->reset_event_buffer(); 58 ds = L4::Ipc::Cap<L4Re::Dataspace>(_ds, L4_CAP_FPAGE_RW); 59 return 0; 60 } 61 62 long op_get_num_streams(L4Re::Event::Rights) 63 { return static_cast<SVR*>(this)->get_num_streams(); } 64 65 long op_get_stream_info(L4Re::Event::Rights, int idx, Event_stream_info &info) 66 { return static_cast<SVR*>(this)->get_stream_info(idx, &info); } 67 68 long op_get_stream_info_for_id(L4Re::Event::Rights, l4_umword_t id, 69 Event_stream_info &info) 70 { return static_cast<SVR*>(this)->get_stream_info_for_id(id, &info); } 71 72 long op_get_axis_info(L4Re::Event::Rights, l4_umword_t id, 73 L4::Ipc::Array_in_buf<unsigned, unsigned long> const &axes, 74 L4::Ipc::Array_ref<Event_absinfo, unsigned long> &info) 75 { 76 unsigned naxes = cxx::min<unsigned>(L4RE_ABS_MAX, axes.length); 77 78 info.length = 0; 79 80 Event_absinfo _info[naxes]; 81 int r = static_cast<SVR*>(this)->get_axis_info(id, naxes, axes.data, _info); 82 if (r < 0) 83 return r; 84 85 for (unsigned i = 0; i < naxes; ++i) 86 info.data[i] = _info[i]; 87 88 info.length = naxes; 89 return r; 90 } 91 92 long op_get_stream_state_for_id(L4Re::Event::Rights, l4_umword_t stream_id, 93 Event_stream_state &state) 94 { return static_cast<SVR*>(this)->get_stream_state_for_id(stream_id, &state); } 95 96 int get_num_streams() const { return 0; } 97 int get_stream_info(int, L4Re::Event_stream_info *) 98 { return -L4_EINVAL; } 99 int get_stream_info_for_id(l4_umword_t, L4Re::Event_stream_info *) 100 { return -L4_EINVAL; } 101 int get_axis_info(l4_umword_t, unsigned /*naxes*/, unsigned const * /*axes*/, 102 L4Re::Event_absinfo *) 103 { return -L4_EINVAL; } 104 int get_stream_state_for_id(l4_umword_t, L4Re::Event_stream_state *) 105 { return -L4_EINVAL; } 106}; 107 108}} 109