From 04434656afa98246c3c2122f710bb448afd03919 Mon Sep 17 00:00:00 2001 From: Adrien Destugues - PulkoMandy Date: Sun, 4 Nov 2012 23:52:48 +0100 Subject: [PATCH] Serial port configuration * Dynamically update the serial port list in the connection menu when devices get added or removed * Make the settings in the settings menu actually do something --- src/apps/serialconnect/SerialApp.cpp | 100 ++++++++++- src/apps/serialconnect/SerialApp.h | 6 + src/apps/serialconnect/SerialWindow.cpp | 216 ++++++++++++++++-------- src/apps/serialconnect/SerialWindow.h | 3 + 4 files changed, 256 insertions(+), 69 deletions(-) diff --git a/src/apps/serialconnect/SerialApp.cpp b/src/apps/serialconnect/SerialApp.cpp index 67a96fa929..24b7d9e7c8 100644 --- a/src/apps/serialconnect/SerialApp.cpp +++ b/src/apps/serialconnect/SerialApp.cpp @@ -37,9 +37,13 @@ void SerialApp::MessageReceived(BMessage* message) case kMsgOpenPort: { const char* portName; - message->FindString("port name", &portName); - fSerialPort.Open(portName); - release_sem(fSerialLock); + if(message->FindString("port name", &portName) == B_OK) + { + fSerialPort.Open(portName); + release_sem(fSerialLock); + } else { + fSerialPort.Close(); + } break; } case kMsgDataRead: @@ -56,6 +60,96 @@ void SerialApp::MessageReceived(BMessage* message) message->FindData("data", B_RAW_TYPE, (const void**)&bytes, &size); fSerialPort.Write(bytes, size); + break; + } + case kMsgSettings: + { + int32 baudrate; + stop_bits stopBits; + data_bits dataBits; + parity_mode parity; + uint32 flowcontrol; + + if(message->FindInt32("databits", (int32*)&dataBits) == B_OK) + fSerialPort.SetDataBits(dataBits); + + if(message->FindInt32("stopbits", (int32*)&stopBits) == B_OK) + fSerialPort.SetStopBits(stopBits); + + if(message->FindInt32("parity", (int32*)&parity) == B_OK) + fSerialPort.SetParityMode(parity); + + if(message->FindInt32("flowcontrol", (int32*)&flowcontrol) == B_OK) + fSerialPort.SetFlowControl(flowcontrol); + + if(message->FindInt32("baudrate", &baudrate) == B_OK) { + data_rate rate; + switch(baudrate) { + case 50: + rate = B_50_BPS; + break; + case 75: + rate = B_75_BPS; + break; + case 110: + rate = B_110_BPS; + break; + case 134: + rate = B_134_BPS; + break; + case 150: + rate = B_150_BPS; + break; + case 200: + rate = B_200_BPS; + break; + case 300: + rate = B_300_BPS; + break; + case 600: + rate = B_600_BPS; + break; + case 1200: + rate = B_1200_BPS; + break; + case 1800: + rate = B_1800_BPS; + break; + case 2400: + rate = B_2400_BPS; + break; + case 4800: + rate = B_4800_BPS; + break; + case 9600: + rate = B_9600_BPS; + break; + case 19200: + rate = B_19200_BPS; + break; + case 31250: + rate = B_31250_BPS; + break; + case 38400: + rate = B_38400_BPS; + break; + case 57600: + rate = B_57600_BPS; + break; + case 115200: + rate = B_115200_BPS; + break; + case 230400: + rate = B_230400_BPS; + break; + default: + rate = B_0_BPS; + break; + } + fSerialPort.SetDataRate(rate); + } + + break; } default: BApplication::MessageReceived(message); diff --git a/src/apps/serialconnect/SerialApp.h b/src/apps/serialconnect/SerialApp.h index a08069a33b..7dd7c50629 100644 --- a/src/apps/serialconnect/SerialApp.h +++ b/src/apps/serialconnect/SerialApp.h @@ -4,6 +4,10 @@ */ +#ifndef _SERIALAPP_H_ +#define _SERIALAPP_H_ + + #include #include @@ -33,5 +37,7 @@ enum messageConstants { kMsgOpenPort = 'open', kMsgDataRead = 'dare', kMsgDataWrite = 'dawr', + kMsgSettings = 'stty', }; +#endif diff --git a/src/apps/serialconnect/SerialWindow.cpp b/src/apps/serialconnect/SerialWindow.cpp index 0dafcd6ebf..ed5f030962 100644 --- a/src/apps/serialconnect/SerialWindow.cpp +++ b/src/apps/serialconnect/SerialWindow.cpp @@ -6,6 +6,8 @@ #include "SerialWindow.h" +#include + #include #include #include @@ -29,18 +31,142 @@ SerialWindow::SerialWindow() AddChild(menuBar); AddChild(fTermView); - BMenu* connectionMenu = new BMenu("Connections"); + fConnectionMenu = new BMenu("Connection"); + fConnectionMenu->SetRadioMode(true); + BMenu* editMenu = new BMenu("Edit"); BMenu* settingsMenu = new BMenu("Settings"); - menuBar->AddItem(connectionMenu); + menuBar->AddItem(fConnectionMenu); menuBar->AddItem(editMenu); menuBar->AddItem(settingsMenu); - // TODO messages - BMenu* connect = new BMenu("Connect"); - connectionMenu->AddItem(connect); + // TODO edit menu - what's in it ? + + // Configuring all this by menus may be a bit unhandy. Make a setting + // window instead ? + BMenu* baudRate = new BMenu("Baud rate"); + baudRate->SetRadioMode(true); + settingsMenu->AddItem(baudRate); + BMenu* parity = new BMenu("Parity"); + parity->SetRadioMode(true); + settingsMenu->AddItem(parity); + + BMenu* stopBits = new BMenu("Stop bits"); + stopBits->SetRadioMode(true); + settingsMenu->AddItem(stopBits); + + BMenu* flowControl = new BMenu("Flow control"); + flowControl->SetRadioMode(true); + settingsMenu->AddItem(flowControl); + + BMenu* dataBits = new BMenu("Data bits"); + dataBits->SetRadioMode(true); + settingsMenu->AddItem(dataBits); + + + BMessage* message = new BMessage(kMsgSettings); + message->AddInt32("parity", B_NO_PARITY); + BMenuItem* parityNone = new BMenuItem("None", message); + + message = new BMessage(kMsgSettings); + message->AddInt32("parity", B_ODD_PARITY); + BMenuItem* parityOdd = new BMenuItem("Odd", message); + + message = new BMessage(kMsgSettings); + message->AddInt32("parity", B_EVEN_PARITY); + BMenuItem* parityEven = new BMenuItem("Even", message); + parityNone->SetMarked(true); + + parity->AddItem(parityNone); + parity->AddItem(parityOdd); + parity->AddItem(parityEven); + parity->SetTargetForItems(be_app); + + message = new BMessage(kMsgSettings); + message->AddInt32("databits", B_DATA_BITS_7); + BMenuItem* data7 = new BMenuItem("7", message); + + message = new BMessage(kMsgSettings); + message->AddInt32("databits", B_DATA_BITS_8); + BMenuItem* data8 = new BMenuItem("8", message); + data8->SetMarked(true); + + dataBits->AddItem(data7); + dataBits->AddItem(data8); + dataBits->SetTargetForItems(be_app); + + message = new BMessage(kMsgSettings); + message->AddInt32("stopbits", B_STOP_BITS_1); + BMenuItem* stop1 = new BMenuItem("1", NULL); + + message = new BMessage(kMsgSettings); + message->AddInt32("stopbits", B_STOP_BITS_2); + BMenuItem* stop2 = new BMenuItem("2", NULL); + stop1->SetMarked(true); + + stopBits->AddItem(stop1); + stopBits->AddItem(stop2); + stopBits->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 + for (int i = sizeof(baudrates) / sizeof(char*); --i >= 0;) + { + message = new BMessage(kMsgSettings); + message->AddInt32("baudrate", baudrates[i]); + + char buffer[7]; + sprintf(buffer,"%d", baudrates[i]); + BMenuItem* item = new BMenuItem(buffer, message); + + if (baudrates[i] == 19200) + item->SetMarked(true); + + baudRate->AddItem(item); + } + + baudRate->SetTargetForItems(be_app); + + message = new BMessage(kMsgSettings); + message->AddInt32("flowcontrol", B_HARDWARE_CONTROL); + BMenuItem* hardware = new BMenuItem("Hardware", message); + hardware->SetMarked(true); + + message = new BMessage(kMsgSettings); + message->AddInt32("flowcontrol", B_SOFTWARE_CONTROL); + BMenuItem* software = new BMenuItem("Software", message); + + message = new BMessage(kMsgSettings); + message->AddInt32("flowcontrol", B_HARDWARE_CONTROL | B_SOFTWARE_CONTROL); + BMenuItem* both = new BMenuItem("Both", message); + + message = new BMessage(kMsgSettings); + message->AddInt32("flowcontrol", 0); + BMenuItem* noFlow = new BMenuItem("None", message); + + flowControl->AddItem(hardware); + flowControl->AddItem(software); + flowControl->AddItem(both); + flowControl->AddItem(noFlow); + flowControl->SetTargetForItems(be_app); + + CenterOnScreen(); +} + +#include + +void SerialWindow::MenusBeginning() +{ + // remove all items from the menu + while(fConnectionMenu->RemoveItem(0L)); + + // fill it with the (updated) serial port list BSerialPort serialPort; int deviceCount = serialPort.CountDevices(); @@ -52,78 +178,36 @@ SerialWindow::SerialWindow() BMessage* message = new BMessage(kMsgOpenPort); message->AddString("port name", buffer); BMenuItem* portItem = new BMenuItem(buffer, message); - - connect->AddItem(portItem); - portItem->SetTarget(be_app); + + fConnectionMenu->AddItem(portItem); } -#if SUPPORTS_MODEM - BMenuItem* connectModem = new BMenuItem( - "Connect via modem" B_UTF8_ELLIPSIS, NULL, 'M', 0); - connectionMenu->AddItem(connectModem); -#endif - BMenuItem* Disconnect = new BMenuItem("Disconnect", NULL, - 'Z', B_OPTION_KEY); - connectionMenu->AddItem(Disconnect); + if (deviceCount > 0) { + fConnectionMenu->AddSeparatorItem(); - // TODO edit menu - what's in it ? - - // Configuring all this by menus may be a bit unhandy. Make a setting - // window instead ? - BMenu* parity = new BMenu("Parity"); - settingsMenu->AddItem(parity); - BMenu* dataBits = new BMenu("Data bits"); - settingsMenu->AddItem(dataBits); - BMenu* stopBits = new BMenu("Stop bits"); - settingsMenu->AddItem(stopBits); - BMenu* baudRate = new BMenu("Baud rate"); - settingsMenu->AddItem(baudRate); - BMenu* flowControl = new BMenu("Flow control"); - settingsMenu->AddItem(flowControl); - - BMenuItem* parityNone = new BMenuItem("None", NULL); - parity->AddItem(parityNone); - BMenuItem* parityOdd = new BMenuItem("Odd", NULL); - parity->AddItem(parityOdd); - BMenuItem* parityEven = new BMenuItem("Even", NULL); - parity->AddItem(parityEven); - - BMenuItem* data7 = new BMenuItem("7", NULL); - dataBits->AddItem(data7); - BMenuItem* data8 = new BMenuItem("8", NULL); - dataBits->AddItem(data8); - - BMenuItem* stop1 = new BMenuItem("1", NULL); - stopBits->AddItem(stop1); - BMenuItem* stop2 = new BMenuItem("2", NULL); - stopBits->AddItem(stop2); - - static const char* 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 - for (int i = sizeof(baudrates) / sizeof(char*); --i >= 0;) - { - BMenuItem* item = new BMenuItem(baudrates[i], NULL); - baudRate->AddItem(item); + BMenuItem* disconnect = new BMenuItem("Disconnect", + new BMessage(kMsgOpenPort), 'Z', B_OPTION_KEY); + fConnectionMenu->AddItem(disconnect); + } else { + BMenuItem* noDevices = new BMenuItem("", NULL); + noDevices->SetEnabled(false); + fConnectionMenu->AddItem(noDevices); } - - BMenuItem* rtsCts = new BMenuItem("RTS/CTS", NULL); - flowControl->AddItem(rtsCts); - BMenuItem* noFlow = new BMenuItem("None", NULL); - flowControl->AddItem(noFlow); - - CenterOnScreen(); } - void SerialWindow::MessageReceived(BMessage* message) { 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; diff --git a/src/apps/serialconnect/SerialWindow.h b/src/apps/serialconnect/SerialWindow.h index 557b0eabc1..d8f20468ba 100644 --- a/src/apps/serialconnect/SerialWindow.h +++ b/src/apps/serialconnect/SerialWindow.h @@ -7,6 +7,7 @@ #include +class BMenu; class TermView; @@ -15,10 +16,12 @@ class SerialWindow: public BWindow public: SerialWindow(); + void MenusBeginning(); void MessageReceived(BMessage* message); private: TermView* fTermView; + BMenu* fConnectionMenu; static const char* kWindowTitle; };