+
+// Note that the accessor functions are unsafe, but this is handled in
+// the next layer up. 64bit uints can be substituted to taste (shift=6).
+template<size_t M> class bitmap
+{
+private:
+ typedef uint32_t bitu_t; enum { shift=5 };
+ enum { bmax=M, bpu=1<<shift, mask=bpu-1, units=(bmax+bpu-1)/bpu };
+ bitu_t bits[units];
+public:
+ bool get(size_t idx) const { return bits[idx>>shift]&(1<<(idx&mask)); }
+ void set(size_t idx) { bits[idx>>shift]|= 1<<(idx&mask); }
+ void reset(size_t idx) { bits[idx>>shift]&=~(1<<(idx&mask)); }
+ void toggle(size_t idx) { bits[idx>>shift]^= 1<<(idx&mask); }
+ size_t maxbit() const { return bmax; }
+ void clear() { memset(bits,0,sizeof(bits)); }
+ bitmap() { clear(); }
+ ~bitmap() { }
+ bool empty() const { // naive invert() will break this
+ for(size_t i=0;i<units;++i)
+ if(bits[i]) return false;
+ return true;
+ }
+};
+
+typedef bitmap<libvlc_VlmMediaInstanceStatusError+1> eventtypes_bitmap_t;
+
+
+class EventObj: private eventtypes_bitmap_t
+{
+private:
+ typedef libvlc_event_type_t event_t;
+ bool have_event(event_t e) const { return e<maxbit()?get(e):false; }
+
+ class Listener: public eventtypes_bitmap_t
+ {
+ public:
+ Listener(event_t e,NPObject *o,bool b): _l(o), _b(b)
+ { NPN_RetainObject(o); set(e); }
+ Listener(): _l(NULL), _b(false) { }
+ ~Listener() { if(_l) NPN_ReleaseObject(_l); }
+ NPObject *listener() const { return _l; }
+ bool bubble() const { return _b; }
+ private:
+ NPObject *_l;
+ bool _b;
+ };
+
+ libvlc_event_manager_t *_em;
+ libvlc_callback_t _cb;
+ void *_ud;
+public:
+ EventObj(): _em(NULL) { /* deferred to init() */ }
+ bool init();
+ ~EventObj();
+
+ void deliver(NPP browser);
+ void callback(const libvlc_event_t*);
+ bool insert(const NPString &, NPObject *, bool);
+ bool remove(const NPString &, NPObject *, bool);
+ void unhook_manager();
+ void hook_manager(libvlc_event_manager_t *,libvlc_callback_t, void *);
+private:
+ event_t find_event(const char *s) const;
+ typedef std::vector<Listener> lr_l;
+ typedef std::vector<libvlc_event_type_t> ev_l;
+ lr_l _llist;
+ ev_l _elist;
+
+ plugin_lock_t lock;
+
+ bool ask_for_event(event_t e);
+ void unask_for_event(event_t e);
+};
+
+