diff --git a/src/kernel/compsor-manager.c b/src/kernel/compsor-manager.c
new file mode 100644
index 00000000..c3d320fb
--- /dev/null
+++ b/src/kernel/compsor-manager.c
@@ -0,0 +1,245 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT NOTICE
+//
+// The following open source license statement does not apply to any
+// entity in the Exception List published by FMSoft.
+//
+// For more information, please visit:
+//
+// https://www.fmsoft.cn/exception-list
+//
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * This file is part of MiniGUI, a mature cross-platform windowing
+ * and Graphics User Interface (GUI) support system for embedded systems
+ * and smart IoT devices.
+ *
+ * Copyright (C) 2002~2020, Beijing FMSoft Technologies Co., Ltd.
+ * Copyright (C) 1998~2002, WEI Yongming
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Or,
+ *
+ * As this program is a library, any link to this program must follow
+ * GNU General Public License version 3 (GPLv3). If you cannot accept
+ * GPLv3, you need to be licensed from FMSoft.
+ *
+ * If you have got a commercial license of this program, please use it
+ * under the terms and conditions of the commercial license.
+ *
+ * For more information about the commercial license, please refer to
+ * .
+ */
+/*
+** compsor-manager.c: the compositor manager module for MiniGUI.
+**
+** Create date: 2020-01-19
+**
+** Current maintainer: Wei Yongming.
+*/
+
+#include
+#include
+#include
+#include
+
+#include "common.h"
+
+#if defined(_MGRM_PROCESSES) && defined(_MGSCHEMA_COMPOSITING)
+
+#include
+
+#include "minigui.h"
+#include "constants.h"
+
+#define MAX_NR_COMPOSITORS 8
+#define LEN_COMPOSITOR_NAME 15
+
+extern CompositorOps __mg_fallback_compositor;
+
+static struct _compositors {
+ char name [LEN_COMPOSITOR_NAME + 1];
+ const CompositorOps* ops;
+} compositors [MAX_NR_COMPOSITORS] = {
+ { "fallback", &__mg_fallback_compositor },
+};
+
+static void* dl_handle;
+
+static const CompositorOps* load_default_compositor (void)
+{
+ const char* filename = NULL;
+ char buff [LEN_SO_NAME + 1];
+ const CompositorOps* (*ex_compsor_get) (const char*, const CompositorOps*);
+ char* error;
+
+ filename = getenv ("MG_DEF_COMPOSITOR_SO");
+ if (filename == NULL) {
+ memset (buff, 0, sizeof (buff));
+ if (GetMgEtcValue ("compositing_schema", "def_compositor_so",
+ buff, LEN_SO_NAME) < 0)
+ return NULL;
+
+ filename = buff;
+ }
+
+ dl_handle = dlopen (filename, RTLD_LAZY);
+ if (!dl_handle) {
+ _WRN_PRINTF ("Failed to open specified shared library for the default compositor: %s (%s)\n",
+ filename, dlerror());
+ return NULL;
+ }
+
+ dlerror(); /* Clear any existing error */
+ ex_compsor_get = dlsym (dl_handle, "__ex_compositor_get");
+ error = dlerror ();
+ if (error) {
+ _WRN_PRINTF ("Failed to get symbol: %s\n", error);
+ dlclose (dl_handle);
+ return NULL;
+ }
+
+ return ex_compsor_get (COMPSOR_NAME_DEFAULT, &__mg_fallback_compositor);
+}
+
+BOOL mg_InitCompositor (void)
+{
+ const char* name = COMPSOR_NAME_FALLBACK;
+ const CompositorOps* ops;
+ CompositorCtxt* ctxt = NULL;
+
+ ops = load_default_compositor ();
+ if (ops && ServerRegisterCompositor (COMPSOR_NAME_DEFAULT, ops)) {
+ name = COMPSOR_NAME_DEFAULT;
+ }
+
+ ServerSelectCompositor (name, &ctxt);
+ return (ctxt != NULL);
+}
+
+void mg_TerminateCompositor (void)
+{
+ CompositorCtxt* ctxt = NULL;
+
+ // Select fallback compositor and terminate the fallback compositor.
+ ServerSelectCompositor (COMPSOR_NAME_FALLBACK, &ctxt);
+ if (ctxt) {
+ __mg_fallback_compositor.terminate (ctxt);
+ }
+
+ if (dl_handle)
+ dlclose (dl_handle);
+}
+
+const CompositorOps* GUIAPI ServerGetCompositorOps (const char* name)
+{
+ int i;
+
+ if (name == NULL || name[0] == 0)
+ return NULL;
+
+ for (i = 0; i < MAX_NR_COMPOSITORS; i++) {
+ if (strcmp (compositors [i].name, name) == 0) {
+ return compositors [i].ops;
+ }
+ }
+
+ return NULL;
+}
+
+BOOL GUIAPI ServerRegisterCompositor (
+ const char* name, const CompositorOps* ops)
+{
+ int i;
+
+ if (name == NULL || name[0] == 0 || ops == NULL)
+ return FALSE;
+
+ for (i = 0; i < MAX_NR_COMPOSITORS; i++) {
+ if (compositors [i].name[0] == 0) {
+ strncpy (compositors [i].name, name, LEN_COMPOSITOR_NAME);
+ compositors [i].ops = ops;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL GUIAPI ServerUnregisterCompositor (const char* name)
+{
+ int i;
+ const CompositorOps* curr_ops;
+
+ if (name == NULL || name[0] == 0 ||
+ strcmp (name, COMPSOR_NAME_FALLBACK) == 0)
+ return FALSE;
+
+ curr_ops = ServerSelectCompositor (NULL, NULL);
+
+ for (i = 0; i < MAX_NR_COMPOSITORS; i++) {
+ if (strcmp (compositors [i].name, name) == 0) {
+ if (curr_ops == compositors [i].ops)
+ return FALSE;
+
+ compositors [i].name[0] = 0;
+ compositors [i].ops = NULL;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+const CompositorOps* GUIAPI ServerSelectCompositor (const char* name,
+ CompositorCtxt** the_ctxt)
+{
+ static const CompositorOps* curr_ops;
+ static CompositorCtxt* curr_ctxt;
+ const CompositorOps* ops;
+
+ if (name == NULL || name [0] == 0) {
+ if (the_ctxt) *the_ctxt = curr_ctxt;
+ return curr_ops;
+ }
+
+ ops = ServerGetCompositorOps (name);
+ if (ops) {
+ CompositorCtxt* ctxt;
+
+ if (ops == curr_ops) {
+ if (the_ctxt) *the_ctxt = curr_ctxt;
+ return ops;
+ }
+
+ ctxt = ops->initialize (name);
+ if (ctxt) {
+ if (curr_ops)
+ curr_ops->terminate (curr_ctxt);
+ curr_ops = ops;
+ curr_ctxt = ctxt;
+ curr_ops->refresh (ctxt);
+ }
+
+ if (the_ctxt) *the_ctxt = curr_ctxt;
+ return curr_ops;
+ }
+
+ return NULL;
+}
+
+#endif /* defined(_MGRM_PROCESSES) && defined(_MGSCHEMA_COMPOSITING) */
+