Add global safe getters for retrieving objects
This commit is contained in:
parent
a52181e140
commit
df32c7aa99
295
xbanan/Base.cpp
295
xbanan/Base.cpp
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Keymap.h"
|
#include "Keymap.h"
|
||||||
|
#include "SafeGetters.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
|
@ -1085,78 +1086,8 @@ static void on_key_event(Client& client_info, WINDOW wid, LibGUI::EventPacket::K
|
||||||
|
|
||||||
BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
{
|
{
|
||||||
struct DrawableInfo
|
|
||||||
{
|
|
||||||
BAN::ByteSpan data;
|
|
||||||
CARD32 w, h;
|
|
||||||
CARD8 depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t opcode = packet[0];
|
const uint8_t opcode = packet[0];
|
||||||
|
|
||||||
const auto get_window =
|
|
||||||
[&client_info, opcode](WINDOW wid) -> BAN::ErrorOr<Object::Window&>
|
|
||||||
{
|
|
||||||
auto it = g_objects.find(wid);
|
|
||||||
if (it == g_objects.end() || it->value->type != Object::Type::Window)
|
|
||||||
{
|
|
||||||
xError error {
|
|
||||||
.type = X_Error,
|
|
||||||
.errorCode = BadWindow,
|
|
||||||
.sequenceNumber = client_info.sequence,
|
|
||||||
.resourceID = wid,
|
|
||||||
.minorCode = 0,
|
|
||||||
.majorCode = opcode,
|
|
||||||
};
|
|
||||||
TRY(encode(client_info.output_buffer, error));
|
|
||||||
return BAN::Error::from_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return it->value->object.get<Object::Window>();
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto get_pixmap =
|
|
||||||
[&client_info, opcode](WINDOW wid) -> BAN::ErrorOr<Object::Pixmap&>
|
|
||||||
{
|
|
||||||
auto it = g_objects.find(wid);
|
|
||||||
if (it == g_objects.end() || it->value->type != Object::Type::Pixmap)
|
|
||||||
{
|
|
||||||
xError error {
|
|
||||||
.type = X_Error,
|
|
||||||
.errorCode = BadPixmap,
|
|
||||||
.sequenceNumber = client_info.sequence,
|
|
||||||
.resourceID = wid,
|
|
||||||
.minorCode = 0,
|
|
||||||
.majorCode = opcode,
|
|
||||||
};
|
|
||||||
TRY(encode(client_info.output_buffer, error));
|
|
||||||
return BAN::Error::from_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return it->value->object.get<Object::Pixmap>();
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto get_drawable =
|
|
||||||
[&client_info, opcode](WINDOW drawable) -> BAN::ErrorOr<Object&>
|
|
||||||
{
|
|
||||||
auto it = g_objects.find(drawable);
|
|
||||||
if (it == g_objects.end() || (it->value->type != Object::Type::Window && it->value->type != Object::Type::Pixmap))
|
|
||||||
{
|
|
||||||
xError error {
|
|
||||||
.type = X_Error,
|
|
||||||
.errorCode = BadDrawable,
|
|
||||||
.sequenceNumber = client_info.sequence,
|
|
||||||
.resourceID = drawable,
|
|
||||||
.minorCode = 0,
|
|
||||||
.majorCode = opcode,
|
|
||||||
};
|
|
||||||
TRY(encode(client_info.output_buffer, error));
|
|
||||||
return BAN::Error::from_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *it->value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto validate_atom =
|
const auto validate_atom =
|
||||||
[&client_info, opcode](ATOM atom) -> BAN::ErrorOr<void>
|
[&client_info, opcode](ATOM atom) -> BAN::ErrorOr<void>
|
||||||
{
|
{
|
||||||
|
|
@ -1186,43 +1117,6 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
return it->value.sv();
|
return it->value.sv();
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto get_drawable_info =
|
|
||||||
[](Object& object) -> DrawableInfo
|
|
||||||
{
|
|
||||||
DrawableInfo info;
|
|
||||||
|
|
||||||
switch (object.type)
|
|
||||||
{
|
|
||||||
case Object::Type::Window:
|
|
||||||
{
|
|
||||||
auto& window = object.object.get<Object::Window>();
|
|
||||||
auto& texture = window.texture();
|
|
||||||
|
|
||||||
info.data = { reinterpret_cast<uint8_t*>(texture.pixels().data()), texture.pixels().size() * 4 };
|
|
||||||
info.w = texture.width();
|
|
||||||
info.h = texture.height();
|
|
||||||
info.depth = window.depth;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Object::Type::Pixmap:
|
|
||||||
{
|
|
||||||
auto& pixmap = object.object.get<Object::Pixmap>();
|
|
||||||
|
|
||||||
info.data = pixmap.data;
|
|
||||||
info.w = pixmap.width;
|
|
||||||
info.h = pixmap.height;
|
|
||||||
info.depth = pixmap.depth;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
};
|
|
||||||
|
|
||||||
client_info.sequence++;
|
client_info.sequence++;
|
||||||
|
|
||||||
if (opcode >= 128)
|
if (opcode >= 128)
|
||||||
|
|
@ -1408,7 +1302,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" window: {}", request.window);
|
dprintln(" window: {}", request.window);
|
||||||
dprintln(" valueMask: {8h}", request.valueMask);
|
dprintln(" valueMask: {8h}", request.valueMask);
|
||||||
|
|
||||||
auto& window = TRY_REF(get_window(request.window));
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
|
|
||||||
CURSOR cursor_id = None;
|
CURSOR cursor_id = None;
|
||||||
|
|
||||||
|
|
@ -1469,7 +1363,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("GetWindowAttributes");
|
dprintln("GetWindowAttributes");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(wid));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
|
|
||||||
xGetWindowAttributesReply reply {
|
xGetWindowAttributesReply reply {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
|
|
@ -1502,7 +1396,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("DestroyWinow");
|
dprintln("DestroyWinow");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
(void)TRY_REF(get_window(wid));
|
(void)TRY_REF(get_window(client_info, wid, opcode));
|
||||||
TRY(destroy_window(client_info, wid));
|
TRY(destroy_window(client_info, wid));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1517,9 +1411,9 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" x: {}", request.x);
|
dprintln(" x: {}", request.x);
|
||||||
dprintln(" y: {}", request.y);
|
dprintln(" y: {}", request.y);
|
||||||
|
|
||||||
auto& window = TRY_REF(get_window(request.window));
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
auto& new_parent = TRY_REF(get_window(request.parent));
|
auto& new_parent = TRY_REF(get_window(client_info, request.parent, opcode));
|
||||||
auto& old_parent = TRY_REF(get_window(window.parent));
|
auto& old_parent = TRY_REF(get_window(client_info, window.parent, opcode));
|
||||||
|
|
||||||
const auto wid = request.window;
|
const auto wid = request.window;
|
||||||
const auto oldpwid = window.parent;
|
const auto oldpwid = window.parent;
|
||||||
|
|
@ -1589,7 +1483,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("MapWindow");
|
dprintln("MapWindow");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
(void)TRY_REF(get_window(wid));
|
(void)TRY_REF(get_window(client_info, wid, opcode));
|
||||||
TRY(map_window(client_info, wid));
|
TRY(map_window(client_info, wid));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1601,7 +1495,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("MapSubwindows");
|
dprintln("MapSubwindows");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(wid));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
for (auto child_wid : window.children)
|
for (auto child_wid : window.children)
|
||||||
TRY(map_window(client_info, child_wid));
|
TRY(map_window(client_info, child_wid));
|
||||||
|
|
||||||
|
|
@ -1614,7 +1508,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("UnmapWindow");
|
dprintln("UnmapWindow");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
(void)TRY_REF(get_window(wid));
|
(void)TRY_REF(get_window(client_info, wid, opcode));
|
||||||
TRY(unmap_window(client_info, wid));
|
TRY(unmap_window(client_info, wid));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1626,7 +1520,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("UnmapSubwindows");
|
dprintln("UnmapSubwindows");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(wid));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
for (auto child_wid : window.children)
|
for (auto child_wid : window.children)
|
||||||
TRY(unmap_window(client_info, child_wid));
|
TRY(unmap_window(client_info, child_wid));
|
||||||
|
|
||||||
|
|
@ -1639,7 +1533,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("ConfigureWindow");
|
dprintln("ConfigureWindow");
|
||||||
dprintln(" window: {}", request.window);
|
dprintln(" window: {}", request.window);
|
||||||
|
|
||||||
auto& window = TRY_REF(get_window(request.window));
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
auto& texture = window.texture();
|
auto& texture = window.texture();
|
||||||
|
|
||||||
int32_t new_x = window.x;
|
int32_t new_x = window.x;
|
||||||
|
|
@ -1764,7 +1658,22 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("GetGeometry");
|
dprintln("GetGeometry");
|
||||||
dprintln(" drawable: {}", drawable_id);
|
dprintln(" drawable: {}", drawable_id);
|
||||||
|
|
||||||
const auto& drawable = TRY_REF(get_drawable(drawable_id));
|
auto it = g_objects.find(drawable_id);
|
||||||
|
if (it == g_objects.end() || (it->value->type != Object::Type::Window && it->value->type != Object::Type::Pixmap))
|
||||||
|
{
|
||||||
|
xError error {
|
||||||
|
.type = X_Error,
|
||||||
|
.errorCode = BadDrawable,
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.resourceID = drawable_id,
|
||||||
|
.minorCode = 0,
|
||||||
|
.majorCode = opcode,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, error));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& drawable = *it->value;
|
||||||
|
|
||||||
INT16 x, y;
|
INT16 x, y;
|
||||||
CARD16 width, height;
|
CARD16 width, height;
|
||||||
|
|
@ -1824,7 +1733,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("QueryTree");
|
dprintln("QueryTree");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(wid));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
|
|
||||||
xQueryTreeReply reply {
|
xQueryTreeReply reply {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
|
|
@ -1914,7 +1823,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
ASSERT(request.format == 8 || request.format == 16 || request.format == 32);
|
ASSERT(request.format == 8 || request.format == 16 || request.format == 32);
|
||||||
|
|
||||||
auto& window = TRY_REF(get_window(request.window));
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
|
|
||||||
auto it = window.properties.find(request.property);
|
auto it = window.properties.find(request.property);
|
||||||
if (it == window.properties.end())
|
if (it == window.properties.end())
|
||||||
|
|
@ -1978,7 +1887,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" window: {}", request.window);
|
dprintln(" window: {}", request.window);
|
||||||
dprintln(" property: {}", g_atoms_id_to_name[request.property]);
|
dprintln(" property: {}", g_atoms_id_to_name[request.property]);
|
||||||
|
|
||||||
auto& window = TRY_REF(get_window(request.window));
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
|
|
||||||
auto it = window.properties.find(request.property);
|
auto it = window.properties.find(request.property);
|
||||||
if (it == window.properties.end())
|
if (it == window.properties.end())
|
||||||
|
|
@ -2015,7 +1924,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" longOffset: {}", request.longOffset);
|
dprintln(" longOffset: {}", request.longOffset);
|
||||||
dprintln(" longLength: {}", request.longLength);
|
dprintln(" longLength: {}", request.longLength);
|
||||||
|
|
||||||
auto& window = TRY_REF(get_window(request.window));
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
|
|
||||||
auto it = window.properties.find(request.property);
|
auto it = window.properties.find(request.property);
|
||||||
if (it == window.properties.end())
|
if (it == window.properties.end())
|
||||||
|
|
@ -2098,7 +2007,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("ListProperties");
|
dprintln("ListProperties");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(wid));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
|
|
||||||
xListPropertiesReply reply {
|
xListPropertiesReply reply {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
|
|
@ -2348,7 +2257,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("QueryPointer");
|
dprintln("QueryPointer");
|
||||||
dprintln(" window: {}", wid);
|
dprintln(" window: {}", wid);
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(wid));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
|
|
||||||
int32_t root_x, root_y;
|
int32_t root_x, root_y;
|
||||||
int32_t event_x, event_y;
|
int32_t event_x, event_y;
|
||||||
|
|
@ -2482,7 +2391,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("FreePixmap");
|
dprintln("FreePixmap");
|
||||||
dprintln(" pixmap: {}", pid);
|
dprintln(" pixmap: {}", pid);
|
||||||
|
|
||||||
(void)TRY_REF(get_pixmap(pid));
|
(void)TRY_REF(get_pixmap(client_info, pid, opcode));
|
||||||
client_info.objects.remove(pid);
|
client_info.objects.remove(pid);
|
||||||
g_objects.remove(pid);
|
g_objects.remove(pid);
|
||||||
|
|
||||||
|
|
@ -2659,6 +2568,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln("FreeGC");
|
dprintln("FreeGC");
|
||||||
dprintln(" gc: {}", gc);
|
dprintln(" gc: {}", gc);
|
||||||
|
|
||||||
|
(void)TRY_REF(get_gc(client_info, gc, opcode));
|
||||||
client_info.objects.remove(gc);
|
client_info.objects.remove(gc);
|
||||||
g_objects.remove(gc);
|
g_objects.remove(gc);
|
||||||
|
|
||||||
|
|
@ -2676,10 +2586,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" width: {}", request.width);
|
dprintln(" width: {}", request.width);
|
||||||
dprintln(" height: {}", request.height);
|
dprintln(" height: {}", request.height);
|
||||||
|
|
||||||
auto& object = *g_objects[request.window];
|
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||||
ASSERT(object.type == Object::Type::Window);
|
auto& texture = window.texture();
|
||||||
|
|
||||||
auto& texture = object.object.get<Object::Window>().texture();
|
|
||||||
|
|
||||||
if (request.width == 0)
|
if (request.width == 0)
|
||||||
request.width = texture.width() - request.x;
|
request.width = texture.width() - request.x;
|
||||||
|
|
@ -2706,71 +2614,21 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" width: {}", request.width);
|
dprintln(" width: {}", request.width);
|
||||||
dprintln(" heigth: {}", request.height);
|
dprintln(" heigth: {}", request.height);
|
||||||
|
|
||||||
auto& src_drawable = TRY_REF(get_drawable(request.srcDrawable));
|
auto [src_data_u32, src_w, src_h, _] = TRY(get_drawable_info(client_info, request.srcDrawable, opcode));
|
||||||
auto [src_data, src_w, src_h, src_depth] = get_drawable_info(src_drawable);
|
auto [dst_data_u32, dst_w, dst_h, _] = TRY(get_drawable_info(client_info, request.dstDrawable, opcode));
|
||||||
|
|
||||||
auto& dst_drawable = TRY_REF(get_drawable(request.dstDrawable));
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
||||||
auto [dst_data, dst_w, dst_h, dst_depth] = get_drawable_info(dst_drawable);
|
|
||||||
|
|
||||||
auto& gc_object = *g_objects[request.gc];
|
|
||||||
ASSERT(gc_object.type == Object::Type::GraphicsContext);
|
|
||||||
auto& gc = gc_object.object.get<Object::GraphicsContext>();
|
|
||||||
|
|
||||||
const auto get_pixel =
|
const auto get_pixel =
|
||||||
[&](int32_t x, int32_t y) -> uint32_t
|
[src_data_u32, src_w](int32_t x, int32_t y) -> uint32_t
|
||||||
{
|
{
|
||||||
const int32_t index = y * src_w + x;
|
return src_data_u32[y * src_w + x];
|
||||||
const auto src_data_u32 = src_data.as_span<uint32_t>();
|
|
||||||
return src_data_u32[index];
|
|
||||||
|
|
||||||
switch (src_depth)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
const int32_t byte = index / 8;
|
|
||||||
const int32_t bit = index % 8;
|
|
||||||
return (src_data[byte] & (1 << bit)) ? 0xFFFFFF : 0x000000;
|
|
||||||
}
|
|
||||||
case 24:
|
|
||||||
case 32:
|
|
||||||
{
|
|
||||||
const auto src_data_u32 = src_data.as_span<uint32_t>();
|
|
||||||
return src_data_u32[index];
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto set_pixel =
|
const auto set_pixel =
|
||||||
[&](int32_t x, int32_t y, uint32_t color) -> void
|
[dst_data_u32, dst_w](int32_t x, int32_t y, uint32_t color) -> void
|
||||||
{
|
{
|
||||||
const int32_t index = y * dst_w + x;
|
dst_data_u32[y * dst_w + x] = color;
|
||||||
const auto dst_data_u32 = dst_data.as_span<uint32_t>();
|
|
||||||
dst_data_u32[index] = color;
|
|
||||||
|
|
||||||
switch (dst_depth)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
const int32_t byte = index / 8;
|
|
||||||
const int32_t bit = index % 8;
|
|
||||||
if (color)
|
|
||||||
dst_data[byte] |= (1 << bit);
|
|
||||||
else
|
|
||||||
dst_data[byte] &= ~(1 << bit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 24:
|
|
||||||
case 32:
|
|
||||||
{
|
|
||||||
const auto dst_data_u32 = dst_data.as_span<uint32_t>();
|
|
||||||
dst_data_u32[index] = color;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32_t start_x = request.srcX < request.dstX ? request.width - 1 : 0;
|
const int32_t start_x = request.srcX < request.dstX ? request.width - 1 : 0;
|
||||||
|
|
@ -2816,7 +2674,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
TRY(encode(client_info.output_buffer, event));
|
TRY(encode(client_info.output_buffer, event));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst_drawable.type == Object::Type::Window)
|
if (g_objects[request.dstDrawable]->type == Object::Type::Window)
|
||||||
invalidate_window(request.dstDrawable, request.dstX, request.dstY, request.width, request.height);
|
invalidate_window(request.dstDrawable, request.dstX, request.dstY, request.width, request.height);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -2829,14 +2687,10 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" drawable: {}", request.drawable);
|
dprintln(" drawable: {}", request.drawable);
|
||||||
dprintln(" gc: {}", request.gc);
|
dprintln(" gc: {}", request.gc);
|
||||||
|
|
||||||
auto& gc_object = *g_objects[request.gc];
|
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
||||||
ASSERT(gc_object.type == Object::Type::GraphicsContext);
|
|
||||||
auto& gc = gc_object.object.get<Object::GraphicsContext>();
|
|
||||||
|
|
||||||
const auto foreground = gc_object.object.get<Object::GraphicsContext>().foreground;
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
||||||
|
const auto foreground = gc.foreground;
|
||||||
auto& drawable = TRY_REF(get_drawable(request.drawable));
|
|
||||||
auto [data, w, h, depth] = get_drawable_info(drawable);
|
|
||||||
|
|
||||||
dprintln(" rects:");
|
dprintln(" rects:");
|
||||||
while (!packet.empty())
|
while (!packet.empty())
|
||||||
|
|
@ -2849,16 +2703,15 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
const int32_t min_x = BAN::Math::max<int32_t>(rect.x, 0);
|
const int32_t min_x = BAN::Math::max<int32_t>(rect.x, 0);
|
||||||
const int32_t min_y = BAN::Math::max<int32_t>(rect.y, 0);
|
const int32_t min_y = BAN::Math::max<int32_t>(rect.y, 0);
|
||||||
const int32_t max_x = BAN::Math::min<int32_t>(rect.x + rect.width, w);
|
const int32_t max_x = BAN::Math::min<int32_t>(rect.x + rect.width, out_w);
|
||||||
const int32_t max_y = BAN::Math::min<int32_t>(rect.y + rect.height, h);
|
const int32_t max_y = BAN::Math::min<int32_t>(rect.y + rect.height, out_h);
|
||||||
|
|
||||||
auto* data_u32 = data.as_span<uint32_t>().data();
|
|
||||||
for (int32_t y = min_y; y < max_y; y++)
|
for (int32_t y = min_y; y < max_y; y++)
|
||||||
for (int32_t x = min_x; x < max_x; x++)
|
for (int32_t x = min_x; x < max_x; x++)
|
||||||
if (!gc.is_clipped(x, y))
|
if (!gc.is_clipped(x, y))
|
||||||
data_u32[y * w + x] = foreground;
|
out_data_u32[y * out_w + x] = foreground;
|
||||||
|
|
||||||
if (drawable.type == Object::Type::Window)
|
if (g_objects[request.drawable]->type == Object::Type::Window)
|
||||||
invalidate_window(request.drawable, min_x, min_y, max_x - min_x, max_y - min_y);
|
invalidate_window(request.drawable, min_x, min_y, max_x - min_x, max_y - min_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2872,16 +2725,10 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" drawable: {}", request.drawable);
|
dprintln(" drawable: {}", request.drawable);
|
||||||
dprintln(" gc: {}", request.gc);
|
dprintln(" gc: {}", request.gc);
|
||||||
|
|
||||||
auto& gc_object = *g_objects[request.gc];
|
auto [out_data_32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
||||||
ASSERT(gc_object.type == Object::Type::GraphicsContext);
|
|
||||||
auto& gc = gc_object.object.get<Object::GraphicsContext>();
|
|
||||||
|
|
||||||
const auto foreground = gc_object.object.get<Object::GraphicsContext>().foreground;
|
auto& gc = TRY_REF(get_gc(client_info, request.gc, X_PolyFillArc));
|
||||||
|
const auto foreground = gc.foreground;
|
||||||
auto& object = *g_objects[request.drawable];
|
|
||||||
ASSERT(object.type == Object::Type::Window);
|
|
||||||
|
|
||||||
auto& texture = object.object.get<Object::Window>().texture();
|
|
||||||
|
|
||||||
const auto normalize_angle =
|
const auto normalize_angle =
|
||||||
[](float f) -> float
|
[](float f) -> float
|
||||||
|
|
@ -2906,8 +2753,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
const int32_t min_x = BAN::Math::max<int32_t>(0, arc.x);
|
const int32_t min_x = BAN::Math::max<int32_t>(0, arc.x);
|
||||||
const int32_t min_y = BAN::Math::max<int32_t>(0, arc.y);
|
const int32_t min_y = BAN::Math::max<int32_t>(0, arc.y);
|
||||||
|
|
||||||
const int32_t max_x = BAN::Math::min<int32_t>(texture.width(), arc.x + arc.width);
|
const int32_t max_x = BAN::Math::min<int32_t>(out_w, arc.x + arc.width);
|
||||||
const int32_t max_y = BAN::Math::min<int32_t>(texture.height(), arc.y + arc.height);
|
const int32_t max_y = BAN::Math::min<int32_t>(out_h, arc.y + arc.height);
|
||||||
|
|
||||||
const auto rx = arc.width / 2;
|
const auto rx = arc.width / 2;
|
||||||
const auto ry = arc.height / 2;
|
const auto ry = arc.height / 2;
|
||||||
|
|
@ -2947,11 +2794,12 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gc.is_clipped(x, y))
|
if (!gc.is_clipped(x, y))
|
||||||
texture.set_pixel(x, y, foreground);
|
out_data_32[y * out_w + x] = foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_objects[request.drawable]->type == Object::Type::Window)
|
||||||
invalidate_window(request.drawable, min_x, min_y, max_x - min_x, max_y - min_y);
|
invalidate_window(request.drawable, min_x, min_y, max_x - min_x, max_y - min_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2973,12 +2821,10 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" height: {}", request.height);
|
dprintln(" height: {}", request.height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto& object = TRY_REF(get_drawable(request.drawable));
|
|
||||||
auto [out_data, out_w, out_h, out_depth] = get_drawable_info(object);
|
|
||||||
|
|
||||||
auto& gc_object = *g_objects[request.gc];
|
auto [out_data, out_w, out_h, out_depth] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
||||||
ASSERT(gc_object.type == Object::Type::GraphicsContext);
|
|
||||||
auto& gc = gc_object.object.get<Object::GraphicsContext>();
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
||||||
|
|
||||||
if (packet.empty())
|
if (packet.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -2987,7 +2833,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
put_image({
|
put_image({
|
||||||
.out_data = out_data.data(),
|
.out_data = out_data,
|
||||||
.out_x = request.dstX,
|
.out_x = request.dstX,
|
||||||
.out_y = request.dstY,
|
.out_y = request.dstY,
|
||||||
.out_w = out_w,
|
.out_w = out_w,
|
||||||
|
|
@ -3006,7 +2852,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.gc = gc,
|
.gc = gc,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (object.type == Object::Type::Window)
|
if (g_objects[request.drawable]->type == Object::Type::Window)
|
||||||
invalidate_window(request.drawable, request.dstX, request.dstY, request.width, request.height);
|
invalidate_window(request.drawable, request.dstX, request.dstY, request.width, request.height);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -3024,8 +2870,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" height: {}", request.height);
|
dprintln(" height: {}", request.height);
|
||||||
dprintln(" planeMask: {}", request.planeMask);
|
dprintln(" planeMask: {}", request.planeMask);
|
||||||
|
|
||||||
auto& object = *g_objects[request.drawable];
|
auto [in_data, in_w, in_h, in_depth] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
||||||
auto [in_data, in_w, in_h, in_depth] = get_drawable_info(object);
|
|
||||||
|
|
||||||
const auto dwords = image_dwords(request.width, request.height, in_depth);
|
const auto dwords = image_dwords(request.width, request.height, in_depth);
|
||||||
|
|
||||||
|
|
@ -3045,7 +2890,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
get_image({
|
get_image({
|
||||||
.out_data = out_data,
|
.out_data = out_data,
|
||||||
.in_data = in_data.data(),
|
.in_data = in_data,
|
||||||
.in_x = request.x,
|
.in_x = request.x,
|
||||||
.in_y = request.y,
|
.in_y = request.y,
|
||||||
.in_w = in_w,
|
.in_w = in_w,
|
||||||
|
|
@ -3200,7 +3045,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" x: {}", request.x);
|
dprintln(" x: {}", request.x);
|
||||||
dprintln(" y: {}", request.y);
|
dprintln(" y: {}", request.y);
|
||||||
|
|
||||||
const auto& source = TRY_REF(get_pixmap(request.source));
|
const auto& source = TRY_REF(get_pixmap(client_info, request.source, opcode));
|
||||||
ASSERT(source.depth == 1);
|
ASSERT(source.depth == 1);
|
||||||
|
|
||||||
const uint32_t foreground =
|
const uint32_t foreground =
|
||||||
|
|
@ -3226,7 +3071,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
if (request.mask != None)
|
if (request.mask != None)
|
||||||
{
|
{
|
||||||
const auto& mask = TRY_REF(get_pixmap(request.mask));
|
const auto& mask = TRY_REF(get_pixmap(client_info, request.mask, opcode));
|
||||||
ASSERT(mask.depth == 1);
|
ASSERT(mask.depth == 1);
|
||||||
ASSERT(mask.width == source.width);
|
ASSERT(mask.width == source.width);
|
||||||
ASSERT(mask.height == source.height);
|
ASSERT(mask.height == source.height);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ set(SOURCES
|
||||||
Font.cpp
|
Font.cpp
|
||||||
Image.cpp
|
Image.cpp
|
||||||
Keymap.cpp
|
Keymap.cpp
|
||||||
|
SafeGetters.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Extensions.h"
|
#include "Extensions.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
|
#include "SafeGetters.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
|
@ -42,21 +43,8 @@ static bool is_local_socket(int socket)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan packet)
|
static BAN::ErrorOr<void*> get_shmseg(Client& client_info, CARD32 shmseg, BYTE op_major, BYTE op_minor)
|
||||||
{
|
{
|
||||||
struct DrawableInfo
|
|
||||||
{
|
|
||||||
BAN::ByteSpan data;
|
|
||||||
CARD32 w, h;
|
|
||||||
CARD8 depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t major_opcode = packet[0];
|
|
||||||
const uint8_t minor_opcode = packet[1];
|
|
||||||
|
|
||||||
const auto get_shmseg =
|
|
||||||
[&client_info, minor_opcode, major_opcode](CARD32 shmseg) -> BAN::ErrorOr<void*>
|
|
||||||
{
|
|
||||||
auto it = g_objects.find(shmseg);
|
auto it = g_objects.find(shmseg);
|
||||||
if (it != g_objects.end() && it->value->type == Object::Type::Extension)
|
if (it != g_objects.end() && it->value->type == Object::Type::Extension)
|
||||||
{
|
{
|
||||||
|
|
@ -70,72 +58,19 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||||
.errorCode = static_cast<BYTE>(s_shm_error_base + BadShmSeg),
|
.errorCode = static_cast<BYTE>(s_shm_error_base + BadShmSeg),
|
||||||
.sequenceNumber = client_info.sequence,
|
.sequenceNumber = client_info.sequence,
|
||||||
.resourceID = shmseg,
|
.resourceID = shmseg,
|
||||||
.minorCode = minor_opcode,
|
.minorCode = op_minor,
|
||||||
.majorCode = major_opcode,
|
.majorCode = op_major,
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, error));
|
TRY(encode(client_info.output_buffer, error));
|
||||||
return BAN::Error::from_errno(ENOENT);
|
return BAN::Error::from_errno(ENOENT);
|
||||||
};
|
}
|
||||||
|
|
||||||
const auto get_drawable =
|
static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
[&client_info, minor_opcode, major_opcode](WINDOW drawable) -> BAN::ErrorOr<Object&>
|
{
|
||||||
{
|
const uint8_t op_major = packet[0];
|
||||||
auto it = g_objects.find(drawable);
|
const uint8_t op_minor = packet[1];
|
||||||
if (it == g_objects.end() || (it->value->type != Object::Type::Window && it->value->type != Object::Type::Pixmap))
|
|
||||||
{
|
|
||||||
xError error {
|
|
||||||
.type = X_Error,
|
|
||||||
.errorCode = BadDrawable,
|
|
||||||
.sequenceNumber = client_info.sequence,
|
|
||||||
.resourceID = drawable,
|
|
||||||
.minorCode = minor_opcode,
|
|
||||||
.majorCode = major_opcode,
|
|
||||||
};
|
|
||||||
TRY(encode(client_info.output_buffer, error));
|
|
||||||
return BAN::Error::from_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *it->value;
|
switch (op_minor)
|
||||||
};
|
|
||||||
|
|
||||||
const auto get_drawable_info =
|
|
||||||
[](Object& object) -> DrawableInfo
|
|
||||||
{
|
|
||||||
DrawableInfo info;
|
|
||||||
|
|
||||||
switch (object.type)
|
|
||||||
{
|
|
||||||
case Object::Type::Window:
|
|
||||||
{
|
|
||||||
auto& window = object.object.get<Object::Window>();
|
|
||||||
auto& texture = window.texture();
|
|
||||||
|
|
||||||
info.data = { reinterpret_cast<uint8_t*>(texture.pixels().data()), texture.pixels().size() * 4 };
|
|
||||||
info.w = texture.width();
|
|
||||||
info.h = texture.height();
|
|
||||||
info.depth = window.depth;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Object::Type::Pixmap:
|
|
||||||
{
|
|
||||||
auto& pixmap = object.object.get<Object::Pixmap>();
|
|
||||||
|
|
||||||
info.data = pixmap.data;
|
|
||||||
info.w = pixmap.width;
|
|
||||||
info.h = pixmap.height;
|
|
||||||
info.depth = pixmap.depth;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (packet[1])
|
|
||||||
{
|
{
|
||||||
case X_ShmQueryVersion:
|
case X_ShmQueryVersion:
|
||||||
{
|
{
|
||||||
|
|
@ -200,7 +135,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||||
dprintln("ShmDetach");
|
dprintln("ShmDetach");
|
||||||
dprintln(" shmseg: {}", request.shmseg);
|
dprintln(" shmseg: {}", request.shmseg);
|
||||||
|
|
||||||
void* shm_segment = TRY(get_shmseg(request.shmseg));
|
void* shm_segment = TRY(get_shmseg(client_info, request.shmseg, op_major, op_minor));
|
||||||
shmdt(shm_segment);
|
shmdt(shm_segment);
|
||||||
|
|
||||||
client_info.objects.remove(request.shmseg);
|
client_info.objects.remove(request.shmseg);
|
||||||
|
|
@ -231,17 +166,14 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||||
dprintln(" offset: {}", request.offset);
|
dprintln(" offset: {}", request.offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* shm_segment = TRY(get_shmseg(request.shmseg));
|
void* shm_segment = TRY(get_shmseg(client_info, request.shmseg, op_major, op_minor));
|
||||||
|
|
||||||
auto& object = TRY_REF(get_drawable(request.drawable));
|
auto [out_data, out_w, out_h, out_depth] = TRY(get_drawable_info(client_info, request.drawable, op_major, op_minor));
|
||||||
auto [out_data, out_w, out_h, out_depth] = get_drawable_info(object);
|
|
||||||
|
|
||||||
auto& gc_object = *g_objects[request.gc];
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, op_major, op_minor));
|
||||||
ASSERT(gc_object.type == Object::Type::GraphicsContext);
|
|
||||||
auto& gc = gc_object.object.get<Object::GraphicsContext>();
|
|
||||||
|
|
||||||
put_image({
|
put_image({
|
||||||
.out_data = out_data.data(),
|
.out_data = out_data,
|
||||||
.out_x = request.dstX,
|
.out_x = request.dstX,
|
||||||
.out_y = request.dstY,
|
.out_y = request.dstY,
|
||||||
.out_w = out_w,
|
.out_w = out_w,
|
||||||
|
|
@ -260,7 +192,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||||
.gc = gc,
|
.gc = gc,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (object.type == Object::Type::Window)
|
if (g_objects[request.drawable]->type == Object::Type::Window)
|
||||||
invalidate_window(request.drawable, request.dstX, request.dstY, request.srcWidth, request.srcHeight);
|
invalidate_window(request.drawable, request.dstX, request.dstY, request.srcWidth, request.srcHeight);
|
||||||
|
|
||||||
if (request.sendEvent)
|
if (request.sendEvent)
|
||||||
|
|
@ -292,16 +224,15 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||||
dprintln(" shmseg: {}", request.shmseg);
|
dprintln(" shmseg: {}", request.shmseg);
|
||||||
dprintln(" offset: {}", request.offset);
|
dprintln(" offset: {}", request.offset);
|
||||||
|
|
||||||
void* shm_segment = TRY(get_shmseg(request.shmseg));
|
void* shm_segment = TRY(get_shmseg(client_info, request.shmseg, op_major, op_minor));
|
||||||
|
|
||||||
auto& object = TRY_REF(get_drawable(request.drawable));
|
auto [in_data, in_w, in_h, in_depth] = TRY(get_drawable_info(client_info, request.drawable, op_major, op_minor));
|
||||||
auto [in_data, in_w, in_h, in_depth] = get_drawable_info(object);
|
|
||||||
|
|
||||||
const auto dwords = image_dwords(request.width, request.height, in_depth);
|
const auto dwords = image_dwords(request.width, request.height, in_depth);
|
||||||
|
|
||||||
get_image({
|
get_image({
|
||||||
.out_data = (uint8_t*)shm_segment + request.offset,
|
.out_data = (uint8_t*)shm_segment + request.offset,
|
||||||
.in_data = in_data.data(),
|
.in_data = in_data,
|
||||||
.in_x = request.x,
|
.in_x = request.x,
|
||||||
.in_y = request.y,
|
.in_y = request.y,
|
||||||
.in_w = in_w,
|
.in_w = in_w,
|
||||||
|
|
@ -339,7 +270,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||||
|
|
||||||
ASSERT(request.depth == 24 || request.depth == 32);
|
ASSERT(request.depth == 24 || request.depth == 32);
|
||||||
|
|
||||||
void* shm_segment = TRY(get_shmseg(request.shmseg));
|
void* shm_segment = TRY(get_shmseg(client_info, request.shmseg, op_major, op_minor));
|
||||||
|
|
||||||
TRY(client_info.objects.insert(request.pid));
|
TRY(client_info.objects.insert(request.pid));
|
||||||
TRY(g_objects.insert(
|
TRY(g_objects.insert(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Definitions.h"
|
#include "Definitions.h"
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
|
#include "SafeGetters.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <BAN/Endianness.h>
|
#include <BAN/Endianness.h>
|
||||||
|
|
@ -500,76 +501,6 @@ static bool matches_pattern(const char* pattern, const char* string)
|
||||||
return *string ? false : true;
|
return *string ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DrawableInfo
|
|
||||||
{
|
|
||||||
uint32_t* out_data_u32;
|
|
||||||
uint32_t out_w, out_h;
|
|
||||||
};
|
|
||||||
|
|
||||||
BAN::ErrorOr<DrawableInfo> get_drawable_info(Client& client_info, CARD32 drawable, BYTE opcode)
|
|
||||||
{
|
|
||||||
auto drawable_it = g_objects.find(drawable);
|
|
||||||
if (drawable_it == g_objects.end() || (drawable_it->value->type != Object::Type::Window && drawable_it->value->type != Object::Type::Pixmap))
|
|
||||||
{
|
|
||||||
xError error {
|
|
||||||
.type = X_Error,
|
|
||||||
.errorCode = BadDrawable,
|
|
||||||
.sequenceNumber = client_info.sequence,
|
|
||||||
.resourceID = drawable,
|
|
||||||
.minorCode = 0,
|
|
||||||
.majorCode = opcode,
|
|
||||||
};
|
|
||||||
TRY(encode(client_info.output_buffer, error));
|
|
||||||
return BAN::Error::from_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawableInfo info;
|
|
||||||
|
|
||||||
switch (drawable_it->value->type)
|
|
||||||
{
|
|
||||||
case Object::Type::Window:
|
|
||||||
{
|
|
||||||
auto& texture = drawable_it->value->object.get<Object::Window>().texture();
|
|
||||||
info.out_data_u32 = texture.pixels().data();
|
|
||||||
info.out_w = texture.width();
|
|
||||||
info.out_h = texture.height();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Object::Type::Pixmap:
|
|
||||||
{
|
|
||||||
auto& pixmap = drawable_it->value->object.get<Object::Pixmap>();
|
|
||||||
info.out_data_u32 = reinterpret_cast<uint32_t*>(pixmap.data.data());
|
|
||||||
info.out_w = pixmap.width;
|
|
||||||
info.out_h = pixmap.height;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BAN::ErrorOr<Object::GraphicsContext&> get_gc(Client& client_info, CARD32 gc, BYTE opcode)
|
|
||||||
{
|
|
||||||
auto it = g_objects.find(gc);
|
|
||||||
if (it == g_objects.end() || it->value->type != Object::Type::GraphicsContext)
|
|
||||||
{
|
|
||||||
xError error {
|
|
||||||
.type = X_Error,
|
|
||||||
.errorCode = BadGC,
|
|
||||||
.sequenceNumber = client_info.sequence,
|
|
||||||
.resourceID = gc,
|
|
||||||
.minorCode = 0,
|
|
||||||
.majorCode = opcode,
|
|
||||||
};
|
|
||||||
TRY(encode(client_info.output_buffer, error));
|
|
||||||
return BAN::Error::from_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return it->value->object.get<Object::GraphicsContext>();
|
|
||||||
}
|
|
||||||
|
|
||||||
static BAN::ErrorOr<BAN::RefPtr<PCFFont>> get_fontable(Client& client_info, CARD32 fid, BYTE opcode)
|
static BAN::ErrorOr<BAN::RefPtr<PCFFont>> get_fontable(Client& client_info, CARD32 fid, BYTE opcode)
|
||||||
{
|
{
|
||||||
auto it = g_objects.find(fid);
|
auto it = g_objects.find(fid);
|
||||||
|
|
@ -809,7 +740,7 @@ BAN::ErrorOr<void> poly_text(Client& client_info, BAN::ConstByteSpan packet, boo
|
||||||
dprintln(" x: {}", request.x);
|
dprintln(" x: {}", request.x);
|
||||||
dprintln(" y: {}", request.y);
|
dprintln(" y: {}", request.y);
|
||||||
|
|
||||||
auto [out_data_u32, out_w, out_h] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
||||||
|
|
||||||
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
||||||
|
|
||||||
|
|
@ -880,7 +811,7 @@ BAN::ErrorOr<void> image_text(Client& client_info, BAN::ConstByteSpan packet, bo
|
||||||
dprintln(" x: {}", request.x);
|
dprintln(" x: {}", request.x);
|
||||||
dprintln(" y: {}", request.y);
|
dprintln(" y: {}", request.y);
|
||||||
|
|
||||||
auto [out_data_u32, out_w, out_h] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, opcode));
|
||||||
|
|
||||||
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, opcode));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include "SafeGetters.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <X11/X.h>
|
||||||
|
|
||||||
|
BAN::ErrorOr<Object::Window&> get_window(Client& client_info, CARD32 wid, BYTE op_major, BYTE op_minor)
|
||||||
|
{
|
||||||
|
auto it = g_objects.find(wid);
|
||||||
|
if (it == g_objects.end() || it->value->type != Object::Type::Window)
|
||||||
|
{
|
||||||
|
xError error {
|
||||||
|
.type = X_Error,
|
||||||
|
.errorCode = BadWindow,
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.resourceID = wid,
|
||||||
|
.minorCode = op_minor,
|
||||||
|
.majorCode = op_major,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, error));
|
||||||
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->value->object.get<Object::Window>();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<Object::Pixmap&> get_pixmap(Client& client_info, CARD32 pid, BYTE op_major, BYTE op_minor)
|
||||||
|
{
|
||||||
|
auto it = g_objects.find(pid);
|
||||||
|
if (it == g_objects.end() || it->value->type != Object::Type::Pixmap)
|
||||||
|
{
|
||||||
|
xError error {
|
||||||
|
.type = X_Error,
|
||||||
|
.errorCode = BadPixmap,
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.resourceID = pid,
|
||||||
|
.minorCode = op_minor,
|
||||||
|
.majorCode = op_major,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, error));
|
||||||
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->value->object.get<Object::Pixmap>();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<Object::GraphicsContext&> get_gc(Client& client_info, CARD32 gc, BYTE op_major, BYTE op_minor)
|
||||||
|
{
|
||||||
|
auto it = g_objects.find(gc);
|
||||||
|
if (it == g_objects.end() || it->value->type != Object::Type::GraphicsContext)
|
||||||
|
{
|
||||||
|
xError error {
|
||||||
|
.type = X_Error,
|
||||||
|
.errorCode = BadGC,
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.resourceID = gc,
|
||||||
|
.minorCode = op_minor,
|
||||||
|
.majorCode = op_major,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, error));
|
||||||
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->value->object.get<Object::GraphicsContext>();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<DrawableInfo> get_drawable_info(Client& client_info, CARD32 drawable, BYTE op_major, BYTE op_minor)
|
||||||
|
{
|
||||||
|
auto drawable_it = g_objects.find(drawable);
|
||||||
|
if (drawable_it == g_objects.end() || (drawable_it->value->type != Object::Type::Window && drawable_it->value->type != Object::Type::Pixmap))
|
||||||
|
{
|
||||||
|
xError error {
|
||||||
|
.type = X_Error,
|
||||||
|
.errorCode = BadDrawable,
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.resourceID = drawable,
|
||||||
|
.minorCode = op_minor,
|
||||||
|
.majorCode = op_major,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, error));
|
||||||
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawableInfo info;
|
||||||
|
|
||||||
|
switch (drawable_it->value->type)
|
||||||
|
{
|
||||||
|
case Object::Type::Window:
|
||||||
|
{
|
||||||
|
auto& window = drawable_it->value->object.get<Object::Window>();
|
||||||
|
auto& texture = window.texture();
|
||||||
|
info.data_u32 = texture.pixels().data();
|
||||||
|
info.w = texture.width();
|
||||||
|
info.h = texture.height();
|
||||||
|
info.depth = window.depth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Object::Type::Pixmap:
|
||||||
|
{
|
||||||
|
auto& pixmap = drawable_it->value->object.get<Object::Pixmap>();
|
||||||
|
info.data_u32 = reinterpret_cast<uint32_t*>(pixmap.data.data());
|
||||||
|
info.w = pixmap.width;
|
||||||
|
info.h = pixmap.height;
|
||||||
|
info.depth = pixmap.depth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Definitions.h"
|
||||||
|
|
||||||
|
struct DrawableInfo
|
||||||
|
{
|
||||||
|
uint32_t* data_u32;
|
||||||
|
uint32_t w, h;
|
||||||
|
uint8_t depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::ErrorOr<Object::Window&> get_window(Client& client_info, CARD32 wid, BYTE op_major, BYTE op_minor = 0);
|
||||||
|
BAN::ErrorOr<Object::Pixmap&> get_pixmap(Client& client_info, CARD32 pid, BYTE op_major, BYTE op_minor = 0);
|
||||||
|
BAN::ErrorOr<Object::GraphicsContext&> get_gc(Client& client_info, CARD32 gc, BYTE op_major, BYTE op_minor = 0);
|
||||||
|
BAN::ErrorOr<DrawableInfo> get_drawable_info(Client& client_info, CARD32 drawable, BYTE op_major, BYTE op_minor = 0);
|
||||||
Loading…
Reference in New Issue