diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html b/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html
index 484f746526..2d53e46cfd 100644
--- a/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/help/help/topics/TraceRmiLauncherServicePlugin/TraceRmiLauncherServicePlugin.html
@@ -90,6 +90,21 @@
selected, then this selects nothing, so that pressing the keystroke twice is effectively
"Select None."
+ Increase Font Size
+
+ This is accessed using the local drop-down menu or the key sequence CTRL-SHIFT-PLUS.
+ It increases the font size for this terminal.
+
+ Decrease Font Size
+
+ This is accessed using the local drop-down menu or the key sequence CTRL-MINUS. It
+ decreases the font size for this terminal.
+
+ Reset Font Size
+
+ This is accessed using the local drop-down menu or the key sequence CTRL-0. It resets
+ the font size for this terminal according to the theme's configuration'.
+
Terminate
This action is accessed using the local drop-down menu. It will terminate the Terminal's
@@ -873,41 +888,45 @@ bdcedit /dbgsettings NET HOSTIP:IP PORT:54321 KEY:1.1.1.1
- Type: The type of kernel connection, either "Remote", "Local", or "EXDI".
- "Remote", the most common type, indicates two-machine debugging over various
- possible connection media, e.g. Ethernet, serial, USB, etc. "Local" is used for limited
- introspection into the target on which the debugger is running. "EXDI" is arguably
- the most exotic type - it essentially simulates the normal "Remote" connection using
- the gdb Remote Serial Protocol. It can be used when connecting to gdbstubs in
- platforms, such as QEMU, VMWare, Trace32, etc.
+ "Remote", the most common type, indicates two-machine debugging over various possible
+ connection media, e.g. Ethernet, serial, USB, etc. "Local" is used for limited introspection
+ into the target on which the debugger is running. "EXDI" is arguably the most exotic type -
+ it essentially simulates the normal "Remote" connection using the gdb Remote Serial Protocol.
+ It can be used when connecting to gdbstubs in platforms, such as QEMU, VMWare, Trace32,
+ etc.
- EXDI
-
- Setup for EXDI connections is fairly complicated and difficult to get correct.
- The argument string typically should be something like:
-
- The CLSID here should match the CLSID in the exdiConfigData.xml file in the debugger architectural directory. If windbg has been
- run using EXDI at some point, there will also be an entry in the System Registry for this CLSID. The InprocServer32 subentry
- for this CLSID in the Registry should point to a copy of ExdiGdbSrv.dll, typically the one in the same directory. This DLL
- must reside somewhere that the debugger has permission to load from, i.e. not in the WindowsApps directory tree.
- The exdiConfigData file should be configured for the target you're using. We heavily recommend using displayCommPackets==yes,
- as many of the tasks take considerable time, and this is the only indicator of progress.
-
+ EXDI
- The Kd=Guess parameter causes the underlying engine to scan memory for the kernel's base address, which will probably not
- be provided by the gdbstub. (Kd=NtBaseAddr is also a valid option, as is eliminating the parameter, but, currently, we have no
- idea how to point the configuration at a correct value. Using this option will cause the load to spin pointlessly.) If you can,
- we highly recommend breaking the target near the base address, as the search proceeds down through memory starting at the current
- program counter. If the difference between the PC and the base address is large, the loading process will punt before useful
- values are detected. If anyone understand how to extend this search (or knows how to set the base address to sidestep the scan),
- we would really love some guidance.
-
+ Setup for EXDI connections is fairly complicated and difficult to get correct. The argument
+ string typically should be something like:
+
+
+
+ The CLSID here should match the CLSID in the exdiConfigData.xml file in the debugger
+ architectural directory. If windbg has been run using EXDI at some point, there will also be an
+ entry in the System Registry for this CLSID. The InprocServer32 subentry for this CLSID in the
+ Registry should point to a copy of ExdiGdbSrv.dll, typically the one in the same directory.
+ This DLL must reside somewhere that the debugger has permission to load from, i.e. not in the
+ WindowsApps directory tree. The exdiConfigData file should be configured for the target
+ you're using. We heavily recommend using displayCommPackets==yes, as many of the tasks
+ take considerable time, and this is the only indicator of progress.
+
+ The Kd=Guess parameter causes the underlying engine to scan memory for the kernel's
+ base address, which will probably not be provided by the gdbstub. (Kd=NtBaseAddr is also
+ a valid option, as is eliminating the parameter, but, currently, we have no idea how to point
+ the configuration at a correct value. Using this option will cause the load to spin
+ pointlessly.) If you can, we highly recommend breaking the target near the base address, as the
+ search proceeds down through memory starting at the current program counter. If the difference
+ between the PC and the base address is large, the loading process will punt before useful
+ values are detected. If anyone understand how to extend this search (or knows how to set the
+ base address to sidestep the scan), we would really love some guidance.
TTD (Time-Travel Debugging)
diff --git a/Ghidra/Features/Base/data/base.theme.properties b/Ghidra/Features/Base/data/base.theme.properties
index 05254d0baf..7742023e5b 100644
--- a/Ghidra/Features/Base/data/base.theme.properties
+++ b/Ghidra/Features/Base/data/base.theme.properties
@@ -127,6 +127,15 @@ color.fg.plugin.terminal.bright.blue = rgb(88,51,255)
color.fg.plugin.terminal.bright.magenta = rgb(249,53,248)
color.fg.plugin.terminal.bright.cyan = rgb(20,240,240)
color.fg.plugin.terminal.bright.white = rgb(233,235,235)
+// Just the normals, since normal is bold and dim is plain weight
+color.fg.plugin.terminal.dim.black = rgb(0,0,0)
+color.fg.plugin.terminal.dim.red = rgb(194,54,33)
+color.fg.plugin.terminal.dim.green = rgb(37,188,36)
+color.fg.plugin.terminal.dim.yellow = rgb(173,173,39)
+color.fg.plugin.terminal.dim.blue = rgb(73,46,255)
+color.fg.plugin.terminal.dim.magenta = rgb(211,56,211)
+color.fg.plugin.terminal.dim.cyan = rgb(51,187,200)
+color.fg.plugin.terminal.dim.white = rgb(203,204,205)
color.bg.plugin.locationreferences.highlight = color.palette.lightcornflowerblue
@@ -183,7 +192,15 @@ font.plugin.tabs = sansserif-plain-11
font.plugin.tabs.list = sansserif-bold-9
font.plugin.tips = dialog-plain-12
font.plugin.tips.label = font.plugin.tips[bold]
-font.plugin.terminal = font.monospaced
+font.plugin.terminal = font.monospaced[bold]
+font.plugin.terminal.italic = font.plugin.terminal[italic]
+font.plugin.terminal.fraktur = font.plugin.terminal
+font.plugin.terminal.bright = font.plugin.terminal[bold]
+font.plugin.terminal.bright.italic = font.plugin.terminal.bright[italic]
+font.plugin.terminal.bright.fraktur = font.plugin.terminal.bright
+font.plugin.terminal.dim = font.plugin.terminal[plain]
+font.plugin.terminal.dim.italic = font.plugin.terminal.dim[italic]
+font.plugin.terminal.dim.fraktur = font.plugin.terminal.dim
font.plugin.terminal.completion.list = dialog-plain-12
font.plugin.window.location = font.monospaced[40]
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayout.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayout.java
index 7807cfcf16..cfe79a266a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayout.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayout.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,8 +35,9 @@ public class TerminalLayout extends SingleRowLayout {
protected final VtLine line;
protected final TerminalTextField field;
- public TerminalLayout(VtLine line, FontMetrics metrics, AnsiColorResolver colors) {
- super(TerminalTextField.create(line, metrics, colors));
+ public TerminalLayout(VtLine line, FontMetrics metrics, float fontSizeAdjustment,
+ AnsiColorResolver colors) {
+ super(TerminalTextField.create(line, metrics, fontSizeAdjustment, colors));
this.line = line;
this.field = (TerminalTextField) getField(0);
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayoutModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayoutModel.java
index e2da7b9a06..60f076dcc3 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayoutModel.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalLayoutModel.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,6 +30,7 @@ import docking.widgets.fieldpanel.listener.LayoutModelListener;
import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.FieldRange;
import ghidra.app.plugin.core.terminal.vt.*;
+import ghidra.app.plugin.core.terminal.vt.AnsiColorResolver.ReverseVideo;
import ghidra.app.plugin.core.terminal.vt.VtCharset.G;
import ghidra.util.*;
@@ -65,6 +66,7 @@ public class TerminalLayoutModel implements LayoutModel, VtHandler {
// Rendering properties
protected FontMetrics metrics;
+ protected float fontSizeAdjustment;
protected final AnsiColorResolver colors;
protected final ArrayList listeners = new ArrayList<>();
@@ -103,6 +105,7 @@ public class TerminalLayoutModel implements LayoutModel, VtHandler {
* @param panel the panel to receive commands from the model's VT/ANSI parser
* @param charset the charset for decoding bytes to characters
* @param metrics font metrics for the monospaced terminal font
+ * @param fontSizeAdjustment the font size adjustment
* @param colors a resolver for ANSI colors
*/
public TerminalLayoutModel(TerminalPanel panel, Charset charset, FontMetrics metrics,
@@ -202,7 +205,7 @@ public class TerminalLayoutModel implements LayoutModel, VtHandler {
}
protected TerminalLayout newLayout(VtLine line) {
- return new TerminalLayout(line, metrics, colors);
+ return new TerminalLayout(line, metrics, fontSizeAdjustment, colors);
}
protected void buildLayouts() {
@@ -371,7 +374,7 @@ public class TerminalLayoutModel implements LayoutModel, VtHandler {
}
@Override
- public void handleReverseVideo(boolean reverse) {
+ public void handleReverseVideo(ReverseVideo reverse) {
buffer.setAttributes(buffer.getAttributes().reverseVideo(reverse));
}
@@ -412,7 +415,7 @@ public class TerminalLayoutModel implements LayoutModel, VtHandler {
@Override
public void handleAutoWrapMode(boolean en) {
- System.err.println("TODO: handleAutoWrapMode: " + en);
+ Msg.trace(this, "TODO: handleAutoWrapMode: " + en);
}
@Override
@@ -641,7 +644,9 @@ public class TerminalLayoutModel implements LayoutModel, VtHandler {
}
}
- public void setFontMetrics(FontMetrics metrics2) {
+ public void setFontMetrics(FontMetrics metrics, float fontSizeAdjustment) {
+ this.metrics = metrics;
+ this.fontSizeAdjustment = fontSizeAdjustment;
layouts.clear();
layoutCache.clear();
buildLayouts();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPanel.java
index 1cdfee0c9a..9c591b8c76 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPanel.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPanel.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -33,8 +33,7 @@ import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.listener.*;
import docking.widgets.fieldpanel.support.*;
import docking.widgets.indexedscrollpane.IndexedScrollPane;
-import generic.theme.GColor;
-import generic.theme.Gui;
+import generic.theme.*;
import ghidra.app.plugin.core.terminal.TerminalFinder.RegexTerminalFinder;
import ghidra.app.plugin.core.terminal.TerminalFinder.TextTerminalFinder;
import ghidra.app.plugin.core.terminal.vt.*;
@@ -56,10 +55,30 @@ import ghidra.util.Msg;
* most sense to declare the various {@link GColor}s here.
*/
public class TerminalPanel extends JPanel implements FieldLocationListener, FieldSelectionListener,
- LayoutListener, AnsiColorResolver {
+ LayoutListener, AnsiColorResolver, ThemeListener {
protected static final int MAX_TITLE_STACK_SIZE = 20;
protected static final String DEFAULT_FONT_ID = "font.plugin.terminal";
+ protected static final String DEFAULT_FRAKTUR_FONT_ID = "font.plugin.terminal.fraktur";
+ protected static final String DEFAULT_ITALIC_FONT_ID = "font.plugin.terminal.italic";
+ protected static final String DIM_FONT_ID = "font.plugin.terminal.dim";
+ protected static final String DIM_FRAKTUR_FONT_ID = "font.plugin.terminal.dim.fraktur";
+ protected static final String DIM_ITALIC_FONT_ID = "font.plugin.terminal.dim.italic";
+ protected static final String BRIGHT_FONT_ID = "font.plugin.terminal.bright";
+ protected static final String BRIGHT_FRAKTUR_FONT_ID = "font.plugin.terminal.bright.fraktur";
+ protected static final String BRIGHT_ITALIC_FONT_ID = "font.plugin.terminal.bright.italic";
+
+ protected static final Set ALL_FONT_IDS = Set.of(
+ DEFAULT_FONT_ID,
+ DEFAULT_FRAKTUR_FONT_ID,
+ DEFAULT_ITALIC_FONT_ID,
+ DIM_FONT_ID,
+ DIM_FRAKTUR_FONT_ID,
+ DIM_ITALIC_FONT_ID,
+ BRIGHT_FONT_ID,
+ BRIGHT_FRAKTUR_FONT_ID,
+ BRIGHT_ITALIC_FONT_ID);
+
protected static final GColor COLOR_BACKGROUND = new GColor("color.bg.plugin.terminal");
protected static final GColor COLOR_FOREGROUND = new GColor("color.fg.plugin.terminal");
protected static final GColor COLOR_CURSOR_FOCUSED =
@@ -84,6 +103,7 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
new GColor("color.fg.plugin.terminal.normal.cyan");
protected static final GColor COLOR_7_WHITE =
new GColor("color.fg.plugin.terminal.normal.white");
+
protected static final GColor COLOR_0_BRIGHT_BLACK =
new GColor("color.fg.plugin.terminal.bright.black");
protected static final GColor COLOR_1_BRIGHT_RED =
@@ -101,6 +121,23 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
protected static final GColor COLOR_7_BRIGHT_WHITE =
new GColor("color.fg.plugin.terminal.bright.white");
+ protected static final GColor COLOR_0_DIM_BLACK =
+ new GColor("color.fg.plugin.terminal.dim.black");
+ protected static final GColor COLOR_1_DIM_RED =
+ new GColor("color.fg.plugin.terminal.dim.red");
+ protected static final GColor COLOR_2_DIM_GREEN =
+ new GColor("color.fg.plugin.terminal.dim.green");
+ protected static final GColor COLOR_3_DIM_YELLOW =
+ new GColor("color.fg.plugin.terminal.dim.yellow");
+ protected static final GColor COLOR_4_DIM_BLUE =
+ new GColor("color.fg.plugin.terminal.dim.blue");
+ protected static final GColor COLOR_5_DIM_MAGENTA =
+ new GColor("color.fg.plugin.terminal.dim.magenta");
+ protected static final GColor COLOR_6_DIM_CYAN =
+ new GColor("color.fg.plugin.terminal.dim.cyan");
+ protected static final GColor COLOR_7_DIM_WHITE =
+ new GColor("color.fg.plugin.terminal.dim.white");
+
protected static final int[] CUBE_STEPS = {
0, 95, 135, 175, 215, 255
};
@@ -129,6 +166,7 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
}
}
+ protected float fontSizeAdjustment = 0;
protected FontMetrics metrics;
protected final TerminalLayoutModel model;
protected final TerminalFieldPanel fieldPanel;
@@ -153,6 +191,7 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
this.provider = provider;
clipboardProvider = new TerminalClipboardProvider(provider);
Gui.registerFont(this, DEFAULT_FONT_ID);
+ Gui.addThemeListener(this);
this.metrics = getFontMetrics(getFont());
this.model = new TerminalLayoutModel(this, charset, metrics, this);
this.fieldPanel = new TerminalFieldPanel(model);
@@ -346,13 +385,57 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
}
}
+ @Override
+ public void themeChanged(ThemeEvent event) {
+ if (event.isLookAndFeelChanged()) {
+ setFont(Gui.getFont(DEFAULT_FONT_ID));
+ }
+ if (event.isFontChanged(DEFAULT_FONT_ID)) {
+ setFont(Gui.getFont(DEFAULT_FONT_ID));
+ }
+ else if (ALL_FONT_IDS.stream().anyMatch(event::isFontChanged)) {
+ if (model != null) {
+ model.modelChanged();
+ }
+ }
+ }
+
+ protected void updateFontMetrics() {
+ Font font = getFont();
+ float size = font.getSize2D();
+ fontSizeAdjustment = Math.max(-size + 1, fontSizeAdjustment);
+ font = font.deriveFont(size + fontSizeAdjustment);
+ metrics = getFontMetrics(font);
+ if (model != null) {
+ model.setFontMetrics(metrics, fontSizeAdjustment);
+ }
+ if (!fixedSize) {
+ resizeTerminalToWindow();
+ }
+ if (model != null) {
+ model.modelChanged();
+ }
+ }
+
@Override
public void setFont(Font font) {
super.setFont(font);
- this.metrics = getFontMetrics(font);
- if (model != null) {
- model.setFontMetrics(this.metrics);
- }
+ updateFontMetrics();
+ }
+
+ protected void increaseFontSize() {
+ fontSizeAdjustment++;
+ updateFontMetrics();
+ }
+
+ protected void decreaseFontSize() {
+ fontSizeAdjustment--;
+ updateFontMetrics();
+ }
+
+ protected void resetFontSize() {
+ fontSizeAdjustment = 0;
+ updateFontMetrics();
}
public TerminalFieldPanel getFieldPanel() {
@@ -424,29 +507,42 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
model.processInput(buffer);
}
- protected Color resolveDefaultColor(WhichGround ground, boolean reverseVideo) {
- if (ground == WhichGround.BACKGROUND) {
- if (reverseVideo) {
- return COLOR_FOREGROUND;
- }
- return null; // background is already drawn
+ protected Color resolveDefaultColor(WhichGround ground, ReverseVideo reverse,
+ Intensity intensity) {
+ Color color = switch (reverse) {
+ case NORMAL -> switch (ground) {
+ case FOREGROUND -> COLOR_FOREGROUND;
+ case BACKGROUND -> null; // background is already drawn
+ };
+ case REVERSED -> switch (ground) {
+ case FOREGROUND -> COLOR_BACKGROUND;
+ case BACKGROUND -> COLOR_FOREGROUND;
+ };
+ };
+ if (color == null) {
+ return null;
}
- if (reverseVideo) {
- return COLOR_BACKGROUND;
- }
- return COLOR_FOREGROUND;
+ return switch (intensity) {
+ case NORMAL -> color;
+ case BOLD -> color.brighter();
+ case DIM -> color.darker();
+ };
}
- protected Color resolveStandardColor(AnsiStandardColor standard) {
- return switch (standard) {
- case BLACK -> COLOR_0_BLACK;
- case RED -> COLOR_1_RED;
- case GREEN -> COLOR_2_GREEN;
- case YELLOW -> COLOR_3_YELLOW;
- case BLUE -> COLOR_4_BLUE;
- case MAGENTA -> COLOR_5_MAGENTA;
- case CYAN -> COLOR_6_CYAN;
- case WHITE -> COLOR_7_WHITE;
+ protected Color resolveStandardColor(AnsiStandardColor standard, Intensity intensity) {
+ return switch (intensity) {
+ case BOLD -> resolveIntenseColor(standard.intense);
+ case DIM -> resolveDimColor(standard.dim);
+ case NORMAL -> switch (standard) {
+ case BLACK -> COLOR_0_BLACK;
+ case RED -> COLOR_1_RED;
+ case GREEN -> COLOR_2_GREEN;
+ case YELLOW -> COLOR_3_YELLOW;
+ case BLUE -> COLOR_4_BLUE;
+ case MAGENTA -> COLOR_5_MAGENTA;
+ case CYAN -> COLOR_6_CYAN;
+ case WHITE -> COLOR_7_WHITE;
+ };
};
}
@@ -463,6 +559,19 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
};
}
+ protected Color resolveDimColor(AnsiDimColor intense) {
+ return switch (intense) {
+ case BLACK -> COLOR_0_DIM_BLACK;
+ case RED -> COLOR_1_DIM_RED;
+ case GREEN -> COLOR_2_DIM_GREEN;
+ case YELLOW -> COLOR_3_DIM_YELLOW;
+ case BLUE -> COLOR_4_DIM_BLUE;
+ case MAGENTA -> COLOR_5_DIM_MAGENTA;
+ case CYAN -> COLOR_6_DIM_CYAN;
+ case WHITE -> COLOR_7_DIM_WHITE;
+ };
+ }
+
protected Color resolve216Color(Ansi216Color cube) {
return ColorUtils.getColor(CUBE_STEPS[cube.r()], CUBE_STEPS[cube.g()],
CUBE_STEPS[cube.b()]);
@@ -478,12 +587,12 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
@Override
public Color resolveColor(AnsiColor color, WhichGround ground, Intensity intensity,
- boolean reverseVideo) {
+ ReverseVideo reverse) {
if (color == AnsiDefaultColor.INSTANCE) {
- return resolveDefaultColor(ground, reverseVideo);
+ return resolveDefaultColor(ground, reverse, intensity);
}
if (color instanceof AnsiStandardColor standard) {
- return resolveStandardColor(standard);
+ return resolveStandardColor(standard, intensity);
}
if (color instanceof AnsiIntenseColor intense) {
return resolveIntenseColor(intense);
@@ -560,6 +669,8 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
}
public void dispose() {
+ Gui.unRegisterFont(this, DEFAULT_FONT_ID);
+ Gui.removeThemeListener(this);
if (this.clipboardService != null) {
clipboardService.deRegisterClipboardContentProvider(clipboardProvider);
}
@@ -663,6 +774,10 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
}
protected void resizeTerminalToWindow() {
+ if (scroller == null) {
+ // Some callback during construction
+ return;
+ }
Rectangle bounds = scroller.getViewportBorderBounds();
int cols = bounds.width / metrics.charWidth('M');
int rows = bounds.height / metrics.getHeight();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java
index 0e6539f8bf..824816bdd8 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -167,6 +167,9 @@ public class TerminalProvider extends ComponentProviderAdapter {
protected DockingAction actionFindPrevious;
protected DockingAction actionSelectAll;
protected DockingAction actionTerminate;
+ protected DockingAction actionIncreaseSize;
+ protected DockingAction actionDecreaseSize;
+ protected DockingAction actionResetSize;
private boolean terminated = false;
@@ -262,6 +265,28 @@ public class TerminalProvider extends ComponentProviderAdapter {
.helpLocation(new HelpLocation(helpPlugin.getName(), "select_all"))
.onAction(this::activatedSelectAll)
.buildAndInstallLocal(this);
+ actionIncreaseSize = new ActionBuilder("Increase Font Size", plugin.getName())
+ .menuPath("Increase Font Size")
+ .menuGroup("View")
+ .keyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS,
+ InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK))
+ .helpLocation(new HelpLocation(helpPlugin.getName(), "increase_font_size"))
+ .onAction(this::activatedIncreaseFontSize)
+ .buildAndInstallLocal(this);
+ actionDecreaseSize = new ActionBuilder("Decrease Font Size", plugin.getName())
+ .menuPath("Decrease Font Size")
+ .menuGroup("View")
+ .keyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK))
+ .helpLocation(new HelpLocation(helpPlugin.getName(), "decrease_font_size"))
+ .onAction(this::activatedDecreaseFontSize)
+ .buildAndInstallLocal(this);
+ actionResetSize = new ActionBuilder("Reset Font Size", plugin.getName())
+ .menuPath("Reset Font Size")
+ .menuGroup("View")
+ .keyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_0, InputEvent.CTRL_DOWN_MASK))
+ .helpLocation(new HelpLocation(helpPlugin.getName(), "decrease_font_size"))
+ .onAction(this::activatedResetFontSize)
+ .buildAndInstallLocal(this);
}
protected void activatedFind(ActionContext ctx) {
@@ -329,6 +354,18 @@ public class TerminalProvider extends ComponentProviderAdapter {
panel.getFieldPanel().setSelection(sel, EventTrigger.GUI_ACTION);
}
+ protected void activatedIncreaseFontSize(ActionContext ctx) {
+ panel.increaseFontSize();
+ }
+
+ protected void activatedDecreaseFontSize(ActionContext ctx) {
+ panel.decreaseFontSize();
+ }
+
+ protected void activatedResetFontSize(ActionContext ctx) {
+ panel.resetFontSize();
+ }
+
/**
* Check if the given keystroke would activate a local action.
*
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextField.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextField.java
index 47e80a4c96..300e399a5c 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextField.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextField.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -51,13 +51,14 @@ public class TerminalTextField implements TextField {
*
* @param line the line from the {@link VtBuffer} that will be rendered in this field
* @param metrics the font metrics
+ * @param fontSizeAdjustment the font size adjustment
* @param colors the color resolver
* @return the field
*/
public static TerminalTextField create(VtLine line, FontMetrics metrics,
- AnsiColorResolver colors) {
- return new TerminalTextField(0, new TerminalTextFieldElement(line, metrics, colors),
- metrics);
+ float fontSizeAdjustment, AnsiColorResolver colors) {
+ return new TerminalTextField(0,
+ new TerminalTextFieldElement(line, metrics, fontSizeAdjustment, colors), metrics);
}
protected TerminalTextField(int startX, TerminalTextFieldElement element, FontMetrics metrics) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextFieldElement.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextFieldElement.java
index 81dada432d..adcf731613 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextFieldElement.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalTextFieldElement.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,8 +22,8 @@ import javax.swing.JComponent;
import docking.widgets.fieldpanel.field.FieldElement;
import docking.widgets.fieldpanel.support.RowColLocation;
+import generic.theme.Gui;
import ghidra.app.plugin.core.terminal.vt.*;
-import ghidra.app.plugin.core.terminal.vt.VtHandler.Intensity;
/**
* A text field element for rendering a full line of terminal text
@@ -41,6 +41,7 @@ public class TerminalTextFieldElement implements FieldElement {
protected final VtLine line;
protected final FontMetrics metrics;
+ protected final float fontSizeAdjustment;
protected final AnsiColorResolver colors;
protected final int em;
@@ -50,11 +51,14 @@ public class TerminalTextFieldElement implements FieldElement {
*
* @param line the line of text from the {@link VtBuffer}
* @param metrics the font metrics
+ * @param fontSizeAdjustment the font size adjustment
* @param colors the color resolver
*/
- public TerminalTextFieldElement(VtLine line, FontMetrics metrics, AnsiColorResolver colors) {
+ public TerminalTextFieldElement(VtLine line, FontMetrics metrics, float fontSizeAdjustment,
+ AnsiColorResolver colors) {
this.line = line;
this.metrics = metrics;
+ this.fontSizeAdjustment = fontSizeAdjustment;
this.colors = colors;
this.em = metrics.charWidth('M');
@@ -163,22 +167,34 @@ public class TerminalTextFieldElement implements FieldElement {
int height = metrics.getHeight();
int left = x + start * em;
int width = em * (end - start);
- Font font = metrics.getFont();
Color bg = attrs.resolveBackground(colors);
if (bg != null) {
g.setColor(bg);
g.fillRect(left, descent - height, width, height);
}
g.setColor(attrs.resolveForeground(colors));
- // NB. I don't really intend to implement blinking.
- // TODO: AnsiFont mapping?
- if (attrs.intensity() == Intensity.DIM) {
- g.setFont(font.deriveFont(Font.PLAIN));
- }
- else {
- // Normal will use bold font, but standard color
- g.setFont(font.deriveFont(Font.BOLD));
- }
+ // I don't really intend to implement blinking.
+ // We still use metrics from DEFAULT_FONT_ID
+ Font font = Gui.getFont(switch (attrs.intensity()) {
+ case NORMAL -> switch (attrs.font()) {
+ case NORMAL -> TerminalPanel.DEFAULT_FONT_ID;
+ case ITALIC -> TerminalPanel.DEFAULT_ITALIC_FONT_ID;
+ case BLACK_LETTER -> TerminalPanel.DEFAULT_FRAKTUR_FONT_ID;
+ };
+ case BOLD -> switch (attrs.font()) {
+ case NORMAL -> TerminalPanel.BRIGHT_FONT_ID;
+ case ITALIC -> TerminalPanel.BRIGHT_ITALIC_FONT_ID;
+ case BLACK_LETTER -> TerminalPanel.BRIGHT_FRAKTUR_FONT_ID;
+ };
+ case DIM -> switch (attrs.font()) {
+ case NORMAL -> TerminalPanel.DIM_FONT_ID;
+ case ITALIC -> TerminalPanel.DIM_ITALIC_FONT_ID;
+ case BLACK_LETTER -> TerminalPanel.DIM_FRAKTUR_FONT_ID;
+ };
+ });
+ font = font.deriveFont(font.getSize2D() + fontSizeAdjustment);
+ g.setFont(font);
+
if (!attrs.hidden()) {
switch (attrs.underline()) {
case DOUBLE:
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/AnsiColorResolver.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/AnsiColorResolver.java
index e0c667ff6f..0cfecd7dba 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/AnsiColorResolver.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/AnsiColorResolver.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,6 +32,35 @@ public interface AnsiColorResolver {
FOREGROUND, BACKGROUND;
}
+ enum ReverseVideo {
+ NORMAL {
+ @Override
+ AnsiColor fg(AnsiColor fg, AnsiColor bg) {
+ return fg;
+ }
+
+ @Override
+ AnsiColor bg(AnsiColor fg, AnsiColor bg) {
+ return bg;
+ }
+ },
+ REVERSED {
+ @Override
+ AnsiColor fg(AnsiColor fg, AnsiColor bg) {
+ return bg;
+ }
+
+ @Override
+ AnsiColor bg(AnsiColor fg, AnsiColor bg) {
+ return fg;
+ }
+ };
+
+ abstract AnsiColor fg(AnsiColor fg, AnsiColor bg);
+
+ abstract AnsiColor bg(AnsiColor fg, AnsiColor bg);
+ }
+
/**
* Convert a color specification to an AWT color
*
@@ -39,11 +68,11 @@ public interface AnsiColorResolver {
* @param ground identifies the colors use in the foreground or the background
* @param intensity gives the intensity of the color, really only used when a basic color is
* specified.
- * @param reverseVideo identifies whether the foreground and background colors were swapped,
- * really only used when the default color is specified.
+ * @param reverse identifies whether the foreground and background colors were swapped, really
+ * only used when the default color is specified.
* @return the AWT color, or null to not draw (usually in the case of the default background
* color)
*/
Color resolveColor(AnsiColor color, WhichGround ground, Intensity intensity,
- boolean reverseVideo);
+ ReverseVideo reverse);
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtAttributes.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtAttributes.java
index 784ad8c197..8a04ad4b25 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtAttributes.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtAttributes.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,6 +17,7 @@ package ghidra.app.plugin.core.terminal.vt;
import java.awt.Color;
+import ghidra.app.plugin.core.terminal.vt.AnsiColorResolver.ReverseVideo;
import ghidra.app.plugin.core.terminal.vt.AnsiColorResolver.WhichGround;
import ghidra.app.plugin.core.terminal.vt.VtHandler.*;
@@ -30,7 +31,7 @@ import ghidra.app.plugin.core.terminal.vt.VtHandler.*;
* in the buffer.
*/
public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
- AnsiFont font, Underline underline, Blink blink, boolean reverseVideo, boolean hidden,
+ AnsiFont font, Underline underline, Blink blink, ReverseVideo reverse, boolean hidden,
boolean strikeThrough, boolean proportionalSpacing) {
/**
@@ -38,8 +39,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
*/
public static final VtAttributes DEFAULTS =
new VtAttributes(AnsiDefaultColor.INSTANCE, AnsiDefaultColor.INSTANCE,
- Intensity.NORMAL, AnsiFont.NORMAL, Underline.NONE, Blink.NONE, false, false, false,
- false);
+ Intensity.NORMAL, AnsiFont.NORMAL, Underline.NONE, Blink.NONE, ReverseVideo.NORMAL,
+ false, false, false);
/**
* Create a copy of this record with the foreground color replaced
@@ -48,8 +49,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes fg(AnsiColor fg) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -59,8 +60,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes bg(AnsiColor bg) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -70,8 +71,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes intensity(Intensity intensity) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -81,8 +82,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes font(AnsiFont font) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -92,8 +93,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes underline(Underline underline) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -103,19 +104,19 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes blink(Blink blink) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
* Create a copy of this record with the reverse-video replaced
*
- * @param reverseVideo the new reverse-video
+ * @param reverse the new reverse-video
* @return the new record
*/
- public VtAttributes reverseVideo(boolean reverseVideo) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ public VtAttributes reverseVideo(ReverseVideo reverse) {
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -125,8 +126,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes hidden(boolean hidden) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -136,8 +137,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes strikeThrough(boolean strikeThrough) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -147,8 +148,8 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the new record
*/
public VtAttributes proportionalSpacing(boolean proportionalSpacing) {
- return new VtAttributes(fg, bg, intensity, font, underline, blink, reverseVideo,
- hidden, strikeThrough, proportionalSpacing);
+ return new VtAttributes(fg, bg, intensity, font, underline, blink, reverse, hidden,
+ strikeThrough, proportionalSpacing);
}
/**
@@ -158,8 +159,7 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the color
*/
public Color resolveForeground(AnsiColorResolver colors) {
- return colors.resolveColor(reverseVideo ? bg : fg, WhichGround.FOREGROUND, intensity,
- reverseVideo);
+ return colors.resolveColor(reverse.fg(fg, bg), WhichGround.FOREGROUND, intensity, reverse);
}
/**
@@ -169,7 +169,7 @@ public record VtAttributes(AnsiColor fg, AnsiColor bg, Intensity intensity,
* @return the color, or null to not paint the background
*/
public Color resolveBackground(AnsiColorResolver colors) {
- return colors.resolveColor(reverseVideo ? fg : bg, WhichGround.BACKGROUND, Intensity.NORMAL,
- reverseVideo);
+ return colors.resolveColor(reverse.bg(fg, bg), WhichGround.BACKGROUND, Intensity.NORMAL,
+ reverse);
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtHandler.java
index f370d4a3a2..570a486c13 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtHandler.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/vt/VtHandler.java
@@ -23,6 +23,7 @@ import java.util.PrimitiveIterator.OfInt;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import ghidra.app.plugin.core.terminal.vt.AnsiColorResolver.ReverseVideo;
import ghidra.util.Msg;
/**
@@ -171,43 +172,51 @@ public interface VtHandler {
* Usually the darkest black available. Implementations may select a color softer on the
* eyes, depending on use. For foreground, this should likely be true black (0,0,0).
*/
- BLACK,
+ BLACK(AnsiIntenseColor.BLACK, AnsiDimColor.BLACK),
/**
* A color whose hue is clearly red.
*/
- RED,
+ RED(AnsiIntenseColor.RED, AnsiDimColor.RED),
/**
* A color whose hue is clearly green.
*/
- GREEN,
+ GREEN(AnsiIntenseColor.GREEN, AnsiDimColor.GREEN),
/**
* A color whose hue is clearly yellow.
*/
- YELLOW,
+ YELLOW(AnsiIntenseColor.YELLOW, AnsiDimColor.YELLOW),
/**
* A color whose hue is clearly blue. For palettes made to display on a dark (but not black)
* background, a hue tinted toward cyan is recommended.
*/
- BLUE,
+ BLUE(AnsiIntenseColor.BLUE, AnsiDimColor.BLUE),
/**
* A color whose hue is clearly magenta or purple. For palettes made to display on a dark
* (but not black) background, a hue tinted toward red is recommended.
*/
- MAGENTA,
+ MAGENTA(AnsiIntenseColor.MAGENTA, AnsiDimColor.MAGENTA),
/**
* A color whose hue is clearly cyan.
*/
- CYAN,
+ CYAN(AnsiIntenseColor.CYAN, AnsiDimColor.CYAN),
/**
* A relatively bright white, sparing the brightest for intense white.
*/
- WHITE;
+ WHITE(AnsiIntenseColor.WHITE, AnsiDimColor.WHITE);
/**
* An unmodifiable list giving all the standard colors
*/
public static final List ALL = List.of(AnsiStandardColor.values());
+ public final AnsiIntenseColor intense;
+ public final AnsiDimColor dim;
+
+ private AnsiStandardColor(AnsiIntenseColor intense, AnsiDimColor dim) {
+ this.intense = intense;
+ this.dim = dim;
+ }
+
/**
* Get the standard color for the given numerical code
*
@@ -282,14 +291,69 @@ public interface VtHandler {
}
}
+ /**
+ * One of the eight ANSI dim colors
+ */
+ public enum AnsiDimColor implements AnsiColor {
+ /**
+ * A relatively dark grey, but not true black.
+ */
+ BLACK,
+ /**
+ * See {@link AnsiStandardColor#RED}, but darker.
+ */
+ RED,
+ /**
+ * See {@link AnsiStandardColor#GREEN}, but darker.
+ */
+ GREEN,
+ /**
+ * See {@link AnsiStandardColor#YELLOW}, but darker.
+ */
+ YELLOW,
+ /**
+ * See {@link AnsiStandardColor#BLUE}, but darker.
+ */
+ BLUE,
+ /**
+ * See {@link AnsiStandardColor#MAGENTA}, but darker.
+ */
+ MAGENTA,
+ /**
+ * See {@link AnsiStandardColor#CYAN}, but darker.
+ */
+ CYAN,
+ /**
+ * Usually grey.
+ */
+ WHITE;
+
+ /**
+ * An unmodifiable list giving all the dim colors
+ */
+ public static final List ALL = List.of(AnsiDimColor.values());
+
+ /**
+ * Get the dim color for the given numerical code
+ *
+ *
+ * For example, the sequence {@code CSI [ 34 m} would use code 4 (blue).
+ *
+ * @param code the code
+ * @return the color
+ */
+ public static AnsiDimColor get(int code) {
+ return ALL.get(code);
+ }
+ }
+
/**
* For 8-bit colors, one of the 216 colors from the RGB cube
*
*
* The r, g, and b fields give the "step" number from 0 to 5, dimmest to brightest.
*/
- public record Ansi216Color(int r, int g, int b) implements AnsiColor {
- }
+ public record Ansi216Color(int r, int g, int b) implements AnsiColor {}
/**
* For 8-bit colors, one of the 24 grays
@@ -298,8 +362,7 @@ public interface VtHandler {
* The v field is a value from 0 to 23, 0 being the dimmest, but not true black, and 23 being
* the brightest, but not true white.
*/
- public record AnsiGrayscaleColor(int v) implements AnsiColor {
- }
+ public record AnsiGrayscaleColor(int v) implements AnsiColor {}
/**
* A 24-bit color
@@ -307,8 +370,7 @@ public interface VtHandler {
*
* The r, g, and b fields are values from 0 to 255 dimmest to brightest.
*/
- public record Ansi24BitColor(int r, int g, int b) implements AnsiColor {
- }
+ public record Ansi24BitColor(int r, int g, int b) implements AnsiColor {}
/**
* Modifies the intensity of the character either by color or by font weight.
@@ -1202,7 +1264,7 @@ public interface VtHandler {
handleBlink(Blink.FAST);
return;
case 7:
- handleReverseVideo(true);
+ handleReverseVideo(ReverseVideo.REVERSED);
return;
case 8:
handleHidden(true);
@@ -1232,7 +1294,7 @@ public interface VtHandler {
handleProportionalSpacing(true);
return;
case 27:
- handleReverseVideo(false);
+ handleReverseVideo(ReverseVideo.NORMAL);
return;
case 28:
handleHidden(false);
@@ -1345,9 +1407,9 @@ public interface VtHandler {
* "default background," care must be taken to ensure the foreground is still painted in
* reversed mode.
*
- * @param reverse true to reverse, false otherwise
+ * @param reverse the reverse video mode
*/
- void handleReverseVideo(boolean reverse);
+ void handleReverseVideo(ReverseVideo reverse);
/**
* Handle toggling of the hidden attribute
diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/terminal/TerminalProviderTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/terminal/TerminalProviderTest.java
index 952c61cb73..05e7e6d843 100644
--- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/terminal/TerminalProviderTest.java
+++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/terminal/TerminalProviderTest.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -63,6 +63,8 @@ public class TerminalProviderTest extends AbstractGhidraHeadedDebuggerTest {
terminalService = addPlugin(tool, TerminalPlugin.class);
clipboardService = addPlugin(tool, ClipboardPlugin.class);
+ env.showFrontEndTool();
+
PtyFactory factory = PtyFactory.local();
try (Pty pty = factory.openpty()) {
Map env = new HashMap<>(System.getenv());