diff options
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 179 |
1 files changed, 40 insertions, 139 deletions
@@ -1,5 +1,4 @@ #define _POSIX_C_SOURCE 200809L -#include <assert.h> #include <ctype.h> #include <poll.h> #include <stdbool.h> @@ -19,10 +18,8 @@ #include "menu.h" #include "pango.h" -#include "pool-buffer.h" #include "render.h" -#include "xdg-activation-v1-client-protocol.h" -#include "wlr-layer-shell-unstable-v1-client-protocol.h" +#include "wayland.h" // Creates and returns a new menu. struct menu *menu_create() { @@ -38,38 +35,6 @@ struct menu *menu_create() { return menu; } -// Creates and returns a new keyboard. -struct keyboard *keyboard_create(struct menu *menu, struct wl_keyboard *wl_keyboard) { - struct keyboard *keyboard = calloc(1, sizeof(struct keyboard)); - keyboard->menu = menu; - keyboard->keyboard = wl_keyboard; - keyboard->context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - assert(keyboard->context != NULL); - keyboard->repeat_timer = timerfd_create(CLOCK_MONOTONIC, 0); - assert(keyboard->repeat_timer != -1); - return keyboard; -} - -// Sets the current keyboard. -void menu_set_keyboard(struct menu *menu, struct keyboard *keyboard) { - menu->keyboard = keyboard; -} - -// Creates and returns a new output. -struct output *output_create(struct menu *menu, struct wl_output *wl_output) { - struct output *output = calloc(1, sizeof(struct output)); - output->menu = menu; - output->output = wl_output; - output->scale = 1; - return output; -} - -// Adds an output to the output list. -void menu_add_output(struct menu *menu, struct output *output) { - output->next = menu->output_list; - menu->output_list = output; -} - static bool parse_color(const char *color, uint32_t *result) { if (color[0] == '#') { ++color; @@ -170,6 +135,22 @@ void menu_getopts(struct menu *menu, int argc, char *argv[]) { menu->padding = height / 2; } +// Add an item to the menu. +void menu_add_item(struct menu *menu, char *text) { + struct item *item = calloc(1, sizeof *item); + if (!item) { + return; + } + item->text = text; + + if (menu->lastitem) { + menu->lastitem->next = item; + } else { + menu->items = item; + } + menu->lastitem = item; +} + static void append_page(struct page *page, struct page **first, struct page **last) { if (*last) { (*last)->next = page; @@ -246,7 +227,7 @@ static const char *fstrstr(struct menu *menu, const char *s, const char *sub) { return NULL; } -static void append_item(struct item *item, struct item **first, struct item **last) { +static void append_match(struct item *item, struct item **first, struct item **last) { if (*last) { (*last)->next_match = item; } else { @@ -300,11 +281,11 @@ static void match_items(struct menu *menu) { continue; } if (!tokc || !menu->strncmp(menu->input, item->text, input_len + 1)) { - append_item(item, &lexact, &exactend); + append_match(item, &lexact, &exactend); } else if (!menu->strncmp(tokv[0], item->text, tok_len)) { - append_item(item, &lprefix, &prefixend); + append_match(item, &lprefix, &prefixend); } else { - append_item(item, &lsubstr, &substrend); + append_match(item, &lsubstr, &substrend); } } @@ -339,45 +320,27 @@ static void match_items(struct menu *menu) { } } -// Read menu items from standard input. -void read_menu_items(struct menu *menu) { - if (menu->passwd) { - // Don't read standard input in password mode - calc_widths(menu); - return; - } - - char buf[sizeof menu->input]; - struct item **next = &menu->items; - while (fgets(buf, sizeof buf, stdin)) { - char *p = strchr(buf, '\n'); - if (p) { - *p = '\0'; - } - struct item *item = calloc(1, sizeof *item); - if (!item) { - return; - } - item->text = strdup(buf); - - *next = item; - next = &item->next; - } - +// Process menu items. +void menu_process_items(struct menu *menu) { calc_widths(menu); match_items(menu); } -static void insert(struct menu *menu, const char *s, ssize_t n) { - if (strlen(menu->input) + n > sizeof menu->input - 1) { +static void insert(struct menu *menu, const char *text, ssize_t len) { + if (strlen(menu->input) + len > sizeof menu->input - 1) { return; } - memmove(menu->input + menu->cursor + n, menu->input + menu->cursor, - sizeof menu->input - menu->cursor - MAX(n, 0)); - if (n > 0 && s != NULL) { - memcpy(menu->input + menu->cursor, s, n); + memmove(menu->input + menu->cursor + len, menu->input + menu->cursor, + sizeof menu->input - menu->cursor - MAX(len, 0)); + if (len > 0 && text != NULL) { + memcpy(menu->input + menu->cursor, text, len); } - menu->cursor += n; + menu->cursor += len; +} + +// Add pasted text to the menu input. +void menu_paste(struct menu *menu, const char *text, ssize_t len) { + insert(menu, text, len); } static size_t nextrune(struct menu *menu, int incr) { @@ -417,14 +380,12 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state, return; } - bool ctrl = xkb_state_mod_name_is_active(menu->keyboard->state, - XKB_MOD_NAME_CTRL, + struct xkb_state *state = context_get_xkb_state(menu->context); + bool ctrl = xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); - bool meta = xkb_state_mod_name_is_active(menu->keyboard->state, - XKB_MOD_NAME_ALT, + bool meta = xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); - bool shift = xkb_state_mod_name_is_active(menu->keyboard->state, - XKB_MOD_NAME_SHIFT, + bool shift = xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); size_t len = strlen(menu->input); @@ -501,32 +462,9 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state, return; case XKB_KEY_Y: // Paste clipboard - if (!menu->data_offer) { + if (!context_paste(menu->context)) { return; } - - int fds[2]; - if (pipe(fds) == -1) { - // Pipe failed - return; - } - wl_data_offer_receive(menu->data_offer, "text/plain", fds[1]); - close(fds[1]); - - wl_display_roundtrip(menu->display); - - while (true) { - char buf[1024]; - ssize_t n = read(fds[0], buf, sizeof(buf)); - if (n <= 0) { - break; - } - insert(menu, buf, n); - } - close(fds[0]); - - wl_data_offer_destroy(menu->data_offer); - menu->data_offer = NULL; match_items(menu); render_menu(menu); return; @@ -696,26 +634,6 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state, } } -// Frees the keyboard. -static void free_keyboard(struct keyboard *keyboard) { - wl_keyboard_release(keyboard->keyboard); - xkb_state_unref(keyboard->state); - xkb_keymap_unref(keyboard->keymap); - xkb_context_unref(keyboard->context); - free(keyboard); -} - -// Frees the outputs. -static void free_outputs(struct menu *menu) { - struct output *next = menu->output_list; - while (next) { - struct output *output = next; - next = output->next; - wl_output_destroy(output->output); - free(output); - } -} - // Frees menu pages. static void free_pages(struct menu *menu) { struct page *next = menu->pages; @@ -739,26 +657,9 @@ static void free_items(struct menu *menu) { // Destroys the menu, freeing memory associated with it. void menu_destroy(struct menu *menu) { - wl_registry_destroy(menu->registry); - wl_compositor_destroy(menu->compositor); - wl_shm_destroy(menu->shm); - wl_seat_destroy(menu->seat); - wl_data_device_manager_destroy(menu->data_device_manager); - zwlr_layer_shell_v1_destroy(menu->layer_shell); - free_outputs(menu); - - free_keyboard(menu->keyboard); - wl_data_device_destroy(menu->data_device); - wl_surface_destroy(menu->surface); - zwlr_layer_surface_v1_destroy(menu->layer_surface); - xdg_activation_v1_destroy(menu->activation); - free_pages(menu); free_items(menu); destroy_buffer(&menu->buffers[0]); destroy_buffer(&menu->buffers[1]); - - wl_display_disconnect(menu->display); - free(menu); } |