#include #include #include #include #include #include "river-status-unstable-v1.h" #include "river-control-unstable-v1.h" #define INT_SIZE sizeof (int) // Size of int in bytes #define INT_BITS INT_SIZE * 8 - 1 // Size of int in bits - 1 int ret = EXIT_SUCCESS; struct wl_display *wl_display = NULL; struct wl_output *wl_output = NULL; struct wl_seat *seat = NULL; struct zriver_status_manager_v1 *river_status_manager = NULL; struct zriver_control_v1 *river_controller = NULL; struct zriver_output_status_v1 *river_output_status = NULL; int shifts = 1; int num_tags = 9; int start_tag = 0; unsigned int new_tags = 0; const char usage[] = "Usage: river-shiftview [OPTIONS]\n" " --shifts VALUE value by which to rotate selected tag.\n" " --num-tags VALUE number of tags to rotate\n" " --start VALUE First tag to rotate from.\n" " --help print this message and exit.\n" "\n" "\n"; void rotate ( unsigned int tagmask, int rotations, int start_tag, int num_tags) { rotations %= (int)INT_BITS; const unsigned int mask = ~(~(0U) << num_tags) << start_tag; unsigned int to_rotate = (tagmask & mask) >> start_tag; if (rotations < 1) { rotations = -rotations; new_tags = (mask & ((to_rotate >> rotations) | (to_rotate << (num_tags - rotations)) << start_tag)) + (~mask & tagmask); } else { new_tags = (mask & ((to_rotate << rotations) | (to_rotate >> (num_tags - rotations)) << start_tag)) + (~mask & tagmask); } } static void print_tagmask ( void *data, struct zriver_output_status_v1 *output_status_v1, unsigned int tagmask) { rotate (tagmask, shifts, start_tag, num_tags); } static void river_status_handle_view_tags ( void *data, struct zriver_output_status_v1 *river_status, struct wl_array *tags) { } static void river_status_handle_urgent_tags ( void *data, struct zriver_output_status_v1 *river_status, uint32_t tags) { } static const struct zriver_output_status_v1_listener output_status_listener = { .focused_tags = print_tagmask, .view_tags = river_status_handle_view_tags, .urgent_tags = river_status_handle_urgent_tags, }; static void global_registry_handler ( void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { if (strcmp (interface, "wl_output") == 0) { wl_output = wl_registry_bind (registry, id, &wl_output_interface, 1); } else if ( strcmp( interface, "wl_seat" ) == 0 ) { seat = wl_registry_bind(registry, id, &wl_seat_interface, 3); } else if (strcmp (interface, zriver_status_manager_v1_interface.name) == 0) { river_status_manager = wl_registry_bind ( registry, id, &zriver_status_manager_v1_interface, 2); } else if (strcmp (interface, zriver_control_v1_interface.name) == 0) { river_controller = wl_registry_bind( registry, id, &zriver_control_v1_interface, 1); } } static void global_registry_remover ( void *data, struct wl_registry *registry, uint32_t id) { } static const struct wl_registry_listener registry_listener = { global_registry_handler, global_registry_remover }; int main (int argc, char *argv[]) { enum { HELP, SHIFT_VALUE, START_TAG, NUM_TAGS }; static struct option opts[] = { { "help", no_argument, NULL, HELP }, { "shifts", required_argument, NULL, SHIFT_VALUE }, { "num-tags", required_argument, NULL, NUM_TAGS }, { "start", required_argument, NULL, START_TAG }, { NULL, 0, NULL, 0 }, }; int opt; while ((opt = getopt_long (argc, argv, "h", opts, NULL)) != -1) { switch (opt) { case HELP: fputs (usage, stderr); return EXIT_SUCCESS; case SHIFT_VALUE: shifts = atoi (optarg); break; case START_TAG: start_tag = atoi (optarg); break; case NUM_TAGS: num_tags = atoi (optarg); break; default: return EXIT_FAILURE; } } const char *display_name = getenv ("WAYLAND_DISPLAY"); if (display_name == NULL) { fputs ("ERROR: WAYLAND_DISPLAY is not set.\n", stderr); return EXIT_FAILURE; } wl_display = wl_display_connect (display_name); if (wl_display == NULL) { fputs ("ERROR: Can not connect to wayland display.\n", stderr); return EXIT_FAILURE; } struct wl_registry *registry = wl_display_get_registry (wl_display); wl_registry_add_listener (registry, ®istry_listener, NULL); wl_display_roundtrip (wl_display); river_output_status = zriver_status_manager_v1_get_river_output_status ( river_status_manager, wl_output); zriver_output_status_v1_add_listener (river_output_status, &output_status_listener, NULL); /* Wait till new_tags is populated */ wl_display_roundtrip (wl_display); /* Set the new focused tags */ zriver_control_v1_add_argument( river_controller, "set-focused-tags" ); char* tags_str = malloc( (size_t)snprintf( NULL, 0, "%d", new_tags )); sprintf(tags_str, "%d", new_tags); zriver_control_v1_add_argument( river_controller, tags_str); zriver_control_v1_run_command ( river_controller, seat); zriver_control_v1_destroy(river_controller); wl_display_roundtrip (wl_display); return ret; }