From 94f07118c118cd5020d5c1f4cf0fb33229e5490a Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 17 Jul 2009 21:30:51 +0000 Subject: [PATCH] subprocess mouse movement --- direct/src/plugin/p3dInstance.cxx | 118 ++++++++++----------- direct/src/plugin/p3dInstance.h | 3 +- direct/src/plugin/p3dOsxSplashWindow.cxx | 6 +- direct/src/plugin/p3dOsxSplashWindow.h | 2 +- direct/src/plugin/p3dSplashWindow.cxx | 6 +- direct/src/plugin/p3dSplashWindow.h | 2 +- direct/src/plugin/p3d_plugin.cxx | 5 +- direct/src/plugin/p3d_plugin.h | 6 +- direct/src/plugin_npapi/ppInstance.cxx | 30 +++++- direct/src/plugin_npapi/ppInstance.h | 2 +- direct/src/plugin_npapi/startup.cxx | 4 +- panda/src/display/subprocessWindow.cxx | 12 ++- panda/src/display/subprocessWindowBuffer.h | 25 +++-- 13 files changed, 125 insertions(+), 96 deletions(-) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 775b06ee8f..705f544eeb 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -74,6 +74,7 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) : _shared_mmap_size = 0; _swbuffer = NULL; _reversed_buffer = NULL; + _mouse_active = false; #endif // __APPLE__ // Set some initial properties. @@ -467,12 +468,16 @@ feed_url_stream(int unique_id, //////////////////////////////////////////////////////////////////// // Function: P3DInstance::handle_event // Access: Public -// Description: Responds to the os-generated window event. +// Description: Responds to the os-generated window event. Returns +// true if the event is handled, false if ignored. //////////////////////////////////////////////////////////////////// -void P3DInstance:: +bool P3DInstance:: handle_event(P3D_event_data event) { + bool retval = false; if (_splash_window != NULL) { - _splash_window->handle_event(event); + if (_splash_window->handle_event(event)) { + retval = true; + } } #ifdef _WIN32 @@ -481,6 +486,29 @@ handle_event(P3D_event_data event) { #elif defined(__APPLE__) EventRecord *er = event._event; + // Need to ensure we have the correct port set, in order to + // convert the mouse coordinates successfully via + // GlobalToLocal(). + GrafPtr out_port = _wparams.get_parent_window()._port; + GrafPtr portSave = NULL; + Boolean portChanged = QDSwapPort(out_port, &portSave); + + Point pt = er->where; + GlobalToLocal(&pt); + + if (portChanged) { + QDSwapPort(portSave, NULL); + } + + SubprocessWindowBuffer::Event swb_event; + swb_event._source = SubprocessWindowBuffer::ES_none; + swb_event._type = SubprocessWindowBuffer::ET_none; + swb_event._code = 0; + swb_event._flags = 0; + add_modifier_flags(swb_event._flags, er->modifiers); + + bool keep_event = false; + switch (er->what) { case nullEvent: // We appear to get this event pretty frequently when nothing else @@ -490,40 +518,21 @@ handle_event(P3D_event_data event) { if (_instance_window_opened && _swbuffer != NULL && _swbuffer->ready_for_read()) { request_refresh(); } + keep_event = true; break; case mouseDown: case mouseUp: { - // Need to ensure we have the correct port set, in order to - // convert the mouse coordinates successfully via - // GlobalToLocal(). - GrafPtr out_port = _wparams.get_parent_window()._port; - GrafPtr portSave = NULL; - Boolean portChanged = QDSwapPort(out_port, &portSave); - - Point pt = er->where; - GlobalToLocal(&pt); P3D_window_handle window = _wparams.get_parent_window(); - if (_swbuffer != NULL) { - SubprocessWindowBuffer::Event swb_event; - swb_event._source = SubprocessWindowBuffer::ES_mouse; - swb_event._code = 0; - if (er->what == mouseUp) { - swb_event._trans = SubprocessWindowBuffer::BT_up; - } else { - swb_event._trans = SubprocessWindowBuffer::BT_down; - } - swb_event._x = pt.h; - swb_event._y = pt.v; - swb_event._flags = SubprocessWindowBuffer::EF_mouse_position; - add_modifier_flags(swb_event._flags, er->modifiers); - _swbuffer->add_event(swb_event); - } - - if (portChanged) { - QDSwapPort(portSave, NULL); + swb_event._source = SubprocessWindowBuffer::ES_mouse; + if (er->what == mouseUp) { + swb_event._type = SubprocessWindowBuffer::ET_button_up; + } else { + swb_event._type = SubprocessWindowBuffer::ET_button_down; } + keep_event = true; + retval = true; } break; @@ -531,59 +540,48 @@ handle_event(P3D_event_data event) { case keyUp: case autoKey: if (_swbuffer != NULL) { - SubprocessWindowBuffer::Event swb_event; swb_event._source = SubprocessWindowBuffer::ES_keyboard; swb_event._code = er->message; if (er->what == keyUp) { - swb_event._trans = SubprocessWindowBuffer::BT_up; + swb_event._type = SubprocessWindowBuffer::ET_button_up; } else if (er->what == keyDown) { - swb_event._trans = SubprocessWindowBuffer::BT_down; + swb_event._type = SubprocessWindowBuffer::ET_button_down; } else { - swb_event._trans = SubprocessWindowBuffer::BT_again; + swb_event._type = SubprocessWindowBuffer::ET_button_again; } - swb_event._flags = 0; - add_modifier_flags(swb_event._flags, er->modifiers); - _swbuffer->add_event(swb_event); + keep_event = true; + retval = true; } break; case updateEvt: paint_window(); + retval = true; break; case activateEvt: - break; - - case diskEvt: - break; - - case osEvt: - // Not getting this event for some reason? - /* - if ((er->message & 0xf0000000) == suspendResumeMessage) { - if (er->message & 1) { - cerr << "suspend\n"; - } else { - cerr << "resume\n"; - } - } else if ((er->message & 0xf0000000) == mouseMovedMessage) { - cerr << "mouse moved\n"; - } else { - cerr << "unhandled osEvt: " << hex << er->message << dec << "\n"; - } - */ - break; - - case kHighLevelEvent: + _mouse_active = ((er->modifiers & 1) != 0); + keep_event = true; break; default: break; } + if (_mouse_active) { + swb_event._x = pt.h; + swb_event._y = pt.v; + swb_event._flags |= SubprocessWindowBuffer::EF_mouse_position | SubprocessWindowBuffer::EF_has_mouse; + } + + if (keep_event && _swbuffer != NULL) { + _swbuffer->add_event(swb_event); + } + #elif defined(HAVE_X11) #endif + return retval; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 49b89f9cba..c4c22ff4cf 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -69,7 +69,7 @@ public: const unsigned char *this_data, size_t this_data_size); - void handle_event(P3D_event_data event); + bool handle_event(P3D_event_data event); inline int get_instance_id() const; inline const string &get_session_key() const; @@ -136,6 +136,7 @@ private: string _shared_filename; SubprocessWindowBuffer *_swbuffer; char *_reversed_buffer; + bool _mouse_active; #endif // __APPLE__ P3DSplashWindow *_splash_window; diff --git a/direct/src/plugin/p3dOsxSplashWindow.cxx b/direct/src/plugin/p3dOsxSplashWindow.cxx index 26e101927a..15ba5b240a 100644 --- a/direct/src/plugin/p3dOsxSplashWindow.cxx +++ b/direct/src/plugin/p3dOsxSplashWindow.cxx @@ -149,14 +149,16 @@ set_install_progress(double install_progress) { // Function: P3DOsxSplashWindow::handle_event // Access: Public, Virtual // Description: Deals with the event callback from the OS window -// system. +// system. Returns true if the event is handled, false +// if ignored. //////////////////////////////////////////////////////////////////// -void P3DOsxSplashWindow:: +bool P3DOsxSplashWindow:: handle_event(P3D_event_data event) { EventRecord *er = event._event; if (er->what == updateEvt) { paint_window(); } + return false; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3dOsxSplashWindow.h b/direct/src/plugin/p3dOsxSplashWindow.h index 6f8a732758..66dec9d31b 100644 --- a/direct/src/plugin/p3dOsxSplashWindow.h +++ b/direct/src/plugin/p3dOsxSplashWindow.h @@ -38,7 +38,7 @@ public: virtual void set_install_label(const string &install_label); virtual void set_install_progress(double install_progress); - virtual void handle_event(P3D_event_data event); + virtual bool handle_event(P3D_event_data event); private: void paint_window(); diff --git a/direct/src/plugin/p3dSplashWindow.cxx b/direct/src/plugin/p3dSplashWindow.cxx index 3a49e23ce3..e0fcd84076 100755 --- a/direct/src/plugin/p3dSplashWindow.cxx +++ b/direct/src/plugin/p3dSplashWindow.cxx @@ -114,10 +114,12 @@ set_install_progress(double install_progress) { // Function: P3DSplashWindow::handle_event // Access: Public, Virtual // Description: Deals with the event callback from the OS window -// system. +// system. Returns true if the event is handled, false +// if ignored. //////////////////////////////////////////////////////////////////// -void P3DSplashWindow:: +bool P3DSplashWindow:: handle_event(P3D_event_data event) { + return false; } diff --git a/direct/src/plugin/p3dSplashWindow.h b/direct/src/plugin/p3dSplashWindow.h index f0aac7c9e9..2629e9bd29 100755 --- a/direct/src/plugin/p3dSplashWindow.h +++ b/direct/src/plugin/p3dSplashWindow.h @@ -47,7 +47,7 @@ public: virtual void set_install_label(const string &install_label); virtual void set_install_progress(double install_progress); - virtual void handle_event(P3D_event_data event); + virtual bool handle_event(P3D_event_data event); void setup_splash_image(); diff --git a/direct/src/plugin/p3d_plugin.cxx b/direct/src/plugin/p3d_plugin.cxx index 269a88b5f3..9e93ef3f7e 100644 --- a/direct/src/plugin/p3d_plugin.cxx +++ b/direct/src/plugin/p3d_plugin.cxx @@ -407,10 +407,11 @@ P3D_instance_feed_url_stream(P3D_instance *instance, int unique_id, return result; } -void +bool P3D_instance_handle_event(P3D_instance *instance, P3D_event_data event) { assert(P3DInstanceManager::get_global_ptr()->is_initialized()); ACQUIRE_LOCK(_api_lock); - ((P3DInstance *)instance)->handle_event(event); + bool result = ((P3DInstance *)instance)->handle_event(event); RELEASE_LOCK(_api_lock); + return result; } diff --git a/direct/src/plugin/p3d_plugin.h b/direct/src/plugin/p3d_plugin.h index fb2e184524..cac161cca0 100644 --- a/direct/src/plugin/p3d_plugin.h +++ b/direct/src/plugin/p3d_plugin.h @@ -812,8 +812,10 @@ typedef struct { plugin. This is presently used only on OSX, where the window events are needed for proper plugin handling; and possibly also on X11. On Windows, window events are handled natively by the plugin. -*/ -typedef void + + The return value is true if the handler has processed the event, + false if it has been ignored. */ +typedef bool P3D_instance_handle_event_func(P3D_instance *instance, P3D_event_data event); #ifdef P3D_FUNCTION_PROTOTYPES diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx index 06cc3d5564..1542ff746b 100644 --- a/direct/src/plugin_npapi/ppInstance.cxx +++ b/direct/src/plugin_npapi/ppInstance.cxx @@ -462,10 +462,13 @@ handle_request(P3D_request *request) { // Function: PPInstance::handle_event // Access: Public // Description: Called by the browser as new window events are -// generated. +// generated. Returns true if the event is handled, +// false if ignored. //////////////////////////////////////////////////////////////////// -void PPInstance:: +bool PPInstance:: handle_event(void *event) { + bool retval = false; + #ifndef HAS_PLUGIN_THREAD_ASYNC_CALL // If we can't ask Mozilla to call us back using // NPN_PluginThreadAsyncCall(), then we'll take advantage of the @@ -475,15 +478,32 @@ handle_event(void *event) { if (_p3d_inst == NULL) { // Ignore events that come in before we've launched the instance. - return; + return retval; } #ifdef __APPLE__ + EventRecord *er = (EventRecord *)event; + + switch (er->what) { + case NPEventType_GetFocusEvent: + case NPEventType_LoseFocusEvent: + retval = true; + break; + + case NPEventType_AdjustCursorEvent: + retval = true; + break; + } + P3D_event_data edata; - edata._event = (EventRecord *)event; - P3D_instance_handle_event(_p3d_inst, edata); + edata._event = er; + if (P3D_instance_handle_event(_p3d_inst, edata)) { + retval = true; + } #endif // __APPLE__ + + return retval; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin_npapi/ppInstance.h b/direct/src/plugin_npapi/ppInstance.h index 9898e8bd81..f1e8cb917e 100644 --- a/direct/src/plugin_npapi/ppInstance.h +++ b/direct/src/plugin_npapi/ppInstance.h @@ -52,7 +52,7 @@ public: void handle_request(P3D_request *request); - void handle_event(void *event); + bool handle_event(void *event); NPObject *get_panda_script_object(); diff --git a/direct/src/plugin_npapi/startup.cxx b/direct/src/plugin_npapi/startup.cxx index 94ab3f7453..da1aa216ff 100644 --- a/direct/src/plugin_npapi/startup.cxx +++ b/direct/src/plugin_npapi/startup.cxx @@ -334,9 +334,7 @@ NPP_HandleEvent(NPP instance, void *event) { PPInstance *inst = (PPInstance *)(instance->pdata); assert(inst != NULL); - inst->handle_event(event); - - return 0; + return inst->handle_event(event); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/subprocessWindow.cxx b/panda/src/display/subprocessWindow.cxx index ae0e2465e0..5ef077eba0 100644 --- a/panda/src/display/subprocessWindow.cxx +++ b/panda/src/display/subprocessWindow.cxx @@ -100,6 +100,8 @@ process_events() { // Deal with this event. if (swb_event._flags & SubprocessWindowBuffer::EF_mouse_position) { _input_devices[0].set_pointer_in_window(swb_event._x, swb_event._y); + } else if ((swb_event._flags & SubprocessWindowBuffer::EF_has_mouse) == 0) { + _input_devices[0].set_pointer_out_of_window(); } unsigned int diff = swb_event._flags ^ _last_event_flags; @@ -118,21 +120,21 @@ process_events() { transition_button(swb_event._flags & SubprocessWindowBuffer::EF_meta_held, KeyboardButton::meta()); } - ButtonHandle button; + ButtonHandle button = ButtonHandle::none(); if (swb_event._source == SubprocessWindowBuffer::ES_mouse) { button = MouseButton::button(swb_event._code); - } else { + } else if (swb_event._source == SubprocessWindowBuffer::ES_keyboard) { int keycode; button = translate_key(keycode, swb_event._code, swb_event._flags); - if (keycode != 0 && swb_event._trans != SubprocessWindowBuffer::BT_up) { + if (keycode != 0 && swb_event._type != SubprocessWindowBuffer::ET_button_up) { _input_devices[0].keystroke(keycode); } } - if (swb_event._trans == SubprocessWindowBuffer::BT_up) { + if (swb_event._type == SubprocessWindowBuffer::ET_button_up) { _input_devices[0].button_up(button); - } else if (swb_event._trans == SubprocessWindowBuffer::BT_down) { + } else if (swb_event._type == SubprocessWindowBuffer::ET_button_down) { _input_devices[0].button_down(button); } } diff --git a/panda/src/display/subprocessWindowBuffer.h b/panda/src/display/subprocessWindowBuffer.h index 70c14c4b6b..eaf8073a7d 100644 --- a/panda/src/display/subprocessWindowBuffer.h +++ b/panda/src/display/subprocessWindowBuffer.h @@ -76,30 +76,33 @@ public: inline void close_write_framebuffer(); enum EventSource { + ES_none, ES_mouse, ES_keyboard }; - enum ButtonTransition { - BT_down, - BT_up, - BT_again // if supported + enum EventType { + ET_none, + ET_button_down, + ET_button_up, + ET_button_again, // if supported }; enum EventFlags { - EF_mouse_position = 0x0001, - EF_shift_held = 0x0002, - EF_control_held = 0x0004, - EF_alt_held = 0x0008, - EF_meta_held = 0x0010, - EF_caps_lock = 0x0020, + EF_has_mouse = 0x0001, + EF_mouse_position = 0x0002, + EF_shift_held = 0x0004, + EF_control_held = 0x0008, + EF_alt_held = 0x0010, + EF_meta_held = 0x0020, + EF_caps_lock = 0x0040, }; class Event { public: EventSource _source; int _code; // mouse button, or os-specific keycode. - ButtonTransition _trans; + EventType _type; int _x, _y; // position of mouse at the time of the event, if EF_mouse_position is set unsigned int _flags; };