File: xlib_support.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (96 lines) | stat: -rw-r--r-- 2,622 bytes parent folder | download | duplicates (6)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "library_loaders/xlib_loader.h"
#include "library_loaders/xlib_xcb_loader.h"

namespace x11 {

namespace {

int XlibErrorHandler(void*, void*) {
  DVLOG(1) << "Xlib error received";
  return 0;
}

XlibLoader* GetXlibLoader() {
  static base::NoDestructor<XlibLoader> xlib_loader;
  return xlib_loader.get();
}

XlibXcbLoader* GetXlibXcbLoader() {
  static base::NoDestructor<XlibXcbLoader> xlib_xcb_loader;
  return xlib_xcb_loader.get();
}

}  // namespace

DISABLE_CFI_DLSYM
void InitXlib() {
  auto* xlib_loader = GetXlibLoader();
  if (xlib_loader->loaded()) {
    return;
  }

  CHECK(xlib_loader->Load("libX11.so.6"));

  auto* xlib_xcb_loader = GetXlibXcbLoader();
  CHECK(xlib_xcb_loader->Load("libX11-xcb.so.1"));

  CHECK(xlib_loader->XInitThreads());

  // The default Xlib error handler calls exit(1), which we don't want.  This
  // shouldn't happen in the browser process since only XProto requests are
  // made, but in the GPU process, GLX can make Xlib requests, so setting an
  // error handler is necessary.  Importantly, there's also an IO error handler,
  // and Xlib always calls exit(1) with no way to change this behavior.
  SetXlibErrorHandler();
}

DISABLE_CFI_DLSYM
void SetXlibErrorHandler() {
  GetXlibLoader()->XSetErrorHandler(XlibErrorHandler);
}

DISABLE_CFI_DLSYM
void XlibFree(void* data) {
  GetXlibLoader()->XFree(data);
}

DISABLE_CFI_DLSYM
XlibDisplay::XlibDisplay(const std::string& address) {
  InitXlib();

  display_ = GetXlibLoader()->XOpenDisplay(address.empty() ? nullptr
                                                           : address.c_str());
}

DISABLE_CFI_DLSYM
XlibDisplay::~XlibDisplay() {
  if (!display_) {
    return;
  }

  auto* loader = GetXlibLoader();
  // Events are not processed on |display_|, so if any client asks to receive
  // events, they will just queue up and leak memory.  This check makes sure
  // |display_| never had any pending events before it is closed.
  CHECK(!loader->XPending(display_));
  // ExtractAsDangling clears the underlying pointer and returns another raw_ptr
  // instance that is allowed to dangle.
  loader->XCloseDisplay(display_.ExtractAsDangling());
}

DISABLE_CFI_DLSYM
struct xcb_connection_t* XlibDisplay::GetXcbConnection() {
  return GetXlibXcbLoader()->XGetXCBConnection(display_);
}

}  // namespace x11