FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
PluginEventMacCocoa.mm
1 /**********************************************************\
2 Original Author: Anson MacKeracher
3 
4 Created: Mar 26, 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 <Foundation/NSString.h>
16 
17 #include "ConstructDefaultPluginWindows.h"
18 #include "KeyCodesCocoa.h"
19 #include "PluginEvents/MacEventCocoa.h"
20 #include "PluginEvents/MouseEvents.h"
21 #include "PluginEvents/GeneralEvents.h"
22 #include "PluginEvents/DrawingEvents.h"
23 #include "PluginEvents/KeyboardEvents.h"
24 
25 #include "PluginWindowMac.h"
26 #include "PluginEventMacCocoa.h"
27 
28 #include <AppKit/AppKit.h>
29 
30 using namespace FB; using namespace std;
31 
32 PluginEventMacCocoa::PluginEventMacCocoa() :
33  m_lastModifierFlags(0)
34 {
35 }
36 
37 PluginEventMacCocoa::~PluginEventMacCocoa() {}
38 
39 inline bool isMouseEvent(NPCocoaEvent* event)
40 {
41  switch(event->type) {
42  case NPCocoaEventMouseDown:
43  case NPCocoaEventMouseUp:
44  case NPCocoaEventMouseMoved:
45  case NPCocoaEventMouseEntered:
46  case NPCocoaEventMouseExited:
47  case NPCocoaEventMouseDragged:
48  case NPCocoaEventScrollWheel:
49  return true;
50  default:
51  return false;
52  }
53 }
54 
55 inline bool isMouseButtonEvent(NPCocoaEvent* event)
56 {
57  switch(event->type) {
58  case NPCocoaEventMouseDown:
59  case NPCocoaEventMouseUp:
60  case NPCocoaEventScrollWheel:
61  return true;
62  default:
63  return false;
64  }
65 }
66 
67 int16_t PluginEventMacCocoa::HandleEvent(void* event) {
68  NPCocoaEvent* evt = (NPCocoaEvent*) event;
69  PluginWindowMacPtr window = m_PluginWindow.lock();
70  if (!window)
71  return false;
72 
73 // if(evt) {
74 // NSLog(@"Event type: %d", evt->type);
75 // }
76 
77  // Let the plugin handle the event if it wants
78  MacEventCocoa macEv(evt);
79  if(window->SendEvent(&macEv)) {
80  return true;
81  }
82 
83  unsigned modifierState = MouseButtonEvent::ModifierState_None;
84  if (isMouseEvent(evt)) {
85  if (evt->data.mouse.modifierFlags & NSShiftKeyMask)
86  modifierState |= MouseButtonEvent::ModifierState_Shift;
87  if (evt->data.mouse.modifierFlags & NSControlKeyMask)
88  modifierState |= MouseButtonEvent::ModifierState_Control;
89  if (evt->data.mouse.modifierFlags & NSAlternateKeyMask)
90  modifierState |= MouseButtonEvent::ModifierState_Alt;
91  }
92 
93  MouseButtonEvent::MouseButton btn = MouseButtonEvent::MouseButton_None;
94  if (isMouseButtonEvent(evt)) {
95  switch(evt->data.mouse.buttonNumber) {
96  case 0:
97  btn = MouseButtonEvent::MouseButton_Left;
98  break;
99  case 1:
100  btn = MouseButtonEvent::MouseButton_Right;
101  break;
102  case 2:
103  btn = MouseButtonEvent::MouseButton_Middle;
104  break;
105  }
106  }
107 
108  // Otherwise process the event into FB platform agnostic events
109  switch(evt->type) {
110  case NPCocoaEventDrawRect: {
111  if (window->getDrawingModel() == PluginWindowMac::DrawingModelCoreGraphics) {
112  FB::Rect clipRect = {
113  static_cast<int32_t>(evt->data.draw.y),
114  static_cast<int32_t>(evt->data.draw.x),
115  static_cast<int32_t>(evt->data.draw.y + evt->data.draw.height),
116  static_cast<int32_t>(evt->data.draw.x + evt->data.draw.width) };
117  FB::Rect bounds = window->getWindowPosition();
118  CoreGraphicsDraw ev(evt->data.draw.context, bounds, clipRect);
119  return window->SendEvent(&ev);
120  } else {
121  RefreshEvent ev;
122  return window->SendEvent(&ev);
123  }
124  break;
125  }
126 
127  case NPCocoaEventMouseDown: {
128  double x = evt->data.mouse.pluginX;
129  double y = evt->data.mouse.pluginY;
130  if (evt->data.mouse.clickCount == 2) {
131  MouseDoubleClickEvent ev(btn, x, y, modifierState);
132  return window->SendEvent(&ev);
133  } else {
134  MouseDownEvent ev(btn, x, y);
135  return window->SendEvent(&ev);
136  }
137  break;
138  }
139 
140  case NPCocoaEventMouseUp: {
141  double x = evt->data.mouse.pluginX;
142  double y = evt->data.mouse.pluginY;
143  MouseUpEvent ev(btn, x, y, modifierState);
144  return window->SendEvent(&ev);
145  break;
146  }
147 
148  case NPCocoaEventMouseMoved: {
149  double x = evt->data.mouse.pluginX;
150  double y = evt->data.mouse.pluginY;
151  MouseMoveEvent ev(x, y, modifierState);
152  return window->SendEvent(&ev);
153  break;
154  }
155 
156  case NPCocoaEventMouseEntered: {
157  double x = evt->data.mouse.pluginX;
158  double y = evt->data.mouse.pluginY;
159  MouseEnteredEvent ev(x, y);
160  return window->SendEvent(&ev);
161  break;
162  }
163 
164  case NPCocoaEventMouseExited: {
165  double x = evt->data.mouse.pluginX;
166  double y = evt->data.mouse.pluginY;
167  MouseExitedEvent ev(x, y);
168  return window->SendEvent(&ev);
169  break;
170  }
171 
172  case NPCocoaEventMouseDragged: {
173  double x = evt->data.mouse.pluginX;
174  double y = evt->data.mouse.pluginY;
175  MouseMoveEvent ev(x, y, modifierState);
176  return window->SendEvent(&ev);
177  break;
178  }
179 
180  case NPCocoaEventScrollWheel: {
181  double x = evt->data.mouse.pluginX;
182  double y = evt->data.mouse.pluginY;
183  MouseScrollEvent ev(x, y, evt->data.mouse.deltaX, evt->data.mouse.deltaY, modifierState);
184  return window->SendEvent(&ev);
185  break;
186  }
187 
188  case NPCocoaEventKeyDown: {
189  uint16_t key = (int)evt->data.key.keyCode;
190  NSString* str = (NSString *)evt->data.key.charactersIgnoringModifiers;
191  unsigned int character = [str characterAtIndex:0];
192  KeyDownEvent ev(CocoaKeyCodeToFBKeyCode(key), character, evt->data.key.modifierFlags);
193  bool rtn = window->SendEvent(&ev);
194  return rtn;
195  break;
196  }
197 
198  case NPCocoaEventKeyUp: {
199  uint16_t key = (int)evt->data.key.keyCode;
200  NSString* str = (NSString *)evt->data.key.charactersIgnoringModifiers;
201  unsigned int character = [str characterAtIndex:0];
202  KeyUpEvent ev(CocoaKeyCodeToFBKeyCode(key), character, evt->data.key.modifierFlags);
203  return window->SendEvent(&ev);
204  break;
205  }
206 
207  case NPCocoaEventFlagsChanged: {
208  return ProcessModifiers(evt->data.key.modifierFlags);
209  break;
210  }
211 
212  case NPCocoaEventFocusChanged: {
213  FocusChangedEvent ev(evt->data.focus.hasFocus);
214  return window->SendEvent(&ev);
215  break;
216  }
217 
218  case NPCocoaEventWindowFocusChanged: {
219  // Not handled
220  break;
221  }
222 
223  case NPCocoaEventTextInput: {
224  NSString* txt = (NSString*)evt->data.text.text;
225  TextEvent ev([txt cStringUsingEncoding:[NSString defaultCStringEncoding]]);
226  return window->SendEvent(&ev);
227  break;
228  }
229  }
230 
231  // Event was not handled by the plugin
232  return false;
233 }
234 
235 int16_t PluginEventMacCocoa::ProcessModifiers(uint32_t modifierFlags) {
236  PluginWindowMacPtr window = m_PluginWindow.lock();
237  if (!window)
238  return false;
239 
240  uint32_t lastModifiers = m_lastModifierFlags;
241  m_lastModifierFlags = modifierFlags;
242 
243  //NSLog(@"Modifiers: %u", modifierFlags);
244 
245  // Shift
246  if (modifierFlags & NSShiftKeyMask && !(lastModifiers & NSShiftKeyMask)) {
247  NSLog(@"Shift pressed!");
248  KeyDownEvent ev(FBKEY_SHIFT, NSShiftKeyMask);
249  return window->SendEvent(&ev);
250  }
251  if (!(modifierFlags & NSShiftKeyMask) && lastModifiers & NSShiftKeyMask) {
252  NSLog(@"Shift depressed!");
253  KeyUpEvent ev(FBKEY_SHIFT, NSShiftKeyMask);
254  return window->SendEvent(&ev);
255  }
256 
257  // Control
258  if (modifierFlags & NSControlKeyMask && !(lastModifiers & NSControlKeyMask)) {
259  NSLog(@"Control pressed!");
260  KeyDownEvent ev(FBKEY_CONTROL, NSControlKeyMask);
261  return window->SendEvent(&ev);
262  }
263  if (!(modifierFlags & NSControlKeyMask) && lastModifiers & NSControlKeyMask) {
264  NSLog(@"Control depressed!");
265  KeyUpEvent ev(FBKEY_CONTROL, NSControlKeyMask);
266  return window->SendEvent(&ev);
267  }
268 
269  // Option
270  if (modifierFlags & NSAlternateKeyMask && !(lastModifiers & NSAlternateKeyMask)) {
271  NSLog(@"Option pressed!");
272  KeyDownEvent ev(FBKEY_OPTION, NSAlternateKeyMask);
273  return window->SendEvent(&ev);
274  }
275  if (!(modifierFlags & NSAlternateKeyMask) && lastModifiers & NSAlternateKeyMask) {
276  NSLog(@"Option depressed!");
277  KeyUpEvent ev(FBKEY_OPTION, NSAlternateKeyMask);
278  return window->SendEvent(&ev);
279  }
280 
281  // Command
282  if (modifierFlags & NSCommandKeyMask && !(lastModifiers & NSCommandKeyMask)) {
283  NSLog(@"Command pressed!");
284  KeyDownEvent ev(FBKEY_COMMAND, NSCommandKeyMask);
285  return window->SendEvent(&ev);
286  }
287  if (!(modifierFlags & NSCommandKeyMask) && lastModifiers & NSCommandKeyMask) {
288  NSLog(@"Command depressed!");
289  KeyUpEvent ev(FBKEY_COMMAND, NSCommandKeyMask);
290  return window->SendEvent(&ev);
291  }
292 
293  return false;
294 }
Fired for a key down event.
Fired when the user moves the scrollwheel.
Definition: MouseEvents.h:116
Cocoa mac event.
Definition: MacEventCocoa.h:37
Fired when the mouse moves.
Definition: MouseEvents.h:50
Fired when a mouse up event occurs.
Definition: MouseEvents.h:105
Fired when the user moves mouse away from the plugin.
Definition: MouseEvents.h:142
Fired when the focus changes.
Fired for a key up event.
Used at least on Mac, possibly elsewhere; gives us text.
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
Fired when the user moves mouse over the plugin.
Definition: MouseEvents.h:131
Mac CoreGraphics Draw event.
Definition: DrawingEvents.h:88
Fired when a mouse double click event occurs.
Definition: MouseEvents.h:94