aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/EventManager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/EventManager.cc')
-rw-r--r--src/FbTk/EventManager.cc192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/FbTk/EventManager.cc b/src/FbTk/EventManager.cc
new file mode 100644
index 0000000..9a11ab2
--- /dev/null
+++ b/src/FbTk/EventManager.cc
@@ -0,0 +1,192 @@
1// EventManager.cc
2// Copyright (c) 2002 Henrik Kinnunen (fluxgen at linuxmail.org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: EventManager.cc,v 1.11 2004/04/19 22:46:46 fluxgen Exp $
23
24#include "EventManager.hh"
25#include "FbWindow.hh"
26#include "App.hh"
27
28#include <iostream>
29using namespace std;
30
31namespace FbTk {
32
33EventManager *EventManager::instance() {
34 static EventManager ev;
35 return &ev;
36}
37
38EventManager::~EventManager() {
39 if (m_eventhandlers.size() != 0)
40 cerr<<"FbTk::EventManager: Warning: unregistered eventhandlers!"<<endl;
41}
42
43void EventManager::handleEvent(XEvent &ev) {
44 dispatch(ev.xany.window, ev);
45}
46
47void EventManager::add(EventHandler &ev, const FbWindow &win) {
48 registerEventHandler(ev, win.window());
49}
50
51void EventManager::addParent(EventHandler &ev, const FbWindow &win) {
52 if (win.window() != 0)
53 m_parent[win.window()] = &ev;
54}
55
56void EventManager::remove(const FbWindow &win) {
57 unregisterEventHandler(win.window());
58}
59
60EventHandler *EventManager::find(Window win) {
61 return m_eventhandlers[win];
62}
63
64
65Window EventManager::getEventWindow(XEvent &ev) {
66 // we only have cases for events that differ from xany
67 switch (ev.type) {
68 case CreateNotify:
69 // XCreateWindowEvent
70 return ev.xcreatewindow.window;
71 break;
72 case DestroyNotify:
73 // XDestroyWindowEvent
74 return ev.xdestroywindow.window;
75 break;
76 case UnmapNotify:
77 // XUnmapEvent
78 return ev.xunmap.window;
79 break;
80 case MapNotify:
81 // XMapEvent
82 return ev.xmap.window;
83 break;
84 case MapRequest:
85 // XMapRequestEvent
86 return ev.xmaprequest.window;
87 break;
88 case ReparentNotify:
89 // XReparentEvent
90 return ev.xreparent.window;
91 break;
92 case ConfigureNotify:
93 // XConfigureNotify
94 return ev.xconfigure.window;
95 break;
96 case GravityNotify:
97 // XGravityNotify
98 return ev.xgravity.window;
99 break;
100 case ConfigureRequest:
101 // XConfigureRequestEvent
102 return ev.xconfigurerequest.window;
103 break;
104 case CirculateNotify:
105 // XCirculateEvent
106 return ev.xcirculate.window;
107 break;
108 case CirculateRequest:
109 // XCirculateRequestEvent
110 return ev.xcirculaterequest.window;
111 break;
112 default:
113 return ev.xany.window;
114 }
115}
116
117void EventManager::registerEventHandler(EventHandler &ev, Window win) {
118 if (win != None)
119 m_eventhandlers[win] = &ev;
120}
121
122void EventManager::unregisterEventHandler(Window win) {
123 if (win != None) {
124 m_eventhandlers.erase(win);
125 m_parent.erase(win);
126 }
127}
128
129void EventManager::dispatch(Window win, XEvent &ev, bool parent) {
130 EventHandler *evhand = 0;
131 if (parent)
132 evhand = m_parent[win];
133 else {
134 win = getEventWindow(ev);
135 evhand = m_eventhandlers[win];
136 }
137
138 if (evhand == 0)
139 return;
140
141 switch (ev.type) {
142 case KeyPress:
143 evhand->keyPressEvent(ev.xkey);
144 break;
145 case KeyRelease:
146 evhand->keyReleaseEvent(ev.xkey);
147 break;
148 case ButtonPress:
149 evhand->buttonPressEvent(ev.xbutton);
150 break;
151 case ButtonRelease:
152 evhand->buttonReleaseEvent(ev.xbutton);
153 break;
154 case MotionNotify:
155 evhand->motionNotifyEvent(ev.xmotion);
156 break;
157 case Expose:
158 evhand->exposeEvent(ev.xexpose);
159 break;
160 case EnterNotify:
161 evhand->enterNotifyEvent(ev.xcrossing);
162 break;
163 case LeaveNotify:
164 evhand->leaveNotifyEvent(ev.xcrossing);
165 break;
166 default:
167 evhand->handleEvent(ev);
168 break;
169 };
170
171 // find out which window is the parent and
172 // dispatch event
173 Window root, parent_win, *children = 0;
174 unsigned int num_children;
175 if (XQueryTree(FbTk::App::instance()->display(), win,
176 &root, &parent_win, &children, &num_children) != 0) {
177 if (children != 0)
178 XFree(children);
179
180 if (parent_win != 0 &&
181 parent_win != root) {
182 if (m_parent[parent_win] == 0)
183 return;
184
185 // dispatch event to parent
186 dispatch(parent_win, ev, true);
187 }
188 }
189
190}
191
192}; // end namespace FbTk