1204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong/*-------------------------------------------------------------------------
2204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * drawElements Quality Program Tester Core
3204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * ----------------------------------------
4204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *
5204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * Copyright (c) 2014 The Android Open Source Project
6204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * Copyright (c) 2016 The Khronos Group Inc.
7204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * Copyright (c) 2016 Mun Gwan-gyeong <elongbug@gmail.com>
8204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *
9204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * Licensed under the Apache License, Version 2.0 (the "License");
10204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * you may not use this file except in compliance with the License.
11204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * You may obtain a copy of the License at
12204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *
13204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *      http://www.apache.org/licenses/LICENSE-2.0
14204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *
15204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * Unless required by applicable law or agreed to in writing, software
16204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * distributed under the License is distributed on an "AS IS" BASIS,
17204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * See the License for the specific language governing permissions and
19204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * limitations under the License.
20204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *
21204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *//*!
22204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * \file
23204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong * \brief wayland Egl Platform.
24204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong *//*--------------------------------------------------------------------*/
25204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
26204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong#include "tcuWaylandEglPlatform.hpp"
27204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong#include "egluGLContextFactory.hpp"
28204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong#include "eglwLibrary.hpp"
29204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong#include "eglwFunctions.hpp"
30204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong#include "eglwEnums.hpp"
31204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
32204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongnamespace tcu
33204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
34204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongnamespace wayland
35204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
36204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongnamespace egl
37204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
38204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
39204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing std::string;
40204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
41204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing de::MovePtr;
42204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing de::UniquePtr;
43204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing glu::ContextFactory;
44204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::GLContextFactory;
45204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::NativeDisplay;
46204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::NativeDisplayFactory;
47204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::NativeWindow;
48204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::NativeWindowFactory;
49204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::NativePixmap;
50204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::NativePixmapFactory;
51204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing eglu::WindowParams;
52204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongusing tcu::TextureLevel;
53204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
54204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongclass Display : public NativeDisplay
55204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
56204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongpublic:
57204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	static const Capability CAPABILITIES		= Capability(CAPABILITY_GET_DISPLAY_LEGACY|
58204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong															 CAPABILITY_GET_DISPLAY_PLATFORM);
59204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
60204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong								Display				(MovePtr<wayland::Display> waylandDisplay)
61204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong									: NativeDisplay	(CAPABILITIES,
62204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong													 EGL_PLATFORM_WAYLAND_KHR,
63204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong													 "EGL_KHR_platform_wayland")
64204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong									, m_display		(waylandDisplay)
65204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong									, m_library		("libEGL.so") {}
66204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
67204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	~Display(void) {}
68204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	wayland::Display&			getWaylandDisplay	(void)	{ return *m_display; }
69204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	eglw::EGLNativeDisplayType	getLegacyNative		(void)	{ return reinterpret_cast<eglw::EGLNativeDisplayType>(m_display->getDisplay()); }
70204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	void*						getPlatformNative	(void)	{ return m_display->getDisplay(); }
71204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	const eglw::Library&		getLibrary			(void) const	{ return m_library; }
72204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	const eglw::EGLAttrib*		getPlatformAttributes	(void) const	{ return DE_NULL; }
73204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
74204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongprivate:
75204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	UniquePtr<wayland::Display>		m_display;
76204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	eglw::DefaultLibrary			m_library;
77204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong};
78204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
79204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongclass Window : public NativeWindow
80204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
81204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongpublic:
82204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	static const Capability	CAPABILITIES		= Capability(CAPABILITY_CREATE_SURFACE_LEGACY |
83204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong															 CAPABILITY_GET_SURFACE_SIZE |
84204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong															 CAPABILITY_SET_SURFACE_SIZE |
85204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong															 CAPABILITY_GET_SCREEN_SIZE);
86204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
87204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong								Window				(Display&				display,
88204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong													 const WindowParams&	params);
89204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
90204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	eglw::EGLNativeWindowType	getLegacyNative		(void) { return reinterpret_cast<eglw::EGLNativeWindowType>(m_window.getWindow()); }
91204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	IVec2						getSurfaceSize		(void) const;
92204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	void						setSurfaceSize		(IVec2 size);
93204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	IVec2						getScreenSize		(void) const { return getSurfaceSize(); }
94204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
95204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongprivate:
96204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	wayland::Window				m_window;
97204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong};
98204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
99204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongWindow::Window (Display& display, const WindowParams& params)
100204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	: NativeWindow	(CAPABILITIES)
101204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	, m_window		(display.getWaylandDisplay(), params.width, params.height)
102204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
103204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
104204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
105204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongIVec2 Window::getSurfaceSize (void) const
106204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
107204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	IVec2 ret;
108204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	m_window.getDimensions(&ret.x(), &ret.y());
109204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	return ret;
110204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
111204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
112204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongvoid Window::setSurfaceSize (IVec2 size)
113204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
114204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	m_window.setDimensions(size.x(), size.y());
115204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
116204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
117204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongclass WindowFactory : public NativeWindowFactory
118204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
119204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongpublic:
120204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong						WindowFactory		(void);
121204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
122204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	NativeWindow*		createWindow		(NativeDisplay*			nativeDisplay,
123204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong											 const WindowParams&	params) const;
124204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
125204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	NativeWindow*		createWindow		(NativeDisplay*			nativeDisplay,
126204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong											 eglw::EGLDisplay		display,
127204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong											 eglw::EGLConfig		config,
128204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong											 const eglw::EGLAttrib*	attribList,
129204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong											 const WindowParams&	params) const;
130204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong};
131204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
132204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongWindowFactory::WindowFactory (void)
133204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	: NativeWindowFactory ("window", "Wayland Window", Window::CAPABILITIES)
134204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
135204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
136204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
137204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongNativeWindow* WindowFactory::createWindow (NativeDisplay*		nativeDisplay,
138204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong										   const WindowParams&	params) const
139204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
140204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	Display&	display	= *dynamic_cast<Display*>(nativeDisplay);
141204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
142204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	return new Window(display, params);
143204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
144204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
145204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongNativeWindow* WindowFactory::createWindow (NativeDisplay*			nativeDisplay,
146204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong										   eglw::EGLDisplay			eglDisplay,
147204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong										   eglw::EGLConfig			config,
148204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong										   const eglw::EGLAttrib*	attribList,
149204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong										   const WindowParams&		params) const
150204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
151204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	DE_UNREF(eglDisplay);
152204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	DE_UNREF(config);
153204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	DE_UNREF(attribList);
154204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
155204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	Display&	display = *dynamic_cast<Display*>(nativeDisplay);
156204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
157204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	return new Window(display, params);
158204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
159204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
160204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongclass DisplayFactory : public NativeDisplayFactory
161204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
162204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongpublic:
163204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong						DisplayFactory		(EventState& eventState);
164204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
165204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	NativeDisplay*		createDisplay		(const eglw::EGLAttrib* attribList) const;
166204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
167204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongprivate:
168204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	EventState&			m_eventState;
169204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong};
170204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
171204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongDisplayFactory::DisplayFactory (EventState& eventState)
172204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	: NativeDisplayFactory	("Wayland", "Native Wayland Display",
173204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong							 Display::CAPABILITIES,
174204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong							 EGL_PLATFORM_WAYLAND_KHR,
175204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong							 "EGL_KHR_platform_wayland")
176204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	, m_eventState			(eventState)
177204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
178204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	m_nativeWindowRegistry.registerFactory(new WindowFactory());
179204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
180204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
181204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongNativeDisplay* DisplayFactory::createDisplay (const eglw::EGLAttrib* attribList) const
182204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
183204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	DE_UNREF(attribList);
184204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
185204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	MovePtr<wayland::Display>	waylandDisplay	(new wayland::Display(m_eventState, DE_NULL));
186204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
187204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	return new Display(waylandDisplay);
188204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
189204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
190204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongPlatform::Platform (EventState& eventState)
191204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
192204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	m_nativeDisplayFactoryRegistry.registerFactory(new DisplayFactory(eventState));
193204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
194204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
195204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeongMovePtr<ContextFactory> Platform::createContextFactory (void)
196204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong{
197204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong	return MovePtr<ContextFactory>(new GLContextFactory(m_nativeDisplayFactoryRegistry));
198204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong}
199204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong
200204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong} // egl
201204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong} // wayland
202204cab3e14d50366384eb129e35b8532e7c948d9Mun Gwan-gyeong} // tcu
203