diff options
| -rw-r--r-- | config.h | 8 | ||||
| -rw-r--r-- | swt.c | 149 | ||||
| -rw-r--r-- | wayland.h | 24 |
3 files changed, 164 insertions, 17 deletions
@@ -65,6 +65,9 @@ int allowaltscreen = 1; setting the clipboard text */ int allowwindowops = 0; +/* Set clipboard max size (default 4MiB) */ +#define CLIPBOARD_SIZE 4194304 + /* * draw latency range in ms - from new content/keypress/etc until drawing. * within this range, st draws when content stops arriving (idle). mostly it's @@ -183,6 +186,11 @@ static unsigned int mousebg = 0; */ static unsigned int defaultattr = 11; +/* Shortcuts */ +static Shortcut shortcut[] = { + { XKB_KEY_c, KEY_MOD_ALT, copy }, + { XKB_KEY_v, KEY_MOD_ALT, paste }, +}; /* * This is the huge key array which defines all compatibility to the Linux @@ -64,7 +64,10 @@ static void setup(); static void cleanup(); static void run(); static void usage(); +static void copy(); +static void paste(); static int matchmod(uint32_t mask, uint32_t mod); +static int execshortcut(); static char *kmap(); static void buffer_release(void *data, struct wl_buffer *buffer); static void draw_frame(); @@ -78,6 +81,7 @@ static void registry_global(void *data, struct wl_registry *registry, uint32_t n static void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name); static void seat_capabilities(void *dat, struct wl_seat *seat, uint32_t capabilities); static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size); +static void keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys); static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t client); static void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group); static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay); @@ -87,6 +91,10 @@ static void pointer_leave(void *data, struct wl_pointer *pointer, uint32_t seria static void pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y); static void pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state); static void pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value); +static void data_device_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); +static void data_device_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); +static void data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int fd); +static void data_source_cancelled(void *data, struct wl_data_source *source); static void dummy() {} @@ -125,11 +133,11 @@ static const struct wl_keyboard_listener keyboard_listener = { .key = keyboard_key, .modifiers = keyboard_modifiers, .repeat_info = keyboard_repeat_info, - .enter = dummy, + .enter = keyboard_enter, .leave = dummy, }; -const struct wl_pointer_listener pointer_listener = { +static const struct wl_pointer_listener pointer_listener = { .enter = pointer_enter, .leave = pointer_leave, .motion = pointer_motion, @@ -142,6 +150,20 @@ const struct wl_pointer_listener pointer_listener = { .frame = dummy, }; +static const struct wl_data_device_listener data_device_listener = { + .data_offer = data_device_data_offer, + .selection = data_device_selection +}; + +static const struct wl_data_source_listener data_source_listener = { + .send = data_source_send, + .cancelled = data_source_cancelled +}; + +static const struct wl_data_offer_listener data_offer_listener = { + .offer = dummy, +}; + Client client = { 0 }; Window win = { 0 }; @@ -155,15 +177,39 @@ static char **opt_cmd = 0; #include "config.h" +static char clipboard[CLIPBOARD_SIZE] = ""; + /* function implementation */ -void wbell() { +void +wbell() { /* TODO */ } -void wclipcopy() { - /* TODO */ +void +wclipcopy() { + copy(); +} + + +void +copy() +{ + struct wl_data_source *source = wl_data_device_manager_create_data_source(client.clipboard.data_device_manager); + + strcpy(clipboard, getsel()); + + wl_data_source_add_listener(source, &data_source_listener, 0); + wl_data_source_offer(source, "text/plain"); + wl_data_device_set_selection(client.clipboard.data_device, source, client.clipboard.keyboard_enter_serial); +} + + +void +paste() +{ + ttywrite(clipboard, strlen(clipboard), 1); } @@ -323,7 +369,7 @@ int wgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) { void wseticontitle(char *title) { - fprintf(stderr, "SET ICON TITLE: %s\n", title); + wsettitle(title); } @@ -450,6 +496,7 @@ registry_global(void *data, struct wl_registry *registry, uint32_t name, const c match_then_bind(client.shm, wl_shm_interface, 1) or_match match_then_bind(client.compositor, wl_compositor_interface, 4) or_match match_then_bind(client.wm_base, xdg_wm_base_interface, 1) + or_match match_then_bind(client.clipboard.data_device_manager, wl_data_device_manager_interface, 3) or_match match_then_bind(client.seat, wl_seat_interface, 7) wl_seat_add_listener(client.seat, &seat_listener, &client); end_match @@ -511,6 +558,13 @@ keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32 void +keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) +{ + client.clipboard.keyboard_enter_serial = serial; +} + + +void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { struct itimerspec spec = { 0 }; @@ -535,14 +589,13 @@ void keyboard_modifiers(void *data, struct wl_keyboard *keybaord, uint32_t serial, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) { xkb_state_update_mask(client.kb.state, depressed, latched, locked, 0, 0, group); - client.kb.event.mod = 0; client.kb.event.mod |= xkb_state_mod_name_is_active( client.kb.state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED ) * KEY_MOD_ALT; - client.kb.event.mod = xkb_state_mod_name_is_active( + client.kb.event.mod |= xkb_state_mod_name_is_active( client.kb.state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED @@ -571,14 +624,32 @@ keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int client.kb.repeat.period = -1; } - int matchmod(uint32_t mask, uint32_t mod) { - return mask == KEY_MOD_ANY || mask == mod; + return mask == KEY_MOD_ANY || mask & mod; } +int +execshortcut() +{ + Shortcut *sc; + + for (sc = shortcut; sc < shortcut + LEN(shortcut); sc++) { + if (sc->k != client.kb.event.sym) + continue; + + if (!matchmod(sc->mask, client.kb.event.mod)) + continue; + + sc->func(); + return 1; + } + + return 0; +} + char * kmap() { @@ -607,6 +678,9 @@ handle_keyboard_event() char c; if (client.kb.event.state == WL_KEYBOARD_KEY_STATE_PRESSED) { + if (execshortcut()) + return; + if ((customkey = kmap())) { ttywrite(customkey, strlen(customkey), 1); return; @@ -707,6 +781,56 @@ pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axi void +data_device_data_offer(void *data, + struct wl_data_device *data_device, struct wl_data_offer *offer) { + wl_data_offer_add_listener(offer, &data_offer_listener, NULL); +} + + +void +data_device_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) +{ + int fds[2]; + ssize_t s; + + if (offer == 0) + return; + + pipe(fds); + wl_data_offer_receive(offer, "text/plain", fds[1]); + close(fds[1]); + + wl_display_roundtrip(client.display); + + s = read(fds[0], clipboard, CLIPBOARD_SIZE - 1); + clipboard[s] = 0; + close(fds[0]); + + wl_data_offer_destroy(offer); +} + + +void +data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int fd) +{ + if (strcmp(mime_type, "text/plain") == 0) { + write(fd, clipboard, strlen(clipboard)); + } else { + fprintf(stderr, "warning: clipboard request does not support mimetype '%s'", mime_type); + } + + close(fd); +} + + +void +data_source_cancelled(void *data, struct wl_data_source *source) +{ + wl_data_source_destroy(source); +} + + +void setup() { win.mode = MODE_VISIBLE; @@ -723,6 +847,10 @@ setup() xdg_wm_base_add_listener(client.wm_base, &wm_base_listener, &client); wl_display_roundtrip(client.display); + client.clipboard.data_device = wl_data_device_manager_get_data_device(client.clipboard.data_device_manager, client.seat); + wl_data_device_add_listener(client.clipboard.data_device, &data_device_listener, 0); + wl_display_roundtrip(client.display); + client.pointer.pointer = wl_seat_get_pointer(client.seat); wl_pointer_add_listener(client.pointer.pointer, &pointer_listener, &client); @@ -827,7 +955,6 @@ usage(void) int main(int argc, char *argv[]) { - ARGBEGIN { case 'a': allowaltscreen = 0; @@ -9,12 +9,12 @@ #include "xdg-shell-client-protocol.h" typedef enum { - KEY_MOD_NONE = 0, - KEY_MOD_CTRL = 1, - KEY_MOD_ALT = 2, - KEY_MOD_SHIFT = 4, - KEY_MOD_LOGO = 8, - KEY_MOD_ANY = 16 + KEY_MOD_NONE = 1 << 0, + KEY_MOD_CTRL = 1 << 1, + KEY_MOD_ALT = 1 << 2, + KEY_MOD_SHIFT = 1 << 3, + KEY_MOD_LOGO = 1 << 4, + KEY_MOD_ANY = 1 << 5 } ModMask; @@ -29,6 +29,13 @@ typedef struct { typedef struct { + uint32_t k; + uint32_t mask; + void (*func)(); +} Shortcut; + + +typedef struct { struct wl_display *display; struct wl_registry *registry; struct wl_shm *shm; @@ -68,6 +75,11 @@ typedef struct { uint32_t tclick; } buttons; } pointer; + struct { + struct wl_data_device_manager *data_device_manager; + struct wl_data_device *data_device; + uint32_t keyboard_enter_serial; + } clipboard; } Client; int allocate_shm_file(size_t size); |