00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "EventManager.hh"
00025 #include "FbWindow.hh"
00026 #include "App.hh"
00027
00028 #include <iostream>
00029 using namespace std;
00030
00031 namespace FbTk {
00032
00033 EventManager *EventManager::instance() {
00034 static EventManager ev;
00035 return &ev;
00036 }
00037
00038 EventManager::~EventManager() {
00039 if (m_eventhandlers.size() != 0)
00040 cerr<<"FbTk::EventManager: Warning: unregistered eventhandlers!"<<endl;
00041 }
00042
00043 void EventManager::handleEvent(XEvent &ev) {
00044 dispatch(ev.xany.window, ev);
00045 }
00046
00047 void EventManager::add(EventHandler &ev, const FbWindow &win) {
00048 registerEventHandler(ev, win.window());
00049 }
00050
00051 void EventManager::addParent(EventHandler &ev, const FbWindow &win) {
00052 if (win.window() != 0)
00053 m_parent[win.window()] = &ev;
00054 }
00055
00056 void EventManager::remove(const FbWindow &win) {
00057 unregisterEventHandler(win.window());
00058 }
00059
00060 Window EventManager::getEventWindow(XEvent &ev) {
00061
00062 switch (ev.type) {
00063 case CreateNotify:
00064
00065 return ev.xcreatewindow.window;
00066 break;
00067 case DestroyNotify:
00068
00069 return ev.xdestroywindow.window;
00070 break;
00071 case UnmapNotify:
00072
00073 return ev.xunmap.window;
00074 break;
00075 case MapNotify:
00076
00077 return ev.xmap.window;
00078 break;
00079 case MapRequest:
00080
00081 return ev.xmaprequest.window;
00082 break;
00083 case ReparentNotify:
00084
00085 return ev.xreparent.window;
00086 break;
00087 case ConfigureNotify:
00088
00089 return ev.xconfigure.window;
00090 break;
00091 case GravityNotify:
00092
00093 return ev.xgravity.window;
00094 break;
00095 case ConfigureRequest:
00096
00097 return ev.xconfigurerequest.window;
00098 break;
00099 case CirculateNotify:
00100
00101 return ev.xcirculate.window;
00102 break;
00103 case CirculateRequest:
00104
00105 return ev.xcirculaterequest.window;
00106 break;
00107 default:
00108 return ev.xany.window;
00109 }
00110 }
00111
00112 void EventManager::registerEventHandler(EventHandler &ev, Window win) {
00113 if (win != None)
00114 m_eventhandlers[win] = &ev;
00115 }
00116
00117 void EventManager::unregisterEventHandler(Window win) {
00118 if (win != None) {
00119 m_eventhandlers.erase(win);
00120 m_parent.erase(win);
00121 }
00122 }
00123
00124 void EventManager::dispatch(Window win, XEvent &ev, bool parent) {
00125 EventHandler *evhand = 0;
00126 if (parent)
00127 evhand = m_parent[win];
00128 else {
00129 win = getEventWindow(ev);
00130 evhand = m_eventhandlers[win];
00131 }
00132
00133 if (evhand == 0)
00134 return;
00135
00136 switch (ev.type) {
00137 case KeyPress:
00138 evhand->keyPressEvent(ev.xkey);
00139 break;
00140 case KeyRelease:
00141 evhand->keyReleaseEvent(ev.xkey);
00142 break;
00143 case ButtonPress:
00144 evhand->buttonPressEvent(ev.xbutton);
00145 break;
00146 case ButtonRelease:
00147 evhand->buttonReleaseEvent(ev.xbutton);
00148 break;
00149 case MotionNotify:
00150 evhand->motionNotifyEvent(ev.xmotion);
00151 break;
00152 case Expose:
00153 evhand->exposeEvent(ev.xexpose);
00154 break;
00155 case EnterNotify:
00156 evhand->enterNotifyEvent(ev.xcrossing);
00157 break;
00158 case LeaveNotify:
00159 evhand->leaveNotifyEvent(ev.xcrossing);
00160 break;
00161 default:
00162 evhand->handleEvent(ev);
00163 break;
00164 };
00165
00166
00167
00168 Window root, parent_win, *children = 0;
00169 unsigned int num_children;
00170 if (XQueryTree(FbTk::App::instance()->display(), win,
00171 &root, &parent_win, &children, &num_children) != 0) {
00172 if (children != 0)
00173 XFree(children);
00174
00175 if (parent_win != 0 &&
00176 parent_win != root) {
00177 if (m_parent[parent_win] == 0)
00178 return;
00179
00180
00181 dispatch(parent_win, ev, true);
00182 }
00183 }
00184
00185 }
00186
00187 };