mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-04 13:29:51 -05:00
Add keyboard input to terminal.
This commit is contained in:
parent
269d6e3daf
commit
6e83d58153
3 changed files with 155 additions and 21 deletions
158
terminal.c
158
terminal.c
|
|
@ -31,6 +31,7 @@
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <eagle.h>
|
#include <eagle.h>
|
||||||
|
|
@ -44,15 +45,20 @@
|
||||||
static const char gem_device[] = "/dev/dri/card0";
|
static const char gem_device[] = "/dev/dri/card0";
|
||||||
static const char socket_name[] = "\0wayland";
|
static const char socket_name[] = "\0wayland";
|
||||||
|
|
||||||
|
#define MOD_SHIFT 0x01
|
||||||
|
#define MOD_ALT 0x02
|
||||||
|
#define MOD_CTRL 0x04
|
||||||
|
|
||||||
struct terminal {
|
struct terminal {
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
int resize_scheduled;
|
int resize_scheduled;
|
||||||
char *data;
|
char *data;
|
||||||
int width, height, tail, row, column;
|
int width, height, tail, row, column;
|
||||||
int fd;
|
int fd, master;
|
||||||
struct buffer *buffer;
|
struct buffer *buffer;
|
||||||
GIOChannel *channel;
|
GIOChannel *channel;
|
||||||
|
uint32_t modifiers;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -117,25 +123,6 @@ idle_redraw(void *data)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
resize_handler(struct window *window, int32_t width, int32_t height, void *data)
|
|
||||||
{
|
|
||||||
struct terminal *terminal = data;
|
|
||||||
|
|
||||||
if (!terminal->resize_scheduled) {
|
|
||||||
g_idle_add(idle_redraw, terminal);
|
|
||||||
terminal->resize_scheduled = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
acknowledge_handler(struct window *window, uint32_t key, void *data)
|
|
||||||
{
|
|
||||||
struct terminal *terminal = data;
|
|
||||||
|
|
||||||
terminal->resize_scheduled = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_data(struct terminal *terminal, const char *data, size_t length)
|
terminal_data(struct terminal *terminal, const char *data, size_t length)
|
||||||
{
|
{
|
||||||
|
|
@ -166,6 +153,134 @@ terminal_data(struct terminal *terminal, const char *data, size_t length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resize_handler(struct window *window, int32_t width, int32_t height, void *data)
|
||||||
|
{
|
||||||
|
struct terminal *terminal = data;
|
||||||
|
|
||||||
|
if (!terminal->resize_scheduled) {
|
||||||
|
g_idle_add(idle_redraw, terminal);
|
||||||
|
terminal->resize_scheduled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
acknowledge_handler(struct window *window, uint32_t key, void *data)
|
||||||
|
{
|
||||||
|
struct terminal *terminal = data;
|
||||||
|
|
||||||
|
terminal->resize_scheduled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct key {
|
||||||
|
int code[2];
|
||||||
|
} evdev_keymap[] = {
|
||||||
|
{ { 0, 0 } }, /* 0 */
|
||||||
|
{ { 0x1b, 0x1b } },
|
||||||
|
{ { '1', '!' } },
|
||||||
|
{ { '2', '@' } },
|
||||||
|
{ { '3', '#' } },
|
||||||
|
{ { '4', '$' } },
|
||||||
|
{ { '5', '%' } },
|
||||||
|
{ { '6', '^' } },
|
||||||
|
{ { '7', '&' } },
|
||||||
|
{ { '8', '*' } },
|
||||||
|
{ { '9', '(' } },
|
||||||
|
{ { '0', ')' } },
|
||||||
|
{ { '-', '_' } },
|
||||||
|
{ { '=', '+' } },
|
||||||
|
{ { '\b', '\b' } },
|
||||||
|
{ { '\t', '\t' } },
|
||||||
|
|
||||||
|
{ { 'q', 'Q' } }, /* 16 */
|
||||||
|
{ { 'w', 'W' } },
|
||||||
|
{ { 'e', 'E' } },
|
||||||
|
{ { 'r', 'R' } },
|
||||||
|
{ { 't', 'T' } },
|
||||||
|
{ { 'y', 'Y' } },
|
||||||
|
{ { 'u', 'U' } },
|
||||||
|
{ { 'i', 'I' } },
|
||||||
|
{ { 'o', 'O' } },
|
||||||
|
{ { 'p', 'P' } },
|
||||||
|
{ { '[', '{' } },
|
||||||
|
{ { ']', '}' } },
|
||||||
|
{ { '\n', '\n' } },
|
||||||
|
{ { 0, 0 } },
|
||||||
|
{ { 'a', 'A' } },
|
||||||
|
{ { 's', 'S' } },
|
||||||
|
|
||||||
|
{ { 'd', 'D' } }, /* 32 */
|
||||||
|
{ { 'f', 'F' } },
|
||||||
|
{ { 'g', 'G' } },
|
||||||
|
{ { 'h', 'H' } },
|
||||||
|
{ { 'j', 'J' } },
|
||||||
|
{ { 'k', 'K' } },
|
||||||
|
{ { 'l', 'L' } },
|
||||||
|
{ { ';', ':' } },
|
||||||
|
{ { '\'', '"' } },
|
||||||
|
{ { '`', '~' } },
|
||||||
|
{ { 0, 0 } },
|
||||||
|
{ { '\\', '|' } },
|
||||||
|
{ { 'z', 'Z' } },
|
||||||
|
{ { 'x', 'X' } },
|
||||||
|
{ { 'c', 'C' } },
|
||||||
|
{ { 'v', 'V' } },
|
||||||
|
|
||||||
|
{ { 'b', 'B' } }, /* 48 */
|
||||||
|
{ { 'n', 'N' } },
|
||||||
|
{ { 'm', 'M' } },
|
||||||
|
{ { ',', '<' } },
|
||||||
|
{ { '.', '>' } },
|
||||||
|
{ { '/', '?' } },
|
||||||
|
{ { 0, 0 } },
|
||||||
|
{ { '*', '*' } },
|
||||||
|
{ { 0, 0 } },
|
||||||
|
{ { ' ', ' ' } },
|
||||||
|
{ { 0, 0 } }
|
||||||
|
|
||||||
|
/* 59 */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||||
|
|
||||||
|
static void
|
||||||
|
key_handler(struct window *window, uint32_t key, uint32_t state, void *data)
|
||||||
|
{
|
||||||
|
struct terminal *terminal = data;
|
||||||
|
uint32_t mod = 0;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case KEY_LEFTSHIFT:
|
||||||
|
case KEY_RIGHTSHIFT:
|
||||||
|
mod = MOD_SHIFT;
|
||||||
|
break;
|
||||||
|
case KEY_LEFTCTRL:
|
||||||
|
case KEY_RIGHTCTRL:
|
||||||
|
mod = MOD_CTRL;
|
||||||
|
break;
|
||||||
|
case KEY_LEFTALT:
|
||||||
|
case KEY_RIGHTALT:
|
||||||
|
mod = MOD_ALT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (key < ARRAY_LENGTH(evdev_keymap)) {
|
||||||
|
if (terminal->modifiers & MOD_SHIFT)
|
||||||
|
c = evdev_keymap[key].code[1];
|
||||||
|
else
|
||||||
|
c = evdev_keymap[key].code[0];
|
||||||
|
if (state && c)
|
||||||
|
write(terminal->master, &c, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
terminal->modifiers |= mod;
|
||||||
|
else
|
||||||
|
terminal->modifiers &= ~mod;
|
||||||
|
}
|
||||||
|
|
||||||
static struct terminal *
|
static struct terminal *
|
||||||
terminal_create(struct wl_display *display, int fd)
|
terminal_create(struct wl_display *display, int fd)
|
||||||
{
|
{
|
||||||
|
|
@ -190,6 +305,7 @@ terminal_create(struct wl_display *display, int fd)
|
||||||
|
|
||||||
window_set_resize_handler(terminal->window, resize_handler, terminal);
|
window_set_resize_handler(terminal->window, resize_handler, terminal);
|
||||||
window_set_acknowledge_handler(terminal->window, acknowledge_handler, terminal);
|
window_set_acknowledge_handler(terminal->window, acknowledge_handler, terminal);
|
||||||
|
window_set_key_handler(terminal->window, key_handler, terminal);
|
||||||
|
|
||||||
return terminal;
|
return terminal;
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +322,6 @@ io_handler(GIOChannel *source,
|
||||||
|
|
||||||
g_io_channel_read_chars(source, buffer, sizeof buffer,
|
g_io_channel_read_chars(source, buffer, sizeof buffer,
|
||||||
&bytes_read, &error);
|
&bytes_read, &error);
|
||||||
printf("got data: %.*s\n", bytes_read, buffer);
|
|
||||||
|
|
||||||
terminal_data(terminal, buffer, bytes_read);
|
terminal_data(terminal, buffer, bytes_read);
|
||||||
|
|
||||||
|
|
@ -234,6 +349,7 @@ terminal_run(struct terminal *terminal, const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
close(slave);
|
close(slave);
|
||||||
|
terminal->master = master;
|
||||||
terminal->channel = g_io_channel_unix_new(master);
|
terminal->channel = g_io_channel_unix_new(master);
|
||||||
fcntl(master, F_SETFL, O_NONBLOCK);
|
fcntl(master, F_SETFL, O_NONBLOCK);
|
||||||
g_io_add_watch(terminal->channel, G_IO_IN,
|
g_io_add_watch(terminal->channel, G_IO_IN,
|
||||||
|
|
|
||||||
13
window.c
13
window.c
|
|
@ -55,6 +55,7 @@ struct window {
|
||||||
window_resize_handler_t resize_handler;
|
window_resize_handler_t resize_handler;
|
||||||
window_frame_handler_t frame_handler;
|
window_frame_handler_t frame_handler;
|
||||||
window_acknowledge_handler_t acknowledge_handler;
|
window_acknowledge_handler_t acknowledge_handler;
|
||||||
|
window_key_handler_t key_handler;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -293,6 +294,10 @@ event_handler(struct wl_display *display,
|
||||||
} else if (button == 0 && state == 0) {
|
} else if (button == 0 && state == 0) {
|
||||||
window->state = WINDOW_STABLE;
|
window->state = WINDOW_STABLE;
|
||||||
}
|
}
|
||||||
|
} else if (opcode == 2) {
|
||||||
|
if (window->key_handler)
|
||||||
|
(*window->key_handler)(window, p[0], p[1],
|
||||||
|
window->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,6 +347,14 @@ window_set_acknowledge_handler(struct window *window,
|
||||||
window->user_data = data;
|
window->user_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_set_key_handler(struct window *window,
|
||||||
|
window_key_handler_t handler, void *data)
|
||||||
|
{
|
||||||
|
window->key_handler = handler;
|
||||||
|
window->user_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_set_minimum_size(struct window *window, uint32_t width, int32_t height)
|
window_set_minimum_size(struct window *window, uint32_t width, int32_t height)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
5
window.h
5
window.h
|
|
@ -35,6 +35,8 @@ struct rectangle {
|
||||||
typedef void (*window_resize_handler_t)(struct window *window, int32_t width, int32_t height, void *data);
|
typedef void (*window_resize_handler_t)(struct window *window, int32_t width, int32_t height, void *data);
|
||||||
typedef void (*window_frame_handler_t)(struct window *window, uint32_t frame, uint32_t timestamp, void *data);
|
typedef void (*window_frame_handler_t)(struct window *window, uint32_t frame, uint32_t timestamp, void *data);
|
||||||
typedef void (*window_acknowledge_handler_t)(struct window *window, uint32_t key, void *data);
|
typedef void (*window_acknowledge_handler_t)(struct window *window, uint32_t key, void *data);
|
||||||
|
typedef void (*window_key_handler_t)(struct window *window, uint32_t key, uint32_t state, void *data);
|
||||||
|
|
||||||
|
|
||||||
struct window *
|
struct window *
|
||||||
window_create(struct wl_display *display, int fd,
|
window_create(struct wl_display *display, int fd,
|
||||||
|
|
@ -63,5 +65,8 @@ window_set_frame_handler(struct window *window,
|
||||||
void
|
void
|
||||||
window_set_acknowledge_handler(struct window *window,
|
window_set_acknowledge_handler(struct window *window,
|
||||||
window_acknowledge_handler_t handler, void *data);
|
window_acknowledge_handler_t handler, void *data);
|
||||||
|
void
|
||||||
|
window_set_key_handler(struct window *window,
|
||||||
|
window_key_handler_t handler, void *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue