Implement terminal reporting features.

This commit is contained in:
Michael Jumper 2013-05-25 20:24:44 -07:00
parent 3a14c864a6
commit 88ca59a5b3

View File

@ -36,12 +36,53 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include "common.h" #include "common.h"
#include "terminal.h" #include "terminal.h"
#include "terminal_handlers.h" #include "terminal_handlers.h"
#include "char_mappings.h" #include "char_mappings.h"
/**
* Response string sent when identification is requested.
*/
#define GUAC_TERMINAL_VT102_ID "\x1B[?6c"
/**
* Arbitrary response to ENQ control character.
*/
#define GUAC_TERMINAL_ANSWERBACK "GUACAMOLE"
/**
* Response which indicates the terminal is alive.
*/
#define GUAC_TERMINAL_OK "\x1B[0n"
/**
* Sends data through STDIN as if typed by the user, using the format
* string given and any args (similar to printf).
*/
static int guac_terminal_respond(guac_terminal* term, const char* format, ...) {
int written;
va_list ap;
char buffer[1024];
/* Print to buffer */
va_start(ap, format);
written = vsnprintf(buffer, sizeof(buffer)-1, format, ap);
va_end(ap);
if (written < 0)
return written;
/* Write to STDIN */
return guac_terminal_write_all(term->stdin_pipe_fd[1], buffer, written);
}
int guac_terminal_echo(guac_terminal* term, char c) { int guac_terminal_echo(guac_terminal* term, char c) {
static int bytes_remaining = 0; static int bytes_remaining = 0;
@ -99,7 +140,7 @@ int guac_terminal_echo(guac_terminal* term, char c) {
/* Enquiry */ /* Enquiry */
case 0x05: case 0x05:
guac_terminal_write_all(term->stdin_pipe_fd[1], "GUACAMOLE", 9); guac_terminal_respond(term, "%s", GUAC_TERMINAL_ANSWERBACK);
break; break;
/* Bell */ /* Bell */
@ -304,7 +345,7 @@ int guac_terminal_escape(guac_terminal* term, char c) {
/* DEC Identify */ /* DEC Identify */
case 'Z': case 'Z':
guac_terminal_write_all(term->stdin_pipe_fd[1], "\x1B[?6c", 5); guac_terminal_respond(term, "%s", GUAC_TERMINAL_VT102_ID);
term->char_handler = guac_terminal_echo; term->char_handler = guac_terminal_echo;
break; break;
@ -655,7 +696,7 @@ int guac_terminal_csi(guac_terminal* term, char c) {
/* c: Identify */ /* c: Identify */
case 'c': case 'c':
if (argv[0] == 0 && private_mode_character == 0) if (argv[0] == 0 && private_mode_character == 0)
guac_terminal_write_all(term->stdin_pipe_fd[1], "\x1B[?6c", 5); guac_terminal_respond(term, "%s", GUAC_TERMINAL_VT102_ID);
break; break;
/* d: Move cursor, current col */ /* d: Move cursor, current col */
@ -764,6 +805,19 @@ int guac_terminal_csi(guac_terminal* term, char c) {
break; break;
/* n: Status report */
case 'n':
/* Device status report */
if (argv[0] == 5 && private_mode_character == 0)
guac_terminal_respond(term, "%s", GUAC_TERMINAL_OK);
/* Cursor position report */
else if (argv[0] == 6 && private_mode_character == 0)
guac_terminal_respond(term, "\x1B[%i;%iR", term->cursor_row+1, term->cursor_col+1);
break;
/* q: Set keyboard LEDs */ /* q: Set keyboard LEDs */
case 'q': case 'q':
/* Explicitly ignored */ /* Explicitly ignored */