#include #include #include #include #include #include #include #include #include "projal.h" #define _APP_ID GFA_APPCTRL_APPID_USER_11 #define _APP_NAME "qmlDemo" #define _UPDATE_TIMER_INT 50 #define _UPDATE_TIMER_INT_HEAVY_LOAD 5000 #define _APP_SUBSCRIPTIONS (GFA_APPCTRL_APPID_ALL_GFA | GFA_APPCTRL_APPID_USER_11) #define _SIG_BLOCK(s) sigprocmask(SIG_BLOCK, (s), NULL) #define _SIG_UNBLOCK(s) sigprocmask(SIG_UNBLOCK, (s), NULL) static sigset_t g_set; static std::atomic_uintptr_t g_appPtr(0); static void _SigHandler(int sig) { QGuiApplication *pApp = (QGuiApplication*)g_appPtr.load(); if(pApp) pApp->exit(-sig); } #undef GfaIpcLockSHM #undef GfaIpcUnlockSHM static void _LockSHM(HSHM hShm) { ::GfaIpcLockSHMAndSigBlock(hShm, &g_set); } static void _UnlockSHM(HSHM hShm) { ::GfaIpcUnlockSHMAndSigUnblock(hShm, &g_set); } int main(int argc, char *argv[]) { ///////////////////////////////////////////////////////////////////////// // check for multiple instances CProcessInstance pi; if(!pi.LockInstance(UUID_SHM)) { ETRACE("Failed to start instance!\n"); return -1; } ///////////////////////////////////////////////////////////////////////// // configure signal handling struct sigaction sa; ::sigfillset(&g_set); ::sigdelset(&g_set, SIGSEGV); memset(&sa, 0, sizeof(sa)); sa.sa_handler = _SigHandler; sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\' sigaction(SIGTERM, &sa, NULL); // handles normal termination sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort()) sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C' sa.sa_handler = SIG_IGN; sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z' sigaction(SIGSTOP, &sa, NULL); // ignores Stop sigaction(SIGCONT, &sa, NULL); // ignores Continue sigaction(SIGCHLD, &sa, NULL); // ignores child process termination sigaction(0, &sa, NULL); // ignores shell termination set_lock_unlock_functions(_LockSHM, _UnlockSHM); ///////////////////////////////////////////////////////////////////////// qputenv("QT_IM_MODULE", QByteArray("QtFreeVirtualKeyboard")); ///////////////////////////////////////////////////////////////////////// QGfaAppCtrl appCtrl; QGuiApplication app(argc, argv); g_appPtr.store((uintptr_t)&app); QQmlApplicationEngine engine; int nRet = -1; HSHM hShm = NULL; if(appCtrl.Create(_APP_ID, _APP_NAME, _UPDATE_TIMER_INT, _UPDATE_TIMER_INT_HEAVY_LOAD)) { appCtrl.SetLockUnlockFunctions(_LockSHM, _UnlockSHM); appCtrl.SubscribeStateEvents(_APP_SUBSCRIPTIONS); appCtrl.SetState(GIAS_Initializing); if((hShm = acquire_shm(sizeof(shm_t)))) { void *pShm = ::GfaIpcAcquirePointer(hShm); if(pShm) { CShm_t shm(pShm, hShm, NULL); CShmWatcher watcher(hShm, shm, pShm); watcher.SetLockUnlockFunctions(_LockSHM, _UnlockSHM); register_types(engine, &shm); appCtrl.RegisterQmlTypes(engine, 1, 0); engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); appCtrl.SetState(GIAS_Running); watcher.StartWatch(_SHM_SCAN_INTERVAL_MS); nRet = app.exec(); watcher.StopWatch(); ::GfaIpcReleasePointer(hShm, pShm); } ::GfaIpcReleaseSHM(hShm); } appCtrl.SetState(GIAS_Terminating); appCtrl.Release(); } g_appPtr.store(0); return nRet; }