Browse Source

fix up mouse stuff

cxgeorge 24 years ago
parent
commit
6acf279b98
2 changed files with 99 additions and 106 deletions
  1. 85 81
      panda/src/wgldisplay/wglGraphicsWindow.cxx
  2. 14 25
      panda/src/wgldisplay/wglGraphicsWindow.h

+ 85 - 81
panda/src/wgldisplay/wglGraphicsWindow.cxx

@@ -47,9 +47,6 @@ TypeHandle wglGraphicsWindow::_type_handle;
 
 static bool wc_registered = false;
 
-#define MOUSE_ENTERED 0
-#define MOUSE_EXITED 1
-
 #define FONT_BITMAP_OGLDISPLAYLISTNUM 1000    // an arbitrary ID #
 
 #define LAST_ERROR 0
@@ -333,10 +330,6 @@ void wglGraphicsWindow::config() {
     _bIsLowVidMemCard = false;
     _active_minimized_fullscreen = false;
     _PandaPausedTimer = NULL;
-    _mouse_input_enabled = false;
-    _mouse_motion_enabled = false;
-    _mouse_passive_motion_enabled = false;
-    _mouse_entry_enabled = false;
     _context = NULL;
     _hdc = NULL;
     _window_inactive = false;
@@ -348,6 +341,13 @@ void wglGraphicsWindow::config() {
 
     WNDCLASS wc;
 
+    // these fns arent defined on win95, so get dynamic ptrs to them to avoid
+    // ugly DLL loader failures on w95
+    HINSTANCE hUser32 = (HINSTANCE) LoadLibrary("user32.dll");
+    assert(hUser32);
+    _pfnTrackMouseEvent = (PFN_TRACKMOUSEEVENT) GetProcAddress(hUser32, "TrackMouseEvent");
+    FreeLibrary(hUser32);
+
     // Clear before filling in window structure!
     ZeroMemory(&wc, sizeof(WNDCLASS));
     wc.style      = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
@@ -576,11 +576,6 @@ void wglGraphicsWindow::config() {
   ShowWindow(_mwindow, SW_SHOWNORMAL);
   ShowWindow(_mwindow, SW_SHOWNORMAL);
 
-  // Enable detection of mouse input
-  enable_mouse_input(true);
-  enable_mouse_motion(true);
-  enable_mouse_passive_motion(true);
-
   // Now indicate that we have our keyboard/mouse device ready.
   GraphicsWindowInputDevice device =
     GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse");
@@ -1245,16 +1240,15 @@ void wglGraphicsWindow::handle_mouse_motion(int x, int y) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: handle_mouse_entry
+//     Function: handle_mouse_exit
 //       Access:
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void wglGraphicsWindow::handle_mouse_entry(int state) {
-  if (state == MOUSE_EXITED) {
+void wglGraphicsWindow::handle_mouse_exit(void) {
+    // note: 'mouse_motion' is considered the 'entry' event
     if (!_input_devices.empty()) {
       _input_devices[0].set_pointer_out_of_window();
     }
-  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1369,33 +1363,6 @@ void wglGraphicsWindow::update() {
 #endif
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: enable_mouse_input
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-void wglGraphicsWindow::enable_mouse_input(bool val) {
-  _mouse_input_enabled = val;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: enable_mouse_motion
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-void wglGraphicsWindow::enable_mouse_motion(bool val) {
-  _mouse_motion_enabled = val;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: enable_mouse_passive_motion
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-void wglGraphicsWindow::enable_mouse_passive_motion(bool val) {
-  _mouse_passive_motion_enabled = val;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: make_current
 //       Access: Public
@@ -1592,6 +1559,23 @@ void wglGraphicsWindow::reactivate_window() {
     }
 }
 
+// Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which emulates
+// TrackMouseEvent on w95, but that requires another 500K of memory to hold that DLL,
+// which is lame just to support w95, which probably has other issues anyway
+INLINE void wglGraphicsWindow::
+track_mouse_leaving(HWND hwnd) {
+  if(_pfnTrackMouseEvent==NULL)
+      return;
+
+  TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,0};
+  BOOL bSucceeded = _pfnTrackMouseEvent(&tme);  // tell win32 to post WM_MOUSELEAVE msgs
+
+  if((!bSucceeded) && wgldisplay_cat.is_debug())
+     wgldisplay_cat.debug() << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
+
+  _tracking_mouse_leaving=true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: window_proc
 //       Access:
@@ -1603,8 +1587,62 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
   int x, y;
 
   switch (msg) {
-    case WM_CREATE:
+
+    case WM_MOUSEMOVE:
+        // Win32 doesn't return the same numbers as X does when the mouse
+        // goes beyond the upper or left side of the window
+        #define SET_MOUSE_COORD(iVal,VAL) { \
+                iVal = VAL;                   \
+                if(iVal & 0x8000)             \
+                  iVal -= 0x10000;            \
+        }
+        
+        if(!_tracking_mouse_leaving) {
+            // need to re-call TrackMouseEvent every time mouse re-enters window
+            track_mouse_leaving(hwnd);
+        }
+    
+        SET_MOUSE_COORD(x,LOWORD(lparam));
+        SET_MOUSE_COORD(y,HIWORD(lparam));
+    
+        if(wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
+            handle_mouse_motion(x, y);
+        } 
+        break;
+    
+    // if cursor is invisible, make it visible when moving in the window bars,etc
+    case WM_NCMOUSEMOVE: {
+        if(!_props._bCursorIsVisible) {
+            if(!_cursor_in_windowclientarea) {
+                ShowCursor(true);
+                _cursor_in_windowclientarea=true;
+            }
+        }
+        break;
+    }
+
+    case WM_NCMOUSELEAVE: {
+        if(!_props._bCursorIsVisible) {
+            ShowCursor(false);
+            _cursor_in_windowclientarea=false;
+        }
+        break;
+    }
+    
+    case WM_MOUSELEAVE: {
+       _tracking_mouse_leaving=false;  
+       handle_mouse_exit();
+       break;
+    }
+    
+    case WM_CREATE: {
+      track_mouse_leaving(hwnd);
+    
+      _cursor_in_windowclientarea=false;
+      if(!_props._bCursorIsVisible)
+          ShowCursor(false);
       break;
+    }
 
     case WM_CLOSE:
           close_window();
@@ -1842,18 +1880,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
       if (button < 0)
         button = 2;
       SetCapture(hwnd);
-      // Win32 doesn't return the same numbers as X does when the mouse
-      // goes beyond the upper or left side of the window
-      #define SET_MOUSE_COORD(iVal,VAL) { \
-            iVal = VAL;                   \
-            if (iVal & 0x8000)             \
-              iVal -= 0x10000;            \
-      }
-
       SET_MOUSE_COORD(x,LOWORD(lparam));
       SET_MOUSE_COORD(y,HIWORD(lparam));
-
-      // make_current();  what does OGL have to do with mouse input??
       handle_keypress(MouseButton::button(button), x, y);
       break;
     case WM_LBUTTONUP:
@@ -1868,33 +1896,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
       #if 0
           SET_MOUSE_COORD(x,LOWORD(lparam));
           SET_MOUSE_COORD(y,HIWORD(lparam));
-          // make_current();  what does OGL have to do with mouse input??
       #endif
       handle_keyrelease(MouseButton::button(button));
       break;
 
-    case WM_MOUSEMOVE:
-        SET_MOUSE_COORD(x,LOWORD(lparam));
-        SET_MOUSE_COORD(y,HIWORD(lparam));
-
-        if (mouse_motion_enabled() &&
-            (wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON))) {
-            // make_current();  what does OGL have to do with mouse input??
-            handle_mouse_motion(x, y);
-        } else if (mouse_passive_motion_enabled() &&
-                   ((wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0)) {
-                    // make_current();  what does OGL have to do with mouse input??
-                    handle_mouse_motion(x, y);
-        }
-        break;
-
     case WM_SETFOCUS: {
             // wgldisplay_cat.info() << "got WM_SETFOCUS\n";
 
-            if (_mouse_entry_enabled) {
-                make_current();
-                handle_mouse_entry(MOUSE_ENTERED);
-            }
+            make_current();
 
             POINT point;
             GetCursorPos(&point);
@@ -1905,8 +1914,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
             // a key-down. it would be better to know the exact set of ModifierButtons the
             // user is using, since we may miss some here
 
-            int i;
-            for(i=0;i<NUM_MODIFIER_KEYS;i++) {
+            for(int i=0;i<NUM_MODIFIER_KEYS;i++) {
               if (GetKeyState(hardcoded_modifier_buttons[i]) < 0)
                 handle_keypress(lookup_key(hardcoded_modifier_buttons[i]),point.x,point.y);
             }
@@ -1914,11 +1922,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
         }
 
     case WM_KILLFOCUS: {
-            if (_mouse_entry_enabled)
-              handle_mouse_entry(MOUSE_EXITED);
-
-            int i;
-            for(i=0;i<NUM_MODIFIER_KEYS;i++) {
+            for(int i=0;i<NUM_MODIFIER_KEYS;i++) {
               if (GetKeyState(hardcoded_modifier_buttons[i]) < 0)
                 handle_keyrelease(lookup_key(hardcoded_modifier_buttons[i]));
             }

+ 14 - 25
panda/src/wgldisplay/wglGraphicsWindow.h

@@ -21,13 +21,18 @@
 ////////////////////////////////////////////////////////////////////
 // Includes
 ////////////////////////////////////////////////////////////////////
-#include <pandabase.h>
 
-#include <graphicsWindow.h>
+// include win32 defns for everything up to XP, and assume I'm smart enough to
+// use GetProcAddress for backward compat on w95/w98 for newer fns
+#define _WIN32_WINNT 0x0501
+
 #define WINDOWS_LEAN_AND_MEAN
 #include <windows.h>
 #undef WINDOWS_LEAN_AND_MEAN
 
+#include <pandabase.h>
+#include <graphicsWindow.h>
+
 ////////////////////////////////////////////////////////////////////
 // Defines
 ////////////////////////////////////////////////////////////////////
@@ -76,33 +81,17 @@ public:
 public:
   virtual void make_current();
   virtual void unmake_current();
-
-  INLINE bool mouse_entry_enabled() { return _mouse_entry_enabled; }
-  INLINE bool mouse_motion_enabled() { return _mouse_motion_enabled; }
-  INLINE bool mouse_passive_motion_enabled() {
-    return _mouse_passive_motion_enabled;
-  }
-//  void handle_reshape(int w, int h);
-
   void handle_mouse_motion(int x, int y);
-  void handle_mouse_entry(int state);
+  void handle_mouse_exit(void);
+  INLINE void track_mouse_leaving(HWND hwnd);
   void handle_keypress(ButtonHandle key, int x, int y);
   void handle_keyrelease(ButtonHandle key);
 
 protected:
-//  PIXELFORMATDESCRIPTOR* try_for_visual(wglGraphicsPipe *pipe,
-//                              int mask, int want_depth_bits = 1, int want_color_bits = 1);
-//  static void get_config(PIXELFORMATDESCRIPTOR* visual, int attrib, int *value);
   int choose_visual(void);
   int find_pixfmtnum(bool bLookforHW);
   virtual void config();
   void setup_colormap(void);
-
-  void enable_mouse_input(bool val);
-  void enable_mouse_motion(bool val);
-  void enable_mouse_passive_motion(bool val);
-  void enable_mouse_entry(bool val);
-
   void handle_reshape();
   void process_events();
 
@@ -126,11 +115,8 @@ private:
   bool              _active_minimized_fullscreen;
   bool              _return_control_to_app;
   bool              _exiting_window;
-
-  bool              _mouse_input_enabled;
-  bool              _mouse_motion_enabled;
-  bool              _mouse_passive_motion_enabled;
-  bool              _mouse_entry_enabled;
+  bool              _cursor_in_windowclientarea;
+  bool              _tracking_mouse_leaving;
   bool              _ime_open;
   bool              _ime_active;
   bool              _ime_composition_w;
@@ -143,6 +129,9 @@ private:
 
   string _extensions_str;
 
+  typedef BOOL (WINAPI* PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT);
+  PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent;
+
 public:
   static TypeHandle get_class_type();
   static void init_type();