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