Last active
October 18, 2020 17:22
-
-
Save caiorss/f7f0b892011ad987bfed531336dbae89 to your computer and use it in GitHub Desktop.
Xlib demo - X11 X Windows System
This file contains 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
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) | |
This file contains 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
#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