ensure that xmlKeepBlankDefault() is called early in instance-life, from PBD::init()
[ardour.git] / libs / pbd / pbd.cc
1 /*
2  * Copyright (C) 2013-2015 Tim Mayberry <mojofunk@gmail.com>
3  * Copyright (C) 2014-2016 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2014-2019 Robin Gareus <robin@gareus.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include <iostream>
22 #include <cstdlib>
23 #include <string>
24
25 #ifdef PLATFORM_WINDOWS
26 #include <fcntl.h>
27 #endif
28
29 #include <giomm.h>
30
31 #include <glibmm/thread.h>
32
33 #include "pbd/pbd.h"
34 #include "pbd/debug.h"
35 #include "pbd/error.h"
36 #include "pbd/id.h"
37 #include "pbd/enumwriter.h"
38 #include "pbd/fpu.h"
39 #include "pbd/xml++.h"
40
41 #ifdef PLATFORM_WINDOWS
42 #include <winsock2.h>
43 #include "pbd/windows_timer_utils.h"
44 #include "pbd/windows_mmcss.h"
45 #endif
46
47 #include "pbd/i18n.h"
48
49 extern void setup_libpbd_enums ();
50
51 namespace {
52
53 static bool libpbd_initialized = false;
54
55 static
56 void
57 set_debug_options_from_env ()
58 {
59         bool set;
60         std::string options;
61
62         options = Glib::getenv ("PBD_DEBUG", set);
63         if (set) {
64                 std::cerr << X_("PBD_DEBUG=") << options << std::endl;
65                 PBD::parse_debug_options (options.c_str());
66         }
67 }
68
69 #ifdef PLATFORM_WINDOWS
70 static
71 void
72 test_timers_from_env ()
73 {
74         bool set;
75         std::string options;
76
77         options = Glib::getenv ("PBD_TEST_TIMERS", set);
78         if (set) {
79                 if (!PBD::QPC::check_timer_valid ()) {
80                         PBD::error << X_("Windows QPC Timer source not usable") << endmsg;
81                 } else {
82                         PBD::info << X_("Windows QPC Timer source usable") << endmsg;
83                 }
84         }
85 }
86 #endif
87
88 } // namespace
89
90 bool
91 PBD::init ()
92 {
93         if (libpbd_initialized) {
94                 return true;
95         }
96
97 #ifdef PLATFORM_WINDOWS
98         // Essential!!  Make sure that any files used by Ardour
99         //              will be created or opened in BINARY mode!
100         _fmode = O_BINARY;
101
102         WSADATA wsaData;
103
104         /* Initialize windows socket DLL for PBD::CrossThreadChannel
105          */
106
107         if (WSAStartup(MAKEWORD(1,1),&wsaData) != 0) {
108                 error << X_("Windows socket initialization failed with error: ") << WSAGetLastError() << endmsg;
109                 return false;
110         }
111
112         QPC::initialize();
113         test_timers_from_env ();
114
115         if (!PBD::MMCSS::initialize()) {
116                 PBD::info << X_("Unable to initialize MMCSS") << endmsg;
117         } else {
118                 PBD::info << X_("MMCSS Initialized") << endmsg;
119         }
120 #endif
121
122         if (!Glib::thread_supported()) {
123                 Glib::thread_init();
124         }
125
126         Gio::init ();
127
128         PBD::ID::init ();
129
130         setup_libpbd_enums ();
131
132         set_debug_options_from_env ();
133
134         /* this call is made by any call to XMLTree::read() and its cousins. It
135            sets the handling of blank space to match the libxml2 standard,
136            rather than the libxml1 version. Without this, the behavior is
137            defined by whoever calls it first.
138         */
139
140         xmlKeepBlanksDefault (0);
141
142         libpbd_initialized = true;
143         return true;
144 }
145
146 void
147 PBD::cleanup ()
148 {
149 #ifdef PLATFORM_WINDOWS
150         PBD::MMCSS::deinitialize ();
151         WSACleanup();
152 #endif
153
154         EnumWriter::destroy ();
155         FPU::destroy ();
156 }