add terminal plugin

This commit is contained in:
lxsang 2015-11-26 13:52:49 +01:00
parent 27fd4a0134
commit 3333e41cae
12 changed files with 364 additions and 3 deletions

View File

@ -5,7 +5,7 @@ EXT=dylib
SERVER=plugin_manager.o ini.o http_server.o plugins/dictionary.o plugins/utils.o
SERVERLIB=-lpthread -ldl
#-lsocket
PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT)
PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT)
PLUGINSDEP = plugins/plugin.o plugins/dbhelper.o plugins/dictionary.o plugins/utils.o plugins/list.o
PLUGINLIBS = -lsqlite3

View File

@ -1,12 +1,14 @@
<HTML>
<head>
<link rel="stylesheet" type="text/css" href="style/font.min.css"/>
<link rel="stylesheet" type="text/css" href="style/w2ui-1.4.2.css" />
<link rel="stylesheet" type="text/css" href="style/w2ui-1.4.2.css" />
<link rel="stylesheet" type="text/css" href="style/site.css" />
<script src="scripts/jquery.min.js"></script>
<script src="scripts/w2ui-1.4.2.js"></script>
<script src="scripts/pluginman.js"></script>
<script src="scripts/fileman.js"></script>
<script src="scripts/camviewer.js"></script>
<script src="scripts/wterm.js"></script>
<script src="scripts/sidebar.js"></script>
<script src="scripts/rcar.js"></script>
</head>

View File

@ -1,3 +1,4 @@
var picam_config = {
name: 'picam_layout',
toolbar:{

View File

@ -14,7 +14,8 @@ var sidebar_config = {
text: 'Plugins',
icon: 'fa-cogs'
},
{ id: 'level-fman', text: 'File manager', icon: 'fa-folder-open' }
{ id: 'level-fman', text: 'File manager', icon: 'fa-folder-open' },
{ id: 'level-wterm', text: 'Terminal', icon: 'fa-wrench' }
]
},
{
@ -47,6 +48,9 @@ var sidebar_config = {
case 'level-picam':
w2ui.layout.content('main', w2ui.picam_layout);
break;
case 'level-wterm':
w2ui.layout.content('main', w2ui.wterm_layout);
break;
default: //do nothing
w2ui.layout.content('main',"Empty page");
console.log('Event: ' + event.type + ' Target: ' + event.target);

View File

@ -0,0 +1,245 @@
/*! terminal.js v2.0 | (c) 2014 Erik Österberg | https://github.com/eosterberg/terminaljs */
var Terminal = (function () {
// PROMPT_TYPE
var PROMPT_INPUT = 1, PROMPT_PASSWORD = 2, PROMPT_CONFIRM = 3
var fireCursorInterval = function (inputField, terminalObj) {
var cursor = terminalObj._cursor
setTimeout(function () {
if (inputField.parentElement && terminalObj._shouldBlinkCursor) {
cursor.style.visibility = cursor.style.visibility === 'visible' ? 'hidden' : 'visible'
fireCursorInterval(inputField, terminalObj)
} else {
cursor.style.visibility = 'visible'
}
}, 500)
}
var firstPrompt = true;
promptInput = function (terminalObj, message, PROMPT_TYPE, callback) {
var shouldDisplayInput = (PROMPT_TYPE === PROMPT_INPUT)
var inputField = document.createElement('input')
inputField.style.position = 'absolute'
inputField.style.zIndex = '-100'
inputField.style.outline = 'none'
inputField.style.border = 'none'
inputField.style.opacity = '0'
inputField.style.fontSize = '0.2em'
terminalObj._inputLine.textContent = ''
terminalObj._input.style.display = 'block'
terminalObj.html.appendChild(inputField)
fireCursorInterval(inputField, terminalObj)
if (message.length) terminalObj.msg(PROMPT_TYPE === PROMPT_CONFIRM ? message + ' (y/n)' : message)
inputField.onblur = function () {
terminalObj._cursor.style.display = 'none'
}
inputField.onfocus = function () {
inputField.value = terminalObj._inputLine.textContent
terminalObj._cursor.style.display = 'inline'
}
terminalObj.html.onclick = function () {
inputField.focus()
}
inputField.onkeydown = function (e) {
if (e.which === 37 || e.which === 39 || e.which === 38 || e.which === 40 || e.which === 9) {
e.preventDefault()
} else if (shouldDisplayInput && e.which !== 13) {
setTimeout(function () {
terminalObj._inputLine.textContent = inputField.value
}, 1)
}
}
inputField.onkeyup = function (e) {
if (PROMPT_TYPE === PROMPT_CONFIRM || e.which === 13) {
terminalObj._input.style.display = 'none'
var inputValue = inputField.value
if (shouldDisplayInput) terminalObj._print(message+inputValue,"wterm_input_div")
terminalObj.html.removeChild(inputField)
if (typeof(callback) === 'function') {
if (PROMPT_TYPE === PROMPT_CONFIRM) {
callback(inputValue.toUpperCase()[0] === 'Y' ? true : false)
} else callback(inputValue)
}
}
}
if (firstPrompt) {
firstPrompt = false
setTimeout(function () { inputField.focus() }, 50)
} else {
inputField.focus()
}
}
var terminalBeep
var TerminalConstructor = function (id) {
if (!terminalBeep) {
terminalBeep = document.createElement('audio')
var source = '<source src="http://www.erikosterberg.com/terminaljs/beep.'
terminalBeep.innerHTML = source + 'mp3" type="audio/mpeg">' + source + 'ogg" type="audio/ogg">'
terminalBeep.volume = 0.05
}
this.html = document.createElement('div')
this.html.className = 'Terminal'
if (typeof(id) === 'string') { this.html.id = id }
this._innerWindow = document.createElement('div')
this._output = document.createElement('p')
this._inputLine = document.createElement('span') //the span element where the users input is put
this._cursor = document.createElement('span')
this._input = document.createElement('p') //the full element administering the user input, including cursor
this._input.className = "wterm_input_p"
this._cursor.className = "wterm_cursor"
//this._output.className = "wterm_output_p"
this._input.appendChild(document.createElement('span'));
this._shouldBlinkCursor = true
this.beep = function () {
terminalBeep.load()
terminalBeep.play()
}
this.msg = function (message) {
this._input.firstChild.textContent = message
}
this._print = function(msg,cls)
{
var newLine = document.createElement('div')
newLine.className = cls
newLine.textContent = msg
this._output.appendChild(newLine)
}
this.print = function (message) {
this._print(message,"wterm_output_div")
}
this.input = function (message, callback) {
promptInput(this, message, PROMPT_INPUT, callback)
}
this.password = function (message, callback) {
promptInput(this, message, PROMPT_PASSWORD, callback)
}
this.confirm = function (message, callback) {
promptInput(this, message, PROMPT_CONFIRM, callback)
}
this.clear = function () {
this._output.innerHTML = ''
}
this.sleep = function (milliseconds, callback) {
setTimeout(callback, milliseconds)
}
this.setTextSize = function (size) {
this._output.style.fontSize = size
this._input.style.fontSize = size
}
this.setTextColor = function (col) {
this.html.style.color = col
this._cursor.style.background = col
}
this.setBackgroundColor = function (col) {
this.html.style.background = col
}
this.setWidth = function (width) {
this.html.style.width = width
}
this.setHeight = function (height) {
this.html.style.height = height
}
this.blinkingCursor = function (bool) {
bool = bool.toString().toUpperCase()
this._shouldBlinkCursor = (bool === 'TRUE' || bool === '1' || bool === 'YES')
}
this._input.appendChild(this._inputLine)
this._input.appendChild(this._cursor)
this._innerWindow.appendChild(this._output)
this._innerWindow.appendChild(this._input)
this.html.appendChild(this._innerWindow)
this.setBackgroundColor('black')
this.setTextColor('white')
this.setTextSize('1em')
this.setWidth('100%')
this.setHeight('100%')
this.html.style.fontFamily = 'Monaco, Courier'
this.html.style.margin = '0'
this._innerWindow.style.padding = '10px'
this._input.style.margin = '0'
this._output.style.margin = '0'
this._cursor.style.background = '#00cc00'
this._cursor.innerHTML = 'C' //put something in the cursor..
this._cursor.style.display = 'none' //then hide it
this._input.style.display = 'none'
}
return TerminalConstructor
}());
var wtermobj;
var wterm_config = {
name: 'wterm_layout',
panels: [
{
type: 'main',
style: 'padding: 0px;',
content: '<div id="wterm" style="padding:0"></div>'
}
],
onRefresh:function(event)
{
if($("#wterm_input") )
{
wtermobj = new Terminal();
wtermobj.setTextSize(11);
var nest_callback = function(data)
{
if(data.length>0)
{
//send to server
var webtty = new EventSource('/wterm?cmd='+data);
webtty.onmessage = function (e) {
wtermobj.print(e.data);
var par = $("#wterm");
par.animate({
scrollTop: par.get(0).scrollHeight
}, 0);
};
webtty.onerror = function(e)
{
// finish the command
webtty.close();
wtermobj.input("antd> ",nest_callback);
}
}
else
{
wtermobj.input("antd> ",nest_callback);
}
};
$("#wterm").html(wtermobj.html);
$("#wterm").parent().css("overflow","hidden");
$("#wterm").parent().css("background-color","black");
wtermobj.input("antd> ",nest_callback);
}
}
}
$().w2layout(wterm_config);

View File

@ -0,0 +1,21 @@
#wterm {
width:100%;
height: 100%;
background-color:black;
position:absolute;
overflow:auto;
}
.wterm_output_div{
padding-left:15px;
}
.wterm_input_div
{
color:#00cc00;
}
.wterm_input_p{
color:#00cc00;
}
.wterm_cursor{
color:#00cc00;
background-color:#00cc00;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
build/plugins/wterm.dylib Executable file

Binary file not shown.

88
plugins/wterm/wterm.c Normal file
View File

@ -0,0 +1,88 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>
#include "../plugin.h"
void init();
call __init__ = init;
void init()
{
}
void pexit()
{
}
int read_buf(int fd, char*buf,int size)
{
int i = 0;
char c = '\0';
int n;
while ((i < size - 1) && (c != '\n'))
{
n = read(fd, &c, 1);
if (n > 0)
{
buf[i] = c;
i++;
}
else if(n == -1) return n;
else
c = '\n';
}
buf[i] = '\0';
return i;
}
void execute(int client, const char* m, dictionary rq)
{
textstream(client);
int filedes[2];
char* code = R_STR(rq, "cmd");
if(!code) return;
if(pipe(filedes) == -1)
{
perror("pipe");
return;
}
pid_t pid = fork();
if(pid == -1)
{
perror("folk");
return;
} else if(pid == 0)
{
while ((dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
close(filedes[1]);
close(filedes[0]);
// executecomand
system(code);
//perror("execl");
_exit(1);
}
close(filedes[1]);
char buffer[1024];
while (1) {
ssize_t count = read_buf(filedes[0],buffer, sizeof(buffer));
if (count == -1) {
if (errno == EINTR) {
continue;
} else {
perror("read");
return;
}
} else if (count == 0) {
break;
} else {
__t(client,"data:%s\n",buffer);
//handle_child_process_output(buffer, count);
}
}
close(filedes[0]);
wait(0);
free(code);
printf("Child process exit\n");
}