summaryrefslogtreecommitdiffstats
path: root/widget/gtk/GfxInfoUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gtk/GfxInfoUtils.h')
-rw-r--r--widget/gtk/GfxInfoUtils.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/widget/gtk/GfxInfoUtils.h b/widget/gtk/GfxInfoUtils.h
new file mode 100644
index 0000000000..b6174842f2
--- /dev/null
+++ b/widget/gtk/GfxInfoUtils.h
@@ -0,0 +1,100 @@
+/* vim: se cin sw=2 ts=2 et : */
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WIDGET_GTK_GFXINFO_UTILS_h__
+#define WIDGET_GTK_GFXINFO_UTILS_h__
+
+// An alternative to mozilla::Unused for use in (a) C code and (b) code where
+// linking with unused.o is difficult.
+#define MOZ_UNUSED(expr) \
+ do { \
+ if (expr) { \
+ (void)0; \
+ } \
+ } while (0)
+
+#define LOG_PIPE 2
+
+static bool enable_logging = false;
+static void log(const char* format, ...) {
+ if (!enable_logging) {
+ return;
+ }
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+static int output_pipe = 1;
+static void close_logging() {
+ // we want to redirect to /dev/null stdout, stderr, and while we're at it,
+ // any PR logging file descriptors. To that effect, we redirect all positive
+ // file descriptors up to what open() returns here. In particular, 1 is stdout
+ // and 2 is stderr.
+ int fd = open("/dev/null", O_WRONLY);
+ for (int i = 1; i < fd; i++) {
+ if (output_pipe != i) {
+ dup2(fd, i);
+ }
+ }
+ close(fd);
+}
+
+// C++ standard collides with C standard in that it doesn't allow casting void*
+// to function pointer types. So the work-around is to convert first to size_t.
+// http://www.trilithium.com/johan/2004/12/problem-with-dlsym/
+template <typename func_ptr_type>
+static func_ptr_type cast(void* ptr) {
+ return reinterpret_cast<func_ptr_type>(reinterpret_cast<size_t>(ptr));
+}
+
+#define BUFFER_SIZE_STEP 4000
+
+static char* test_buf = nullptr;
+static int test_bufsize = 0;
+static int test_length = 0;
+
+static void record_value(const char* format, ...) {
+ if (!test_buf || test_length + BUFFER_SIZE_STEP / 2 > test_bufsize) {
+ test_bufsize += BUFFER_SIZE_STEP;
+ test_buf = (char*)realloc(test_buf, test_bufsize);
+ }
+ int remaining = test_bufsize - test_length;
+
+ // Append the new values to the buffer, not to exceed the remaining space.
+ va_list args;
+ va_start(args, format);
+ int max_added = vsnprintf(test_buf + test_length, remaining, format, args);
+ va_end(args);
+
+ if (max_added >= remaining) {
+ test_length += remaining;
+ } else {
+ test_length += max_added;
+ }
+}
+
+static void record_error(const char* str) { record_value("ERROR\n%s\n", str); }
+
+static void record_warning(const char* str) {
+ record_value("WARNING\n%s\n", str);
+}
+
+static void record_flush() {
+ if (!test_buf) {
+ return;
+ }
+ MOZ_UNUSED(write(output_pipe, test_buf, test_length));
+ if (enable_logging) {
+ MOZ_UNUSED(write(LOG_PIPE, test_buf, test_length));
+ }
+ free(test_buf);
+ test_buf = nullptr;
+}
+
+#endif /* WIDGET_GTK_GFXINFO_h__ */