Skip to content

Instantly share code, notes, and snippets.

@0xd61
Last active November 17, 2023 22:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xd61/43d2fa8b93c9656cca92956b70a5216f to your computer and use it in GitHub Desktop.
Save 0xd61/43d2fa8b93c9656cca92956b70a5216f to your computer and use it in GitHub Desktop.
Linux XCB Fullscreen Toggle Snippet
//
// This section is just for context
//
#include <xcb/xcb.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef float real32;
typedef double real64;
typedef int32 bool32;
#define Assert(Expression) if(!(Expression)) {__builtin_trap();}
struct xcb_context
{
const xcb_setup_t *Setup;
xcb_connection_t *Connection;
xcb_format_t *Format;
xcb_window_t Window;
xcb_atom_t Protocols;
xcb_atom_t DeleteWindow;
xcb_pixmap_t CursorPixmap;
xcb_cursor_t Cursor;
};
inline uint16
SafeTruncateSize16(uint32 Value)
{
Assert(Value <= 0xFFFF);
uint16 Result = (uint16)Value;
return (Result);
}
internal uint32
StringLength(char *String)
{
uint32 Result = 0;
while(*String++)
{
++Result;
}
return(Result);
}
//
//
//
internal xcb_intern_atom_reply_t*
LinuxXCBInternAtomHelper(xcb_context *Context, char *AtomID)
{
xcb_intern_atom_reply_t *Result;
uint32 AtomIDCount = StringLength(AtomID);
xcb_intern_atom_cookie_t AtomCookie = xcb_intern_atom(Context->Connection, 0, SafeTruncateSize16(AtomIDCount), AtomID);
xcb_flush(Context->Connection);
Result = xcb_intern_atom_reply(Context->Connection, AtomCookie, 0);
return(Result);
}
internal void
LinuxToggleFullscreen(xcb_context *Context)
{
// TODO(dgl): @@cleanup Naming and Types
xcb_intern_atom_reply_t *AtomState = LinuxXCBInternAtomHelper(Context, "_NET_WM_STATE");
xcb_intern_atom_reply_t *AtomFullscreen = LinuxXCBInternAtomHelper(Context, "_NET_WM_STATE_FULLSCREEN");
xcb_get_property_cookie_t CurrentFullscreenCookie = xcb_get_property(Context->Connection,
0, /* _delete */
Context->Window,
AtomState->atom,
XCB_ATOM_ATOM,
0, sizeof(xcb_atom_t)*);
xcb_get_property_reply_t *CurrentFullscreenProperty = xcb_get_property_reply(Context->Connection, CurrentFullscreenCookie, NULL);
xcb_atom_t *CurrentAtomFullscreen = (xcb_atom_t *)xcb_get_property_value(CurrentFullscreenProperty);
bool32 IsFullscreen = (*CurrentAtomFullscreen == AtomFullscreen->atom);
if(IsFullscreen)
{
xcb_delete_property(Context->Connection,
Context->Window,
AtomState->atom);
}
else
{
xcb_change_property(Context->Connection,
XCB_PROP_MODE_REPLACE,
Context->Window,
AtomState->atom,
XCB_ATOM_ATOM, sizeof(xcb_atom_t)*, 1,
&(AtomFullscreen->atom));
}
free(CurrentFullscreenProperty);
free(AtomState);
free(AtomFullscreen);
xcb_unmap_window(Context->Connection, Context->Window);
xcb_map_window(Context->Connection, Context->Window);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment