FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
PluginEventMacCarbon.cpp
1 /**********************************************************\
2  Original Author: Anson MacKeracher
3 
4  Created: Jul 12, 2010
5  License: Dual license model; choose one of two:
6  New BSD License
7  http://www.opensource.org/licenses/bsd-license.php
8  - or -
9  GNU Lesser General Public License, version 2.1
10  http://www.gnu.org/licenses/lgpl-2.1.html
11 
12  Copyright 2010 Anson MacKeracher, Firebreath development team
13  \**********************************************************/
14 
15 #include "ConstructDefaultPluginWindows.h"
16 #include "KeyCodesCarbon.h"
17 #include "PluginEvents/MacEventCarbon.h"
18 #include "PluginEvents/GeneralEvents.h"
19 #include "PluginEvents/DrawingEvents.h"
20 #include "PluginEvents/MouseEvents.h"
21 #include "PluginEvents/KeyboardEvents.h"
22 
23 #include "PluginWindowMac.h"
24 #include "PluginEventMacCarbon.h"
25 
26 using namespace FB;
27 
28 #ifndef NP_NO_CARBON
29 
30 PluginEventMacCarbon::PluginEventMacCarbon()
31  : PluginEventMac(), m_old_h(0.0f), m_old_v(0.0f), m_mouseEntered(false)
32  , m_tisKeyLayoutData(NULL), m_deadKeyState(0)
33 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
34  , m_tisInputSource(NULL)
35 #endif
36 {
37 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
38  m_tisInputSource = TISCopyCurrentKeyboardInputSource();
39  m_tisKeyLayoutData = (CFDataRef) TISGetInputSourceProperty(m_tisInputSource, kTISPropertyUnicodeKeyLayoutData);
40 #endif
41 }
42 
43 PluginEventMacCarbon::~PluginEventMacCarbon()
44 {
45 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
46  if (m_tisInputSource) {
47  CFRelease(m_tisInputSource);
48  m_tisInputSource = NULL;
49  }
50 #endif
51 }
52 
53 Point PluginEventMacCarbon::GlobalToLocal(Point location) {
54  Point rval = { location.v, location.h };
55  PluginWindowMacPtr pluginWindow = m_PluginWindow.lock();
56  if (pluginWindow) {
57  WindowRef window = pluginWindow->getWindowRef();
58  // Convert the global mouse location to window structure location.
59  HIPoint local = {static_cast<float>(location.h), static_cast<float>(location.v)};
60  HIPointConvert(&local, kHICoordSpaceScreenPixel, NULL, kHICoordSpaceWindow, window);
61 
62  // Get the location of the structure and port in the window.
63  ::Rect structRect = {0}, portRect= {0};
64  OSStatus status = GetWindowBounds(window, kWindowStructureRgn, &structRect);
65  status = GetWindowBounds(window, kWindowGlobalPortRgn, &portRect);
66 
67 #if 0 // This used to be necessary, but doesn't seem to be needed with Firefox 3.6.18 Carbon/CoreGraphics.
68  // Convert window structure location to window port location by subtracting out the offset of the port in the structure.
69  local.x -= portRect.left - structRect.left;
70  local.y -= portRect.top - structRect.top;
71 #endif
72  // Convert window port location to plugin location.
73  FB::Rect bounds = pluginWindow->getWindowPosition();
74  rval.h = local.x - bounds.left;
75  rval.v = local.y - bounds.top;
76  }
77  return rval;
78 }
79 
80 bool PluginEventMacCarbon::isMouseOver(Point localPt) {
81  // Did mouse event happen inside the plugin's clip rect?
82  bool rval = false;
83  PluginWindowMacPtr pluginWindow = m_PluginWindow.lock();
84  if (pluginWindow) {
85  FB::Rect bounds = pluginWindow->getWindowPosition();
86  localPt.h += bounds.left;
87  localPt.v += bounds.top;
88  FB::Rect clip = pluginWindow->getWindowClipping();
89  rval = ((clip.left <= localPt.h) && (localPt.h < clip.right) && (clip.top <= localPt.v) && (localPt.v < clip.bottom));
90  }
91  return rval;
92 }
93 
94 int16_t PluginEventMacCarbon::HandleEvent(void* event)
95 {
96  EventRecord* evt = (EventRecord*) event;
97  PluginWindowMacPtr pluginWindow = m_PluginWindow.lock();
98  if (!pluginWindow)
99  return false;
100 
101  // Give the plugin a chance to handle the event itself if desired
102  MacEventCarbon macEvent(evt);
103  CarbonToNPCocoaEvent(evt, macEvent.msgCocoa);
104  if (pluginWindow->SendEvent(&macEvent)) {
105  return true;
106  }
107 
108  // Otherwise process the event into FireBreath platform-agnostic events
109  switch (evt->what) {
110  case mouseDown:
111  {
112  Point local = GlobalToLocal(evt->where);
113  MouseDownEvent ev(MouseButtonEvent::MouseButton_Left, local.h, local.v);
114  return pluginWindow->SendEvent(&ev);
115  }
116 
117  case mouseUp:
118  {
119  Point local = GlobalToLocal(evt->where);
120  MouseUpEvent ev(MouseButtonEvent::MouseButton_Left, local.h, local.v);
121  return pluginWindow->SendEvent(&ev);
122  }
123 
124  case keyDown:
125  {
126  // I don't know why, but the key codes are shifted 8 bits left,
127  // we must shift them back to their natural positions before
128  // the keymap can work properly
129  FBKeyCode fb_key = CarbonKeyCodeToFBKeyCode((evt->message & keyCodeMask) >> 8);
130  unsigned int os_key = (evt->modifiers & 0xFFFF0000) | (evt->message & (charCodeMask | keyCodeMask));
131  KeyDownEvent ev(fb_key, os_key);
132  return pluginWindow->SendEvent(&ev);
133  }
134 
135  case keyUp:
136  {
137  // I don't know why, but the key codes are shifted 8 bits left,
138  // we must shift them back to their natural positions before
139  // the keymap can work properly
140  FBKeyCode fb_key = CarbonKeyCodeToFBKeyCode((evt->message & keyCodeMask) >> 8);
141  unsigned int os_key = (evt->modifiers & 0xFFFF0000) | (evt->message & (charCodeMask | keyCodeMask));
142  KeyUpEvent ev(fb_key, os_key);
143  return pluginWindow->SendEvent(&ev);
144  }
145 
146 #if 0 // Should use NPEventType_AdjustCursorEvent below.
147  case nullEvent: // This is totally a hack
148  {
149  // Get mouse coordinates and fire an event to the plugin
150  if ((this->m_old_h != evt->where.h) || (this->m_old_v != evt->where.v)) {
151  this->m_old_h = evt->where.h;
152  this->m_old_v = evt->where.v;
153 
154  Point local = GlobalToLocal(evt->where);
155 
156  // Did mouse event happen inside the plugin's clip rect?
157  if(isMouseOver(local)) {
158  MouseMoveEvent mmEvt(local.h, local.v);
159  pluginWindow->SendEvent(&mmEvt);
160  }
161  }
162  return false;
163  }
164 #endif
165 
166  case updateEvt:
167  {
168  FB::Rect bounds = pluginWindow->getWindowPosition(), clip = pluginWindow->getWindowClipping();
169  switch(pluginWindow->getDrawingModel()) {
170  case PluginWindowMac::DrawingModelCoreGraphics: {
171  CoreGraphicsDraw ev((CGContextRef)pluginWindow->getDrawingPrimitive(), bounds, clip);
172  return pluginWindow->SendEvent(&ev);
173  } break;
174  case PluginWindowMac::DrawingModelQuickDraw: {
175  QuickDrawDraw ev((CGrafPtr) pluginWindow->getDrawingPrimitive(), bounds, clip);
176  return pluginWindow->SendEvent(&ev);
177  } break;
178  default: {
179  RefreshEvent ev;
180  return pluginWindow->SendEvent(&ev);
181  } break;
182  }
183  break;
184  }
185 
186  case NPEventType_AdjustCursorEvent:
187  {
188  Point local = GlobalToLocal(evt->where);
189  if(isMouseOver(local)) {
190  MouseMoveEvent mmEvt(local.h, local.v);
191  pluginWindow->SendEvent(&mmEvt);
192  }
193  }
194 
195  default:
196  break;
197  }
198  return false;
199 }
200 #endif
Fired for a key down event.
Carbon Mac event.
Fired when the mouse moves.
Definition: MouseEvents.h:50
Fired when a mouse up event occurs.
Definition: MouseEvents.h:105
Mac QuickDraw Draw event.
Definition: DrawingEvents.h:72
Fired for a key up event.
FBKeyCode
Values that represent different keys in a platform agnostic way.
Definition: KeyCodes.h:26
Fired when a mouse down event occurs.
Definition: MouseEvents.h:83
Fired when the plugin should repaint itself (such as on windows when WM_PAINT is received) ...
Definition: DrawingEvents.h:55
Mac CoreGraphics Draw event.
Definition: DrawingEvents.h:88