platform-x11.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /******************************************************************************
  2. Copyright (C) 2013 by Hugh Bailey <[email protected]>
  3. Copyright (C) 2014 by Zachary Lund <[email protected]>
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. ******************************************************************************/
  15. #include <obs-config.h>
  16. #include "obs-app.hpp"
  17. #include <QGuiApplication>
  18. #include <QScreen>
  19. #include <unistd.h>
  20. #include <sstream>
  21. #include <locale.h>
  22. #include "platform.hpp"
  23. #ifdef __linux__
  24. #include <sys/socket.h>
  25. #include <string.h>
  26. #include <sys/types.h>
  27. #include <stdio.h>
  28. #include <sys/un.h>
  29. #endif
  30. using namespace std;
  31. #ifdef __linux__
  32. void RunningInstanceCheck(bool &already_running)
  33. {
  34. int uniq = socket(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  35. if (uniq == -1) {
  36. blog(LOG_ERROR,
  37. "Failed to check for running instance, socket: %d", errno);
  38. already_running = 0;
  39. return;
  40. }
  41. struct sockaddr_un bindInfo;
  42. memset(&bindInfo, 0, sizeof(sockaddr_un));
  43. bindInfo.sun_family = AF_LOCAL;
  44. char *abstactSockName = NULL;
  45. asprintf(&abstactSockName, "%s %d %s", "/com/obsproject", getpid(),
  46. App()->GetVersionString().c_str());
  47. memmove(bindInfo.sun_path + 1, abstactSockName,
  48. strlen(abstactSockName));
  49. free(abstactSockName);
  50. int bindErr = bind(uniq, (struct sockaddr *)&bindInfo,
  51. sizeof(struct sockaddr_un));
  52. already_running = bindErr == 0 ? 0 : 1;
  53. if (already_running) {
  54. return;
  55. }
  56. FILE *fp = fopen("/proc/net/unix", "re");
  57. if (fp == NULL) {
  58. return;
  59. }
  60. char *line = NULL;
  61. size_t n = 0;
  62. int obsCnt = 0;
  63. while (getdelim(&line, &n, ' ', fp) != EOF) {
  64. line[strcspn(line, "\n")] = '\0';
  65. if (*line == '@') {
  66. if (strstr(line, "@/com/obsproject") != NULL) {
  67. ++obsCnt;
  68. }
  69. }
  70. }
  71. already_running = obsCnt == 1 ? 0 : 1;
  72. free(line);
  73. fclose(fp);
  74. }
  75. #endif
  76. static inline bool check_path(const char *data, const char *path,
  77. string &output)
  78. {
  79. ostringstream str;
  80. str << path << data;
  81. output = str.str();
  82. printf("Attempted path: %s\n", output.c_str());
  83. return (access(output.c_str(), R_OK) == 0);
  84. }
  85. #define INSTALL_DATA_PATH OBS_INSTALL_PREFIX OBS_DATA_PATH "/obs-studio/"
  86. bool GetDataFilePath(const char *data, string &output)
  87. {
  88. char *data_path = getenv("OBS_DATA_PATH");
  89. if (data_path != NULL) {
  90. if (check_path(data, data_path, output))
  91. return true;
  92. }
  93. if (check_path(data, OBS_DATA_PATH "/obs-studio/", output))
  94. return true;
  95. if (check_path(data, INSTALL_DATA_PATH, output))
  96. return true;
  97. return false;
  98. }
  99. bool InitApplicationBundle()
  100. {
  101. return true;
  102. }
  103. string GetDefaultVideoSavePath()
  104. {
  105. return string(getenv("HOME"));
  106. }
  107. vector<string> GetPreferredLocales()
  108. {
  109. setlocale(LC_ALL, "");
  110. vector<string> matched;
  111. string messages = setlocale(LC_MESSAGES, NULL);
  112. if (!messages.size() || messages == "C" || messages == "POSIX")
  113. return {};
  114. if (messages.size() > 2)
  115. messages[2] = '-';
  116. for (auto &locale_pair : GetLocaleNames()) {
  117. auto &locale = locale_pair.first;
  118. if (locale == messages.substr(0, locale.size()))
  119. return {locale};
  120. if (locale.substr(0, 2) == messages.substr(0, 2))
  121. matched.push_back(locale);
  122. }
  123. return matched;
  124. }
  125. bool IsAlwaysOnTop(QWidget *window)
  126. {
  127. return (window->windowFlags() & Qt::WindowStaysOnTopHint) != 0;
  128. }
  129. void SetAlwaysOnTop(QWidget *window, bool enable)
  130. {
  131. Qt::WindowFlags flags = window->windowFlags();
  132. if (enable)
  133. flags |= Qt::WindowStaysOnTopHint;
  134. else
  135. flags &= ~Qt::WindowStaysOnTopHint;
  136. window->setWindowFlags(flags);
  137. window->show();
  138. }