diff --git a/src/apps/serialconnect/SerialApp.cpp b/src/apps/serialconnect/SerialApp.cpp index d28958539c..dfce199680 100644 --- a/src/apps/serialconnect/SerialApp.cpp +++ b/src/apps/serialconnect/SerialApp.cpp @@ -18,6 +18,49 @@ #include "SerialWindow.h" +static property_info sProperties[] = { + { "baudrate", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 }, + "get or set the baudrate", + 0, { B_INT32_TYPE } + }, + { "bits", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 }, + "get or set the number of data bits (7 or 8)", + 0, { B_INT32_TYPE } + }, + { "stopbits", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 }, + "get or set the number of stop bits (1 or 2)", + 0, { B_INT32_TYPE } + }, + { "parity", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 }, + "get or set the parity (none, even or odd)", + 0, { B_STRING_TYPE } + }, + { "flowcontrol", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, B_DIRECT_SPECIFIER, 0 }, + "get or set the flow control (hardware, software, both, or none)", + 0, { B_STRING_TYPE } + }, + { "port", + { B_GET_PROPERTY, B_SET_PROPERTY, B_DELETE_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "get or set the port device", + 0, { B_STRING_TYPE } + }, + { NULL } +}; + +const BPropertyInfo SerialApp::kScriptingProperties(sProperties); + + SerialApp::SerialApp() : BApplication(SerialApp::kApplicationSignature) , fLogFile(NULL) @@ -55,7 +98,7 @@ void SerialApp::MessageReceived(BMessage* message) } else { fSerialPort.Close(); } - break; + return; } case kMsgDataRead: { @@ -68,13 +111,12 @@ void SerialApp::MessageReceived(BMessage* message) ssize_t length; message->FindData("data", B_RAW_TYPE, (const void**)&bytes, &length); - if (fLogFile->Write(bytes, length) != length) - { + if (fLogFile->Write(bytes, length) != length) { // TODO error handling } } - break; + return; } case kMsgDataWrite: { @@ -82,11 +124,9 @@ void SerialApp::MessageReceived(BMessage* message) ssize_t size; if (message->FindData("data", B_RAW_TYPE, (const void**)&bytes, - &size) != B_OK) - break; - - fSerialPort.Write(bytes, size); - break; + &size) == B_OK) + fSerialPort.Write(bytes, size); + return; } case kMsgLogfile: { @@ -104,7 +144,7 @@ void SerialApp::MessageReceived(BMessage* message) puts(strerror(error)); } else debugger("Invalid BMessage received"); - break; + return; } case kMsgSettings: { @@ -131,11 +171,134 @@ void SerialApp::MessageReceived(BMessage* message) fSerialPort.SetDataRate(rate); } - break; + return; } - default: - BApplication::MessageReceived(message); } + + // Handle scripting messages + if (message->HasSpecifiers()) { + BMessage specifier; + int32 what; + int32 index; + const char* property; + + BMessage reply(B_REPLY); + BMessage settings(kMsgSettings); + bool settingsChanged = false; + + if (message->GetCurrentSpecifier(&index, &specifier, &what, &property) + == B_OK) { + switch (kScriptingProperties.FindMatch(message, index, &specifier, + what, property)) { + case 0: // baudrate + if (message->what == B_GET_PROPERTY) { + reply.AddInt32("result", fSerialPort.DataRate()); + message->SendReply(&reply); + return; + } + if (message->what == B_SET_PROPERTY) { + int32 rate = message->FindInt32("data"); + settingsChanged = true; + settings.AddInt32("baudrate", rate); + } + break; + case 1: // data bits + if (message->what == B_GET_PROPERTY) { + reply.AddInt32("result", fSerialPort.DataBits() + 7); + message->SendReply(&reply); + return; + } + if (message->what == B_SET_PROPERTY) { + int32 bits = message->FindInt32("data"); + settingsChanged = true; + settings.AddInt32("databits", bits - 7); + } + break; + case 2: // stop bits + if (message->what == B_GET_PROPERTY) { + reply.AddInt32("result", fSerialPort.StopBits() + 1); + message->SendReply(&reply); + return; + } + if (message->what == B_SET_PROPERTY) { + int32 bits = message->FindInt32("data"); + settingsChanged = true; + settings.AddInt32("stopbits", bits - 1); + } + break; + case 3: // parity + { + static const char* strings[] = {"none", "odd", "even"}; + if (message->what == B_GET_PROPERTY) { + reply.AddString("result", + strings[fSerialPort.ParityMode()]); + message->SendReply(&reply); + return; + } + if (message->what == B_SET_PROPERTY) { + BString bits = message->FindString("data"); + int i; + for (i = 0; i < 3; i++) { + if (bits == strings[i]) + break; + } + + if (i < 3) { + settingsChanged = true; + settings.AddInt32("parity", i); + } + } + break; + } + case 4: // flow control + { + static const char* strings[] = {"none", "hardware", + "software", "both"}; + if (message->what == B_GET_PROPERTY) { + reply.AddString("result", + strings[fSerialPort.FlowControl()]); + message->SendReply(&reply); + return; + } + if (message->what == B_SET_PROPERTY) { + BString bits = message->FindString("data"); + int i; + for (i = 0; i < 4; i++) { + if (bits == strings[i]) + break; + } + + if (i < 4) { + settingsChanged = true; + settings.AddInt32("flowcontrol", i); + } + } + break; + } + case 5: // port + if (message->what == B_GET_PROPERTY) { + reply.AddString("port", GetPort()); + message->SendReply(&reply); + } else if (message->what == B_DELETE_PROPERTY + || message->what == B_SET_PROPERTY) { + BString path = message->FindString("data"); + BMessage openMessage(kMsgOpenPort); + openMessage.AddString("port name", path); + PostMessage(&openMessage); + fWindow->PostMessage(&openMessage); + } + return; + } + } + + if (settingsChanged) { + PostMessage(&settings); + fWindow->PostMessage(&settings); + return; + } + } + + BApplication::MessageReceived(message); } @@ -229,3 +392,25 @@ int main(int argc, char** argv) SerialApp app; app.Run(); } + + +status_t +SerialApp::GetSupportedSuites(BMessage* message) +{ + message->AddString("suites", "suite/vnd.Haiku-SerialPort"); + message->AddFlat("messages", &kScriptingProperties); + return BApplication::GetSupportedSuites(message); +} + + +BHandler* +SerialApp::ResolveSpecifier(BMessage* message, int32 index, + BMessage* specifier, int32 what, const char* property) +{ + if (kScriptingProperties.FindMatch(message, index, specifier, what, + property) >= 0) + return this; + + return BApplication::ResolveSpecifier(message, index, specifier, what, + property); +} diff --git a/src/apps/serialconnect/SerialApp.h b/src/apps/serialconnect/SerialApp.h index 33bee0b44a..03f83d713e 100644 --- a/src/apps/serialconnect/SerialApp.h +++ b/src/apps/serialconnect/SerialApp.h @@ -9,6 +9,7 @@ #include +#include #include #include @@ -20,28 +21,33 @@ class SerialWindow; class SerialApp: public BApplication { public: - SerialApp(); - ~SerialApp(); - void ReadyToRun(); - void MessageReceived(BMessage* message); - bool QuitRequested(); + SerialApp(); + ~SerialApp(); + void ReadyToRun(); + void MessageReceived(BMessage* message); + bool QuitRequested(); - const BString& GetPort(); + status_t GetSupportedSuites(BMessage* message); + BHandler* ResolveSpecifier(BMessage*, int32, BMessage*, int32, + const char*); + + const BString& GetPort(); private: - void LoadSettings(); - void SaveSettings(); - + void LoadSettings(); + void SaveSettings(); + private: - BSerialPort fSerialPort; - sem_id fSerialLock; - SerialWindow* fWindow; - BFile* fLogFile; - BString fPortPath; + BSerialPort fSerialPort; + sem_id fSerialLock; + SerialWindow* fWindow; + BFile* fLogFile; + BString fPortPath; - static status_t PollSerial(void*); + static status_t PollSerial(void*); - static const char* kApplicationSignature; + static const BPropertyInfo kScriptingProperties; + static const char* kApplicationSignature; }; diff --git a/src/apps/serialconnect/SerialWindow.cpp b/src/apps/serialconnect/SerialWindow.cpp index dcd38aa4db..cce467a092 100644 --- a/src/apps/serialconnect/SerialWindow.cpp +++ b/src/apps/serialconnect/SerialWindow.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012, Adrien Destugues, pulkomandy@gmail.com + * Copyright 2012-2014, Adrien Destugues, pulkomandy@pulkomandy.tk * Distributed under the terms of the MIT licence. */ @@ -242,6 +242,7 @@ void SerialWindow::MenusBeginning() new BMessage(kMsgOpenPort), 'Z', B_OPTION_KEY); if (!connected) disconnect->SetEnabled(false); + disconnect->SetTarget(be_app); fConnectionMenu->AddItem(disconnect); } else { BMenuItem* noDevices = new BMenuItem("", NULL); @@ -253,16 +254,8 @@ void SerialWindow::MenusBeginning() void SerialWindow::MessageReceived(BMessage* message) { - switch(message->what) + switch (message->what) { - case kMsgOpenPort: - { - BMenuItem* disconnectMenu; - if (message->FindPointer("source", (void**)&disconnectMenu) == B_OK) - disconnectMenu->SetMarked(false); - be_app->PostMessage(new BMessage(*message)); - break; - } case kMsgDataRead: { const char* bytes; @@ -270,7 +263,7 @@ void SerialWindow::MessageReceived(BMessage* message) if (message->FindData("data", B_RAW_TYPE, (const void**)&bytes, &length) == B_OK) fTermView->PushBytes(bytes, length); - break; + return; } case kMsgLogfile: { @@ -281,7 +274,7 @@ void SerialWindow::MessageReceived(BMessage* message) fLogFilePanel->SetMessage(message); } fLogFilePanel->Show(); - break; + return; } case kMsgSettings: { @@ -348,9 +341,9 @@ void SerialWindow::MessageReceived(BMessage* message) } } - break; + return; } - default: - BWindow::MessageReceived(message); } + + BWindow::MessageReceived(message); } diff --git a/src/apps/serialconnect/SerialWindow.h b/src/apps/serialconnect/SerialWindow.h index e7e3035b13..b6c935262f 100644 --- a/src/apps/serialconnect/SerialWindow.h +++ b/src/apps/serialconnect/SerialWindow.h @@ -1,5 +1,5 @@ /* - * Copyright 2012, Adrien Destugues, pulkomandy@gmail.com + * Copyright 2012-2014, Adrien Destugues, pulkomandy@pulkomandy.tk * Distributed under the terms of the MIT licence. */ @@ -15,24 +15,25 @@ class TermView; class SerialWindow: public BWindow { public: - SerialWindow(); - ~SerialWindow(); + SerialWindow(); + ~SerialWindow(); + + void MenusBeginning(); + void MessageReceived(BMessage* message); - void MenusBeginning(); - void MessageReceived(BMessage* message); private: - TermView* fTermView; + TermView* fTermView; - BMenu* fConnectionMenu; - BMenu* fDatabitsMenu; - BMenu* fStopbitsMenu; - BMenu* fParityMenu; - BMenu* fFlowcontrolMenu; - BMenu* fBaudrateMenu; - BFilePanel* fLogFilePanel; + BMenu* fConnectionMenu; + BMenu* fDatabitsMenu; + BMenu* fStopbitsMenu; + BMenu* fParityMenu; + BMenu* fFlowcontrolMenu; + BMenu* fBaudrateMenu; + BFilePanel* fLogFilePanel; - static const int kBaudrates[]; - static const int kBaudrateConstants[]; - static const char* kWindowTitle; + static const int kBaudrates[]; + static const int kBaudrateConstants[]; + static const char* kWindowTitle; };