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 15int 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