fix up mouse stuff

This commit is contained in:
cxgeorge 2002-03-08 03:42:17 +00:00
parent 6051745d92
commit 6acf279b98
2 changed files with 99 additions and 106 deletions

View File

@ -47,9 +47,6 @@ TypeHandle wglGraphicsWindow::_type_handle;
static bool wc_registered = false; static bool wc_registered = false;
#define MOUSE_ENTERED 0
#define MOUSE_EXITED 1
#define FONT_BITMAP_OGLDISPLAYLISTNUM 1000 // an arbitrary ID # #define FONT_BITMAP_OGLDISPLAYLISTNUM 1000 // an arbitrary ID #
#define LAST_ERROR 0 #define LAST_ERROR 0
@ -333,10 +330,6 @@ void wglGraphicsWindow::config() {
_bIsLowVidMemCard = false; _bIsLowVidMemCard = false;
_active_minimized_fullscreen = false; _active_minimized_fullscreen = false;
_PandaPausedTimer = NULL; _PandaPausedTimer = NULL;
_mouse_input_enabled = false;
_mouse_motion_enabled = false;
_mouse_passive_motion_enabled = false;
_mouse_entry_enabled = false;
_context = NULL; _context = NULL;
_hdc = NULL; _hdc = NULL;
_window_inactive = false; _window_inactive = false;
@ -348,6 +341,13 @@ void wglGraphicsWindow::config() {
WNDCLASS wc; 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! // Clear before filling in window structure!
ZeroMemory(&wc, sizeof(WNDCLASS)); ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
@ -576,11 +576,6 @@ void wglGraphicsWindow::config() {
ShowWindow(_mwindow, SW_SHOWNORMAL); ShowWindow(_mwindow, SW_SHOWNORMAL);
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. // Now indicate that we have our keyboard/mouse device ready.
GraphicsWindowInputDevice device = GraphicsWindowInputDevice device =
GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); 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: // Access:
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wglGraphicsWindow::handle_mouse_entry(int state) { void wglGraphicsWindow::handle_mouse_exit(void) {
if (state == MOUSE_EXITED) { // note: 'mouse_motion' is considered the 'entry' event
if (!_input_devices.empty()) { if (!_input_devices.empty()) {
_input_devices[0].set_pointer_out_of_window(); _input_devices[0].set_pointer_out_of_window();
} }
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1369,33 +1363,6 @@ void wglGraphicsWindow::update() {
#endif #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 // Function: make_current
// Access: Public // 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 // Function: window_proc
// Access: // Access:
@ -1603,9 +1587,63 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
int x, y; int x, y;
switch (msg) { 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; 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: case WM_CLOSE:
close_window(); close_window();
@ -1842,18 +1880,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
if (button < 0) if (button < 0)
button = 2; button = 2;
SetCapture(hwnd); 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(x,LOWORD(lparam));
SET_MOUSE_COORD(y,HIWORD(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); handle_keypress(MouseButton::button(button), x, y);
break; break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
@ -1868,33 +1896,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
#if 0 #if 0
SET_MOUSE_COORD(x,LOWORD(lparam)); SET_MOUSE_COORD(x,LOWORD(lparam));
SET_MOUSE_COORD(y,HIWORD(lparam)); SET_MOUSE_COORD(y,HIWORD(lparam));
// make_current(); what does OGL have to do with mouse input??
#endif #endif
handle_keyrelease(MouseButton::button(button)); handle_keyrelease(MouseButton::button(button));
break; 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: { case WM_SETFOCUS: {
// wgldisplay_cat.info() << "got WM_SETFOCUS\n"; // wgldisplay_cat.info() << "got WM_SETFOCUS\n";
if (_mouse_entry_enabled) {
make_current(); make_current();
handle_mouse_entry(MOUSE_ENTERED);
}
POINT point; POINT point;
GetCursorPos(&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 // a key-down. it would be better to know the exact set of ModifierButtons the
// user is using, since we may miss some here // user is using, since we may miss some here
int i; for(int i=0;i<NUM_MODIFIER_KEYS;i++) {
for(i=0;i<NUM_MODIFIER_KEYS;i++) {
if (GetKeyState(hardcoded_modifier_buttons[i]) < 0) if (GetKeyState(hardcoded_modifier_buttons[i]) < 0)
handle_keypress(lookup_key(hardcoded_modifier_buttons[i]),point.x,point.y); 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: { case WM_KILLFOCUS: {
if (_mouse_entry_enabled) for(int i=0;i<NUM_MODIFIER_KEYS;i++) {
handle_mouse_entry(MOUSE_EXITED);
int i;
for(i=0;i<NUM_MODIFIER_KEYS;i++) {
if (GetKeyState(hardcoded_modifier_buttons[i]) < 0) if (GetKeyState(hardcoded_modifier_buttons[i]) < 0)
handle_keyrelease(lookup_key(hardcoded_modifier_buttons[i])); handle_keyrelease(lookup_key(hardcoded_modifier_buttons[i]));
} }

View File

@ -21,13 +21,18 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Includes // 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 #define WINDOWS_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#undef WINDOWS_LEAN_AND_MEAN #undef WINDOWS_LEAN_AND_MEAN
#include <pandabase.h>
#include <graphicsWindow.h>
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Defines // Defines
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -76,33 +81,17 @@ public:
public: public:
virtual void make_current(); virtual void make_current();
virtual void unmake_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_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_keypress(ButtonHandle key, int x, int y);
void handle_keyrelease(ButtonHandle key); void handle_keyrelease(ButtonHandle key);
protected: 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 choose_visual(void);
int find_pixfmtnum(bool bLookforHW); int find_pixfmtnum(bool bLookforHW);
virtual void config(); virtual void config();
void setup_colormap(void); 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 handle_reshape();
void process_events(); void process_events();
@ -126,11 +115,8 @@ private:
bool _active_minimized_fullscreen; bool _active_minimized_fullscreen;
bool _return_control_to_app; bool _return_control_to_app;
bool _exiting_window; bool _exiting_window;
bool _cursor_in_windowclientarea;
bool _mouse_input_enabled; bool _tracking_mouse_leaving;
bool _mouse_motion_enabled;
bool _mouse_passive_motion_enabled;
bool _mouse_entry_enabled;
bool _ime_open; bool _ime_open;
bool _ime_active; bool _ime_active;
bool _ime_composition_w; bool _ime_composition_w;
@ -143,6 +129,9 @@ private:
string _extensions_str; string _extensions_str;
typedef BOOL (WINAPI* PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT);
PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent;
public: public:
static TypeHandle get_class_type(); static TypeHandle get_class_type();
static void init_type(); static void init_type();