xref: /aosp_15_r20/external/skia/tools/sk_app/win/main_win.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2 * Copyright 2016 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 <windows.h>
9 #include <tchar.h>
10 
11 #include "include/core/SkTypes.h"
12 #include "include/private/base/SkMalloc.h"
13 #include "tools/sk_app/Application.h"
14 #include "tools/sk_app/win/Window_win.h"
15 #include "tools/timer/Timer.h"
16 
17 using sk_app::Application;
18 
tchar_to_utf8(const TCHAR * str)19 static char* tchar_to_utf8(const TCHAR* str) {
20 #ifdef _UNICODE
21     int size = WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), nullptr, 0, nullptr, nullptr);
22     char* str8 = (char*)sk_malloc_throw(size + 1);
23     WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), str8, size, nullptr, nullptr);
24     str8[size] = '\0';
25     return str8;
26 #else
27     return _strdup(str);
28 #endif
29 }
30 
31 // This file can work with GUI or CONSOLE subsystem types since we define _tWinMain and main().
32 
33 static int main_common(HINSTANCE hInstance, int show, int argc, char**argv);
34 
_tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)35 int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
36                        int nCmdShow) {
37 
38     // convert from lpCmdLine to argc, argv.
39     char* argv[4096];
40     int argc = 0;
41     TCHAR exename[1024], *next;
42     int exenameLen = GetModuleFileName(nullptr, exename, std::size(exename));
43     // we're ignoring the possibility that the exe name exceeds the exename buffer
44     (void)exenameLen;
45     argv[argc++] = tchar_to_utf8(exename);
46     TCHAR* arg = _tcstok_s(lpCmdLine, _T(" "), &next);
47     while (arg != nullptr) {
48         argv[argc++] = tchar_to_utf8(arg);
49         arg = _tcstok_s(nullptr, _T(" "), &next);
50     }
51     int result = main_common(hInstance, nCmdShow, argc, argv);
52     for (int i = 0; i < argc; ++i) {
53         sk_free(argv[i]);
54     }
55     return result;
56 }
57 
main(int argc,char ** argv)58 int main(int argc, char**argv) {
59     return main_common(GetModuleHandle(nullptr), SW_SHOW, argc, argv);
60 }
61 
main_common(HINSTANCE hInstance,int show,int argc,char ** argv)62 static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) {
63 
64     Application* app = Application::Create(argc, argv, (void*)hInstance);
65 
66     MSG msg;
67     memset(&msg, 0, sizeof(msg));
68 
69     bool idled = false;
70 
71     // Main message loop
72     while (WM_QUIT != msg.message) {
73         if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
74             TranslateMessage(&msg);
75 
76             if (WM_PAINT == msg.message) {
77                 // Ensure that call onIdle at least once per WM_PAINT, or mouse events can
78                 // overwhelm the message processing loop, and prevent animation from running.
79                 if (!idled) {
80                     app->onIdle();
81                 }
82                 idled = false;
83             }
84             DispatchMessage(&msg);
85         } else {
86             app->onIdle();
87             idled = true;
88         }
89     }
90 
91     delete app;
92 
93     return (int)msg.wParam;
94 }
95