/******************************************************************************* * This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * Synopsys, Inc. - ARC GNU Toolchain support *******************************************************************************/ package com.arc.embeddedcdt.dsf; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.service.AbstractDsfService; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.debug.core.ILaunch; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.widgets.Display; import org.eclipse.tm.internal.terminal.control.ITerminalViewControl; import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; import org.eclipse.tm.terminal.view.core.TerminalServiceFactory; import org.eclipse.tm.terminal.view.core.interfaces.ITerminalService; import org.eclipse.tm.terminal.view.core.interfaces.constants.ITerminalsConnectorConstants; import org.eclipse.tm.terminal.view.ui.interfaces.ILauncherDelegate; import org.eclipse.tm.terminal.view.ui.launcher.LauncherDelegateManager; import org.eclipse.tm.terminal.view.ui.manager.ConsoleManager; import org.eclipse.tm.terminal.view.ui.tabs.TabFolderManager; import org.eclipse.ui.IViewPart; import org.eclipse.ui.PlatformUI; import org.osgi.framework.BundleContext; import com.arc.embeddedcdt.LaunchPlugin; import com.arc.embeddedcdt.dsf.utils.ConfigurationReader; /** * DSF service for connecting to the UART on the board and opening Terminal view in Eclipse. */ public class TerminalService extends AbstractDsfService { private static final String viewId = "org.eclipse.tm.terminal.view.ui.TerminalsView"; private static final String delegateId = "org.eclipse.tm.terminal.connector.serial.launcher.serial"; private Map<String, Object> properties; { properties = new HashMap<>(); properties.put(ITerminalsConnectorConstants.PROP_SERIAL_BAUD_RATE, "115200"); properties.put(ITerminalsConnectorConstants.PROP_TIMEOUT, "5"); properties.put(ITerminalsConnectorConstants.PROP_SERIAL_DATA_BITS, "8"); properties.put(ITerminalsConnectorConstants.PROP_SERIAL_STOP_BITS, "1"); properties.put(ITerminalsConnectorConstants.PROP_SERIAL_PARITY, "N"); properties.put(ITerminalsConnectorConstants.PROP_SERIAL_FLOW_CONTROL, "XON/XOFF"); properties.put(ITerminalsConnectorConstants.PROP_DELEGATE_ID, delegateId); } private ITerminalService terminal = TerminalServiceFactory.getService(); private ILauncherDelegate delegate = LauncherDelegateManager.getInstance() .getLauncherDelegate(delegateId, false); private ITerminalConnector connector; public TerminalService(DsfSession session) { super(session); ILaunch launch = (ILaunch) session.getModelAdapter(ILaunch.class); ConfigurationReader cfgReader = new ConfigurationReader(launch.getLaunchConfiguration()); String serialPort = cfgReader.getComPort(); properties.put(ITerminalsConnectorConstants.PROP_SERIAL_DEVICE, serialPort); connector = delegate.createTerminalConnector(properties); } @Override public void initialize(final RequestMonitor requestMonitor) { super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @Override public void handleSuccess() { doInitialize(requestMonitor); } }); } private void doInitialize(RequestMonitor requestMonitor) { register(new String[] { TerminalService.class.getName() }, new Hashtable<String, String>()); startTerminal(); requestMonitor.done(); } @Override public void shutdown(RequestMonitor requestMonitor) { if (terminal != null) { terminal.terminateConsole(properties, null); } unregister(); super.shutdown(requestMonitor); } /** * Opens the Terminal View and creates a connection using properties. */ public void startTerminal() { try { Display display = PlatformUI.getWorkbench().getDisplay(); display.asyncExec(new Runnable() { @Override public void run() { String title = getTitleOfOpenConsole(); if (title != null) { properties.put(ITerminalsConnectorConstants.PROP_TITLE, title); } delegate.execute(properties, null); } }); } catch (Exception e) { } } /** * Searches for open console with properties equal to ours. If this console exists, return its * title. * * This is needed because in TM Terminal there is no way to connect to open console knowing all * its properties, but not title. On the other hand, when Eclipse is closed, all the connection * states are saved, and all the properties of the open consoles, except for names. On Eclipse * launching all these saved connections are reopened, but with different console names (because * these names include terminal consoles' opening times). In order not to open new console with * the same properties (which would be immediately closed because the serial port is already * taken), but connect to existing one, we need to find out its name. * * Must be run from the UI thread. * * @return title of open console with properties equal to ours, or null if is does not exist */ private String getTitleOfOpenConsole() { IViewPart view = ConsoleManager.getInstance().showConsoleView(viewId, null); TabFolderManager manager = view.getAdapter(TabFolderManager.class); manager.removeTerminatedItems(); CTabFolder tabFolder = view.getAdapter(CTabFolder.class); if (tabFolder == null) { return null; } for (CTabItem item : tabFolder.getItems()) { // Disposed items cannot be matched if (item.isDisposed()) { continue; } ITerminalViewControl terminal = (ITerminalViewControl) item.getData(); ITerminalConnector connector2 = terminal.getTerminalConnector(); if (connector.getName().equals(connector2.getName())) { if (!connector.isInitialized()) { return item.getText(); } String summary = connector.getSettingsSummary(); String summary2 = connector2.getSettingsSummary(); if (summary.equals(summary2)) { return item.getText(); } } } return null; } @Override protected BundleContext getBundleContext() { return LaunchPlugin.getBundleContext(); } }