The Pedigree Project 0.1
user/applications/uitest/main.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <cerrno>
21#include <cstdio>
22#include <optional>
23#include <poll.h>
24
25#include "demo-app.h"
26#include "libui/types.h"
27
28int main(int argc, char** argv) {
29 const std::optional<demo::Options> options = demo::parseOptions(argc, argv);
30 if (!options)
31 return 2;
32
33 libui::client::Client client = libui::client::Client::connect(options->socketPath);
34 if (!client.valid()) {
35 std::fprintf(stderr, "uitest could not connect to compositor\n");
36 return 1;
37 }
38
39 demo::Options redOptions = *options;
40 redOptions.title = "UI Test A";
41 redOptions.background = libui::packColor({255, 0, 0, 255});
42 std::optional<libui::client::Window> redResult = demo::createWindow(client, redOptions);
43 if (!redResult) {
44 std::fprintf(stderr, "uitest could not create red window\n");
45 return 1;
46 }
47
48 demo::Options greenOptions = *options;
49 greenOptions.title = "UI Test B";
50 greenOptions.x += 40;
51 greenOptions.y += 40;
52 greenOptions.background = libui::packColor({0, 255, 0, 255});
53 std::optional<libui::client::Window> greenResult = demo::createWindow(client, greenOptions);
54 if (!greenResult) {
55 std::fprintf(stderr, "uitest could not create green window\n");
56 return 1;
57 }
58
59 libui::client::Window& redWindow = redResult.value();
60 libui::client::Window& greenWindow = greenResult.value();
61 bool redClosed = false;
62 bool greenClosed = false;
63
64 redWindow.setWindowProc([&redClosed](libui::client::Window&, const libui::client::Event& event) {
65 if (event.type() == libui::client::Event::Type::Close) {
66 redClosed = true;
67 return true;
68 }
69 return false;
70 });
71 greenWindow.setWindowProc(
72 [&greenClosed](libui::client::Window&, const libui::client::Event& event) {
73 if (event.type() == libui::client::Event::Type::Close) {
74 greenClosed = true;
75 return true;
76 }
77 return false;
78 });
79
80 auto dispatchPending = [&] {
81 for (;;) {
82 bool progressed = false;
83 if (client.dispatch(redWindow, false, false))
84 progressed = true;
85 if (client.dispatch(greenWindow, false, false))
86 progressed = true;
87 if (!progressed || !client.hasPendingMessages())
88 break;
89 }
90 };
91
92 if (!client.setNonBlocking(true) || !client.paint(redWindow) || !client.paint(greenWindow))
93 return 1;
94
95 while ((!redClosed || !greenClosed) && client.valid()) {
96 if ((!redClosed && !client.paintDirty(redWindow)) ||
97 (!greenClosed && !client.paintDirty(greenWindow)))
98 return 1;
99
100 if (client.hasPendingMessages()) {
101 dispatchPending();
102 continue;
103 }
104
105 pollfd descriptor{client.descriptor(), POLLIN, 0};
106 const int result = ::poll(&descriptor, 1, 50);
107 if (result < 0) {
108 if (errno == EINTR)
109 continue;
110 break;
111 }
112 if (result == 0)
113 continue;
114 if (descriptor.revents & (POLLHUP | POLLERR | POLLNVAL))
115 break;
116 if (descriptor.revents & POLLIN)
117 dispatchPending();
118 }
119
120 return (redClosed && greenClosed) ? 0 : 1;
121}