mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-29 05:40:21 -04:00
300 lines
9.8 KiB
C
300 lines
9.8 KiB
C
#include "dwl-ipc-unstable-v2-protocol.h"
|
|
|
|
static void dwl_ipc_manager_bind(struct wl_client *client, void *data,
|
|
unsigned int version, unsigned int id);
|
|
static void dwl_ipc_manager_destroy(struct wl_resource *resource);
|
|
static void dwl_ipc_manager_get_output(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
unsigned int id,
|
|
struct wl_resource *output);
|
|
static void dwl_ipc_manager_release(struct wl_client *client,
|
|
struct wl_resource *resource);
|
|
static void dwl_ipc_output_destroy(struct wl_resource *resource);
|
|
static void dwl_ipc_output_printstatus(Monitor *monitor);
|
|
static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output);
|
|
static void dwl_ipc_output_set_client_tags(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
unsigned int and_tags,
|
|
unsigned int xor_tags);
|
|
static void dwl_ipc_output_set_layout(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
unsigned int index);
|
|
static void dwl_ipc_output_set_tags(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
unsigned int tagmask,
|
|
unsigned int toggle_tagset);
|
|
static void dwl_ipc_output_quit(struct wl_client *client,
|
|
struct wl_resource *resource);
|
|
static void dwl_ipc_output_dispatch(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
const char *dispatch, const char *arg1,
|
|
const char *arg2, const char *arg3,
|
|
const char *arg4, const char *arg5);
|
|
static void dwl_ipc_output_release(struct wl_client *client,
|
|
struct wl_resource *resource);
|
|
|
|
/* global event handlers */
|
|
static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {
|
|
.release = dwl_ipc_manager_release,
|
|
.get_output = dwl_ipc_manager_get_output};
|
|
static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {
|
|
.release = dwl_ipc_output_release,
|
|
.set_tags = dwl_ipc_output_set_tags,
|
|
.quit = dwl_ipc_output_quit,
|
|
.dispatch = dwl_ipc_output_dispatch,
|
|
.set_layout = dwl_ipc_output_set_layout,
|
|
.set_client_tags = dwl_ipc_output_set_client_tags};
|
|
|
|
void dwl_ipc_manager_bind(struct wl_client *client, void *data,
|
|
unsigned int version, unsigned int id) {
|
|
struct wl_resource *manager_resource =
|
|
wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id);
|
|
if (!manager_resource) {
|
|
wl_client_post_no_memory(client);
|
|
return;
|
|
}
|
|
wl_resource_set_implementation(manager_resource,
|
|
&dwl_manager_implementation, NULL,
|
|
dwl_ipc_manager_destroy);
|
|
|
|
zdwl_ipc_manager_v2_send_tags(manager_resource, LENGTH(tags));
|
|
|
|
for (unsigned int i = 0; i < LENGTH(layouts); i++)
|
|
zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol);
|
|
}
|
|
|
|
void dwl_ipc_manager_destroy(struct wl_resource *resource) {
|
|
/* No state to destroy */
|
|
}
|
|
|
|
void dwl_ipc_manager_get_output(struct wl_client *client,
|
|
struct wl_resource *resource, unsigned int id,
|
|
struct wl_resource *output) {
|
|
DwlIpcOutput *ipc_output;
|
|
struct wlr_output *op = wlr_output_from_resource(output);
|
|
if (!op)
|
|
return;
|
|
Monitor *monitor = op->data;
|
|
struct wl_resource *output_resource =
|
|
wl_resource_create(client, &zdwl_ipc_output_v2_interface,
|
|
wl_resource_get_version(resource), id);
|
|
if (!output_resource)
|
|
return;
|
|
|
|
ipc_output = ecalloc(1, sizeof(*ipc_output));
|
|
ipc_output->resource = output_resource;
|
|
ipc_output->mon = monitor;
|
|
wl_resource_set_implementation(output_resource, &dwl_output_implementation,
|
|
ipc_output, dwl_ipc_output_destroy);
|
|
wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link);
|
|
dwl_ipc_output_printstatus_to(ipc_output);
|
|
}
|
|
|
|
void dwl_ipc_manager_release(struct wl_client *client,
|
|
struct wl_resource *resource) {
|
|
wl_resource_destroy(resource);
|
|
}
|
|
|
|
static void dwl_ipc_output_destroy(struct wl_resource *resource) {
|
|
DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource);
|
|
wl_list_remove(&ipc_output->link);
|
|
free(ipc_output);
|
|
}
|
|
|
|
void dwl_ipc_output_printstatus(Monitor *monitor) {
|
|
DwlIpcOutput *ipc_output;
|
|
wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link)
|
|
dwl_ipc_output_printstatus_to(ipc_output);
|
|
}
|
|
|
|
void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) {
|
|
Monitor *monitor = ipc_output->mon;
|
|
Client *c, *focused;
|
|
struct wlr_keyboard *keyboard;
|
|
xkb_layout_index_t current;
|
|
int tagmask, state, numclients, focused_client, tag;
|
|
const char *title, *appid, *symbol, *kb_layout;
|
|
focused = focustop(monitor);
|
|
zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon);
|
|
|
|
for (tag = 0; tag < LENGTH(tags); tag++) {
|
|
numclients = state = focused_client = 0;
|
|
tagmask = 1 << tag;
|
|
if ((tagmask & monitor->tagset[monitor->seltags]) != 0)
|
|
state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE;
|
|
wl_list_for_each(c, &clients, link) {
|
|
if (c->mon != monitor)
|
|
continue;
|
|
if (!(c->tags & tagmask))
|
|
continue;
|
|
if (c == focused)
|
|
focused_client = 1;
|
|
if (c->isurgent)
|
|
state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT;
|
|
numclients++;
|
|
}
|
|
zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state,
|
|
numclients, focused_client);
|
|
}
|
|
|
|
title = focused ? client_get_title(focused) : "";
|
|
appid = focused ? client_get_appid(focused) : "";
|
|
|
|
if (monitor->pertag->curtag) {
|
|
symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol;
|
|
} else if (monitor->isoverview) {
|
|
symbol = overviewlayout.symbol;
|
|
} else {
|
|
symbol = monitor->pertag->ltidxs[monitor->pertag->prevtag]->symbol;
|
|
}
|
|
|
|
keyboard = &kb_group->wlr_group->keyboard;
|
|
current = xkb_state_serialize_layout(keyboard->xkb_state,
|
|
XKB_STATE_LAYOUT_EFFECTIVE);
|
|
kb_layout =
|
|
get_layout_abbr(xkb_keymap_layout_get_name(keyboard->keymap, current));
|
|
|
|
zdwl_ipc_output_v2_send_layout(
|
|
ipc_output->resource,
|
|
monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts);
|
|
zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken);
|
|
zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken);
|
|
zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol);
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource,
|
|
focused ? focused->isfullscreen : 0);
|
|
}
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_floating(ipc_output->resource,
|
|
focused ? focused->isfloating : 0);
|
|
}
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_x(ipc_output->resource,
|
|
focused ? focused->geom.x : 0);
|
|
}
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_y(ipc_output->resource,
|
|
focused ? focused->geom.y : 0);
|
|
}
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_width(ipc_output->resource,
|
|
focused ? focused->geom.width : 0);
|
|
}
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_height(ipc_output->resource,
|
|
focused ? focused->geom.height : 0);
|
|
}
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_last_layer(ipc_output->resource,
|
|
monitor->last_surface_ws_name);
|
|
}
|
|
|
|
if (wl_resource_get_version(ipc_output->resource) >=
|
|
ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) {
|
|
zdwl_ipc_output_v2_send_kb_layout(ipc_output->resource, kb_layout);
|
|
}
|
|
|
|
zdwl_ipc_output_v2_send_frame(ipc_output->resource);
|
|
}
|
|
|
|
void dwl_ipc_output_set_client_tags(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
unsigned int and_tags,
|
|
unsigned int xor_tags) {
|
|
DwlIpcOutput *ipc_output;
|
|
Monitor *monitor;
|
|
Client *selected_client;
|
|
unsigned int newtags = 0;
|
|
|
|
ipc_output = wl_resource_get_user_data(resource);
|
|
if (!ipc_output)
|
|
return;
|
|
|
|
monitor = ipc_output->mon;
|
|
selected_client = focustop(monitor);
|
|
if (!selected_client)
|
|
return;
|
|
|
|
newtags = (selected_client->tags & and_tags) ^ xor_tags;
|
|
if (!newtags)
|
|
return;
|
|
|
|
selected_client->tags = newtags;
|
|
if (selmon == monitor)
|
|
focusclient(focustop(monitor), 1);
|
|
arrange(selmon, false);
|
|
printstatus();
|
|
}
|
|
|
|
void dwl_ipc_output_set_layout(struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
unsigned int index) {
|
|
DwlIpcOutput *ipc_output;
|
|
Monitor *monitor;
|
|
|
|
ipc_output = wl_resource_get_user_data(resource);
|
|
if (!ipc_output)
|
|
return;
|
|
|
|
monitor = ipc_output->mon;
|
|
if (index >= LENGTH(layouts))
|
|
index = 0;
|
|
|
|
monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index];
|
|
arrange(monitor, false);
|
|
printstatus();
|
|
}
|
|
|
|
void dwl_ipc_output_set_tags(struct wl_client *client,
|
|
struct wl_resource *resource, unsigned int tagmask,
|
|
unsigned int toggle_tagset) {
|
|
DwlIpcOutput *ipc_output;
|
|
Monitor *monitor;
|
|
unsigned int newtags = tagmask & TAGMASK;
|
|
|
|
ipc_output = wl_resource_get_user_data(resource);
|
|
if (!ipc_output)
|
|
return;
|
|
monitor = ipc_output->mon;
|
|
|
|
view_in_mon(&(Arg){.ui = newtags}, true, monitor);
|
|
}
|
|
|
|
void dwl_ipc_output_quit(struct wl_client *client,
|
|
struct wl_resource *resource) {
|
|
quit(&(Arg){0});
|
|
}
|
|
|
|
void dwl_ipc_output_dispatch(struct wl_client *client,
|
|
struct wl_resource *resource, const char *dispatch,
|
|
const char *arg1, const char *arg2,
|
|
const char *arg3, const char *arg4,
|
|
const char *arg5) {
|
|
|
|
void (*func)(const Arg *);
|
|
Arg arg;
|
|
func = parse_func_name((char *)dispatch, &arg, (char *)arg1, (char *)arg2,
|
|
(char *)arg3, (char *)arg4, (char *)arg5);
|
|
if (func) {
|
|
func(&arg);
|
|
}
|
|
|
|
if (arg.v)
|
|
free(arg.v);
|
|
if (arg.v2)
|
|
free(arg.v2);
|
|
if (arg.v3)
|
|
free(arg.v3);
|
|
}
|
|
|
|
void dwl_ipc_output_release(struct wl_client *client,
|
|
struct wl_resource *resource) {
|
|
wl_resource_destroy(resource);
|
|
}
|