Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef toolx_X11_base_session 4 #ifndef toolx_X11_base_session 5 #define toolx_X11_base_session 5 #define toolx_X11_base_session 6 6 7 // pure X11 code, no GL. 7 // pure X11 code, no GL. 8 8 9 #include <ostream> 9 #include <ostream> 10 #include <vector> 10 #include <vector> 11 11 12 #include "dispatcher" 12 #include "dispatcher" 13 #include <tools/forit> 13 #include <tools/forit> 14 14 15 #include <X11/Xatom.h> //XA_INTEGER 15 #include <X11/Xatom.h> //XA_INTEGER 16 16 17 #include <X11/Xutil.h> //XVisualInfo 17 #include <X11/Xutil.h> //XVisualInfo 18 18 19 namespace toolx { 19 namespace toolx { 20 namespace X11 { 20 namespace X11 { 21 21 22 class base_session { 22 class base_session { 23 public: 23 public: 24 //virtual bool make_current(Window) const { 24 //virtual bool make_current(Window) const { 25 // if(!m_display) return false; 25 // if(!m_display) return false; 26 // return true; 26 // return true; 27 //} 27 //} 28 //virtual bool swap_buffers(Window) const { 28 //virtual bool swap_buffers(Window) const { 29 // if(!m_display) return false; 29 // if(!m_display) return false; 30 // return true; 30 // return true; 31 //} 31 //} 32 public: 32 public: 33 base_session(std::ostream& a_out,unsigned in 33 base_session(std::ostream& a_out,unsigned int a_monitor = 0) 34 :m_out(a_out) 34 :m_out(a_out) 35 ,m_monitor(a_monitor) 35 ,m_monitor(a_monitor) 36 ,m_display(0) 36 ,m_display(0) 37 ,m_WM_DELETE_WINDOW_atom(None) 37 ,m_WM_DELETE_WINDOW_atom(None) 38 ,m_SESSION_EXIT_STEER_atom(None) 38 ,m_SESSION_EXIT_STEER_atom(None) 39 { 39 { 40 //NOTE : macOS : XOpenDisplay leaks 128 by 40 //NOTE : macOS : XOpenDisplay leaks 128 bytes. 41 m_display = ::XOpenDisplay(NULL); 41 m_display = ::XOpenDisplay(NULL); 42 if(!m_display) { 42 if(!m_display) { 43 m_out << "toolx::X11::base_session::base 43 m_out << "toolx::X11::base_session::base_session : can't open display." << std::endl; 44 return; 44 return; 45 } 45 } 46 46 47 int monitors = ::XScreenCount(m_display); 47 int monitors = ::XScreenCount(m_display); 48 if(int(m_monitor)>=monitors) { 48 if(int(m_monitor)>=monitors) { 49 m_out << "toolx::X11::base_session::base 49 m_out << "toolx::X11::base_session::base_session : bad monitor index " 50 << m_monitor << ". (#monitors " << 50 << m_monitor << ". (#monitors " << monitors << ")." << std::endl; 51 ::XCloseDisplay(m_display); 51 ::XCloseDisplay(m_display); 52 m_display = 0; 52 m_display = 0; 53 return; 53 return; 54 } 54 } 55 55 56 m_WM_DELETE_WINDOW_atom = ::XInternAtom(m_ 56 m_WM_DELETE_WINDOW_atom = ::XInternAtom(m_display,"WM_DELETE_WINDOW",False); 57 if(m_WM_DELETE_WINDOW_atom==None) { 57 if(m_WM_DELETE_WINDOW_atom==None) { 58 m_out << "toolx::X11::base_session::base 58 m_out << "toolx::X11::base_session::base_session : can't create WM_DELETE_WINDOW Atom." << std::endl; 59 ::XCloseDisplay(m_display); 59 ::XCloseDisplay(m_display); 60 m_display = 0; 60 m_display = 0; 61 return; 61 return; 62 } 62 } 63 63 64 m_SESSION_EXIT_STEER_atom = ::XInternAtom( 64 m_SESSION_EXIT_STEER_atom = ::XInternAtom(m_display,"TOOLX_X11_SESSION_EXIT_STEER",False); 65 if(m_SESSION_EXIT_STEER_atom==None) { 65 if(m_SESSION_EXIT_STEER_atom==None) { 66 m_out << "toolx::X11::base_session::base 66 m_out << "toolx::X11::base_session::base_session :" 67 << " can't create TOOLX_X11_SESSIO 67 << " can't create TOOLX_X11_SESSION_EXIT_STEER Atom." << std::endl; 68 ::XCloseDisplay(m_display); 68 ::XCloseDisplay(m_display); 69 m_display = 0; 69 m_display = 0; 70 return; 70 return; 71 } 71 } 72 } 72 } 73 virtual ~base_session() { 73 virtual ~base_session() { 74 clear_dispatchers(); 74 clear_dispatchers(); 75 if(m_display) ::XCloseDisplay(m_display); 75 if(m_display) ::XCloseDisplay(m_display); 76 m_display = 0; 76 m_display = 0; 77 //std::cout << "debug : ~base_session" << 77 //std::cout << "debug : ~base_session" << std::endl; 78 } 78 } 79 protected: 79 protected: 80 base_session(const base_session& a_from) 80 base_session(const base_session& a_from) 81 :m_out(a_from.m_out) 81 :m_out(a_from.m_out) 82 ,m_monitor(a_from.m_monitor) 82 ,m_monitor(a_from.m_monitor) 83 ,m_display(0) 83 ,m_display(0) 84 ,m_WM_DELETE_WINDOW_atom(None) 84 ,m_WM_DELETE_WINDOW_atom(None) 85 ,m_SESSION_EXIT_STEER_atom(None) 85 ,m_SESSION_EXIT_STEER_atom(None) 86 {} 86 {} 87 base_session& operator=(const base_session& 87 base_session& operator=(const base_session& a_from){ 88 if(&a_from==this) return *this; 88 if(&a_from==this) return *this; 89 return *this; 89 return *this; 90 } 90 } 91 public: 91 public: 92 std::ostream& out() const {return m_out;} 92 std::ostream& out() const {return m_out;} 93 93 94 Atom WM_DELETE_WINDOW_atom() const {return m 94 Atom WM_DELETE_WINDOW_atom() const {return m_WM_DELETE_WINDOW_atom;} 95 Atom SESSION_EXIT_STEER_atom() const {return 95 Atom SESSION_EXIT_STEER_atom() const {return m_SESSION_EXIT_STEER_atom;} 96 96 97 bool is_valid() const {return m_display?true 97 bool is_valid() const {return m_display?true:false;} 98 98 99 unsigned int monitor() const {return m_monit 99 unsigned int monitor() const {return m_monitor;} 100 Display* display() const {return m_display;} 100 Display* display() const {return m_display;} 101 101 102 bool steer() { 102 bool steer() { 103 if(!m_display) return false; 103 if(!m_display) return false; 104 104 105 while(true) { 105 while(true) { 106 XEvent xevent; 106 XEvent xevent; 107 ::XNextEvent(m_display,&xevent); 107 ::XNextEvent(m_display,&xevent); 108 if(xevent.type==ClientMessage) { 108 if(xevent.type==ClientMessage) { 109 if(xevent.xclient.data.l[0]==(long)m_S 109 if(xevent.xclient.data.l[0]==(long)m_SESSION_EXIT_STEER_atom) break; 110 } 110 } 111 dispatch(xevent); 111 dispatch(xevent); 112 } 112 } 113 113 114 return true; 114 return true; 115 } 115 } 116 116 117 bool sync() { 117 bool sync() { 118 if(!m_display) return false; 118 if(!m_display) return false; 119 //::glXWaitX(); 119 //::glXWaitX(); 120 ::XSync(m_display,False); 120 ::XSync(m_display,False); 121 while(true) { 121 while(true) { 122 XEvent xevent; 122 XEvent xevent; 123 if(::XPending(m_display)) { 123 if(::XPending(m_display)) { 124 ::XNextEvent(m_display,&xevent); 124 ::XNextEvent(m_display,&xevent); 125 if(xevent.type==ClientMessage) { 125 if(xevent.type==ClientMessage) { 126 if(xevent.xclient.data.l[0]==(long)m 126 if(xevent.xclient.data.l[0]==(long)m_SESSION_EXIT_STEER_atom) return false; 127 } 127 } 128 dispatch(xevent); 128 dispatch(xevent); 129 } else { 129 } else { 130 break; 130 break; 131 } 131 } 132 } 132 } 133 return true; 133 return true; 134 } 134 } 135 135 136 bool event_pending(bool& a_is) { 136 bool event_pending(bool& a_is) { 137 if(!m_display) {a_is = false;return false; 137 if(!m_display) {a_is = false;return false;} 138 a_is = ::XPending(m_display)?true:false; 138 a_is = ::XPending(m_display)?true:false; 139 return true; 139 return true; 140 } 140 } 141 141 142 bool next_event(bool& a_to_exit) { 142 bool next_event(bool& a_to_exit) { 143 if(!m_display) {a_to_exit = false;return f 143 if(!m_display) {a_to_exit = false;return false;} 144 XEvent xevent; 144 XEvent xevent; 145 ::XNextEvent(m_display,&xevent); 145 ::XNextEvent(m_display,&xevent); 146 if(xevent.type==ClientMessage) { 146 if(xevent.type==ClientMessage) { 147 if(xevent.xclient.data.l[0]==(long)m_SES 147 if(xevent.xclient.data.l[0]==(long)m_SESSION_EXIT_STEER_atom) { 148 a_to_exit = true; 148 a_to_exit = true; 149 return true; 149 return true; 150 } 150 } 151 } 151 } 152 dispatch(xevent); 152 dispatch(xevent); 153 a_to_exit = false; 153 a_to_exit = false; 154 return true; 154 return true; 155 } 155 } 156 156 157 bool flush() { 157 bool flush() { 158 if(!m_display) return false; 158 if(!m_display) return false; 159 ::XFlush(m_display); 159 ::XFlush(m_display); 160 return true; 160 return true; 161 } 161 } 162 162 163 163 164 //////////////////////////////////////////// 164 ////////////////////////////////////////////////// 165 //////////////////////////////////////////// 165 ////////////////////////////////////////////////// 166 //////////////////////////////////////////// 166 ////////////////////////////////////////////////// 167 Window create_window(const char* a_title,int 167 Window create_window(const char* a_title,int a_x,int a_y,unsigned int a_width,unsigned int a_height) { 168 if(!m_display) return 0L; 168 if(!m_display) return 0L; 169 169 170 XSetWindowAttributes swa; 170 XSetWindowAttributes swa; 171 swa.event_mask = StructureNotifyMask | Exp 171 swa.event_mask = StructureNotifyMask | ExposureMask 172 | ButtonPressMask | ButtonReleaseMask | 172 | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask 173 | PointerMotionMask 173 | PointerMotionMask 174 | KeyPressMask; 174 | KeyPressMask; 175 175 176 swa.background_pixel = ::XWhitePixel(m_dis 176 swa.background_pixel = ::XWhitePixel(m_display,m_monitor); 177 177 178 Window window = ::XCreateWindow(m_display, 178 Window window = ::XCreateWindow(m_display, 179 ::XRootWin 179 ::XRootWindow(m_display,m_monitor), 180 a_x,a_y,a_ 180 a_x,a_y,a_width,a_height, 181 0, 181 0, 182 (int)CopyF 182 (int)CopyFromParent, 183 InputOutpu 183 InputOutput, 184 (Visual*)C 184 (Visual*)CopyFromParent, 185 CWEventMask|CWBackPixel,&swa); 185 CWEventMask|CWBackPixel,&swa); 186 if(window==0L) { 186 if(window==0L) { 187 m_out << "toolx::X11::base_session::crea 187 m_out << "toolx::X11::base_session::create_window : can't create a X11 window." << std::endl; 188 return 0L; 188 return 0L; 189 } 189 } 190 190 191 XTextProperty tp; 191 XTextProperty tp; 192 ::XStringListToTextProperty((char**)&a_tit 192 ::XStringListToTextProperty((char**)&a_title,1,&tp); 193 XSizeHints sh; 193 XSizeHints sh; 194 sh.flags = USPosition | USSize; 194 sh.flags = USPosition | USSize; 195 ::XSetWMProperties(m_display,window,&tp,&t 195 ::XSetWMProperties(m_display,window,&tp,&tp,0,0,&sh,0,0); 196 ::XFree(tp.value); 196 ::XFree(tp.value); 197 197 198 ::XSetWMProtocols(m_display,window,&m_WM_D 198 ::XSetWMProtocols(m_display,window,&m_WM_DELETE_WINDOW_atom,1); 199 return window; 199 return window; 200 } 200 } 201 201 202 void map_raise_window(Window a_window) const 202 void map_raise_window(Window a_window) const { 203 if(!m_display) return; 203 if(!m_display) return; 204 ::XMapWindow(m_display,a_window); 204 ::XMapWindow(m_display,a_window); 205 ::XRaiseWindow(m_display,a_window); 205 ::XRaiseWindow(m_display,a_window); 206 } 206 } 207 207 208 void show_window(Window a_window) const { 208 void show_window(Window a_window) const { 209 if(!m_display) return; 209 if(!m_display) return; 210 210 211 XWindowAttributes watbs; 211 XWindowAttributes watbs; 212 ::XGetWindowAttributes(m_display,a_window, 212 ::XGetWindowAttributes(m_display,a_window,&watbs); 213 if(watbs.map_state!=IsUnmapped) return; 213 if(watbs.map_state!=IsUnmapped) return; 214 214 215 ::XMapWindow(m_display,a_window); 215 ::XMapWindow(m_display,a_window); 216 ::XRaiseWindow(m_display,a_window); 216 ::XRaiseWindow(m_display,a_window); 217 217 218 {XEvent event; 218 {XEvent event; 219 ::XIfEvent(m_display,&event,wait_map_notif 219 ::XIfEvent(m_display,&event,wait_map_notify,(char*)a_window);} 220 } 220 } 221 221 222 void hide_window(Window a_window) const { 222 void hide_window(Window a_window) const { 223 if(!m_display) return; 223 if(!m_display) return; 224 224 225 XWindowAttributes watbs; 225 XWindowAttributes watbs; 226 ::XGetWindowAttributes(m_display,a_window, 226 ::XGetWindowAttributes(m_display,a_window,&watbs); 227 if(watbs.map_state==IsUnmapped) return; 227 if(watbs.map_state==IsUnmapped) return; 228 228 229 ::XUnmapWindow(m_display,a_window); 229 ::XUnmapWindow(m_display,a_window); 230 230 231 {XEvent event; 231 {XEvent event; 232 ::XIfEvent(m_display,&event,wait_unmap_not 232 ::XIfEvent(m_display,&event,wait_unmap_notify,(char*)a_window);} 233 } 233 } 234 234 235 void resize_window(Window a_window,unsigned 235 void resize_window(Window a_window,unsigned int a_width,unsigned int a_height) const { 236 if(!m_display) return; 236 if(!m_display) return; 237 unsigned int mask = CWWidth | CWHeight | C 237 unsigned int mask = CWWidth | CWHeight | CWBorderWidth; 238 XWindowChanges changes; 238 XWindowChanges changes; 239 changes.border_width = 0; 239 changes.border_width = 0; 240 changes.width = a_width; 240 changes.width = a_width; 241 changes.height = a_height; 241 changes.height = a_height; 242 ::XConfigureWindow(m_display,a_window,mask 242 ::XConfigureWindow(m_display,a_window,mask,&changes); 243 } 243 } 244 244 245 bool window_size(Window a_window,int& a_widt 245 bool window_size(Window a_window,int& a_width,int& a_height) const { 246 if(!m_display) {a_width = 0;a_height = 0;r 246 if(!m_display) {a_width = 0;a_height = 0;return false;} 247 XWindowAttributes watbs; 247 XWindowAttributes watbs; 248 if(!XGetWindowAttributes(m_display,a_windo 248 if(!XGetWindowAttributes(m_display,a_window,&watbs)) {a_width = 0;a_height = 0;return false;} 249 a_width = watbs.width; 249 a_width = watbs.width; 250 a_height = watbs.height; 250 a_height = watbs.height; 251 return true; 251 return true; 252 } 252 } 253 253 254 void delete_window(Window a_window) const { 254 void delete_window(Window a_window) const { 255 if(!m_display) return; 255 if(!m_display) return; 256 ::XDestroyWindow(m_display,a_window); 256 ::XDestroyWindow(m_display,a_window); 257 } 257 } 258 258 259 void set_override_redirect(Window a_window) 259 void set_override_redirect(Window a_window) const { 260 //must be executed before window is mapped 260 //must be executed before window is mapped. 261 if(!m_display) return; 261 if(!m_display) return; 262 XSetWindowAttributes swa; 262 XSetWindowAttributes swa; 263 swa.override_redirect = True; 263 swa.override_redirect = True; 264 ::XChangeWindowAttributes(m_display,a_wind 264 ::XChangeWindowAttributes(m_display,a_window,CWOverrideRedirect,&swa); 265 } 265 } 266 266 267 void set_wm_no_decorations(Window a_window) 267 void set_wm_no_decorations(Window a_window) const { 268 //must be executed before window is mapped 268 //must be executed before window is mapped. 269 if(!m_display) return; 269 if(!m_display) return; 270 270 271 // struct, mwm_hints_decorations taken fro 271 // struct, mwm_hints_decorations taken from OpenMotif MwmUtils.h. 272 struct{ 272 struct{ 273 unsigned long flags; 273 unsigned long flags; 274 unsigned long functions; 274 unsigned long functions; 275 unsigned long decorations; 275 unsigned long decorations; 276 long inputMode; 276 long inputMode; 277 unsigned long status; 277 unsigned long status; 278 } prop; 278 } prop; 279 279 280 //unsigned long mwm_hints_functions = 1L < 280 //unsigned long mwm_hints_functions = 1L << 0; 281 unsigned long mwm_hints_decorations = 1L 281 unsigned long mwm_hints_decorations = 1L << 1; 282 282 283 Atom atom = ::XInternAtom(m_display,"_MOTI 283 Atom atom = ::XInternAtom(m_display,"_MOTIF_WM_HINTS",False); 284 if(atom==None) { 284 if(atom==None) { 285 m_out << "toolx::X11::base_session::set_ 285 m_out << "toolx::X11::base_session::set_wm_no_decorations : can't create/get _MOTIF_WM_HINTS Atom." << std::endl; 286 return; 286 return; 287 } 287 } 288 prop.flags = mwm_hints_decorations; 288 prop.flags = mwm_hints_decorations; 289 prop.functions = 0; 289 prop.functions = 0; 290 prop.decorations = 0; 290 prop.decorations = 0; 291 291 292 ::XChangeProperty(m_display,a_window,atom, 292 ::XChangeProperty(m_display,a_window,atom,atom,32,PropModeReplace,(unsigned char*)&prop,5); 293 } 293 } 294 294 295 bool post(Window a_win, 295 bool post(Window a_win, 296 long a_0 = 0,long a_1 = 0, 296 long a_0 = 0,long a_1 = 0, 297 long a_2 = 0,long a_3 = 0, 297 long a_2 = 0,long a_3 = 0, 298 long a_4 = 0) const { 298 long a_4 = 0) const { 299 if(!m_display) return false; 299 if(!m_display) return false; 300 XEvent event; 300 XEvent event; 301 event.type = ClientMessage; 301 event.type = ClientMessage; 302 event.xclient.display = m_display; 302 event.xclient.display = m_display; 303 event.xclient.window = a_win; 303 event.xclient.window = a_win; 304 event.xclient.message_type = XA_INTEGER; 304 event.xclient.message_type = XA_INTEGER; 305 event.xclient.format = 8; /* put 8 beca 305 event.xclient.format = 8; /* put 8 because bug with 32 on VMCMS */ 306 event.xclient.data.l[0] = a_0; 306 event.xclient.data.l[0] = a_0; 307 event.xclient.data.l[1] = a_1; 307 event.xclient.data.l[1] = a_1; 308 event.xclient.data.l[2] = a_2; 308 event.xclient.data.l[2] = a_2; 309 event.xclient.data.l[3] = a_3; 309 event.xclient.data.l[3] = a_3; 310 event.xclient.data.l[4] = a_4; 310 event.xclient.data.l[4] = a_4; 311 //lock(); 311 //lock(); 312 Status stat = ::XSendEvent(m_display,a_win 312 Status stat = ::XSendEvent(m_display,a_win,False,0L,&event); 313 ::XFlush(m_display); 313 ::XFlush(m_display); 314 //unlock(); 314 //unlock(); 315 return (stat==0?false:true); 315 return (stat==0?false:true); 316 } 316 } 317 317 318 bool post_EXIT_STEER(Window a_win) { 318 bool post_EXIT_STEER(Window a_win) { 319 return post(a_win,SESSION_EXIT_STEER_atom( 319 return post(a_win,SESSION_EXIT_STEER_atom()); 320 } 320 } 321 321 322 //////////////////////////////////////////// 322 ////////////////////////////////////////////////// 323 //////////////////////////////////////////// 323 ////////////////////////////////////////////////// 324 //////////////////////////////////////////// 324 ////////////////////////////////////////////////// 325 void add_dispatcher(dispatcher* a_dispatcher 325 void add_dispatcher(dispatcher* a_dispatcher) { 326 m_dispatchers.push_back(a_dispatcher); //t 326 m_dispatchers.push_back(a_dispatcher); //take ownership. 327 } 327 } 328 328 329 void invalidate_dispatchers_with_window(Wind 329 void invalidate_dispatchers_with_window(Window a_win){ 330 tools_vforit(dispatcher*,m_dispatchers,it) 330 tools_vforit(dispatcher*,m_dispatchers,it) { 331 if((*it)->window()==a_win) (*it)->invali 331 if((*it)->window()==a_win) (*it)->invalidate(); 332 } 332 } 333 } 333 } 334 334 335 void remove_dispatchers_with_window(Window a 335 void remove_dispatchers_with_window(Window a_win){ 336 tools_vforit_npp(dispatcher*,m_dispatchers 336 tools_vforit_npp(dispatcher*,m_dispatchers,it) { 337 if((*it)->window()==a_win) { 337 if((*it)->window()==a_win) { 338 dispatcher* obj = *it; 338 dispatcher* obj = *it; 339 it = m_dispatchers.erase(it); 339 it = m_dispatchers.erase(it); 340 delete obj; 340 delete obj; 341 } else { 341 } else { 342 it++; 342 it++; 343 } 343 } 344 } 344 } 345 } 345 } 346 346 347 bool dispatch(XEvent& a_event) { 347 bool dispatch(XEvent& a_event) { 348 {tools_vforit_npp(dispatcher*,m_dispatchers 348 {tools_vforit_npp(dispatcher*,m_dispatchers,it) { 349 if(!(*it)->is_valid()) { 349 if(!(*it)->is_valid()) { 350 dispatcher* obj = *it; 350 dispatcher* obj = *it; 351 it = m_dispatchers.erase(it); 351 it = m_dispatchers.erase(it); 352 delete obj; 352 delete obj; 353 } else { 353 } else { 354 it++; 354 it++; 355 } 355 } 356 }} 356 }} 357 tools_vforit(dispatcher*,m_dispatchers,it) 357 tools_vforit(dispatcher*,m_dispatchers,it) { 358 if((*it)->is_valid()) { 358 if((*it)->is_valid()) { 359 if((*it)->dispatch(a_event)) return tr 359 if((*it)->dispatch(a_event)) return true; 360 } 360 } 361 } 361 } 362 return false; 362 return false; 363 } 363 } 364 protected: 364 protected: 365 static Bool wait_map_notify(Display*,XEvent* 365 static Bool wait_map_notify(Display*,XEvent* a_event,char* a_arg){ 366 return (a_event->type == MapNotify) && (a_ 366 return (a_event->type == MapNotify) && (a_event->xmap.window == (Window)a_arg); 367 } 367 } 368 static Bool wait_unmap_notify(Display*,XEven 368 static Bool wait_unmap_notify(Display*,XEvent* a_event,char* a_arg){ 369 return (a_event->type == UnmapNotify) && ( 369 return (a_event->type == UnmapNotify) && (a_event->xmap.window == (Window)a_arg); 370 } 370 } 371 371 372 /* 372 /* 373 void wait_xxx(Window a_window) { 373 void wait_xxx(Window a_window) { 374 if(!m_display) return; 374 if(!m_display) return; 375 {wait_what arg; 375 {wait_what arg; 376 arg.m_event_type = ConfigureNotify; 376 arg.m_event_type = ConfigureNotify; 377 arg.m_window = a_window; 377 arg.m_window = a_window; 378 XEvent event; 378 XEvent event; 379 ::XIfEvent(m_display,&event,wait_for,(char 379 ::XIfEvent(m_display,&event,wait_for,(char*)&arg); 380 dispatch(event);} 380 dispatch(event);} 381 } 381 } 382 382 383 struct wait_what { 383 struct wait_what { 384 int m_event_type; 384 int m_event_type; 385 Window m_window; 385 Window m_window; 386 }; 386 }; 387 static Bool wait_for(Display*,XEvent* a_even 387 static Bool wait_for(Display*,XEvent* a_event,char* a_arg){ 388 wait_what* arg = (wait_what*)a_arg; 388 wait_what* arg = (wait_what*)a_arg; 389 return (a_event->type == arg->m_event_type 389 return (a_event->type == arg->m_event_type) && 390 (a_event->xmap.window == arg->m_win 390 (a_event->xmap.window == arg->m_window); 391 } 391 } 392 */ 392 */ 393 393 394 void clear_dispatchers() { 394 void clear_dispatchers() { 395 tools_vforit_npp(dispatcher*,m_dispatchers 395 tools_vforit_npp(dispatcher*,m_dispatchers,it) { 396 dispatcher* obj = *it; 396 dispatcher* obj = *it; 397 it = m_dispatchers.erase(it); 397 it = m_dispatchers.erase(it); 398 delete obj; 398 delete obj; 399 } 399 } 400 m_dispatchers.clear(); 400 m_dispatchers.clear(); 401 } 401 } 402 402 403 protected: 403 protected: 404 std::ostream& m_out; 404 std::ostream& m_out; 405 unsigned int m_monitor; 405 unsigned int m_monitor; 406 Display* m_display; 406 Display* m_display; 407 Atom m_WM_DELETE_WINDOW_atom; 407 Atom m_WM_DELETE_WINDOW_atom; 408 Atom m_SESSION_EXIT_STEER_atom; 408 Atom m_SESSION_EXIT_STEER_atom; 409 std::vector<dispatcher*> m_dispatchers; 409 std::vector<dispatcher*> m_dispatchers; 410 }; 410 }; 411 411 412 }} 412 }} 413 413 414 414 415 #endif 415 #endif 416 416