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 "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);
}
}
+8 -6
View File
@@ -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',
};
+31 -4
View File
@@ -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
View File
@@ -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;
};
+78 -15
View File
@@ -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,
+7
View File
@@ -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;