Skip to content

Instantly share code, notes, and snippets.

@jezek
Created April 25, 2022 15:51
Show Gist options
  • Save jezek/9f00af7712a5d660e187fb9beca2bf4b to your computer and use it in GitHub Desktop.
Save jezek/9f00af7712a5d660e187fb9beca2bf4b to your computer and use it in GitHub Desktop.
C and go programs for x11 key press/release events bytes (discussed in https://github.com/jezek/xgb/issues/6).
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <xcb/xcb.h>
int main () {
/* Open the connection to the X server */
xcb_connection_t *connection = xcb_connect (NULL, NULL);
/* Get the first screen */
xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
/* Create the window */
xcb_window_t window = xcb_generate_id (connection);
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[2] = {
screen->white_pixel,
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE
};
xcb_create_window (connection,
0, /* depth */
window,
screen->root, /* parent window */
10, 10, /* x, y */
200, 200, /* width, height */
1, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
screen->root_visual, /* visual */
mask, values ); /* masks */
/* Map the window on the screen */
xcb_map_window (connection, window);
xcb_flush (connection);
/* Event loop */
xcb_generic_event_t *event;
while ( (event = xcb_wait_for_event (connection)) ) {
/* Keyboard events */
switch (event->response_type & ~0x80) {
case XCB_KEY_PRESS: {
xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
printf ("KeyPress : %x\n", kp->detail);
printf ("KeyPressBytes : ");
uint8_t* bytearray = (uint8_t*)kp;
for (int i=0; i<sizeof(xcb_key_press_event_t); i++) {
printf ("%02x ", bytearray[i]);
}
printf ("\n");
/* Exit on ESC key press */
if (kp->detail == 0x09) {
return 0;
}
break;
}
case XCB_KEY_RELEASE: {
xcb_key_release_event_t *kr = (xcb_key_release_event_t *)event;
printf ("KeyRelease: %x\n", kr->detail);
printf ("KeyReleaseBytes: ");
uint8_t* bytearray = (uint8_t*)kr;
for (int i=0; i<sizeof(xcb_key_release_event_t); i++) {
printf ("%02x ", bytearray[i]);
}
printf ("\n");
break;
}
}
free (event);
}
return 0;
}
package main
import (
"fmt"
"github.com/jezek/xgb"
"github.com/jezek/xgb/xproto"
)
func main() {
/* Open the connection to the X server */
X, err := xgb.NewConn()
if err != nil {
fmt.Println(err)
return
}
defer X.Close()
/* Get the first screen */
screen := xproto.Setup(X).DefaultScreen(X)
/* Create the window */
wid, _ := xproto.NewWindowId(X)
mask := uint32(xproto.CwBackPixel | xproto.CwEventMask)
values := []uint32{ // values must be in the order defined by the protocol
0xffffffff,
xproto.EventMaskKeyPress | xproto.EventMaskKeyRelease,
}
xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root,
10, 10, 200, 200, 1,
xproto.WindowClassInputOutput, screen.RootVisual, mask, values)
/* Map the window on the screen */
err = xproto.MapWindowChecked(X, wid).Check()
if err != nil {
fmt.Printf("Checked Error for mapping window %d: %s\n", wid, err)
}
/* Event loop */
for {
ev, xerr := X.WaitForEvent()
if ev == nil && xerr == nil {
fmt.Println("Both event and error are nil. Exiting...")
return
}
/* Keyboard events */
switch ev.(type) {
case xproto.KeyPressEvent:
kpe := ev.(xproto.KeyPressEvent)
fmt.Printf("KeyPress : %x\n", kpe.Detail)
fmt.Printf("KeyPressBytes :")
for i := range kpe.Bytes() {
fmt.Printf("%02x ", kpe.Bytes()[i])
}
fmt.Printf("\n")
/* Exit on ESC key press */
if kpe.Detail == 9 {
return
}
case xproto.KeyReleaseEvent:
kre := ev.(xproto.KeyReleaseEvent)
fmt.Printf("KeyRelease: %x\n", kre.Detail)
fmt.Printf("KeyReleaseBytes:")
for i := range kre.Bytes() {
fmt.Printf("%02x ", kre.Bytes()[i])
}
fmt.Printf("\n")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment