mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/GP-5003_improveTerminalFonts--SQUASHED'
This commit is contained in:
commit
473c16f1cb
12 changed files with 456 additions and 152 deletions
|
@ -90,6 +90,21 @@
|
|||
selected, then this selects nothing, so that pressing the keystroke twice is effectively
|
||||
"Select None."</P>
|
||||
|
||||
<H3><A name="increase_font_size"></A>Increase Font Size</H3>
|
||||
|
||||
<P>This is accessed using the local drop-down menu or the key sequence <B>CTRL-SHIFT-PLUS</B>.
|
||||
It increases the font size for this terminal.</P>
|
||||
|
||||
<H3><A name="decrease_font_size"></A>Decrease Font Size</H3>
|
||||
|
||||
<P>This is accessed using the local drop-down menu or the key sequence <B>CTRL-MINUS</B>. It
|
||||
decreases the font size for this terminal.</P>
|
||||
|
||||
<H3><A name="reset_font_size"></A>Reset Font Size</H3>
|
||||
|
||||
<P>This is accessed using the local drop-down menu or the key sequence <B>CTRL-0</B>. It resets
|
||||
the font size for this terminal according to the theme's configuration'.</P>
|
||||
|
||||
<H3><A name="terminate"></A>Terminate</H3>
|
||||
|
||||
<P>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
|
|||
|
||||
<UL>
|
||||
<LI><B>Type</B>: 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.</LI>
|
||||
"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.</LI>
|
||||
</UL>
|
||||
|
||||
<H4>EXDI</H4>
|
||||
|
||||
<P>Setup for EXDI connections is fairly complicated and difficult to get correct.
|
||||
The argument string typically should be something like:</P>
|
||||
<P>Setup for EXDI connections is fairly complicated and difficult to get correct. The argument
|
||||
string typically should be something like:</P>
|
||||
|
||||
<UL style='list-style-type: none'>
|
||||
<LI>
|
||||
<PRE>
|
||||
exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,DataBreaks=Exdi
|
||||
</PRE>
|
||||
<PRE>
|
||||
exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,DataBreaks=Exdi
|
||||
</PRE>
|
||||
</LI>
|
||||
</UL>
|
||||
<P>The CLSID here should match the CLSID in the <B>exdiConfigData.xml</B> 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 <B>exdiConfigData</B> file should be configured for the target you're using. We heavily recommend using <B>displayCommPackets==yes</B>,
|
||||
as many of the tasks take considerable time, and this is the only indicator of progress.
|
||||
</P>
|
||||
|
||||
<P>The <B>Kd=Guess</B> parameter causes the underlying engine to scan memory for the kernel's base address, which will probably not
|
||||
be provided by the gdbstub. (<B>Kd=NtBaseAddr</B> 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.
|
||||
</P>
|
||||
<P>The CLSID here should match the CLSID in the <B>exdiConfigData.xml</B> 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 <B>exdiConfigData</B> file should be configured for the target
|
||||
you're using. We heavily recommend using <B>displayCommPackets==yes</B>, as many of the tasks
|
||||
take considerable time, and this is the only indicator of progress.</P>
|
||||
|
||||
<P>The <B>Kd=Guess</B> parameter causes the underlying engine to scan memory for the kernel's
|
||||
base address, which will probably not be provided by the gdbstub. (<B>Kd=NtBaseAddr</B> 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.</P>
|
||||
|
||||
<H3><A name="dbgeng_ttd"></A>TTD (Time-Travel Debugging)</H3>
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<LayoutModelListener> 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();
|
||||
|
|
|
@ -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<String> 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,21 +507,33 @@ 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;
|
||||
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;
|
||||
}
|
||||
return null; // background is already drawn
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
|
@ -448,6 +543,7 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel
|
|||
case CYAN -> COLOR_6_CYAN;
|
||||
case WHITE -> COLOR_7_WHITE;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
protected Color resolveIntenseColor(AnsiIntenseColor intense) {
|
||||
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<AnsiStandardColor> 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<AnsiDimColor> ALL = List.of(AnsiDimColor.values());
|
||||
|
||||
/**
|
||||
* Get the dim color for the given numerical code
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
*
|
||||
* <p>
|
||||
* 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 {
|
|||
* <p>
|
||||
* 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
|
||||
|
|
|
@ -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<String, String> env = new HashMap<>(System.getenv());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue