The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
events.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "global.hpp"
16 
17 #include "desktop/clipboard.hpp"
18 #include "cursor.hpp"
19 #include "events.hpp"
20 #include "log.hpp"
21 #include "sound.hpp"
22 #include "quit_confirmation.hpp"
23 #include "preferences.hpp"
24 #include "video.hpp"
25 #if defined _WIN32
27 #endif
28 
29 #include <SDL.h>
30 
31 #include <algorithm>
32 #include <cassert>
33 #include <deque>
34 #include <utility>
35 #include <vector>
36 #include <algorithm>
37 #include <boost/thread.hpp>
38 
39 #define ERR_GEN LOG_STREAM(err, lg::general)
40 
41 namespace events
42 {
43 
45 {
46  handlers.push_back(ptr);
47 }
48 
50 {
51  if(focused_handler == static_cast<int>(handler)) {
52  focused_handler = -1;
53  } else if(focused_handler > static_cast<int>(handler)) {
55  }
56 
57  handlers.erase(handlers.begin()+handler);
58 }
59 
61 {
62  if(handlers.empty()) {
63  return false;
64  }
65 
66  static int depth = 0;
67  ++depth;
68 
69  //the handler is most likely on the back of the events array,
70  //so look there first, otherwise do a complete search.
71  if(handlers.back() == ptr) {
73  } else {
75  if(i != handlers.end()) {
76  delete_handler_index(i - handlers.begin());
77  } else {
78  return false;
79  }
80  }
81 
82  --depth;
83 
84  if(depth == 0) {
85  cycle_focus();
86  } else {
87  focused_handler = -1;
88  }
89 
90  return true;
91 }
92 
94 {
95  int index = focused_handler+1;
96  for(size_t i = 0; i != handlers.size(); ++i) {
97  if(size_t(index) == handlers.size()) {
98  index = 0;
99  }
100 
101  if(handlers[size_t(index)]->requires_event_focus()) {
103  break;
104  }
105  }
106 
107  return focused_handler;
108 }
109 
111 {
112  const std::vector<sdl_handler*>::const_iterator i = std::find(handlers.begin(),handlers.end(),ptr);
113  if(i != handlers.end() && (**i).requires_event_focus()) {
114  focused_handler = int(i - handlers.begin());
115  }
116 }
117 
118 //this object stores all the event handlers. It is a stack of event 'contexts'.
119 //a new event context is created when e.g. a modal dialog is opened, and then
120 //closed when that dialog is closed. Each context contains a list of the handlers
121 //in that context. The current context is the one on the top of the stack
122 std::deque<context> event_contexts;
123 
124 //add a global context for event handlers. Whichever object has joined this will always
125 //receive all events, regardless of the current context.
127 
128 std::vector<pump_monitor*> pump_monitors;
129 
131  pump_monitors.push_back(this);
132 }
133 
135  pump_monitors.erase(
136  std::remove(pump_monitors.begin(), pump_monitors.end(), this),
137  pump_monitors.end());
138 }
139 
141 {
142  event_contexts.push_back(context());
143 }
144 
146 {
147  assert(event_contexts.empty() == false);
148  event_contexts.pop_back();
149 }
150 
151 sdl_handler::sdl_handler(const bool auto_join) :
152  has_joined_(false),
153  has_joined_global_(false)
154 {
155 
156  if(auto_join) {
157  assert(!event_contexts.empty());
158  event_contexts.back().add_handler(this);
159  has_joined_ = true;
160  }
161 }
162 
164 {
165  if (has_joined_)
166  leave();
167 
168  if (has_joined_global_)
169  leave_global();
170 
171 }
172 
174  join(event_contexts.back());
175 }
176 
178 {
179  if(has_joined_) {
180  leave(); // should not be in multiple event contexts
181  }
182  //join self
183  c.add_handler(this);
184  has_joined_ = true;
185 
186  //instruct members to join
188  if(!members.empty()) {
189  for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
190  (*i)->join(c);
191  }
192  }
193 }
194 
196 {
197  if(has_joined_) {
198  leave(); // should not be in multiple event contexts
199  }
200 
201  for(std::deque<context>::reverse_iterator i = event_contexts.rbegin(); i != event_contexts.rend(); ++i) {
202  std::vector<sdl_handler *> &handlers = (*i).handlers;
203  if (std::find(handlers.begin(), handlers.end(), parent) != handlers.end()) {
204  join(*i);
205  return;
206  }
207  }
208  join(global_context);
209 
210 }
211 
213 {
215  if(!members.empty()) {
216  for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
217  (*i)->leave();
218  }
219  } else {
220  assert(event_contexts.empty() == false);
221  }
222  for(std::deque<context>::reverse_iterator i = event_contexts.rbegin(); i != event_contexts.rend(); ++i) {
223  if(i->remove_handler(this)) {
224  break;
225  }
226  }
227  has_joined_ = false;
228 }
229 
231 {
232  if(has_joined_global_) {
233  leave_global(); // should not be in multiple event contexts
234  }
235  //join self
236  global_context.add_handler(this);
237  has_joined_global_ = true;
238 
239  //instruct members to join
241  if(!members.empty()) {
242  for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
243  (*i)->join_global();
244  }
245  }
246 }
247 
249 {
251  if(!members.empty()) {
252  for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
253  (*i)->leave_global();
254  }
255  }
256 
257  global_context.remove_handler(this);
258 
259  has_joined_global_ = false;
260 }
261 
262 void focus_handler(const sdl_handler* ptr)
263 {
264  if(event_contexts.empty() == false) {
265  event_contexts.back().set_focus(ptr);
266  }
267 }
268 
269 bool has_focus(const sdl_handler* hand, const SDL_Event* event)
270 {
271  if(event_contexts.empty()) {
272  return true;
273  }
274 
275  if(hand->requires_event_focus(event) == false) {
276  return true;
277  }
278 
279  const int foc_i = event_contexts.back().focused_handler;
280 
281  //if no-one has focus at the moment, this handler obviously wants
282  //focus, so give it to it.
283  if(foc_i == -1) {
284  focus_handler(hand);
285  return true;
286  }
287 
288  sdl_handler *const foc_hand = event_contexts.back().handlers[foc_i];
289  if(foc_hand == hand){
290  return true;
291  } else if(!foc_hand->requires_event_focus(event)) {
292  //if the currently focused handler doesn't need focus for this event
293  //allow the most recent interested handler to take care of it
294  int back_i = event_contexts.back().handlers.size() - 1;
295  for(int i=back_i; i>=0; --i) {
296  sdl_handler *const thief_hand = event_contexts.back().handlers[i];
297  if(i != foc_i && thief_hand->requires_event_focus(event)) {
298  //steal focus
299  focus_handler(thief_hand);
300  if(foc_i < back_i) {
301  //position the previously focused handler to allow stealing back
302  event_contexts.back().delete_handler_index(foc_i);
303  event_contexts.back().add_handler(foc_hand);
304  }
305  return thief_hand == hand;
306  }
307  }
308  }
309  return false;
310 }
311 
312 
313 const Uint32 resize_timeout = 100;
316 
317 static bool remove_on_resize(const SDL_Event &a) {
318  if (a.type == DRAW_EVENT || a.type == DRAW_ALL_EVENT) {
319  return true;
320  }
321  if (a.type == SHOW_HELPTIP_EVENT) {
322  return true;
323  }
324  if ((a.type == SDL_WINDOWEVENT) &&
325  (a.window.event == SDL_WINDOWEVENT_RESIZED ||
326  a.window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
327  a.window.event == SDL_WINDOWEVENT_EXPOSED)) {
328  return true;
329  }
330 
331  return false;
332 }
333 
334 // TODO: I'm uncertain if this is always safe to call at static init; maybe set in main() instead?
336 void pump()
337 {
338  if(boost::this_thread::get_id() != main_thread) {
339  // Can only call this on the main thread!
340  return;
341  }
342  SDL_PumpEvents();
343  peek_for_resize();
344  pump_info info;
345 
346  //used to keep track of double click events
347  static int last_mouse_down = -1;
348  static int last_click_x = -1, last_click_y = -1;
349 
350  SDL_Event temp_event;
351  int poll_count = 0;
352  int begin_ignoring = 0;
353  std::vector< SDL_Event > events;
354  while(SDL_PollEvent(&temp_event)) {
355  ++poll_count;
356  peek_for_resize();
357 
358  if(!begin_ignoring && temp_event.type == SDL_WINDOWEVENT
359  && (temp_event.window.event == SDL_WINDOWEVENT_ENTER
360  || temp_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED))
361  {
362  begin_ignoring = poll_count;
363  } else if(begin_ignoring > 0 && is_input(temp_event)) {
364  //ignore user input events that occurred after the window was activated
365  continue;
366  }
367  events.push_back(temp_event);
368  }
369 
370  std::vector<SDL_Event>::iterator ev_it = events.begin();
371  for(int i=1; i < begin_ignoring; ++i){
372  if(is_input(*ev_it)) {
373  //ignore user input events that occurred before the window was activated
374  ev_it = events.erase(ev_it);
375  } else {
376  ++ev_it;
377  }
378  }
379 
380  std::vector<SDL_Event>::iterator ev_end = events.end();
381  bool resize_found = false;
382  for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
383  SDL_Event &event = *ev_it;
384  if (event.type == SDL_WINDOWEVENT &&
385  event.window.event == SDL_WINDOWEVENT_RESIZED) {
386  resize_found = true;
387  last_resize_event = event;
388  last_resize_event_used = false;
389 
390  }
391  }
392  // remove all inputs, draw events and only keep the last of the resize events
393  // This will turn horrible after ~38 days when the Uint32 wraps.
394  if (resize_found || SDL_GetTicks() <= last_resize_event.window.timestamp + resize_timeout) {
395  events.erase(std::remove_if(events.begin(), events.end(), remove_on_resize), events.end());
396  } else if(SDL_GetTicks() > last_resize_event.window.timestamp + resize_timeout && !last_resize_event_used) {
397  events.insert(events.begin(), last_resize_event);
398  last_resize_event_used = true;
399  }
400 
401  ev_end = events.end();
402 
403  for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
404  SDL_Event &event = *ev_it;
405  switch(event.type) {
406 
407  case SDL_WINDOWEVENT:
408  switch(event.window.event) {
409  case SDL_WINDOWEVENT_ENTER:
410  case SDL_WINDOWEVENT_FOCUS_GAINED:
412  break;
413 
414  case SDL_WINDOWEVENT_LEAVE:
415  case SDL_WINDOWEVENT_FOCUS_LOST:
417  break;
418 
419  case SDL_WINDOWEVENT_RESIZED:
420  info.resize_dimensions.first = event.window.data1;
421  info.resize_dimensions.second = event.window.data2;
422  break;
423  }
424  //make sure this runs in it's own scope.
425  {
426  for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
427  const std::vector<sdl_handler*>& event_handlers = (*i).handlers;
428  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
429  event_handlers[i1]->handle_window_event(event);
430  }
431  }
432  const std::vector<sdl_handler*>& event_handlers = global_context.handlers;
433  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
434  event_handlers[i1]->handle_window_event(event);
435  }
436  }
437 
438  //This event was just distributed, don't re-distribute.
439  continue;
440 
441  case SDL_MOUSEMOTION: {
442  //always make sure a cursor is displayed if the
443  //mouse moves or if the user clicks
444  cursor::set_focus(true);
445  raise_help_string_event(event.motion.x,event.motion.y);
446  break;
447  }
448 
449  case SDL_MOUSEBUTTONDOWN: {
450  //always make sure a cursor is displayed if the
451  //mouse moves or if the user clicks
452  cursor::set_focus(true);
453  if(event.button.button == SDL_BUTTON_LEFT) {
454  static const int DoubleClickTime = 500;
455  static const int DoubleClickMaxMove = 3;
456  if(last_mouse_down >= 0 && info.ticks() - last_mouse_down < DoubleClickTime &&
457  abs(event.button.x - last_click_x) < DoubleClickMaxMove &&
458  abs(event.button.y - last_click_y) < DoubleClickMaxMove) {
459  SDL_UserEvent user_event;
460  user_event.type = DOUBLE_CLICK_EVENT;
461  user_event.code = 0;
462  user_event.data1 = reinterpret_cast<void*>(event.button.x);
463  user_event.data2 = reinterpret_cast<void*>(event.button.y);
464  ::SDL_PushEvent(reinterpret_cast<SDL_Event*>(&user_event));
465  }
466  last_mouse_down = info.ticks();
467  last_click_x = event.button.x;
468  last_click_y = event.button.y;
469  }
470  break;
471  }
472  case DRAW_ALL_EVENT:
473  {
474  /* iterate backwards as the most recent things will be at the top */
475  for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
476  const std::vector<sdl_handler*>& event_handlers = (*i).handlers;
477  for( std::vector<sdl_handler*>::const_iterator i1 = event_handlers.begin(); i1 != event_handlers.end(); ++i1) {
478  (*i1)->handle_event(event);
479  }
480  }
481  continue; //do not do further handling here
482  }
483 
484 #ifndef __APPLE__
485  case SDL_KEYDOWN: {
486  if(event.key.keysym.sym == SDLK_F4 && (event.key.keysym.mod == KMOD_RALT || event.key.keysym.mod == KMOD_LALT)) {
488  continue; // this event is already handled
489  }
490  break;
491  }
492 #endif
493 
494 #if defined(_X11) && !defined(__APPLE__)
495  case SDL_SYSWMEVENT: {
496  //clipboard support for X11
498  break;
499  }
500 #endif
501 
502 #if defined _WIN32
503  case SDL_SYSWMEVENT: {
505  break;
506  }
507 #endif
508 
509  case SDL_QUIT: {
511  continue; //this event is already handled.
512  }
513  }
514 
515  const std::vector<sdl_handler*>& event_handlers = global_context.handlers;
516  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
517  event_handlers[i1]->handle_event(event);
518  }
519 
520  if(event_contexts.empty() == false) {
521 
522  const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
523 
524  //events may cause more event handlers to be added and/or removed,
525  //so we must use indexes instead of iterators here.
526  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
527  event_handlers[i1]->handle_event(event);
528  }
529  }
530 
531  }
532 
533  //inform the pump monitors that an events::pump() has occurred
534  for(size_t i1 = 0, i2 = pump_monitors.size(); i1 != i2 && i1 < pump_monitors.size(); ++i1) {
535  pump_monitors[i1]->process(info);
536  }
537 }
538 
540 {
541  if(event_contexts.empty() == false) {
542 
543  const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
544 
545  //events may cause more event handlers to be added and/or removed,
546  //so we must use indexes instead of iterators here.
547  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
548  event_handlers[i1]->process_event();
549  }
550  }
551 }
552 
554 {
555  SDL_Event event;
556  event.window.type = SDL_WINDOWEVENT;
557  event.window.event = SDL_WINDOWEVENT_RESIZED;
558  event.window.windowID = 0; // We don't check this anyway... I think...
559  event.window.data1 = CVideo::get_singleton().getx();
560  event.window.data2 = CVideo::get_singleton().gety();
561 
562  SDL_PushEvent(&event);
563 }
564 
566 {
567  if(event_contexts.empty() == false) {
568 
569  const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
570 
571  //events may cause more event handlers to be added and/or removed,
572  //so we must use indexes instead of iterators here.
573  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
574  event_handlers[i1]->draw();
575  }
576  }
577 }
578 
580 {
581  for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
582  const std::vector<sdl_handler*>& event_handlers = (*i).handlers;
583  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
584  event_handlers[i1]->draw();
585  }
586  }
587 }
588 
590 {
591  if(event_contexts.empty() == false) {
592 
593  const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
594 
595  //events may cause more event handlers to be added and/or removed,
596  //so we must use indexes instead of iterators here.
597  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
598  event_handlers[i1]->volatile_draw();
599  }
600  }
601 }
602 
604 {
605  for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
606  const std::vector<sdl_handler*>& event_handlers = (*i).handlers;
607  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
608  event_handlers[i1]->volatile_draw();
609  }
610  }
611 }
612 
614 {
615  if(event_contexts.empty() == false) {
616 
617  const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
618 
619  //events may cause more event handlers to be added and/or removed,
620  //so we must use indexes instead of iterators here.
621  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
622  event_handlers[i1]->volatile_undraw();
623  }
624  }
625 }
626 
627 void raise_help_string_event(int mousex, int mousey)
628 {
629  if(event_contexts.empty() == false) {
630 
631  const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
632 
633  for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
634  event_handlers[i1]->process_help_string(mousex,mousey);
635  event_handlers[i1]->process_tooltip_string(mousex,mousey);
636  }
637  }
638 }
639 
640 int pump_info::ticks(unsigned *refresh_counter, unsigned refresh_rate) {
641  if(!ticks_ && !(refresh_counter && ++*refresh_counter % refresh_rate)) {
642  ticks_ = ::SDL_GetTicks();
643  }
644  return ticks_;
645 }
646 
647 
648 /* The constants for the minimum and maximum are picked from the headers. */
649 #define INPUT_MIN 0x300
650 #define INPUT_MAX 0x8FF
651 
652 bool is_input(const SDL_Event& event)
653 {
654  return event.type >= INPUT_MIN && event.type <= INPUT_MAX;
655 }
656 
658 {
659  SDL_FlushEvents(INPUT_MIN, INPUT_MAX);
660 }
661 
663 {
664  SDL_Event events[100];
665  int num = SDL_PeepEvents(events, 100, SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT);
666  for (int i = 0; i < num; ++i) {
667  if (events[i].type == SDL_WINDOWEVENT &&
668  events[i].window.event == SDL_WINDOWEVENT_RESIZED) {
670 
671  }
672  }
673 }
674 
675 
676 } //end events namespace
677 
void raise_resize_event()
Definition: events.cpp:553
void raise_volatile_undraw_event()
Definition: events.cpp:613
void discard_input()
Discards all input events.
Definition: events.cpp:657
static thandler * handler
Definition: handler.cpp:60
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glew.h:1222
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:163
bool last_resize_event_used
Definition: events.cpp:315
const GLfloat * c
Definition: glew.h:12741
bool has_joined_global_
Definition: events.hpp:96
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
logger & info()
Definition: log.cpp:91
int ticks(unsigned *refresh_counter=nullptr, unsigned refresh_rate=1)
Definition: events.cpp:640
#define DRAW_EVENT
Definition: events.hpp:26
virtual void leave_global()
Definition: events.cpp:248
int cycle_focus()
Definition: events.cpp:93
static CVideo & get_singleton()
Definition: video.hpp:75
-file util.hpp
virtual void join_same(sdl_handler *parent)
Definition: events.cpp:195
const Uint32 resize_timeout
Definition: events.cpp:313
void raise_draw_all_event()
Definition: events.cpp:579
static bool remove_on_resize(const SDL_Event &a)
Definition: events.cpp:317
void focus_handler(const sdl_handler *ptr)
Definition: events.cpp:262
GLuint id
Definition: glew.h:1647
void set_focus(bool focus)
Definition: cursor.cpp:199
int gety() const
Definition: video.cpp:481
std::vector< sdl_handler * > handlers
Definition: events.hpp:49
void raise_volatile_draw_all_event()
Definition: events.cpp:603
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
#define INPUT_MAX
Definition: events.cpp:650
void set_focus(const sdl_handler *ptr)
Definition: events.cpp:110
virtual void join()
Definition: events.cpp:173
GLuint num
Definition: glew.h:2552
void peek_for_resize()
Definition: events.cpp:662
static const boost::thread::id main_thread
Definition: events.cpp:335
int focused_handler
Definition: events.hpp:50
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void raise_draw_event()
Definition: events.cpp:565
context global_context
Definition: events.cpp:126
void pump()
Definition: events.cpp:336
void delete_handler_index(size_t handler)
Definition: events.cpp:49
#define DRAW_ALL_EVENT
Definition: events.hpp:29
virtual ~sdl_handler()
Definition: events.cpp:163
#define DOUBLE_CLICK_EVENT
Definition: events.hpp:23
void raise_process_event()
Definition: events.cpp:539
static void quit_to_desktop()
int getx() const
Definition: video.cpp:472
#define SHOW_HELPTIP_EVENT
Definition: events.hpp:28
bool is_input(const SDL_Event &event)
Is the event an input event?
Definition: events.cpp:652
void raise_help_string_event(int mousex, int mousey)
Definition: events.cpp:627
void handle_system_event(const SDL_Event &)
Definition: clipboard.cpp:57
GLuint index
Definition: glew.h:1782
virtual bool requires_event_focus(const SDL_Event *=nullptr) const
Definition: events.hpp:73
size_t i
Definition: function.cpp:1057
void raise_volatile_draw_event()
Definition: events.cpp:589
virtual std::vector< sdl_handler * > handler_members()
Definition: events.hpp:89
std::deque< context > event_contexts
Definition: events.cpp:122
Handling of system events.
Definition: manager.hpp:42
std::vector< pump_monitor * > pump_monitors
Definition: events.cpp:128
sdl_handler(const bool auto_join=true)
Definition: events.cpp:151
bool find(E event, F functor)
Tests whether an event handler is available.
cl_event event
Definition: glew.h:3070
void add_handler(sdl_handler *ptr)
Definition: events.cpp:44
bool has_focus(const sdl_handler *hand, const SDL_Event *event)
Definition: events.cpp:269
Standard logging facilities (interface).
std::pair< int, int > resize_dimensions
Definition: events.hpp:127
const std::string remove
remove directive
SDL_Event last_resize_event
Definition: events.cpp:314
void update_framebuffer()
Definition: video.cpp:375
static void handle_system_event(const SDL_Event &event)
Frees resources when a notification disappears, switches user to the wesnoth window if the notificati...
virtual void leave()
Definition: events.cpp:212
bool remove_handler(sdl_handler *ptr)
Definition: events.cpp:60
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
virtual ~pump_monitor()
Definition: events.cpp:134
virtual void join_global()
Definition: events.cpp:230
HOTKEY_COMMAND get_id(const std::string &command)
returns get_hotkey_command(command).id
#define INPUT_MIN
Definition: events.cpp:649