summaryrefslogtreecommitdiffstats
path: root/win8/metro_driver/metro_driver_win7.cc
diff options
context:
space:
mode:
Diffstat (limited to 'win8/metro_driver/metro_driver_win7.cc')
-rw-r--r--win8/metro_driver/metro_driver_win7.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/win8/metro_driver/metro_driver_win7.cc b/win8/metro_driver/metro_driver_win7.cc
new file mode 100644
index 0000000..253e527
--- /dev/null
+++ b/win8/metro_driver/metro_driver_win7.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "stdafx.h"
+
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+
+struct Globals {
+ LPTHREAD_START_ROUTINE host_main;
+ void* host_context;
+ HWND core_window;
+ HWND host_window;
+ HANDLE host_thread;
+ DWORD main_thread_id;
+} globals;
+
+
+void ODS(const char* str, LONG_PTR val = 0) {
+ char buf[80];
+ size_t len = strlen(str);
+ if (len > 50) {
+ ::OutputDebugStringA("ODS: buffer too long");
+ return;
+ }
+
+ if (str[0] == '!') {
+ // Fatal error.
+ DWORD gle = ::GetLastError();
+ if (::IsDebuggerPresent())
+ __debugbreak();
+ wsprintfA(buf, "ODS:fatal %s (%p) gle=0x%x", str, val, gle);
+ ::MessageBoxA(NULL, buf, "!!!", MB_OK);
+ ::ExitProcess(gle);
+ } else {
+ // Just information.
+ wsprintfA(buf, "ODS:%s (%p)\n", str, val);
+ ::OutputDebugStringA(buf);
+ }
+}
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam) {
+ PAINTSTRUCT ps;
+ HDC hdc;
+ switch (message) {
+ case WM_PAINT:
+ hdc = BeginPaint(hwnd, &ps);
+ EndPaint(hwnd, &ps);
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ ODS("Metro WM_DESTROY received");
+ break;
+ default:
+ return DefWindowProc(hwnd, message, wparam, lparam);
+ }
+ return 0;
+}
+
+HWND CreateMetroTopLevelWindow() {
+ HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase);
+ WNDCLASSEXW wcex;
+ wcex.cbSize = sizeof(wcex);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInst;
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = L"Windows.UI.Core.CoreWindow";
+ wcex.hIconSm = 0;
+
+ HWND hwnd = ::CreateWindowExW(0,
+ MAKEINTATOM(::RegisterClassExW(&wcex)),
+ L"metro_metro",
+ WS_POPUP,
+ 0, 0, 0, 0,
+ NULL, NULL, hInst, NULL);
+ return hwnd;
+}
+
+DWORD WINAPI HostThread(void*) {
+ // The sleeps simulates the delay we have in the actual metro code
+ // which takes in account the corewindow being created and some other
+ // unknown machinations of metro.
+ ODS("Chrome main thread", ::GetCurrentThreadId());
+ ::Sleep(30);
+ return globals.host_main(globals.host_context);
+}
+
+extern "C" __declspec(dllexport)
+int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) {
+ ODS("InitMetro [Win7 emulation]");
+ HWND window = CreateMetroTopLevelWindow();
+ if (!window)
+ return 1;
+ // This magic incatation tells windows that the window is going fullscreen
+ // so the taskbar gets out of the wait automatically.
+ ::SetWindowPos(window,
+ HWND_TOP,
+ 0,0,
+ GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN),
+ SWP_SHOWWINDOW);
+
+ // Ready to start our caller.
+ globals.core_window = window;
+ globals.host_main = thread_proc;
+ globals.host_context = context;
+ HANDLE thread = ::CreateThread(NULL, 0, &HostThread, NULL, 0, NULL);
+
+ // Main message loop.
+ MSG msg = {0};
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return (int) msg.wParam;
+}
+
+extern "C" _declspec(dllexport) HWND GetRootWindow() {
+ ODS("GetRootWindow", ULONG_PTR(globals.core_window));
+ return globals.core_window;
+}
+
+extern "C" _declspec(dllexport) void SetFrameWindow(HWND window) {
+ ODS("SetFrameWindow", ULONG_PTR(window));
+ globals.host_window = window;
+}
+
+extern "C" __declspec(dllexport) const wchar_t* GetInitialUrl() {
+ return L"";
+}
+