Ejemplo n.º 1
0
        private void Run()
        {
            _libDevFd = libinput_get_fd(_libInputContext);

            var timeval = stackalloc IntPtr[2];

            foreach (var f in Directory.GetFiles("/dev/input", "event*"))
            {
                if (this.Log().IsEnabled(LogLevel.Debug))
                {
                    this.Log().Debug($"Opening input device {f}");
                }

                libinput_path_add_device(_libInputContext, f);
            }

            while (!_cts.IsCancellationRequested)
            {
                IntPtr rawEvent;
                libinput_dispatch(_libInputContext);
                while ((rawEvent = libinput_get_event(_libInputContext)) != IntPtr.Zero)
                {
                    var type = libinput_event_get_type(rawEvent);

                    if (this.Log().IsEnabled(LogLevel.Trace))
                    {
                        this.Log().Trace($"Got event type (0x{rawEvent:X16}) {type}");
                    }

                    if (type >= LIBINPUT_EVENT_TOUCH_DOWN &&
                        type <= LIBINPUT_EVENT_TOUCH_CANCEL)
                    {
                        ProcessTouchEvent(rawEvent, type);
                    }

                    if (type >= LIBINPUT_EVENT_POINTER_MOTION &&
                        type <= LIBINPUT_EVENT_POINTER_AXIS)
                    {
                        ProcessMouseEvent(rawEvent, type);
                    }

                    if (type == LIBINPUT_EVENT_KEYBOARD_KEY)
                    {
                        ProcessKeyboardEvent(rawEvent, type);
                    }

                    libinput_event_destroy(rawEvent);
                    libinput_dispatch(_libInputContext);
                }

                var pfd = new pollfd {
                    fd = _libDevFd, events = 1
                };
                Libc.poll(&pfd, (IntPtr)1, -1);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Polls a File Descriptor for the passed in flags.
        /// </summary>
        /// <param name="fd">The descriptor to poll</param>
        /// <param name="flags">The flags to poll for</param>
        /// <param name="timeout">The amount of time to wait; -1 for infinite, 0 for immediate return, and a positive number is the number of milliseconds</param>
        /// <param name="resultFlags">The flags that were returned by the poll call</param>
        /// <returns>
        /// Returns a positive number (which is the number of structures with nonzero revent files), 0 for a timeout or no
        /// descriptors were ready, or -1 on error.
        /// </returns>
        internal unsafe static int poll(int fd, PollFlags flags, int timeout, out PollFlags resultFlags)
        {
            pollfd pfd = default(pollfd);

            pfd.fd     = fd;
            pfd.events = flags;
            int result = poll(&pfd, 1, timeout);

            resultFlags = pfd.revents;
            return(result);
        }
Ejemplo n.º 3
0
        public static int Poll(this Socket socket, IntPtr ringFd, int timeoutMs)
        {
            var pollFds = new pollfd[1];

            pollFds[0].fd     = ringFd;
            pollFds[0].events = (short)(PollEvents.POLLIN | PollEvents.POLLPRI);

            var result = poll(pollFds, (uint)pollFds.Length, timeoutMs);

            return(result);
        }
Ejemplo n.º 4
0
 void setupInternalHandles(Span <pollfd> waitHandles, int startIndex)
 {
     waitHandles[startIndex] = new pollfd()
     {
         fd = pendingQueue.queues.encodedQueueHandle, events = ePollEvents.POLLIN
     };
     waitHandles[startIndex + 1] = new pollfd()
     {
         fd = shutdownEvent, events = ePollEvents.POLLIN
     };
     waitHandles[startIndex + 2] = new pollfd()
     {
         fd = seekEventHandle, events = ePollEvents.POLLIN
     };
 }
Ejemplo n.º 5
0
                public void Dispose()
                {
                    _parent._eglDisplay.GlInterface.Flush();
                    _parent._eglSurface.SwapBuffers();

                    var nextBo = gbm_surface_lock_front_buffer(_parent._gbmTargetSurface);

                    if (nextBo == IntPtr.Zero)
                    {
                        // Not sure what else can be done
                        Console.WriteLine("gbm_surface_lock_front_buffer failed");
                    }
                    else
                    {
                        var  fb             = _parent.GetFbIdForBo(nextBo);
                        bool waitingForFlip = true;

                        drmModePageFlip(_parent._card.Fd, _parent._crtcId, fb, DrmModePageFlip.Event, null);

                        DrmEventPageFlipHandlerDelegate flipCb =
                            (int fd, uint sequence, uint tv_sec, uint tv_usec, void *user_data) =>
                        {
                            waitingForFlip = false;
                        };
                        var cbHandle = GCHandle.Alloc(flipCb);
                        var ctx      = new DrmEventContext
                        {
                            version = 4, page_flip_handler = Marshal.GetFunctionPointerForDelegate(flipCb)
                        };
                        while (waitingForFlip)
                        {
                            var pfd = new pollfd {
                                events = 1, fd = _parent._card.Fd
                            };
                            poll(&pfd, new IntPtr(1), -1);
                            drmHandleEvent(_parent._card.Fd, &ctx);
                        }

                        cbHandle.Free();
                        gbm_surface_release_buffer(_parent._gbmTargetSurface, _parent._currentBo);
                        _parent._currentBo = nextBo;
                    }
                    _parent._eglDisplay.ClearContext();
                }
Ejemplo n.º 6
0
        private unsafe void InputThread(IntPtr ctx)
        {
            var fd = libinput_get_fd(ctx);

            var timeval = stackalloc IntPtr[2];


            foreach (var f in Directory.GetFiles("/dev/input", "event*"))
            {
                libinput_path_add_device(ctx, f);
            }
            while (true)
            {
                IntPtr ev;
                libinput_dispatch(ctx);
                while ((ev = libinput_get_event(ctx)) != IntPtr.Zero)
                {
                    var type = libinput_event_get_type(ev);
                    if (type >= LibInputEventType.LIBINPUT_EVENT_TOUCH_DOWN &&
                        type <= LibInputEventType.LIBINPUT_EVENT_TOUCH_CANCEL)
                    {
                        HandleTouch(ev, type);
                    }

                    if (type >= LibInputEventType.LIBINPUT_EVENT_POINTER_MOTION &&
                        type <= LibInputEventType.LIBINPUT_EVENT_POINTER_AXIS)
                    {
                        HandlePointer(ev, type);
                    }

                    libinput_event_destroy(ev);
                    libinput_dispatch(ctx);
                }

                pollfd pfd = new pollfd {
                    fd = fd, events = 1
                };
                NativeUnsafeMethods.poll(&pfd, new IntPtr(1), 10);
            }
        }
Ejemplo n.º 7
0
        public override void Run()
        {
            var fds = new pollfd[1];

            fds[0].fd     = udev_monitor_get_fd(monitor);
            fds[0].events = pollev.IN;
            while (true)
            {
                int ret = retry(() => poll(fds, (IntPtr)fds.Length, -1));
                if (ret == -1)
                {
                    // FIXME: how do we notify the main program that something bad happened here?
                    break;
                }
                var device = udev_monitor_receive_device(monitor);
                try {
                    var action  = udev_device_get_action(device);
                    var syspath = udev_device_get_syspath(device);
                    switch (action)
                    {
                    case "add":
                        if (syspath != null)
                        {
                            paths.Add(syspath);
                        }
                        break;

                    case "remove":
                        paths.Remove(syspath);
                        break;
                    }
                } finally {
                    udev_device_unref(device);
                }
            }
        }
Ejemplo n.º 8
0
 public static extern int poll(ref pollfd fds, uint nfds, int timeout);
Ejemplo n.º 9
0
 public static extern int poll(ref pollfd fd, uint nfds, int timeout = -1); // < 0 if failed
Ejemplo n.º 10
0
 private static unsafe extern int poll(pollfd* fds, uint count, int timeout);
Ejemplo n.º 11
0
 public static extern int poll(ref pollfd fds, IntPtr nfds, int timeout);
Ejemplo n.º 12
0
        private void runLinux(Control control)
        {
            this.mainControl = control;

            if (userCanvasSize.IsEmpty)
            {
                // Create physical canvas with actual terminal size
                winsize ws = Libc.GetTerminalSize(isDarwin);
                canvas = new PhysicalCanvas(ws.ws_col, ws.ws_row);
            }
            else
            {
                canvas = new PhysicalCanvas(userCanvasSize.Width, userCanvasSize.Height);
            }
            renderer.Canvas          = canvas;
            renderer.RootElementRect = userRootElementRect.IsEmpty
                ? new Rect(canvas.Size) : userRootElementRect;
            renderer.RootElement = mainControl;
            //
            mainControl.Invalidate();

            // Terminal initialization sequence

            // This is magic workaround to avoid messing up terminal after program finish
            // The bug is described at https://bugzilla.xamarin.com/show_bug.cgi?id=15118
            bool ignored = Console.KeyAvailable;

            IntPtr stdscr = NCurses.initscr();

            NCurses.cbreak();
            NCurses.noecho();
            NCurses.nonl();
            NCurses.intrflush(stdscr, false);
            NCurses.keypad(stdscr, true);
            NCurses.start_color();

            HideCursor();
            try {
                renderer.UpdateLayout( );
                renderer.FinallyApplyChangesToCanvas(  );

                termkeyHandle = LibTermKey.termkey_new(0, TermKeyFlag.TERMKEY_FLAG_SPACESYMBOL);

                // Setup the input mode
                Console.Write("\x1B[?1002h");
                pollfd fd = new pollfd( );
                fd.fd     = 0;
                fd.events = POLL_EVENTS.POLLIN;

                pollfd[] fds = new pollfd[2];
                fds[0] = fd;
                fds[1] = new pollfd( );
                int pipeResult = Libc.pipe(pipeFds);
                if (pipeResult == -1)
                {
                    throw new InvalidOperationException("Cannot create self-pipe.");
                }
                fds[1].fd     = pipeFds[0];
                fds[1].events = POLL_EVENTS.POLLIN;

                try {
#if !WIN32
                    // Catch SIGWINCH to handle terminal resizing
                    UnixSignal[] signals = new UnixSignal [] {
                        new UnixSignal(Signum.SIGWINCH)
                    };
                    Thread signal_thread = new Thread(delegate() {
                        while (true)
                        {
                            // Wait for a signal to be delivered
                            int index     = UnixSignal.WaitAny(signals, -1);
                            Signum signal = signals [index].Signum;
                            Libc.writeInt64(pipeFds[1], 2);
                        }
                    }
                                                      );
                    signal_thread.IsBackground = false;
                    signal_thread.Start();
#endif
                    TermKeyKey key = new TermKeyKey( );
                    //
                    this.running      = true;
                    this.mainThreadId = Thread.CurrentThread.ManagedThreadId;
                    //
                    int nextwait = -1;
                    while (true)
                    {
                        int pollRes = Libc.poll(fds, 2, nextwait);
                        if (pollRes == 0)
                        {
                            if (nextwait == -1)
                            {
                                throw new InvalidOperationException("Assertion failed.");
                            }
                            if (TermKeyResult.TERMKEY_RES_KEY == LibTermKey.termkey_getkey_force(termkeyHandle, ref key))
                            {
                                processLinuxInput(key);
                            }
                        }
                        if (pollRes == -1)
                        {
                            int errorCode = Marshal.GetLastWin32Error();
                            if (errorCode != Libc.EINTR)
                            {
                                throw new InvalidOperationException(string.Format("poll() returned with error code {0}", errorCode));
                            }
                        }

                        if (fds[1].revents != POLL_EVENTS.NONE)
                        {
                            UInt64 u;
                            Libc.readInt64(fds[1].fd, out u);
                            if (u == 1)
                            {
                                // Exit from application
#if !WIN32
                                signal_thread.Abort();
#endif
                                break;
                            }
                            if (u == 2)
                            {
                                // Get new term size and process appropriate INPUT_RECORD event
                                INPUT_RECORD inputRecord = new INPUT_RECORD( );
                                inputRecord.EventType = EventType.WINDOW_BUFFER_SIZE_EVENT;

                                winsize ws = Libc.GetTerminalSize(isDarwin);

                                inputRecord.WindowBufferSizeEvent.dwSize.X = ( short )ws.ws_col;
                                inputRecord.WindowBufferSizeEvent.dwSize.Y = ( short )ws.ws_row;
                                processInputEvent(inputRecord);
                            }
                            if (u == 3)
                            {
                                // It is signal from async actions invocation stuff
                            }
                        }

                        if ((fds[0].revents & POLL_EVENTS.POLLIN) == POLL_EVENTS.POLLIN ||
                            (fds[0].revents & POLL_EVENTS.POLLHUP) == POLL_EVENTS.POLLHUP ||
                            (fds[0].revents & POLL_EVENTS.POLLERR) == POLL_EVENTS.POLLERR)
                        {
                            LibTermKey.termkey_advisereadable(termkeyHandle);
                        }

                        TermKeyResult result = (LibTermKey.termkey_getkey(termkeyHandle, ref key));
                        while (result == TermKeyResult.TERMKEY_RES_KEY)
                        {
                            processLinuxInput(key);
                            result = (LibTermKey.termkey_getkey(termkeyHandle, ref key));
                        }

                        if (result == TermKeyResult.TERMKEY_RES_AGAIN)
                        {
                            nextwait = LibTermKey.termkey_get_waittime(termkeyHandle);
                        }
                        else
                        {
                            nextwait = -1;
                        }

                        while (true)
                        {
                            bool anyInvokeActions      = isAnyInvokeActions( );
                            bool anyRoutedEvent        = !EventManager.IsQueueEmpty( );
                            bool anyLayoutToRevalidate = renderer.AnyControlInvalidated;

                            if (!anyInvokeActions && !anyRoutedEvent && !anyLayoutToRevalidate)
                            {
                                break;
                            }

                            EventManager.ProcessEvents();
                            processInvokeActions(  );
                            renderer.UpdateLayout(  );
                        }

                        renderer.FinallyApplyChangesToCanvas( );
                    }
                } finally {
                    LibTermKey.termkey_destroy(termkeyHandle);
                    Libc.close(pipeFds[0]);
                    Libc.close(pipeFds[1]);
                    Console.Write("\x1B[?1002l");
                }
            } finally {
                // Restore cursor visibility before exit
                ShowCursor( );
                NCurses.endwin( );
            }

            renderer.RootElement = null;
        }
Ejemplo n.º 13
0
        public static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(() => {
                Thread.Sleep(TimeSpan.FromSeconds(5));
                Console.WriteLine("Message from thread");
                int res = LibTermKey.writeInt64(eventfd, 1);
                Console.WriteLine("write(1) returned {0}\n", res);
                if (res == -1)
                {
                    int lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    Console.WriteLine("Last error is {0}\n", lastError);
                }
            }));

            thread.IsBackground = true;
            thread.Start();

            IntPtr handle = LibTermKey.termkey_new(0, TermKeyFlag.TERMKEY_FLAG_SPACESYMBOL);

            Console.Write("\x1B[?1002h");
            pollfd fd = new pollfd();

            fd.fd     = 0;
            fd.events = POLL_EVENTS.POLLIN;

            pollfd[] fds = new pollfd[2];
            fds[0] = fd;

            fds[1]  = new pollfd();
            eventfd = LibTermKey.eventfd(0, EVENTFD_FLAGS.EFD_CLOEXEC);
            if (eventfd == -1)
            {
                Console.WriteLine("Cannot create eventfd\n");
                int lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                Console.WriteLine("Last error is {0}\n", lastError);
            }
            fds[1].fd     = eventfd;
            fds[1].events = POLL_EVENTS.POLLIN;

            TermKeyKey key = new TermKeyKey();

            while (true)
            {
                int pollRes = LibTermKey.poll(fds, 2, -1);
                if (0 == pollRes)
                {
                    // timed out
                    Console.WriteLine("Timed out");
                    if (LibTermKey.termkey_getkey_force(handle, ref key) == TermKeyResult.TERMKEY_RES_KEY)
                    {
                        Console.WriteLine("got TERMKEY_RES_KEY");
                    }
                }
                else if (-1 == pollRes)
                {
                    int errorCode = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    Console.WriteLine(string.Format("ErrorCode = {0}", errorCode));
                }
                Console.WriteLine(string.Format("PollRes is {0}", pollRes));

                for (int i = 0; i < 2; i++)
                {
                    if (fds[i].revents != POLL_EVENTS.NONE)
                    {
                        if (i == 1)
                        {
                            UInt64 u;
                            LibTermKey.readInt64(fds[i].fd, out u);
                            Console.WriteLine("Readed eventfd counter : {0}\n", u);
                        }
                    }
                }

                if ((fds[0].revents & POLL_EVENTS.POLLIN) == POLL_EVENTS.POLLIN ||
                    (fds[0].revents & POLL_EVENTS.POLLHUP) == POLL_EVENTS.POLLHUP ||
                    (fds[0].revents & POLL_EVENTS.POLLERR) == POLL_EVENTS.POLLERR)
                {
                    // todo : log return value
                    LibTermKey.termkey_advisereadable(handle);
                }

                TermKeyResult result;
                while ((result = LibTermKey.termkey_getkey(handle, ref key)) == TermKeyResult.TERMKEY_RES_KEY)
                {
                    Console.WriteLine("Received some key.");
                    string descr = String.Format("Type : {0} Modifiers: {1} Utf8 bytes: {2}{3}{4}{5}{6}{7}{8}",
                                                 key.type, key.modifiers, key.utf8_0,
                                                 key.utf8_1, key.utf8_2, key.utf8_3,
                                                 key.utf8_4, key.utf8_5, key.utf8_6);
                    //dump the retrieved structure
                    //byte[] buffer = new byte[30];
                    //IntPtr nativeBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(30);
                    //System.Runtime.InteropServices.Marshal.StructureToPtr(key, nativeBuffer, false);
                    //System.Runtime.InteropServices.Marshal.Copy(nativeBuffer, buffer, 0, 30);
                    //for (int i = 0; i < 30; i++ ) {
                    //	Console.Write("{0} ", buffer[i]);
                    //	if ((i + 1) % 10 == 0)
                    //		Console.WriteLine();
                    //}
                    //System.Runtime.InteropServices.Marshal.FreeHGlobal(nativeBuffer);
                    Console.WriteLine(descr);
                    if (key.type == TermKeyType.TERMKEY_TYPE_UNICODE)
                    {
                        byte[] data = new byte[7];
                        data[0] = key.utf8_0;
                        data[1] = key.utf8_1;
                        data[2] = key.utf8_2;
                        data[3] = key.utf8_3;
                        data[4] = key.utf8_4;
                        data[5] = key.utf8_5;
                        data[6] = key.utf8_6;
                        string d = System.Text.Encoding.UTF8.GetString(data);
                        Console.WriteLine(String.Format("Unicode symbol : {0}", d));
                    }
                    else if (key.type == TermKeyType.TERMKEY_TYPE_MOUSE)
                    {
                        TermKeyMouseEvent ev;
                        int button;
                        int line, col;
                        LibTermKey.termkey_interpret_mouse(handle, ref key, out ev, out button, out line, out col);
                        Console.WriteLine("MouseEvent : {0} (button {1}) at {2}:{3}", ev, button, line, col);
                    }
                }
            }

            LibTermKey.termkey_destroy(handle);
            LibTermKey.close(eventfd);
        }