obs-app.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /******************************************************************************
  2. Copyright (C) 2013 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include <sstream>
  15. #include <util/bmem.h>
  16. #include <util/dstr.h>
  17. #include <util/platform.h>
  18. #include <obs.hpp>
  19. #include <QProxyStyle>
  20. #include "qt-wrappers.hpp"
  21. #include "obs-app.hpp"
  22. #include "window-basic-main.hpp"
  23. #include "platform.hpp"
  24. #ifdef _WIN32
  25. #include <windows.h>
  26. #endif
  27. using namespace std;
  28. static void do_log(int log_level, const char *msg, va_list args)
  29. {
  30. #ifdef _WIN32
  31. char bla[4096];
  32. vsnprintf(bla, 4095, msg, args);
  33. OutputDebugStringA(bla);
  34. OutputDebugStringA("\n");
  35. if (log_level <= LOG_ERROR && IsDebuggerPresent())
  36. __debugbreak();
  37. #else
  38. vprintf(msg, args);
  39. printf("\n");
  40. UNUSED_PARAMETER(log_level);
  41. #endif
  42. }
  43. bool OBSApp::InitGlobalConfigDefaults()
  44. {
  45. config_set_default_string(globalConfig, "General", "Language", "en");
  46. #if _WIN32
  47. config_set_default_string(globalConfig, "Video", "Renderer",
  48. "Direct3D 11");
  49. #else
  50. config_set_default_string(globalConfig, "Video", "Renderer", "OpenGL");
  51. #endif
  52. return true;
  53. }
  54. static bool do_mkdir(const char *path)
  55. {
  56. if (os_mkdir(path) == MKDIR_ERROR) {
  57. OBSErrorBox(NULL, "Failed to create directory %s", path);
  58. return false;
  59. }
  60. return true;
  61. }
  62. static bool MakeUserDirs()
  63. {
  64. BPtr<char> configPath;
  65. configPath = os_get_config_path("obs-studio");
  66. if (!do_mkdir(configPath))
  67. return false;
  68. configPath = os_get_config_path("obs-studio/basic");
  69. if (!do_mkdir(configPath))
  70. return false;
  71. configPath = os_get_config_path("obs-studio/studio");
  72. if (!do_mkdir(configPath))
  73. return false;
  74. return true;
  75. }
  76. bool OBSApp::InitGlobalConfig()
  77. {
  78. BPtr<char> path(os_get_config_path("obs-studio/global.ini"));
  79. int errorcode = globalConfig.Open(path, CONFIG_OPEN_ALWAYS);
  80. if (errorcode != CONFIG_SUCCESS) {
  81. OBSErrorBox(NULL, "Failed to open global.ini: %d", errorcode);
  82. return false;
  83. }
  84. return InitGlobalConfigDefaults();
  85. }
  86. #define DEFAULT_LANG "en"
  87. bool OBSApp::InitLocale()
  88. {
  89. const char *lang = config_get_string(globalConfig, "General",
  90. "Language");
  91. locale = lang;
  92. stringstream file;
  93. file << "locale/" << lang << ".txt";
  94. string englishPath;
  95. if (!GetDataFilePath("locale/" DEFAULT_LANG ".txt", englishPath)) {
  96. OBSErrorBox(NULL, "Failed to find locale/" DEFAULT_LANG ".txt");
  97. return false;
  98. }
  99. textLookup = text_lookup_create(englishPath.c_str());
  100. if (!textLookup) {
  101. OBSErrorBox(NULL, "Failed to create locale from file '%s'",
  102. englishPath.c_str());
  103. return false;
  104. }
  105. if (astrcmpi(lang, DEFAULT_LANG) == 0)
  106. return true;
  107. string path;
  108. if (GetDataFilePath(file.str().c_str(), path)) {
  109. if (!text_lookup_add(textLookup, path.c_str()))
  110. blog(LOG_ERROR, "Failed to add locale file '%s'",
  111. path.c_str());
  112. } else {
  113. blog(LOG_ERROR, "Could not find locale file '%s'",
  114. file.str().c_str());
  115. }
  116. return true;
  117. }
  118. OBSApp::OBSApp(int &argc, char **argv)
  119. : QApplication(argc, argv)
  120. {
  121. if (!InitApplicationBundle())
  122. throw "Failed to initialize application bundle";
  123. if (!MakeUserDirs())
  124. throw "Failed to created required user directories";
  125. if (!InitGlobalConfig())
  126. throw "Failed to initialize global config";
  127. if (!InitLocale())
  128. throw "Failed to load locale";
  129. mainWindow = move(unique_ptr<OBSBasic>(new OBSBasic()));
  130. }
  131. const char *OBSApp::GetRenderModule() const
  132. {
  133. const char *renderer = config_get_string(globalConfig, "Video",
  134. "Renderer");
  135. if (astrcmpi(renderer, "Direct3D 11") == 0)
  136. return "libobs-d3d11";
  137. else
  138. return "libobs-opengl";
  139. }
  140. void OBSApp::OBSInit()
  141. {
  142. mainWindow->OBSInit();
  143. }
  144. #ifdef __APPLE__
  145. #define INPUT_AUDIO_SOURCE "coreaudio_input_capture"
  146. #define OUTPUT_AUDIO_SOURCE "coreaudio_output_capture"
  147. #elif _WIN32
  148. #define INPUT_AUDIO_SOURCE "wasapi_input_capture"
  149. #define OUTPUT_AUDIO_SOURCE "wasapi_output_capture"
  150. #else
  151. #define INPUT_AUDIO_SOURCE "pulse_input_capture"
  152. #define OUTPUT_AUDIO_SOURCE "pulse_output_capture"
  153. #endif
  154. const char *OBSApp::InputAudioSource() const
  155. {
  156. return INPUT_AUDIO_SOURCE;
  157. }
  158. const char *OBSApp::OutputAudioSource() const
  159. {
  160. return OUTPUT_AUDIO_SOURCE;
  161. }
  162. struct NoFocusFrameStyle : QProxyStyle
  163. {
  164. void drawControl(ControlElement element, const QStyleOption *option,
  165. QPainter *painter, const QWidget *widget=nullptr)
  166. const override
  167. {
  168. if (element == CE_FocusFrame)
  169. return;
  170. QProxyStyle::drawControl(element, option, painter, widget);
  171. }
  172. };
  173. int main(int argc, char *argv[])
  174. {
  175. int ret = -1;
  176. QCoreApplication::addLibraryPath(".");
  177. #ifdef _WIN32
  178. base_set_log_handler(do_log);
  179. #endif
  180. try {
  181. OBSApp program(argc, argv);
  182. program.setStyle(new NoFocusFrameStyle);
  183. program.OBSInit();
  184. ret = program.exec();
  185. } catch (const char *error) {
  186. blog(LOG_ERROR, "%s", error);
  187. }
  188. blog(LOG_INFO, "Number of memory leaks: %ld", bnum_allocs());
  189. return ret;
  190. }