main.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include <signal.h>
  2. #include <atomic>
  3. #include <QGuiApplication>
  4. #include <QQmlApplicationEngine>
  5. #include <gfa/qappctrl.h>
  6. #include <gfa/svc/common/instance.h>
  7. #include <gfa/svc/common/debug.h>
  8. #include <gfa/svc/shmqml/shmthread.h>
  9. #include "projal.h"
  10. #define _APP_ID GFA_APPCTRL_APPID_USER_11
  11. #define _APP_NAME "qmlDemo"
  12. #define _UPDATE_TIMER_INT 50
  13. #define _UPDATE_TIMER_INT_HEAVY_LOAD 5000
  14. #define _APP_SUBSCRIPTIONS (GFA_APPCTRL_APPID_ALL_GFA | GFA_APPCTRL_APPID_USER_11)
  15. #define _SIG_BLOCK(s) sigprocmask(SIG_BLOCK, (s), NULL)
  16. #define _SIG_UNBLOCK(s) sigprocmask(SIG_UNBLOCK, (s), NULL)
  17. static sigset_t g_set;
  18. static std::atomic_uintptr_t g_appPtr(0);
  19. static void _SigHandler(int sig)
  20. {
  21. QGuiApplication *pApp = (QGuiApplication*)g_appPtr.load();
  22. if(pApp)
  23. pApp->exit(-sig);
  24. }
  25. #undef GfaIpcLockSHM
  26. #undef GfaIpcUnlockSHM
  27. static void _LockSHM(HSHM hShm)
  28. {
  29. ::GfaIpcLockSHMAndSigBlock(hShm, &g_set);
  30. }
  31. static void _UnlockSHM(HSHM hShm)
  32. {
  33. ::GfaIpcUnlockSHMAndSigUnblock(hShm, &g_set);
  34. }
  35. int main(int argc, char *argv[])
  36. {
  37. /////////////////////////////////////////////////////////////////////////
  38. // check for multiple instances
  39. CProcessInstance pi;
  40. if(!pi.LockInstance(UUID_SHM))
  41. {
  42. ETRACE("Failed to start instance!\n");
  43. return -1;
  44. }
  45. /////////////////////////////////////////////////////////////////////////
  46. // configure signal handling
  47. struct sigaction sa;
  48. ::sigfillset(&g_set);
  49. ::sigdelset(&g_set, SIGSEGV);
  50. memset(&sa, 0, sizeof(sa));
  51. sa.sa_handler = _SigHandler;
  52. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  53. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  54. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  55. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  56. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  57. sa.sa_handler = SIG_IGN;
  58. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  59. sigaction(SIGSTOP, &sa, NULL); // ignores Stop
  60. sigaction(SIGCONT, &sa, NULL); // ignores Continue
  61. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  62. sigaction(0, &sa, NULL); // ignores shell termination
  63. set_lock_unlock_functions(_LockSHM, _UnlockSHM);
  64. /////////////////////////////////////////////////////////////////////////
  65. qputenv("QT_IM_MODULE", QByteArray("QtFreeVirtualKeyboard"));
  66. /////////////////////////////////////////////////////////////////////////
  67. QGfaAppCtrl appCtrl;
  68. QGuiApplication app(argc, argv);
  69. g_appPtr.store((uintptr_t)&app);
  70. QQmlApplicationEngine engine;
  71. int nRet = -1;
  72. HSHM hShm = NULL;
  73. if(appCtrl.Create(_APP_ID, _APP_NAME, _UPDATE_TIMER_INT, _UPDATE_TIMER_INT_HEAVY_LOAD))
  74. {
  75. appCtrl.SetLockUnlockFunctions(_LockSHM, _UnlockSHM);
  76. appCtrl.SubscribeStateEvents(_APP_SUBSCRIPTIONS);
  77. appCtrl.SetState(GIAS_Initializing);
  78. if((hShm = acquire_shm(sizeof(shm_t))))
  79. {
  80. void *pShm = ::GfaIpcAcquirePointer(hShm);
  81. if(pShm)
  82. {
  83. CShm_t shm(pShm, hShm, NULL);
  84. CShmWatcher<CShm_t, shm_t> watcher(hShm, shm, pShm);
  85. watcher.SetLockUnlockFunctions(_LockSHM, _UnlockSHM);
  86. register_types(engine, &shm);
  87. appCtrl.RegisterQmlTypes(engine, 1, 0);
  88. engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
  89. appCtrl.SetState(GIAS_Running);
  90. watcher.StartWatch(_SHM_SCAN_INTERVAL_MS);
  91. nRet = app.exec();
  92. watcher.StopWatch();
  93. ::GfaIpcReleasePointer(hShm, pShm);
  94. }
  95. ::GfaIpcReleaseSHM(hShm);
  96. }
  97. appCtrl.SetState(GIAS_Terminating);
  98. appCtrl.Release();
  99. }
  100. g_appPtr.store(0);
  101. return nRet;
  102. }