Initial conversion to new architecture, stub out deltas.

This commit is contained in:
Michael Jumper 2013-03-19 22:48:43 -07:00
parent 15a0e44474
commit b7af1d45f5
8 changed files with 367 additions and 71 deletions

View File

@ -41,12 +41,14 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libguac-client-ssh.la
libguac_client_ssh_la_SOURCES = \
src/delta.c \
src/ssh_client.c \
src/ssh_handlers.c \
src/terminal.c \
src/terminal_handlers.c
noinst_HEADERS = \
include/delta.h \
include/ssh_client.h \
include/ssh_handlers.h \
include/terminal.h \

View File

@ -0,0 +1,158 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac-client-ssh.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _SSH_GUAC_DELTA_H
#define _SSH_GUAC_DELTA_H
#include <guacamole/client.h>
#include "terminal.h"
/**
* All available terminal operations which affect character cells.
*/
typedef enum guac_terminal_operation_type {
/**
* Operation which does nothing.
*/
GUAC_CHAR_NOP,
/**
* Operation which copies a character from a given row/column coordinate.
*/
GUAC_CHAR_COPY,
/**
* Operation which sets the character and attributes.
*/
GUAC_CHAR_SET
} guac_terminal_operation_type;
/**
* A pairing of a guac_terminal_operation_type and all parameters required by
* that operation type.
*/
typedef struct guac_terminal_operation {
/**
* The type of operation to perform.
*/
guac_terminal_operation_type type;
/**
* The character (and attributes) to set the current location to. This is
* only applicable to GUAC_CHAR_SET.
*/
guac_terminal_char character;
/**
* The row to copy a character from. This is only applicable to
* GUAC_CHAR_COPY.
*/
int row;
/**
* The column to copy a character from. This is only applicable to
* GUAC_CHAR_COPY.
*/
int column;
} guac_terminal_operation;
/**
* Set of all pending operations for the currently-visible screen area.
*/
typedef struct guac_terminal_delta {
/**
* Array of all operations pending for the visible screen area.
*/
guac_terminal_operation* operations;
/**
* The width of the screen, in characters.
*/
int width;
/**
* The height of the screen, in characters.
*/
int height;
} guac_terminal_delta;
/**
* Allocates a new guac_terminal_delta.
*/
guac_terminal_delta* guac_terminal_delta_alloc(int width, int height);
/**
* Frees the given guac_terminal_delta.
*/
void guac_terminal_delta_free(guac_terminal_delta* delta);
/**
* Resizes the given guac_terminal_delta to the given dimensions.
*/
void guac_terminal_delta_resize(guac_terminal_delta* delta,
int width, int height);
/**
* Stores a set operation at the given location.
*/
void guac_terminal_delta_set(guac_terminal_delta* delta, int r, int c,
guac_terminal_char* character);
/**
* Stores a rectangle of copy operations, copying existing operations as
* necessary.
*/
void guac_terminal_delta_copy(guac_terminal_delta* delta,
int dst_row, int dst_column,
int src_row, int src_column,
int w, int h);
/**
* Flushes all pending operations within the given guac_client_delta to the
* given guac_terminal.
*/
void guac_terminal_delta_flush(guac_terminal_delta* delta,
guac_terminal* terminal);
#endif

View File

@ -38,6 +38,8 @@
#ifndef _SSH_GUAC_TERMINAL_H
#define _SSH_GUAC_TERMINAL_H
#include <stdbool.h>
#include <pango/pangocairo.h>
#include <guacamole/client.h>
@ -51,6 +53,67 @@ typedef struct guac_terminal guac_terminal;
*/
typedef int guac_terminal_char_handler(guac_terminal* term, char c);
/**
* An RGB color, where each component ranges from 0 to 255.
*/
typedef struct guac_terminal_color {
/**
* The red component of this color.
*/
int red;
/**
* The green component of this color.
*/
int green;
/**
* The blue component of this color.
*/
int blue;
} guac_terminal_color;
/**
* Terminal attributes, as can be applied to a single character.
*/
typedef struct guac_terminal_attributes {
/**
* Whether the character should be rendered bold.
*/
bool bold;
/**
* Whether the character should be rendered with reversed colors
* (background becomes foreground and vice-versa).
*/
bool reverse;
/**
* Whether to render the character with underscore.
*/
bool underscore;
/**
* The foreground color of this character, as a palette index.
*/
int foreground;
/**
* The background color of this character, as a palette index.
*/
int background;
} guac_terminal_attributes;
/**
* The available color palette. All integer colors within structures
* here are indices into this palette.
*/
extern const guac_terminal_color guac_terminal_palette[16];
/**
* Represents a single character for display in a terminal, including actual
* character value, foreground color, and background color.
@ -63,14 +126,9 @@ typedef struct guac_terminal_char {
char value;
/**
* The foreground color of the character to display.
* The attributes of the character to display.
*/
int foreground;
/**
* The background color of the character to display.
*/
int background;
guac_terminal_attributes attributes;
} guac_terminal_char;
@ -173,36 +231,42 @@ struct guac_terminal {
*/
guac_layer* cursor_layer;
int foreground;
int background;
int reverse;
int bold;
int underscore;
/**
* The attributes which will be applied to future characters.
*/
guac_terminal_attributes current_attributes;
int default_foreground;
int default_background;
/**
* The attributes which will be applied to characters by default, unless
* other attributes are explicitly specified.
*/
guac_terminal_attributes default_attributes;
/**
* Handler which will receive all printed characters, updating the terminal
* accordingly.
*/
guac_terminal_char_handler* char_handler;
};
typedef struct guac_terminal_color {
int red;
int green;
int blue;
} guac_terminal_color;
extern const guac_terminal_color guac_terminal_palette[16];
/**
* Creates a new guac_terminal, having the given width and height, and
* rendering to the given client.
*/
guac_terminal* guac_terminal_create(guac_client* client,
int width, int height);
/**
* Frees all resources associated with the given terminal.
*/
void guac_terminal_free(guac_terminal* term);
/**
* Writes the given string of characters to the terminal.
*/
int guac_terminal_write(guac_terminal* term, const char* c, int size);
int guac_terminal_redraw_cursor(guac_terminal* term);
int guac_terminal_set_colors(guac_terminal* term,
int foreground, int background);

72
protocols/ssh/src/delta.c Normal file
View File

@ -0,0 +1,72 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac-client-ssh.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <guacamole/client.h>
#include "terminal.h"
#include "delta.h"
guac_terminal_delta* guac_terminal_delta_alloc(int width, int height) {
/* STUB */
return NULL;
}
void guac_terminal_delta_free(guac_terminal_delta* delta) {
/* STUB */
}
void guac_terminal_delta_resize(guac_terminal_delta* delta,
int width, int height) {
/* STUB */
}
void guac_terminal_delta_set(guac_terminal_delta* delta, int r, int c,
guac_terminal_char* character) {
/* STUB */
}
void guac_terminal_delta_copy(guac_terminal_delta* delta,
int dst_row, int dst_column,
int src_row, int src_column,
int w, int h) {
/* STUB */
}
void guac_terminal_delta_flush(guac_terminal_delta* delta,
guac_terminal* terminal) {
/* STUB */
}

View File

@ -69,7 +69,6 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
/* Add to password */
client_data->password[client_data->password_length++] = keysym;
guac_terminal_write(client_data->term, "*", 1);
guac_terminal_redraw_cursor(client_data->term);
guac_socket_flush(client->socket);
}
else if (keysym == 0xFF08) {
@ -79,7 +78,6 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
/* Backspace */
guac_terminal_write(client_data->term, "\x08\x1B[K", 4);
guac_terminal_redraw_cursor(client_data->term);
guac_socket_flush(client->socket);
}
@ -91,7 +89,6 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
/* Clear screen */
guac_terminal_write(client_data->term, "\x1B[2J\x1B[1;1H", 10);
guac_terminal_redraw_cursor(client_data->term);
guac_socket_flush(client->socket);
return ssh_guac_client_auth(client, client_data->password);
@ -166,7 +163,6 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
client_data->password_length = 0;
guac_terminal_write(client_data->term, "Password: ", 10);
guac_terminal_redraw_cursor(client_data->term);
guac_socket_flush(client->socket);
client->key_handler = ssh_guac_client_password_key_handler;

View File

@ -91,7 +91,6 @@ int ssh_guac_client_handle_messages(guac_client* client) {
&& (bytes_read = channel_read_nonblocking(client_data->term_channel, buffer, sizeof(buffer), 0)) > 0) {
if (guac_terminal_write(client_data->term, buffer, bytes_read)
|| guac_terminal_redraw_cursor(client_data->term)
|| guac_socket_flush(socket))
return 1;

View File

@ -76,6 +76,14 @@ const guac_terminal_color guac_terminal_palette[16] = {
guac_terminal* guac_terminal_create(guac_client* client,
int width, int height) {
guac_terminal_attributes default_attributes = {
.foreground = 7,
.background = 0,
.bold = false,
.reverse = false,
.underscore = false
};
int row, col;
PangoFontMap* font_map;
@ -86,11 +94,10 @@ guac_terminal* guac_terminal_create(guac_client* client,
guac_terminal* term = malloc(sizeof(guac_terminal));
term->client = client;
term->glyph_foreground = term->foreground = term->default_foreground = 7; /* White */
term->glyph_background = term->background = term->default_background = 0; /* Black */
term->reverse = 0; /* Normal video */
term->bold = 0; /* Normal intensity */
term->underscore = 0; /* No underline */
term->current_attributes =
term->default_attributes = default_attributes;
term->glyph_foreground = default_attributes.foreground;
term->glyph_background = default_attributes.background;
memset(term->glyphs, 0, sizeof(term->glyphs));
term->glyph_stroke = guac_client_alloc_buffer(client);
@ -151,8 +158,7 @@ guac_terminal* guac_terminal_create(guac_client* client,
/* Empty character, default colors */
current_row[col].value = '\0';
current_row[col].foreground = term->default_foreground;
current_row[col].background = term->default_background;
current_row[col].attributes = term->default_attributes;
}
@ -161,7 +167,7 @@ guac_terminal* guac_terminal_create(guac_client* client,
/* Clear with background color */
guac_terminal_clear(term,
0, 0, term->term_height, term->term_width,
term->background);
term->current_attributes.background);
return term;
@ -407,7 +413,7 @@ int guac_terminal_scroll_up(guac_terminal* term,
/* Fill new rows with background */
|| guac_terminal_clear(term,
end_row - amount + 1, 0, amount, term->term_width,
term->background);
term->current_attributes.background);
}
@ -428,7 +434,7 @@ int guac_terminal_scroll_down(guac_terminal* term,
/* Fill new rows with background */
|| guac_terminal_clear(term,
start_row, 0, amount, term->term_width,
term->background);
term->current_attributes.background);
}

View File

@ -42,8 +42,8 @@
int guac_terminal_echo(guac_terminal* term, char c) {
int foreground = term->foreground;
int background = term->background;
int foreground = term->current_attributes.foreground;
int background = term->current_attributes.background;
switch (c) {
@ -100,14 +100,14 @@ int guac_terminal_echo(guac_terminal* term, char c) {
}
/* Handle reverse video */
if (term->reverse) {
if (term->current_attributes.reverse) {
int swap = background;
background = foreground;
foreground = swap;
}
/* Handle bold */
if (term->bold && foreground <= 7)
if (term->current_attributes.bold && foreground <= 7)
foreground += 8;
guac_terminal_set_colors(term,
@ -268,60 +268,59 @@ int guac_terminal_csi(guac_terminal* term, char c) {
int value = argv[i];
/* Reset attributes */
if (value == 0) {
term->foreground = term->default_foreground;
term->background = term->default_background;
term->reverse = 0;
term->underscore = 0;
term->bold = 0;
}
if (value == 0)
term->current_attributes = term->default_attributes;
/* Bold */
else if (value == 1)
term->bold = 1;
term->current_attributes.bold = true;
/* Underscore on */
else if (value == 4)
term->underscore = 1;
term->current_attributes.underscore = true;
/* Foreground */
else if (value >= 30 && value <= 37)
term->foreground = value - 30;
term->current_attributes.foreground = value - 30;
/* Background */
else if (value >= 40 && value <= 47)
term->background = value - 40;
term->current_attributes.background = value - 40;
/* Underscore on, default foreground */
else if (value == 38) {
term->underscore = 1;
term->foreground = term->default_foreground;
term->current_attributes.underscore = true;
term->current_attributes.foreground =
term->default_attributes.foreground;
}
/* Underscore off, default foreground */
else if (value == 39) {
term->underscore = 0;
term->foreground = term->default_foreground;
term->current_attributes.underscore = false;
term->current_attributes.foreground =
term->default_attributes.foreground;
}
/* Reset background */
else if (value == 49)
term->background = term->default_background;
term->current_attributes.background =
term->default_attributes.background;
/* Reverse video */
else if (value == 7)
term->reverse = 1;
term->current_attributes.reverse = true;
/* Reset reverse video */
else if (value == 27)
term->reverse = 0;
term->current_attributes.reverse = false;
/* Reset intensity */
else if (value == 27)
term->bold = 0;
term->current_attributes.bold = false;
else
guac_client_log_info(term->client, "Unhandled graphics rendition: %i", value);
guac_client_log_info(term->client,
"Unhandled graphics rendition: %i", value);
}
@ -364,20 +363,20 @@ int guac_terminal_csi(guac_terminal* term, char c) {
guac_terminal_clear_range(term,
term->cursor_row, term->cursor_col,
term->term_height-1, term->term_width-1,
term->background);
term->current_attributes.background);
/* Erase from start to cursor */
else if (argv[0] == 1)
guac_terminal_clear_range(term,
0, 0,
term->cursor_row, term->cursor_col,
term->background);
term->current_attributes.background);
/* Entire screen */
else if (argv[0] == 2)
guac_terminal_clear(term,
0, 0, term->term_height, term->term_width,
term->background);
term->current_attributes.background);
break;
@ -389,7 +388,7 @@ int guac_terminal_csi(guac_terminal* term, char c) {
guac_terminal_clear(term,
term->cursor_row, term->cursor_col,
1, term->term_width - term->cursor_col,
term->background);
term->current_attributes.background);
/* Erase from start to cursor */
@ -397,14 +396,14 @@ int guac_terminal_csi(guac_terminal* term, char c) {
guac_terminal_clear(term,
term->cursor_row, 0,
1, term->cursor_col + 1,
term->background);
term->current_attributes.background);
/* Erase line */
else if (argv[0] == 2)
guac_terminal_clear(term,
term->cursor_row, 0,
1, term->term_width,
term->background);
term->current_attributes.background);
break;
@ -448,7 +447,7 @@ int guac_terminal_csi(guac_terminal* term, char c) {
guac_terminal_clear(term,
term->cursor_row, term->term_width - amount,
1, amount,
term->background);
term->current_attributes.background);
break;
@ -469,7 +468,7 @@ int guac_terminal_csi(guac_terminal* term, char c) {
guac_terminal_clear(term,
term->cursor_row, term->cursor_col,
1, amount,
term->background);
term->current_attributes.background);
break;