swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 374e92246a19df53d4882d4ece39f31b4aabccee
parent 08b530bde8b5fa06dc069241a13a61979840220a
Author: nia <nia@netbsd.org>
Date:   Wed, 11 Dec 2019 16:23:11 +0000

NetBSD support w/ wscons input

Diffstat:
MMakefile | 8+++++---
Alaunch/devmajor-linux.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Alaunch/devmajor-netbsd.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alaunch/devmajor.h | 36++++++++++++++++++++++++++++++++++++
Mlaunch/launch.c | 43++++++++++++++++++++++++++++++-------------
Mlaunch/local.mk | 9++++++++-
Mlibswc/keyboard.c | 7++++---
Mlibswc/keyboard.h | 3++-
Mlibswc/local.mk | 15++++++++++-----
Alibswc/seat-ws.c | 451+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlibswc/seat.c | 2+-
Mlibswc/shm.c | 12+++++++++++-
Alibswc/wscons/atKeynames.h | 281+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibswc/wscons/bsd_KbdMap.h | 485+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14 files changed, 1462 insertions(+), 28 deletions(-)

diff --git a/Makefile b/Makefile @@ -28,15 +28,17 @@ include config.mk # Dependencies PACKAGES := \ libdrm \ - libinput \ pixman-1 \ wayland-server \ wayland-protocols \ wld \ xkbcommon -ifeq ($(ENABLE_LIBUDEV),1) -PACKAGES += libudev +ifneq ($(shell uname),NetBSD) + PACKAGES += libinput + ifeq ($(ENABLE_LIBUDEV),1) + PACKAGES += libudev + endif endif libinput_CONSTRAINTS := --atleast-version=0.4 diff --git a/launch/devmajor-linux.c b/launch/devmajor-linux.c @@ -0,0 +1,52 @@ +/* swc: launch/devmajor-linux.c + * + * Copyright (c) 2013, 2014, 2016 Michael Forney + * Copyright (c) 2020 Nia Alarie + * + * Based in part upon weston-launch.c from weston which is: + * + * Copyright © 2012 Benjamin Franzke + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + */ +#include <sys/sysmacros.h> +#include <linux/major.h> +#include "devmajor.h" + +#ifndef DRM_MAJOR +#define DRM_MAJOR 226 +#endif + +bool +device_is_input(dev_t rdev) +{ + return major(rdev) == INPUT_MAJOR; +} + +bool +device_is_tty(dev_t rdev) +{ + return major(rdev) == TTY_MAJOR; +} + +bool +device_is_drm(dev_t rdev) +{ + return major(rdev) == DRM_MAJOR; +} diff --git a/launch/devmajor-netbsd.c b/launch/devmajor-netbsd.c @@ -0,0 +1,86 @@ +/* swc: launch/devmajor-netbsd.c + * + * Copyright (c) 2020 Nia Alarie + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + */ +#include <sys/types.h> +#include <sys/sysctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "devmajor.h" + +static int +sysctl_devmajor(const char *devname) +{ + static int name[] = { CTL_KERN, KERN_DRIVERS }; + struct kinfo_drivers *drivers = NULL; + size_t i, len, newlen; + int major; + + if (sysctl(name, 2, NULL, &len, NULL, 0)) { + perror("sysctl"); + goto fail; + } + if ((drivers = calloc(sizeof(struct kinfo_drivers), len)) == NULL) { + perror("calloc"); + goto fail; + } + newlen = len; + if (sysctl(name, 2, drivers, &newlen, NULL, 0)) { + perror("sysctl"); + goto fail; + } + for (i = 0; i < len; ++i) { + if (strcmp(devname, drivers[i].d_name) == 0) { + major = drivers[i].d_cmajor; + free(drivers); + return major; + } + } +fail: + free(drivers); + return -1; +} + +bool +device_is_input(dev_t rdev) +{ + if (major(rdev) == sysctl_devmajor("wskbd")) + return true; + if (major(rdev) == sysctl_devmajor("wsmouse")) + return true; + if (major(rdev) == sysctl_devmajor("wsmux")) + return true; + return false; +} + +bool +device_is_tty(dev_t rdev) +{ + return major(rdev) == sysctl_devmajor("wsdisplay"); +} + +bool +device_is_drm(dev_t rdev) +{ + return major(rdev) == sysctl_devmajor("drm"); +} + diff --git a/launch/devmajor.h b/launch/devmajor.h @@ -0,0 +1,36 @@ +/* swc: launch/devmajor.h + * + * Copyright (c) 2020 Nia Alarie + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef DEVMAJOR_H +#define DEVMAJOR_H + +#include <sys/stat.h> +#include <stdbool.h> + +bool device_is_input(dev_t); + +bool device_is_tty(dev_t); + +bool device_is_drm(dev_t); + +#endif diff --git a/launch/launch.c b/launch/launch.c @@ -26,6 +26,7 @@ */ #include "protocol.h" +#include "devmajor.h" #include <errno.h> #include <fcntl.h> @@ -38,21 +39,25 @@ #include <stdnoreturn.h> #include <string.h> #include <unistd.h> +#include <signal.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/ioctl.h> +#include <sys/types.h> +#ifndef minor #include <sys/sysmacros.h> +#endif +#ifdef __NetBSD__ +#include <dev/wscons/wsdisplay_usl_io.h> +extern char **environ; +#else #include <linux/input.h> #include <linux/kd.h> -#include <linux/major.h> #include <linux/vt.h> -#include <xf86drm.h> - -#ifndef DRM_MAJOR -#define DRM_MAJOR 226 #endif +#include <xf86drm.h> #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array)[0]) @@ -116,8 +121,10 @@ stop_devices(bool fatal) die("drmDropMaster:"); } for (i = 0; i < num_input_fds; ++i) { +#ifdef EVIOCREVOKE if (ioctl(input_fds[i], EVIOCREVOKE, 0) < 0 && errno != ENODEV && fatal) die("ioctl EVIOCREVOKE:"); +#endif close(input_fds[i]); } num_input_fds = 0; @@ -216,8 +223,7 @@ handle_socket_data(int socket) goto fail; } - switch (major(st.st_rdev)) { - case INPUT_MAJOR: + if (device_is_input(st.st_rdev)) { if (!active) goto fail; if (num_input_fds == ARRAY_LENGTH(input_fds)) { @@ -225,16 +231,14 @@ handle_socket_data(int socket) goto fail; } input_fds[num_input_fds++] = fd; - break; - case DRM_MAJOR: + } else if (device_is_drm(st.st_rdev)) { if (num_drm_fds == ARRAY_LENGTH(drm_fds)) { fprintf(stderr, "too many DRM devices opened\n"); goto fail; } drm_fds[num_drm_fds++] = fd; - break; - default: - fprintf(stderr, "device is not an input device\n"); + } else { + fprintf(stderr, "requested fd is not a DRM or input device\n"); goto fail; } break; @@ -265,6 +269,10 @@ done: static void find_vt(char *vt, size_t size) { +#ifdef __NetBSD__ + if (snprintf(vt, size, "/dev/ttyE1") >= size) + die("VT number is too large"); +#else char *vtnr; int tty0_fd, vt_num; @@ -283,6 +291,7 @@ find_vt(char *vt, size_t size) if (snprintf(vt, size, "/dev/tty%s", vtnr) >= size) die("XDG_VTNR is too long"); } +#endif } static int @@ -317,19 +326,27 @@ setup_tty(int fd) if (fstat(fd, &st) == -1) die("failed to stat TTY fd:"); vt = minor(st.st_rdev); - if (major(st.st_rdev) != TTY_MAJOR || vt == 0) + + if (!device_is_tty(st.st_rdev) || vt == 0) die("not a valid VT"); if (ioctl(fd, VT_GETSTATE, &state) == -1) die("failed to get the current VT state:"); original_vt_state.vt = state.v_active; +#ifdef KDGETMODE if (ioctl(fd, KDGKBMODE, &original_vt_state.kb_mode)) die("failed to get keyboard mode:"); if (ioctl(fd, KDGETMODE, &original_vt_state.console_mode)) die("failed to get console mode:"); +#else + original_vt_state.kb_mode = K_XLATE; + original_vt_state.console_mode = KD_TEXT; +#endif +#ifdef K_OFF if (ioctl(fd, KDSKBMODE, K_OFF) == -1) die("failed to set keyboard mode to K_OFF:"); +#endif if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) { perror("failed to set console mode to KD_GRAPHICS"); goto error0; diff --git a/launch/local.mk b/launch/local.mk @@ -5,13 +5,20 @@ dir := launch $(dir)_TARGETS := $(dir)/swc-launch $(dir)_PACKAGES := libdrm -$(dir)/swc-launch: $(dir)/launch.o $(dir)/protocol.o +ifeq ($(shell uname),NetBSD) + DEVMAJOR_OBJ=devmajor-netbsd.o +else + DEVMAJOR_OBJ=devmajor-linux.o +endif + +$(dir)/swc-launch: $(dir)/$(DEVMAJOR_OBJ) $(dir)/launch.o $(dir)/protocol.o $(link) $(launch_PACKAGE_LIBS) install-$(dir): $(dir)/swc-launch | $(DESTDIR)$(BINDIR) install -m 4755 launch/swc-launch $(DESTDIR)$(BINDIR) CLEAN_FILES += $(dir)/launch.o +CLEAN_FILES += $(dir)/$(DEVMAJOR_OBJ) include common.mk diff --git a/libswc/keyboard.c b/libswc/keyboard.c @@ -150,7 +150,8 @@ update_keymap(struct xkb *xkb) unlink(keymap_path); - if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0) { + if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0 && + ftruncate(xkb->keymap.fd, xkb->keymap.size) != 0) { WARNING("Could not resize XKB keymap file\n"); goto error2; } @@ -176,7 +177,7 @@ error0: } struct keyboard * -keyboard_create(void) +keyboard_create(struct xkb_rule_names *names) { struct keyboard *keyboard; struct xkb *xkb; @@ -191,7 +192,7 @@ keyboard_create(void) goto error1; } - if (!(xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, NULL, 0))) { + if (!(xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, names, 0))) { ERROR("Could not create XKB keymap\n"); goto error2; } diff --git a/libswc/keyboard.h b/libswc/keyboard.h @@ -26,6 +26,7 @@ #include "input.h" +#include <xkbcommon/xkbcommon.h> #include <wayland-util.h> /* Keycodes are offset by 8 in XKB. */ @@ -83,7 +84,7 @@ struct keyboard { uint32_t modifiers; }; -struct keyboard *keyboard_create(void); +struct keyboard *keyboard_create(struct xkb_rule_names *names); void keyboard_destroy(struct keyboard *keyboard); bool keyboard_reset(struct keyboard *keyboard); void keyboard_set_focus(struct keyboard *keyboard, struct compositor_view *view); diff --git a/libswc/local.mk b/libswc/local.mk @@ -17,7 +17,7 @@ $(dir)_TARGETS += \ $(dir)/$(LIBSWC_LINK) endif -$(dir)_PACKAGES := libdrm libinput pixman-1 wayland-server wld xkbcommon +$(dir)_PACKAGES := libdrm pixman-1 wayland-server wld xkbcommon $(dir)_CFLAGS += -Iprotocol SWC_SOURCES = \ @@ -42,7 +42,6 @@ SWC_SOURCES = \ libswc/primary_plane.c \ libswc/region.c \ libswc/screen.c \ - libswc/seat.c \ libswc/shell.c \ libswc/shell_surface.c \ libswc/shm.c \ @@ -63,9 +62,15 @@ SWC_SOURCES = \ protocol/xdg-decoration-unstable-v1-protocol.c \ protocol/xdg-shell-protocol.c -ifeq ($(ENABLE_LIBUDEV),1) -$(dir)_CFLAGS += -DENABLE_LIBUDEV -$(dir)_PACKAGES += libudev +ifeq ($(shell uname),NetBSD) + SWC_SOURCES += libswc/seat-ws.c +else + SWC_SOURCES += libswc/seat.c + $(dir)_PACKAGES += libinput + ifeq ($(ENABLE_LIBUDEV),1) + $(dir)_CFLAGS += -DENABLE_LIBUDEV + $(dir)_PACKAGES += libudev + endif endif SWC_STATIC_OBJECTS = $(SWC_SOURCES:%.c=%.o) diff --git a/libswc/seat-ws.c b/libswc/seat-ws.c @@ -0,0 +1,451 @@ +/* swc: libswc/seat-ws.c + * + * Copyright (c) 2013, 2014 Michael Forney + * Copyright (c) 2019 Nia Alarie + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "wscons/atKeynames.h" +#include "wscons/bsd_KbdMap.h" +#include "seat.h" +#include "compositor.h" +#include "data_device.h" +#include "event.h" +#include "internal.h" +#include "keyboard.h" +#include "launch.h" +#include "pointer.h" +#include "screen.h" +#include "surface.h" +#include "util.h" + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsksymdef.h> +#include <sys/ioctl.h> + +/* Map wscons encodings to libxkbcommon layout names. */ +struct ws_xkb_map { + const int ws; + const char * const xkb; +}; + +static const struct ws_xkb_map ws_xkb_encodings[] = { + { KB_UK, "gb" }, + { KB_BE, "be" }, + { KB_CZ, "cz" }, + { KB_DK, "dk" }, + { KB_NL, "nl" }, + { KB_DE, "de" }, + { KB_GR, "gr" }, + { KB_HU, "hu" }, + { KB_IT, "it" }, + { KB_JP, "jp" }, + { KB_NO, "no" }, + { KB_PL, "pl" }, + { KB_PT, "pt" }, + { KB_RU, "ru" }, + { KB_ES, "es" }, + { KB_SV, "sv" }, + { KB_SG, "sg" }, + { KB_TR, "tr" }, + { KB_UA, "ua" }, + { -1, NULL } +}; + +struct seat { + struct swc_seat base; + + char *name; + uint32_t capabilities; + + int mouse_fd; + int kbd_fd; + bool ignore; + + unsigned kbd_type; + + struct xkb_rule_names names; + + struct wl_event_source *mouse_source; + struct wl_event_source *kbd_source; + + struct wl_listener swc_listener; + + struct wl_listener keyboard_focus_listener; + struct pointer pointer; + struct wl_listener data_device_listener; + + struct wl_global *global; + struct wl_list resources; +}; + +static void +handle_keyboard_focus_event(struct wl_listener *listener, void *data) +{ + struct seat *seat = wl_container_of(listener, seat, keyboard_focus_listener); + struct event *ev = data; + struct input_focus_event_data *event_data = ev->data; + + if (ev->type != INPUT_FOCUS_EVENT_CHANGED) + return; + + if (event_data->new) { + struct wl_client *client = wl_resource_get_client(event_data->new->surface->resource); + + /* Offer the selection to the new focus. */ + data_device_offer_selection(seat->base.data_device, client); + } +} + +static void +handle_data_device_event(struct wl_listener *listener, void *data) +{ + struct seat *seat = wl_container_of(listener, seat, data_device_listener); + struct event *ev = data; + + if (ev->type != DATA_DEVICE_EVENT_SELECTION_CHANGED) + return; + + if (seat->base.keyboard->focus.client) + data_device_offer_selection(seat->base.data_device, seat->base.keyboard->focus.client); +} + +static void +handle_swc_event(struct wl_listener *listener, void *data) +{ + struct seat *seat = wl_container_of(listener, seat, swc_listener); + struct event *ev = data; + + switch (ev->type) { + case SWC_EVENT_DEACTIVATED: + seat->ignore = true; + keyboard_reset(seat->base.keyboard); + break; + case SWC_EVENT_ACTIVATED: + seat->ignore = false; + break; + } +} + +/* Wayland Seat Interface */ +static void +get_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id) +{ + struct seat *seat = wl_resource_get_user_data(resource); + + pointer_bind(&seat->pointer, client, wl_resource_get_version(resource), id); +} + +static void +get_keyboard(struct wl_client *client, struct wl_resource *resource, uint32_t id) +{ + struct seat *seat = wl_resource_get_user_data(resource); + + keyboard_bind(seat->base.keyboard, client, wl_resource_get_version(resource), id); +} + +static void +get_touch(struct wl_client *client, struct wl_resource *resource, uint32_t id) +{ + /* XXX: Implement */ +} + +static struct wl_seat_interface seat_impl = { + .get_pointer = get_pointer, + .get_keyboard = get_keyboard, + .get_touch = get_touch, +}; + +static void +bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct seat *seat = data; + struct wl_resource *resource; + + if (version > 4) + version = 4; + + resource = wl_resource_create(client, &wl_seat_interface, version, id); + wl_resource_set_implementation(resource, &seat_impl, seat, &remove_resource); + wl_list_insert(&seat->resources, wl_resource_get_link(resource)); + + if (version >= 2) + wl_seat_send_name(resource, seat->name); + + wl_seat_send_capabilities(resource, seat->capabilities); +} + +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: + case WSKBD_TYPE_MAPLE: + return wsUsbMap[key]; + default: + fprintf(stderr, "Unknown wskbd type %d\n", 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 int +handle_ws_data(int fd, uint32_t mask, void *data) +{ + struct seat *seat = data; + struct wscons_event ev; + + while (!seat->ignore && (read(fd, &ev, sizeof(ev))) != -1) { + uint32_t state, time; + int key; + wl_fixed_t pos; + + time = ev.time.tv_sec + (ev.time.tv_nsec / 1000000L); + switch (ev.type) { + case WSCONS_EVENT_KEY_UP: + state = WL_KEYBOARD_KEY_STATE_RELEASED; + key = ws_to_xkb(seat->kbd_type, ev.value); + keyboard_handle_key(seat->base.keyboard, time, key, state); + break; + case WSCONS_EVENT_KEY_DOWN: + state = WL_KEYBOARD_KEY_STATE_PRESSED; + key = ws_to_xkb(seat->kbd_type, ev.value); + keyboard_handle_key(seat->base.keyboard, time, key, state); + break; + case WSCONS_EVENT_ALL_KEYS_UP: + break; + case WSCONS_EVENT_MOUSE_UP: + state = WL_POINTER_BUTTON_STATE_RELEASED; + key = wsmouse_to_evdev(ev.value); + pointer_handle_button(seat->base.pointer, time, key, state); + break; + case WSCONS_EVENT_MOUSE_DOWN: + state = WL_POINTER_BUTTON_STATE_PRESSED; + key = wsmouse_to_evdev(ev.value); + pointer_handle_button(seat->base.pointer, time, key, state); + break; + case WSCONS_EVENT_MOUSE_DELTA_X: + pos = wl_fixed_from_int(ev.value); + pointer_handle_relative_motion(seat->base.pointer, time, pos, 0); + break; + case WSCONS_EVENT_MOUSE_DELTA_Y: + pos = wl_fixed_from_int(-ev.value); + pointer_handle_relative_motion(seat->base.pointer, time, 0, pos); + break; + case WSCONS_EVENT_MOUSE_DELTA_Z: + pos = wl_fixed_from_int(ev.value * 10); + pointer_handle_axis(seat->base.pointer, time, 0, pos); + break; + case WSCONS_EVENT_MOUSE_DELTA_W: + pos = wl_fixed_from_int(ev.value * 10); + pointer_handle_axis(seat->base.pointer, time, 1, pos); + break; + case WSCONS_EVENT_MOUSE_ABSOLUTE_X: + pos = wl_fixed_from_int(ev.value); + pointer_handle_absolute_motion(seat->base.pointer, time, pos, 0); + break; + case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: + pos = wl_fixed_from_int(-ev.value); + pointer_handle_absolute_motion(seat->base.pointer, time, 0, pos); + break; + } + } + return 0; +} + +static bool +initialize_wscons(struct seat *seat) +{ + int mouse_ver = WSMOUSE_EVENT_VERSION; + int kbd_ver = WSKBDIO_EVENT_VERSION; + int encoding_layout; + kbd_t encoding; + unsigned i; + + if ((seat->mouse_fd = launch_open_device("/dev/wsmouse", O_RDONLY | O_NONBLOCK)) == -1) { + ERROR("Could not open mouse device\n"); + goto error0; + } + if ((seat->kbd_fd = launch_open_device("/dev/wskbd", O_RDONLY | O_NONBLOCK)) == -1) { + ERROR("Could not open keyboard device\n"); + goto error1; + } + + (void)ioctl(seat->mouse_fd, WSMOUSEIO_SETVERSION, &mouse_ver); + (void)ioctl(seat->kbd_fd, WSKBDIO_SETVERSION, &kbd_ver); + + if (ioctl(seat->kbd_fd, WSKBDIO_GTYPE, &seat->kbd_type) == -1) { + ERROR("Could not get keyboard type\n"); + goto error2; + } + + if (ioctl(seat->kbd_fd, WSKBDIO_GETENCODING, &encoding) != -1) { + encoding_layout = KB_ENCODING(encoding); + for (i = 0; ws_xkb_encodings[i].xkb != NULL; ++i) { + if (ws_xkb_encodings[i].ws == encoding_layout) { + seat->names.layout = ws_xkb_encodings[i].xkb; + break; + } + } + switch (KB_VARIANT(encoding)) { + case KB_NODEAD: + seat->names.variant = "nodeadkeys"; + break; + case KB_SWAPCTRLCAPS: + seat->names.options = "ctrl:swapcaps"; + break; + case KB_DVORAK: + seat->names.variant = "dvorak"; + break; + case KB_COLEMAK: + seat->names.variant = "colemak"; + break; + } + } + + return true; +error2: + close(seat->kbd_fd); +error1: + close(seat->mouse_fd); +error0: + return false; +} + +struct swc_seat * +seat_create(struct wl_display *display, const char *seat_name) +{ + struct seat *seat; + + seat = malloc(sizeof(*seat)); + if (!seat) + goto error0; + + seat->names.rules = "base"; + seat->names.model = "pc105"; + seat->names.layout = "us"; + seat->names.variant = "basic"; + + seat->name = strdup(seat_name); + if (!seat->name) { + ERROR("Could not allocate seat name string\n"); + goto error1; + } + + if (!initialize_wscons(seat)) + goto error2; + + seat->global = wl_global_create(display, &wl_seat_interface, 4, seat, &bind_seat); + if (!seat->global) + goto error2; + seat->capabilities = WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER; + wl_list_init(&seat->resources); + + seat->swc_listener.notify = &handle_swc_event; + wl_signal_add(&swc.event_signal, &seat->swc_listener); + + seat->base.data_device = data_device_create(); + if (!seat->base.data_device) { + ERROR("Could not initialize data device\n"); + goto error3; + } + seat->data_device_listener.notify = &handle_data_device_event; + wl_signal_add(&seat->base.data_device->event_signal, &seat->data_device_listener); + + seat->base.keyboard = keyboard_create(&seat->names); + if (!seat->base.keyboard) { + ERROR("Could not initialize keyboard\n"); + goto error4; + } + seat->keyboard_focus_listener.notify = handle_keyboard_focus_event; + wl_signal_add(&seat->base.keyboard->focus.event_signal, &seat->keyboard_focus_listener); + + if (!pointer_initialize(&seat->pointer)) { + ERROR("Could not initialize pointer\n"); + goto error5; + } + seat->base.pointer = &seat->pointer; + + seat->kbd_source = wl_event_loop_add_fd + (swc.event_loop, seat->kbd_fd, WL_EVENT_READABLE, + &handle_ws_data, seat); + seat->mouse_source = wl_event_loop_add_fd + (swc.event_loop, seat->mouse_fd, WL_EVENT_READABLE, + &handle_ws_data, seat); + + return &seat->base; + +error5: + keyboard_destroy(seat->base.keyboard); +error4: + data_device_destroy(seat->base.data_device); +error3: + wl_global_destroy(seat->global); +error2: + free(seat->name); +error1: + free(seat); +error0: + return NULL; +} + +void +seat_destroy(struct swc_seat *seat_base) +{ + struct seat *seat = wl_container_of(seat_base, seat, base); + + wl_event_source_remove(seat->mouse_source); + wl_event_source_remove(seat->kbd_source); + close(seat->mouse_fd); + seat->mouse_fd = -1; + close(seat->kbd_fd); + seat->kbd_fd = -1; + + pointer_finalize(&seat->pointer); + keyboard_destroy(seat->base.keyboard); + data_device_destroy(seat->base.data_device); + + wl_global_destroy(seat->global); + free(seat->name); + free(seat); +} diff --git a/libswc/seat.c b/libswc/seat.c @@ -395,7 +395,7 @@ seat_create(struct wl_display *display, const char *seat_name) seat->data_device_listener.notify = &handle_data_device_event; wl_signal_add(&seat->base.data_device->event_signal, &seat->data_device_listener); - seat->base.keyboard = keyboard_create(); + seat->base.keyboard = keyboard_create(NULL); if (!seat->base.keyboard) { ERROR("Could not initialize keyboard\n"); goto error4; diff --git a/libswc/shm.c b/libswc/shm.c @@ -51,6 +51,16 @@ struct pool_reference { struct pool *pool; }; +static void * +swc_mremap(void *oldp, size_t oldsize, size_t newsize) +{ +#ifdef __NetBSD__ + return mremap(oldp, oldsize, NULL, newsize, 0); +#else /* Linux-style mremap */ + return mremap(oldp, oldsize, newsize, MREMAP_MAYMOVE); +#endif +} + static void unref_pool(struct pool *pool) { @@ -138,7 +148,7 @@ resize(struct wl_client *client, struct wl_resource *resource, int32_t size) struct pool *pool = wl_resource_get_user_data(resource); void *data; - data = mremap(pool->data, pool->size, size, MREMAP_MAYMOVE); + data = swc_mremap(pool->data, pool->size, size); if (data == MAP_FAILED) { wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mremap failed: %s", strerror(errno)); return; diff --git a/libswc/wscons/atKeynames.h b/libswc/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/libswc/wscons/bsd_KbdMap.h b/libswc/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 <stdint.h> + +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, +};