Files
MiniGUI/src/kernel/init-lite.c
2020-01-19 16:20:25 +08:00

621 lines
15 KiB
C

///////////////////////////////////////////////////////////////////////////////
//
// 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/>.
*/
/*
** init-lite.c: The Initialization/Termination routines for
** MiniGUI-Processes and MiniGUI-Standalone.
**
** Current maintainer: Wei Yongming.
**
** Create date: 2000/11/05
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#ifndef _MGRM_THREADS
#ifndef WIN32
#include <unistd.h>
#include <sys/termios.h>
#endif /* WIN32 */
#include <signal.h>
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "cliprect.h"
#include "gal.h"
#include "internals.h"
#include "ctrlclass.h"
#include "cursor.h"
#include "event.h"
#include "misc.h"
#include "menu.h"
#include "timer.h"
#include "accelkey.h"
#include "license.h"
/* Minimal graphics support by humingming 2010.7.8 */
#ifdef _MG_MINIMALGDI
static struct termios savedtermio;
#define err_message(step, message) _ERR_PRINTF ("KERNEL>InitGUI (step %d): %s\n", step, message)
static void sig_handler (int v)
{
;
}
/* for pc_xvfb test by humingming 2010.7.9 */
#include "dc.h"
void kernel_ShowCursorForGDI(BOOL fShow, void* pdc)
{
PDC cur_pdc = (PDC)pdc;
const RECT* prc = NULL;
prc = &cur_pdc->rc_output;
if (fShow)
GAL_UpdateRect (cur_pdc->surface,
prc->left, prc->top, RECTWP(prc), RECTHP(prc));
}
int InitGUI (int argc, const char* agr[])
{
char engine [LEN_ENGINE_NAME + 1];
char mode [LEN_VIDEO_MODE + 1];
int step = 1;
__mg_quiting_stage = _MG_QUITING_STAGE_RUNNING;
#ifndef __NOUNIX__
tcgetattr (0, &savedtermio);
#endif
step++;
if (!mg_InitSliceAllocator ()) {
_ERR_PRINTF ("KERNEL>InitGUI: failed to initialize slice allocator!\n");
return step;
}
if (!mg_InitFixStr ()) {
err_message (step, "Can not initialize Fixed String heap!\n");
return step;
}
step++;
if (!mg_InitMisc ()) {
err_message (step, "Can not initialize miscellous things!");
return step;
}
step++;
/* Init GAL engine. */
switch (mg_InitGAL (engine, mode)) {
case ERR_CONFIG_FILE:
err_message (step, "Reading configuration failure!");
return step;
case ERR_NO_ENGINE:
err_message (step, "No graphics engine defined!");
return step;
case ERR_NO_MATCH:
err_message (step, "Can not get graphics engine information!");
return step;
case ERR_GFX_ENGINE:
err_message (step, "Can not initialize graphics engine!");
return step;
}
step++;
atexit (mg_TerminateGAL);
/* Init Master Screen DC here */
if (!mg_InitScreenDC (__gal_screen)) {
err_message (step, "Can not initialize screen DC!");
return step;
}
step++;
atexit (mg_TerminateScreenDC);
#if 0
g_rcScr.left = 0;
g_rcScr.top = 0;
g_rcScr.right = GetGDCapability (HDC_SCREEN_SYS, GDCAP_MAXX) + 1;
g_rcScr.bottom = GetGDCapability (HDC_SCREEN_SYS, GDCAP_MAXY) + 1;
#endif
mg_TerminateMgEtc ();
return 0;
}
void TerminateGUI (int rcByGUI)
{
mg_TerminateMisc ();
mg_TerminateFixStr ();
mg_TerminateSliceAllocator();
}
#warning ExitGUISafely?
#else /* _MG_MINIMALGDI */
#ifdef _MGRM_PROCESSES
#include "sharedres.h"
#include "client.h"
#include "server.h"
void* mgSharedRes;
size_t mgSizeRes;
#endif /* _MGRM_PROCESSES */
BOOL GUIAPI ReinitDesktopEx (BOOL init_sys_text)
{
return SendMessage (HWND_DESKTOP, MSG_REINITSESSION, init_sys_text, 0) == 0;
}
#ifndef WIN32
static struct termios savedtermio;
#endif
void* GUIAPI GetOriginalTermIO (void)
{
#ifdef _MGRM_STANDALONE
#ifdef WIN32
return NULL;
#else
return &savedtermio;
#endif
#else
return &SHAREDRES_TERMIOS;
#endif
}
static BOOL InitResource (void)
{
#ifdef _MGHAVE_CURSOR
if (!mg_InitCursor ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Can not initialize mouse cursor!\n");
goto failure;
}
#endif
#ifdef _MGHAVE_MENU
if (!mg_InitMenu ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Init Menu module failure!\n");
goto failure;
}
#endif
if (!mg_InitControlClass ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Init Control Class failure!\n");
goto failure;
}
if (!mg_InitAccel ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Init Accelerator failure!\n");
goto failure;
}
if (!mg_InitDesktop ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Init Desktop error!\n");
goto failure;
}
if (!mg_InitFreeQMSGList ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Init free QMSG list error!\n");
goto failure;
}
if (!InitDskMsgQueue ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Init MSG queue error!\n");
goto failure;
}
return TRUE;
failure:
return FALSE;
}
#define err_message(step, message) _ERR_PRINTF ("KERNEL>InitGUI (step %d): %s\n", step, message)
static void sig_handler (int v)
{
if (v == SIGSEGV) {
kill (getpid(), SIGABRT); /* cause core dump */
}
else if (v == SIGINT) {
_exit(1); /* force to quit */
}
else if (__mg_quiting_stage > 0) {
ExitGUISafely(-1);
}
else {
exit(1); /* force to quit */
}
}
static BOOL InstallSEGVHandler (void)
{
struct sigaction siga;
siga.sa_handler = sig_handler;
siga.sa_flags = 0;
memset (&siga.sa_mask, 0, sizeof (sigset_t));
sigaction (SIGSEGV, &siga, NULL);
sigaction (SIGTERM, &siga, NULL);
sigaction (SIGINT, &siga, NULL);
sigaction (SIGPIPE, &siga, NULL);
return TRUE;
}
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef _MGRM_PROCESSES
static BOOL _is_server = FALSE;
BOOL IsServer(void)
{
return _is_server;
}
#endif
int InitGUI (int argc, const char* agr[])
{
char engine [LEN_ENGINE_NAME + 1];
char mode [LEN_VIDEO_MODE + 1];
int step = 1;
__mg_quiting_stage = _MG_QUITING_STAGE_RUNNING;
#ifdef _MGRM_PROCESSES
const char* name;
if ((name = strrchr (agr [0], '/')) == NULL)
name = agr [0];
else
name ++;
if (!strcmp (name, "mginit"))
_is_server = TRUE;
#endif
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "C");
#endif
/* Save original termio */
#ifdef _MGRM_PROCESSES
if (_is_server)
#endif
#ifndef __NOUNIX__
tcgetattr (0, &savedtermio);
#endif
/*Initialize default window process*/
__mg_def_proc[0] = PreDefMainWinProc;
__mg_def_proc[1] = PreDefDialogProc;
__mg_def_proc[2] = PreDefControlProc;
if (!mg_InitSliceAllocator ()) {
_ERR_PRINTF ("KERNEL>InitGUI: failed to initialize slice allocator!\n");
return step;
}
step++;
atexit (mg_TerminateSliceAllocator);
if (!mg_InitFixStr ()) {
err_message (step, "Can not initialize Fixed String heap!\n");
return step;
}
step++;
atexit (mg_TerminateFixStr);
#if 0
if (!mg_InitSemManger (NR_COMPOSITING_SEMS)) {
err_message (step, "Can not initialize SysV semaphore manager!");
return step;
}
step++;
atexit (mg_TerminateSemManager);
#endif
if (!mg_InitMisc ()) {
err_message (step, "Can not initialize miscellous things!");
return step;
}
step++;
atexit (mg_TerminateMisc);
#ifdef _MGRM_PROCESSES
if (_is_server && !kernel_IsOnlyMe ()) {
err_message (step, "There is already an instance of 'mginit'!");
return step;
}
step++;
#endif
#ifdef _MGRM_PROCESSES
if (!_is_server) {
if (!client_ClientStartup ()) {
err_message (step, "Can not start client (Please run mginit first)!");
return step;
}
step++;
if ((mgSharedRes = kernel_AttachSharedResource ()) == NULL) {
err_message (step, "Can not attach shared resource (Please run mginit first)!");
return step;
}
atexit (kernel_UnattachSharedResource);
}
#endif
/* Init GAL engine. */
switch (mg_InitGAL (engine, mode)) {
case ERR_CONFIG_FILE:
err_message (step, "Reading configuration failure!");
return step;
case ERR_NO_ENGINE:
err_message (step, "No graphics engine defined!");
return step;
case ERR_NO_MATCH:
err_message (step, "Can not get graphics engine information!");
return step;
case ERR_GFX_ENGINE:
err_message (step, "Can not initialize graphics engine!");
return step;
}
step++;
atexit (mg_TerminateGAL);
/* install signal handlers */
#ifdef _MGRM_PROCESSES
if (_is_server)
#endif
InstallSEGVHandler ();
/** initialize icon bitmap resource.*/
if (mg_InitSystemRes () == FALSE) {
_ERR_PRINTF ("KERNEL>IniGUI: init system res error!\n");
return step;
}
step++;
/* DK[11/29/10]: For fix bug 4440, avoid double free. */
/* atexit (mg_TerminateSystemRes);
*/
if (!mg_InitGDI ()) {
err_message (step, "Initialization of GDI resource failure!\n");
return step;
}
step++;
atexit (mg_TerminateGDI);
/* Init Master Screen DC here */
if (!mg_InitScreenDC (__gal_screen)) {
err_message (step, "Can not initialize screen DC!");
return step;
}
step++;
atexit (mg_TerminateScreenDC);
#if 0
g_rcScr.left = 0;
g_rcScr.top = 0;
g_rcScr.right = GetGDCapability (HDC_SCREEN_SYS, GDCAP_MAXX) + 1;
g_rcScr.bottom = GetGDCapability (HDC_SCREEN_SYS, GDCAP_MAXY) + 1;
#endif
#ifdef _MGRM_PROCESSES
if (_is_server) {
/* Load shared resource and create shared memory. */
if ((mgSharedRes = kernel_LoadSharedResource ()) == NULL) {
err_message (step, "Can not load shared resource!");
return step;
}
atexit (kernel_UnloadSharedResource);
SHAREDRES_TERMIOS = savedtermio;
/* Since 4.2.0
* Copy the video engine information to the shared resource segement
*/
strncpy (SHAREDRES_VIDEO_ENGINE, engine, LEN_ENGINE_NAME);
strncpy (SHAREDRES_VIDEO_MODE, mode, LEN_VIDEO_MODE);
if (GetMgEtcValue (engine, "device", SHAREDRES_VIDEO_DEVICE, LEN_DEVICE_NAME) < 0)
*SHAREDRES_VIDEO_DEVICE = 0;
if (GetMgEtcValue (engine, "pixelformat", SHAREDRES_VIDEO_FOURCC, LEN_FOURCC_FORMAT) < 0)
*SHAREDRES_VIDEO_FOURCC = 0;
if (GetMgEtcValue (engine, "exdriver", SHAREDRES_VIDEO_EXDRIVER, LEN_EXDRIVER_NAME) < 0)
*SHAREDRES_VIDEO_EXDRIVER = 0;
SHAREDRES_VIDEO_DPI = __gal_screen->dpi;
SHAREDRES_VIDEO_HRES = __gal_screen->w;
SHAREDRES_VIDEO_VRES = __gal_screen->h;
SHAREDRES_VIDEO_DEPTH = __gal_screen->format->BitsPerPixel;
SHAREDRES_VIDEO_RMASK = __gal_screen->format->Rmask;
SHAREDRES_VIDEO_GMASK = __gal_screen->format->Gmask;
SHAREDRES_VIDEO_BMASK = __gal_screen->format->Bmask;
SHAREDRES_VIDEO_AMASK = __gal_screen->format->Amask;
}
else {
_DBG_PRINTF("Engien info from shared resource: %s %s %d\n",
SHAREDRES_VIDEO_ENGINE, SHAREDRES_VIDEO_MODE, SHAREDRES_VIDEO_DPI);
}
step++;
#endif /* _MGRM_PROCESSES */
if (!mg_InitLFManager ()) {
err_message (step, "Can not initialize LFManager!\n");
return step;
}
step++;
atexit (mg_TerminateLFManager);
#ifdef _MGRM_PROCESSES
if (_is_server)
#endif
{
__mg_license_create();
__mg_splash_draw_framework();
__mg_splash_delay();
}
/* Initialize resource */
if (!InitResource ()) {
err_message (step, "Can not initialize resource!");
return step;
}
step++;
#ifdef _MGRM_STANDALONE
/* Init IAL engine.. */
if (!mg_InitLWEvent ()) {
err_message (step, "Can not initialize low level event!");
return step;
}
step++;
atexit (mg_TerminateLWEvent);
SetDskIdleHandler (salone_IdleHandler4StandAlone);
if (!salone_StandAloneStartup ()) {
_ERR_PRINTF ("KERNEL>InitGUI: Can not start MiniGUI-StandAlone version.\n");
return step;
}
#else /* not defined _MGRM_STANDALONE */
if (_is_server) {
/* Init IAL engine.. */
if (!mg_InitLWEvent ()) {
err_message (step, "Can not initialize low level event!");
return step;
}
step++;
atexit (mg_TerminateLWEvent);
SetDskIdleHandler (server_IdleHandler4Server);
}
else {
SetDskIdleHandler (client_IdleHandler4Client);
}
#endif /* not defined _MGRM_STANDALONE */
SetKeyboardLayout ("default");
mg_TerminateMgEtc ();
#ifdef _MGSCHEMA_COMPOSITING
if (_is_server) {
if (!mg_InitCompositor ()) {
err_message (step, "Can not initialize compositor!");
return step;
}
atexit (mg_TerminateCompositor);
}
#endif
return 0;
}
void TerminateGUI (int rcByGUI)
{
/* printf("Quit from MiniGUIMain()\n"); */
DestroyDskMsgQueue ();
mg_DestroyFreeQMSGList ();
mg_TerminateAccel ();
mg_TerminateControlClass ();
#ifdef _MGHAVE_MENU
mg_TerminateMenu ();
#endif
#ifdef _MGHAVE_CURSOR
mg_TerminateCursor ();
#endif
#ifdef _MGRM_PROCESSES
if (_is_server)
#endif
{
__mg_license_destroy();
}
#ifdef _MGRM_STANDALONE
mg_TerminateDesktop ();
salone_StandAloneCleanup ();
#else
if (_is_server) {
mg_TerminateDesktop ();
/* Cleanup UNIX domain socket and other IPC objects. */
server_ServerCleanup ();
}
else {
client_ClientCleanup ();
}
#endif
}
#endif /* ifndef _MG_MINIMALGDI */
#endif /* !_MGRM_THREADS */