1 /*
2
3 * Copyright 2016 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "include/core/SkTypes.h"
10 #include "include/private/SkTHash.h"
11 #include "tools/sk_app/Application.h"
12 #include "tools/sk_app/unix/Window_unix.h"
13 #include "tools/timer/Timer.h"
14
main(int argc,char ** argv)15 int main(int argc, char**argv) {
16 XInitThreads();
17 Display* display = XOpenDisplay(nullptr);
18
19 sk_app::Application* app = sk_app::Application::Create(argc, argv, (void*)display);
20
21 // Get the file descriptor for the X display
22 const int x11_fd = ConnectionNumber(display);
23
24 bool done = false;
25 while (!done) {
26 if (0 == XPending(display)) {
27 // Only call select() when we have no events.
28
29 // Create a file description set containing x11_fd
30 fd_set in_fds;
31 FD_ZERO(&in_fds);
32 FD_SET(x11_fd, &in_fds);
33
34 // Set a sleep timer
35 struct timeval tv;
36 tv.tv_usec = 10;
37 tv.tv_sec = 0;
38
39 // Wait for an event on the file descriptor or for timer expiration
40 (void)select(1, &in_fds, nullptr, nullptr, &tv);
41 }
42
43 // Handle all pending XEvents (if any) and flush the input
44 // Only handle a finite number of events before finishing resize and paint..
45 if (int count = XPending(display)) {
46 // collapse any Expose and Resize events.
47 SkTHashSet<sk_app::Window_unix*> pendingWindows;
48 while (count-- && !done) {
49 XEvent event;
50 XNextEvent(display, &event);
51
52 sk_app::Window_unix* win = sk_app::Window_unix::gWindowMap.find(event.xany.window);
53 if (!win) {
54 continue;
55 }
56
57 // paint and resize events get collapsed
58 switch (event.type) {
59 case Expose:
60 win->markPendingPaint();
61 pendingWindows.add(win);
62 break;
63 case ConfigureNotify:
64 win->markPendingResize(event.xconfigurerequest.width,
65 event.xconfigurerequest.height);
66 pendingWindows.add(win);
67 break;
68 default:
69 if (win->handleEvent(event)) {
70 done = true;
71 }
72 break;
73 }
74 }
75 pendingWindows.foreach([](sk_app::Window_unix* win) {
76 win->finishResize();
77 win->finishPaint();
78 });
79 } else {
80 // We are only really "idle" when the timer went off with zero events.
81 app->onIdle();
82 }
83
84 XFlush(display);
85 }
86
87 delete app;
88
89 XCloseDisplay(display);
90
91 return 0;
92 }
93