added SDL event filter to track mouse position from mouse motion events
[rocksndiamonds.git] / src / events.c
index 05c4f2a019ff7ce1cbf7b3a9981a2184fe7303ab..bd82a609734afb1c06ebf95f52862a82594ab54c 100644 (file)
@@ -47,6 +47,31 @@ static void HandleNoEvent(void);
 static void HandleEventActions(void);
 
 
+// event filter to set mouse x/y position (for pointer class global animations)
+// (this is especially required to ensure smooth global animation mouse pointer
+// movement when the screen is updated without handling events; this can happen
+// when drawing door/envelope request animations, for example)
+
+int FilterMouseMotionEvents(void *userdata, Event *event)
+{
+  if (event->type != EVENT_MOTIONNOTIFY)
+    return 1;
+
+  int mouse_x = ((MotionEvent *)event)->x;
+  int mouse_y = ((MotionEvent *)event)->y;
+
+  // mouse events do not contain logical screen size corrections at this stage
+  SDLCorrectMouseEventXY(&mouse_x, &mouse_y);
+
+  mouse_x -= video.screen_xoffset;
+  mouse_y -= video.screen_yoffset;
+
+  gfx.mouse_x = mouse_x;
+  gfx.mouse_y = mouse_y;
+
+  return 1;
+}
+
 // event filter especially needed for SDL event filtering due to
 // delay problems with lots of mouse motion events when mouse button
 // not pressed (X11 can handle this with 'PointerMotionHintMask')
@@ -74,9 +99,6 @@ static int FilterEvents(const Event *event)
   {
     ((MotionEvent *)event)->x -= video.screen_xoffset;
     ((MotionEvent *)event)->y -= video.screen_yoffset;
-
-    gfx.mouse_x = ((MotionEvent *)event)->x;
-    gfx.mouse_y = ((MotionEvent *)event)->y;
   }
 
   // non-motion events are directly passed to event handler functions
@@ -218,6 +240,10 @@ static void HandleEvents(void)
        HandleKeyEvent((KeyEvent *) &event);
        break;
 
+      case EVENT_USER:
+       HandleUserEvent((UserEvent *) &event);
+       break;
+
       default:
        HandleOtherEvents(&event);
        break;
@@ -1599,6 +1625,24 @@ void HandleDropEvent(Event *event)
     SDL_free(event->drop.file);
 }
 
+void HandleUserEvent(UserEvent *event)
+{
+  switch (event->code)
+  {
+    case USEREVENT_ANIM_DELAY_ACTION:
+    case USEREVENT_ANIM_EVENT_ACTION:
+      // execute action functions until matching action was found
+      if (DoKeysymAction(event->value1) ||
+         DoGadgetAction(event->value1) ||
+         DoScreenAction(event->value1))
+       return;
+      break;
+
+    default:
+      break;
+  }
+}
+
 void HandleButton(int mx, int my, int button, int button_nr)
 {
   static int old_mx = 0, old_my = 0;
@@ -2132,9 +2176,12 @@ void HandleKey(Key key, int key_status)
     return;
   }
 
-  if (HandleGlobalAnimClicks(-1, -1, (key == KSYM_space ||
-                                     key == KSYM_Return ||
-                                     key == KSYM_Escape), TRUE))
+  // some key events are handled like clicks for global animations
+  boolean click = (key == KSYM_space ||
+                  key == KSYM_Return ||
+                  key == KSYM_Escape);
+
+  if (click && HandleGlobalAnimClicks(-1, -1, MB_LEFTBUTTON, TRUE))
   {
     // do not handle this key event anymore
     if (key != KSYM_Escape)    // always allow ESC key to be handled