From 489be2aa59303412afcb5462668df220eb259536 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 25 Aug 2016 08:46:31 -0400 Subject: [PATCH] Bug 303808: Moving old gdb console to Debugger Console view Making this change reduces richness of such a console with respect to menus, toolbar, etc. However, I think the consistency is more important. Besides, this old gdb console is so poor, I don't expect it was used much. Change-Id: I28870192dd51c673f35d6147d5196bc771ebfa55 --- .../debuggerconsole/DebuggerConsoleView.java | 72 +++++- .../ui/debuggerconsole/IDebuggerConsole.java | 2 +- .../ui/console/GdbBasicCliConsole.java | 243 ++++++++++++++++++ .../ui/console/GdbBasicCliConsolePage.java | 88 +++++++ .../ui/console/GdbCliConsoleManager.java | 109 ++++---- .../console/GdbConsoleInvertColorsAction.java | 4 +- .../console/GdbConsoleLifecycleListener.java | 48 ++++ ...CliConsole.java => GdbFullCliConsole.java} | 34 ++- ...lePage.java => GdbFullCliConsolePage.java} | 15 +- .../internal/ui/console/IGdbCliConsole.java | 17 ++ .../cdt/dsf/gdb/launching/GDBProcess.java | 47 ++-- 11 files changed, 575 insertions(+), 104 deletions(-) create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsole.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsolePage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleLifecycleListener.java rename dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/{GdbCliConsole.java => GdbFullCliConsole.java} (79%) rename dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/{GdbCliConsolePage.java => GdbFullCliConsolePage.java} (95%) create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/IGdbCliConsole.java diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java index b35dc4ec98c..8a3fb23eb28 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/debuggerconsole/DebuggerConsoleView.java @@ -24,6 +24,8 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleListener; +import org.eclipse.ui.console.IConsoleView; +import org.eclipse.ui.console.IOConsole; import org.eclipse.ui.part.IPage; import org.eclipse.ui.part.IPageBookViewPage; import org.eclipse.ui.part.MessagePage; @@ -31,7 +33,16 @@ import org.eclipse.ui.part.PageBook; import org.eclipse.ui.part.PageBookView; import org.eclipse.ui.part.PageSwitcher; -public class DebuggerConsoleView extends PageBookView implements IDebuggerConsoleView, IConsoleListener, IPropertyChangeListener { +/** + * The Debugger console view shows different {@link IDebuggerConsole}. + * + * This class extends {@link IConsoleView} to allow it to easily display + * consoles of type {@link IOConsole}. + * + * @see {@link IDebuggerConsoleManager} + */ +public class DebuggerConsoleView extends PageBookView +implements IConsoleView, IDebuggerConsoleView, IConsoleListener, IPropertyChangeListener { public static final String DEBUGGER_CONSOLE_VIEW_ID = "org.eclipse.cdt.debug.ui.debuggerConsoleView"; //$NON-NLS-1$ @@ -67,7 +78,7 @@ public class DebuggerConsoleView extends PageBookView implements IDebuggerConsol protected PageRec doCreatePage(IWorkbenchPart dummyPart) { DebuggerConsoleWorkbenchPart part = (DebuggerConsoleWorkbenchPart)dummyPart; IDebuggerConsole console = fPartToConsole.get(part); - IPageBookViewPage page = console.createPage(this); + IPageBookViewPage page = console.createDebuggerPage(this); initPage(page); page.createControl(getPageBook()); console.addPropertyChangeListener(this); @@ -307,4 +318,61 @@ public class DebuggerConsoleView extends PageBookView implements IDebuggerConsol } }; } + + @Override + public void setAutoScrollLock(boolean scrollLock) { + } + + @Override + public boolean getAutoScrollLock() { + return false; + } + + @Override + public void display(IConsole console) { + if (console instanceof IDebuggerConsole) { + display((IDebuggerConsole)console); + } + } + + @Override + public void setPinned(boolean pin) { + } + + @Override + public void pin(IConsole console) { + } + + @Override + public boolean isPinned() { + return false; + } + + @Override + public IConsole getConsole() { + return getCurrentConsole(); + } + + @Override + public void warnOfContentChange(IConsole console) { + assert false; + } + + @Override + public void setScrollLock(boolean scrollLock) { + } + + @Override + public boolean getScrollLock() { + return false; + } + + @Override + public void setWordWrap(boolean wordWrap) { + } + + @Override + public boolean getWordWrap() { + return false; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java index 09170b52b52..86f83f23f46 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/debuggerconsole/IDebuggerConsole.java @@ -29,7 +29,7 @@ public interface IDebuggerConsole extends IConsole { * @param view the view in which the page is to be created * @return a page book view page representation of this console */ - IPageBookViewPage createPage(IDebuggerConsoleView view); + IPageBookViewPage createDebuggerPage(IDebuggerConsoleView view); /** * Request a re-computation of the name of the console. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsole.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsole.java new file mode 100644 index 00000000000..05f2ecdcadb --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsole.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.console; + +import java.io.IOException; + +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleView; +import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; +import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.console.IConsoleView; +import org.eclipse.ui.console.IOConsole; +import org.eclipse.ui.console.IOConsoleOutputStream; +import org.eclipse.ui.part.IPageBookViewPage; + +/** + * A GDB CLI console. + * This console simply provides an IOConsole to perform CLI commands + * towards GDB. It is used whenever {@link IGDBBackend#isFullGdbConsoleSupported()} + * returns false. + */ +public class GdbBasicCliConsole extends IOConsole implements IDebuggerConsole, IGdbCliConsole { + + private final ILaunch fLaunch; + private final String fLabel; + private final Process fProcess; + private final IOConsoleOutputStream fOutputStream; + private final IOConsoleOutputStream fErrorStream; + + public GdbBasicCliConsole(ILaunch launch, String label, Process process) { + super("", null, null, false); //$NON-NLS-1$ + fLaunch = launch; + fLabel = label; + fProcess = process; + fOutputStream = newOutputStream(); + fErrorStream = newOutputStream(); + + assert(process != null); + + // Create a lifecycle listener to call init() and dispose() + new GdbConsoleLifecycleListener(this); + + resetName(); + setColors(); + + new InputReadJob().schedule(); + new OutputReadJob().schedule(); + new ErrorReadJob().schedule(); + } + + @Override + protected void dispose() { + try { + fOutputStream.close(); + } catch (IOException e) { + } + try { + fErrorStream.close(); + } catch (IOException e) { + } + + super.dispose(); + } + + private void setColors() { + // Set the inverted colors option based on the stored preference + IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore(); + boolean enabled = store.getBoolean(IGdbDebugPreferenceConstants.PREF_CONSOLE_INVERTED_COLORS); + + Display.getDefault().asyncExec(() -> { + getInputStream().setColor(Display.getDefault().getSystemColor(SWT.COLOR_GREEN)); + fErrorStream.setColor(Display.getDefault().getSystemColor(SWT.COLOR_RED)); + + setInvertedColors(enabled); + }); + } + + @Override + public ILaunch getLaunch() { + return fLaunch; + } + + @Override + public void resetName() { + String newName = computeName(); + String name = getName(); + if (!name.equals(newName)) { + PlatformUI.getWorkbench().getDisplay().asyncExec(() -> setName(newName)); + } + } + + protected String computeName() { + if (fLaunch == null) { + return ""; //$NON-NLS-1$ + } + + String label = fLabel; + + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + if (config != null && !DebugUITools.isPrivate(config)) { + String type = null; + try { + type = config.getType().getName(); + } catch (CoreException e) { + } + StringBuffer buffer = new StringBuffer(); + buffer.append(config.getName()); + if (type != null) { + buffer.append(" ["); //$NON-NLS-1$ + buffer.append(type); + buffer.append("] "); //$NON-NLS-1$ + } + buffer.append(label); + label = buffer.toString(); + } + + if (fLaunch.isTerminated()) { + return ConsoleMessages.ConsoleMessages_console_terminated + label; + } + + return label; + } + + @Override + public IPageBookViewPage createPage(IConsoleView view) { + return new GdbBasicCliConsolePage(this, view); + } + + @Override + public IPageBookViewPage createDebuggerPage(IDebuggerConsoleView view) { + if (view instanceof IConsoleView) { + return createPage((IConsoleView)view); + } + return null; + } + + @Override + public void setInvertedColors(boolean enable) { + if (enable) { + setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + fOutputStream.setColor(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + } else { + setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + fOutputStream.setColor(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + } + } + + private class InputReadJob extends Job { + { + setSystem(true); + } + + InputReadJob() { + super("GDB CLI Input Job"); //$NON-NLS-1$ + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + byte[] b = new byte[1024]; + int read = 0; + do { + read = getInputStream().read(b); + if (read > 0) { + fProcess.getOutputStream().write(b, 0, read); + } + } while (read >= 0); + } catch (IOException e) { + } + return Status.OK_STATUS; + } + } + + private class OutputReadJob extends Job { + { + setSystem(true); + } + + OutputReadJob() { + super("GDB CLI output Job"); //$NON-NLS-1$ + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + byte[] b = new byte[1024]; + int read = 0; + do { + read = fProcess.getInputStream().read(b); + if (read > 0) { + fOutputStream.write(b, 0, read); + } + } while (read >= 0); + } catch (IOException e) { + } + return Status.OK_STATUS; + } + } + + private class ErrorReadJob extends Job { + { + setSystem(true); + } + + ErrorReadJob() { + super("GDB CLI error output Job"); //$NON-NLS-1$ + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + byte[] b = new byte[1024]; + int read = 0; + do { + read = fProcess.getErrorStream().read(b); + if (read > 0) { + fErrorStream.write(b, 0, read); + } + } while (read >= 0); + } catch (IOException e) { + } + return Status.OK_STATUS; + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsolePage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsolePage.java new file mode 100644 index 00000000000..40341438efc --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbBasicCliConsolePage.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.console; + +import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.console.IConsoleView; +import org.eclipse.ui.internal.console.IOConsolePage; + +@SuppressWarnings("restriction") +public class GdbBasicCliConsolePage extends IOConsolePage implements IDebugContextListener { + + private final ILaunch fLaunch; + private final IConsoleView fView; + private final IDebuggerConsole fConsole; + + private GdbConsoleInvertColorsAction fInvertColorsAction; + + public GdbBasicCliConsolePage(GdbBasicCliConsole gdbConsole, IConsoleView view) { + super(gdbConsole, view); + fConsole = gdbConsole; + fView = view; + fLaunch = gdbConsole.getLaunch(); + } + + @Override + public void dispose() { + super.dispose(); + DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).removeDebugContextListener(this); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).addDebugContextListener(this); + } + + @Override + protected void configureToolBar(IToolBarManager mgr) { + // Don't do anything + } + + @Override + protected void createActions() { + fInvertColorsAction = new GdbConsoleInvertColorsAction(); + } + + @Override + protected void contextMenuAboutToShow(IMenuManager menuManager) { + menuManager.add(fInvertColorsAction); + } + + /** + * Returns the launch to which the current selection belongs. + * + * @return the launch to which the current selection belongs. + */ + protected ILaunch getCurrentLaunch() { + IAdaptable context = DebugUITools.getDebugContext(); + if (context != null) { + return context.getAdapter(ILaunch.class); + } + return null; + } + + @Override + public void debugContextChanged(DebugContextEvent event) { + if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { + // Show this GDB console if it matches with the currently + // selected debug session + if (fLaunch.equals(getCurrentLaunch())) { + fView.display(fConsole); + } + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java index 54303051f50..bef81c92448 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsoleManager.java @@ -1,12 +1,9 @@ /******************************************************************************* - * Copyright (c) 2009, 2015 Ericsson and others. + * Copyright (c) 2016 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.console; @@ -17,11 +14,13 @@ import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsole; import org.eclipse.cdt.debug.ui.debuggerconsole.IDebuggerConsoleManager; import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlInitializedDMEvent; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.IMIBackend; -import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; @@ -126,9 +125,10 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { } /** - * Class that determines if a GdbCliConsole should be created for - * this particular Gdblaunch. It figures this out by asking the - * Backend service. + * Class that determines what type of console should be created + * for this particular Gdblaunch. It figures this out by asking the + * Backend service. It then either creates a GdbFullCliConsole or + * a GdbBasicCliConsole. */ private class GdbConsoleCreator { private GdbLaunch fLaunch; @@ -147,15 +147,20 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { // Look for backend service right away. It probably // won't be available yet but we must make sure. DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId()); - IGDBBackend backend = tracker.getService(IGDBBackend.class); + // Use the lowest level service name in case those are created but don't implement + // the most specialized classes IGDBControl or IGDBBackend. + ICommandControlService control = tracker.getService(ICommandControlService.class); + IMIBackend backend = tracker.getService(IMIBackend.class); tracker.dispose(); - if (backend != null) { - // Backend service already available, us it! - verifyAndCreateConsole(backend); + // If we use the old console we not only need the backend service but + // also the control service. For simplicity, always wait for both. + if (backend != null && control != null) { + // Backend and Control services already available, we can start! + verifyAndCreateCliConsole(); } else { - // Backend service not available yet, let's wait for it to start. - fSession.addServiceEventListener(new GdbBackendStartedListener(GdbConsoleCreator.this, fSession), null); + // Backend service or Control service not available yet, let's wait for them to start. + new GdbServiceStartedListener(GdbConsoleCreator.this, fSession); } } }); @@ -164,61 +169,61 @@ public class GdbCliConsoleManager implements ILaunchesListener2 { } @ConfinedToDsfExecutor("fSession.getExecutor()") - private void verifyAndCreateConsole(IGDBBackend backend) { - if (backend != null && backend.isFullGdbConsoleSupported()) { - // Create an new Cli console . - String gdbVersion; - try { - gdbVersion = fLaunch.getGDBVersion(); - } catch (CoreException e) { - assert false : "Should not happen since the gdb version is cached"; //$NON-NLS-1$ - gdbVersion = "???"; //$NON-NLS-1$ - } - String consoleTitle = fLaunch.getGDBPath().toOSString().trim() + " (" + gdbVersion +")"; //$NON-NLS-1$ //$NON-NLS-2$ + private void verifyAndCreateCliConsole() { + String gdbVersion; + try { + gdbVersion = fLaunch.getGDBVersion(); + } catch (CoreException e) { + gdbVersion = "???"; //$NON-NLS-1$ + assert false : "Should not happen since the gdb version is cached"; //$NON-NLS-1$ + } + String consoleTitle = fLaunch.getGDBPath().toOSString().trim() + " (" + gdbVersion +")"; //$NON-NLS-1$ //$NON-NLS-2$ - IDebuggerConsole console = new GdbCliConsole(fLaunch, consoleTitle); - addConsole(console); - - // Make sure the Debugger Console view is visible - getDebuggerConsoleManager().showConsoleView(console); - } - // Else, not the right type of backend service, or - // the service said not to start a GdbCliConsole - } - - @ConfinedToDsfExecutor("fSession.getExecutor()") - private void backendStarted() { DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId()); + IGDBControl control = tracker.getService(IGDBControl.class); IGDBBackend backend = tracker.getService(IGDBBackend.class); tracker.dispose(); - verifyAndCreateConsole(backend); + IDebuggerConsole console; + if (backend != null && backend.isFullGdbConsoleSupported()) { + // Create a full GDB cli console + console = new GdbFullCliConsole(fLaunch, consoleTitle); + } else if (control != null) { + // Create a simple text console for the cli. + console = new GdbBasicCliConsole(fLaunch, consoleTitle, control.getGDBBackendProcess()); + } else { + // Something is wrong. Don't create a console + assert false; + return; + } + + addConsole(console); + // Make sure the Debugger Console view is visible + getDebuggerConsoleManager().showConsoleView(console); } } /** - * Class used to listen for Backend started event which indicate - * the DSF-GDB backend service can be used. + * Class used to listen for started events for the services we need. * This class must be public to receive the event. */ - public class GdbBackendStartedListener { + public class GdbServiceStartedListener { private DsfSession fSession; private GdbConsoleCreator fCreator; - public GdbBackendStartedListener(GdbConsoleCreator creator, DsfSession session) { - fCreator = creator; + public GdbServiceStartedListener(GdbConsoleCreator creator, DsfSession session) { + fCreator = creator; fSession = session; + fSession.addServiceEventListener(this, null); } @DsfServiceEventHandler - public void eventDispatched(BackendStateChangedEvent event) { - if (event.getState() == IMIBackend.State.STARTED && - event.getSessionId().equals(fSession.getId())) - { - fCreator.backendStarted(); - // No longer need to receive events. - fSession.removeServiceEventListener(this); - } - } + public final void eventDispatched(ICommandControlInitializedDMEvent event) { + // With the commandControl service started, we know the backend service + // is also started. So we are good to go. + fCreator.verifyAndCreateCliConsole(); + // No longer need to receive events. + fSession.removeServiceEventListener(this); + } } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleInvertColorsAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleInvertColorsAction.java index 11e423694db..b047dac83dc 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleInvertColorsAction.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleInvertColorsAction.java @@ -41,8 +41,8 @@ public class GdbConsoleInvertColorsAction extends Action { IDebuggerConsoleManager manager = CDebugUIPlugin.getDebuggerConsoleManager(); for (IDebuggerConsole console : manager.getConsoles()) { - if (console instanceof GdbCliConsole) { - ((GdbCliConsole)console).setInvertedColors(!enabled); + if (console instanceof IGdbCliConsole) { + ((IGdbCliConsole)console).setInvertedColors(!enabled); } } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleLifecycleListener.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleLifecycleListener.java new file mode 100644 index 00000000000..3c92f666f06 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbConsoleLifecycleListener.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.console; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.ui.console.AbstractConsole; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleListener; + +/** + * Used to notify this debugger console of lifecycle methods init() + * and dispose(). + */ +public class GdbConsoleLifecycleListener implements IConsoleListener { + + private final AbstractConsole fConsole; + + public GdbConsoleLifecycleListener(AbstractConsole console) { + fConsole = console; + CDebugUIPlugin.getDebuggerConsoleManager().addConsoleListener(this); + } + + @Override + public void consolesAdded(IConsole[] consoles) { + for (IConsole console : consoles) { + if (console.equals(fConsole)) { + fConsole.initialize(); + break; + } + } + } + + @Override + public void consolesRemoved(IConsole[] consoles) { + for (IConsole console : consoles) { + if (console.equals(fConsole)) { + CDebugUIPlugin.getDebuggerConsoleManager().removeConsoleListener(this); + fConsole.destroy(); + break; + } + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbFullCliConsole.java similarity index 79% rename from dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java rename to dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbFullCliConsole.java index 1ecf0a20d0f..315080bbad2 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsole.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbFullCliConsole.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Ericsson and others. + * Copyright (c) 2016 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -24,16 +24,19 @@ import org.eclipse.ui.part.IPageBookViewPage; * full-featured CLI interface. This is only supported with GDB >= 7.12 * and if IGDBBackend.isFullGdbConsoleSupported() returns true. */ -public class GdbCliConsole extends AbstractConsole implements IDebuggerConsole { +public class GdbFullCliConsole extends AbstractConsole implements IDebuggerConsole, IGdbCliConsole { private final ILaunch fLaunch; - private String fLabel; - private GdbCliConsolePage fConsolePage; + private final String fLabel; + private GdbFullCliConsolePage fConsolePage; - public GdbCliConsole(ILaunch launch, String label) { - super(label, null); + public GdbFullCliConsole(ILaunch launch, String label) { + super(label, null, false); fLaunch = launch; fLabel = label; + // Create a lifecycle listener to call init() and dispose() + new GdbConsoleLifecycleListener(this); + resetName(); } @@ -50,6 +53,10 @@ public class GdbCliConsole extends AbstractConsole implements IDebuggerConsole { } protected String computeName() { + if (fLaunch == null) { + return ""; //$NON-NLS-1$ + } + String label = fLabel; ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); @@ -78,18 +85,19 @@ public class GdbCliConsole extends AbstractConsole implements IDebuggerConsole { } @Override - public IPageBookViewPage createPage(IDebuggerConsoleView view) { + public IPageBookViewPage createPage(IConsoleView view) { + // This console is not meant for the standard console view + return null; + } + + @Override + public IPageBookViewPage createDebuggerPage(IDebuggerConsoleView view) { view.setFocus(); - fConsolePage = new GdbCliConsolePage(this, view); + fConsolePage = new GdbFullCliConsolePage(this, view); return fConsolePage; } @Override - public IPageBookViewPage createPage(IConsoleView view) { - // This console is not used in the IConsoleView - return null; - } - public void setInvertedColors(boolean enable) { if (fConsolePage != null) { fConsolePage.setInvertedColors(enable); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbFullCliConsolePage.java similarity index 95% rename from dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java rename to dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbFullCliConsolePage.java index 67522206142..3b002751d68 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbCliConsolePage.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/GdbFullCliConsolePage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2016 Ericsson and others. + * Copyright (c) 2016 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -48,13 +48,13 @@ import org.eclipse.tm.terminal.view.ui.interfaces.ILauncherDelegate; import org.eclipse.tm.terminal.view.ui.launcher.LauncherDelegateManager; import org.eclipse.ui.part.Page; -public class GdbCliConsolePage extends Page implements IDebugContextListener { +public class GdbFullCliConsolePage extends Page implements IDebugContextListener { - private DsfSession fSession; - private ILaunch fLaunch; + private final DsfSession fSession; + private final ILaunch fLaunch; private Composite fMainComposite; - private IDebuggerConsoleView fView; - private IDebuggerConsole fConsole; + private final IDebuggerConsoleView fView; + private final IDebuggerConsole fConsole; private MenuManager fMenuManager; @@ -63,13 +63,14 @@ public class GdbCliConsolePage extends Page implements IDebugContextListener { /** The control for the terminal widget embedded in the console */ private ITerminalViewControl fTerminalControl; - public GdbCliConsolePage(GdbCliConsole gdbConsole, IDebuggerConsoleView view) { + public GdbFullCliConsolePage(GdbFullCliConsole gdbConsole, IDebuggerConsoleView view) { fConsole = gdbConsole; fView = view; fLaunch = gdbConsole.getLaunch(); if (fLaunch instanceof GdbLaunch) { fSession = ((GdbLaunch)fLaunch).getSession(); } else { + fSession = null; assert false; } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/IGdbCliConsole.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/IGdbCliConsole.java new file mode 100644 index 00000000000..3fdefbde2bf --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/console/IGdbCliConsole.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.console; + +import org.eclipse.ui.console.IConsole; + +public interface IGdbCliConsole extends IConsole { + /** + * Enable or disable the inverted color option of the console. + */ + void setInvertedColors(boolean enable); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java index 22cf639c5fd..03db629a68d 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GDBProcess.java @@ -13,7 +13,6 @@ package org.eclipse.cdt.dsf.gdb.launching; import java.io.IOException; import java.util.Map; -import org.eclipse.cdt.dsf.gdb.service.command.IGDBBackendProcessWithoutIO; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IStreamMonitor; import org.eclipse.debug.core.model.IStreamsProxy; @@ -22,9 +21,8 @@ import org.eclipse.debug.core.model.RuntimeProcess; /** * A process for the gdb backend to differentiate it from the inferior. * - * This process disables the base class handling of IO streams if we - * are using the full GDB console, which is handled by the - * GdbConsoleManager instead. + * This process disables the base class handling of IO streams since + * all IO is handled by the different specialized {@link IDebuggerConsole} * * @since 3.0 */ @@ -37,37 +35,32 @@ public class GDBProcess extends RuntimeProcess { @Override public IStreamsProxy getStreamsProxy() { - IStreamsProxy proxy = super.getStreamsProxy(); - // If our proxy is the one that ignores the streams, - // this method should return null. - // Returning null insures that there will not be a - // text console automatically created for this process - // see ProcessConsoleManager#launchChanged() - return proxy instanceof NoStreamsProxy ? null : proxy; + /** + * Returning null insures that there will not be a + * text console automatically created for this process + * in the standard console view. + * + * @see {@link ProcessConsoleManager#launchChanged} + */ + return null; } @Override protected IStreamsProxy createStreamsProxy() { - // TRICKY. This method is called by the constructor of - // the super class. This means we don't have time to - // set any fields in this class by then. Therefore, - // we can only use what was set by the base class constructor - // to figure out how to behave. - // We can call getSystemProcess() as it is set earlier - // in the constructor then when this method is called. - if (getSystemProcess() instanceof IGDBBackendProcessWithoutIO) { - // If the GDB process used does not handle I/O, we return a proxy - // that ignores the streams. - return new NoStreamsProxy(); - } - return super.createStreamsProxy(); + /** + * The I/O handling does not go through this RuntimeProcess. + * Instead, the different consoles will connect directly to + * the process to obtain the input, output and error streams. + * + * @see {@link GdbFullCliConsolePage} and {@link GdbBasicCliConsole} + */ + return new NoStreamsProxy(); } /** * Class that provides a streams proxy that actually - * ignores the I/O streams. We use this in the case - * of the full GDB console where the GDB CLI is used directly, - * without us needing to do anything with the I/O ourselves. + * ignores the I/O streams. We use this because the I/O + * is handled directly by the different {@link IDebuggerConsole}. * * This is different than NullStreamsProxy which would * still read but discard the IO, which is not what we want.