Support setting window title (as OS command)

This commit is contained in:
Keith Winstein
2011-02-01 04:14:16 -05:00
parent 2f1ccdf6eb
commit e057ea6598
9 changed files with 97 additions and 18 deletions
+15
View File
@@ -50,3 +50,18 @@ void Esc_Dispatch::act_on_terminal( Terminal::Emulator *emu )
{
emu->Esc_dispatch( this );
}
void OSC_Put::act_on_terminal( Terminal::Emulator *emu )
{
emu->dispatch.OSC_put( this );
}
void OSC_Start::act_on_terminal( Terminal::Emulator *emu )
{
emu->dispatch.OSC_start( this );
}
void OSC_End::act_on_terminal( Terminal::Emulator *emu )
{
emu->OSC_end( this );
}
+9 -3
View File
@@ -73,13 +73,19 @@ namespace Parser {
public: std::string name( void ) { return std::string( "Unhook" ); }
};
class OSC_Start : public Action {
public: std::string name( void ) { return std::string( "OSC_Start" ); }
public:
std::string name( void ) { return std::string( "OSC_Start" ); }
void act_on_terminal( Terminal::Emulator *emu );
};
class OSC_Put : public Action {
public: std::string name( void ) { return std::string( "OSC_Put" ); }
public:
std::string name( void ) { return std::string( "OSC_Put" ); }
void act_on_terminal( Terminal::Emulator *emu );
};
class OSC_End : public Action {
public: std::string name( void ) { return std::string( "OSC_End" ); }
public:
std::string name( void ) { return std::string( "OSC_End" ); }
void act_on_terminal( Terminal::Emulator *emu );
};
}
+18
View File
@@ -120,6 +120,12 @@ void Emulator::CSI_dispatch( Parser::CSI_Dispatch *act )
dispatch.dispatch( CSI, act, &fb );
}
void Emulator::OSC_end( Parser::OSC_End *act )
{
fb.ds.next_print_will_wrap = false;
dispatch.OSC_dispatch( act, &fb );
}
void Emulator::Esc_dispatch( Parser::Esc_Dispatch *act )
{
fb.ds.next_print_will_wrap = false;
@@ -140,6 +146,18 @@ void Emulator::debug_printout( int fd )
std::string screen;
screen.append( "\033[H" );
/* set window title */
screen.append( "\033]0;" );
std::vector<wchar_t> window_title = fb.get_window_title();
for ( std::vector<wchar_t>::iterator i = window_title.begin();
i != window_title.end();
i++ ) {
char utf8[ 8 ];
snprintf( utf8, 8, "%lc", *i );
screen.append( utf8 );
}
screen.append( "\x7" ); /* xterm's "OSC" string ends in BEL... */
for ( int y = 0; y < fb.ds.get_height(); y++ ) {
for ( int x = 0; x < fb.ds.get_width(); /* let charwidth handle advance */ ) {
char curmove[ 32 ];
+4 -10
View File
@@ -19,6 +19,9 @@ namespace Terminal {
friend void Parser::Collect::act_on_terminal( Emulator * );
friend void Parser::CSI_Dispatch::act_on_terminal( Emulator * );
friend void Parser::Esc_Dispatch::act_on_terminal( Emulator * );
friend void Parser::OSC_Start::act_on_terminal( Emulator * );
friend void Parser::OSC_Put::act_on_terminal( Emulator * );
friend void Parser::OSC_End::act_on_terminal( Emulator * );
private:
Parser::UTF8Parser parser;
@@ -28,18 +31,9 @@ namespace Terminal {
/* action methods */
void print( Parser::Print *act );
void execute( Parser::Execute *act );
void param( Parser::Param *act );
void collect( Parser::Collect *act );
void clear( Parser::Clear *act );
void CSI_dispatch( Parser::CSI_Dispatch *act );
void Esc_dispatch( Parser::Esc_Dispatch *act );
/* CSI and Escape methods */
void CSI_EL( void );
void CSI_ED( void );
void CSI_cursormove( void );
void CSI_DA( void );
void Esc_DECALN( void );
void OSC_end( Parser::OSC_End *act );
public:
Emulator( size_t s_width, size_t s_height );
+17 -3
View File
@@ -9,7 +9,7 @@ using namespace Terminal;
Dispatcher::Dispatcher()
: params(), parsed_params(), parsed( false ), dispatch_chars(),
terminal_to_host()
OSC_string(), terminal_to_host()
{}
void Dispatcher::newparamchar( Parser::Param *act )
@@ -146,8 +146,7 @@ Function::Function( Function_Type type, std::string dispatch_chars,
void Dispatcher::dispatch( Function_Type type, Parser::Action *act, Framebuffer *fb )
{
/* add final char to dispatch key */
if ( type != CONTROL ) {
if ( (type == ESCAPE) || (type == CSI) ) {
assert( act->char_present );
Parser::Collect act2;
act2.char_present = true;
@@ -177,3 +176,18 @@ void Dispatcher::dispatch( Function_Type type, Parser::Action *act, Framebuffer
return i->second.function( fb, this );
}
}
void Dispatcher::OSC_put( Parser::OSC_Put *act )
{
assert( act->char_present );
if ( OSC_string.size() < 256 ) { /* should be a long enough window title */
OSC_string.push_back( act->ch );
act->handled = true;
}
}
void Dispatcher::OSC_start( Parser::OSC_Start *act )
{
OSC_string.clear();
act->handled = true;
}
+10 -1
View File
@@ -13,6 +13,9 @@ namespace Parser {
class Esc_Dispatch;
class CSI_Dispatch;
class Execute;
class OSC_Start;
class OSC_Put;
class OSC_End;
}
namespace Terminal {
@@ -49,6 +52,7 @@ namespace Terminal {
bool parsed;
std::string dispatch_chars;
std::vector<wchar_t> OSC_string; /* only used to set the window title */
void parse_params( void );
@@ -66,7 +70,12 @@ namespace Terminal {
std::string str( void );
void dispatch( Function_Type type, Parser::Action *act, Framebuffer *fb );
const std::string get_dispatch_chars( void ) { return dispatch_chars; }
std::string get_dispatch_chars( void ) { return dispatch_chars; }
std::vector<wchar_t> get_OSC_string( void ) { return OSC_string; }
void OSC_put( Parser::OSC_Put *act );
void OSC_start( Parser::OSC_Start *act );
void OSC_dispatch( Parser::OSC_End *act, Framebuffer *fb );
};
}
+2 -1
View File
@@ -55,7 +55,7 @@ DrawState::DrawState( int s_width, int s_height )
}
Framebuffer::Framebuffer( int s_width, int s_height )
: rows( s_height, Row( s_width ) ), ds( s_width, s_height )
: rows( s_height, Row( s_width ) ), window_title(), ds( s_width, s_height )
{}
void Framebuffer::scroll( int N )
@@ -311,6 +311,7 @@ void Framebuffer::reset( void )
{
int width = ds.get_width(), height = ds.get_height();
rows = std::deque<Row>( height, Row( width ) );
window_title.clear();
ds = DrawState( width, height );
}
+5
View File
@@ -3,6 +3,7 @@
#include <vector>
#include <deque>
#include <string>
/* Terminal framebuffer */
@@ -109,6 +110,7 @@ namespace Terminal {
class Framebuffer {
private:
std::deque<Row> rows;
std::vector<wchar_t> window_title;
void scroll( int N );
@@ -132,6 +134,9 @@ namespace Terminal {
void reset( void );
void soft_reset( void );
void set_window_title( std::vector<wchar_t> s ) { window_title = s; }
std::vector<wchar_t> get_window_title( void ) { return window_title; }
};
}
+17
View File
@@ -1,7 +1,9 @@
#include <unistd.h>
#include <string>
#include "terminaldispatcher.hpp"
#include "terminalframebuffer.hpp"
#include "parseraction.hpp"
using namespace Terminal;
@@ -457,3 +459,18 @@ void CSI_DECSTR( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) )
}
static Function func_CSI_DECSTR( CSI, "!p", CSI_DECSTR );
/* xterm uses an Operating System Command to set the window title */
void Dispatcher::OSC_dispatch( Parser::OSC_End *act, Framebuffer *fb )
{
if ( OSC_string.size() >= 2 ) {
if ( (OSC_string[ 0 ] == L'0')
&& (OSC_string[ 1 ] == L';') ) {
std::vector<wchar_t> newtitle = OSC_string;
newtitle.erase( newtitle.begin() );
newtitle.erase( newtitle.begin() );
fb->set_window_title( newtitle );
act->handled = true;
}
}
}