129 lines
3.7 KiB
C
Executable File
129 lines
3.7 KiB
C
Executable File
#if 0
|
|
mkdir -p build
|
|
clang -o build/demo -g x11.c -lX11
|
|
exit 0
|
|
#endif
|
|
|
|
/*
|
|
** Reading From:
|
|
** (1) xlib manual https://tronche.com/gui/x/xlib/
|
|
*/
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
int main(int argc, char **argv){
|
|
/* (1) /display/opening.html
|
|
** " The XOpenDisplay() function returns a Display structure that serves
|
|
** as the connection to the X server and that contains all the
|
|
** information about that X server. "
|
|
*/
|
|
Display *display = XOpenDisplay(0);
|
|
if (display == 0){
|
|
printf("XOpenDisplay failed\n");
|
|
}
|
|
|
|
/* (1) /window-information/XInternAtom.html
|
|
** " returns the atom identifier associated with the specified
|
|
** atom_name string "
|
|
*/
|
|
Atom atom__WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", False);
|
|
|
|
/* (1) /window/XCreateWindow.html
|
|
** " The XCreateWindow function creates an unmapped subwindow for a
|
|
** specified parent window "
|
|
*/
|
|
Window window = 0;
|
|
if (display != 0){
|
|
Window parent = DefaultRootWindow(display);
|
|
int x = 0;
|
|
int y = 0;
|
|
int w = 640;
|
|
int h = 480;
|
|
int border_width = 0;
|
|
int depth = CopyFromParent;
|
|
unsigned int xclass = InputOutput;
|
|
Visual *visual = CopyFromParent;
|
|
unsigned long valuemask = CWEventMask;
|
|
|
|
XSetWindowAttributes attributes = {0};
|
|
attributes.event_mask = StructureNotifyMask;
|
|
|
|
window = XCreateWindow(display, parent, x, y, w, h, border_width,
|
|
depth, xclass, visual, valuemask,
|
|
&attributes);
|
|
|
|
if (window == 0){
|
|
printf("XCreateWindow failed\n");
|
|
}
|
|
}
|
|
|
|
if (window != 0){
|
|
/* (1) /ICC/client-to-window-manager/XStoreName.html
|
|
** " assigns the name passed to window_name to the specified window "
|
|
*/
|
|
XStoreName(display, window, "Example Window");
|
|
|
|
/* (1) /window/XMapWindow.html
|
|
** " maps the window and all of its subwindows that have had map requests "
|
|
**~ NOTE: This makes the window visible on the screen.
|
|
*/
|
|
XMapWindow(display, window);
|
|
|
|
/*~ NOTE: Main loop */
|
|
int exit_loop = 0;
|
|
for (;!exit_loop;){
|
|
|
|
/* (1) /event-handling/XPending.html
|
|
** " returns the number of events that have been received from the X
|
|
** server but have not been removed from the event queue "
|
|
**~ NOTE: The docs say this returns the number of events, but it's
|
|
** easier, and possibly more reliable to just use it to check if
|
|
** there is at lesat one input.
|
|
*/
|
|
for (;XPending(display) > 0;){
|
|
/* (1) /event-handling/manipulating-event-queue/XNextEvent.html
|
|
** " copies the first event from the event queue into the specified
|
|
** XEvent structure and then removes it from the queue "
|
|
*/
|
|
XEvent event;
|
|
XNextEvent(display, &event);
|
|
|
|
/* (1) /events/structures.html
|
|
** " The XEvent structure is a union of the individual structures
|
|
** declared for each event type. Depending on the type, you should
|
|
** access members of each event by using the XEvent union. "
|
|
*/
|
|
switch (event.type){
|
|
case ClientMessage: {
|
|
Atom atom = event.xclient.data.l[0];
|
|
if (atom == atom__WM_DELETE_WINDOW){
|
|
exit_loop = 1;
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*~ NOTE: Shutdown */
|
|
|
|
/* (1) /window/XDestroyWindow.html
|
|
** " destroys the specified window as well as all of its subwindows "
|
|
*/
|
|
if (display != 0 && window != 0){
|
|
XDestroyWindow(display, window);
|
|
}
|
|
|
|
/* (1) /display/closing.html
|
|
** " To close a display or disconnect from the X server, use
|
|
** XCloseDisplay(). "
|
|
*/
|
|
if (display != 0){
|
|
XCloseDisplay(display);
|
|
}
|
|
|
|
return(0);
|
|
}
|