| /* |
| * Copyright 2015 Google Inc. All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/stringprintf.h" |
| #include "cobalt/base/event_dispatcher.h" |
| #include "cobalt/deprecated/platform_delegate.h" |
| #include "cobalt/system_window/keyboard_event.h" |
| #include "cobalt/system_window/starboard/system_window.h" |
| #include "starboard/system.h" |
| |
| namespace cobalt { |
| namespace system_window { |
| |
| namespace { |
| |
| SystemWindowStarboard* g_the_window = NULL; |
| |
| // Unbound callback handler for SbWindowShowDialog. |
| void StarboardDialogCallback(SbSystemPlatformErrorResponse response) { |
| DCHECK(g_the_window); |
| g_the_window->HandleDialogClose(response); |
| } |
| |
| void UpdateVideoContainerSizeOverride(SbWindow window) { |
| SbWindowSize window_size; |
| if (!SbWindowGetSize(window, &window_size)) { |
| DLOG(WARNING) << "SbWindowGetSize() failed."; |
| return; |
| } |
| if (window_size.video_pixel_ratio == 1.0f) { |
| return; |
| } |
| |
| deprecated::PlatformDelegate::Get()->SetVideoContainerSizeOverride( |
| base::StringPrintf( |
| "%dx%d", |
| static_cast<int>(window_size.width * window_size.video_pixel_ratio), |
| static_cast<int>(window_size.height * |
| window_size.video_pixel_ratio))); |
| } |
| |
| } // namespace |
| |
| SystemWindowStarboard::SystemWindowStarboard( |
| base::EventDispatcher* event_dispatcher) |
| : SystemWindow(event_dispatcher), |
| window_(kSbWindowInvalid), |
| key_down_(false) { |
| window_ = SbWindowCreate(NULL); |
| DCHECK(SbWindowIsValid(window_)); |
| DCHECK(!g_the_window) << "TODO: Support multiple SystemWindows."; |
| UpdateVideoContainerSizeOverride(window_); |
| g_the_window = this; |
| } |
| |
| SystemWindowStarboard::SystemWindowStarboard( |
| base::EventDispatcher* event_dispatcher, const math::Size& window_size) |
| : SystemWindow(event_dispatcher), |
| window_(kSbWindowInvalid), |
| key_down_(false) { |
| SbWindowOptions options; |
| SbWindowSetDefaultOptions(&options); |
| options.size.width = window_size.width(); |
| options.size.height = window_size.height(); |
| window_ = SbWindowCreate(&options); |
| DCHECK(SbWindowIsValid(window_)); |
| DCHECK(!g_the_window) << "TODO: Support multiple SystemWindows."; |
| UpdateVideoContainerSizeOverride(window_); |
| g_the_window = this; |
| } |
| |
| SystemWindowStarboard::~SystemWindowStarboard() { |
| DCHECK_EQ(this, g_the_window); |
| |
| if (g_the_window == this) { |
| deprecated::PlatformDelegate::Get()->SetVideoContainerSizeOverride(""); |
| g_the_window = NULL; |
| } |
| SbWindowDestroy(window_); |
| } |
| |
| math::Size SystemWindowStarboard::GetWindowSize() const { |
| SbWindowSize window_size; |
| if (!SbWindowGetSize(window_, &window_size)) { |
| DLOG(WARNING) << "SbWindowGetSize() failed."; |
| return math::Size(0, 0); |
| } |
| return math::Size(window_size.width, window_size.height); |
| } |
| |
| SbWindow SystemWindowStarboard::GetSbWindow() { return window_; } |
| |
| void* SystemWindowStarboard::GetWindowHandle() { |
| return SbWindowGetPlatformHandle(window_); |
| } |
| |
| void SystemWindowStarboard::HandleInputEvent(const SbInputData& data) { |
| DCHECK_EQ(window_, data.window); |
| |
| if (data.type == kSbInputEventTypePress) { |
| // Starboard handily uses the Microsoft key mapping, which is also what |
| // Cobalt uses. |
| int key_code = static_cast<int>(data.key); |
| scoped_ptr<KeyboardEvent> keyboard_event( |
| new KeyboardEvent(KeyboardEvent::kKeyDown, key_code, data.key_modifiers, |
| key_down_ /* is_repeat */)); |
| key_down_ = true; |
| event_dispatcher()->DispatchEvent(keyboard_event.PassAs<base::Event>()); |
| } else if (data.type == kSbInputEventTypeUnpress) { |
| key_down_ = false; |
| int key_code = static_cast<int>(data.key); |
| scoped_ptr<KeyboardEvent> keyboard_event( |
| new KeyboardEvent(KeyboardEvent::kKeyUp, key_code, data.key_modifiers, |
| false /* is_repeat */)); |
| event_dispatcher()->DispatchEvent(keyboard_event.PassAs<base::Event>()); |
| } |
| } |
| |
| void OnDialogClose(SbSystemPlatformErrorResponse response, void* user_data) { |
| DCHECK(user_data); |
| SystemWindowStarboard* system_window = |
| static_cast<SystemWindowStarboard*>(user_data); |
| system_window->HandleDialogClose(response); |
| } |
| |
| void SystemWindowStarboard::ShowDialog( |
| const SystemWindow::DialogOptions& options) { |
| SbSystemPlatformErrorType error_type; |
| switch (options.message_code) { |
| case kDialogConnectionError: |
| error_type = kSbSystemPlatformErrorTypeConnectionError; |
| break; |
| case kDialogUserSignedOut: |
| error_type = kSbSystemPlatformErrorTypeUserSignedOut; |
| break; |
| case kDialogUserAgeRestricted: |
| error_type = kSbSystemPlatformErrorTypeUserAgeRestricted; |
| break; |
| default: |
| NOTREACHED(); |
| break; |
| } |
| |
| SbSystemPlatformError handle = |
| SbSystemRaisePlatformError(error_type, OnDialogClose, this); |
| if (SbSystemPlatformErrorIsValid(handle)) { |
| current_dialog_callback_ = options.callback; |
| } else { |
| DLOG(WARNING) << "Failed to notify user of error: " |
| << options.message_code; |
| } |
| } |
| |
| void SystemWindowStarboard::HandleDialogClose( |
| SbSystemPlatformErrorResponse response) { |
| DCHECK(!current_dialog_callback_.is_null()); |
| switch (response) { |
| case kSbSystemPlatformErrorResponsePositive: |
| current_dialog_callback_.Run(kDialogPositiveResponse); |
| break; |
| case kSbSystemPlatformErrorResponseNegative: |
| current_dialog_callback_.Run(kDialogNegativeResponse); |
| break; |
| case kSbSystemPlatformErrorResponseCancel: |
| current_dialog_callback_.Run(kDialogCancelResponse); |
| break; |
| default: |
| DLOG(WARNING) << "Unrecognized dialog response: " << response; |
| break; |
| } |
| } |
| |
| scoped_ptr<SystemWindow> CreateSystemWindow( |
| base::EventDispatcher* event_dispatcher, |
| const base::optional<math::Size>& window_size) { |
| if (window_size) { |
| return scoped_ptr<SystemWindow>( |
| new SystemWindowStarboard(event_dispatcher, *window_size)); |
| } else { |
| return scoped_ptr<SystemWindow>( |
| new SystemWindowStarboard(event_dispatcher)); |
| } |
| } |
| |
| // Returns true if the event was handled. |
| void HandleInputEvent(const SbEvent* event) { |
| if (event->type != kSbEventTypeInput) { |
| return; |
| } |
| |
| DCHECK(g_the_window); |
| DCHECK(event->data); |
| SbInputData* data = reinterpret_cast<SbInputData*>(event->data); |
| g_the_window->HandleInputEvent(*data); |
| return; |
| } |
| |
| } // namespace system_window |
| } // namespace cobalt |