diff --git a/backend/backend.c b/backend/backend.c index 3d84aa636..faf9bdea0 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -32,6 +32,10 @@ #include #endif +#if WLR_HAS_WSCONS_BACKEND +#include +#endif + #define WAIT_SESSION_TIMEOUT 10000 // ms void wlr_backend_init(struct wlr_backend *backend, @@ -287,6 +291,15 @@ static struct wlr_backend *attempt_libinput_backend(struct wlr_session *session) #endif } +static struct wlr_backend *attempt_wscons_backend(struct wlr_session *session) { +#if WLR_HAS_WSCONS_BACKEND + return wlr_wscons_backend_create(session); +#else + wlr_log(WLR_ERROR, "Cannot create wscons backend: disabled at compile-time"); + return NULL; +#endif +} + static bool attempt_backend_by_name(struct wl_event_loop *loop, struct wlr_backend *multi, char *name, struct wlr_session **session_ptr) { @@ -297,8 +310,9 @@ static bool attempt_backend_by_name(struct wl_event_loop *loop, backend = attempt_x11_backend(loop, NULL); } else if (strcmp(name, "headless") == 0) { backend = attempt_headless_backend(loop); - } else if (strcmp(name, "drm") == 0 || strcmp(name, "libinput") == 0) { - // DRM and libinput need a session + } else if (strcmp(name, "drm") == 0 || strcmp(name, "libinput") == 0 + || strcmp(name, "wscons") == 0) { + // DRM and libinput/wscons need a session if (*session_ptr == NULL) { *session_ptr = session_create_and_wait(loop); if (*session_ptr == NULL) { @@ -309,6 +323,8 @@ static bool attempt_backend_by_name(struct wl_event_loop *loop, if (strcmp(name, "libinput") == 0) { backend = attempt_libinput_backend(*session_ptr); + } else if (strcmp(name, "wscons") == 0) { + backend = attempt_wscons_backend(*session_ptr); } else { // attempt_drm_backend() adds the multi drm backends itself return attempt_drm_backend(multi, *session_ptr) != NULL; @@ -393,13 +409,24 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_event_loop *loop, goto success; } - // Attempt DRM+libinput + // Attempt DRM+libinput/wscons session = session_create_and_wait(loop); if (!session) { wlr_log(WLR_ERROR, "Failed to start a DRM session"); goto error; } +#if WLR_HAS_WSCONS_BACKEND + struct wlr_backend *wscons = attempt_wscons_backend(session); + if (!wscons) { + wlr_log(WLR_ERROR, "Failed to start wscons backend"); + goto error; + } + wlr_multi_backend_add(multi, wscons); + if (!auto_backend_monitor_create(multi, wscons)) { + goto error; + } +#else struct wlr_backend *libinput = attempt_libinput_backend(session); if (libinput) { wlr_multi_backend_add(multi, libinput); @@ -414,6 +441,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_event_loop *loop, wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to skip libinput"); goto error; } +#endif struct wlr_backend *primary_drm = attempt_drm_backend(multi, session); if (primary_drm == NULL) { diff --git a/backend/meson.build b/backend/meson.build index ed977d3b6..2d0011cb0 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -1,6 +1,6 @@ wlr_files += files('backend.c') -all_backends = ['drm', 'libinput', 'x11'] +all_backends = ['drm', 'libinput', 'x11', 'wscons'] backends = get_option('backends') if 'auto' in backends and get_option('auto_features').enabled() backends = all_backends @@ -8,10 +8,10 @@ elif 'auto' in backends and get_option('auto_features').disabled() backends = [] endif -session_required = 'drm' in backends or 'libinput' in backends or get_option('session').enabled() +session_required = 'drm' in backends or 'libinput' in backends or 'wscons' in backends or get_option('session').enabled() if get_option('session').disabled() if session_required - error('Session support is required for the DRM or libinput backends') + error('Session support is required for the DRM or libinput/wscons backends') endif session_required = disabler() endif diff --git a/backend/wscons/atKeynames.h b/backend/wscons/atKeynames.h new file mode 100644 index 000000000..2ce8b1fd6 --- /dev/null +++ b/backend/wscons/atKeynames.h @@ -0,0 +1,281 @@ +/* + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Thomas Roell not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Roell makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * Copyright (c) 1994-2003 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +#ifndef _ATKEYNAMES_H +#define _ATKEYNAMES_H + +#define XK_TECHNICAL +#define XK_KATAKANA + +/* + * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three) + * sets of scancodes. Set3 can only be generated by a MF keyboard. + * Set2 sends a makecode for keypress, and the same code prefixed by a + * F0 for keyrelease. This is a little bit ugly to handle. Thus we use + * here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes. + * Bit 7 ist set if the key is released. The code E0 switches to a + * different meaning to add the new MF cursorkeys, while not breaking old + * applications. E1 is another special prefix. Since I assume that there + * will be further versions of PC/XT scancode compatible keyboards, we + * may be in trouble one day. + * + * IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3. + * 2) Use the keyboards native set and translate it to common keysyms. + */ + +/* + * definition of the AT84/MF101/MF102 Keyboard: + * ============================================================ + * Defined Key Cap Glyphs Pressed value + * Key Name Main Also (hex) (dec) + * ---------------- ---------- ------- ------ ------ + */ + +#define KEY_Escape /* Escape 0x01 */ 1 +#define KEY_1 /* 1 ! 0x02 */ 2 +#define KEY_2 /* 2 @ 0x03 */ 3 +#define KEY_3 /* 3 # 0x04 */ 4 +#define KEY_4 /* 4 $ 0x05 */ 5 +#define KEY_5 /* 5 % 0x06 */ 6 +#define KEY_6 /* 6 ^ 0x07 */ 7 +#define KEY_7 /* 7 & 0x08 */ 8 +#define KEY_8 /* 8 * 0x09 */ 9 +#define KEY_9 /* 9 ( 0x0a */ 10 +#define KEY_0 /* 0 ) 0x0b */ 11 +#define KEY_Minus /* - (Minus) _ (Under) 0x0c */ 12 +#define KEY_Equal /* = (Equal) + 0x0d */ 13 +#define KEY_BackSpace /* Back Space 0x0e */ 14 +#define KEY_Tab /* Tab 0x0f */ 15 +#define KEY_Q /* Q 0x10 */ 16 +#define KEY_W /* W 0x11 */ 17 +#define KEY_E /* E 0x12 */ 18 +#define KEY_R /* R 0x13 */ 19 +#define KEY_T /* T 0x14 */ 20 +#define KEY_Y /* Y 0x15 */ 21 +#define KEY_U /* U 0x16 */ 22 +#define KEY_I /* I 0x17 */ 23 +#define KEY_O /* O 0x18 */ 24 +#define KEY_P /* P 0x19 */ 25 +#define KEY_LBrace /* [ { 0x1a */ 26 +#define KEY_RBrace /* ] } 0x1b */ 27 +#define KEY_Enter /* Enter 0x1c */ 28 +#define KEY_LCtrl /* Ctrl(left) 0x1d */ 29 +#define KEY_A /* A 0x1e */ 30 +#define KEY_S /* S 0x1f */ 31 +#define KEY_D /* D 0x20 */ 32 +#define KEY_F /* F 0x21 */ 33 +#define KEY_G /* G 0x22 */ 34 +#define KEY_H /* H 0x23 */ 35 +#define KEY_J /* J 0x24 */ 36 +#define KEY_K /* K 0x25 */ 37 +#define KEY_L /* L 0x26 */ 38 +#define KEY_SemiColon /* ;(SemiColon) :(Colon) 0x27 */ 39 +#define KEY_Quote /* ' (Apostr) " (Quote) 0x28 */ 40 +#define KEY_Tilde /* ` (Accent) ~ (Tilde) 0x29 */ 41 +#define KEY_ShiftL /* Shift(left) 0x2a */ 42 +#define KEY_BSlash /* \(BckSlash) |(VertBar)0x2b */ 43 +#define KEY_Z /* Z 0x2c */ 44 +#define KEY_X /* X 0x2d */ 45 +#define KEY_C /* C 0x2e */ 46 +#define KEY_V /* V 0x2f */ 47 +#define KEY_B /* B 0x30 */ 48 +#define KEY_N /* N 0x31 */ 49 +#define KEY_M /* M 0x32 */ 50 +#define KEY_Comma /* , (Comma) < (Less) 0x33 */ 51 +#define KEY_Period /* . (Period) >(Greater)0x34 */ 52 +#define KEY_Slash /* / (Slash) ? 0x35 */ 53 +#define KEY_ShiftR /* Shift(right) 0x36 */ 54 +#define KEY_KP_Multiply /* * 0x37 */ 55 +#define KEY_Alt /* Alt(left) 0x38 */ 56 +#define KEY_Space /* (SpaceBar) 0x39 */ 57 +#define KEY_CapsLock /* CapsLock 0x3a */ 58 +#define KEY_F1 /* F1 0x3b */ 59 +#define KEY_F2 /* F2 0x3c */ 60 +#define KEY_F3 /* F3 0x3d */ 61 +#define KEY_F4 /* F4 0x3e */ 62 +#define KEY_F5 /* F5 0x3f */ 63 +#define KEY_F6 /* F6 0x40 */ 64 +#define KEY_F7 /* F7 0x41 */ 65 +#define KEY_F8 /* F8 0x42 */ 66 +#define KEY_F9 /* F9 0x43 */ 67 +#define KEY_F10 /* F10 0x44 */ 68 +#define KEY_NumLock /* NumLock 0x45 */ 69 +#define KEY_ScrollLock /* ScrollLock 0x46 */ 70 +#define KEY_KP_7 /* 7 Home 0x47 */ 71 +#define KEY_KP_8 /* 8 Up 0x48 */ 72 +#define KEY_KP_9 /* 9 PgUp 0x49 */ 73 +#define KEY_KP_Minus /* - (Minus) 0x4a */ 74 +#define KEY_KP_4 /* 4 Left 0x4b */ 75 +#define KEY_KP_5 /* 5 0x4c */ 76 +#define KEY_KP_6 /* 6 Right 0x4d */ 77 +#define KEY_KP_Plus /* + (Plus) 0x4e */ 78 +#define KEY_KP_1 /* 1 End 0x4f */ 79 +#define KEY_KP_2 /* 2 Down 0x50 */ 80 +#define KEY_KP_3 /* 3 PgDown 0x51 */ 81 +#define KEY_KP_0 /* 0 Insert 0x52 */ 82 +#define KEY_KP_Decimal /* . (Decimal) Delete 0x53 */ 83 +#define KEY_SysReqest /* SysReqest 0x54 */ 84 + /* NOTUSED 0x55 */ +#define KEY_Less /* < (Less) >(Greater) 0x56 */ 86 +#define KEY_F11 /* F11 0x57 */ 87 +#define KEY_F12 /* F12 0x58 */ 88 + +#define KEY_Prefix0 /* special 0x60 */ 96 +#define KEY_Prefix1 /* specail 0x61 */ 97 + +/* + * The 'scancodes' below are generated by the server, because the MF101/102 + * keyboard sends them as sequence of other scancodes + */ +#define KEY_Home /* Home 0x59 */ 89 +#define KEY_Up /* Up 0x5a */ 90 +#define KEY_PgUp /* PgUp 0x5b */ 91 +#define KEY_Left /* Left 0x5c */ 92 +#define KEY_Begin /* Begin 0x5d */ 93 +#define KEY_Right /* Right 0x5e */ 94 +#define KEY_End /* End 0x5f */ 95 +#define KEY_Down /* Down 0x60 */ 96 +#define KEY_PgDown /* PgDown 0x61 */ 97 +#define KEY_Insert /* Insert 0x62 */ 98 +#define KEY_Delete /* Delete 0x63 */ 99 +#define KEY_KP_Enter /* Enter 0x64 */ 100 +#define KEY_RCtrl /* Ctrl(right) 0x65 */ 101 +#define KEY_Pause /* Pause 0x66 */ 102 +#define KEY_Print /* Print 0x67 */ 103 +#define KEY_KP_Divide /* Divide 0x68 */ 104 +#define KEY_AltLang /* AtlLang(right) 0x69 */ 105 +#define KEY_Break /* Break 0x6a */ 106 +#define KEY_LMeta /* Left Meta 0x6b */ 107 +#define KEY_RMeta /* Right Meta 0x6c */ 108 +#define KEY_Menu /* Menu 0x6d */ 109 +#define KEY_F13 /* F13 0x6e */ 110 +#define KEY_F14 /* F14 0x6f */ 111 +#define KEY_F15 /* F15 0x70 */ 112 +#define KEY_HKTG /* Hirugana/Katakana tog 0x70 */ 112 +#define KEY_F16 /* F16 0x71 */ 113 +#define KEY_F17 /* F17 0x72 */ 114 +#define KEY_KP_DEC /* KP_DEC 0x73 */ 115 +#define KEY_BSlash2 /* \ _ 0x73 */ 115 +#define KEY_KP_Equal /* Equal (Keypad) 0x76 */ 118 +#define KEY_XFER /* Kanji Transfer 0x79 */ 121 +#define KEY_NFER /* No Kanji Transfer 0x7b */ 123 +#define KEY_Yen /* Yen 0x7d */ 125 + +#define KEY_Power /* Power Key 0x84 */ 132 +#define KEY_Mute /* Audio Mute 0x85 */ 133 +#define KEY_AudioLower /* Audio Lower 0x86 */ 134 +#define KEY_AudioRaise /* Audio Raise 0x87 */ 135 +#define KEY_Help /* Help 0x88 */ 136 +#define KEY_L1 /* Stop 0x89 */ 137 +#define KEY_L2 /* Again 0x8a */ 138 +#define KEY_L3 /* Props 0x8b */ 139 +#define KEY_L4 /* Undo 0x8c */ 140 +#define KEY_L5 /* Front 0x8d */ 141 +#define KEY_L6 /* Copy 0x8e */ 142 +#define KEY_L7 /* Open 0x8f */ 143 +#define KEY_L8 /* Paste 0x90 */ 144 +#define KEY_L9 /* Find 0x91 */ 145 +#define KEY_L10 /* Cut 0x92 */ 146 + +/* + * Fake 'scancodes' in the following ranges are generated for 2-byte + * codes not handled elsewhere. These correspond to most extended keys + * on so-called "Internet" keyboards: + * + * 0x79-0x93 + * 0x96-0xa1 + * 0xa3-0xac + * 0xb1-0xb4 + * 0xba-0xbd + * 0xc2 + * 0xcc-0xd2 + * 0xd6-0xf7 + */ + +/* + * Remapped 'scancodes' are generated for single-byte codes in the range + * 0x59-0x5f,0x62-0x76. These are used for some extra keys on some keyboards. + */ + +#define KEY_0x59 0x95 +#define KEY_0x5A 0xA2 +#define KEY_0x5B 0xAD +#define KEY_0x5C KEY_KP_EQUAL +#define KEY_0x5D 0xAE +#define KEY_0x5E 0xAF +#define KEY_0x5F 0xB0 +#define KEY_0x62 0xB5 +#define KEY_0x63 0xB6 +#define KEY_0x64 0xB7 +#define KEY_0x65 0xB8 +#define KEY_0x66 0xB9 +#define KEY_0x67 0xBE +#define KEY_0x68 0xBF +#define KEY_0x69 0xC0 +#define KEY_0x6A 0xC1 +#define KEY_0x6B 0xC3 +#define KEY_0x6C 0xC4 +#define KEY_0x6D 0xC5 +#define KEY_0x6E 0xC6 +#define KEY_0x6F 0xC7 +#define KEY_0x70 0xC8 +#define KEY_0x71 0xC9 +#define KEY_0x72 0xCA +#define KEY_0x73 0xCB +#define KEY_0x74 0xD3 +#define KEY_0x75 0xD4 +#define KEY_0x76 0xD5 +#define KEY_R_0xF4 0xF4 +#define KEY_R_0xF5 0xF5 + +/* These are for "notused" and "unknown" entries in translation maps. */ +#define KEY_NOTUSED 0 +#define KEY_UNKNOWN 255 + +#endif /* _ATKEYNAMES_H */ diff --git a/backend/wscons/backend.c b/backend/wscons/backend.c new file mode 100644 index 000000000..63a850df4 --- /dev/null +++ b/backend/wscons/backend.c @@ -0,0 +1,332 @@ +#define _BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "backend/wscons.h" +#include "util/time.h" + +#include "atKeynames.h" +#include "bsd_KbdMap.h" + +static struct wlr_wscons_backend *get_wscons_backend_from_backend( + struct wlr_backend *wlr_backend) { + assert(wlr_backend_is_wscons(wlr_backend)); + struct wlr_wscons_backend *backend = wl_container_of(wlr_backend, backend, backend); + return backend; +} + +static int ws_to_xkb(unsigned type, int key) { + switch (type) { + case WSKBD_TYPE_PC_XT: + case WSKBD_TYPE_PC_AT: + return wsXtMap[key]; + case WSKBD_TYPE_USB: + return wsUsbMap[key]; + default: + wlr_log(WLR_INFO, "Unknown wskbd type %d", type); + return key; + } +} + +static int wsmouse_to_evdev(int button) { + // The right and middle mouse buttons must be swapped + switch (button) { + case 1: // Middle + return 0x112; + case 2: // Right + return 0x111; + default: + return button + 0x110; + } +} + +static void notify_key(struct wlr_keyboard *wlr_kbd, uint32_t msec, + uint32_t state, uint32_t keycode) { + struct wlr_keyboard_key_event ev; + ev.update_state = true; + ev.time_msec = msec; + ev.state = state; + ev.keycode = keycode; + + wlr_keyboard_notify_key(wlr_kbd, &ev); +} + +static void notify_button(struct wlr_pointer *wlr_ptr, uint32_t msec, + uint32_t state, uint32_t button) { + struct wlr_pointer_button_event ev; + ev.pointer = wlr_ptr; + ev.time_msec = msec; + ev.button = button; + ev.state = state; + + wlr_pointer_notify_button(wlr_ptr, &ev); + wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr); +} + +static void notify_motion(struct wlr_pointer *wlr_ptr, uint32_t msec, + double x, double y) { + struct wlr_pointer_motion_event ev; + ev.pointer = wlr_ptr; + ev.time_msec = msec; + ev.delta_x = x; + ev.delta_y = y; + ev.unaccel_dx = x; + ev.unaccel_dy = y; + + wl_signal_emit_mutable(&wlr_ptr->events.motion, &ev); + wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr); +} + +static void notify_axis(struct wlr_pointer *wlr_ptr, uint32_t msec, + uint32_t axis, double delta) { + struct wlr_pointer_axis_event ev; + ev.pointer = wlr_ptr; + ev.time_msec = msec; + ev.source = WL_POINTER_AXIS_SOURCE_WHEEL; + ev.relative_direction = WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL; + ev.delta_discrete = 0; // XXX + ev.orientation = axis; + ev.delta = delta; + + wl_signal_emit_mutable(&wlr_ptr->events.axis, &ev); + wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr); +} + +static void notify_motion_abs(struct wlr_pointer *wlr_ptr, uint32_t msec, + double x, double y) { + struct wlr_pointer_motion_absolute_event ev; + ev.pointer = wlr_ptr; + ev.time_msec = msec; + ev.x = x; + ev.y = y; + + wl_signal_emit_mutable(&wlr_ptr->events.motion_absolute, &ev); + wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr); +} + +static void handle_event(struct wlr_wscons_backend *backend, struct wscons_event *ws_ev) { + struct wlr_keyboard *wlr_kbd = &backend->kbd; + struct wlr_pointer *wlr_ptr = &backend->mouse; + + uint32_t msec = timespec_to_msec(&ws_ev->time); + // TODO: make sure all types are handled + switch (ws_ev->type) { + case WSCONS_EVENT_KEY_UP: + notify_key(wlr_kbd, msec, WL_KEYBOARD_KEY_STATE_RELEASED, + ws_to_xkb(backend->kbd_type, ws_ev->value)); + break; + case WSCONS_EVENT_KEY_DOWN: + notify_key(wlr_kbd, msec, WL_KEYBOARD_KEY_STATE_PRESSED, + ws_to_xkb(backend->kbd_type, ws_ev->value)); + break; + case WSCONS_EVENT_MOUSE_UP: + notify_button(wlr_ptr, msec, WL_POINTER_BUTTON_STATE_RELEASED, + wsmouse_to_evdev(ws_ev->value)); + break; + case WSCONS_EVENT_MOUSE_DOWN: + notify_button(wlr_ptr, msec, WL_POINTER_BUTTON_STATE_PRESSED, + wsmouse_to_evdev(ws_ev->value)); + break; + case WSCONS_EVENT_MOUSE_DELTA_X: + notify_motion(wlr_ptr, msec, ws_ev->value, 0); + break; + case WSCONS_EVENT_MOUSE_DELTA_Y: + notify_motion(wlr_ptr, msec, 0, -ws_ev->value); + break; + case WSCONS_EVENT_MOUSE_DELTA_Z: + notify_axis(wlr_ptr, msec, WL_POINTER_AXIS_VERTICAL_SCROLL, + ws_ev->value * 10); + break; + case WSCONS_EVENT_MOUSE_DELTA_W: + notify_axis(wlr_ptr, msec, WL_POINTER_AXIS_HORIZONTAL_SCROLL, + ws_ev->value * 10); + break; + case WSCONS_EVENT_MOUSE_ABSOLUTE_X: + notify_motion_abs(wlr_ptr, msec, ws_ev->value, 0); + break; + case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: + notify_motion_abs(wlr_ptr, msec, 0, -ws_ev->value); + break; + case WSCONS_EVENT_ALL_KEYS_UP: + case WSCONS_EVENT_WSMOUSED_ON: + case WSCONS_EVENT_WSMOUSED_OFF: + break; + default: + wlr_log(WLR_DEBUG, "Unknown wscons event type: %x", ws_ev->type); + break; + } +} + +static int handle_wscons_readable(int fd, uint32_t mask, void *_backend) { + struct wlr_wscons_backend *backend = _backend; + + while (backend->session->active) { + struct kevent kq_ev; + static const struct timespec dontblock = {0}; + if (kevent(fd, NULL, 0, &kq_ev, 1, &dontblock) <= 0) { + return 0; + } + assert(kq_ev.filter == EVFILT_READ); + int in_fd = kq_ev.ident; + + struct wscons_event ws_ev; + if (read(in_fd, &ws_ev, sizeof(ws_ev)) <= 0) { + continue; + } + handle_event(backend, &ws_ev); + } + return 0; +} + +static void keyboard_set_leds(struct wlr_keyboard *wlr_kb, uint32_t leds) { + // TODO: use WSKBDIO_SETLEDS +} + +const struct wlr_keyboard_impl wscons_keyboard_impl = { + .name = "wscons-keyboard", + .led_update = keyboard_set_leds +}; + +const struct wlr_pointer_impl wscons_pointer_impl = { + .name = "wscons-pointer", +}; + +static int init_wscons(struct wlr_wscons_backend *backend) { + struct wlr_device *mouse_dev = wlr_session_open_file(backend->session, "/dev/wsmouse"); + struct wlr_device *kbd_dev = wlr_session_open_file(backend->session, "/dev/wskbd"); + if (!mouse_dev || !kbd_dev) { + wlr_log(WLR_ERROR, "Failed to open input devices"); + return -1; + } + + if (ioctl(kbd_dev->fd, WSKBDIO_GTYPE, &backend->kbd_type) == -1) { + // TODO: free + wlr_log(WLR_ERROR, "Failed to get keyboard type"); + return -1; + } + + int kfd = kqueue1(O_CLOEXEC); + if (kfd == -1) { + // TODO: free + wlr_log(WLR_ERROR, "Failed to create kqueue fd"); + return -1; + } + struct kevent evs[2]; + EV_SET(&evs[0], mouse_dev->fd, EVFILT_READ, EV_ADD, 0, 0, NULL); + EV_SET(&evs[1], kbd_dev->fd, EVFILT_READ, EV_ADD, 0, 0, NULL); + if (kevent(kfd, evs, sizeof(evs) / sizeof(evs[0]), NULL, 0, NULL) == -1) { + // TODO: free + wlr_log(WLR_ERROR, "Failed to setup kqueue"); + return -1; + } + + backend->mouse_dev = mouse_dev; + backend->kbd_dev = kbd_dev; + + struct wlr_keyboard *wlr_kbd = &backend->kbd; + wlr_keyboard_init(wlr_kbd, &wscons_keyboard_impl, "wscons-keyboard"); + wl_signal_emit_mutable(&backend->backend.events.new_input, &wlr_kbd->base); + + struct wlr_pointer *wlr_ptr = &backend->mouse; + wlr_pointer_init(wlr_ptr, &wscons_pointer_impl, "wscons-pointer"); + wl_signal_emit_mutable(&backend->backend.events.new_input, &wlr_ptr->base); + + return kfd; +} + +static bool backend_start(struct wlr_backend *wlr_backend) { + struct wlr_wscons_backend *backend = + get_wscons_backend_from_backend(wlr_backend); + wlr_log(WLR_DEBUG, "Starting wscons backend"); + + int fd = init_wscons(backend); + if (fd < 0) { + wlr_log(WLR_ERROR, "Failed to initialize wscons backend"); + return false; + } + backend->kqueue_fd = fd; + + if (backend->input_event) { + wl_event_source_remove(backend->input_event); + } + backend->input_event = wl_event_loop_add_fd(backend->session->event_loop, fd, + WL_EVENT_READABLE, handle_wscons_readable, backend); + if (!backend->input_event) { + wlr_log(WLR_ERROR, "Failed to create input event on event loop"); + return false; + } + wlr_log(WLR_DEBUG, "wscons successfully initialized"); + return true; +} + +static void backend_destroy(struct wlr_backend *wlr_backend) { + if (!wlr_backend) { + return; + } + struct wlr_wscons_backend *backend = + get_wscons_backend_from_backend(wlr_backend); + + wlr_backend_finish(wlr_backend); + + wl_list_remove(&backend->session_destroy.link); + + if (backend->input_event) { + wl_event_source_remove(backend->input_event); + } + + close(backend->kqueue_fd); + + if (backend->mouse_dev) { + wlr_session_close_file(backend->session, backend->mouse_dev); + } + if (backend->kbd_dev) { + wlr_session_close_file(backend->session, backend->kbd_dev); + } + + free(backend); +} + +static const struct wlr_backend_impl backend_impl = { + .start = backend_start, + .destroy = backend_destroy, +}; + +bool wlr_backend_is_wscons(const struct wlr_backend *b) { + return b->impl == &backend_impl; +} + +static void handle_session_destroy(struct wl_listener *listener, void *data) { + struct wlr_wscons_backend *backend = + wl_container_of(listener, backend, session_destroy); + backend_destroy(&backend->backend); +} + +struct wlr_backend *wlr_wscons_backend_create(struct wlr_session *session) { + struct wlr_wscons_backend *backend = calloc(1, sizeof(*backend)); + if (!backend) { + wlr_log(WLR_ERROR, "Allocation failed: %s", strerror(errno)); + return NULL; + } + wlr_backend_init(&backend->backend, &backend_impl); + + backend->session = session; + backend->kqueue_fd = -1; + + backend->session_destroy.notify = handle_session_destroy; + wl_signal_add(&session->events.destroy, &backend->session_destroy); + + return &backend->backend; +} diff --git a/backend/wscons/bsd_KbdMap.h b/backend/wscons/bsd_KbdMap.h new file mode 100644 index 000000000..467c5e2c5 --- /dev/null +++ b/backend/wscons/bsd_KbdMap.h @@ -0,0 +1,485 @@ +/* + * Slightly modified xf86KbdBSD.c which is + * + * Derived from xf86Kbd.c by S_ren Schmidt (sos@login.dkuug.dk) + * which is Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. + * and from xf86KbdCODrv.c by Holger Veit + */ + +#include + +static uint8_t wsUsbMap[] = { + /* 0 */ KEY_NOTUSED, + /* 1 */ KEY_NOTUSED, + /* 2 */ KEY_NOTUSED, + /* 3 */ KEY_NOTUSED, + /* 4 */ KEY_A, + /* 5 */ KEY_B, + /* 6 */ KEY_C, + /* 7 */ KEY_D, + /* 8 */ KEY_E, + /* 9 */ KEY_F, + /* 10 */ KEY_G, + /* 11 */ KEY_H, + /* 12 */ KEY_I, + /* 13 */ KEY_J, + /* 14 */ KEY_K, + /* 15 */ KEY_L, + /* 16 */ KEY_M, + /* 17 */ KEY_N, + /* 18 */ KEY_O, + /* 19 */ KEY_P, + /* 20 */ KEY_Q, + /* 21 */ KEY_R, + /* 22 */ KEY_S, + /* 23 */ KEY_T, + /* 24 */ KEY_U, + /* 25 */ KEY_V, + /* 26 */ KEY_W, + /* 27 */ KEY_X, + /* 28 */ KEY_Y, + /* 29 */ KEY_Z, + /* 30 */ KEY_1, /* 1 !*/ + /* 31 */ KEY_2, /* 2 @ */ + /* 32 */ KEY_3, /* 3 # */ + /* 33 */ KEY_4, /* 4 $ */ + /* 34 */ KEY_5, /* 5 % */ + /* 35 */ KEY_6, /* 6 ^ */ + /* 36 */ KEY_7, /* 7 & */ + /* 37 */ KEY_8, /* 8 * */ + /* 38 */ KEY_9, /* 9 ( */ + /* 39 */ KEY_0, /* 0 ) */ + /* 40 */ KEY_Enter, /* Return */ + /* 41 */ KEY_Escape, /* Escape */ + /* 42 */ KEY_BackSpace, /* Backspace Delete */ + /* 43 */ KEY_Tab, /* Tab */ + /* 44 */ KEY_Space, /* Space */ + /* 45 */ KEY_Minus, /* - _ */ + /* 46 */ KEY_Equal, /* = + */ + /* 47 */ KEY_LBrace, /* [ { */ + /* 48 */ KEY_RBrace, /* ] } */ + /* 49 */ KEY_BSlash, /* \ | */ + /* 50 */ KEY_BSlash, /* \ _ # ~ on some keyboards */ + /* 51 */ KEY_SemiColon, /* ; : */ + /* 52 */ KEY_Quote, /* ' " */ + /* 53 */ KEY_Tilde, /* ` ~ */ + /* 54 */ KEY_Comma, /* , < */ + /* 55 */ KEY_Period, /* . > */ + /* 56 */ KEY_Slash, /* / ? */ + /* 57 */ KEY_CapsLock, /* Caps Lock */ + /* 58 */ KEY_F1, /* F1 */ + /* 59 */ KEY_F2, /* F2 */ + /* 60 */ KEY_F3, /* F3 */ + /* 61 */ KEY_F4, /* F4 */ + /* 62 */ KEY_F5, /* F5 */ + /* 63 */ KEY_F6, /* F6 */ + /* 64 */ KEY_F7, /* F7 */ + /* 65 */ KEY_F8, /* F8 */ + /* 66 */ KEY_F9, /* F9 */ + /* 67 */ KEY_F10, /* F10 */ + /* 68 */ KEY_F11, /* F11 */ + /* 69 */ KEY_F12, /* F12 */ + /* 70 */ KEY_Print, /* PrintScrn SysReq */ + /* 71 */ KEY_ScrollLock, /* Scroll Lock */ + /* 72 */ KEY_Pause, /* Pause Break */ + /* 73 */ KEY_Insert, /* Insert XXX Help on some Mac Keyboards */ + /* 74 */ KEY_Home, /* Home */ + /* 75 */ KEY_PgUp, /* Page Up */ + /* 76 */ KEY_Delete, /* Delete */ + /* 77 */ KEY_End, /* End */ + /* 78 */ KEY_PgDown, /* Page Down */ + /* 79 */ KEY_Right, /* Right Arrow */ + /* 80 */ KEY_Left, /* Left Arrow */ + /* 81 */ KEY_Down, /* Down Arrow */ + /* 82 */ KEY_Up, /* Up Arrow */ + /* 83 */ KEY_NumLock, /* Num Lock */ + /* 84 */ KEY_KP_Divide, /* Keypad / */ + /* 85 */ KEY_KP_Multiply, /* Keypad * */ + /* 86 */ KEY_KP_Minus, /* Keypad - */ + /* 87 */ KEY_KP_Plus, /* Keypad + */ + /* 88 */ KEY_KP_Enter, /* Keypad Enter */ + /* 89 */ KEY_KP_1, /* Keypad 1 End */ + /* 90 */ KEY_KP_2, /* Keypad 2 Down */ + /* 91 */ KEY_KP_3, /* Keypad 3 Pg Down */ + /* 92 */ KEY_KP_4, /* Keypad 4 Left */ + /* 93 */ KEY_KP_5, /* Keypad 5 */ + /* 94 */ KEY_KP_6, /* Keypad 6 */ + /* 95 */ KEY_KP_7, /* Keypad 7 Home */ + /* 96 */ KEY_KP_8, /* Keypad 8 Up */ + /* 97 */ KEY_KP_9, /* KEypad 9 Pg Up */ + /* 98 */ KEY_KP_0, /* Keypad 0 Ins */ + /* 99 */ KEY_KP_Decimal, /* Keypad . Del */ + /* 100 */ KEY_Less, /* < > on some keyboards */ + /* 101 */ KEY_Menu, /* Menu */ + /* 102 */ KEY_Power, /* sleep key on Sun USB */ + /* 103 */ KEY_KP_Equal, /* Keypad = on Mac keyboards */ + /* 104 */ KEY_F13, + /* 105 */ KEY_F14, + /* 106 */ KEY_F15, + /* 107 */ KEY_F16, + /* 108 */ KEY_NOTUSED, + /* 109 */ KEY_Power, + /* 110 */ KEY_NOTUSED, + /* 111 */ KEY_NOTUSED, + /* 112 */ KEY_NOTUSED, + /* 113 */ KEY_NOTUSED, + /* 114 */ KEY_NOTUSED, + /* 115 */ KEY_NOTUSED, + /* 116 */ KEY_L7, + /* 117 */ KEY_Help, + /* 118 */ KEY_L3, + /* 119 */ KEY_L5, + /* 120 */ KEY_L1, + /* 121 */ KEY_L2, + /* 122 */ KEY_L4, + /* 123 */ KEY_L10, + /* 124 */ KEY_L6, + /* 125 */ KEY_L8, + /* 126 */ KEY_L9, + /* 127 */ KEY_Mute, + /* 128 */ KEY_AudioRaise, + /* 129 */ KEY_AudioLower, + /* 130 */ KEY_NOTUSED, + /* 131 */ KEY_NOTUSED, + /* 132 */ KEY_NOTUSED, + /* 133 */ KEY_NOTUSED, + /* 134 */ KEY_NOTUSED, +/* + * Special keycodes for Japanese keyboards + * Override atKeyname HKTG and BSlash2 code to unique values for JP106 keyboards + */ +#undef KEY_HKTG +#define KEY_HKTG 200 /* Japanese Hiragana Katakana Toggle */ +#undef KEY_BSlash2 +#define KEY_BSlash2 203 /* Japanese '\_' key */ + + /* 135 */ KEY_BSlash2, /* Japanese 106 kbd: '\_' */ + /* 136 */ KEY_HKTG, /* Japanese 106 kbd: Hiragana Katakana toggle */ + /* 137 */ KEY_Yen, /* Japanese 106 kbd: '\|' */ + /* 138 */ KEY_XFER, /* Japanese 106 kbd: Henkan */ + /* 139 */ KEY_NFER, /* Japanese 106 kbd: Muhenkan */ + /* 140 */ KEY_NOTUSED, + /* 141 */ KEY_NOTUSED, + /* 142 */ KEY_NOTUSED, + /* 143 */ KEY_NOTUSED, +/* + * Special keycodes for Korean keyboards + * Define Hangul and Hangul_Hanja unique key codes + * These keys also use KANA and EISU on some Macintosh Japanese USB keyboards + */ +#define KEY_Hangul 201 /* Also KANA Key on Mac JP USB kbd */ +#define KEY_Hangul_Hanja 202 /* Also EISU Key on Mac JP USB kbd */ + /* 144 */ KEY_Hangul, /* Korean 106 kbd: Hangul */ + /* 145 */ KEY_Hangul_Hanja, /* Korean 106 kbd: Hangul Hanja */ + /* 146 */ KEY_NOTUSED, + /* 147 */ KEY_NOTUSED, + /* 148 */ KEY_NOTUSED, + /* 149 */ KEY_NOTUSED, + /* 150 */ KEY_NOTUSED, + /* 151 */ KEY_NOTUSED, + /* 152 */ KEY_NOTUSED, + /* 153 */ KEY_NOTUSED, + /* 154 */ KEY_NOTUSED, + /* 155 */ KEY_NOTUSED, + /* 156 */ KEY_NOTUSED, + /* 157 */ KEY_NOTUSED, + /* 158 */ KEY_NOTUSED, + /* 159 */ KEY_NOTUSED, + /* 160 */ KEY_NOTUSED, + /* 161 */ KEY_NOTUSED, + /* 162 */ KEY_NOTUSED, + /* 163 */ KEY_NOTUSED, + /* 164 */ KEY_NOTUSED, + /* 165 */ KEY_NOTUSED, + /* 166 */ KEY_NOTUSED, + /* 167 */ KEY_NOTUSED, + /* 168 */ KEY_NOTUSED, + /* 169 */ KEY_NOTUSED, + /* 170 */ KEY_NOTUSED, + /* 171 */ KEY_NOTUSED, + /* 172 */ KEY_NOTUSED, + /* 173 */ KEY_NOTUSED, + /* 174 */ KEY_NOTUSED, + /* 175 */ KEY_NOTUSED, + /* 176 */ KEY_NOTUSED, + /* 177 */ KEY_NOTUSED, + /* 178 */ KEY_NOTUSED, + /* 179 */ KEY_NOTUSED, + /* 180 */ KEY_NOTUSED, + /* 181 */ KEY_NOTUSED, + /* 182 */ KEY_NOTUSED, + /* 183 */ KEY_NOTUSED, + /* 184 */ KEY_NOTUSED, + /* 185 */ KEY_NOTUSED, + /* 186 */ KEY_NOTUSED, + /* 187 */ KEY_NOTUSED, + /* 188 */ KEY_NOTUSED, + /* 189 */ KEY_NOTUSED, + /* 190 */ KEY_NOTUSED, + /* 191 */ KEY_NOTUSED, + /* 192 */ KEY_NOTUSED, + /* 193 */ KEY_NOTUSED, + /* 194 */ KEY_NOTUSED, + /* 195 */ KEY_NOTUSED, + /* 196 */ KEY_NOTUSED, + /* 197 */ KEY_NOTUSED, + /* 198 */ KEY_NOTUSED, + /* 199 */ KEY_NOTUSED, + /* 200 */ KEY_NOTUSED, + /* 201 */ KEY_NOTUSED, + /* 202 */ KEY_NOTUSED, + /* 203 */ KEY_NOTUSED, + /* 204 */ KEY_NOTUSED, + /* 205 */ KEY_NOTUSED, + /* 206 */ KEY_NOTUSED, + /* 207 */ KEY_NOTUSED, + /* 208 */ KEY_NOTUSED, + /* 209 */ KEY_NOTUSED, + /* 210 */ KEY_NOTUSED, + /* 211 */ KEY_NOTUSED, + /* 212 */ KEY_NOTUSED, + /* 213 */ KEY_NOTUSED, + /* 214 */ KEY_NOTUSED, + /* 215 */ KEY_NOTUSED, + /* 216 */ KEY_NOTUSED, + /* 217 */ KEY_NOTUSED, + /* 218 */ KEY_NOTUSED, + /* 219 */ KEY_NOTUSED, + /* 220 */ KEY_NOTUSED, + /* 221 */ KEY_NOTUSED, + /* 222 */ KEY_NOTUSED, + /* 223 */ KEY_NOTUSED, + /* 224 */ KEY_LCtrl, /* Left Control */ + /* 225 */ KEY_ShiftL, /* Left Shift */ + /* 226 */ KEY_Alt, /* Left Alt */ + /* 227 */ KEY_LMeta, /* Left Meta */ + /* 228 */ KEY_RCtrl, /* Right Control */ + /* 229 */ KEY_ShiftR, /* Right Shift */ + /* 230 */ KEY_AltLang, /* Right Alt, AKA AltGr */ + /* 231 */ KEY_LMeta, /* Right Meta XXX */ +}; + +static uint8_t wsXtMap[] = { + /* 0 */ KEY_NOTUSED, + /* 1 */ KEY_Escape, + /* 2 */ KEY_1, + /* 3 */ KEY_2, + /* 4 */ KEY_3, + /* 5 */ KEY_4, + /* 6 */ KEY_5, + /* 7 */ KEY_6, + /* 8 */ KEY_7, + /* 9 */ KEY_8, + /* 10 */ KEY_9, + /* 11 */ KEY_0, + /* 12 */ KEY_Minus, + /* 13 */ KEY_Equal, + /* 14 */ KEY_BackSpace, + /* 15 */ KEY_Tab, + /* 16 */ KEY_Q, + /* 17 */ KEY_W, + /* 18 */ KEY_E, + /* 19 */ KEY_R, + /* 20 */ KEY_T, + /* 21 */ KEY_Y, + /* 22 */ KEY_U, + /* 23 */ KEY_I, + /* 24 */ KEY_O, + /* 25 */ KEY_P, + /* 26 */ KEY_LBrace, + /* 27 */ KEY_RBrace, + /* 28 */ KEY_Enter, + /* 29 */ KEY_LCtrl, + /* 30 */ KEY_A, + /* 31 */ KEY_S, + /* 32 */ KEY_D, + /* 33 */ KEY_F, + /* 34 */ KEY_G, + /* 35 */ KEY_H, + /* 36 */ KEY_J, + /* 37 */ KEY_K, + /* 38 */ KEY_L, + /* 39 */ KEY_SemiColon, + /* 40 */ KEY_Quote, + /* 41 */ KEY_Tilde, + /* 42 */ KEY_ShiftL, + /* 43 */ KEY_BSlash, + /* 44 */ KEY_Z, + /* 45 */ KEY_X, + /* 46 */ KEY_C, + /* 47 */ KEY_V, + /* 48 */ KEY_B, + /* 49 */ KEY_N, + /* 50 */ KEY_M, + /* 51 */ KEY_Comma, + /* 52 */ KEY_Period, + /* 53 */ KEY_Slash, + /* 54 */ KEY_ShiftR, + /* 55 */ KEY_KP_Multiply, + /* 56 */ KEY_Alt, + /* 57 */ KEY_Space, + /* 58 */ KEY_CapsLock, + /* 59 */ KEY_F1, + /* 60 */ KEY_F2, + /* 61 */ KEY_F3, + /* 62 */ KEY_F4, + /* 63 */ KEY_F5, + /* 64 */ KEY_F6, + /* 65 */ KEY_F7, + /* 66 */ KEY_F8, + /* 67 */ KEY_F9, + /* 68 */ KEY_F10, + /* 69 */ KEY_NumLock, + /* 70 */ KEY_ScrollLock, + /* 71 */ KEY_KP_7, + /* 72 */ KEY_KP_8, + /* 73 */ KEY_KP_9, + /* 74 */ KEY_KP_Minus, + /* 75 */ KEY_KP_4, + /* 76 */ KEY_KP_5, + /* 77 */ KEY_KP_6, + /* 78 */ KEY_KP_Plus, + /* 79 */ KEY_KP_1, + /* 80 */ KEY_KP_2, + /* 81 */ KEY_KP_3, + /* 82 */ KEY_KP_0, + /* 83 */ KEY_KP_Decimal, + /* 84 */ KEY_NOTUSED, + /* 85 */ KEY_NOTUSED, + /* 86 */ KEY_Less, /* backslash on uk, < on german */ + /* 87 */ KEY_F11, + /* 88 */ KEY_F12, + /* 89 */ KEY_NOTUSED, + /* 90 */ KEY_NOTUSED, + /* 91 */ KEY_NOTUSED, + /* 92 */ KEY_NOTUSED, + /* 93 */ KEY_NOTUSED, + /* 94 */ KEY_NOTUSED, + /* 95 */ KEY_NOTUSED, + /* 96 */ KEY_NOTUSED, + /* 97 */ KEY_NOTUSED, + /* 98 */ KEY_NOTUSED, + /* 99 */ KEY_NOTUSED, + /* 100 */ KEY_NOTUSED, + /* 101 */ KEY_NOTUSED, + /* 102 */ KEY_NOTUSED, + /* 103 */ KEY_NOTUSED, + /* 104 */ KEY_NOTUSED, + /* 105 */ KEY_NOTUSED, + /* 106 */ KEY_NOTUSED, + /* 107 */ KEY_NOTUSED, + /* 108 */ KEY_NOTUSED, + /* 109 */ KEY_NOTUSED, + /* 110 */ KEY_NOTUSED, + /* 111 */ KEY_NOTUSED, + /* 112 */ KEY_NOTUSED, + /* 113 */ KEY_NOTUSED, + /* 114 */ KEY_NOTUSED, + /* 115 */ KEY_NOTUSED, + /* 116 */ KEY_NOTUSED, + /* 117 */ KEY_NOTUSED, + /* 118 */ KEY_NOTUSED, + /* 119 */ KEY_NOTUSED, + /* 120 */ KEY_NOTUSED, + /* 121 */ KEY_NOTUSED, + /* 122 */ KEY_NOTUSED, + /* 123 */ KEY_NOTUSED, + /* 124 */ KEY_NOTUSED, + /* 125 */ KEY_NOTUSED, + /* 126 */ KEY_NOTUSED, + /* 127 */ KEY_Pause, + /* 128 */ KEY_NOTUSED, + /* 129 */ KEY_NOTUSED, + /* 130 */ KEY_NOTUSED, + /* 131 */ KEY_NOTUSED, + /* 132 */ KEY_NOTUSED, + /* 133 */ KEY_NOTUSED, + /* 134 */ KEY_NOTUSED, + /* 135 */ KEY_NOTUSED, + /* 136 */ KEY_NOTUSED, + /* 137 */ KEY_NOTUSED, + /* 138 */ KEY_NOTUSED, + /* 139 */ KEY_NOTUSED, + /* 140 */ KEY_NOTUSED, + /* 141 */ KEY_NOTUSED, + /* 142 */ KEY_NOTUSED, + /* 143 */ KEY_NOTUSED, + /* 144 */ KEY_NOTUSED, + /* 145 */ KEY_NOTUSED, + /* 146 */ KEY_NOTUSED, + /* 147 */ KEY_NOTUSED, + /* 148 */ KEY_NOTUSED, + /* 149 */ KEY_NOTUSED, + /* 150 */ KEY_NOTUSED, + /* 151 */ KEY_NOTUSED, + /* 152 */ KEY_NOTUSED, + /* 153 */ KEY_NOTUSED, + /* 154 */ KEY_NOTUSED, + /* 155 */ KEY_NOTUSED, + /* 156 */ KEY_KP_Enter, + /* 157 */ KEY_RCtrl, + /* 158 */ KEY_NOTUSED, + /* 159 */ KEY_NOTUSED, + /* 160 */ KEY_Mute, + /* 161 */ KEY_NOTUSED, + /* 162 */ KEY_NOTUSED, + /* 163 */ KEY_NOTUSED, + /* 164 */ KEY_NOTUSED, + /* 165 */ KEY_NOTUSED, + /* 166 */ KEY_NOTUSED, + /* 167 */ KEY_NOTUSED, + /* 168 */ KEY_NOTUSED, + /* 169 */ KEY_NOTUSED, + /* 170 */ KEY_Print, + /* 171 */ KEY_NOTUSED, + /* 172 */ KEY_NOTUSED, + /* 173 */ KEY_NOTUSED, + /* 174 */ KEY_AudioLower, + /* 175 */ KEY_AudioRaise, + /* 176 */ KEY_NOTUSED, + /* 177 */ KEY_NOTUSED, + /* 178 */ KEY_NOTUSED, + /* 179 */ KEY_NOTUSED, + /* 180 */ KEY_NOTUSED, + /* 181 */ KEY_KP_Divide, + /* 182 */ KEY_NOTUSED, + /* 183 */ KEY_Print, + /* 184 */ KEY_AltLang, + /* 185 */ KEY_NOTUSED, + /* 186 */ KEY_NOTUSED, + /* 187 */ KEY_NOTUSED, + /* 188 */ KEY_NOTUSED, + /* 189 */ KEY_NOTUSED, + /* 190 */ KEY_NOTUSED, + /* 191 */ KEY_NOTUSED, + /* 192 */ KEY_NOTUSED, + /* 193 */ KEY_NOTUSED, + /* 194 */ KEY_NOTUSED, + /* 195 */ KEY_NOTUSED, + /* 196 */ KEY_NOTUSED, + /* 197 */ KEY_NOTUSED, + /* 198 */ KEY_NOTUSED, + /* 199 */ KEY_Home, + /* 200 */ KEY_Up, + /* 201 */ KEY_PgUp, + /* 202 */ KEY_NOTUSED, + /* 203 */ KEY_Left, + /* 204 */ KEY_NOTUSED, + /* 205 */ KEY_Right, + /* 206 */ KEY_NOTUSED, + /* 207 */ KEY_End, + /* 208 */ KEY_Down, + /* 209 */ KEY_PgDown, + /* 210 */ KEY_Insert, + /* 211 */ KEY_Delete, + /* 212 */ KEY_NOTUSED, + /* 213 */ KEY_NOTUSED, + /* 214 */ KEY_NOTUSED, + /* 215 */ KEY_NOTUSED, + /* 216 */ KEY_NOTUSED, + /* 217 */ KEY_NOTUSED, + /* 218 */ KEY_NOTUSED, + /* 219 */ KEY_LMeta, + /* 220 */ KEY_RMeta, + /* 221 */ KEY_Menu, +}; diff --git a/backend/wscons/meson.build b/backend/wscons/meson.build new file mode 100644 index 000000000..f4d4731e1 --- /dev/null +++ b/backend/wscons/meson.build @@ -0,0 +1,9 @@ +platform = target_machine.system() +if platform != 'openbsd' + subdir_done() +endif + +wlr_files += files('atKeynames.h') +wlr_files += files('bsd_KbdMap.h') +wlr_files += files('backend.c') +features += { 'wscons-backend': true } diff --git a/include/backend/wscons.h b/include/backend/wscons.h new file mode 100644 index 000000000..b8c807b3b --- /dev/null +++ b/include/backend/wscons.h @@ -0,0 +1,32 @@ +#ifndef BACKEND_WSCONS_H +#define BACKEND_WSCONS_H + +#include +#include +#include +#include +#include +#include + +struct wlr_wscons_backend { + struct wlr_backend backend; + + struct wlr_device *mouse_dev; + struct wlr_device *kbd_dev; + + struct wlr_keyboard kbd; + struct wlr_pointer mouse; + + unsigned kbd_type; + int kqueue_fd; + + struct wlr_session *session; + + struct wl_event_source *input_event; + struct wl_listener session_destroy; +}; + +extern const struct wlr_keyboard_impl wscons_keyboard_impl; +extern const struct wlr_pointer_impl wscons_pointer_impl; + +#endif diff --git a/include/meson.build b/include/meson.build index 165166c33..20376e026 100644 --- a/include/meson.build +++ b/include/meson.build @@ -23,6 +23,9 @@ endif if not features.get('session') exclude_files += 'backend/session.h' endif +if not features.get('wscons-backend') + exclude_files += 'backend/wscons.h' +endif install_subdir('wlr', install_dir: get_option('includedir') / versioned_name, diff --git a/include/wlr/backend/wscons.h b/include/wlr/backend/wscons.h new file mode 100644 index 000000000..817445061 --- /dev/null +++ b/include/wlr/backend/wscons.h @@ -0,0 +1,23 @@ +/* + * This an unstable interface of wlroots. No guarantees are made regarding the + * future consistency of this API. + */ +#ifndef WLR_USE_UNSTABLE +#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" +#endif + +#ifndef WLR_BACKEND_WSCONS_H +#define WLR_BACKEND_WSCONS_H + +#include +#include +#include + +struct wlr_input_device; + +struct wlr_backend *wlr_wscons_backend_create(struct wlr_session *session); + +bool wlr_backend_is_wscons(const struct wlr_backend *backend); +bool wlr_input_device_is_wscons(struct wlr_input_device *device); + +#endif diff --git a/include/wlr/config.h.in b/include/wlr/config.h.in index 8c9f7bbde..dc5ddb48c 100644 --- a/include/wlr/config.h.in +++ b/include/wlr/config.h.in @@ -15,6 +15,13 @@ * Required for . */ #mesondefine WLR_HAS_LIBINPUT_BACKEND +/** + * Whether the wscons backend is compile-time enabled. Equivalent to the + * pkg-config "have_wscons_backend" vartiable. + * + * Required for . + */ +#mesondefine WLR_HAS_WSCONS_BACKEND /** * Whether the X11 backend is compile-time enabled. Equivalent to the * pkg-config "have_x11_backend" variable. diff --git a/meson.build b/meson.build index ae63986b5..f199c2b4d 100644 --- a/meson.build +++ b/meson.build @@ -70,6 +70,7 @@ features = { 'drm-backend': false, 'x11-backend': false, 'libinput-backend': false, + 'wscons-backend': false, 'xwayland': false, 'gles2-renderer': false, 'vulkan-renderer': false, diff --git a/meson.options b/meson.options index d8a8ca940..7fdc21ef2 100644 --- a/meson.options +++ b/meson.options @@ -3,7 +3,7 @@ option('xwayland', type: 'feature', value: 'auto', yield: true, description: 'En option('examples', type: 'boolean', value: true, description: 'Build example applications') option('icon_directory', description: 'Location used to look for cursors (default: ${datadir}/icons)', type: 'string', value: '') option('renderers', type: 'array', choices: ['auto', 'gles2', 'vulkan'], value: ['auto'], description: 'Select built-in renderers') -option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11'], value: ['auto'], description: 'Select built-in backends') +option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11', 'wscons'], value: ['auto'], description: 'Select built-in backends') option('allocators', type: 'array', choices: ['auto', 'gbm', 'udmabuf'], value: ['auto'], description: 'Select built-in allocators') option('session', type: 'feature', value: 'auto', description: 'Enable session support')