- add sources.
[platform/framework/web/crosswalk.git] / src / win8 / metro_driver / metro_driver_win7.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "stdafx.h"
6
7 EXTERN_C IMAGE_DOS_HEADER __ImageBase;
8
9 struct Globals {
10   LPTHREAD_START_ROUTINE host_main;
11   void* host_context;
12   HWND core_window;
13   HWND host_window;
14   HANDLE host_thread;
15   DWORD main_thread_id;
16 } globals;
17
18
19 void ODS(const char* str, LONG_PTR val = 0) {
20   char buf[80];
21   size_t len = strlen(str);
22   if (len > 50) {
23     ::OutputDebugStringA("ODS: buffer too long");
24     return;
25   }
26
27   if (str[0] == '!') {
28     // Fatal error.
29     DWORD gle = ::GetLastError();
30     if (::IsDebuggerPresent())
31       __debugbreak();
32     wsprintfA(buf, "ODS:fatal %s (%p) gle=0x%x", str, val, gle);
33     ::MessageBoxA(NULL, buf, "!!!", MB_OK);
34     ::ExitProcess(gle);
35   } else {
36     // Just information.
37     wsprintfA(buf, "ODS:%s (%p)\n", str, val);
38     ::OutputDebugStringA(buf);
39   }
40 }
41
42 LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
43                          WPARAM wparam, LPARAM lparam) {
44   PAINTSTRUCT ps;
45   HDC hdc;
46   switch (message) {
47     case WM_PAINT:
48       hdc = BeginPaint(hwnd, &ps);
49       EndPaint(hwnd, &ps);
50       break;
51     case WM_DESTROY:
52       PostQuitMessage(0);
53       ODS("Metro WM_DESTROY received");
54       break;
55     default:
56       return DefWindowProc(hwnd, message, wparam, lparam);
57   }
58   return 0;
59 }
60
61 HWND CreateMetroTopLevelWindow() {
62   HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase);
63   WNDCLASSEXW wcex;
64   wcex.cbSize = sizeof(wcex);
65   wcex.style                    = CS_HREDRAW | CS_VREDRAW;
66         wcex.lpfnWndProc        = WndProc;
67         wcex.cbClsExtra         = 0;
68         wcex.cbWndExtra         = 0;
69         wcex.hInstance          = hInst;
70         wcex.hIcon              = 0;
71         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
72         wcex.hbrBackground      = (HBRUSH)(COLOR_INACTIVECAPTION+1);
73         wcex.lpszMenuName       = 0;
74         wcex.lpszClassName      = L"Windows.UI.Core.CoreWindow";
75         wcex.hIconSm            = 0;
76
77   HWND hwnd = ::CreateWindowExW(0,
78                                 MAKEINTATOM(::RegisterClassExW(&wcex)),
79                                 L"metro_metro",
80                                 WS_POPUP,
81                                 0, 0, 0, 0,
82                                 NULL, NULL, hInst, NULL);
83   return hwnd;
84 }
85
86 DWORD WINAPI HostThread(void*) {
87   // The sleeps simulates the delay we have in the actual metro code
88   // which takes in account the corewindow being created and some other
89   // unknown machinations of metro.
90   ODS("Chrome main thread", ::GetCurrentThreadId());
91   ::Sleep(30);
92   return globals.host_main(globals.host_context);
93 }
94
95 extern "C" __declspec(dllexport)
96 int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) {
97   ODS("InitMetro [Win7 emulation]");
98   HWND window = CreateMetroTopLevelWindow();
99   if (!window)
100     return 1;
101   // This magic incatation tells windows that the window is going fullscreen
102   // so the taskbar gets out of the wait automatically.
103   ::SetWindowPos(window,
104                  HWND_TOP,
105                  0,0,
106                  GetSystemMetrics(SM_CXSCREEN),
107                  GetSystemMetrics(SM_CYSCREEN),
108                  SWP_SHOWWINDOW);
109
110   // Ready to start our caller.
111   globals.core_window = window;
112   globals.host_main = thread_proc;
113   globals.host_context = context;
114   HANDLE thread = ::CreateThread(NULL, 0, &HostThread, NULL, 0, NULL);
115
116   // Main message loop.
117   MSG msg = {0};
118   while (GetMessage(&msg, NULL, 0, 0)) {
119     TranslateMessage(&msg);
120     DispatchMessage(&msg);
121   }
122
123   return (int) msg.wParam;
124 }
125
126 extern "C" _declspec(dllexport) HWND GetRootWindow() {
127   ODS("GetRootWindow", ULONG_PTR(globals.core_window));
128   return globals.core_window;
129 }
130
131 extern "C" _declspec(dllexport) void SetFrameWindow(HWND window) {
132   ODS("SetFrameWindow", ULONG_PTR(window));
133   globals.host_window = window;
134 }
135
136 extern "C" __declspec(dllexport) const wchar_t* GetInitialUrl() {
137   return L"";
138 }
139