Last active
November 17, 2023 22:05
-
-
Save 0xd61/43d2fa8b93c9656cca92956b70a5216f to your computer and use it in GitHub Desktop.
Linux XCB Fullscreen Toggle Snippet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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