// Copyright (C) 2002-2003 Gideon May (gideon@computer.org) // // Permission to copy, use, sell and distribute this software is granted // provided this copyright notice appears in all copies. // Permission to modify the code and to distribute modified code is granted // provided this copyright notice appears in all copies, and a notice // that the code was modified is included with the copyright notice. // // This software is provided "as is" without express or implied warranty, // and with no claim as to its suitability for any purpose. #include #include #include #include #include #include #include #include #include #ifdef __USE_OSX_IMPLEMENTATION__ #include "missing.hpp" #undef check #endif #include #include #include "producer_ptr.hpp" using namespace boost::python; namespace { class KeyboardMouseCallback : public Producer::KeyboardMouseCallback { public: KeyboardMouseCallback(PyObject * self) : _self(self), _mouseScroll(NULL), _mouseMotion(NULL), _passiveMouseMotion(NULL), _buttonPress(NULL), _doubleButtonPress(NULL), _buttonRelease(NULL), _keyPress(NULL), _keyRelease(NULL), _specialKeyPress(NULL), _specialKeyRelease(NULL), _idle(NULL), _shutdown(NULL) { // XXX PyEval_AcquireLock(); // _tstate = Py_NewInterpreter(); // if (_tstate == NULL) { // fprintf(stderr, "Can't create interpreter\n"); // exit(1); // } Py_XINCREF(_self); if (!PyObject_HasAttrString(_self, "mouseScroll")) _mouseScroll = Py_None; if (!PyObject_HasAttrString(_self, "mouseMotion")) _mouseMotion = Py_None; if (!PyObject_HasAttrString(_self, "passiveMouseMotion")) _passiveMouseMotion = Py_None; if (!PyObject_HasAttrString(_self, "buttonPress")) _buttonPress = Py_None; if (!PyObject_HasAttrString(_self, "doubleButtonPress")) _doubleButtonPress = Py_None; if (!PyObject_HasAttrString(_self, "buttonRelease")) _buttonRelease = Py_None; if (!PyObject_HasAttrString(_self, "keyPress")) _keyPress = Py_None; if (!PyObject_HasAttrString(_self, "keyRelease")) _keyRelease = Py_None; if (!PyObject_HasAttrString(_self, "specialKeyPress")) _specialKeyPress = Py_None; if (!PyObject_HasAttrString(_self, "specialKeyRelease")) _specialKeyRelease = Py_None; if (!PyObject_HasAttrString(_self, "shutdown")) _shutdown = Py_None; if (!PyObject_HasAttrString(_self, "idle")) _idle = Py_None; // XXX PyEval_ReleaseLock(); } virtual ~KeyboardMouseCallback() { Py_XDECREF(_self); // Py_EndInterpreter(_tstate); } virtual void mouseScroll(Producer::KeyboardMouseCallback::ScrollingMotion sm) { if (_mouseScroll != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "mouseScroll", sm); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void mouseMotion(float x, float y) { if (_mouseMotion != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "mouseMotion", x, y); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void passiveMouseMotion(float x, float y) { if (_passiveMouseMotion != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "passiveMouseMotion", x, y); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void buttonPress(float x, float y, unsigned int but) { if (_buttonPress != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "buttonPress", x, y, but); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void buttonRelease(float x, float y, unsigned int but) { if (_buttonRelease != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "buttonRelease", x, y, but); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void keyPress(Producer::KeyCharacter key) { if (_keyPress != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "keyPress", key); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void keyRelease(Producer::KeyCharacter key) { if (_keyRelease != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "keyRelease", key); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void specialKeyPress(Producer::KeyCharacter key) { if (_specialKeyPress != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "specialKeyPress", key); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void specialKeyRelease(Producer::KeyCharacter key) { if (_specialKeyRelease != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "specialKeyRelease", key); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual void shutdown() { if (_shutdown != Py_None) { // XXX PyEval_AcquireLock(); try { call_method(_self, "shutdown"); } catch(...) { handle_exception(); PyErr_Print(); } // XXX PyEval_ReleaseLock(); } } virtual bool idle() { bool ret = false; if (_idle != Py_None) { // PyEval_AcquireLock(); try { ret = call_method(_self, "idle"); } catch(...) { /** handle_exception(); PyErr_Print(); **/ throw_error_already_set(); } // PyEval_ReleaseLock(); } return ret; } private : PyObject * _self; PyObject * _mouseScroll; PyObject * _mouseMotion; PyObject * _passiveMouseMotion; PyObject * _buttonPress; PyObject * _doubleButtonPress; PyObject * _buttonRelease; PyObject * _keyPress; PyObject * _keyRelease; PyObject * _specialKeyPress; PyObject * _specialKeyRelease; PyObject * _idle; PyObject * _shutdown; // PyThreadState * _tstate; }; } namespace PyProd { void init_KeyboardMouse() { class_ keyboard_mouse_callback("KeyboardMouseCallback"); { scope keyboard_mouse_callback_scope(keyboard_mouse_callback); // keyboard_mouse_callback // .def() //. ; #define ENUM_MOTION(VALUE) \ (motion.value(#VALUE, Producer::KeyboardMouseCallback::VALUE), \ keyboard_mouse_callback.def(#VALUE, object(Producer::KeyboardMouseCallback::VALUE))) enum_ motion("ScrollingMotion"); ENUM_MOTION(ScrollNone); ENUM_MOTION(ScrollUp); ENUM_MOTION(ScrollDown); } class_, bases, boost::noncopyable > keyboard_mouse("KeyboardMouse", no_init); scope keyboard_mouse_scope(keyboard_mouse); keyboard_mouse .def(init()) .def(init()) .def("update", &Producer::KeyboardMouse::update) .def("setCallback", &Producer::KeyboardMouse::setCallback) .def("positionPointer", &Producer::KeyboardMouse::positionPointer) .def("getRenderSurface", (Producer::RenderSurface * (Producer::KeyboardMouse::*)()) &Producer::KeyboardMouse::getRenderSurface, return_internal_reference<>()) .def("getInputArea", (Producer::InputArea * (Producer::KeyboardMouse::*)()) &Producer::KeyboardMouse::getInputArea, return_internal_reference<>()) .def("computePixelCoords", &Producer::KeyboardMouse::computePixelCoords) // Methods from base class OpenThreads::Thread .def("start", &Producer::KeyboardMouse::start) .def("startThread", &Producer::KeyboardMouse::startThread) ; } } #if 0 class PR_EXPORT KeyboardMouse : public Producer::Thread { public : KeyboardMouse(Producer::RenderSurface *rs) : KeyboardMouse(Producer::InputArea *inputArea) : virtual ~KeyboardMouse(); void update(KeyboardMouseCallback &, bool block=false); void setCallback( KeyboardMouseCallback *cb ); void positionPointer( float x, float y ); Producer::RenderSurface *getRenderSurface() { return _rs; } const Producer::RenderSurface *getRenderSurface() const { return _rs; } Producer::InputArea *getInputArea() { return _inputArea; } const Producer::InputArea *getInputArea() const { return _inputArea; } void setDoNormalizedMouseMotion( bool flag ); bool getDoNormalizedMouseMotion() { return _doNormalizedMouseMotion; } /** compute, from normalized mouse coords (x,y) the, for the specified * RenderSurface, the pixel coordinates (pixel_x,pixel_y). return true * if pixel_x and pixel_y have been successful computed, otherwise return * false with pixel_x and pixel_y left unchanged.*/ bool computePixelCoords(float x, float y, RenderSurface* rs, float& pixel_x, float& pixel_y); } #endif