mirror of
https://github.com/clockworkpi/Menu.git
synced 2026-03-20 19:02:50 +01:00
gcores ~/apps/Menu branch first commit
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
|
||||
/*
|
||||
FIXME
|
||||
*/
|
||||
|
||||
class app_list+ {
|
||||
|
||||
private import rt::c;
|
||||
|
||||
private alias
|
||||
string = std::string,
|
||||
vector = std::vector;
|
||||
|
||||
struct app {
|
||||
slot int;
|
||||
type int;
|
||||
title string;
|
||||
cmd string;
|
||||
icon string;
|
||||
extra string;
|
||||
}
|
||||
|
||||
struct app_list {
|
||||
db database;
|
||||
apps vector<app>;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
constructor(this); }
|
||||
func destructor() {
|
||||
destructor(this); }
|
||||
|
||||
func init(filename. char) bool {
|
||||
if !this.db->open(filename);
|
||||
return false;
|
||||
this.db->exec(
|
||||
"
|
||||
CREATE TABLE IF NOT EXISTS apps (
|
||||
slot INTEGER PRIMARY KEY,
|
||||
type INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
command TEXT NOT NULL,
|
||||
icon TEXT,
|
||||
extra TEXT
|
||||
);
|
||||
"
|
||||
);
|
||||
var stmt database::stmt;
|
||||
if !this.db->prepare(&stmt, "SELECT * FROM apps");
|
||||
return false;
|
||||
while stmt->step() {
|
||||
var app. app = this.apps->new();
|
||||
app.slot = stmt->column_int(0);
|
||||
app.type = stmt->column_int(1);
|
||||
app.title->set(stmt->column_text(2));
|
||||
app.cmd->set(stmt->column_text(3));
|
||||
app.icon->set(stmt->column_text(4));
|
||||
app.extra->set(stmt->column_text(5));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
func for_each(begin int, end int, callback void, arg void) {
|
||||
forvar i size_t = 0, c size_t = this.apps->count(); i < c; i++ {
|
||||
var app. app = this.apps->at(i);
|
||||
if app.slot >= begin and app.slot <= end {
|
||||
proto fn(app void, arg void);
|
||||
fn[callback](app, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func get_app_from_vector(slot int) .app {
|
||||
forvar index size_t = 0, count size_t = this.apps->count(); index < count; index++ {
|
||||
var app. app = this.apps->at(index);
|
||||
if app.slot == slot;
|
||||
return app;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
func remove_app_from_vector(slot int) bool {
|
||||
forvar index size_t = 0, count size_t = this.apps->count(); index < count; index++ {
|
||||
if this.apps->at(index).slot == slot;
|
||||
return this.apps->erase(index);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
func insert(slot int, type int, title. char, cmd. char, icon. char = null, extra. char = null) .app {
|
||||
if !this.db->execf("INSERT INTO apps (slot, type, title, command, icon, extra) VALUES (%d, %d, %Q, %Q, %Q, %Q)",
|
||||
slot, type, title, cmd, icon, extra) {
|
||||
return null;
|
||||
}
|
||||
func = this.apps->new();
|
||||
func.slot = slot;
|
||||
func.type = type;
|
||||
func.title->set(title);
|
||||
func.cmd->set(cmd);
|
||||
func.icon->set(icon);
|
||||
func.extra->set(extra);
|
||||
}
|
||||
|
||||
func update(slot int, type int, title. char, cmd. char, icon. char = null, extra. char = null) .app {
|
||||
if !this.db->execf("UPDATE apps SET type=%d, title=%Q, command=%Q, icon=%Q, extra=%Q WHERE slot=%d",
|
||||
type, title, cmd, icon, extra, slot) {
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
fixme
|
||||
*/
|
||||
if (func = this->get_app_from_vector(slot)) == null;
|
||||
return;
|
||||
func.type = type;
|
||||
func.title->set(title);
|
||||
func.cmd->set(cmd);
|
||||
func.icon->set(icon);
|
||||
func.extra->set(extra);
|
||||
}
|
||||
|
||||
func remove(slot int) bool {
|
||||
this->remove_app_from_vector(slot);
|
||||
/*
|
||||
fixme
|
||||
*/
|
||||
return this.db->execf("DELETE FROM apps WHERE slot=%d", slot);
|
||||
}
|
||||
|
||||
func move(from int, to int) bool {
|
||||
this->remove(to);
|
||||
if !this.db->execf("UPDATE apps SET slot=%d WHERE slot=%d", to, from) {
|
||||
/*
|
||||
fixme
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
using app. app = this->get_app_from_vector(from) {
|
||||
if app ~= null {
|
||||
app.slot = to;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
|
||||
class cfg {
|
||||
|
||||
private import rt::c;
|
||||
|
||||
private alias
|
||||
vector = std::vector,
|
||||
string = std::string;
|
||||
|
||||
struct item {
|
||||
name string;
|
||||
value string;
|
||||
cover char;
|
||||
}
|
||||
|
||||
struct cfg {
|
||||
items vector<item>;
|
||||
filename string;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
constructor(this);
|
||||
}
|
||||
|
||||
func destructor() {
|
||||
destructor(this);
|
||||
}
|
||||
|
||||
func open(filename. char) bool {
|
||||
define {
|
||||
SIZE_LIMIT = 0x1000000;
|
||||
}
|
||||
lambda read(filename. char, file_size& size_t) void [
|
||||
var stream void = fopen(filename, "rb");
|
||||
if stream == null;
|
||||
return null;
|
||||
defer fclose(stream);
|
||||
if fseek(stream, 0, SEEK_END) < 0;
|
||||
return null;
|
||||
var tail long = ftell(stream);
|
||||
if tail < 0 or tail > SIZE_LIMIT;
|
||||
return null;
|
||||
rewind(stream);
|
||||
func = malloc(tail);
|
||||
var offset size_t = 0;
|
||||
var remain size_t = tail;
|
||||
while remain {
|
||||
var size size_t = fread(func + offset, 1, remain, stream);
|
||||
if ferror(stream) {
|
||||
free(func);
|
||||
return null;
|
||||
}
|
||||
offset += size;
|
||||
remain -= size;
|
||||
}
|
||||
file_size = offset;
|
||||
];
|
||||
var size size_t;
|
||||
var buf. char = read(filename, size);
|
||||
if buf == null;
|
||||
return false;
|
||||
defer free(buf);
|
||||
this.items->clear();
|
||||
this.filename->clear();
|
||||
lambda skip_space(buf. char, index& size_t, size size_t) bool [
|
||||
for ; index < size; index++ {
|
||||
if !isspace(buf[index]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
];
|
||||
lambda skip_line(buf. char, index& size_t, size size_t, end& size_t) bool [
|
||||
for ; index < size; index++ {
|
||||
var c char = buf[index];
|
||||
if c == '\r' {
|
||||
end = index;
|
||||
if ++index < size {
|
||||
if buf[index] == '\n' {
|
||||
index++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
elseif c == '\n';
|
||||
end = index++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
end = index;
|
||||
return false;
|
||||
];
|
||||
lambda skip_name(buf. char, index& size_t, size size_t) bool [
|
||||
for ; index < size; index++ {
|
||||
var c char = buf[index];
|
||||
if c == ' ' or c == '\t' or c == '\r' or c == '\n' or c == '=' {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
];
|
||||
lambda skip_until(buf. char, index& size_t, size size_t, end char) bool [
|
||||
for ; index < size; index++ {
|
||||
if buf[index] == end {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
];
|
||||
forvar index size_t = 0 ;; {
|
||||
if !skip_space(buf, index, size);
|
||||
break;
|
||||
var name_offset size_t = index;
|
||||
if !skip_name(buf, index, size);
|
||||
break;
|
||||
var name_size size_t = index - name_offset;
|
||||
if !name_size;
|
||||
return false;
|
||||
if buf[index] ~= '=' {
|
||||
if !skip_space(buf, ++index, size);
|
||||
break;
|
||||
if buf[index] ~= '=';
|
||||
return false;
|
||||
}
|
||||
if !skip_space(buf, ++index, size);
|
||||
break;
|
||||
var value_offset size_t;
|
||||
var value_size size_t;
|
||||
var cover char;
|
||||
if buf[index] == '\'' or
|
||||
buf[index] == '\"' {
|
||||
cover = buf[index];
|
||||
value_offset = ++index;
|
||||
if !skip_until(buf, index, size, cover);
|
||||
break;
|
||||
value_size = index++ - value_offset;
|
||||
else
|
||||
value_offset = index;
|
||||
var end size_t;
|
||||
skip_line(buf, index, size, end);
|
||||
value_size = end - value_offset;
|
||||
cover = 0;
|
||||
}
|
||||
var item. item = this.items->new();
|
||||
item.name->set(buf + name_offset, name_size);
|
||||
if value_size;
|
||||
item.value->set(buf + value_offset, value_size);
|
||||
item.cover = cover;
|
||||
}
|
||||
this.filename->set(filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
func save(filename. char = null) bool {
|
||||
var stream void;
|
||||
if filename == null {
|
||||
if this.filename->empty();
|
||||
return false;
|
||||
stream = fopen(this.filename->ptr(), "w");
|
||||
else
|
||||
stream = fopen(filename, "w");
|
||||
}
|
||||
if stream == null;
|
||||
return false;
|
||||
forvar index size_t = 0, count size_t = this.items->count(); index < count; index++ {
|
||||
var item. item = this.items->at(index);
|
||||
if item.cover {
|
||||
fprintf("%s = %c%s%c\n",
|
||||
item.name->ptr(),
|
||||
item.cover,
|
||||
item.value->ptr(),
|
||||
item.cover);
|
||||
else
|
||||
fprintf("%s = %s\n",
|
||||
item.name->ptr(),
|
||||
item.value->ptr());
|
||||
}
|
||||
}
|
||||
fclose(stream);
|
||||
}
|
||||
|
||||
func find(name. char) .item {
|
||||
var count size_t = this.items->count();
|
||||
while count {
|
||||
var item. item = this.items->at(--count);
|
||||
if !strcasecmp(item.name->ptr(), name) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
func get(name. char) .char {
|
||||
var item. item = this->find(name);
|
||||
if item == null;
|
||||
return null;
|
||||
return item.value->ptr();
|
||||
}
|
||||
|
||||
func set(name. char, value. char) bool {
|
||||
var item. item = this->find(name);
|
||||
if item == null;
|
||||
return false;
|
||||
item.value->set(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
func add(name. char, value. char = null, cover char = '"') bool {
|
||||
var item. item = this->find(name);
|
||||
if item ~= null;
|
||||
return false;
|
||||
item = this.items->new();
|
||||
item.name->set(name);
|
||||
if value ~= null;
|
||||
item.value->set(value);
|
||||
item.cover = cover;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
|
||||
class database+ {
|
||||
|
||||
private import lib::sqlite3;
|
||||
|
||||
struct database {
|
||||
db void;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
this.db = null;
|
||||
}
|
||||
|
||||
func destructor() {
|
||||
this->close();
|
||||
}
|
||||
|
||||
func open(filename+ char, flags int =
|
||||
SQLITE_OPEN_READWRITE |
|
||||
SQLITE_OPEN_CREATE) bool {
|
||||
this->close();
|
||||
return sqlite3_open_v2(filename, &this.db, flags, null) == SQLITE_OK;
|
||||
}
|
||||
|
||||
func close() {
|
||||
if this.db ~= null;
|
||||
sqlite3_close_v2(this.db), this.db = null;
|
||||
}
|
||||
|
||||
inline exec(sql+ char) bool {
|
||||
return sqlite3_exec(this.db, sql, null, null, null) == SQLITE_OK;
|
||||
}
|
||||
|
||||
func execf(sql+ char, ...) bool {
|
||||
if (sql = sqlite3_vmprintf(sql, va_start(this))) == null;
|
||||
return false;
|
||||
func = this->exec(sql);
|
||||
sqlite3_free(sql);
|
||||
}
|
||||
|
||||
inline prepare(stmt. stmt, sql+ char) bool {
|
||||
return sqlite3_prepare_v2(this.db, sql, -1, &stmt.obj, null) == SQLITE_OK;
|
||||
}
|
||||
|
||||
func preparef(stmt. stmt, sql+ char, ...) bool {
|
||||
if (sql = sqlite3_vmprintf(sql, va_start(this))) == null;
|
||||
return false;
|
||||
func = this->prepare(stmt, sql);
|
||||
sqlite3_free(sql);
|
||||
}
|
||||
|
||||
func prepare_step(stmt. stmt, sql+ char) bool {
|
||||
if !this->prepare(stmt, sql);
|
||||
return false;
|
||||
return stmt->step();
|
||||
}
|
||||
|
||||
func preparef_step(stmt. stmt, sql+ char, ...) bool {
|
||||
if (sql = sqlite3_vmprintf(sql, va_start(this))) == null;
|
||||
return false;
|
||||
defer sqlite3_free(sql);
|
||||
if !this->prepare(stmt, sql);
|
||||
return false;
|
||||
return stmt->step();
|
||||
}
|
||||
|
||||
inline last_insert_rowid() int64 {
|
||||
return sqlite3_last_insert_rowid(this.db);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
static inline free(ptr void) {
|
||||
sqlite3_free(ptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class database+, stmt {
|
||||
|
||||
private import lib::sqlite3;
|
||||
|
||||
struct stmt {
|
||||
obj void;
|
||||
step_error bool;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
this.obj = null;
|
||||
this.step_error = false;
|
||||
}
|
||||
|
||||
func destructor() {
|
||||
this->finalize();
|
||||
}
|
||||
|
||||
inline bind_blob(index int, blob void, blob_size int, callback void) bool {
|
||||
return sqlite3_bind_blob(this.obj, index, blob, blob_size, callback) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_double(index int, data double) bool {
|
||||
return sqlite3_bind_double(this.obj, index, data) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_int(index int, data int) bool {
|
||||
return sqlite3_bind_int(this.obj, index, data) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_null(index int) bool {
|
||||
return sqlite3_bind_null(this.obj, index) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_text(index int, text+ char, text_len int, callback void) bool {
|
||||
return sqlite3_bind_text(this.obj, index, text, text_len, callback) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_text16(index int, text void, text_len int, callback void) bool {
|
||||
return sqlite3_bind_text16(this.obj, index, text, text_len, callback) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_text64(index int, text+ char, text_len int64, callback void, encoding char) bool {
|
||||
return sqlite3_bind_text64(this.obj, index, text, text_len, callback, encoding) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_value(index int, value void) bool {
|
||||
return sqlite3_bind_value(this.obj, index, value) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_zeroblob(index int, size int) bool {
|
||||
return sqlite3_bind_zeroblob(this.obj, index, size) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline bind_param_count() int {
|
||||
return sqlite3_bind_parameter_count(this.obj);
|
||||
}
|
||||
|
||||
inline bind_param_name(index int) +char {
|
||||
return sqlite3_bind_parameter_name(this.obj, index);
|
||||
}
|
||||
|
||||
inline bind_param_index(name+ char) int {
|
||||
return sqlite3_bind_parameter_index(this.obj, name);
|
||||
}
|
||||
|
||||
inline clear_bind() bool {
|
||||
return sqlite3_clear_bindings(this.obj) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline data_count() int {
|
||||
return sqlite3_data_count(this.obj);
|
||||
}
|
||||
|
||||
inline column_count() int {
|
||||
return sqlite3_column_count(this.obj);
|
||||
}
|
||||
|
||||
inline column_name(index int) +char {
|
||||
return sqlite3_column_name(this.obj, index);
|
||||
}
|
||||
|
||||
inline column_name16(index int) void {
|
||||
return sqlite3_column_name16(this.obj, index);
|
||||
}
|
||||
|
||||
func step() bool {
|
||||
var result int = sqlite3_step(this.obj);
|
||||
if result ~= SQLITE_ROW {
|
||||
/*
|
||||
SQLITE_BUSY
|
||||
SQLITE_ERROR
|
||||
SQLITE_MISUSE
|
||||
*/
|
||||
this.step_error = result ~= SQLITE_DONE;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline step_error?() bool {
|
||||
return this.step_error;
|
||||
}
|
||||
|
||||
inline reset() bool {
|
||||
return sqlite3_reset(this.obj) == SQLITE_OK;
|
||||
}
|
||||
|
||||
inline column_blob(col int) void {
|
||||
return sqlite3_column_blob(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_double(col int) double {
|
||||
return sqlite3_column_double(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_int(col int) int {
|
||||
return sqlite3_column_int(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_text(col int) +char {
|
||||
return sqlite3_column_text(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_text16(col int) void {
|
||||
return sqlite3_column_text16(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_value(col int) void {
|
||||
return sqlite3_column_value(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_bytes(col int) int {
|
||||
return sqlite3_column_bytes(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_bytes16(col int) int {
|
||||
return sqlite3_column_bytes16(this.obj, col);
|
||||
}
|
||||
|
||||
inline column_type(col int) int {
|
||||
return sqlite3_column_type(this.obj, col);
|
||||
}
|
||||
|
||||
func finalize() bool {
|
||||
if this.obj ~= null {
|
||||
if sqlite3_finalize(this.obj) ~= SQLITE_OK;
|
||||
return false;
|
||||
this.obj = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
|
||||
func exec(file. char, ap void) bool {
|
||||
import rt::c;
|
||||
var pid pid_t = fork();
|
||||
if pid == -1 {
|
||||
return false;
|
||||
elseif pid == 0;
|
||||
execvp(file, ap);
|
||||
return false;
|
||||
else
|
||||
wait(null);
|
||||
/*
|
||||
for some reasons.
|
||||
*/
|
||||
sleep(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
func exec2(cmd. char) bool {
|
||||
import rt::c;
|
||||
alias
|
||||
dmem = std::dmem,
|
||||
strings = std::strings;
|
||||
var args dmem;
|
||||
var strs strings;
|
||||
enum {
|
||||
mode_none,
|
||||
mode_word,
|
||||
mode_quote,
|
||||
mode_double_quote
|
||||
}
|
||||
var mode int = mode_none;
|
||||
var begin size_t;
|
||||
forvar index size_t = 0, count size_t = strlen(cmd); index < count; index++ {
|
||||
var c char = cmd[index];
|
||||
if c == ' ' or c == '\t' {
|
||||
if mode == mode_word {
|
||||
.args->alloc_t<char*>() =
|
||||
strs->add(cmd + begin, index - begin);
|
||||
mode = mode_none;
|
||||
}
|
||||
elseif c == '\'';
|
||||
if mode == mode_none {
|
||||
begin = index + 1;
|
||||
mode = mode_quote;
|
||||
elseif mode == mode_word;
|
||||
// fixme
|
||||
return false;
|
||||
elseif mode == mode_quote;
|
||||
.args->alloc_t<char*>() =
|
||||
strs->add(cmd + begin, index - begin);
|
||||
mode = mode_none;
|
||||
}
|
||||
elseif c == '\"';
|
||||
if mode == mode_none {
|
||||
begin = index + 1;
|
||||
mode = mode_double_quote;
|
||||
elseif mode == mode_word;
|
||||
// fixme
|
||||
return false;
|
||||
elseif mode == mode_double_quote;
|
||||
.args->alloc_t<char*>() =
|
||||
strs->add(cmd + begin, index - begin);
|
||||
mode = mode_none;
|
||||
}
|
||||
else
|
||||
if mode == mode_none {
|
||||
begin = index;
|
||||
mode = mode_word;
|
||||
}
|
||||
}
|
||||
}
|
||||
if mode == mode_word {
|
||||
.args->alloc_t<char*>() =
|
||||
strs->add(cmd + begin);
|
||||
}
|
||||
if strs->empty() {
|
||||
return false;
|
||||
}
|
||||
.args->alloc_t<char*>() = null;
|
||||
return exec(strs->first_item(), args.ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
fixme
|
||||
*/
|
||||
func exec3(window. game::window, text. char, cmd. char) bool {
|
||||
import lib::sdl2, game;
|
||||
define {
|
||||
PADDING = 10;
|
||||
}
|
||||
var render void = window->get_render();
|
||||
var font texture;
|
||||
font->init(global::uni_font->create_tex(render, text, 0xff000000));
|
||||
var width int = font->get_width();
|
||||
var height int = font->get_height();
|
||||
var rect SDL_Rect = 0;
|
||||
window->get_size(&rect.w, &rect.h);
|
||||
var sub_rect SDL_Rect;
|
||||
sub_rect.x = (rect.w - width) / 2 - PADDING;
|
||||
sub_rect.y = (rect.h - height) / 2 - PADDING;
|
||||
sub_rect.w = width + (PADDING * 2);
|
||||
sub_rect.h = height + (PADDING * 2);
|
||||
var screen texture;
|
||||
screen->init(window->screen_capture2());
|
||||
screen->draw(render, 0, 0);
|
||||
SDL_SetRenderDrawColor(render, 0xff, 0xff, 0xff, 0xff);
|
||||
SDL_RenderFillRect(render, &sub_rect);
|
||||
SDL_SetRenderDrawColor(render, 127, 127, 127, 0xff);
|
||||
SDL_RenderDrawRect(render, &sub_rect);
|
||||
font->draw(render,
|
||||
sub_rect.x + PADDING,
|
||||
sub_rect.y + PADDING);
|
||||
window->present();
|
||||
return exec2(cmd);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
func append_log(format. char, ...) {
|
||||
import rt::c;
|
||||
define {
|
||||
filename = "bean.log";
|
||||
}
|
||||
var stream void = fopen(filename, "a");
|
||||
if stream ~= null {
|
||||
vfprintf(stream, format, va_start(format));
|
||||
fclose(stream);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
/*
|
||||
slow
|
||||
*/
|
||||
func find_pid_by_cmdline(cmdline. char) int {
|
||||
import rt::c;
|
||||
alias string = std::string,
|
||||
strings = std::strings;
|
||||
var dir void = opendir("/proc");
|
||||
defer closedir(dir);
|
||||
using ent. struct_dirent {
|
||||
while (ent = readdir(dir)) ~= null {
|
||||
if ent.d_type == DT_DIR {
|
||||
if ent.d_name[0] == '.' and !ent.d_name[1] or
|
||||
ent.d_name[1] == '.' and !ent.d_name[2] {
|
||||
continue;
|
||||
}
|
||||
if isnumeric(&ent.d_name) {
|
||||
lambda pread(cmd. char, lines. strings) bool [
|
||||
var stream void = popen(cmd, "r");
|
||||
if stream == null;
|
||||
return false;
|
||||
defer fclose(stream);
|
||||
var line(0x200) char;
|
||||
while fgets(&line, 0x200, stream) ~= null;
|
||||
lines->add(&line);
|
||||
return true;
|
||||
];
|
||||
static cmd string;
|
||||
static lines strings;
|
||||
lines->clear();
|
||||
if pread(cmd->format("sudo cat /proc/%s/cmdline", &ent.d_name), &lines) {
|
||||
if !lines->empty() {
|
||||
if !strcmp(lines->first_item(), cmdline);
|
||||
return atoi(&ent.d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1,411 +0,0 @@
|
||||
|
||||
class wifi+ {
|
||||
|
||||
private import rt::c, lib::dbus;
|
||||
|
||||
struct wifi {
|
||||
conn void;
|
||||
err DBusError;
|
||||
wicd wicd;
|
||||
wicd_wl wicd_wl;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
this.conn = null;
|
||||
dbus_error_init(&this.err);
|
||||
}
|
||||
|
||||
func destructor() {
|
||||
dbus_error_free(&this.err);
|
||||
}
|
||||
|
||||
func init() bool {
|
||||
this.conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this.err);
|
||||
if dbus_error_is_set(&this.err);
|
||||
return false;
|
||||
this.wicd->init(this.conn);
|
||||
this.wicd_wl->init(this.conn);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
func get_signal_strength() int {
|
||||
var iwconfig. char = null;
|
||||
if this.wicd->needs_external_calls() {
|
||||
if (iwconfig = this.wicd_wl->get_iwconfig()) == null;
|
||||
return -1;
|
||||
iwconfig = strdup(iwconfig);
|
||||
}
|
||||
if this.wicd->get_signal_disply_type() == 0 {
|
||||
func = this.wicd_wl->get_cur_signal_strength(iwconfig);
|
||||
else
|
||||
func = this.wicd_wl->get_cur_dbm_strength(iwconfig);
|
||||
}
|
||||
if iwconfig ~= null;
|
||||
free(iwconfig);
|
||||
}
|
||||
|
||||
func is_connecting() bool {
|
||||
return this.wicd_wl->check_if_wireless_connecting();
|
||||
}
|
||||
|
||||
func is_connected(signal_strength. int = null) bool {
|
||||
if this.wicd_wl->check_if_wireless_connecting();
|
||||
return false;
|
||||
var x int = this->get_signal_strength();
|
||||
if x == -1;
|
||||
return false;
|
||||
if signal_strength ~= null;
|
||||
.signal_strength = x;
|
||||
return true;
|
||||
}
|
||||
|
||||
func scan(sync bool = false) {
|
||||
this.wicd_wl->scan(sync);
|
||||
}
|
||||
|
||||
func connect(id int) {
|
||||
this.wicd_wl->connect(id);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
inline get_sys_bus() void {
|
||||
return this.conn;
|
||||
}
|
||||
|
||||
inline get_bus_err() .DBusError {
|
||||
return &this.err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class wifi+, signal_thread {
|
||||
|
||||
private import rt::c, lib::dbus;
|
||||
|
||||
private alias
|
||||
string = std::string,
|
||||
vector = std::vector;
|
||||
|
||||
struct hook {
|
||||
iface. char;
|
||||
sig_name. char;
|
||||
callback void;
|
||||
arg void;
|
||||
}
|
||||
|
||||
struct signal_thread {
|
||||
thread pthread_t;
|
||||
wifi. wifi;
|
||||
hooks vector<hook>;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
this.thread = null;
|
||||
this.wifi = null;
|
||||
constructor(this);
|
||||
}
|
||||
|
||||
func destructor() {
|
||||
this->stop();
|
||||
destructor(this);
|
||||
}
|
||||
|
||||
func init(wifi. wifi) {
|
||||
this.wifi = wifi;
|
||||
}
|
||||
|
||||
/*
|
||||
callback = lambda(arg void, iter void) [
|
||||
...
|
||||
];
|
||||
*/
|
||||
func hook_signal(iface. char, sig_name. char, callback void, arg void) bool {
|
||||
if this.thread ~= null;
|
||||
return false;
|
||||
var conn void = this.wifi->get_sys_bus();
|
||||
var err void = this.wifi->get_bus_err();
|
||||
using rule string;
|
||||
dbus_bus_add_match(conn,
|
||||
rule->format("type='signal',interface='%s'", iface), err);
|
||||
dbus_connection_flush(conn);
|
||||
if dbus_error_is_set(err);
|
||||
return false;
|
||||
var hook. hook = this.hooks->new();
|
||||
hook.iface = iface;
|
||||
hook.sig_name = sig_name;
|
||||
hook.callback = callback;
|
||||
hook.arg = arg;
|
||||
return true;
|
||||
}
|
||||
|
||||
func start() bool {
|
||||
if this.thread ~= null;
|
||||
return true;
|
||||
if pthread_create(&this.thread, null, lambda(this.signal_thread) void [
|
||||
var conn void = this.wifi->get_sys_bus();
|
||||
while this.thread ~= null {
|
||||
for ;; {
|
||||
dbus_connection_read_write(conn, 0);
|
||||
var msg void = dbus_connection_pop_message(conn);
|
||||
if msg == null;
|
||||
break;
|
||||
forvar index size_t = 0, count size_t = this.hooks->count(); index < count; index++ {
|
||||
var hook. hook = this.hooks->at(index);
|
||||
if dbus_message_is_signal(msg, hook.iface, hook.sig_name) {
|
||||
var iter void;
|
||||
if !dbus_message_iter_init(msg, &iter);
|
||||
iter = null;
|
||||
proto fn(arg void, iter void);
|
||||
fn[hook.callback](hook.arg, iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
], this));
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
func stop() {
|
||||
var thread pthread_t = this.thread;
|
||||
if thread ~= null {
|
||||
this.thread = null;
|
||||
pthread_join(thread, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class wifi+, dbus {
|
||||
|
||||
private import lib::dbus;
|
||||
|
||||
struct dbus {
|
||||
conn void;
|
||||
bus_name. char;
|
||||
path. char;
|
||||
iface. char;
|
||||
}
|
||||
|
||||
func init(conn void, bus_name. char, path. char, iface. char) {
|
||||
this.conn = conn;
|
||||
this.bus_name = bus_name;
|
||||
this.path = path;
|
||||
this.iface = iface;
|
||||
}
|
||||
|
||||
func call(method. char, format. char = null, ...) void {
|
||||
var msg void = dbus_message_new_method_call(this.bus_name, this.path, this.iface, method);
|
||||
if msg == null;
|
||||
return null;
|
||||
defer dbus_message_unref(msg);
|
||||
if format ~= null {
|
||||
var args DBusMessageIter;
|
||||
dbus_message_iter_init_append(msg, &args);
|
||||
forvar ap void = va_start(this) ;; {
|
||||
var type char = .format++;
|
||||
if !type;
|
||||
break;
|
||||
if !dbus_message_iter_append_basic(&args, type, ap);
|
||||
return null;
|
||||
va_next<word>(ap);
|
||||
}
|
||||
}
|
||||
if !dbus_connection_send_with_reply(this.conn, msg, &func, -1);
|
||||
return null;
|
||||
if func ~= null;
|
||||
dbus_connection_flush(this.conn);
|
||||
}
|
||||
|
||||
static func get(pending void, format. char = null, ...) bool {
|
||||
if pending == null;
|
||||
return false;
|
||||
dbus_pending_call_block(pending);
|
||||
var msg void = dbus_pending_call_steal_reply(pending);
|
||||
dbus_pending_call_unref(pending);
|
||||
if msg == null;
|
||||
return false;
|
||||
defer dbus_message_unref(msg);
|
||||
if format ~= null {
|
||||
var args DBusMessageIter;
|
||||
if dbus_message_iter_init(msg, &args) {
|
||||
forvar ap. void = va_start(pending) ;; {
|
||||
var type char = .format++;
|
||||
if !type;
|
||||
break;
|
||||
if dbus_message_iter_get_arg_type(&args) ~= type;
|
||||
return false;
|
||||
dbus_message_iter_get_basic(&args, .ap);
|
||||
if !dbus_message_iter_next(&args);
|
||||
break;
|
||||
va_next<void>(ap);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class wifi+, wicd {
|
||||
|
||||
private import lib::dbus;
|
||||
|
||||
struct wicd {
|
||||
bus dbus;
|
||||
}
|
||||
|
||||
func init(conn void) {
|
||||
this.bus->init(conn,
|
||||
"org.wicd.daemon", "/org/wicd/daemon",
|
||||
"org.wicd.daemon");
|
||||
}
|
||||
|
||||
func format_signal_for_printing(signal int) .char {
|
||||
func = null;
|
||||
this.bus->get(
|
||||
this.bus->call("FormatSignalForPrinting", "i", signal), "s", &func);
|
||||
}
|
||||
|
||||
func get_signal_disply_type() int {
|
||||
func = -1;
|
||||
this.bus->get(
|
||||
this.bus->call("GetSignalDisplayType"), "i", &func);
|
||||
}
|
||||
|
||||
func needs_external_calls() dbus_bool_t {
|
||||
func = 0;
|
||||
this.bus->get(
|
||||
this.bus->call("NeedsExternalCalls"), "b", &func);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class wifi+, wicd_wl {
|
||||
|
||||
private import lib::dbus;
|
||||
|
||||
struct wicd_wl {
|
||||
bus dbus;
|
||||
}
|
||||
|
||||
func init(conn void) {
|
||||
this.bus->init(conn,
|
||||
"org.wicd.daemon", "/org/wicd/daemon/wireless",
|
||||
"org.wicd.daemon.wireless");
|
||||
}
|
||||
|
||||
func check_if_wireless_connecting() dbus_bool_t {
|
||||
func = 0;
|
||||
this.bus->get(
|
||||
this.bus->call("CheckIfWirelessConnecting"), "b", &func);
|
||||
}
|
||||
|
||||
func check_wireless_connecting_msg() .char {
|
||||
func = null;
|
||||
this.bus->get(
|
||||
this.bus->call("CheckWirelessConnectingMessage"), "s", &func);
|
||||
}
|
||||
|
||||
// result?
|
||||
func connect(id int) {
|
||||
this.bus->get(
|
||||
this.bus->call("ConnectWireless", "i", id));
|
||||
}
|
||||
|
||||
func get_cur_dbm_strength(iwconfig. char) int {
|
||||
func = -1;
|
||||
var pending void;
|
||||
if iwconfig == null {
|
||||
pending = this.bus->call("GetCurrentDBMStrength");
|
||||
else
|
||||
pending = this.bus->call("GetCurrentDBMStrength", "s", iwconfig);
|
||||
}
|
||||
this.bus->get(pending, "i", &func);
|
||||
}
|
||||
|
||||
func get_cur_signal_strength(iwconfig. char) int {
|
||||
func = -1;
|
||||
var pending void;
|
||||
if iwconfig == null {
|
||||
pending = this.bus->call("GetCurrentSignalStrength");
|
||||
else
|
||||
pending = this.bus->call("GetCurrentSignalStrength", "s", iwconfig);
|
||||
}
|
||||
this.bus->get(pending, "i", &func);
|
||||
}
|
||||
|
||||
func get_cur_network(iwconfig. char) .char {
|
||||
func = null;
|
||||
var pending void;
|
||||
if iwconfig == null {
|
||||
pending = this.bus->call("GetCurrentNetwork");
|
||||
else
|
||||
pending = this.bus->call("GetCurrentNetwork", "s", iwconfig);
|
||||
}
|
||||
this.bus->get(pending, "s", &func);
|
||||
}
|
||||
|
||||
func get_cur_network_id(iwconfig. char) int {
|
||||
func = -1;
|
||||
var pending void;
|
||||
if iwconfig == null {
|
||||
pending = this.bus->call("GetCurrentNetworkID");
|
||||
else
|
||||
pending = this.bus->call("GetCurrentNetworkID", "s", iwconfig);
|
||||
}
|
||||
this.bus->get(pending, "i", &func);
|
||||
}
|
||||
|
||||
func get_iwconfig() .char {
|
||||
func = null;
|
||||
this.bus->get(
|
||||
this.bus->call("GetIwconfig"), "s", &func);
|
||||
}
|
||||
|
||||
func get_num_of_networks() int {
|
||||
func = -1;
|
||||
this.bus->get(
|
||||
this.bus->call("GetNumberOfNetworks"), "i", &func);
|
||||
}
|
||||
|
||||
func get_wireless_ip(s. char) .char {
|
||||
func = null;
|
||||
var pending void;
|
||||
if s == null {
|
||||
pending = this.bus->call("GetWirelessIP");
|
||||
else
|
||||
pending = this.bus->call("GetWirelessIP", "s", s);
|
||||
}
|
||||
this.bus->get(pending, "s", &func);
|
||||
}
|
||||
|
||||
func get_wireless_prop(id int, prop_name. char) .char {
|
||||
func = null;
|
||||
this.bus->get(
|
||||
this.bus->call("GetWirelessProperty", "is", id, prop_name), "s", &func);
|
||||
}
|
||||
|
||||
// result?
|
||||
func scan(sync dbus_bool_t) {
|
||||
this.bus->get(
|
||||
this.bus->call("Scan", "b", sync));
|
||||
}
|
||||
|
||||
func set_wireless_prop_str(id int, prop_name. char, s. char) bool {
|
||||
return this.bus->get(
|
||||
this.bus->call("SetWirelessProperty", "iss", id, prop_name, s));
|
||||
}
|
||||
|
||||
func set_wireless_prop_int(id int, prop_name. char, i int) bool {
|
||||
return this.bus->get(
|
||||
this.bus->call("SetWirelessProperty", "isi", id, prop_name, i));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user