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