mirror of
https://github.com/swaywm/sway.git
synced 2024-12-29 16:36:26 +01:00
5dbbab7bdc
When we have type safety we'll need to have functions for workspace_add_tiling and so on. This means the existing container functions will be just for containers, so they are being moved to container.c. At this point layout.c doesn't contain much else, so I've relocated everything and removed the file. * container_swap and its static functions have been moved to the swap command and made static. * container_recursive_resize has been moved to the resize command and made static. * The following have been moved to container.c: * container_handle_fullscreen_reparent * container_insert_child * container_add_sibling * container_add_child * container_remove_child * container_replace_child * container_split * enum movement_direction and sway_dir_to_wlr have been moved to util.c. Side note: Several commands included layout.h which then included root.h. With layout.h gone, root.h has to be included by those commands.
198 lines
4.1 KiB
C
198 lines
4.1 KiB
C
#define _XOPEN_SOURCE 700
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <xkbcommon/xkbcommon-names.h>
|
|
#include <wlr/types/wlr_keyboard.h>
|
|
#include "log.h"
|
|
#include "readline.h"
|
|
#include "util.h"
|
|
|
|
int wrap(int i, int max) {
|
|
return ((i % max) + max) % max;
|
|
}
|
|
|
|
int numlen(int n) {
|
|
if (n == 0) {
|
|
return 1;
|
|
}
|
|
return log10(n) + 1;
|
|
}
|
|
|
|
static struct modifier_key {
|
|
char *name;
|
|
uint32_t mod;
|
|
} modifiers[] = {
|
|
{ XKB_MOD_NAME_SHIFT, WLR_MODIFIER_SHIFT },
|
|
{ XKB_MOD_NAME_CAPS, WLR_MODIFIER_CAPS },
|
|
{ XKB_MOD_NAME_CTRL, WLR_MODIFIER_CTRL },
|
|
{ "Ctrl", WLR_MODIFIER_CTRL },
|
|
{ XKB_MOD_NAME_ALT, WLR_MODIFIER_ALT },
|
|
{ "Alt", WLR_MODIFIER_ALT },
|
|
{ XKB_MOD_NAME_NUM, WLR_MODIFIER_MOD2 },
|
|
{ "Mod3", WLR_MODIFIER_MOD3 },
|
|
{ XKB_MOD_NAME_LOGO, WLR_MODIFIER_LOGO },
|
|
{ "Mod5", WLR_MODIFIER_MOD5 },
|
|
};
|
|
|
|
uint32_t get_modifier_mask_by_name(const char *name) {
|
|
int i;
|
|
for (i = 0; i < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++i) {
|
|
if (strcasecmp(modifiers[i].name, name) == 0) {
|
|
return modifiers[i].mod;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char *get_modifier_name_by_mask(uint32_t modifier) {
|
|
int i;
|
|
for (i = 0; i < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++i) {
|
|
if (modifiers[i].mod == modifier) {
|
|
return modifiers[i].name;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int get_modifier_names(const char **names, uint32_t modifier_masks) {
|
|
int length = 0;
|
|
int i;
|
|
for (i = 0; i < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++i) {
|
|
if ((modifier_masks & modifiers[i].mod) != 0) {
|
|
names[length] = modifiers[i].name;
|
|
++length;
|
|
modifier_masks ^= modifiers[i].mod;
|
|
}
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
pid_t get_parent_pid(pid_t child) {
|
|
pid_t parent = -1;
|
|
char file_name[100];
|
|
char *buffer = NULL;
|
|
char *token = NULL;
|
|
const char *sep = " ";
|
|
FILE *stat = NULL;
|
|
|
|
sprintf(file_name, "/proc/%d/stat", child);
|
|
|
|
if ((stat = fopen(file_name, "r"))) {
|
|
if ((buffer = read_line(stat))) {
|
|
token = strtok(buffer, sep); // pid
|
|
token = strtok(NULL, sep); // executable name
|
|
token = strtok(NULL, sep); // state
|
|
token = strtok(NULL, sep); // parent pid
|
|
parent = strtol(token, NULL, 10);
|
|
}
|
|
free(buffer);
|
|
fclose(stat);
|
|
}
|
|
|
|
if (parent) {
|
|
return (parent == child) ? -1 : parent;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
uint32_t parse_color(const char *color) {
|
|
if (color[0] == '#') {
|
|
++color;
|
|
}
|
|
|
|
int len = strlen(color);
|
|
if (len != 6 && len != 8) {
|
|
wlr_log(WLR_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
|
|
return 0xFFFFFFFF;
|
|
}
|
|
uint32_t res = (uint32_t)strtoul(color, NULL, 16);
|
|
if (strlen(color) == 6) {
|
|
res = (res << 8) | 0xFF;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool parse_boolean(const char *boolean, bool current) {
|
|
if (strcasecmp(boolean, "1") == 0
|
|
|| strcasecmp(boolean, "yes") == 0
|
|
|| strcasecmp(boolean, "on") == 0
|
|
|| strcasecmp(boolean, "true") == 0
|
|
|| strcasecmp(boolean, "enable") == 0
|
|
|| strcasecmp(boolean, "enabled") == 0
|
|
|| strcasecmp(boolean, "active") == 0) {
|
|
return true;
|
|
} else if (strcasecmp(boolean, "toggle") == 0) {
|
|
return !current;
|
|
}
|
|
// All other values are false to match i3
|
|
return false;
|
|
}
|
|
|
|
char* resolve_path(const char* path) {
|
|
struct stat sb;
|
|
ssize_t r;
|
|
int i;
|
|
char *current = NULL;
|
|
char *resolved = NULL;
|
|
|
|
if(!(current = strdup(path))) {
|
|
return NULL;
|
|
}
|
|
for (i = 0; i < 16; ++i) {
|
|
if (lstat(current, &sb) == -1) {
|
|
goto failed;
|
|
}
|
|
if((sb.st_mode & S_IFMT) != S_IFLNK) {
|
|
return current;
|
|
}
|
|
if (!(resolved = malloc(sb.st_size + 1))) {
|
|
goto failed;
|
|
}
|
|
r = readlink(current, resolved, sb.st_size);
|
|
if (r == -1 || r > sb.st_size) {
|
|
goto failed;
|
|
}
|
|
resolved[r] = '\0';
|
|
free(current);
|
|
current = strdup(resolved);
|
|
free(resolved);
|
|
resolved = NULL;
|
|
}
|
|
|
|
failed:
|
|
free(resolved);
|
|
free(current);
|
|
return NULL;
|
|
}
|
|
|
|
bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
|
|
switch (dir) {
|
|
case MOVE_UP:
|
|
*out = WLR_DIRECTION_UP;
|
|
break;
|
|
case MOVE_DOWN:
|
|
*out = WLR_DIRECTION_DOWN;
|
|
break;
|
|
case MOVE_LEFT:
|
|
*out = WLR_DIRECTION_LEFT;
|
|
break;
|
|
case MOVE_RIGHT:
|
|
*out = WLR_DIRECTION_RIGHT;
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|