Working serial connection.
Still need some work on displaying the right chars at the right place.
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SerialApp.h"
|
||||
|
||||
#include "SerialWindow.h"
|
||||
@@ -15,7 +17,7 @@ SerialApp::SerialApp()
|
||||
{
|
||||
fWindow = new SerialWindow();
|
||||
|
||||
serialLock = create_sem(0, "Serial port lock");
|
||||
fSerialLock = create_sem(0, "Serial port lock");
|
||||
thread_id id = spawn_thread(PollSerial, "Serial port poller",
|
||||
B_LOW_PRIORITY, this);
|
||||
resume_thread(id);
|
||||
@@ -36,15 +38,25 @@ void SerialApp::MessageReceived(BMessage* message)
|
||||
{
|
||||
const char* portName;
|
||||
message->FindString("port name", &portName);
|
||||
serialPort.Open(portName);
|
||||
release_sem(serialLock);
|
||||
fSerialPort.Open(portName);
|
||||
release_sem(fSerialLock);
|
||||
break;
|
||||
}
|
||||
case kMsgDataRead:
|
||||
{
|
||||
// TODO forward to the window
|
||||
// forward the message to the window, which will display the
|
||||
// incoming data
|
||||
fWindow->PostMessage(message);
|
||||
break;
|
||||
}
|
||||
case kMsgDataWrite:
|
||||
{
|
||||
const char* bytes;
|
||||
ssize_t size;
|
||||
|
||||
message->FindData("data", B_RAW_TYPE, &(const void*)bytes, &size);
|
||||
fSerialPort.Write(bytes, size);
|
||||
}
|
||||
default:
|
||||
BApplication::MessageReceived(message);
|
||||
}
|
||||
@@ -61,16 +73,15 @@ status_t SerialApp::PollSerial(void*)
|
||||
{
|
||||
ssize_t bytesRead;
|
||||
|
||||
bytesRead = application->serialPort.Read(buffer, 256);
|
||||
bytesRead = application->fSerialPort.Read(buffer, 256);
|
||||
if (bytesRead == B_FILE_ERROR)
|
||||
{
|
||||
// Port is not open - wait for it and start over
|
||||
acquire_sem(application->serialLock);
|
||||
} else {
|
||||
acquire_sem(application->fSerialLock);
|
||||
} else if (bytesRead > 0) {
|
||||
// We read something, forward it to the app for handling
|
||||
BMessage* serialData = new BMessage(kMsgDataRead);
|
||||
// TODO bytesRead is not nul terminated. Use generic data rather
|
||||
serialData->AddString("data", buffer);
|
||||
serialData->AddData("data", B_RAW_TYPE, buffer, bytesRead);
|
||||
be_app_messenger.SendMessage(serialData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,17 +19,19 @@ class SerialApp: public BApplication
|
||||
void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
BSerialPort serialPort;
|
||||
static status_t PollSerial(void*);
|
||||
|
||||
sem_id serialLock;
|
||||
BSerialPort fSerialPort;
|
||||
sem_id fSerialLock;
|
||||
SerialWindow* fWindow;
|
||||
|
||||
static status_t PollSerial(void*);
|
||||
|
||||
static const char* kApplicationSignature;
|
||||
};
|
||||
|
||||
|
||||
enum messageConstants {
|
||||
kMsgOpenPort = 'open',
|
||||
kMsgDataRead = 'dare',
|
||||
kMsgOpenPort = 'open',
|
||||
kMsgDataRead = 'dare',
|
||||
kMsgDataWrite = 'dawr',
|
||||
};
|
||||
|
||||
|
||||
@@ -12,21 +12,22 @@
|
||||
#include <MenuItem.h>
|
||||
#include <SerialPort.h>
|
||||
|
||||
#include "SerialApp.h"
|
||||
#include "TermView.h"
|
||||
|
||||
|
||||
SerialWindow::SerialWindow()
|
||||
:
|
||||
BWindow(BRect(100, 100, 400, 400), SerialWindow::kWindowTitle,
|
||||
B_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE)
|
||||
B_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
|
||||
{
|
||||
SetLayout(new BGroupLayout(B_VERTICAL, 0.0f));
|
||||
|
||||
BMenuBar* menuBar = new BMenuBar("menuBar");
|
||||
TermView* termView = new TermView();
|
||||
fTermView = new TermView();
|
||||
|
||||
AddChild(menuBar);
|
||||
AddChild(termView);
|
||||
AddChild(fTermView);
|
||||
|
||||
BMenu* connectionMenu = new BMenu("Connections");
|
||||
BMenu* editMenu = new BMenu("Edit");
|
||||
@@ -48,7 +49,9 @@ SerialWindow::SerialWindow()
|
||||
char buffer[256];
|
||||
serialPort.GetDeviceName(i, buffer, 256);
|
||||
|
||||
BMenuItem* portItem = new BMenuItem(buffer, NULL);
|
||||
BMessage* message = new BMessage(kMsgOpenPort);
|
||||
message->AddString("port name", buffer);
|
||||
BMenuItem* portItem = new BMenuItem(buffer, message);
|
||||
|
||||
connect->AddItem(portItem);
|
||||
}
|
||||
@@ -115,4 +118,28 @@ SerialWindow::SerialWindow()
|
||||
}
|
||||
|
||||
|
||||
void SerialWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch(message->what)
|
||||
{
|
||||
case kMsgDataRead:
|
||||
{
|
||||
const char* bytes;
|
||||
ssize_t length;
|
||||
message->FindData("data", B_RAW_TYPE, &(const void*)bytes, &length);
|
||||
fTermView->PushBytes(bytes, length);
|
||||
break;
|
||||
}
|
||||
case kMsgOpenPort:
|
||||
{
|
||||
// Forward message to application
|
||||
be_app->PostMessage(message);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char* SerialWindow::kWindowTitle = "SerialConnect";
|
||||
|
||||
@@ -7,11 +7,18 @@
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
class TermView;
|
||||
|
||||
|
||||
class SerialWindow: public BWindow
|
||||
{
|
||||
public:
|
||||
SerialWindow::SerialWindow();
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
TermView* fTermView;
|
||||
|
||||
static const char* kWindowTitle;
|
||||
};
|
||||
|
||||
@@ -10,12 +10,19 @@
|
||||
|
||||
#include <Layout.h>
|
||||
|
||||
#include "SerialApp.h"
|
||||
|
||||
|
||||
TermView::TermView()
|
||||
:
|
||||
BView("TermView", B_WILL_DRAW)
|
||||
{
|
||||
font_height height;
|
||||
GetFontHeight(&height);
|
||||
fFontHeight = height.ascent + height.descent + height.leading;
|
||||
fFontWidth = be_fixed_font->StringWidth("X");
|
||||
fTerm = vterm_new(kDefaultWidth, kDefaultHeight);
|
||||
|
||||
vterm_parser_set_utf8(fTerm, 1);
|
||||
|
||||
fTermScreen = vterm_obtain_screen(fTerm);
|
||||
@@ -23,14 +30,6 @@ TermView::TermView()
|
||||
vterm_screen_reset(fTermScreen, 1);
|
||||
|
||||
SetFont(be_fixed_font);
|
||||
|
||||
font_height height;
|
||||
GetFontHeight(&height);
|
||||
fFontHeight = height.ascent + height.descent + height.leading;
|
||||
fFontWidth = be_fixed_font->StringWidth("X");
|
||||
|
||||
// TEST
|
||||
//vterm_push_bytes(fTerm,"Hello World!",11);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +39,12 @@ TermView::~TermView()
|
||||
}
|
||||
|
||||
|
||||
void TermView::AttachedToWindow()
|
||||
{
|
||||
MakeFocus();
|
||||
}
|
||||
|
||||
|
||||
void TermView::Draw(BRect updateRect)
|
||||
{
|
||||
VTermRect updatedChars = PixelsToGlyphs(updateRect);
|
||||
@@ -66,6 +71,29 @@ void TermView::Draw(BRect updateRect)
|
||||
}
|
||||
|
||||
|
||||
void TermView::GetPreferredSize(float* width, float* height)
|
||||
{
|
||||
if (width != NULL)
|
||||
*width = kDefaultWidth * fFontWidth;
|
||||
if (height != NULL)
|
||||
*height = kDefaultHeight * fFontHeight;
|
||||
}
|
||||
|
||||
|
||||
void TermView::KeyDown(const char* bytes, int32 numBytes)
|
||||
{
|
||||
BMessage* keyEvent = new BMessage(kMsgDataWrite);
|
||||
keyEvent->AddData("data", B_RAW_TYPE, bytes, numBytes);
|
||||
be_app_messenger.SendMessage(keyEvent);
|
||||
}
|
||||
|
||||
|
||||
void TermView::PushBytes(const char* bytes, size_t length)
|
||||
{
|
||||
vterm_push_bytes(fTerm, bytes, length);
|
||||
}
|
||||
|
||||
|
||||
VTermRect TermView::PixelsToGlyphs(BRect pixels) const
|
||||
{
|
||||
pixels.OffsetBy(-kBorderSpacing, -kBorderSpacing);
|
||||
@@ -76,12 +104,17 @@ VTermRect TermView::PixelsToGlyphs(BRect pixels) const
|
||||
rect.start_row = (int)floor(pixels.top / fFontHeight);
|
||||
rect.end_row = (int)ceil(pixels.bottom / fFontHeight);
|
||||
|
||||
#if 0
|
||||
printf("pixels:\t%d\t%d\t%d\t%d\n"
|
||||
"glyps:\t%d\t%d\t%d\t%d\n",
|
||||
(int)pixels.top, (int)pixels.bottom, (int)pixels.left, (int)pixels.right,
|
||||
rect.start_row, rect.end_row, rect.start_col, rect.end_col);
|
||||
#endif
|
||||
printf(
|
||||
"TOP %d ch < %f px\n"
|
||||
"BTM %d ch < %f px\n"
|
||||
"LFT %d ch < %f px\n"
|
||||
"RGH %d ch < %f px\n",
|
||||
rect.start_row, pixels.top,
|
||||
rect.end_row, pixels.bottom,
|
||||
rect.start_col, pixels.left,
|
||||
rect.end_col, pixels.right
|
||||
);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
@@ -94,6 +127,19 @@ BRect TermView::GlyphsToPixels(const VTermRect& glyphs) const
|
||||
rect.left = glyphs.start_col * fFontWidth;
|
||||
rect.right = glyphs.end_col * fFontWidth;
|
||||
|
||||
rect.OffsetBy(kBorderSpacing, kBorderSpacing);
|
||||
|
||||
printf(
|
||||
"TOP %d ch > %f px (%f)\n"
|
||||
"BTM %d ch > %f px\n"
|
||||
"LFT %d ch > %f px (%f)\n"
|
||||
"RGH %d ch > %f px\n",
|
||||
glyphs.start_row, rect.top, fFontHeight,
|
||||
glyphs.end_row, rect.bottom,
|
||||
glyphs.start_col, rect.left, fFontWidth,
|
||||
glyphs.end_col, rect.right
|
||||
);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
@@ -109,8 +155,25 @@ BRect TermView::GlyphsToPixels(const int width, const int height) const
|
||||
}
|
||||
|
||||
|
||||
void TermView::Damage(VTermRect rect)
|
||||
{
|
||||
Invalidate();
|
||||
// Invalidate(GlyphsToPixels(rect));
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
int TermView::Damage(VTermRect rect, void* user)
|
||||
{
|
||||
TermView* view = (TermView*)user;
|
||||
view->Damage(rect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const VTermScreenCallbacks TermView::sScreenCallbacks = {
|
||||
/*.damage =*/ NULL,
|
||||
&TermView::Damage,
|
||||
/*.moverect =*/ NULL,
|
||||
/*.movecursor =*/ NULL,
|
||||
/*.settermprop =*/ NULL,
|
||||
|
||||
@@ -16,12 +16,19 @@ class TermView: public BView
|
||||
TermView();
|
||||
~TermView();
|
||||
|
||||
void AttachedToWindow();
|
||||
void Draw(BRect updateRect);
|
||||
void GetPreferredSize(float* width, float* height);
|
||||
void KeyDown(const char* bytes, int32 numBytes);
|
||||
void PushBytes(const char* bytes, const size_t length);
|
||||
|
||||
private:
|
||||
VTermRect PixelsToGlyphs(BRect pixels) const;
|
||||
BRect GlyphsToPixels(const VTermRect& glyphs) const;
|
||||
BRect GlyphsToPixels(const int width, const int height) const;
|
||||
void Damage(VTermRect rect);
|
||||
|
||||
static int Damage(VTermRect rect, void* user);
|
||||
|
||||
private:
|
||||
VTerm* fTerm;
|
||||
|
||||
Reference in New Issue
Block a user