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) */ +