Skip to content
This repository was archived by the owner on Nov 12, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@ keywords = [ "x11", "xorg", "xproto", "xrs", "window" ]
categories = [ "data-structures", "api-bindings", "encoding" ]

[features]
default = ["big-requests"]
try = []

# Protocol Extentions

# Big Requests
# https://www.x.org/releases/X11R7.7/doc/bigreqsproto/bigreq.html
big-requests = []

[workspace]
# XRB is defined as a workspace that automatically includes all its path
# dependencies. Currently, that means `xrb-proc-macros` and `cornflakes`.
Expand Down
19 changes: 19 additions & 0 deletions src/big_requests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Messages defined in the [Big Requests extension].
//!
//! The [Big Requests extension] enables extended length field for large
//! requests.
//!
//! [Requests]: crate::message::Request
//! [Replies]: crate::message::Reply
//! [Big Requests extension]: https://www.x.org/releases/X11R7.7/doc/bigreqsproto/bigreq.html

/// This extension's internal name.
/// This is used to retrieve the major opcode for this extension.
pub const EXTENSION_NAME: &str = "BIG-REQUESTS";

pub mod reply;
pub mod request;
51 changes: 51 additions & 0 deletions src/big_requests/reply.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! [Replies] defined in the [Big Requests extension].
//!
//! [Replies] are messages sent from the X server to an X client in response to
//! a [request].
//!
//! [Replies]: crate::message::Reply
//! [request]: crate::message::Request
//! [Big Requests extension]: super

extern crate self as xrb;

use crate::{big_requests::request, message::Reply};
use derivative::Derivative;
use xrbk_macro::derive_xrb;

derive_xrb! {
/// The [reply] to a [`EnableBigRequests` request].
///
/// [reply]: Reply
///
/// [`EnableBigRequests` request]: request::EnableBigRequests
#[derive(Derivative, Debug, X11Size, Readable, Writable)]
#[derivative(Hash, PartialEq, Eq)]
pub struct EnableBigRequests: Reply for request::EnableBigRequests {
/// The sequence number identifying the [request] that generated this
/// [reply].
///
/// See [`Reply::sequence`] for more information.
///
/// [request]: crate::message::Request
/// [reply]: Reply
///
/// [`Reply::sequence`]: Reply
#[sequence]
#[derivative(Hash = "ignore", PartialEq = "ignore")]
pub sequence: u16,

/// The new maximum length for a [request].
///
/// This value will always be greater than the one returned in [initial setup].
///
/// [initial setup]: crate::connection
/// [request]: crate::message::Request
pub maximum_request_length: u32,
[_; 2],
}
}
34 changes: 34 additions & 0 deletions src/big_requests/request.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! [Requests] defined in the [Big Requests extension].
//!
//! [Requests] are messages sent from an X client to the X server.
//!
//! [Requests]: crate::message::Request
//! [Big Requests extension]: super

extern crate self as xrb;

use crate::{big_requests::reply, message::Request};
use derivative::Derivative;
use xrbk_macro::derive_xrb;

derive_xrb! {
/// A [request] that enables extended-length protocol requests for the requesting client.
///
/// # Replies
/// This [request] generates a [`EnableBigRequests` reply].
///
/// # Events and Errors
/// This request does not generate any [Events] or [Errors].
///
/// [request]: Request
/// [Events]: crate::message::Event
/// [Errors]: crate::message::Error
/// [`EnableBigRequests` reply]: reply::EnableBigRequests
#[derive(Derivative, Debug, X11Size, Readable, Writable)]
#[derivative(Hash, PartialEq, Eq)]
pub struct EnableBigRequests: Request(0 /* TODO: extensions use dynamic major opcodes */) -> reply::EnableBigRequests {}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not using the todo macro here, because it prevents the crate from compiling

}
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ pub mod connection;
pub mod message;
pub mod unit;
pub mod x11;

// Protocol Extensions

#[cfg(feature = "big-requests")]
pub mod big_requests;
15 changes: 15 additions & 0 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ pub trait Request: X11Size + Writable {
/// }
/// }
/// ```
#[cfg(not(feature = "big-requests"))]
#[allow(clippy::cast_possible_truncation)]
fn length(&self) -> u16 {
let size = self.x11_size();
Expand All @@ -135,6 +136,20 @@ pub trait Request: X11Size + Writable {

(size / 4) as u16
}

#[cfg(feature = "big-requests")]
#[allow(clippy::cast_possible_truncation)]
fn length(&self) -> u32 {
let size = self.x11_size();

assert_eq!(
size % 4,
0,
"expected Request size to be a multiple of 4, found {size}"
);

(size / 4) as u32
}
}

/// The result of sending a [request].
Expand Down
22 changes: 20 additions & 2 deletions src/x11/request/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ request_error! {
}
}

/// Writes the length of the request to the provided buffer.
fn write_size(request: &impl Request, buf: &mut impl BufMut) {
#[cfg(not(feature = "big-requests"))]
buf.put_u16(request.length());
#[cfg(feature = "big-requests")]
{
let length = request.length();
match u16::try_from(length) {
Ok(length) => buf.put_u16(length),
// length is too big for u16, using the extended length field
Err(_) => {
buf.put_u16(0);
buf.put_u32(length);
},
}
}
}

derive_xrb! {
/// A [request] that clears a particular area of a [window].
///
Expand Down Expand Up @@ -2102,7 +2120,7 @@ impl Writable for DrawText8 {
buf.put_u8(Self::MAJOR_OPCODE);
// Unused metabyte position.
buf.put_u8(0);
buf.put_u16(self.length());
write_size(self, buf);

self.target.write_to(buf)?;
self.graphics_context.write_to(buf)?;
Expand Down Expand Up @@ -2470,7 +2488,7 @@ impl Writable for DrawText16 {
buf.put_u8(Self::MAJOR_OPCODE);
// Unused metabyte position.
buf.put_u8(0);
buf.put_u16(self.length());
write_size(self, buf);

self.target.write_to(buf)?;
self.graphics_context.write_to(buf)?;
Expand Down
9 changes: 9 additions & 0 deletions src/x11/request/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use xrbk::{
ReadResult,
Readable,
Writable,
WriteError,
WriteResult,
X11Size,
};
Expand Down Expand Up @@ -1439,7 +1440,15 @@ impl<const KEYSYMS_PER_KEYCODE: usize> Writable for ChangeKeyboardMapping<KEYSYM
#[allow(clippy::cast_possible_truncation)]
fn write_to(&self, buf: &mut impl BufMut) -> WriteResult {
// Limit `buf` by the length (converted to bytes).
#[cfg(not(feature = "big-requests"))]
let buf = &mut buf.limit(usize::from(self.length()) * 4);
#[cfg(feature = "big-requests")]
let size = match usize::try_from(self.length()) {
Ok(size) => size * 4,

Err(error) => return Err(WriteError::Other(Box::new(error))),
};
let buf = &mut buf.limit(size);

// The major opcode.
Self::MAJOR_OPCODE.write_to(buf)?;
Expand Down
7 changes: 7 additions & 0 deletions xrbk_macro/src/definition/expansion/message_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,17 @@ impl Request {
#minor_opcode
};

#[cfg(not(feature = "big-requests"))]
#[allow(clippy::cast_possible_truncation)]
fn length(&self) -> u16 {
(<Self as ::xrbk::X11Size>::x11_size(self) / 4) as u16
}

#[cfg(feature = "big-requests")]
#[allow(clippy::cast_possible_truncation)]
fn length(&self) -> u32 {
(<Self as ::xrbk::X11Size>::x11_size(self) / 4) as u32
}
}
)
});
Expand Down
7 changes: 7 additions & 0 deletions xrbk_macro/src/definition/expansion/readable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,14 @@ impl Request {
// read.
#metabyte
// Read the request's length.
#[cfg(not(feature = "big-requests"))]
let length = <_ as ::xrbk::Buf>::get_u16(buf);
#[cfg(feature = "big-requests")]
let length = match <_ as ::xrbk::Buf>::get_u16(buf) as u32 {
0 => <_ as ::xrbk::Buf>::get_u32(buf),
length => length,
};

let buf = &mut <_ as ::xrbk::Buf>::take(
buf,
((length - 1) as usize) * 4,
Expand Down
22 changes: 22 additions & 0 deletions xrbk_macro/src/definition/expansion/writable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,32 @@ impl Request {
// Metabyte position
#metabyte
// Length
#[cfg(not(feature = "big-requests"))]
<_ as ::xrbk::BufMut>::put_u16(
buf,
<Self as xrb::message::Request>::length(&self),
);
#[cfg(feature = "big-requests")]
{
let length = <Self as xrb::message::Request>::length(&self);
match u16::try_from(length) {
Ok(length) => <_ as ::xrbk::BufMut>::put_u16(
buf,
length
),
// length is too big for u16, using the extended length field
Err(_) => {
<_ as ::xrbk::BufMut>::put_u16(
buf,
0,
);
<_ as ::xrbk::BufMut>::put_u32(
buf,
length,
);
},
}
}

// Other elements
#writes
Expand Down