removed STD archeus, moved console and ssh into linux folder. also added libdbus
This commit is contained in:
parent
119d1b2c64
commit
8fe402e04e
27 changed files with 622 additions and 145 deletions
147
packages/linux/console/ncurses/buffer.c
Normal file
147
packages/linux/console/ncurses/buffer.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include "arc/console/buffer.h"
|
||||
|
||||
#include "arc/console/view.h"
|
||||
#include "arc/std/string.h"
|
||||
#include "arc/std/vector.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct ARC_ConsoleBuffer {
|
||||
ARC_Vector *bufferLines;
|
||||
};
|
||||
|
||||
void ARC_ConsoleBuffer_Create(ARC_ConsoleBuffer **buffer){
|
||||
*buffer = (ARC_ConsoleBuffer *)malloc(sizeof(ARC_ConsoleBuffer));
|
||||
|
||||
ARC_Vector_Create(&((*buffer)->bufferLines));
|
||||
|
||||
//add first line to vector
|
||||
ARC_Vector_Add((*buffer)->bufferLines, NULL);
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_Destroy(ARC_ConsoleBuffer *buffer){
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(buffer->bufferLines); i++){
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i);
|
||||
|
||||
if(bufferLine != NULL){
|
||||
ARC_String_Destroy(bufferLine);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Vector_Destroy(buffer->bufferLines);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_Clear(ARC_ConsoleBuffer *buffer){
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(buffer->bufferLines); i++){
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i);
|
||||
|
||||
if(bufferLine != NULL){
|
||||
ARC_String_Destroy(bufferLine);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Vector_Destroy(buffer->bufferLines);
|
||||
ARC_Vector_Create(&(buffer->bufferLines));
|
||||
|
||||
//add first line to vector
|
||||
ARC_Vector_Add(buffer->bufferLines, NULL);
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_Render(ARC_ConsoleBuffer *buffer, ARC_ConsoleView *view){
|
||||
ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view);
|
||||
|
||||
uint32_t bufferStartIndex = 0;
|
||||
if(ARC_Vector_Size(buffer->bufferLines) > (uint32_t)viewBounds.h){
|
||||
bufferStartIndex = ARC_Vector_Size(buffer->bufferLines) - viewBounds.h;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < (uint32_t)viewBounds.h; i++){
|
||||
if(i + bufferStartIndex > ARC_Vector_Size(buffer->bufferLines)){
|
||||
break;
|
||||
}
|
||||
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i + bufferStartIndex);
|
||||
if(bufferLine == NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
ARC_ConsoleView_RenderStringAt(view, bufferLine, (ARC_Point){ 0, i });
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_RenderSection(ARC_ConsoleBuffer *buffer, ARC_ConsoleView *view, uint32_t startIndex, uint32_t lines){
|
||||
ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view);
|
||||
|
||||
for(uint32_t i = 0; i < lines; i++){
|
||||
if(i + startIndex >= ARC_Vector_Size(buffer->bufferLines)){
|
||||
break;
|
||||
}
|
||||
|
||||
if(i >= (uint32_t)viewBounds.h){
|
||||
break;
|
||||
}
|
||||
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i + startIndex);
|
||||
if(bufferLine == NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
ARC_ConsoleView_RenderStringAt(view, bufferLine, (ARC_Point){ 0, i });
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_AddChar(ARC_ConsoleBuffer *buffer, char character){
|
||||
if(character == '\n'){
|
||||
ARC_Vector_Add(buffer->bufferLines, (void *)NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
//get the last line and add a char to it
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, ARC_Vector_Size(buffer->bufferLines) - 1);
|
||||
ARC_Vector_RemoveIndex(buffer->bufferLines, ARC_Vector_Size(buffer->bufferLines) - 1);
|
||||
|
||||
if(bufferLine == NULL){
|
||||
ARC_String_Create(&bufferLine, &character, 1);
|
||||
ARC_Vector_Add(buffer->bufferLines, (void *)bufferLine);
|
||||
return;
|
||||
}
|
||||
|
||||
//add char to the end of the bufferline
|
||||
ARC_String *nextChar;
|
||||
ARC_String_Create(&nextChar, &character, 1);
|
||||
|
||||
ARC_String *tempBufferLine = bufferLine;
|
||||
ARC_String_Merge(&bufferLine, tempBufferLine, nextChar);
|
||||
|
||||
ARC_String_Destroy(tempBufferLine);
|
||||
ARC_String_Destroy(nextChar);
|
||||
|
||||
//add buffer line back to the bufferLines
|
||||
ARC_Vector_Add(buffer->bufferLines, (void *)bufferLine);
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_AddString(ARC_ConsoleBuffer *buffer, ARC_String *string){
|
||||
//TODO: this in a more efficient way
|
||||
for(uint64_t i = 0; i < string->length; i++){
|
||||
ARC_ConsoleBuffer_AddChar(buffer, string->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_AddCString(ARC_ConsoleBuffer *buffer, char *cstring, uint64_t length){
|
||||
//TODO: this in a more efficient way
|
||||
for(uint64_t i = 0; i < length; i++){
|
||||
ARC_ConsoleBuffer_AddChar(buffer, cstring[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleBuffer_AddCStringWithStrlen(ARC_ConsoleBuffer *buffer, char *cstring){
|
||||
//TODO: this in a more efficient way
|
||||
for(uint64_t i = 0; i < strlen(cstring); i++){
|
||||
ARC_ConsoleBuffer_AddChar(buffer, cstring[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ARC_ConsoleBuffer_GetLineNumbers(ARC_ConsoleBuffer *buffer){
|
||||
return ARC_Vector_Size(buffer->bufferLines);
|
||||
}
|
||||
52
packages/linux/console/ncurses/element.c
Normal file
52
packages/linux/console/ncurses/element.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include "arc/console/element.h"
|
||||
#include "arc/console/view.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
void ARC_ConsoleElement_Create(ARC_ConsoleElement **element, uint32_t type, uint8_t flags, ARC_String *string, ARC_Point pos, ARC_ConsoleElement_RenderFn renderFn){
|
||||
*element = (ARC_ConsoleElement *)malloc(sizeof(ARC_ConsoleElement));
|
||||
|
||||
(*element)->type = type;
|
||||
(*element)->flags = flags;
|
||||
(*element)->string = string;
|
||||
(*element)->pos = pos;
|
||||
(*element)->renderFn = renderFn;
|
||||
}
|
||||
|
||||
void ARC_ConsoleElement_Destroy(ARC_ConsoleElement *element){
|
||||
free(element);
|
||||
}
|
||||
|
||||
void ARC_ConsoleElement_DefaultRenderFn(ARC_ConsoleView *view, ARC_ConsoleElement *element){
|
||||
if(element->flags & ARC_CONSOLE_ELEMENT_FLAG_SELECTED){
|
||||
ARC_ConsoleView_SetAttribute(view, ARC_CONSOLE_VIEW_ATTRIBUTE_REVERSE);
|
||||
}
|
||||
|
||||
ARC_ConsoleView_RenderStringAt(view, element->string, element->pos);
|
||||
|
||||
if(element->flags & ARC_CONSOLE_ELEMENT_FLAG_SELECTED){
|
||||
ARC_ConsoleView_SetAttribute(view, ARC_CONSOLE_VIEW_ATTRIBUTE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Bool ARC_ConsoleElement_IsSelectable(ARC_ConsoleElement *element){
|
||||
if(element->flags & ARC_CONSOLE_ELEMENT_FLAG_SELECTABLE){
|
||||
return ARC_True;
|
||||
}
|
||||
|
||||
return ARC_False;
|
||||
}
|
||||
|
||||
void ARC_ConsoleElement_SetSelected(ARC_ConsoleElement *element, ARC_Bool selected){
|
||||
if(selected){
|
||||
element->flags |= ARC_CONSOLE_ELEMENT_FLAG_SELECTED;
|
||||
return;
|
||||
}
|
||||
|
||||
element->flags &= ~ARC_CONSOLE_ELEMENT_FLAG_SELECTED;
|
||||
}
|
||||
|
||||
void ARC_NCursesElement_ToggleSelected(ARC_ConsoleElement *element){
|
||||
element->flags ^= ARC_CONSOLE_ELEMENT_FLAG_SELECTED;
|
||||
}
|
||||
171
packages/linux/console/ncurses/key.c
Normal file
171
packages/linux/console/ncurses/key.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#include "arc/console/key.h"
|
||||
#include "key.h"
|
||||
#include "arc/std/bool.h"
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void ARC_ConsoleKey_Create(ARC_ConsoleKey **consoleKey, ARC_ConsoleKey_Key *key){
|
||||
*consoleKey = (ARC_ConsoleKey *)malloc(sizeof(ARC_ConsoleKey));
|
||||
(*consoleKey)->key = 0;
|
||||
|
||||
if(key != NULL){
|
||||
(*consoleKey)->key = *key;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleKey_Destroy(ARC_ConsoleKey *consoleKey){
|
||||
free(consoleKey);
|
||||
}
|
||||
|
||||
ARC_Bool ARC_ConsoleKey_Equals(ARC_ConsoleKey consoleKey, ARC_ConsoleKey_Key key){
|
||||
return consoleKey.key == ARC_Keyboard_GetConsoleKey(key).key;
|
||||
}
|
||||
|
||||
ARC_Bool ARC_ConsoleKey_EqualsPointer(ARC_ConsoleKey *consoleKey, ARC_ConsoleKey_Key key){
|
||||
return consoleKey->key == ARC_Keyboard_GetConsoleKey(key).key;
|
||||
}
|
||||
|
||||
ARC_ConsoleKey ARC_Keyboard_GetConsoleKey(enum ARC_ConsoleKey_Key key){
|
||||
switch(key){
|
||||
case ARC_CONSOLE_KEY_A:
|
||||
return (ARC_ConsoleKey){ (int32_t)'a' };
|
||||
|
||||
case ARC_CONSOLE_KEY_B:
|
||||
return (ARC_ConsoleKey){ (int32_t)'b' };
|
||||
|
||||
case ARC_CONSOLE_KEY_C:
|
||||
return (ARC_ConsoleKey){ (int32_t)'c' };
|
||||
|
||||
case ARC_CONSOLE_KEY_D:
|
||||
return (ARC_ConsoleKey){ (int32_t)'d' };
|
||||
|
||||
case ARC_CONSOLE_KEY_E:
|
||||
return (ARC_ConsoleKey){ (int32_t)'e' };
|
||||
|
||||
case ARC_CONSOLE_KEY_F:
|
||||
return (ARC_ConsoleKey){ (int32_t)'f' };
|
||||
|
||||
case ARC_CONSOLE_KEY_G:
|
||||
return (ARC_ConsoleKey){ (int32_t)'g' };
|
||||
|
||||
case ARC_CONSOLE_KEY_H:
|
||||
return (ARC_ConsoleKey){ (int32_t)'h' };
|
||||
|
||||
case ARC_CONSOLE_KEY_I:
|
||||
return (ARC_ConsoleKey){ (int32_t)'i' };
|
||||
|
||||
case ARC_CONSOLE_KEY_J:
|
||||
return (ARC_ConsoleKey){ (int32_t)'j' };
|
||||
|
||||
case ARC_CONSOLE_KEY_K:
|
||||
return (ARC_ConsoleKey){ (int32_t)'k' };
|
||||
|
||||
case ARC_CONSOLE_KEY_L:
|
||||
return (ARC_ConsoleKey){ (int32_t)'l' };
|
||||
|
||||
case ARC_CONSOLE_KEY_M:
|
||||
return (ARC_ConsoleKey){ (int32_t)'m' };
|
||||
|
||||
case ARC_CONSOLE_KEY_N:
|
||||
return (ARC_ConsoleKey){ (int32_t)'n' };
|
||||
|
||||
case ARC_CONSOLE_KEY_O:
|
||||
return (ARC_ConsoleKey){ (int32_t)'o' };
|
||||
|
||||
case ARC_CONSOLE_KEY_P:
|
||||
return (ARC_ConsoleKey){ (int32_t)'p' };
|
||||
|
||||
case ARC_CONSOLE_KEY_Q:
|
||||
return (ARC_ConsoleKey){ (int32_t)'q' };
|
||||
|
||||
case ARC_CONSOLE_KEY_R:
|
||||
return (ARC_ConsoleKey){ (int32_t)'r' };
|
||||
|
||||
case ARC_CONSOLE_KEY_S:
|
||||
return (ARC_ConsoleKey){ (int32_t)'s' };
|
||||
|
||||
case ARC_CONSOLE_KEY_T:
|
||||
return (ARC_ConsoleKey){ (int32_t)'t' };
|
||||
|
||||
case ARC_CONSOLE_KEY_U:
|
||||
return (ARC_ConsoleKey){ (int32_t)'u' };
|
||||
|
||||
case ARC_CONSOLE_KEY_V:
|
||||
return (ARC_ConsoleKey){ (int32_t)'v' };
|
||||
|
||||
case ARC_CONSOLE_KEY_W:
|
||||
return (ARC_ConsoleKey){ (int32_t)'w' };
|
||||
|
||||
case ARC_CONSOLE_KEY_X:
|
||||
return (ARC_ConsoleKey){ (int32_t)'x' };
|
||||
|
||||
case ARC_CONSOLE_KEY_Y:
|
||||
return (ARC_ConsoleKey){ (int32_t)'y' };
|
||||
|
||||
case ARC_CONSOLE_KEY_Z:
|
||||
return (ARC_ConsoleKey){ (int32_t)'z' };
|
||||
|
||||
case ARC_CONSOLE_KEY_0:
|
||||
return (ARC_ConsoleKey){ (int32_t)'0' };
|
||||
|
||||
case ARC_CONSOLE_KEY_1:
|
||||
return (ARC_ConsoleKey){ (int32_t)'1' };
|
||||
|
||||
case ARC_CONSOLE_KEY_2:
|
||||
return (ARC_ConsoleKey){ (int32_t)'2' };
|
||||
|
||||
case ARC_CONSOLE_KEY_3:
|
||||
return (ARC_ConsoleKey){ (int32_t)'3' };
|
||||
|
||||
case ARC_CONSOLE_KEY_4:
|
||||
return (ARC_ConsoleKey){ (int32_t)'4' };
|
||||
|
||||
case ARC_CONSOLE_KEY_5:
|
||||
return (ARC_ConsoleKey){ (int32_t)'5' };
|
||||
|
||||
case ARC_CONSOLE_KEY_6:
|
||||
return (ARC_ConsoleKey){ (int32_t)'6' };
|
||||
|
||||
case ARC_CONSOLE_KEY_7:
|
||||
return (ARC_ConsoleKey){ (int32_t)'7' };
|
||||
|
||||
case ARC_CONSOLE_KEY_8:
|
||||
return (ARC_ConsoleKey){ (int32_t)'8' };
|
||||
|
||||
case ARC_CONSOLE_KEY_9:
|
||||
return (ARC_ConsoleKey){ (int32_t)'9' };
|
||||
|
||||
case ARC_CONSOLE_KEY_UP:
|
||||
return (ARC_ConsoleKey){ KEY_UP };
|
||||
|
||||
case ARC_CONSOLE_KEY_DOWN:
|
||||
return (ARC_ConsoleKey){ KEY_DOWN };
|
||||
|
||||
case ARC_CONSOLE_KEY_LEFT:
|
||||
return (ARC_ConsoleKey){ KEY_LEFT };
|
||||
|
||||
case ARC_CONSOLE_KEY_RIGHT:
|
||||
return (ARC_ConsoleKey){ KEY_RIGHT };
|
||||
|
||||
case ARC_CONSOLE_KEY_FORWARD_SLASH:
|
||||
return (ARC_ConsoleKey){ (int32_t)'/' };
|
||||
|
||||
case ARC_CONSOLE_KEY_BACKSPACE:
|
||||
return (ARC_ConsoleKey){ KEY_BACKSPACE };
|
||||
|
||||
//TODO: This should probs be KEY_ENTER, but idk why it wasn't working
|
||||
case ARC_CONSOLE_KEY_ENTER:
|
||||
return (ARC_ConsoleKey){ 10 };
|
||||
|
||||
//TODO: This is escape and alt, need to fix
|
||||
case ARC_CONSOLE_KEY_ESC:
|
||||
return (ARC_ConsoleKey){ 27 };
|
||||
|
||||
default:
|
||||
return (ARC_ConsoleKey){ 0 };
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ARC_ConsoleKey_GetCharFromKey(ARC_ConsoleKey *consoleKey){
|
||||
return consoleKey->key;
|
||||
}
|
||||
19
packages/linux/console/ncurses/key.h
Normal file
19
packages/linux/console/ncurses/key.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef ARC_CONSOLE_NCURSES_KEY_H_
|
||||
#define ARC_CONSOLE_NCURSES_KEY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "arc/console/key.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct ARC_ConsoleKeyType {
|
||||
int32_t key;
|
||||
} ARC_ConsoleKeyType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !ARC_CONSOLE_NCURSES_KEY_H_
|
||||
57
packages/linux/console/ncurses/shell.c
Normal file
57
packages/linux/console/ncurses/shell.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include "arc/console/shell.h"
|
||||
|
||||
#include "arc/console/buffer.h"
|
||||
#include "arc/std/string.h"
|
||||
#include "arc/std/vector.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void ARC_ConsoleShell_Create(ARC_ConsoleShell **shell, ARC_ConsoleView *view, ARC_ConsoleShell_UpdateFn updateFn){
|
||||
*shell = (ARC_ConsoleShell *)malloc(sizeof(ARC_ConsoleShell));
|
||||
|
||||
(*shell)->view = view;
|
||||
ARC_ConsoleBuffer_Create(&((*shell)->buffer));
|
||||
(*shell)->bufferLineIndex = 0;
|
||||
|
||||
ARC_Vector_Create(&((*shell)->history));
|
||||
(*shell)->historyIndex = 0;
|
||||
|
||||
(*shell)->updateFn = updateFn;
|
||||
(*shell)->currentLine = NULL;
|
||||
(*shell)->userInput = NULL;
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_Destroy(ARC_ConsoleShell *shell){
|
||||
ARC_ConsoleBuffer_Destroy(shell->buffer);
|
||||
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(shell->history); i++){
|
||||
ARC_String *temp = (ARC_String *)ARC_Vector_Get(shell->history, i);
|
||||
|
||||
if(temp != NULL){
|
||||
ARC_String_Destroy(temp);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Vector_Destroy(shell->history);
|
||||
free(shell);
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_Update(ARC_ConsoleShell *shell){
|
||||
shell->updateFn(shell);
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_Render(ARC_ConsoleShell *shell){
|
||||
ARC_ConsoleBuffer_Render(shell->buffer, shell->view);
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_AddHistory(ARC_ConsoleShell *shell, ARC_String *string){
|
||||
ARC_Vector_Add(shell->history, (void *)string);
|
||||
}
|
||||
|
||||
ARC_String *ARC_ConsoleShell_GetHistoryAt(ARC_ConsoleShell *shell, uint32_t index){
|
||||
uint32_t maxHistory = ARC_Vector_Size(shell->history);
|
||||
if(index >= maxHistory){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (ARC_String *)ARC_Vector_Get(shell->history, (maxHistory - 1) - index);
|
||||
}
|
||||
268
packages/linux/console/ncurses/view.c
Normal file
268
packages/linux/console/ncurses/view.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
#include "arc/console/view.h"
|
||||
|
||||
#include "key.h"
|
||||
#include "arc/console/element.h"
|
||||
#include "arc/std/bool.h"
|
||||
#include "arc/std/errno.h"
|
||||
#include "arc/std/vector.h"
|
||||
#include "arc/std/string.h"
|
||||
#include <locale.h>
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint8_t arc_ncurses_win_size = 0;
|
||||
|
||||
struct ARC_ConsoleView {
|
||||
WINDOW *window;
|
||||
ARC_Rect bounds;
|
||||
ARC_Bool echo;
|
||||
|
||||
ARC_Vector *elements;
|
||||
};
|
||||
|
||||
void ARC_ConsoleView_Create(ARC_ConsoleView **view, ARC_Rect bounds){
|
||||
if(arc_ncurses_win_size == ~(uint8_t)0){
|
||||
arc_errno = ARC_ERRNO_OVERFLOW;
|
||||
ARC_DEBUG_ERR("ARC_NCurses_Create(ncurses), max num of ARC_NCurses have been created, consider making arc_ncurses_win_size a uint32_t to increase the max");
|
||||
*view = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
//if this is the first ncurses, init ncurses
|
||||
if(arc_ncurses_win_size == 0){
|
||||
setlocale(LC_ALL, "");
|
||||
initscr();
|
||||
//start_color();
|
||||
cbreak();
|
||||
keypad(stdscr, TRUE);
|
||||
refresh();
|
||||
}
|
||||
|
||||
*view = (ARC_ConsoleView *)malloc(sizeof(ARC_ConsoleView));
|
||||
|
||||
ARC_Rect viewBounds = { 0, 0, COLS, LINES };
|
||||
if(bounds.w != 0 && bounds.h != 0){
|
||||
viewBounds = bounds;
|
||||
}
|
||||
|
||||
(*view)->window = newwin(viewBounds.h, viewBounds.w, viewBounds.y, viewBounds.x);
|
||||
(*view)->bounds = viewBounds;
|
||||
|
||||
keypad((*view)->window, TRUE);
|
||||
|
||||
noecho();
|
||||
(*view)->echo = false;
|
||||
|
||||
ARC_Vector_Create(&(*view)->elements);
|
||||
|
||||
wrefresh((*view)->window);
|
||||
|
||||
arc_ncurses_win_size++;
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_Destroy(ARC_ConsoleView *ncurses){
|
||||
arc_ncurses_win_size--;
|
||||
|
||||
ARC_Vector_Destroy(ncurses->elements);
|
||||
|
||||
delwin(ncurses->window);
|
||||
free(ncurses);
|
||||
|
||||
if(arc_ncurses_win_size == 0){
|
||||
endwin();
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_AddElement(ARC_ConsoleView *view, ARC_ConsoleElement *element){
|
||||
ARC_Vector_Add(view->elements, (void *)element);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RemoveElement(ARC_ConsoleView *view, uint32_t index){
|
||||
ARC_Vector_RemoveIndex(view->elements, index);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_Clear(ARC_ConsoleView *view){
|
||||
wclear(view->window);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderCharAt(ARC_ConsoleView *view, char character, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%c", character);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderWCharAt(ARC_ConsoleView *view, wchar_t character, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%lc", character);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderKeyAt(ARC_ConsoleView *view, ARC_ConsoleKey key, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%c", (char)key.key);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderUint32At(ARC_ConsoleView *view, uint32_t uint32, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%d", uint32);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderStringAt(ARC_ConsoleView *view, ARC_String *text, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%s", text->data);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderCStringWithStrlenAt(ARC_ConsoleView *view, char *cstr, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%s", cstr);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderRect(ARC_ConsoleView *view, ARC_Rect bounds){
|
||||
//render corners
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'┌', (ARC_Point){ bounds.x, bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'└', (ARC_Point){ bounds.x, (bounds.h - 1) + bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'┐', (ARC_Point){ (bounds.w - 1) + bounds.x, bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'┘', (ARC_Point){ (bounds.w - 1) + bounds.x, (bounds.h - 1) + bounds.y });
|
||||
|
||||
//render virticle lines
|
||||
for(int32_t x = 1; x < bounds.w - 1; x++){
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'─', (ARC_Point){ bounds.x + x, bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'─', (ARC_Point){ bounds.x + x, (bounds.h - 1) + bounds.y });
|
||||
}
|
||||
|
||||
//render horizontal lines
|
||||
for(int32_t y = 1; y < bounds.h - 1; y++){
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'│', (ARC_Point){ bounds.x, bounds.y + y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'│', (ARC_Point){ (bounds.w - 1) + bounds.x, bounds.y + y });
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderElements(ARC_ConsoleView *view){
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(view->elements); i++){
|
||||
ARC_ConsoleElement *element = (ARC_ConsoleElement *)ARC_Vector_Get(view->elements, i);
|
||||
element->renderFn(view, element);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Rect ARC_ConsoleView_GetBounds(ARC_ConsoleView *view){
|
||||
return view->bounds;
|
||||
}
|
||||
|
||||
ARC_ConsoleElement *ARC_ConsoleView_GetElement(ARC_ConsoleView *view, uint32_t index){
|
||||
return (ARC_ConsoleElement *)ARC_Vector_Get(view->elements, index);
|
||||
}
|
||||
|
||||
char ARC_ConsoleView_GetChar(ARC_ConsoleView *view){
|
||||
return wgetch(view->window);
|
||||
}
|
||||
|
||||
char ARC_ConsoleView_GetCharAt(ARC_ConsoleView *view, ARC_Point pos){
|
||||
return mvwgetch(view->window, pos.y, pos.x);
|
||||
}
|
||||
|
||||
ARC_ConsoleKey ARC_ConsoleView_GetConsoleKeyAt(ARC_ConsoleView *view, ARC_Point pos){
|
||||
return (ARC_ConsoleKey){ mvwgetch(view->window, pos.y, pos.x) };
|
||||
}
|
||||
|
||||
ARC_ConsoleKey *ARC_ConsoleView_GetCreateConsoleKeyAt(ARC_ConsoleView *view, ARC_Point pos){
|
||||
ARC_ConsoleKey *key;
|
||||
ARC_ConsoleKey_Create(&key, NULL);
|
||||
key->key = mvwgetch(view->window, pos.y, pos.x);
|
||||
return key;
|
||||
}
|
||||
|
||||
ARC_String *ARC_ConsoleView_GetStringInput(ARC_ConsoleView *view, ARC_Point pos, ARC_ConsoleView_OverrideCharInputFn *overrideCharInputFn, void *userdata){
|
||||
noecho();
|
||||
|
||||
uint32_t cstringSize = view->bounds.w - pos.x;
|
||||
char cstring[view->bounds.w - pos.x];
|
||||
|
||||
ARC_ConsoleKey temp = ARC_ConsoleView_GetConsoleKeyAt(view, pos);
|
||||
uint32_t index = 0;
|
||||
while(temp.key != '\n'){
|
||||
//store the last size to be able to clear efficeintly
|
||||
uint32_t lastSize = index;
|
||||
|
||||
//if override function exists and it overrode the current char
|
||||
if(overrideCharInputFn != NULL && (*overrideCharInputFn)(&temp, cstring, &index, cstringSize, userdata)){
|
||||
for(uint32_t i = 0; i < lastSize; i++){
|
||||
ARC_ConsoleView_RenderCharAt(view, ' ', (ARC_Point){ pos.x + i, pos.y });
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < index; i++){
|
||||
ARC_ConsoleView_RenderCharAt(view, cstring[i], (ARC_Point){ pos.x + i, pos.y });
|
||||
}
|
||||
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
continue;
|
||||
}
|
||||
|
||||
if(temp.key == KEY_BACKSPACE || temp.key == KEY_DC || temp.key == 127){
|
||||
if(index == 0){
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
continue;
|
||||
}
|
||||
|
||||
index--;
|
||||
ARC_ConsoleView_RenderCharAt(view, ' ', (ARC_Point){ pos.x + index, pos.y });
|
||||
cstring[index] = '\0';
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
continue;
|
||||
}
|
||||
|
||||
if(index < (view->bounds.w - 1) - pos.x){
|
||||
ARC_ConsoleView_RenderCharAt(view, (char)(temp.key), (ARC_Point){ pos.x + index, pos.y });
|
||||
cstring[index] = (char)(temp.key);
|
||||
index++;
|
||||
}
|
||||
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
}
|
||||
|
||||
if(view->echo){
|
||||
echo();
|
||||
}
|
||||
|
||||
if(index == 0){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ARC_String *string;
|
||||
ARC_String_Create(&string, cstring, index);
|
||||
return string;
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_SetCursorVisibility(ARC_ConsoleView *view, uint8_t visibility){
|
||||
switch(visibility){
|
||||
case ARC_CONSOLE_VIEW_CURSOR_HIDDEN:
|
||||
curs_set(0);
|
||||
break;
|
||||
case ARC_CONSOLE_VIEW_CURSOR_VISIBLE:
|
||||
curs_set(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_SetBorder(ARC_ConsoleView *view, uint32_t border){
|
||||
switch(border){
|
||||
case ARC_CONSOLE_VIEW_BORDER_NONE:
|
||||
wborder(view->window, ' ', ' ', ' ',' ',' ',' ',' ',' ');
|
||||
break;
|
||||
case ARC_CONSOLE_VIEW_BORDER_DEFAULT:
|
||||
box(view->window, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_SetAttribute(ARC_ConsoleView *view, uint32_t attribute){
|
||||
switch(attribute){
|
||||
case ARC_CONSOLE_VIEW_ATTRIBUTE_NONE:
|
||||
wattroff(view->window, A_REVERSE);
|
||||
break;
|
||||
case ARC_CONSOLE_VIEW_ATTRIBUTE_REVERSE:
|
||||
wattron(view->window, A_REVERSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
292
packages/linux/dbus/libdbus/dbus.c
Normal file
292
packages/linux/dbus/libdbus/dbus.c
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
#include "arc/linux/dbus/dbus.h"
|
||||
#include "arc/linux/dbus/helpers.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *handleCStr = "ARC_Controller";
|
||||
static const char *sessionHandleCStr = "arc_controller";
|
||||
|
||||
static const char *busNameCStr = "org.freedesktop.portal.Desktop";
|
||||
static const char *requestInterfaceCStr = "org.freedesktop.portal.Request";
|
||||
static const char *shortcutInterfaceCStr = "org.freedesktop.portal.GlobalShortcuts";
|
||||
static const char *objectPathCStr = "/org/freedesktop/portal/desktop";
|
||||
|
||||
typedef struct ARC_DBus {
|
||||
DBusConnection *connection;
|
||||
DBusError error;
|
||||
|
||||
const char *handle;
|
||||
} ARC_DBus;
|
||||
|
||||
typedef struct ARC_DBusShortcut {
|
||||
const char *id;
|
||||
const char *description;
|
||||
const char *preferredTrigger;
|
||||
} ARC_DBusShortcut;
|
||||
|
||||
void ARC_DBus_Create(ARC_DBus **dbus){
|
||||
*dbus = (ARC_DBus *)malloc(sizeof(ARC_DBus));
|
||||
|
||||
dbus_error_init(&((*dbus)->error));
|
||||
|
||||
(*dbus)->connection = dbus_bus_get(DBUS_BUS_SESSION, &((*dbus)->error));
|
||||
if((*dbus)->connection == NULL){
|
||||
printf("Connection to D-Bus failed %s\n", ((*dbus)->error).message);
|
||||
dbus_error_free(&((*dbus)->error));
|
||||
|
||||
free(*dbus);
|
||||
*dbus = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_DBus_Destroy(ARC_DBus *dbus){
|
||||
dbus_error_free(&(dbus->error));
|
||||
|
||||
dbus_connection_unref(dbus->connection);
|
||||
free(dbus);
|
||||
}
|
||||
|
||||
//Docs: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Request.html#org-freedesktop-portal-request-response
|
||||
void ARC_DBus_RequestResponse(){
|
||||
//create the create session message
|
||||
DBusMessage *message = dbus_message_new_method_call(busNameCStr, objectPathCStr, requestInterfaceCStr, "Response");
|
||||
if(!message){
|
||||
//TODO: arc errno stuff here
|
||||
printf("Message creation failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//initialize the message arguments
|
||||
DBusMessageIter arguments;
|
||||
dbus_message_iter_init_append(message, &arguments);
|
||||
}
|
||||
|
||||
//Docs: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.GlobalShortcuts.html#org-freedesktop-portal-globalshortcuts-createsession
|
||||
void ARC_DBus_InitSession(ARC_DBus *dbus){
|
||||
//create the create session message
|
||||
DBusMessage *message = dbus_message_new_method_call(busNameCStr, objectPathCStr, shortcutInterfaceCStr, "CreateSession");
|
||||
if(!message){
|
||||
//TODO: arc errno stuff here
|
||||
printf("Message creation failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//initialize the message arguments
|
||||
DBusMessageIter arguments;
|
||||
dbus_message_iter_init_append(message, &arguments);
|
||||
|
||||
//create the dictionary to add the message arguments to and make sure it can open
|
||||
DBusMessageIter dictonaryIter;
|
||||
if(!dbus_message_iter_open_container(&arguments, DBUS_TYPE_ARRAY, "{sv}", &dictonaryIter)){
|
||||
printf("Failed to append array to the message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//init variable container for handle and session handle
|
||||
ARC_DBusHelper_AddStringVarientStringToMessageIterDictionary(&dictonaryIter, "handle_token" , handleCStr);
|
||||
ARC_DBusHelper_AddStringVarientStringToMessageIterDictionary(&dictonaryIter, "session_handle_token", sessionHandleCStr);
|
||||
|
||||
//close to be able to send the message
|
||||
dbus_message_iter_close_container(&arguments, &dictonaryIter);
|
||||
|
||||
//send the message and store the handle response in a reply message
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(dbus->connection, message, -1, &(dbus->error));
|
||||
if(reply == NULL){
|
||||
//TODO: arc errno stuff here
|
||||
printf("ERROR: %s\n", dbus->error.message);
|
||||
}
|
||||
|
||||
//wait until message queue is empty then clean up the message
|
||||
dbus_connection_flush(dbus->connection);
|
||||
dbus_message_unref(message);
|
||||
|
||||
//get the reply message iterator and make sure it stores an object (this will be a handle on success)
|
||||
DBusMessageIter replyIter;
|
||||
dbus_message_iter_init(reply, &replyIter);
|
||||
if(dbus_message_iter_get_arg_type(&replyIter) != 'o'){
|
||||
//TODO: arc errno stuff here
|
||||
printf("object expected, but recieved something else, '%c'\n", (char)dbus_message_iter_get_arg_type(&replyIter));
|
||||
return;
|
||||
}
|
||||
|
||||
//store the handle from the iterator into the dbus type
|
||||
//TODO: probably want to warn if dbus->handle already stores something
|
||||
dbus_message_iter_get_basic(&replyIter, &(dbus->handle));
|
||||
|
||||
//request response shit?
|
||||
// dbus_connection_read_write(dbus->connection, 0);
|
||||
//
|
||||
// DBusMessage *message = dbus_connection_pop_message(dbus->connection);
|
||||
// if(message == NULL){
|
||||
// continue;
|
||||
// }
|
||||
|
||||
//cleanup
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
//Docs: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.GlobalShortcuts.html#org-freedesktop-portal-globalshortcuts-bindshortcuts
|
||||
//NOTE: this is a vector of ARC_DBusShortcut
|
||||
void ARC_DBus_BindShortcuts(ARC_DBus *dbus, ARC_Vector *dbusShortcutVector){
|
||||
//create the create session message
|
||||
DBusMessage *message = dbus_message_new_method_call(busNameCStr, objectPathCStr, shortcutInterfaceCStr, "BindShortcuts");
|
||||
if(!message){
|
||||
//TODO: arc errno stuff here
|
||||
printf("Message creation failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//initialize the message arguments
|
||||
DBusMessageIter arguments;
|
||||
dbus_message_iter_init_append(message, &arguments);
|
||||
|
||||
/* ~ session handle ~ */
|
||||
dbus_message_iter_append_basic(&arguments, DBUS_TYPE_OBJECT_PATH, &(dbus->handle));
|
||||
|
||||
/* ~ shortcuts ~ */
|
||||
//create the dictionary to add the message arguments to and make sure it can open
|
||||
DBusMessageIter shortcutsIter;
|
||||
if(!dbus_message_iter_open_container(&arguments, DBUS_TYPE_ARRAY, "(sa{sv})", &shortcutsIter)){
|
||||
printf("Failed to append array to the message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//add all the shortcuts from the vector to the shortcuts
|
||||
for(uint32_t index = 0; index < ARC_Vector_GetSize(dbusShortcutVector); index++){
|
||||
DBusMessageIter shortcutStructIter;
|
||||
if(!dbus_message_iter_open_container(&shortcutsIter, DBUS_TYPE_STRUCT, NULL, &shortcutStructIter)){
|
||||
printf("Failed to append array to the message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_DBusShortcut *shortcut = ARC_Vector_Get(dbusShortcutVector, index);
|
||||
dbus_message_iter_append_basic(&shortcutStructIter, DBUS_TYPE_STRING, &shortcut->id);
|
||||
|
||||
DBusMessageIter shortcutItemIter;
|
||||
if(!dbus_message_iter_open_container(&shortcutStructIter, DBUS_TYPE_ARRAY, "{sv}", &shortcutItemIter)){
|
||||
printf("Failed to append array to the message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//add the shortcut to the dictionary
|
||||
ARC_DBusHelper_AddStringVarientStringToMessageIterDictionary(&shortcutItemIter, shortcut->description, shortcut->preferredTrigger);
|
||||
|
||||
//close to be able to send the message
|
||||
dbus_message_iter_close_container(&shortcutStructIter, &shortcutItemIter);
|
||||
dbus_message_iter_close_container(&shortcutsIter, &shortcutStructIter);
|
||||
}
|
||||
|
||||
//close to be able to send the message
|
||||
dbus_message_iter_close_container(&arguments, &shortcutsIter);
|
||||
|
||||
/* ~ parent window ~ */
|
||||
const char *parentWindow = "";
|
||||
dbus_message_iter_append_basic(&arguments, DBUS_TYPE_STRING, &parentWindow);
|
||||
|
||||
/* ~ options ~ */
|
||||
DBusMessageIter optionsIter;
|
||||
if(!dbus_message_iter_open_container(&arguments, DBUS_TYPE_ARRAY, "{sv}", &optionsIter)){
|
||||
printf("Failed to append array to the message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container(&arguments, &optionsIter);
|
||||
|
||||
//send the message and store the handle response in a reply message
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(dbus->connection, message, -1, &(dbus->error));
|
||||
if(reply == NULL){
|
||||
//TODO: arc errno stuff here
|
||||
printf("ERROR: %s\n", dbus->error.message);
|
||||
}
|
||||
|
||||
//wait until message queue is empty then clean up the message
|
||||
dbus_connection_flush(dbus->connection);
|
||||
dbus_message_unref(message);
|
||||
|
||||
//get the reply message iterator and make sure it stores an object (this will be a handle on success)
|
||||
DBusMessageIter replyIter;
|
||||
dbus_message_iter_init(reply, &replyIter);
|
||||
if(dbus_message_iter_get_arg_type(&replyIter) != 'o'){
|
||||
//TODO: arc errno stuff here
|
||||
printf("object expected, but recieved something else, '%c'\n", (char)dbus_message_iter_get_arg_type(&replyIter));
|
||||
return;
|
||||
}
|
||||
|
||||
//get the request handle. not sure what to do with this yet...
|
||||
const char *requestHandle;
|
||||
dbus_message_iter_get_basic(&replyIter, &requestHandle);
|
||||
printf("Request Handle: %s\n", requestHandle);
|
||||
|
||||
//cleanup
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
//NOTE: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.GlobalShortcuts.html#org-freedesktop-portal-globalshortcuts-listshortcuts
|
||||
void ARC_DBus_ListShortcuts(ARC_DBus *dbus){
|
||||
//create the create session message
|
||||
DBusMessage *message = dbus_message_new_method_call(busNameCStr, objectPathCStr, shortcutInterfaceCStr, "ListShortcuts");
|
||||
if(!message){
|
||||
//TODO: arc errno stuff here
|
||||
printf("Message creation failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//initialize the message arguments
|
||||
DBusMessageIter arguments;
|
||||
dbus_message_iter_init_append(message, &arguments);
|
||||
|
||||
/* ~ session handle ~ */
|
||||
dbus_message_iter_append_basic(&arguments, DBUS_TYPE_OBJECT_PATH, &(dbus->handle));
|
||||
|
||||
/* ~ options ~ */
|
||||
DBusMessageIter optionsIter;
|
||||
if(!dbus_message_iter_open_container(&arguments, DBUS_TYPE_ARRAY, "{sv}", &optionsIter)){
|
||||
printf("Failed to append array to the message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container(&arguments, &optionsIter);
|
||||
|
||||
//send the message and store the handle response in a reply message
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(dbus->connection, message, -1, &(dbus->error));
|
||||
if(reply == NULL){
|
||||
//TODO: arc errno stuff here
|
||||
printf("ERROR: %s\n", dbus->error.message);
|
||||
}
|
||||
|
||||
//wait until message queue is empty then clean up the message
|
||||
dbus_connection_flush(dbus->connection);
|
||||
dbus_message_unref(message);
|
||||
|
||||
/*
|
||||
//get the reply message iterator and make sure it stores an object (this will be a handle on success)
|
||||
DBusMessageIter replyIter;
|
||||
dbus_message_iter_init(reply, &replyIter);
|
||||
if(dbus_message_iter_get_arg_type(&replyIter) != 'o'){
|
||||
//TODO: arc errno stuff here
|
||||
printf("object expected, but recieved something else, '%c'\n", (char)dbus_message_iter_get_arg_type(&replyIter));
|
||||
return;
|
||||
}
|
||||
|
||||
//get the request handle. not sure what to do with this yet...
|
||||
const char *requestHandle;
|
||||
dbus_message_iter_get_basic(&replyIter, &requestHandle);
|
||||
printf("Request Handle: %s\n", requestHandle);
|
||||
*/
|
||||
|
||||
//cleanup
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
ARC_DBusShortcut *ARC_DBusShortcut_CreateAndReturn(const char *id, const char *description, const char *preferredTrigger){
|
||||
ARC_DBusShortcut *shortcut = (ARC_DBusShortcut *)malloc(sizeof(ARC_DBusShortcut));
|
||||
|
||||
*shortcut = (ARC_DBusShortcut){
|
||||
id,
|
||||
description,
|
||||
preferredTrigger
|
||||
};
|
||||
|
||||
return shortcut;
|
||||
}
|
||||
63
packages/linux/dbus/libdbus/helpers.c
Normal file
63
packages/linux/dbus/libdbus/helpers.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include "arc/linux/dbus/helpers.h"
|
||||
#include "arc/linux/dbus/dbus.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct ARC_DBus {
|
||||
DBusConnection *connection;
|
||||
DBusError error;
|
||||
|
||||
const char *handle;
|
||||
} ARC_DBus;
|
||||
|
||||
void ARC_DBusHelper_BusRequestName(ARC_DBus *dbus, const char *interface, const char *objectPath){
|
||||
int32_t response = dbus_bus_request_name(dbus->connection, interface, DBUS_NAME_FLAG_REPLACE_EXISTING, &(dbus->error));
|
||||
if(response == -1){
|
||||
printf("Request name failed %s\n", (dbus->error).message);
|
||||
dbus_error_free(&(dbus->error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_DBusHelper_BusAddMatch(ARC_DBus *dbus, const char *interface, const char *objectPath, const char *member){
|
||||
//add response signal
|
||||
const char *matchRuleCStr = "type='signal',interface='%s',path='%s',member='%s'";
|
||||
uint32_t matchRuleLen = strlen(matchRuleCStr) + strlen(interface) + strlen(objectPath) + strlen(member);
|
||||
char matchRule[matchRuleLen];
|
||||
snprintf(matchRule, matchRuleLen, matchRuleCStr, interface, objectPath, member);
|
||||
|
||||
dbus_bus_add_match(dbus->connection, matchRule, &(dbus->error));
|
||||
if(dbus_error_is_set(&(dbus->error))){
|
||||
printf("failed to add match rule: %s\n", matchRuleCStr);
|
||||
dbus_error_free(&(dbus->error));
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_DBusHelper_HandleSignal(DBusMessage *message){
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
|
||||
uint32_t response;
|
||||
|
||||
DBusMessageIter argumentsIter;
|
||||
dbus_message_iter_init(message, &argumentsIter);
|
||||
dbus_message_iter_get_basic(&argumentsIter, &response);
|
||||
|
||||
printf("Response signal: %u\n", response);
|
||||
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
void ARC_DBusHelper_AddStringVarientStringToMessageIterDictionary(DBusMessageIter *dictonaryIter, const char *stringKey, const char *varientStringValue){
|
||||
//TODO: should add arc error checks here
|
||||
DBusMessageIter keyIter;
|
||||
dbus_message_iter_open_container(dictonaryIter, DBUS_TYPE_DICT_ENTRY, NULL, &keyIter);
|
||||
dbus_message_iter_append_basic(&keyIter, DBUS_TYPE_STRING, &stringKey);
|
||||
|
||||
DBusMessageIter valueIter;
|
||||
dbus_message_iter_open_container(&keyIter, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &valueIter);
|
||||
dbus_message_iter_append_basic(&valueIter, DBUS_TYPE_STRING, &varientStringValue);
|
||||
|
||||
dbus_message_iter_close_container(&keyIter, &valueIter);
|
||||
dbus_message_iter_close_container(dictonaryIter, &keyIter);
|
||||
}
|
||||
291
packages/linux/ssh/libssh/ssh.c
Normal file
291
packages/linux/ssh/libssh/ssh.c
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
#include "arc/networking/ssh.h"
|
||||
|
||||
#include "arc/std/errno.h"
|
||||
#include "arc/std/string.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
struct ARC_Ssh {
|
||||
ssh_session session;
|
||||
};
|
||||
|
||||
int verify_knownhost(ssh_session session){
|
||||
enum ssh_known_hosts_e state;
|
||||
unsigned char *hash = NULL;
|
||||
ssh_key srv_pubkey = NULL;
|
||||
size_t hlen;
|
||||
char buf[10];
|
||||
char *hexa;
|
||||
char *p;
|
||||
int cmp;
|
||||
int rc;
|
||||
|
||||
rc = ssh_get_server_publickey(session, &srv_pubkey);
|
||||
if(rc < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_get_publickey_hash(srv_pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen);
|
||||
ssh_key_free(srv_pubkey);
|
||||
if(rc < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
state = ssh_session_is_known_server(session);
|
||||
switch(state){
|
||||
case SSH_KNOWN_HOSTS_OK:
|
||||
/* OK */
|
||||
break;
|
||||
|
||||
case SSH_KNOWN_HOSTS_CHANGED:
|
||||
fprintf(stderr, "Host key for server changed: it is now:\n");
|
||||
//ssh_print_hexa("Public key hash", hash, hlen);
|
||||
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
|
||||
case SSH_KNOWN_HOSTS_OTHER:
|
||||
fprintf(stderr, "The host key for this server was not found but an other type of key exists.\n");
|
||||
fprintf(stderr, "An attacker might change the default server key to confuse your client into thinking the key does not exist\n");
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
|
||||
case SSH_KNOWN_HOSTS_NOT_FOUND:
|
||||
fprintf(stderr, "Could not find known host file.\n");
|
||||
fprintf(stderr, "If you accept the host key here, the file will be automatically created.\n");
|
||||
/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
|
||||
|
||||
case SSH_KNOWN_HOSTS_UNKNOWN:
|
||||
hexa = ssh_get_hexa(hash, hlen);
|
||||
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||
ssh_string_free_char(hexa);
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
p = fgets(buf, sizeof(buf), stdin);
|
||||
if(p == NULL){
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmp = strncasecmp(buf, "yes", 3);
|
||||
if(cmp != 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_session_update_known_hosts(session);
|
||||
if(rc < 0){
|
||||
fprintf(stderr, "Error %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SSH_KNOWN_HOSTS_ERROR:
|
||||
fprintf(stderr, "Error %s", ssh_get_error(session));
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ARC_Ssh_Create(ARC_Ssh **ssh, char *host, char *user, char *password){
|
||||
*ssh = (ARC_Ssh *)malloc(sizeof(ARC_Ssh));
|
||||
|
||||
(*ssh)->session = ssh_new();
|
||||
if((*ssh)->session == NULL){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
ARC_DEBUG_ERR("ARC_Ssh_Create(ssh), ssh session could not be created\n");
|
||||
free(*ssh);
|
||||
*ssh = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(host != NULL){
|
||||
ssh_options_set((*ssh)->session, SSH_OPTIONS_HOST, host);
|
||||
}
|
||||
|
||||
if(user != NULL){
|
||||
ssh_options_set((*ssh)->session, SSH_OPTIONS_USER, user);
|
||||
}
|
||||
|
||||
int32_t returnCode = ssh_connect((*ssh)->session);
|
||||
if(returnCode != SSH_OK){
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_Create(ssh), ssh failed to connect to localhost: %s\n", ssh_get_error((*ssh)->session));
|
||||
ssh_free((*ssh)->session);
|
||||
free(*ssh);
|
||||
*ssh = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(verify_knownhost((*ssh)->session) < 0){
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_ERR("ARC_Ssh_Create(ssh), ssh failed to verify knownhost\n");
|
||||
ssh_disconnect((*ssh)->session);
|
||||
ssh_free((*ssh)->session);
|
||||
free(*ssh);
|
||||
*ssh = NULL;
|
||||
}
|
||||
|
||||
//if no password is provided try to connect with a public key
|
||||
if(password == NULL){
|
||||
returnCode = ssh_userauth_publickey_auto((*ssh)->session, NULL, NULL);
|
||||
if(returnCode != SSH_AUTH_SUCCESS){
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_Create(ssh), ssh failed to authenticate with password: %s\n", ssh_get_error((*ssh)->session));
|
||||
ssh_disconnect((*ssh)->session);
|
||||
ssh_free((*ssh)->session);
|
||||
free(*ssh);
|
||||
*ssh = NULL;
|
||||
}
|
||||
|
||||
ssh_send_ignore((*ssh)->session, "mpv https://youtu.be/1P5BSm_oFJg --input-ipc-server=/tmp/mpvsocket --no-terminal & disown");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//try connecting with password
|
||||
returnCode = ssh_userauth_password((*ssh)->session, NULL, password);
|
||||
if(returnCode != SSH_AUTH_SUCCESS){
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_Create(ssh), ssh failed to authenticate with password: %s\n", ssh_get_error((*ssh)->session));
|
||||
ssh_disconnect((*ssh)->session);
|
||||
ssh_free((*ssh)->session);
|
||||
free(*ssh);
|
||||
*ssh = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_Ssh_Destroy(ARC_Ssh *ssh){
|
||||
if(ssh == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_disconnect(ssh->session);
|
||||
ssh_free(ssh->session);
|
||||
free(ssh);
|
||||
}
|
||||
|
||||
void ARC_Ssh_RunInSession(ARC_Ssh *ssh, ARC_Ssh_SessionFn sessionFn){
|
||||
ssh_channel channel;
|
||||
|
||||
channel = ssh_channel_new(ssh->session);
|
||||
if(channel == NULL){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to create channel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t returnCode = ssh_channel_open_session(channel);
|
||||
if(returnCode != SSH_OK){
|
||||
ssh_channel_free(channel);
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to open session with return code: %d\n", returnCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// sessionFn(ssh, );
|
||||
returnCode = ssh_channel_request_exec(channel, "export DISPLAY=:0 ; volume --inc");
|
||||
printf("return code: %d\n", returnCode);
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
void ARC_Ssh_ExecStrInNewSession(ARC_Ssh *ssh, char *command){
|
||||
ssh_channel channel;
|
||||
channel = ssh_channel_new(ssh->session);
|
||||
if(channel == NULL){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to create channel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t returnCode = ssh_channel_open_session(channel);
|
||||
if(returnCode != SSH_OK){
|
||||
ssh_channel_free(channel);
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to open session with return code: %d\n", returnCode);
|
||||
return;
|
||||
}
|
||||
|
||||
returnCode = ssh_channel_request_exec(channel, command);
|
||||
if(returnCode != SSH_OK){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed when executing command with error code: %d\n", returnCode);
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
|
||||
ARC_String *ARC_Ssh_ExecStrInNewSessionAndGetResponse(ARC_Ssh *ssh, char *command){
|
||||
ssh_channel channel;
|
||||
channel = ssh_channel_new(ssh->session);
|
||||
if(channel == NULL){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to create channel\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t returnCode = ssh_channel_open_session(channel);
|
||||
if(returnCode != SSH_OK){
|
||||
ssh_channel_free(channel);
|
||||
arc_errno = ARC_ERRNO_CONNECTION;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to open session with return code: %d\n", returnCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
returnCode = ssh_channel_request_exec(channel, command);
|
||||
if(returnCode != SSH_OK){
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed when executing command with error code: %d\n", returnCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//this is taken from https://api.libssh.org/master/libssh_tutor_command.html
|
||||
char buffer[256];
|
||||
int32_t bytesSize;
|
||||
|
||||
ARC_String *returnString = NULL;
|
||||
|
||||
bytesSize = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
while(bytesSize > 0){
|
||||
if(returnString == NULL){
|
||||
ARC_String_Create(&returnString, buffer, bytesSize);
|
||||
|
||||
bytesSize = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
ARC_String_AppendCString(&returnString, (const char *)buffer, bytesSize);
|
||||
|
||||
bytesSize = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
}
|
||||
|
||||
if(bytesSize < 0){
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed when reading bytes from channel\n");
|
||||
|
||||
if(returnString != NULL){
|
||||
ARC_String_Destroy(returnString);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
|
||||
return returnString;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue