Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: plugin/mac/fullscreen_window_mac.mm

Issue 2129015: Refactored full-screen code under FullscreenWindowMac base class and... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/o3d/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « plugin/mac/fullscreen_window_mac.h ('k') | plugin/mac/main_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright 2010, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #import "fullscreen_window_mac.h"
33
34 #include <QuickTime/QuickTime.h>
35
36 #import "graphics_utils_mac.h"
37 #import "overlay_window_mac.h"
38 #import "plugin_mac.h"
39 #import "core/cross/display_mode.h"
40 #import "plugin/cross/o3d_glue.h"
41 #import "plugin/mac/graphics_utils_mac.h"
42
43 using glue::_o3d::PluginObject;
44
45 namespace o3d {
46
47 //----------------------------------------------------------------------
48 // Carbon full-screen implementation.
49 //
50
51 // Convenience function for fetching SInt32 parameters from Carbon EventRefs.
52 static SInt32 GetIntEventParam(EventRef inEvent, EventParamName inName) {
53 SInt32 value = 0;
54 return (GetEventParameter(inEvent, inName, typeSInt32, NULL, sizeof(value),
55 NULL, &value) == noErr) ? value : 0;
56 }
57
58
59 // Maps the MacOS button numbers to the constants used by our
60 // event mechanism. Not quite as obvious as you might think, as the Mac
61 // thinks the numbering should go left, right, middle and our W3C-influenced
62 // system goes left, middle, right.
63 // Defaults to left-button if passed a strange value. Pass Cocoa mouse button
64 // codes as-is (they start at 0), pass Carbon button codes - 1.
65 o3d::Event::Button MacOSMouseButtonNumberToO3DButton(int inButton) {
66
67 switch(inButton) {
68 case 0:
69 return o3d::Event::BUTTON_LEFT;
70 case 1:
71 return o3d::Event::BUTTON_RIGHT;
72 case 2:
73 return o3d::Event::BUTTON_MIDDLE;
74 case 3:
75 return o3d::Event::BUTTON_4;
76 case 4:
77 return o3d::Event::BUTTON_5;
78 }
79
80 return o3d::Event::BUTTON_LEFT;
81 }
82
83
84 // Handles the CarbonEvents that we get sent for the fullscreen mode window.
85 // Most of these can be converted to EventRecord events and handled by the
86 // HandleMacEvent() function in main_mac.mm, but some have no equivalent in
87 // that space, scroll-wheel events for example, and so must be handled here.
88 static OSStatus HandleFullscreenWindow(EventHandlerCallRef inHandlerCallRef,
89 EventRef inEvent,
90 void *inUserData) {
91 OSType event_class = GetEventClass(inEvent);
92 OSType event_kind = GetEventKind(inEvent);
93 NPP instance = (NPP)inUserData;
94 PluginObject* obj = (PluginObject*)(instance->pdata);
95 HIPoint mouse_loc = { 0.0, 0.0 };
96 bool is_scroll_event = event_class == kEventClassMouse &&
97 (event_kind == kEventMouseScroll ||
98 event_kind == kEventMouseWheelMoved);
99
100 // If it's any kind of mouse event, get the global mouse loc.
101 if (event_class == kEventClassMouse) {
102 GetEventParameter(inEvent, kEventParamMouseLocation,
103 typeHIPoint, NULL,
104 sizeof(mouse_loc), NULL,
105 &mouse_loc);
106 }
107
108 // Handle the two kinds of scroll message we understand.
109 if (is_scroll_event) {
110 SInt32 x_scroll = 0;
111 SInt32 y_scroll = 0;
112 EventMouseWheelAxis axis = kEventMouseWheelAxisY;
113
114 switch (event_kind) {
115 // The newer kind of scroll event, as sent when two-finger
116 // dragging on a touchpad.
117 case kEventMouseScroll:
118 x_scroll = GetIntEventParam(inEvent,
119 kEventParamMouseWheelSmoothHorizontalDelta);
120 y_scroll = GetIntEventParam(inEvent,
121 kEventParamMouseWheelSmoothVerticalDelta);
122
123 // only pass x or y value - pass whichever is larger
124 if (x_scroll && y_scroll) {
125 if (abs(x_scroll) > abs(y_scroll))
126 y_scroll = 0;
127 else
128 x_scroll = 0;
129 }
130 break;
131 // The older kind of scroll event, as sent when using the wheel on
132 // a third-party mouse.
133 case kEventMouseWheelMoved:
134 GetEventParameter(inEvent, kEventParamMouseWheelAxis,
135 typeMouseWheelAxis, NULL,
136 sizeof(axis), NULL,
137 &axis);
138
139 if (axis == kEventMouseWheelAxisY) {
140 y_scroll = GetIntEventParam(inEvent,
141 kEventParamMouseWheelDelta);
142 } else {
143 x_scroll = GetIntEventParam(inEvent,
144 kEventParamMouseWheelDelta);
145 }
146 break;
147 }
148
149 // Dispatch the event now that we have all the data.
150 if (x_scroll || y_scroll) {
151 o3d::Event event(o3d::Event::TYPE_WHEEL);
152 event.set_delta(x_scroll, y_scroll);
153 // Global and local locs are the same, in this case,
154 // as we have a fullscreen window at 0,0.
155 event.set_position(mouse_loc.x, mouse_loc.y,
156 mouse_loc.x, mouse_loc.y, true);
157 obj->client()->AddEventToQueue(event);
158 }
159 return noErr;
160 } else if (event_class == kEventClassMouse &&
161 (event_kind == kEventMouseDown || event_kind == kEventMouseUp)) {
162
163 o3d::Event::Type type = (event_kind == kEventMouseDown) ?
164 o3d::Event::TYPE_MOUSEDOWN :
165 o3d::Event::TYPE_MOUSEUP;
166 o3d::Event event(type);
167 event.set_position(mouse_loc.x, mouse_loc.y,
168 mouse_loc.x, mouse_loc.y, true);
169
170 EventMouseButton button = 0;
171 GetEventParameter(inEvent, kEventParamMouseButton,
172 typeMouseButton, NULL,
173 sizeof(button), NULL,
174 &button);
175 // Carbon mouse button numbers start at 1, so subtract 1 here -
176 // Cocoa mouse buttons, by contrast, start at 0).
177 event.set_button(MacOSMouseButtonNumberToO3DButton(button - 1));
178
179 // add the modifiers to the event, if any
180 UInt32 carbonMods = GetIntEventParam(inEvent,
181 kEventParamKeyModifiers);
182 if (carbonMods) {
183 int modifier_state = 0;
184 if (carbonMods & controlKey) {
185 modifier_state |= o3d::Event::MODIFIER_CTRL;
186 }
187 if (carbonMods & shiftKey) {
188 modifier_state |= o3d::Event::MODIFIER_SHIFT;
189 }
190 if (carbonMods & optionKey) {
191 modifier_state |= o3d::Event::MODIFIER_ALT;
192 }
193 if (carbonMods & cmdKey) {
194 modifier_state |= o3d::Event::MODIFIER_META;
195 }
196
197 event.set_modifier_state(modifier_state);
198 }
199
200 obj->client()->AddEventToQueue(event);
201 } else { // not a scroll event or a click
202
203 // All other events are currently handled by being converted to an
204 // old-style EventRecord as passed by the classic NPAPI interface
205 // and dispatched through our common routine.
206 EventRecord eventRecord;
207
208 if (ConvertEventRefToEventRecord(inEvent, &eventRecord)) {
209 HandleMacEvent(&eventRecord, (NPP)inUserData);
210 return noErr;
211 } else {
212 return eventNotHandledErr;
213 }
214 }
215 return noErr;
216 }
217
218
219 static WindowRef CreateFullscreenWindow(WindowRef window,
220 PluginObject *obj) {
221 Rect bounds = CGRect2Rect(CGDisplayBounds(CGMainDisplayID()));
222 OSStatus err = noErr;
223 EventTypeSpec eventTypes[] = {
224 {kEventClassKeyboard, kEventRawKeyDown},
225 {kEventClassKeyboard, kEventRawKeyRepeat},
226 {kEventClassKeyboard, kEventRawKeyUp},
227 {kEventClassMouse, kEventMouseDown},
228 {kEventClassMouse, kEventMouseUp},
229 {kEventClassMouse, kEventMouseMoved},
230 {kEventClassMouse, kEventMouseDragged},
231 {kEventClassMouse, kEventMouseScroll},
232 {kEventClassMouse, kEventMouseWheelMoved}
233 };
234
235 if (window == NULL)
236 err = CreateNewWindow(kSimpleWindowClass,
237 kWindowStandardHandlerAttribute,
238 &bounds,
239 &window);
240 if (err)
241 return NULL;
242
243 SetWindowLevel(window, CGShieldingWindowLevel() + 1);
244
245 InstallEventHandler(GetWindowEventTarget(window), HandleFullscreenWindow,
246 sizeof(eventTypes)/sizeof(eventTypes[0]), eventTypes,
247 obj->npp(), NULL);
248 ShowWindow(window);
249 return window;
250 }
251
252 class CarbonFullscreenWindowMac : public FullscreenWindowMac {
253 public:
254 CarbonFullscreenWindowMac(PluginObject* obj);
255 virtual ~CarbonFullscreenWindowMac();
256
257 virtual bool Initialize(int target_width, int target_height);
258 virtual bool Shutdown(const GLint* last_buffer_rect);
259 virtual CGRect GetWindowBounds() const;
260 virtual bool IsActive() const;
261
262 private:
263 PluginObject* obj_;
264 WindowRef fullscreen_window_;
265 Ptr fullscreen_state_;
266
267 DISALLOW_COPY_AND_ASSIGN(CarbonFullscreenWindowMac);
268 };
269
270 CarbonFullscreenWindowMac::CarbonFullscreenWindowMac(PluginObject* obj)
271 : obj_(obj),
272 fullscreen_window_(NULL),
273 fullscreen_state_(NULL) {
274 }
275
276 CarbonFullscreenWindowMac::~CarbonFullscreenWindowMac() {
277 }
278
279 bool CarbonFullscreenWindowMac::Initialize(int target_width,
280 int target_height) {
281 // check which mode we are in now
282 o3d::DisplayMode current_mode;
283 GetCurrentDisplayMode(&current_mode);
284
285 WindowRef temp_window = NULL;
286
287 // Determine if screen mode switching is actually required.
288 if (target_width != 0 &&
289 target_height != 0 &&
290 target_width != current_mode.width() &&
291 target_height != current_mode.height()) {
292 short short_target_width = target_width;
293 short short_target_height = target_height;
294 BeginFullScreen(&fullscreen_state_,
295 nil, // Value of nil selects the main screen.
296 &short_target_width,
297 &short_target_height,
298 &temp_window,
299 NULL,
300 fullScreenCaptureAllDisplays);
301 } else {
302 SetSystemUIMode(kUIModeAllSuppressed, kUIOptionAutoShowMenuBar);
303 fullscreen_state_ = NULL;
304 }
305
306 fullscreen_window_ = CreateFullscreenWindow(NULL, obj_);
307 SetWindowForAGLContext(obj_->GetMacAGLContext(), fullscreen_window_);
308 aglDisable(obj_->GetMacAGLContext(), AGL_BUFFER_RECT);
309 // This must be done after all of the above setup in order for the
310 // overlay window to appear on top.
311 FullscreenWindowMac::Initialize(target_width, target_height);
312 return true;
313 }
314
315 bool CarbonFullscreenWindowMac::Shutdown(const GLint* last_buffer_rect) {
316 FullscreenWindowMac::Shutdown(last_buffer_rect);
317 SetWindowForAGLContext(obj_->GetMacAGLContext(), obj_->GetMacWindow());
318 aglSetInteger(obj_->GetMacAGLContext(), AGL_BUFFER_RECT, last_buffer_rect);
319 aglEnable(obj_->GetMacAGLContext(), AGL_BUFFER_RECT);
320 if (fullscreen_window_) {
321 HideWindow(fullscreen_window_);
322 ReleaseWindowGroup(GetWindowGroup(fullscreen_window_));
323 DisposeWindow(fullscreen_window_);
324 fullscreen_window_ = NULL;
325 }
326 if (fullscreen_state_) {
327 EndFullScreen(fullscreen_state_, 0);
328 fullscreen_state_ = NULL;
329 } else {
330 SetSystemUIMode(kUIModeNormal, 0);
331 }
332 return true;
333 }
334
335 CGRect CarbonFullscreenWindowMac::GetWindowBounds() const {
336 Rect bounds = {0,0,0,0};
337 ::GetWindowBounds(fullscreen_window_, kWindowContentRgn, &bounds);
338 return Rect2CGRect(bounds);
339 }
340
341 bool CarbonFullscreenWindowMac::IsActive() const {
342 return fullscreen_window_ == ActiveNonFloatingWindow();
343 }
344
345 //----------------------------------------------------------------------
346 // FullscreenWindowMac implementation.
347 //
348
349 FullscreenWindowMac* FullscreenWindowMac::Create(
350 glue::_o3d::PluginObject* obj,
351 int target_width,
352 int target_height) {
353 FullscreenWindowMac* window = new CarbonFullscreenWindowMac(obj);
354 if (!window->Initialize(target_width, target_height)) {
355 delete window;
356 return NULL;
357 }
358
359 return window;
360 }
361
362 FullscreenWindowMac::~FullscreenWindowMac() {
363 }
364
365 bool FullscreenWindowMac::Initialize(int target_width, int target_height) {
366 #ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG
367 overlay_window_.reset(new OverlayWindowMac());
368 #endif
369 return true;
370 }
371
372 void FullscreenWindowMac::IdleCallback() {
373 #ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG
374 if (overlay_window_.get()) {
375 overlay_window_->IdleCallback();
376 }
377 #endif
378 }
379
380 bool FullscreenWindowMac::Shutdown(const GLint* last_buffer_rect) {
381 #ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG
382 overlay_window_.reset();
383 #endif
384 return true;
385 }
386
387 } // namespace o3d
388
OLDNEW
« no previous file with comments | « plugin/mac/fullscreen_window_mac.h ('k') | plugin/mac/main_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698