private void InputThreadLoop(object semaphore) { Debug.Print("[Input] Running on thread {0}", Thread.CurrentThread.ManagedThreadId); Setup(); // Inform the parent thread that initialization has completed successfully (semaphore as Semaphore).Release(); Debug.Print("[Input] Released main thread.", input_context); // Use a blocking poll for input messages, in order to reduce CPU usage var poll_fd = new PollFD(); poll_fd.fd = fd; poll_fd.events = PollFlags.In; Debug.Print("[Input] Created PollFD({0}, {1})", poll_fd.fd, poll_fd.events); Debug.Print("[Input] Entering input loop.", poll_fd.fd, poll_fd.events); while (Interlocked.Read(ref exit) == 0) { var ret = Libc.poll(ref poll_fd, 1, -1); var error = (ErrorNumber)Marshal.GetLastWin32Error(); var is_error = ret < 0 && !(error == ErrorNumber.Again || error == ErrorNumber.Interrupted) || (poll_fd.revents & (PollFlags.Hup | PollFlags.Error | PollFlags.Invalid)) != 0; // We need to query the desktop bounds in order to position the mouse cursor correctly. // This value will be used for the current bunch of input events. If a monitor changes // resolution in the meantime, we might be slightly off in our calculations - this error // will be corrected when the next bunch of input events arrives. UpdateDisplayBounds(); if (ret > 0 && (poll_fd.revents & (PollFlags.In | PollFlags.Pri)) != 0) { ProcessEvents(input_context); } if (is_error) { Debug.Print("[Input] Exiting input loop {0} due to poll error [ret:{1} events:{2}]. Error: {3}.", input_thread.ManagedThreadId, ret, poll_fd.revents, error); Interlocked.Increment(ref exit); } } Debug.Print("[Input] Exited input loop.", poll_fd.fd, poll_fd.events); }
private void WaitFlip(bool block) { PollFD fds = new PollFD(); fds.fd = fd; fds.events = PollFlags.In; EventContext evctx = new EventContext(); evctx.version = EventContext.Version; evctx.page_flip_handler = PageFlipPtr; int timeout = block ? -1 : 0; while (is_flip_queued) { fds.revents = 0; if (Libc.poll(ref fds, 1, timeout) < 0) { break; } if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0) { break; } if ((fds.revents & PollFlags.In) != 0) { Drm.HandleEvent(fd, ref evctx); } else { break; } } // Page flip has taken place, update buffer objects if (!is_flip_queued) { IntPtr gbm_surface = WindowInfo.Handle; Gbm.ReleaseBuffer(gbm_surface, bo); bo = bo_next; } }
public static int poll(ref PollFD fd, int fd_count, int timeout) { return poll(ref fd, (IntPtr)fd_count, timeout); }
public static extern int poll(ref PollFD fd, IntPtr fd_count, int timeout);
void WaitFlip(bool block) { PollFD fds = new PollFD(); fds.fd = fd; fds.events = PollFlags.In; EventContext evctx = new EventContext(); evctx.version = EventContext.Version; evctx.page_flip_handler = PageFlipPtr; int timeout = block ? -1 : 0; while (is_flip_queued) { fds.revents = 0; if (Libc.poll(ref fds, 1, timeout) < 0) break; if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0) break; if ((fds.revents & PollFlags.In) != 0) Drm.HandleEvent(fd, ref evctx); else break; } // Page flip has taken place, update buffer objects if (!is_flip_queued) { IntPtr gbm_surface = WindowInfo.Handle; Gbm.ReleaseBuffer(gbm_surface, bo); bo = bo_next; } }
public static int poll(ref PollFD fd, int fd_count, int timeout) { return(poll(ref fd, (IntPtr)fd_count, timeout)); }
void InputThreadLoop(object semaphore) { Debug.Print("[Input] Running on thread {0}", Thread.CurrentThread.ManagedThreadId); Setup(); // Inform the parent thread that initialization has completed successfully (semaphore as Semaphore).Release(); Debug.Print("[Input] Released main thread.", input_context); // Use a blocking poll for input messages, in order to reduce CPU usage PollFD poll_fd = new PollFD(); poll_fd.fd = fd; poll_fd.events = PollFlags.In; Debug.Print("[Input] Created PollFD({0}, {1})", poll_fd.fd, poll_fd.events); Debug.Print("[Input] Entering input loop.", poll_fd.fd, poll_fd.events); while (Interlocked.Read(ref exit) == 0) { int ret = Libc.poll(ref poll_fd, 1, -1); ErrorNumber error = (ErrorNumber)Marshal.GetLastWin32Error(); bool is_error = ret < 0 && !(error == ErrorNumber.Again || error == ErrorNumber.Interrupted) || (poll_fd.revents & (PollFlags.Hup | PollFlags.Error | PollFlags.Invalid)) != 0; // We need to query the desktop bounds in order to position the mouse cursor correctly. // This value will be used for the current bunch of input events. If a monitor changes // resolution in the meantime, we might be slightly off in our calculations - this error // will be corrected when the next bunch of input events arrives. UpdateDisplayBounds(); if (ret > 0 && (poll_fd.revents & (PollFlags.In | PollFlags.Pri)) != 0) { ProcessEvents(input_context); } if (is_error) { Debug.Print("[Input] Exiting input loop {0} due to poll error [ret:{1} events:{2}]. Error: {3}.", input_thread.ManagedThreadId, ret, poll_fd.revents, error); Interlocked.Increment(ref exit); } } Debug.Print("[Input] Exited input loop.", poll_fd.fd, poll_fd.events); }