Skip to content

Instantly share code, notes, and snippets.

@caiorss
Last active October 18, 2020 17:22
Show Gist options
  • Save caiorss/f7f0b892011ad987bfed531336dbae89 to your computer and use it in GitHub Desktop.
Save caiorss/f7f0b892011ad987bfed531336dbae89 to your computer and use it in GitHub Desktop.
Xlib demo - X11 X Windows System
cmake_minimum_required(VERSION 3.9)
project(Simple_Cmake_Project)
#========== Global Configurations =============#
#----------------------------------------------#
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILE ON)
find_package(X11 REQUIRED)
#========== Targets Configurations ============#
add_executable( xlib-demo xlib-demo.cpp )
target_link_libraries( xlib-demo ${X11_LIBRARIES} )
# add_executable(app2 application2.cpp)
#include <iostream>
#include <string>
#include <cstring>
#include <cassert>
#include <X11/Xlib.h>
#include <cstdlib>
void abort_on_failure(bool predicate, const char* message = "Abort runtime.")
{
if(predicate) return;
std::fprintf(stderr, " [ABORT] %s", message);
abort();
}
int main(int argc, char** argv)
{
/** If the value passed to XOpenDisplay is null, the XClient (Xlib) attempts
* to connect to the display server designated by the environment variable
* $DISPLAY, which is often set to the :1.0 or the local machine.
*------------------------------------------------------------------------*/
Display* dpy = XOpenDisplay(nullptr);
abort_on_failure(dpy != nullptr, "Cannot open display.");
/** ----- Query Information about display server ------------------------*/
int version = XProtocolVersion(dpy);
std::cout << " [INFO] X11 protocol version = " << version << '\n';
const char* vendor = XServerVendor(dpy);
std::cout << " [INFO] X11 XServer vendor = " << vendor << '\n';
const char* disp_str = XDisplayString(dpy);
std::cout << " [INFO] X11 Display string = " << disp_str << '\n';
int n_screen = XScreenCount(dpy);
std::cout << " [INFO] Number of screens = " << n_screen << '\n';
/** ----- Draw Screen ------------------------------------------------*/
int screen = DefaultScreen(dpy);
Window wnd = XCreateSimpleWindow(
dpy // Display
, RootWindow(dpy, screen) // Parent Window
, 10, 20 // Position (x - horizontal, y - vertical) from top-left corner
, 400, 500 // Dimensions (width, height)
, 1 // Border width
, BlackPixel(dpy, screen) // Border
, WhitePixel(dpy, screen) // Background color
);
/* Casting void means that the return value (type int) is being ignored. */
(void) XStoreName(dpy, wnd, "X Windows-System X11");
// Makes window visible
XMapWindow(dpy, wnd);
XFlush(dpy);
XEvent event;
// Select events that the application is interested in.
// Only those events will notify the application. (XClient)
auto mask = ExposureMask
| ButtonPressMask // Event: mouse button press
| KeyPressMask // Event: key press (keyboard)
| KeyReleaseMask // Event: key release (keyboard)
//| PointerMotionMask // Event: Mouse Move
;
XSelectInput(dpy, wnd, mask);
// Process window close event in X11 event loop for(;;)
Atom wnd_del = XInternAtom(dpy, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(dpy, wnd, &wnd_del, 1);
const char* message = "Draw some string on X11 - X windows system.";
/* ------- X11 (X Windows System) - Event loop ------------ */
for(;;)
{
std::fprintf(stderr, "\n [TRACE] Waiting event. \n");;
// Get next X11 event
XNextEvent(dpy, &event);
if(event.type == ClientMessage){
fprintf(stderr, " [Event] User closed window. => Shutdown \n");
break;
}
if(event.type == Expose)
fprintf(stderr, " [Event] Expose event. \n");
if(event.type == KeyPress)
fprintf(stderr, " [Event] Key pressed. \n");
if(event.type == ButtonPress)
fprintf(stderr, " [Event] Mouse button pressed. \n");
if(event.type == PointerMotionMask)
fprintf(stderr, " [Event] Mouse button pressed. \n");
// X11 Graphics context, useful for drawing
GC gctx = DefaultGC(dpy, screen);
XFillRectangle( dpy, wnd, gctx
, 20, 50 // (x, y) position from top-left corner origin
, 100, 200 // width and height
);
GC gctx2 = DefaultGC(dpy, screen);
XDrawString( dpy // Pointer to display object
, wnd // Pointer to window
, gctx // Graphics context
, 90, 300 // (x, y) Position where string will be drawn (from top-left corner)
, message
, strlen(message) );
} // ----- End of event loop -------- //
fprintf(stderr, " [TRACE] User closed window. Shutdown application. Ok \n");
XDestroyWindow(dpy, wnd);
// Always close display
XCloseDisplay(dpy);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment