Serenity Operating System
at master 130 lines 4.4 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Debug.h> 8#include <Kernel/API/MousePacket.h> 9#include <WindowServer/ConnectionFromClient.h> 10#include <WindowServer/Cursor.h> 11#include <WindowServer/EventLoop.h> 12#include <WindowServer/Screen.h> 13#include <WindowServer/WMConnectionFromClient.h> 14#include <WindowServer/WindowManager.h> 15#include <fcntl.h> 16#include <stdio.h> 17#include <unistd.h> 18 19namespace WindowServer { 20 21EventLoop::EventLoop() 22{ 23 m_keyboard_fd = open("/dev/input/keyboard/0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); 24 m_mouse_fd = open("/dev/input/mouse/0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); 25 26 m_window_server = MUST(IPC::MultiServer<ConnectionFromClient>::try_create("/tmp/portal/window")); 27 m_wm_server = MUST(IPC::MultiServer<WMConnectionFromClient>::try_create("/tmp/portal/wm")); 28 29 if (m_keyboard_fd >= 0) { 30 m_keyboard_notifier = Core::Notifier::construct(m_keyboard_fd, Core::Notifier::Read); 31 m_keyboard_notifier->on_ready_to_read = [this] { drain_keyboard(); }; 32 } else { 33 dbgln("Couldn't open /dev/input/keyboard/0"); 34 } 35 36 if (m_mouse_fd >= 0) { 37 m_mouse_notifier = Core::Notifier::construct(m_mouse_fd, Core::Notifier::Read); 38 m_mouse_notifier->on_ready_to_read = [this] { drain_mouse(); }; 39 } else { 40 dbgln("Couldn't open /dev/input/mouse/0"); 41 } 42} 43 44void EventLoop::drain_mouse() 45{ 46 auto& screen_input = ScreenInput::the(); 47 MousePacket state; 48 state.buttons = screen_input.mouse_button_state(); 49 MousePacket packets[32]; 50 51 ssize_t nread = read(m_mouse_fd, &packets, sizeof(packets)); 52 if (nread < 0) { 53 perror("EventLoop::drain_mouse read"); 54 return; 55 } 56 size_t npackets = nread / sizeof(MousePacket); 57 if (!npackets) 58 return; 59 60 bool state_is_sent = false; 61 for (size_t i = 0; i < npackets; ++i) { 62 auto& packet = packets[i]; 63 dbgln_if(WSMESSAGELOOP_DEBUG, "EventLoop: Mouse X {}, Y {}, Z {}, W {}, relative={}", packet.x, packet.y, packet.z, packet.w, packet.is_relative); 64 65 state.is_relative = packet.is_relative; 66 if (packet.is_relative) { 67 state.x += packet.x; 68 state.y -= packet.y; 69 } else { 70 state.x = packet.x; 71 state.y = packet.y; 72 } 73 state.w += packet.w; 74 state_is_sent = false; 75 76 // Invert scroll direction if checked in the settings. 77 if (WindowManager::the().is_natural_scroll()) 78 state.z -= packet.z; 79 else 80 state.z += packet.z; 81 82 if (packet.buttons != state.buttons) { 83 state.buttons = packet.buttons; 84 dbgln_if(WSMESSAGELOOP_DEBUG, "EventLoop: Mouse Button Event"); 85 86 // Swap primary (1) and secondary (2) buttons if checked in Settings. 87 // Doing the swap here avoids all emulator and hardware issues. 88 if (WindowManager::the().are_mouse_buttons_switched()) { 89 bool has_primary = state.buttons & MousePacket::Button::LeftButton; 90 bool has_secondary = state.buttons & MousePacket::Button::RightButton; 91 state.buttons = state.buttons & ~(MousePacket::Button::LeftButton | MousePacket::Button::RightButton); 92 // Invert the buttons: 93 if (has_primary) 94 state.buttons |= MousePacket::Button::RightButton; 95 if (has_secondary) 96 state.buttons |= MousePacket::Button::LeftButton; 97 } 98 99 screen_input.on_receive_mouse_data(state); 100 state_is_sent = true; 101 if (state.is_relative) { 102 state.x = 0; 103 state.y = 0; 104 state.z = 0; 105 state.w = 0; 106 } 107 } 108 } 109 if (state_is_sent) 110 return; 111 if (state.is_relative && (state.x || state.y || state.z || state.w)) 112 screen_input.on_receive_mouse_data(state); 113 if (!state.is_relative) 114 screen_input.on_receive_mouse_data(state); 115} 116 117void EventLoop::drain_keyboard() 118{ 119 auto& screen_input = ScreenInput::the(); 120 for (;;) { 121 ::KeyEvent event; 122 ssize_t nread = read(m_keyboard_fd, (u8*)&event, sizeof(::KeyEvent)); 123 if (nread == 0) 124 break; 125 VERIFY(nread == sizeof(::KeyEvent)); 126 screen_input.on_receive_keyboard_data(event); 127 } 128} 129 130}