xcb_change_gc(3)

πŸ“¦
version 1.17.0 Β· 4 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

xcb_change_gc πŸ’…βœ¨

okay bestie, welcome to the xcb_change_gc page from the XCB Requests corner of the manual universe πŸ¦‹ this is part 1 of the whole thing, so grab a lil drink and let's get into it πŸ“


🌸 NAME 🌸

xcb_change_gc β€” change graphics context components πŸ’–

like, it literally does what it says on the tin, no cap. you got a graphics context (a GC, the lil bundle of drawing settings) and you wanna swap out some of its components. this is the function that does the swapping ✨


πŸŽ€ SYNOPSIS πŸŽ€

#include <xcb/xproto.h>

Request function πŸ‘‘

xcb_void_cookie_t xcb_change_gc(xcb_connection_t *conn,
       xcb_gcontext_t gc, uint32_t value_mask, const void *value_list);

so here's the whole vibe, argument by argument, and yes you're gonna read all of them because we're thorough in this house 🫢

  • conn β€” your xcb_connection_t *, the connection to the X server. it's the lil thread tying you to everything, main character energy fr fr 🌈
  • gc β€” the xcb_gcontext_t you're messing with. this is the graphics context, the one getting its components changed, so be nice to it πŸ’œ
  • value_mask β€” a uint32_t that says which components you're changing. it's the mask, the "here's what I'm touching" list, iconic behavior only 😌
  • value_list β€” a const void * holding the actual values. it's giving "the receipts" for whatever value_mask promised πŸ”₯

and the return type is xcb_void_cookie_t, which is a void cookie β€” so you get a lil ticket back, not a value, because this request doesn't hand you a reply directly. slay ✨


bestie reminder: this is only part 1, so don't go anywhere πŸ’– the rest is coming and it's lowkey a lot, but we're gonna get through it together 🧚

πŸŽ€ REQUEST ARGUMENTS πŸŽ€

Okay bestie, here's who's who in this request. Pay attention, this is the good part. πŸ’–

  • conn β€” the XCB connection to X11. Like, the whole reason we're here. Your link to the mothership.
  • gc β€” the graphics context you wanna change. This is your main character right here. πŸ‘‘
  • value_mask β€” one of these lil guys. Pick your fighter:
    • XCB_GC_FUNCTION
TODO: Refer to GX. Yeah bestie, the original page really does just say that. Not me leaving it as-is πŸ’€
  • XCB_GC_PLANE_MASK β€” okay so in graphics operations, you give it a source pixel and a destination pixel, and the result gets computed bitwise on the corresponding bits of those pixels. Basically a Boolean operation happens in every single bit plane, no cap. The plane-mask restricts that operation to a subset of planes, so the result is:
((src FUNC dst) AND plane-mask) OR (dst AND (NOT plane-mask))

Iconic formula honestly. ✨

  • XCB_GC_FOREGROUND β€” foreground colorpixel.
  • XCB_GC_BACKGROUND β€” background colorpixel.
  • XCB_GC_LINE_WIDTH β€” measured in pixels. It can be greater than or equal to one (that's a wide line, periodt) or the special value zero, which is a thin line.
  • XCB_GC_LINE_STYLE β€” defines which sections of a line actually get drawn:
    • Solid β€” the full path of the line is drawn.
    • DoubleDash β€” the full path is drawn, but the even dashes get filled differently than the odd dashes (see fill-style), with Butt cap-style used wherever even and odd dashes meet.
    • OnOffDash β€” only the even dashes are drawn, and cap-style applies to all internal ends of the individual dashes (except NotLast, which is treated as Butt).
  • XCB_GC_CAP_STYLE β€” defines how the endpoints of a path get drawn:
    • NotLast β€” equivalent to Butt, except that for a line-width of zero the final endpoint is not drawn.
    • Butt β€” square at the endpoint (perpendicular to the slope of the line) with no projection beyond.
    • Round β€” a circular arc with its diameter equal to the line-width, centered on the endpoint; equivalent to Butt for line-width zero.
    • Projecting β€” square at the end, but the path continues beyond the endpoint for a distance equal to half the line-width; equivalent to Butt for line-width zero.
  • XCB_GC_JOIN_STYLE β€” defines how corners get drawn for wide lines:
    • Miter β€” the outer edges of the two lines extend to meet at an angle. But heads up, if that angle is less than 11 degrees, a Bevel join-style gets used instead.
    • Round β€” a circular arc with a diameter equal to the line-width, centered on the joinpoint.
    • Bevel β€” Butt endpoint styles, and then the triangular notch is filled.
  • XCB_GC_FILL_STYLE β€” defines the contents of the source for line, text, and fill requests. For all text and fill requests (for example, PolyText8, PolyText16, PolyFillRectangle, FillPoly, and PolyFillArc), as well as for line requests with line-style Solid (for example, PolyLine, PolySegment, PolyRectangle, PolyArc), and for the even dashes for line requests with line-style OnOffDash or DoubleDash:
    • Solid β€” Foreground
    • Tiled β€” Tile
    • OpaqueStippled β€” a tile with the same width and height as stipple but with background everywhere stipple has a zero and with foreground everywhere stipple has a one
    • Stippled β€” Foreground masked by stipple

And for the odd dashes for line requests with line-style DoubleDash:

  • Solid β€” Background
  • Tiled β€” same as for even dashes
  • OpaqueStippled β€” same as for even dashes
  • Stippled β€” Background masked by stipple
  • XCB_GC_FILL_RULE
Ngl the original page gives this one literally zero description. Nothing. Empty. It's giving mystery πŸ’…
  • XCB_GC_TILE β€” okay so the tile/stipple is an infinite two-dimensional plane, with the tile/stipple replicated in all dimensions. When that plane gets superimposed on the drawable for use in a graphics operation, the upper-left corner of some instance of the tile/stipple sits at the coordinates within the drawable specified by the tile/stipple origin. The tile/stipple and clip origins are interpreted relative to the origin of whatever destination drawable is specified in a graphics request. The tile pixmap must have the same root and depth as the gcontext (or a Match error results). The stipple pixmap must have depth one and must have the same root as the gcontext (or a Match error results). For fill-style Stippled (but not fill-style OpaqueStippled), the stipple pattern is tiled in a single plane and acts as an additional clip mask to be ANDed with the clip-mask. Any size pixmap can be used for tiling or stippling, although some sizes may be faster to use than others.
  • XCB_GC_STIPPLE β€” literally the exact same deal as tile/stipple above, so here it is again: the tile/stipple is an infinite two-dimensional plane, with the tile/stipple replicated in all dimensions. When that plane is superimposed on the drawable for use in a graphics operation, the upper-left corner of some instance of the tile/stipple is at the coordinates within the drawable specified by the tile/stipple origin. The tile/stipple and clip origins are interpreted relative to the origin of whatever destination drawable is specified in a graphics request. The tile pixmap must have the same root and depth as the gcontext (or a Match error results). The stipple pixmap must have depth one and must have the same root as the gcontext (or a Match error results). For fill-style Stippled (but not fill-style OpaqueStippled), the stipple pattern is tiled in a single plane and acts as an additional clip mask to be ANDed with the clip-mask. Any size pixmap can be used for tiling or stippling, although some sizes may be faster to use than others. πŸ¦‹
  • XCB_GC_TILE_STIPPLE_ORIGIN_X
TODO. Again, that's the whole thing. The page said TODO and I'm nothing if not honest. 😭
  • XCB_GC_TILE_STIPPLE_ORIGIN_Y
TODO. Same energy, bestie.
  • XCB_GC_FONT β€” which font to use for the ImageText8 and ImageText16 requests.
  • XCB_GC_SUBWINDOW_MODE β€” for ClipByChildren, both source and destination windows are additionally clipped by all viewable InputOutput children. For IncludeInferiors, neither source nor destination window is clipped by inferiors. That means you get subwindow contents included in the source, and drawing happens straight through subwindow boundaries of the destination. Using IncludeInferiors with a source or destination window of one depth with mapped inferiors of differing depth is not illegal, but the semantics is undefined by the core protocol. 🫠
  • XCB_GC_GRAPHICS_EXPOSURES β€” whether ExposureEvents should be generated (1) or not (0).

The default is 1.

  • XCB_GC_CLIP_ORIGIN_X
TODO. Yes, again. The page is like this, I don't make the rules. πŸ™ˆ
  • XCB_GC_CLIP_ORIGIN_Y
TODO. We stay consistent.
  • XCB_GC_CLIP_MASK β€” the clip-mask restricts writes to the destination drawable. Only pixels where the clip-mask has bits set to 1 are drawn. Pixels are not drawn outside the area covered by the clip-mask, or where the clip-mask has bits set to 0. The clip-mask affects all graphics requests, but it does not clip sources. The clip-mask origin is interpreted relative to the origin of whatever destination drawable is specified in a graphics request. If a pixmap is specified as the clip-mask, it must have depth 1 and have the same root as the gcontext (or a Match error results). If clip-mask is None, then pixels are always drawn, regardless of the clip origin. The clip-mask can also be set with the SetClipRectangles request.
  • XCB_GC_DASH_OFFSET
TODO. Bestie I'm just the messenger. 🌸
  • XCB_GC_DASH_LIST
TODO.
  • XCB_GC_ARC_MODE
TODO.
  • value_list β€” the values for each of the components you specified in the bitmask value_mask. The order has to correspond to the order of possible value_mask bits. Go look at the example, fr fr. ⭐

🌈 DESCRIPTION 🌈

Changes the components specified by value_mask for the specified graphics context.

That's it. That's the whole description. Short, sweet, gets the job done. πŸ’…

✨ RETURN VALUE ✨

okay so bestie, here's the tea on what you get back πŸ’…

You get an xcb_void_cookie_t. That's it, that's the whole vibe β€” it's a void cookie, meaning it's not carrying any juicy reply data for you. But here's the important part, so listen up πŸ‘‚: any errors (if there are any) have to be handled in the event loop. The cookie doesn't hand them to you directly. Periodt.

If you'd rather handle errors right away instead of waiting around for the event loop like it's the group chat, then use xcb_change_gc_checked. That one lets you check errors directly with xcb_request_check. Head over to xcb-requests(3) for the full breakdown, iykyk 🫢


πŸ’€ ERRORS πŸ’€

bestie these are the little gremlins that can pop up πŸ™ˆ

  • xcb_alloc_error_t β€” the X server could not allocate the requested resources (no memory? 😭 like it literally ran out of room for your stuff)
  • xcb_font_error_t β€” TODO: reasons?
  • xcb_g_context_error_t β€” TODO: reasons?
  • xcb_match_error_t β€” TODO: reasons?
  • xcb_pixmap_error_t β€” TODO: reasons?
  • xcb_value_error_t β€” TODO: reasons?
no cap, some of these reasons are literally still a TODO in the source. the manpage said what it said, so we're passing that energy straight through to you πŸ’–

🌸 EXAMPLE 🌸

here's the moment you've been waiting for, the actual code, slay ✨

/*
 * Changes the foreground color component of the specified graphics context.
 *
 */
void my_example(xcb_connection_t *conn, xcb_gcontext_t gc, uint32_t fg, uint32_t bg) {
    /* C99 allows us to use a compact way of changing a single component: */
    xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, (uint32_t[]){ fg });

    /* The more explicit way. Beware that the order of values is important! */
    uint32_t mask = 0;
    mask |= XCB_GC_FOREGROUND;
    mask |= XCB_GC_BACKGROUND;

    uint32_t values[] = {
        fg,
        bg
    };
    xcb_change_gc(conn, gc, mask, values);
    xcb_flush(conn);
}

okay a couple things to clock here πŸ‘‘

  1. the compact C99 way is giving minimalist icon behavior β€” you change just one component and pass it as a compound literal (uint32_t[]){ fg }
  2. the explicit way is more main character energy β€” you build up a mask with |= and then line up your values[] array
⚠️ and the comment said it, so imma say it louder: beware that the order of values is important! the array positions gotta match the order the bits are set in the mask, fr fr. don't get it twisted πŸŽ€

and then xcb_flush(conn) at the end because nothing goes out until you flush, bestie πŸ¦‹


πŸ‘‘ SEE ALSO πŸ‘‘


πŸŽ€ AUTHOR πŸŽ€

Generated from xproto.xml. Contact xcb@lists.freedesktop.org for corrections and improvements.


and that's a wrap on part 3, you ate that whole page up πŸ’…βœ¨ this lil cutie came to you from X Version 11, running libxcb 1.17.0, filed under xcb_change_gc(3). go forth and change those graphics contexts, bestie, you got this πŸ«ΆπŸ’–πŸŒˆ