首页 文章

如何实现X11(屏幕像素的返回颜色)luajit的ffi的C代码?

提问于
浏览
0

我想用luajit录制我的屏幕的一小部分 .

除了http://luajit.org/ext_ffi.html之外,网上的Haven 't found any module for that. And there are barely any documentations/tutorials/examples about luajit' s ffi没有提供使用其他C库的任何示例 .

我有一个原生的C代码片段 . 你将如何实现luajit的ffi的C代码?

Luajit示例代码:

--ffi part

local screen = {}
for y = 1, 100 do
    for x = 1, 100 do
        local r, g, b = ffi.C.getpixel(x, y)
        table.insert(screen, r)
    end
end

C代码段:

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main()
{
    XColor c;
    Display *d = XOpenDisplay((char *) NULL);

    int x=1920/2;  // Pixel x 
    int y=1080/2;  // Pixel y

    XImage *image;
    image = XGetImage (d, XRootWindow (d, XDefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
    c.pixel = XGetPixel (image, 0, 0);
    XFree (image);
    XQueryColor (d, XDefaultColormap(d, XDefaultScreen (d)), &c);
    printf("%d %d %d\n", c.red/256, c.green/256, c.blue/256);

    return 0;
}

1 回答

  • 0

    基本上,您只需将标头中的所有声明复制到 ffi.cdef 部分,然后通过库的句柄调用这些名称 . 原则上,您可以将C代码一对一转换,但获取变量的地址除外 . 但是,这是在您链接的FFI教程中记录的(http://luajit.org/ext_ffi_tutorial.html#idioms

    C code          Lua code
    Functions with outargs      int len = x;    local len = ffi.new("int[1]", x)
    void foo(int *inoutlen);    foo(&len);      foo(len)
                                y = len;        y = len[0]
    

    这是您在LuaJIT中的C代码 . 我没有复制 DisplayXImage 的定义,因为我们从不访问它们的成员,只使用它们的指针,因此它们仍然是不透明的 struct .

    local ffi = assert(require("ffi"))
    
    ffi.cdef[[
    // Types from various headers
    typedef struct _Display Display;
    typedef struct _XImage XImage;
    typedef struct {
            unsigned long pixel;
            unsigned short red, green, blue;
            char flags;  /* do_red, do_green, do_blue */
            char pad;
    } XColor; // Xlib.h
    typedef unsigned long XID; // Xdefs.h
    typedef XID Window; // X.h
    typedef XID Drawable; // X.h
    typedef XID Colormap; // X.h
    
    // Functions from Xlib.h
    Display *XOpenDisplay(
        char*       /* display_name */
    );
    int XDefaultScreen(
        Display*            /* display */
    );
    Window XRootWindow(
        Display*            /* display */,
        int                 /* screen_number */
    );
    XImage *XGetImage(
        Display*            /* display */,
        Drawable            /* d */,
        int                 /* x */,
        int                 /* y */,
        unsigned int        /* width */,
        unsigned int        /* height */,
        unsigned long       /* plane_mask */,
        int                 /* format */
    );
    int XFree(
        void*               /* data */
    );
    int XQueryColor(
        Display*            /* display */,
        Colormap            /* colormap */,
        XColor*             /* def_in_out */
    );
    Colormap XDefaultColormap(
        Display*            /* display */,
        int                 /* screen_number */
    );
    // Functions from Xutil.h
    unsigned long XGetPixel(
            XImage *ximage,
            int x, int y);
    ]]
    
    local X11 = assert(ffi.load("X11"))
    
    local AllPlanes = -1 -- Xlib.h: #define AllPlanes ((unsigned long)~0L)
    local XYPixmap = 1 -- X.h: #define XYPixmap 1
    
    local c = ffi.new("XColor[1]")
    local d = X11.XOpenDisplay(ffi.NULL)
    
    local x = 1920 / 2
    local y = 1080 / 2
    
    local image = X11.XGetImage(d, X11.XRootWindow(d, X11.XDefaultScreen(d)), x, y, 1, 1, AllPlanes, XYPixmap)
    c[0].pixel = X11.XGetPixel(image, 0, 0)
    X11.XFree(image)
    X11.XQueryColor(d, X11.XDefaultColormap(d, X11.XDefaultScreen(d)), c)
    print(string.format("%d %d %d", c[0].red/256, c[0].green/256, c[0].blue/256))
    

相关问题