[Share Experiences] 其实直接调用xlib来绘制界面也不是不可以
Tofloor
poster avatar
把一切操作变成GUI
deepin
Backbone of ecological co-construction group
2023-05-21 12:07
Author

众所周知,Linux平台下大部分图形界面库像gtk,fltk,qt的底层都是基于xlib和xcb进行的一个调用和封装而已,

所以,

其实直接调用xlib来绘制界面也不是不可以,只不过稍微代码多一点而已,但是资源消耗可是极低,

Rust中调用xlib进行窗口绘制的简单示例:就简单绘制一个窗口

Cargo.toml

[package]
name = "one"
version = "0.1.0"
edition = "2021"



[dependencies]
libc="0.2"

main.rs

extern crate libc; // 引入 libc crate
use libc::{c_int, c_ulong,c_void,c_long}; // 引入 c_int 和 c_ulong 类型
use std::ffi::CString; // 引入 CString 类型
use std::ptr; // 引入指针模块
use core::ffi::*;

#[link(name = "X11")] // 链接 xlib 库
extern "C" {
    // 声明 xlib 库中的函数
    fn XOpenDisplay(display_name: *const i8) -> *mut c_ulong;
    fn XDefaultRootWindow(display: *mut c_ulong) -> c_ulong;
    fn XCreateSimpleWindow(
        display: *mut c_ulong,
        parent: c_ulong,
        x: c_int,
        y: c_int,
        width: c_uint,
        height: c_uint,
        border_width: c_uint,
        border: c_ulong,
        background: c_ulong,
    ) -> c_ulong;
    fn XSelectInput(display: *mut c_ulong, window: c_ulong, event_mask: c_long);
    fn XMapWindow(display: *mut c_ulong, window: c_ulong);
    fn XStoreName(display: *mut c_ulong, window: c_ulong, window_name: *const i8);
    fn XDrawString(
        display: *mut c_ulong,
        window: c_ulong,
        gc: *mut c_void,
        x: c_int,
        y: c_int,
        string: *const i8,
        length: c_int,
    );
    fn XDefaultGC(display: *mut c_ulong, screen_number: c_int) -> *mut c_void;
    fn XNextEvent(display: *mut c_ulong, event_return: *mut XEvent) -> c_int;
}

#[repr(C)] // 指定 C 语言兼容的内存布局
union XEvent { // 声明一个联合体类型来表示 xlib 库中的 XEvent 类型
    type_: c_int,
    pad: [c_long; 24],
}

const EXPOSE_EVENT_TYPE: i32 = 12; // 定义一个常量来表示重绘事件类型

fn main() {
    unsafe { // 使用 unsafe 块来调用外部函数
        let display = XOpenDisplay(ptr::null()); // 打开显示器
        let window = XCreateSimpleWindow( // 创建窗口
            display,
            XDefaultRootWindow(display),
            0,
            0,
            200,
            100,
            1,
            0,
            0xFFFFFF,
        );
        let gc = XDefaultGC(display, 0); // 获取默认的图形上下文
        let window_name = CString::new("Hello, World!").unwrap(); // 创建窗口标题字符串
        XStoreName(display, window, window_name.as_ptr()); // 设置窗口标题
        XSelectInput(display, window, 1 << EXPOSE_EVENT_TYPE); // 监听重绘事件
        XMapWindow(display, window); // 显示窗口

        loop { // 进入事件循环
            let mut event = std::mem::MaybeUninit::::uninit(); // 创建一个未初始化的 XEvent 变量
            XNextEvent(display, event.as_mut_ptr()); // 等待下一个事件
            let event = event.assume_init(); // 获取事件数据
            if event.type_ == EXPOSE_EVENT_TYPE { // 如果是重绘事件
                let text = CString::new("Hello, World!").unwrap(); // 创建文本字符串
                XDrawString( // 在窗口中绘制文本
                    display,
                    window,
                    gc,
                    50,
                    50,
                    text.as_ptr(),
                    text.to_bytes().len() as i32,
                );
            }
        }
    }
}

录屏_选择区域_20230521040156.gif

内存才180K
image.png

文件占用储存空间4MB左右。


但是不知道那个窗口绘制文本为什么不显示,还得再看看接口,不熟悉xlib😢

Reply Favorite View the author
All Replies
deepin尐助手
deepin
2023-05-21 12:10
#1

wayland 协议就没法用了

Reply View the author
阿尼樱奈奈
Moderator
2023-05-21 15:46
#2

applaud

Reply View the author
W2J
deepin
2023-05-21 17:42
#3

说干就干,Rust使用的进展很快嘛,你这位同学

Reply View the author
W2J
deepin
2023-05-21 17:44
#4

你Rust程序的窗口竟然是圆角的,cool!

Reply View the author
xiao80
deepin
2023-05-21 20:59
#5

显示文字需要字体吧。
把 rust 用在这种示例上,代码表示不堪累赘。

Reply View the author
longzhx
deepin
2023-05-21 22:59
#6

用了 unsafe ,也就不再rust了

Reply View the author
把一切操作变成GUI
deepin
Backbone of ecological co-construction group
2023-05-22 02:02
#7
longzhx

用了 unsafe ,也就不再rust了

这个示例只是表明可以用xlib而已,具体用c还是rust,这个看个人喜好吧

Reply View the author
把一切操作变成GUI
deepin
Backbone of ecological co-construction group
2023-05-22 02:03
#8
xiao80

显示文字需要字体吧。
把 rust 用在这种示例上,代码表示不堪累赘。

那个文字忘了删除了,不打算显示文字了😂 只是想显示个窗口让大家知道xlib的存在。

这个示例只是表明可以用xlib而已,具体用c还是rust,这个看个人喜好吧

Reply View the author
justforlxz
deepin developers team
2023-05-22 18:04
#9
W2J

你Rust程序的窗口竟然是圆角的,cool!

全局圆角插件表示哭晕在厕所 sob

Reply View the author