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
This commit is contained in:
Adrien Destugues - PulkoMandy 2012-11-04 23:52:48 +01:00
parent 634feff0e9
commit 04434656af
4 changed files with 256 additions and 69 deletions

View File

@ -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);

View File

@ -4,6 +4,10 @@
*/
#ifndef _SERIALAPP_H_
#define _SERIALAPP_H_
#include <Application.h>
#include <SerialPort.h>
@ -33,5 +37,7 @@ enum messageConstants {
kMsgOpenPort = 'open',
kMsgDataRead = 'dare',
kMsgDataWrite = 'dawr',
kMsgSettings = 'stty',
};
#endif

View File

@ -6,6 +6,8 @@
#include "SerialWindow.h"
#include <stdio.h>
#include <GroupLayout.h>
#include <Menu.h>
#include <MenuBar.h>
@ -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 <stdio.h>
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("<no serial port available>", 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;

View File

@ -7,6 +7,7 @@
#include <Window.h>
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;
};