Added ability to receive windowing events in python.

Added Windows 7 multitouch support. Makepanda will detect when compiling with the Win7 SDK and turn on Win7 multitouch features.
This commit is contained in:
Walt Destler 2010-06-22 16:37:17 +00:00
parent 47649afc5b
commit b4231f8df0
11 changed files with 531 additions and 2 deletions

View File

@ -0,0 +1,44 @@
// Filename: customGraphicsWindowProc.cxx
// Created by: Walt Destler (May 2010)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "customGraphicsWindowProc.h"
CustomGraphicsWindowProc::CustomGraphicsWindowProc(PyObject* handler, PyObject* name){
_handler = handler;
_name = name;
Py_INCREF(_handler);
Py_INCREF(_name);
}
CustomGraphicsWindowProc::~CustomGraphicsWindowProc(){
Py_DECREF(_name);
Py_DECREF(_handler);
}
#if defined(__WIN32__) || defined(_WIN32)
LONG CustomGraphicsWindowProc::wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){
PyObject* ret = PyObject_CallFunction(_handler, "IIII", hwnd, msg, wparam, lparam);
Py_XDECREF(ret);
return 0;
}
#endif
PyObject* CustomGraphicsWindowProc::get_handler(){
return _handler;
}
PyObject* CustomGraphicsWindowProc::get_name(){
return _name;
}

View File

@ -0,0 +1,37 @@
// Filename: customGgraphicswindowProc.h
// Created by: Walt Destler (May 2010)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef CUSTOMGRAPHICSWINDOWPROC_H
#define CUSTOMGRAPHICSWINDOWPROC_H
#include "graphicsWindowProc.h"
class CustomGraphicsWindowProc: public GraphicsWindowProc{
public:
CustomGraphicsWindowProc(PyObject* handler, PyObject* name);
virtual ~CustomGraphicsWindowProc();
#if defined(__WIN32__) || defined(_WIN32)
virtual LONG wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
#endif
PyObject* get_handler();
PyObject* get_name();
private:
PyObject* _handler;
PyObject* _name;
};
#endif //CUSTOMGRAPHICSWINDOWPROC_H

View File

@ -2,12 +2,15 @@
#include "graphicsStateGuardian.cxx" #include "graphicsStateGuardian.cxx"
#include "graphicsThreadingModel.cxx" #include "graphicsThreadingModel.cxx"
#include "graphicsWindow.cxx" #include "graphicsWindow.cxx"
#include "graphicsWindowProc.cxx"
#include "customGraphicsWindowProc.cxx"
#include "graphicsWindowInputDevice.cxx" #include "graphicsWindowInputDevice.cxx"
#include "lru.cxx" #include "lru.cxx"
#include "nativeWindowHandle.cxx" #include "nativeWindowHandle.cxx"
#include "parasiteBuffer.cxx" #include "parasiteBuffer.cxx"
#include "standardMunger.cxx" #include "standardMunger.cxx"
#include "stencilRenderStates.cxx" #include "stencilRenderStates.cxx"
#include "touchInfo.cxx"
#include "stereoDisplayRegion.cxx" #include "stereoDisplayRegion.cxx"
#include "subprocessWindow.cxx" #include "subprocessWindow.cxx"
#ifdef IS_OSX #ifdef IS_OSX

View File

@ -77,6 +77,12 @@ GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
GraphicsWindow:: GraphicsWindow::
~GraphicsWindow() { ~GraphicsWindow() {
// Clean up custom event handlers.
CustomWinProcClasses::iterator iter;
for(iter = _custom_window_proc_classes.begin(); iter != _custom_window_proc_classes.end(); ++iter){
delete *iter;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -910,7 +916,6 @@ mouse_mode_relative() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::mouse_mode_absolute // Function: GraphicsWindow::mouse_mode_absolute
// Access: Protected, Virtual // Access: Protected, Virtual
@ -921,3 +926,86 @@ void GraphicsWindow::
mouse_mode_absolute() { mouse_mode_absolute() {
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::add_custom_event_handler
// Access: Published
// Description: Adds a custom python event handler to be called
// when a window event occurs.
//
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
add_custom_event_handler(PyObject* handler, PyObject* name){
CustomGraphicsWindowProc* cgwp = new CustomGraphicsWindowProc(handler, name);
_custom_window_proc_classes.insert(cgwp);
add_window_proc(cgwp);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::remove_custom_event_handler
// Access: Published
// Description: Removes the specified custom python event handler.
//
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
remove_custom_event_handler(PyObject* name){
//nassertv(wnd_proc != NULL);
//_window_proc_classes.erase( (GraphicsWindowProc*)wnd_proc );
list<CustomGraphicsWindowProc*> toRemove;
CustomWinProcClasses::iterator iter;
for(iter = _custom_window_proc_classes.begin(); iter != _custom_window_proc_classes.end(); ++iter){
CustomGraphicsWindowProc* cgwp = *iter;
if(PyObject_Compare(cgwp->get_name(), name) == 0)
toRemove.push_back(cgwp);
}
list<CustomGraphicsWindowProc*>::iterator iter2;
for(iter2 = toRemove.begin(); iter2 != toRemove.end(); ++iter2){
CustomGraphicsWindowProc* cgwp = *iter2;
remove_window_proc(cgwp);
_custom_window_proc_classes.erase(cgwp);
delete cgwp;
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::supports_window_procs
// Access: Published, Virtual
// Description: Returns whether this window supports adding of Windows proc handlers.
//
////////////////////////////////////////////////////////////////////
bool GraphicsWindow::supports_window_procs() const{
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::is_touch_msg
// Access: Published, Virtual
// Description: Returns whether the specified event msg is a touch message.
//
////////////////////////////////////////////////////////////////////
bool GraphicsWindow::
is_touch_msg(UINT msg){
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_num_touches
// Access: Published, Virtual
// Description: Returns the current number of touches on this window.
//
////////////////////////////////////////////////////////////////////
int GraphicsWindow::
get_num_touches(){
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_touch_info
// Access: Published, Virtual
// Description: Returns the TouchInfo object describing the specified touch.
//
////////////////////////////////////////////////////////////////////
TouchInfo GraphicsWindow::
get_touch_info(int index){
return TouchInfo();
}

View File

@ -19,6 +19,8 @@
#include "graphicsOutput.h" #include "graphicsOutput.h"
#include "graphicsWindowInputDevice.h" #include "graphicsWindowInputDevice.h"
#include "graphicsWindowProc.h"
#include "customGraphicsWindowProc.h"
#include "windowProperties.h" #include "windowProperties.h"
#include "mouseData.h" #include "mouseData.h"
#include "modifierButtons.h" #include "modifierButtons.h"
@ -29,6 +31,7 @@
#include "lightReMutex.h" #include "lightReMutex.h"
#include "pvector.h" #include "pvector.h"
#include "windowHandle.h" #include "windowHandle.h"
#include "touchInfo.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : GraphicsWindow // Class : GraphicsWindow
@ -84,6 +87,13 @@ PUBLISHED:
virtual bool move_pointer(int device, int x, int y); virtual bool move_pointer(int device, int x, int y);
virtual void close_ime(); virtual void close_ime();
void add_custom_event_handler(PyObject* handler, PyObject* name);
void remove_custom_event_handler(PyObject* name);
virtual bool is_touch_msg(UINT msg);
virtual int get_num_touches();
virtual TouchInfo get_touch_info(int index);
public: public:
// No need to publish these. // No need to publish these.
bool has_button_event(int device) const; bool has_button_event(int device) const;
@ -91,6 +101,11 @@ public:
bool has_pointer_event(int device) const; bool has_pointer_event(int device) const;
PT(PointerEventList) get_pointer_events(int device); PT(PointerEventList) get_pointer_events(int device);
virtual void add_window_proc( const GraphicsWindowProc* wnd_proc_object ){};
virtual void remove_window_proc( const GraphicsWindowProc* wnd_proc_object ){};
virtual void clear_window_procs(){};
virtual bool supports_window_procs() const;
virtual int verify_window_sizes(int numsizes, int *dimen); virtual int verify_window_sizes(int numsizes, int *dimen);
public: public:
@ -143,6 +158,9 @@ private:
WindowProperties _rejected_properties; WindowProperties _rejected_properties;
string _window_event; string _window_event;
string _close_request_event; string _close_request_event;
typedef pset<CustomGraphicsWindowProc*> CustomWinProcClasses;
CustomWinProcClasses _custom_window_proc_classes;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {

View File

@ -0,0 +1,26 @@
// Filename: graphicsWindowProc.cxx
// Created by: Bei (Mar2010)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "graphicsWindowProc.h"
TypeHandle GraphicsWindowProc::_type_handle;
GraphicsWindowProc::GraphicsWindowProc(){
}
#if defined(__WIN32__) || defined(_WIN32)
LONG GraphicsWindowProc::wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){
return 0;
}
#endif
//most an empty file.

View File

@ -0,0 +1,63 @@
// Filename: graphicswindowProc.h
// Created by: Bei Yang (Mar 2010)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef GRAPHICSWINDOWPROC_H
#define GRAPHICSWINDOWPROC_H
#include "pandabase.h"
#include "typedReferenceCount.h"
#if defined(__WIN32__) || defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
/*
Defines a little interface for storing a platform specific window
processor methods. Since this is a purely virtual class, it never
really gets instaniated so this even though this is type reference
counted, it doesn't need to registered.
*/
class EXPCL_PANDA_DISPLAY GraphicsWindowProc: public TypedReferenceCount{
public:
GraphicsWindowProc();
#if defined(__WIN32__) || defined(_WIN32)
virtual LONG wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
#endif
//purely virtual class
// In theory, this stuff below never gets used since it's purely virtual
// class that can't be instaniated anyways
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "GraphicsWindowProc",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#endif //GRAPHICSWINDOWPROC_H

View File

@ -0,0 +1,54 @@
// Filename: touchInfo.cxx
// Created by: Walt Destler (May 25, 2010)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "touchInfo.h"
TouchInfo::TouchInfo(){
_x = 0;
_y = 0;
_id = 0;
_flags = 0;
}
LONG TouchInfo::get_x(){
return _x;
}
LONG TouchInfo::get_y(){
return _y;
}
DWORD TouchInfo::get_id(){
return _id;
}
DWORD TouchInfo::get_flags(){
return _flags;
}
void TouchInfo::set_x(LONG x){
_x = x;
}
void TouchInfo::set_y(LONG y){
_y = y;
}
void TouchInfo::set_id(DWORD id){
_id = id;
}
void TouchInfo::set_flags(DWORD flags){
_flags = flags;
}

View File

@ -0,0 +1,56 @@
// Filename: touchInfo.h
// Created by: Walt Destler (May 25, 2010)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef TOUCHINFO_H
#define TOUCHINFO_H
////////////////////////////////////////////////////////////////////
// Class : TouchInfo
// Description : Stores information for a single touch event.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_DISPLAY TouchInfo {
PUBLISHED:
enum TouchInfoFlags
{
TIF_move = 0x0001,
TIF_down = 0x0002,
TIF_UP = 0x0004,
};
public:
TouchInfo();
void set_x(LONG x);
void set_y(LONG y);
void set_id(DWORD id);
void set_flags(DWORD flags);
PUBLISHED:
LONG get_x();
LONG get_y();
DWORD get_id();
DWORD get_flags();
private:
LONG _x;
LONG _y;
DWORD _id;
DWORD _flags;
};
#endif

View File

@ -31,7 +31,6 @@
TypeHandle WinGraphicsWindow::_type_handle; TypeHandle WinGraphicsWindow::_type_handle;
TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle; TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
@ -109,6 +108,9 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
_lalt_down = false; _lalt_down = false;
_ralt_down = false; _ralt_down = false;
_hparent = NULL; _hparent = NULL;
#ifdef PANDA_WIN7
_numTouches = 0;
#endif
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -470,6 +472,11 @@ open_window() {
// set us as the focus window for keyboard input // set us as the focus window for keyboard input
set_focus(); set_focus();
// Register for Win7 touch events.
#ifdef PANDA_WIN7
RegisterTouchWindow(_hWnd, 0);
#endif
return true; return true;
} }
@ -2071,6 +2078,21 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
properties.set_foreground(false); properties.set_foreground(false);
system_changed_properties(properties); system_changed_properties(properties);
break; break;
#ifdef PANDA_WIN7
case WM_TOUCH:
_numTouches = LOWORD(wparam);
if(_numTouches > MAX_TOUCHES)
_numTouches = MAX_TOUCHES;
GetTouchInputInfo((HTOUCHINPUT)lparam, _numTouches, _touches, sizeof(TOUCHINPUT));
CloseTouchInputHandle((HTOUCHINPUT)lparam);
break;
#endif
}
//do custom messages processing if any has been set
for ( WinProcClasses::iterator it=_window_proc_classes.begin() ; it != _window_proc_classes.end(); it++ ){
(*it)->wnd_proc(hwnd, msg, wparam, lparam);
} }
return DefWindowProc(hwnd, msg, wparam, lparam); return DefWindowProc(hwnd, msg, wparam, lparam);
@ -2793,3 +2815,101 @@ void get_client_rect_screen(HWND hwnd, RECT *view_rect) {
view_rect->right = lr.x; view_rect->right = lr.x;
view_rect->bottom = lr.y; view_rect->bottom = lr.y;
} }
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::add_window_proc
// Access: Public, Virtual
// Description: Adds the specified Windows proc event handler to be called
// whenever a Windows event occurs.
//
////////////////////////////////////////////////////////////////////
void WinGraphicsWindow::add_window_proc( const GraphicsWindowProc* wnd_proc ){
nassertv(wnd_proc != NULL);
_window_proc_classes.insert( (GraphicsWindowProc*)wnd_proc );
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::remove_window_proc
// Access: Public, Virtual
// Description: Removes the specified Windows proc event handler.
//
////////////////////////////////////////////////////////////////////
void WinGraphicsWindow::remove_window_proc( const GraphicsWindowProc* wnd_proc ){
nassertv(wnd_proc != NULL);
_window_proc_classes.erase( (GraphicsWindowProc*)wnd_proc );
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::clear_window_procs
// Access: Public, Virtual
// Description: Removes all Windows proc event handlers.
//
////////////////////////////////////////////////////////////////////
void WinGraphicsWindow::clear_window_procs(){
_window_proc_classes.clear();
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::supports_window_procs
// Access: Public, Virtual
// Description: Returns whether this window supports adding of windows proc handlers.
//
////////////////////////////////////////////////////////////////////
bool WinGraphicsWindow::supports_window_procs() const{
return true;
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::is_touch_msg
// Access: Public, Virtual
// Description: Returns whether the specified event msg is a touch message.
//
////////////////////////////////////////////////////////////////////
bool WinGraphicsWindow::is_touch_msg(UINT msg){
#ifdef PANDA_WIN7
return msg == WM_TOUCH;
#else
return false;
#endif
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::get_num_touches
// Access: Public, Virtual
// Description: Returns the current number of touches on this window.
//
////////////////////////////////////////////////////////////////////
int WinGraphicsWindow::
get_num_touches(){
#ifdef PANDA_WIN7
return _numTouches;
#else
return 0;
#endif
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::get_touch_info
// Access: Public, Virtual
// Description: Returns the TouchInfo object describing the specified touch.
//
////////////////////////////////////////////////////////////////////
TouchInfo WinGraphicsWindow::
get_touch_info(int index){
#ifdef PANDA_WIN7
TOUCHINPUT ti = _touches[index];
POINT point;
point.x = TOUCH_COORD_TO_PIXEL(ti.x);
point.y = TOUCH_COORD_TO_PIXEL(ti.y);
ScreenToClient(_hWnd, &point);
TouchInfo ret = TouchInfo();
ret.set_x(point.x);
ret.set_y(point.y);
ret.set_id(ti.dwID);
ret.set_flags(ti.dwFlags);
return ret;
#else
return TouchInfo();
#endif
}

View File

@ -28,6 +28,8 @@ class WinGraphicsPipe;
#define PM_INACTIVE (WM_APP+124) #define PM_INACTIVE (WM_APP+124)
#define MAX_TOUCHES 20
typedef struct { typedef struct {
int x; int x;
int y; int y;
@ -76,6 +78,14 @@ public:
INLINE HWND get_ime_hwnd(); INLINE HWND get_ime_hwnd();
virtual void add_window_proc( const GraphicsWindowProc* wnd_proc_object );
virtual void remove_window_proc( const GraphicsWindowProc* wnd_proc_object );
virtual void clear_window_procs();
virtual bool supports_window_procs() const;
virtual bool is_touch_msg(UINT msg);
virtual int get_num_touches();
virtual TouchInfo get_touch_info(int index);
protected: protected:
virtual void close_window(); virtual void close_window();
@ -178,6 +188,16 @@ private:
bool _lalt_down; bool _lalt_down;
bool _ralt_down; bool _ralt_down;
// following adds support platform specfic window processing
// functions.
typedef pset<GraphicsWindowProc*> WinProcClasses;
WinProcClasses _window_proc_classes;
#ifdef PANDA_WIN7
UINT _numTouches;
TOUCHINPUT _touches[MAX_TOUCHES];
#endif
private: private:
// We need this map to support per-window calls to window_proc(). // We need this map to support per-window calls to window_proc().
typedef map<HWND, WinGraphicsWindow *> WindowHandles; typedef map<HWND, WinGraphicsWindow *> WindowHandles;