一. xlib 创建窗口

文章目录

    • 1.xlib
    • 2.第一个图形应用程序
    • 3.编译程序
    • 4.xlib与gtk、QT

xlib用于在linux操作系统下创建GUI应用程序,笔者在将duilib移植到linux操作系统下时,使用了xlib创建窗口、文本以及图片渲染。以此文档记录xlib的使用。目前跨平台的duilib界面库还在开发中,项目代码地址基于duilib的跨平台界面库

1.xlib

X Window System

什么是X Window System,以下是维基百科对于X Window System的解释

X窗口系统(X Window System,也常称为X11或X,天窗口系统)是一种以位图方式显示的软件窗口系统。最初是1984年麻省理工学院的研究,之后变成UNIX、类UNIX、以及OpenVMS等操作系统所一致适用的标准化软件工具包及显示架构的运作协议。X窗口系统通过软件工具及架构协议来建立操作系统所用的图形用户界面,此后则逐渐扩展适用到各形各色的其他操作系统上。现在几乎所有的操作系统都能支持与使用X。更重要的是,今日知名的桌面环境——GNOME和KDE也都是以X窗口系统为基础建构成的。

xlib

xlib是用于与X Window System进行交互的c语言库。这是构成X客户端的基础,允许应用程序创建窗口、绘制图形和管理用户输入等操作。

2.第一个图形应用程序

#include 
#include 
#include 

int main() {
    Display *display;
    Window window;
    int screen;

    /* 打开与X服务器的连接 */
    display = XOpenDisplay(NULL);
    if (display == NULL) {
        fprintf(stderr, "无法打开X显示器\n");
        exit(1);
    }

    screen = DefaultScreen(display);

    /* 创建窗口 */
    window = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 400, 300, 1,
                                 BlackPixel(display, screen), WhitePixel(display, screen));

    /* 显示(映射)窗口 */
    XMapWindow(display, window);

    XEvent  event;
    while (1) {
        XNextEvent(display,&event);
    }

    XDestroyWindow(display, window);
    XCloseDisplay(display);

    return 0;
}

以上代码XOpenDisplay返回一个Display类型的指针,xlib其本身是一个客户端/服务端架构的界面程序,XOpenDisplay用于说明将要连接的服务器。我们创建一个本地的界面应用程序,所以XOpenDisplay参数给NULL。DefaultScreen用于获取Display所对应的Server默认的屏幕编号。XCreateSimpleWindow用于创建一个窗口,该函数原型如下

extern Window XCreateSimpleWindow(
    Display*        /* display */,
    Window        /* parent */,
    int            /* x */,
    int            /* y */,
    unsigned int    /* width */,
    unsigned int    /* height */,
    unsigned int    /* border_width */,
    unsigned long    /* border */,
    unsigned long    /* background */
);

XMapWindow将XCreateSimpleWindow创建的窗口进行映射显示。XNetEvent,窗口创建成功后会产生许多类型的消息如显示,窗口大小变化、鼠标移动、键盘输入等事件,在Xlib中使用XNextEvent获取窗口的消息事件。并进行处理。

XDestroyWindow销毁创建的窗口。XCloseDisplay,关闭连接到X Server的句柄,并释放资源。

3.编译程序

在linux系统下编译xlib图形应用程序,需要x11开发包。本文以ubuntu20.04为例,描述如何编译xib操作系统。首先使用apt search查看x11的开发包是否已经安装。如下

apt search libx11-dev

若出现类似如下信息,说明xlib的开发包已经安装。

libx11-dev/focal-updates,focal-security,now 2:1.6.9-2ubuntu1.6 amd64 [已安装,自动]
  X11 client-side library (development headers)

若没有以上信息,则执行apt install安装xlib开发包

sudo apt install libx11-dev

我们可以使用gcc/g++或者clang编译以上源码。以下以gcc为例

gcc FirstUIApp.c -o FirstUIApp -lX11

在编译源码时我们需要链接libX11.so这样的库,如果没有链接这个库,则会提示XOpenDisplay等函数的实现找不到。编译后运行我们的程序,则会在屏幕上显示我们在linux操作系统下的第一个界面应用程序,运行结果如下

一. xlib 创建窗口_第1张图片

这里显示了一个空白的界面,界面的风格与你操作系统所设置的主题风格有关。

4.xlib与gtk、QT

xlib提供了较低层次的创建窗口的接口,gtk和qt对xlib进行了封装,便于开发,并提供了跨操作系统平台的接口功能,xlib运行在linux/unix系统,而gtk、qt可以运行在windows、linux以及mac系统。由于xlib的设计过于陈旧,现代操作系统中引入了一些新的界面框架,如wayland,通过使用ldd在ubuntu系统下分析libgtk-3.so动态库,该库依赖了libX11.so以及libwayland.so系统列的动态库。所以在这猜测gtk应该是对linux系统下多种窗口系统进行了封装,并向外提供统一的接口。关于QT使用ldd分析libQt5Gui.so动态库,其依赖了libGL.so、libGLX.so等动态库,而libGLX.so又依赖了libX11.so库,所以Qt库可能也是对xlib的接口进行封装,并提供跨平台访问接口。

最后我们可以打印系统环境变量获取当前操作系统使用的窗口系统,环境变量名为:XDG_SESSION_TYPE。

echo $XDG_SESSION_TYPE

当linux操作系统界面使用x11作为窗口系统时,以上打印x11,使用其它的窗口系统则会打印出相应的字符串信息如:wayland

你可能感兴趣的:(Linux,GUI程序,c++,linux,gui程序)