/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkTypes.h" #include "include/private/SkTHash.h" #include "tools/sk_app/Application.h" #include "tools/sk_app/unix/Window_unix.h" #include "tools/timer/Timer.h" int main(int argc, char**argv) { XInitThreads(); Display* display = XOpenDisplay(nullptr); sk_app::Application* app = sk_app::Application::Create(argc, argv, (void*)display); // Get the file descriptor for the X display const int x11_fd = ConnectionNumber(display); bool done = false; while (!done) { if (0 == XPending(display)) { // Only call select() when we have no events. // Create a file description set containing x11_fd fd_set in_fds; FD_ZERO(&in_fds); FD_SET(x11_fd, &in_fds); // Set a sleep timer struct timeval tv; tv.tv_usec = 10; tv.tv_sec = 0; // Wait for an event on the file descriptor or for timer expiration (void)select(1, &in_fds, nullptr, nullptr, &tv); } // Handle all pending XEvents (if any) and flush the input // Only handle a finite number of events before finishing resize and paint.. if (int count = XPending(display)) { // collapse any Expose and Resize events. SkTHashSet pendingWindows; while (count-- && !done) { XEvent event; XNextEvent(display, &event); sk_app::Window_unix* win = sk_app::Window_unix::gWindowMap.find(event.xany.window); if (!win) { continue; } // paint and resize events get collapsed switch (event.type) { case Expose: win->markPendingPaint(); pendingWindows.add(win); break; case ConfigureNotify: win->markPendingResize(event.xconfigurerequest.width, event.xconfigurerequest.height); pendingWindows.add(win); break; default: if (win->handleEvent(event)) { done = true; } break; } } pendingWindows.foreach([](sk_app::Window_unix* win) { win->finishResize(); win->finishPaint(); }); } else { // We are only really "idle" when the timer went off with zero events. app->onIdle(); } XFlush(display); } delete app; XCloseDisplay(display); return 0; }