summaryrefslogtreecommitdiff
path: root/chromium/ui/gfx/x/xproto_util.cc
blob: e08bf4f6b5a0205b60b8b45154e2edbdb3a4a2e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/x/xproto_util.h"

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/xproto.h"

namespace x11 {

void LogErrorEventDescription(const XErrorEvent& error_event) {
  // This function may make some expensive round trips (XListExtensions,
  // XQueryExtension), but the only effect this function has is LOG(WARNING),
  // so early-return if the log would never be sent anyway.
  if (!LOG_IS_ON(WARNING))
    return;

  char error_str[256];
  char request_str[256];

  XDisplay* dpy = error_event.display;
  x11::Connection* conn = x11::Connection::Get();
  XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str));

  strncpy(request_str, "Unknown", sizeof(request_str));
  if (error_event.request_code < 128) {
    std::string num = base::NumberToString(error_event.request_code);
    XGetErrorDatabaseText(dpy, "XRequest", num.c_str(), "Unknown", request_str,
                          sizeof(request_str));
  } else {
    if (auto response = conn->ListExtensions({}).Sync()) {
      for (const auto& str : response->names) {
        int ext_code, first_event, first_error;
        const char* name = str.name.c_str();
        XQueryExtension(dpy, name, &ext_code, &first_event, &first_error);
        if (error_event.request_code == ext_code) {
          std::string msg =
              base::StringPrintf("%s.%d", name, error_event.minor_code);
          XGetErrorDatabaseText(dpy, "XRequest", msg.c_str(), "Unknown",
                                request_str, sizeof(request_str));
          break;
        }
      }
    }
  }

  LOG(WARNING) << "X error received: "
               << "serial " << error_event.serial << ", "
               << "error_code " << static_cast<int>(error_event.error_code)
               << " (" << error_str << "), "
               << "request_code " << static_cast<int>(error_event.request_code)
               << ", "
               << "minor_code " << static_cast<int>(error_event.minor_code)
               << " (" << request_str << ")";
}

}  // namespace x11