Make SerialConnect more complete
* Mark the current connected device, or disable "Disconnect" menu when there is no connection. * Save and restore serial port settings * Improve drawing code: make sure the border around the termview is repainted, and do not leave a 1px space between lines unpainted.
This commit is contained in:
@@ -12,6 +12,8 @@
|
|||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
#include "SerialWindow.h"
|
#include "SerialWindow.h"
|
||||||
|
|
||||||
@@ -37,6 +39,7 @@ SerialApp::~SerialApp()
|
|||||||
|
|
||||||
void SerialApp::ReadyToRun()
|
void SerialApp::ReadyToRun()
|
||||||
{
|
{
|
||||||
|
LoadSettings();
|
||||||
fWindow->Show();
|
fWindow->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +50,9 @@ void SerialApp::MessageReceived(BMessage* message)
|
|||||||
{
|
{
|
||||||
case kMsgOpenPort:
|
case kMsgOpenPort:
|
||||||
{
|
{
|
||||||
const char* portName;
|
if(message->FindString("port name", &fPortPath) == B_OK)
|
||||||
if(message->FindString("port name", &portName) == B_OK)
|
|
||||||
{
|
{
|
||||||
fSerialPort.Open(portName);
|
fSerialPort.Open(fPortPath);
|
||||||
release_sem(fSerialLock);
|
release_sem(fSerialLock);
|
||||||
} else {
|
} else {
|
||||||
fSerialPort.Close();
|
fSerialPort.Close();
|
||||||
@@ -207,6 +209,62 @@ void SerialApp::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SerialApp::QuitRequested()
|
||||||
|
{
|
||||||
|
if(BApplication::QuitRequested()) {
|
||||||
|
SaveSettings();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BString& SerialApp::GetPort()
|
||||||
|
{
|
||||||
|
return fPortPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SerialApp::LoadSettings()
|
||||||
|
{
|
||||||
|
BPath path;
|
||||||
|
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||||
|
path.Append("SerialConnect");
|
||||||
|
|
||||||
|
BFile file(path.Path(), B_READ_ONLY);
|
||||||
|
BMessage message(kMsgSettings);
|
||||||
|
if(message.Unflatten(&file) != B_OK)
|
||||||
|
{
|
||||||
|
message.AddInt32("parity", fSerialPort.ParityMode());
|
||||||
|
message.AddInt32("databits", fSerialPort.DataBits());
|
||||||
|
message.AddInt32("stopbits", fSerialPort.StopBits());
|
||||||
|
message.AddInt32("baudrate", fSerialPort.DataRate());
|
||||||
|
message.AddInt32("flowcontrol", fSerialPort.FlowControl());
|
||||||
|
}
|
||||||
|
|
||||||
|
be_app->PostMessage(&message);
|
||||||
|
fWindow->PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SerialApp::SaveSettings()
|
||||||
|
{
|
||||||
|
BMessage message(kMsgSettings);
|
||||||
|
message.AddInt32("parity", fSerialPort.ParityMode());
|
||||||
|
message.AddInt32("databits", fSerialPort.DataBits());
|
||||||
|
message.AddInt32("stopbits", fSerialPort.StopBits());
|
||||||
|
message.AddInt32("baudrate", fSerialPort.DataRate());
|
||||||
|
message.AddInt32("flowcontrol", fSerialPort.FlowControl());
|
||||||
|
|
||||||
|
BPath path;
|
||||||
|
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||||
|
path.Append("SerialConnect");
|
||||||
|
|
||||||
|
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
||||||
|
message.Flatten(&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
status_t SerialApp::PollSerial(void*)
|
status_t SerialApp::PollSerial(void*)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <SerialPort.h>
|
#include <SerialPort.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
class BFile;
|
class BFile;
|
||||||
@@ -23,12 +24,20 @@ class SerialApp: public BApplication
|
|||||||
~SerialApp();
|
~SerialApp();
|
||||||
void ReadyToRun();
|
void ReadyToRun();
|
||||||
void MessageReceived(BMessage* message);
|
void MessageReceived(BMessage* message);
|
||||||
|
bool QuitRequested();
|
||||||
|
|
||||||
|
const BString& GetPort();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void LoadSettings();
|
||||||
|
void SaveSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BSerialPort fSerialPort;
|
BSerialPort fSerialPort;
|
||||||
sem_id fSerialLock;
|
sem_id fSerialLock;
|
||||||
SerialWindow* fWindow;
|
SerialWindow* fWindow;
|
||||||
BFile* fLogFile;
|
BFile* fLogFile;
|
||||||
|
BString fPortPath;
|
||||||
|
|
||||||
static status_t PollSerial(void*);
|
static status_t PollSerial(void*);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,14 @@
|
|||||||
#include "TermView.h"
|
#include "TermView.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int SerialWindow::kBaudrates[] = { 50, 75, 110, 134, 150, 200, 300, 600,
|
||||||
|
1200, 1800, 2400, 4800, 9600, 19200, 31250, 38400, 57600, 115200, 230400
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char* SerialWindow::kWindowTitle = "SerialConnect";
|
||||||
|
|
||||||
|
|
||||||
SerialWindow::SerialWindow()
|
SerialWindow::SerialWindow()
|
||||||
: BWindow(BRect(100, 100, 400, 400), SerialWindow::kWindowTitle,
|
: BWindow(BRect(100, 100, 400, 400), SerialWindow::kWindowTitle,
|
||||||
B_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
|
B_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
|
||||||
@@ -49,34 +57,37 @@ SerialWindow::SerialWindow()
|
|||||||
BMenuItem* logFile = new BMenuItem("Log to file" B_UTF8_ELLIPSIS,
|
BMenuItem* logFile = new BMenuItem("Log to file" B_UTF8_ELLIPSIS,
|
||||||
new BMessage(kMsgLogfile));
|
new BMessage(kMsgLogfile));
|
||||||
fileMenu->AddItem(logFile);
|
fileMenu->AddItem(logFile);
|
||||||
|
#if 0
|
||||||
|
// TODO implement these
|
||||||
BMenuItem* xmodemSend = new BMenuItem("X/Y/ZModem send" B_UTF8_ELLIPSIS,
|
BMenuItem* xmodemSend = new BMenuItem("X/Y/ZModem send" B_UTF8_ELLIPSIS,
|
||||||
NULL);
|
NULL);
|
||||||
fileMenu->AddItem(xmodemSend);
|
fileMenu->AddItem(xmodemSend);
|
||||||
BMenuItem* xmodemReceive = new BMenuItem(
|
BMenuItem* xmodemReceive = new BMenuItem(
|
||||||
"X/Y/Zmodem receive" B_UTF8_ELLIPSIS, NULL);
|
"X/Y/Zmodem receive" B_UTF8_ELLIPSIS, NULL);
|
||||||
fileMenu->AddItem(xmodemReceive);
|
fileMenu->AddItem(xmodemReceive);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Configuring all this by menus may be a bit unhandy. Make a setting
|
// Configuring all this by menus may be a bit unhandy. Make a setting
|
||||||
// window instead ?
|
// window instead ?
|
||||||
BMenu* baudRate = new BMenu("Baud rate");
|
fBaudrateMenu = new BMenu("Baud rate");
|
||||||
baudRate->SetRadioMode(true);
|
fBaudrateMenu->SetRadioMode(true);
|
||||||
settingsMenu->AddItem(baudRate);
|
settingsMenu->AddItem(fBaudrateMenu);
|
||||||
|
|
||||||
BMenu* parity = new BMenu("Parity");
|
fParityMenu = new BMenu("Parity");
|
||||||
parity->SetRadioMode(true);
|
fParityMenu->SetRadioMode(true);
|
||||||
settingsMenu->AddItem(parity);
|
settingsMenu->AddItem(fParityMenu);
|
||||||
|
|
||||||
BMenu* stopBits = new BMenu("Stop bits");
|
fStopbitsMenu = new BMenu("Stop bits");
|
||||||
stopBits->SetRadioMode(true);
|
fStopbitsMenu->SetRadioMode(true);
|
||||||
settingsMenu->AddItem(stopBits);
|
settingsMenu->AddItem(fStopbitsMenu);
|
||||||
|
|
||||||
BMenu* flowControl = new BMenu("Flow control");
|
fFlowcontrolMenu = new BMenu("Flow control");
|
||||||
flowControl->SetRadioMode(true);
|
fFlowcontrolMenu->SetRadioMode(true);
|
||||||
settingsMenu->AddItem(flowControl);
|
settingsMenu->AddItem(fFlowcontrolMenu);
|
||||||
|
|
||||||
BMenu* dataBits = new BMenu("Data bits");
|
fDatabitsMenu = new BMenu("Data bits");
|
||||||
dataBits->SetRadioMode(true);
|
fDatabitsMenu->SetRadioMode(true);
|
||||||
settingsMenu->AddItem(dataBits);
|
settingsMenu->AddItem(fDatabitsMenu);
|
||||||
|
|
||||||
|
|
||||||
BMessage* message = new BMessage(kMsgSettings);
|
BMessage* message = new BMessage(kMsgSettings);
|
||||||
@@ -90,12 +101,11 @@ SerialWindow::SerialWindow()
|
|||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("parity", B_EVEN_PARITY);
|
message->AddInt32("parity", B_EVEN_PARITY);
|
||||||
BMenuItem* parityEven = new BMenuItem("Even", message);
|
BMenuItem* parityEven = new BMenuItem("Even", message);
|
||||||
parityNone->SetMarked(true);
|
|
||||||
|
|
||||||
parity->AddItem(parityNone);
|
fParityMenu->AddItem(parityNone);
|
||||||
parity->AddItem(parityOdd);
|
fParityMenu->AddItem(parityOdd);
|
||||||
parity->AddItem(parityEven);
|
fParityMenu->AddItem(parityEven);
|
||||||
parity->SetTargetForItems(be_app);
|
fParityMenu->SetTargetForItems(be_app);
|
||||||
|
|
||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("databits", B_DATA_BITS_7);
|
message->AddInt32("databits", B_DATA_BITS_7);
|
||||||
@@ -104,52 +114,41 @@ SerialWindow::SerialWindow()
|
|||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("databits", B_DATA_BITS_8);
|
message->AddInt32("databits", B_DATA_BITS_8);
|
||||||
BMenuItem* data8 = new BMenuItem("8", message);
|
BMenuItem* data8 = new BMenuItem("8", message);
|
||||||
data8->SetMarked(true);
|
|
||||||
|
|
||||||
dataBits->AddItem(data7);
|
fDatabitsMenu->AddItem(data7);
|
||||||
dataBits->AddItem(data8);
|
fDatabitsMenu->AddItem(data8);
|
||||||
dataBits->SetTargetForItems(be_app);
|
fDatabitsMenu->SetTargetForItems(be_app);
|
||||||
|
|
||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("stopbits", B_STOP_BITS_1);
|
message->AddInt32("stopbits", B_STOP_BITS_1);
|
||||||
BMenuItem* stop1 = new BMenuItem("1", NULL);
|
BMenuItem* stop1 = new BMenuItem("1", message);
|
||||||
|
|
||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("stopbits", B_STOP_BITS_2);
|
message->AddInt32("stopbits", B_STOP_BITS_2);
|
||||||
BMenuItem* stop2 = new BMenuItem("2", NULL);
|
BMenuItem* stop2 = new BMenuItem("2", message);
|
||||||
stop1->SetMarked(true);
|
|
||||||
|
|
||||||
stopBits->AddItem(stop1);
|
fStopbitsMenu->AddItem(stop1);
|
||||||
stopBits->AddItem(stop2);
|
fStopbitsMenu->AddItem(stop2);
|
||||||
stopBits->SetTargetForItems(be_app);
|
fStopbitsMenu->SetTargetForItems(be_app);
|
||||||
|
|
||||||
static const int baudrates[] = { 50, 75, 110, 134, 150, 200, 300, 600,
|
|
||||||
1200, 1800, 2400, 4800, 9600, 19200, 31250, 38400, 57600, 115200,
|
|
||||||
230400
|
|
||||||
};
|
|
||||||
|
|
||||||
// Loop backwards to add fastest rates at top of menu
|
// Loop backwards to add fastest rates at top of menu
|
||||||
for (int i = sizeof(baudrates) / sizeof(char*); --i >= 0;)
|
for (int i = sizeof(kBaudrates) / sizeof(char*); --i >= 0;)
|
||||||
{
|
{
|
||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("baudrate", baudrates[i]);
|
message->AddInt32("baudrate", kBaudrates[i]);
|
||||||
|
|
||||||
char buffer[7];
|
char buffer[7];
|
||||||
sprintf(buffer,"%d", baudrates[i]);
|
sprintf(buffer,"%d", kBaudrates[i]);
|
||||||
BMenuItem* item = new BMenuItem(buffer, message);
|
BMenuItem* item = new BMenuItem(buffer, message);
|
||||||
|
|
||||||
if (baudrates[i] == 19200)
|
fBaudrateMenu->AddItem(item);
|
||||||
item->SetMarked(true);
|
|
||||||
|
|
||||||
baudRate->AddItem(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
baudRate->SetTargetForItems(be_app);
|
fBaudrateMenu->SetTargetForItems(be_app);
|
||||||
|
|
||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("flowcontrol", B_HARDWARE_CONTROL);
|
message->AddInt32("flowcontrol", B_HARDWARE_CONTROL);
|
||||||
BMenuItem* hardware = new BMenuItem("Hardware", message);
|
BMenuItem* hardware = new BMenuItem("Hardware", message);
|
||||||
hardware->SetMarked(true);
|
|
||||||
|
|
||||||
message = new BMessage(kMsgSettings);
|
message = new BMessage(kMsgSettings);
|
||||||
message->AddInt32("flowcontrol", B_SOFTWARE_CONTROL);
|
message->AddInt32("flowcontrol", B_SOFTWARE_CONTROL);
|
||||||
@@ -163,11 +162,11 @@ SerialWindow::SerialWindow()
|
|||||||
message->AddInt32("flowcontrol", 0);
|
message->AddInt32("flowcontrol", 0);
|
||||||
BMenuItem* noFlow = new BMenuItem("None", message);
|
BMenuItem* noFlow = new BMenuItem("None", message);
|
||||||
|
|
||||||
flowControl->AddItem(hardware);
|
fFlowcontrolMenu->AddItem(hardware);
|
||||||
flowControl->AddItem(software);
|
fFlowcontrolMenu->AddItem(software);
|
||||||
flowControl->AddItem(both);
|
fFlowcontrolMenu->AddItem(both);
|
||||||
flowControl->AddItem(noFlow);
|
fFlowcontrolMenu->AddItem(noFlow);
|
||||||
flowControl->SetTargetForItems(be_app);
|
fFlowcontrolMenu->SetTargetForItems(be_app);
|
||||||
|
|
||||||
CenterOnScreen();
|
CenterOnScreen();
|
||||||
}
|
}
|
||||||
@@ -188,6 +187,7 @@ void SerialWindow::MenusBeginning()
|
|||||||
// fill it with the (updated) serial port list
|
// fill it with the (updated) serial port list
|
||||||
BSerialPort serialPort;
|
BSerialPort serialPort;
|
||||||
int deviceCount = serialPort.CountDevices();
|
int deviceCount = serialPort.CountDevices();
|
||||||
|
bool connected = false;
|
||||||
|
|
||||||
for(int i = 0; i < deviceCount; i++)
|
for(int i = 0; i < deviceCount; i++)
|
||||||
{
|
{
|
||||||
@@ -199,6 +199,13 @@ void SerialWindow::MenusBeginning()
|
|||||||
BMenuItem* portItem = new BMenuItem(buffer, message);
|
BMenuItem* portItem = new BMenuItem(buffer, message);
|
||||||
portItem->SetTarget(be_app);
|
portItem->SetTarget(be_app);
|
||||||
|
|
||||||
|
const BString& connectedPort = ((SerialApp*)be_app)->GetPort();
|
||||||
|
|
||||||
|
if(connectedPort == buffer) {
|
||||||
|
connected = true;
|
||||||
|
portItem->SetMarked(true);
|
||||||
|
}
|
||||||
|
|
||||||
fConnectionMenu->AddItem(portItem);
|
fConnectionMenu->AddItem(portItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +214,8 @@ void SerialWindow::MenusBeginning()
|
|||||||
|
|
||||||
BMenuItem* disconnect = new BMenuItem("Disconnect",
|
BMenuItem* disconnect = new BMenuItem("Disconnect",
|
||||||
new BMessage(kMsgOpenPort), 'Z', B_OPTION_KEY);
|
new BMessage(kMsgOpenPort), 'Z', B_OPTION_KEY);
|
||||||
|
if(!connected)
|
||||||
|
disconnect->SetEnabled(false);
|
||||||
fConnectionMenu->AddItem(disconnect);
|
fConnectionMenu->AddItem(disconnect);
|
||||||
} else {
|
} else {
|
||||||
BMenuItem* noDevices = new BMenuItem("<no serial port available>", NULL);
|
BMenuItem* noDevices = new BMenuItem("<no serial port available>", NULL);
|
||||||
@@ -246,10 +255,82 @@ void SerialWindow::MessageReceived(BMessage* message)
|
|||||||
fLogFilePanel->Show();
|
fLogFilePanel->Show();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case kMsgSettings:
|
||||||
|
{
|
||||||
|
int32 baudrate;
|
||||||
|
stop_bits stopBits;
|
||||||
|
data_bits dataBits;
|
||||||
|
parity_mode parity;
|
||||||
|
uint32 flowcontrol;
|
||||||
|
|
||||||
|
if(message->FindInt32("databits", (int32*)&dataBits) == B_OK)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < fDatabitsMenu->CountItems(); i++)
|
||||||
|
{
|
||||||
|
BMenuItem* item = fDatabitsMenu->ItemAt(i);
|
||||||
|
int32 code;
|
||||||
|
item->Message()->FindInt32("databits", &code);
|
||||||
|
|
||||||
|
if(code == dataBits)
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message->FindInt32("stopbits", (int32*)&stopBits) == B_OK)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < fStopbitsMenu->CountItems(); i++)
|
||||||
|
{
|
||||||
|
BMenuItem* item = fStopbitsMenu->ItemAt(i);
|
||||||
|
int32 code;
|
||||||
|
item->Message()->FindInt32("stopbits", &code);
|
||||||
|
|
||||||
|
if(code == stopBits)
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message->FindInt32("parity", (int32*)&parity) == B_OK)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < fParityMenu->CountItems(); i++)
|
||||||
|
{
|
||||||
|
BMenuItem* item = fParityMenu->ItemAt(i);
|
||||||
|
int32 code;
|
||||||
|
item->Message()->FindInt32("parity", &code);
|
||||||
|
|
||||||
|
if(code == parity)
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message->FindInt32("flowcontrol", (int32*)&flowcontrol) == B_OK)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < fFlowcontrolMenu->CountItems(); i++)
|
||||||
|
{
|
||||||
|
BMenuItem* item = fFlowcontrolMenu->ItemAt(i);
|
||||||
|
int32 code;
|
||||||
|
item->Message()->FindInt32("flowcontrol", &code);
|
||||||
|
|
||||||
|
if(code == (int32)flowcontrol)
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message->FindInt32("baudrate", &baudrate) == B_OK)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < fBaudrateMenu->CountItems(); i++)
|
||||||
|
{
|
||||||
|
BMenuItem* item = fBaudrateMenu->ItemAt(i);
|
||||||
|
int32 code;
|
||||||
|
item->Message()->FindInt32("baudrate", &code);
|
||||||
|
|
||||||
|
if(code == kBaudrates[baudrate])
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(message);
|
BWindow::MessageReceived(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* SerialWindow::kWindowTitle = "SerialConnect";
|
|
||||||
|
|||||||
@@ -23,7 +23,13 @@ class SerialWindow: public BWindow
|
|||||||
private:
|
private:
|
||||||
TermView* fTermView;
|
TermView* fTermView;
|
||||||
BMenu* fConnectionMenu;
|
BMenu* fConnectionMenu;
|
||||||
|
BMenu* fDatabitsMenu;
|
||||||
|
BMenu* fStopbitsMenu;
|
||||||
|
BMenu* fParityMenu;
|
||||||
|
BMenu* fFlowcontrolMenu;
|
||||||
|
BMenu* fBaudrateMenu;
|
||||||
BFilePanel* fLogFilePanel;
|
BFilePanel* fLogFilePanel;
|
||||||
|
|
||||||
|
static const int kBaudrates[];
|
||||||
static const char* kWindowTitle;
|
static const char* kWindowTitle;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,19 +19,19 @@ TermView::TermView()
|
|||||||
:
|
:
|
||||||
BView("TermView", B_WILL_DRAW | B_FRAME_EVENTS)
|
BView("TermView", B_WILL_DRAW | B_FRAME_EVENTS)
|
||||||
{
|
{
|
||||||
|
SetFont(be_fixed_font);
|
||||||
|
|
||||||
font_height height;
|
font_height height;
|
||||||
GetFontHeight(&height);
|
GetFontHeight(&height);
|
||||||
fFontHeight = height.ascent + height.descent + height.leading;
|
fFontHeight = height.ascent + height.descent + height.leading;
|
||||||
fFontWidth = be_fixed_font->StringWidth("X");
|
fFontWidth = be_fixed_font->StringWidth("X");
|
||||||
fTerm = vterm_new(kDefaultHeight, kDefaultWidth);
|
fTerm = vterm_new(kDefaultHeight, kDefaultWidth);
|
||||||
|
|
||||||
vterm_parser_set_utf8(fTerm, 1);
|
|
||||||
|
|
||||||
fTermScreen = vterm_obtain_screen(fTerm);
|
fTermScreen = vterm_obtain_screen(fTerm);
|
||||||
vterm_screen_set_callbacks(fTermScreen, &sScreenCallbacks, this);
|
vterm_screen_set_callbacks(fTermScreen, &sScreenCallbacks, this);
|
||||||
vterm_screen_reset(fTermScreen, 1);
|
vterm_screen_reset(fTermScreen, 1);
|
||||||
|
|
||||||
SetFont(be_fixed_font);
|
vterm_parser_set_utf8(fTerm, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -61,52 +61,60 @@ void TermView::Draw(BRect updateRect)
|
|||||||
for (pos.row = updatedChars.start_row; pos.row <= updatedChars.end_row;
|
for (pos.row = updatedChars.start_row; pos.row <= updatedChars.end_row;
|
||||||
pos.row++) {
|
pos.row++) {
|
||||||
float x = updatedChars.start_col * fFontWidth + kBorderSpacing;
|
float x = updatedChars.start_col * fFontWidth + kBorderSpacing;
|
||||||
float y = pos.row * fFontHeight + height.ascent + kBorderSpacing;
|
float y = pos.row * fFontHeight + height.ascent + kBorderSpacing + 1;
|
||||||
MovePenTo(x, y);
|
MovePenTo(x, y);
|
||||||
|
|
||||||
for (pos.col = updatedChars.start_col;
|
for (pos.col = updatedChars.start_col;
|
||||||
pos.col <= updatedChars.end_col;) {
|
pos.col <= updatedChars.end_col;) {
|
||||||
|
VTermScreenCell cell;
|
||||||
|
|
||||||
if (pos.col < 0 || pos.row < 0 || pos.col >= availableCols
|
if (pos.col < 0 || pos.row < 0 || pos.col >= availableCols
|
||||||
|| pos.row >= availableRows) {
|
|| pos.row >= availableRows) {
|
||||||
|
|
||||||
|
// All cells outside the used terminal area are drawn with the
|
||||||
|
// same background color as the top-left one.
|
||||||
|
VTermPos firstPos;
|
||||||
|
firstPos.row = 0;
|
||||||
|
firstPos.col = 0;
|
||||||
|
vterm_screen_get_cell(fTermScreen, firstPos, &cell);
|
||||||
|
cell.chars[0] = 0;
|
||||||
|
cell.width = 1;
|
||||||
|
} else
|
||||||
|
vterm_screen_get_cell(fTermScreen, pos, &cell);
|
||||||
|
|
||||||
|
rgb_color foreground, background;
|
||||||
|
foreground.red = cell.fg.red;
|
||||||
|
foreground.green = cell.fg.green;
|
||||||
|
foreground.blue = cell.fg.blue;
|
||||||
|
background.red = cell.bg.red;
|
||||||
|
background.green = cell.bg.green;
|
||||||
|
background.blue = cell.bg.blue;
|
||||||
|
|
||||||
|
if(cell.attrs.reverse) {
|
||||||
|
SetLowColor(foreground);
|
||||||
|
SetViewColor(foreground);
|
||||||
|
SetHighColor(background);
|
||||||
|
} else {
|
||||||
|
SetLowColor(background);
|
||||||
|
SetViewColor(background);
|
||||||
|
SetHighColor(foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPoint penLocation = PenLocation();
|
||||||
|
FillRect(BRect(penLocation.x, penLocation.y - height.ascent,
|
||||||
|
penLocation.x + cell.width * fFontWidth, penLocation.y + 1),
|
||||||
|
B_SOLID_LOW);
|
||||||
|
|
||||||
|
if (cell.chars[0] == 0) {
|
||||||
DrawString(" ");
|
DrawString(" ");
|
||||||
pos.col ++;
|
pos.col ++;
|
||||||
} else {
|
} else {
|
||||||
VTermScreenCell cell;
|
char buffer[VTERM_MAX_CHARS_PER_CELL];
|
||||||
vterm_screen_get_cell(fTermScreen, pos, &cell);
|
wcstombs(buffer, (wchar_t*)cell.chars,
|
||||||
|
|
||||||
rgb_color foreground, background;
|
|
||||||
foreground.red = cell.fg.red;
|
|
||||||
foreground.green = cell.fg.green;
|
|
||||||
foreground.blue = cell.fg.blue;
|
|
||||||
background.red = cell.bg.red;
|
|
||||||
background.green = cell.bg.green;
|
|
||||||
background.blue = cell.bg.blue;
|
|
||||||
|
|
||||||
if(cell.attrs.reverse) {
|
|
||||||
SetLowColor(foreground);
|
|
||||||
SetViewColor(foreground);
|
|
||||||
SetHighColor(background);
|
|
||||||
} else {
|
|
||||||
SetLowColor(background);
|
|
||||||
SetViewColor(background);
|
|
||||||
SetHighColor(foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
BPoint penLocation = PenLocation();
|
|
||||||
FillRect(BRect(penLocation.x, penLocation.y - height.ascent,
|
|
||||||
penLocation.x + cell.width * fFontWidth, penLocation.y), B_SOLID_LOW);
|
|
||||||
|
|
||||||
if (cell.chars[0] == 0) {
|
|
||||||
DrawString(" ");
|
|
||||||
pos.col ++;
|
|
||||||
} else {
|
|
||||||
char buffer[VTERM_MAX_CHARS_PER_CELL];
|
|
||||||
wcstombs(buffer, (wchar_t*)cell.chars,
|
|
||||||
VTERM_MAX_CHARS_PER_CELL);
|
VTERM_MAX_CHARS_PER_CELL);
|
||||||
|
|
||||||
DrawString(buffer);
|
DrawString(buffer);
|
||||||
pos.col += cell.width;
|
pos.col += cell.width;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +124,7 @@ void TermView::Draw(BRect updateRect)
|
|||||||
void TermView::FrameResized(float width, float height)
|
void TermView::FrameResized(float width, float height)
|
||||||
{
|
{
|
||||||
VTermRect newSize = PixelsToGlyphs(BRect(0, 0, width - 2 * kBorderSpacing,
|
VTermRect newSize = PixelsToGlyphs(BRect(0, 0, width - 2 * kBorderSpacing,
|
||||||
height - 2 * kBorderSpacing));
|
height - 2 * kBorderSpacing));
|
||||||
vterm_set_size(fTerm, newSize.end_row, newSize.end_col);
|
vterm_set_size(fTerm, newSize.end_row, newSize.end_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user