Implement GrabServer and UngrabServer
These seem very scary but they are part of the spec :)
This commit is contained in:
parent
8a0f287d8c
commit
a52181e140
|
|
@ -2297,12 +2297,48 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
case X_GrabServer:
|
case X_GrabServer:
|
||||||
{
|
{
|
||||||
dwarnln("GrabServer");
|
g_server_grabber_fd = client_info.fd;
|
||||||
|
|
||||||
|
for (const auto& [_, thingy] : g_epoll_thingies)
|
||||||
|
{
|
||||||
|
if (thingy.type != EpollThingy::Type::Client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& other_client = thingy.value.get<Client>();
|
||||||
|
if (client_info.fd == other_client.fd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t events = 0;
|
||||||
|
if (other_client.has_epollout)
|
||||||
|
events |= EPOLLOUT;
|
||||||
|
|
||||||
|
epoll_event event { .events = events, .data = { .fd = other_client.fd } };
|
||||||
|
epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, other_client.fd, &event);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case X_UngrabServer:
|
case X_UngrabServer:
|
||||||
{
|
{
|
||||||
dwarnln("UngrabServer");
|
g_server_grabber_fd = -1;
|
||||||
|
|
||||||
|
for (const auto& [_, thingy] : g_epoll_thingies)
|
||||||
|
{
|
||||||
|
if (thingy.type != EpollThingy::Type::Client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& other_client = thingy.value.get<Client>();
|
||||||
|
if (client_info.fd == other_client.fd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t events = EPOLLIN;
|
||||||
|
if (other_client.has_epollout)
|
||||||
|
events |= EPOLLOUT;
|
||||||
|
|
||||||
|
epoll_event event { .events = events, .data = { .fd = other_client.fd } };
|
||||||
|
epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, other_client.fd, &event);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case X_QueryPointer:
|
case X_QueryPointer:
|
||||||
|
|
|
||||||
|
|
@ -194,3 +194,5 @@ extern ATOM g_atom_value;
|
||||||
|
|
||||||
extern int g_epoll_fd;
|
extern int g_epoll_fd;
|
||||||
extern BAN::HashMap<int, EpollThingy> g_epoll_thingies;
|
extern BAN::HashMap<int, EpollThingy> g_epoll_thingies;
|
||||||
|
|
||||||
|
extern int g_server_grabber_fd;
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,8 @@ ATOM g_atom_value = XA_LAST_PREDEFINED + 1;
|
||||||
int g_epoll_fd;
|
int g_epoll_fd;
|
||||||
BAN::HashMap<int, EpollThingy> g_epoll_thingies;
|
BAN::HashMap<int, EpollThingy> g_epoll_thingies;
|
||||||
|
|
||||||
|
int g_server_grabber_fd = -1;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
for (int sig = 1; sig < NSIG; sig++)
|
for (int sig = 1; sig < NSIG; sig++)
|
||||||
|
|
@ -292,6 +294,26 @@ int main()
|
||||||
epoll_ctl(g_epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
epoll_ctl(g_epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
||||||
close(client_fd);
|
close(client_fd);
|
||||||
g_epoll_thingies.remove(client_fd);
|
g_epoll_thingies.remove(client_fd);
|
||||||
|
|
||||||
|
if (client_fd == g_server_grabber_fd)
|
||||||
|
{
|
||||||
|
g_server_grabber_fd = -1;
|
||||||
|
|
||||||
|
for (const auto& [_, thingy] : g_epoll_thingies)
|
||||||
|
{
|
||||||
|
if (thingy.type != EpollThingy::Type::Client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& other_client = thingy.value.get<Client>();
|
||||||
|
|
||||||
|
uint32_t events = EPOLLIN;
|
||||||
|
if (other_client.has_epollout)
|
||||||
|
events |= EPOLLOUT;
|
||||||
|
|
||||||
|
epoll_event event { .events = events, .data = { .fd = other_client.fd } };
|
||||||
|
epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, other_client.fd, &event);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MUST(g_objects.insert(g_root.windowId,
|
MUST(g_objects.insert(g_root.windowId,
|
||||||
|
|
@ -335,7 +357,11 @@ int main()
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
epoll_event event = { .events = EPOLLIN, .data = { .fd = client_sock } };
|
uint32_t events = 0;
|
||||||
|
if (g_server_grabber_fd == -1)
|
||||||
|
events |= EPOLLIN;
|
||||||
|
|
||||||
|
epoll_event event = { .events = events, .data = { .fd = client_sock } };
|
||||||
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, client_sock, &event) == -1)
|
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, client_sock, &event) == -1)
|
||||||
{
|
{
|
||||||
perror("xbanan: epoll_ctl");
|
perror("xbanan: epoll_ctl");
|
||||||
|
|
@ -398,7 +424,11 @@ int main()
|
||||||
|
|
||||||
if (client_info.output_buffer.empty())
|
if (client_info.output_buffer.empty())
|
||||||
{
|
{
|
||||||
epoll_event event { .events = EPOLLIN, .data = { .fd = client_info.fd } };
|
uint32_t events = 0;
|
||||||
|
if (g_server_grabber_fd == -1 || g_server_grabber_fd == client_info.fd)
|
||||||
|
events |= EPOLLIN;
|
||||||
|
|
||||||
|
epoll_event event { .events = events, .data = { .fd = client_info.fd } };
|
||||||
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, client_info.fd, &event) == -1)
|
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, client_info.fd, &event) == -1)
|
||||||
{
|
{
|
||||||
perror("xbanan: epoll_ctl");
|
perror("xbanan: epoll_ctl");
|
||||||
|
|
@ -416,6 +446,9 @@ int main()
|
||||||
if (!(events[i].events & EPOLLIN))
|
if (!(events[i].events & EPOLLIN))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (g_server_grabber_fd != -1 && g_server_grabber_fd != client_info.fd)
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (client_info.state)
|
switch (client_info.state)
|
||||||
{
|
{
|
||||||
case Client::State::ConnectionSetup:
|
case Client::State::ConnectionSetup:
|
||||||
|
|
@ -533,7 +566,11 @@ int main()
|
||||||
if (client_info.output_buffer.empty() || client_info.has_epollout)
|
if (client_info.output_buffer.empty() || client_info.has_epollout)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
epoll_event event { .events = EPOLLIN | EPOLLOUT, .data = { .fd = client_info.fd } };
|
uint32_t events = EPOLLOUT;
|
||||||
|
if (g_server_grabber_fd == -1 || g_server_grabber_fd == client_info.fd)
|
||||||
|
events |= EPOLLIN;
|
||||||
|
|
||||||
|
epoll_event event { .events = events, .data = { .fd = client_info.fd } };
|
||||||
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, client_info.fd, &event) == -1)
|
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_MOD, client_info.fd, &event) == -1)
|
||||||
{
|
{
|
||||||
perror("xbanan: epoll_ctl");
|
perror("xbanan: epoll_ctl");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue