1/*
2 * Copyright 2005-2007, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Axel D��rfler, axeld@pinc-software.de
7 */
8#ifndef EVENT_DISPATCHER_H
9#define EVENT_DISPATCHER_H
10
11
12#include <AutoDeleter.h>
13#include <Locker.h>
14#include <Message.h>
15#include <MessageFilter.h>
16#include <Messenger.h>
17#include <ObjectList.h>
18
19
20class Desktop;
21class EventStream;
22class HWInterface;
23class ServerBitmap;
24
25struct event_listener;
26
27
28class EventTarget {
29	public:
30		EventTarget();
31		~EventTarget();
32
33		void SetTo(const BMessenger& messenger);
34		BMessenger& Messenger() { return fMessenger; }
35
36		event_listener* FindListener(int32 token, int32* _index = NULL);
37		bool AddListener(int32 token, uint32 eventMask, uint32 options,
38				bool temporary);
39		void RemoveListener(event_listener* listener, bool temporary);
40
41		bool RemoveListener(int32 token);
42		bool RemoveTemporaryListener(int32 token);
43		void RemoveTemporaryListeners();
44
45		bool IsEmpty() const { return fListeners.IsEmpty(); }
46
47		int32 CountListeners() const { return fListeners.CountItems(); }
48		event_listener* ListenerAt(int32 index) const
49				{ return fListeners.ItemAt(index); }
50
51	private:
52		bool _RemoveTemporaryListener(event_listener* listener, int32 index);
53
54		BObjectList<event_listener> fListeners;
55		BMessenger	fMessenger;
56};
57
58class EventFilter {
59	public:
60		virtual ~EventFilter() {};
61		virtual filter_result Filter(BMessage* event, EventTarget** _target,
62			int32* _viewToken = NULL, BMessage* latestMouseMoved = NULL) = 0;
63		virtual void RemoveTarget(EventTarget* target);
64};
65
66class EventDispatcher : public BLocker {
67	public:
68		EventDispatcher();
69		~EventDispatcher();
70
71		status_t SetTo(EventStream* stream);
72		status_t InitCheck();
73
74		void RemoveTarget(EventTarget& target);
75
76		bool AddListener(EventTarget& target, int32 token,
77				uint32 eventMask, uint32 options);
78		bool AddTemporaryListener(EventTarget& target,
79				int32 token, uint32 eventMask, uint32 options);
80		void RemoveListener(EventTarget& target, int32 token);
81		void RemoveTemporaryListener(EventTarget& target, int32 token);
82
83		void SetMouseFilter(EventFilter* filter);
84		void SetKeyboardFilter(EventFilter* filter);
85
86		void GetMouse(BPoint& where, int32& buttons);
87		void SendFakeMouseMoved(EventTarget& target, int32 viewToken);
88		bigtime_t IdleTime();
89
90		bool HasCursorThread();
91		void SetHWInterface(HWInterface* interface);
92
93		void SetDragMessage(BMessage& message, ServerBitmap* bitmap,
94				const BPoint& offsetFromCursor);
95			// the message should be delivered on the next
96			// "mouse up".
97			// if the mouse is not pressed, it should
98			// be delivered to the "current" target right away.
99
100		void SetDesktop(Desktop* desktop);
101
102	private:
103		status_t _Run();
104		void _Unset();
105
106		void _SendFakeMouseMoved(BMessage* message);
107		bool _SendMessage(BMessenger& messenger, BMessage* message,
108				float importance);
109
110		bool _AddTokens(BMessage* message, EventTarget* target,
111				uint32 eventMask, BMessage* nextMouseMoved = NULL,
112				int32* _viewToken = NULL);
113		void _RemoveTokens(BMessage* message);
114		void _SetFeedFocus(BMessage* message);
115		void _UnsetFeedFocus(BMessage* message);
116
117		void _SetMouseTarget(const BMessenger* messenger);
118		void _UnsetLastMouseTarget();
119
120		bool _AddListener(EventTarget& target, int32 token,
121				uint32 eventMask, uint32 options, bool temporary);
122		void _RemoveTemporaryListeners();
123
124		void _DeliverDragMessage();
125
126		void _EventLoop();
127		void _CursorLoop();
128
129		static status_t _event_looper(void* dispatcher);
130		static status_t _cursor_looper(void* dispatcher);
131
132	private:
133		EventStream*	fStream;
134		thread_id		fThread;
135		thread_id		fCursorThread;
136
137		EventTarget*	fPreviousMouseTarget;
138		EventTarget*	fFocus;
139		bool			fSuspendFocus;
140
141		ObjectDeleter <EventFilter>
142						fMouseFilter;
143		ObjectDeleter<EventFilter>
144						fKeyboardFilter;
145
146		BObjectList<EventTarget> fTargets;
147
148		BMessage*		fNextLatestMouseMoved;
149		BPoint			fLastCursorPosition;
150		int32			fLastButtons;
151		bigtime_t		fLastUpdate;
152
153		BMessage		fDragMessage;
154		bool			fDraggingMessage;
155		BPoint			fDragOffset;
156
157		BLocker			fCursorLock;
158		HWInterface*	fHWInterface;
159		Desktop*		fDesktop;
160};
161
162#endif	/* EVENT_DISPATCHER_H */
163