summaryrefslogtreecommitdiff
path: root/chromium/ui/gfx/x/connection.h
blob: a103b431d71ddefdbef890e3a66aac9f35a69880 (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
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// 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.

#ifndef UI_GFX_X_CONNECTION_H_
#define UI_GFX_X_CONNECTION_H_

#include <list>
#include <queue>

#include "base/component_export.h"
#include "ui/gfx/x/event.h"
#include "ui/gfx/x/extension_manager.h"
#include "ui/gfx/x/xproto.h"

namespace x11 {

// Represents a socket to the X11 server.
class COMPONENT_EXPORT(X11) Connection : public XProto,
                                         public ExtensionManager {
 public:
  class Delegate {
   public:
    virtual bool ShouldContinueStream() const = 0;
    virtual void DispatchXEvent(x11::Event* event) = 0;

   protected:
    virtual ~Delegate() = default;
  };

  // Gets or creates the singleton connection.
  static Connection* Get();

  explicit Connection();
  ~Connection();

  Connection(const Connection&) = delete;
  Connection(Connection&&) = delete;

  XDisplay* display() const { return display_; }
  xcb_connection_t* XcbConnection();

  uint32_t extended_max_request_length() const {
    return extended_max_request_length_;
  }

  const Setup& setup() const { return setup_; }
  const Screen& default_screen() const { return *default_screen_; }
  x11::Window default_root() const { return default_screen().root; }
  const Depth& default_root_depth() const { return *default_root_depth_; }
  const VisualType& default_root_visual() const {
    return *default_root_visual_;
  }

  int DefaultScreenId() const;

  template <typename T>
  T GenerateId() {
    return static_cast<T>(xcb_generate_id(XcbConnection()));
  }

  // Is the connection up and error-free?
  bool Ready() const;

  // Write all requests to the socket.
  void Flush();

  // Flush and block until the server has responded to all requests.
  void Sync();

  // Read all responses from the socket without blocking.
  void ReadResponses();

  // Are there any events, errors, or replies already buffered?
  bool HasPendingResponses() const;

  // Dispatch any buffered events, errors, or replies.
  void Dispatch(Delegate* delegate);

  // Access the event buffer.  Clients can add, delete, or modify events.
  std::list<Event>& events() { return events_; }

 private:
  friend class FutureBase;

  struct Request {
    Request(unsigned int sequence, FutureBase::ResponseCallback callback);
    Request(Request&& other);
    ~Request();

    const unsigned int sequence;
    FutureBase::ResponseCallback callback;
  };

  void AddRequest(unsigned int sequence, FutureBase::ResponseCallback callback);

  bool HasNextResponse() const;

  void PreDispatchEvent(const Event& event);

  int ScreenIndexFromRootWindow(x11::Window root) const;

  XDisplay* const display_;

  uint32_t extended_max_request_length_ = 0;

  Setup setup_;
  Screen* default_screen_ = nullptr;
  Depth* default_root_depth_ = nullptr;
  VisualType* default_root_visual_ = nullptr;

  std::list<Event> events_;

  std::queue<Request> requests_;
};

}  // namespace x11

#endif  // UI_GFX_X_CONNECTION_H_