mirror of https://github.com/arendst/Tasmota.git
Merge pull request #12507 from s-hadinger/lvgl_prepare
LVGL Prepare last phase custom types
This commit is contained in:
commit
2a53cb0d06
|
@ -13,6 +13,7 @@
|
||||||
#include "be_exec.h"
|
#include "be_exec.h"
|
||||||
#include "be_vm.h"
|
#include "be_vm.h"
|
||||||
#include "be_mem.h"
|
#include "be_mem.h"
|
||||||
|
#include "be_constobj.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
@ -47,13 +48,6 @@ static void buf_set_len(buf_impl* buf, const size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void buf_set1(buf_impl* buf, const size_t offset, const uint8_t data)
|
|
||||||
{
|
|
||||||
if (offset < buf->len) {
|
|
||||||
buf->buf[offset] = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t buf_add1(buf_impl* buf, const uint8_t data) // append 8 bits value
|
static size_t buf_add1(buf_impl* buf, const uint8_t data) // append 8 bits value
|
||||||
{
|
{
|
||||||
if (buf->len < buf->size) { // do we have room for 1 byte
|
if (buf->len < buf->size) { // do we have room for 1 byte
|
||||||
|
@ -120,7 +114,31 @@ static uint8_t buf_get1(buf_impl* buf, int offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t buf_get2_le(buf_impl* buf, int offset) {
|
static void buf_set1(buf_impl* buf, const size_t offset, const uint8_t data)
|
||||||
|
{
|
||||||
|
if (offset < buf->len) {
|
||||||
|
buf->buf[offset] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buf_set2_le(buf_impl* buf, const size_t offset, const uint16_t data)
|
||||||
|
{
|
||||||
|
if ((offset >= 0) && (offset < buf->len - 1)) {
|
||||||
|
buf->buf[offset] = data & 0xFF;
|
||||||
|
buf->buf[offset+1] = data >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buf_set2_be(buf_impl* buf, const size_t offset, const uint16_t data)
|
||||||
|
{
|
||||||
|
if ((offset >= 0) && (offset < buf->len - 1)) {
|
||||||
|
buf->buf[offset+1] = data & 0xFF;
|
||||||
|
buf->buf[offset] = data >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t buf_get2_le(buf_impl* buf, int offset)
|
||||||
|
{
|
||||||
if ((offset >= 0) && (offset < buf->len - 1)) {
|
if ((offset >= 0) && (offset < buf->len - 1)) {
|
||||||
return buf->buf[offset] | (buf->buf[offset+1] << 8);
|
return buf->buf[offset] | (buf->buf[offset+1] << 8);
|
||||||
}
|
}
|
||||||
|
@ -135,6 +153,26 @@ static uint16_t buf_get2_be(buf_impl* buf, int offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void buf_set4_le(buf_impl* buf, const size_t offset, const uint32_t data)
|
||||||
|
{
|
||||||
|
if ((offset >= 0) && (offset < buf->len - 3)) {
|
||||||
|
buf->buf[offset] = data & 0xFF;
|
||||||
|
buf->buf[offset+1] = (data >> 8) & 0xFF;
|
||||||
|
buf->buf[offset+2] = (data >> 16) & 0xFF;
|
||||||
|
buf->buf[offset+3] = data >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buf_set4_be(buf_impl* buf, const size_t offset, const uint32_t data)
|
||||||
|
{
|
||||||
|
if ((offset >= 0) && (offset < buf->len - 3)) {
|
||||||
|
buf->buf[offset+3] = data & 0xFF;
|
||||||
|
buf->buf[offset+2] = (data >> 8) & 0xFF;
|
||||||
|
buf->buf[offset+1] = (data >> 16) & 0xFF;
|
||||||
|
buf->buf[offset] = data >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t buf_get4_le(buf_impl* buf, int offset)
|
static uint32_t buf_get4_le(buf_impl* buf, int offset)
|
||||||
{
|
{
|
||||||
if ((offset >= 0) && (offset < buf->len - 3)) {
|
if ((offset >= 0) && (offset < buf->len - 3)) {
|
||||||
|
@ -383,13 +421,13 @@ static int m_add(bvm *vm)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get an int made of 1, 2 or 4 bytes, in little or big endian
|
* Get an int made of 1, 2 or 4 bytes, in little or big endian
|
||||||
* `get(index:int[, size:int = 1]) -> instance`
|
* `get(index:int[, size:int = 1]) -> int`
|
||||||
*
|
*
|
||||||
* size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
|
* size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
|
||||||
* obvisouly -1 is idntical to 1
|
* obvisouly -1 is identical to 1
|
||||||
* 0 returns nil
|
* 0 returns nil
|
||||||
*/
|
*/
|
||||||
static int m_get(bvm *vm)
|
static int m_get(bvm *vm, bbool sign)
|
||||||
{
|
{
|
||||||
int argc = be_top(vm);
|
int argc = be_top(vm);
|
||||||
buf_impl * buf = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
|
buf_impl * buf = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
|
||||||
|
@ -403,10 +441,16 @@ static int m_get(bvm *vm)
|
||||||
switch (vsize) {
|
switch (vsize) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
case -1: /* fallback below */
|
case -1: /* fallback below */
|
||||||
case 1: ret = buf_get1(buf, idx); break;
|
case 1: ret = buf_get1(buf, idx);
|
||||||
case 2: ret = buf_get2_le(buf, idx); break;
|
if (sign) { ret = (int8_t)(uint8_t) ret; }
|
||||||
|
break;
|
||||||
|
case 2: ret = buf_get2_le(buf, idx);
|
||||||
|
if (sign) { ret = (int16_t)(uint16_t) ret; }
|
||||||
|
break;
|
||||||
case 4: ret = buf_get4_le(buf, idx); break;
|
case 4: ret = buf_get4_le(buf, idx); break;
|
||||||
case -2: ret = buf_get2_be(buf, idx); break;
|
case -2: ret = buf_get2_be(buf, idx);
|
||||||
|
if (sign) { ret = (int16_t)(uint16_t) ret; }
|
||||||
|
break;
|
||||||
case -4: ret = buf_get4_be(buf, idx); break;
|
case -4: ret = buf_get4_be(buf, idx); break;
|
||||||
default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4.");
|
default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4.");
|
||||||
}
|
}
|
||||||
|
@ -421,6 +465,53 @@ static int m_get(bvm *vm)
|
||||||
be_return_nil(vm);
|
be_return_nil(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* signed int */
|
||||||
|
static int m_geti(bvm *vm)
|
||||||
|
{
|
||||||
|
return m_get(vm, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unsigned int */
|
||||||
|
static int m_getu(bvm *vm)
|
||||||
|
{
|
||||||
|
return m_get(vm, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set an int made of 1, 2 or 4 bytes, in little or big endian
|
||||||
|
* `set(index:int, value:int[, size:int = 1]) -> nil`
|
||||||
|
*
|
||||||
|
* size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
|
||||||
|
* obvisouly -1 is identical to 1
|
||||||
|
* 0 returns nil
|
||||||
|
*/
|
||||||
|
static int m_set(bvm *vm)
|
||||||
|
{
|
||||||
|
int argc = be_top(vm);
|
||||||
|
buf_impl * buf = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
|
||||||
|
if (argc >=3 && be_isint(vm, 2) && be_isint(vm, 3)) {
|
||||||
|
int32_t idx = be_toint(vm, 2);
|
||||||
|
int32_t value = be_toint(vm, 3);
|
||||||
|
int vsize = 1;
|
||||||
|
if (argc >= 4 && be_isint(vm, 4)) {
|
||||||
|
vsize = be_toint(vm, 4);
|
||||||
|
}
|
||||||
|
switch (vsize) {
|
||||||
|
case 0: break;
|
||||||
|
case -1: /* fallback below */
|
||||||
|
case 1: buf_set1(buf, idx, value); break;
|
||||||
|
case 2: buf_set2_le(buf, idx, value); break;
|
||||||
|
case 4: buf_set4_le(buf, idx, value); break;
|
||||||
|
case -2: buf_set2_be(buf, idx, value); break;
|
||||||
|
case -4: buf_set4_be(buf, idx, value); break;
|
||||||
|
default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4.");
|
||||||
|
}
|
||||||
|
be_pop(vm, argc - 1);
|
||||||
|
be_return_nil(vm);
|
||||||
|
}
|
||||||
|
be_return_nil(vm);
|
||||||
|
}
|
||||||
|
|
||||||
static int m_setitem(bvm *vm)
|
static int m_setitem(bvm *vm)
|
||||||
{
|
{
|
||||||
int argc = be_top(vm);
|
int argc = be_top(vm);
|
||||||
|
@ -608,6 +699,26 @@ static int m_nequal(bvm *vm)
|
||||||
return bytes_equal(vm, bfalse);
|
return bytes_equal(vm, bfalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Advanced API
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve the memory address of the raw buffer
|
||||||
|
* to be used in C functions.
|
||||||
|
*
|
||||||
|
* Note: the address is guaranteed not to move unless you
|
||||||
|
* resize the buffer
|
||||||
|
*
|
||||||
|
* `_buffer() -> comptr`
|
||||||
|
*/
|
||||||
|
static int m_buffer(bvm *vm)
|
||||||
|
{
|
||||||
|
buf_impl * buf = bytes_check_data(vm, 0);
|
||||||
|
be_pushcomptr(vm, &buf->buf);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External API
|
* External API
|
||||||
*/
|
*/
|
||||||
|
@ -642,17 +753,219 @@ BERRY_API const void *be_tobytes(bvm *vm, int rel_index, size_t *len)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper code to compile bytecode
|
||||||
|
|
||||||
|
|
||||||
|
class Bytes : bytes
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- 'getbits' function
|
||||||
|
#-
|
||||||
|
#- Reads a bit-field in a `bytes()` object
|
||||||
|
#-
|
||||||
|
#- Input:
|
||||||
|
#- offset_bytes (int): byte offset in the bytes() object
|
||||||
|
#- offset_bits (int): bit number to start reading from (0 = LSB)
|
||||||
|
#- len_bits (int): how many bits to read
|
||||||
|
#- Output:
|
||||||
|
#- valuer (int)
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
def getbits(offset_bits, len_bits)
|
||||||
|
if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
|
||||||
|
var ret = 0
|
||||||
|
|
||||||
|
var offset_bytes = offset_bits >> 3
|
||||||
|
offset_bits = offset_bits % 8
|
||||||
|
|
||||||
|
var bit_shift = 0 #- bit number to write to -#
|
||||||
|
|
||||||
|
while (len_bits > 0)
|
||||||
|
var block_bits = 8 - offset_bits # how many bits to read in the current block (block = byte) -#
|
||||||
|
if block_bits > len_bits block_bits = len_bits end
|
||||||
|
|
||||||
|
var mask = ( (1<<block_bits) - 1) << offset_bits
|
||||||
|
ret = ret | ( ((self[offset_bytes] & mask) >> offset_bits) << bit_shift)
|
||||||
|
|
||||||
|
#- move the input window -#
|
||||||
|
bit_shift += block_bits
|
||||||
|
len_bits -= block_bits
|
||||||
|
offset_bits = 0 #- start at full next byte -#
|
||||||
|
offset_bytes += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- 'setbits' function
|
||||||
|
#-
|
||||||
|
#- Writes a bit-field in a `bytes()` object
|
||||||
|
#-
|
||||||
|
#- Input:
|
||||||
|
#- offset_bytes (int): byte offset in the bytes() object
|
||||||
|
#- offset_bits (int): bit number to start writing to (0 = LSB)
|
||||||
|
#- len_bits (int): how many bits to write
|
||||||
|
#- Output:
|
||||||
|
#- bytes() object modified (by reference)
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
def setbits(offset_bits, len_bits, val)
|
||||||
|
if len_bits < 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
|
||||||
|
|
||||||
|
var offset_bytes = offset_bits >> 3
|
||||||
|
offset_bits = offset_bits % 8
|
||||||
|
|
||||||
|
while (len_bits > 0)
|
||||||
|
var block_bits = 8 - offset_bits #- how many bits to write in the current block (block = byte) -#
|
||||||
|
if block_bits > len_bits block_bits = len_bits end
|
||||||
|
|
||||||
|
var mask_val = (1<<block_bits) - 1 #- mask to the n bits to get for this block -#
|
||||||
|
var mask_b_inv = 0xFF - (mask_val << offset_bits)
|
||||||
|
self[offset_bytes] = (self[offset_bytes] & mask_b_inv) | ((val & mask_val) << offset_bits)
|
||||||
|
|
||||||
|
#- move the input window -#
|
||||||
|
val >>= block_bits
|
||||||
|
len_bits -= block_bits
|
||||||
|
offset_bits = 0 #- start at full next byte -#
|
||||||
|
offset_bytes += 1
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: getbits
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(getbits, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
9, /* nstack */
|
||||||
|
3, /* argc */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 5]) { /* constants */
|
||||||
|
{ { .i=0 }, BE_INT},
|
||||||
|
{ { .s=be_nested_const_str("value_error", 773297791, 11) }, BE_STRING},
|
||||||
|
{ { .s=be_nested_const_str("length in bits must be between 0 and 32", -1710458168, 39) }, BE_STRING},
|
||||||
|
{ { .i=3 }, BE_INT},
|
||||||
|
{ { .i=1 }, BE_INT},
|
||||||
|
}),
|
||||||
|
(be_nested_const_str("getbits", -1200798317, 7)),
|
||||||
|
(be_nested_const_str("stdin", -1529146723, 5)),
|
||||||
|
( &(const binstruction[32]) { /* code */
|
||||||
|
0x180C0500, // 0000 LE R3 R2 R256
|
||||||
|
0x740E0002, // 0001 JMPT R3 #0005
|
||||||
|
0x540E001F, // 0002 LDINT R3 32
|
||||||
|
0x240C0403, // 0003 GT R3 R2 R3
|
||||||
|
0x780E0000, // 0004 JMPF R3 #0006
|
||||||
|
0xB0060302, // 0005 RAISE 1 R257 R258
|
||||||
|
0x580C0000, // 0006 LDCONST R3 K0
|
||||||
|
0x3C100303, // 0007 SHR R4 R1 R259
|
||||||
|
0x54160007, // 0008 LDINT R5 8
|
||||||
|
0x10040205, // 0009 MOD R1 R1 R5
|
||||||
|
0x58140000, // 000A LDCONST R5 K0
|
||||||
|
0x24180500, // 000B GT R6 R2 R256
|
||||||
|
0x781A0011, // 000C JMPF R6 #001F
|
||||||
|
0x541A0007, // 000D LDINT R6 8
|
||||||
|
0x04180C01, // 000E SUB R6 R6 R1
|
||||||
|
0x241C0C02, // 000F GT R7 R6 R2
|
||||||
|
0x781E0000, // 0010 JMPF R7 #0012
|
||||||
|
0x5C180400, // 0011 MOVE R6 R2
|
||||||
|
0x381E0806, // 0012 SHL R7 R260 R6
|
||||||
|
0x041C0F04, // 0013 SUB R7 R7 R260
|
||||||
|
0x381C0E01, // 0014 SHL R7 R7 R1
|
||||||
|
0x94200004, // 0015 GETIDX R8 R0 R4
|
||||||
|
0x2C201007, // 0016 AND R8 R8 R7
|
||||||
|
0x3C201001, // 0017 SHR R8 R8 R1
|
||||||
|
0x38201005, // 0018 SHL R8 R8 R5
|
||||||
|
0x300C0608, // 0019 OR R3 R3 R8
|
||||||
|
0x00140A06, // 001A ADD R5 R5 R6
|
||||||
|
0x04080406, // 001B SUB R2 R2 R6
|
||||||
|
0x58040000, // 001C LDCONST R1 K0
|
||||||
|
0x00100904, // 001D ADD R4 R4 R260
|
||||||
|
0x7001FFEB, // 001E JMP #000B
|
||||||
|
0x80040600, // 001F RET 1 R3
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: setbits
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(setbits, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
10, /* nstack */
|
||||||
|
4, /* argc */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 5]) { /* constants */
|
||||||
|
{ { .i=0 }, BE_INT},
|
||||||
|
{ { .s=be_nested_const_str("value_error", 773297791, 11) }, BE_STRING},
|
||||||
|
{ { .s=be_nested_const_str("length in bits must be between 0 and 32", -1710458168, 39) }, BE_STRING},
|
||||||
|
{ { .i=3 }, BE_INT},
|
||||||
|
{ { .i=1 }, BE_INT},
|
||||||
|
}),
|
||||||
|
(be_nested_const_str("setbits", -1532559129, 7)),
|
||||||
|
(be_nested_const_str("stdin", -1529146723, 5)),
|
||||||
|
( &(const binstruction[33]) { /* code */
|
||||||
|
0x14100500, // 0000 LT R4 R2 R256
|
||||||
|
0x74120002, // 0001 JMPT R4 #0005
|
||||||
|
0x5412001F, // 0002 LDINT R4 32
|
||||||
|
0x24100404, // 0003 GT R4 R2 R4
|
||||||
|
0x78120000, // 0004 JMPF R4 #0006
|
||||||
|
0xB0060302, // 0005 RAISE 1 R257 R258
|
||||||
|
0x3C100303, // 0006 SHR R4 R1 R259
|
||||||
|
0x54160007, // 0007 LDINT R5 8
|
||||||
|
0x10040205, // 0008 MOD R1 R1 R5
|
||||||
|
0x24140500, // 0009 GT R5 R2 R256
|
||||||
|
0x78160014, // 000A JMPF R5 #0020
|
||||||
|
0x54160007, // 000B LDINT R5 8
|
||||||
|
0x04140A01, // 000C SUB R5 R5 R1
|
||||||
|
0x24180A02, // 000D GT R6 R5 R2
|
||||||
|
0x781A0000, // 000E JMPF R6 #0010
|
||||||
|
0x5C140400, // 000F MOVE R5 R2
|
||||||
|
0x381A0805, // 0010 SHL R6 R260 R5
|
||||||
|
0x04180D04, // 0011 SUB R6 R6 R260
|
||||||
|
0x541E00FE, // 0012 LDINT R7 255
|
||||||
|
0x38200C01, // 0013 SHL R8 R6 R1
|
||||||
|
0x041C0E08, // 0014 SUB R7 R7 R8
|
||||||
|
0x94200004, // 0015 GETIDX R8 R0 R4
|
||||||
|
0x2C201007, // 0016 AND R8 R8 R7
|
||||||
|
0x2C240606, // 0017 AND R9 R3 R6
|
||||||
|
0x38241201, // 0018 SHL R9 R9 R1
|
||||||
|
0x30201009, // 0019 OR R8 R8 R9
|
||||||
|
0x98000808, // 001A SETIDX R0 R4 R8
|
||||||
|
0x3C0C0605, // 001B SHR R3 R3 R5
|
||||||
|
0x04080405, // 001C SUB R2 R2 R5
|
||||||
|
0x58040000, // 001D LDCONST R1 K0
|
||||||
|
0x00100904, // 001E ADD R4 R4 R260
|
||||||
|
0x7001FFE8, // 001F JMP #0009
|
||||||
|
0x80040000, // 0020 RET 1 R0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
#if !BE_USE_PRECOMPILED_OBJECT
|
#if !BE_USE_PRECOMPILED_OBJECT
|
||||||
void be_load_byteslib(bvm *vm)
|
void be_load_byteslib(bvm *vm)
|
||||||
{
|
{
|
||||||
static const bnfuncinfo members[] = {
|
static const bnfuncinfo members[] = {
|
||||||
{ ".p", NULL },
|
{ ".p", NULL },
|
||||||
|
{ "_buffer", m_buffer },
|
||||||
{ "init", m_init },
|
{ "init", m_init },
|
||||||
{ "tostring", m_tostring },
|
{ "tostring", m_tostring },
|
||||||
{ "asstring", m_asstring },
|
{ "asstring", m_asstring },
|
||||||
{ "fromstring", m_fromstring },
|
{ "fromstring", m_fromstring },
|
||||||
{ "add", m_add },
|
{ "add", m_add },
|
||||||
{ "get", m_get },
|
{ "get", m_getu },
|
||||||
|
{ "geti", m_geti },
|
||||||
|
{ "set", m_set },
|
||||||
{ "item", m_item },
|
{ "item", m_item },
|
||||||
{ "setitem", m_setitem },
|
{ "setitem", m_setitem },
|
||||||
{ "size", m_size },
|
{ "size", m_size },
|
||||||
|
@ -663,6 +976,11 @@ void be_load_byteslib(bvm *vm)
|
||||||
{ "..", m_connect },
|
{ "..", m_connect },
|
||||||
{ "==", m_equal },
|
{ "==", m_equal },
|
||||||
{ "!=", m_nequal },
|
{ "!=", m_nequal },
|
||||||
|
|
||||||
|
{ NULL, (bntvfunc) BE_CLOSURE }, /* mark section for berry closures */
|
||||||
|
{ "getbits", (bntvfunc) &getbits_closure },
|
||||||
|
{ "setbits", (bntvfunc) &setbits_closure },
|
||||||
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
be_regclass(vm, "bytes", members);
|
be_regclass(vm, "bytes", members);
|
||||||
|
@ -671,12 +989,15 @@ void be_load_byteslib(bvm *vm)
|
||||||
/* @const_object_info_begin
|
/* @const_object_info_begin
|
||||||
class be_class_bytes (scope: global, name: bytes) {
|
class be_class_bytes (scope: global, name: bytes) {
|
||||||
.p, var
|
.p, var
|
||||||
|
_buffer, func(m_buffer)
|
||||||
init, func(m_init)
|
init, func(m_init)
|
||||||
tostring, func(m_tostring)
|
tostring, func(m_tostring)
|
||||||
asstring, func(m_asstring)
|
asstring, func(m_asstring)
|
||||||
fromstring, func(m_fromstring)
|
fromstring, func(m_fromstring)
|
||||||
add, func(m_add)
|
add, func(m_add)
|
||||||
get, func(m_get)
|
get, func(m_getu)
|
||||||
|
geti, func(m_geti)
|
||||||
|
set, func(m_set)
|
||||||
item, func(m_item)
|
item, func(m_item)
|
||||||
setitem, func(m_setitem)
|
setitem, func(m_setitem)
|
||||||
size, func(m_size)
|
size, func(m_size)
|
||||||
|
@ -687,6 +1008,9 @@ class be_class_bytes (scope: global, name: bytes) {
|
||||||
.., func(m_connect)
|
.., func(m_connect)
|
||||||
==, func(m_equal)
|
==, func(m_equal)
|
||||||
!=, func(m_nequal)
|
!=, func(m_nequal)
|
||||||
|
|
||||||
|
getbits, closure(getbits_closure)
|
||||||
|
setbits, closure(setbits_closure)
|
||||||
}
|
}
|
||||||
@const_object_info_end */
|
@const_object_info_end */
|
||||||
#include "../generate/be_fixed_be_class_bytes.h"
|
#include "../generate/be_fixed_be_class_bytes.h"
|
||||||
|
|
|
@ -122,7 +122,7 @@ static void m_solidify_proto(bvm *vm, bproto *pr, const char * func_name, int bu
|
||||||
logfmt("%*s( &(const binstruction[%2d]) { /* code */\n", indent, "", pr->codesize);
|
logfmt("%*s( &(const binstruction[%2d]) { /* code */\n", indent, "", pr->codesize);
|
||||||
for (int pc = 0; pc < pr->codesize; pc++) {
|
for (int pc = 0; pc < pr->codesize; pc++) {
|
||||||
uint32_t ins = pr->code[pc];
|
uint32_t ins = pr->code[pc];
|
||||||
logfmt("%*s 0x%04X, //", indent, "", ins);
|
logfmt("%*s 0x%08X, //", indent, "", ins);
|
||||||
be_print_inst(ins, pc);
|
be_print_inst(ins, pc);
|
||||||
bopcode op = IGET_OP(ins);
|
bopcode op = IGET_OP(ins);
|
||||||
if (op == OP_GETGBL || op == OP_SETGBL) {
|
if (op == OP_GETGBL || op == OP_SETGBL) {
|
||||||
|
|
|
@ -165,3 +165,33 @@ assert(str(b) =="bytes('416130')")
|
||||||
b=bytes()
|
b=bytes()
|
||||||
b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
|
b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
|
||||||
assert(str(b) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')")
|
assert(str(b) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')")
|
||||||
|
|
||||||
|
#- setters -#
|
||||||
|
b=bytes().resize(16)
|
||||||
|
b.set(5,-1,2)
|
||||||
|
assert(b == bytes('0000000000FFFF000000000000000000'))
|
||||||
|
b.set(10,-2,4)
|
||||||
|
assert(b == bytes('0000000000FFFF000000FEFFFFFF0000'))
|
||||||
|
b.set(0,0xAA55,1)
|
||||||
|
assert(b == bytes('5500000000FFFF000000FEFFFFFF0000'))
|
||||||
|
|
||||||
|
#- getbits -#
|
||||||
|
b=bytes("00AAFF55010300")
|
||||||
|
assert(b.getbits(8,8) == 0xAA)
|
||||||
|
assert(b.getbits(0,1) == 0)
|
||||||
|
assert(b.getbits(8,1) == 0)
|
||||||
|
assert(b.getbits(9,1) == 1)
|
||||||
|
assert(b.getbits(16,8) == 0xFF)
|
||||||
|
assert(b.getbits(16,16) == 0x55FF)
|
||||||
|
assert(b.getbits(16,24) == 0x0155FF)
|
||||||
|
assert(b.getbits(16,32) == 0x030155FF)
|
||||||
|
assert(b.getbits(20,8) == 0x5F)
|
||||||
|
|
||||||
|
#- setbits -#
|
||||||
|
b=bytes("00000000FFFFFFFF")
|
||||||
|
assert(b.setbits(0,1,1) == bytes('01000000FFFFFFFF'))
|
||||||
|
assert(b.setbits(1,1,1) == bytes('03000000FFFFFFFF'))
|
||||||
|
assert(b.setbits(0,1,0) == bytes('02000000FFFFFFFF'))
|
||||||
|
assert(b.setbits(12,16,0xAA55) == bytes('0250A50AFFFFFFFF'))
|
||||||
|
assert(b.setbits(63,0,0) == bytes('0250A50AFFFFFFFF'))
|
||||||
|
assert(b.setbits(63,1,0) == bytes('0250A50AFFFFFF7F'))
|
||||||
|
|
|
@ -0,0 +1,563 @@
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- Ctypes for Berry
|
||||||
|
#-
|
||||||
|
#- Inspired from Python's ctypes structure
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
import string
|
||||||
|
|
||||||
|
ctypes = module('ctypes')
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- Basic types for mapping
|
||||||
|
#-
|
||||||
|
#- ints of size 1/2/4 bytes (little endian by default)
|
||||||
|
#- usigned ints of size 1/2/4 bytes (little endian by default)
|
||||||
|
#-
|
||||||
|
#- (Big Endian are negative numbers)
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
|
||||||
|
# default is little_endian
|
||||||
|
ctypes.i32 = 14
|
||||||
|
ctypes.i16 = 12
|
||||||
|
ctypes.i8 = 11
|
||||||
|
ctypes.u32 = 4
|
||||||
|
ctypes.u16 = 2
|
||||||
|
ctypes.u8 = 1
|
||||||
|
|
||||||
|
# explicit little endian
|
||||||
|
ctypes.le_i32 = 14
|
||||||
|
ctypes.le_i16 = 12
|
||||||
|
ctypes.le_i8 = 11
|
||||||
|
ctypes.le_u32 = 4
|
||||||
|
ctypes.le_u16 = 2
|
||||||
|
ctypes.le_u8 = 1
|
||||||
|
|
||||||
|
# big endian
|
||||||
|
ctypes.be_i32 = -14
|
||||||
|
ctypes.be_i16 = -12
|
||||||
|
ctypes.be_i8 = -11
|
||||||
|
ctypes.be_u32 = -4
|
||||||
|
ctypes.be_u16 = -2
|
||||||
|
ctypes.be_u8 = -1
|
||||||
|
|
||||||
|
# bitfields (always unsigned)
|
||||||
|
ctypes.bf_0 = 100 # serves as base
|
||||||
|
ctypes.bf_1 = 101
|
||||||
|
ctypes.bf_2 = 102
|
||||||
|
ctypes.bf_3 = 103
|
||||||
|
ctypes.bf_4 = 104
|
||||||
|
ctypes.bf_5 = 105
|
||||||
|
ctypes.bf_6 = 106
|
||||||
|
ctypes.bf_7 = 107
|
||||||
|
ctypes.bf_8 = 108
|
||||||
|
ctypes.bf_9 = 109
|
||||||
|
ctypes.bf_10 = 110
|
||||||
|
ctypes.bf_11 = 111
|
||||||
|
ctypes.bf_12 = 112
|
||||||
|
ctypes.bf_13 = 113
|
||||||
|
ctypes.bf_14 = 114
|
||||||
|
ctypes.bf_15 = 115
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- 'get_bits' function
|
||||||
|
#-
|
||||||
|
#- Reads a bit-field in a `bytes()` object
|
||||||
|
#-
|
||||||
|
#- Input:
|
||||||
|
#- b: bytes() object to read from
|
||||||
|
#- offset_bytes (int): byte offset in the bytes() object
|
||||||
|
#- offset_bits (int): bit number to start reading from (0 = LSB)
|
||||||
|
#- len_bits (int): how many bits to read
|
||||||
|
#- Output:
|
||||||
|
#- valuer (int)
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
ctypes.get_bits = def (b, offset_bytes, offset_bits, len_bits)
|
||||||
|
if !isinstance(b, bytes) raise "value_error", "first argument must be of type 'bytes'" end
|
||||||
|
if offset_bits < 0 || offset_bits > 7 raise "value_error", "offset_bits must be between 0 and 7" end
|
||||||
|
if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
|
||||||
|
var ret = 0
|
||||||
|
|
||||||
|
var bit_shift = 0 # bit number to write to
|
||||||
|
|
||||||
|
while (len_bits > 0)
|
||||||
|
var block_bits = 8 - offset_bits # how many bits to read in the current block (block = byte)
|
||||||
|
if block_bits > len_bits block_bits = len_bits end
|
||||||
|
|
||||||
|
var mask = ( (1<<block_bits) - 1) << offset_bits
|
||||||
|
# print(string.format("mask = %02X", mask))
|
||||||
|
ret = ret | ( ((b[offset_bytes] & mask) >> offset_bits) << bit_shift)
|
||||||
|
|
||||||
|
# move the input window
|
||||||
|
bit_shift += block_bits
|
||||||
|
len_bits -= block_bits
|
||||||
|
offset_bits = 0 # start at full next byte
|
||||||
|
offset_bytes += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
ctypes.sort = def (l)
|
||||||
|
# insertion sort
|
||||||
|
for i:1..size(l)-1
|
||||||
|
var k = l[i]
|
||||||
|
var j = i
|
||||||
|
while (j > 0) && (l[j-1] > k)
|
||||||
|
l[j] = l[j-1]
|
||||||
|
j -= 1
|
||||||
|
end
|
||||||
|
l[j] = k
|
||||||
|
end
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- 'set_bits' function
|
||||||
|
#-
|
||||||
|
#- Writes a bit-field in a `bytes()` object
|
||||||
|
#-
|
||||||
|
#- Input:
|
||||||
|
#- b: bytes() object to write to
|
||||||
|
#- offset_bytes (int): byte offset in the bytes() object
|
||||||
|
#- offset_bits (int): bit number to start writing to (0 = LSB)
|
||||||
|
#- len_bits (int): how many bits to write
|
||||||
|
#- Output:
|
||||||
|
#- bytes() object modified (by reference)
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
ctypes.set_bits = def (b, offset_bytes, offset_bits, len_bits, val)
|
||||||
|
if !isinstance(b, bytes) raise "value_error", "first argument must be of type 'bytes'" end
|
||||||
|
if offset_bits < 0 || offset_bits > 7 raise "value_error", "offset_bits must be between 0 and 7" end
|
||||||
|
if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
|
||||||
|
|
||||||
|
while (len_bits > 0)
|
||||||
|
var block_bits = 8 - offset_bits # how many bits to write in the current block (block = byte)
|
||||||
|
if block_bits > len_bits block_bits = len_bits end
|
||||||
|
|
||||||
|
var mask_val = (1<<block_bits) - 1 # mask to the n bits to get for this block
|
||||||
|
var mask_b_inv = 0xFF - (mask_val << offset_bits)
|
||||||
|
b[offset_bytes] = (b[offset_bytes] & mask_b_inv) | ((val & mask_val) << offset_bits)
|
||||||
|
|
||||||
|
# move the input window
|
||||||
|
val >>= block_bits
|
||||||
|
len_bits -= block_bits
|
||||||
|
offset_bits = 0 # start at full next byte
|
||||||
|
offset_bytes += 1
|
||||||
|
end
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
#- print the C types -#1
|
||||||
|
ctypes.print_types = def ()
|
||||||
|
print("enum {")
|
||||||
|
print(" ctypes_ptr = 0,")
|
||||||
|
print(" ctypes_uint = 1,")
|
||||||
|
print(" ctypes_int = 2,")
|
||||||
|
print(" ctypes_str = 3,")
|
||||||
|
print("};")
|
||||||
|
print()
|
||||||
|
print("typedef struct be_ctypes_structure_t {")
|
||||||
|
print(" const char * name;")
|
||||||
|
print(" uint16_t offset_bits;")
|
||||||
|
print(" uint16_t len_bits : 13;")
|
||||||
|
print(" uint16_t type : 3;")
|
||||||
|
print("} be_ctypes_structure_t;")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- 'ctypes.structure' class
|
||||||
|
#-
|
||||||
|
#- Parses a ctypes structure descriptor and creates
|
||||||
|
#- a set of getters and setters
|
||||||
|
#-
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
class structure
|
||||||
|
var cur_offset # offset in bytes from buffer start
|
||||||
|
var bit_offset # are we intra-byte?
|
||||||
|
var get_closures #
|
||||||
|
var set_closures #
|
||||||
|
var size_bytes # size in bytes
|
||||||
|
var mapping # map to generate C binding
|
||||||
|
|
||||||
|
# init world
|
||||||
|
def init(mapping, name)
|
||||||
|
self.cur_offset = 0
|
||||||
|
self.bit_offset = 0
|
||||||
|
self.size_bytes = 0 # overall size in bytes
|
||||||
|
self.get_closures = {}
|
||||||
|
self.set_closures = {}
|
||||||
|
self.mapping = {}
|
||||||
|
|
||||||
|
# parse mapping
|
||||||
|
self.parse_mapping(mapping, name)
|
||||||
|
end
|
||||||
|
#- iteratively parse mapping
|
||||||
|
#-
|
||||||
|
#- if name is not nil, it also outputs a C structure for the mapping
|
||||||
|
#-
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
def parse_mapping(mapping, name)
|
||||||
|
for map_line: mapping
|
||||||
|
self.parse_line(map_line)
|
||||||
|
end
|
||||||
|
|
||||||
|
if name != nil
|
||||||
|
print(string.format("const be_ctypes_structure_t be_%s[%d] = {", name, size(self.mapping)))
|
||||||
|
# list keys for future binary search
|
||||||
|
var names = []
|
||||||
|
for n:self.mapping.keys() names.push(n) end # convert to list
|
||||||
|
ctypes.sort(names)
|
||||||
|
for n:names
|
||||||
|
var args = self.mapping[n]
|
||||||
|
print(string.format(" { \"%s\", %i, %i, %s },", n, args[0], args[1], args[2]))
|
||||||
|
end
|
||||||
|
print("};")
|
||||||
|
print()
|
||||||
|
end
|
||||||
|
|
||||||
|
# clear any outstanding bitfield
|
||||||
|
self.align(1)
|
||||||
|
self.size_bytes = self.cur_offset
|
||||||
|
end
|
||||||
|
|
||||||
|
def size()
|
||||||
|
return self.size_bytes
|
||||||
|
end
|
||||||
|
|
||||||
|
# parse a single line
|
||||||
|
def parse_line(map_line)
|
||||||
|
var type_obj = map_line[0]
|
||||||
|
var name = map_line[1]
|
||||||
|
var bits = 0
|
||||||
|
if size(map_line) >= 3 bits = map_line[2] end
|
||||||
|
|
||||||
|
if isinstance(type_obj, ctypes.structure)
|
||||||
|
# nested structure
|
||||||
|
self.nested(name, type_obj)
|
||||||
|
elif type(type_obj) == 'int'
|
||||||
|
# TODO check actual type
|
||||||
|
if type_obj > ctypes.bf_0
|
||||||
|
# bit field
|
||||||
|
self.get_bitfield_closure(name, type_obj - ctypes.bf_0)
|
||||||
|
else
|
||||||
|
# multi-bytes
|
||||||
|
self.get_int_closure(name, type_obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#- ensure alignment to 1/2/4 bytes -#
|
||||||
|
def align(n)
|
||||||
|
if n != 1 && n != 2 && n != 4 raise "value_error", "acceptable values are 1/2/4" end
|
||||||
|
|
||||||
|
#- align to byte boundary if we're in a bitfield -#
|
||||||
|
if self.bit_offset != 0
|
||||||
|
#- we are not byte aligned, let's re-aling -#
|
||||||
|
self.cur_offset += 1
|
||||||
|
self.bit_offset = 0
|
||||||
|
|
||||||
|
#- check 2/4 bytes alignment -#
|
||||||
|
if self.cur_offset % n != 0
|
||||||
|
# we are not aligned with current size
|
||||||
|
self.cur_offset += n - self.cur_offset % n
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def nested(name, type_obj)
|
||||||
|
var sub_size = type_obj.size()
|
||||||
|
if sub_size <= 0 raise "value_error", "empty sub-structure not supported" end
|
||||||
|
|
||||||
|
# align to appropriate sub-size
|
||||||
|
var align_size = sub_size
|
||||||
|
if align_size == 3 || align_size > 4 align_size = 4 end
|
||||||
|
self.align(align_size)
|
||||||
|
|
||||||
|
var offset = self.cur_offset # var for closure
|
||||||
|
|
||||||
|
# inlcude nested
|
||||||
|
for subname:type_obj.mapping.keys()
|
||||||
|
var val = type_obj.mapping[subname]
|
||||||
|
self.mapping[name+"_"+subname] = [val[0] + (offset << 3), val[1], val[2]]
|
||||||
|
end
|
||||||
|
# self.mapping[name] = [offset << 3, sub_size << 3]
|
||||||
|
|
||||||
|
self.get_closures[name] = def (b, p) return ctypes.nested_buffer(type_obj, offset + p, b) end
|
||||||
|
# self.set_closures[name] = def (b, p, v) return ctypes.nested_buffer(type_obj, offset + p, b) end
|
||||||
|
|
||||||
|
self.cur_offset += sub_size
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_int_closure(name, size_in_bytes_le_be) # can be 1/2/4
|
||||||
|
#- abs size -#
|
||||||
|
var size_in_bytes = size_in_bytes_le_be < 0 ? - size_in_bytes_le_be : size_in_bytes_le_be
|
||||||
|
var signed = size_in_bytes > 10
|
||||||
|
size_in_bytes_le_be = size_in_bytes_le_be % 10 # remove sign marker
|
||||||
|
size_in_bytes = size_in_bytes % 10 # remove sign marker
|
||||||
|
|
||||||
|
self.align(size_in_bytes) # force alignment
|
||||||
|
var offset = self.cur_offset # prepare variable for capture in closure
|
||||||
|
|
||||||
|
self.mapping[name] = [offset << 3, size_in_bytes_le_be << 3, signed ? "ctypes_int" : "ctypes_uint"]
|
||||||
|
|
||||||
|
#- add closures -#
|
||||||
|
if signed
|
||||||
|
self.get_closures[name] = def (b, p) return b.geti(offset + p, size_in_bytes_le_be) end
|
||||||
|
else
|
||||||
|
self.get_closures[name] = def (b, p) return b.get(offset + p, size_in_bytes_le_be) end
|
||||||
|
end
|
||||||
|
self.set_closures[name] = def (b, p, v) return b.set(offset+ p, v, size_in_bytes_le_be) end
|
||||||
|
|
||||||
|
self.cur_offset += size_in_bytes # next offset
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def get_bitfield_closure(name, size_in_bits) # can be 1..32
|
||||||
|
var cur_offset = self.cur_offset # prepare variable for capture in closure
|
||||||
|
var bit_offset = self.bit_offset
|
||||||
|
self.mapping[name] = [bit_offset + (cur_offset << 3), size_in_bits, "ctypes_uint"]
|
||||||
|
self.get_closures[name] = def (b, p) return ctypes.get_bits(b, cur_offset + p, bit_offset, size_in_bits) end
|
||||||
|
self.set_closures[name] = def (b, p, v) return ctypes.set_bits(b, cur_offset+ p, bit_offset, size_in_bits, v) end
|
||||||
|
|
||||||
|
self.cur_offset += size_in_bits / 8
|
||||||
|
self.cur_offset += (self.bit_offset + size_in_bits) / 8
|
||||||
|
self.bit_offset = (self.bit_offset + size_in_bits) % 8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ctypes.structure = structure
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- Structured buffer
|
||||||
|
#-
|
||||||
|
#- Inspired from Python's ctypes structure
|
||||||
|
#-
|
||||||
|
#- This class is a wrapper around `bytes()` object (actually a subclass)
|
||||||
|
#- providing virtual members mapped to the ctypes structure.
|
||||||
|
#-
|
||||||
|
#- Takes as argument a ctypes.structure and an optional bytes() object
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
class buffer : bytes
|
||||||
|
var _cs # ctypes_structure associated
|
||||||
|
|
||||||
|
def init(cs, b)
|
||||||
|
if !isinstance(cs, ctypes.structure) raise "value_error", "first argument must be an instance of 'ctypes.structure'" end
|
||||||
|
self._cs = cs
|
||||||
|
var size = self._cs.size() # size in bytes of the structure
|
||||||
|
|
||||||
|
super(self, bytes).init(size) # init bytes object with reserved size in memory
|
||||||
|
|
||||||
|
if isinstance(b, bytes)
|
||||||
|
self..b
|
||||||
|
end
|
||||||
|
self.resize(size) # size once for all to the target size and complete with 00s
|
||||||
|
end
|
||||||
|
|
||||||
|
# accessor for virtual member
|
||||||
|
def member(name)
|
||||||
|
return self._cs.get_closures[name](self, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
# setter for virtual member
|
||||||
|
def setmember(name, value)
|
||||||
|
self._cs.set_closures[name](self, 0, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ctypes.buffer = buffer
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
#- Nested buffer
|
||||||
|
#-
|
||||||
|
#- Nested structures are just pointers to the master bytes() object
|
||||||
|
#-------------------------------------------------------------#
|
||||||
|
class nested_buffer
|
||||||
|
var _cs # ctypes.structure instance for this buffer
|
||||||
|
var _offset # offset un bytes() to the structure
|
||||||
|
var _bytes # reference to the overall buffer (by reference)
|
||||||
|
|
||||||
|
def init(cs, offset, b)
|
||||||
|
if !isinstance(cs, ctypes.structure) raise "value_error", "first argument must be an instance of 'ctypes.structure'" end
|
||||||
|
if type(offset) != 'int' raise "value_error", "second argument must be of type 'int'" end
|
||||||
|
if !isinstance(b, bytes) raise "value_error", "third argument must be an instance of 'bytes'" end
|
||||||
|
self._cs = cs
|
||||||
|
self._offset = offset
|
||||||
|
self._bytes = b
|
||||||
|
end
|
||||||
|
|
||||||
|
# accessor for virtual member
|
||||||
|
def member(name)
|
||||||
|
return self._cs.get_closures[name](self._bytes, self._offset)
|
||||||
|
end
|
||||||
|
|
||||||
|
# setter for virtual member
|
||||||
|
def setmember(name, value)
|
||||||
|
self._cs.set_closures[name](self._bytes, self._offset, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def tostring()
|
||||||
|
return self._bytes[self._offset..self._offset+self._cs.size()-1].tostring()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ctypes.nested_buffer = nested_buffer
|
||||||
|
|
||||||
|
|
||||||
|
return ctypes
|
||||||
|
|
||||||
|
# ex = [
|
||||||
|
# [ctypes.u32, "a"],
|
||||||
|
# [ctypes.u16, "b"],
|
||||||
|
# [ctypes.i8, "c"],
|
||||||
|
# [ctypes.i32, "d"], # should infer an empty byte
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# cs = ctypes.structure(ex)
|
||||||
|
# bb = ctypes.buffer(cs, bytes("aabb"))
|
||||||
|
|
||||||
|
# fa = cp.get_int_closure('a', 4)
|
||||||
|
# fb = cp.get_int_closure('b', 2)
|
||||||
|
# fc = cp.get_int_closure('c', 1)
|
||||||
|
# fd = cp.get_int_closure('d', 4)
|
||||||
|
|
||||||
|
# b = bytes("04030201AA55FFFF00010001")
|
||||||
|
|
||||||
|
# cp.get_closures['a'](b)
|
||||||
|
# cp.get_closures['b'](b)
|
||||||
|
# cp.get_closures['c'](b)
|
||||||
|
# cp.get_closures['d'](b)
|
||||||
|
|
||||||
|
# bb = ctypes_buffer(cp, b)
|
||||||
|
|
||||||
|
# bb.a = 0x11223344
|
||||||
|
# bb
|
||||||
|
# bb.a
|
||||||
|
|
||||||
|
|
||||||
|
# > bb = ctypes_buffer(cp, b)
|
||||||
|
# > bb.a
|
||||||
|
# 16909060
|
||||||
|
# > bb.b
|
||||||
|
# 21930
|
||||||
|
# > bb.c
|
||||||
|
# 255
|
||||||
|
# > bb.d
|
||||||
|
# 16777472
|
||||||
|
# > bb.e
|
||||||
|
# key_error: e
|
||||||
|
# stack traceback:
|
||||||
|
# <native>: in native function
|
||||||
|
# stdin:11: in function `member`
|
||||||
|
# stdin:1: in function `main`
|
||||||
|
|
||||||
|
|
||||||
|
# > bb['a']
|
||||||
|
# 16909060
|
||||||
|
# > bb['b']
|
||||||
|
# 21930
|
||||||
|
# > bb['c']
|
||||||
|
# 255
|
||||||
|
# > bb['d']
|
||||||
|
# 16777472
|
||||||
|
|
||||||
|
#-
|
||||||
|
> fa(b)
|
||||||
|
16909060
|
||||||
|
> fb(b)
|
||||||
|
21930
|
||||||
|
> fc(b)
|
||||||
|
255
|
||||||
|
> fd(b)
|
||||||
|
16777472
|
||||||
|
|
||||||
|
-#
|
||||||
|
|
||||||
|
# def get_bits(b, offset_bytes, offset_bits, len_bits)
|
||||||
|
# if !isinstance(b, bytes) raise "value_error", "first argument must be of type 'bytes'" end
|
||||||
|
# if offset_bits < 0 || offset_bits > 7 raise "value_error", "offset_bits must be between 0 and 7" end
|
||||||
|
# if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
|
||||||
|
# var ret = 0
|
||||||
|
|
||||||
|
# var bit_shift = 0 # bit number to wrtie to
|
||||||
|
|
||||||
|
# while (len_bits > 0)
|
||||||
|
# var block_bits = 8 - offset_bits # bit number to read in current block (block = byte)
|
||||||
|
# if block_bits > len_bits block_bits = len_bits end
|
||||||
|
|
||||||
|
# var mask = ( (1<<block_bits) - 1) << offset_bits
|
||||||
|
# # print(string.format("mask = %02X", mask))
|
||||||
|
# ret = ret | ( ((b[offset_bytes] & mask) >> offset_bits) << bit_shift)
|
||||||
|
|
||||||
|
# # move the input window
|
||||||
|
# bit_shift += block_bits
|
||||||
|
# len_bits -= block_bits
|
||||||
|
# offset_bits = 0 # start at full next byte
|
||||||
|
# offset_bytes += 1
|
||||||
|
# end
|
||||||
|
|
||||||
|
# return ret
|
||||||
|
# end
|
||||||
|
|
||||||
|
# Test
|
||||||
|
|
||||||
|
# b=bytes("AAFF10")
|
||||||
|
# assert(get_bits(b, 0, 0, 1) == 0)
|
||||||
|
# assert(get_bits(b, 0, 1, 1) == 1)
|
||||||
|
# assert(get_bits(b, 0, 2, 1) == 0)
|
||||||
|
# assert(get_bits(b, 0, 3, 1) == 1)
|
||||||
|
|
||||||
|
# assert(get_bits(b, 0, 0, 2) == 2)
|
||||||
|
# assert(get_bits(b, 0, 1, 2) == 1)
|
||||||
|
# assert(get_bits(b, 0, 2, 2) == 2)
|
||||||
|
|
||||||
|
# assert(get_bits(b, 0, 0, 8) == 0xAA)
|
||||||
|
# assert(get_bits(b, 0, 0, 10) == 0x3AA)
|
||||||
|
# assert(get_bits(b, 0, 2, 8) == 0xEA)
|
||||||
|
|
||||||
|
# assert(get_bits(b, 1, 0, 8) == 0xFF)
|
||||||
|
# assert(get_bits(b, 1, 0, 10) == 0x0FF)
|
||||||
|
|
||||||
|
# assert(get_bits(b, 1, 0, 16) == 0x10FF)
|
||||||
|
|
||||||
|
|
||||||
|
# assert(get_bits(b, 1, 7, 4) == 0x01)
|
||||||
|
# assert(get_bits(b, 1, 7, 6) == 0x21)
|
||||||
|
|
||||||
|
# def set_bits(b, offset_bytes, offset_bits, len_bits, val)
|
||||||
|
# if !isinstance(b, bytes) raise "value_error", "first argument must be of type 'bytes'" end
|
||||||
|
# if offset_bits < 0 || offset_bits > 7 raise "value_error", "offset_bits must be between 0 and 7" end
|
||||||
|
# if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
|
||||||
|
|
||||||
|
# while (len_bits > 0)
|
||||||
|
# var block_bits = 8 - offset_bits # how many bits to write in the current block (block = byte)
|
||||||
|
# if block_bits > len_bits block_bits = len_bits end
|
||||||
|
|
||||||
|
# var mask_val = (1<<block_bits) - 1 # mask to the n bits to get for this block
|
||||||
|
# var mask_b_inv = 0xFF - (mask_val << offset_bits)
|
||||||
|
# b[offset_bytes] = (b[offset_bytes] & mask_b_inv) | ((val & mask_val) << offset_bits)
|
||||||
|
|
||||||
|
# # move the input window
|
||||||
|
# val >>= block_bits
|
||||||
|
# len_bits -= block_bits
|
||||||
|
# offset_bits = 0 # start at full next byte
|
||||||
|
# offset_bytes += 1
|
||||||
|
# end
|
||||||
|
# return b
|
||||||
|
# end
|
||||||
|
|
||||||
|
# b=bytes("00000000")
|
||||||
|
|
||||||
|
# assert(set_bits(b,0,0,1,1) == bytes('01000000'))
|
||||||
|
# assert(set_bits(b,1,0,1,1) == bytes('01010000'))
|
||||||
|
# assert(set_bits(b,0,0,1,2) == bytes('00010000'))
|
||||||
|
# assert(set_bits(b,0,4,1,1) == bytes('10010000'))
|
||||||
|
# assert(set_bits(b,0,4,1,0) == bytes('00010000'))
|
||||||
|
|
||||||
|
# b=bytes("FF000000")
|
||||||
|
# assert(set_bits(b,0,4,1,0) == bytes('EF000000'))
|
||||||
|
# assert(set_bits(b,0,4,1,1) == bytes('FF000000'))
|
||||||
|
|
||||||
|
# b=bytes("00000000")
|
||||||
|
# assert(set_bits(b,2,6,1,-1) == bytes('00004000'))
|
||||||
|
# b=bytes("00000000")
|
||||||
|
# assert(set_bits(b,2,1,6,-1) == bytes('00007E00'))
|
|
@ -0,0 +1,315 @@
|
||||||
|
#
|
||||||
|
# ctype buidings for LVGL
|
||||||
|
#
|
||||||
|
# To generate C bindings, do:
|
||||||
|
# > compile("lvgl_ctypes.be","file")()
|
||||||
|
#
|
||||||
|
# and copy/paste output in C format
|
||||||
|
#
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
ctypes.print_types()
|
||||||
|
|
||||||
|
lv_style_int_t = ctypes.i16
|
||||||
|
lv_color_t = ctypes.u16 # depends on colors
|
||||||
|
lv_grad_dir_t = ctypes.u8
|
||||||
|
lv_opa_t = ctypes.u8
|
||||||
|
lv_blend_mode_t = ctypes.u8
|
||||||
|
lv_align_t = ctypes.u8
|
||||||
|
lv_coord_t = ctypes.i16
|
||||||
|
lv_bidi_dir_t = ctypes.u8
|
||||||
|
lv_txt_flag_t = ctypes.u8
|
||||||
|
lv_text_decor_t = ctypes.u8
|
||||||
|
lv_font_t = ctypes.u32
|
||||||
|
uint8_t_1 = ctypes.bf_1
|
||||||
|
uint8_t_2 = ctypes.bf_2
|
||||||
|
uint8_t = ctypes.u8
|
||||||
|
uint16_t = ctypes.u16
|
||||||
|
uint32_t = ctypes.u32
|
||||||
|
int32_t = ctypes.i32
|
||||||
|
ptr = ctypes.u32
|
||||||
|
|
||||||
|
lv_point_t = [
|
||||||
|
[lv_coord_t, "x"],
|
||||||
|
[lv_coord_t, "y"],
|
||||||
|
]
|
||||||
|
lv_point_t = ctypes.structure(lv_point_t, "lv_point_t")
|
||||||
|
|
||||||
|
lv_area_t = [
|
||||||
|
[lv_coord_t, "x1"],
|
||||||
|
[lv_coord_t, "y1"],
|
||||||
|
[lv_coord_t, "x2"],
|
||||||
|
[lv_coord_t, "y2"],
|
||||||
|
]
|
||||||
|
lv_area_t = ctypes.structure(lv_area_t, "lv_area_t")
|
||||||
|
|
||||||
|
test_t = [
|
||||||
|
[lv_area_t, "a"],
|
||||||
|
[lv_area_t, "b"]
|
||||||
|
]
|
||||||
|
test_t = ctypes.structure(test_t, "test_t")
|
||||||
|
|
||||||
|
lv_draw_rect_dsc_t = [
|
||||||
|
[lv_style_int_t, "radius"],
|
||||||
|
|
||||||
|
#/*Background*/
|
||||||
|
[lv_color_t, "bg_color"],
|
||||||
|
[lv_color_t, "bg_grad_color"],
|
||||||
|
[lv_grad_dir_t, "bg_grad_dir"],
|
||||||
|
[lv_style_int_t, "bg_main_color_stop"],
|
||||||
|
[lv_style_int_t, "bg_grad_color_stop"],
|
||||||
|
[lv_opa_t, "bg_opa"],
|
||||||
|
[lv_blend_mode_t, "bg_blend_mode"],
|
||||||
|
|
||||||
|
#/*Border*/
|
||||||
|
[lv_color_t, "border_color"],
|
||||||
|
[lv_style_int_t, "border_width"],
|
||||||
|
[lv_style_int_t, "border_side"],
|
||||||
|
[lv_opa_t, "border_opa"],
|
||||||
|
[lv_blend_mode_t, "border_blend_mode"],
|
||||||
|
[uint8_t_1, "border_post"],
|
||||||
|
|
||||||
|
#/*Outline*/
|
||||||
|
[lv_color_t, "outline_color"],
|
||||||
|
[lv_style_int_t, "outline_width"],
|
||||||
|
[lv_style_int_t, "outline_pad"],
|
||||||
|
[lv_opa_t, "outline_opa"],
|
||||||
|
[lv_blend_mode_t, "outline_blend_mode"],
|
||||||
|
|
||||||
|
#/*Shadow*/
|
||||||
|
[lv_color_t, "shadow_color"],
|
||||||
|
[lv_style_int_t, "shadow_width"],
|
||||||
|
[lv_style_int_t, "shadow_ofs_x"],
|
||||||
|
[lv_style_int_t, "shadow_ofs_y"],
|
||||||
|
[lv_style_int_t, "shadow_spread"],
|
||||||
|
[lv_opa_t, "shadow_opa"],
|
||||||
|
[lv_blend_mode_t, "shadow_blend_mode"],
|
||||||
|
|
||||||
|
#/*Pattern*/
|
||||||
|
[ptr, "pattern_image"],
|
||||||
|
[ptr, "pattern_font"],
|
||||||
|
[lv_color_t, "pattern_recolor"],
|
||||||
|
[lv_opa_t, "pattern_opa"],
|
||||||
|
[lv_opa_t, "pattern_recolor_opa"],
|
||||||
|
[uint8_t_1, "pattern_repeat"],
|
||||||
|
[lv_blend_mode_t, "pattern_blend_mode"],
|
||||||
|
|
||||||
|
#/*Value*/
|
||||||
|
[ptr, "value_str"],
|
||||||
|
[ptr, "value_font"],
|
||||||
|
[lv_opa_t, "value_opa"],
|
||||||
|
[lv_color_t, "value_color"],
|
||||||
|
[lv_style_int_t, "value_ofs_x"],
|
||||||
|
[lv_style_int_t, "value_ofs_y"],
|
||||||
|
[lv_style_int_t, "value_letter_space"],
|
||||||
|
[lv_style_int_t, "value_line_space"],
|
||||||
|
[lv_align_t, "value_align"],
|
||||||
|
[lv_blend_mode_t, "value_blend_mode"],
|
||||||
|
]
|
||||||
|
lv_draw_rect_dsc_t = ctypes.structure(lv_draw_rect_dsc_t, "lv_draw_rect_dsc_t")
|
||||||
|
|
||||||
|
lv_draw_line_dsc_t = [
|
||||||
|
[lv_color_t, "color"],
|
||||||
|
[lv_style_int_t, "width"],
|
||||||
|
[lv_style_int_t, "dash_width"],
|
||||||
|
[lv_style_int_t, "dash_gap"],
|
||||||
|
[lv_opa_t, "opa"],
|
||||||
|
[uint8_t_2, "blend_mode"],
|
||||||
|
[uint8_t_1, "round_start"],
|
||||||
|
[uint8_t_1, "round_end"],
|
||||||
|
[uint8_t_1, "raw_end"],
|
||||||
|
]
|
||||||
|
lv_draw_line_dsc_t = ctypes.structure(lv_draw_line_dsc_t, "lv_draw_line_dsc_t")
|
||||||
|
|
||||||
|
lv_draw_img_dsc_t = [
|
||||||
|
[lv_opa_t, "opa"],
|
||||||
|
[uint16_t, "angle"],
|
||||||
|
[lv_point_t, "pivot"],
|
||||||
|
[uint16_t, "zoom"],
|
||||||
|
[lv_opa_t, "recolor_opa"],
|
||||||
|
[lv_color_t, "recolor"],
|
||||||
|
[lv_blend_mode_t, "blend_mode"],
|
||||||
|
[uint8_t_1, "antialias"],
|
||||||
|
]
|
||||||
|
lv_draw_img_dsc_t = ctypes.structure(lv_draw_img_dsc_t, "lv_draw_img_dsc_t")
|
||||||
|
|
||||||
|
lv_draw_label_dsc_t = [
|
||||||
|
[lv_color_t, "color"],
|
||||||
|
[lv_color_t, "sel_color"],
|
||||||
|
[lv_color_t, "sel_bg_color"],
|
||||||
|
[lv_font_t, "font"],
|
||||||
|
[lv_opa_t, "opa"],
|
||||||
|
[lv_style_int_t, "line_space"],
|
||||||
|
[lv_style_int_t, "letter_space"],
|
||||||
|
[uint32_t, "sel_start"],
|
||||||
|
[uint32_t, "sel_end"],
|
||||||
|
[lv_coord_t, "ofs_x"],
|
||||||
|
[lv_coord_t, "ofs_y"],
|
||||||
|
[lv_bidi_dir_t, "bidi_dir"],
|
||||||
|
[lv_txt_flag_t, "flag"],
|
||||||
|
[lv_text_decor_t, "decor"],
|
||||||
|
[lv_blend_mode_t, "blend_mode"],
|
||||||
|
]
|
||||||
|
lv_draw_label_dsc_t = ctypes.structure(lv_draw_label_dsc_t, "lv_draw_label_dsc_t")
|
||||||
|
|
||||||
|
#- --------- lv_mask --------- -#
|
||||||
|
lv_draw_mask_xcb_t = ptr # callback
|
||||||
|
lv_draw_mask_type_t = ctypes.u8
|
||||||
|
lv_draw_mask_line_side_t = ctypes.u8
|
||||||
|
|
||||||
|
lv_draw_mask_common_dsc_t = [
|
||||||
|
[lv_draw_mask_xcb_t, "cb"],
|
||||||
|
[lv_draw_mask_type_t, "type"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_common_dsc_t = ctypes.structure(lv_draw_mask_common_dsc_t, "lv_draw_mask_common_dsc_t")
|
||||||
|
|
||||||
|
lv_draw_mask_line_param_cfg_t = [
|
||||||
|
#/*First point */
|
||||||
|
[lv_point_t, "p1"],
|
||||||
|
|
||||||
|
#/*Second point*/
|
||||||
|
[lv_point_t, "p2"],
|
||||||
|
|
||||||
|
#/*Which side to keep?*/
|
||||||
|
[uint8_t_2, "side"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_line_param_cfg_t = ctypes.structure(lv_draw_mask_line_param_cfg_t, "lv_draw_mask_line_param_cfg_t")
|
||||||
|
|
||||||
|
lv_draw_mask_line_param_t = [
|
||||||
|
#/*The first element must be the common descriptor*/
|
||||||
|
[lv_draw_mask_common_dsc_t, "dsc"],
|
||||||
|
[lv_draw_mask_line_param_cfg_t, "cfg"],
|
||||||
|
#/*A point of the line*/
|
||||||
|
[lv_point_t, "origo"],
|
||||||
|
#/* X / (1024*Y) steepness (X is 0..1023 range). What is the change of X in 1024 Y?*/
|
||||||
|
[int32_t, "xy_steep"],
|
||||||
|
#/* Y / (1024*X) steepness (Y is 0..1023 range). What is the change of Y in 1024 X?*/
|
||||||
|
[int32_t, "yx_steep"],
|
||||||
|
#/*Helper which stores yx_steep for flat lines and xy_steep for steep (non flat) lines */
|
||||||
|
[int32_t, "steep"],
|
||||||
|
#/*Steepness in 1 px in 0..255 range. Used only by flat lines. */
|
||||||
|
[int32_t, "spx"],
|
||||||
|
#/*1: It's a flat line? (Near to horizontal)*/
|
||||||
|
[uint8_t_1, "flat"],
|
||||||
|
#/* Invert the mask. The default is: Keep the left part.
|
||||||
|
# * It is used to select left/right/top/bottom*/
|
||||||
|
[uint8_t_1, "inv"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_line_param_t = ctypes.structure(lv_draw_mask_line_param_t, "lv_draw_mask_line_param_t")
|
||||||
|
|
||||||
|
lv_draw_mask_angle_param_cfg_t = [
|
||||||
|
[lv_point_t, "vertex_p"],
|
||||||
|
[lv_coord_t, "start_angle"],
|
||||||
|
[lv_coord_t, "end_angle"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_angle_param_cfg_t = ctypes.structure(lv_draw_mask_angle_param_cfg_t, "lv_draw_mask_angle_param_cfg_t")
|
||||||
|
|
||||||
|
lv_draw_mask_angle_param_t = [
|
||||||
|
#/*The first element must be the common descriptor*/
|
||||||
|
[lv_draw_mask_common_dsc_t, "dsc"],
|
||||||
|
[lv_draw_mask_angle_param_cfg_t, "cfg"],
|
||||||
|
|
||||||
|
[lv_draw_mask_line_param_t, "start_line"],
|
||||||
|
[lv_draw_mask_line_param_t, "end_line"],
|
||||||
|
[uint16_t, "delta_deg"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_angle_param_t = ctypes.structure(lv_draw_mask_angle_param_t, "lv_draw_mask_angle_param_t")
|
||||||
|
|
||||||
|
|
||||||
|
lv_draw_mask_radius_param_cfg_t = [
|
||||||
|
[lv_area_t, "rect"],
|
||||||
|
[lv_coord_t, "radius"],
|
||||||
|
[uint8_t_1, "outer"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_radius_param_cfg_t = ctypes.structure(lv_draw_mask_radius_param_cfg_t, "lv_draw_mask_radius_param_cfg_t")
|
||||||
|
|
||||||
|
lv_sqrt_res_t = [
|
||||||
|
[uint16_t, "i"],
|
||||||
|
[uint16_t, "f"],
|
||||||
|
]
|
||||||
|
lv_sqrt_res_t = ctypes.structure(lv_sqrt_res_t, "lv_sqrt_res_t")
|
||||||
|
|
||||||
|
lv_draw_mask_radius_param_t = [
|
||||||
|
#/*The first element must be the common descriptor*/
|
||||||
|
[lv_draw_mask_common_dsc_t, "dsc"],
|
||||||
|
[lv_draw_mask_radius_param_cfg_t, "cfg"],
|
||||||
|
[int32_t, "y_prev"],
|
||||||
|
[lv_sqrt_res_t, "y_prev_x"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_radius_param_t = ctypes.structure(lv_draw_mask_radius_param_t, "lv_draw_mask_radius_param_t")
|
||||||
|
|
||||||
|
|
||||||
|
lv_draw_mask_fade_param_cfg_t = [
|
||||||
|
[lv_area_t, "coords"],
|
||||||
|
[lv_coord_t, "y_top"],
|
||||||
|
[lv_coord_t, "y_bottom"],
|
||||||
|
[lv_opa_t, "opa_top"],
|
||||||
|
[lv_opa_t, "opa_bottom"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_fade_param_cfg_t = ctypes.structure(lv_draw_mask_fade_param_cfg_t, "lv_draw_mask_fade_param_cfg_t")
|
||||||
|
|
||||||
|
lv_draw_mask_fade_param_t = [
|
||||||
|
# /*The first element must be the common descriptor*/
|
||||||
|
[lv_draw_mask_common_dsc_t, "dsc"],
|
||||||
|
[lv_draw_mask_fade_param_cfg_t, "cfg"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_fade_param_t = ctypes.structure(lv_draw_mask_fade_param_t, "lv_draw_mask_fade_param_t")
|
||||||
|
|
||||||
|
|
||||||
|
lv_draw_mask_map_param_cfg_t = [
|
||||||
|
[lv_area_t, "coords"],
|
||||||
|
[ptr, "map"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_map_param_cfg_t = ctypes.structure(lv_draw_mask_map_param_cfg_t, "lv_draw_mask_map_param_cfg_t")
|
||||||
|
|
||||||
|
lv_draw_mask_map_param_t = [
|
||||||
|
#/*The first element must be the common descriptor*/
|
||||||
|
[lv_draw_mask_common_dsc_t, "dsc"],
|
||||||
|
[lv_draw_mask_map_param_cfg_t, "cfg"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_map_param_t = ctypes.structure(lv_draw_mask_map_param_t, "lv_draw_mask_map_param_t")
|
||||||
|
|
||||||
|
lv_draw_mask_saved_t = [
|
||||||
|
[ptr, "param"],
|
||||||
|
[ptr, "custom_id"],
|
||||||
|
]
|
||||||
|
lv_draw_mask_saved_t = ctypes.structure(lv_draw_mask_saved_t, "lv_draw_mask_saved_t")
|
||||||
|
|
||||||
|
|
||||||
|
# Ex:
|
||||||
|
# bb = ctypes.buffer(test_t, bytes("0101020203030404FFFFFEFEFCFC8080"))
|
||||||
|
|
||||||
|
# Ex:
|
||||||
|
# bb = ctypes.buffer(lv_draw_rect)
|
||||||
|
|
||||||
|
#- Ex
|
||||||
|
|
||||||
|
bb=ctypes.buffer(lv_draw_line_dsc_t)
|
||||||
|
bb.color
|
||||||
|
bb.blend_mode
|
||||||
|
|
||||||
|
bb.color = -1
|
||||||
|
- bytes('FFFF0000000000000003')
|
||||||
|
|
||||||
|
bb.blend_mode=3
|
||||||
|
- bytes('FFFF0000000000000003')
|
||||||
|
|
||||||
|
bb.raw_end = 1
|
||||||
|
- bytes('FFFF0000000000000013')
|
||||||
|
|
||||||
|
bb.blend_mode=0
|
||||||
|
- bytes('FFFF0000000000000010')
|
||||||
|
|
||||||
|
lv_draw_line_dsc_t = [
|
||||||
|
[lv_color_t, "color"],
|
||||||
|
[lv_style_int_t, "width"],
|
||||||
|
[lv_style_int_t, "dash_width"],
|
||||||
|
[lv_style_int_t, "dash_gap"],
|
||||||
|
[lv_opa_t, "opa"],
|
||||||
|
[uint8_t_2, "blend_mode"],
|
||||||
|
[uint8_t_1, "round_start"],
|
||||||
|
[uint8_t_1, "round_end"],
|
||||||
|
[uint8_t_1, "raw_end"],
|
||||||
|
]
|
||||||
|
|
||||||
|
-#
|
|
@ -0,0 +1,318 @@
|
||||||
|
/*
|
||||||
|
xdrv_52_3_berry_native.ino - Berry scripting language, native fucnctions
|
||||||
|
|
||||||
|
Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_BERRY
|
||||||
|
#ifdef USE_LVGL
|
||||||
|
|
||||||
|
#include <berry.h>
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include "be_lvgl.h"
|
||||||
|
|
||||||
|
// Berry easy logging
|
||||||
|
extern "C" {
|
||||||
|
extern void berry_log_C(const char * berry_buf, ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Generated code, don't edit
|
||||||
|
*******************************************************************/
|
||||||
|
enum {
|
||||||
|
ctypes_ptr = 0,
|
||||||
|
ctypes_uint = 1,
|
||||||
|
ctypes_int = 2,
|
||||||
|
ctypes_str = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct be_ctypes_structure_t {
|
||||||
|
const char * name;
|
||||||
|
uint16_t offset_bits;
|
||||||
|
uint16_t len_bits : 13;
|
||||||
|
uint16_t type : 3;
|
||||||
|
} be_ctypes_structure_t;
|
||||||
|
const be_ctypes_structure_t be_lv_point_t[2] = {
|
||||||
|
{ "x", 0, 16, ctypes_int },
|
||||||
|
{ "y", 16, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_area_t[4] = {
|
||||||
|
{ "x1", 0, 16, ctypes_int },
|
||||||
|
{ "x2", 32, 16, ctypes_int },
|
||||||
|
{ "y1", 16, 16, ctypes_int },
|
||||||
|
{ "y2", 48, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_test_t[8] = {
|
||||||
|
{ "a_x1", 0, 16, ctypes_int },
|
||||||
|
{ "a_x2", 32, 16, ctypes_int },
|
||||||
|
{ "a_y1", 16, 16, ctypes_int },
|
||||||
|
{ "a_y2", 48, 16, ctypes_int },
|
||||||
|
{ "b_x1", 64, 16, ctypes_int },
|
||||||
|
{ "b_x2", 96, 16, ctypes_int },
|
||||||
|
{ "b_y1", 80, 16, ctypes_int },
|
||||||
|
{ "b_y2", 112, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_rect_dsc_t[43] = {
|
||||||
|
{ "bg_blend_mode", 96, 8, ctypes_uint },
|
||||||
|
{ "bg_color", 16, 16, ctypes_uint },
|
||||||
|
{ "bg_grad_color", 32, 16, ctypes_uint },
|
||||||
|
{ "bg_grad_color_stop", 72, 16, ctypes_int },
|
||||||
|
{ "bg_grad_dir", 48, 8, ctypes_uint },
|
||||||
|
{ "bg_main_color_stop", 56, 16, ctypes_int },
|
||||||
|
{ "bg_opa", 88, 8, ctypes_uint },
|
||||||
|
{ "border_blend_mode", 160, 8, ctypes_uint },
|
||||||
|
{ "border_color", 104, 16, ctypes_uint },
|
||||||
|
{ "border_opa", 152, 8, ctypes_uint },
|
||||||
|
{ "border_post", 168, 1, ctypes_uint },
|
||||||
|
{ "border_side", 136, 16, ctypes_int },
|
||||||
|
{ "border_width", 120, 16, ctypes_int },
|
||||||
|
{ "outline_blend_mode", 232, 8, ctypes_uint },
|
||||||
|
{ "outline_color", 176, 16, ctypes_uint },
|
||||||
|
{ "outline_opa", 224, 8, ctypes_uint },
|
||||||
|
{ "outline_pad", 208, 16, ctypes_int },
|
||||||
|
{ "outline_width", 192, 16, ctypes_int },
|
||||||
|
{ "pattern_blend_mode", 440, 8, ctypes_uint },
|
||||||
|
{ "pattern_font", 368, 32, ctypes_uint },
|
||||||
|
{ "pattern_image", 336, 32, ctypes_uint },
|
||||||
|
{ "pattern_opa", 416, 8, ctypes_uint },
|
||||||
|
{ "pattern_recolor", 400, 16, ctypes_uint },
|
||||||
|
{ "pattern_recolor_opa", 424, 8, ctypes_uint },
|
||||||
|
{ "pattern_repeat", 432, 1, ctypes_uint },
|
||||||
|
{ "radius", 0, 16, ctypes_int },
|
||||||
|
{ "shadow_blend_mode", 328, 8, ctypes_uint },
|
||||||
|
{ "shadow_color", 240, 16, ctypes_uint },
|
||||||
|
{ "shadow_ofs_x", 272, 16, ctypes_int },
|
||||||
|
{ "shadow_ofs_y", 288, 16, ctypes_int },
|
||||||
|
{ "shadow_opa", 320, 8, ctypes_uint },
|
||||||
|
{ "shadow_spread", 304, 16, ctypes_int },
|
||||||
|
{ "shadow_width", 256, 16, ctypes_int },
|
||||||
|
{ "value_align", 600, 8, ctypes_uint },
|
||||||
|
{ "value_blend_mode", 608, 8, ctypes_uint },
|
||||||
|
{ "value_color", 520, 16, ctypes_uint },
|
||||||
|
{ "value_font", 480, 32, ctypes_uint },
|
||||||
|
{ "value_letter_space", 568, 16, ctypes_int },
|
||||||
|
{ "value_line_space", 584, 16, ctypes_int },
|
||||||
|
{ "value_ofs_x", 536, 16, ctypes_int },
|
||||||
|
{ "value_ofs_y", 552, 16, ctypes_int },
|
||||||
|
{ "value_opa", 512, 8, ctypes_uint },
|
||||||
|
{ "value_str", 448, 32, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_line_dsc_t[9] = {
|
||||||
|
{ "blend_mode", 72, 2, ctypes_uint },
|
||||||
|
{ "color", 0, 16, ctypes_uint },
|
||||||
|
{ "dash_gap", 48, 16, ctypes_int },
|
||||||
|
{ "dash_width", 32, 16, ctypes_int },
|
||||||
|
{ "opa", 64, 8, ctypes_uint },
|
||||||
|
{ "raw_end", 76, 1, ctypes_uint },
|
||||||
|
{ "round_end", 75, 1, ctypes_uint },
|
||||||
|
{ "round_start", 74, 1, ctypes_uint },
|
||||||
|
{ "width", 16, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_img_dsc_t[9] = {
|
||||||
|
{ "angle", 8, 16, ctypes_uint },
|
||||||
|
{ "antialias", 104, 1, ctypes_uint },
|
||||||
|
{ "blend_mode", 96, 8, ctypes_uint },
|
||||||
|
{ "opa", 0, 8, ctypes_uint },
|
||||||
|
{ "pivot_x", 24, 16, ctypes_int },
|
||||||
|
{ "pivot_y", 40, 16, ctypes_int },
|
||||||
|
{ "recolor", 80, 16, ctypes_uint },
|
||||||
|
{ "recolor_opa", 72, 8, ctypes_uint },
|
||||||
|
{ "zoom", 56, 16, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_label_dsc_t[15] = {
|
||||||
|
{ "bidi_dir", 216, 8, ctypes_uint },
|
||||||
|
{ "blend_mode", 240, 8, ctypes_uint },
|
||||||
|
{ "color", 0, 16, ctypes_uint },
|
||||||
|
{ "decor", 232, 8, ctypes_uint },
|
||||||
|
{ "flag", 224, 8, ctypes_uint },
|
||||||
|
{ "font", 48, 32, ctypes_uint },
|
||||||
|
{ "letter_space", 104, 16, ctypes_int },
|
||||||
|
{ "line_space", 88, 16, ctypes_int },
|
||||||
|
{ "ofs_x", 184, 16, ctypes_int },
|
||||||
|
{ "ofs_y", 200, 16, ctypes_int },
|
||||||
|
{ "opa", 80, 8, ctypes_uint },
|
||||||
|
{ "sel_bg_color", 32, 16, ctypes_uint },
|
||||||
|
{ "sel_color", 16, 16, ctypes_uint },
|
||||||
|
{ "sel_end", 152, 32, ctypes_uint },
|
||||||
|
{ "sel_start", 120, 32, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_common_dsc_t[2] = {
|
||||||
|
{ "cb", 0, 32, ctypes_uint },
|
||||||
|
{ "type", 32, 8, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_line_param_cfg_t[5] = {
|
||||||
|
{ "p1_x", 0, 16, ctypes_int },
|
||||||
|
{ "p1_y", 16, 16, ctypes_int },
|
||||||
|
{ "p2_x", 32, 16, ctypes_int },
|
||||||
|
{ "p2_y", 48, 16, ctypes_int },
|
||||||
|
{ "side", 64, 2, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_line_param_t[15] = {
|
||||||
|
{ "cfg_p1_x", 40, 16, ctypes_int },
|
||||||
|
{ "cfg_p1_y", 56, 16, ctypes_int },
|
||||||
|
{ "cfg_p2_x", 72, 16, ctypes_int },
|
||||||
|
{ "cfg_p2_y", 88, 16, ctypes_int },
|
||||||
|
{ "cfg_side", 104, 2, ctypes_uint },
|
||||||
|
{ "dsc_cb", 0, 32, ctypes_uint },
|
||||||
|
{ "dsc_type", 32, 8, ctypes_uint },
|
||||||
|
{ "flat", 272, 1, ctypes_uint },
|
||||||
|
{ "inv", 273, 1, ctypes_uint },
|
||||||
|
{ "origo_x", 112, 16, ctypes_int },
|
||||||
|
{ "origo_y", 128, 16, ctypes_int },
|
||||||
|
{ "spx", 240, 32, ctypes_int },
|
||||||
|
{ "steep", 208, 32, ctypes_int },
|
||||||
|
{ "xy_steep", 144, 32, ctypes_int },
|
||||||
|
{ "yx_steep", 176, 32, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_angle_param_cfg_t[4] = {
|
||||||
|
{ "end_angle", 48, 16, ctypes_int },
|
||||||
|
{ "start_angle", 32, 16, ctypes_int },
|
||||||
|
{ "vertex_p_x", 0, 16, ctypes_int },
|
||||||
|
{ "vertex_p_y", 16, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_angle_param_t[37] = {
|
||||||
|
{ "cfg_end_angle", 88, 16, ctypes_int },
|
||||||
|
{ "cfg_start_angle", 72, 16, ctypes_int },
|
||||||
|
{ "cfg_vertex_p_x", 40, 16, ctypes_int },
|
||||||
|
{ "cfg_vertex_p_y", 56, 16, ctypes_int },
|
||||||
|
{ "delta_deg", 664, 16, ctypes_uint },
|
||||||
|
{ "dsc_cb", 0, 32, ctypes_uint },
|
||||||
|
{ "dsc_type", 32, 8, ctypes_uint },
|
||||||
|
{ "end_line_cfg_p1_x", 424, 16, ctypes_int },
|
||||||
|
{ "end_line_cfg_p1_y", 440, 16, ctypes_int },
|
||||||
|
{ "end_line_cfg_p2_x", 456, 16, ctypes_int },
|
||||||
|
{ "end_line_cfg_p2_y", 472, 16, ctypes_int },
|
||||||
|
{ "end_line_cfg_side", 488, 2, ctypes_uint },
|
||||||
|
{ "end_line_dsc_cb", 384, 32, ctypes_uint },
|
||||||
|
{ "end_line_dsc_type", 416, 8, ctypes_uint },
|
||||||
|
{ "end_line_flat", 656, 1, ctypes_uint },
|
||||||
|
{ "end_line_inv", 657, 1, ctypes_uint },
|
||||||
|
{ "end_line_origo_x", 496, 16, ctypes_int },
|
||||||
|
{ "end_line_origo_y", 512, 16, ctypes_int },
|
||||||
|
{ "end_line_spx", 624, 32, ctypes_int },
|
||||||
|
{ "end_line_steep", 592, 32, ctypes_int },
|
||||||
|
{ "end_line_xy_steep", 528, 32, ctypes_int },
|
||||||
|
{ "end_line_yx_steep", 560, 32, ctypes_int },
|
||||||
|
{ "start_line_cfg_p1_x", 144, 16, ctypes_int },
|
||||||
|
{ "start_line_cfg_p1_y", 160, 16, ctypes_int },
|
||||||
|
{ "start_line_cfg_p2_x", 176, 16, ctypes_int },
|
||||||
|
{ "start_line_cfg_p2_y", 192, 16, ctypes_int },
|
||||||
|
{ "start_line_cfg_side", 208, 2, ctypes_uint },
|
||||||
|
{ "start_line_dsc_cb", 104, 32, ctypes_uint },
|
||||||
|
{ "start_line_dsc_type", 136, 8, ctypes_uint },
|
||||||
|
{ "start_line_flat", 376, 1, ctypes_uint },
|
||||||
|
{ "start_line_inv", 377, 1, ctypes_uint },
|
||||||
|
{ "start_line_origo_x", 216, 16, ctypes_int },
|
||||||
|
{ "start_line_origo_y", 232, 16, ctypes_int },
|
||||||
|
{ "start_line_spx", 344, 32, ctypes_int },
|
||||||
|
{ "start_line_steep", 312, 32, ctypes_int },
|
||||||
|
{ "start_line_xy_steep", 248, 32, ctypes_int },
|
||||||
|
{ "start_line_yx_steep", 280, 32, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_radius_param_cfg_t[6] = {
|
||||||
|
{ "outer", 80, 1, ctypes_uint },
|
||||||
|
{ "radius", 64, 16, ctypes_int },
|
||||||
|
{ "rect_x1", 0, 16, ctypes_int },
|
||||||
|
{ "rect_x2", 32, 16, ctypes_int },
|
||||||
|
{ "rect_y1", 16, 16, ctypes_int },
|
||||||
|
{ "rect_y2", 48, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_sqrt_res_t[2] = {
|
||||||
|
{ "f", 16, 16, ctypes_uint },
|
||||||
|
{ "i", 0, 16, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_radius_param_t[11] = {
|
||||||
|
{ "cfg_outer", 120, 1, ctypes_uint },
|
||||||
|
{ "cfg_radius", 104, 16, ctypes_int },
|
||||||
|
{ "cfg_rect_x1", 40, 16, ctypes_int },
|
||||||
|
{ "cfg_rect_x2", 72, 16, ctypes_int },
|
||||||
|
{ "cfg_rect_y1", 56, 16, ctypes_int },
|
||||||
|
{ "cfg_rect_y2", 88, 16, ctypes_int },
|
||||||
|
{ "dsc_cb", 0, 32, ctypes_uint },
|
||||||
|
{ "dsc_type", 32, 8, ctypes_uint },
|
||||||
|
{ "y_prev", 128, 32, ctypes_int },
|
||||||
|
{ "y_prev_x_f", 176, 16, ctypes_uint },
|
||||||
|
{ "y_prev_x_i", 160, 16, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_fade_param_cfg_t[8] = {
|
||||||
|
{ "coords_x1", 0, 16, ctypes_int },
|
||||||
|
{ "coords_x2", 32, 16, ctypes_int },
|
||||||
|
{ "coords_y1", 16, 16, ctypes_int },
|
||||||
|
{ "coords_y2", 48, 16, ctypes_int },
|
||||||
|
{ "opa_bottom", 104, 8, ctypes_uint },
|
||||||
|
{ "opa_top", 96, 8, ctypes_uint },
|
||||||
|
{ "y_bottom", 80, 16, ctypes_int },
|
||||||
|
{ "y_top", 64, 16, ctypes_int },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_fade_param_t[10] = {
|
||||||
|
{ "cfg_coords_x1", 40, 16, ctypes_int },
|
||||||
|
{ "cfg_coords_x2", 72, 16, ctypes_int },
|
||||||
|
{ "cfg_coords_y1", 56, 16, ctypes_int },
|
||||||
|
{ "cfg_coords_y2", 88, 16, ctypes_int },
|
||||||
|
{ "cfg_opa_bottom", 144, 8, ctypes_uint },
|
||||||
|
{ "cfg_opa_top", 136, 8, ctypes_uint },
|
||||||
|
{ "cfg_y_bottom", 120, 16, ctypes_int },
|
||||||
|
{ "cfg_y_top", 104, 16, ctypes_int },
|
||||||
|
{ "dsc_cb", 0, 32, ctypes_uint },
|
||||||
|
{ "dsc_type", 32, 8, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_map_param_cfg_t[5] = {
|
||||||
|
{ "coords_x1", 0, 16, ctypes_int },
|
||||||
|
{ "coords_x2", 32, 16, ctypes_int },
|
||||||
|
{ "coords_y1", 16, 16, ctypes_int },
|
||||||
|
{ "coords_y2", 48, 16, ctypes_int },
|
||||||
|
{ "map", 64, 32, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_map_param_t[7] = {
|
||||||
|
{ "cfg_coords_x1", 40, 16, ctypes_int },
|
||||||
|
{ "cfg_coords_x2", 72, 16, ctypes_int },
|
||||||
|
{ "cfg_coords_y1", 56, 16, ctypes_int },
|
||||||
|
{ "cfg_coords_y2", 88, 16, ctypes_int },
|
||||||
|
{ "cfg_map", 104, 32, ctypes_uint },
|
||||||
|
{ "dsc_cb", 0, 32, ctypes_uint },
|
||||||
|
{ "dsc_type", 32, 8, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
const be_ctypes_structure_t be_lv_draw_mask_saved_t[2] = {
|
||||||
|
{ "custom_id", 32, 32, ctypes_uint },
|
||||||
|
{ "param", 0, 32, ctypes_uint },
|
||||||
|
};
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
#endif // USE_LVGL
|
||||||
|
|
||||||
|
#endif // USE_BERRY
|
Loading…
Reference in New Issue