aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.h8
-rw-r--r--swt.c149
-rw-r--r--wayland.h24
3 files changed, 164 insertions, 17 deletions
diff --git a/config.h b/config.h
index d4d88c7..19496ce 100644
--- a/config.h
+++ b/config.h
@@ -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
diff --git a/swt.c b/swt.c
index c444397..6f59256 100644
--- a/swt.c
+++ b/swt.c
@@ -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;
diff --git a/wayland.h b/wayland.h
index b12cd00..97c608a 100644
--- a/wayland.h
+++ b/wayland.h
@@ -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);