mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -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