Working serial connection.

Still need some work on displaying the right chars at the right place.
This commit is contained in:
Adrien Destugues - PulkoMandy
2012-07-25 23:24:22 +02:00
parent bed0d7384b
commit f441fd03b6
6 changed files with 151 additions and 34 deletions
+20 -9
View File
@@ -4,6 +4,8 @@
*/ */
#include <stdio.h>
#include "SerialApp.h" #include "SerialApp.h"
#include "SerialWindow.h" #include "SerialWindow.h"
@@ -15,7 +17,7 @@ SerialApp::SerialApp()
{ {
fWindow = new SerialWindow(); 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", thread_id id = spawn_thread(PollSerial, "Serial port poller",
B_LOW_PRIORITY, this); B_LOW_PRIORITY, this);
resume_thread(id); resume_thread(id);
@@ -36,15 +38,25 @@ void SerialApp::MessageReceived(BMessage* message)
{ {
const char* portName; const char* portName;
message->FindString("port name", &portName); message->FindString("port name", &portName);
serialPort.Open(portName); fSerialPort.Open(portName);
release_sem(serialLock); release_sem(fSerialLock);
break; break;
} }
case kMsgDataRead: case kMsgDataRead:
{ {
// TODO forward to the window // forward the message to the window, which will display the
// incoming data
fWindow->PostMessage(message);
break; break;
} }
case kMsgDataWrite:
{
const char* bytes;
ssize_t size;
message->FindData("data", B_RAW_TYPE, &(const void*)bytes, &size);
fSerialPort.Write(bytes, size);
}
default: default:
BApplication::MessageReceived(message); BApplication::MessageReceived(message);
} }
@@ -61,16 +73,15 @@ status_t SerialApp::PollSerial(void*)
{ {
ssize_t bytesRead; ssize_t bytesRead;
bytesRead = application->serialPort.Read(buffer, 256); bytesRead = application->fSerialPort.Read(buffer, 256);
if (bytesRead == B_FILE_ERROR) if (bytesRead == B_FILE_ERROR)
{ {
// Port is not open - wait for it and start over // Port is not open - wait for it and start over
acquire_sem(application->serialLock); acquire_sem(application->fSerialLock);
} else { } else if (bytesRead > 0) {
// We read something, forward it to the app for handling // We read something, forward it to the app for handling
BMessage* serialData = new BMessage(kMsgDataRead); BMessage* serialData = new BMessage(kMsgDataRead);
// TODO bytesRead is not nul terminated. Use generic data rather serialData->AddData("data", B_RAW_TYPE, buffer, bytesRead);
serialData->AddString("data", buffer);
be_app_messenger.SendMessage(serialData); be_app_messenger.SendMessage(serialData);
} }
} }
+8 -6
View File
@@ -19,17 +19,19 @@ class SerialApp: public BApplication
void MessageReceived(BMessage* message); void MessageReceived(BMessage* message);
private: private:
BSerialPort serialPort; BSerialPort fSerialPort;
static status_t PollSerial(void*); sem_id fSerialLock;
sem_id serialLock;
SerialWindow* fWindow; SerialWindow* fWindow;
static status_t PollSerial(void*);
static const char* kApplicationSignature; static const char* kApplicationSignature;
}; };
enum messageConstants { enum messageConstants {
kMsgOpenPort = 'open', kMsgOpenPort = 'open',
kMsgDataRead = 'dare', kMsgDataRead = 'dare',
kMsgDataWrite = 'dawr',
}; };
+31 -4
View File
@@ -12,21 +12,22 @@
#include <MenuItem.h> #include <MenuItem.h>
#include <SerialPort.h> #include <SerialPort.h>
#include "SerialApp.h"
#include "TermView.h" #include "TermView.h"
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_DOCUMENT_WINDOW, B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
{ {
SetLayout(new BGroupLayout(B_VERTICAL, 0.0f)); SetLayout(new BGroupLayout(B_VERTICAL, 0.0f));
BMenuBar* menuBar = new BMenuBar("menuBar"); BMenuBar* menuBar = new BMenuBar("menuBar");
TermView* termView = new TermView(); fTermView = new TermView();
AddChild(menuBar); AddChild(menuBar);
AddChild(termView); AddChild(fTermView);
BMenu* connectionMenu = new BMenu("Connections"); BMenu* connectionMenu = new BMenu("Connections");
BMenu* editMenu = new BMenu("Edit"); BMenu* editMenu = new BMenu("Edit");
@@ -48,7 +49,9 @@ SerialWindow::SerialWindow()
char buffer[256]; char buffer[256];
serialPort.GetDeviceName(i, 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); 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"; const char* SerialWindow::kWindowTitle = "SerialConnect";
+7
View File
@@ -7,11 +7,18 @@
#include <Window.h> #include <Window.h>
class TermView;
class SerialWindow: public BWindow class SerialWindow: public BWindow
{ {
public: public:
SerialWindow::SerialWindow(); SerialWindow::SerialWindow();
void MessageReceived(BMessage* message);
private: private:
TermView* fTermView;
static const char* kWindowTitle; static const char* kWindowTitle;
}; };
+78 -15
View File
@@ -10,12 +10,19 @@
#include <Layout.h> #include <Layout.h>
#include "SerialApp.h"
TermView::TermView() TermView::TermView()
: :
BView("TermView", B_WILL_DRAW) 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); fTerm = vterm_new(kDefaultWidth, kDefaultHeight);
vterm_parser_set_utf8(fTerm, 1); vterm_parser_set_utf8(fTerm, 1);
fTermScreen = vterm_obtain_screen(fTerm); fTermScreen = vterm_obtain_screen(fTerm);
@@ -23,14 +30,6 @@ TermView::TermView()
vterm_screen_reset(fTermScreen, 1); vterm_screen_reset(fTermScreen, 1);
SetFont(be_fixed_font); 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) void TermView::Draw(BRect updateRect)
{ {
VTermRect updatedChars = PixelsToGlyphs(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 VTermRect TermView::PixelsToGlyphs(BRect pixels) const
{ {
pixels.OffsetBy(-kBorderSpacing, -kBorderSpacing); pixels.OffsetBy(-kBorderSpacing, -kBorderSpacing);
@@ -76,12 +104,17 @@ VTermRect TermView::PixelsToGlyphs(BRect pixels) const
rect.start_row = (int)floor(pixels.top / fFontHeight); rect.start_row = (int)floor(pixels.top / fFontHeight);
rect.end_row = (int)ceil(pixels.bottom / fFontHeight); rect.end_row = (int)ceil(pixels.bottom / fFontHeight);
#if 0 printf(
printf("pixels:\t%d\t%d\t%d\t%d\n" "TOP %d ch < %f px\n"
"glyps:\t%d\t%d\t%d\t%d\n", "BTM %d ch < %f px\n"
(int)pixels.top, (int)pixels.bottom, (int)pixels.left, (int)pixels.right, "LFT %d ch < %f px\n"
rect.start_row, rect.end_row, rect.start_col, rect.end_col); "RGH %d ch < %f px\n",
#endif rect.start_row, pixels.top,
rect.end_row, pixels.bottom,
rect.start_col, pixels.left,
rect.end_col, pixels.right
);
return rect; return rect;
} }
@@ -94,6 +127,19 @@ BRect TermView::GlyphsToPixels(const VTermRect& glyphs) const
rect.left = glyphs.start_col * fFontWidth; rect.left = glyphs.start_col * fFontWidth;
rect.right = glyphs.end_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; 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 = { const VTermScreenCallbacks TermView::sScreenCallbacks = {
/*.damage =*/ NULL, &TermView::Damage,
/*.moverect =*/ NULL, /*.moverect =*/ NULL,
/*.movecursor =*/ NULL, /*.movecursor =*/ NULL,
/*.settermprop =*/ NULL, /*.settermprop =*/ NULL,
+7
View File
@@ -16,12 +16,19 @@ class TermView: public BView
TermView(); TermView();
~TermView(); ~TermView();
void AttachedToWindow();
void Draw(BRect updateRect); 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: private:
VTermRect PixelsToGlyphs(BRect pixels) const; VTermRect PixelsToGlyphs(BRect pixels) const;
BRect GlyphsToPixels(const VTermRect& glyphs) const; BRect GlyphsToPixels(const VTermRect& glyphs) const;
BRect GlyphsToPixels(const int width, const int height) const; BRect GlyphsToPixels(const int width, const int height) const;
void Damage(VTermRect rect);
static int Damage(VTermRect rect, void* user);
private: private:
VTerm* fTerm; VTerm* fTerm;