Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse the rest of the connection setup buffer to get the screens, depths, and visual types #8

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

MadLittleMods
Copy link
Contributor

@MadLittleMods MadLittleMods commented Sep 15, 2023

Parse the rest of the connection setup buffer to get the screens, depths, and visual types

This is one step on the path towards making the window transparent (support 32-bit color depth). Even though you can use 0xAARRGGBB colors, the alpha channel has no effect when using the 24-bit color depth that gets inherited from the root window by default.

If you naively, only set create_window.Args.depth = 32, you get a ErrorCode.match error when creating the window.

So when creating the window, I think we need to also set the matching visual type ID that has the correct depth and .true_color and use it when creating the window. Albeit, you still get a ErrorCode.match error at this point.

Judging from the conversation on this StackOverflow question, I think another piece is figuring out what colormap to set on window.Options.colormap but I can tackle this in another follow-up PR if necessary -> #9

Tested with Zig 0.11.0 on Manjaro Linux (arch-based) with XFCE.

Update: Now tested with Zig 0.13.0


Feel free to nit whatever 🙇. I'm new to Zig and X11 development so there is bound to be better patterns to accomplish some of these things and would love to learn the better ways.

Testing

zig build test --summary all
zig test x.zig

Dev notes

(source https://www.x.org/releases/current/doc/xproto/x11protocol.html#Encoding::Connection_Setup)

Connection setup buffer format
     1     1                               Success
     1                                     unused
     2     CARD16                          protocol-major-version
     2     CARD16                          protocol-minor-version
     2     8+2n+(v+p+m)/4                  length in 4-byte units of
                                           "additional data"
     4     CARD32                          release-number
     4     CARD32                          resource-id-base
     4     CARD32                          resource-id-mask
     4     CARD32                          motion-buffer-size
     2     v                               length of vendor
     2     CARD16                          maximum-request-length
     1     CARD8                           number of SCREENs in roots
     1     n                               number for FORMATs in
                                           pixmap-formats
     1                                     image-byte-order
          0     LSBFirst
          1     MSBFirst
     1                                     bitmap-format-bit-order
          0     LeastSignificant
          1     MostSignificant
     1     CARD8                           bitmap-format-scanline-unit
     1     CARD8                           bitmap-format-scanline-pad
     1     KEYCODE                         min-keycode
     1     KEYCODE                         max-keycode
     4                                     unused
     v     STRING8                         vendor
     p                                     unused, p=pad(v)
     8n     LISTofFORMAT                   pixmap-formats
     m     LISTofSCREEN                    roots (m is always a multiple of 4)
FORMAT
     1     CARD8                           depth
     1     CARD8                           bits-per-pixel
     1     CARD8                           scanline-pad
     5                                     unused
SCREEN
     4     WINDOW                          root
     4     COLORMAP                        default-colormap
     4     CARD32                          white-pixel
     4     CARD32                          black-pixel
     4     SETofEVENT                      current-input-masks
     2     CARD16                          width-in-pixels
     2     CARD16                          height-in-pixels
     2     CARD16                          width-in-millimeters
     2     CARD16                          height-in-millimeters
     2     CARD16                          min-installed-maps
     2     CARD16                          max-installed-maps
     4     VISUALID                        root-visual
     1                                     backing-stores
          0     Never
          1     WhenMapped
          2     Always
     1     BOOL                            save-unders
     1     CARD8                           root-depth
     1     CARD8                           number of DEPTHs in allowed-depths
     n     LISTofDEPTH                     allowed-depths (n is always a
                                           multiple of 4)
DEPTH
     1     CARD8                           depth
     1                                     unused
     2     n                               number of VISUALTYPES in visuals
     4                                     unused
     24n     LISTofVISUALTYPE              visuals
VISUALTYPE
     4     VISUALID                        visual-id
     1                                     class
          0     StaticGray
          1     GrayScale
          2     StaticColor
          3     PseudoColor
          4     TrueColor
          5     DirectColor
     1     CARD8                           bits-per-rgb-value
     2     CARD16                          colormap-entries
     4     CARD32                          red-mask
     4     CARD32                          green-mask
     4     CARD32                          blue-mask
     4                                     unused

The nested flexible array members (variable length array) of screens, depths, and visual types make the pointer arithmetic a bit more hairy than desired.

x.zig Outdated
};

var TEST_RECEIVED_CONNECT_SETUP_BUFFER align(4) = [_]u8{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some dummy data of 2x screens that have depths at 1, 4, 24, 32 and some visual types for each depth.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a comment to the diff ⏩

Copy link
Owner

Choose a reason for hiding this comment

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

Oh cool a unit test for a connection. Let's put this in a separate file though. Maybe we could add a test directory and put it in there? Or we could just add a test.zig?

Copy link
Contributor Author

@MadLittleMods MadLittleMods Sep 21, 2023

Choose a reason for hiding this comment

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

Moved the tests to a test/ directory and things seem to run as expected when using zig build test --summary all. Also had to rename the standalone test shell script to test.sh so it doesn't conflict with the directory.

Does that look about right?

Comment on lines +2545 to +2546
const format_list_offset = ConnectSetup.getFormatListOffset(self.fixed().vendor_len);
const format_list_limit = ConnectSetup.getFormatListLimit(format_list_offset, self.fixed().format_count);
Copy link
Contributor Author

@MadLittleMods MadLittleMods Sep 15, 2023

Choose a reason for hiding this comment

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

The signatures of these functions are little bit cumbersome to use everywhere.

It seems like we could update them to just reference everything from self and handle the complexity of getting the right fields in the functions. Is there a benefit to the current way?

ex.

pub fn getFormatListOffset(self: @This()) u32 {
    return VendorOffset + std.mem.alignForward(u32, self.fixed().vendor_len, 4);
}
pub fn getFormatListLimit(self: @This()) u32 {
    return self.getFormatListOffset() + (@sizeOf(Format) * self.fixed().format_count);
}

Then when someone wants to get the format list, they can simply just call...

Before:

const format_list_offset = x.ConnectSetup.getFormatListOffset(fixed.vendor_len);
const format_list_limit = x.ConnectSetup.getFormatListLimit(format_list_offset, fixed.format_count);
const formats = try conn.setup.getFormatList(format_list_offset, format_list_limit);

After:

const formats = try conn.setup.getFormatList();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(this is something for a future PR in any case)

MadLittleMods added a commit to MadLittleMods/zigx that referenced this pull request Dec 24, 2023
@@ -1,3 +1,4 @@
zig-cache/
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added this back because it's nice to be able to switch Zig versions without these files appearing in staging.

// This exposes a `test` step to the `zig build --help` menu, providing a way for
// the user to request running the unit tests.
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@marler8997 Friendly poke to review/merge (it's been updated to support Zig 0.13.0). I'd like to start getting some of these PR's merged so they don't keep stacking up with lots of juggling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants