1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6
7#include "base/basictypes.h"
8#include "remoting/base/constants.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11// X11 headers must be #included after gtest.h, since the X11 headers define
12// some macros that cause errors in gtest-type-util.h.
13#include <X11/Xlib.h>
14#include "remoting/host/linux/x_server_clipboard.h"
15
16namespace remoting {
17
18namespace {
19
20class ClipboardTestClient {
21 public:
22  ClipboardTestClient() : display_(NULL) {}
23  ~ClipboardTestClient() {}
24
25  void Init(Display* display) {
26    display_ = display;
27    clipboard_.Init(display,
28                    base::Bind(&ClipboardTestClient::OnClipboardChanged,
29                               base::Unretained(this)));
30  }
31
32  void SetClipboardData(const std::string& clipboard_data) {
33    clipboard_data_ = clipboard_data;
34    clipboard_.SetClipboard(kMimeTypeTextUtf8, clipboard_data);
35  }
36
37  void OnClipboardChanged(const std::string& mime_type,
38                          const std::string& data) {
39    clipboard_data_ = data;
40  }
41
42  // Process X events on the connection, returning true if any events were
43  // processed.
44  bool PumpXEvents() {
45    bool result = false;
46    while (XPending(display_)) {
47      XEvent event;
48      XNextEvent(display_, &event);
49      clipboard_.ProcessXEvent(&event);
50      result = true;
51    }
52    return result;
53  }
54
55  const std::string& clipboard_data() const { return clipboard_data_; }
56  Display* display() const { return display_; }
57
58 private:
59  std::string clipboard_data_;
60  XServerClipboard clipboard_;
61  Display* display_;
62
63  DISALLOW_COPY_AND_ASSIGN(ClipboardTestClient);
64};
65
66}  // namespace
67
68class XServerClipboardTest : public testing::Test {
69 public:
70  virtual void SetUp() OVERRIDE {
71    // XSynchronize() ensures that PumpXEvents() fully processes all X server
72    // requests and responses before returning to the caller.
73    Display* display1 = XOpenDisplay(NULL);
74    XSynchronize(display1, True);
75    client1_.Init(display1);
76    Display* display2 = XOpenDisplay(NULL);
77    XSynchronize(display2, True);
78    client2_.Init(display2);
79  }
80
81  virtual void TearDown() OVERRIDE {
82    XCloseDisplay(client1_.display());
83    XCloseDisplay(client2_.display());
84  }
85
86  void PumpXEvents() {
87    while (true) {
88      if (!client1_.PumpXEvents() && !client2_.PumpXEvents()) {
89        break;
90      }
91    }
92  }
93
94  ClipboardTestClient client1_;
95  ClipboardTestClient client2_;
96};
97
98// http://crbug.com/163428
99TEST_F(XServerClipboardTest, DISABLED_CopyPaste) {
100  // Verify clipboard data can be transferred more than once. Then verify that
101  // the code continues to function in the opposite direction (so client1_ will
102  // send then receive, and client2_ will receive then send).
103  client1_.SetClipboardData("Text1");
104  PumpXEvents();
105  EXPECT_EQ("Text1", client2_.clipboard_data());
106
107  client1_.SetClipboardData("Text2");
108  PumpXEvents();
109  EXPECT_EQ("Text2", client2_.clipboard_data());
110
111  client2_.SetClipboardData("Text3");
112  PumpXEvents();
113  EXPECT_EQ("Text3", client1_.clipboard_data());
114
115  client2_.SetClipboardData("Text4");
116  PumpXEvents();
117  EXPECT_EQ("Text4", client1_.clipboard_data());
118}
119
120}  // namespace remoting
121