1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkTypes.h"
9
10 #include <tchar.h>
11
12 #include "SkApplication.h"
13 #include "SkGraphics.h"
14 #include "SkOSWindow_Win.h"
15
16 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
17
18 // Returns the main window Win32 class name.
register_class(HINSTANCE hInstance)19 static const TCHAR* register_class(HINSTANCE hInstance) {
20 WNDCLASSEX wcex;
21 // The main window class name
22 static const TCHAR gSZWindowClass[] = _T("SkiaApp");
23
24 wcex.cbSize = sizeof(WNDCLASSEX);
25
26 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
27 wcex.lpfnWndProc = WndProc;
28 wcex.cbClsExtra = 0;
29 wcex.cbWndExtra = 0;
30 wcex.hInstance = hInstance;
31 wcex.hIcon = NULL;
32 wcex.hCursor = NULL;
33 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
34 wcex.lpszMenuName = NULL;
35 wcex.lpszClassName = gSZWindowClass;
36 wcex.hIconSm = NULL;
37
38 RegisterClassEx(&wcex);
39
40 return gSZWindowClass;
41 }
42
tchar_to_utf8(const TCHAR * str)43 static char* tchar_to_utf8(const TCHAR* str) {
44 #ifdef _UNICODE
45 int size = WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), NULL, 0, NULL, NULL);
46 char* str8 = (char*) sk_malloc_throw(size+1);
47 WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), str8, size, NULL, NULL);
48 str8[size] = '\0';
49 return str8;
50 #else
51 return _strdup(str);
52 #endif
53 }
54
55 // This file can work with GUI or CONSOLE subsystem types since we define _tWinMain and main().
56
57 static int main_common(HINSTANCE hInstance, int show, int argc, char**argv);
58
_tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)59 int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
60 int nCmdShow) {
61
62 // convert from lpCmdLine to argc, argv.
63 char* argv[4096];
64 int argc = 0;
65 TCHAR exename[1024], *next;
66 int exenameLen = GetModuleFileName(NULL, exename, SK_ARRAY_COUNT(exename));
67 // we're ignoring the possibility that the exe name exceeds the exename buffer
68 (void) exenameLen;
69 argv[argc++] = tchar_to_utf8(exename);
70 TCHAR* arg = _tcstok_s(lpCmdLine, _T(" "), &next);
71 while (arg != NULL) {
72 argv[argc++] = tchar_to_utf8(arg);
73 arg = _tcstok_s(NULL, _T(" "), &next);
74 }
75 int result = main_common(hInstance, nCmdShow, argc, argv);
76 for (int i = 0; i < argc; ++i) {
77 sk_free(argv[i]);
78 }
79 return result;
80 }
81
main(int argc,char ** argv)82 int main(int argc, char**argv) {
83 SkGraphics::Init();
84 return main_common(GetModuleHandle(NULL), SW_SHOW, argc, argv);
85 }
86
main_common(HINSTANCE hInstance,int show,int argc,char ** argv)87 static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) {
88 const TCHAR* windowClass = register_class(hInstance);
89
90 application_init();
91
92 SkOSWindow::WindowInit winInit;
93 winInit.fInstance = hInstance;
94 winInit.fClass = windowClass;
95
96 create_sk_window(&winInit, argc, argv);
97 SkOSWindow::ForAllWindows([show](void* hWnd, SkOSWindow**) {
98 ShowWindow((HWND)hWnd, show);
99 UpdateWindow((HWND)hWnd); }
100 );
101
102 MSG msg;
103 // Main message loop
104 while (GetMessage(&msg, NULL, 0, 0)) {
105 if (true) {
106 TranslateMessage(&msg);
107 DispatchMessage(&msg);
108 }
109 }
110
111 application_term();
112
113 return (int) msg.wParam;
114 }
115
116 extern SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
117
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)118 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
119 switch (message) {
120 case WM_COMMAND:
121 return DefWindowProc(hWnd, message, wParam, lParam);
122 case WM_DESTROY:
123 PostQuitMessage(0);
124 break;
125 default: {
126 SkOSWindow* window = SkOSWindow::GetOSWindowForHWND(hWnd);
127 if (window && window->wndProc(hWnd, message, wParam, lParam)) {
128 return 0;
129 } else {
130 return DefWindowProc(hWnd, message, wParam, lParam);
131 }
132 }
133 }
134 return 0;
135 }
136