generated from templates/simple-C-project
Annwan
5 months ago
6 changed files with 290 additions and 7 deletions
-
4.gitignore
-
17Build.moon
-
0README
-
59README.org
-
45src/common.h
-
172src/xel.c
@ -1,2 +1,2 @@ |
|||
/*.o |
|||
/out |
|||
*.o |
|||
/xel |
@ -0,0 +1,59 @@ |
|||
#+title: xel |
|||
|
|||
A (hopefully) better X Event Logger |
|||
|
|||
* What? |
|||
|
|||
For logging X events, the X.org projects provides the ~xev~ utility. While it |
|||
works, its CLI parsing is jank and its output is inconsistent. This utility aims |
|||
to provide a saner interface and a more consistant output (in the form of a TOML |
|||
object list). |
|||
|
|||
* How to build |
|||
|
|||
This project uses [[https://github.com/natnat-mc/moonbuild][Moonbuild]] as a build system. |
|||
|
|||
To compile: |
|||
#+begin_src shell |
|||
moonbuild |
|||
#+end_src |
|||
|
|||
* To use |
|||
|
|||
#+begin_example |
|||
Usage: |
|||
./xel -h |
|||
./xel [-e <ev>|-n <ev>]* [-a <id>] |
|||
Options: |
|||
-h Prints this message |
|||
-e ev Enable logging event category ev, can be repeated |
|||
-n ev Disable logging event category ev, can be repeated |
|||
If the first event specifier is -e the default is no event, |
|||
otherwise the default is all events |
|||
-a id Attach to window <id>, doesn't allow to specify events |
|||
Available event categories (for -e and -n): |
|||
keyboard, mouse, button, expose, visibility, structure, |
|||
substructure, focus, property, color_map, owner_grab_button |
|||
#+end_example |
|||
|
|||
* LICENSE |
|||
|
|||
Copyright © 2024 Annwan |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
|||
this software and associated documentation files (the “Software”), to deal in |
|||
the Software without restriction, including without limitation the rights to |
|||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
|||
the Software, and to permit persons to whom the Software is furnished to do so, |
|||
subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
|||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|||
|
|||
|
|||
NOTE: Code heavily inspired by the ~xev~ utility by the X.org project (available under the X.Org at [[https://gitlab.freedesktop.org/xorg/app/xev][the FreeDesktop Gitlab]]) |
|||
|
@ -0,0 +1,45 @@ |
|||
#ifndef COMMON_H |
|||
#define COMMON_H |
|||
|
|||
#include <stdint.h> |
|||
#include <stddef.h> |
|||
#include <stdbool.h> |
|||
|
|||
/*============================================================================== |
|||
| Sensible Type Names | |
|||
==============================================================================*/ |
|||
|
|||
/** 8-bit unsingned integer */ |
|||
typedef uint8_t u8; |
|||
/** 16-bit unsingned integer */ |
|||
typedef uint16_t u16; |
|||
/** 32-bit unsingned integer */ |
|||
typedef uint32_t u32; |
|||
/** 64-bit unsingned integer */ |
|||
typedef uint64_t u64; |
|||
|
|||
|
|||
/** 8-bit singned integer */ |
|||
typedef int8_t i8; |
|||
/** 16-bit singned integer */ |
|||
typedef int16_t i16; |
|||
/** 32-bit singned integer */ |
|||
typedef int32_t i32; |
|||
/** 64-bit singned integer */ |
|||
typedef int64_t i64; |
|||
|
|||
/** Unsinged pointer-capacity integer */ |
|||
typedef uintptr_t uptr; |
|||
/** Singed pointer-capacity integer */ |
|||
typedef intptr_t iptr; |
|||
/** Uninged size-capacity integer */ |
|||
typedef size_t usize; |
|||
/** Singed size-capacity integer */ |
|||
typedef ptrdiff_t isize; |
|||
|
|||
/** 32-bit IEEE754 floating point number*/ |
|||
typedef float f32; |
|||
/** 64-bit IEEE754 floating point number*/ |
|||
typedef double f64; |
|||
|
|||
#endif /* COMMON_H */ |
@ -0,0 +1,172 @@ |
|||
#include "common.h" |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <unistd.h> |
|||
#include <xcb/xcb.h> |
|||
#include <xcb/xproto.h> |
|||
|
|||
/* EVENT SETS */ |
|||
xcb_event_mask_t const KBD_EVENTS = XCB_EVENT_MASK_KEY_PRESS | |
|||
XCB_EVENT_MASK_KEY_RELEASE | |
|||
XCB_EVENT_MASK_KEYMAP_STATE; |
|||
xcb_event_mask_t const MOUSE_EVENTS = |
|||
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | |
|||
XCB_EVENT_MASK_BUTTON_1_MOTION | XCB_EVENT_MASK_BUTTON_2_MOTION | |
|||
XCB_EVENT_MASK_BUTTON_3_MOTION | XCB_EVENT_MASK_BUTTON_4_MOTION | |
|||
XCB_EVENT_MASK_BUTTON_5_MOTION | XCB_EVENT_MASK_BUTTON_MOTION | |
|||
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT | |
|||
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW; |
|||
xcb_event_mask_t const BUTTON_EVENTS = |
|||
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE; |
|||
xcb_event_mask_t const EXPOSE_EVENTS = XCB_EVENT_MASK_EXPOSURE; |
|||
xcb_event_mask_t const VISIBILITY_EVENTS = XCB_EVENT_MASK_VISIBILITY_CHANGE; |
|||
xcb_event_mask_t const STRUCTURE_EVENTS = XCB_EVENT_MASK_STRUCTURE_NOTIFY; |
|||
xcb_event_mask_t const SUBSTRUCTURE_EVENTS = |
|||
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; |
|||
xcb_event_mask_t const FOCUS_EVENTS = XCB_EVENT_MASK_FOCUS_CHANGE; |
|||
xcb_event_mask_t const PROPERTY_EVENTS = XCB_EVENT_MASK_PROPERTY_CHANGE; |
|||
xcb_event_mask_t const COLOR_MAP_EVENTS = XCB_EVENT_MASK_COLOR_MAP_CHANGE; |
|||
xcb_event_mask_t const OWNER_GRAB_EVENT = XCB_EVENT_MASK_OWNER_GRAB_BUTTON; |
|||
|
|||
void Usage(char *pname, FILE *dest) { |
|||
fprintf(dest, |
|||
"Usage:\n" |
|||
"\t%s -h\n" |
|||
"\t%s [-e <ev>|-n <ev>]* [-a <id>]\n" |
|||
"Options:\n" |
|||
"\t-h\tPrints this message\n" |
|||
"\t-e ev\tEnable logging event category ev, can " |
|||
"be repeated\n" |
|||
"\t-n ev\tDisable logging event category ev, can " |
|||
"be repeated\n" |
|||
"\t\tIf the first event specifier is -e the " |
|||
"default is no event,\n" |
|||
"\t\totherwise the default is all events\n" |
|||
"\t-a id\tAttach to window <id>, doesn't allow " |
|||
"to specify events\n" |
|||
"Available event categories (for -e and -n):\n" |
|||
"\tkeyboard, mouse, button, expose, visibility, structure,\n" |
|||
"\tsubstructure, focus, property, color_map, owner_grab_button\n", |
|||
pname, pname, pname); |
|||
} |
|||
|
|||
void ProcessEvent() {} |
|||
|
|||
void TakeFromMask(bool *inited, xcb_event_mask_t *mask, char *event) { |
|||
if (!*inited) { |
|||
*mask = ~(xcb_event_mask_t)0; |
|||
*inited = true; |
|||
} |
|||
if (!strcmp(event, "keyboard")) |
|||
*mask &= ~KBD_EVENTS; |
|||
else if (!strcmp(event, "mouse")) |
|||
*mask &= ~MOUSE_EVENTS; |
|||
else if (!strcmp(event, "button")) |
|||
*mask &= ~BUTTON_EVENTS; |
|||
else if (!strcmp(event, "expose")) |
|||
*mask &= ~EXPOSE_EVENTS; |
|||
else if (!strcmp(event, "visibility")) |
|||
*mask &= ~VISIBILITY_EVENTS; |
|||
else if (!strcmp(event, "structure")) |
|||
*mask &= ~STRUCTURE_EVENTS; |
|||
else if (!strcmp(event, "substructure")) |
|||
*mask &= ~SUBSTRUCTURE_EVENTS; |
|||
else if (!strcmp(event, "focus")) |
|||
*mask &= ~FOCUS_EVENTS; |
|||
else if (!strcmp(event, "property")) |
|||
*mask &= ~PROPERTY_EVENTS; |
|||
else if (!strcmp(event, "color_map")) |
|||
*mask &= ~COLOR_MAP_EVENTS; |
|||
else if (!strcmp(event, "owner_grab_button")) |
|||
*mask &= ~OWNER_GRAB_EVENT; |
|||
else { |
|||
fprintf(stderr, "Unkown event category: %s", event); |
|||
} |
|||
} |
|||
|
|||
void AddToMask(bool *inited, xcb_event_mask_t *mask, char *event) { |
|||
if (!*inited) { |
|||
*mask = 0; |
|||
*inited = true; |
|||
} |
|||
if (!strcmp(event, "keyboard")) |
|||
*mask |= KBD_EVENTS; |
|||
else if (!strcmp(event, "mouse")) |
|||
*mask |= MOUSE_EVENTS; |
|||
else if (!strcmp(event, "button")) |
|||
*mask |= BUTTON_EVENTS; |
|||
else if (!strcmp(event, "expose")) |
|||
*mask |= EXPOSE_EVENTS; |
|||
else if (!strcmp(event, "visibility")) |
|||
*mask |= VISIBILITY_EVENTS; |
|||
else if (!strcmp(event, "structure")) |
|||
*mask |= STRUCTURE_EVENTS; |
|||
else if (!strcmp(event, "substructure")) |
|||
*mask |= SUBSTRUCTURE_EVENTS; |
|||
else if (!strcmp(event, "focus")) |
|||
*mask |= FOCUS_EVENTS; |
|||
else if (!strcmp(event, "property")) |
|||
*mask |= PROPERTY_EVENTS; |
|||
else if (!strcmp(event, "color_map")) |
|||
*mask |= COLOR_MAP_EVENTS; |
|||
else if (!strcmp(event, "owner_grab_button")) |
|||
*mask |= OWNER_GRAB_EVENT; |
|||
else { |
|||
fprintf(stderr, "Unkown event category: %s", event); |
|||
} |
|||
} |
|||
|
|||
|
|||
i32 main(int argc, char *argv[]) { |
|||
|
|||
u32 window_id = 0; |
|||
bool mask_initialised = false; |
|||
xcb_event_mask_t mask; |
|||
i32 opt; |
|||
char *outfilename = NULL; |
|||
|
|||
while (opt = getopt(argc, argv, "hn:e:a:o:"), opt != -1) { |
|||
switch (opt) { |
|||
case 'h': |
|||
Usage(argv[0], stdout); |
|||
exit(0); |
|||
case 'n': |
|||
TakeFromMask(&mask_initialised, &mask, optarg); |
|||
break; |
|||
case 'e': |
|||
AddToMask(&mask_initialised, &mask, optarg); |
|||
break; |
|||
case 'a': |
|||
window_id = atol(optarg); |
|||
break; |
|||
case 'o': |
|||
outfilename = optarg; |
|||
break; |
|||
default: |
|||
Usage(argv[0], stderr); |
|||
exit(1); |
|||
} |
|||
} |
|||
if (!mask_initialised) { |
|||
mask = ~(xcb_event_mask_t)0; |
|||
} |
|||
FILE *outfile = stdout; |
|||
if (outfilename) { |
|||
outfile = fopen(outfilename, "w"); |
|||
} |
|||
xcb_connection_t *c = xcb_connect(NULL, NULL); |
|||
|
|||
if (window_id) { /* A window id has been provided */ |
|||
|
|||
|
|||
} else { /* We need to create our own window */ |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
/* cleanup */ |
|||
|
|||
return 0; |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue