implement mg_InitCompositor, mg_TerminateCompositor, ServerGetCompositorOps, ServerRegisterCompositor, ServerUnregisterCompositor, and ServerSelectCompositor

This commit is contained in:
Vincent Wei
2020-01-19 16:22:35 +08:00
parent 9cd099e793
commit afa496324e

View File

@@ -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 <http://www.gnu.org/licenses/>.
*
* 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
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
*/
/*
** compsor-manager.c: the compositor manager module for MiniGUI.
**
** Create date: 2020-01-19
**
** Current maintainer: Wei Yongming.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "common.h"
#if defined(_MGRM_PROCESSES) && defined(_MGSCHEMA_COMPOSITING)
#include <dlfcn.h>
#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) */