diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ICPUInfo.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ICPUInfo.java new file mode 100644 index 00000000000..4761799ef82 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ICPUInfo.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core; + +/** + */ +public interface ICPUInfo { + public String getId(); + public String getNumOfCores(); +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ICoreInfo.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ICoreInfo.java new file mode 100644 index 00000000000..3eba56f8783 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ICoreInfo.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core; + +/** + */ +public interface ICoreInfo { + public String getId(); + public String getPhysicalId(); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.classpath b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.classpath new file mode 100644 index 00000000000..31db9a91174 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.project b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.project new file mode 100644 index 00000000000..8b3f7a66576 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.project @@ -0,0 +1,34 @@ + + + org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.settings/org.eclipse.jdt.core.prefs b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..669b0a3caf2 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,70 @@ +#Tue Jun 24 11:04:03 PDT 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..eef9f222bf8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-Vendor: %providerName +Bundle-SymbolicName: org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.cdt.dsf, + org.eclipse.cdt.dsf.ui, + org.eclipse.cdt.dsf.gdb, + org.eclipse.cdt.ui, + org.eclipse.cdt.visualizer.core, + org.eclipse.cdt.visualizer.ui, + org.eclipse.debug.ui +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: com.ibm.icu.text +Export-Package: org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/about.html b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/about.html @@ -0,0 +1,24 @@ + + + + +About +

About This Content

+ +

June 5, 2007

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/build.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/build.properties new file mode 100644 index 00000000000..6b63ac40a03 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/build.properties @@ -0,0 +1,19 @@ +############################################################################### +# Copyright (c) 2012 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: +# Marc Khouzam (Ericsson) - initial API and implementation +############################################################################### +source.. = src/,\ + resources/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + about.html,\ + plugin.properties +src.includes = about.html diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/plugin.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/plugin.properties new file mode 100644 index 00000000000..7216b261257 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/plugin.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2012 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: +# Marc Khouzam (Ericsson) - initial API and implementation +############################################################################### +pluginName=Multicore Visualizer for DSF-GDB Integration +providerName=Eclipse CDT diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/plugin.xml new file mode 100644 index 00000000000..46a0aac6dde --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/plugin.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/pom.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/pom.xml new file mode 100644 index 00000000000..d3a9fcbd007 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + org.eclipse.cdt + cdt-parent + 8.1.0-SNAPSHOT + ../../pom.xml + + + 1.0.0-SNAPSHOT + org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui + eclipse-plugin + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/resources/messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/resources/messages.properties new file mode 100644 index 00000000000..0103a53551c --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/resources/messages.properties @@ -0,0 +1,21 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Application string resources +# ----------------------------------------------------------------------------- + +# MulticoreVisualizer actions +MulticoreVisualizer.actions.SelectAll.text=Select &All@Ctrl+A +MulticoreVisualizer.actions.SelectAll.description=Select all thread(s) + +MulticoreVisualizer.actions.Refresh.text=Refresh@F5 +MulticoreVisualizer.actions.Refresh.description=Refresh the visualizer display diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/MulticoreVisualizerUIPlugin.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/MulticoreVisualizerUIPlugin.java new file mode 100644 index 00000000000..f780d4e4051 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/MulticoreVisualizerUIPlugin.java @@ -0,0 +1,282 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - initial API and implementation + * William R. Swanson (Tilera Corporation) - added resource support + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui; + +import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; +import org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin; +import org.eclipse.cdt.visualizer.ui.util.UIResourceManager; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class MulticoreVisualizerUIPlugin extends AbstractUIPlugin +{ + // --- constants --- + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui"; //$NON-NLS-1$ + + + // --- static members --- + + /** Singleton instance */ + private static MulticoreVisualizerUIPlugin plugin; + + /** Bundle context */ + private static BundleContext fgBundleContext; + + /** Resource manager */ + protected static UIResourceManager s_resources = null; + + /** + * Returns the shared instance + */ + public static MulticoreVisualizerUIPlugin getDefault() { + return plugin; + } + + /** + * Returns the bundle context for this plugin. + */ + public static BundleContext getBundleContext() { + return fgBundleContext; + } + + + // --- constructors/destructors --- + + /** + * The constructor + */ + public MulticoreVisualizerUIPlugin() { + } + + + // --- plugin startup/shutdown methods --- + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + plugin = this; + + // initialize resource management (strings, images, fonts, colors, etc.) + getPluginResources(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + // clean up resource management + cleanupPluginResources(); + + plugin = null; + super.stop(context); + fgBundleContext = null; + } + + + // --- logging --- + + /** + * Logs the specified status with this plug-in's log. + * + * @param status + * status to log + */ + public static void log(IStatus status) { + getDefault().getLog().log(status); + } + /** + * Logs an internal error with the specified message. + * + * @param message + * the error message to log + */ + public static void logErrorMessage(String message) { + log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null)); + } + + /** + * Logs an internal error with the specified throwable + * + * @param e + * the exception to be logged + */ + public static void log(Throwable e) { + log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), e)); + } + + + // --- accessors --- + + /** + * Convenience method which returns the unique identifier of this plugin. + */ + public static String getUniqueIdentifier() { + if (getDefault() == null) { + // If the default instance is not yet initialized, + // return a static identifier. This identifier must + // match the plugin id defined in plugin.xml + return PLUGIN_ID; + } + return getDefault().getBundle().getSymbolicName(); + } + + + // --- UI plugin support --- + + /** + * copied from org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin + */ + private static Shell debugDialogShell; + + /** + * Returns shell (workbench or dialog) for this plugin. + */ + public static Shell getShell() { + if (getActiveWorkbenchShell() != null) { + return getActiveWorkbenchShell(); + } + if (debugDialogShell != null) { + if (!debugDialogShell.isDisposed()) + return debugDialogShell; + debugDialogShell = null; + } + IWorkbenchWindow[] windows = getDefault().getWorkbench().getWorkbenchWindows(); + return windows[0].getShell(); + } + + public static void setDialogShell(Shell shell) { + debugDialogShell = shell; + } + + /** + * Returns the active workbench window + * + * @return the active workbench window + */ + public static IWorkbenchWindow getActiveWorkbenchWindow() { + return getDefault().getWorkbench().getActiveWorkbenchWindow(); + } + + public static IWorkbenchPage getActivePage() { + IWorkbenchWindow w = getActiveWorkbenchWindow(); + if (w != null) { + return w.getActivePage(); + } + return null; + } + + /** + * Returns the active workbench shell or null if none + * + * @return the active workbench shell or null if none + */ + public static Shell getActiveWorkbenchShell() { + IWorkbenchWindow window = getActiveWorkbenchWindow(); + if (window != null) { + return window.getShell(); + } + return null; + } + + /** + * Displays an error dialog. + */ + public static void errorDialog(String message, IStatus status) { + log(status); + Shell shell = getActiveWorkbenchShell(); + if (shell != null) { + ErrorDialog.openError(shell, LaunchMessages.getString("LaunchUIPlugin.Error"), message, status); //$NON-NLS-1$ + } + } + + /** + * Displays an error dialog. + */ + public static void errorDialog(String message, Throwable t) { + log(t); + Shell shell = getActiveWorkbenchShell(); + if (shell != null) { + IStatus status = new Status(IStatus.ERROR, getUniqueIdentifier(), 1, t.getMessage(), null); + ErrorDialog.openError(shell, LaunchMessages.getString("LaunchUIPlugin.Error"), message, status); //$NON-NLS-1$ + } + } + + // --- resource management --- + + /** Returns resource manager for this plugin */ + public UIResourceManager getPluginResources() { + if (s_resources == null) { + s_resources = new UIResourceManager(this); + s_resources.setParentManager(CDTVisualizerUIPlugin.getResources()); + } + + return s_resources; + } + + /** Releases resource manager for this plugin. */ + public void cleanupPluginResources() { + s_resources.dispose(); + } + + /** Convenience method for getting plugin resource manager */ + public static UIResourceManager getResources() { + return getDefault().getPluginResources(); + } + + /** Convenience method for looking up string resources */ + public static String getString(String key) { + return getDefault().getPluginResources().getString(key); + } + /** Convenience method for looking up string resources */ + public static String getString(String key, Object... arguments) { + return getDefault().getPluginResources().getString(key, arguments); + } + + /** Convenience method for looking up image resources */ + public static Image getImage(String key) { + return getDefault().getPluginResources().getImage(key); + } + /** Convenience method for looking up image resources */ + public static ImageDescriptor getImageDescriptor(String key) { + return getDefault().getPluginResources().getImageDescriptor(key); + } + + /** Convenience method for looking up font resources */ + public static Font getFont(String fontName, int height) { + return getDefault().getPluginResources().getFont(fontName, height); + } + /** Convenience method for looking up font resources */ + public static Font getFont(String fontName, int height, int style) { + return getDefault().getPluginResources().getFont(fontName, height, style); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/actions/RefreshAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/actions/RefreshAction.java new file mode 100644 index 00000000000..d60327715f9 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/actions/RefreshAction.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view.MulticoreVisualizer; +import org.eclipse.cdt.visualizer.ui.VisualizerAction; +import org.eclipse.swt.SWT; + +/** Select All action for Visualizer context menu. */ +public class RefreshAction extends VisualizerAction +{ + // --- members --- + + /** Visualizer instance we're associated with. */ + MulticoreVisualizer m_visualizer = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public RefreshAction() + { + setText(MulticoreVisualizerUIPlugin.getString( + "MulticoreVisualizer.actions.Refresh.text")); //$NON-NLS-1$ + setDescription(MulticoreVisualizerUIPlugin.getString( + "MulticoreVisualizer.actions.Refresh.description")); //$NON-NLS-1$ + setAccelerator(SWT.F5); + } + + /** Dispose method. */ + @Override + public void dispose() + { + m_visualizer = null; + super.dispose(); + } + + + // --- init methods --- + + /** Initializes this action for the specified view. */ + public void init(MulticoreVisualizer visualizer) + { + m_visualizer = visualizer; + } + + + // --- methods --- + + /** Invoked when action is triggered. */ + @Override + public void run() { + if (m_visualizer != null) + m_visualizer.refresh(); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/actions/SelectAllAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/actions/SelectAllAction.java new file mode 100644 index 00000000000..80123a9f526 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/actions/SelectAllAction.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view.MulticoreVisualizer; +import org.eclipse.cdt.visualizer.ui.VisualizerAction; +import org.eclipse.swt.SWT; + +/** Select All action for Visualizer context menu. */ +public class SelectAllAction extends VisualizerAction +{ + // --- members --- + + /** Visualizer instance we're associated with. */ + MulticoreVisualizer m_visualizer = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public SelectAllAction() + { + setText(MulticoreVisualizerUIPlugin.getString( + "MulticoreVisualizer.actions.SelectAll.text")); //$NON-NLS-1$ + setDescription(MulticoreVisualizerUIPlugin.getString( + "MulticoreVisualizer.actions.SelectAll.description")); //$NON-NLS-1$ + setAccelerator(SWT.CTRL + 'A'); + } + + /** Dispose method. */ + @Override + public void dispose() + { + m_visualizer = null; + super.dispose(); + } + + + // --- init methods --- + + /** Initializes this action for the specified view. */ + public void init(MulticoreVisualizer visualizer) + { + m_visualizer = visualizer; + } + + + // --- methods --- + + /** Invoked when action is triggered. */ + @Override + public void run() { + if (m_visualizer != null) + m_visualizer.selectAll(); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerCPU.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerCPU.java new file mode 100755 index 00000000000..1f92161f1fd --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerCPU.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +//---------------------------------------------------------------------------- +// VisualizerCPU +//---------------------------------------------------------------------------- + +/** Represents single CPU. */ +public class VisualizerCPU + implements Comparable +{ + // --- members --- + + /** ID of this core. */ + public int m_id; + + /** List of cores */ + protected ArrayList m_cores; + + /** Lookup table for cores. */ + protected Hashtable m_coreMap; + + + // --- constructors/destructors --- + + /** Constructor */ + public VisualizerCPU(int id) { + m_id = id; + m_cores = new ArrayList(); + m_coreMap = new Hashtable(); + } + + /** Dispose method */ + public void dispose() { + if (m_cores != null) { + for (VisualizerCore core : m_cores) { + core.dispose(); + } + m_coreMap.clear(); + m_coreMap = null; + m_cores.clear(); + m_cores = null; + } + } + + + // --- Object methods --- + + /** Returns string representation. */ + @Override + public String toString() { + return "CPU:" + m_id; //$NON-NLS-1$ + } + + + // --- accessors --- + + /** Gets ID of this CPU. */ + public int getID() { + return m_id; + } + + + // --- methods --- + + /** Gets number of cores. */ + public int getCoreCount() { + return m_cores.size(); + } + + /** Gets cores. */ + public List getCores() { + return m_cores; + } + + /** Gets core with specified ID. */ + public VisualizerCore getCore(int id) { + return m_coreMap.get(id); + } + + /** Adds core. */ + public VisualizerCore addCore(VisualizerCore core) { + m_cores.add(core); + m_coreMap.put(core.getID(), core); + return core; + } + + /** Removes core. */ + public void removeCore(VisualizerCore core) { + m_cores.remove(core); + m_coreMap.remove(core.getID()); + } + + + /** Sorts cores, cpus, etc. by IDs. */ + public void sort() { + Collections.sort(m_cores); + } + + + // --- Comparable implementation --- + + /** Compares this item to the specified item. */ + @Override + public int compareTo(VisualizerCPU o) { + int result = 0; + if (o != null) { + if (m_id < o.m_id) { + result = -1; + } + else if (m_id > o.m_id) { + result = 1; + } + } + return result; + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerCore.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerCore.java new file mode 100755 index 00000000000..87bc1c55e96 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerCore.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; + +/** Represents single core of a CPU. */ +public class VisualizerCore + implements Comparable +{ + // --- members --- + + /** CPU this core is part of. */ + public VisualizerCPU m_cpu = null; + + /** Linux CPU ID of this core. */ + public int m_id = 0; + + + // --- constructors/destructors --- + + /** Constructor */ + public VisualizerCore(VisualizerCPU cpu, int id) { + m_cpu = cpu; + m_id = id; + } + + /** Dispose method */ + public void dispose() { + } + + + // --- Object methods --- + + /** Returns string representation. */ + @Override + public String toString() { + return m_cpu + ",Core:" + m_id; //$NON-NLS-1$ + } + + + // --- accessors --- + + /** Gets CPU this core is part of. */ + public VisualizerCPU getCPU() { + return m_cpu; + } + + /** Gets Linux CPU ID of this core. */ + public int getID() { + return m_id; + } + + + // --- methods --- + + + + // --- Comparable implementation --- + + /** Compares this item to the specified item. */ + @Override + public int compareTo(VisualizerCore o) { + int result = 0; + if (o != null) { + if (m_id < o.m_id) { + result = -1; + } + else if (m_id > o.m_id) { + result = 1; + } + } + return result; + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerExecutionState.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerExecutionState.java new file mode 100644 index 00000000000..965a2e84ffe --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerExecutionState.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; + +/** + * Execution state for the different multicore visualizer objects. + */ +public enum VisualizerExecutionState { + RUNNING, + SUSPENDED, + CRASHED, + EXITED +}; diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerModel.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerModel.java new file mode 100755 index 00000000000..d62a71435d7 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerModel.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.visualizer.ui.util.Todo; + +/** + * Class representing the state of the data to display in the MulticoreVisualizer. + */ +public class VisualizerModel +{ + // --- members --- + + /** List of cpus (and cores) */ + protected ArrayList m_cpus; + + /** Lookup table for CPUs */ + protected Hashtable m_cpuMap; + + /** List of threads */ + protected ArrayList m_threads; + + /** Completion state tracker. */ + protected Todo m_todo; + + // Setting to remove exited threads, or keep them shown. + // If we are to support this, we should have a preference + // and a way to for the user to clean up old threads, + // or maybe a timeout to remove them. + private boolean m_keepExitedThreads = false; + + // --- constructors/destructors --- + + /** Constructor */ + public VisualizerModel() { + m_cpus = new ArrayList(); + m_cpuMap = new Hashtable(); + m_threads = new ArrayList(); + m_todo = new Todo(); + } + + /** Dispose method */ + public void dispose() { + if (m_cpus != null) { + for (VisualizerCPU cpu : m_cpus) { + cpu.dispose(); + } + m_cpuMap.clear(); + m_cpuMap = null; + m_cpus.clear(); + m_cpus = null; + } + if (m_threads != null) { + for (VisualizerThread thread : m_threads) { + thread.dispose(); + } + m_threads.clear(); + m_threads = null; + } + if (m_todo != null) { + m_todo.dispose(); + m_todo = null; + } + } + + + // --- accessors --- + + /** Gets completion state tracker. */ + public Todo getTodo() { + return m_todo; + } + + // --- methods --- + + /** Sorts cores, cpus, etc. by IDs. */ + public void sort() { + Collections.sort(m_cpus); + for (VisualizerCPU cpu : m_cpus) cpu.sort(); + Collections.sort(m_threads); + } + + + // --- core/cpu management --- + + /** Gets number of CPUs. */ + public int getCPUCount() { + return m_cpus.size(); + } + + /** Gets CPU with specified ID. */ + public VisualizerCPU getCPU(int id) { + return m_cpuMap.get(id); + } + + /** Gets Core with specified ID. */ + public VisualizerCore getCore(int id) { + VisualizerCore result = null; + for (VisualizerCPU cpu: m_cpus) { + result = cpu.getCore(id); + if (result != null) break; + } + return result; + } + + /** Gets CPU set. */ + public List getCPUs() { + return m_cpus; + } + + /** Adds CPU. */ + public VisualizerCPU addCPU(VisualizerCPU cpu) { + m_cpus.add(cpu); + m_cpuMap.put(cpu.getID(), cpu); + return cpu; + } + + /** Removes CPU. */ + public void removeCPU(VisualizerCPU cpu) { + m_cpus.remove(cpu); + m_cpuMap.remove(cpu.getID()); + } + + + /** Gets maximum number of cores per CPU. */ + public int getCoresPerCPU() { + int maxCores = 1; + for (VisualizerCPU cpu : m_cpus) { + int cores = cpu.getCoreCount(); + if (cores > maxCores) maxCores = cores; + } + return maxCores; + } + + + // --- thread management --- + + /** Gets threads. */ + public List getThreads() { + return m_threads; + } + + /** + * Finds thread(s) by process ID. + * If no threads are found, returns null rather + * than an empty list. + */ + public List getThreadsForProcess(int processId) { + List result = null; + for (VisualizerThread thread : m_threads) { + if (thread.getPID() == processId) { + if (result == null) result = new ArrayList(); + result.add(thread); + } + } + return result; + } + + /** + * Find a thread by GDB threadId. + * Since thread ids are unique across a GDB session, + * we can uniquely find a thread based on its id. + */ + public VisualizerThread getThread(int threadId) { + VisualizerThread result = null; + for (VisualizerThread thread : m_threads) { + if (thread.getGDBTID() == threadId) { + result = thread; + break; + } + } + return result; + } + + /** Adds thread. */ + public VisualizerThread addThread(VisualizerThread thread) { + m_threads.add(thread); + return thread; + } + + /** Removes thread. */ + public void removeThread(VisualizerThread thread) { + m_threads.remove(thread); + } + + /** + * Removes thread by GDB threadId. + */ + public void removeThread(int threadId) { + Iterator itr = m_threads.iterator(); + while (itr.hasNext()) { + VisualizerThread thread = itr.next(); + if (thread.getGDBTID() == threadId) { + itr.remove(); + break; + } + } + } + + /** + * Mark the specified thread as having exited. + */ + public void markThreadExited(int threadId) { + if (m_keepExitedThreads) { + VisualizerThread thread = getThread(threadId); + thread.setState(VisualizerExecutionState.EXITED); + } else { + removeThread(threadId); + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerThread.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerThread.java new file mode 100755 index 00000000000..9c19d57bc5b --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/model/VisualizerThread.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + * Marc Khouzam (Ericsson) - Added knowledge about execution + * state and os/gdb thread ids + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; + +/** Represents single thread. */ +public class VisualizerThread + implements Comparable +{ + // --- members --- + + /** Current core this thread is on. */ + protected VisualizerCore m_core; + + /** Process ID (pid). */ + protected int m_pid; + + /** OS Thread ID (tid). */ + protected int m_tid; + + /** Thread ID as chosen by GDB. */ + protected int m_gdbtid; + + /** Thread execution state. */ + protected VisualizerExecutionState m_threadState; + + + // --- constructors/destructors --- + + /** Constructor. */ + public VisualizerThread(VisualizerCore core, int pid, int tid, int gdbtid, VisualizerExecutionState state) { + m_core = core; + m_pid = pid; + m_tid = tid; + m_gdbtid = gdbtid; + m_threadState = state; + } + + /** Dispose method */ + public void dispose() { + m_core = null; + } + + + // --- Object methods --- + + /** Equality comparison. */ + @Override + public boolean equals(Object obj) { + boolean result = false; + if (obj instanceof VisualizerThread) { + VisualizerThread v = (VisualizerThread) obj; + result = ( + v.m_pid == m_pid && + v.m_tid == m_tid && + v.m_gdbtid == m_gdbtid + ); + } + return result; + } + + /** Returns string representation. */ + @Override + public String toString() { + StringBuffer output = new StringBuffer(); + output.append(m_core).append(",Proc:").append(m_pid) //$NON-NLS-1$ + .append(",Thread:(").append(m_tid).append(",").append(m_gdbtid).append(")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + return output.toString(); + } + + + // --- accessors --- + + /** Gets core. */ + public VisualizerCore getCore() { + return m_core; + } + + public void setCore(VisualizerCore core) { + m_core = core; + } + + /** Returns true if this is the "process" thread, i.e. + * its PID and OS TID are the same. + */ + public boolean isProcessThread() + { + return m_pid == m_tid; + } + + /** Gets process id (pid). */ + public int getPID() { + return m_pid; + } + + /** Gets thread id (tid). */ + public int getTID() { + return m_tid; + } + + /** Gets gdb thread id. */ + public int getGDBTID() { + return m_gdbtid; + } + + /** Gets thread execution state. */ + public VisualizerExecutionState getState() { + return m_threadState; + } + + /** Sets thread execution state. */ + public void setState(VisualizerExecutionState state) { + m_threadState = state; + } + + + // --- methods --- + + + + // --- Comparable implementation --- + + /** Compares this item to the specified item. */ + @Override + public int compareTo(VisualizerThread o) { + int result = 0; + if (o != null) { + if (m_pid < o.m_pid) { + result = -1; + } + else if (m_pid > o.m_pid) { + result = 1; + } + else if (m_tid < o.m_tid) { + result = -1; + } + else if (m_tid > o.m_tid) { + result = 1; + } + } + return result; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/IMulticoreVisualizerConstants.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/IMulticoreVisualizerConstants.java new file mode 100644 index 00000000000..5b3a280cacc --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/IMulticoreVisualizerConstants.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.swt.graphics.Color; + + +/** + * Constants to be used in the Multicore Visualizer. + */ +public class IMulticoreVisualizerConstants +{ + // General canvas colors + public static final Color COLOR_SELECTED = Colors.CYAN; + + // Colors for drawing threads + + /** Color to be used to draw a running thread */ + public static final Color COLOR_RUNNING_THREAD = Colors.GREEN; + /** Color to be used to draw a suspended thread */ + public static final Color COLOR_SUSPENDED_THREAD = Colors.YELLOW; + /** Color to be used to draw a crashed thread */ + public static final Color COLOR_CRASHED_THREAD = Colors.RED; + /** Color to be used to draw an exited thread (if they are being shown) */ + public static final Color COLOR_EXITED_THREAD = Colors.GRAY; + + /** Color to be used to draw an highlight for the process thread */ + public static final Color COLOR_PROCESS_THREAD = Colors.WHITE; + + // Colors for drawing cores + + /** Color to be used to draw a running core */ + public static final Color COLOR_RUNNING_CORE_FG = Colors.GREEN; + public static final Color COLOR_RUNNING_CORE_BG = Colors.DARK_GREEN; + /** Color to be used to draw a suspended core */ + public static final Color COLOR_SUSPENDED_CORE_FG = Colors.YELLOW; + public static final Color COLOR_SUSPENDED_CORE_BG = Colors.DARK_YELLOW; + /** Color to be used to draw a crashed core */ + public static final Color COLOR_CRASHED_CORE_FG = Colors.RED; + public static final Color COLOR_CRASHED_CORE_BG = Colors.DARK_RED; + + // Colors for text + + /** Color to be used to draw a the text for a thread */ + public static final Color COLOR_THREAD_TEXT_FG = Colors.WHITE; + public static final Color COLOR_THREAD_TEXT_BG = Colors.BLACK; + + /** Color to be used to draw a the text for a core */ + public static final Color COLOR_CORE_TEXT_FG = Colors.WHITE; + public static final Color COLOR_CORE_TEXT_BG = Colors.BLACK; +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java new file mode 100755 index 00000000000..8dc1a78028d --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java @@ -0,0 +1,879 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData; +import org.eclipse.cdt.dsf.gdb.launching.GDBProcess; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.RefreshAction; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.SelectAllAction; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCPU; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCore; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerExecutionState; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerModel; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DSFDebugModel; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DSFDebugModelListener; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DSFSessionState; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DebugViewUtils; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.ICPUDMContext; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.ICoreDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.cdt.visualizer.ui.canvas.GraphicCanvas; +import org.eclipse.cdt.visualizer.ui.canvas.GraphicCanvasVisualizer; +import org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin; +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.cdt.visualizer.ui.util.GUIUtils; +import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.internal.ui.commands.actions.DropToFrameCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.ResumeCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.StepIntoCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.StepOverCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.StepReturnCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.SuspendCommandAction; +import org.eclipse.debug.internal.ui.commands.actions.TerminateCommandAction; +import org.eclipse.debug.internal.ui.views.launch.LaunchView; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; + +/** + * The Multicore Visualizer is a generic visualizer that displays + * CPUs, cores, threads graphically. + * + * This visualizer uses the CDT Visualizer framework. + */ +@SuppressWarnings("restriction") +public class MulticoreVisualizer extends GraphicCanvasVisualizer + implements DSFDebugModelListener +{ + // --- constants --- + + /** Eclipse ID for this view */ + public static final String ECLIPSE_ID = "org.eclipse.cdt.dsf.gdb.multicorevisualizer.visualizer"; //$NON-NLS-1$ + + + // --- members --- + + /** + * The data model drawn by this visualizer. + */ + protected VisualizerModel fDataModel; + + /** Downcast reference to canvas. */ + protected MulticoreVisualizerCanvas m_canvas; + + /** DSF debug context session object. */ + protected DSFSessionState m_sessionState; + + /** Event listener class for DSF events */ + protected MulticoreVisualizerEventListener fEventListener; + + + // --- UI members --- + + /** Whether actions have been initialized. */ + boolean m_actionsInitialized = false; + + /** Toolbar / menu action */ + Separator m_separatorAction = null; + + /** Toolbar / menu action */ + ResumeCommandAction m_resumeAction = null; + + /** Toolbar / menu action */ + SuspendCommandAction m_suspendAction = null; + + /** Toolbar / menu action */ + TerminateCommandAction m_terminateAction = null; + + /** Toolbar / menu action */ + StepReturnCommandAction m_stepReturnAction = null; + + /** Toolbar / menu action */ + StepOverCommandAction m_stepOverAction = null; + + /** Toolbar / menu action */ + StepIntoCommandAction m_stepIntoAction = null; + + /** Toolbar / menu action */ + DropToFrameCommandAction m_dropToFrameAction = null; + + /** Toolbar / menu action */ + SelectAllAction m_selectAllAction = null; + + /** Toolbar / menu action */ + RefreshAction m_refreshAction = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public MulticoreVisualizer() + { + } + + /** Dispose method. */ + @Override + public void dispose() + { + super.dispose(); + disposeActions(); + } + + + // --- init methods --- + + /** Invoked when visualizer is created, to permit any initialization. */ + @Override + public void initializeVisualizer() { + fEventListener = new MulticoreVisualizerEventListener(this); + } + + /** Invoked when visualizer is disposed, to permit any cleanup. */ + @Override + public void disposeVisualizer() + { + // handle any other cleanup + dispose(); + } + + + // --- accessors --- + + /** Returns non-localized unique name for this visualizer. */ + @Override + public String getName() { + return "multicore"; //$NON-NLS-1$ + } + + /** Returns localized name to display for this visualizer. */ + @Override + public String getDisplayName() { + // TODO: use a string resource here. + return "Multicore Visualizer"; //$NON-NLS-1$ + } + + /** Returns localized tooltip text to display for this visualizer. */ + @Override + public String getDescription() { + // TODO: use a string resource here. + return "Displays current state of selected debug target."; //$NON-NLS-1$ + } + + + // --- canvas management --- + + /** Creates and returns visualizer canvas control. */ + @Override + public GraphicCanvas createCanvas(Composite parent) + { + m_canvas = new MulticoreVisualizerCanvas(parent); + m_canvas.addSelectionChangedListener(this); + return m_canvas; + } + + /** Invoked when canvas control should be disposed. */ + @Override + public void disposeCanvas() + { + if (m_canvas != null) { + m_canvas.removeSelectionChangedListener(this); + m_canvas.dispose(); + m_canvas = null; + } + } + + /** Invoked after visualizer control creation, */ + @Override + protected void initializeCanvas(GraphicCanvas canvas) + { + // Any workbench views left open at application shutdown may be instanced + // before our plugins are fully loaded, so make sure resource manager is initialized. + // Note: this also associates the resource manager with the Colors class; + // until this is done, the Colors constants are null. + CDTVisualizerUIPlugin.getResources(); + + m_canvas.setBackground(Colors.BLACK); + m_canvas.setForeground(Colors.GREEN); + } + + /** Returns downcast reference to grid view canvas. */ + public MulticoreVisualizerCanvas getMulticoreVisualizerCanvas() + { + return (MulticoreVisualizerCanvas) getCanvas(); + } + + /** Return the data model backing this multicore visualizer */ + public VisualizerModel getModel() { + return fDataModel; + } + + + // --- action management --- + + /** Creates actions for menus/toolbar. */ + protected void createActions() + { + if (m_actionsInitialized) return; // already done + + LaunchView debugView = DebugViewUtils.getDebugView(); + + m_separatorAction = new Separator(); + + m_resumeAction = new ResumeCommandAction(); + if (debugView != null) m_resumeAction.init(debugView); + + m_suspendAction = new SuspendCommandAction(); + if (debugView != null) m_suspendAction.init(debugView); + + m_terminateAction = new TerminateCommandAction(); + if (debugView != null) m_terminateAction.init(debugView); + + + m_stepReturnAction = new StepReturnCommandAction(); + if (debugView != null) m_stepReturnAction.init(debugView); + + m_stepOverAction = new StepOverCommandAction(); + if (debugView != null) m_stepOverAction.init(debugView); + + m_stepIntoAction = new StepIntoCommandAction(); + if (debugView != null) m_stepIntoAction.init(debugView); + + m_dropToFrameAction = new DropToFrameCommandAction(); + if (debugView != null) m_dropToFrameAction.init(debugView); + + m_selectAllAction = new SelectAllAction(); + m_selectAllAction.init(this); + + m_refreshAction = new RefreshAction(); + m_refreshAction.init(this); + + // Note: debug view may not be initialized at startup, + // so we'll pretend the actions are not yet updated, + // and reinitialize them later. + m_actionsInitialized = (debugView != null); + } + + /** Updates actions displayed on menu/toolbars. */ + protected void updateActions() + { + if (! m_actionsInitialized) return; + + // TODO: do we need any special enabling code here? + // Seems like we can rely on the enabling done by the DebugView itself, + // since we've associated these actions with it. + + boolean enabled = hasSelection(); + + m_resumeAction.setEnabled(enabled); + m_suspendAction.setEnabled(enabled); + m_terminateAction.setEnabled(enabled); + + m_stepReturnAction.setEnabled(enabled); + m_stepOverAction.setEnabled(enabled); + m_stepIntoAction.setEnabled(enabled); + m_dropToFrameAction.setEnabled(enabled); + + } + + /** Updates actions specific to context menu. */ + protected void updateContextMenuActions(Point location) + { + } + + /** Cleans up actions. */ + protected void disposeActions() { + if (m_resumeAction != null) { + m_resumeAction.dispose(); + m_resumeAction = null; + } + + if (m_suspendAction != null) { + m_suspendAction.dispose(); + m_suspendAction = null; + } + + if (m_terminateAction != null) { + m_terminateAction.dispose(); + m_terminateAction = null; + } + + if (m_stepReturnAction != null) { + m_stepReturnAction.dispose(); + m_stepReturnAction = null; + } + + if (m_stepOverAction != null) { + m_stepOverAction.dispose(); + m_stepOverAction = null; + } + + if (m_stepIntoAction != null) { + m_stepIntoAction.dispose(); + m_stepIntoAction = null; + } + + if (m_dropToFrameAction != null) { + m_dropToFrameAction.dispose(); + m_dropToFrameAction = null; + } + + if (m_selectAllAction != null) { + m_selectAllAction.dispose(); + m_selectAllAction = null; + } + + if (m_refreshAction != null) { + m_refreshAction.dispose(); + m_refreshAction = null; + } + + m_actionsInitialized = false; + } + + + // --- menu/toolbar management --- + + /** Invoked when visualizer is selected, to populate the toolbar. */ + @Override + public void populateToolBar(IToolBarManager toolBarManager) + { + // initialize menu/toolbar actions, if needed + createActions(); + + toolBarManager.add(m_resumeAction); + toolBarManager.add(m_suspendAction); + toolBarManager.add(m_terminateAction); + + toolBarManager.add(m_separatorAction); + + toolBarManager.add(m_stepReturnAction); + toolBarManager.add(m_stepOverAction); + toolBarManager.add(m_stepIntoAction); + toolBarManager.add(m_dropToFrameAction); + + updateActions(); + } + + /** Invoked when visualizer is selected, to populate the toolbar's menu. */ + @Override + public void populateMenu(IMenuManager menuManager) + { + // initialize menu/toolbar actions, if needed + createActions(); + + // TODO: Anything we want to hide on the toolbar menu? + + updateActions(); + } + + /** Invoked when visualizer view's context menu is invoked, to populate it. */ + @Override + public void populateContextMenu(IMenuManager menuManager) + { + // initialize menu/toolbar actions, if needed + createActions(); + + menuManager.add(m_resumeAction); + menuManager.add(m_suspendAction); + menuManager.add(m_terminateAction); + + menuManager.add(m_separatorAction); + + menuManager.add(m_stepReturnAction); + menuManager.add(m_stepOverAction); + menuManager.add(m_stepIntoAction); + menuManager.add(m_dropToFrameAction); + + menuManager.add(m_separatorAction); + + menuManager.add(m_selectAllAction); + menuManager.add(m_refreshAction); + + updateActions(); + Point location = m_viewer.getContextMenuLocation(); + updateContextMenuActions(location); + } + + + // --- visualizer selection management --- + + /** Invoked when visualizer has been selected. */ + @Override + public void visualizerSelected() { + updateActions(); + }; + + /** Invoked when another visualizer has been selected, hiding this one. */ + @Override + public void visualizerDeselected() { + }; + + + // --- workbench selection management --- + + /** + * Tests whether if the IVisualizer can display the selection + * (or something reachable from it). + */ + @Override + public int handlesSelection(ISelection selection) + { + // By default, we don't support anything. + int result = 0; + + Object sel = SelectionUtils.getSelectedObject(selection); + if (sel instanceof GdbLaunch || + sel instanceof GDBProcess || + sel instanceof IDMVMContext) + { + result = 1; + } + else { + result = 0; + } + + return result; + } + + /** + * Invoked by VisualizerViewer when workbench selection changes. + */ + @Override + public void workbenchSelectionChanged(ISelection selection) + { + refresh(); + } + + /** Refreshes visualizer content from model. */ + public void refresh() + { + // See if we need to update our debug info from + // the workbench selection. This will be done asynchronously. + boolean changed = updateDebugContext(); + + // Even if debug info doesn't change, we still want to + // check whether the canvas selection needs to change + // to reflect the current workbench selection. + if (!changed) updateCanvasSelection(); + } + + + // --- ISelectionChangedListener implementation --- + + /** + * Invoked when visualizer control's selection changes. + * Sets control selection as its own selection, + * and raises selection changed event for any listeners. + */ + @Override + public void selectionChanged(SelectionChangedEvent event) { + super.selectionChanged(event); + + // Force Debug View's selection to reflect visualizer selection, + // since debug view doesn't update itself from the workbench selection. + // NOTE: This can be overridden by the model selection policy, if there is one. + ISelection debugViewSelection = visualizerToDebugViewSelection(getSelection()); + DebugViewUtils.setDebugViewSelection(debugViewSelection); + + // update actions to reflect change of selection + updateActions(); + } + + + // --- Selection conversion methods --- + + /** Gets debug view selection from visualizer selection. */ + protected ISelection visualizerToDebugViewSelection(ISelection visualizerSelection) + { + MulticoreVisualizerSelectionFinder selectionFinder = + new MulticoreVisualizerSelectionFinder(); + ISelection workbenchSelection = + selectionFinder.findSelection(visualizerSelection); + return workbenchSelection; + } + + /** Gets visualizer selection from debug view selection. */ + protected ISelection workbenchToVisualizerSelection(ISelection workbenchSelection) + { + ISelection visualizerSelection = null; + + List items = SelectionUtils.getSelectedObjects(workbenchSelection); + + // Use the current canvas model to match Debug View items + // with corresponding threads, if any. + VisualizerModel model = m_canvas.getModel(); + if (model != null) { + + Set selected = new HashSet(); + + for (Object item : items) { + + // Currently, we ignore selections other than DSF context objects. + // TODO: any other cases where we could map selections to canvas? + if (item instanceof IDMVMContext) + { + IDMContext context = ((IDMVMContext) item).getDMContext(); + + IMIProcessDMContext processContext = + DMContexts.getAncestorOfType(context, IMIProcessDMContext.class); + int pid = Integer.parseInt(processContext.getProcId()); + + IMIExecutionDMContext execContext = + DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + int tid = (execContext == null) ? 0 : execContext.getThreadId(); + + if (tid == 0) { // process + List threads = model.getThreadsForProcess(pid); + if (threads != null) { + selected.addAll(threads); + } + } + else { // thread + VisualizerThread thread = model.getThread(tid); + if (thread != null) { + selected.add(thread); + } + } + } + } + + visualizerSelection = SelectionUtils.toSelection(selected); + } + + return visualizerSelection; + } + + + // --- DSF Context Management --- + + /** Updates debug context being displayed by canvas. + * Returns true if canvas context actually changes, false if not. + */ + public boolean updateDebugContext() + { + String sessionId = null; + IAdaptable debugContext = DebugUITools.getDebugContext(); + if (debugContext instanceof IDMVMContext) { + sessionId = ((IDMVMContext)debugContext).getDMContext().getSessionId(); + } else if (debugContext instanceof GdbLaunch) { + GdbLaunch gdbLaunch = (GdbLaunch)debugContext; + if (gdbLaunch.isTerminated() == false) { + sessionId = gdbLaunch.getSession().getId(); + } + } else if (debugContext instanceof GDBProcess) { + ILaunch launch = ((GDBProcess)debugContext).getLaunch(); + if (launch.isTerminated() == false && + launch instanceof GdbLaunch) { + sessionId = ((GdbLaunch)launch).getSession().getId(); + } + } + + return setDebugSession(sessionId); + } + + /** Sets debug context being displayed by canvas. + * Returns true if canvas context actually changes, false if not. + */ + public boolean setDebugSession(String sessionId) { + boolean changed = true; + + if (m_sessionState != null && + ! m_sessionState.getSessionID().equals(sessionId)) + { + m_sessionState.removeServiceEventListener(fEventListener); + m_sessionState.dispose(); + m_sessionState = null; + changed = true; + } + + if (m_sessionState == null && + sessionId != null) + { + m_sessionState = new DSFSessionState(sessionId); + m_sessionState.addServiceEventListener(fEventListener); + changed = true; + } + + if (changed) update(); + + return changed; + } + + + // --- Update methods --- + + /** Updates visualizer canvas state. */ + public void update() { + // Create new VisualizerModel and hand it to canvas, + // TODO: cache the VisualizerModel somehow and update it, + // rather than creating it from scratch each time. + if (m_sessionState == null) { + // no state to display, we can immediately clear the canvas + setCanvasModel(null); + return; + } + m_sessionState.execute(new DsfRunnable() { @Override public void run() { + // get model asynchronously, and update canvas + // in getVisualizerModelDone(). + getVisualizerModel(); + }}); + } + + /** Sets canvas model. (Also updates canvas selection.) */ + protected void setCanvasModel(VisualizerModel model) { + final VisualizerModel model_f = model; + GUIUtils.exec(new Runnable() { @Override public void run() { + m_canvas.setModel(model_f); + + // Update the canvas's selection from the current workbench selection. + updateCanvasSelectionInternal(); + }}); + } + + /** Updates canvas selection from current workbench selection. */ + protected void updateCanvasSelection() { + GUIUtils.exec(new Runnable() { @Override public void run() { + // Update the canvas's selection from the current workbench selection. + updateCanvasSelectionInternal(); + }}); + } + + /** Updates canvas selection from current workbench selection. + * Note: this method assumes it is called on the UI thread. */ + protected void updateCanvasSelectionInternal() + { + updateCanvasSelectionInternal(SelectionUtils.getWorkbenchSelection()); + } + + /** Updates canvas selection from current workbench selection. + * Note: this method assumes it is called on the UI thread. */ + protected void updateCanvasSelectionInternal(ISelection selection) + { + ISelection canvasSelection = workbenchToVisualizerSelection(selection); + + // canvas does not raise a selection changed event in this case + // to avoid circular selection update events + if (canvasSelection != null) + m_canvas.setSelection(canvasSelection, false); + } + + + /** Selects all thread(s) displayed in the canvas. */ + public void selectAll() + { + m_canvas.selectAll(); + } + + // --- Visualizer model update methods --- + + /** Starts visualizer model request. + * Calls getVisualizerModelDone() with the constructed model. + */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getVisualizerModel() { + fDataModel = new VisualizerModel(); + DSFDebugModel.getCPUs(m_sessionState, this, fDataModel); + } + + /** Invoked when getModel() request completes. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getVisualizerModelDone(VisualizerModel model) { + model.sort(); + setCanvasModel(model); + } + + + // --- DSFDebugModelListener implementation --- + + /** Invoked when DSFDebugModel.getCPUs() completes. */ + @Override + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getCPUsDone(ICPUDMContext[] cpuContexts, Object arg) + { + VisualizerModel model = (VisualizerModel) arg; + + if (cpuContexts == null || cpuContexts.length == 0) { + // Whoops, no CPU data. + // We'll fake a CPU and use it to contain any cores we find. + + model.addCPU(new VisualizerCPU(0)); + + // keep track of CPUs left to visit + model.getTodo().add(1); + + // Collect core data. + DSFDebugModel.getCores(m_sessionState, this, model); + } else { + // keep track of CPUs left to visit + int count = cpuContexts.length; + model.getTodo().add(count); + + for (ICPUDMContext cpuContext : cpuContexts) { + int cpuID = Integer.parseInt(cpuContext.getId()); + model.addCPU(new VisualizerCPU(cpuID)); + + // Collect core data. + DSFDebugModel.getCores(m_sessionState, cpuContext, this, model); + } + + } + } + + + /** Invoked when getCores() request completes. */ + @Override + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getCoresDone(ICPUDMContext cpuContext, + ICoreDMContext[] coreContexts, + Object arg) + { + VisualizerModel model = (VisualizerModel) arg; + + if (coreContexts == null || coreContexts.length == 0) { + // no cores for this cpu context + // That's fine. + } else { + int cpuID = Integer.parseInt(cpuContext.getId()); + VisualizerCPU cpu = model.getCPU(cpuID); + + // keep track of Cores left to visit + int count = coreContexts.length; + model.getTodo().add(count); + + for (ICoreDMContext coreContext : coreContexts) { + int coreID = Integer.parseInt(coreContext.getId()); + cpu.addCore(new VisualizerCore(cpu, coreID)); + + // Collect thread data + DSFDebugModel.getThreads(m_sessionState, cpuContext, coreContext, this, model); + } + } + + // keep track of CPUs visited + // note: do this _after_ incrementing for cores + done(1, model); + } + + + /** Invoked when getThreads() request completes. */ + @Override + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getThreadsDone(ICPUDMContext cpuContext, + ICoreDMContext coreContext, + IDMContext[] threadContexts, + Object arg) + { + VisualizerModel model = (VisualizerModel) arg; + + if (threadContexts == null || threadContexts.length == 0) { + // no threads for this core + // That's fine. + } else { + // keep track of threads left to visit + int count = threadContexts.length; + model.getTodo().add(count); + + for (IDMContext threadContext : threadContexts) { + IMIExecutionDMContext execContext = + DMContexts.getAncestorOfType(threadContext, IMIExecutionDMContext.class); + + // Don't add the thread to the model just yet, let's wait until we have its data and execution state. + // Collect thread data + DSFDebugModel.getThreadData(m_sessionState, cpuContext, coreContext, execContext, this, model); + } + + } + + // keep track of cores visited + // note: do this _after_ incrementing for threads + done(1, model); + } + + /** Invoked when getThreads() request completes. */ + @Override + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getThreadDataDone(ICPUDMContext cpuContext, + ICoreDMContext coreContext, + IMIExecutionDMContext execContext, + IThreadDMData threadData, + Object arg) + { + + // Don't add the thread to the model just yet, let's wait until we have its execution state. + DSFDebugModel.getThreadExecutionState(m_sessionState, cpuContext, coreContext, execContext, threadData, this, arg); + } + + + /** Invoked when getThreadExecutionState() request completes. */ + @Override + @ConfinedToDsfExecutor("getSession().getExecutor()") + public void getThreadExecutionStateDone(ICPUDMContext cpuContext, + ICoreDMContext coreContext, + IMIExecutionDMContext execContext, + IThreadDMData threadData, + VisualizerExecutionState state, + Object arg) + { + VisualizerModel model = (VisualizerModel) arg; + int cpuID = Integer.parseInt(cpuContext.getId()); + VisualizerCPU cpu = model.getCPU(cpuID); + int coreID = Integer.parseInt(coreContext.getId()); + VisualizerCore core = cpu.getCore(coreID); + + if (state == null) { + // Unable to obtain execution state. Assume running + state = VisualizerExecutionState.RUNNING; + } + + IMIProcessDMContext processContext = + DMContexts.getAncestorOfType(execContext, IMIProcessDMContext.class); + int pid = Integer.parseInt(processContext.getProcId()); + int tid = execContext.getThreadId(); + String osTIDValue = threadData.getId(); + + // If we can't get the real Linux OS tid, fallback to using the gdb thread id + int osTid = (osTIDValue == null) ? tid : Integer.parseInt(osTIDValue); + + model.addThread(new VisualizerThread(core, pid, osTid, tid, state)); + + // keep track of threads visited + done(1, model); + } + + /** Update "done" count for current visualizer model. */ + protected void done(int n, VisualizerModel model) { + model.getTodo().done(n); + if (model.getTodo().isDone()) { + getVisualizerModelDone(model); + } + } +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCPU.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCPU.java new file mode 100755 index 00000000000..fc0cf24f29d --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCPU.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.cdt.visualizer.ui.util.GUIUtils; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; + +/** + * Graphic object for MulticoreVisualizer. + */ +public class MulticoreVisualizerCPU extends MulticoreVisualizerGraphicObject +{ + // --- members --- + + /** CPU ID. */ + protected int m_id; + + /** Child cores. */ + protected ArrayList m_cores; + + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerCPU(int id) + { + m_id = id; + m_cores = new ArrayList(); + } + + /** Dispose method */ + @Override + public void dispose() { + super.dispose(); + } + + + // --- accessors --- + + /** Gets CPU ID. */ + public int getID() { + return m_id; + } + + + // --- methods --- + + /** Adds child core. */ + public void addCore(MulticoreVisualizerCore core) + { + m_cores.add(core); + } + + /** Removes child core. */ + public void removeCore(MulticoreVisualizerCore core) + { + m_cores.remove(core); + } + + /** Gets list of child cores. */ + public List getCores() + { + return m_cores; + } + + + // --- paint methods --- + + /** Invoked to allow element to paint itself on the viewer canvas */ + @Override + public void paintContent(GC gc) { + Color fg, bg; + fg = Colors.getColor(0,255,0); + bg = Colors.getColor(0,64,0); + gc.setForeground(fg); + gc.setBackground(bg); + + gc.fillRectangle(m_bounds); + gc.drawRectangle(m_bounds); + } + + /** Returns true if object has decorations to paint. */ + @Override + public boolean hasDecorations() { + return true; + } + + /** Invoked to allow element to paint decorations on top of anything drawn on it */ + @Override + public void paintDecorations(GC gc) { + if (m_bounds.height > 20) { + Color fg, bg; + fg = Colors.getColor(0,255,0); + bg = Colors.getColor(0,64,0); + gc.setForeground(fg); + gc.setBackground(bg); + + int text_indent = 6; + int tx = m_bounds.x + m_bounds.width - text_indent; + int ty = m_bounds.y + m_bounds.height - text_indent; + GUIUtils.drawTextAligned(gc, Integer.toString(m_id), tx, ty, false, false); + } + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java new file mode 100755 index 00000000000..993e2270b65 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java @@ -0,0 +1,896 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCPU; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCore; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerModel; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread; +import org.eclipse.cdt.visualizer.ui.canvas.GraphicCanvas; +import org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin; +import org.eclipse.cdt.visualizer.ui.util.GUIUtils; +import org.eclipse.cdt.visualizer.ui.util.MouseMonitor; +import org.eclipse.cdt.visualizer.ui.util.SelectionManager; +import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; +import org.eclipse.cdt.visualizer.ui.util.Timer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + + +/** + * MulticoreVisualizer's display canvas. + */ +public class MulticoreVisualizerCanvas extends GraphicCanvas + implements ISelectionProvider +{ + // --- constants --- + + /** Canvas update interval in milliseconds. */ + protected static final int CANVAS_UPDATE_INTERVAL = 100; + + /** Spacing to allow between threads, when many are displayed on same tile. */ + protected static final int THREAD_SPACING = 8; + + + // --- members --- + + /** Update timer */ + protected Timer m_updateTimer = null; + + /** Whether we need to recache graphic objects. */ + protected boolean m_recache = true; + + /** + * Whether we need to recache objects that depend on target state. + */ + protected boolean m_recacheState = true; + + /** + * Whether view size has changed, requiring us to recalculate object sizes. + */ + protected boolean m_recacheSizes = true; + + /** Whether we need to repaint the canvas */ + protected boolean m_update = true; + + + // --- UI members --- + + /** Text font */ + protected Font m_textFont = null; + + /** Externally visible selection manager. */ + protected SelectionManager m_selectionManager; + + /** Mouse-drag marquee graphic element */ + protected MulticoreVisualizerMarquee m_marquee = null; + + /** Last mouse down/up point, for shift-click selections. */ + protected Point m_lastSelectionClick = new Point(0,0); + + /** Mouse click/drag monitor */ + protected MouseMonitor m_mouseMonitor = null; + + + // --- cached repaint state --- + + /** Current visualizer model we're displaying. */ + protected VisualizerModel m_model = null; + + /** Number of CPUs to display. */ + protected int m_cpu_count = 15; + + /** Number of Cores per CPU to display. */ + protected int m_cores_per_cpu = 3; + + /** List of CPUs we're displaying. */ + protected ArrayList m_cpus = null; + /** Mapping from model to view objects. */ + protected Hashtable m_cpuMap = null; + + /** List of CPU cores we're displaying. */ + protected ArrayList m_cores = null; + /** Mapping from model to view objects. */ + protected Hashtable m_coreMap = null; + + /** Graphic objects representing threads */ + protected ArrayList m_threads = null; + /** Mapping from model to view objects. */ + protected Hashtable m_threadMap = null; + + /** Selected PIDs. */ + protected HashSet m_selectedPIDs = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public MulticoreVisualizerCanvas(Composite parent) { + super(parent); + initMulticoreVisualizerCanvas(parent); + } + + /** Dispose method. */ + @Override + public void dispose() { + cleanupMulticoreVisualizerCanvas(); + super.dispose(); + } + + + // --- init methods --- + + /** Initializes control */ + protected void initMulticoreVisualizerCanvas(Composite parent) { + // perform any initialization here + + // text font + m_textFont = CDTVisualizerUIPlugin.getResources().getFont("Luxi Sans", 8); //$NON-NLS-1$ + setFont(m_textFont); + + // initialize cached state storage + m_cpus = new ArrayList(); + m_cpuMap = new Hashtable(); + + m_cores = new ArrayList(); + m_coreMap = new Hashtable(); + + m_threads = new ArrayList(); + m_threadMap = new Hashtable(); + + m_selectedPIDs = new HashSet(); + + // mouse-drag monitor + m_mouseMonitor = new MouseMonitor(this) { + /** Invoked for a selection click at the specified point. */ + @Override + public void select(int x, int y, int keys) { + MulticoreVisualizerCanvas.this.select(x, y, keys); + } + + /** Invoked for a double click at the specified point. */ + @Override + public void mouseDoubleClick(int button, int x, int y, int keys) { + MulticoreVisualizerCanvas.this.select(x, y, keys); + } + + /** Invoked for a menu mouse down at the specified point. */ + @Override + public void mouseDown(int button, int x, int y, int keys) { + if (button == RIGHT_BUTTON) { + if (! hasSelection()) { + // If there isn't a selection currently, try to + // select item(s) under the mouse before popping up the context menu. + MulticoreVisualizerCanvas.this.select(x, y, keys); + } + } + } + + /** Invoked when mouse is dragged. */ + @Override + public void drag(int button, int x, int y, int keys, int dragState) { + if (button == LEFT_BUTTON) { + MulticoreVisualizerCanvas.this.drag(x, y, keys, dragState); + } + } + }; + + // selection marquee + m_marquee = new MulticoreVisualizerMarquee(); + + // selection manager + m_selectionManager = new SelectionManager(this, "MulticoreVisualizerCanvas selection manager"); //$NON-NLS-1$ + + // add update timer + m_updateTimer = new Timer(CANVAS_UPDATE_INTERVAL) { + @Override + public void run() { + update(); + } + }; + m_updateTimer.setRepeating(false); // one-shot timer + m_updateTimer.start(); + } + + /** Cleans up control */ + protected void cleanupMulticoreVisualizerCanvas() { + if (m_updateTimer != null) { + m_updateTimer.dispose(); + m_updateTimer = null; + } + if (m_marquee != null) { + m_marquee.dispose(); + m_marquee = null; + } + if (m_mouseMonitor != null) { + m_mouseMonitor.dispose(); + m_mouseMonitor = null; + } + if (m_selectionManager != null) { + m_selectionManager.dispose(); + m_selectionManager = null; + } + if (m_cpus != null) { + m_cpus.clear(); + m_cpus = null; + } + if (m_cpuMap != null) { + m_cpuMap.clear(); + m_cpuMap = null; + } + if (m_cores != null) { + m_cores.clear(); + m_cores = null; + } + if (m_coreMap != null) { + m_coreMap.clear(); + m_coreMap = null; + } + if (m_threads != null) { + m_threads.clear(); + m_threads = null; + } + if (m_threadMap != null) { + m_threadMap.clear(); + m_threadMap = null; + } + if (m_selectedPIDs != null) { + m_selectedPIDs.clear(); + m_selectedPIDs = null; + } + } + + + // --- accessors --- + + /** Gets currently displayed model. */ + public VisualizerModel getModel() + { + return m_model; + } + + /** Sets model to display, and requests canvas update. */ + public void setModel(VisualizerModel model) + { + m_model = model; + requestRecache(); + requestUpdate(); + } + + + + // --- resize methods --- + + /** Invoked when control is resized. */ + @Override + public void resized(Rectangle bounds) { + requestRecache(false, true); + // note: resize itself will trigger an update, so we don't have to request one + } + + + // --- update methods --- + + /** + * Requests an update on next timer tick. + * NOTE: use this method instead of normal update(), + * multiple update requests on same tick are batched. + */ + public void requestUpdate() { + GUIUtils.exec(new Runnable() { @Override public void run() { + m_updateTimer.start(); + }}); + } + + + // --- paint methods --- + + /** Requests that next paint call should recache state and/or size information */ + // synchronized so we don't change recache flags while doing a recache + public synchronized void requestRecache() { + requestRecache(true, true); + } + + /** Requests that next paint call should recache state and/or size information */ + // synchronized so we don't change recache flags while doing a recache + public synchronized void requestRecache(boolean state, boolean sizes) { + m_recache = true; + // NOTE: we intentionally OR these flags with any pending request(s) + m_recacheState |= state; + m_recacheSizes |= sizes; + } + + /** Fits n square items into a rectangle of the specified size. + * Returns largest edge of one of the square items that allows + * them all to pack neatly in rows/columns in the specified area. */ + public int fitSquareItems(int nitems, int width, int height) { + int max_edge = 0; + if (width > height) { + for (int items_per_row = nitems; items_per_row > 0; --items_per_row) { + int rows = (int) Math.ceil(1.0 * nitems / items_per_row); + int w = width / items_per_row; + int h = height / rows; + int edge = (w < h) ? w : h; + if (edge * rows > height || edge * items_per_row > width) continue; + if (edge > max_edge) max_edge = edge; + } + } + else { + for (int items_per_col = nitems; items_per_col > 0; --items_per_col) { + int cols = (int) Math.ceil(1.0 * nitems / items_per_col); + int w = width / cols; + int h = height / items_per_col; + int edge = (w < h) ? w : h; + if (edge * cols > width || edge * items_per_col > height) continue; + if (edge > max_edge) max_edge = edge; + } + } + return max_edge; + } + + /** Recache persistent objects (tiles, etc.) for new monitor */ + // synchronized so we don't change recache flags while doing a recache + public synchronized void recache() { + if (! m_recache) return; // nothing to do, free the lock quickly + + if (m_recacheState) { + + // clear all grid view objects + clear(); + + // clear cached state + m_cpus.clear(); + m_cores.clear(); + m_threads.clear(); + + // For debugging purposes only, allows us to force a CPU count. + //int cpu_count = 0; + //int force_cpu_count = 2; + + if (m_model != null) { + for (VisualizerCPU cpu : m_model.getCPUs()) { + //if (force_cpu_count >= cpu_count) break; + //cpu_count++; + MulticoreVisualizerCPU mcpu = new MulticoreVisualizerCPU(cpu.getID()); + m_cpus.add(mcpu); + m_cpuMap.put(cpu, mcpu); + for (VisualizerCore core : cpu.getCores()) { + MulticoreVisualizerCore mcore = new MulticoreVisualizerCore(mcpu, core.getID()); + m_cores.add(mcore); + m_coreMap.put(core, mcore); + } + } + } + /* + while (cpu_count < force_cpu_count) { + MulticoreVisualizerCPU mcpu = new MulticoreVisualizerCPU(cpu_count); + m_cpus.add(mcpu); + cpu_count++; + } + */ + + // we've recached state, which implies recacheing sizes too + m_recacheState = false; + m_recacheSizes = true; + } + + if (m_recacheSizes) { + // update cached size information + + // General margin/spacing constants. + int cpu_margin = 8; // margin around edges of CPU grid + int cpu_separation = 6; // spacing between CPUS + + int core_margin = 4; // margin around cores in a CPU + int core_separation = 2; // spacing between cores + + // Get overall area we have for laying out content. + Rectangle bounds = getClientArea(); + GUIUtils.inset(bounds, cpu_margin); + + // Figure out area to allocate to each CPU box. + int ncpus = m_cpus.size(); + int width = bounds.width + cpu_separation; + int height = bounds.height + cpu_separation; + int cpu_edge = fitSquareItems(ncpus, width, height); + int cpu_size = cpu_edge - cpu_separation; + if (cpu_size < 0) cpu_size = 0; + + // Calculate area on each CPU for placing cores. + int ncores = m_cores.size(); + int cpu_width = cpu_size - core_margin * 2 + core_separation; + int cpu_height = cpu_size - core_margin * 2 + core_separation; + int core_edge = fitSquareItems(ncores, cpu_width, cpu_height); + int core_size = core_edge - core_separation; + if (core_size < 0) core_size = 0; + + int x = bounds.x, y = bounds.y; + for (MulticoreVisualizerCPU cpu : m_cpus) { + cpu.setBounds(x, y, cpu_size-1, cpu_size-1); + + int left = x + core_margin; + int cx = left, cy = y + core_margin; + for (MulticoreVisualizerCore core : cpu.getCores()) + { + core.setBounds(cx, cy, core_size, core_size); + + cx += core_size + core_separation; + if (cx + core_size > x + cpu_size) { + cx = left; + cy += core_size + core_separation; + } + } + + x += cpu_size + cpu_separation; + if (x + cpu_size > bounds.x + width) { + x = bounds.x; + y += cpu_size + cpu_separation; + } + } + + m_recacheSizes = false; + } + } + + /** Invoked when canvas repaint event is raised. + * Default implementation clears canvas to background color. + */ + @Override + public void paintCanvas(GC gc) { + // NOTE: We have a little setup to do first, + // so we delay clearing/redrawing the canvas until needed, + // to minimize any potential visual flickering. + + // recache/resize tiles & shims if needed + recache(); + + // do any "per frame" updating/replacement of graphic objects + + // recalculate process/thread graphic objects on the fly + // TODO: can we cache/pool these and just move them around? + for (MulticoreVisualizerCore core : m_cores) { + core.removeAllThreads(); + } + m_threads.clear(); + m_threadMap.clear(); + + // update based on current processes/threads + if (m_model != null) { + + // NOTE: we assume that we've already created and sized the graphic + // objects for cpus/cores in recache() above, + // so we can use these to determine the size/location of more dynamic elements + // like processes and threads + + for (VisualizerThread thread : m_model.getThreads()) { + VisualizerCore core = thread.getCore(); + MulticoreVisualizerCore mcore = m_coreMap.get(core); + if (mcore != null) { + MulticoreVisualizerThread mthread = + new MulticoreVisualizerThread(mcore, thread); + mcore.addThread(mthread); + m_threads.add(mthread); + m_threadMap.put(thread, mthread); + } + } + + // now set sizes of processes/threads for each tile + for (MulticoreVisualizerCore core : m_cores) { + Rectangle bounds = core.getBounds(); + + // how we lay out threads depends on how many there are + List threads = core.getThreads(); + int threadspotsize = MulticoreVisualizerThread.THREAD_SPOT_SIZE; + int threadheight = threadspotsize + THREAD_SPACING; + int count = threads.size(); + int tileheight = bounds.height - 4; + int tx = bounds.x + 2; + int ty = bounds.y + 2; + int dty = (count < 1) ? 0 : tileheight / count; + if (dty > threadheight) dty = threadheight; + if (count > 0 && dty * count <= tileheight) { + ty = bounds.y + 2 + (tileheight - (dty * count)) / 2; + if (ty < bounds.y + 2) ty = bounds.y + 2; + } + else if (count > 0) { + dty = tileheight / count; + if (dty > threadheight) dty = threadheight; + } + int t = 0; + for (MulticoreVisualizerThread threadobj : threads) { + int y = ty + dty * (t++); + threadobj.setBounds(tx, y, threadspotsize, threadspotsize); + } + } + } + + // restore canvas object highlighting from model object selection + restoreSelection(); + + // FIXME: enable secondary highlight for threads that are + // part of a selected process. + m_selectedPIDs.clear(); + for (MulticoreVisualizerThread mthread : m_threads) { + if (mthread.isSelected()) { + m_selectedPIDs.add(mthread.getPID()); + } + } + for (MulticoreVisualizerThread mthread : m_threads) { + mthread.setProcessSelected(m_selectedPIDs.contains(mthread.getPID())); + } + + // NOW we can clear the background + clearCanvas(gc); + + // Make sure color/font resources are properly initialized. + MulticoreVisualizerUIPlugin.getResources(); + + // paint cpus + for (MulticoreVisualizerCPU cpu : m_cpus) { + cpu.paintContent(gc); + } + + // paint cores + for (MulticoreVisualizerCore core : m_cores) { + core.paintContent(gc); + } + + // paint cpus IDs on top of cores + for (MulticoreVisualizerCPU cpu : m_cpus) { + cpu.paintDecorations(gc); + } + + // paint threads on top of cores + for (MulticoreVisualizerThread thread : m_threads) { + thread.paintContent(gc); + } + + // paint drag-selection marquee last, so it's on top. + m_marquee.paintContent(gc); + } + + + // --- mouse event handlers --- + + /** Invoked when mouse is dragged. */ + public void drag(int x, int y, int keys, int dragState) + { + Rectangle region = m_mouseMonitor.getDragRegion(); + switch (dragState) { + case MouseMonitor.MOUSE_DRAG_BEGIN: + m_marquee.setBounds(region); + m_marquee.setVisible(true); + update(); + break; + case MouseMonitor.MOUSE_DRAG: + m_marquee.setBounds(region); + update(); + break; + case MouseMonitor.MOUSE_DRAG_END: + default: + m_marquee.setBounds(region); + m_marquee.setVisible(false); + + boolean addToSelection = MouseMonitor.isShiftDown(keys); + boolean toggleSelection = MouseMonitor.isControlDown(keys); + + selectRegion(m_marquee.getBounds(), addToSelection, toggleSelection); + + // remember last mouse-up point for shift-click selection + m_lastSelectionClick.x = x; + m_lastSelectionClick.y = y; + + update(); + break; + } + } + + /** Invoked for a selection click at the specified point. */ + public void select(int x, int y, int keys) + { + boolean addToSelection = MouseMonitor.isShiftDown(keys); + boolean toggleSelection = MouseMonitor.isControlDown(keys); + + selectPoint(x,y, addToSelection, toggleSelection); + } + + + // --- selection methods --- + + /** + * Selects item(s), if any, in specified region + * + * If addToSelection is true, appends item(s) to current selection + * without changing selection state of other items. + * + * If toggleSelection is true, toggles selection of item(s) + * without changing selection state of other items. + * + * If both are true, deselects item(s) + * without changing selection state of other items. + * + * Otherwise, selects item(s) and deselects other items. + */ + public void selectRegion(Rectangle region, + boolean addToSelection, boolean toggleSelection) + { + // currently, we select/deselect threads, not processes or tiles + if (m_threads != null) { + + boolean changed = false; + + for (MulticoreVisualizerThread tobj : m_threads) { + boolean within = tobj.isWithin(region); + + if (addToSelection && toggleSelection) { + if (within) { + tobj.setSelected(false); + changed = true; + } + } + else if (addToSelection) { + if (within) { + tobj.setSelected(true); + changed = true; + } + } + else if (toggleSelection) { + if (within) { + tobj.setSelected(! tobj.isSelected()); + changed = true; + } + } + else { + tobj.setSelected(within); + changed = true; + } + } + + if (changed) + selectionChanged(); + } + } + + /** + * Selects item(s), if any, at specified point. + * + * If addToSelection is true, appends item(s) to current selection + * without changing selection state of other items. + * + * If toggleSelection is true, toggles selection of item(s) + * without changing selection state of other items. + * + * If both are true, deselects item(s) + * without changing selection state of other items. + * + * Otherwise, selects item(s) and deselects other items. + */ + public void selectPoint(int x, int y, + boolean addToSelection, boolean toggleSelection) + { + // Currently we only allow selection of threads. + if (m_threads != null) { + + List threads = new ArrayList(); + + // first see if selection click landed on a thread dot. + for (MulticoreVisualizerThread tobj : m_threads) { + if (tobj.contains(x,y)) { + threads.add(tobj); + break; + } + } + + // if not, see if it landed on a core; if so, select its threads + if (threads.isEmpty()) { + for (MulticoreVisualizerCore tobj : m_cores) { + if (tobj.contains(x,y)) { + List corethreads = tobj.getThreads(); + threads.addAll(corethreads); + break; + } + } + } + + // in addToSelection case, include any threads in region + // bracketed by last selection click and current click + // (with some extra slop added so we pick up threads that + // overlap the edge of this region) + if (addToSelection) { + int spotSize = MulticoreVisualizerThread.THREAD_SPOT_SIZE * 3; + Rectangle r1 = new Rectangle(m_lastSelectionClick.x - spotSize/2, + m_lastSelectionClick.y - spotSize/2, + spotSize, spotSize); + Rectangle r2 = new Rectangle(x - spotSize/2, y - spotSize/2, spotSize, spotSize); + Rectangle region = r1.union(r2); + + for (MulticoreVisualizerThread tobj : m_threads) { + if (tobj.isWithin(region)) { + threads.add(tobj); + } + } + } + + boolean changed = false; + + for (MulticoreVisualizerThread tobj : m_threads) { + boolean within = threads.contains(tobj); + + if (addToSelection && toggleSelection) { + if (within) { + tobj.setSelected(false); + changed = true; + } + } + else if (addToSelection) { + if (within) { + tobj.setSelected(true); + changed = true; + } + } + else if (toggleSelection) { + if (within) { + tobj.setSelected(! tobj.isSelected()); + changed = true; + } + } + else { + tobj.setSelected(within); + changed = true; + } + } + + if (changed) + selectionChanged(); + } + + // remember last mouse-up point for shift-click selection + m_lastSelectionClick.x = x; + m_lastSelectionClick.y = y; + } + + + // --- selection management methods --- + + /** Selects all items in the canvas. */ + public void selectAll() + { + // currently, we select/deselect threads, not processes or tiles + if (m_threads != null) { + + for (MulticoreVisualizerThread tobj : m_threads) { + tobj.setSelected(true); + } + + selectionChanged(); + } + } + + /** Clears selection. */ + public void clearSelection() { + // currently, we select/deselect threads, not processes or tiles + if (m_threads != null) { + + for (MulticoreVisualizerThread tobj : m_threads) { + tobj.setSelected(false); + } + + selectionChanged(); + } + } + + /** Things to do whenever the selection changes. */ + protected void selectionChanged() { + selectionChanged(true); + } + + /** Things to do whenever the selection changes. */ + protected void selectionChanged(boolean raiseEvent) { + // Note: we save selection (and raise event) now, + // and let canvas "catch up" on its next update tick. + updateSelection(raiseEvent); + requestUpdate(); + } + + /** Saves current canvas selection as list of model objects. */ + protected void updateSelection(boolean raiseEvent) { + // get model objects (if any) corresponding to canvas selection + HashSet selectedThreads = new HashSet(); + if (m_threads != null) { + for (MulticoreVisualizerThread tobj : m_threads) { + if (tobj.isSelected()) { + selectedThreads.add(tobj.getThread()); + } + } + } + + // update model object selection + ISelection selection = SelectionUtils.toSelection(selectedThreads); + setSelection(selection, raiseEvent); + } + + /** Restores current selection from saved list of model objects. */ + protected void restoreSelection() { + ISelection selection = getSelection(); + List selectedThreads = SelectionUtils.getSelectedObjects(selection); + if (m_threads != null) { + for (MulticoreVisualizerThread tobj : m_threads) { + tobj.setSelected(selectedThreads.contains(tobj.getThread())); + } + } + } + + + // --- ISelectionProvider implementation --- + + // Delegate to selection manager. + + /** Adds external listener for selection change events. */ + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionManager.addSelectionChangedListener(listener); + } + + /** Removes external listener for selection change events. */ + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionManager.removeSelectionChangedListener(listener); + } + + /** Raises selection changed event. */ + public void raiseSelectionChangedEvent() { + m_selectionManager.raiseSelectionChangedEvent(); + } + + /** Returns true if we have a selection. */ + public boolean hasSelection() + { + return m_selectionManager.hasSelection(); + } + + /** Gets current externally-visible selection. */ + @Override + public ISelection getSelection() + { + return m_selectionManager.getSelection(); + } + + /** Sets externally-visible selection. */ + @Override + public void setSelection(ISelection selection) + { + m_selectionManager.setSelection(selection); + } + + /** Sets externally-visible selection. */ + public void setSelection(ISelection selection, boolean raiseEvent) + { + m_selectionManager.setSelection(selection, raiseEvent); + } + + /** Sets whether selection events are enabled. */ + public void setSelectionEventsEnabled(boolean enabled) { + m_selectionManager.setSelectionEventsEnabled(enabled); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCore.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCore.java new file mode 100755 index 00000000000..2772a058ea7 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCore.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerExecutionState; +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.cdt.visualizer.ui.util.GUIUtils; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; + +/** + * MulticoreVisualizer CPU core object. + */ +public class MulticoreVisualizerCore extends MulticoreVisualizerGraphicObject +{ + // --- members --- + + /** Parent CPU. */ + protected MulticoreVisualizerCPU m_cpu = null; + + /** Core ID. */ + protected int m_id; + + /** List of threads currently on this core. */ + protected ArrayList m_threads; + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerCore(MulticoreVisualizerCPU cpu, int id) { + m_cpu = cpu; + if (m_cpu != null) m_cpu.addCore(this); + m_id = id; + m_threads = new ArrayList(); + } + + /** Dispose method */ + @Override + public void dispose() { + super.dispose(); + if (m_threads != null) { + m_threads.clear(); + m_threads = null; + } + } + + + // --- accessors --- + + /** Gets parent CPU. */ + public MulticoreVisualizerCPU getCPU() { + return m_cpu; + } + + /** Gets Core ID. */ + public int getID() { + return m_id; + } + + + // --- methods --- + + /** Adds child thread. */ + public void addThread(MulticoreVisualizerThread thread) + { + m_threads.add(thread); + } + + /** Removes child thread. */ + public void removeThread(MulticoreVisualizerThread thread) + { + m_threads.remove(thread); + } + + /** Removes all child threads. */ + public void removeAllThreads() + { + m_threads.clear(); + } + + /** Gets list of child threads. */ + public List getThreads() + { + return m_threads; + } + + /** + * A core state is based on its thread states. + * If any thread is CRASHED, the core is CRASHED. + * If no thread is CRASHED and any thread is SUSPENDED, the core is SUSPENDED. + * If no thread is CRASHED and no thread is SUSPENDED, the core is RUNNING. + */ + protected VisualizerExecutionState getCoreState() { + VisualizerExecutionState state = VisualizerExecutionState.RUNNING; + + for (MulticoreVisualizerThread thread : m_threads) { + switch (thread.getState()) { + case CRASHED: + // As soon as we have a crashed thread, we mark + // the core as crashed. + return VisualizerExecutionState.CRASHED; + case SUSPENDED: + // As soon as we have a suspended thread, we + // consider the core as suspended. However, + // we keep looping through the threads + // looking for a crashed one. + state = VisualizerExecutionState.SUSPENDED; + break; + } + } + + return state; + } + + /** Returns core color for current state. */ + protected Color getCoreStateColor(boolean foreground) { + VisualizerExecutionState state = getCoreState(); + + switch (state) { + case RUNNING: + if (foreground) return IMulticoreVisualizerConstants.COLOR_RUNNING_CORE_FG; + return IMulticoreVisualizerConstants.COLOR_RUNNING_CORE_BG; + case SUSPENDED: + if (foreground) return IMulticoreVisualizerConstants.COLOR_SUSPENDED_CORE_FG; + return IMulticoreVisualizerConstants.COLOR_SUSPENDED_CORE_BG; + case CRASHED: + if (foreground) return IMulticoreVisualizerConstants.COLOR_CRASHED_CORE_FG; + return IMulticoreVisualizerConstants.COLOR_CRASHED_CORE_BG; + } + + assert false; + return Colors.BLACK; + } + + // --- paint methods --- + + /** Invoked to allow element to paint itself on the viewer canvas */ + @Override + public void paintContent(GC gc) { + gc.setForeground(getCoreStateColor(true)); + gc.setBackground(getCoreStateColor(false)); + + gc.fillRectangle(m_bounds); + gc.drawRectangle(m_bounds); + + if (m_bounds.height > 16) { + int text_indent = 3; + int tx = m_bounds.x + m_bounds.width - text_indent; + int ty = m_bounds.y + text_indent; + GUIUtils.drawTextAligned(gc, Integer.toString(m_id), tx, ty, false, true); + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java new file mode 100644 index 00000000000..cacb15f641b --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCore; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerExecutionState; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DSFDebugModel; +import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext; +import org.eclipse.cdt.dsf.mi.service.command.events.IMIDMEvent; +import org.eclipse.cdt.dsf.mi.service.command.events.MISignalEvent; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; + + +/** + * DSF event listener class for the Multicore Visualizer. + * This class will handle different relevant DSF events + * and update the Multicore Visualizer accordingly. + */ +public class MulticoreVisualizerEventListener { + + // --- members --- + + /** Visualizer we're managing events for. */ + protected MulticoreVisualizer fVisualizer; + + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerEventListener(MulticoreVisualizer visualizer) { + fVisualizer = visualizer; + } + + + // --- event handlers --- + + /** Invoked when a thread or process is suspended. */ + @DsfServiceEventHandler + public void handleEvent(ISuspendedDMEvent event) { + IDMContext context = event.getDMContext(); + if (context instanceof IContainerDMContext) { + // We don't deal with processes + } else if (context instanceof IMIExecutionDMContext) { + // Thread suspended + int tid = ((IMIExecutionDMContext)context).getThreadId(); + + VisualizerThread thread = fVisualizer.getModel().getThread(tid); + + if (thread != null) { + assert thread.getState() == VisualizerExecutionState.RUNNING; + + VisualizerExecutionState newState = VisualizerExecutionState.SUSPENDED; + + if (event.getReason() == StateChangeReason.SIGNAL) { + if (event instanceof IMIDMEvent) { + Object miEvent = ((IMIDMEvent)event).getMIEvent(); + if (miEvent instanceof MISignalEvent) { + String signalName = ((MISignalEvent)miEvent).getName(); + if (DSFDebugModel.isCrashSignal(signalName)) { + newState = VisualizerExecutionState.CRASHED; + } + + } + } + } + + thread.setState(newState); + fVisualizer.getMulticoreVisualizerCanvas().requestUpdate(); + } + } + } + + /** Invoked when a thread or process is resumed. */ + @DsfServiceEventHandler + public void handleEvent(IResumedDMEvent event) { + IDMContext context = event.getDMContext(); + if (context instanceof IContainerDMContext) { + // We don't deal with processes + } else if (context instanceof IMIExecutionDMContext) { + // Thread resumed + int tid = ((IMIExecutionDMContext)context).getThreadId(); + + VisualizerThread thread = fVisualizer.getModel().getThread(tid); + + if (thread != null) { + assert thread.getState() == VisualizerExecutionState.SUSPENDED || + thread.getState() == VisualizerExecutionState.CRASHED; + + thread.setState(VisualizerExecutionState.RUNNING); + fVisualizer.getMulticoreVisualizerCanvas().requestUpdate(); + } + } + } + + /** Invoked when a thread or process starts. */ + @DsfServiceEventHandler + public void handleEvent(IStartedDMEvent event) { + IDMContext context = event.getDMContext(); + if (context instanceof IContainerDMContext) { + // We don't deal with processes + } else if (context instanceof IMIExecutionDMContext) { + // New thread added + final IMIExecutionDMContext execDmc = (IMIExecutionDMContext)context; + final IMIProcessDMContext processContext = + DMContexts.getAncestorOfType(execDmc, IMIProcessDMContext.class); + IThreadDMContext threadContext = + DMContexts.getAncestorOfType(execDmc, IThreadDMContext.class); + + DsfServicesTracker tracker = + new DsfServicesTracker(MulticoreVisualizerUIPlugin.getBundleContext(), + execDmc.getSessionId()); + IProcesses procService = tracker.getService(IProcesses.class); + tracker.dispose(); + + procService.getExecutionData(threadContext, + new ImmediateDataRequestMonitor() { + @Override + protected void handleSuccess() { + IThreadDMData data = getData(); + + // Check whether we know about cores + if (data instanceof IGdbThreadDMData) { + String[] cores = ((IGdbThreadDMData)data).getCores(); + if (cores != null) { + assert cores.length == 1; // A thread belongs to a single core + int coreId = Integer.parseInt(cores[0]); + VisualizerCore vCore = fVisualizer.getModel().getCore(coreId); + + int pid = Integer.parseInt(processContext.getProcId()); + int tid = execDmc.getThreadId(); + + int osTid = 0; + try { + osTid = Integer.parseInt(data.getId()); + } catch (NumberFormatException e) { + // I've seen a case at startup where GDB is not ready to + // return the osTID so we get null. + // That is ok, we'll be refreshing right away at startup + } + + fVisualizer.getModel().addThread(new VisualizerThread(vCore, pid, osTid, tid, VisualizerExecutionState.RUNNING)); + + fVisualizer.getMulticoreVisualizerCanvas().requestUpdate(); + } + } + } + } + ); + } + } + + /** Invoked when a thread or process exits. */ + @DsfServiceEventHandler + public void handleEvent(IExitedDMEvent event) { + IDMContext context = event.getDMContext(); + if (context instanceof IContainerDMContext) { + // We don't deal with processes + } else if (context instanceof IMIExecutionDMContext) { + // Thread exited + int tid = ((IMIExecutionDMContext)context).getThreadId(); + + fVisualizer.getModel().markThreadExited(tid); + + fVisualizer.getMulticoreVisualizerCanvas().requestUpdate(); + } + } +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerGraphicObject.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerGraphicObject.java new file mode 100755 index 00000000000..7e3a4cc6b20 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerGraphicObject.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import org.eclipse.cdt.visualizer.ui.canvas.GraphicObject; +import org.eclipse.swt.graphics.GC; + +/** + * Graphic object for MulticoreVisualizer. + */ +public class MulticoreVisualizerGraphicObject extends GraphicObject +{ + // --- members --- + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerGraphicObject() { + } + + /** Dispose method */ + @Override + public void dispose() { + super.dispose(); + } + + + // --- methods --- + + /** Invoked to allow element to paint itself on the viewer canvas */ + @Override + public void paintContent(GC gc) { + gc.fillRectangle(m_bounds); + gc.drawRectangle(m_bounds); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerMarquee.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerMarquee.java new file mode 100644 index 00000000000..db872dd26a9 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerMarquee.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; + +/** + * MulticoreVisualizer "marquee" (selection box) object. + */ +public class MulticoreVisualizerMarquee extends MulticoreVisualizerGraphicObject +{ + // --- members --- + + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerMarquee() { + setVisible(false); + } + + /** Dispose method */ + @Override + public void dispose() { + super.dispose(); + } + + + // --- Object methods --- + + /** Returns string representation of element */ + @Override + public String toString() { + return "MarqueeGraphicObject[" + //$NON-NLS-1$ + m_bounds.x + "," + //$NON-NLS-1$ + m_bounds.y + "," + //$NON-NLS-1$ + m_bounds.width + "," + //$NON-NLS-1$ + m_bounds.height + "]"; //$NON-NLS-1$ + } + + + // --- accessors --- + + + // --- methods --- + + /** Invoked to allow element to paint itself on the viewer canvas */ + @Override + public void paintContent(GC gc) { + if (m_visible) { + Color bg = Colors.BLACK; + Color fg = IMulticoreVisualizerConstants.COLOR_SELECTED; + gc.setBackground(bg); + gc.setForeground(fg); + gc.drawRectangle(m_bounds); + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerSelectionFinder.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerSelectionFinder.java new file mode 100644 index 00000000000..4fcda4411e0 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerSelectionFinder.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils.DebugViewTreeWalker; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreePath; + + +/** +* Debug view tree walker that finds elements to select +* based on selection obtained from the multicore visualizer. +*/ +@SuppressWarnings("restriction") // allow access to internal interfaces +public class MulticoreVisualizerSelectionFinder + extends DebugViewTreeWalker +{ + // --- members --- + + /** Selection item(s) we're currently looking for. */ + List m_selection = null; + + /** Result we're found, if any. */ + Set m_result = null; + + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerSelectionFinder() + { + } + + /** Dispose method */ + @Override + public void dispose() { + super.dispose(); + } + + // --- methods --- + + /** Finds and returns Debug View element for specified + * Visualizer selection item. + * (E.g. the IDMVMContext for a VisualizerThread. + * Returns null if no match is found. + */ + public ISelection findSelection(ISelection selection) + { + m_selection = SelectionUtils.getSelectedObjects(selection); + + m_result = new HashSet(); + walk(); + ISelection found = SelectionUtils.toSelection(m_result); + return found; + } + + /** Processes an element of the tree view. + * Returns true if children of this element should be processed, + * and false if they can be skipped. + */ + @Override + public boolean processElement(TreePath path) + { + boolean result = true; + + Object element = getElement(path); + + if (element instanceof IDMVMContext) { + IDMContext context = ((IDMVMContext) element).getDMContext(); + int pid = getPID(context); + int tid = getTID(context); + + if (isThreadContext(context)) + { + for (Object o : m_selection) { + if (o instanceof VisualizerThread) { + VisualizerThread thread = (VisualizerThread) o; + // The Debug view model uses the GDB thread, to we need to use that one from the Visualizer model + if (thread.getPID() == pid && thread.getGDBTID() == tid) + { + m_result.add(element); + } + } + } + } + else if (context instanceof IFrameDMContext) + { + // FIXME: if we have frame[0] under a selected thread, + // select that stack frame instead of the thread + if (isThreadFrameZero(context)) + { + IDMVMContext threadContext = (IDMVMContext) path.getParentPath().getLastSegment(); + if (m_result.contains(threadContext)) + { + m_result.remove(threadContext); + m_result.add(element); + } + } + } + } + + return result; + } + + /** Returns PID for specified debug context. */ + public static int getPID(IDMContext context) + { + IMIProcessDMContext processContext = + DMContexts.getAncestorOfType(context, IMIProcessDMContext.class); + int pid = (processContext == null) ? 0 : + Integer.parseInt(processContext.getProcId()); + return pid; + } + + /** Returns TID for specified debug context. */ + public static int getTID(IDMContext context) + { + IMIExecutionDMContext execContext = + DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + int tid = (execContext == null) ? 0 : + execContext.getThreadId(); + return tid; + } + + /** Returns true if specified context represents a thread. */ + public static boolean isThreadContext(IDMContext context) + { + // TODO: is there a more elegant way to express this? + return + context instanceof IMIExecutionDMContext && + context.getParents().length >= 2 && + (context.getParents()[0] instanceof IThreadDMContext || + context.getParents()[1] instanceof IThreadDMContext); + } + + /** Returns true if context represents the topmost (0th) frame under a thread. */ + public static boolean isThreadFrameZero(IDMContext context) + { + // TODO: is there a more elegant way to express this? + String value = context.toString(); + return (value != null && value.endsWith(".frame[0]")); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerThread.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerThread.java new file mode 100755 index 00000000000..c46708020b2 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerThread.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; + +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerExecutionState; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread; +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.cdt.visualizer.ui.util.GUIUtils; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; + +/** + * MulticoreVisualizer Thread object. + */ +public class MulticoreVisualizerThread extends MulticoreVisualizerGraphicObject +{ + // --- constants --- + + /** Thread "pixie" spot width/height */ + public static final int THREAD_SPOT_SIZE = 18; + + /** Minimum containing object size to allow thread to draw itself. */ + public static final int MIN_PARENT_WIDTH = THREAD_SPOT_SIZE + 4; + + + // --- members --- + + /** Parent CPU. */ + protected MulticoreVisualizerCore m_core; + + /** Visualizer model thread. */ + protected VisualizerThread m_thread; + + /** Whether this thread is part of a currently selected process. */ + protected boolean m_processSelected = true; + + + // --- constructors/destructors --- + + /** Constructor */ + public MulticoreVisualizerThread(MulticoreVisualizerCore core, VisualizerThread thread) { + m_core = core; + m_thread = thread; + } + + /** Dispose method */ + @Override + public void dispose() { + super.dispose(); + m_thread = null; + } + + + // --- accessors --- + + /** Gets parent Core. */ + public MulticoreVisualizerCore getCore() { + return m_core; + } + + /** Sets parent Core. */ + public void setCore(MulticoreVisualizerCore core) { + m_core = core; + } + + /** Gets thread model object. */ + public VisualizerThread getThread() + { + return m_thread; + } + + /** Gets Process ID. */ + public int getPID() { + return m_thread.getPID(); + } + + /** Gets Thread ID. */ + public int getTID() { + return m_thread.getTID(); + } + + /** Gets thread state. */ + public VisualizerExecutionState getState() { + return m_thread.getState(); + } + + /** Sets whether thread's process is selected. */ + public void setProcessSelected(boolean processSelected) + { + m_processSelected = processSelected; + } + + /** Gets whether thread's process is selected. */ + public boolean getProcessSelected() + { + return m_processSelected; + } + + + // --- methods --- + + /** Gets thread color based on current state. */ + protected Color getThreadStateColor() { + switch (m_thread.getState()) { + case RUNNING: + return IMulticoreVisualizerConstants.COLOR_RUNNING_THREAD; + case SUSPENDED: + return IMulticoreVisualizerConstants.COLOR_SUSPENDED_THREAD; + case CRASHED: + return IMulticoreVisualizerConstants.COLOR_CRASHED_THREAD; + case EXITED: + return IMulticoreVisualizerConstants.COLOR_EXITED_THREAD; + } + + assert false; + return Colors.BLACK; + } + + // --- paint methods --- + + /** Invoked to allow element to paint itself on the viewer canvas */ + @Override + public void paintContent(GC gc) { + if (m_core.getWidth() >= MIN_PARENT_WIDTH) { + gc.setBackground(getThreadStateColor()); + + int x = m_bounds.x; + int y = m_bounds.y; + int w = THREAD_SPOT_SIZE; + int h = THREAD_SPOT_SIZE; + + // draw an alpha-shaded "pixie" light for each thread + int step1 = 3; + int step2 = 6; + int alpha1 = 128; + int alpha2 = 196; + int alpha3 = 255; + if (! m_processSelected) { + alpha1 -= 64; + alpha2 -= 64; + alpha3 -= 64; + } + gc.setAlpha(alpha1); + gc.fillOval(x, y, w, h); + gc.setAlpha(alpha2); + gc.fillOval(x+step1, y+step1, w-step1*2, h-step1*2); + gc.setAlpha(alpha3); + gc.fillOval(x+step2, y+step2, w-step2*2, h-step2*2); + gc.setAlpha(255); + + // special case: for the "process" thread, draw an enclosing circle + if (m_thread.isProcessThread()) { + // Subtract one from the width and height + // in the case of drawOval because that method + // adds a pixel to each value for some reason + gc.setForeground(IMulticoreVisualizerConstants.COLOR_PROCESS_THREAD); + gc.drawOval(x,y,w-1,h-1); + } + + // draw text annotations + gc.setBackground(IMulticoreVisualizerConstants.COLOR_THREAD_TEXT_BG); + gc.setForeground(IMulticoreVisualizerConstants.COLOR_THREAD_TEXT_FG); + + // if it has an associated debugger, add a marker + // (for now, every thread is debugged.) +// GUIUtils.drawText(gc, "D", x+w, y-8); //$NON-NLS-1$ + + // draw TID + String displayTID = Integer.toString(m_thread.getTID()); + GUIUtils.drawText(gc, displayTID, x + w + 4, y + 2); + + // draw selection marker, if any + if (m_selected) + { + gc.setForeground(IMulticoreVisualizerConstants.COLOR_SELECTED); + gc.drawOval(x-2,y-2,w+3,h+3); + gc.drawOval(x-3,y-3,w+5,h+5); + } + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFDebugModel.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFDebugModel.java new file mode 100644 index 00000000000..101673d3b91 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFDebugModel.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils; + +import java.util.ArrayList; + +import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.cdt.dsf.concurrent.ImmediateCountingRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData2; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerExecutionState; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.ICPUDMContext; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.ICoreDMContext; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.IHardwareTargetDMContext; +import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; + + +/** Debugger state information accessors. + * + * NOTE: The methods on this class perform asynchronous operations, + * and call back to a method on a provided DSFDebugModelListener instance + * when the operation is completed. + * + * The "arg" argument to each method can be used by the caller to + * pass through information (partial state, etc.) that will be needed + * by the callback method. This argument is ignored by the methods + * on this class, and is allowed to be null. + */ +public class DSFDebugModel { + + // --- static methods --- + + /** Requests list of CPUs. + * Calls back to getCPUsDone() on listener. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public static void getCPUs(DSFSessionState sessionState, + final DSFDebugModelListener listener, + final Object arg) + { + ICommandControlService controlService = sessionState.getService(ICommandControlService.class); + IGDBHardware hwService = sessionState.getService(IGDBHardware.class); + if (controlService == null || hwService == null) { + listener.getCPUsDone(null, arg); + return; + } + + IHardwareTargetDMContext contextToUse = DMContexts.getAncestorOfType(controlService.getContext(), + IHardwareTargetDMContext.class); + hwService.getCPUs(contextToUse, + new ImmediateDataRequestMonitor() { + @Override + protected void handleCompleted() { + ICPUDMContext[] cpuContexts = getData(); + if (! isSuccess()) cpuContexts = null; + listener.getCPUsDone(cpuContexts, arg); + } + } + ); + } + + /** Requests list of Cores. + * Calls back to getCoresDone() on listener. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public static void getCores(DSFSessionState sessionState, + DSFDebugModelListener listener, + Object arg) + { + getCores(sessionState, null, listener, arg); + } + + /** Requests list of Cores. + * Calls back to getCoresDone() on listener. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public static void getCores(DSFSessionState sessionState, + final ICPUDMContext cpuContext, + final DSFDebugModelListener listener, + final Object arg) + { + IGDBHardware hwService = sessionState.getService(IGDBHardware.class); + if (hwService == null) { + listener.getCoresDone(cpuContext, null, arg); + return; + } + + IDMContext targetContextToUse = cpuContext; + if (targetContextToUse == null) { + // if caller doesn't supply a specific cpu context, + // use the hardware context (so we get all available cores) + ICommandControlService controlService = sessionState.getService(ICommandControlService.class); + targetContextToUse = DMContexts.getAncestorOfType(controlService.getContext(), + IHardwareTargetDMContext.class); + } + + hwService.getCores(targetContextToUse, + new ImmediateDataRequestMonitor() { + @Override + protected void handleCompleted() { + ICoreDMContext[] coreContexts = getData(); + + if (!isSuccess() || coreContexts == null || coreContexts.length < 1) { + // Unable to get any core data + listener.getCoresDone(cpuContext, null, arg); + return; + } + + ICPUDMContext cpuContextToUse = cpuContext; + if (cpuContextToUse == null) { + // If we didn't have a CPU context, lets use the ancestor of the first core context + cpuContextToUse = DMContexts.getAncestorOfType(coreContexts[0], ICPUDMContext.class); + } + listener.getCoresDone(cpuContextToUse, coreContexts, arg); + } + } + ); + } + + /** Requests list of Threads. + * Calls back to getThreadsDone() on listener. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public static void getThreads(DSFSessionState sessionState, + final ICPUDMContext cpuContext, + final ICoreDMContext coreContext, + final DSFDebugModelListener listener, + final Object arg) + { + // Get control DM context associated with the core + // Process/Thread Info service (GDBProcesses_X_Y_Z) + final IProcesses procService = sessionState.getService(IProcesses.class); + // Debugger control context (GDBControlDMContext) + ICommandControlDMContext controlContext = + DMContexts.getAncestorOfType(coreContext, ICommandControlDMContext.class); + if (procService == null || controlContext == null) { + listener.getThreadsDone(cpuContext, coreContext, null, arg); + return; + } + + // Get debugged processes + procService.getProcessesBeingDebugged(controlContext, + new ImmediateDataRequestMonitor() { + + @Override + protected void handleCompleted() { + IDMContext[] processContexts = getData(); + + if (!isSuccess() || processContexts == null || processContexts.length < 1) { + // Unable to get any process data for this core + // Is this an issue? A core may have no processes/threads, right? + listener.getThreadsDone(cpuContext, coreContext, null, arg); + return; + } + + final ArrayList threadContextsList = new ArrayList(); + + final ImmediateCountingRequestMonitor crm1 = new ImmediateCountingRequestMonitor( + new ImmediateRequestMonitor() { + @Override + protected void handleCompleted() { + IDMContext[] threadContexts = threadContextsList.toArray(new IDMContext[threadContextsList.size()]); + listener.getThreadsDone(cpuContext, coreContext, threadContexts, arg); + } + }); + crm1.setDoneCount(processContexts.length); + + for (IDMContext processContext : processContexts) { + IContainerDMContext containerContext = + DMContexts.getAncestorOfType(processContext, IContainerDMContext.class); + + procService.getProcessesBeingDebugged(containerContext, + new ImmediateDataRequestMonitor(crm1) { + + @Override + protected void handleCompleted() { + IDMContext[] threadContexts = getData(); + + if (!isSuccess() || threadContexts == null || threadContexts.length < 1) { + crm1.done(); + return; + } + + final ImmediateCountingRequestMonitor crm2 = new ImmediateCountingRequestMonitor(crm1); + crm2.setDoneCount(threadContexts.length); + + for (final IDMContext threadContext : threadContexts) { + IThreadDMContext threadContext2 = + DMContexts.getAncestorOfType(threadContext, IThreadDMContext.class); + + procService.getExecutionData(threadContext2, + new ImmediateDataRequestMonitor(crm2) { + + @Override + protected void handleCompleted() { + IThreadDMData data = getData(); + + // Check whether we know about cores + if (data != null && data instanceof IGdbThreadDMData) { + String[] cores = ((IGdbThreadDMData)data).getCores(); + if (cores != null && cores.length == 1) { + if (coreContext.getId().equals(cores[0])) { + // This thread belongs to the proper core + threadContextsList.add(threadContext); + } + } + } + crm2.done(); + } + } + ); + } + } + } + ); + } + } + } + ); + } + + /** Requests data of a thread. + * Calls back to getThreadDataDone() on listener. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public static void getThreadData(DSFSessionState sessionState, + final ICPUDMContext cpuContext, + final ICoreDMContext coreContext, + final IMIExecutionDMContext execContext, + final DSFDebugModelListener listener, + final Object arg) + { + IProcesses procService = sessionState.getService(IProcesses.class); + + if (procService == null) { + listener.getThreadDataDone(cpuContext, coreContext, execContext, null, arg); + return; + } + + final IThreadDMContext threadContext = DMContexts.getAncestorOfType(execContext, IThreadDMContext.class); + procService.getExecutionData(threadContext, + new ImmediateDataRequestMonitor() { + @Override + protected void handleCompleted() { + IThreadDMData threadData = isSuccess() ? getData() : null; + listener.getThreadDataDone(cpuContext, coreContext, execContext, threadData, arg); + } + }); + + } + + /** Requests execution state of a thread. + * Calls back to getThreadExecutionStateDone() on listener. */ + @ConfinedToDsfExecutor("getSession().getExecutor()") + public static void getThreadExecutionState(DSFSessionState sessionState, + final ICPUDMContext cpuContext, + final ICoreDMContext coreContext, + final IMIExecutionDMContext execContext, + final IThreadDMData threadData, + final DSFDebugModelListener listener, + final Object arg) + { + IRunControl runControl = sessionState.getService(IRunControl.class); + + if (runControl == null) { + listener.getThreadExecutionStateDone(cpuContext, coreContext, execContext, threadData, null, arg); + return; + } + + if (runControl.isSuspended(execContext) == false) { + // The thread is running + listener.getThreadExecutionStateDone(cpuContext, coreContext, execContext, threadData, + VisualizerExecutionState.RUNNING, arg); + } else { + // For a suspended thread, let's see why it is suspended, + // to find out if the thread is crashed + runControl.getExecutionData(execContext, + new ImmediateDataRequestMonitor() { + @Override + protected void handleCompleted() { + IExecutionDMData executionData = getData(); + + VisualizerExecutionState state = VisualizerExecutionState.SUSPENDED; + + if (isSuccess() && executionData != null) { + if (executionData.getStateChangeReason() == StateChangeReason.SIGNAL) { + if (executionData instanceof IExecutionDMData2) { + String details = ((IExecutionDMData2)executionData).getDetails(); + if (details != null) { + if (isCrashSignal(details)) { + state = VisualizerExecutionState.CRASHED; + } + } + } + } + } + + listener.getThreadExecutionStateDone(cpuContext, coreContext, execContext, threadData, state, arg); + } + }); + } + + } + + /** + * Return true if the string SIGNALINFO describes a signal + * that indicates a crash. + */ + public static boolean isCrashSignal(String signalInfo) { + if (signalInfo.startsWith("SIGHUP") || //$NON-NLS-1$ + signalInfo.startsWith("SIGILL") || //$NON-NLS-1$ + signalInfo.startsWith("SIGABRT") || //$NON-NLS-1$ + signalInfo.startsWith("SIGBUS") || //$NON-NLS-1$ + signalInfo.startsWith("SIGSEGV")) { //$NON-NLS-1$ + // Not sure about the list of events here... + // We are dealing with a crash + return true; + } + + return false; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFDebugModelListener.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFDebugModelListener.java new file mode 100644 index 00000000000..ccc0eed5fb8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFDebugModelListener.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils; + + +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerExecutionState; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.ICPUDMContext; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.ICoreDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; + +/** Interface for classes that interact with DSFDebugModel. + * + * An instance of this interface is passed as + * an argument to a method of DSFDebugModel, and + * the corresponding callback on this interface is + * invoked when the method completes. + * + * The "arg" argument is the value (if any) passed + * through the corresponding "arg" argument of the + * DSFDebugModel method. + * + * TODO: we intend to refactor this API and make this + * a base class rather than an instance. + */ +public interface DSFDebugModelListener { + + /** Invoked when getCPUs() request completes. */ + public void getCPUsDone(ICPUDMContext[] cpuContexts, + Object arg); + + /** Invoked when getCores() request completes. */ + public void getCoresDone(ICPUDMContext cpuContext, + ICoreDMContext[] coreContexts, + Object arg); + + /** Invoked when getThreads() request completes. */ + public void getThreadsDone(ICPUDMContext cpuContext, + ICoreDMContext coreContext, + IDMContext[] threadContexts, + Object arg); + + /** Invoked when getThreadDataState() request completes. */ + public void getThreadDataDone(ICPUDMContext cpuContext, + ICoreDMContext coreContext, + IMIExecutionDMContext threadContext, + IThreadDMData data, + Object arg); + + /** Invoked when getThreadExecutionState() request completes. */ + public void getThreadExecutionStateDone(ICPUDMContext cpuContext, + ICoreDMContext coreContext, + IMIExecutionDMContext threadContext, + IThreadDMData threadData, + VisualizerExecutionState state, + Object arg); + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFSessionState.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFSessionState.java new file mode 100755 index 00000000000..ea7fc5249eb --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DSFSessionState.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; + +/** + * DSF session state object. + * + * Encapsulates and manages DsfSession we're currently tracking. + */ +public class DSFSessionState +{ + // --- members --- + + /** Current session ID. */ + protected String m_sessionId; + + /** Current set of session event listeners. */ + protected List m_sessionListeners; + + /** Services tracker, used to access services. */ + protected DsfServicesTracker m_servicesTracker; + + // --- constructors/destructors --- + + public DSFSessionState(String sessionId) { + m_sessionId = sessionId; + m_sessionListeners = new ArrayList(); + m_servicesTracker = new DsfServicesTracker(MulticoreVisualizerUIPlugin.getBundleContext(), m_sessionId); + } + + /** Dispose method. */ + public void dispose() + { + if (m_sessionId != null) { + removeAllServiceEventListeners(); + m_sessionId = null; + m_sessionListeners = null; + } + + if (m_servicesTracker != null) { + m_servicesTracker.dispose(); + m_servicesTracker = null; + } + } + + + // --- accessors --- + + /** Returns session ID. */ + public String getSessionID() + { + return m_sessionId; + } + + + // --- listener management --- + + /** Adds a service event listener. */ + public void addServiceEventListener(Object listener) + { + final Object listener_f = listener; + final DsfSession session_f = getDsfSession(); + if (session_f != null) { + try { + session_f.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + session_f.addServiceEventListener(listener_f, null); + m_sessionListeners.add(listener_f); + } + }); + } catch (RejectedExecutionException e) { + // Session is shut down. + } + } + } + + /** Removes a service event listener. */ + public void removeServiceEventListener(Object listener) + { + final Object listener_f = listener; + final DsfSession session_f = getDsfSession(); + if (session_f != null) { + try { + session_f.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + if (m_sessionListeners != null) { + session_f.removeServiceEventListener(listener_f); + m_sessionListeners.remove(listener_f); + } + } + }); + } catch (RejectedExecutionException e) { + // Session is shut down. + } + } + } + + /** Removes all service event listeners. */ + public void removeAllServiceEventListeners() + { + final DsfSession session_f = getDsfSession(); + if (session_f != null) { + try { + session_f.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + if (m_sessionListeners != null) { + for (Object listener : m_sessionListeners) { + session_f.removeServiceEventListener(listener); + } + m_sessionListeners.clear(); + } + } + }); + } catch (RejectedExecutionException e) { + // Session is shut down. + } + } + } + + + // --- methods --- + + /** Gets current DsfSession, if it's still active. */ + protected DsfSession getDsfSession() { + return DsfSession.getSession(m_sessionId); + } + + /** Executes DsfRunnable. */ + public void execute(DsfRunnable runnable) + { + try { + DsfSession session = getDsfSession(); + if (session == null) { + // TODO: log this? + } + else { + session.getExecutor().execute(runnable); + } + } + catch (RejectedExecutionException e) { + // TODO: log or handle this properly. + System.err.println("DSFSessionState.execute(): session rejected execution request."); //$NON-NLS-1$ + } + } + + /** Gets service of the specified type. */ + @ConfinedToDsfExecutor("getDsfSession().getExecutor()") + public V getService(Class serviceClass) { + return (m_servicesTracker == null) ? null : m_servicesTracker.getService(serviceClass); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DebugViewTreeWalker.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DebugViewTreeWalker.java new file mode 100644 index 00000000000..5f7776dc971 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/utils/DebugViewTreeWalker.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +/** + * Base class that walks Debug View tree elements. + * + * Intended to be subclassed by code that needs to walk the content + * of the Debug View (e.g. to find elements or construct model deltas). + * + * In the simplest case, a derived class should only need to + * implement processElement(), and one should then only need + * to call walk() to walk the tree and get an appropriate delta. + */ +@SuppressWarnings("restriction") // allow access to internal classes +public class DebugViewTreeWalker +{ + // --- members --- + + /** Debug View tree viewer */ + TreeModelViewer m_viewer = null; + + + // --- constructors/destructors --- + + /** Constructor */ + public DebugViewTreeWalker() + { + m_viewer = DebugViewUtils.getDebugViewer(); + } + + /** Dispose method */ + public void dispose() + { + m_viewer = null; + } + + + // --- methods --- + + /** Walks the Debug View's tree, + * calling processElement for each element. + */ + public void walk() + { + walk(getRootPath()); + } + + /** + * Walks the Debug View's tree from the specified element. + * This method should invoke processElement on the element + * itself, and walkChildren() to process the children of the element. + */ + public void walk(TreePath path) + { + if (path == null) return; + boolean processChildren = processElement(path); + if (processChildren) { + walkChildren(path); + } + } + + /** Walks children of the specified element. + * This method should invoke walk() to process + * each child element. + */ + public void walkChildren(TreePath path) + { + if (path == null) return; + int children = m_viewer.getChildCount(path); + if (children > 0) { + for (int i=0; i runnable = + new RunnableWithResult() { + @Override + public IViewPart call() { + IViewPart view = null; + IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + if (activePage != null) { + view = (viewID_f == null) ? null : activePage.findView(viewID_f); + } + return view; + } + }; + // run on UI thread, wait for result + GUIUtils.execAndWait(runnable); + IViewPart result = runnable.getResult(); + return result; + } + + /** + * Sets debug view selection. + * Specified selection is an IStructuredSelection containing a flat list + * of the model objects (that is, _not_ the tree view nodes) to be selected. + */ + public static boolean setDebugViewSelection(ISelection selection) + { + TreeModelViewer viewer = DebugViewUtils.getDebugViewer(); + if (viewer == null || selection == null) return false; + return viewer.trySelection(selection, true, true); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java new file mode 100644 index 00000000000..c8a70ec724e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Vector; + +import org.eclipse.cdt.internal.core.ICoreInfo; + +/** + */ +public class CoreList { + + private class CoreInfo implements ICoreInfo { + private String fId; + private String fPhysicalId; + + public CoreInfo(String id, String pId) { + fId = id; + fPhysicalId = pId; + } + + @Override + public String getId() { + return fId; + } + + @Override + public String getPhysicalId() { + return fPhysicalId; + } + } + + private ICoreInfo[] fCoreList; + + public CoreList() { + } + + /** + * Returns the list of cores as shown in /proc/cpuinfo + * This method will only parse /proc/cpuinfo once and cache + * the result. To force a re-parse, one must create a new + * CoreList object. + */ + public ICoreInfo[] getCoreList() { + if (fCoreList != null) { + return fCoreList; + } + + File cpuInfo = new File("/proc/cpuinfo"); //$NON-NLS-1$ + + Vector coreInfo = new Vector(); + BufferedReader reader = null; + try { + String physicalId = null; + String coreId = null; + String cpuCores = null; + + Reader r = new InputStreamReader(new FileInputStream(cpuInfo)); + reader = new BufferedReader(r); + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (line.startsWith("physical id")) { //$NON-NLS-1$ + // Found the physical id of this core, so store it temporarily + physicalId = line.split(":")[1].trim(); //$NON-NLS-1$ + } else if (line.startsWith("core id")) { //$NON-NLS-1$ + // Found core id of this core which come after the entry + // for physical id, so we have both now. + coreId = line.split(":")[1].trim(); //$NON-NLS-1$ + } else if (line.startsWith("cpu cores")) { //$NON-NLS-1$ + // Found CPU core count which comes after the entry + // for core id, so we have all three by now. + cpuCores = line.split(":")[1].trim(); //$NON-NLS-1$ + + int cid = Integer.parseInt(coreId); + int pid = Integer.parseInt(physicalId); + int cores_per_pid = Integer.parseInt(cpuCores); + String absoluteCoreID = Integer.toString(cid + pid * cores_per_pid); + + coreInfo.add(new CoreInfo(absoluteCoreID, physicalId)); + + // Get ready to look for the next core. + physicalId = null; + coreId = null; + cpuCores = null; + } + } + } catch (IOException e) { + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) {/* Don't care */} + reader = null; + } + + fCoreList = coreInfo.toArray(new ICoreInfo[coreInfo.size()]); + return fCoreList; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java index 43e253aadd0..22ffdf57f92 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/ServicesLaunchSequence.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2012 Wind River Systems 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 @@ -10,6 +10,7 @@ * Nokia - created GDBBackend service. Sep. 2008 * IBM Corporation * Ericsson - Support for Tracing Control service + * Marc Khouzam (Ericsson) - Start IGDBHardware service for the multicore visualizer (Bug 335027) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.launching; @@ -25,9 +26,10 @@ import org.eclipse.cdt.dsf.debug.service.IProcesses; import org.eclipse.cdt.dsf.debug.service.IRegisters; import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.ISourceLookup; -import org.eclipse.cdt.dsf.debug.service.IStack; import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware; import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl; import org.eclipse.cdt.dsf.mi.service.CSourceLookup; import org.eclipse.cdt.dsf.mi.service.IMIBackend; @@ -59,6 +61,11 @@ public class ServicesLaunchSequence extends Sequence { } }, new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + IGDBHardware hwService = fLaunch.getServiceFactory().createService(IGDBHardware.class, fSession, fLaunch.getLaunchConfiguration()); + hwService.initialize(requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { fProcService = (IMIProcesses)fLaunch.getServiceFactory().createService(IProcesses.class, fSession); fProcService.initialize(requestMonitor); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java new file mode 100644 index 00000000000..06c07c2b0ca --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java @@ -0,0 +1,357 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMData; +import org.eclipse.cdt.dsf.debug.service.ICachingService; +import org.eclipse.cdt.dsf.gdb.internal.CoreList; +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; +import org.eclipse.cdt.dsf.mi.service.IMICommandControl; +import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; +import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo; +import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo; +import org.eclipse.cdt.dsf.service.AbstractDsfService; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.internal.core.ICoreInfo; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.BundleContext; + +/** + * This class implements the IGDBHardware interface which gives access + * to hardware information about the target. + * + * @since 4.1 + */ +@SuppressWarnings("restriction") +public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICachingService { + + @Immutable + protected static class GDBCPUDMC extends AbstractDMContext + implements ICPUDMContext + { + /** + * String ID that is used to identify the thread in the GDB/MI protocol. + */ + private final String fId; + + /** + */ + protected GDBCPUDMC(String sessionId, IHardwareTargetDMContext targetDmc, String id) { + super(sessionId, targetDmc == null ? new IDMContext[0] : new IDMContext[] { targetDmc }); + fId = id; + } + + public String getId(){ + return fId; + } + + @Override + public String toString() { return baseToString() + ".CPU[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && ((GDBCPUDMC)obj).fId.equals(fId); + } + + @Override + public int hashCode() { return baseHashCode() ^ fId.hashCode(); } + } + + @Immutable + protected static class GDBCoreDMC extends AbstractDMContext + implements ICoreDMContext + { + private final String fId; + + public GDBCoreDMC(String sessionId, ICPUDMContext CPUDmc, String id) { + super(sessionId, CPUDmc == null ? new IDMContext[0] : new IDMContext[] { CPUDmc }); + fId = id; + } + + public String getId(){ return fId; } + + @Override + public String toString() { return baseToString() + ".core[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && + (((GDBCoreDMC)obj).fId == null ? fId == null : ((GDBCoreDMC)obj).fId.equals(fId)); + } + + @Override + public int hashCode() { return baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); } + } + + @Immutable + protected static class GDBCPUDMData implements ICPUDMData { + final int fNumCores; + + public GDBCPUDMData(int num) { + fNumCores = num; + } + + public int getNumCores() { return fNumCores; } + } + + @Immutable + protected static class GDBCoreDMData implements ICoreDMData { + final String fPhysicalId; + + public GDBCoreDMData(String id) { + fPhysicalId = id; + } + + public String getPhysicalId() { return fPhysicalId; } + } + + + private IGDBControl fCommandControl; + private IGDBBackend fBackend; + private CommandFactory fCommandFactory; + + // The list of cores should not change, so we can store + // it once we figured it out. + private ICPUDMContext[] fCPUs; + private ICoreDMContext[] fCores; + + + public GDBHardware(DsfSession session) { + super(session); + } + + /** + * This method initializes this service. + * + * @param requestMonitor + * The request monitor indicating the operation is finished + */ + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize(new RequestMonitor(ImmediateExecutor.getInstance(), requestMonitor) { + @Override + protected void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + /** + * This method initializes this service after our superclass's initialize() + * method succeeds. + * + * @param requestMonitor + * The call-back object to notify when this service's + * initialization is done. + */ + private void doInitialize(RequestMonitor requestMonitor) { + + fCommandControl = getServicesTracker().getService(IGDBControl.class); + fBackend = getServicesTracker().getService(IGDBBackend.class); + + fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); + + // Register this service. + register(new String[] { IGDBHardware.class.getName(), + GDBHardware.class.getName() }, + new Hashtable()); + + requestMonitor.done(); + } + + + /** + * This method shuts down this service. It unregisters the service, stops + * receiving service events, and calls the superclass shutdown() method to + * finish the shutdown process. + * + * @return void + */ + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } + + /** + * @return The bundle context of the plug-in to which this service belongs. + */ + @Override + protected BundleContext getBundleContext() { + return GdbPlugin.getBundleContext(); + } + + public void getCPUs(IHardwareTargetDMContext dmc, DataRequestMonitor rm) { + if (fCPUs != null) { + rm.done(fCPUs); + return; + } + + if (fBackend.getSessionType() == SessionType.REMOTE) { + // Until we can get /proc/cpuinfo from the remote, we can't do anything + fCPUs = new ICPUDMContext[0]; + rm.done(fCPUs); + } else { + // For a local session, let's use /proc/cpuinfo on linux + if (Platform.getOS().equals(Platform.OS_LINUX)) { + Set cpuIds = new HashSet(); + + ICoreInfo[] cores = new CoreList().getCoreList(); + for (ICoreInfo core : cores) { + cpuIds.add(core.getPhysicalId()); + } + + String[] cpuIdsArray = cpuIds.toArray(new String[cpuIds.size()]); + fCPUs = new ICPUDMContext[cpuIdsArray.length]; + for (int i = 0; i < cpuIdsArray.length; i++) { + fCPUs[i] = createCPUContext(dmc, cpuIdsArray[i]); + } + } else { + // No way to know the CPUs on a local Windows session. + fCPUs = new ICPUDMContext[0]; + } + rm.done(fCPUs); + } + } + + public void getCores(IDMContext dmc, final DataRequestMonitor rm) { + if (dmc instanceof ICPUDMContext) { + // Get the cores under this particular CPU + ICPUDMContext cpuDmc = (ICPUDMContext)dmc; + + if (fBackend.getSessionType() == SessionType.REMOTE) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$ + } else { + if (Platform.getOS().equals(Platform.OS_LINUX)) { + // Use /proc/cpuinfo to find the cores and match them to the specified CPU + ICoreInfo[] cores = new CoreList().getCoreList(); + + Vector coreDmcs = new Vector(); + for (ICoreInfo core : cores) { + if (core.getPhysicalId().equals(cpuDmc.getId())){ + // This core belongs to the right CPU + coreDmcs.add(new GDBCoreDMC(getSession().getId(), cpuDmc, core.getId())); + } + } + + rm.done(coreDmcs.toArray(new ICoreDMContext[coreDmcs.size()])); + } else { + // No way to know the cores for a specific CPU on a remote Windows session. + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$ + } + } + } else if (dmc instanceof IHardwareTargetDMContext) { + // Get all the cores for this target + + final IHardwareTargetDMContext targetDmc = (IHardwareTargetDMContext)dmc; + + // We already know the list of cores. Just return it. + if (fCores != null) { + rm.done(fCores); + return; + } + + if (fBackend.getSessionType() == SessionType.REMOTE) { + // For a remote session, we can use GDB's -list-thread-groups --available + // command, which shows on which cores a process is running. This does + // not necessarily give the exhaustive list of cores, but that is the best + // we have right now. + // + // In this case, we don't have knowledge about CPUs, so we lump all cores + // into a single CPU. + fCommandControl.queueCommand( + fCommandFactory.createMIListThreadGroups(fCommandControl.getContext(), true), + new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleSuccess() { + // First extract the string id for every core GDB reports + Set coreIds = new HashSet(); + IThreadGroupInfo[] groups = getData().getGroupList(); + for (IThreadGroupInfo group : groups) { + coreIds.addAll(Arrays.asList(group.getCores())); + } + + // Now create the context for each distinct core + // + // We don't have CPU info in this case so let's put them all under + // a single CPU + ICPUDMContext cpuDmc = createCPUContext(targetDmc, "0"); //$NON-NLS-1$ + Set coreDmcs = new HashSet(); + for (String id : coreIds) { + coreDmcs.add(new GDBCoreDMC(getSession().getId(), cpuDmc, id)); + } + fCores = coreDmcs.toArray(new ICoreDMContext[coreDmcs.size()]); + + rm.done(fCores); + } + }); + } else { + // For a local session, -list-thread-groups --available does not return + // the cores field. Let's use /proc/cpuinfo on linux instead + if (Platform.getOS().equals(Platform.OS_LINUX)) { + ICoreInfo[] cores = new CoreList().getCoreList(); + fCores = new ICoreDMContext[cores.length]; + for (int i = 0; i < cores.length; i++) { + ICPUDMContext cpuDmc = createCPUContext(targetDmc, cores[i].getPhysicalId()); + fCores[i] = createCoreContext(cpuDmc, cores[i].getId()); + } + } else { + // No way to know the cores on a local Windows session. + fCores = new ICoreDMContext[0]; + } + rm.done(fCores); + } + } else { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$ + } + } + + public void getExecutionData(IDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof ICoreDMContext) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Not done yet", null)); //$NON-NLS-1$ + } else if (dmc instanceof ICPUDMContext) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Not done yet", null)); //$NON-NLS-1$ + + } else { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$ + } + } + + @Override + public ICPUDMContext createCPUContext(IHardwareTargetDMContext targetDmc, String CPUId) { + return new GDBCPUDMC(getSession().getId(), targetDmc, CPUId); + } + + @Override + public ICoreDMContext createCoreContext(ICPUDMContext cpuDmc, String coreId) { + return new GDBCoreDMC(getSession().getId(), cpuDmc, coreId); + } + + public void flushCache(IDMContext context) { + fCPUs = null; + fCores = null; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java index 5eaccda0f6e..7d6c78fcee7 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java @@ -10,6 +10,7 @@ * Nokia - create and use backend service. * Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306) * Marc Khouzam (Ericsson) - Support for GDB 7.4 (Bug 367788) + * Marc Khouzam (Ericsson) - Include IGDBHardware service for the multicore visualizer (Bug 335027) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -95,7 +96,13 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { return (V)createTraceControlService(session, (ILaunchConfiguration)arg); } } - } + } else if (IGDBHardware.class.isAssignableFrom(clazz)) { + for (Object arg : optionalArguments) { + if (arg instanceof ILaunchConfiguration) { + return (V)createHardwareService(session, (ILaunchConfiguration)arg); + } + } + } return super.createService(clazz, session); } @@ -214,4 +221,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { // in those older GDB versions. Also, gdbserver only supports tracing starting with 7.2 return null; } + + /** @since 4.1 */ + protected IGDBHardware createHardwareService(DsfSession session, ILaunchConfiguration config) { + return new GDBHardware(session); + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBHardware.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBHardware.java new file mode 100644 index 00000000000..205d38ebadd --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBHardware.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMData; +import org.eclipse.cdt.dsf.service.IDsfService; + +/** + * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + * + * The IGDBHardware service provides access to information about the target + * hardware, such as the number of cores. + * + * @since 4.1 + */ +public interface IGDBHardware extends IDsfService { + + /** + * The physical target that has CPUs and Cores. + */ + public interface IHardwareTargetDMContext extends IDMContext {} + + /** + * A physical container of cores. + */ + public interface ICPUDMContext extends IDMContext { + String getId(); + } + + /** + * A logical core. Without SMT (Simultaneous Multi-Threading), + * a logical core is a physical core. However, with SMT, each + * physical core will have two logical cores. + * This context represents each logical core. + */ + public interface ICoreDMContext extends IDMContext { + String getId(); + } + + /** + * Model data interface corresponding to ICPUDMContext. + */ + public interface ICPUDMData extends IDMData { + /** Number of cores contained in this CPU */ + int getNumCores(); + } + + /** + * Model data interface corresponding to ICoreDMContext. + */ + public interface ICoreDMData extends IDMData { + /** + * The physical id of the core. Multiple cores can have + * the same physical id in the case of Simultaneous Multi-Threading. + */ + String getPhysicalId(); + } + + // + // Events, e.g., a core halting, starting, etc + // + + /** + * Returns an array of CPUs, based on the specified context. + * + * @param context The context to which this method applies. + */ + public void getCPUs(IHardwareTargetDMContext context, DataRequestMonitor rm); + + /** + * Returns an array of cores, based on the specified context. + * + * @param context The context to which this method applies. + * For an IHardwareTargetDMContext, all cores will be returned; + * for an ICPUDMContext, the cores on that CPU will be returned. + */ + public void getCores(IDMContext context, DataRequestMonitor rm); + + /** + * Retrieves data for a given ICPUDMContext or ICoreDMContext context. + */ + public void getExecutionData(IDMContext dmc, DataRequestMonitor rm); + + /** + * Create a CPU context. + * + * @param targetDmc The parent context of this context + * @param CPUId The id of the CPU + */ + public ICPUDMContext createCPUContext(IHardwareTargetDMContext targetDmc, String CPUId); + + /** + * Create a core context. + * + * @param cpuDmc The parent CPU context of this context + * @param coreId The id of the core + */ + public ICoreDMContext createCoreContext(ICPUDMContext cpuDmc, String coreId); + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControlDMContext.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControlDMContext.java index d2bd4fe106d..546e1a094d2 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControlDMContext.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControlDMContext.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 Wind River Systems and others. + * Copyright (c) 2007, 2012 Wind River Systems 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 @@ -8,12 +8,14 @@ * Contributors: * Wind River Systems - initial API and implementation * Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 335324) + * Marc Khouzam (Ericsson) - Include IHardwareTargetDMContext for the multicore visualizer (Bug 335027) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service.command; import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext; import org.eclipse.cdt.dsf.debug.service.ISignals.ISignalsDMContext; import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardware.IHardwareTargetDMContext; import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext; import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext; @@ -22,7 +24,7 @@ import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext; */ public class GDBControlDMContext extends MIControlDMContext implements ISymbolDMContext, ISourceLookupDMContext, - ISignalsDMContext, ITraceTargetDMContext + ISignalsDMContext, ITraceTargetDMContext, IHardwareTargetDMContext { public GDBControlDMContext(String sessionId, String commandControlId) { diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/.project b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/.project new file mode 100644 index 00000000000..8f8b178a737 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.cdt.gnu.multicorevisualizer-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/build.properties b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/build.properties new file mode 100755 index 00000000000..1f4c8ef5685 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/build.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2012 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: +# Marc Khouzam (Ericsson) +############################################################################### +bin.includes = feature.xml,\ + feature.properties,\ + license.html,\ + epl-v10.html,\ + eclipse_update_120.jpg + \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/eclipse_update_120.jpg b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/eclipse_update_120.jpg new file mode 100644 index 00000000000..bfdf708ad61 Binary files /dev/null and b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/eclipse_update_120.jpg differ diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/epl-v10.html b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/epl-v10.html new file mode 100644 index 00000000000..ed4b196655e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/epl-v10.html @@ -0,0 +1,328 @@ + + + + + + + + +Eclipse Public License - Version 1.0 + + + + + + +
+ +

Eclipse Public License - v 1.0 +

+ +

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER +THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, +REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE +OF THIS AGREEMENT.

+ +

1. DEFINITIONS

+ +

"Contribution" means:

+ +

a) +in the case of the initial Contributor, the initial code and documentation +distributed under this Agreement, and
+b) in the case of each subsequent Contributor:

+ +

i) +changes to the Program, and

+ +

ii) +additions to the Program;

+ +

where +such changes and/or additions to the Program originate from and are distributed +by that particular Contributor. A Contribution 'originates' from a Contributor +if it was added to the Program by such Contributor itself or anyone acting on +such Contributor's behalf. Contributions do not include additions to the +Program which: (i) are separate modules of software distributed in conjunction +with the Program under their own license agreement, and (ii) are not derivative +works of the Program.

+ +

"Contributor" means any person or +entity that distributes the Program.

+ +

"Licensed Patents " mean patent +claims licensable by a Contributor which are necessarily infringed by the use +or sale of its Contribution alone or when combined with the Program.

+ +

"Program" means the Contributions +distributed in accordance with this Agreement.

+ +

"Recipient" means anyone who +receives the Program under this Agreement, including all Contributors.

+ +

2. GRANT OF RIGHTS

+ +

a) +Subject to the terms of this Agreement, each Contributor hereby grants Recipient +a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly +display, publicly perform, distribute and sublicense the Contribution of such +Contributor, if any, and such derivative works, in source code and object code +form.

+ +

b) +Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free +patent license under Licensed Patents to make, use, sell, offer to sell, import +and otherwise transfer the Contribution of such Contributor, if any, in source +code and object code form. This patent license shall apply to the combination +of the Contribution and the Program if, at the time the Contribution is added +by the Contributor, such addition of the Contribution causes such combination +to be covered by the Licensed Patents. The patent license shall not apply to +any other combinations which include the Contribution. No hardware per se is +licensed hereunder.

+ +

c) +Recipient understands that although each Contributor grants the licenses to its +Contributions set forth herein, no assurances are provided by any Contributor +that the Program does not infringe the patent or other intellectual property +rights of any other entity. Each Contributor disclaims any liability to Recipient +for claims brought by any other entity based on infringement of intellectual +property rights or otherwise. As a condition to exercising the rights and +licenses granted hereunder, each Recipient hereby assumes sole responsibility +to secure any other intellectual property rights needed, if any. For example, +if a third party patent license is required to allow Recipient to distribute +the Program, it is Recipient's responsibility to acquire that license before +distributing the Program.

+ +

d) +Each Contributor represents that to its knowledge it has sufficient copyright +rights in its Contribution, if any, to grant the copyright license set forth in +this Agreement.

+ +

3. REQUIREMENTS

+ +

A Contributor may choose to distribute the +Program in object code form under its own license agreement, provided that: +

+ +

a) +it complies with the terms and conditions of this Agreement; and

+ +

b) +its license agreement:

+ +

i) +effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose;

+ +

ii) +effectively excludes on behalf of all Contributors all liability for damages, +including direct, indirect, special, incidental and consequential damages, such +as lost profits;

+ +

iii) +states that any provisions which differ from this Agreement are offered by that +Contributor alone and not by any other party; and

+ +

iv) +states that source code for the Program is available from such Contributor, and +informs licensees how to obtain it in a reasonable manner on or through a +medium customarily used for software exchange.

+ +

When the Program is made available in source +code form:

+ +

a) +it must be made available under this Agreement; and

+ +

b) a +copy of this Agreement must be included with each copy of the Program.

+ +

Contributors may not remove or alter any +copyright notices contained within the Program.

+ +

Each Contributor must identify itself as the +originator of its Contribution, if any, in a manner that reasonably allows +subsequent Recipients to identify the originator of the Contribution.

+ +

4. COMMERCIAL DISTRIBUTION

+ +

Commercial distributors of software may +accept certain responsibilities with respect to end users, business partners +and the like. While this license is intended to facilitate the commercial use +of the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes the +Program in a commercial product offering, such Contributor ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages and +costs (collectively "Losses") arising from claims, lawsuits and other +legal actions brought by a third party against the Indemnified Contributor to +the extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may participate +in any such claim at its own expense.

+ +

For example, a Contributor might include the +Program in a commercial product offering, Product X. That Contributor is then a +Commercial Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance claims and +warranties are such Commercial Contributor's responsibility alone. Under this +section, the Commercial Contributor would have to defend claims against the +other Contributors related to those performance claims and warranties, and if a +court requires any other Contributor to pay any damages as a result, the +Commercial Contributor must pay those damages.

+ +

5. NO WARRANTY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, +WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and distributing the +Program and assumes all risks associated with its exercise of rights under this +Agreement , including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs or +equipment, and unavailability or interruption of operations.

+ +

6. DISCLAIMER OF LIABILITY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF +THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES.

+ +

7. GENERAL

+ +

If any provision of this Agreement is invalid +or unenforceable under applicable law, it shall not affect the validity or +enforceability of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable.

+ +

If Recipient institutes patent litigation +against any entity (including a cross-claim or counterclaim in a lawsuit) +alleging that the Program itself (excluding combinations of the Program with +other software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the date +such litigation is filed.

+ +

All Recipient's rights under this Agreement +shall terminate if it fails to comply with any of the material terms or +conditions of this Agreement and does not cure such failure in a reasonable +period of time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use and +distribution of the Program as soon as reasonably practicable. However, +Recipient's obligations under this Agreement and any licenses granted by +Recipient relating to the Program shall continue and survive.

+ +

Everyone is permitted to copy and distribute +copies of this Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The Agreement +Steward reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement Steward has +the right to modify this Agreement. The Eclipse Foundation is the initial +Agreement Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version of +the Agreement under which it was received. In addition, after a new version of +the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to +the intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved.

+ +

This Agreement is governed by the laws of the +State of New York and the intellectual property laws of the United States of +America. No party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. Each party waives +its rights to a jury trial in any resulting litigation.

+ +

 

+ +
+ + + + \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/feature.properties b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/feature.properties new file mode 100644 index 00000000000..85e9b92c711 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/feature.properties @@ -0,0 +1,166 @@ +# ============================================================================= +# Copyright (c) 2012 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: +# Marc Khouzam (Ericsson) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Feature string resources +# ----------------------------------------------------------------------------- + +# "featureName" property - name of the feature +featureName=CDT Multicore Visualizer + +# "providerName" property - name of the company that provides the feature +providerName=Eclipse CDT + +# "updateSiteName" property - label for the update site +updateSiteName=Eclipse CDT Update Site + +# "description" property - description of the feature +description=Multicore Visualizer which displays the debug session graphically in the Visualizer view. + +# copyright +copyright=\ +Copyright (c) 2012 Ericsson and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +February 1, 2011\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the\n\ +Eclipse Foundation is provided to you under the terms and conditions of\n\ +the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is\n\ +provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse Foundation source code\n\ +repository ("Repository") in software modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Provisioning Technology (as defined below), you must agree to a license ("Feature \n\ +Update License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties" found within a Feature.\n\ +Such Abouts, Feature Licenses, and Feature Update Licenses contain the\n\ +terms and conditions (or references to such terms and conditions) that\n\ +govern your use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Eclipse Distribution License Version 1.0 (available at http://www.eclipse.org/licenses/edl-v1.0.html)\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +\n\Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which include,\n\ +but are not limited to, p2 and the Eclipse Update Manager ("Provisioning Technology") for\n\ +the purpose of allowing users to install software, documentation, information and/or\n\ +other materials (collectively "Installable Software"). This capability is provided with\n\ +the intent of allowing such users to install, extend and update Eclipse-based products.\n\ +Information about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install Installable Software.\n\ +You shall be responsible for enabling the applicable license agreements relating to the\n\ +Installable Software to be presented to, and accepted by, the users of the Provisioning Technology\n\ +in accordance with the Specification. By using Provisioning Technology in such a manner and\n\ +making it available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the following:\n\ +\n\ + 1. A series of actions may occur ("Provisioning Process") in which a user may execute\n\ + the Provisioning Technology on a machine ("Target Machine") with the intent of installing,\n\ + extending or updating the functionality of an Eclipse-based product.\n\ + 2. During the Provisioning Process, the Provisioning Technology may cause third party\n\ + Installable Software or a portion thereof to be accessed and copied to the Target Machine.\n\ + 3. Pursuant to the Specification, you will provide to the user the terms and conditions that\n\ + govern the use of the Installable Software ("Installable Software Agreement") and such\n\ + Installable Software Agreement shall be accessed from the Target Machine in accordance\n\ + with the Specification. Such Installable Software Agreement must inform the user of the\n\ + terms and conditions that govern the Installable Software and must solicit acceptance by\n\ + the end user in the manner prescribed in such Installable Software Agreement. Upon such\n\ + indication of agreement by the user, the provisioning Technology will complete installation\n\ + of the Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use, and\n\ +re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/feature.xml b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/feature.xml new file mode 100755 index 00000000000..818d399a038 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/feature.xml @@ -0,0 +1,27 @@ + + + + + %description + + + + %copyright + + + + %license + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/license.html b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/license.html new file mode 100644 index 00000000000..f19c483b9c8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/license.html @@ -0,0 +1,108 @@ + + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

February 1, 2011

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

+ +

Applicable Licenses

+ +

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ +
    +
  • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
  • +
  • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
  • +
  • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
  • +
  • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
  • +
+ +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ +
    +
  • The top-level (root) directory
  • +
  • Plug-in and Fragment directories
  • +
  • Inside Plug-ins and Fragments packaged as JARs
  • +
  • Sub-directories of the directory named "src" of certain Plug-ins
  • +
  • Feature directories
  • +
+ +

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

+ +

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

+ + + +

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. +
+ +

Cryptography

+ +

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ + diff --git a/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/pom.xml b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/pom.xml new file mode 100644 index 00000000000..d63af096830 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.gnu.multicorevisualizer-feature/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + org.eclipse.cdt + cdt-parent + 8.1.0-SNAPSHOT + ../../pom.xml + + + org.eclipse.cdt.features + 1.0.0-SNAPSHOT + org.eclipse.cdt.multicorevisualizer + eclipse-feature + diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/.project b/visualizer/org.eclipse.cdt.visualizer-feature/.project new file mode 100755 index 00000000000..085bc9060c2 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/.project @@ -0,0 +1,17 @@ + + + org.eclipse.cdt.visualizer-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/ABOUT.txt b/visualizer/org.eclipse.cdt.visualizer-feature/ABOUT.txt new file mode 100644 index 00000000000..7184727dae9 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/ABOUT.txt @@ -0,0 +1,359 @@ +############################################################################### +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +############################################################################### + +Visualizer View Framework +========================= +Version: 1.0 +Last updated: 1/19/12 + +Overview +-------- + +- The Visualizer framework supports the addition of visual (i.e. graphical) + representations of run/debug launches to the Eclipse workbench. + It provides interfaces and default implementations to be used by + integrators in adding their own graphical views to Eclipse. + +- The Visualizer framework is an optional feature of CDT. + +- The Visualizer framework consists of the following features/plugins: + - org.eclipse.cdt.visualizer-feature: + - org.eclipse.cdt.visualizer.core -- non-UI interface and utilities + - org.eclipse.cdt.visualizer.ui -- UI classes and utilities + +- The Visualizer framework has the following goals: + - make it easy to present multiple graphical presentations of + a running/debugging launch, and allow the user to select between them + - provide a pluggable infrastructure that does not limit an integrator + to a specific model, event, or graphic "canvas" in creating such presentations + - provide sufficient default implementations to make creating a new + custom presentation as simple as possible + +- The framework consists of the following set of interfaces and classes: + + ========================== + | VisualizerView | + ========================== + | VisualizerViewer | + | | + | -------------------- | ------------------ + | | | | | | + | | IVisualizer's | <=== | IVisualizer | ===> (Model Object) + | | graphic | | | implementation | + | | control | | | | + | | | | ------------------ + | -------------------- | + | | + ========================== + + - VisualizerView -- a top-level Eclipse workbench view that + contains and presents a VisualizerViewer + + The VisualizerView also provides support for a toolbar and + context menu, which can be populated by IVisualizers when + they are selected. + + - VisualierViewer -- a container control that manages one or more + IVisualizers and their corresponding graphic controls. + + The VisualizerViewer automatically switches between its available + IVisualizers based on the current workbench selection. + + The viewer also mediates between its parent View and child IVisualizers + on things like: + - content selection (workbench selection <==> IVisulizer selection) + - toolbar population and updating + - context menu events and updating + + - IVisualizer -- an API for a class that encapsulates: + - a graphic representation of one or more model object types + - a top-level graphic display control (e.g. an SWT canvas, GEF canvas, etc.) + that is used to present this graphic representation in the VisualizerViewer + + - the "model" class -- this is not a specific class type, + it's basically any top-level Object that can be selected and + used to obtain the state to be presented by an IVisualizer + (for example, a Launch in the Debug View, or a text selection + in an editor) + +- The framework provides default implementations of VisualizerView, + and VisualizerViewer, and base classes that can be used to + create IVisualizer implementations. + +- The framework provides an extension point by which IVisualizer implementations + can be registered. This is read by the default VisualizerViewer, + and used to populate its initial set of IVisualizer views + + +Extension Points: +----------------- + +The base class VisualizerViewer checks the following extension point +for plugin contributions of IVisualizer implementations: + +- org.eclipse.cdt.visualizer.ui.vizualizer + - id: unique ID of this visualizer type + - class: implementation of IVisualizer interface + + Examples: + + + + + + + + + + + + + + + + +Package/Class hierarchy: +------------------------ + +- feature: org.eclipse.cdt.visualizer + + - plugin: org.eclipse.cdt.visualizer.core + + - org.eclipse.cdt.visualizer.core.plugin + + - CDTVisualizerCorePlugin -- plugin activator class (mainly used to access ResourceManager) + + - org.eclipse.cdt.visualizer.core + + - ResourceManager -- resource manager, handles strings only (see UIResourceManager below) + - Extension -- utility class for dealing with extension points + - ExtensionElement -- utility class for dealing with extension definitions + + - plugin: org.eclipse.cdt.visualizer.ui + + - org.eclipse.cdt.visualizer.ui.plugin + + - CDTVisualizerUIPlugin -- plugin activator class (mainly used for logging and UIResourceManager) + + - org.eclipse.cdt.visualizer.ui + + - VisualizerView -- base class for top-level Visualizer "view" in Eclipse workbench + - handles: + - display of single IVisualizerViewer + - boilerplate code for workbench views + + - IVisualizerViewer -- visualizer "viewer" container interface + - VisualizerViewer -- base class for IVisualizerViewer implementations + - handles: + - loading and managing a list of IVisualizers + - routing of selection + - from workbench into current IVisualizer + - from current IVisualizer back to workbench + - manages viewer toolbar and content menu, + asks current IVisualizer to populate these as needed + + - IVisualizer -- interface for visualizer (graphic representation, like Grid View) + - Visualizer -- base class for IVisualizer implementations + - handles: + - creating and painting a graphic component + - management of selection for that component + - populating toolbar and context menu content on demand + + - VisualizerAction -- base class for toolbar/menu actions (convenience wrapper for Action class) + + - org.eclipse.cdt.visualizer.ui.events + + - VisualizerViewerEvent -- event raised by VisualizerViewer (visualizer changed, context menu event) + - IVisualizerViewerListener -- listener interface for VisualizerViewerEvent listeners + + - org.eclipse.cdt.visualizer.ui.canvas + + - GraphicCanvasVisualizer -- base class for visualizers based on GraphicCanvas component + - GraphicCanvas -- simple canvas that paints a list of GraphicObjects + - IGraphicObject -- interface for objects to be drawn on GraphicCanvas + - GraphicObject -- base class implementation of IGraphicObject + - BufferedCanvas -- base class for GraphicCanvas (or any canvas component with back-buffering) + + - org.eclipse.cdt.visualizer.ui.test + + - TestCanvasVisualizer -- IVisualizer wrapper for TestCanvas + - TestCanvas -- simple canvas example that displays current selection as text + + - org.eclipse.cdt.visualizer.ui.util + + - GUIUtils -- assorted UI utility methods + - UIResourceManager -- resource manager, includes strings, images, fonts, colors + - Colors -- SWT color resource manager, used with UIResourceManager + - SelectionUtils -- ISelection manipulation utilities + - SelectionManager -- ISelectionProvider implementation, manages selection for a containing class + - SelectionProviderAdapter -- ISelectionProvider wrapper for classes that don't implement it + - ListenerList -- listener manager class + - Event -- event base class + - MouseMonitor -- mouse event tracking utility class + - RunnableWithResult -- Runnable that returns a result + - Timer -- UI timer class + - Todo -- work tracking utility class + - WorkbenchSelectionAdapter -- manages interaction between workbench selection and a specified IViewPart + + +Creating a Visualizer +--------------------- + +This is a summary of the steps to take in developing a visualizer. +(For a specific example of this, see the Multicore Debug Visualizer, +defined in the org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui plugin.) + +- Add the VisualizerView to the workbench. + Note: this implicitly creates a VisualizerViewer instance. + + NOTE: This is currently done by the Visualizer framework itself, + with the following plugin.xml extension markup: + + For example: + + + + + + + +- declare your visualizer class via the extension point + (described below under Extension Points) + + + + + + + + +- Define your IVisualizer class, either: + + - completely from scratch, implementing IVisualizer + + - derived from the Visualizer base class + + - if you want to use the supplied GraphicCanvas as your control, + use the GraphicCanvasVisualizer base class instead + + +- Implement the IVisualizer interface: + + - implement getName(), getDisplayName(), and getDescription() + to provide a UI-visible name and tooltip for your visualizer + + - implement createControl() to return the UI control to be + displayed for your visualizer in the VisualizerView + (if you're using the GraphicCanvasVisualizer base class, + override createCanvas() and initializeCanvas() instead) + + - implement handlesSelection() to determine whether your + visualizer can display the current selection + (your visualizer is only selected if it returns a higher + value from this call than any other visualizer) + + - implement visualizerSelected()/visualizerDeselected() + to handle any setup/cleanup when your visualizer becomes + active or inactive + + - implement workbenchSelectionChanged() to handle changes in + the workbench selection (typically, this means updating the + visualizer's displayed content, and/or mapping the current + selection to selected item(s) in the visualizer display) + + - implement the selection-management methods + (getSelection(), setSelection() and add/removeSelectionChangedListener()) + to handle exposing the visualizer's selection to the workbench + (typically, these methods can be delegated to an instance of + the SelectionManager utility class, and then your visualizer + just needs to keep the SelectionManager's content up to date) + + - when your visualizer's selection changes (i.e. by the user clicking + or dragging on the visualizer's control, update the exposed + selection (i.e. update the SelectionManager instance) + + - optionally, to enable toolbar/menu support: + - implement createActions()/updateActions() to create and + update the enabling of your actions + - implement populateToolbar() to add actions to the visualizer toolbar + (note: the toolbar is initially empty each time this is called) + - implement populateMenu() to add actions to the toolbar's menu + - implement populateContextMenu() to add actions to the + VisualizerView's context menu + - whenever the selection changes (workbench or visualizer), + invoke updateActions() to keep your toolbar/menu actions + enabled properly + +- If you use the GraphicCanvasVisualizer, here's some additional hints: + + - create an internal "model" class for your canvas, if you don't + already have such a model + + - when the workbench selection changes update this model + with any needed changes; this allows you to decouple the + canvas repaint step from workbench events, + + - have your GraphicCanvas implementation create and update instances + of GraphicObject classes associated with your model objects; + also cache GraphicObjects for model state that doesn't + change on every repaint + + - don't repaint your visualizer canvas on every event; + use a Timer instance and "batch up" requests that come in + during the timer interval (for example, start the timer when + the first update request comes in, and when the timer goes off, + display the current state, effectively "rolling up" any update + requests that came in during the timer interval) + + - add selection support to your canvas (i.e. let the user click- + and drag-select items in the visualization), and use the + selection-management interface of the IVisualizer class to + expose this to the workbench + + - remember that the IVisualizerViewer/IVisualizer API provides + support for a context menu on the visualizer, so you don't need + to provide one for your canvas control + +- Remember the goal of the visualizer: to provide a clear, high-level + view of the selected object -- for example, the hierarchy of processes + and threads in a running program. You can provide options or overlays + for additional detail, but keep the basic picture simple. + + +Current State, Future Plans +--------------------------- + +- In the initial implementation, the IVisualizer implementation + is required to use the selection to locate the object (i.e. the current launch) + that it is to represent visually, and to construct and maintain + a graphic representation of it. + +- In future, the Visualizer framework will want to provide APIs + that factor out and simplify common aspects of interaction with + launches and launch targets. For example: + + - a service-based target introspection layer, which can be used by + IPresentation implementations to discover details of the current + launch target in a platform-neutral way diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/build.properties b/visualizer/org.eclipse.cdt.visualizer-feature/build.properties new file mode 100755 index 00000000000..7a4864dbb62 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/build.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +############################################################################### +bin.includes = feature.xml,\ + feature.properties,\ + license.html,\ + epl-v10.html,\ + eclipse_update_120.jpg,\ + About.txt + \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/eclipse_update_120.jpg b/visualizer/org.eclipse.cdt.visualizer-feature/eclipse_update_120.jpg new file mode 100644 index 00000000000..bfdf708ad61 Binary files /dev/null and b/visualizer/org.eclipse.cdt.visualizer-feature/eclipse_update_120.jpg differ diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/epl-v10.html b/visualizer/org.eclipse.cdt.visualizer-feature/epl-v10.html new file mode 100644 index 00000000000..ed4b196655e --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/epl-v10.html @@ -0,0 +1,328 @@ + + + + + + + + +Eclipse Public License - Version 1.0 + + + + + + +
+ +

Eclipse Public License - v 1.0 +

+ +

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER +THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, +REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE +OF THIS AGREEMENT.

+ +

1. DEFINITIONS

+ +

"Contribution" means:

+ +

a) +in the case of the initial Contributor, the initial code and documentation +distributed under this Agreement, and
+b) in the case of each subsequent Contributor:

+ +

i) +changes to the Program, and

+ +

ii) +additions to the Program;

+ +

where +such changes and/or additions to the Program originate from and are distributed +by that particular Contributor. A Contribution 'originates' from a Contributor +if it was added to the Program by such Contributor itself or anyone acting on +such Contributor's behalf. Contributions do not include additions to the +Program which: (i) are separate modules of software distributed in conjunction +with the Program under their own license agreement, and (ii) are not derivative +works of the Program.

+ +

"Contributor" means any person or +entity that distributes the Program.

+ +

"Licensed Patents " mean patent +claims licensable by a Contributor which are necessarily infringed by the use +or sale of its Contribution alone or when combined with the Program.

+ +

"Program" means the Contributions +distributed in accordance with this Agreement.

+ +

"Recipient" means anyone who +receives the Program under this Agreement, including all Contributors.

+ +

2. GRANT OF RIGHTS

+ +

a) +Subject to the terms of this Agreement, each Contributor hereby grants Recipient +a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly +display, publicly perform, distribute and sublicense the Contribution of such +Contributor, if any, and such derivative works, in source code and object code +form.

+ +

b) +Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free +patent license under Licensed Patents to make, use, sell, offer to sell, import +and otherwise transfer the Contribution of such Contributor, if any, in source +code and object code form. This patent license shall apply to the combination +of the Contribution and the Program if, at the time the Contribution is added +by the Contributor, such addition of the Contribution causes such combination +to be covered by the Licensed Patents. The patent license shall not apply to +any other combinations which include the Contribution. No hardware per se is +licensed hereunder.

+ +

c) +Recipient understands that although each Contributor grants the licenses to its +Contributions set forth herein, no assurances are provided by any Contributor +that the Program does not infringe the patent or other intellectual property +rights of any other entity. Each Contributor disclaims any liability to Recipient +for claims brought by any other entity based on infringement of intellectual +property rights or otherwise. As a condition to exercising the rights and +licenses granted hereunder, each Recipient hereby assumes sole responsibility +to secure any other intellectual property rights needed, if any. For example, +if a third party patent license is required to allow Recipient to distribute +the Program, it is Recipient's responsibility to acquire that license before +distributing the Program.

+ +

d) +Each Contributor represents that to its knowledge it has sufficient copyright +rights in its Contribution, if any, to grant the copyright license set forth in +this Agreement.

+ +

3. REQUIREMENTS

+ +

A Contributor may choose to distribute the +Program in object code form under its own license agreement, provided that: +

+ +

a) +it complies with the terms and conditions of this Agreement; and

+ +

b) +its license agreement:

+ +

i) +effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose;

+ +

ii) +effectively excludes on behalf of all Contributors all liability for damages, +including direct, indirect, special, incidental and consequential damages, such +as lost profits;

+ +

iii) +states that any provisions which differ from this Agreement are offered by that +Contributor alone and not by any other party; and

+ +

iv) +states that source code for the Program is available from such Contributor, and +informs licensees how to obtain it in a reasonable manner on or through a +medium customarily used for software exchange.

+ +

When the Program is made available in source +code form:

+ +

a) +it must be made available under this Agreement; and

+ +

b) a +copy of this Agreement must be included with each copy of the Program.

+ +

Contributors may not remove or alter any +copyright notices contained within the Program.

+ +

Each Contributor must identify itself as the +originator of its Contribution, if any, in a manner that reasonably allows +subsequent Recipients to identify the originator of the Contribution.

+ +

4. COMMERCIAL DISTRIBUTION

+ +

Commercial distributors of software may +accept certain responsibilities with respect to end users, business partners +and the like. While this license is intended to facilitate the commercial use +of the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes the +Program in a commercial product offering, such Contributor ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages and +costs (collectively "Losses") arising from claims, lawsuits and other +legal actions brought by a third party against the Indemnified Contributor to +the extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may participate +in any such claim at its own expense.

+ +

For example, a Contributor might include the +Program in a commercial product offering, Product X. That Contributor is then a +Commercial Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance claims and +warranties are such Commercial Contributor's responsibility alone. Under this +section, the Commercial Contributor would have to defend claims against the +other Contributors related to those performance claims and warranties, and if a +court requires any other Contributor to pay any damages as a result, the +Commercial Contributor must pay those damages.

+ +

5. NO WARRANTY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, +WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and distributing the +Program and assumes all risks associated with its exercise of rights under this +Agreement , including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs or +equipment, and unavailability or interruption of operations.

+ +

6. DISCLAIMER OF LIABILITY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF +THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES.

+ +

7. GENERAL

+ +

If any provision of this Agreement is invalid +or unenforceable under applicable law, it shall not affect the validity or +enforceability of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable.

+ +

If Recipient institutes patent litigation +against any entity (including a cross-claim or counterclaim in a lawsuit) +alleging that the Program itself (excluding combinations of the Program with +other software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the date +such litigation is filed.

+ +

All Recipient's rights under this Agreement +shall terminate if it fails to comply with any of the material terms or +conditions of this Agreement and does not cure such failure in a reasonable +period of time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use and +distribution of the Program as soon as reasonably practicable. However, +Recipient's obligations under this Agreement and any licenses granted by +Recipient relating to the Program shall continue and survive.

+ +

Everyone is permitted to copy and distribute +copies of this Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The Agreement +Steward reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement Steward has +the right to modify this Agreement. The Eclipse Foundation is the initial +Agreement Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version of +the Agreement under which it was received. In addition, after a new version of +the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to +the intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved.

+ +

This Agreement is governed by the laws of the +State of New York and the intellectual property laws of the United States of +America. No party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. Each party waives +its rights to a jury trial in any resulting litigation.

+ +

 

+ +
+ + + + \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/feature.properties b/visualizer/org.eclipse.cdt.visualizer-feature/feature.properties new file mode 100644 index 00000000000..41c07c9a829 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/feature.properties @@ -0,0 +1,166 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Feature string resources +# ----------------------------------------------------------------------------- + +# "featureName" property - name of the feature +featureName=CDT Visualizer Framework + +# "providerName" property - name of the company that provides the feature +providerName=Eclipse CDT + +# "updateSiteName" property - label for the update site +updateSiteName=Eclipse CDT Update Site + +# "description" property - description of the feature +description=Visualizer View and Framework that allows to build custom visualizers. + +# copyright +copyright=\ +Copyright (c) 2012 Tilera Corporation and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +February 1, 2011\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the\n\ +Eclipse Foundation is provided to you under the terms and conditions of\n\ +the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is\n\ +provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse Foundation source code\n\ +repository ("Repository") in software modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Provisioning Technology (as defined below), you must agree to a license ("Feature \n\ +Update License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties" found within a Feature.\n\ +Such Abouts, Feature Licenses, and Feature Update Licenses contain the\n\ +terms and conditions (or references to such terms and conditions) that\n\ +govern your use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Eclipse Distribution License Version 1.0 (available at http://www.eclipse.org/licenses/edl-v1.0.html)\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +\n\Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which include,\n\ +but are not limited to, p2 and the Eclipse Update Manager ("Provisioning Technology") for\n\ +the purpose of allowing users to install software, documentation, information and/or\n\ +other materials (collectively "Installable Software"). This capability is provided with\n\ +the intent of allowing such users to install, extend and update Eclipse-based products.\n\ +Information about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install Installable Software.\n\ +You shall be responsible for enabling the applicable license agreements relating to the\n\ +Installable Software to be presented to, and accepted by, the users of the Provisioning Technology\n\ +in accordance with the Specification. By using Provisioning Technology in such a manner and\n\ +making it available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the following:\n\ +\n\ + 1. A series of actions may occur ("Provisioning Process") in which a user may execute\n\ + the Provisioning Technology on a machine ("Target Machine") with the intent of installing,\n\ + extending or updating the functionality of an Eclipse-based product.\n\ + 2. During the Provisioning Process, the Provisioning Technology may cause third party\n\ + Installable Software or a portion thereof to be accessed and copied to the Target Machine.\n\ + 3. Pursuant to the Specification, you will provide to the user the terms and conditions that\n\ + govern the use of the Installable Software ("Installable Software Agreement") and such\n\ + Installable Software Agreement shall be accessed from the Target Machine in accordance\n\ + with the Specification. Such Installable Software Agreement must inform the user of the\n\ + terms and conditions that govern the Installable Software and must solicit acceptance by\n\ + the end user in the manner prescribed in such Installable Software Agreement. Upon such\n\ + indication of agreement by the user, the provisioning Technology will complete installation\n\ + of the Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use, and\n\ +re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/feature.xml b/visualizer/org.eclipse.cdt.visualizer-feature/feature.xml new file mode 100755 index 00000000000..532b8663439 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/feature.xml @@ -0,0 +1,34 @@ + + + + + %description + + + + %copyright + + + + %license + + + + + + + diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/license.html b/visualizer/org.eclipse.cdt.visualizer-feature/license.html new file mode 100644 index 00000000000..f19c483b9c8 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/license.html @@ -0,0 +1,108 @@ + + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

February 1, 2011

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

+ +

Applicable Licenses

+ +

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ +
    +
  • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
  • +
  • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
  • +
  • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
  • +
  • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
  • +
+ +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ +
    +
  • The top-level (root) directory
  • +
  • Plug-in and Fragment directories
  • +
  • Inside Plug-ins and Fragments packaged as JARs
  • +
  • Sub-directories of the directory named "src" of certain Plug-ins
  • +
  • Feature directories
  • +
+ +

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

+ +

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

+ + + +

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. +
+ +

Cryptography

+ +

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ + diff --git a/visualizer/org.eclipse.cdt.visualizer-feature/pom.xml b/visualizer/org.eclipse.cdt.visualizer-feature/pom.xml new file mode 100644 index 00000000000..9dc4a21f830 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer-feature/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + org.eclipse.cdt + cdt-parent + 8.1.0-SNAPSHOT + ../../pom.xml + + + org.eclipse.cdt.features + 1.0.0-SNAPSHOT + org.eclipse.cdt.visualizer + eclipse-feature + diff --git a/visualizer/org.eclipse.cdt.visualizer.core/.classpath b/visualizer/org.eclipse.cdt.visualizer.core/.classpath new file mode 100755 index 00000000000..31db9a91174 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/visualizer/org.eclipse.cdt.visualizer.core/.project b/visualizer/org.eclipse.cdt.visualizer.core/.project new file mode 100755 index 00000000000..77747f8e3ea --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/.project @@ -0,0 +1,28 @@ + + + org.eclipse.cdt.visualizer.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/visualizer/org.eclipse.cdt.visualizer.core/.settings/org.eclipse.jdt.core.prefs b/visualizer/org.eclipse.cdt.visualizer.core/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..743b93d39ff --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Jul 01 09:20:33 EDT 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/visualizer/org.eclipse.cdt.visualizer.core/ABOUT.txt b/visualizer/org.eclipse.cdt.visualizer.core/ABOUT.txt new file mode 100755 index 00000000000..ad3ea21360a --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/ABOUT.txt @@ -0,0 +1,17 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +This plugin defines the non-UI components of the CDT Visualizer feature. + +For an overview of the Visualizer feature, see the following file: + + /org.eclipse.cdt.visualizer-feature/ABOUT.txt. + \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer.core/META-INF/MANIFEST.MF b/visualizer/org.eclipse.cdt.visualizer.core/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..6fec5fa40a4 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.cdt.visualizer.core;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.cdt.visualizer.core.plugin.CDTVisualizerCorePlugin +Bundle-Vendor: %provider.name +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.resources +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin +Export-Package: org.eclipse.cdt.visualizer.core, + org.eclipse.cdt.visualizer.core.plugin diff --git a/visualizer/org.eclipse.cdt.visualizer.core/about.html b/visualizer/org.eclipse.cdt.visualizer.core/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/about.html @@ -0,0 +1,24 @@ + + + + +About +

About This Content

+ +

June 5, 2007

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer.core/build.properties b/visualizer/org.eclipse.cdt.visualizer.core/build.properties new file mode 100755 index 00000000000..07409e935ad --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/build.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +############################################################################### +source.. = src/,\ + resources/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + about.html \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer.core/plugin.properties b/visualizer/org.eclipse.cdt.visualizer.core/plugin.properties new file mode 100644 index 00000000000..43181240cd1 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/plugin.properties @@ -0,0 +1,17 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Plugin string resources +# ----------------------------------------------------------------------------- + +plugin.name=CDT Visualizer Core Plug-in +provider.name=Eclipse CDT diff --git a/visualizer/org.eclipse.cdt.visualizer.core/pom.xml b/visualizer/org.eclipse.cdt.visualizer.core/pom.xml new file mode 100644 index 00000000000..bde189daa95 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + org.eclipse.cdt + cdt-parent + 8.1.0-SNAPSHOT + ../../pom.xml + + + 1.0.0-SNAPSHOT + org.eclipse.cdt.visualizer.core + eclipse-plugin + diff --git a/visualizer/org.eclipse.cdt.visualizer.core/resources/messages.properties b/visualizer/org.eclipse.cdt.visualizer.core/resources/messages.properties new file mode 100644 index 00000000000..70fa2ec9226 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/resources/messages.properties @@ -0,0 +1,14 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Application string resources +# ----------------------------------------------------------------------------- diff --git a/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/Extension.java b/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/Extension.java new file mode 100644 index 00000000000..10aac2651c2 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/Extension.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; + + +// --------------------------------------------------------------------------- +// Extension +// --------------------------------------------------------------------------- + +/** Facade/utility class for dealing with Eclipse extensions. */ +public class Extension extends ExtensionElement +{ + // --- static methods --- + + /** Gets extension point declaration with specified full ID (including plugin ID prefix). */ + public static IExtensionPoint getExtensionPoint(String extensionPointID) + { + IExtensionPoint extensionPoint = + Platform.getExtensionRegistry().getExtensionPoint( + extensionPointID); + return extensionPoint; + } + + /** Gets extension point declaration with specified name defined by specified plugin. */ + public static IExtensionPoint getExtensionPoint(String pluginID, String extensionPointName) + { + IExtensionPoint extensionPoint = + Platform.getExtensionRegistry().getExtensionPoint( + pluginID, extensionPointName); + return extensionPoint; + } + + /** Gets list of extensions for specified extension point ID (including plugin ID prefix). */ + public static List getExtensions(String extensionPointID) + { + IExtensionPoint extensionPoint = getExtensionPoint(extensionPointID); + return getExtensions(extensionPoint); + } + + /** Gets list of extensions for specified plugin and extension point name. */ + public static List getExtensions(String pluginID, String extensionPointName) + { + IExtensionPoint extensionPoint = getExtensionPoint(pluginID, extensionPointName); + return getExtensions(extensionPoint); + } + + /** Gets list of extensions for specified plugin and extension point name. */ + public static List getExtensions(IExtensionPoint extensionPoint) + { + return (extensionPoint == null) ? null : + Extension.wrapExtensions(extensionPoint.getConfigurationElements()); + } + + /** Wraps list of raw extension declarations. */ + public static List wrapExtensions(IConfigurationElement[] elements) + { + int count = (elements == null) ? 0 : elements.length; + List result = new ArrayList(count); + for (int i=0; i wrapExtensionElements(IConfigurationElement[] elements) + { + int count = (elements == null) ? 0 : elements.length; + List result = new ArrayList(count); + for (int i=0; i T getClassAttribute() + { + return getClassAttribute("class"); + } + + /** Creates and returns instance of implementing class, using class name found in specified attribute. */ + @SuppressWarnings("unchecked") + public T getClassAttribute(String attributeName) + { + T result = null; + try { + // TODO: Hmm... is there a right way to do this, without an unchecked cast? + result = (T) m_element.createExecutableExtension(attributeName); + } + catch (ClassCastException ex) { + // For now, eat it, and don't return this extension. + // TODO: decide how to log this + } + catch (CoreException ex) { + // For now, eat it, and don't return this extension. + // TODO: decide how to log this + } + return result; + } + + /** Creates and returns instance of implementing class, using class name found in specified attribute. */ + @SuppressWarnings("unchecked") + public T getClassAttribute(String attributeName, Object... arguments) + { + // Make sure we default to zero-argument form if we can. + if (arguments == null || arguments.length == 0) + return getClassAttribute(attributeName); + + // If we have arguments, have to do a little extra work. + T result = null; + try { + // Get name of class we're trying to load from attribute. + String className = getAttribute(attributeName); + + // Attempt to load class using the source plugin's class loader. + // TODO: is there a better way? + IContributor contributor = m_element.getContributor(); + String pluginID = contributor.getName(); + Bundle plugin = Platform.getBundle(pluginID); + Class instance = plugin.loadClass(className); + + // Select appropriate constructor for provided argument(s). + int argumentsLength = (arguments == null) ? 0 : arguments.length; + Class[] argumentTypes = new Class[argumentsLength]; + for (int i=0; i constructor = (Constructor) + instance.getConstructor(argumentTypes); + + // Invoke the constructor. + result = (T) constructor.newInstance(arguments); + } + catch (ClassNotFoundException ex) { + // TODO: decide how to log this + } + catch (NoSuchMethodException ex) { + // TODO: decide how to log this + } + catch (InvocationTargetException ex) { + // TODO: decide how to log this + } + catch (IllegalAccessException ex) { + // TODO: decide how to log this + } + catch (InstantiationException ex) { + // TODO: decide how to log this + } + catch (ClassCastException ex) { + // TODO: decide how to log this + } + catch (Exception ex) { + // TODO: decide how to log this + } + return result; + } + + /** Returns child elements of this element. */ + public List getChildren() + { + return wrapExtensionElements(m_element.getChildren()); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/ResourceManager.java b/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/ResourceManager.java new file mode 100755 index 00000000000..91e4c54377f --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/ResourceManager.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.core; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.core.runtime.Plugin; + + +// --------------------------------------------------------------------------- +// ResourceManager +// --------------------------------------------------------------------------- + +/** + * Plugin resource manager. + * This class should be instanced in the plugin's "start()" method, + * and disposed in the "stop()" method. + */ +public class ResourceManager{ + + // --- members --- + + /** Plugin ID */ + protected String m_pluginID = null; + + /** Plugin */ + protected Plugin m_plugin = null; + + /** Parent resource manager, if any */ + protected ResourceManager m_parentManager = null; + + /** String resource manager */ + protected ResourceBundle m_stringResources = null; + + /** String resource property file name */ + protected String m_stringResourceFilename = null; + + + // --- constructors/destructors --- + + /** + * Constructor, + * Assumes string resources are in the file "messages.properties". + */ + public ResourceManager(Plugin plugin) { + this(plugin, "messages.properties"); + } + + /** Constructor */ + public ResourceManager(Plugin plugin, String stringResourceFilename) { + m_pluginID = plugin.getBundle().getSymbolicName(); + m_plugin = plugin; + m_stringResourceFilename = stringResourceFilename; + getStringRegistry(); // creates registry object + } + + /** Dispose method */ + public void dispose() { + disposeStringRegistry(); + m_stringResourceFilename = null; + m_plugin = null; + m_pluginID = null; + } + + + // --- accessors --- + + /** Returns plugin we're associated with */ + public Plugin getPlugin() { + return m_plugin; + } + + + // --- parent manager management --- + + /** Sets parent resource manager, if any */ + public void setParentManager(ResourceManager parentManager) { + m_parentManager = parentManager; + } + + /** Gets parent resource manager, if any */ + public ResourceManager getParentManager() { + return m_parentManager; + } + + + // --- string resource management --- + + /** Creates/returns string registry */ + protected ResourceBundle getStringRegistry() { + if (m_stringResources == null) { + String filename = m_stringResourceFilename; + + // The ".properties" extension is assumed, so we trim it here + String propertiesExtension = ".properties"; + if (filename.endsWith(propertiesExtension)) { + filename = filename.substring(0, filename.length() - + propertiesExtension.length()); + } + + // NOTE: We have to be careful to pick up the class loader + // from the plugin class, otherwise we default to the classloader + // of the ResourceManager class, which is the classloader + // for the plugin the ResourceManager comes from. + ClassLoader classLoader = m_plugin.getClass().getClassLoader(); + Locale locale = Locale.getDefault(); + + // we'll check for .properties file first + // in the same directory as the plugin activator class + String propertyFileName1 = m_pluginID + ".plugin." + filename; + try { + m_stringResources = + ResourceBundle.getBundle(propertyFileName1, + locale, classLoader); + } + catch (MissingResourceException e) { + // TODO: log this exception (probably a .properties file is missing) + m_stringResources = null; + } + + // if not found, we try in the default package + // (that is, the top-level "src" or "resources" folder) + String propertyFileName2 = filename; + if (m_stringResources == null) { + try { + m_stringResources = + ResourceBundle.getBundle(propertyFileName2, + locale, classLoader); + } + catch (MissingResourceException e) { + // TODO: log this exception (probably a .properties file is missing) + m_stringResources = null; + } + } + } + return m_stringResources; + } + + /** Disposes of string registry */ + protected void disposeStringRegistry() { + m_stringResources = null; + } + + /** Returns string resource for specified key */ + public String getString(String key) { + String result = null; + if (key == null) return "(null resource)"; + + // get string registry, look up key + ResourceBundle strings = getStringRegistry(); + if (strings == null) { + // if we can't get the registry, display the key instead, + // so we know what's missing (e.g. the .properties file) + result = "(" + key + ")"; + } + else { + try { + result = strings.getString(key); + } + catch (MissingResourceException e) { + // we fail, but don't throw an exception + // so we don't screw any UI setup that depends + // on this string resource + result = null; + } + } + + // if we fail, try the parent manager if there is one + if (result == null && m_parentManager != null) { + result = m_parentManager.getString(key); + } + + // if we still fail, display the key instead, + // so we know what's missing + if (result == null) result = "[" + key + "]"; + return result; + } + + /** Formats string resource with specified argument(s) */ + public String getString(String key, Object... arguments) { + return MessageFormat.format(getString(key), arguments); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/plugin/CDTVisualizerCorePlugin.java b/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/plugin/CDTVisualizerCorePlugin.java new file mode 100755 index 00000000000..5b6b7e44881 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.core/src/org/eclipse/cdt/visualizer/core/plugin/CDTVisualizerCorePlugin.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.core.plugin; + +import org.eclipse.cdt.visualizer.core.ResourceManager; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + + +// ---------------------------------------------------------------------------- +// CDTVisualizerCorePlugin +// ---------------------------------------------------------------------------- + +/** + * CDT visualizer core plugin class. + * + * This plugin contains the non-UI components of the visualizer framework. + */ +public class CDTVisualizerCorePlugin extends AbstractUIPlugin +{ + // --- constants --- + + /** The plug-in ID */ + public static final String PLUGIN_ID = "org.eclipse.cdt.visualizer.core"; //$NON-NLS-1$ + + + // --- static members --- + + /** Singleton instance */ + protected static CDTVisualizerCorePlugin s_plugin; + + /** Returns the singleton instance */ + public static CDTVisualizerCorePlugin getDefault() { + return s_plugin; + } + + /** Resource manager */ + protected static ResourceManager s_resources = null; + + + // --- constructors/destructors --- + + /** Constructor */ + public CDTVisualizerCorePlugin() { + } + + + // --- plugin startup/shutdown methods --- + + /** Invoked when plugin is loaded. */ + public void start(BundleContext context) throws Exception { + super.start(context); + s_plugin = this; + + // touch activator classes of any plugins we depend on, + // to ensure their start() methods are called first + // (None for now.) + + // initialize resource management (strings, images, fonts, colors, etc.) + getPluginResources(); + } + + /** Invoked when plugin is stopped. */ + public void stop(BundleContext context) throws Exception { + // clean up resource management + cleanupPluginResources(); + + s_plugin = null; + super.stop(context); + } + + + // --- logging --- + + /** + * Writes message to Eclipse log. + * Severity can be one of: + * Status.OK, Status.ERROR, Status.INFO, Status.WARNING, Status.CANCEL + */ + public static void log(int severity, String text) + { + Status status = new Status(severity, PLUGIN_ID, text); + ResourcesPlugin.getPlugin().getLog().log(status); + } + + + // --- resource management --- + + /** Returns resource manager for this plugin */ + public ResourceManager getPluginResources() { + if (s_resources == null) { + s_resources = new ResourceManager(this); + } + return s_resources; + } + + /** Releases resource manager for this plugin. */ + public void cleanupPluginResources() { + s_resources.dispose(); + } + + /** Convenience method for getting plugin resource manager */ + public static ResourceManager getResources() { + return getDefault().getPluginResources(); + } + + /** Convenience method for looking up string resources */ + public static String getString(String key) { + return getDefault().getPluginResources().getString(key); + } + /** Convenience method for looking up string resources */ + public static String getString(String key, Object... arguments) { + return getDefault().getPluginResources().getString(key, arguments); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/.classpath b/visualizer/org.eclipse.cdt.visualizer.ui/.classpath new file mode 100755 index 00000000000..31db9a91174 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/.project b/visualizer/org.eclipse.cdt.visualizer.ui/.project new file mode 100755 index 00000000000..a76968ea1d3 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/.project @@ -0,0 +1,28 @@ + + + org.eclipse.cdt.visualizer.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/.settings/org.eclipse.jdt.core.prefs b/visualizer/org.eclipse.cdt.visualizer.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..a2d0967c487 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Jul 01 09:07:15 EDT 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/ABOUT.txt b/visualizer/org.eclipse.cdt.visualizer.ui/ABOUT.txt new file mode 100755 index 00000000000..ed483c41987 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/ABOUT.txt @@ -0,0 +1,17 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +This plugin defines the UI components of the CDT Visualizer feature. + +For an overview of the Visualizer feature, see the following file: + + /org.eclipse.cdt.visualizer-feature/ABOUT.txt. + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/META-INF/MANIFEST.MF b/visualizer/org.eclipse.cdt.visualizer.ui/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..baacda0774b --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.cdt.visualizer.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin +Bundle-Vendor: %provider.name +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.cdt.visualizer.core, + org.eclipse.core.resources +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin +Export-Package: org.eclipse.cdt.visualizer.ui, + org.eclipse.cdt.visualizer.ui.canvas, + org.eclipse.cdt.visualizer.ui.events, + org.eclipse.cdt.visualizer.ui.plugin, + org.eclipse.cdt.visualizer.ui.test, + org.eclipse.cdt.visualizer.ui.util diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/about.html b/visualizer/org.eclipse.cdt.visualizer.ui/about.html new file mode 100644 index 00000000000..cb740ae8bc8 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/about.html @@ -0,0 +1,24 @@ + + + + +About +

About This Content

+ +

June 5, 2007

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/build.properties b/visualizer/org.eclipse.cdt.visualizer.ui/build.properties new file mode 100755 index 00000000000..cd7654a8664 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/build.properties @@ -0,0 +1,23 @@ +############################################################################### +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +############################################################################### +source.. = src/,\ + resources/ +src.includes = schema/,\ + about.html +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + about.html,\ + icons/,\ + plugin.xml +src.includes = about.html + \ No newline at end of file diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/icons/full/view16/visualizer_view.png b/visualizer/org.eclipse.cdt.visualizer.ui/icons/full/view16/visualizer_view.png new file mode 100755 index 00000000000..c7d0e9f44a5 Binary files /dev/null and b/visualizer/org.eclipse.cdt.visualizer.ui/icons/full/view16/visualizer_view.png differ diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/plugin.properties b/visualizer/org.eclipse.cdt.visualizer.ui/plugin.properties new file mode 100644 index 00000000000..9e0a6a8cdc8 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/plugin.properties @@ -0,0 +1,19 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Plugin string resources +# ----------------------------------------------------------------------------- + +plugin.name=CDT Visualizer UI Plug-in +provider.name=Eclipse CDT + +view.visualizer.name=Visualizer diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/plugin.xml b/visualizer/org.eclipse.cdt.visualizer.ui/plugin.xml new file mode 100755 index 00000000000..5b5ea5e7d9c --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/plugin.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/pom.xml b/visualizer/org.eclipse.cdt.visualizer.ui/pom.xml new file mode 100644 index 00000000000..b52eb491215 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + org.eclipse.cdt + cdt-parent + 8.1.0-SNAPSHOT + ../../pom.xml + + + 1.0.0-SNAPSHOT + org.eclipse.cdt.visualizer.ui + eclipse-plugin + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/resources/messages.properties b/visualizer/org.eclipse.cdt.visualizer.ui/resources/messages.properties new file mode 100644 index 00000000000..56de5d40b3b --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/resources/messages.properties @@ -0,0 +1,17 @@ +# ============================================================================= +# Copyright (c) 2012 Tilera Corporation 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: +# William R. Swanson (Tilera Corporation) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Application string resources +# ----------------------------------------------------------------------------- + +# Visualizer viewer +VisualizerViewer.no.visualizers.defined=No visualizers defined. diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/schema/org.eclipse.cdt.visualizer.ui.visualizer.exsd b/visualizer/org.eclipse.cdt.visualizer.ui/schema/org.eclipse.cdt.visualizer.ui.visualizer.exsd new file mode 100644 index 00000000000..3f7e5e5f788 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/schema/org.eclipse.cdt.visualizer.ui.visualizer.exsd @@ -0,0 +1,123 @@ + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IVisualizer type definition. + + + + + + + IVisualizer unique ID. + + + + + + + IVisualizer implementing class. + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/IVisualizer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/IVisualizer.java new file mode 100644 index 00000000000..7f5f63b84a3 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/IVisualizer.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + + +// ---------------------------------------------------------------------------- +// IVisualizer +// ---------------------------------------------------------------------------- + +/** + * CDT Visualizer interface. + * + * An IVisualizer encapsulates a specific graphic presentation of the + * currently selected object (launch, target, etc.). + * + * It knows how to create a Control to draw on, which is displayed by + * the Visualizer Viewer, and also knows how to draw its presentation on + * that control. + * + * A visualizer can be generic (e.g. knows how to draw any kind of + * launch) or specific (e.g. specialized for a particular type of + * launch or execution target). The viewer automatically chooses + * the most specific IVisualizer that reports it is able to render + * the current selection. + */ +public interface IVisualizer + extends ISelectionProvider +{ + // --- init methods --- + + /** Invoked when visualizer is created, to permit any initialization. */ + public void initializeVisualizer(); + + /** Invoked when visualizer is disposed, to permit any cleanup. */ + public void disposeVisualizer(); + + + // --- accessors --- + + /** Sets non-localized name. */ + public void setName(String name); + /** Gets non-localized name. */ + + public String getName(); + + /** Sets localized display name. */ + public void setDisplayName(String displayName); + + /** Gets localized display name. */ + public String getDisplayName(); + + /** Sets localized description string. */ + public void setDescription(String description); + + /** Gets localized description string. */ + public String getDescription(); + + + // --- viewer management --- + + /** Called by viewer when visualizer is added to it. */ + public void setViewer(IVisualizerViewer viewer); + + /** Returns viewer control for this visualizer. */ + public IVisualizerViewer getViewer(); + + + // --- visualizer selection management --- + + /** Invoked when visualizer has been selected. */ + public void visualizerSelected(); + + /** Invoked when another visualizer has been selected, hiding this one. */ + public void visualizerDeselected(); + + + // --- control management --- + + /** Creates and returns visualizer's UI control on specified parent control. */ + public Control createControl(Composite parent); + + /** Gets visualizer control. + * Returns null if createControl() has not yet been called. + */ + public Control getControl(); + + + // --- menu/toolbar management --- + + /** + * Invoked when visualizer is selected, to populate the toolbar. + * The toolbar starts in a completely cleared state. + * The Visualizer can add/edit actions as desired. + * There is no need to invoke update on the toolbar, the viewer handles that. + */ + public void populateToolBar(IToolBarManager toolBarManager); + + /** + * Invoked when visualizer is selected, to populate the toolbar's menu. + * The toolbar starts in a completely cleared state. + * The Visualizer can add/edit actions as desired. + * There is no need to invoke update on the toolbar, the viewer handles that. + */ + public void populateMenu(IMenuManager menuManager); + + /** + * Invoked when visualizer view's context menu is invoked, to populate it. + * The toolbar starts in a completely cleared state. + * The Visualizer can add/edit actions as desired. + * There is no need to invoke update on the toolbar, the viewer handles that. + */ + public void populateContextMenu(IMenuManager menuManager); + + + // --- workbench selection management --- + + /** + * Tests whether if the IVisualizer can display the selection + * (or something reachable from it). + * + * Returns a positive "weight" if true, and zero otherwise. + * If multiple visualizers can handle a given selection, + * the one reporting the highest weight value "wins". + * In case of ties, an arbitrary visualizer is selected. + * + * The weight should reflect the specificity of the visualizer; + * in other words, a "default" visualization for a given selection + * should have a low weight, and a special case should have + * a higher weight; this allows the visualizer view to "fall back" + * to the default visualization in the general case. + */ + public int handlesSelection(ISelection selection); + + /** + * Invoked by VisualizerViewer when workbench selection changes. + */ + public void workbenchSelectionChanged(ISelection selection); + + + // --- selection changed event handling --- + + /** Adds external listener for selection change events. */ + public void addSelectionChangedListener(ISelectionChangedListener listener); + + /** Removes external listener for selection change events. */ + public void removeSelectionChangedListener(ISelectionChangedListener listener); + + /** Gets current externally-visible selection. */ + public ISelection getSelection(); + + /** Sets current externally-visible selection. */ + public void setSelection(ISelection selection); + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/IVisualizerViewer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/IVisualizerViewer.java new file mode 100644 index 00000000000..5cdda14cc78 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/IVisualizerViewer.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui; + +import org.eclipse.cdt.visualizer.ui.events.IVisualizerViewerListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Control; + + +// ---------------------------------------------------------------------------- +// IVisualizerViewer +// ---------------------------------------------------------------------------- + +/** + * CDT Visualizer Viewer interface. + * + * An IVisualizerViewer is a simple container for multiple + * IVisualizers, where the currently selected IVisualizer + * determines which IVisualizer control is displayed in the viewer. + */ +public interface IVisualizerViewer +{ + // --- accessors --- + + /** Gets containing view. */ + public VisualizerView getView(); + + /** Returns non-localized unique name for selected visualizer. */ + public String getVisualizerName(); + + /** Returns localized name to display for selected visualizer. */ + public String getVisualizerDisplayName(); + + /** Returns localized tooltip text to display for selected visualizer. */ + public String getVisualizerDescription(); + + + + // --- control management --- + + /** Gets viewer control. */ + public Control getControl(); + + + // --- focus handling --- + + /** + * Invoked by VisualizerView when currently selected presentation, + * if any, should take the focus. + */ + public boolean setFocus(); + + + // --- menu/toolbar management --- + + /** Invoked when visualizer is selected, to populate the toolbar. */ + public void populateToolBar(IToolBarManager toolBarManager); + + /** Invoked when visualizer is selected, to populate the toolbar's menu. */ + public void populateMenu(IMenuManager menuManager); + + + // --- context menu handling --- + + /** Invoked when context menu is about to be shown. */ + public void populateContextMenu(IMenuManager m); + + /** Gets context menu location. */ + public Point getContextMenuLocation(); + + + // --- selection handling --- + + /** + * Invoked by VisualizerView when workbench selection changes, + * and the change was made by some other view. + */ + public void workbenchSelectionChanged(ISelection selection); + + /** Adds external listener for selection change events. */ + public void addSelectionChangedListener(ISelectionChangedListener listener); + + /** Removes external listener for selection change events. */ + public void removeSelectionChangedListener(ISelectionChangedListener listener); + + /** Gets current externally-visible selection. */ + public ISelection getSelection(); + + + // --- events --- + + /** Adds listener for viewer events. */ + public void addVisualizerViewerListener(IVisualizerViewerListener listener); + + /** Removes listener for viewer events. */ + public void removeVisualizerViewerListener(IVisualizerViewerListener listener); + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/Visualizer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/Visualizer.java new file mode 100755 index 00000000000..a2b110b60c5 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/Visualizer.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui; + +import org.eclipse.cdt.visualizer.ui.util.SelectionManager; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + + +// --------------------------------------------------------------------------- +// Visualizer +// --------------------------------------------------------------------------- + +/** + * Base class for IVisualizer implementations. + */ +abstract public class Visualizer + implements IVisualizer, ISelectionProvider, ISelectionChangedListener +{ + // --- members --- + + /** Visualizer's non-localized name. */ + protected String m_name; + + /** Visualizer's localized, displayable name. */ + protected String m_displayName; + + /** Visualizer's localized, displayable description. */ + protected String m_description; + + /** The parent view control. */ + protected IVisualizerViewer m_viewer; + + /** The visualizer control. */ + protected Control m_control; + + /** Externally visible selection manager. */ + protected SelectionManager m_selectionManager; + + + // --- constructors/destructors --- + + /** Constructor. */ + public Visualizer() { + // TODO: internationalize these strings. + this("visualizer", "Visualizer", "Displays graphic representation of selection."); + } + + /** Constructor. */ + public Visualizer(String name, String displayName, String description) { + setName(name); + setDisplayName(displayName); + setDescription(description); + m_selectionManager = new SelectionManager(this, "Visualizer selection manager"); + } + + /** Dispose method. */ + public void dispose() { + m_name = null; + m_displayName = null; + m_description = null; + disposeControl(); + m_viewer = null; + if (m_selectionManager != null) { + m_selectionManager.dispose(); + m_selectionManager = null; + } + } + + + // --- init methods --- + + /** Invoked when visualizer is created, to permit any initialization. + * Intended to be overridden. Default implementation does nothing. + */ + public void initializeVisualizer() + { + } + + /** Invoked when visualizer is disposed, to permit any cleanup. + * Intended to be overridden. Default implementation calls dispose(). + */ + public void disposeVisualizer() + { + dispose(); + } + + + // --- accessors --- + + /** Sets non-localized name. */ + public void setName(String name) { + m_name = name; + } + /** Gets non-localized name. */ + public String getName() { + return m_name; + } + + /** Sets localized display name. */ + public void setDisplayName(String displayName) { + m_displayName = displayName; + } + /** Gets localized display name. */ + public String getDisplayName() { + return m_displayName; + } + + /** Sets localized description string. */ + public void setDescription(String description) { + m_description = description; + } + /** Gets localized description string. */ + public String getDescription() { + return m_description; + } + + + // --- viewer management --- + + /** Sets viewer we're associated with. */ + public void setViewer(IVisualizerViewer viewer) { + m_viewer = viewer; + } + + /** Gets viewer we're associated with. */ + public IVisualizerViewer getViewer() { + return m_viewer; + } + + + // --- visualizer selection management --- + + /** Invoked when visualizer has been selected. */ + public void visualizerSelected() { + }; + + /** Invoked when another visualizer has been selected, hiding this one. */ + public void visualizerDeselected() { + }; + + + // --- control management --- + + /** Creates and returns visualizer's UI control on specified parent control. */ + abstract public Control createControl(Composite parent); + + /** Invoked when visualizer control should be disposed. */ + abstract public void disposeControl(); + + /** + * Sets visualizer control. + * Intended to be called from createControl(); + */ + protected void setControl(Control control) { + m_control = control; + } + + /** Gets visualizer control. + * Returns null if createControl() has not yet been called. + */ + public Control getControl() { + return m_control; + } + + + // --- menu/toolbar management --- + + /** Invoked by VisualizerViewer when toolbar needs to be populated. */ + public void populateToolBar(IToolBarManager toolBarManager) { + } + + /** Invoked by VisualizerViewer when toolbar menu needs to be populated. */ + public void populateMenu(IMenuManager menuManager) { + } + + + // --- context menu handling --- + + /** Invoked by VisualizerViewer when context menu needs to be populated. */ + public void populateContextMenu(IMenuManager menuManager) { + } + + + // --- workbench selection management --- + + /** + * Tests whether if the IVisualizer can display the selection + * (or something reachable from it). + */ + public int handlesSelection(ISelection selection) + { + // Default implementation doesn't know how to display anything. + return 0; + } + + /** + * Invoked by VisualizerViewer when workbench selection changes. + */ + public void workbenchSelectionChanged(ISelection selection) + { + // Default implementation does nothing. + } + + + // --- ISelectionProvider implementation --- + + // Delegate to selection manager. + + /** Adds external listener for selection change events. */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionManager.addSelectionChangedListener(listener); + } + + /** Removes external listener for selection change events. */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionManager.removeSelectionChangedListener(listener); + } + + /** Raises selection changed event. */ + public void raiseSelectionChangedEvent() { + m_selectionManager.raiseSelectionChangedEvent(); + } + + /** Gets current externally-visible selection. */ + public ISelection getSelection() + { + return m_selectionManager.getSelection(); + } + + /** Sets externally-visible selection. */ + public void setSelection(ISelection selection) + { + m_selectionManager.setSelection(selection); + } + + /** Sets externally-visible selection. */ + public void setSelection(ISelection selection, boolean raiseEvent) + { + m_selectionManager.setSelection(selection, raiseEvent); + } + + /** Returns true if we currently have a non-empty selection. */ + public boolean hasSelection() + { + return m_selectionManager.hasSelection(); + } + + + // --- ISelectionChangedListener implementation --- + + /** + * Intended to be invoked when visualizer control's selection changes. + * Sets control selection as its own selection, + * and raises selection changed event for any listeners. + */ + public void selectionChanged(SelectionChangedEvent event) { + setSelection(event.getSelection()); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerAction.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerAction.java new file mode 100755 index 00000000000..0098d84854d --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerAction.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.widgets.Event; + + +// --------------------------------------------------------------------------- +// VisualizerAction +// --------------------------------------------------------------------------- + +/** Base class for visualizer actions. + * (Viewers are not required to use this class. This is simply a + * convenience wrapper for the standard Action class.) + */ +public class VisualizerAction extends Action +{ + // --- members --- + + // --- constructors/destructors --- + + /** Constructor. */ + protected VisualizerAction() { + // NOTE: this constructor is only intended for deriving classes + // that need to construct the text/description/image attributes + // programmatically. + } + + /** Constructor. */ + public VisualizerAction(String text, String description) { + super(text); + setDescription(description); + } + + /** Constructor. */ + public VisualizerAction(String text, String description, + ImageDescriptor image) { + super(text, image); + setDescription(description); + } + + /** Constructor. */ + public VisualizerAction(String text, String description, + ImageDescriptor enabledImage, ImageDescriptor disabledImage) { + super(text, enabledImage); + setDescription(description); + setDisabledImageDescriptor(disabledImage); + } + + /** Dispose method. */ + public void dispose() + { + } + + + // --- methods --- + + /** Invoked when action is triggered. */ + public void run() { + } + + /** Invoked when action is triggered, + * with the event that caused it. + */ + public void runWithEvent(Event event) { + run(); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerView.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerView.java new file mode 100644 index 00000000000..ec5ce2d73db --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerView.java @@ -0,0 +1,415 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +// Package declaration +package org.eclipse.cdt.visualizer.ui; + +// Java classes +import java.util.List; + +// SWT/JFace classes +import org.eclipse.jface.action.IMenuListener2; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.jface.action.IToolBarManager; + +// Eclipse/CDT classes +import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.IActionBars; + +// Custom classes +import org.eclipse.cdt.visualizer.ui.events.IVisualizerViewerListener; +import org.eclipse.cdt.visualizer.ui.events.VisualizerViewerEvent; +import org.eclipse.cdt.visualizer.ui.util.SelectionProviderAdapter; +import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; +import org.eclipse.cdt.visualizer.ui.util.WorkbenchSelectionAdapter; + + +// ---------------------------------------------------------------------------- +// VisualizerView +// ---------------------------------------------------------------------------- + +/** + * CDT Visualizer View class. + * + * This is the default implementation of the Visualizer View. + * It can also serve as a base class for custom visualizer views. + * + * The Visualizer View is a simple container with a toolbar, + * which presents an instance of an IVisualizerViewer, + * and mediates passing of selections to and from the viewer. + * + * The intent of the VisualizerView class is to encapsulate the + * standard Eclipse workbench view support, so the viewer does + * not have to worry about such things. + */ +public class VisualizerView + extends ViewPart + implements IVisualizerViewerListener, + ISelectionChangedListener +{ + // --- members --- + + /** Whether view has been initialized */ + protected boolean m_initialized = false; + + /** Parent control of view. */ + protected Composite m_parentControl = null; + + /** Contained IVisualizerViewer control. */ + protected IVisualizerViewer m_viewer = null; + + /** Selection change event manager */ + protected WorkbenchSelectionAdapter m_workbenchSelectionAdapter = null; + + /** Context menu manager. */ + protected MenuManager m_contextMenuManager = null; + + /** Last context menu display location. */ + protected Point m_contextMenuLocation = null; + + + // --- constructors/destructors --- + + /** Constructor */ + public VisualizerView() { + super(); + } + + /** Dispose method */ + public void dispose() { + super.dispose(); + setViewer(null); + disposeSelectionHandling(); + } + + + // --- accessors --- + + /** Returns whether view has been initialized. */ + public boolean isInitialized() + { + return m_initialized; + } + + /** Gets contained viewer control. */ + public IVisualizerViewer getViewer() + { + return m_viewer; + } + + /** Sets contained viewer control. */ + public void setViewer(IVisualizerViewer viewer) + { + if (m_viewer != null) { + m_viewer.removeSelectionChangedListener(this); + m_viewer.removeVisualizerViewerListener(this); + } + + m_viewer = viewer; + + if (m_viewer != null) + { + m_viewer.addVisualizerViewerListener(this); + m_viewer.addSelectionChangedListener(this); + updateUI(); + } + } + + + // --- ViewPart implementation --- + + // IMPORTANT: a view may be loaded before the plugins, etc. + // that its content depends on, since Eclipse loads saved workbench "memento" state, + // including current perspective and view layout, before loading dependent plugins, + // and lazily loads plugins based on classes that get touched. + // + // Hence, a view class should invoke setInitialized(true) at the end + // of its createPartControl() method, and any methods that touch/repaint/update + // the view's controls, etc. should call isInitialized() to be sure + // these controls have been created. + + /** Invoked when UI controls need to be created */ + public void createPartControl(Composite parent) { + m_parentControl = parent; + + // Reminder: Don't muck with the toolbar or toolbar menu here. + // (I.e. don't try to clean them out or set initial items.) + // VisualizerViewer's selection handling code + // allows the selected visualizer to set their content, and + // any fiddling you do here will only interfere with that. + + // set up context menu support + initializeContextMenu(); + + // set up selection handling + initializeSelectionHandling(); + + // initialize viewer control + initializeViewer(); + + m_initialized = true; + } + + /** Invoked when view should take the focus. + * Note: this can be invoked before the view is fully initialized + * (for example, when loading views from workspace memento information), + * in which case it should silently do nothing. + */ + public void setFocus() { + if (m_viewer != null) m_viewer.setFocus(); + } + + + // --- initialization support --- + + /** + * Creates and returns VisualizerViewer control. + * Intended to be overridden by derived types. + */ + protected IVisualizerViewer createViewer(Composite parent) + { + return (m_viewer != null) ? m_viewer : new VisualizerViewer(this, parent); + } + + /** + * Invoked by createPartControl() method when view instance is created. + * Intended to be overridden by derived classes. + */ + protected void initializeViewer() { + IVisualizerViewer viewer = createViewer(m_parentControl); + setViewer(viewer); + } + + + // --- tab name management --- + + /** Sets displayed tab name and description for this view. */ + public void setTabName(String displayName) + { + setPartName(displayName); + } + + /** Sets displayed tab name and description for this view. */ + public void setTabDescription(String description) + { + setTitleToolTip(description); + } + + + // --- selection handling --- + + /** Initializes selection handling for this view. */ + protected void initializeSelectionHandling() { + // create workbench selection change adapter, + // to hook us into the workbench selection event mechanism + m_workbenchSelectionAdapter = new WorkbenchSelectionAdapter(this); + m_workbenchSelectionAdapter.addSelectionChangedListener(this); + } + + /** Disposes selection handling for this view. */ + protected void disposeSelectionHandling() { + if (m_workbenchSelectionAdapter != null) { + m_workbenchSelectionAdapter.dispose(); + m_workbenchSelectionAdapter = null; + } + } + + /** Gets current workbench selection. */ + public ISelection getWorkbenchSelection() { + return m_workbenchSelectionAdapter.getSelection(); + } + + /** Sets current workbench selection, and raises selection changed event. */ + public void setWorkbenchSelection(ISelection selection) { + m_workbenchSelectionAdapter.setSelection(this, selection); + } + + /** Sets current workbench selection, and raises selection changed event. */ + public void setWorkbenchSelection(List selection) { + ISelection iselection = SelectionUtils.toSelection(selection); + m_workbenchSelectionAdapter.setSelection(this, iselection); + } + + // --- ISelectionChangedListener implementation --- + + /** Invoked by WorkbenchSelectionAdapter when selection changes, + * and by viewer when visualizer selection changes. + */ + public void selectionChanged(SelectionChangedEvent event) { + Object source = event.getSource(); + if (source instanceof SelectionProviderAdapter) { + source = ((SelectionProviderAdapter) source).getActualSource(); + } + // if the source is the current VisualizerViewer, + // it's a user selection in the viewer, so we want to pass + // the selection change on to the workbench + if (source == m_viewer) { + // tell viewer about workbench selection + ISelection selection = event.getSelection(); + setWorkbenchSelection(selection); + + // update toolbar/menu to reflect changed selection + updateUI(); + } + // if the source is this view, it's an echo of a workbench + // event we sent out, so ignore it. + else if (source == this) { + // Do nothing. + } + // else this is a selection change from some other view + // in the workbench, which we should pass down to the viewer + else { + ISelection selection = event.getSelection(); + workbenchSelectionChanged(selection); + + // update toolbar/menu to reflect changed selection + updateUI(); + } + } + + /** + * Invoked from selectionChanged() when workbench's selection changes, + * but only if the selection change did not come from this view. + */ + public void workbenchSelectionChanged(ISelection selection) { + if (m_viewer != null) { + m_viewer.workbenchSelectionChanged(selection); + } + } + + + // --- IVisulizerViewerListener implementation --- + + /** Invoked when visualizer in view has changed. */ + public void visualizerEvent(IVisualizerViewer source, VisualizerViewerEvent event) { + switch (event.getType()) { + case VisualizerViewerEvent.VISUALIZER_CHANGED: + updateUI(); + break; + case VisualizerViewerEvent.VISUALIZER_CONTEXT_MENU: + showContextMenu(event.x, event.y); + } + } + + + // --- update methods --- + + /** Updates tab name, toolbar, etc. from viewer. */ + public void updateUI() { + + // Update tab name/tooltip + // TODO: internationalize these default strings + String name = "Visualizer View"; + String description = "Displays visualizations of launches."; + if (m_viewer != null) { + name = m_viewer.getVisualizerDisplayName(); + description = m_viewer.getVisualizerDescription(); + + } + setTabName(name); + setTabDescription(description); + + // Update toolbar & toolbar menu + if (m_viewer != null) { + IActionBars actionBars = getViewSite().getActionBars(); + + // Allow presentation to set the displayed toolbar content, if any + IToolBarManager toolBarManager = actionBars.getToolBarManager(); + toolBarManager.removeAll(); + m_viewer.populateToolBar(toolBarManager); + toolBarManager.update(true); + + // Allow presentation to set the toolbar's menu content, if any + IMenuManager menuManager = actionBars.getMenuManager(); + menuManager.removeAll(); + m_viewer.populateMenu(menuManager); + menuManager.update(true); + + // Note: when context menu is invoked, + // the poplateContextMenu() method is called by the view, + // which in turn delegates to the current visualizer + // to populate the context menu. + + // Propagate the changes + actionBars.updateActionBars(); + } + } + + + // --- context menu support --- + + /** Sets up context menu support. */ + protected void initializeContextMenu() { + m_contextMenuManager = new MenuManager(); + m_contextMenuManager.addMenuListener(new IMenuListener2() { + public void menuAboutToShow(IMenuManager m) { + VisualizerView.this.contextMenuShow(m); + } + public void menuAboutToHide(IMenuManager m) { + VisualizerView.this.contextMenuHide(m); + } + }); + + // We associate the view's context menu with the parent control. + // Viewer has the option of calling showContextMenu() + // to display the view's context menu. + Menu menu= m_contextMenuManager.createContextMenu(m_parentControl); + m_parentControl.setMenu(menu); + } + + /** Invoked when context menu is about to be shown. */ + protected void contextMenuShow(IMenuManager m) + { + m.removeAll(); + m_viewer.populateContextMenu(m); + m.update(); + } + + /** Invoked when context menu is about to be hidden. */ + protected void contextMenuHide(IMenuManager m) + { + } + + /** Shows view's context menu at specified position. */ + public void showContextMenu(int x, int y) + { + Menu menu = m_parentControl.getMenu(); + if (menu != null) { + menu.setLocation(x, y); + + // capture context menu location in relative coordinates + m_contextMenuLocation = m_parentControl.toControl(x,y); + + // Note: showing menu implicitly invokes populateContextMenu() + // to populate context menu items. + menu.setVisible(true); + + // Make sure we have the focus now + // so we'll still have it when the menu goes away, + // and user doesn't have to click twice. + setFocus(); + } + } + + /** Gets context menu location. */ + public Point getContextMenuLocation() { + // Just asking the menu for its own location doesn't work, + // so we have to capture it above and return it here. + return m_contextMenuLocation; + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java new file mode 100644 index 00000000000..a9c71c2d1b3 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java @@ -0,0 +1,540 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui; + +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.visualizer.core.Extension; +import org.eclipse.cdt.visualizer.ui.events.IVisualizerViewerListener; +import org.eclipse.cdt.visualizer.ui.events.VisualizerViewerEvent; +import org.eclipse.cdt.visualizer.ui.plugin.CDTVisualizerUIPlugin; +import org.eclipse.cdt.visualizer.ui.util.ListenerList; +import org.eclipse.cdt.visualizer.ui.util.SelectionManager; +import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MenuDetectEvent; +import org.eclipse.swt.events.MenuDetectListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.PageBook; + + +// ---------------------------------------------------------------------------- +// VisualizerViewer +// ---------------------------------------------------------------------------- + +/** + * CDT Visualizer Viewer class. + * + * This is the default implementation of IVisualizerViewer. + * It can also serve as a base class for custom visualizer viewers. + * + * The Visualizer Viewer is a simple container for multiple + * IVisualizers, where the currently selected IVisualizer + * determines which IVisualizer control is displayed in the viewer. + * + * The base implementation simply displays a single IVisualizer at a time. + * One can programmatically switch selections, but there are no user + * controls for doing so. (The intent is that derived types can add + * various kinds of switching controls, like a combo box, etc.) + */ +public class VisualizerViewer extends PageBook + implements IVisualizerViewer, MenuDetectListener, + ISelectionProvider, ISelectionChangedListener +{ + // --- constants --- + + /** Extension point name for list of IVisualizer types. */ + public static final String VISUALIZER_EXTENSION_POINT_NAME = "visualizer"; //$NON-NLS-1$ + + + // --- members --- + + /** Containing view. */ + protected VisualizerView m_view = null; + + /** Parent control. */ + protected Composite m_parent = null; + + /** List of registered visualizer types. */ + protected Map m_visualizers = null; + + /** Currently selected visualizer. */ + protected IVisualizer m_currentVisualizer = null; + + /** Event listeners. */ + protected ListenerList m_listeners = null; + + /** Viewer selection manager. */ + protected SelectionManager m_selectionManager = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public VisualizerViewer(VisualizerView view, Composite parent) { + super(parent, SWT.NONE); + initVisualizerViewer(view, parent); + } + + /** Dispose method. */ + public void dispose() { + cleanupVisualizerViewer(); + super.dispose(); + } + + /** Overridden to permit subclassing of SWT component */ + protected void checkSubclass() { + // Do nothing. + // (Superclass implementation throws "Subclassing not allowed" exception.) + } + + + // --- init methods --- + + /** Initializes control */ + protected void initVisualizerViewer(VisualizerView view, Composite parent) { + m_view = view; + m_parent = parent; + + // Event listener support + m_listeners = new ListenerList(this, "VisualizerViewer event listeners") + { + public void raise(Object listener, Object event) { + if (listener instanceof IVisualizerViewerListener && + event instanceof VisualizerViewerEvent) + { + IVisualizerViewerListener typedListener = (IVisualizerViewerListener) listener; + VisualizerViewerEvent typedEvent = (VisualizerViewerEvent) event; + typedListener.visualizerEvent(VisualizerViewer.this, typedEvent); + } + } + }; + + // Selection change listener support + m_selectionManager = new SelectionManager(this, "Visualizer Viewer selection manager"); + + // Set default colors for empty viewer. + Display display = getDisplay(); + setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + setForeground(display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + + // Listen to paint event to draw "No visualizers" warning if needed. + this.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent e) { + VisualizerViewer.this.paint(e.gc); + } + }); + + // Load any visualizers defined through extension point. + loadVisualizers(); + } + + /** Cleans up control */ + protected void cleanupVisualizerViewer() { + // perform any cleanup here + disposeVisualizers(); + if (m_selectionManager != null) { + m_selectionManager.dispose(); + m_selectionManager = null; + } + } + + + // --- accessors --- + + /** Gets containing view. */ + public VisualizerView getView() { + return m_view; + } + + /** Returns non-localized unique name for selected visualizer. */ + public String getVisualizerName() + { + String result = "visualizer"; + if (m_currentVisualizer != null) result = m_currentVisualizer.getName(); + return result; + } + + /** Returns localized name to display for selected visualizer. */ + public String getVisualizerDisplayName() + { + String result = "Visualizer"; + if (m_currentVisualizer != null) result = m_currentVisualizer.getDisplayName(); + return result; + } + + /** Returns localized tooltip text to display for selected visualizer. */ + public String getVisualizerDescription() + { + String result = "Visualizer"; + if (m_currentVisualizer != null) result = m_currentVisualizer.getDescription(); + return result; + } + + + // --- control management --- + + /** Gets viewer control. */ + public Control getControl() { + return this; + } + + + // --- focus handling --- + + /** + * Invoked by VisualizerView when currently selected presentation, + * if any, should take the focus. + */ + public boolean setFocus() + { + boolean result = false; + if (m_currentVisualizer != null) { + // Tell current visualizer's control to take the focus. + m_currentVisualizer.getControl().setFocus(); + } + else { + // Otherwise, let viewer take the focus. + result = super.setFocus(); + } + return result; + } + + + // --- viewer events --- + + /** Adds listener for viewer events. */ + public void addVisualizerViewerListener(IVisualizerViewerListener listener) + { + m_listeners.addListener(listener); + } + + /** Removes listener for viewer events. */ + public void removeVisualizerViewerListener(IVisualizerViewerListener listener) + { + m_listeners.removeListener(listener); + } + + /** Raises change event for all listeners. */ + public void raiseVisualizerChangedEvent() + { + VisualizerViewerEvent event = + new VisualizerViewerEvent(this, VisualizerViewerEvent.VISUALIZER_CHANGED); + m_listeners.raise(event); + } + + /** Raises context menu event for all listeners. */ + public void raiseContextMenuEvent(int x, int y) + { + VisualizerViewerEvent event = + new VisualizerViewerEvent(this, VisualizerViewerEvent.VISUALIZER_CONTEXT_MENU, x, y); + m_listeners.raise(event); + } + + + // --- visualizer management --- + + /** Loads initial set of visualizers and constructs viewer controls. */ + protected void loadVisualizers() + { + // TODO: add error checking, logging for errors in extension declarations + // TODO: do we need to worry about this being called more than once? + + m_visualizers = new Hashtable(); + + List visualizers = Extension.getExtensions( + CDTVisualizerUIPlugin.FEATURE_ID, VISUALIZER_EXTENSION_POINT_NAME); + + if (visualizers != null) { + for(Extension e : visualizers) { + String id = e.getAttribute("id"); + IVisualizer visualizerInstance = e.getClassAttribute(); + if (id != null && visualizerInstance != null) { + // Add visualizer's control to viewer's "pagebook" of controls. + visualizerInstance.setViewer(this); + visualizerInstance.initializeVisualizer(); + visualizerInstance.createControl(this); + m_visualizers.put(id, visualizerInstance); + } + } + } + + // select initial visualization + selectDefaultVisualizer(); + } + + /** Cleans up visualizers. */ + protected void disposeVisualizers() + { + for (String id : m_visualizers.keySet()) { + IVisualizer v = m_visualizers.get(id); + Control c = v.getControl(); + c.dispose(); + v.disposeVisualizer(); + } + m_visualizers.clear(); + } + + + /** Selects default visualizer. + * Default implementation displays visualizer that can handle + * the current selection. + */ + public void selectDefaultVisualizer() + { + // fake a workbench selection changed event + updateVisualizerFromWorkbenchSelection(); + } + + /** Selects specified visualizer, makes its control visible. */ + public void selectVisualizer(IVisualizer visualizer) + { + if (visualizer == null) return; + if (visualizer == m_currentVisualizer) return; + + if (m_currentVisualizer != null) { + // let the visualizer know it's being hidden + m_currentVisualizer.visualizerDeselected(); + + // stop listening for context menu events + m_currentVisualizer.getControl().removeMenuDetectListener(this); + + // stop listening for selection changed events + m_currentVisualizer.removeSelectionChangedListener(this); + } + + m_currentVisualizer = visualizer; + + if (m_currentVisualizer != null) { + // We've added visualizer's control in loadVisualizers(), + // so all we need to do here is select it. + showPage(visualizer.getControl()); + + // start listening for context menu events + m_currentVisualizer.getControl().addMenuDetectListener(this); + + // start listening for selection changed events + m_currentVisualizer.addSelectionChangedListener(this); + + // raise visualizer changed event, so view knows + // it should update tab name, toolbar, etc. + raiseVisualizerChangedEvent(); + + // make sure workbench knows about current visualizer selection + updateWorkbenchFromVisualizerSelection(); + + // no need to update visualizer from workbench selection, + // we already do that whenever the workbench selection changes + + // let the visualizer know it's been shown + m_currentVisualizer.visualizerDeselected(); + } + } + + /** Gets current visualizer. */ + public IVisualizer getVisualizer() + { + return m_currentVisualizer; + } + + + // --- menu/toolbar management --- + + /** Invoked when visualizer is selected, to populate the toolbar. */ + public void populateToolBar(IToolBarManager toolBarManager) + { + if (m_currentVisualizer != null) + m_currentVisualizer.populateToolBar(toolBarManager); + } + + /** Invoked when visualizer is selected, to populate the toolbar's menu. */ + public void populateMenu(IMenuManager menuManager) + { + if (m_currentVisualizer != null) + m_currentVisualizer.populateMenu(menuManager); + } + + + // --- context menu handling --- + + /** Invoked when context menu gesture happens on current + * visualizer control. + */ + public void menuDetected(MenuDetectEvent e) { + // raise event to allow view to show context menu + raiseContextMenuEvent(e.x, e.y); + } + + /** Invoked when context menu is about to be shown. */ + public void populateContextMenu(IMenuManager m) + { + if (m_currentVisualizer != null) { + m_currentVisualizer.populateContextMenu(m); + } + } + + /** Gets context menu location. */ + public Point getContextMenuLocation() { + return m_view.getContextMenuLocation(); + } + + + // --- paint methods --- + + /** + * Invoked when viewer needs to be repainted. + * May be overridden by derived classes. + * Default implementation displays "No visualizers defined." message + */ + public void paint(GC gc) + { + gc.fillRectangle(getClientArea()); + if (m_visualizers == null || m_visualizers.size() == 0) { + String noVisualizersMessage = + CDTVisualizerUIPlugin.getString("VisualizerViewer.no.visualizers.defined"); + gc.drawString("(" + noVisualizersMessage + ")", 10, 10); + } + } + + + // --- ISelectionProvider implementation --- + + // Delegate to selection manager. + + /** Adds external listener for selection change events. */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionManager.addSelectionChangedListener(listener); + } + + /** Removes external listener for selection change events. */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionManager.removeSelectionChangedListener(listener); + } + + /** Raises selection changed event. */ + public void raiseSelectionChangedEvent() { + m_selectionManager.raiseSelectionChangedEvent(); + } + + /** Gets current externally-visible selection. */ + public ISelection getSelection() + { + return m_selectionManager.getSelection(); + } + + /** Sets externally-visible selection. */ + public void setSelection(ISelection selection) + { + m_selectionManager.setSelection(selection); + } + + + // --- workbench selection handling --- + + /** + * Updates visualizer from current workbench selection. + * NOTE: normally VisulizerView keeps the viewer in synch + * with the selection, so this should not need to be called + * except in special cases. + */ + public void updateVisualizerFromWorkbenchSelection() { + ISelection selection = SelectionUtils.getWorkbenchSelection(); + workbenchSelectionChanged(selection); + } + + /** + * Invoked by VisualizerView when workbench selection changes, + * and change's source is not this view. + * + * Selects visualizer (if any) that knows how to display current + * selection. Also invokes workbenchSelectionChanged() on visualizer + * so it can update itself accordingly. + */ + public void workbenchSelectionChanged(ISelection selection) + { + // See if we need to change visualizers to handle selection type. + IVisualizer handles = null; + int weight = 0; + + // First, see if the current visualizer can handle the new selection. + // (This gives it automatic precedence if there's a tie.) + if (m_currentVisualizer != null) { + int w = m_currentVisualizer.handlesSelection(selection); + if (w > weight) { + handles = m_currentVisualizer; + weight = w; + } + } + + // Next, check the list of other visualizers, to see if any + // of them is more specific than the current one. + for (IVisualizer v : m_visualizers.values()) { + if (v == m_currentVisualizer) continue; // already checked + int w = v.handlesSelection(selection); + if (w > weight) { + handles = v; + weight = w; + } + } + + // If NOBODY claims ownership, and we don't have a visualizer yet, + // then pick somebody and let them take a whack at it. + if (handles == null && m_visualizers.size() > 0) { + handles = m_visualizers.values().iterator().next(); + } + + // If we need to change visualizers, select the new one. + // Note: this also reports the new visualizer's selection to the workbench + if (handles != null && handles != m_currentVisualizer) { + selectVisualizer(handles); + } + + // Notify current visualizer that workbench selection has changed. + // (This means a visualizer is only notified of workbench selection changes + // if the selection is something it has reported that it can display.) + if (m_currentVisualizer != null) { + m_currentVisualizer.workbenchSelectionChanged(selection); + } + } + + + // --- visualizer selection handling --- + + /** Updates workbench selection from current visualizer selection. + * Note: normally the viewer keeps the selection in synch, + * so you should not need to call this method except in special cases. + */ + public void updateWorkbenchFromVisualizerSelection() { + // fake a selection changed event + m_selectionManager.raiseSelectionChangedEvent(); + } + + /** Invoked when visualizer's selection changes. */ + public void selectionChanged(SelectionChangedEvent event) { + // Publish changed visualizer selection to any listeners. + setSelection(event.getSelection()); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java new file mode 100755 index 00000000000..b4f2778cef4 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.canvas; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + + +// --------------------------------------------------------------------------- +// BufferedCanvas +// --------------------------------------------------------------------------- + +/** Canvas control with double-buffering support. */ +public class BufferedCanvas extends Canvas + implements PaintListener, ControlListener +{ + // --- members --- + + /** double-buffering image */ + protected Image m_doubleBuffer = null; + + /** buffer GC */ + protected GC m_doubleBufferGC = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public BufferedCanvas(Composite parent) { + super(parent, + SWT.NO_BACKGROUND | // don't automatically clear background on paint event + SWT.NO_REDRAW_RESIZE // don't automatically repaint on resize event + ); + initBufferedCanvas(); + } + + /** Dispose method. */ + public void dispose() { + super.dispose(); + cleanupBufferedCanvas(); + } + + // --- init methods --- + + /** Initializes control. */ + protected void initBufferedCanvas() { + addControlListener(this); + addPaintListener(this); + } + + /** Cleans up control. */ + protected void cleanupBufferedCanvas() { + removePaintListener(this); + removeControlListener(this); + if (m_doubleBuffer != null) { + m_doubleBuffer.dispose(); + m_doubleBuffer = null; + } + } + + + // --- event handlers --- + + /** Invoked when control is moved/resized */ + public void controlMoved(ControlEvent e) { + // do nothing, we don't care + } + + /** Invoked when control is resized */ + public void controlResized(ControlEvent e) { + resized(getBounds()); + } + + + // --- resize methods --- + + /** Invoked when control is resized. + * Default implementation does nothing, + * intended to be overridden by derived types. + */ + public void resized(Rectangle bounds) { + + } + + + // --- GC management --- + + /** Gets/creates GC for current background buffer. + * NOTE: The GC is disposed whenever the canvas size changes, + * so caller should not retain a reference to this GC. + */ + protected synchronized GC getBufferedGC() { + if (m_doubleBufferGC == null) { + + m_doubleBufferGC = new GC(m_doubleBuffer); + } + return m_doubleBufferGC; + } + + /** Disposes of current background buffer GC. */ + protected synchronized void disposeBufferedGC() { + if (m_doubleBufferGC != null) { + m_doubleBufferGC.dispose(); + m_doubleBufferGC = null; + } + } + + + // --- paint methods --- + + /** Invoked when control needs to be repainted */ + public void paintControl(PaintEvent e) { + // Handle last paint event of a cluster. + if (e.count<=1) { + Display display = e.display; + GC gc = e.gc; + paintDoubleBuffered(display, gc); + } + } + + /** Internal -- handles double-buffering support, calls paintCanvas() */ + // NOTE: need display to create image buffer, not for painting code + protected void paintDoubleBuffered(Display display, GC gc) { + // get/create background image buffer + Rectangle clientArea = getClientArea(); + int width = clientArea.width; + int height = clientArea.height; + if (m_doubleBuffer == null + || m_doubleBuffer.getBounds().width < width + || m_doubleBuffer.getBounds().height < height) + { + m_doubleBuffer = new Image(display, width, height); + disposeBufferedGC(); + } + + // create graphics context for buffer + GC bgc = getBufferedGC(); + + // copy current GC properties into it as defaults + bgc.setBackground(gc.getBackground()); + bgc.setForeground(gc.getForeground()); + bgc.setFont(gc.getFont()); + bgc.setAlpha(255); + + // invoke paintCanvas() method to paint into the buffer + try { + paintCanvas(bgc); + } + catch (Throwable t) { + // Throwing an exception in painting code can hang Eclipse, + // so catch any exceptions here. + System.err.println("BufferedCanvas: Exception thrown in painting code: \n" + t); + } + + // then copy image buffer to actual canvas (reduces repaint flickering) + gc.drawImage(m_doubleBuffer, 0,0); + } + + /** Invoked when canvas repaint event is raised. + * Default implementation clears canvas to background color. + */ + public void paintCanvas(GC gc) { + clearCanvas(gc); + } + + /** Clears canvas to background color. */ + public void clearCanvas(GC gc) { + Rectangle bounds = getClientArea(); + gc.fillRectangle(bounds); + } + + + // --- update methods --- + + /** Redraws control */ + public void update() { + // guard against update events that happen + // after app has shut down + if (! isDisposed()) { + redraw(); + } + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicCanvas.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicCanvas.java new file mode 100755 index 00000000000..1fbf1a4c590 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicCanvas.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.canvas; + +import java.util.ArrayList; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Composite; + + +// --------------------------------------------------------------------------- +// GraphicCanvas +// --------------------------------------------------------------------------- + +/** + * Viewer canvas -- base class for canvas that displays a collection + * of persistent, repositionable graphic objects. + * + * Note: painting is done in order objects were added, + * so objects added last are drawn "on top" of others. + * Use raise/lower methods to change the object z-ordering, if needed. + */ +public class GraphicCanvas extends BufferedCanvas +{ + // --- members --- + + /** Viewer elements. */ + protected ArrayList m_objects = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public GraphicCanvas(Composite parent) { + super(parent); + m_objects = new ArrayList(); + } + + /** Dispose method. */ + public void dispose() { + if (m_objects != null) { + m_objects.clear(); + m_objects = null; + } + super.dispose(); + } + + + // --- object management methods --- + + /** Removes all elements */ + public void clear() { + m_objects.clear(); + } + + /** Adds an element */ + public IGraphicObject add(IGraphicObject element) { + if (! m_objects.contains(element)) { + m_objects.add(element); + } + return element; + } + + /** Removes an element */ + public void remove(IGraphicObject element) { + m_objects.remove(element); + } + + /** Raises an element to top of repaint z-ordering */ + public void raiseToFront(IGraphicObject element) { + if (m_objects.contains(element)) { + m_objects.remove(element); + m_objects.add(element); + } + } + + /** Lowers an element to bottom of repaint z-ordering */ + public void lowerToBack(IGraphicObject element) { + if (m_objects.contains(element)) { + m_objects.remove(element); + m_objects.add(0, element); + } + } + + + // --- painting methods --- + + /** Paints elements on canvas. */ + public void paintCanvas(GC gc) { + // paint background first + clearCanvas(gc); + + // we paint object list from start to end, + // so end of the list is "top" in z-ordering + + // allow objects to draw themselves + for (IGraphicObject gobj : m_objects) { + gobj.paint(gc, false); + } + + // allow objects to paint any "decorations" on top of other stuff + for (IGraphicObject gobj : m_objects) { + if (gobj.hasDecorations()) + gobj.paint(gc, true); + } + } + + + // --- point-to-object accessors --- + + /** Returns first graphic object found under specified point */ + public IGraphicObject getGraphicObject(int x, int y) { + return getGraphicObject(null, x, y); + } + + /** Returns first graphic object found under specified point. + * If type argument is non-null, returns first object assignable to specified type. + */ + public IGraphicObject getGraphicObject(Class type, int x, int y) { + IGraphicObject result = null; + + // note: have to search list in reverse order we draw it, + // so we hit items "on top" in the z-ordering first + int count = (m_objects == null) ? 0 : m_objects.size(); + for (int i=count-1; i>=0; i--) { + IGraphicObject gobj = m_objects.get(i); + if (gobj.contains(x, y)) { + if (type != null) { + Class objType = gobj.getClass(); + if (! type.isAssignableFrom(objType)) continue; + } + result = gobj; + break; + } + } + + return result; + } + + // --- model data accessors --- + + /** Returns graphic object (if any) that has specified data value. */ + public IGraphicObject getGraphicObjectFor(Object value) { + IGraphicObject result = null; + for (IGraphicObject gobj : m_objects) { + if (gobj.getData() == value) { + result = gobj; + break; + } + } + return result; + } + + /** Returns data value (if any) for the specified graphic element. */ + public Object getDataFor(IGraphicObject IGraphicObject) { + return (IGraphicObject == null) ? null : IGraphicObject.getData(); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicCanvasVisualizer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicCanvasVisualizer.java new file mode 100644 index 00000000000..5fcef0d92d8 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicCanvasVisualizer.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.canvas; + +import org.eclipse.cdt.visualizer.ui.Visualizer; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + + +// --------------------------------------------------------------------------- +// GraphicCanvasVisualizer +// --------------------------------------------------------------------------- + +/** + * Viewer canvas -- base class for canvas that displays a collection + * of persistent, repositionable graphic objects. + * + * Note: painting is done in order objects were added, + * so objects added last are drawn "on top" of others. + * Use raise/lower methods to change the object z-ordering, if needed. + */ +public class GraphicCanvasVisualizer extends Visualizer +{ + // --- members --- + + + // --- constructors/destructors --- + + /** Constructor. */ + public GraphicCanvasVisualizer() + { + // TODO: internationalize these strings. + super("canvas", "Canvas Visualizer", "Displays graphic representation of selection."); + } + + /** Dispose method. */ + public void dispose() { + super.dispose(); + } + + + // --- control management --- + + /** Creates and returns visualizer control on specified parent. */ + public Control createControl(Composite parent) + { + if (m_control == null) { + GraphicCanvas canvas = createCanvas(parent); + canvas.setMenu(parent.getMenu()); + setControl(canvas); + initializeCanvas(canvas); + } + return getControl(); + } + + /** Invoked when visualizer control should be disposed. */ + public void disposeControl() + { + if (m_control != null) { + disposeCanvas(); + m_control.dispose(); + setControl(null); + } + } + + + // --- canvas management --- + + /** Creates and returns visualizer canvas control. */ + public GraphicCanvas createCanvas(Composite parent) + { + return new GraphicCanvas(parent); + } + + /** Invoked when canvas control should be disposed. */ + public void disposeCanvas() + { + + } + + /** Invoked after visualizer control creation, + * to allow derived classes to do any initialization of canvas. + */ + protected void initializeCanvas(GraphicCanvas canvas) + { + } + + /** Gets downcast reference to canvas control. */ + public GraphicCanvas getCanvas() + { + return (GraphicCanvas) getControl(); + } + + + // --- menu/toolbar management --- + + /** Invoked when visualizer is selected, to populate the toolbar. */ + public void populateToolBar(IToolBarManager toolBarManager) + {} + + /** Invoked when visualizer is selected, to populate the toolbar's menu. */ + public void populateMenu(IMenuManager menuManager) + {} + + + // --- context menu handling --- + + /** Invoked when visualizer view's context menu is invoked, to populate it. */ + public void populateContextMenu(IMenuManager menuManager) + {} + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicObject.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicObject.java new file mode 100755 index 00000000000..e89ad65bd23 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/GraphicObject.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.canvas; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; + + +// --------------------------------------------------------------------------- +// GraphicObject +// --------------------------------------------------------------------------- + +/** + * Graphic object base class. + * Base class for objects that can be displayed and manipulated on a GraphicCanvas. + */ +public class GraphicObject + implements IGraphicObject +{ + // --- members --- + + /** Data object, if any, associated with this graphic object. */ + protected Object m_data = null; + + /** Bounding rectangle of this element. */ + protected Rectangle m_bounds = new Rectangle(0,0,0,0); + + /** Whether this element is visible. */ + protected boolean m_visible = true; + + /** Whether this element is selected. */ + protected boolean m_selected = false; + + /** Foreground color (null means inherit from canvas) */ + protected Color m_foreground = null; + + /** Background color (null means inherit from canvas) */ + protected Color m_background = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public GraphicObject() { + } + + /** Constructor. */ + public GraphicObject(int x, int y, int width, int height) { + m_bounds.x = x; + m_bounds.y = y; + m_bounds.width = width; + m_bounds.height = height; + } + + /** Constructor. */ + public GraphicObject(Rectangle bounds) { + m_bounds.x = bounds.x; + m_bounds.y = bounds.y; + m_bounds.width = bounds.width; + m_bounds.height = bounds.height; + } + + /** Constructor. */ + public GraphicObject(Object data) { + m_data = data; + } + + /** Constructor. */ + public GraphicObject(int x, int y, int width, int height, Object data) { + m_bounds.x = x; + m_bounds.y = y; + m_bounds.width = width; + m_bounds.height = height; + m_data = data; + } + + + /** Constructor. */ + public GraphicObject(Rectangle bounds, Object data) + { + m_bounds.x = bounds.x; + m_bounds.y = bounds.y; + m_bounds.width = bounds.width; + m_bounds.height = bounds.height; + m_data = data; + } + + /** Dispose method. */ + public void dispose() { + m_data = null; + } + + + // --- accessors --- + + /** Gets data object associated with this view element. */ + public Object getData() { + return m_data; + } + /** Sets data object associated with this view element. */ + public void setData(Object data) { + m_data = data; + } + + + /** Gets x location of this element */ + public int getX() { return m_bounds.x; } + /** Sets x location of this element */ + public void setX(int x) { + m_bounds.x = x; + } + + /** Gets y location of this element */ + public int getY() { return m_bounds.y; } + /** Sets y location of this element */ + public void setY(int y) { m_bounds.y = y; } + + /** Sets x/y position of this element */ + public void setPosition(int x, int y) { + m_bounds.x = x; m_bounds.y = y; + } + + + /** Gets width of this element */ + public int getWidth() { return m_bounds.width; } + /** Sets width of this element */ + public void setWidth(int w) { m_bounds.width = w; } + + /** Gets y location of this element */ + public int getHeight() { return m_bounds.height; } + /** Sets y location of this element */ + public void setHeight(int h) { m_bounds.height = h; } + + /** Sets width/height of this element */ + public void setSize(int w, int h) { + m_bounds.width = w; m_bounds.height = h; + } + + /** Gets bounding rectangle of this element. */ + public Rectangle getBounds() { + return m_bounds; + } + /** Sets bounding rectangle of this element. */ + public void setBounds(int x, int y, int w, int h) { + m_bounds.x = x; + m_bounds.y = y; + m_bounds.width = w; + m_bounds.height = h; + } + /** Sets bounding rectangle of this element. */ + public void setBounds(Rectangle bounds) { + m_bounds.x = bounds.x; + m_bounds.y = bounds.y; + m_bounds.width = bounds.width; + m_bounds.height = bounds.height; + } + + /** Returns true if element bounds contains point. */ + public boolean contains(int x, int y) { + return m_bounds.contains(x,y); + } + /** Returns true if element bounds are within specified rectangle. */ + public boolean isWithin(Rectangle region) { + return (region.x <= m_bounds.x && + region.y <= m_bounds.y && + region.x + region.width >= m_bounds.x + m_bounds.width && + region.y + region.height >= m_bounds.y + m_bounds.height); + } + + /** Gets whether this element is visible. */ + public boolean isVisible() { + return m_visible; + } + + /** Sets whether this element is visible. */ + public void setVisible(boolean visible) { + m_visible = visible; + } + + /** Gets whether this element is selected. */ + public boolean isSelected() { + return m_selected; + } + + /** Sets whether this element is selected. */ + public void setSelected(boolean selected) { + m_selected = selected; + } + + /** Sets foreground color (null means inherit from container) */ + public void setForeground(Color color) { + m_foreground = color; + } + /** Gets foreground color (null means inherit from container) */ + public Color getForeground() { + return m_foreground; + } + + /** Sets foreground color (null means inherit from container) */ + public void setBackground(Color color) { + m_background = color; + } + /** Gets background color (null means inherit from container) */ + public Color getBackground() { + return m_background; + } + + + // --- methods --- + + /** Invoked to allow element to paint itself on the viewer canvas */ + public void paint(GC gc, boolean decorations) { + if (isVisible()) { + // Set GC to reflect object properties, if set. + Color oldForeground = null; + Color oldBackground = null; + if (m_foreground != null) { + oldForeground = gc.getForeground(); + gc.setForeground(m_foreground); + } + if (m_background != null) { + oldBackground = gc.getBackground(); + gc.setBackground(m_background); + } + + // Paint the object. + if (! decorations) + paintContent(gc); + else + paintDecorations(gc); + + // Restore old state. + if (m_foreground != null) gc.setForeground(oldForeground); + if (m_background != null) gc.setBackground(oldBackground); + } + } + + /** + * Paints content of graphic object. + * GC has already been set to this object's + * current foreground/background colors. + * Default implementation draws object's bounding box. + */ + public void paintContent(GC gc) { + // Draw boundary rectangle of object. + gc.drawRectangle(m_bounds); + + // Display selection as thicker boundary. + if (isSelected()) { + int x = m_bounds.x + 1; + int y = m_bounds.y + 1; + int width = m_bounds.width - 2; if (width < 0) width = 0; + int height = m_bounds.height - 2; if (height < 0) height = 0; + gc.drawRectangle(x,y,width,height); + } + } + + /** Returns true if object has decorations to paint. */ + public boolean hasDecorations() { + return false; + } + + /** Invoked to allow element to paint decorations + * on top of other items drawn on top of it. + */ + public void paintDecorations(GC gc) { + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/IGraphicObject.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/IGraphicObject.java new file mode 100755 index 00000000000..dc9c5f18df5 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/IGraphicObject.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.canvas; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; + + +// --------------------------------------------------------------------------- +// IGraphicObject +// --------------------------------------------------------------------------- + +/** + * An object that can be displayed and manipulated on a GraphicCanvas. + */ +public interface IGraphicObject +{ + // --- methods --- + + /** Paints object using specified graphics context. + * If decorations is false, draws ordinary object content. + * If decorations is true, paints optional "decorations" layer. + */ + public void paint(GC gc, boolean decorations); + + /** Returns true if object has decorations to paint. */ + public boolean hasDecorations(); + + /** Gets model data (if any) associated with this graphic object */ + public Object getData(); + + /** Sets model data (if any) associated with this graphic object */ + public void setData(Object data); + + /** Whether graphic object contains the specified point. */ + public boolean contains(int x, int y); + + /** Returns true if element bounds are within specified rectangle. */ + public boolean isWithin(Rectangle region); +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/events/IVisualizerViewerListener.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/events/IVisualizerViewerListener.java new file mode 100644 index 00000000000..82e20d0c3c8 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/events/IVisualizerViewerListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.events; + +import org.eclipse.cdt.visualizer.ui.IVisualizerViewer; + + +// --------------------------------------------------------------------------- +// IVisualizerViewerListener +// --------------------------------------------------------------------------- + +/** + * IVisualizerViewer event listener. + */ +public interface IVisualizerViewerListener +{ + // --- methods --- + + /** Invoked when VisualizerViewer's selected IVisualizer changes. */ + public void visualizerEvent(IVisualizerViewer source, VisualizerViewerEvent event); + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/events/VisualizerViewerEvent.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/events/VisualizerViewerEvent.java new file mode 100644 index 00000000000..825d24d0305 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/events/VisualizerViewerEvent.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.events; + +import org.eclipse.cdt.visualizer.ui.IVisualizerViewer; +import org.eclipse.cdt.visualizer.ui.util.Event; + + +// --------------------------------------------------------------------------- +// VisualizerViewerEvent +// --------------------------------------------------------------------------- + +/** + * IVisualizerViewer event + */ +public class VisualizerViewerEvent extends Event +{ + // --- event types --- + + /** Event type constant */ + public static final int VISUALIZER_CHANGED = 1; + + /** Event type constant */ + public static final int VISUALIZER_CONTEXT_MENU = 2; + + + // --- members --- + + /** X coordinate, for menu events. */ + public int x; + + /** Y coordinate, for menu events. */ + public int y; + + + // --- constructors/destructors --- + + /** Constructor. */ + public VisualizerViewerEvent(IVisualizerViewer source, int eventType) { + super(source, eventType); + } + + /** Constructor. */ + public VisualizerViewerEvent(IVisualizerViewer source, int eventType, int x, int y) { + super(source, eventType); + this.x = x; + this.y = y; + } + + /** Dispose method. */ + public void dispose() { + super.dispose(); + } + + // --- Object methods --- + + /** Converts event type to string */ + public String typeToString(int type) { + String result = ""; + switch (type) { + case VISUALIZER_CHANGED: + result = "VISUALIZER_CHANGED"; break; + default: + result = super.typeToString(type); + break; + } + return result; + } + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/plugin/CDTVisualizerUIPlugin.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/plugin/CDTVisualizerUIPlugin.java new file mode 100755 index 00000000000..3d47d69ea1f --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/plugin/CDTVisualizerUIPlugin.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.plugin; + +import org.eclipse.cdt.visualizer.core.plugin.CDTVisualizerCorePlugin; +import org.eclipse.cdt.visualizer.ui.util.Colors; +import org.eclipse.cdt.visualizer.ui.util.UIResourceManager; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + + +// ---------------------------------------------------------------------------- +// CDTVisualizerUIPlugin +// ---------------------------------------------------------------------------- + +/** + * CDT visualizer UI plugin class. + * + * This plugin contains the UI components of the visualizer framework. + */ +public class CDTVisualizerUIPlugin extends AbstractUIPlugin +{ + // --- constants --- + + /** Feature ID (used as prefix for extension points, etc). */ + public static final String FEATURE_ID = "org.eclipse.cdt.visualizer.ui"; //$NON-NLS-1$ + + /** The plug-in ID */ + public static final String PLUGIN_ID = "org.eclipse.cdt.visualizer.ui"; //$NON-NLS-1$ + + + // --- static members --- + + /** Singleton instance */ + protected static CDTVisualizerUIPlugin s_plugin; + + /** Returns the singleton instance */ + public static CDTVisualizerUIPlugin getDefault() { + return s_plugin; + } + + /** Resource manager */ + protected static UIResourceManager s_resources = null; + + + // --- constructors/destructors --- + + /** + * Constructor + */ + public CDTVisualizerUIPlugin() { + } + + + // --- plugin startup/shutdown methods --- + + /** Invoked when plugin is loaded. */ + public void start(BundleContext context) throws Exception { + super.start(context); + s_plugin = this; + + // touch activator classes of any plugins we depend on, + // to ensure their start() methods are called first + // (None for now.) + + // initialize resource management (strings, images, fonts, colors, etc.) + getPluginResources(); + } + + /** Invoked when plugin is stopped. */ + public void stop(BundleContext context) throws Exception { + // clean up resource management + cleanupPluginResources(); + + s_plugin = null; + super.stop(context); + } + + + // --- logging --- + + /** + * Writes message to Eclipse log. + * Severity can be one of: + * Status.OK, Status.ERROR, Status.INFO, Status.WARNING, Status.CANCEL + */ + public static void log(int severity, String text) + { + Status status = new Status(severity, PLUGIN_ID, text); + ResourcesPlugin.getPlugin().getLog().log(status); + } + + + // --- resource management --- + + /** Returns resource manager for this plugin */ + public UIResourceManager getPluginResources() { + if (s_resources == null) { + s_resources = new UIResourceManager(this); + s_resources.setParentManager(CDTVisualizerCorePlugin.getResources()); + + // initialize Colors class, now that UIResources object is available. + Colors.initialize(s_resources); + } + + return s_resources; + } + + /** Releases resource manager for this plugin. */ + public void cleanupPluginResources() { + s_resources.dispose(); + } + + /** Convenience method for getting plugin resource manager */ + public static UIResourceManager getResources() { + return getDefault().getPluginResources(); + } + + /** Convenience method for looking up string resources */ + public static String getString(String key) { + return getDefault().getPluginResources().getString(key); + } + /** Convenience method for looking up string resources */ + public static String getString(String key, Object... arguments) { + return getDefault().getPluginResources().getString(key, arguments); + } + + /** Convenience method for looking up image resources */ + public static Image getImage(String key) { + return getDefault().getPluginResources().getImage(key); + } + /** Convenience method for looking up image resources */ + public static ImageDescriptor getImageDescriptor(String key) { + return getDefault().getPluginResources().getImageDescriptor(key); + } + + /** Convenience method for looking up font resources */ + public static Font getFont(String fontName, int height) { + return getDefault().getPluginResources().getFont(fontName, height); + } + /** Convenience method for looking up font resources */ + public static Font getFont(String fontName, int height, int style) { + return getDefault().getPluginResources().getFont(fontName, height, style); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/test/TestCanvas.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/test/TestCanvas.java new file mode 100755 index 00000000000..13ea52d2e7a --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/test/TestCanvas.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.test; + +import org.eclipse.cdt.visualizer.ui.canvas.GraphicCanvas; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Composite; + + +// --------------------------------------------------------------------------- +// TestCanvas +// --------------------------------------------------------------------------- + +/** + * Default canvas control, used by TestCanvasVisualizer. + */ +public class TestCanvas extends GraphicCanvas +{ + // --- members --- + + /** Text string to display. */ + String m_text = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public TestCanvas(Composite parent) { + super(parent); + initDefaultCanvas(parent); + } + + /** Dispose method. */ + public void dispose() { + cleanupDefaultCanvas(); + super.dispose(); + } + + + // --- init methods --- + + /** Initializes control */ + protected void initDefaultCanvas(Composite parent) { + // perform any initialization here + } + + /** Cleans up control */ + protected void cleanupDefaultCanvas() { + } + + + // --- accessors --- + + /** Sets text string to display. */ + public void setText(String text) + { + m_text = text; + } + + + // --- methods --- + + /** Invoked when canvas repaint event is raised. + * Default implementation clears canvas to background color. + */ + public void paintCanvas(GC gc) { + super.paintCanvas(gc); + + int margin = 10; + drawStringWrapNewlines(gc, m_text, margin, margin); + } + + + // --- utilities --- + + /** Gets line height of text, based on current font */ + public static int getTextHeight(GC gc) { + return gc.getFontMetrics().getHeight(); + } + + /** Draw string, wrapping if there are any newline chars. */ + public static void drawStringWrapNewlines(GC gc, String text, int x, int y) { + int lineHeight = getTextHeight(gc); + drawStringWrapNewlines(gc, text, x, y, lineHeight); + } + + /** Draw string, wrapping if there are any newline chars. */ + public static void drawStringWrapNewlines(GC gc, String text, int x, int y, int lineHeight) { + if (text != null) { + String[] lines = text.split("\n"); + for (int i=0; i m_listeners = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public ListenerList(Object owner, String label) { + m_owner = owner; + m_label = label; + } + + /** Dispose method. */ + public void dispose() { + m_owner = null; + m_label = null; + if (m_listeners != null) { + clear(); + m_listeners = null; + } + } + + + // --- methods --- + + /** Clears list of listeners */ + public synchronized void clear() { + if (m_listeners != null) { + m_listeners.clear(); + } + } + + /** Returns count of current listeners. */ + public synchronized int size() { + return (m_listeners == null) ? 0 : m_listeners.size(); + } + + /** Adds a listener */ + public synchronized void addListener(Object listener) { + if (m_listeners == null) { + m_listeners = new ArrayList(); + } + if (! m_listeners.contains(listener)) { + m_listeners.add(listener); + } + } + + /** Removes a listener */ + public synchronized void removeListener(Object listener) { + if (m_listeners != null) { + m_listeners.remove(listener); + } + } + + /** + * Dispatches event to all attached listeners + * Invokes raise(listener, event) for each attached listener. + */ + public void raise (final Object event) + { + // we can't use an iterator here, because + // the listener list might change while we're walking it, + // which would make the iterator throw a ConcurrentModificationException, + // hence we'll make a private copy of the listener list + ArrayList listeners = null; + synchronized (this) { + // keep the lock on the listener list as brief as possible + if (m_listeners != null) { + listeners = new ArrayList(m_listeners); + } + } + int count = (listeners == null) ? 0 : listeners.size(); + for (int i=0; i MOUSE_DRAG_HYSTERESIS) { + m_mouseDrag = true; + + // initialize mouse drag + drag(m_mouseDownButton, m_mouseDownPoint.x, m_mouseDownPoint.y, keys, MOUSE_DRAG_BEGIN); + } + } + if (m_mouseDrag) { + // update mouse drag + int dx = x - m_mouseDownPoint.x; + int dy = y - m_mouseDownPoint.y; + setDragPoint(x,y); + setDragRegionFromPoints(m_mouseDownPoint.x, m_mouseDownPoint.y, x, y); + drag(m_mouseDownButton, dx, dy, keys, MOUSE_DRAG); + } + } + mouseMove(x, y, keys); + } + + /** Invoked when mouse button is released */ + protected void mouseUpHandler(int button, int x, int y, int keys) { + if (m_mouseDown) { + if (m_mouseDrag) { + // finish mouse drag + int dx = x - m_mouseDownPoint.x; + int dy = y - m_mouseDownPoint.y; + setDragPoint(x,y); + setDragRegionFromPoints(m_mouseDownPoint.x, m_mouseDownPoint.y, x, y); + drag(m_mouseDownButton, dx, dy, keys, MOUSE_DRAG_END); + m_mouseDrag = false; + } + else { + if (button == RIGHT_BUTTON) { + contextMenu(x, y, keys); + } + else { + select(x, y, keys); + } + } + m_mouseDown = false; + } + mouseUp(button, x, y, keys); + } + + /** Invoked when mouse button is double-clicked */ + protected void mouseDoubleClickHandler(int button, int x, int y, int keys) { + mouseDoubleClick(button, x, y, keys); + } + + /** Invoked when mouse pointer enters control region */ + protected void mouseEnterHandler(int x, int y) { + if (! m_mouseDown) { + mouseEnter(x, y); + } + } + + /** Invoked when mouse pointer exits control region */ + protected void mouseExitHandler(int x, int y) { + if (! m_mouseDown) { + mouseExit(x, y); + } + } + + /** Invoked when mouse pointer hovers over control */ + protected void mouseHoverHandler(int x, int y) { + if (! m_mouseDown) { + mouseHover(x, y); + } + } + + + // --- event handlers --- + + // These are intended to be overridden by derived types. + // A user of this class need only override methods for events + // that need to be tracked. + + /** Invoked when mouse button is pressed */ + public void mouseDown(int button, int x, int y, int keys) {} + + /** Invoked when mouse is moved */ + public void mouseMove(int x, int y, int keys) {} + + /** Invoked when mouse button is released */ + public void mouseUp(int button, int x, int y, int keys) {} + + /** Invoked for a selection click at the specified point. */ + public void select(int x, int y, int keys) {} + + /** Invoked for a context menu click at the specified point. */ + public void contextMenu(int x, int y, int keys) {} + + /** Invoked when mouse button is double-clicked */ + public void mouseDoubleClick(int button, int x, int y, int keys) {} + + /** Invoked when mouse is dragged (moved with mouse button down). + * Drag state indicates stage of drag: + * - MOUSE_DRAG_BEGIN -- dx, dy offset from initial mouse down point (initial mouse down) + * - MOUSE_DRAG -- dx, dy of intermediate drag offset (initial mouse down, then each mouse move) + * - MOUSE_DRAG_END -- dx, dy of final drag offset (mouse up) + * The pattern of calls is always: BEGIN, DRAG(+), END. + */ + public void drag(int button, int x, int y, int keys, int dragState) {} + + /** Invoked when mouse pointer enters control region */ + public void mouseEnter(int x, int y) {} + + /** Invoked when mouse pointer exits control region */ + public void mouseExit(int x, int y) {} + + /** Invoked when mouse pointer hovers over control */ + public void mouseHover(int x, int y) {} + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/RunnableWithResult.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/RunnableWithResult.java new file mode 100644 index 00000000000..952d17730da --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/RunnableWithResult.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import java.util.concurrent.Callable; + + +/** + * Runnable object that returns a result object. + * + * This is like Future from the concurrent package, + * but with a few less bells and whistles. + * + * Intended to be used, for example, as follows: + * + * RunnableWithResult runnable = new RunnableWithResult() { + * public X call() { + * ... do work, return an X object ... + * } + * } + * + * Thread thread = new Thread(runnable); + * thread.start(); + * X result = runnable.getResult(0); + * + * or, to run it on the UI thread... + * + * GUIUtils.execAndWait(runnable); + * X result = runnable.getResult(0); + * + * Note: if you're invoking this from the UI thread, + * it's important to use execAndWait(), so that the runnable + * gets a turn on the event loop, otherwise you'll hang the UI! + * + */ +public class RunnableWithResult + implements Runnable, Callable +{ + // --- members --- + + /** Result to return */ + protected V m_result = null; + + /** Whether run() has completed */ + protected boolean m_done = false; + + + // --- constructors/destructors --- + + /** Constructor. */ + public RunnableWithResult() { + } + + /** Dispose method. */ + public void dispose() { + m_result = null; + } + + + // --- accessors --- + + /** Sets result value */ + public void setResult(V result) { + m_result = result; + } + + /** Gets result value. */ + public V getResult() { + return m_result; + } + + + // --- Runnable implementation --- + + /** Run method. + * Derived types should override call() rather than this method. + */ + public void run() { + m_done = false; + setResult(call()); + m_done = true; + synchronized (this) { + notifyAll(); + } + } + + + // --- Callable implementation --- + + /** Method that returns the value. + * Default implementation returns null. + */ + public V call() { + return null; + } + + + // --- methods --- + + /** Waits for result and returns it. */ + public V waitForResult() { + return waitForResult(0, null); + } + + /** Waits for result and returns it. */ + public V waitForResult(long timeout) { + return waitForResult(timeout, null); + } + + /** Waits for result and returns it. + * Returns null if specified timeout is exceeded. + */ + public V waitForResult(long timeout, V defaultValue) { + V result = defaultValue; + try { + if (timeout == 0) { + // wait forever + // (guard against spurious thread wakeup -- see wait() Javadoc) + while (! m_done) { + synchronized (this) { + this.wait(0); + } + } + } + else { + // wait until specified timeout + // (guard against spurious thread wakeup -- see wait() Javadoc) + long then = now(); + long waitstep = timeout / 10; + if (waitstep == 0) waitstep = 1; + do { + synchronized (this) { + this.wait(waitstep); + } + } + while (! m_done && ((now() - then) < timeout)); + } + } + catch (InterruptedException e) { + } + if (m_done) result = getResult(); + return result; + } + + /** Returns current time in milliseconds. */ + protected static long now() { + return System.currentTimeMillis(); + } +} + diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionManager.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionManager.java new file mode 100755 index 00000000000..0609d566243 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionManager.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; + + +// --------------------------------------------------------------------------- +// SelectionManager +// --------------------------------------------------------------------------- + +/** + * Selection management utility class + */ +public class SelectionManager + implements ISelectionProvider +{ + // --- members --- + + /** Actual source to report for selection change events. */ + protected ISelectionProvider m_source = null; + + /** Manager label, also used on listener list. */ + protected String m_label = null; + + /** Current selection, if any. */ + protected ISelection m_selection = SelectionUtils.EMPTY_SELECTION; + + /** Selection changed listeners */ + protected ListenerList m_selectionListeners = null; + + /** Whether selection events are enabled */ + protected boolean m_selectionEventsEnabled = true; + + // --- constructors/destructors --- + + /** Constructor. */ + public SelectionManager(ISelectionProvider source, String label) + { + m_source = (source == null) ? this : source; + m_label = label; + m_selectionListeners = new ListenerList(this, label + ", listener list") { + public void raise(Object listener, Object event) { + if (listener instanceof ISelectionChangedListener && + event instanceof SelectionChangedEvent) + { + ISelectionChangedListener typedListener = (ISelectionChangedListener) listener; + SelectionChangedEvent typedEvent = (SelectionChangedEvent) event; + typedListener.selectionChanged(typedEvent); + } + } + }; + } + + /** Dispose method. */ + public void dispose() + { + m_selectionEventsEnabled = false; + m_selection = SelectionUtils.EMPTY_SELECTION; + if (m_selectionListeners != null) { + m_selectionListeners.clear(); + m_selectionListeners = null; + } + // m_label = null; // leave label, to aid in debugging cleanup + m_source = null; + } + + // --- ISelectionProvider implementation --- + + /** Adds selection changed listener. */ + public void addSelectionChangedListener(ISelectionChangedListener listener) + { + if (listener == null) return; + m_selectionListeners.addListener(listener); + // fake a selection changed event so new listener can update itself properly + listener.selectionChanged(new SelectionChangedEvent(m_source, getSelection())); + } + + /** Removes selection changed listener. */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) + { + if (listener == null) return; + m_selectionListeners.removeListener(listener); + } + + /** Returns current selection. */ + public ISelection getSelection() + { + return m_selection; + } + + /** Sets selection, and raises change event. */ + public void setSelection(ISelection selection) + { + setSelection(selection, true); + } + + /** Sets selection, and raises change event with specified provider as the source. */ + public void setSelection(ISelectionProvider provider, ISelection selection) + { + setSelection(provider, selection, true); + } + + /** Sets selection, and raises change event + * if raiseEvent is true. */ + public void setSelection(ISelection selection, boolean raiseEvent) + { + if (selection == null) + selection = SelectionUtils.EMPTY_SELECTION; + m_selection = selection; + if (raiseEvent) raiseSelectionChangedEvent(); + } + + /** Sets selection, and raises change event with specified provider as the source + * if raiseEvent is true. */ + public void setSelection(ISelectionProvider provider, ISelection selection, boolean raiseEvent) + { + if (selection == null) + selection = SelectionUtils.EMPTY_SELECTION; + m_selection = selection; + if (raiseEvent) raiseSelectionChangedEvent(provider); + } + + /** Returns true if we currently have a non-emptr selection. */ + public boolean hasSelection() + { + return (SelectionUtils.getSelectionSize(m_selection) > 0); + } + + + // --- methods --- + + /** Gets whether selection events are enabled. */ + public boolean getSelectionEventsEnabled() { + return m_selectionEventsEnabled; + } + + /** Sets whether selection events are enabled. */ + public void setSelectionEventsEnabled(boolean enabled) { + m_selectionEventsEnabled = enabled; + } + + /** Raises selection changed event. */ + public void raiseSelectionChangedEvent() { + if (m_selectionEventsEnabled) + m_selectionListeners.raise(new SelectionChangedEvent(m_source, getSelection())); + } + + /** Raises selection changed event with specified provider as source. */ + public void raiseSelectionChangedEvent(ISelectionProvider provider) { + if (m_selectionEventsEnabled) + m_selectionListeners.raise(new SelectionChangedEvent(provider, getSelection())); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionProviderAdapter.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionProviderAdapter.java new file mode 100755 index 00000000000..522700edb60 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionProviderAdapter.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; + + +// --------------------------------------------------------------------------- +// SelectionProviderAdapter +// --------------------------------------------------------------------------- + +/** + * Wrapper for selection "providers" that don't happen to implement + * ISelectionProvider interface. + */ +public class SelectionProviderAdapter + implements ISelectionProvider +{ + // --- members --- + + /** Real source object. */ + protected Object m_source = null; + + /** Selection manager. */ + protected SelectionManager m_selectionManager = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public SelectionProviderAdapter(Object source) { + m_source = source; + m_selectionManager = new SelectionManager(this, "SelectionProviderAdapter for source " + m_source.toString()); + } + + /** Dispose method. */ + public void dispose() { + m_source = null; + if (m_selectionManager != null) { + m_selectionManager.dispose(); + m_selectionManager = null; + } + } + + + // --- accessors --- + + /** Gets wrapped selection source. */ + public Object getActualSource() { + return m_source; + } + + + // --- ISelectionProvider implementation --- + + /** Adds selection change listener. + * Default implementation does nothing. + */ + public void addSelectionChangedListener(ISelectionChangedListener listener) + { + m_selectionManager.addSelectionChangedListener(listener); + } + + /** Removes selection change listener. + * Default implementation does nothing. + */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) + { + m_selectionManager.removeSelectionChangedListener(listener); + } + + /** Gets selection. + * Default implementation does nothing. + */ + public ISelection getSelection() { + return m_selectionManager.getSelection(); + } + + /** Sets selection. + * Default implementation does nothing. + */ + public void setSelection(ISelection selection) + { + m_selectionManager.setSelection(selection); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionUtils.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionUtils.java new file mode 100644 index 00000000000..fd6f9a5b637 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/SelectionUtils.java @@ -0,0 +1,280 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + + +//---------------------------------------------------------------------------- +// SelectionUtils +//---------------------------------------------------------------------------- + +/** Eclipse ISelection munging utilities. */ +public class SelectionUtils +{ + // --- constants --- + + /** Special value for an "empty" selection, + * since selection cannot be null. + */ + public static final ISelection EMPTY_SELECTION = new EmptySelection(); + + /** "Empty" or undefined selection. */ + public static class EmptySelection + implements ISelection, IStructuredSelection + { + public boolean isEmpty() { + return true; + } + + public Iterator iterator() { + return new ArrayList().iterator(); + } + + public List toList() { + return new ArrayList(); + } + + public int size() { + return 0; + } + + public Object getFirstElement() { + return null; + } + + public Object[] toArray() { + return new Object[0]; + } + } + + + // --- selection utilities --- + + /** + * Returns workbench selection, if any. + */ + public static ISelection getWorkbenchSelection() { + ISelection result = null; + IWorkbenchPage page = getWorkbenchPage(); + if (page != null) { + result = page.getSelection(); + } + return result; + } + + /** Creates an ISelection from a collection of objects */ + public static ISelection toSelection(Collection objects) { + return (objects == null) ? null : new StructuredSelection(toList(objects)); + } + + /** Creates an ISelection from a list of objects */ + public static ISelection toSelection(List objects) { + return (objects == null) ? null : new StructuredSelection(objects); + } + + /** Creates an ISelection from the specified object(s) */ + public static ISelection toSelection(T... objects) { + return (objects == null) ? null : new StructuredSelection(objects); + } + + /** + * Gets number of top-level object(s) from an Eclipse ISelection. + */ + public static int getSelectionSize(ISelection selection) { + int result = 0; + if (selection == EMPTY_SELECTION) { + // nothing to do + } + else if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + result = structuredSelection.size(); + } + else if (selection instanceof ISelection) { + result = ((ISelection) selection).isEmpty() ? 0 : 1; + } + // collections are not ISelections, this just makes the method a little more generic + else if (selection instanceof Collection) { + Collection collection = (Collection) selection; + result = collection.size(); + } + else if (selection != null) { + result = 1; + } + return result; + } + + /** + * Gets selected object(s) from an Eclipse ISelection as a List. + * If selection is a multiple selection (an IStructuredSelection or Collection), + * the list contains the top-level elements of the selection. + * Otherwise the list contains the ISelection itself. + */ + public static List getSelectedObjects(ISelection selection) { + List result = null; + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + result = new ArrayList((List) structuredSelection.toList()); + } + else if (selection instanceof Collection) { + Collection collection = (Collection) selection; + result = new ArrayList(collection); + } + else { + List list = new ArrayList(); + list.add(selection); + result = list; + } + return result; + } + + /** + * Gets single selected object from an Eclipse ISelection. + * If selection is a single selection, returns it. + * If selection is multiple selection, returns first selected item. + */ + public static Object getSelectedObject(ISelection selection) { + Object result = null; + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + result = structuredSelection.getFirstElement(); + } + else if (selection instanceof Collection) { + Collection collection = (Collection) selection; + Iterator i = collection.iterator(); + if (i.hasNext()) result = i.next(); + } + else { + result = selection; + } + return result; + } + + /** + * Creates Eclipse ISelection from a list. + */ + public static ISelection toISelection(List items) { + return new StructuredSelection(items); + } + + /** + * Creates Eclipse ISelection from one or more items or an array of items. + */ + public static ISelection toISelection(T... items) { + return new StructuredSelection(items); + } + + /** + * Gets iterator for an ISelection. + * Note: returns null if ISelection is not an IStructuredSelection, + * which is the only interface that currently defines an Iterator. + */ + public static Iterator getSelectionIterator(ISelection iselection) { + Iterator result = null; + if (iselection instanceof IStructuredSelection) { + result = ((IStructuredSelection) iselection).iterator(); + } + return result; + } + + + // --- debugging tools --- + + /** Converts selection to string, for debug display. */ + public static String toString(ISelection selection) { + String result = null; + // convert selection to text string + if (selection == null) { + result = "No selection"; + } + else if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + List elements = structuredSelection.toList(); + int size = elements.size(); + if (size == 0) { + result = "Empty selection"; + } + else { + result = "Selection: "; + for (int i=0; i0) result += "\n"; + Object o = elements.get(i); + String type = o.getClass().getName(); + String value = o.toString(); + result += "[" + i + "]: type= + " + type + ", value='" + value + "'"; + } + } + } + else { + String type = selection.getClass().getName(); + String value = selection.toString(); + result = "Selection: (type = " + type + ") " + value; + } + return result; + } + + // --- utilities --- + + /** Creates list from array/set of elements */ + public static List toList(Collection collection) { + int size = (collection == null) ? 0 : collection.size(); + List result = new ArrayList(size); + if (collection != null) result.addAll(collection); + return result; + } + + /** Gets current Eclipse workbench */ + public static IWorkbench getWorkbench() { + IWorkbench result = null; + try { + result = PlatformUI.getWorkbench(); + } + catch (IllegalStateException e) { + // Workbench is not defined for some reason. Oh well. + } + return result; + } + + /** Gets current Eclipse workbench window. + * Returns null if workbench does not exist. + */ + public static IWorkbenchWindow getWorkbenchWindow() { + IWorkbenchWindow result = null; + IWorkbench workbench = getWorkbench(); + if (workbench != null) { + result = workbench.getActiveWorkbenchWindow(); + if (result == null) { + if (workbench.getWorkbenchWindowCount() > 0) { + result = (IWorkbenchWindow) workbench.getWorkbenchWindows()[0]; + } + } + } + return result; + } + + /** Gets current Eclipse workbench page */ + public static IWorkbenchPage getWorkbenchPage() { + IWorkbenchWindow window = getWorkbenchWindow(); + return (window == null) ? null : window.getActivePage(); + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/Timer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/Timer.java new file mode 100755 index 00000000000..28b31bd3267 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/Timer.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + + +// --------------------------------------------------------------------------- +// Timer +// --------------------------------------------------------------------------- + +/** + * Periodic event timer class. + */ +public class Timer + implements ActionListener, Runnable +{ + // --- members --- + + /** Actual timer */ + // NOTE: we delegate rather than subclassing, because + // Timer class implements ISerializable, so every derived type + // must either declare a serialization ID, or suppress the warning. + protected javax.swing.Timer m_timer = null; + + + // --- constructors/destructors --- + + /** Constructor. */ + public Timer(int intervalMilliseconds) { + m_timer = new javax.swing.Timer(intervalMilliseconds, null); + m_timer.addActionListener(this); + m_timer.setRepeats(true); + m_timer.setCoalesce(true); + m_timer.start(); + } + + /** Dispose method. */ + public void dispose() { + if (m_timer != null) { + if (m_timer.isRunning()) { + m_timer.stop(); + } + m_timer = null; + } + } + + + // --- methods --- + + /** Gets whether timer repeatedly fires events. */ + public boolean isRepeating() { + return m_timer.isRepeats(); + } + + /** Sets whether timer repeatedly fires events. */ + public void setRepeating(boolean repeats) { + m_timer.setRepeats(repeats); + } + + /** Starts/restarts timer. + * Has no effect if timer is already running + */ + public void start() { + if (! m_timer.isRunning()) m_timer.start(); + } + + /** Stops timer. + * Has no effect if timer is already stopped. + */ + public void stop() { + if (m_timer.isRunning()) m_timer.stop(); + } + + + // --- ActionListener implementation --- + + /** + * Invoked each time the timer fires. + * Default implementation invokes the run() method on the UI thread. + */ + public void actionPerformed(ActionEvent e) { + GUIUtils.exec(this); + } + + /** Invoked each time the timer fires. */ + public void run() { + } + +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/Todo.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/Todo.java new file mode 100644 index 00000000000..3dfdec2d8a9 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/Todo.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +/** Counter for objects that need to track asynchronous progress. */ +public class Todo { + + // --- members --- + + /** Count of things left to do. */ + int m_count = 0; + + + // --- constructors/destructors --- + + /** Constructor. */ + public Todo() { + } + + /** Constructor. */ + public Todo(int count) { + m_count = count; + } + + /** Dispose method. */ + public void dispose() { + m_count = 0; + } + + + // --- accessors --- + + /** Gets count. */ + public int get() { + return m_count; + } + + /** Sets count. */ + public void set(int count) { + m_count = count; + } + + /** Returns true if count has reached zero. */ + public boolean isDone() { + return m_count <= 0; + } + + /** Increments count, returns new value. */ + public int increment(int n) { + return (m_count += n); + } + + /** Increments count, returns new value. */ + public int increment() { + return (m_count += 1); + } + + /** Decrements count, returns new value. */ + public int decrement(int n) { + return (m_count -= n); + } + + /** Decrements count, returns new value. */ + public int decrement() { + return (m_count -= 1); + } + + + // --- methods --- + + /** Adds completion steps to count. */ + public void add(int n) { + increment(n); + } + + /** Adds completion step to count. */ + public void add() { + increment(1); + } + + /** Decrements count, returns true when it's reached zero. */ + public boolean done(int n) { + return decrement(n) <= 0; + } + + /** Decrements count, returns true when it's reached zero. */ + public boolean done() { + return decrement() <= 0; + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/UIResourceManager.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/UIResourceManager.java new file mode 100755 index 00000000000..353481b2d7b --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/UIResourceManager.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import java.net.URL; + +import org.eclipse.cdt.visualizer.core.ResourceManager; +import org.eclipse.jface.resource.ColorRegistry; +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.plugin.AbstractUIPlugin; + + +// --------------------------------------------------------------------------- +// UIResourceManager +// --------------------------------------------------------------------------- + +/** + * Plugin resource manager. + * Provides one-stop-shopping for UI plugin resources + * (strings, images, fonts, colors). + * This class should be instanced in the UI plugin's "start()" method, + * and disposed in the "stop()" method. + */ +public class UIResourceManager extends ResourceManager +{ + // --- members --- + + /** UI Plugin */ + protected AbstractUIPlugin m_UIplugin = null; + + /** Parent resource manager, if any */ + protected UIResourceManager m_parentUIManager = null; + + /** Image resource manager */ + protected ImageRegistry m_images = null; + + /** Font resource manager */ + protected FontRegistry m_fonts = null; + + /** Color resource manager */ + protected ColorRegistry m_colors = null; + + + // --- constructors/destructors --- + + /** Constructor + * Note: the plugin ID is assumed to also be the parent package name + * of the plugin, for example "com.tilera.ide.core"; it's assumed that string + * resources are found in the plugin directory in "messages.properties". + */ + public UIResourceManager(AbstractUIPlugin plugin) { + super(plugin); + m_UIplugin = plugin; + getImageRegistry(); // creates registry object + getFontRegistry(); // creates registry object + getColorRegistry(); // creates registry object + } + + /** Dispose method */ + public void dispose() { + disposeImageRegistry(); + disposeFontRegistry(); + disposeColorRegistry(); + } + + + // --- parent manager management --- + + /** Sets parent resource manager, if any */ + public void setParentManager(ResourceManager parentManager) { + super.setParentManager(parentManager); + if (parentManager instanceof UIResourceManager) { + m_parentUIManager = (UIResourceManager) parentManager; + } + else { + m_parentUIManager = null; + } + } + + /** Gets parent UI resource manager, if any */ + public UIResourceManager getParentManager() { + return m_parentUIManager; + } + + + // --- image resource management --- + + /** Creates/returns image registry */ + protected ImageRegistry getImageRegistry() { + if (m_images == null) { + // use the plugin's image registry + m_images = m_UIplugin.getImageRegistry(); + } + return m_images; + } + + /** Disposes image registry */ + protected void disposeImageRegistry() { + if (m_images != null) { + // we're using the plugin's image registry, so it will dispose of it + //m_images.dispose(); + m_images = null; + } + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + */ + public ImageDescriptor getImageDescriptor(String path) { + ImageDescriptor result = null; + if (path == null) return result; + + // get image registry, look up path + ImageRegistry images = getImageRegistry(); + result = images.getDescriptor(path); + + // if we don't find it, see if it exists as a file in this plugin + if (result == null) { + URL url = m_UIplugin.getBundle().getEntry(path); + if (url != null) { + // if so, we'll add an entry for it to this resource manager + ImageDescriptor desc = ImageDescriptor.createFromURL(url); + images.put(path, desc); + result = images.getDescriptor(path); + } + else { + // if not, see if we can find it in the parent manager + // NOTE: this may be in a different plugin, so the path will be + // resolved relative to that plugin's base directory + UIResourceManager parent = getParentManager(); + if (parent != null) { + result = parent.getImageDescriptor(path); + } + } + } + return result; + } + + /** + * Gets specified image from plugin directory. + * Caches images so subsequent requests will be faster. + */ + public Image getImage(String path) { + Image result = null; + if (path == null) return result; + + // get image registry, look up path + ImageRegistry images = getImageRegistry(); + result = images.get(path); + + // if we don't find it, see if it exists as a file in this plugin + if (result == null) { + URL url = m_UIplugin.getBundle().getEntry(path); + if (url != null) { + // if so, we'll add an entry for it to this resource manager + ImageDescriptor desc = ImageDescriptor.createFromURL(url); + images.put(path, desc); + result = images.get(path); + } + else { + // if not, see if we can find it in the parent manager + // NOTE: this may be in a different plugin, so the path will be + // resolved relative to that plugin's base directory + UIResourceManager parent = getParentManager(); + if (parent != null) { + result = parent.getImage(path); + } + } + } + return result; + } + + + // --- font registry --- + + /** Creates/returns font registry */ + protected FontRegistry getFontRegistry() { + if (m_fonts == null) { + Display display = getDisplay(); + m_fonts = new FontRegistry(display); + } + return m_fonts; + } + + /** Disposes font registry */ + protected void disposeFontRegistry() { + if (m_fonts != null) { + // doesn't appear to be a way to flush the registry cache + // so let finalizer handle it + m_fonts = null; + } + } + + /** Sets cached font for specified ID */ + public void setFont(String fontID, String fontName, int height, int style) { + setCachedFont(fontID, fontName, height, style); + } + + /** Gets cached font for specified ID */ + public Font getFont(String fontID) { + return getCachedFont(fontID); + } + + /** Gets/creates font with specified properties */ + public Font getFont(String fontName, int height) { + return getCachedFont(fontName, height, SWT.NORMAL); + } + + /** Gets/creates font with specified properties */ + public Font getFont(String fontName, int height, int style) { + return getCachedFont(fontName, height, style); + } + + /** Sets cached font for specified ID */ + protected void setCachedFont(String fontID, String fontName, int height, int style) { + FontData[] fontData = new FontData[1]; + fontData[0] = new FontData(fontName, height, style); + FontRegistry fonts = getFontRegistry(); + fonts.put(fontID, fontData); + } + + /** Gets cached font, if any, for specified ID */ + protected Font getCachedFont(String fontID) { + Font result = null; + + // get font registry, look up font ID + FontRegistry fonts = getFontRegistry(); + if (fonts.hasValueFor(fontID)) { + result = fonts.get(fontID); + } + else { + // if we don't find it, see if parent manager has it + UIResourceManager parent = getParentManager(); + if (parent != null) { + result = parent.getCachedFont(fontID); + } + } + return result; + } + + /** Gets/creates font with specified properties */ + protected Font getCachedFont(String fontName, int height, int style) { + Font result = null; + String fontID = fontName + "," + height + "," + style; + + // look for the cached font (this checks the parent manager too) + result = getCachedFont(fontID); + + // if we didn't find it, add an entry to this resource manager + if (result == null) { + setCachedFont(fontID, fontName, height, style); + result = getCachedFont(fontID); + } + return result; + } + + + // --- color registry --- + + /** Creates/returns color registry */ + protected ColorRegistry getColorRegistry() { + if (m_colors == null) { + Display display = getDisplay(); + m_colors = new ColorRegistry(display); + } + return m_colors; + } + + /** Disposes color registry */ + protected void disposeColorRegistry() { + if (m_colors != null) { + // doesn't appear to be a way to flush the registry cache + // so let finalizer handle it + m_colors = null; + } + } + + /** Gets cached color with specified SWT color ID */ + public Color getColor(int colorID) { + // NOTE: we don't cache these colors, we just look them up every time + return getDisplay().getSystemColor(colorID); + } + + /** Gets cached color with specified ID */ + public Color getColor(String colorID) { + return getCachedColor(colorID); + } + + /** Gets/creates color with specified properties */ + public Color getColor(int red, int green, int blue) { + return getCachedColor(red, green, blue); + } + + /** Sets cached color for specified ID */ + protected void setCachedColor(String colorID, int red, int green, int blue) { + RGB rgb = new RGB(red, green, blue); + ColorRegistry colors = getColorRegistry(); + colors.put(colorID, rgb); + } + + /** Gets cached color with specified ID */ + protected Color getCachedColor(String colorID) { + Color result = null; + ColorRegistry colors = getColorRegistry(); + if (colors.hasValueFor(colorID)) { + result = colors.get(colorID); + } + else { + // if we don't find it, see if parent manager has it + UIResourceManager parent = getParentManager(); + if (parent != null) { + result = parent.getCachedColor(colorID); + } + } + return result; + } + + /** Gets/creates color with specified properties */ + protected Color getCachedColor(int red, int green, int blue) { + Color result = null; + String colorID = "Color[R=" + red + ",G=" + green + ",B=" + blue + "]"; + + // look for the cached color (this checks the parent manager too) + result = getCachedColor(colorID); + + // if we don't find it, create an entry in this resource manager + if (result == null) { + setCachedColor(colorID, red, green, blue); + result = getCachedColor(colorID); + } + return result; + } + + + // --- utilities --- + + /** + * Returns the current SWT display. + * + * The method first checks whether the caller already has + * an associated display. If so, this display is returned. + * Otherwise the method returns the default display. + * + * This allows GUIUtils to work in contexts like tests + * where the SWT display has not already been defined. + * + * (Credit: Borrowed from DebugUIPlugin.) + */ + public static Display getDisplay() { + Display display= Display.getCurrent(); + if (display == null) { + display= Display.getDefault(); + } + return display; + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/WorkbenchSelectionAdapter.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/WorkbenchSelectionAdapter.java new file mode 100755 index 00000000000..0c268491f51 --- /dev/null +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/util/WorkbenchSelectionAdapter.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2012 Tilera Corporation 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: + * William R. Swanson (Tilera Corporation) + *******************************************************************************/ + +package org.eclipse.cdt.visualizer.ui.util; + +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPart; + + +// --------------------------------------------------------------------------- +// WorkbenchSelectionAdapter +// --------------------------------------------------------------------------- + +/** + * Selection change event manager + */ +public class WorkbenchSelectionAdapter + implements ISelectionListener, ISelectionProvider +{ + // --- members --- + + /** Workbench part (view) this adapter is associated with. */ + protected IViewPart m_view = null; + + /** Current selection */ + protected ISelection m_selection = null; + + /** Listeners for selection changed events. */ + protected ListenerList m_selectionListeners = null; + + /** Whether selection events are reported */ + protected boolean m_trackSelection = true; + + + // --- constructors/destructors --- + + /** Constructor. */ + public WorkbenchSelectionAdapter(IViewPart view) { + m_view = view; + m_selection = null; + m_selectionListeners = new ListenerList(view, "WorkbenchSelectionAdapter for view " + view.getClass().getSimpleName()) + { + /** Dispatches event to listeners */ + public void raise(Object listener, Object event) { + if (listener instanceof ISelectionChangedListener && + event instanceof SelectionChangedEvent) + { + ISelectionChangedListener typedListener = (ISelectionChangedListener) listener; + SelectionChangedEvent typedEvent = (SelectionChangedEvent) event; + typedListener.selectionChanged(typedEvent); + } + } + }; + + // listen for external selection changed events + m_view.getSite().getPage().addSelectionListener(this); + + // set selection provider for this view + m_view.getSite().setSelectionProvider(this); + + // initialize selection + setSelection(m_view.getSite().getPage().getSelection()); + + } + + /** Dispose method. */ + public void dispose() { + if (m_view != null) { + m_view.getSite().getPage().removeSelectionListener(this); + m_view.getViewSite().setSelectionProvider(null); + m_view = null; + } + m_selection = null; + if (m_selectionListeners != null) { + m_selectionListeners.clear(); + m_selectionListeners = null; + } + } + + + // --- accessors --- + + /** Gets whether selection change events are reported. */ + public boolean getTrackSelection() { + return m_trackSelection; + } + + /** Sets whether selection change events are reported. */ + public void setTrackSelection(boolean trackSelection) { + m_trackSelection = trackSelection; + } + + + // --- ISelectionListener implementation --- + + /** Invoked when selection changes externally. */ + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + // ignore selection change events that came from us + if (part == m_view) return; + if (m_trackSelection) { + workbenchSelectionChanged(part, selection); + } + } + + /** Invoked when selection changes. + * Intended to be overloaded by derived implementations. + */ + public void workbenchSelectionChanged(ISelection selection) { + setSelection(selection); + } + + /** Invoked when selection changes. + * Intended to be overloaded by derived implementations. + */ + public void workbenchSelectionChanged(ISelectionProvider provider, ISelection selection) { + setSelection(provider, selection); + } + + /** Invoked when selection changes. + * Intended to be overloaded by derived implementations. + */ + public void workbenchSelectionChanged(Object provider, ISelection selection) { + setSelection(provider, selection); + } + + + // --- ISelectionProvider implementation --- + + /** Gets current selection. */ + public ISelection getSelection() { + return m_selection; + } + + /** Sets current selection, and raises selection changed event. */ + public void setSelection(ISelection selection) { + // for some reason, SelectionChangedEvent can't stand a null selection + if (selection == null) selection = StructuredSelection.EMPTY; + m_selection = selection; + m_selectionListeners.raise(new SelectionChangedEvent(this, m_selection)); + } + + /** Sets current selection, and raises selection changed event. */ + public void setSelection(ISelectionProvider source, ISelection selection) { + // for some reason, SelectionChangedEvent can't stand a null selection + if (selection == null) selection = StructuredSelection.EMPTY; + m_selection = selection; + m_selectionListeners.raise(new SelectionChangedEvent(source, m_selection)); + } + + /** Sets current selection, and raises selection changed event. */ + public void setSelection(Object source, ISelection selection) { + // for some reason, SelectionChangedEvent can't stand a null selection + if (selection == null) selection = StructuredSelection.EMPTY; + m_selection = selection; + m_selectionListeners.raise(new SelectionChangedEvent(new SelectionProviderAdapter(source), m_selection)); + } + + /** Adds external listener for selection change events. */ + public void addSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionListeners.addListener(listener); + } + + /** Removes external listener for selection change events. */ + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + m_selectionListeners.removeListener(listener); + } + + + // --- utilities --- + + /** Converts selection to string, for debug display. */ + protected String selectionToString(ISelection selection) { + String result = null; + // convert selection to text string + if (m_selection == null) { + result = "No Selection"; + } + else if (m_selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) m_selection; + List elements = structuredSelection.toList(); + int size = elements.size(); + if (size == 0) { + result = "Empty Selection"; + } + else { + result = ""; + for (int i=0; i0) result += "\n"; + Object o = elements.get(i); + String type = o.getClass().getName(); + String value = o.toString(); + result += "[" + i + "]: type= + " + type + ", value='" + value + "'"; + } + } + } + else { + String type = m_selection.getClass().getName(); + String value = m_selection.toString(); + result = "type=" + type + ", value='" + value + "'"; + } + return result; + } +}