Как реализовать код X11 (вернуть цвет пикселя на экране) C для ffi luajit? - PullRequest
0 голосов
/ 09 декабря 2018

Я хочу записать небольшую часть моего экрана с помощью luajit.

Не найдено ни одного модуля для этого.И есть только какие-либо документация / учебные пособия / примеры о ffi luajit в сети, кроме http://luajit.org/ext_ffi.html, которая не предоставляет никаких примеров использования других библиотек C.

У меня есть фрагмент кода C, которыйработает родной.Как бы вы реализовали код C для ffi luajit?

Пример кода 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 голосов
/ 09 декабря 2018

В основном вам нужно только скопировать все объявления из заголовков в раздел 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]

. Вот ваш код на C в LuaJIT. Я не копировал определения для Display и XImage, потому что мы никогдаполучить доступ к своим членам и использовать только указатели на них, поэтому они остаются непрозрачными struct s.

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))
...